diff options
Diffstat (limited to 'sound')
115 files changed, 891 insertions, 9432 deletions
diff --git a/sound/Kconfig b/sound/Kconfig index e56d96d2b11c..0ddfb717b81d 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -107,7 +107,6 @@ endif # !UML endif # SOUND -# AC97_BUS is used from both sound and ucb1400 config AC97_BUS tristate help diff --git a/sound/core/control.c b/sound/core/control.c index 50e7ba66f187..82aa1af1d1d8 100644 --- a/sound/core/control.c +++ b/sound/core/control.c @@ -1203,14 +1203,19 @@ static int snd_ctl_elem_read(struct snd_card *card, const u32 pattern = 0xdeadbeef; int ret; + down_read(&card->controls_rwsem); kctl = snd_ctl_find_id(card, &control->id); - if (kctl == NULL) - return -ENOENT; + if (kctl == NULL) { + ret = -ENOENT; + goto unlock; + } index_offset = snd_ctl_get_ioff(kctl, &control->id); vd = &kctl->vd[index_offset]; - if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) - return -EPERM; + if (!(vd->access & SNDRV_CTL_ELEM_ACCESS_READ) || kctl->get == NULL) { + ret = -EPERM; + goto unlock; + } snd_ctl_build_ioff(&control->id, kctl, index_offset); @@ -1220,7 +1225,7 @@ static int snd_ctl_elem_read(struct snd_card *card, info.id = control->id; ret = __snd_ctl_elem_info(card, kctl, &info, NULL); if (ret < 0) - return ret; + goto unlock; #endif if (!snd_ctl_skip_validation(&info)) @@ -1230,7 +1235,7 @@ static int snd_ctl_elem_read(struct snd_card *card, ret = kctl->get(kctl, control); snd_power_unref(card); if (ret < 0) - return ret; + goto unlock; if (!snd_ctl_skip_validation(&info) && sanity_check_elem_value(card, control, &info, pattern) < 0) { dev_err(card->dev, @@ -1238,8 +1243,11 @@ static int snd_ctl_elem_read(struct snd_card *card, control->id.iface, control->id.device, control->id.subdevice, control->id.name, control->id.index); - return -EINVAL; + ret = -EINVAL; + goto unlock; } +unlock: + up_read(&card->controls_rwsem); return ret; } @@ -1253,9 +1261,7 @@ static int snd_ctl_elem_read_user(struct snd_card *card, if (IS_ERR(control)) return PTR_ERR(control); - down_read(&card->controls_rwsem); result = snd_ctl_elem_read(card, control); - up_read(&card->controls_rwsem); if (result < 0) goto error; diff --git a/sound/core/control_led.c b/sound/core/control_led.c index f975cc85772b..3cadd40100f3 100644 --- a/sound/core/control_led.c +++ b/sound/core/control_led.c @@ -530,12 +530,11 @@ static ssize_t set_led_id(struct snd_ctl_led_card *led_card, const char *buf, si bool attach) { char buf2[256], *s, *os; - size_t len = max(sizeof(s) - 1, count); struct snd_ctl_elem_id id; int err; - strncpy(buf2, buf, len); - buf2[len] = '\0'; + if (strscpy(buf2, buf, sizeof(buf2)) < 0) + return -E2BIG; memset(&id, 0, sizeof(id)); id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; s = buf2; diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c index 81025f50a542..f901504b5afc 100644 --- a/sound/core/memalloc.c +++ b/sound/core/memalloc.c @@ -541,16 +541,15 @@ static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size) struct sg_table *sgt; void *p; +#ifdef CONFIG_SND_DMA_SGBUF + if (cpu_feature_enabled(X86_FEATURE_XENPV)) + return snd_dma_sg_fallback_alloc(dmab, size); +#endif sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir, DEFAULT_GFP, 0); #ifdef CONFIG_SND_DMA_SGBUF - if (!sgt && !get_dma_ops(dmab->dev.dev)) { - if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) - dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; - else - dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; + if (!sgt && !get_dma_ops(dmab->dev.dev)) return snd_dma_sg_fallback_alloc(dmab, size); - } #endif if (!sgt) return NULL; @@ -717,19 +716,38 @@ static const struct snd_malloc_ops snd_dma_sg_wc_ops = { /* Fallback SG-buffer allocations for x86 */ struct snd_dma_sg_fallback { + bool use_dma_alloc_coherent; size_t count; struct page **pages; + /* DMA address array; the first page contains #pages in ~PAGE_MASK */ + dma_addr_t *addrs; }; static void __snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab, struct snd_dma_sg_fallback *sgbuf) { - bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; - size_t i; - - for (i = 0; i < sgbuf->count && sgbuf->pages[i]; i++) - do_free_pages(page_address(sgbuf->pages[i]), PAGE_SIZE, wc); + size_t i, size; + + if (sgbuf->pages && sgbuf->addrs) { + i = 0; + while (i < sgbuf->count) { + if (!sgbuf->pages[i] || !sgbuf->addrs[i]) + break; + size = sgbuf->addrs[i] & ~PAGE_MASK; + if (WARN_ON(!size)) + break; + if (sgbuf->use_dma_alloc_coherent) + dma_free_coherent(dmab->dev.dev, size << PAGE_SHIFT, + page_address(sgbuf->pages[i]), + sgbuf->addrs[i] & PAGE_MASK); + else + do_free_pages(page_address(sgbuf->pages[i]), + size << PAGE_SHIFT, false); + i += size; + } + } kvfree(sgbuf->pages); + kvfree(sgbuf->addrs); kfree(sgbuf); } @@ -738,24 +756,36 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) struct snd_dma_sg_fallback *sgbuf; struct page **pagep, *curp; size_t chunk, npages; + dma_addr_t *addrp; dma_addr_t addr; void *p; - bool wc = dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; + + /* correct the type */ + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_SG) + dmab->dev.type = SNDRV_DMA_TYPE_DEV_SG_FALLBACK; + else if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG) + dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK; sgbuf = kzalloc(sizeof(*sgbuf), GFP_KERNEL); if (!sgbuf) return NULL; + sgbuf->use_dma_alloc_coherent = cpu_feature_enabled(X86_FEATURE_XENPV); size = PAGE_ALIGN(size); sgbuf->count = size >> PAGE_SHIFT; sgbuf->pages = kvcalloc(sgbuf->count, sizeof(*sgbuf->pages), GFP_KERNEL); - if (!sgbuf->pages) + sgbuf->addrs = kvcalloc(sgbuf->count, sizeof(*sgbuf->addrs), GFP_KERNEL); + if (!sgbuf->pages || !sgbuf->addrs) goto error; pagep = sgbuf->pages; - chunk = size; + addrp = sgbuf->addrs; + chunk = (PAGE_SIZE - 1) << PAGE_SHIFT; /* to fit in low bits in addrs */ while (size > 0) { chunk = min(size, chunk); - p = do_alloc_pages(dmab->dev.dev, chunk, &addr, wc); + if (sgbuf->use_dma_alloc_coherent) + p = dma_alloc_coherent(dmab->dev.dev, chunk, &addr, DEFAULT_GFP); + else + p = do_alloc_pages(dmab->dev.dev, chunk, &addr, false); if (!p) { if (chunk <= PAGE_SIZE) goto error; @@ -767,17 +797,25 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) size -= chunk; /* fill pages */ npages = chunk >> PAGE_SHIFT; + *addrp = npages; /* store in lower bits */ curp = virt_to_page(p); - while (npages--) + while (npages--) { *pagep++ = curp++; + *addrp++ |= addr; + addr += PAGE_SIZE; + } } p = vmap(sgbuf->pages, sgbuf->count, VM_MAP, PAGE_KERNEL); if (!p) goto error; + + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK) + set_pages_array_wc(sgbuf->pages, sgbuf->count); + dmab->private_data = sgbuf; /* store the first page address for convenience */ - dmab->addr = snd_sgbuf_get_addr(dmab, 0); + dmab->addr = sgbuf->addrs[0] & PAGE_MASK; return p; error: @@ -787,10 +825,23 @@ static void *snd_dma_sg_fallback_alloc(struct snd_dma_buffer *dmab, size_t size) static void snd_dma_sg_fallback_free(struct snd_dma_buffer *dmab) { + struct snd_dma_sg_fallback *sgbuf = dmab->private_data; + + if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK) + set_pages_array_wb(sgbuf->pages, sgbuf->count); vunmap(dmab->area); __snd_dma_sg_fallback_free(dmab, dmab->private_data); } +static dma_addr_t snd_dma_sg_fallback_get_addr(struct snd_dma_buffer *dmab, + size_t offset) +{ + struct snd_dma_sg_fallback *sgbuf = dmab->private_data; + size_t index = offset >> PAGE_SHIFT; + + return (sgbuf->addrs[index] & PAGE_MASK) | (offset & ~PAGE_MASK); +} + static int snd_dma_sg_fallback_mmap(struct snd_dma_buffer *dmab, struct vm_area_struct *area) { @@ -805,8 +856,8 @@ static const struct snd_malloc_ops snd_dma_sg_fallback_ops = { .alloc = snd_dma_sg_fallback_alloc, .free = snd_dma_sg_fallback_free, .mmap = snd_dma_sg_fallback_mmap, + .get_addr = snd_dma_sg_fallback_get_addr, /* reuse vmalloc helpers */ - .get_addr = snd_dma_vmalloc_get_addr, .get_page = snd_dma_vmalloc_get_page, .get_chunk_size = snd_dma_vmalloc_get_chunk_size, }; diff --git a/sound/firewire/motu/motu-hwdep.c b/sound/firewire/motu/motu-hwdep.c index a900fc0e7644..88d1f4b56e4b 100644 --- a/sound/firewire/motu/motu-hwdep.c +++ b/sound/firewire/motu/motu-hwdep.c @@ -87,6 +87,10 @@ static long hwdep_read(struct snd_hwdep *hwdep, char __user *buf, long count, return -EFAULT; count = consumed; + } else { + spin_unlock_irq(&motu->lock); + + count = 0; } return count; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index ff685321f1a1..9afc5906d662 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -152,7 +152,6 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x4e534300, 0xffffffff, "LM4540,43,45,46,48", NULL, NULL }, // only guess --jk { 0x4e534331, 0xffffffff, "LM4549", NULL, NULL }, { 0x4e534350, 0xffffffff, "LM4550", patch_lm4550, NULL }, // volume wrap fix -{ 0x50534304, 0xffffffff, "UCB1400", patch_ucb1400, NULL }, { 0x53494c20, 0xffffffe0, "Si3036,8", mpatch_si3036, mpatch_si3036, AC97_MODEM_PATCH }, { 0x53544d02, 0xffffffff, "ST7597", NULL, NULL }, { 0x54524102, 0xffffffff, "TR28022", NULL, NULL }, diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index 025c1666c1fc..4b5f33de70d5 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3937,43 +3937,3 @@ static int patch_lm4550(struct snd_ac97 *ac97) ac97->res_table = lm4550_restbl; return 0; } - -/* - * UCB1400 codec (http://www.semiconductors.philips.com/acrobat_download/datasheets/UCB1400-02.pdf) - */ -static const struct snd_kcontrol_new snd_ac97_controls_ucb1400[] = { -/* enable/disable headphone driver which allows direct connection to - stereo headphone without the use of external DC blocking - capacitors */ -AC97_SINGLE("Headphone Driver", 0x6a, 6, 1, 0), -/* Filter used to compensate the DC offset is added in the ADC to remove idle - tones from the audio band. */ -AC97_SINGLE("DC Filter", 0x6a, 4, 1, 0), -/* Control smart-low-power mode feature. Allows automatic power down - of unused blocks in the ADC analog front end and the PLL. */ -AC97_SINGLE("Smart Low Power Mode", 0x6c, 4, 3, 0), -}; - -static int patch_ucb1400_specific(struct snd_ac97 * ac97) -{ - int idx, err; - for (idx = 0; idx < ARRAY_SIZE(snd_ac97_controls_ucb1400); idx++) { - err = snd_ctl_add(ac97->bus->card, snd_ctl_new1(&snd_ac97_controls_ucb1400[idx], ac97)); - if (err < 0) - return err; - } - return 0; -} - -static const struct snd_ac97_build_ops patch_ucb1400_ops = { - .build_specific = patch_ucb1400_specific, -}; - -static int patch_ucb1400(struct snd_ac97 * ac97) -{ - ac97->build_ops = &patch_ucb1400_ops; - /* enable headphone driver and smart low power mode by default */ - snd_ac97_write_cache(ac97, 0x6a, 0x0050); - snd_ac97_write_cache(ac97, 0x6c, 0x0030); - return 0; -} diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c index 91842c0c8c74..f7815ee24f83 100644 --- a/sound/pci/hda/cs35l41_hda.c +++ b/sound/pci/hda/cs35l41_hda.c @@ -598,8 +598,8 @@ static int cs35l41_system_suspend(struct device *dev) dev_dbg(cs35l41->dev, "System Suspend\n"); if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { - dev_err(cs35l41->dev, "System Suspend not supported\n"); - return -EINVAL; + dev_err_once(cs35l41->dev, "System Suspend not supported\n"); + return 0; /* don't block the whole system suspend */ } ret = pm_runtime_force_suspend(dev); @@ -624,8 +624,8 @@ static int cs35l41_system_resume(struct device *dev) dev_dbg(cs35l41->dev, "System Resume\n"); if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) { - dev_err(cs35l41->dev, "System Resume not supported\n"); - return -EINVAL; + dev_err_once(cs35l41->dev, "System Resume not supported\n"); + return 0; /* don't block the whole system resume */ } if (cs35l41->reset_gpio) { @@ -647,6 +647,15 @@ static int cs35l41_system_resume(struct device *dev) return ret; } +static int cs35l41_runtime_idle(struct device *dev) +{ + struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); + + if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH) + return -EBUSY; /* suspend not supported yet on this model */ + return 0; +} + static int cs35l41_runtime_suspend(struct device *dev) { struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev); @@ -1536,7 +1545,8 @@ void cs35l41_hda_remove(struct device *dev) EXPORT_SYMBOL_NS_GPL(cs35l41_hda_remove, SND_HDA_SCODEC_CS35L41); const struct dev_pm_ops cs35l41_hda_pm_ops = { - RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL) + RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, + cs35l41_runtime_idle) SYSTEM_SLEEP_PM_OPS(cs35l41_system_suspend, cs35l41_system_resume) }; EXPORT_SYMBOL_NS_GPL(cs35l41_hda_pm_ops, SND_HDA_SCODEC_CS35L41); diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c index 1a868dd9dc4b..890c2f7c33fc 100644 --- a/sound/pci/hda/hda_bind.c +++ b/sound/pci/hda/hda_bind.c @@ -144,6 +144,7 @@ static int hda_codec_driver_probe(struct device *dev) error: snd_hda_codec_cleanup_for_unbind(codec); + codec->preset = NULL; return err; } @@ -166,6 +167,7 @@ static int hda_codec_driver_remove(struct device *dev) if (codec->patch_ops.free) codec->patch_ops.free(codec); snd_hda_codec_cleanup_for_unbind(codec); + codec->preset = NULL; module_put(dev->driver->owner); return 0; } diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index edd653ece70d..2e728aad6771 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -795,7 +795,6 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) snd_array_free(&codec->cvt_setups); snd_array_free(&codec->spdif_out); snd_array_free(&codec->verbs); - codec->preset = NULL; codec->follower_dig_outs = NULL; codec->spdif_status_reset = 0; snd_array_free(&codec->mixers); @@ -928,7 +927,6 @@ snd_hda_codec_device_init(struct hda_bus *bus, unsigned int codec_addr, codec->depop_delay = -1; codec->fixup_id = HDA_FIXUP_ID_NOT_SET; codec->core.dev.release = snd_hda_codec_dev_release; - codec->core.exec_verb = codec_exec_verb; codec->core.type = HDA_DEV_LEGACY; mutex_init(&codec->spdif_mutex); @@ -999,6 +997,7 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) return -EINVAL; + codec->core.exec_verb = codec_exec_verb; codec->card = card; codec->addr = codec_addr; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 7b1a30a551f6..75e1d00074b9 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -1125,6 +1125,7 @@ static const struct hda_device_id snd_hda_id_conexant[] = { HDA_CODEC_ENTRY(0x14f11f87, "SN6140", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f12008, "CX8200", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f120d0, "CX11970", patch_conexant_auto), + HDA_CODEC_ENTRY(0x14f120d1, "SN6180", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15045, "CX20549 (Venice)", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15047, "CX20551 (Waikiki)", patch_conexant_auto), HDA_CODEC_ENTRY(0x14f15051, "CX20561 (Hermosa)", patch_conexant_auto), diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 386dd9d9143f..9ea633fe9339 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1981,6 +1981,7 @@ static const struct snd_pci_quirk force_connect_list[] = { SND_PCI_QUIRK(0x103c, 0x870f, "HP", 1), SND_PCI_QUIRK(0x103c, 0x871a, "HP", 1), SND_PCI_QUIRK(0x103c, 0x8711, "HP", 1), + SND_PCI_QUIRK(0x103c, 0x8715, "HP", 1), SND_PCI_QUIRK(0x1462, 0xec94, "MS-7C94", 1), SND_PCI_QUIRK(0x8086, 0x2081, "Intel NUC 10", 1), {} diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3794b522c222..e103bb3693c0 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -832,7 +832,7 @@ do_sku: alc_setup_gpio(codec, 0x02); break; case 7: - alc_setup_gpio(codec, 0x03); + alc_setup_gpio(codec, 0x04); break; case 5: default: @@ -3564,6 +3564,15 @@ static void alc256_init(struct hda_codec *codec) hda_nid_t hp_pin = alc_get_hp_pin(spec); bool hp_pin_sense; + if (spec->ultra_low_power) { + alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1); + alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2); + alc_update_coef_idx(codec, 0x08, 7<<4, 0); + alc_update_coef_idx(codec, 0x3b, 1<<15, 0); + alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6); + msleep(30); + } + if (!hp_pin) hp_pin = 0x21; @@ -3575,14 +3584,6 @@ static void alc256_init(struct hda_codec *codec) msleep(2); alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ - if (spec->ultra_low_power) { - alc_update_coef_idx(codec, 0x03, 1<<1, 1<<1); - alc_update_coef_idx(codec, 0x08, 3<<2, 3<<2); - alc_update_coef_idx(codec, 0x08, 7<<4, 0); - alc_update_coef_idx(codec, 0x3b, 1<<15, 0); - alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6); - msleep(30); - } snd_hda_codec_write(codec, hp_pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); @@ -3713,6 +3714,13 @@ static void alc225_init(struct hda_codec *codec) hda_nid_t hp_pin = alc_get_hp_pin(spec); bool hp1_pin_sense, hp2_pin_sense; + if (spec->ultra_low_power) { + alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2); + alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6); + alc_update_coef_idx(codec, 0x33, 1<<11, 0); + msleep(30); + } + if (spec->codec_variant != ALC269_TYPE_ALC287 && spec->codec_variant != ALC269_TYPE_ALC245) /* required only at boot or S3 and S4 resume time */ @@ -3734,12 +3742,6 @@ static void alc225_init(struct hda_codec *codec) msleep(2); alc_update_coefex_idx(codec, 0x57, 0x04, 0x0007, 0x1); /* Low power */ - if (spec->ultra_low_power) { - alc_update_coef_idx(codec, 0x08, 0x0f << 2, 3<<2); - alc_update_coef_idx(codec, 0x0e, 7<<6, 7<<6); - alc_update_coef_idx(codec, 0x33, 1<<11, 0); - msleep(30); - } if (hp1_pin_sense || spec->ultra_low_power) snd_hda_codec_write(codec, hp_pin, 0, @@ -4644,6 +4646,16 @@ static void alc285_fixup_hp_coef_micmute_led(struct hda_codec *codec, } } +static void alc285_fixup_hp_gpio_micmute_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + struct alc_spec *spec = codec->spec; + + if (action == HDA_FIXUP_ACT_PRE_PROBE) + spec->micmute_led_polarity = 1; + alc_fixup_hp_gpio_led(codec, action, 0, 0x04); +} + static void alc236_fixup_hp_coef_micmute_led(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -4665,6 +4677,13 @@ static void alc285_fixup_hp_mute_led(struct hda_codec *codec, alc285_fixup_hp_coef_micmute_led(codec, fix, action); } +static void alc285_fixup_hp_spectre_x360_mute_led(struct hda_codec *codec, + const struct hda_fixup *fix, int action) +{ + alc285_fixup_hp_mute_led_coefbit(codec, fix, action); + alc285_fixup_hp_gpio_micmute_led(codec, fix, action); +} + static void alc236_fixup_hp_mute_led(struct hda_codec *codec, const struct hda_fixup *fix, int action) { @@ -7106,6 +7125,7 @@ enum { ALC285_FIXUP_ASUS_G533Z_PINS, ALC285_FIXUP_HP_GPIO_LED, ALC285_FIXUP_HP_MUTE_LED, + ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED, ALC236_FIXUP_HP_GPIO_LED, ALC236_FIXUP_HP_MUTE_LED, ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF, @@ -8486,6 +8506,10 @@ static const struct hda_fixup alc269_fixups[] = { .type = HDA_FIXUP_FUNC, .v.func = alc285_fixup_hp_mute_led, }, + [ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc285_fixup_hp_spectre_x360_mute_led, + }, [ALC236_FIXUP_HP_GPIO_LED] = { .type = HDA_FIXUP_FUNC, .v.func = alc236_fixup_hp_gpio_led, @@ -9178,6 +9202,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x142b, "Acer Swift SF314-42", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1430, "Acer TravelMate B311R-31", ALC256_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1025, 0x1466, "Acer Aspire A515-56", ALC255_FIXUP_ACER_HEADPHONE_AND_MIC), + SND_PCI_QUIRK(0x1025, 0x1534, "Acer Predator PH315-54", ALC255_FIXUP_ACER_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x1028, 0x053c, "Dell Latitude E5430", ALC292_FIXUP_DELL_E7X), SND_PCI_QUIRK(0x1028, 0x054b, "Dell XPS one 2710", ALC275_FIXUP_DELL_XPS), @@ -9239,6 +9264,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0b1a, "Dell Precision 5570", ALC289_FIXUP_DUAL_SPK), SND_PCI_QUIRK(0x1028, 0x0b37, "Dell Inspiron 16 Plus 7620 2-in-1", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), SND_PCI_QUIRK(0x1028, 0x0b71, "Dell Inspiron 16 Plus 7620", ALC295_FIXUP_DELL_INSPIRON_TOP_SPEAKERS), + SND_PCI_QUIRK(0x1028, 0x0c03, "Dell Precision 5340", ALC269_FIXUP_DELL4_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1028, 0x0c19, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), SND_PCI_QUIRK(0x1028, 0x0c1a, "Dell Precision 3340", ALC236_FIXUP_DELL_DUAL_CODECS), SND_PCI_QUIRK(0x1028, 0x0c1b, "Dell Precision 3440", ALC236_FIXUP_DELL_DUAL_CODECS), @@ -9327,6 +9353,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x86c7, "HP Envy AiO 32", ALC274_FIXUP_HP_ENVY_GPIO), SND_PCI_QUIRK(0x103c, 0x86e7, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), SND_PCI_QUIRK(0x103c, 0x86e8, "HP Spectre x360 15-eb0xxx", ALC285_FIXUP_HP_SPECTRE_X360_EB1), + SND_PCI_QUIRK(0x103c, 0x86f9, "HP Spectre x360 13-aw0xxx", ALC285_FIXUP_HP_SPECTRE_X360_MUTE_LED), SND_PCI_QUIRK(0x103c, 0x8716, "HP Elite Dragonfly G2 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8720, "HP EliteBook x360 1040 G8 Notebook PC", ALC285_FIXUP_HP_GPIO_AMP_INIT), SND_PCI_QUIRK(0x103c, 0x8724, "HP EliteBook 850 G7", ALC285_FIXUP_HP_GPIO_LED), @@ -9396,6 +9423,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x89c3, "Zbook Studio G9", ALC245_FIXUP_CS35L41_SPI_4_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89c6, "Zbook Fury 17 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x89ca, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x89d3, "HP EliteBook 645 G9 (MB 89D2)", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8a78, "HP Dev One", ALC285_FIXUP_HP_LIMIT_INT_MIC_BOOST), SND_PCI_QUIRK(0x103c, 0x8aa0, "HP ProBook 440 G9 (MB 8A9E)", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8aa3, "HP ProBook 450 G9 (MB 8AA1)", ALC236_FIXUP_HP_GPIO_LED), @@ -9404,8 +9432,22 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x8abb, "HP ZBook Firefly 14 G9", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ad1, "HP EliteBook 840 14 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8ad2, "HP EliteBook 860 16 inch G9 Notebook PC", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b42, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b43, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b44, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b45, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b46, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b47, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), SND_PCI_QUIRK(0x103c, 0x8b5d, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), SND_PCI_QUIRK(0x103c, 0x8b5e, "HP", ALC236_FIXUP_HP_MUTE_LED_MICMUTE_VREF), + SND_PCI_QUIRK(0x103c, 0x8b7a, "HP", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b7d, "HP", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b87, "HP", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b8a, "HP", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b8b, "HP", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b8d, "HP", ALC236_FIXUP_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8b92, "HP", ALC245_FIXUP_CS35L41_SPI_2_HP_GPIO_LED), + SND_PCI_QUIRK(0x103c, 0x8bf0, "HP", ALC236_FIXUP_HP_GPIO_LED), SND_PCI_QUIRK(0x1043, 0x103e, "ASUS X540SA", ALC256_FIXUP_ASUS_MIC), SND_PCI_QUIRK(0x1043, 0x103f, "ASUS TX300", ALC282_FIXUP_ASUS_TX300), SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), @@ -9451,6 +9493,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1d4e, "ASUS TM420", ALC256_FIXUP_ASUS_HPE), SND_PCI_QUIRK(0x1043, 0x1e02, "ASUS UX3402", ALC245_FIXUP_CS35L41_SPI_2), SND_PCI_QUIRK(0x1043, 0x1e11, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA502), + SND_PCI_QUIRK(0x1043, 0x1e12, "ASUS UM3402", ALC287_FIXUP_CS35L41_I2C_2), SND_PCI_QUIRK(0x1043, 0x1e51, "ASUS Zephyrus M15", ALC294_FIXUP_ASUS_GU502_PINS), SND_PCI_QUIRK(0x1043, 0x1e5e, "ASUS ROG Strix G513", ALC294_FIXUP_ASUS_G513_PINS), SND_PCI_QUIRK(0x1043, 0x1e8e, "ASUS Zephyrus G15", ALC289_FIXUP_ASUS_GA401), @@ -9494,6 +9537,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc812, "Samsung Notebook Pen S (NT950SBE-X58)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc830, "Samsung Galaxy Book Ion (NT950XCJ-X716A)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x144d, 0xc832, "Samsung Galaxy Book Flex Alpha (NP730QCJ)", ALC256_FIXUP_SAMSUNG_HEADPHONE_VERY_QUIET), + SND_PCI_QUIRK(0x144d, 0xca03, "Samsung Galaxy Book2 Pro 360 (NP930QED)", ALC298_FIXUP_SAMSUNG_AMP), SND_PCI_QUIRK(0x1458, 0xfa53, "Gigabyte BXBT-2807", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb120, "MSI Cubi MS-B120", ALC283_FIXUP_HEADSET_MIC), SND_PCI_QUIRK(0x1462, 0xb171, "Cubi N 8GL (MS-B171)", ALC283_FIXUP_HEADSET_MIC), @@ -9672,6 +9716,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), + SND_PCI_QUIRK(0x1c6c, 0x1251, "Positivo N14KP6-TG", ALC288_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS), SND_PCI_QUIRK(0x1d05, 0x1096, "TongFang GMxMRxx", ALC269_FIXUP_NO_SHUTUP), SND_PCI_QUIRK(0x1d05, 0x1100, "TongFang GKxNRxx", ALC269_FIXUP_NO_SHUTUP), diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index aea7fae2ca4b..2994f85bc1b9 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -819,6 +819,9 @@ static int add_secret_dac_path(struct hda_codec *codec) return 0; nums = snd_hda_get_connections(codec, spec->gen.mixer_nid, conn, ARRAY_SIZE(conn) - 1); + if (nums < 0) + return nums; + for (i = 0; i < nums; i++) { if (get_wcaps_type(get_wcaps(codec, conn[i])) == AC_WID_AUD_OUT) return 0; diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index d3f58a3d17fb..b5b0d43bb8dc 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c @@ -493,12 +493,11 @@ int lx_buffer_ask(struct lx6464es *chip, u32 pipe, int is_capture, dev_dbg(chip->card->dev, "CMD_08_ASK_BUFFERS: needed %d, freed %d\n", *r_needed, *r_freed); - for (i = 0; i < MAX_STREAM_BUFFER; ++i) { - for (i = 0; i != chip->rmh.stat_len; ++i) - dev_dbg(chip->card->dev, - " stat[%d]: %x, %x\n", i, - chip->rmh.stat[i], - chip->rmh.stat[i] & MASK_DATA_SIZE); + for (i = 0; i < MAX_STREAM_BUFFER && i < chip->rmh.stat_len; + ++i) { + dev_dbg(chip->card->dev, " stat[%d]: %x, %x\n", i, + chip->rmh.stat[i], + chip->rmh.stat[i] & MASK_DATA_SIZE); } } diff --git a/sound/soc/amd/acp-es8336.c b/sound/soc/amd/acp-es8336.c index 2fe8df86053a..89499542c803 100644 --- a/sound/soc/amd/acp-es8336.c +++ b/sound/soc/amd/acp-es8336.c @@ -198,9 +198,11 @@ static int st_es8336_late_probe(struct snd_soc_card *card) int ret; adev = acpi_dev_get_first_match_dev("ESSX8336", NULL, -1); - if (adev) - put_device(&adev->dev); + if (!adev) + return -ENODEV; + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) dev_err(card->dev, "can not find codec dev\n"); diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c index 1f0b5527c594..36314753923b 100644 --- a/sound/soc/amd/yc/acp6x-mach.c +++ b/sound/soc/amd/yc/acp6x-mach.c @@ -209,6 +209,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { { .driver_data = &acp6x_card, .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "M5402RA"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { DMI_MATCH(DMI_BOARD_VENDOR, "Alienware"), DMI_MATCH(DMI_PRODUCT_NAME, "Alienware m17 R5 AMD"), } @@ -220,6 +227,34 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 14 2022"), } }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "TIMI"), + DMI_MATCH(DMI_PRODUCT_NAME, "Redmi Book Pro 15 2022"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Razer"), + DMI_MATCH(DMI_PRODUCT_NAME, "Blade 14 (2022) - RZ09-0427"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "RB"), + DMI_MATCH(DMI_PRODUCT_NAME, "Swift SFA16-41"), + } + }, + { + .driver_data = &acp6x_card, + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "IRBIS"), + DMI_MATCH(DMI_PRODUCT_NAME, "15NBC1011"), + } + }, {} }; diff --git a/sound/soc/cirrus/Kconfig b/sound/soc/cirrus/Kconfig index 8039a8febefa..34870c2d0cba 100644 --- a/sound/soc/cirrus/Kconfig +++ b/sound/soc/cirrus/Kconfig @@ -27,29 +27,6 @@ config SND_EP93XX_SOC_I2S_WATCHDOG endif # if SND_EP93XX_SOC_I2S -config SND_EP93XX_SOC_AC97 - tristate - select AC97_BUS - select SND_SOC_AC97_BUS - -config SND_EP93XX_SOC_SNAPPERCL15 - tristate "SoC Audio support for Bluewater Systems Snapper CL15 module" - depends on SND_EP93XX_SOC && MACH_SNAPPER_CL15 && I2C - select SND_EP93XX_SOC_I2S - select SND_SOC_TLV320AIC23_I2C - help - Say Y or M here if you want to add support for I2S audio on the - Bluewater Systems Snapper CL15 module. - -config SND_EP93XX_SOC_SIMONE - tristate "SoC Audio support for Simplemachines Sim.One board" - depends on SND_EP93XX_SOC && MACH_SIM_ONE - select SND_EP93XX_SOC_AC97 - select SND_SOC_AC97_CODEC - help - Say Y or M here if you want to add support for AC97 audio on the - Simplemachines Sim.One board. - config SND_EP93XX_SOC_EDB93XX tristate "SoC Audio support for Cirrus Logic EDB93xx boards" depends on SND_EP93XX_SOC && (MACH_EDB9301 || MACH_EDB9302 || MACH_EDB9302A || MACH_EDB9307A || MACH_EDB9315A) diff --git a/sound/soc/cirrus/Makefile b/sound/soc/cirrus/Makefile index bfb8dc409f53..19a86daad660 100644 --- a/sound/soc/cirrus/Makefile +++ b/sound/soc/cirrus/Makefile @@ -2,17 +2,11 @@ # EP93xx Platform Support snd-soc-ep93xx-objs := ep93xx-pcm.o snd-soc-ep93xx-i2s-objs := ep93xx-i2s.o -snd-soc-ep93xx-ac97-objs := ep93xx-ac97.o obj-$(CONFIG_SND_EP93XX_SOC) += snd-soc-ep93xx.o obj-$(CONFIG_SND_EP93XX_SOC_I2S) += snd-soc-ep93xx-i2s.o -obj-$(CONFIG_SND_EP93XX_SOC_AC97) += snd-soc-ep93xx-ac97.o # EP93XX Machine Support -snd-soc-snappercl15-objs := snappercl15.o -snd-soc-simone-objs := simone.o snd-soc-edb93xx-objs := edb93xx.o -obj-$(CONFIG_SND_EP93XX_SOC_SNAPPERCL15) += snd-soc-snappercl15.o -obj-$(CONFIG_SND_EP93XX_SOC_SIMONE) += snd-soc-simone.o obj-$(CONFIG_SND_EP93XX_SOC_EDB93XX) += snd-soc-edb93xx.o diff --git a/sound/soc/cirrus/ep93xx-ac97.c b/sound/soc/cirrus/ep93xx-ac97.c deleted file mode 100644 index 37593abe6053..000000000000 --- a/sound/soc/cirrus/ep93xx-ac97.c +++ /dev/null @@ -1,446 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ASoC driver for Cirrus Logic EP93xx AC97 controller. - * - * Copyright (c) 2010 Mika Westerberg - * - * Based on s3c-ac97 ASoC driver by Jaswinder Singh. - */ - -#include <linux/delay.h> -#include <linux/err.h> -#include <linux/io.h> -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include <sound/core.h> -#include <sound/dmaengine_pcm.h> -#include <sound/ac97_codec.h> -#include <sound/soc.h> - -#include <linux/platform_data/dma-ep93xx.h> -#include <linux/soc/cirrus/ep93xx.h> - -#include "ep93xx-pcm.h" - -/* - * Per channel (1-4) registers. - */ -#define AC97CH(n) (((n) - 1) * 0x20) - -#define AC97DR(n) (AC97CH(n) + 0x0000) - -#define AC97RXCR(n) (AC97CH(n) + 0x0004) -#define AC97RXCR_REN BIT(0) -#define AC97RXCR_RX3 BIT(3) -#define AC97RXCR_RX4 BIT(4) -#define AC97RXCR_CM BIT(15) - -#define AC97TXCR(n) (AC97CH(n) + 0x0008) -#define AC97TXCR_TEN BIT(0) -#define AC97TXCR_TX3 BIT(3) -#define AC97TXCR_TX4 BIT(4) -#define AC97TXCR_CM BIT(15) - -#define AC97SR(n) (AC97CH(n) + 0x000c) -#define AC97SR_TXFE BIT(1) -#define AC97SR_TXUE BIT(6) - -#define AC97RISR(n) (AC97CH(n) + 0x0010) -#define AC97ISR(n) (AC97CH(n) + 0x0014) -#define AC97IE(n) (AC97CH(n) + 0x0018) - -/* - * Global AC97 controller registers. - */ -#define AC97S1DATA 0x0080 -#define AC97S2DATA 0x0084 -#define AC97S12DATA 0x0088 - -#define AC97RGIS 0x008c -#define AC97GIS 0x0090 -#define AC97IM 0x0094 -/* - * Common bits for RGIS, GIS and IM registers. - */ -#define AC97_SLOT2RXVALID BIT(1) -#define AC97_CODECREADY BIT(5) -#define AC97_SLOT2TXCOMPLETE BIT(6) - -#define AC97EOI 0x0098 -#define AC97EOI_WINT BIT(0) -#define AC97EOI_CODECREADY BIT(1) - -#define AC97GCR 0x009c -#define AC97GCR_AC97IFE BIT(0) - -#define AC97RESET 0x00a0 -#define AC97RESET_TIMEDRESET BIT(0) - -#define AC97SYNC 0x00a4 -#define AC97SYNC_TIMEDSYNC BIT(0) - -#define AC97_TIMEOUT msecs_to_jiffies(5) - -/** - * struct ep93xx_ac97_info - EP93xx AC97 controller info structure - * @lock: mutex serializing access to the bus (slot 1 & 2 ops) - * @dev: pointer to the platform device dev structure - * @regs: mapped AC97 controller registers - * @done: bus ops wait here for an interrupt - */ -struct ep93xx_ac97_info { - struct mutex lock; - struct device *dev; - void __iomem *regs; - struct completion done; - struct snd_dmaengine_dai_dma_data dma_params_rx; - struct snd_dmaengine_dai_dma_data dma_params_tx; -}; - -/* currently ALSA only supports a single AC97 device */ -static struct ep93xx_ac97_info *ep93xx_ac97_info; - -static struct ep93xx_dma_data ep93xx_ac97_pcm_out = { - .name = "ac97-pcm-out", - .port = EP93XX_DMA_AAC1, - .direction = DMA_MEM_TO_DEV, -}; - -static struct ep93xx_dma_data ep93xx_ac97_pcm_in = { - .name = "ac97-pcm-in", - .port = EP93XX_DMA_AAC1, - .direction = DMA_DEV_TO_MEM, -}; - -static inline unsigned ep93xx_ac97_read_reg(struct ep93xx_ac97_info *info, - unsigned reg) -{ - return __raw_readl(info->regs + reg); -} - -static inline void ep93xx_ac97_write_reg(struct ep93xx_ac97_info *info, - unsigned reg, unsigned val) -{ - __raw_writel(val, info->regs + reg); -} - -static unsigned short ep93xx_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - struct ep93xx_ac97_info *info = ep93xx_ac97_info; - unsigned short val; - - mutex_lock(&info->lock); - - ep93xx_ac97_write_reg(info, AC97S1DATA, reg); - ep93xx_ac97_write_reg(info, AC97IM, AC97_SLOT2RXVALID); - if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT)) { - dev_warn(info->dev, "timeout reading register %x\n", reg); - mutex_unlock(&info->lock); - return -ETIMEDOUT; - } - val = (unsigned short)ep93xx_ac97_read_reg(info, AC97S2DATA); - - mutex_unlock(&info->lock); - return val; -} - -static void ep93xx_ac97_write(struct snd_ac97 *ac97, - unsigned short reg, - unsigned short val) -{ - struct ep93xx_ac97_info *info = ep93xx_ac97_info; - - mutex_lock(&info->lock); - - /* - * Writes to the codec need to be done so that slot 2 is filled in - * before slot 1. - */ - ep93xx_ac97_write_reg(info, AC97S2DATA, val); - ep93xx_ac97_write_reg(info, AC97S1DATA, reg); - - ep93xx_ac97_write_reg(info, AC97IM, AC97_SLOT2TXCOMPLETE); - if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT)) - dev_warn(info->dev, "timeout writing register %x\n", reg); - - mutex_unlock(&info->lock); -} - -static void ep93xx_ac97_warm_reset(struct snd_ac97 *ac97) -{ - struct ep93xx_ac97_info *info = ep93xx_ac97_info; - - mutex_lock(&info->lock); - - /* - * We are assuming that before this functions gets called, the codec - * BIT_CLK is stopped by forcing the codec into powerdown mode. We can - * control the SYNC signal directly via AC97SYNC register. Using - * TIMEDSYNC the controller will keep the SYNC high > 1us. - */ - ep93xx_ac97_write_reg(info, AC97SYNC, AC97SYNC_TIMEDSYNC); - ep93xx_ac97_write_reg(info, AC97IM, AC97_CODECREADY); - if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT)) - dev_warn(info->dev, "codec warm reset timeout\n"); - - mutex_unlock(&info->lock); -} - -static void ep93xx_ac97_cold_reset(struct snd_ac97 *ac97) -{ - struct ep93xx_ac97_info *info = ep93xx_ac97_info; - - mutex_lock(&info->lock); - - /* - * For doing cold reset, we disable the AC97 controller interface, clear - * WINT and CODECREADY bits, and finally enable the interface again. - */ - ep93xx_ac97_write_reg(info, AC97GCR, 0); - ep93xx_ac97_write_reg(info, AC97EOI, AC97EOI_CODECREADY | AC97EOI_WINT); - ep93xx_ac97_write_reg(info, AC97GCR, AC97GCR_AC97IFE); - - /* - * Now, assert the reset and wait for the codec to become ready. - */ - ep93xx_ac97_write_reg(info, AC97RESET, AC97RESET_TIMEDRESET); - ep93xx_ac97_write_reg(info, AC97IM, AC97_CODECREADY); - if (!wait_for_completion_timeout(&info->done, AC97_TIMEOUT)) - dev_warn(info->dev, "codec cold reset timeout\n"); - - /* - * Give the codec some time to come fully out from the reset. This way - * we ensure that the subsequent reads/writes will work. - */ - usleep_range(15000, 20000); - - mutex_unlock(&info->lock); -} - -static irqreturn_t ep93xx_ac97_interrupt(int irq, void *dev_id) -{ - struct ep93xx_ac97_info *info = dev_id; - unsigned status, mask; - - /* - * Just mask out the interrupt and wake up the waiting thread. - * Interrupts are cleared via reading/writing to slot 1 & 2 registers by - * the waiting thread. - */ - status = ep93xx_ac97_read_reg(info, AC97GIS); - mask = ep93xx_ac97_read_reg(info, AC97IM); - mask &= ~status; - ep93xx_ac97_write_reg(info, AC97IM, mask); - - complete(&info->done); - return IRQ_HANDLED; -} - -static struct snd_ac97_bus_ops ep93xx_ac97_ops = { - .read = ep93xx_ac97_read, - .write = ep93xx_ac97_write, - .reset = ep93xx_ac97_cold_reset, - .warm_reset = ep93xx_ac97_warm_reset, -}; - -static int ep93xx_ac97_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); - unsigned v = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - /* - * Enable compact mode, TX slots 3 & 4, and the TX FIFO - * itself. - */ - v |= AC97TXCR_CM; - v |= AC97TXCR_TX3 | AC97TXCR_TX4; - v |= AC97TXCR_TEN; - ep93xx_ac97_write_reg(info, AC97TXCR(1), v); - } else { - /* - * Enable compact mode, RX slots 3 & 4, and the RX FIFO - * itself. - */ - v |= AC97RXCR_CM; - v |= AC97RXCR_RX3 | AC97RXCR_RX4; - v |= AC97RXCR_REN; - ep93xx_ac97_write_reg(info, AC97RXCR(1), v); - } - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - /* - * As per Cirrus EP93xx errata described below: - * - * https://www.cirrus.com/en/pubs/errata/ER667E2B.pdf - * - * we will wait for the TX FIFO to be empty before - * clearing the TEN bit. - */ - unsigned long timeout = jiffies + AC97_TIMEOUT; - - do { - v = ep93xx_ac97_read_reg(info, AC97SR(1)); - if (time_after(jiffies, timeout)) { - dev_warn(info->dev, "TX timeout\n"); - break; - } - } while (!(v & (AC97SR_TXFE | AC97SR_TXUE))); - - /* disable the TX FIFO */ - ep93xx_ac97_write_reg(info, AC97TXCR(1), 0); - } else { - /* disable the RX FIFO */ - ep93xx_ac97_write_reg(info, AC97RXCR(1), 0); - } - break; - - default: - dev_warn(info->dev, "unknown command %d\n", cmd); - return -EINVAL; - } - - return 0; -} - -static int ep93xx_ac97_dai_probe(struct snd_soc_dai *dai) -{ - struct ep93xx_ac97_info *info = snd_soc_dai_get_drvdata(dai); - - info->dma_params_tx.filter_data = &ep93xx_ac97_pcm_out; - info->dma_params_rx.filter_data = &ep93xx_ac97_pcm_in; - - dai->playback_dma_data = &info->dma_params_tx; - dai->capture_dma_data = &info->dma_params_rx; - - return 0; -} - -static const struct snd_soc_dai_ops ep93xx_ac97_dai_ops = { - .trigger = ep93xx_ac97_trigger, -}; - -static struct snd_soc_dai_driver ep93xx_ac97_dai = { - .name = "ep93xx-ac97", - .id = 0, - .probe = ep93xx_ac97_dai_probe, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &ep93xx_ac97_dai_ops, -}; - -static const struct snd_soc_component_driver ep93xx_ac97_component = { - .name = "ep93xx-ac97", - .legacy_dai_naming = 1, -}; - -static int ep93xx_ac97_probe(struct platform_device *pdev) -{ - struct ep93xx_ac97_info *info; - int irq; - int ret; - - info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(info->regs)) - return PTR_ERR(info->regs); - - irq = platform_get_irq(pdev, 0); - if (irq <= 0) - return irq < 0 ? irq : -ENODEV; - - ret = devm_request_irq(&pdev->dev, irq, ep93xx_ac97_interrupt, - IRQF_TRIGGER_HIGH, pdev->name, info); - if (ret) - goto fail; - - dev_set_drvdata(&pdev->dev, info); - - mutex_init(&info->lock); - init_completion(&info->done); - info->dev = &pdev->dev; - - ep93xx_ac97_info = info; - platform_set_drvdata(pdev, info); - - ret = snd_soc_set_ac97_ops(&ep93xx_ac97_ops); - if (ret) - goto fail; - - ret = snd_soc_register_component(&pdev->dev, &ep93xx_ac97_component, - &ep93xx_ac97_dai, 1); - if (ret) - goto fail; - - ret = devm_ep93xx_pcm_platform_register(&pdev->dev); - if (ret) - goto fail_unregister; - - return 0; - -fail_unregister: - snd_soc_unregister_component(&pdev->dev); -fail: - ep93xx_ac97_info = NULL; - snd_soc_set_ac97_ops(NULL); - return ret; -} - -static int ep93xx_ac97_remove(struct platform_device *pdev) -{ - struct ep93xx_ac97_info *info = platform_get_drvdata(pdev); - - snd_soc_unregister_component(&pdev->dev); - - /* disable the AC97 controller */ - ep93xx_ac97_write_reg(info, AC97GCR, 0); - - ep93xx_ac97_info = NULL; - - snd_soc_set_ac97_ops(NULL); - - return 0; -} - -static struct platform_driver ep93xx_ac97_driver = { - .probe = ep93xx_ac97_probe, - .remove = ep93xx_ac97_remove, - .driver = { - .name = "ep93xx-ac97", - }, -}; - -module_platform_driver(ep93xx_ac97_driver); - -MODULE_DESCRIPTION("EP93xx AC97 ASoC Driver"); -MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ep93xx-ac97"); diff --git a/sound/soc/cirrus/simone.c b/sound/soc/cirrus/simone.c deleted file mode 100644 index 801c90877d77..000000000000 --- a/sound/soc/cirrus/simone.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * simone.c -- ASoC audio for Simplemachines Sim.One board - * - * Copyright (c) 2010 Mika Westerberg - * - * Based on snappercl15 machine driver by Ryan Mallon. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/soc/cirrus/ep93xx.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> - -SND_SOC_DAILINK_DEFS(hifi, - DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-ac97"))); - -static struct snd_soc_dai_link simone_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(hifi), -}; - -static struct snd_soc_card snd_soc_simone = { - .name = "Sim.One", - .owner = THIS_MODULE, - .dai_link = &simone_dai, - .num_links = 1, -}; - -static struct platform_device *simone_snd_ac97_device; - -static int simone_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &snd_soc_simone; - int ret; - - simone_snd_ac97_device = platform_device_register_simple("ac97-codec", - -1, NULL, 0); - if (IS_ERR(simone_snd_ac97_device)) - return PTR_ERR(simone_snd_ac97_device); - - card->dev = &pdev->dev; - - ret = snd_soc_register_card(card); - if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - platform_device_unregister(simone_snd_ac97_device); - } - - return ret; -} - -static int simone_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - - snd_soc_unregister_card(card); - platform_device_unregister(simone_snd_ac97_device); - - return 0; -} - -static struct platform_driver simone_driver = { - .driver = { - .name = "simone-audio", - }, - .probe = simone_probe, - .remove = simone_remove, -}; - -module_platform_driver(simone_driver); - -MODULE_DESCRIPTION("ALSA SoC Simplemachines Sim.One"); -MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:simone-audio"); diff --git a/sound/soc/cirrus/snappercl15.c b/sound/soc/cirrus/snappercl15.c deleted file mode 100644 index a286f5beeaeb..000000000000 --- a/sound/soc/cirrus/snappercl15.c +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * snappercl15.c -- SoC audio for Bluewater Systems Snapper CL15 module - * - * Copyright (C) 2008 Bluewater Systems Ltd - * Author: Ryan Mallon - */ - -#include <linux/platform_device.h> -#include <linux/module.h> -#include <linux/soc/cirrus/ep93xx.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> - -#include "../codecs/tlv320aic23.h" - -#define CODEC_CLOCK 5644800 - -static int snappercl15_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int err; - - err = snd_soc_dai_set_sysclk(codec_dai, 0, CODEC_CLOCK, - SND_SOC_CLOCK_IN); - if (err) - return err; - - err = snd_soc_dai_set_sysclk(cpu_dai, 0, CODEC_CLOCK, - SND_SOC_CLOCK_OUT); - if (err) - return err; - - return 0; -} - -static const struct snd_soc_ops snappercl15_ops = { - .hw_params = snappercl15_hw_params, -}; - -static const struct snd_soc_dapm_widget tlv320aic23_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Jack", NULL, "LHPOUT"}, - {"Headphone Jack", NULL, "RHPOUT"}, - - {"LLINEIN", NULL, "Line In"}, - {"RLINEIN", NULL, "Line In"}, - - {"MICIN", NULL, "Mic Jack"}, -}; - -SND_SOC_DAILINK_DEFS(aic23, - DAILINK_COMP_ARRAY(COMP_CPU("ep93xx-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic23-codec.0-001a", - "tlv320aic23-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("ep93xx-i2s"))); - -static struct snd_soc_dai_link snappercl15_dai = { - .name = "tlv320aic23", - .stream_name = "AIC23", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBC_CFC, - .ops = &snappercl15_ops, - SND_SOC_DAILINK_REG(aic23), -}; - -static struct snd_soc_card snd_soc_snappercl15 = { - .name = "Snapper CL15", - .owner = THIS_MODULE, - .dai_link = &snappercl15_dai, - .num_links = 1, - - .dapm_widgets = tlv320aic23_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static int snappercl15_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &snd_soc_snappercl15; - int ret; - - ret = ep93xx_i2s_acquire(); - if (ret) - return ret; - - card->dev = &pdev->dev; - - ret = snd_soc_register_card(card); - if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - ep93xx_i2s_release(); - } - - return ret; -} - -static int snappercl15_remove(struct platform_device *pdev) -{ - struct snd_soc_card *card = platform_get_drvdata(pdev); - - snd_soc_unregister_card(card); - ep93xx_i2s_release(); - - return 0; -} - -static struct platform_driver snappercl15_driver = { - .driver = { - .name = "snappercl15-audio", - }, - .probe = snappercl15_probe, - .remove = snappercl15_remove, -}; - -module_platform_driver(snappercl15_driver); - -MODULE_AUTHOR("Ryan Mallon"); -MODULE_DESCRIPTION("ALSA SoC Snapper CL15"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:snappercl15-audio"); diff --git a/sound/soc/codecs/cs42l56.c b/sound/soc/codecs/cs42l56.c index 26066682c983..3b0e715549c9 100644 --- a/sound/soc/codecs/cs42l56.c +++ b/sound/soc/codecs/cs42l56.c @@ -1191,18 +1191,12 @@ static int cs42l56_i2c_probe(struct i2c_client *i2c_client) if (pdata) { cs42l56->pdata = *pdata; } else { - pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata), - GFP_KERNEL); - if (!pdata) - return -ENOMEM; - if (i2c_client->dev.of_node) { ret = cs42l56_handle_of_data(i2c_client, &cs42l56->pdata); if (ret != 0) return ret; } - cs42l56->pdata = *pdata; } if (cs42l56->pdata.gpio_nreset) { diff --git a/sound/soc/codecs/es8326.c b/sound/soc/codecs/es8326.c index 9ddf6a35e91c..28a0565c2a95 100755..100644 --- a/sound/soc/codecs/es8326.c +++ b/sound/soc/codecs/es8326.c @@ -729,14 +729,16 @@ static int es8326_probe(struct snd_soc_component *component) } dev_dbg(component->dev, "jack-pol %x", es8326->jack_pol); - ret = device_property_read_u8(component->dev, "everest,interrupt-src", &es8326->jack_pol); + ret = device_property_read_u8(component->dev, "everest,interrupt-src", + &es8326->interrupt_src); if (ret != 0) { dev_dbg(component->dev, "interrupt-src return %d", ret); es8326->interrupt_src = ES8326_HP_DET_SRC_PIN9; } dev_dbg(component->dev, "interrupt-src %x", es8326->interrupt_src); - ret = device_property_read_u8(component->dev, "everest,interrupt-clk", &es8326->jack_pol); + ret = device_property_read_u8(component->dev, "everest,interrupt-clk", + &es8326->interrupt_clk); if (ret != 0) { dev_dbg(component->dev, "interrupt-clk return %d", ret); es8326->interrupt_clk = 0x45; diff --git a/sound/soc/codecs/es8326.h b/sound/soc/codecs/es8326.h index 8e5ffe5ee10d..8e5ffe5ee10d 100755..100644 --- a/sound/soc/codecs/es8326.h +++ b/sound/soc/codecs/es8326.h diff --git a/sound/soc/codecs/rt715-sdca-sdw.c b/sound/soc/codecs/rt715-sdca-sdw.c index 3f981a9e7fb6..c54ecf3e6987 100644 --- a/sound/soc/codecs/rt715-sdca-sdw.c +++ b/sound/soc/codecs/rt715-sdca-sdw.c @@ -167,7 +167,7 @@ static int rt715_sdca_read_prop(struct sdw_slave *slave) } /* set the timeout values */ - prop->clk_stop_timeout = 20; + prop->clk_stop_timeout = 200; return 0; } diff --git a/sound/soc/codecs/rt9120.c b/sound/soc/codecs/rt9120.c index 644300e88b4c..fcf4fbaed3c7 100644 --- a/sound/soc/codecs/rt9120.c +++ b/sound/soc/codecs/rt9120.c @@ -177,8 +177,20 @@ static int rt9120_codec_probe(struct snd_soc_component *comp) return 0; } +static int rt9120_codec_suspend(struct snd_soc_component *comp) +{ + return pm_runtime_force_suspend(comp->dev); +} + +static int rt9120_codec_resume(struct snd_soc_component *comp) +{ + return pm_runtime_force_resume(comp->dev); +} + static const struct snd_soc_component_driver rt9120_component_driver = { .probe = rt9120_codec_probe, + .suspend = rt9120_codec_suspend, + .resume = rt9120_codec_resume, .controls = rt9120_snd_controls, .num_controls = ARRAY_SIZE(rt9120_snd_controls), .dapm_widgets = rt9120_dapm_widgets, diff --git a/sound/soc/codecs/tas5805m.c b/sound/soc/codecs/tas5805m.c index beb4ec629a03..4e38eb7acea1 100644 --- a/sound/soc/codecs/tas5805m.c +++ b/sound/soc/codecs/tas5805m.c @@ -154,6 +154,7 @@ static const uint32_t tas5805m_volume[] = { #define TAS5805M_VOLUME_MIN 0 struct tas5805m_priv { + struct i2c_client *i2c; struct regulator *pvdd; struct gpio_desc *gpio_pdn_n; @@ -165,6 +166,9 @@ struct tas5805m_priv { int vol[2]; bool is_powered; bool is_muted; + + struct work_struct work; + struct mutex lock; }; static void set_dsp_scale(struct regmap *rm, int offset, int vol) @@ -181,13 +185,11 @@ static void set_dsp_scale(struct regmap *rm, int offset, int vol) regmap_bulk_write(rm, offset, v, ARRAY_SIZE(v)); } -static void tas5805m_refresh(struct snd_soc_component *component) +static void tas5805m_refresh(struct tas5805m_priv *tas5805m) { - struct tas5805m_priv *tas5805m = - snd_soc_component_get_drvdata(component); struct regmap *rm = tas5805m->regmap; - dev_dbg(component->dev, "refresh: is_muted=%d, vol=%d/%d\n", + dev_dbg(&tas5805m->i2c->dev, "refresh: is_muted=%d, vol=%d/%d\n", tas5805m->is_muted, tas5805m->vol[0], tas5805m->vol[1]); regmap_write(rm, REG_PAGE, 0x00); @@ -201,6 +203,9 @@ static void tas5805m_refresh(struct snd_soc_component *component) set_dsp_scale(rm, 0x24, tas5805m->vol[0]); set_dsp_scale(rm, 0x28, tas5805m->vol[1]); + regmap_write(rm, REG_PAGE, 0x00); + regmap_write(rm, REG_BOOK, 0x00); + /* Set/clear digital soft-mute */ regmap_write(rm, REG_DEVICE_CTRL_2, (tas5805m->is_muted ? DCTRL2_MUTE : 0) | @@ -226,8 +231,11 @@ static int tas5805m_vol_get(struct snd_kcontrol *kcontrol, struct tas5805m_priv *tas5805m = snd_soc_component_get_drvdata(component); + mutex_lock(&tas5805m->lock); ucontrol->value.integer.value[0] = tas5805m->vol[0]; ucontrol->value.integer.value[1] = tas5805m->vol[1]; + mutex_unlock(&tas5805m->lock); + return 0; } @@ -243,11 +251,13 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol, snd_soc_kcontrol_component(kcontrol); struct tas5805m_priv *tas5805m = snd_soc_component_get_drvdata(component); + int ret = 0; if (!(volume_is_valid(ucontrol->value.integer.value[0]) && volume_is_valid(ucontrol->value.integer.value[1]))) return -EINVAL; + mutex_lock(&tas5805m->lock); if (tas5805m->vol[0] != ucontrol->value.integer.value[0] || tas5805m->vol[1] != ucontrol->value.integer.value[1]) { tas5805m->vol[0] = ucontrol->value.integer.value[0]; @@ -256,11 +266,12 @@ static int tas5805m_vol_put(struct snd_kcontrol *kcontrol, tas5805m->vol[0], tas5805m->vol[1], tas5805m->is_powered); if (tas5805m->is_powered) - tas5805m_refresh(component); - return 1; + tas5805m_refresh(tas5805m); + ret = 1; } + mutex_unlock(&tas5805m->lock); - return 0; + return ret; } static const struct snd_kcontrol_new tas5805m_snd_controls[] = { @@ -294,54 +305,83 @@ static int tas5805m_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_component *component = dai->component; struct tas5805m_priv *tas5805m = snd_soc_component_get_drvdata(component); - struct regmap *rm = tas5805m->regmap; - unsigned int chan, global1, global2; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - dev_dbg(component->dev, "DSP startup\n"); - - /* We mustn't issue any I2C transactions until the I2S - * clock is stable. Furthermore, we must allow a 5ms - * delay after the first set of register writes to - * allow the DSP to boot before configuring it. - */ - usleep_range(5000, 10000); - send_cfg(rm, dsp_cfg_preboot, - ARRAY_SIZE(dsp_cfg_preboot)); - usleep_range(5000, 15000); - send_cfg(rm, tas5805m->dsp_cfg_data, - tas5805m->dsp_cfg_len); - - tas5805m->is_powered = true; - tas5805m_refresh(component); + dev_dbg(component->dev, "clock start\n"); + schedule_work(&tas5805m->work); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - dev_dbg(component->dev, "DSP shutdown\n"); + break; - tas5805m->is_powered = false; + default: + return -EINVAL; + } - regmap_write(rm, REG_PAGE, 0x00); - regmap_write(rm, REG_BOOK, 0x00); + return 0; +} - regmap_read(rm, REG_CHAN_FAULT, &chan); - regmap_read(rm, REG_GLOBAL_FAULT1, &global1); - regmap_read(rm, REG_GLOBAL_FAULT2, &global2); +static void do_work(struct work_struct *work) +{ + struct tas5805m_priv *tas5805m = + container_of(work, struct tas5805m_priv, work); + struct regmap *rm = tas5805m->regmap; - dev_dbg(component->dev, - "fault regs: CHAN=%02x, GLOBAL1=%02x, GLOBAL2=%02x\n", - chan, global1, global2); + dev_dbg(&tas5805m->i2c->dev, "DSP startup\n"); - regmap_write(rm, REG_DEVICE_CTRL_2, DCTRL2_MODE_HIZ); - break; + mutex_lock(&tas5805m->lock); + /* We mustn't issue any I2C transactions until the I2S + * clock is stable. Furthermore, we must allow a 5ms + * delay after the first set of register writes to + * allow the DSP to boot before configuring it. + */ + usleep_range(5000, 10000); + send_cfg(rm, dsp_cfg_preboot, ARRAY_SIZE(dsp_cfg_preboot)); + usleep_range(5000, 15000); + send_cfg(rm, tas5805m->dsp_cfg_data, tas5805m->dsp_cfg_len); + + tas5805m->is_powered = true; + tas5805m_refresh(tas5805m); + mutex_unlock(&tas5805m->lock); +} - default: - return -EINVAL; +static int tas5805m_dac_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm); + struct tas5805m_priv *tas5805m = + snd_soc_component_get_drvdata(component); + struct regmap *rm = tas5805m->regmap; + + if (event & SND_SOC_DAPM_PRE_PMD) { + unsigned int chan, global1, global2; + + dev_dbg(component->dev, "DSP shutdown\n"); + cancel_work_sync(&tas5805m->work); + + mutex_lock(&tas5805m->lock); + if (tas5805m->is_powered) { + tas5805m->is_powered = false; + + regmap_write(rm, REG_PAGE, 0x00); + regmap_write(rm, REG_BOOK, 0x00); + + regmap_read(rm, REG_CHAN_FAULT, &chan); + regmap_read(rm, REG_GLOBAL_FAULT1, &global1); + regmap_read(rm, REG_GLOBAL_FAULT2, &global2); + + dev_dbg(component->dev, "fault regs: CHAN=%02x, " + "GLOBAL1=%02x, GLOBAL2=%02x\n", + chan, global1, global2); + + regmap_write(rm, REG_DEVICE_CTRL_2, DCTRL2_MODE_HIZ); + } + mutex_unlock(&tas5805m->lock); } return 0; @@ -354,7 +394,8 @@ static const struct snd_soc_dapm_route tas5805m_audio_map[] = { static const struct snd_soc_dapm_widget tas5805m_dapm_widgets[] = { SND_SOC_DAPM_AIF_IN("DAC IN", "Playback", 0, SND_SOC_NOPM, 0, 0), - SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, + tas5805m_dac_event, SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_OUTPUT("OUT") }; @@ -375,11 +416,14 @@ static int tas5805m_mute(struct snd_soc_dai *dai, int mute, int direction) struct tas5805m_priv *tas5805m = snd_soc_component_get_drvdata(component); + mutex_lock(&tas5805m->lock); dev_dbg(component->dev, "set mute=%d (is_powered=%d)\n", mute, tas5805m->is_powered); + tas5805m->is_muted = mute; if (tas5805m->is_powered) - tas5805m_refresh(component); + tas5805m_refresh(tas5805m); + mutex_unlock(&tas5805m->lock); return 0; } @@ -434,6 +478,7 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c) if (!tas5805m) return -ENOMEM; + tas5805m->i2c = i2c; tas5805m->pvdd = devm_regulator_get(dev, "pvdd"); if (IS_ERR(tas5805m->pvdd)) { dev_err(dev, "failed to get pvdd supply: %ld\n", @@ -507,6 +552,9 @@ static int tas5805m_i2c_probe(struct i2c_client *i2c) gpiod_set_value(tas5805m->gpio_pdn_n, 1); usleep_range(10000, 15000); + INIT_WORK(&tas5805m->work, do_work); + mutex_init(&tas5805m->lock); + /* Don't register through devm. We need to be able to unregister * the component prior to deasserting PDN# */ @@ -527,6 +575,7 @@ static void tas5805m_i2c_remove(struct i2c_client *i2c) struct device *dev = &i2c->dev; struct tas5805m_priv *tas5805m = dev_get_drvdata(dev); + cancel_work_sync(&tas5805m->work); snd_soc_unregister_component(dev); gpiod_set_value(tas5805m->gpio_pdn_n, 0); usleep_range(10000, 15000); diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index ca6a01a230af..791d8738d1c0 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -697,6 +697,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, int dcs_mask; int dcs_l, dcs_r; int dcs_l_reg, dcs_r_reg; + int an_out_reg; int timeout; int pwr_reg; @@ -712,6 +713,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, dcs_mask = WM8904_DCS_ENA_CHAN_0 | WM8904_DCS_ENA_CHAN_1; dcs_r_reg = WM8904_DC_SERVO_8; dcs_l_reg = WM8904_DC_SERVO_9; + an_out_reg = WM8904_ANALOGUE_OUT1_LEFT; dcs_l = 0; dcs_r = 1; break; @@ -720,6 +722,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, dcs_mask = WM8904_DCS_ENA_CHAN_2 | WM8904_DCS_ENA_CHAN_3; dcs_r_reg = WM8904_DC_SERVO_6; dcs_l_reg = WM8904_DC_SERVO_7; + an_out_reg = WM8904_ANALOGUE_OUT2_LEFT; dcs_l = 2; dcs_r = 3; break; @@ -792,6 +795,10 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, snd_soc_component_update_bits(component, reg, WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP, WM8904_HPL_ENA_OUTP | WM8904_HPR_ENA_OUTP); + + /* Update volume, requires PGA to be powered */ + val = snd_soc_component_read(component, an_out_reg); + snd_soc_component_write(component, an_out_reg, val); break; case SND_SOC_DAPM_POST_PMU: diff --git a/sound/soc/codecs/wsa883x.c b/sound/soc/codecs/wsa883x.c index 966ba4909204..58fdb4e9fd97 100644 --- a/sound/soc/codecs/wsa883x.c +++ b/sound/soc/codecs/wsa883x.c @@ -1359,8 +1359,8 @@ static struct snd_soc_dai_driver wsa883x_dais[] = { .stream_name = "SPKR Playback", .rates = WSA883X_RATES | WSA883X_FRAC_RATES, .formats = WSA883X_FORMATS, - .rate_max = 8000, - .rate_min = 352800, + .rate_min = 8000, + .rate_max = 352800, .channels_min = 1, .channels_max = 1, }, diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c index c836848ef0a6..8d14b5593658 100644 --- a/sound/soc/fsl/fsl-asoc-card.c +++ b/sound/soc/fsl/fsl-asoc-card.c @@ -121,11 +121,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static const struct snd_soc_dapm_route audio_map_ac97[] = { /* 1st half -- Normal DAPM routes */ - {"Playback", NULL, "AC97 Playback"}, - {"AC97 Capture", NULL, "Capture"}, + {"AC97 Playback", NULL, "CPU AC97 Playback"}, + {"CPU AC97 Capture", NULL, "AC97 Capture"}, /* 2nd half -- ASRC DAPM routes */ - {"AC97 Playback", NULL, "ASRC-Playback"}, - {"ASRC-Capture", NULL, "AC97 Capture"}, + {"CPU AC97 Playback", NULL, "ASRC-Playback"}, + {"ASRC-Capture", NULL, "CPU AC97 Capture"}, }; static const struct snd_soc_dapm_route audio_map_tx[] = { diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c index 7b17f152bbf3..94341e4352b3 100644 --- a/sound/soc/fsl/fsl_micfil.c +++ b/sound/soc/fsl/fsl_micfil.c @@ -315,21 +315,21 @@ static int hwvad_detected(struct snd_kcontrol *kcontrol, static const struct snd_kcontrol_new fsl_micfil_snd_controls[] = { SOC_SINGLE_SX_TLV("CH0 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(0), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(0), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH1 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(1), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(1), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH2 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(2), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(2), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH3 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(3), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(3), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH4 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(4), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(4), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH5 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(5), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(5), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH6 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(6), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(6), 0x8, 0xF, gain_tlv), SOC_SINGLE_SX_TLV("CH7 Volume", REG_MICFIL_OUT_CTRL, - MICFIL_OUTGAIN_CHX_SHIFT(7), 0xF, 0x7, gain_tlv), + MICFIL_OUTGAIN_CHX_SHIFT(7), 0x8, 0xF, gain_tlv), SOC_ENUM_EXT("MICFIL Quality Select", fsl_micfil_quality_enum, micfil_quality_get, micfil_quality_set), diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 1c9be8a5dcb1..35a52c3a020d 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -1141,6 +1141,7 @@ static int fsl_sai_check_version(struct device *dev) sai->verid.version = val & (FSL_SAI_VERID_MAJOR_MASK | FSL_SAI_VERID_MINOR_MASK); + sai->verid.version >>= FSL_SAI_VERID_MINOR_SHIFT; sai->verid.feature = val & FSL_SAI_VERID_FEATURE_MASK; ret = regmap_read(sai->regmap, FSL_SAI_PARAM, &val); diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index c9e0e31d5b34..46a53551b955 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c @@ -1189,14 +1189,14 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { .symmetric_channels = 1, .probe = fsl_ssi_dai_probe, .playback = { - .stream_name = "AC97 Playback", + .stream_name = "CPU AC97 Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_48000, .formats = SNDRV_PCM_FMTBIT_S16 | SNDRV_PCM_FMTBIT_S20, }, .capture = { - .stream_name = "AC97 Capture", + .stream_name = "CPU AC97 Capture", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_48000, diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c index 2ca24273c491..637501850728 100644 --- a/sound/soc/intel/avs/core.c +++ b/sound/soc/intel/avs/core.c @@ -481,6 +481,29 @@ err_remap_bar0: return ret; } +static void avs_pci_shutdown(struct pci_dev *pci) +{ + struct hdac_bus *bus = pci_get_drvdata(pci); + struct avs_dev *adev = hdac_to_avs(bus); + + cancel_work_sync(&adev->probe_work); + avs_ipc_block(adev->ipc); + + snd_hdac_stop_streams(bus); + avs_dsp_op(adev, int_control, false); + snd_hdac_ext_bus_ppcap_int_enable(bus, false); + snd_hdac_ext_bus_link_power_down_all(bus); + + snd_hdac_bus_stop_chip(bus); + snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false); + + if (avs_platattr_test(adev, CLDMA)) + pci_free_irq(pci, 0, &code_loader); + pci_free_irq(pci, 0, adev); + pci_free_irq(pci, 0, bus); + pci_free_irq_vectors(pci); +} + static void avs_pci_remove(struct pci_dev *pci) { struct hdac_device *hdev, *save; @@ -739,6 +762,7 @@ static struct pci_driver avs_pci_driver = { .id_table = avs_ids, .probe = avs_pci_probe, .remove = avs_pci_remove, + .shutdown = avs_pci_shutdown, .driver = { .pm = &avs_dev_pm, }, diff --git a/sound/soc/intel/boards/Kconfig b/sound/soc/intel/boards/Kconfig index a472de1909f4..99308ed85277 100644 --- a/sound/soc/intel/boards/Kconfig +++ b/sound/soc/intel/boards/Kconfig @@ -554,10 +554,12 @@ config SND_SOC_INTEL_SOF_NAU8825_MACH select SND_SOC_RT1015P select SND_SOC_MAX98373_I2C select SND_SOC_MAX98357A + select SND_SOC_NAU8315 select SND_SOC_DMIC select SND_SOC_HDAC_HDMI select SND_SOC_INTEL_HDA_DSP_COMMON select SND_SOC_INTEL_SOF_MAXIM_COMMON + select SND_SOC_INTEL_SOF_REALTEK_COMMON help This adds support for ASoC machine driver for SOF platforms with nau8825 codec. diff --git a/sound/soc/intel/boards/bytcht_es8316.c b/sound/soc/intel/boards/bytcht_es8316.c index 09d1f0f6d686..df157b01df8b 100644 --- a/sound/soc/intel/boards/bytcht_es8316.c +++ b/sound/soc/intel/boards/bytcht_es8316.c @@ -497,21 +497,28 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) if (adev) { snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_cht_es8316_dais[dai_index].codecs->name = codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); return -ENXIO; } + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + priv->codec_dev = get_device(codec_dev); + /* override platform name, if required */ byt_cht_es8316_card.dev = dev; platform_name = mach->mach_params.platform; ret = snd_soc_fixup_dai_links_platform_name(&byt_cht_es8316_card, platform_name); - if (ret) + if (ret) { + put_device(codec_dev); return ret; + } /* Check for BYTCR or other platform and setup quirks */ dmi_id = dmi_first_match(byt_cht_es8316_quirk_table); @@ -539,13 +546,10 @@ static int snd_byt_cht_es8316_mc_probe(struct platform_device *pdev) /* get the clock */ priv->mclk = devm_clk_get(dev, "pmc_plt_clk_3"); - if (IS_ERR(priv->mclk)) + if (IS_ERR(priv->mclk)) { + put_device(codec_dev); return dev_err_probe(dev, PTR_ERR(priv->mclk), "clk_get pmc_plt_clk_3 failed\n"); - - codec_dev = acpi_get_first_physical_node(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); + } if (quirk & BYT_CHT_ES8316_JD_INVERTED) props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); diff --git a/sound/soc/intel/boards/bytcr_rt5640.c b/sound/soc/intel/boards/bytcr_rt5640.c index 4699ca79f3ea..79e0039c79a3 100644 --- a/sound/soc/intel/boards/bytcr_rt5640.c +++ b/sound/soc/intel/boards/bytcr_rt5640.c @@ -1636,13 +1636,18 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) if (adev) { snprintf(byt_rt5640_codec_name, sizeof(byt_rt5640_codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_rt5640_dais[dai_index].codecs->name = byt_rt5640_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); return -ENXIO; } + codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); + if (!codec_dev) + return -EPROBE_DEFER; + priv->codec_dev = get_device(codec_dev); + /* * swap SSP0 if bytcr is detected * (will be overridden if DMI quirk is detected) @@ -1717,11 +1722,6 @@ static int snd_byt_rt5640_mc_probe(struct platform_device *pdev) byt_rt5640_quirk = quirk_override; } - codec_dev = acpi_get_first_physical_node(adev); - if (!codec_dev) - return -EPROBE_DEFER; - priv->codec_dev = get_device(codec_dev); - if (byt_rt5640_quirk & BYT_RT5640_JD_HP_ELITEP_1000G2) { acpi_dev_add_driver_gpios(ACPI_COMPANION(priv->codec_dev), byt_rt5640_hp_elitepad_1000g2_gpios); diff --git a/sound/soc/intel/boards/bytcr_rt5651.c b/sound/soc/intel/boards/bytcr_rt5651.c index 81ac6eeda2e6..8fca9b82d4d0 100644 --- a/sound/soc/intel/boards/bytcr_rt5651.c +++ b/sound/soc/intel/boards/bytcr_rt5651.c @@ -922,7 +922,6 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) if (adev) { snprintf(byt_rt5651_codec_name, sizeof(byt_rt5651_codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); byt_rt5651_dais[dai_index].codecs->name = byt_rt5651_codec_name; } else { dev_err(dev, "Error cannot find '%s' dev\n", mach->id); @@ -930,6 +929,7 @@ static int snd_byt_rt5651_mc_probe(struct platform_device *pdev) } codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; priv->codec_dev = get_device(codec_dev); diff --git a/sound/soc/intel/boards/bytcr_wm5102.c b/sound/soc/intel/boards/bytcr_wm5102.c index 1669eb3bd80f..c0706537f673 100644 --- a/sound/soc/intel/boards/bytcr_wm5102.c +++ b/sound/soc/intel/boards/bytcr_wm5102.c @@ -411,9 +411,9 @@ static int snd_byt_wm5102_mc_probe(struct platform_device *pdev) return -ENOENT; } snprintf(codec_name, sizeof(codec_name), "spi-%s", acpi_dev_name(adev)); - put_device(&adev->dev); codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, codec_name); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; diff --git a/sound/soc/intel/boards/sof_cs42l42.c b/sound/soc/intel/boards/sof_cs42l42.c index e38bd2831e6a..e9d190cb13b0 100644 --- a/sound/soc/intel/boards/sof_cs42l42.c +++ b/sound/soc/intel/boards/sof_cs42l42.c @@ -336,6 +336,9 @@ static int create_spk_amp_dai_links(struct device *dev, links[*id].platforms = platform_component; links[*id].num_platforms = ARRAY_SIZE(platform_component); links[*id].dpcm_playback = 1; + /* firmware-generated echo reference */ + links[*id].dpcm_capture = 1; + links[*id].no_pcm = 1; links[*id].cpus = &cpus[*id]; links[*id].num_cpus = 1; diff --git a/sound/soc/intel/boards/sof_es8336.c b/sound/soc/intel/boards/sof_es8336.c index 773e5d1d87d4..894b6610b9e2 100644 --- a/sound/soc/intel/boards/sof_es8336.c +++ b/sound/soc/intel/boards/sof_es8336.c @@ -681,7 +681,6 @@ static int sof_es8336_probe(struct platform_device *pdev) if (adev) { snprintf(codec_name, sizeof(codec_name), "i2c-%s", acpi_dev_name(adev)); - put_device(&adev->dev); dai_links[0].codecs->name = codec_name; /* also fixup codec dai name if relevant */ @@ -692,16 +691,19 @@ static int sof_es8336_probe(struct platform_device *pdev) return -ENXIO; } - ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card, - mach->mach_params.platform); - if (ret) - return ret; - codec_dev = acpi_get_first_physical_node(adev); + acpi_dev_put(adev); if (!codec_dev) return -EPROBE_DEFER; priv->codec_dev = get_device(codec_dev); + ret = snd_soc_fixup_dai_links_platform_name(&sof_es8336_card, + mach->mach_params.platform); + if (ret) { + put_device(codec_dev); + return ret; + } + if (quirk & SOF_ES8336_JD_INVERTED) props[cnt++] = PROPERTY_ENTRY_BOOL("everest,jack-detect-inverted"); diff --git a/sound/soc/intel/boards/sof_nau8825.c b/sound/soc/intel/boards/sof_nau8825.c index 27880224359d..6794a0249a9a 100644 --- a/sound/soc/intel/boards/sof_nau8825.c +++ b/sound/soc/intel/boards/sof_nau8825.c @@ -48,6 +48,7 @@ #define SOF_MAX98373_SPEAKER_AMP_PRESENT BIT(15) #define SOF_MAX98360A_SPEAKER_AMP_PRESENT BIT(16) #define SOF_RT1015P_SPEAKER_AMP_PRESENT BIT(17) +#define SOF_NAU8318_SPEAKER_AMP_PRESENT BIT(18) static unsigned long sof_nau8825_quirk = SOF_NAU8825_SSP_CODEC(0); @@ -338,6 +339,13 @@ static struct snd_soc_dai_link_component rt1019p_component[] = { } }; +static struct snd_soc_dai_link_component nau8318_components[] = { + { + .name = "NVTN2012:00", + .dai_name = "nau8315-hifi", + } +}; + static struct snd_soc_dai_link_component dummy_component[] = { { .name = "snd-soc-dummy", @@ -479,13 +487,16 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].init = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - /* feedback stream */ - links[id].dpcm_capture = 1; } else if (sof_nau8825_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { max_98360a_dai_link(&links[id]); } else if (sof_nau8825_quirk & SOF_RT1015P_SPEAKER_AMP_PRESENT) { sof_rt1015p_dai_link(&links[id]); + } else if (sof_nau8825_quirk & + SOF_NAU8318_SPEAKER_AMP_PRESENT) { + links[id].codecs = nau8318_components; + links[id].num_codecs = ARRAY_SIZE(nau8318_components); + links[id].init = speaker_codec_init; } else { goto devm_err; } @@ -493,6 +504,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; + /* feedback stream or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; @@ -618,7 +632,7 @@ static const struct platform_device_id board_ids[] = { }, { - .name = "adl_rt1019p_nau8825", + .name = "adl_rt1019p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_RT1019P_SPEAKER_AMP_PRESENT | @@ -626,7 +640,7 @@ static const struct platform_device_id board_ids[] = { SOF_NAU8825_NUM_HDMIDEV(4)), }, { - .name = "adl_max98373_nau8825", + .name = "adl_max98373_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_MAX98373_SPEAKER_AMP_PRESENT | @@ -637,7 +651,7 @@ static const struct platform_device_id board_ids[] = { }, { /* The limitation of length of char array, shorten the name */ - .name = "adl_mx98360a_nau8825", + .name = "adl_mx98360a_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_MAX98360A_SPEAKER_AMP_PRESENT | @@ -648,7 +662,7 @@ static const struct platform_device_id board_ids[] = { }, { - .name = "adl_rt1015p_nau8825", + .name = "adl_rt1015p_8825", .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | SOF_SPEAKER_AMP_PRESENT | SOF_RT1015P_SPEAKER_AMP_PRESENT | @@ -657,6 +671,16 @@ static const struct platform_device_id board_ids[] = { SOF_BT_OFFLOAD_SSP(2) | SOF_SSP_BT_OFFLOAD_PRESENT), }, + { + .name = "adl_nau8318_8825", + .driver_data = (kernel_ulong_t)(SOF_NAU8825_SSP_CODEC(0) | + SOF_SPEAKER_AMP_PRESENT | + SOF_NAU8318_SPEAKER_AMP_PRESENT | + SOF_NAU8825_SSP_AMP(1) | + SOF_NAU8825_NUM_HDMIDEV(4) | + SOF_BT_OFFLOAD_SSP(2) | + SOF_SSP_BT_OFFLOAD_PRESENT), + }, { } }; MODULE_DEVICE_TABLE(platform, board_ids); diff --git a/sound/soc/intel/boards/sof_rt5682.c b/sound/soc/intel/boards/sof_rt5682.c index 2eabc4b0fafa..71a11d747622 100644 --- a/sound/soc/intel/boards/sof_rt5682.c +++ b/sound/soc/intel/boards/sof_rt5682.c @@ -761,8 +761,6 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].num_codecs = ARRAY_SIZE(max_98373_components); links[id].init = max_98373_spk_codec_init; links[id].ops = &max_98373_ops; - /* feedback stream */ - links[id].dpcm_capture = 1; } else if (sof_rt5682_quirk & SOF_MAX98360A_SPEAKER_AMP_PRESENT) { max_98360a_dai_link(&links[id]); @@ -789,6 +787,9 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; + /* feedback stream or firmware-generated echo reference */ + links[id].dpcm_capture = 1; + links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; diff --git a/sound/soc/intel/boards/sof_ssp_amp.c b/sound/soc/intel/boards/sof_ssp_amp.c index 94d25aeb6e7c..7b74f122e340 100644 --- a/sound/soc/intel/boards/sof_ssp_amp.c +++ b/sound/soc/intel/boards/sof_ssp_amp.c @@ -258,13 +258,12 @@ static struct snd_soc_dai_link *sof_card_dai_links_create(struct device *dev, sof_rt1308_dai_link(&links[id]); } else if (sof_ssp_amp_quirk & SOF_CS35L41_SPEAKER_AMP_PRESENT) { cs35l41_set_dai_link(&links[id]); - - /* feedback from amplifier */ - links[id].dpcm_capture = 1; } links[id].platforms = platform_component; links[id].num_platforms = ARRAY_SIZE(platform_component); links[id].dpcm_playback = 1; + /* feedback from amplifier or firmware-generated echo reference */ + links[id].dpcm_capture = 1; links[id].no_pcm = 1; links[id].cpus = &cpus[id]; links[id].num_cpus = 1; diff --git a/sound/soc/intel/common/soc-acpi-intel-adl-match.c b/sound/soc/intel/common/soc-acpi-intel-adl-match.c index 60aee56f94bd..56ee5fef66a8 100644 --- a/sound/soc/intel/common/soc-acpi-intel-adl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-adl-match.c @@ -450,6 +450,11 @@ static const struct snd_soc_acpi_codecs adl_lt6911_hdmi = { .codecs = {"INTC10B0"} }; +static const struct snd_soc_acpi_codecs adl_nau8318_amp = { + .num_codecs = 1, + .codecs = {"NVTN2012"} +}; + struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { { .comp_ids = &adl_rt5682_rt5682s_hp, @@ -474,21 +479,21 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { }, { .id = "10508825", - .drv_name = "adl_rt1019p_nau8825", + .drv_name = "adl_rt1019p_8825", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &adl_rt1019p_amp, .sof_tplg_filename = "sof-adl-rt1019-nau8825.tplg", }, { .id = "10508825", - .drv_name = "adl_max98373_nau8825", + .drv_name = "adl_max98373_8825", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &adl_max98373_amp, .sof_tplg_filename = "sof-adl-max98373-nau8825.tplg", }, { .id = "10508825", - .drv_name = "adl_mx98360a_nau8825", + .drv_name = "adl_mx98360a_8825", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &adl_max98360a_amp, .sof_tplg_filename = "sof-adl-max98360a-nau8825.tplg", @@ -502,13 +507,20 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_adl_machines[] = { }, { .id = "10508825", - .drv_name = "adl_rt1015p_nau8825", + .drv_name = "adl_rt1015p_8825", .machine_quirk = snd_soc_acpi_codec_list, .quirk_data = &adl_rt1015p_amp, .sof_tplg_filename = "sof-adl-rt1015-nau8825.tplg", }, { .id = "10508825", + .drv_name = "adl_nau8318_8825", + .machine_quirk = snd_soc_acpi_codec_list, + .quirk_data = &adl_nau8318_amp, + .sof_tplg_filename = "sof-adl-nau8318-nau8825.tplg", + }, + { + .id = "10508825", .drv_name = "sof_nau8825", .sof_tplg_filename = "sof-adl-nau8825.tplg", }, diff --git a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c index 31b43116e3d8..07f96a11ea2f 100644 --- a/sound/soc/intel/common/soc-acpi-intel-rpl-match.c +++ b/sound/soc/intel/common/soc-acpi-intel-rpl-match.c @@ -203,6 +203,25 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01_rt71 {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link2_rt1316_link01[] = { + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt711_sdca_2_adr), + .adr_d = rt711_sdca_2_adr, + }, + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt1316_0_group2_adr), + .adr_d = rt1316_0_group2_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1316_1_group2_adr), + .adr_d = rt1316_1_group2_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1318_link12_rt714_link3[] = { { .mask = BIT(0), @@ -227,6 +246,25 @@ static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1318_link12_rt71 {} }; +static const struct snd_soc_acpi_link_adr rpl_sdw_rt711_link0_rt1318_link12[] = { + { + .mask = BIT(0), + .num_adr = ARRAY_SIZE(rt711_sdca_0_adr), + .adr_d = rt711_sdca_0_adr, + }, + { + .mask = BIT(1), + .num_adr = ARRAY_SIZE(rt1318_1_group1_adr), + .adr_d = rt1318_1_group1_adr, + }, + { + .mask = BIT(2), + .num_adr = ARRAY_SIZE(rt1318_2_group1_adr), + .adr_d = rt1318_2_group1_adr, + }, + {} +}; + static const struct snd_soc_acpi_link_adr rpl_sdw_rt1316_link12_rt714_link0[] = { { .mask = BIT(1), @@ -272,12 +310,24 @@ struct snd_soc_acpi_mach snd_soc_acpi_intel_rpl_sdw_machines[] = { .sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12-rt714-l3.tplg", }, { + .link_mask = 0x7, /* rt711 on link0 & two rt1318s on link1 and link2 */ + .links = rpl_sdw_rt711_link0_rt1318_link12, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l0-rt1318-l12.tplg", + }, + { .link_mask = 0x7, /* rt714 on link0 & two rt1316s on link1 and link2 */ .links = rpl_sdw_rt1316_link12_rt714_link0, .drv_name = "sof_sdw", .sof_tplg_filename = "sof-rpl-rt1316-l12-rt714-l0.tplg", }, { + .link_mask = 0x7, /* rt711 on link2 & two rt1316s on link0 and link1 */ + .links = rpl_sdw_rt711_link2_rt1316_link01, + .drv_name = "sof_sdw", + .sof_tplg_filename = "sof-rpl-rt711-l2-rt1316-l01.tplg", + }, + { .link_mask = 0x1, /* link0 required */ .links = rpl_rvp, .drv_name = "sof_sdw", diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 363fa4d47680..b027fba8233d 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -182,10 +182,12 @@ config SND_SOC_MT8186_MT6366_DA7219_MAX98357 If unsure select "N". config SND_SOC_MT8186_MT6366_RT1019_RT5682S - tristate "ASoC Audio driver for MT8186 with RT1019 RT5682S codec" + tristate "ASoC Audio driver for MT8186 with RT1019 RT5682S MAX98357A/MAX98360 codec" depends on I2C && GPIOLIB depends on SND_SOC_MT8186 && MTK_PMIC_WRAP + select SND_SOC_MAX98357A select SND_SOC_MT6358 + select SND_SOC_MAX98357A select SND_SOC_RT1015P select SND_SOC_RT5682S select SND_SOC_BT_SCO diff --git a/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c b/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c index 8f77a0bc1dc8..af44e331dae8 100644 --- a/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c +++ b/sound/soc/mediatek/mt8186/mt8186-mt6366-rt1019-rt5682s.c @@ -1083,6 +1083,21 @@ static struct snd_soc_card mt8186_mt6366_rt1019_rt5682s_soc_card = { .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf), }; +static struct snd_soc_card mt8186_mt6366_rt5682s_max98360_soc_card = { + .name = "mt8186_rt5682s_max98360", + .owner = THIS_MODULE, + .dai_link = mt8186_mt6366_rt1019_rt5682s_dai_links, + .num_links = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_dai_links), + .controls = mt8186_mt6366_rt1019_rt5682s_controls, + .num_controls = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_controls), + .dapm_widgets = mt8186_mt6366_rt1019_rt5682s_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_widgets), + .dapm_routes = mt8186_mt6366_rt1019_rt5682s_routes, + .num_dapm_routes = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_routes), + .codec_conf = mt8186_mt6366_rt1019_rt5682s_codec_conf, + .num_configs = ARRAY_SIZE(mt8186_mt6366_rt1019_rt5682s_codec_conf), +}; + static int mt8186_mt6366_rt1019_rt5682s_dev_probe(struct platform_device *pdev) { struct snd_soc_card *card; @@ -1232,9 +1247,14 @@ err_adsp_node: #if IS_ENABLED(CONFIG_OF) static const struct of_device_id mt8186_mt6366_rt1019_rt5682s_dt_match[] = { - { .compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound", + { + .compatible = "mediatek,mt8186-mt6366-rt1019-rt5682s-sound", .data = &mt8186_mt6366_rt1019_rt5682s_soc_card, }, + { + .compatible = "mediatek,mt8186-mt6366-rt5682s-max98360-sound", + .data = &mt8186_mt6366_rt5682s_max98360_soc_card, + }, {} }; MODULE_DEVICE_TABLE(of, mt8186_mt6366_rt1019_rt5682s_dt_match); diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index a045693d5bc2..c26d1b36e8f7 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig @@ -8,10 +8,6 @@ config SND_PXA2XX_SOC the PXA2xx AC97, I2S or SSP interface. You will also need to select the audio interfaces to support below. -config SND_MMP_SOC - bool - select MMP_SRAM - config SND_PXA2XX_AC97 tristate @@ -41,15 +37,6 @@ config SND_MMP_SOC_SSPA Say Y if you want to add support for codecs attached to the MMP SSPA interface. -config SND_PXA2XX_SOC_CORGI - tristate "SoC Audio support for Sharp Zaurus SL-C7x0" - depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx && I2C - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8731_I2C - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-C7x0 models (Corgi, Shepherd, Husky). - config SND_PXA2XX_SOC_SPITZ tristate "SoC Audio support for Sharp Zaurus SL-Cxx00" depends on SND_PXA2XX_SOC && PXA_SHARP_Cxx00 && I2C @@ -59,101 +46,6 @@ config SND_PXA2XX_SOC_SPITZ Say Y if you want to add support for SoC audio on Sharp Zaurus SL-Cxx00 models (Spitz, Borzoi and Akita). -config SND_PXA2XX_SOC_Z2 - tristate "SoC Audio support for Zipit Z2" - depends on SND_PXA2XX_SOC && MACH_ZIPIT2 && I2C - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8750 - help - Say Y if you want to add support for SoC audio on Zipit Z2. - -config SND_PXA2XX_SOC_POODLE - tristate "SoC Audio support for Poodle" - depends on SND_PXA2XX_SOC && MACH_POODLE && I2C - select SND_PXA2XX_SOC_I2S - select SND_SOC_WM8731_I2C - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-5600 model (Poodle). - -config SND_PXA2XX_SOC_TOSA - tristate "SoC AC97 Audio support for Tosa" - depends on SND_PXA2XX_SOC && MACH_TOSA - depends on MFD_TC6393XB - depends on AC97_BUS=n - select REGMAP - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_PXA2XX_SOC_AC97 - select SND_SOC_WM9712 - help - Say Y if you want to add support for SoC audio on Sharp - Zaurus SL-C6000x models (Tosa). - -config SND_PXA2XX_SOC_E740 - tristate "SoC AC97 Audio support for e740" - depends on SND_PXA2XX_SOC && MACH_E740 - depends on AC97_BUS=n - select REGMAP - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_SOC_WM9705 - select SND_PXA2XX_SOC_AC97 - help - Say Y if you want to add support for SoC audio on the - toshiba e740 PDA - -config SND_PXA2XX_SOC_E750 - tristate "SoC AC97 Audio support for e750" - depends on SND_PXA2XX_SOC && MACH_E750 - depends on AC97_BUS=n - select REGMAP - select SND_SOC_WM9705 - select SND_PXA2XX_SOC_AC97 - help - Say Y if you want to add support for SoC audio on the - toshiba e750 PDA - -config SND_PXA2XX_SOC_E800 - tristate "SoC AC97 Audio support for e800" - depends on SND_PXA2XX_SOC && MACH_E800 - depends on AC97_BUS=n - select REGMAP - select SND_SOC_WM9712 - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_PXA2XX_SOC_AC97 - help - Say Y if you want to add support for SoC audio on the - Toshiba e800 PDA - -config SND_PXA2XX_SOC_EM_X270 - tristate "SoC Audio support for CompuLab CM-X300" - depends on SND_PXA2XX_SOC && MACH_CM_X300 - depends on AC97_BUS=n - select REGMAP - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_PXA2XX_SOC_AC97 - select SND_SOC_WM9712 - help - Say Y if you want to add support for SoC audio on - CompuLab EM-x270, eXeda and CM-X300 machines. - -config SND_PXA2XX_SOC_PALM27X - bool "SoC Audio support for Palm T|X, T5, E2 and LifeDrive" - depends on SND_PXA2XX_SOC && (MACH_PALMLD || MACH_PALMTX || \ - MACH_PALMT5 || MACH_PALMTE2) - depends on AC97_BUS=n - select REGMAP - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_PXA2XX_SOC_AC97 - select SND_SOC_WM9712 - help - Say Y if you want to add support for SoC audio on - Palm T|X, T5, E2 or LifeDrive handheld computer. - config SND_PXA910_SOC tristate "SoC Audio for Marvell PXA910 chip" depends on ARCH_MMP && SND @@ -161,71 +53,3 @@ config SND_PXA910_SOC help Say Y if you want to add support for SoC audio on the Marvell PXA910 reference platform. - -config SND_SOC_TTC_DKB - tristate "SoC Audio support for TTC DKB" - depends on SND_PXA910_SOC && MACH_TTC_DKB && I2C=y - select PXA_SSP - select SND_PXA_SOC_SSP - select SND_MMP_SOC - select MFD_88PM860X - select SND_SOC_88PM860X - help - Say Y if you want to add support for SoC audio on TTC DKB - - -config SND_SOC_ZYLONITE - tristate "SoC Audio support for Marvell Zylonite" - depends on SND_PXA2XX_SOC && MACH_ZYLONITE - depends on AC97_BUS=n - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_PXA2XX_SOC_AC97 - select REGMAP - select SND_PXA_SOC_SSP - select SND_SOC_WM9713 - help - Say Y if you want to add support for SoC audio on the - Marvell Zylonite reference platform. - -config SND_PXA2XX_SOC_HX4700 - tristate "SoC Audio support for HP iPAQ hx4700" - depends on SND_PXA2XX_SOC && MACH_H4700 && I2C - select SND_PXA2XX_SOC_I2S - select SND_SOC_AK4641 - help - Say Y if you want to add support for SoC audio on the - HP iPAQ hx4700. - -config SND_PXA2XX_SOC_MAGICIAN - tristate "SoC Audio support for HTC Magician" - depends on SND_PXA2XX_SOC && MACH_MAGICIAN && I2C - select SND_PXA2XX_SOC_I2S - select SND_PXA_SOC_SSP - select SND_SOC_UDA1380 - help - Say Y if you want to add support for SoC audio on the - HTC Magician. - -config SND_PXA2XX_SOC_MIOA701 - tristate "SoC Audio support for MIO A701" - depends on SND_PXA2XX_SOC && MACH_MIOA701 - depends on AC97_BUS=n - select REGMAP - select AC97_BUS_NEW - select AC97_BUS_COMPAT - select SND_PXA2XX_SOC_AC97 - select SND_SOC_WM9713 - help - Say Y if you want to add support for SoC audio on the - MIO A701. - -config SND_MMP_SOC_BROWNSTONE - tristate "SoC Audio support for Marvell Brownstone" - depends on SND_MMP_SOC_SSPA && MACH_BROWNSTONE && I2C - select SND_MMP_SOC - select MFD_WM8994 - select SND_SOC_WM8994 - help - Say Y if you want to add support for SoC audio on the - Marvell Brownstone reference platform. diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile index b712eb894a61..406605fc7414 100644 --- a/sound/soc/pxa/Makefile +++ b/sound/soc/pxa/Makefile @@ -4,47 +4,14 @@ snd-soc-pxa2xx-objs := pxa2xx-pcm.o snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o snd-soc-pxa-ssp-objs := pxa-ssp.o -snd-soc-mmp-objs := mmp-pcm.o snd-soc-mmp-sspa-objs := mmp-sspa.o obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o -obj-$(CONFIG_SND_MMP_SOC) += snd-soc-mmp.o obj-$(CONFIG_SND_MMP_SOC_SSPA) += snd-soc-mmp-sspa.o # PXA Machine Support -snd-soc-corgi-objs := corgi.o -snd-soc-poodle-objs := poodle.o -snd-soc-tosa-objs := tosa.o -snd-soc-e740-objs := e740_wm9705.o -snd-soc-e750-objs := e750_wm9705.o -snd-soc-e800-objs := e800_wm9712.o snd-soc-spitz-objs := spitz.o -snd-soc-em-x270-objs := em-x270.o -snd-soc-palm27x-objs := palm27x.o -snd-soc-zylonite-objs := zylonite.o -snd-soc-hx4700-objs := hx4700.o -snd-soc-magician-objs := magician.o -snd-soc-mioa701-objs := mioa701_wm9713.o -snd-soc-z2-objs := z2.o -snd-soc-brownstone-objs := brownstone.o -snd-soc-ttc-dkb-objs := ttc-dkb.o - -obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o -obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o -obj-$(CONFIG_SND_PXA2XX_SOC_TOSA) += snd-soc-tosa.o -obj-$(CONFIG_SND_PXA2XX_SOC_E740) += snd-soc-e740.o -obj-$(CONFIG_SND_PXA2XX_SOC_E750) += snd-soc-e750.o -obj-$(CONFIG_SND_PXA2XX_SOC_E800) += snd-soc-e800.o obj-$(CONFIG_SND_PXA2XX_SOC_SPITZ) += snd-soc-spitz.o -obj-$(CONFIG_SND_PXA2XX_SOC_EM_X270) += snd-soc-em-x270.o -obj-$(CONFIG_SND_PXA2XX_SOC_PALM27X) += snd-soc-palm27x.o -obj-$(CONFIG_SND_PXA2XX_SOC_HX4700) += snd-soc-hx4700.o -obj-$(CONFIG_SND_PXA2XX_SOC_MAGICIAN) += snd-soc-magician.o -obj-$(CONFIG_SND_PXA2XX_SOC_MIOA701) += snd-soc-mioa701.o -obj-$(CONFIG_SND_PXA2XX_SOC_Z2) += snd-soc-z2.o -obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o -obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o -obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c deleted file mode 100644 index f310a8e91bbf..000000000000 --- a/sound/soc/pxa/brownstone.c +++ /dev/null @@ -1,133 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * linux/sound/soc/pxa/brownstone.c - * - * Copyright (C) 2011 Marvell International Ltd. - */ - -#include <linux/module.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/jack.h> - -#include "../codecs/wm8994.h" -#include "mmp-sspa.h" - -static const struct snd_kcontrol_new brownstone_dapm_control[] = { - SOC_DAPM_PIN_SWITCH("Ext Spk"), -}; - -static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Main Mic", NULL), -}; - -static const struct snd_soc_dapm_route brownstone_audio_map[] = { - {"Ext Spk", NULL, "SPKOUTLP"}, - {"Ext Spk", NULL, "SPKOUTLN"}, - {"Ext Spk", NULL, "SPKOUTRP"}, - {"Ext Spk", NULL, "SPKOUTRN"}, - - {"Headset Stereophone", NULL, "HPOUT1L"}, - {"Headset Stereophone", NULL, "HPOUT1R"}, - - {"IN1RN", NULL, "Headset Mic"}, - - {"DMIC1DAT", NULL, "MICBIAS1"}, - {"MICBIAS1", NULL, "Main Mic"}, -}; - -static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int freq_out, sspa_mclk, sysclk; - - if (params_rate(params) > 11025) { - freq_out = params_rate(params) * 512; - sysclk = params_rate(params) * 256; - sspa_mclk = params_rate(params) * 64; - } else { - freq_out = params_rate(params) * 1024; - sysclk = params_rate(params) * 512; - sspa_mclk = params_rate(params) * 64; - } - - snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0); - snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk); - snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk); - - /* set wm8994 sysclk */ - snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0); - - return 0; -} - -/* machine stream operations */ -static const struct snd_soc_ops brownstone_ops = { - .hw_params = brownstone_wm8994_hw_params, -}; - -SND_SOC_DAILINK_DEFS(wm8994, - DAILINK_COMP_ARRAY(COMP_CPU("mmp-sspa-dai.0")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8994-codec", "wm8994-aif1")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("mmp-pcm-audio"))); - -static struct snd_soc_dai_link brownstone_wm8994_dai[] = { -{ - .name = "WM8994", - .stream_name = "WM8994 HiFi", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &brownstone_ops, - SND_SOC_DAILINK_REG(wm8994), -}, -}; - -/* audio machine driver */ -static struct snd_soc_card brownstone = { - .name = "brownstone", - .owner = THIS_MODULE, - .dai_link = brownstone_wm8994_dai, - .num_links = ARRAY_SIZE(brownstone_wm8994_dai), - - .controls = brownstone_dapm_control, - .num_controls = ARRAY_SIZE(brownstone_dapm_control), - .dapm_widgets = brownstone_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets), - .dapm_routes = brownstone_audio_map, - .num_dapm_routes = ARRAY_SIZE(brownstone_audio_map), - .fully_routed = true, -}; - -static int brownstone_probe(struct platform_device *pdev) -{ - int ret; - - brownstone.dev = &pdev->dev; - ret = devm_snd_soc_register_card(&pdev->dev, &brownstone); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static struct platform_driver mmp_driver = { - .driver = { - .name = "brownstone-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = brownstone_probe, -}; - -module_platform_driver(mmp_driver); - -MODULE_AUTHOR("Leo Yan <leoy@marvell.com>"); -MODULE_DESCRIPTION("ALSA SoC Brownstone"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:brownstone-audio"); diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c deleted file mode 100644 index 4489d2c8b124..000000000000 --- a/sound/soc/pxa/corgi.c +++ /dev/null @@ -1,332 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * corgi.c -- SoC audio for Corgi - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood <lrg@slimlogic.co.uk> - * Richard Purdie <richard@openedhand.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/timer.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/gpio.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> - -#include "../codecs/wm8731.h" -#include "pxa2xx-i2s.h" - -#define CORGI_HP 0 -#define CORGI_MIC 1 -#define CORGI_LINE 2 -#define CORGI_HEADSET 3 -#define CORGI_HP_OFF 4 -#define CORGI_SPK_ON 0 -#define CORGI_SPK_OFF 1 - - /* audio clock in Hz - rounded from 12.235MHz */ -#define CORGI_AUDIO_CLOCK 12288000 - -static int corgi_jack_func; -static int corgi_spk_func; - -static struct gpio_desc *gpiod_mute_l, *gpiod_mute_r, - *gpiod_apm_on, *gpiod_mic_bias; - -static void corgi_ext_control(struct snd_soc_dapm_context *dapm) -{ - snd_soc_dapm_mutex_lock(dapm); - - /* set up jack connection */ - switch (corgi_jack_func) { - case CORGI_HP: - /* set = unmute headphone */ - gpiod_set_value(gpiod_mute_l, 1); - gpiod_set_value(gpiod_mute_r, 1); - snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); - break; - case CORGI_MIC: - /* reset = mute headphone */ - gpiod_set_value(gpiod_mute_l, 0); - gpiod_set_value(gpiod_mute_r, 0); - snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); - break; - case CORGI_LINE: - gpiod_set_value(gpiod_mute_l, 0); - gpiod_set_value(gpiod_mute_r, 0); - snd_soc_dapm_disable_pin_unlocked(dapm, "Mic Jack"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Line Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); - break; - case CORGI_HEADSET: - gpiod_set_value(gpiod_mute_l, 0); - gpiod_set_value(gpiod_mute_r, 1); - snd_soc_dapm_enable_pin_unlocked(dapm, "Mic Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Line Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack"); - break; - } - - if (corgi_spk_func == CORGI_SPK_ON) - snd_soc_dapm_enable_pin_unlocked(dapm, "Ext Spk"); - else - snd_soc_dapm_disable_pin_unlocked(dapm, "Ext Spk"); - - /* signal a DAPM event */ - snd_soc_dapm_sync_unlocked(dapm); - - snd_soc_dapm_mutex_unlock(dapm); -} - -static int corgi_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - - /* check the jack status at stream startup */ - corgi_ext_control(&rtd->card->dapm); - - return 0; -} - -/* we need to unmute the HP at shutdown as the mute burns power on corgi */ -static void corgi_shutdown(struct snd_pcm_substream *substream) -{ - /* set = unmute headphone */ - gpiod_set_value(gpiod_mute_l, 1); - gpiod_set_value(gpiod_mute_r, 1); -} - -static int corgi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops corgi_ops = { - .startup = corgi_startup, - .hw_params = corgi_hw_params, - .shutdown = corgi_shutdown, -}; - -static int corgi_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = corgi_jack_func; - return 0; -} - -static int corgi_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (corgi_jack_func == ucontrol->value.enumerated.item[0]) - return 0; - - corgi_jack_func = ucontrol->value.enumerated.item[0]; - corgi_ext_control(&card->dapm); - return 1; -} - -static int corgi_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = corgi_spk_func; - return 0; -} - -static int corgi_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (corgi_spk_func == ucontrol->value.enumerated.item[0]) - return 0; - - corgi_spk_func = ucontrol->value.enumerated.item[0]; - corgi_ext_control(&card->dapm); - return 1; -} - -static int corgi_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_apm_on, SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -static int corgi_mic_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_mic_bias, SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -/* corgi machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { -SND_SOC_DAPM_HP("Headphone Jack", NULL), -SND_SOC_DAPM_MIC("Mic Jack", corgi_mic_event), -SND_SOC_DAPM_SPK("Ext Spk", corgi_amp_event), -SND_SOC_DAPM_LINE("Line Jack", NULL), -SND_SOC_DAPM_HP("Headset Jack", NULL), -}; - -/* Corgi machine audio map (connections to the codec pins) */ -static const struct snd_soc_dapm_route corgi_audio_map[] = { - - /* headset Jack - in = micin, out = LHPOUT*/ - {"Headset Jack", NULL, "LHPOUT"}, - - /* headphone connected to LHPOUT1, RHPOUT1 */ - {"Headphone Jack", NULL, "LHPOUT"}, - {"Headphone Jack", NULL, "RHPOUT"}, - - /* speaker connected to LOUT, ROUT */ - {"Ext Spk", NULL, "ROUT"}, - {"Ext Spk", NULL, "LOUT"}, - - /* mic is connected to MICIN (via right channel of headphone jack) */ - {"MICIN", NULL, "Mic Jack"}, - - /* Same as the above but no mic bias for line signals */ - {"MICIN", NULL, "Line Jack"}, -}; - -static const char * const jack_function[] = {"Headphone", "Mic", "Line", - "Headset", "Off"}; -static const char * const spk_function[] = {"On", "Off"}; -static const struct soc_enum corgi_enum[] = { - SOC_ENUM_SINGLE_EXT(5, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const struct snd_kcontrol_new wm8731_corgi_controls[] = { - SOC_ENUM_EXT("Jack Function", corgi_enum[0], corgi_get_jack, - corgi_set_jack), - SOC_ENUM_EXT("Speaker Function", corgi_enum[1], corgi_get_spk, - corgi_set_spk), -}; - -/* corgi digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(wm8731, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link corgi_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &corgi_ops, - SND_SOC_DAILINK_REG(wm8731), -}; - -/* corgi audio machine driver */ -static struct snd_soc_card corgi = { - .name = "Corgi", - .owner = THIS_MODULE, - .dai_link = &corgi_dai, - .num_links = 1, - - .controls = wm8731_corgi_controls, - .num_controls = ARRAY_SIZE(wm8731_corgi_controls), - .dapm_widgets = wm8731_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), - .dapm_routes = corgi_audio_map, - .num_dapm_routes = ARRAY_SIZE(corgi_audio_map), - .fully_routed = true, -}; - -static int corgi_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &corgi; - int ret; - - card->dev = &pdev->dev; - - gpiod_mute_l = devm_gpiod_get(&pdev->dev, "mute-l", GPIOD_OUT_HIGH); - if (IS_ERR(gpiod_mute_l)) - return PTR_ERR(gpiod_mute_l); - gpiod_mute_r = devm_gpiod_get(&pdev->dev, "mute-r", GPIOD_OUT_HIGH); - if (IS_ERR(gpiod_mute_r)) - return PTR_ERR(gpiod_mute_r); - gpiod_apm_on = devm_gpiod_get(&pdev->dev, "apm-on", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_apm_on)) - return PTR_ERR(gpiod_apm_on); - gpiod_mic_bias = devm_gpiod_get(&pdev->dev, "mic-bias", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_mic_bias)) - return PTR_ERR(gpiod_mic_bias); - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static struct platform_driver corgi_driver = { - .driver = { - .name = "corgi-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = corgi_probe, -}; - -module_platform_driver(corgi_driver); - -/* Module information */ -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Corgi"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:corgi-audio"); diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c deleted file mode 100644 index 4e0e9b778d4c..000000000000 --- a/sound/soc/pxa/e740_wm9705.c +++ /dev/null @@ -1,168 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * e740-wm9705.c -- SoC audio for e740 - * - * Copyright 2007 (c) Ian Molton <spyro@f2s.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/gpio/consumer.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <linux/platform_data/asoc-pxa.h> - -#include <asm/mach-types.h> - -static struct gpio_desc *gpiod_output_amp, *gpiod_input_amp; -static struct gpio_desc *gpiod_audio_power; - -#define E740_AUDIO_OUT 1 -#define E740_AUDIO_IN 2 - -static int e740_audio_power; - -static void e740_sync_audio_power(int status) -{ - gpiod_set_value(gpiod_audio_power, !status); - gpiod_set_value(gpiod_output_amp, (status & E740_AUDIO_OUT) ? 1 : 0); - gpiod_set_value(gpiod_input_amp, (status & E740_AUDIO_IN) ? 1 : 0); -} - -static int e740_mic_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - e740_audio_power |= E740_AUDIO_IN; - else if (event & SND_SOC_DAPM_POST_PMD) - e740_audio_power &= ~E740_AUDIO_IN; - - e740_sync_audio_power(e740_audio_power); - - return 0; -} - -static int e740_output_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - e740_audio_power |= E740_AUDIO_OUT; - else if (event & SND_SOC_DAPM_POST_PMD) - e740_audio_power &= ~E740_AUDIO_OUT; - - e740_sync_audio_power(e740_audio_power); - - return 0; -} - -static const struct snd_soc_dapm_widget e740_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_MIC("Mic (Internal)", NULL), - SND_SOC_DAPM_PGA_E("Output Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e740_output_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("Mic Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e740_mic_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Output Amp", NULL, "LOUT"}, - {"Output Amp", NULL, "ROUT"}, - {"Output Amp", NULL, "MONOOUT"}, - - {"Speaker", NULL, "Output Amp"}, - {"Headphone Jack", NULL, "Output Amp"}, - - {"MIC1", NULL, "Mic Amp"}, - {"Mic Amp", NULL, "Mic (Internal)"}, -}; - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link e740_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(ac97), - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - SND_SOC_DAILINK_REG(ac97_aux), - }, -}; - -static struct snd_soc_card e740 = { - .name = "Toshiba e740", - .owner = THIS_MODULE, - .dai_link = e740_dai, - .num_links = ARRAY_SIZE(e740_dai), - - .dapm_widgets = e740_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(e740_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, -}; - -static int e740_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &e740; - int ret; - - gpiod_input_amp = devm_gpiod_get(&pdev->dev, "Mic amp", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(gpiod_input_amp); - if (ret) - return ret; - gpiod_output_amp = devm_gpiod_get(&pdev->dev, "Output amp", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(gpiod_output_amp); - if (ret) - return ret; - gpiod_audio_power = devm_gpiod_get(&pdev->dev, "Audio power", GPIOD_OUT_HIGH); - ret = PTR_ERR_OR_ZERO(gpiod_audio_power); - if (ret) - return ret; - - card->dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static int e740_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver e740_driver = { - .driver = { - .name = "e740-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = e740_probe, - .remove = e740_remove, -}; - -module_platform_driver(e740_driver); - -/* Module information */ -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("ALSA SoC driver for e740"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:e740-audio"); diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c deleted file mode 100644 index 7a1e0d8bfd11..000000000000 --- a/sound/soc/pxa/e750_wm9705.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * e750-wm9705.c -- SoC audio for e750 - * - * Copyright 2007 (c) Ian Molton <spyro@f2s.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/gpio/consumer.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <linux/platform_data/asoc-pxa.h> - -#include <asm/mach-types.h> - -static struct gpio_desc *gpiod_spk_amp, *gpiod_hp_amp; - -static int e750_spk_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpiod_set_value(gpiod_spk_amp, 1); - else if (event & SND_SOC_DAPM_POST_PMD) - gpiod_set_value(gpiod_spk_amp, 0); - - return 0; -} - -static int e750_hp_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpiod_set_value(gpiod_hp_amp, 1); - else if (event & SND_SOC_DAPM_POST_PMD) - gpiod_set_value(gpiod_hp_amp, 0); - - return 0; -} - -static const struct snd_soc_dapm_widget e750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_MIC("Mic (Internal)", NULL), - SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e750_hp_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e750_spk_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Amp", NULL, "HPOUTL"}, - {"Headphone Amp", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "Headphone Amp"}, - - {"Speaker Amp", NULL, "MONOOUT"}, - {"Speaker", NULL, "Speaker Amp"}, - - {"MIC1", NULL, "Mic (Internal)"}, -}; - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9705-codec", "wm9705-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link e750_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(ac97), - /* use ops to check startup state */ - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - SND_SOC_DAILINK_REG(ac97_aux), - }, -}; - -static struct snd_soc_card e750 = { - .name = "Toshiba e750", - .owner = THIS_MODULE, - .dai_link = e750_dai, - .num_links = ARRAY_SIZE(e750_dai), - - .dapm_widgets = e750_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(e750_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, -}; - -static int e750_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &e750; - int ret; - - gpiod_hp_amp = devm_gpiod_get(&pdev->dev, "Headphone amp", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(gpiod_hp_amp); - if (ret) - return ret; - gpiod_spk_amp = devm_gpiod_get(&pdev->dev, "Speaker amp", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(gpiod_spk_amp); - if (ret) - return ret; - - card->dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static int e750_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver e750_driver = { - .driver = { - .name = "e750-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = e750_probe, - .remove = e750_remove, -}; - -module_platform_driver(e750_driver); - -/* Module information */ -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("ALSA SoC driver for e750"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:e750-audio"); diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c deleted file mode 100644 index a39c494127cf..000000000000 --- a/sound/soc/pxa/e800_wm9712.c +++ /dev/null @@ -1,147 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * e800-wm9712.c -- SoC audio for e800 - * - * Copyright 2007 (c) Ian Molton <spyro@f2s.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/gpio/consumer.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> - -static struct gpio_desc *gpiod_spk_amp, *gpiod_hp_amp; - -static int e800_spk_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpiod_set_value(gpiod_spk_amp, 1); - else if (event & SND_SOC_DAPM_POST_PMD) - gpiod_set_value(gpiod_spk_amp, 0); - - return 0; -} - -static int e800_hp_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (event & SND_SOC_DAPM_PRE_PMU) - gpiod_set_value(gpiod_hp_amp, 1); - else if (event & SND_SOC_DAPM_POST_PMD) - gpiod_set_value(gpiod_hp_amp, 0); - - return 0; -} - -static const struct snd_soc_dapm_widget e800_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic (Internal1)", NULL), - SND_SOC_DAPM_MIC("Mic (Internal2)", NULL), - SND_SOC_DAPM_SPK("Speaker", NULL), - SND_SOC_DAPM_PGA_E("Headphone Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e800_hp_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("Speaker Amp", SND_SOC_NOPM, 0, 0, NULL, 0, - e800_spk_amp_event, SND_SOC_DAPM_PRE_PMU | - SND_SOC_DAPM_POST_PMD), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Jack", NULL, "HPOUTL"}, - {"Headphone Jack", NULL, "HPOUTR"}, - {"Headphone Jack", NULL, "Headphone Amp"}, - - {"Speaker Amp", NULL, "MONOOUT"}, - {"Speaker", NULL, "Speaker Amp"}, - - {"MIC1", NULL, "Mic (Internal1)"}, - {"MIC2", NULL, "Mic (Internal2)"}, -}; - - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link e800_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(ac97), - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - SND_SOC_DAILINK_REG(ac97_aux), - }, -}; - -static struct snd_soc_card e800 = { - .name = "Toshiba e800", - .owner = THIS_MODULE, - .dai_link = e800_dai, - .num_links = ARRAY_SIZE(e800_dai), - - .dapm_widgets = e800_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(e800_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static int e800_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &e800; - int ret; - - gpiod_hp_amp = devm_gpiod_get(&pdev->dev, "Headphone amp", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(gpiod_hp_amp); - if (ret) - return ret; - gpiod_spk_amp = devm_gpiod_get(&pdev->dev, "Speaker amp", GPIOD_OUT_LOW); - ret = PTR_ERR_OR_ZERO(gpiod_spk_amp); - if (ret) - return ret; - - card->dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static int e800_remove(struct platform_device *pdev) -{ - return 0; -} - -static struct platform_driver e800_driver = { - .driver = { - .name = "e800-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = e800_probe, - .remove = e800_remove, -}; - -module_platform_driver(e800_driver); - -/* Module information */ -MODULE_AUTHOR("Ian Molton <spyro@f2s.com>"); -MODULE_DESCRIPTION("ALSA SoC driver for e800"); -MODULE_LICENSE("GPL v2"); -MODULE_ALIAS("platform:e800-audio"); diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c deleted file mode 100644 index b59ec22e1e7e..000000000000 --- a/sound/soc/pxa/em-x270.c +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SoC audio driver for EM-X270, eXeda and CM-X300 - * - * Copyright 2007, 2009 CompuLab, Ltd. - * - * Author: Mike Rapoport <mike@compulab.co.il> - * - * Copied from tosa.c: - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood <lrg@slimlogic.co.uk> - * Richard Purdie <richard@openedhand.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link em_x270_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(ac97), - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - SND_SOC_DAILINK_REG(ac97_aux), - }, -}; - -static struct snd_soc_card em_x270 = { - .name = "EM-X270", - .owner = THIS_MODULE, - .dai_link = em_x270_dai, - .num_links = ARRAY_SIZE(em_x270_dai), -}; - -static struct platform_device *em_x270_snd_device; - -static int __init em_x270_init(void) -{ - int ret; - - if (!(machine_is_em_x270() || machine_is_exeda() - || machine_is_cm_x300())) - return -ENODEV; - - em_x270_snd_device = platform_device_alloc("soc-audio", -1); - if (!em_x270_snd_device) - return -ENOMEM; - - platform_set_drvdata(em_x270_snd_device, &em_x270); - ret = platform_device_add(em_x270_snd_device); - - if (ret) - platform_device_put(em_x270_snd_device); - - return ret; -} - -static void __exit em_x270_exit(void) -{ - platform_device_unregister(em_x270_snd_device); -} - -module_init(em_x270_init); -module_exit(em_x270_exit); - -/* Module information */ -MODULE_AUTHOR("Mike Rapoport"); -MODULE_DESCRIPTION("ALSA SoC EM-X270, eXeda and CM-X300"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/pxa/hx4700.c b/sound/soc/pxa/hx4700.c deleted file mode 100644 index a323ddb8fc3e..000000000000 --- a/sound/soc/pxa/hx4700.c +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SoC audio for HP iPAQ hx4700 - * - * Copyright (c) 2009 Philipp Zabel - */ - -#include <linux/module.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/gpio/consumer.h> - -#include <sound/core.h> -#include <sound/jack.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include "pxa2xx-i2s.h" - -static struct gpio_desc *gpiod_hp_driver, *gpiod_spk_sd; -static struct snd_soc_jack hs_jack; - -/* Headphones jack detection DAPM pin */ -static struct snd_soc_jack_pin hs_jack_pin[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - .invert = 1, - }, - { - .pin = "Speaker", - /* disable speaker when hp jack is inserted */ - .mask = SND_JACK_HEADPHONE, - }, -}; - -/* Headphones jack detection GPIO */ -static struct snd_soc_jack_gpio hs_jack_gpio = { - .name = "earphone-det", - .report = SND_JACK_HEADPHONE, - .debounce_time = 200, -}; - -/* - * iPAQ hx4700 uses I2S for capture and playback. - */ -static int hx4700_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int ret = 0; - - /* set the I2S system clock as output */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - /* inform codec driver about clock freq * - * (PXA I2S always uses divider 256) */ - ret = snd_soc_dai_set_sysclk(codec_dai, 0, 256 * params_rate(params), - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops hx4700_ops = { - .hw_params = hx4700_hw_params, -}; - -static int hx4700_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_spk_sd, !SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -static int hx4700_hp_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_hp_driver, !!SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -/* hx4700 machine dapm widgets */ -static const struct snd_soc_dapm_widget hx4700_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", hx4700_hp_power), - SND_SOC_DAPM_SPK("Speaker", hx4700_spk_power), - SND_SOC_DAPM_MIC("Built-in Microphone", NULL), -}; - -/* hx4700 machine audio_map */ -static const struct snd_soc_dapm_route hx4700_audio_map[] = { - - /* Headphone connected to LOUT, ROUT */ - {"Headphone Jack", NULL, "LOUT"}, - {"Headphone Jack", NULL, "ROUT"}, - - /* Speaker connected to MOUT2 */ - {"Speaker", NULL, "MOUT2"}, - - /* Microphone connected to MICIN */ - {"MICIN", NULL, "Built-in Microphone"}, - {"AIN", NULL, "MICOUT"}, -}; - -/* - * Logic for a ak4641 as connected on a HP iPAQ hx4700 - */ -static int hx4700_ak4641_init(struct snd_soc_pcm_runtime *rtd) -{ - int err; - - /* Jack detection API stuff */ - err = snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack", - SND_JACK_HEADPHONE, &hs_jack, - hs_jack_pin, ARRAY_SIZE(hs_jack_pin)); - if (err) - return err; - - err = snd_soc_jack_add_gpios(&hs_jack, 1, &hs_jack_gpio); - - return err; -} - -/* hx4700 digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(ak4641, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("ak4641.0-0012", "ak4641-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link hx4700_dai = { - .name = "ak4641", - .stream_name = "AK4641", - .init = hx4700_ak4641_init, - .dai_fmt = SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &hx4700_ops, - SND_SOC_DAILINK_REG(ak4641), -}; - -/* hx4700 audio machine driver */ -static struct snd_soc_card snd_soc_card_hx4700 = { - .name = "iPAQ hx4700", - .owner = THIS_MODULE, - .dai_link = &hx4700_dai, - .num_links = 1, - .dapm_widgets = hx4700_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(hx4700_dapm_widgets), - .dapm_routes = hx4700_audio_map, - .num_dapm_routes = ARRAY_SIZE(hx4700_audio_map), - .fully_routed = true, -}; - -static int hx4700_audio_probe(struct platform_device *pdev) -{ - int ret; - - if (!machine_is_h4700()) - return -ENODEV; - - gpiod_hp_driver = devm_gpiod_get(&pdev->dev, "hp-driver", GPIOD_ASIS); - ret = PTR_ERR_OR_ZERO(gpiod_hp_driver); - if (ret) - return ret; - gpiod_spk_sd = devm_gpiod_get(&pdev->dev, "spk-sd", GPIOD_ASIS); - ret = PTR_ERR_OR_ZERO(gpiod_spk_sd); - if (ret) - return ret; - - hs_jack_gpio.gpiod_dev = &pdev->dev; - snd_soc_card_hx4700.dev = &pdev->dev; - ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_hx4700); - - return ret; -} - -static int hx4700_audio_remove(struct platform_device *pdev) -{ - gpiod_set_value(gpiod_hp_driver, 0); - gpiod_set_value(gpiod_spk_sd, 0); - return 0; -} - -static struct platform_driver hx4700_audio_driver = { - .driver = { - .name = "hx4700-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = hx4700_audio_probe, - .remove = hx4700_audio_remove, -}; - -module_platform_driver(hx4700_audio_driver); - -MODULE_AUTHOR("Philipp Zabel"); -MODULE_DESCRIPTION("ALSA SoC iPAQ hx4700"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:hx4700-audio"); diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c deleted file mode 100644 index b791a2ba5ce5..000000000000 --- a/sound/soc/pxa/magician.c +++ /dev/null @@ -1,366 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * SoC audio for HTC Magician - * - * Copyright (c) 2006 Philipp Zabel <philipp.zabel@gmail.com> - * - * based on spitz.c, - * Authors: Liam Girdwood <lrg@slimlogic.co.uk> - * Richard Purdie <richard@openedhand.com> - */ - -#include <linux/module.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/delay.h> -#include <linux/gpio/consumer.h> -#include <linux/i2c.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include "../codecs/uda1380.h" -#include "pxa2xx-i2s.h" -#include "pxa-ssp.h" - -#define MAGICIAN_MIC 0 -#define MAGICIAN_MIC_EXT 1 - -static int magician_hp_switch; -static int magician_spk_switch = 1; -static int magician_in_sel = MAGICIAN_MIC; - -static struct gpio_desc *gpiod_spk_power, *gpiod_ep_power, *gpiod_mic_power; -static struct gpio_desc *gpiod_in_sel0, *gpiod_in_sel1; - -static void magician_ext_control(struct snd_soc_dapm_context *dapm) -{ - - snd_soc_dapm_mutex_lock(dapm); - - if (magician_spk_switch) - snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker"); - else - snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker"); - if (magician_hp_switch) - snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); - else - snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); - - switch (magician_in_sel) { - case MAGICIAN_MIC: - snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Mic"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Call Mic"); - break; - case MAGICIAN_MIC_EXT: - snd_soc_dapm_disable_pin_unlocked(dapm, "Call Mic"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Mic"); - break; - } - - snd_soc_dapm_sync_unlocked(dapm); - - snd_soc_dapm_mutex_unlock(dapm); -} - -static int magician_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - - /* check the jack status at stream startup */ - magician_ext_control(&rtd->card->dapm); - - return 0; -} - -/* - * Magician uses SSP port for playback. - */ -static int magician_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int width; - int ret = 0; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_MSB | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_BC_FC); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_BP_FP); - if (ret < 0) - return ret; - - width = snd_pcm_format_physical_width(params_format(params)); - ret = snd_soc_dai_set_tdm_slot(cpu_dai, 1, 0, 1, width); - if (ret < 0) - return ret; - - /* set audio clock as clock source */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - return 0; -} - -/* - * Magician uses I2S for capture. - */ -static int magician_capture_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int ret = 0; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_BC_FC); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_MSB | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_BP_FP); - if (ret < 0) - return ret; - - /* set the I2S system clock as output */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops magician_capture_ops = { - .startup = magician_startup, - .hw_params = magician_capture_hw_params, -}; - -static const struct snd_soc_ops magician_playback_ops = { - .startup = magician_startup, - .hw_params = magician_playback_hw_params, -}; - -static int magician_get_hp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = magician_hp_switch; - return 0; -} - -static int magician_set_hp(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (magician_hp_switch == ucontrol->value.integer.value[0]) - return 0; - - magician_hp_switch = ucontrol->value.integer.value[0]; - magician_ext_control(&card->dapm); - return 1; -} - -static int magician_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = magician_spk_switch; - return 0; -} - -static int magician_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (magician_spk_switch == ucontrol->value.integer.value[0]) - return 0; - - magician_spk_switch = ucontrol->value.integer.value[0]; - magician_ext_control(&card->dapm); - return 1; -} - -static int magician_get_input(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = magician_in_sel; - return 0; -} - -static int magician_set_input(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (magician_in_sel == ucontrol->value.enumerated.item[0]) - return 0; - - magician_in_sel = ucontrol->value.enumerated.item[0]; - - switch (magician_in_sel) { - case MAGICIAN_MIC: - gpiod_set_value(gpiod_in_sel1, 1); - break; - case MAGICIAN_MIC_EXT: - gpiod_set_value(gpiod_in_sel1, 0); - } - - return 1; -} - -static int magician_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_spk_power, SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -static int magician_hp_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_ep_power, SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -static int magician_mic_bias(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_mic_power, SND_SOC_DAPM_EVENT_ON(event)); - return 0; -} - -/* magician machine dapm widgets */ -static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", magician_hp_power), - SND_SOC_DAPM_SPK("Speaker", magician_spk_power), - SND_SOC_DAPM_MIC("Call Mic", magician_mic_bias), - SND_SOC_DAPM_MIC("Headset Mic", magician_mic_bias), -}; - -/* magician machine audio_map */ -static const struct snd_soc_dapm_route audio_map[] = { - - /* Headphone connected to VOUTL, VOUTR */ - {"Headphone Jack", NULL, "VOUTL"}, - {"Headphone Jack", NULL, "VOUTR"}, - - /* Speaker connected to VOUTL, VOUTR */ - {"Speaker", NULL, "VOUTL"}, - {"Speaker", NULL, "VOUTR"}, - - /* Mics are connected to VINM */ - {"VINM", NULL, "Headset Mic"}, - {"VINM", NULL, "Call Mic"}, -}; - -static const char * const input_select[] = {"Call Mic", "Headset Mic"}; -static const struct soc_enum magician_in_sel_enum = - SOC_ENUM_SINGLE_EXT(2, input_select); - -static const struct snd_kcontrol_new uda1380_magician_controls[] = { - SOC_SINGLE_BOOL_EXT("Headphone Switch", - (unsigned long)&magician_hp_switch, - magician_get_hp, magician_set_hp), - SOC_SINGLE_BOOL_EXT("Speaker Switch", - (unsigned long)&magician_spk_switch, - magician_get_spk, magician_set_spk), - SOC_ENUM_EXT("Input Select", magician_in_sel_enum, - magician_get_input, magician_set_input), -}; - -/* magician digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(playback, - DAILINK_COMP_ARRAY(COMP_CPU("pxa-ssp-dai.0")), - DAILINK_COMP_ARRAY(COMP_CODEC("uda1380-codec.0-0018", - "uda1380-hifi-playback")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(capture, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("uda1380-codec.0-0018", - "uda1380-hifi-capture")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link magician_dai[] = { -{ - .name = "uda1380", - .stream_name = "UDA1380 Playback", - .ops = &magician_playback_ops, - SND_SOC_DAILINK_REG(playback), -}, -{ - .name = "uda1380", - .stream_name = "UDA1380 Capture", - .ops = &magician_capture_ops, - SND_SOC_DAILINK_REG(capture), -} -}; - -/* magician audio machine driver */ -static struct snd_soc_card snd_soc_card_magician = { - .name = "Magician", - .owner = THIS_MODULE, - .dai_link = magician_dai, - .num_links = ARRAY_SIZE(magician_dai), - - .controls = uda1380_magician_controls, - .num_controls = ARRAY_SIZE(uda1380_magician_controls), - .dapm_widgets = uda1380_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, -}; - -static int magician_audio_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - gpiod_spk_power = devm_gpiod_get(dev, "SPK_POWER", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_spk_power)) - return PTR_ERR(gpiod_spk_power); - gpiod_ep_power = devm_gpiod_get(dev, "EP_POWER", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_ep_power)) - return PTR_ERR(gpiod_ep_power); - gpiod_mic_power = devm_gpiod_get(dev, "MIC_POWER", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_mic_power)) - return PTR_ERR(gpiod_mic_power); - gpiod_in_sel0 = devm_gpiod_get(dev, "IN_SEL0", GPIOD_OUT_HIGH); - if (IS_ERR(gpiod_in_sel0)) - return PTR_ERR(gpiod_in_sel0); - gpiod_in_sel1 = devm_gpiod_get(dev, "IN_SEL1", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_in_sel1)) - return PTR_ERR(gpiod_in_sel1); - - snd_soc_card_magician.dev = &pdev->dev; - return devm_snd_soc_register_card(&pdev->dev, &snd_soc_card_magician); -} - -static struct platform_driver magician_audio_driver = { - .driver.name = "magician-audio", - .driver.pm = &snd_soc_pm_ops, - .probe = magician_audio_probe, -}; -module_platform_driver(magician_audio_driver); - -MODULE_AUTHOR("Philipp Zabel"); -MODULE_DESCRIPTION("ALSA SoC Magician"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:magician-audio"); diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c deleted file mode 100644 index 0fa37637eca9..000000000000 --- a/sound/soc/pxa/mioa701_wm9713.c +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Handles the Mitac mioa701 SoC system - * - * Copyright (C) 2008 Robert Jarzmik - * - * This is a little schema of the sound interconnections : - * - * Sagem X200 Wolfson WM9713 - * +--------+ +-------------------+ Rear Speaker - * | | | | /-+ - * | +--->----->---+MONOIN SPKL+--->----+-+ | - * | GSM | | | | | | - * | +--->----->---+PCBEEP SPKR+--->----+-+ | - * | CHIP | | | \-+ - * | +---<-----<---+MONO | - * | | | | Front Speaker - * +--------+ | | /-+ - * | HPL+--->----+-+ | - * | | | | | - * | OUT3+--->----+-+ | - * | | \-+ - * | | - * | | Front Micro - * | | + - * | MIC1+-----<--+o+ - * | | + - * +-------------------+ --- - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/platform_device.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/initval.h> -#include <sound/ac97_codec.h> - -#include "../codecs/wm9713.h" - -#define AC97_GPIO_PULL 0x58 - -/* Use GPIO8 for rear speaker amplifier */ -static int rear_amp_power(struct snd_soc_component *component, int power) -{ - unsigned short reg; - - if (power) { - reg = snd_soc_component_read(component, AC97_GPIO_CFG); - snd_soc_component_write(component, AC97_GPIO_CFG, reg | 0x0100); - reg = snd_soc_component_read(component, AC97_GPIO_PULL); - snd_soc_component_write(component, AC97_GPIO_PULL, reg | (1<<15)); - } else { - reg = snd_soc_component_read(component, AC97_GPIO_CFG); - snd_soc_component_write(component, AC97_GPIO_CFG, reg & ~0x0100); - reg = snd_soc_component_read(component, AC97_GPIO_PULL); - snd_soc_component_write(component, AC97_GPIO_PULL, reg & ~(1<<15)); - } - - return 0; -} - -static int rear_amp_event(struct snd_soc_dapm_widget *widget, - struct snd_kcontrol *kctl, int event) -{ - struct snd_soc_card *card = widget->dapm->card; - struct snd_soc_pcm_runtime *rtd; - struct snd_soc_component *component; - - rtd = snd_soc_get_pcm_runtime(card, &card->dai_link[0]); - component = asoc_rtd_to_codec(rtd, 0)->component; - return rear_amp_power(component, SND_SOC_DAPM_EVENT_ON(event)); -} - -/* mioa701 machine dapm widgets */ -static const struct snd_soc_dapm_widget mioa701_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Front Speaker", NULL), - SND_SOC_DAPM_SPK("Rear Speaker", rear_amp_event), - SND_SOC_DAPM_MIC("Headset", NULL), - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Front Mic", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* Call Mic */ - {"Mic Bias", NULL, "Front Mic"}, - {"MIC1", NULL, "Mic Bias"}, - - /* Headset Mic */ - {"LINEL", NULL, "Headset Mic"}, - {"LINER", NULL, "Headset Mic"}, - - /* GSM Module */ - {"MONOIN", NULL, "GSM Line Out"}, - {"PCBEEP", NULL, "GSM Line Out"}, - {"GSM Line In", NULL, "MONO"}, - - /* headphone connected to HPL, HPR */ - {"Headset", NULL, "HPL"}, - {"Headset", NULL, "HPR"}, - - /* front speaker connected to HPL, OUT3 */ - {"Front Speaker", NULL, "HPL"}, - {"Front Speaker", NULL, "OUT3"}, - - /* rear speaker connected to SPKL, SPKR */ - {"Rear Speaker", NULL, "SPKL"}, - {"Rear Speaker", NULL, "SPKR"}, -}; - -static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - - /* Prepare GPIO8 for rear speaker amplifier */ - snd_soc_component_update_bits(component, AC97_GPIO_CFG, 0x100, 0x100); - - /* Prepare MIC input */ - snd_soc_component_update_bits(component, AC97_3D_CONTROL, 0xc000, 0xc000); - - return 0; -} - -static struct snd_soc_ops mioa701_ops; - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link mioa701_dai[] = { - { - .name = "AC97", - .stream_name = "AC97 HiFi", - .init = mioa701_wm9713_init, - .ops = &mioa701_ops, - SND_SOC_DAILINK_REG(ac97), - }, - { - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .ops = &mioa701_ops, - SND_SOC_DAILINK_REG(ac97_aux), - }, -}; - -static struct snd_soc_card mioa701 = { - .name = "MioA701", - .owner = THIS_MODULE, - .dai_link = mioa701_dai, - .num_links = ARRAY_SIZE(mioa701_dai), - - .dapm_widgets = mioa701_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(mioa701_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static int mioa701_wm9713_probe(struct platform_device *pdev) -{ - int rc; - - if (!machine_is_mioa701()) - return -ENODEV; - - mioa701.dev = &pdev->dev; - rc = devm_snd_soc_register_card(&pdev->dev, &mioa701); - if (!rc) - dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will " - "lead to overheating and possible destruction of your device." - " Do not use without a good knowledge of mio's board design!\n"); - return rc; -} - -static struct platform_driver mioa701_wm9713_driver = { - .probe = mioa701_wm9713_probe, - .driver = { - .name = "mioa701-wm9713", - .pm = &snd_soc_pm_ops, - }, -}; - -module_platform_driver(mioa701_wm9713_driver); - -/* Module information */ -MODULE_AUTHOR("Robert Jarzmik (rjarzmik@free.fr)"); -MODULE_DESCRIPTION("ALSA SoC WM9713 MIO A701"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mioa701-wm9713"); diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c deleted file mode 100644 index 99b245e3079a..000000000000 --- a/sound/soc/pxa/mmp-pcm.c +++ /dev/null @@ -1,267 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * linux/sound/soc/pxa/mmp-pcm.c - * - * Copyright (C) 2011 Marvell International Ltd. - */ -#include <linux/module.h> -#include <linux/init.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <linux/dma-mapping.h> -#include <linux/dmaengine.h> -#include <linux/platform_data/dma-mmp_tdma.h> -#include <linux/platform_data/mmp_audio.h> - -#include <sound/pxa2xx-lib.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> -#include <sound/dmaengine_pcm.h> - -#define DRV_NAME "mmp-pcm" - -struct mmp_dma_data { - int ssp_id; - struct resource *dma_res; -}; - -#define MMP_PCM_INFO (SNDRV_PCM_INFO_MMAP | \ - SNDRV_PCM_INFO_MMAP_VALID | \ - SNDRV_PCM_INFO_INTERLEAVED | \ - SNDRV_PCM_INFO_PAUSE | \ - SNDRV_PCM_INFO_RESUME | \ - SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) - -static struct snd_pcm_hardware mmp_pcm_hardware[] = { - { - .info = MMP_PCM_INFO, - .period_bytes_min = 1024, - .period_bytes_max = 2048, - .periods_min = 2, - .periods_max = 32, - .buffer_bytes_max = 4096, - .fifo_size = 32, - }, - { - .info = MMP_PCM_INFO, - .period_bytes_min = 1024, - .period_bytes_max = 2048, - .periods_min = 2, - .periods_max = 32, - .buffer_bytes_max = 4096, - .fifo_size = 32, - }, -}; - -static int mmp_pcm_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream); - struct dma_slave_config slave_config; - int ret; - - ret = - snd_dmaengine_pcm_prepare_slave_config(substream, params, - &slave_config); - if (ret) - return ret; - - ret = dmaengine_slave_config(chan, &slave_config); - if (ret) - return ret; - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - - return 0; -} - -static int mmp_pcm_trigger(struct snd_soc_component *component, - struct snd_pcm_substream *substream, int cmd) -{ - return snd_dmaengine_pcm_trigger(substream, cmd); -} - -static snd_pcm_uframes_t mmp_pcm_pointer(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - return snd_dmaengine_pcm_pointer(substream); -} - -static bool filter(struct dma_chan *chan, void *param) -{ - struct mmp_dma_data *dma_data = param; - bool found = false; - char *devname; - - devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name, - dma_data->ssp_id); - if (devname && (strcmp(dev_name(chan->device->dev), devname) == 0) && - (chan->chan_id == dma_data->dma_res->start)) { - found = true; - } - - kfree(devname); - return found; -} - -static int mmp_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct platform_device *pdev = to_platform_device(component->dev); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct mmp_dma_data dma_data; - struct resource *r; - - r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream); - if (!r) - return -EBUSY; - - snd_soc_set_runtime_hwparams(substream, - &mmp_pcm_hardware[substream->stream]); - - dma_data.dma_res = r; - dma_data.ssp_id = cpu_dai->id; - - return snd_dmaengine_pcm_open_request_chan(substream, filter, - &dma_data); -} - -static int mmp_pcm_close(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - return snd_dmaengine_pcm_close_release_chan(substream); -} - -static int mmp_pcm_mmap(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - unsigned long off = vma->vm_pgoff; - - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - return remap_pfn_range(vma, vma->vm_start, - __phys_to_pfn(runtime->dma_addr) + off, - vma->vm_end - vma->vm_start, vma->vm_page_prot); -} - -static void mmp_pcm_free_dma_buffers(struct snd_soc_component *component, - struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - struct gen_pool *gpool; - - gpool = sram_get_gpool("asram"); - if (!gpool) - return; - - for (stream = 0; stream < 2; stream++) { - size_t size = mmp_pcm_hardware[stream].buffer_bytes_max; - - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - gen_pool_free(gpool, (unsigned long)buf->area, size); - buf->area = NULL; - } - -} - -static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream, - int stream) -{ - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = mmp_pcm_hardware[stream].buffer_bytes_max; - struct gen_pool *gpool; - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = substream->pcm->card->dev; - buf->private_data = NULL; - - gpool = sram_get_gpool("asram"); - if (!gpool) - return -ENOMEM; - - buf->area = gen_pool_dma_alloc(gpool, size, &buf->addr); - if (!buf->area) - return -ENOMEM; - buf->bytes = size; - return 0; -} - -static int mmp_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - struct snd_pcm_substream *substream; - struct snd_pcm *pcm = rtd->pcm; - int ret, stream; - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - - ret = mmp_pcm_preallocate_dma_buffer(substream, stream); - if (ret) - goto err; - } - - return 0; - -err: - mmp_pcm_free_dma_buffers(component, pcm); - return ret; -} - -static const struct snd_soc_component_driver mmp_soc_component = { - .name = DRV_NAME, - .open = mmp_pcm_open, - .close = mmp_pcm_close, - .hw_params = mmp_pcm_hw_params, - .trigger = mmp_pcm_trigger, - .pointer = mmp_pcm_pointer, - .mmap = mmp_pcm_mmap, - .pcm_construct = mmp_pcm_new, - .pcm_destruct = mmp_pcm_free_dma_buffers, -}; - -static int mmp_pcm_probe(struct platform_device *pdev) -{ - struct mmp_audio_platdata *pdata = pdev->dev.platform_data; - - if (pdata) { - mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].buffer_bytes_max = - pdata->buffer_max_playback; - mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].period_bytes_max = - pdata->period_max_playback; - mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].buffer_bytes_max = - pdata->buffer_max_capture; - mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max = - pdata->period_max_capture; - } - return devm_snd_soc_register_component(&pdev->dev, &mmp_soc_component, - NULL, 0); -} - -static struct platform_driver mmp_pcm_driver = { - .driver = { - .name = "mmp-pcm-audio", - }, - - .probe = mmp_pcm_probe, -}; - -module_platform_driver(mmp_pcm_driver); - -MODULE_AUTHOR("Leo Yan <leoy@marvell.com>"); -MODULE_DESCRIPTION("MMP Soc Audio DMA module"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:mmp-pcm-audio"); diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c deleted file mode 100644 index a2321c01c160..000000000000 --- a/sound/soc/pxa/palm27x.c +++ /dev/null @@ -1,162 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/sound/soc/pxa/palm27x.c - * - * SoC Audio driver for Palm T|X, T5 and LifeDrive - * - * based on tosa.c - * - * Copyright (C) 2008 Marek Vasut <marek.vasut@gmail.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> -#include <linux/gpio.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/jack.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> -#include <linux/platform_data/asoc-palm27x.h> - -static struct snd_soc_jack hs_jack; - -/* Headphones jack detection DAPM pins */ -static struct snd_soc_jack_pin hs_jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, -}; - -/* Headphones jack detection gpios */ -static struct snd_soc_jack_gpio hs_jack_gpios[] = { - [0] = { - /* gpio is set on per-platform basis */ - .name = "hp-gpio", - .report = SND_JACK_HEADPHONE, - .debounce_time = 200, - }, -}; - -/* Palm27x machine dapm widgets */ -static const struct snd_soc_dapm_widget palm27x_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Ext. Speaker", NULL), - SND_SOC_DAPM_MIC("Ext. Microphone", NULL), -}; - -/* PalmTX audio map */ -static const struct snd_soc_dapm_route audio_map[] = { - /* headphone connected to HPOUTL, HPOUTR */ - {"Headphone Jack", NULL, "HPOUTL"}, - {"Headphone Jack", NULL, "HPOUTR"}, - - /* ext speaker connected to ROUT2, LOUT2 */ - {"Ext. Speaker", NULL, "LOUT2"}, - {"Ext. Speaker", NULL, "ROUT2"}, - - /* mic connected to MIC1 */ - {"MIC1", NULL, "Ext. Microphone"}, -}; - -static struct snd_soc_card palm27x_asoc; - -static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) -{ - int err; - - /* Jack detection API stuff */ - err = snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack", - SND_JACK_HEADPHONE, &hs_jack, - hs_jack_pins, - ARRAY_SIZE(hs_jack_pins)); - if (err) - return err; - - err = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - - return err; -} - -SND_SOC_DAILINK_DEFS(hifi, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link palm27x_dai[] = { -{ - .name = "AC97 HiFi", - .stream_name = "AC97 HiFi", - .init = palm27x_ac97_init, - SND_SOC_DAILINK_REG(hifi), -}, -{ - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - SND_SOC_DAILINK_REG(aux), -}, -}; - -static struct snd_soc_card palm27x_asoc = { - .name = "Palm/PXA27x", - .owner = THIS_MODULE, - .dai_link = palm27x_dai, - .num_links = ARRAY_SIZE(palm27x_dai), - .dapm_widgets = palm27x_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(palm27x_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, -}; - -static int palm27x_asoc_probe(struct platform_device *pdev) -{ - int ret; - - if (!(machine_is_palmtx() || machine_is_palmt5() || - machine_is_palmld() || machine_is_palmte2())) - return -ENODEV; - - if (!pdev->dev.platform_data) { - dev_err(&pdev->dev, "please supply platform_data\n"); - return -ENODEV; - } - - hs_jack_gpios[0].gpio = ((struct palm27x_asoc_info *) - (pdev->dev.platform_data))->jack_gpio; - - palm27x_asoc.dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, &palm27x_asoc); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static struct platform_driver palm27x_wm9712_driver = { - .probe = palm27x_asoc_probe, - .driver = { - .name = "palm27x-asoc", - .pm = &snd_soc_pm_ops, - }, -}; - -module_platform_driver(palm27x_wm9712_driver); - -/* Module information */ -MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); -MODULE_DESCRIPTION("ALSA SoC Palm T|X, T5 and LifeDrive"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:palm27x-asoc"); diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c deleted file mode 100644 index 5fdaa477e85d..000000000000 --- a/sound/soc/pxa/poodle.c +++ /dev/null @@ -1,291 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * poodle.c -- SoC audio for Poodle - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood <lrg@slimlogic.co.uk> - * Richard Purdie <richard@openedhand.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/timer.h> -#include <linux/i2c.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include <asm/hardware/locomo.h> -#include <linux/platform_data/asoc-pxa.h> -#include <linux/platform_data/asoc-poodle.h> - -#include "../codecs/wm8731.h" -#include "pxa2xx-i2s.h" - -#define POODLE_HP 1 -#define POODLE_HP_OFF 0 -#define POODLE_SPK_ON 1 -#define POODLE_SPK_OFF 0 - - /* audio clock in Hz - rounded from 12.235MHz */ -#define POODLE_AUDIO_CLOCK 12288000 - -static int poodle_jack_func; -static int poodle_spk_func; - -static struct poodle_audio_platform_data *poodle_pdata; - -static void poodle_ext_control(struct snd_soc_dapm_context *dapm) -{ - /* set up jack connection */ - if (poodle_jack_func == POODLE_HP) { - /* set = unmute headphone */ - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_l, 1); - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_r, 1); - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - } else { - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_l, 0); - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_r, 0); - snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); - } - - /* set the endpoints to their new connection states */ - if (poodle_spk_func == POODLE_SPK_ON) - snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - else - snd_soc_dapm_disable_pin(dapm, "Ext Spk"); - - /* signal a DAPM event */ - snd_soc_dapm_sync(dapm); -} - -static int poodle_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - - /* check the jack status at stream startup */ - poodle_ext_control(&rtd->card->dapm); - - return 0; -} - -/* we need to unmute the HP at shutdown as the mute burns power on poodle */ -static void poodle_shutdown(struct snd_pcm_substream *substream) -{ - /* set = unmute headphone */ - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_l, 1); - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_r, 1); -} - -static int poodle_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8731_SYSCLK_XTAL, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops poodle_ops = { - .startup = poodle_startup, - .hw_params = poodle_hw_params, - .shutdown = poodle_shutdown, -}; - -static int poodle_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = poodle_jack_func; - return 0; -} - -static int poodle_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (poodle_jack_func == ucontrol->value.enumerated.item[0]) - return 0; - - poodle_jack_func = ucontrol->value.enumerated.item[0]; - poodle_ext_control(&card->dapm); - return 1; -} - -static int poodle_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = poodle_spk_func; - return 0; -} - -static int poodle_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (poodle_spk_func == ucontrol->value.enumerated.item[0]) - return 0; - - poodle_spk_func = ucontrol->value.enumerated.item[0]; - poodle_ext_control(&card->dapm); - return 1; -} - -static int poodle_amp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_amp_on, 0); - else - locomo_gpio_write(poodle_pdata->locomo_dev, - poodle_pdata->gpio_amp_on, 1); - - return 0; -} - -/* poodle machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { -SND_SOC_DAPM_HP("Headphone Jack", NULL), -SND_SOC_DAPM_SPK("Ext Spk", poodle_amp_event), -SND_SOC_DAPM_MIC("Microphone", NULL), -}; - -/* Corgi machine connections to the codec pins */ -static const struct snd_soc_dapm_route poodle_audio_map[] = { - - /* headphone connected to LHPOUT1, RHPOUT1 */ - {"Headphone Jack", NULL, "LHPOUT"}, - {"Headphone Jack", NULL, "RHPOUT"}, - - /* speaker connected to LOUT, ROUT */ - {"Ext Spk", NULL, "ROUT"}, - {"Ext Spk", NULL, "LOUT"}, - - {"MICIN", NULL, "Microphone"}, -}; - -static const char * const jack_function[] = {"Off", "Headphone"}; -static const char * const spk_function[] = {"Off", "On"}; -static const struct soc_enum poodle_enum[] = { - SOC_ENUM_SINGLE_EXT(2, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const struct snd_kcontrol_new wm8731_poodle_controls[] = { - SOC_ENUM_EXT("Jack Function", poodle_enum[0], poodle_get_jack, - poodle_set_jack), - SOC_ENUM_EXT("Speaker Function", poodle_enum[1], poodle_get_spk, - poodle_set_spk), -}; - -/* poodle digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(wm8731, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8731.0-001b", "wm8731-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link poodle_dai = { - .name = "WM8731", - .stream_name = "WM8731", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &poodle_ops, - SND_SOC_DAILINK_REG(wm8731), -}; - -/* poodle audio machine driver */ -static struct snd_soc_card poodle = { - .name = "Poodle", - .dai_link = &poodle_dai, - .num_links = 1, - .owner = THIS_MODULE, - - .controls = wm8731_poodle_controls, - .num_controls = ARRAY_SIZE(wm8731_poodle_controls), - .dapm_widgets = wm8731_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), - .dapm_routes = poodle_audio_map, - .num_dapm_routes = ARRAY_SIZE(poodle_audio_map), - .fully_routed = true, -}; - -static int poodle_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &poodle; - int ret; - - poodle_pdata = pdev->dev.platform_data; - locomo_gpio_set_dir(poodle_pdata->locomo_dev, - poodle_pdata->gpio_amp_on, 0); - /* should we mute HP at startup - burning power ?*/ - locomo_gpio_set_dir(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_l, 0); - locomo_gpio_set_dir(poodle_pdata->locomo_dev, - poodle_pdata->gpio_mute_r, 0); - - card->dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - return ret; -} - -static struct platform_driver poodle_driver = { - .driver = { - .name = "poodle-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = poodle_probe, -}; - -module_platform_driver(poodle_driver); - -/* Module information */ -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Poodle"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:poodle-audio"); diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c deleted file mode 100644 index 30f83cab0c32..000000000000 --- a/sound/soc/pxa/tosa.c +++ /dev/null @@ -1,255 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * tosa.c -- SoC audio for Tosa - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * Authors: Liam Girdwood <lrg@slimlogic.co.uk> - * Richard Purdie <richard@openedhand.com> - * - * GPIO's - * 1 - Jack Insertion - * 5 - Hookswitch (headset answer/hang up switch) - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> -#include <linux/gpio/consumer.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> - -#define TOSA_HP 0 -#define TOSA_MIC_INT 1 -#define TOSA_HEADSET 2 -#define TOSA_HP_OFF 3 -#define TOSA_SPK_ON 0 -#define TOSA_SPK_OFF 1 - -static struct gpio_desc *tosa_mute; -static int tosa_jack_func; -static int tosa_spk_func; - -static void tosa_ext_control(struct snd_soc_dapm_context *dapm) -{ - - snd_soc_dapm_mutex_lock(dapm); - - /* set up jack connection */ - switch (tosa_jack_func) { - case TOSA_HP: - snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); - break; - case TOSA_MIC_INT: - snd_soc_dapm_enable_pin_unlocked(dapm, "Mic (Internal)"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headset Jack"); - break; - case TOSA_HEADSET: - snd_soc_dapm_disable_pin_unlocked(dapm, "Mic (Internal)"); - snd_soc_dapm_disable_pin_unlocked(dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin_unlocked(dapm, "Headset Jack"); - break; - } - - if (tosa_spk_func == TOSA_SPK_ON) - snd_soc_dapm_enable_pin_unlocked(dapm, "Speaker"); - else - snd_soc_dapm_disable_pin_unlocked(dapm, "Speaker"); - - snd_soc_dapm_sync_unlocked(dapm); - - snd_soc_dapm_mutex_unlock(dapm); -} - -static int tosa_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - - /* check the jack status at stream startup */ - tosa_ext_control(&rtd->card->dapm); - - return 0; -} - -static const struct snd_soc_ops tosa_ops = { - .startup = tosa_startup, -}; - -static int tosa_get_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = tosa_jack_func; - return 0; -} - -static int tosa_set_jack(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (tosa_jack_func == ucontrol->value.enumerated.item[0]) - return 0; - - tosa_jack_func = ucontrol->value.enumerated.item[0]; - tosa_ext_control(&card->dapm); - return 1; -} - -static int tosa_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = tosa_spk_func; - return 0; -} - -static int tosa_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_card *card = snd_kcontrol_chip(kcontrol); - - if (tosa_spk_func == ucontrol->value.enumerated.item[0]) - return 0; - - tosa_spk_func = ucontrol->value.enumerated.item[0]; - tosa_ext_control(&card->dapm); - return 1; -} - -/* tosa dapm event handlers */ -static int tosa_hp_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(tosa_mute, SND_SOC_DAPM_EVENT_ON(event) ? 1 : 0); - return 0; -} - -/* tosa machine dapm widgets */ -static const struct snd_soc_dapm_widget tosa_dapm_widgets[] = { -SND_SOC_DAPM_HP("Headphone Jack", tosa_hp_event), -SND_SOC_DAPM_HP("Headset Jack", NULL), -SND_SOC_DAPM_MIC("Mic (Internal)", NULL), -SND_SOC_DAPM_SPK("Speaker", NULL), -}; - -/* tosa audio map */ -static const struct snd_soc_dapm_route audio_map[] = { - - /* headphone connected to HPOUTL, HPOUTR */ - {"Headphone Jack", NULL, "HPOUTL"}, - {"Headphone Jack", NULL, "HPOUTR"}, - - /* ext speaker connected to LOUT2, ROUT2 */ - {"Speaker", NULL, "LOUT2"}, - {"Speaker", NULL, "ROUT2"}, - - /* internal mic is connected to mic1, mic2 differential - with bias */ - {"MIC1", NULL, "Mic Bias"}, - {"MIC2", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Mic (Internal)"}, - - /* headset is connected to HPOUTR, and LINEINR with bias */ - {"Headset Jack", NULL, "HPOUTR"}, - {"LINEINR", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Jack"}, -}; - -static const char * const jack_function[] = {"Headphone", "Mic", "Line", - "Headset", "Off"}; -static const char * const spk_function[] = {"On", "Off"}; -static const struct soc_enum tosa_enum[] = { - SOC_ENUM_SINGLE_EXT(5, jack_function), - SOC_ENUM_SINGLE_EXT(2, spk_function), -}; - -static const struct snd_kcontrol_new tosa_controls[] = { - SOC_ENUM_EXT("Jack Function", tosa_enum[0], tosa_get_jack, - tosa_set_jack), - SOC_ENUM_EXT("Speaker Function", tosa_enum[1], tosa_get_spk, - tosa_set_spk), -}; - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link tosa_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .ops = &tosa_ops, - SND_SOC_DAILINK_REG(ac97), -}, -{ - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - .ops = &tosa_ops, - SND_SOC_DAILINK_REG(ac97_aux), -}, -}; - -static struct snd_soc_card tosa = { - .name = "Tosa", - .owner = THIS_MODULE, - .dai_link = tosa_dai, - .num_links = ARRAY_SIZE(tosa_dai), - - .controls = tosa_controls, - .num_controls = ARRAY_SIZE(tosa_controls), - .dapm_widgets = tosa_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(tosa_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, -}; - -static int tosa_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = ⤩ - int ret; - - tosa_mute = devm_gpiod_get(&pdev->dev, NULL, GPIOD_OUT_LOW); - if (IS_ERR(tosa_mute)) - return dev_err_probe(&pdev->dev, PTR_ERR(tosa_mute), - "failed to get L_MUTE GPIO\n"); - gpiod_set_consumer_name(tosa_mute, "Headphone Jack"); - - card->dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) { - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - } - return ret; -} - -static struct platform_driver tosa_driver = { - .driver = { - .name = "tosa-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = tosa_probe, -}; - -module_platform_driver(tosa_driver); - -/* Module information */ -MODULE_AUTHOR("Richard Purdie"); -MODULE_DESCRIPTION("ALSA SoC Tosa"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:tosa-audio"); diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c deleted file mode 100644 index 6cc970bb2aac..000000000000 --- a/sound/soc/pxa/ttc-dkb.c +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * linux/sound/soc/pxa/ttc_dkb.c - * - * Copyright (C) 2012 Marvell International Ltd. - */ -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/jack.h> -#include <asm/mach-types.h> -#include <sound/pcm_params.h> -#include "../codecs/88pm860x-codec.h" - -static struct snd_soc_jack hs_jack, mic_jack; - -static struct snd_soc_jack_pin hs_jack_pins[] = { - { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, }, -}; - -static struct snd_soc_jack_pin mic_jack_pins[] = { - { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, }, -}; - -/* ttc machine dapm widgets */ -static const struct snd_soc_dapm_widget ttc_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_LINE("Lineout Out 1", NULL), - SND_SOC_DAPM_LINE("Lineout Out 2", NULL), - SND_SOC_DAPM_SPK("Ext Speaker", NULL), - SND_SOC_DAPM_MIC("Ext Mic 1", NULL), - SND_SOC_DAPM_MIC("Headset Mic 2", NULL), - SND_SOC_DAPM_MIC("Ext Mic 3", NULL), -}; - -/* ttc machine audio map */ -static const struct snd_soc_dapm_route ttc_audio_map[] = { - {"Headset Stereophone", NULL, "HS1"}, - {"Headset Stereophone", NULL, "HS2"}, - - {"Ext Speaker", NULL, "LSP"}, - {"Ext Speaker", NULL, "LSN"}, - - {"Lineout Out 1", NULL, "LINEOUT1"}, - {"Lineout Out 2", NULL, "LINEOUT2"}, - - {"MIC1P", NULL, "Mic1 Bias"}, - {"MIC1N", NULL, "Mic1 Bias"}, - {"Mic1 Bias", NULL, "Ext Mic 1"}, - - {"MIC2P", NULL, "Mic1 Bias"}, - {"MIC2N", NULL, "Mic1 Bias"}, - {"Mic1 Bias", NULL, "Headset Mic 2"}, - - {"MIC3P", NULL, "Mic3 Bias"}, - {"MIC3N", NULL, "Mic3 Bias"}, - {"Mic3 Bias", NULL, "Ext Mic 3"}, -}; - -static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component; - - /* Headset jack detection */ - snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack", - SND_JACK_HEADPHONE | SND_JACK_BTN_0 | - SND_JACK_BTN_1 | SND_JACK_BTN_2, - &hs_jack, - hs_jack_pins, ARRAY_SIZE(hs_jack_pins)); - snd_soc_card_jack_new_pins(rtd->card, "Microphone Jack", - SND_JACK_MICROPHONE, &mic_jack, - mic_jack_pins, ARRAY_SIZE(mic_jack_pins)); - - /* headphone, microphone detection & headset short detection */ - pm860x_hs_jack_detect(component, &hs_jack, SND_JACK_HEADPHONE, - SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2); - pm860x_mic_jack_detect(component, &hs_jack, SND_JACK_MICROPHONE); - - return 0; -} - -/* ttc/td-dkb digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(i2s, - DAILINK_COMP_ARRAY(COMP_CPU("pxa-ssp-dai.1")), - DAILINK_COMP_ARRAY(COMP_CODEC("88pm860x-codec", "88pm860x-i2s")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("mmp-pcm-audio"))); - -static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = { -{ - .name = "88pm860x i2s", - .stream_name = "audio playback", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, - .init = ttc_pm860x_init, - SND_SOC_DAILINK_REG(i2s), -}, -}; - -/* ttc/td audio machine driver */ -static struct snd_soc_card ttc_dkb_card = { - .name = "ttc-dkb-hifi", - .owner = THIS_MODULE, - .dai_link = ttc_pm860x_hifi_dai, - .num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai), - - .dapm_widgets = ttc_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(ttc_dapm_widgets), - .dapm_routes = ttc_audio_map, - .num_dapm_routes = ARRAY_SIZE(ttc_audio_map), -}; - -static int ttc_dkb_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &ttc_dkb_card; - int ret; - - card->dev = &pdev->dev; - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n", - ret); - - return ret; -} - -static struct platform_driver ttc_dkb_driver = { - .driver = { - .name = "ttc-dkb-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = ttc_dkb_probe, -}; - -module_platform_driver(ttc_dkb_driver); - -/* Module information */ -MODULE_AUTHOR("Qiao Zhou, <zhouqiao@marvell.com>"); -MODULE_DESCRIPTION("ALSA SoC TTC DKB"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:ttc-dkb-audio"); diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c deleted file mode 100644 index 020dcce1df1f..000000000000 --- a/sound/soc/pxa/z2.c +++ /dev/null @@ -1,218 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * linux/sound/soc/pxa/z2.c - * - * SoC Audio driver for Aeronix Zipit Z2 - * - * Copyright (C) 2009 Ken McGuire <kenm@desertweyr.com> - * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/timer.h> -#include <linux/interrupt.h> -#include <linux/platform_device.h> -#include <linux/gpio/consumer.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/soc.h> -#include <sound/jack.h> - -#include <asm/mach-types.h> -#include <linux/platform_data/asoc-pxa.h> - -#include "../codecs/wm8750.h" -#include "pxa2xx-i2s.h" - -static struct snd_soc_card snd_soc_z2; - -static int z2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the I2S system clock as input (unused) */ - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA2XX_I2S_SYSCLK, 0, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_jack hs_jack; - -/* Headset jack detection DAPM pins */ -static struct snd_soc_jack_pin hs_jack_pins[] = { - { - .pin = "Mic Jack", - .mask = SND_JACK_MICROPHONE, - }, - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Ext Spk", - .mask = SND_JACK_HEADPHONE, - .invert = 1 - }, -}; - -/* Headset jack detection gpios */ -static struct snd_soc_jack_gpio hs_jack_gpios[] = { - { - .name = "hsdet-gpio", - .report = SND_JACK_HEADSET, - .debounce_time = 200, - .invert = 1, - }, -}; - -/* z2 machine dapm widgets */ -static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_SPK("Ext Spk", NULL), - - /* headset is a mic and mono headphone */ - SND_SOC_DAPM_HP("Headset Jack", NULL), -}; - -/* Z2 machine audio_map */ -static const struct snd_soc_dapm_route z2_audio_map[] = { - - /* headphone connected to LOUT1, ROUT1 */ - {"Headphone Jack", NULL, "LOUT1"}, - {"Headphone Jack", NULL, "ROUT1"}, - - /* ext speaker connected to LOUT2, ROUT2 */ - {"Ext Spk", NULL, "ROUT2"}, - {"Ext Spk", NULL, "LOUT2"}, - - /* mic is connected to R input 2 - with bias */ - {"RINPUT2", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Mic Jack"}, -}; - -/* - * Logic for a wm8750 as connected on a Z2 Device - */ -static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) -{ - int ret; - - /* Jack detection API stuff */ - ret = snd_soc_card_jack_new_pins(rtd->card, "Headset Jack", - SND_JACK_HEADSET, &hs_jack, - hs_jack_pins, - ARRAY_SIZE(hs_jack_pins)); - if (ret) - goto err; - - ret = snd_soc_jack_add_gpios(&hs_jack, ARRAY_SIZE(hs_jack_gpios), - hs_jack_gpios); - if (ret) - goto err; - - return 0; - -err: - return ret; -} - -static const struct snd_soc_ops z2_ops = { - .hw_params = z2_hw_params, -}; - -/* z2 digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(wm8750, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8750.0-001b", "wm8750-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link z2_dai = { - .name = "wm8750", - .stream_name = "WM8750", - .init = z2_wm8750_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &z2_ops, - SND_SOC_DAILINK_REG(wm8750), -}; - -/* z2 audio machine driver */ -static struct snd_soc_card snd_soc_z2 = { - .name = "Z2", - .owner = THIS_MODULE, - .dai_link = &z2_dai, - .num_links = 1, - - .dapm_widgets = wm8750_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), - .dapm_routes = z2_audio_map, - .num_dapm_routes = ARRAY_SIZE(z2_audio_map), - .fully_routed = true, -}; - -static struct platform_device *z2_snd_device; - -static int __init z2_init(void) -{ - int ret; - - if (!machine_is_zipit2()) - return -ENODEV; - - z2_snd_device = platform_device_alloc("soc-audio", -1); - if (!z2_snd_device) - return -ENOMEM; - - hs_jack_gpios[0].gpiod_dev = &z2_snd_device->dev; - platform_set_drvdata(z2_snd_device, &snd_soc_z2); - ret = platform_device_add(z2_snd_device); - - if (ret) - platform_device_put(z2_snd_device); - - return ret; -} - -static void __exit z2_exit(void) -{ - platform_device_unregister(z2_snd_device); -} - -module_init(z2_init); -module_exit(z2_exit); - -MODULE_AUTHOR("Ken McGuire <kenm@desertweyr.com>, " - "Marek Vasut <marek.vasut@gmail.com>"); -MODULE_DESCRIPTION("ALSA SoC ZipitZ2"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c deleted file mode 100644 index bb89a53f4ab1..000000000000 --- a/sound/soc/pxa/zylonite.c +++ /dev/null @@ -1,266 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * zylonite.c -- SoC audio for Zylonite - * - * Copyright 2008 Wolfson Microelectronics PLC. - * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/device.h> -#include <linux/clk.h> -#include <linux/i2c.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/soc.h> - -#include "../codecs/wm9713.h" -#include "pxa-ssp.h" - -/* - * There is a physical switch SW15 on the board which changes the MCLK - * for the WM9713 between the standard AC97 master clock and the - * output of the CLK_POUT signal from the PXA. - */ -static int clk_pout; -module_param(clk_pout, int, 0); -MODULE_PARM_DESC(clk_pout, "Use CLK_POUT as WM9713 MCLK (SW15 on board)."); - -static struct clk *pout; - -static struct snd_soc_card zylonite; - -static const struct snd_soc_dapm_widget zylonite_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Headset Microphone", NULL), - SND_SOC_DAPM_MIC("Handset Microphone", NULL), - SND_SOC_DAPM_SPK("Multiactor", NULL), - SND_SOC_DAPM_SPK("Headset Earpiece", NULL), -}; - -/* Currently supported audio map */ -static const struct snd_soc_dapm_route audio_map[] = { - - /* Headphone output connected to HPL/HPR */ - { "Headphone", NULL, "HPL" }, - { "Headphone", NULL, "HPR" }, - - /* On-board earpiece */ - { "Headset Earpiece", NULL, "OUT3" }, - - /* Headphone mic */ - { "MIC2A", NULL, "Mic Bias" }, - { "Mic Bias", NULL, "Headset Microphone" }, - - /* On-board mic */ - { "MIC1", NULL, "Mic Bias" }, - { "Mic Bias", NULL, "Handset Microphone" }, - - /* Multiactor differentially connected over SPKL/SPKR */ - { "Multiactor", NULL, "SPKL" }, - { "Multiactor", NULL, "SPKR" }, -}; - -static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd) -{ - if (clk_pout) - snd_soc_dai_set_pll(asoc_rtd_to_codec(rtd, 0), 0, 0, - clk_get_rate(pout), 0); - - return 0; -} - -static int zylonite_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int wm9713_div = 0; - int ret = 0; - int rate = params_rate(params); - - /* Only support ratios that we can generate neatly from the AC97 - * based master clock - in particular, this excludes 44.1kHz. - * In most applications the voice DAC will be used for telephony - * data so multiples of 8kHz will be the common case. - */ - switch (rate) { - case 8000: - wm9713_div = 12; - break; - case 16000: - wm9713_div = 6; - break; - case 48000: - wm9713_div = 2; - break; - default: - /* Don't support OSS emulation */ - return -EINVAL; - } - - ret = snd_soc_dai_set_sysclk(cpu_dai, PXA_SSP_CLK_AUDIO, 0, 1); - if (ret < 0) - return ret; - - if (clk_pout) - ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_PLL_DIV, - WM9713_PCMDIV(wm9713_div)); - else - ret = snd_soc_dai_set_clkdiv(codec_dai, WM9713_PCMCLK_DIV, - WM9713_PCMDIV(wm9713_div)); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops zylonite_voice_ops = { - .hw_params = zylonite_voice_hw_params, -}; - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(ac97_aux, - DAILINK_COMP_ARRAY(COMP_CPU("pxa2xx-ac97-aux")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-aux")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -SND_SOC_DAILINK_DEFS(voice, - DAILINK_COMP_ARRAY(COMP_CPU("pxa-ssp-dai.2")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm9713-codec", "wm9713-voice")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("pxa-pcm-audio"))); - -static struct snd_soc_dai_link zylonite_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .init = zylonite_wm9713_init, - SND_SOC_DAILINK_REG(ac97), -}, -{ - .name = "AC97 Aux", - .stream_name = "AC97 Aux", - SND_SOC_DAILINK_REG(ac97_aux), -}, -{ - .name = "WM9713 Voice", - .stream_name = "WM9713 Voice", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &zylonite_voice_ops, - SND_SOC_DAILINK_REG(voice), -}, -}; - -static int zylonite_probe(struct snd_soc_card *card) -{ - int ret; - - if (clk_pout) { - pout = clk_get(NULL, "CLK_POUT"); - if (IS_ERR(pout)) { - dev_err(card->dev, "Unable to obtain CLK_POUT: %ld\n", - PTR_ERR(pout)); - return PTR_ERR(pout); - } - - ret = clk_enable(pout); - if (ret != 0) { - dev_err(card->dev, "Unable to enable CLK_POUT: %d\n", - ret); - clk_put(pout); - return ret; - } - - dev_dbg(card->dev, "MCLK enabled at %luHz\n", - clk_get_rate(pout)); - } - - return 0; -} - -static int zylonite_remove(struct snd_soc_card *card) -{ - if (clk_pout) { - clk_disable(pout); - clk_put(pout); - } - - return 0; -} - -static int zylonite_suspend_post(struct snd_soc_card *card) -{ - if (clk_pout) - clk_disable(pout); - - return 0; -} - -static int zylonite_resume_pre(struct snd_soc_card *card) -{ - int ret = 0; - - if (clk_pout) { - ret = clk_enable(pout); - if (ret != 0) - dev_err(card->dev, "Unable to enable CLK_POUT: %d\n", - ret); - } - - return ret; -} - -static struct snd_soc_card zylonite = { - .name = "Zylonite", - .owner = THIS_MODULE, - .probe = &zylonite_probe, - .remove = &zylonite_remove, - .suspend_post = &zylonite_suspend_post, - .resume_pre = &zylonite_resume_pre, - .dai_link = zylonite_dai, - .num_links = ARRAY_SIZE(zylonite_dai), - - .dapm_widgets = zylonite_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(zylonite_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static struct platform_device *zylonite_snd_ac97_device; - -static int __init zylonite_init(void) -{ - int ret; - - zylonite_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!zylonite_snd_ac97_device) - return -ENOMEM; - - platform_set_drvdata(zylonite_snd_ac97_device, &zylonite); - - ret = platform_device_add(zylonite_snd_ac97_device); - if (ret != 0) - platform_device_put(zylonite_snd_ac97_device); - - return ret; -} - -static void __exit zylonite_exit(void) -{ - platform_device_unregister(zylonite_snd_ac97_device); -} - -module_init(zylonite_init); -module_exit(zylonite_exit); - -MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); -MODULE_DESCRIPTION("ALSA SoC WM9713 Zylonite"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index 96a6d4731e6f..e7b00d1d9e99 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -2,7 +2,6 @@ menuconfig SND_SOC_QCOM tristate "ASoC support for QCOM platforms" depends on ARCH_QCOM || COMPILE_TEST - imply SND_SOC_QCOM_COMMON help Say Y or M if you want to add support to use audio devices in Qualcomm Technologies SOC-based platforms. @@ -60,14 +59,16 @@ config SND_SOC_STORM config SND_SOC_APQ8016_SBC tristate "SoC Audio support for APQ8016 SBC platforms" select SND_SOC_LPASS_APQ8016 - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON help Support for Qualcomm Technologies LPASS audio block in APQ8016 SOC-based systems. Say Y if you want to use audio devices on MI2S. config SND_SOC_QCOM_COMMON - depends on SOUNDWIRE + tristate + +config SND_SOC_QCOM_SDW tristate config SND_SOC_QDSP6_COMMON @@ -144,7 +145,7 @@ config SND_SOC_MSM8996 depends on QCOM_APR depends on COMMON_CLK select SND_SOC_QDSP6 - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON help Support for Qualcomm Technologies LPASS audio block in APQ8096 SoC-based systems. @@ -155,7 +156,7 @@ config SND_SOC_SDM845 depends on QCOM_APR && I2C && SOUNDWIRE depends on COMMON_CLK select SND_SOC_QDSP6 - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON select SND_SOC_RT5663 select SND_SOC_MAX98927 imply SND_SOC_CROS_EC_CODEC @@ -169,7 +170,8 @@ config SND_SOC_SM8250 depends on QCOM_APR && SOUNDWIRE depends on COMMON_CLK select SND_SOC_QDSP6 - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_SDW help To add support for audio on Qualcomm Technologies Inc. SM8250 SoC-based systems. @@ -180,7 +182,8 @@ config SND_SOC_SC8280XP depends on QCOM_APR && SOUNDWIRE depends on COMMON_CLK select SND_SOC_QDSP6 - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_SDW help To add support for audio on Qualcomm Technologies Inc. SC8280XP SoC-based systems. @@ -190,7 +193,7 @@ config SND_SOC_SC7180 tristate "SoC Machine driver for SC7180 boards" depends on I2C && GPIOLIB depends on SOUNDWIRE || SOUNDWIRE=n - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON select SND_SOC_LPASS_SC7180 select SND_SOC_MAX98357A select SND_SOC_RT5682_I2C @@ -204,7 +207,7 @@ config SND_SOC_SC7180 config SND_SOC_SC7280 tristate "SoC Machine driver for SC7280 boards" depends on I2C && SOUNDWIRE - depends on SND_SOC_QCOM_COMMON + select SND_SOC_QCOM_COMMON select SND_SOC_LPASS_SC7280 select SND_SOC_MAX98357A select SND_SOC_WCD938X_SDW diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index 8b97172cf990..254350d9dc06 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile @@ -28,6 +28,7 @@ snd-soc-sdm845-objs := sdm845.o snd-soc-sm8250-objs := sm8250.o snd-soc-sc8280xp-objs := sc8280xp.o snd-soc-qcom-common-objs := common.o +snd-soc-qcom-sdw-objs := sdw.o obj-$(CONFIG_SND_SOC_STORM) += snd-soc-storm.o obj-$(CONFIG_SND_SOC_APQ8016_SBC) += snd-soc-apq8016-sbc.o @@ -38,6 +39,7 @@ obj-$(CONFIG_SND_SOC_SC8280XP) += snd-soc-sc8280xp.o obj-$(CONFIG_SND_SOC_SDM845) += snd-soc-sdm845.o obj-$(CONFIG_SND_SOC_SM8250) += snd-soc-sm8250.o obj-$(CONFIG_SND_SOC_QCOM_COMMON) += snd-soc-qcom-common.o +obj-$(CONFIG_SND_SOC_QCOM_SDW) += snd-soc-qcom-sdw.o #DSP lib obj-$(CONFIG_SND_SOC_QDSP6) += qdsp6/ diff --git a/sound/soc/qcom/common.c b/sound/soc/qcom/common.c index 49c74c1662a3..96fe80241fb4 100644 --- a/sound/soc/qcom/common.c +++ b/sound/soc/qcom/common.c @@ -180,120 +180,6 @@ err_put_np: } EXPORT_SYMBOL_GPL(qcom_snd_parse_of); -int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, - struct sdw_stream_runtime *sruntime, - bool *stream_prepared) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int ret; - - if (!sruntime) - return 0; - - switch (cpu_dai->id) { - case WSA_CODEC_DMA_RX_0: - case WSA_CODEC_DMA_RX_1: - case RX_CODEC_DMA_RX_0: - case RX_CODEC_DMA_RX_1: - case TX_CODEC_DMA_TX_0: - case TX_CODEC_DMA_TX_1: - case TX_CODEC_DMA_TX_2: - case TX_CODEC_DMA_TX_3: - break; - default: - return 0; - } - - if (*stream_prepared) { - sdw_disable_stream(sruntime); - sdw_deprepare_stream(sruntime); - *stream_prepared = false; - } - - ret = sdw_prepare_stream(sruntime); - if (ret) - return ret; - - /** - * NOTE: there is a strict hw requirement about the ordering of port - * enables and actual WSA881x PA enable. PA enable should only happen - * after soundwire ports are enabled if not DC on the line is - * accumulated resulting in Click/Pop Noise - * PA enable/mute are handled as part of codec DAPM and digital mute. - */ - - ret = sdw_enable_stream(sruntime); - if (ret) { - sdw_deprepare_stream(sruntime); - return ret; - } - *stream_prepared = true; - - return ret; -} -EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); - -int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct sdw_stream_runtime **psruntime) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct sdw_stream_runtime *sruntime; - int i; - - switch (cpu_dai->id) { - case WSA_CODEC_DMA_RX_0: - case RX_CODEC_DMA_RX_0: - case RX_CODEC_DMA_RX_1: - case TX_CODEC_DMA_TX_0: - case TX_CODEC_DMA_TX_1: - case TX_CODEC_DMA_TX_2: - case TX_CODEC_DMA_TX_3: - for_each_rtd_codec_dais(rtd, i, codec_dai) { - sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); - if (sruntime != ERR_PTR(-ENOTSUPP)) - *psruntime = sruntime; - } - break; - } - - return 0; - -} -EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params); - -int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, - struct sdw_stream_runtime *sruntime, bool *stream_prepared) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - - switch (cpu_dai->id) { - case WSA_CODEC_DMA_RX_0: - case WSA_CODEC_DMA_RX_1: - case RX_CODEC_DMA_RX_0: - case RX_CODEC_DMA_RX_1: - case TX_CODEC_DMA_TX_0: - case TX_CODEC_DMA_TX_1: - case TX_CODEC_DMA_TX_2: - case TX_CODEC_DMA_TX_3: - if (sruntime && *stream_prepared) { - sdw_disable_stream(sruntime); - sdw_deprepare_stream(sruntime); - *stream_prepared = false; - } - break; - default: - break; - } - - return 0; -} -EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free); - int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd, struct snd_soc_jack *jack, bool *jack_setup) { diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h index 3ef5bb6d12df..d7f80ee5ae26 100644 --- a/sound/soc/qcom/common.h +++ b/sound/soc/qcom/common.h @@ -5,19 +5,9 @@ #define __QCOM_SND_COMMON_H__ #include <sound/soc.h> -#include <linux/soundwire/sdw.h> int qcom_snd_parse_of(struct snd_soc_card *card); int qcom_snd_wcd_jack_setup(struct snd_soc_pcm_runtime *rtd, struct snd_soc_jack *jack, bool *jack_setup); -int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, - struct sdw_stream_runtime *runtime, - bool *stream_prepared); -int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct sdw_stream_runtime **psruntime); -int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, - struct sdw_stream_runtime *sruntime, - bool *stream_prepared); #endif diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 54353842dc07..dbdaaa85ce48 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -1037,10 +1037,11 @@ static void of_lpass_cpu_parse_dai_data(struct device *dev, struct lpass_data *data) { struct device_node *node; - int ret, id; + int ret, i, id; /* Allow all channels by default for backwards compatibility */ - for (id = 0; id < data->variant->num_dai; id++) { + for (i = 0; i < data->variant->num_dai; i++) { + id = data->variant->dai_driver[i].id; data->mi2s_playback_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH; data->mi2s_capture_sd_mode[id] = LPAIF_I2SCTL_MODE_8CH; } diff --git a/sound/soc/qcom/sc8280xp.c b/sound/soc/qcom/sc8280xp.c index ade44ad7c585..14d9fea33d16 100644 --- a/sound/soc/qcom/sc8280xp.c +++ b/sound/soc/qcom/sc8280xp.c @@ -12,6 +12,7 @@ #include <linux/input-event-codes.h> #include "qdsp6/q6afe.h" #include "common.h" +#include "sdw.h" #define DRIVER_NAME "sc8280xp" diff --git a/sound/soc/qcom/sdw.c b/sound/soc/qcom/sdw.c new file mode 100644 index 000000000000..10249519a39e --- /dev/null +++ b/sound/soc/qcom/sdw.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2018, Linaro Limited. +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#include <linux/module.h> +#include <sound/soc.h> +#include "qdsp6/q6afe.h" +#include "sdw.h" + +int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, + struct sdw_stream_runtime *sruntime, + bool *stream_prepared) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + int ret; + + if (!sruntime) + return 0; + + switch (cpu_dai->id) { + case WSA_CODEC_DMA_RX_0: + case WSA_CODEC_DMA_RX_1: + case RX_CODEC_DMA_RX_0: + case RX_CODEC_DMA_RX_1: + case TX_CODEC_DMA_TX_0: + case TX_CODEC_DMA_TX_1: + case TX_CODEC_DMA_TX_2: + case TX_CODEC_DMA_TX_3: + break; + default: + return 0; + } + + if (*stream_prepared) { + sdw_disable_stream(sruntime); + sdw_deprepare_stream(sruntime); + *stream_prepared = false; + } + + ret = sdw_prepare_stream(sruntime); + if (ret) + return ret; + + /** + * NOTE: there is a strict hw requirement about the ordering of port + * enables and actual WSA881x PA enable. PA enable should only happen + * after soundwire ports are enabled if not DC on the line is + * accumulated resulting in Click/Pop Noise + * PA enable/mute are handled as part of codec DAPM and digital mute. + */ + + ret = sdw_enable_stream(sruntime); + if (ret) { + sdw_deprepare_stream(sruntime); + return ret; + } + *stream_prepared = true; + + return ret; +} +EXPORT_SYMBOL_GPL(qcom_snd_sdw_prepare); + +int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct sdw_stream_runtime **psruntime) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct sdw_stream_runtime *sruntime; + int i; + + switch (cpu_dai->id) { + case WSA_CODEC_DMA_RX_0: + case RX_CODEC_DMA_RX_0: + case RX_CODEC_DMA_RX_1: + case TX_CODEC_DMA_TX_0: + case TX_CODEC_DMA_TX_1: + case TX_CODEC_DMA_TX_2: + case TX_CODEC_DMA_TX_3: + for_each_rtd_codec_dais(rtd, i, codec_dai) { + sruntime = snd_soc_dai_get_stream(codec_dai, substream->stream); + if (sruntime != ERR_PTR(-ENOTSUPP)) + *psruntime = sruntime; + } + break; + } + + return 0; + +} +EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_params); + +int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, + struct sdw_stream_runtime *sruntime, bool *stream_prepared) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + + switch (cpu_dai->id) { + case WSA_CODEC_DMA_RX_0: + case WSA_CODEC_DMA_RX_1: + case RX_CODEC_DMA_RX_0: + case RX_CODEC_DMA_RX_1: + case TX_CODEC_DMA_TX_0: + case TX_CODEC_DMA_TX_1: + case TX_CODEC_DMA_TX_2: + case TX_CODEC_DMA_TX_3: + if (sruntime && *stream_prepared) { + sdw_disable_stream(sruntime); + sdw_deprepare_stream(sruntime); + *stream_prepared = false; + } + break; + default: + break; + } + + return 0; +} +EXPORT_SYMBOL_GPL(qcom_snd_sdw_hw_free); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/qcom/sdw.h b/sound/soc/qcom/sdw.h new file mode 100644 index 000000000000..d74cbb84da13 --- /dev/null +++ b/sound/soc/qcom/sdw.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +// Copyright (c) 2018, The Linux Foundation. All rights reserved. + +#ifndef __QCOM_SND_SDW_H__ +#define __QCOM_SND_SDW_H__ + +#include <linux/soundwire/sdw.h> + +int qcom_snd_sdw_prepare(struct snd_pcm_substream *substream, + struct sdw_stream_runtime *runtime, + bool *stream_prepared); +int qcom_snd_sdw_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct sdw_stream_runtime **psruntime); +int qcom_snd_sdw_hw_free(struct snd_pcm_substream *substream, + struct sdw_stream_runtime *sruntime, + bool *stream_prepared); +#endif diff --git a/sound/soc/qcom/sm8250.c b/sound/soc/qcom/sm8250.c index 8dbe9ef41b1c..9626a9ef78c2 100644 --- a/sound/soc/qcom/sm8250.c +++ b/sound/soc/qcom/sm8250.c @@ -12,6 +12,7 @@ #include <linux/input-event-codes.h> #include "qdsp6/q6afe.h" #include "common.h" +#include "sdw.h" #define DRIVER_NAME "sm8250" #define MI2S_BCLK_RATE 1536000 diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 2a61e620cd3b..93c2b1b08d0a 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -11,16 +11,6 @@ menuconfig SND_SOC_SAMSUNG if SND_SOC_SAMSUNG -config SND_S3C24XX_I2S - tristate - -config SND_S3C_I2SV2_SOC - tristate - -config SND_S3C2412_SOC_I2S - tristate - select SND_S3C_I2SV2_SOC - config SND_SAMSUNG_PCM tristate "Samsung PCM interface support" @@ -31,35 +21,6 @@ config SND_SAMSUNG_SPDIF config SND_SAMSUNG_I2S tristate "Samsung I2S interface support" -config SND_SOC_SAMSUNG_NEO1973_WM8753 - tristate "Audio support for Openmoko Neo1973 Smartphones (GTA02)" - depends on MACH_NEO1973_GTA02 || COMPILE_TEST - depends on SND_SOC_I2C_AND_SPI - select SND_S3C24XX_I2S - select SND_SOC_WM8753 - select SND_SOC_BT_SCO - help - Say Y here to enable audio support for the Openmoko Neo1973 - Smartphones. - -config SND_SOC_SAMSUNG_JIVE_WM8750 - tristate "SoC I2S Audio support for Jive" - depends on MACH_JIVE && I2C || COMPILE_TEST && ARM - depends on SND_SOC_I2C_AND_SPI - select SND_SOC_WM8750 - select SND_S3C2412_SOC_I2S - help - Say Y if you want to add support for SoC audio on the Jive. - -config SND_SOC_SAMSUNG_SMDK_WM8580 - tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on MACH_SMDK6410 || COMPILE_TEST - depends on I2C - select SND_SOC_WM8580 - select SND_SAMSUNG_I2S - help - Say Y if you want to add support for SoC audio on the SMDKs. - config SND_SOC_SAMSUNG_SMDK_WM8994 tristate "SoC I2S Audio support for WM8994 on SMDK" depends on I2C=y @@ -69,60 +30,6 @@ config SND_SOC_SAMSUNG_SMDK_WM8994 help Say Y if you want to add support for SoC audio on the SMDKs. -config SND_SOC_SAMSUNG_S3C24XX_UDA134X - tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" - depends on ARCH_S3C24XX || COMPILE_TEST - select SND_S3C24XX_I2S - select SND_SOC_L3 - select SND_SOC_UDA134X - -config SND_SOC_SAMSUNG_SIMTEC - tristate - help - Internal node for common S3C24XX/Simtec support. - -config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 - tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" - depends on ARCH_S3C24XX || COMPILE_TEST - depends on I2C - select SND_S3C24XX_I2S - select SND_SOC_TLV320AIC23_I2C - select SND_SOC_SAMSUNG_SIMTEC - -config SND_SOC_SAMSUNG_SIMTEC_HERMES - tristate "SoC I2S Audio support for Simtec Hermes board" - depends on ARCH_S3C24XX || COMPILE_TEST - depends on I2C - select SND_S3C24XX_I2S - select SND_SOC_TLV320AIC3X - select SND_SOC_SAMSUNG_SIMTEC - -config SND_SOC_SAMSUNG_H1940_UDA1380 - tristate "Audio support for the HP iPAQ H1940" - depends on ARCH_H1940 || COMPILE_TEST - depends on I2C - select SND_S3C24XX_I2S - select SND_SOC_UDA1380 - help - This driver provides audio support for HP iPAQ h1940 PDA. - -config SND_SOC_SAMSUNG_RX1950_UDA1380 - tristate "Audio support for the HP iPAQ RX1950" - depends on MACH_RX1950 || COMPILE_TEST - depends on I2C - select SND_S3C24XX_I2S - select SND_SOC_UDA1380 - help - This driver provides audio support for HP iPAQ RX1950 PDA. - -config SND_SOC_SMARTQ - tristate "SoC I2S Audio support for SmartQ board" - depends on MACH_SMARTQ || COMPILE_TEST - depends on GPIOLIB || COMPILE_TEST - depends on I2C - select SND_SAMSUNG_I2S - select SND_SOC_WM8750 - config SND_SOC_SAMSUNG_SMDK_SPDIF tristate "SoC S/PDIF Audio support for SMDK" select SND_SAMSUNG_SPDIF diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 398e843f388c..f5d327b90a4e 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -2,35 +2,19 @@ # S3c24XX Platform Support snd-soc-s3c-dma-objs := dmaengine.o snd-soc-idma-objs := idma.o -snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o -snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o -snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o snd-soc-i2s-objs := i2s.o obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c-dma.o -obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o -obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-idma.o # S3C24XX Machine Support -snd-soc-jive-wm8750-objs := jive_wm8750.o -snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o -snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o -snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o -snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o -snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o -snd-soc-h1940-uda1380-objs := h1940_uda1380.o -snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o -snd-soc-smdk-wm8580-objs := smdk_wm8580.o snd-soc-smdk-wm8994-objs := smdk_wm8994.o snd-soc-snow-objs := snow.o -snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-smdk-spdif-objs := smdk_spdif.o snd-soc-smdk-wm8994pcm-objs := smdk_wm8994pcm.o snd-soc-speyside-objs := speyside.o @@ -44,18 +28,8 @@ snd-soc-tm2-wm5110-objs := tm2_wm5110.o snd-soc-aries-wm8994-objs := aries_wm8994.o snd-soc-midas-wm1811-objs := midas_wm1811.o -obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o -obj-$(CONFIG_SND_SOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o -obj-$(CONFIG_SND_SOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o -obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o -obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o -obj-$(CONFIG_SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o -obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o -obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o -obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o obj-$(CONFIG_SND_SOC_SNOW) += snd-soc-snow.o -obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o obj-$(CONFIG_SND_SOC_SMDK_WM8994_PCM) += snd-soc-smdk-wm8994pcm.o obj-$(CONFIG_SND_SOC_SPEYSIDE) += snd-soc-speyside.o diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c deleted file mode 100644 index fa45a54ab18f..000000000000 --- a/sound/soc/samsung/h1940_uda1380.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// h1940_uda1380.c - ALSA SoC Audio Layer -// -// Copyright (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org> -// Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com> -// -// Based on version from Arnaud Patard <arnaud.patard@rtp-net.org> - -#include <linux/types.h> -#include <linux/gpio/consumer.h> -#include <linux/module.h> - -#include <sound/soc.h> -#include <sound/jack.h> - -#include "regs-iis.h" -#include "s3c24xx-i2s.h" - -static const unsigned int rates[] = { - 11025, - 22050, - 44100, -}; - -static const struct snd_pcm_hw_constraint_list hw_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, -}; - -static struct gpio_desc *gpiod_speaker_power; - -static struct snd_soc_jack hp_jack; - -static struct snd_soc_jack_pin hp_jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Speaker", - .mask = SND_JACK_HEADPHONE, - .invert = 1, - }, -}; - -static struct snd_soc_jack_gpio hp_jack_gpios[] = { - { - .name = "hp-gpio", - .report = SND_JACK_HEADPHONE, - .invert = 1, - .debounce_time = 200, - }, -}; - -static int h1940_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &hw_rates); -} - -static int h1940_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int div; - int ret; - unsigned int rate = params_rate(params); - - switch (rate) { - case 11025: - case 22050: - case 44100: - div = s3c24xx_i2s_get_clockrate() / (384 * rate); - if (s3c24xx_i2s_get_clockrate() % (384 * rate) > (192 * rate)) - div++; - break; - default: - dev_err(rtd->dev, "%s: rate %d is not supported\n", - __func__, rate); - return -EINVAL; - } - - /* select clock source */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_384FS); - if (ret < 0) - return ret; - - /* set BCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(div, div)); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops h1940_ops = { - .startup = h1940_startup, - .hw_params = h1940_hw_params, -}; - -static int h1940_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - gpiod_set_value(gpiod_speaker_power, 1); - else - gpiod_set_value(gpiod_speaker_power, 0); - - return 0; -} - -/* h1940 machine dapm widgets */ -static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", h1940_spk_power), -}; - -/* h1940 machine audio_map */ -static const struct snd_soc_dapm_route audio_map[] = { - /* headphone connected to VOUTLHP, VOUTRHP */ - {"Headphone Jack", NULL, "VOUTLHP"}, - {"Headphone Jack", NULL, "VOUTRHP"}, - - /* ext speaker connected to VOUTL, VOUTR */ - {"Speaker", NULL, "VOUTL"}, - {"Speaker", NULL, "VOUTR"}, - - /* mic is connected to VINM */ - {"VINM", NULL, "Mic Jack"}, -}; - -static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) -{ - snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack", - SND_JACK_HEADPHONE, - &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins)); - - snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - -/* s3c24xx digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(uda1380, - DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), - DAILINK_COMP_ARRAY(COMP_CODEC("uda1380-codec.0-001a", "uda1380-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); - -static struct snd_soc_dai_link h1940_uda1380_dai[] = { - { - .name = "uda1380", - .stream_name = "UDA1380 Duplex", - .init = h1940_uda1380_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &h1940_ops, - SND_SOC_DAILINK_REG(uda1380), - }, -}; - -static struct snd_soc_card h1940_asoc = { - .name = "h1940", - .owner = THIS_MODULE, - .dai_link = h1940_uda1380_dai, - .num_links = ARRAY_SIZE(h1940_uda1380_dai), - - .dapm_widgets = uda1380_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static int h1940_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - h1940_asoc.dev = dev; - hp_jack_gpios[0].gpiod_dev = dev; - gpiod_speaker_power = devm_gpiod_get(&pdev->dev, "speaker-power", - GPIOD_OUT_LOW); - - if (IS_ERR(gpiod_speaker_power)) { - dev_err(dev, "Could not get gpio\n"); - return PTR_ERR(gpiod_speaker_power); - } - - return devm_snd_soc_register_card(dev, &h1940_asoc); -} - -static struct platform_driver h1940_audio_driver = { - .driver = { - .name = "h1940-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = h1940_probe, -}; -module_platform_driver(h1940_audio_driver); - -/* Module information */ -MODULE_AUTHOR("Arnaud Patard, Vasily Khoruzhick"); -MODULE_DESCRIPTION("ALSA SoC H1940"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:h1940-audio"); diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c deleted file mode 100644 index 40a85f539509..000000000000 --- a/sound/soc/samsung/jive_wm8750.c +++ /dev/null @@ -1,143 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright 2007,2008 Simtec Electronics -// -// Based on sound/soc/pxa/spitz.c -// Copyright 2005 Wolfson Microelectronics PLC. -// Copyright 2005 Openedhand Ltd. - -#include <linux/module.h> -#include <sound/soc.h> - -#include <asm/mach-types.h> - -#include "s3c2412-i2s.h" -#include "../codecs/wm8750.h" - -static const struct snd_soc_dapm_route audio_map[] = { - { "Headphone Jack", NULL, "LOUT1" }, - { "Headphone Jack", NULL, "ROUT1" }, - { "Internal Speaker", NULL, "LOUT2" }, - { "Internal Speaker", NULL, "ROUT2" }, - { "LINPUT1", NULL, "Line Input" }, - { "RINPUT1", NULL, "Line Input" }, -}; - -static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Internal Speaker", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), -}; - -static int jive_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - struct s3c_i2sv2_rate_calc div; - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), - s3c_i2sv2_get_clock(cpu_dai)); - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, - div.clk_div - 1); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops jive_ops = { - .hw_params = jive_hw_params, -}; - -SND_SOC_DAILINK_DEFS(wm8750, - DAILINK_COMP_ARRAY(COMP_CPU("s3c2412-i2s")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8750.0-001a", "wm8750-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c2412-i2s"))); - -static struct snd_soc_dai_link jive_dai = { - .name = "wm8750", - .stream_name = "WM8750", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &jive_ops, - SND_SOC_DAILINK_REG(wm8750), -}; - -/* jive audio machine driver */ -static struct snd_soc_card snd_soc_machine_jive = { - .name = "Jive", - .owner = THIS_MODULE, - .dai_link = &jive_dai, - .num_links = 1, - - .dapm_widgets = wm8750_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8750_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .fully_routed = true, -}; - -static struct platform_device *jive_snd_device; - -static int __init jive_init(void) -{ - int ret; - - if (!machine_is_jive()) - return 0; - - printk("JIVE WM8750 Audio support\n"); - - jive_snd_device = platform_device_alloc("soc-audio", -1); - if (!jive_snd_device) - return -ENOMEM; - - platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive); - ret = platform_device_add(jive_snd_device); - - if (ret) - platform_device_put(jive_snd_device); - - return ret; -} - -static void __exit jive_exit(void) -{ - platform_device_unregister(jive_snd_device); -} - -module_init(jive_init); -module_exit(jive_exit); - -MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("ALSA SoC Jive Audio support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c deleted file mode 100644 index e9f2334028bf..000000000000 --- a/sound/soc/samsung/neo1973_wm8753.c +++ /dev/null @@ -1,360 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// neo1973_wm8753.c - SoC audio for Openmoko Neo1973 and Freerunner devices -// -// Copyright 2007 Openmoko Inc -// Author: Graeme Gregory <graeme@openmoko.org> -// Copyright 2007 Wolfson Microelectronics PLC. -// Author: Graeme Gregory -// graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com -// Copyright 2009 Wolfson Microelectronics - -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/gpio/consumer.h> - -#include <sound/soc.h> - -#include "regs-iis.h" -#include "../codecs/wm8753.h" -#include "s3c24xx-i2s.h" - -static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int pll_out = 0, bclk = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - switch (params_rate(params)) { - case 8000: - case 16000: - pll_out = 12288000; - break; - case 48000: - bclk = WM8753_BCLK_DIV_4; - pll_out = 12288000; - break; - case 96000: - bclk = WM8753_BCLK_DIV_2; - pll_out = 12288000; - break; - case 11025: - bclk = WM8753_BCLK_DIV_16; - pll_out = 11289600; - break; - case 22050: - bclk = WM8753_BCLK_DIV_8; - pll_out = 11289600; - break; - case 44100: - bclk = WM8753_BCLK_DIV_4; - pll_out = 11289600; - break; - case 88200: - bclk = WM8753_BCLK_DIV_2; - pll_out = 11289600; - break; - } - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - /* set codec BCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(4, 4)); - if (ret < 0) - return ret; - - /* codec PLL input is PCLK/4 */ - ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, - iis_clkrate / 4, pll_out); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - - /* disable the PLL */ - return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); -} - -/* - * Neo1973 WM8753 HiFi DAI opserations. - */ -static const struct snd_soc_ops neo1973_hifi_ops = { - .hw_params = neo1973_hifi_hw_params, - .hw_free = neo1973_hifi_hw_free, -}; - -static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - unsigned int pcmdiv = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - if (params_rate(params) != 8000) - return -EINVAL; - if (params_channels(params) != 1) - return -EINVAL; - - pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec PCM division for sample rate */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); - if (ret < 0) - return ret; - - /* configure and enable PLL for 12.288MHz output */ - ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, - iis_clkrate / 4, 12288000); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - - /* disable the PLL */ - return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); -} - -static const struct snd_soc_ops neo1973_voice_ops = { - .hw_params = neo1973_voice_hw_params, - .hw_free = neo1973_voice_hw_free, -}; - -static struct gpio_desc *gpiod_hp_in, *gpiod_amp_shut; -static int gta02_speaker_enabled; - -static int lm4853_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - gta02_speaker_enabled = ucontrol->value.integer.value[0]; - - gpiod_set_value(gpiod_hp_in, !gta02_speaker_enabled); - - return 0; -} - -static int lm4853_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = gta02_speaker_enabled; - return 0; -} - -static int lm4853_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, int event) -{ - gpiod_set_value(gpiod_amp_shut, SND_SOC_DAPM_EVENT_OFF(event)); - - return 0; -} - -static const struct snd_soc_dapm_widget neo1973_wm8753_dapm_widgets[] = { - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_SPK("Handset Spk", NULL), - SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), -}; - -static const struct snd_soc_dapm_route neo1973_wm8753_routes[] = { - /* Connections to the GSM Module */ - {"GSM Line Out", NULL, "MONO1"}, - {"GSM Line Out", NULL, "MONO2"}, - {"RXP", NULL, "GSM Line In"}, - {"RXN", NULL, "GSM Line In"}, - - /* Connections to Headset */ - {"MIC1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Mic"}, - - /* Call Mic */ - {"MIC2", NULL, "Mic Bias"}, - {"MIC2N", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Handset Mic"}, - - /* Connect the ALC pins */ - {"ACIN", NULL, "ACOP"}, - - /* Connections to the amp */ - {"Stereo Out", NULL, "LOUT1"}, - {"Stereo Out", NULL, "ROUT1"}, - - /* Call Speaker */ - {"Handset Spk", NULL, "LOUT2"}, - {"Handset Spk", NULL, "ROUT2"}, -}; - -static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { - SOC_DAPM_PIN_SWITCH("GSM Line Out"), - SOC_DAPM_PIN_SWITCH("GSM Line In"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Handset Mic"), - SOC_DAPM_PIN_SWITCH("Handset Spk"), - SOC_DAPM_PIN_SWITCH("Stereo Out"), - - SOC_SINGLE_BOOL_EXT("Amp Spk Switch", 0, - lm4853_get_spk, - lm4853_set_spk), -}; - -static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - - /* set endpoints to default off mode */ - snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(&card->dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(&card->dapm, "Handset Mic"); - snd_soc_dapm_disable_pin(&card->dapm, "Stereo Out"); - snd_soc_dapm_disable_pin(&card->dapm, "Handset Spk"); - - /* allow audio paths from the GSM modem to run during suspend */ - snd_soc_dapm_ignore_suspend(&card->dapm, "GSM Line Out"); - snd_soc_dapm_ignore_suspend(&card->dapm, "GSM Line In"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Stereo Out"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Handset Spk"); - - return 0; -} - -SND_SOC_DAILINK_DEFS(wm8753, - DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8753.0-001a", "wm8753-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); - -SND_SOC_DAILINK_DEFS(bluetooth, - DAILINK_COMP_ARRAY(COMP_CPU("bt-sco-pcm")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8753.0-001a", "wm8753-voice"))); - -static struct snd_soc_dai_link neo1973_dai[] = { -{ /* Hifi Playback - for similatious use with voice below */ - .name = "WM8753", - .stream_name = "WM8753 HiFi", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM, - .init = neo1973_wm8753_init, - .ops = &neo1973_hifi_ops, - SND_SOC_DAILINK_REG(wm8753), -}, -{ /* Voice via BT */ - .name = "Bluetooth", - .stream_name = "Voice", - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &neo1973_voice_ops, - SND_SOC_DAILINK_REG(bluetooth), -}, -}; - -static struct snd_soc_aux_dev neo1973_aux_devs[] = { - { - .dlc = COMP_AUX("dfbmcs320.0"), - }, -}; - -static struct snd_soc_codec_conf neo1973_codec_conf[] = { - { - .dlc = COMP_CODEC_CONF("lm4857.0-007c"), - .name_prefix = "Amp", - }, -}; - -static struct snd_soc_card neo1973 = { - .name = "neo1973gta02", - .owner = THIS_MODULE, - .dai_link = neo1973_dai, - .num_links = ARRAY_SIZE(neo1973_dai), - .aux_dev = neo1973_aux_devs, - .num_aux_devs = ARRAY_SIZE(neo1973_aux_devs), - .codec_conf = neo1973_codec_conf, - .num_configs = ARRAY_SIZE(neo1973_codec_conf), - - .controls = neo1973_wm8753_controls, - .num_controls = ARRAY_SIZE(neo1973_wm8753_controls), - .dapm_widgets = neo1973_wm8753_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets), - .dapm_routes = neo1973_wm8753_routes, - .num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes), - .fully_routed = true, -}; - -static int neo1973_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - gpiod_hp_in = devm_gpiod_get(dev, "hp", GPIOD_OUT_HIGH); - if (IS_ERR(gpiod_hp_in)) { - dev_err(dev, "missing gpio %s\n", "hp"); - return PTR_ERR(gpiod_hp_in); - } - gpiod_amp_shut = devm_gpiod_get(dev, "amp-shut", GPIOD_OUT_HIGH); - if (IS_ERR(gpiod_amp_shut)) { - dev_err(dev, "missing gpio %s\n", "amp-shut"); - return PTR_ERR(gpiod_amp_shut); - } - - neo1973.dev = dev; - return devm_snd_soc_register_card(dev, &neo1973); -} - -static struct platform_driver neo1973_audio = { - .driver = { - .name = "neo1973-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = neo1973_probe, -}; -module_platform_driver(neo1973_audio); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); -MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 and Frerunner"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:neo1973-audio"); diff --git a/sound/soc/samsung/regs-i2s-v2.h b/sound/soc/samsung/regs-i2s-v2.h deleted file mode 100644 index 867984e75709..000000000000 --- a/sound/soc/samsung/regs-i2s-v2.h +++ /dev/null @@ -1,111 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright 2007 Simtec Electronics <linux@simtec.co.uk> - * http://armlinux.simtec.co.uk/ - * - * S3C2412 IIS register definition - */ - -#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H -#define __ASM_ARCH_REGS_S3C2412_IIS_H - -#define S3C2412_IISCON (0x00) -#define S3C2412_IISMOD (0x04) -#define S3C2412_IISFIC (0x08) -#define S3C2412_IISPSR (0x0C) -#define S3C2412_IISTXD (0x10) -#define S3C2412_IISRXD (0x14) - -#define S5PC1XX_IISFICS 0x18 -#define S5PC1XX_IISTXDS 0x1C - -#define S5PC1XX_IISCON_SW_RST (1 << 31) -#define S5PC1XX_IISCON_FRXOFSTATUS (1 << 26) -#define S5PC1XX_IISCON_FRXORINTEN (1 << 25) -#define S5PC1XX_IISCON_FTXSURSTAT (1 << 24) -#define S5PC1XX_IISCON_FTXSURINTEN (1 << 23) -#define S5PC1XX_IISCON_TXSDMAPAUSE (1 << 20) -#define S5PC1XX_IISCON_TXSDMACTIVE (1 << 18) - -#define S3C64XX_IISCON_FTXURSTATUS (1 << 17) -#define S3C64XX_IISCON_FTXURINTEN (1 << 16) -#define S3C64XX_IISCON_TXFIFO2_EMPTY (1 << 15) -#define S3C64XX_IISCON_TXFIFO1_EMPTY (1 << 14) -#define S3C64XX_IISCON_TXFIFO2_FULL (1 << 13) -#define S3C64XX_IISCON_TXFIFO1_FULL (1 << 12) - -#define S3C2412_IISCON_LRINDEX (1 << 11) -#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) -#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) -#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) -#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) -#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) -#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) -#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) -#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) -#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) -#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) -#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) - -#define S5PC1XX_IISMOD_OPCLK_CDCLK_OUT (0 << 30) -#define S5PC1XX_IISMOD_OPCLK_CDCLK_IN (1 << 30) -#define S5PC1XX_IISMOD_OPCLK_BCLK_OUT (2 << 30) -#define S5PC1XX_IISMOD_OPCLK_PCLK (3 << 30) -#define S5PC1XX_IISMOD_OPCLK_MASK (3 << 30) -#define S5PC1XX_IISMOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ -#define S5PC1XX_IISMOD_BLCS_MASK 0x3 -#define S5PC1XX_IISMOD_BLCS_SHIFT 26 -#define S5PC1XX_IISMOD_BLCP_MASK 0x3 -#define S5PC1XX_IISMOD_BLCP_SHIFT 24 - -#define S3C64XX_IISMOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ -#define S3C64XX_IISMOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ -#define S3C64XX_IISMOD_C1DD_HHALF (1 << 19) -#define S3C64XX_IISMOD_C1DD_LHALF (1 << 18) -#define S3C64XX_IISMOD_DC2_EN (1 << 17) -#define S3C64XX_IISMOD_DC1_EN (1 << 16) -#define S3C64XX_IISMOD_BLC_16BIT (0 << 13) -#define S3C64XX_IISMOD_BLC_8BIT (1 << 13) -#define S3C64XX_IISMOD_BLC_24BIT (2 << 13) -#define S3C64XX_IISMOD_BLC_MASK (3 << 13) - -#define S3C2412_IISMOD_IMS_SYSMUX (1 << 10) -#define S3C2412_IISMOD_SLAVE (1 << 11) -#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) -#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) -#define S3C2412_IISMOD_MODE_TXRX (2 << 8) -#define S3C2412_IISMOD_MODE_MASK (3 << 8) -#define S3C2412_IISMOD_LR_LLOW (0 << 7) -#define S3C2412_IISMOD_LR_RLOW (1 << 7) -#define S3C2412_IISMOD_SDF_IIS (0 << 5) -#define S3C2412_IISMOD_SDF_MSB (1 << 5) -#define S3C2412_IISMOD_SDF_LSB (2 << 5) -#define S3C2412_IISMOD_SDF_MASK (3 << 5) -#define S3C2412_IISMOD_RCLK_256FS (0 << 3) -#define S3C2412_IISMOD_RCLK_512FS (1 << 3) -#define S3C2412_IISMOD_RCLK_384FS (2 << 3) -#define S3C2412_IISMOD_RCLK_768FS (3 << 3) -#define S3C2412_IISMOD_RCLK_MASK (3 << 3) -#define S3C2412_IISMOD_BCLK_32FS (0 << 1) -#define S3C2412_IISMOD_BCLK_48FS (1 << 1) -#define S3C2412_IISMOD_BCLK_16FS (2 << 1) -#define S3C2412_IISMOD_BCLK_24FS (3 << 1) -#define S3C2412_IISMOD_BCLK_MASK (3 << 1) -#define S3C2412_IISMOD_8BIT (1 << 0) - -#define S3C64XX_IISMOD_CDCLKCON (1 << 12) - -#define S3C2412_IISPSR_PSREN (1 << 15) - -#define S3C64XX_IISFIC_TX2COUNT(x) (((x) >> 24) & 0xf) -#define S3C64XX_IISFIC_TX1COUNT(x) (((x) >> 16) & 0xf) - -#define S3C2412_IISFIC_TXFLUSH (1 << 15) -#define S3C2412_IISFIC_RXFLUSH (1 << 7) -#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) -#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) - -#define S5PC1XX_IISFICS_TXFLUSH (1 << 15) -#define S5PC1XX_IISFICS_TXCOUNT(x) (((x) >> 8) & 0x7f) - -#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ diff --git a/sound/soc/samsung/regs-iis.h b/sound/soc/samsung/regs-iis.h deleted file mode 100644 index 253e172ad3b6..000000000000 --- a/sound/soc/samsung/regs-iis.h +++ /dev/null @@ -1,66 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (c) 2003 Simtec Electronics <linux@simtec.co.uk> - * http://www.simtec.co.uk/products/SWLINUX/ - * - * S3C2410 IIS register definition - */ - -#ifndef __SAMSUNG_REGS_IIS_H__ -#define __SAMSUNG_REGS_IIS_H__ - -#define S3C2410_IISCON (0x00) - -#define S3C2410_IISCON_LRINDEX (1 << 8) -#define S3C2410_IISCON_TXFIFORDY (1 << 7) -#define S3C2410_IISCON_RXFIFORDY (1 << 6) -#define S3C2410_IISCON_TXDMAEN (1 << 5) -#define S3C2410_IISCON_RXDMAEN (1 << 4) -#define S3C2410_IISCON_TXIDLE (1 << 3) -#define S3C2410_IISCON_RXIDLE (1 << 2) -#define S3C2410_IISCON_PSCEN (1 << 1) -#define S3C2410_IISCON_IISEN (1 << 0) - -#define S3C2410_IISMOD (0x04) - -#define S3C2440_IISMOD_MPLL (1 << 9) -#define S3C2410_IISMOD_SLAVE (1 << 8) -#define S3C2410_IISMOD_NOXFER (0 << 6) -#define S3C2410_IISMOD_RXMODE (1 << 6) -#define S3C2410_IISMOD_TXMODE (2 << 6) -#define S3C2410_IISMOD_TXRXMODE (3 << 6) -#define S3C2410_IISMOD_LR_LLOW (0 << 5) -#define S3C2410_IISMOD_LR_RLOW (1 << 5) -#define S3C2410_IISMOD_IIS (0 << 4) -#define S3C2410_IISMOD_MSB (1 << 4) -#define S3C2410_IISMOD_8BIT (0 << 3) -#define S3C2410_IISMOD_16BIT (1 << 3) -#define S3C2410_IISMOD_BITMASK (1 << 3) -#define S3C2410_IISMOD_256FS (0 << 2) -#define S3C2410_IISMOD_384FS (1 << 2) -#define S3C2410_IISMOD_16FS (0 << 0) -#define S3C2410_IISMOD_32FS (1 << 0) -#define S3C2410_IISMOD_48FS (2 << 0) -#define S3C2410_IISMOD_FS_MASK (3 << 0) - -#define S3C2410_IISPSR (0x08) - -#define S3C2410_IISPSR_INTMASK (31 << 5) -#define S3C2410_IISPSR_INTSHIFT (5) -#define S3C2410_IISPSR_EXTMASK (31 << 0) -#define S3C2410_IISPSR_EXTSHFIT (0) - -#define S3C2410_IISFCON (0x0c) - -#define S3C2410_IISFCON_TXDMA (1 << 15) -#define S3C2410_IISFCON_RXDMA (1 << 14) -#define S3C2410_IISFCON_TXENABLE (1 << 13) -#define S3C2410_IISFCON_RXENABLE (1 << 12) -#define S3C2410_IISFCON_TXMASK (0x3f << 6) -#define S3C2410_IISFCON_TXSHIFT (6) -#define S3C2410_IISFCON_RXMASK (0x3f) -#define S3C2410_IISFCON_RXSHIFT (0) - -#define S3C2410_IISFIFO (0x10) - -#endif /* __SAMSUNG_REGS_IIS_H__ */ diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c deleted file mode 100644 index abf28321f7d7..000000000000 --- a/sound/soc/samsung/rx1950_uda1380.c +++ /dev/null @@ -1,245 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// rx1950.c - ALSA SoC Audio Layer -// -// Copyright (c) 2010 Vasily Khoruzhick <anarsoul@gmail.com> -// -// Based on smdk2440.c and magician.c -// -// Authors: Graeme Gregory graeme.gregory@wolfsonmicro.com -// Philipp Zabel <philipp.zabel@gmail.com> -// Denis Grigoriev <dgreenday@gmail.com> -// Vasily Khoruzhick <anarsoul@gmail.com> - -#include <linux/types.h> -#include <linux/gpio/consumer.h> -#include <linux/module.h> - -#include <sound/soc.h> -#include <sound/jack.h> - -#include "regs-iis.h" -#include "s3c24xx-i2s.h" - -static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); -static int rx1950_startup(struct snd_pcm_substream *substream); -static int rx1950_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params); -static int rx1950_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event); - -static const unsigned int rates[] = { - 16000, - 44100, - 48000, -}; - -static const struct snd_pcm_hw_constraint_list hw_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, -}; - -static struct snd_soc_jack hp_jack; - -static struct snd_soc_jack_pin hp_jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Speaker", - .mask = SND_JACK_HEADPHONE, - .invert = 1, - }, -}; - -static struct snd_soc_jack_gpio hp_jack_gpios[] = { - [0] = { - .name = "hp-gpio", - .report = SND_JACK_HEADPHONE, - .invert = 1, - .debounce_time = 200, - }, -}; - -static const struct snd_soc_ops rx1950_ops = { - .startup = rx1950_startup, - .hw_params = rx1950_hw_params, -}; - -/* s3c24xx digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(uda1380, - DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), - DAILINK_COMP_ARRAY(COMP_CODEC("uda1380-codec.0-001a", - "uda1380-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); - -static struct snd_soc_dai_link rx1950_uda1380_dai[] = { - { - .name = "uda1380", - .stream_name = "UDA1380 Duplex", - .init = rx1950_uda1380_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &rx1950_ops, - SND_SOC_DAILINK_REG(uda1380), - }, -}; - -/* rx1950 machine dapm widgets */ -static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", rx1950_spk_power), -}; - -/* rx1950 machine audio_map */ -static const struct snd_soc_dapm_route audio_map[] = { - /* headphone connected to VOUTLHP, VOUTRHP */ - {"Headphone Jack", NULL, "VOUTLHP"}, - {"Headphone Jack", NULL, "VOUTRHP"}, - - /* ext speaker connected to VOUTL, VOUTR */ - {"Speaker", NULL, "VOUTL"}, - {"Speaker", NULL, "VOUTR"}, - - /* mic is connected to VINM */ - {"VINM", NULL, "Mic Jack"}, -}; - -static struct snd_soc_card rx1950_asoc = { - .name = "rx1950", - .owner = THIS_MODULE, - .dai_link = rx1950_uda1380_dai, - .num_links = ARRAY_SIZE(rx1950_uda1380_dai), - - .dapm_widgets = uda1380_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(uda1380_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static int rx1950_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - return snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &hw_rates); -} - -static struct gpio_desc *gpiod_speaker_power; - -static int rx1950_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - gpiod_set_value(gpiod_speaker_power, 1); - else - gpiod_set_value(gpiod_speaker_power, 0); - - return 0; -} - -static int rx1950_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int div; - int ret; - unsigned int rate = params_rate(params); - int clk_source, fs_mode; - - switch (rate) { - case 16000: - case 48000: - clk_source = S3C24XX_CLKSRC_PCLK; - fs_mode = S3C2410_IISMOD_256FS; - div = s3c24xx_i2s_get_clockrate() / (256 * rate); - if (s3c24xx_i2s_get_clockrate() % (256 * rate) > (128 * rate)) - div++; - break; - case 44100: - case 88200: - clk_source = S3C24XX_CLKSRC_MPLL; - fs_mode = S3C2410_IISMOD_384FS; - div = 1; - break; - default: - printk(KERN_ERR "%s: rate %d is not supported\n", - __func__, rate); - return -EINVAL; - } - - /* select clock source */ - ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - fs_mode); - if (ret < 0) - return ret; - - /* set BCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(div, div)); - if (ret < 0) - return ret; - - return 0; -} - -static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) -{ - snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack", - SND_JACK_HEADPHONE, - &hp_jack, hp_jack_pins, ARRAY_SIZE(hp_jack_pins)); - - snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - -static int rx1950_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - - /* configure some gpios */ - gpiod_speaker_power = devm_gpiod_get(dev, "speaker-power", GPIOD_OUT_LOW); - if (IS_ERR(gpiod_speaker_power)) { - dev_err(dev, "cannot get gpio\n"); - return PTR_ERR(gpiod_speaker_power); - } - - hp_jack_gpios[0].gpiod_dev = dev; - rx1950_asoc.dev = dev; - - return devm_snd_soc_register_card(dev, &rx1950_asoc); -} - -static struct platform_driver rx1950_audio = { - .driver = { - .name = "rx1950-audio", - .pm = &snd_soc_pm_ops, - }, - .probe = rx1950_probe, -}; - -module_platform_driver(rx1950_audio); - -/* Module information */ -MODULE_AUTHOR("Vasily Khoruzhick"); -MODULE_DESCRIPTION("ALSA SoC RX1950"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:rx1950-audio"); diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c deleted file mode 100644 index 2b221cb0ed03..000000000000 --- a/sound/soc/samsung/s3c-i2s-v2.c +++ /dev/null @@ -1,670 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. -// -// Copyright (c) 2006 Wolfson Microelectronics PLC. -// Graeme Gregory graeme.gregory@wolfsonmicro.com -// linux@wolfsonmicro.com -// -// Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics -// http://armlinux.simtec.co.uk/ -// Ben Dooks <ben@simtec.co.uk> - -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/io.h> - -#include <sound/soc.h> -#include <sound/pcm_params.h> - -#include "regs-i2s-v2.h" -#include "s3c-i2s-v2.h" - -#define S3C2412_I2S_DEBUG_CON 0 - -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return snd_soc_dai_get_drvdata(cpu_dai); -} - -#define bit_set(v, b) (((v) & (b)) ? 1 : 0) - -#if S3C2412_I2S_DEBUG_CON -static void dbg_showcon(const char *fn, u32 con) -{ - printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, - bit_set(con, S3C2412_IISCON_LRINDEX), - bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), - bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), - bit_set(con, S3C2412_IISCON_TXFIFO_FULL), - bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); - - printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", - fn, - bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), - bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), - bit_set(con, S3C2412_IISCON_TXCH_PAUSE), - bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); - printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, - bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), - bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), - bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); -} -#else -static inline void dbg_showcon(const char *fn, u32 con) -{ -} -#endif - -/* Turn on or off the transmission path. */ -static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) -{ - void __iomem *regs = i2s->regs; - u32 fic, con, mod; - - pr_debug("%s(%d)\n", __func__, on); - - fic = readl(regs + S3C2412_IISFIC); - con = readl(regs + S3C2412_IISCON); - mod = readl(regs + S3C2412_IISMOD); - - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); - - if (on) { - con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; - con &= ~S3C2412_IISCON_TXDMA_PAUSE; - con &= ~S3C2412_IISCON_TXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXONLY: - case S3C2412_IISMOD_MODE_TXRX: - /* do nothing, we are in the right mode */ - break; - - case S3C2412_IISMOD_MODE_RXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXRX; - break; - - default: - dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; - } - - writel(con, regs + S3C2412_IISCON); - writel(mod, regs + S3C2412_IISMOD); - } else { - /* Note, we do not have any indication that the FIFO problems - * tha the S3C2410/2440 had apply here, so we should be able - * to disable the DMA and TX without resetting the FIFOS. - */ - - con |= S3C2412_IISCON_TXDMA_PAUSE; - con |= S3C2412_IISCON_TXCH_PAUSE; - con &= ~S3C2412_IISCON_TXDMA_ACTIVE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXRX: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_RXONLY; - break; - - case S3C2412_IISMOD_MODE_TXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - con &= ~S3C2412_IISCON_IIS_ACTIVE; - break; - - default: - dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; - } - - writel(mod, regs + S3C2412_IISMOD); - writel(con, regs + S3C2412_IISCON); - } - - fic = readl(regs + S3C2412_IISFIC); - dbg_showcon(__func__, con); - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); -} - -static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) -{ - void __iomem *regs = i2s->regs; - u32 fic, con, mod; - - pr_debug("%s(%d)\n", __func__, on); - - fic = readl(regs + S3C2412_IISFIC); - con = readl(regs + S3C2412_IISCON); - mod = readl(regs + S3C2412_IISMOD); - - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); - - if (on) { - con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; - con &= ~S3C2412_IISCON_RXDMA_PAUSE; - con &= ~S3C2412_IISCON_RXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXRX: - case S3C2412_IISMOD_MODE_RXONLY: - /* do nothing, we are in the right mode */ - break; - - case S3C2412_IISMOD_MODE_TXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXRX; - break; - - default: - dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - } - - writel(mod, regs + S3C2412_IISMOD); - writel(con, regs + S3C2412_IISCON); - } else { - /* See txctrl notes on FIFOs. */ - - con &= ~S3C2412_IISCON_RXDMA_ACTIVE; - con |= S3C2412_IISCON_RXDMA_PAUSE; - con |= S3C2412_IISCON_RXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_RXONLY: - con &= ~S3C2412_IISCON_IIS_ACTIVE; - mod &= ~S3C2412_IISMOD_MODE_MASK; - break; - - case S3C2412_IISMOD_MODE_TXRX: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXONLY; - break; - - default: - dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - } - - writel(con, regs + S3C2412_IISCON); - writel(mod, regs + S3C2412_IISMOD); - } - - fic = readl(regs + S3C2412_IISFIC); - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); -} - -#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) - -/* - * Wait for the LR signal to allow synchronisation to the L/R clock - * from the codec. May only be needed for slave mode. - */ -static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) -{ - u32 iiscon; - unsigned long loops = msecs_to_loops(5); - - pr_debug("Entered %s\n", __func__); - - while (--loops) { - iiscon = readl(i2s->regs + S3C2412_IISCON); - if (iiscon & S3C2412_IISCON_LRINDEX) - break; - - cpu_relax(); - } - - if (!loops) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } - - return 0; -} - -/* - * Set S3C2412 I2S DAI format - */ -static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("hw_params r: IISMOD: %x \n", iismod); - - switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BC_FC: - i2s->master = 0; - iismod |= S3C2412_IISMOD_SLAVE; - break; - case SND_SOC_DAIFMT_BP_FP: - i2s->master = 1; - iismod &= ~S3C2412_IISMOD_SLAVE; - break; - default: - pr_err("unknown master/slave format\n"); - return -EINVAL; - } - - iismod &= ~S3C2412_IISMOD_SDF_MASK; - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - iismod |= S3C2412_IISMOD_LR_RLOW; - iismod |= S3C2412_IISMOD_SDF_MSB; - break; - case SND_SOC_DAIFMT_LEFT_J: - iismod |= S3C2412_IISMOD_LR_RLOW; - iismod |= S3C2412_IISMOD_SDF_LSB; - break; - case SND_SOC_DAIFMT_I2S: - iismod &= ~S3C2412_IISMOD_LR_RLOW; - iismod |= S3C2412_IISMOD_SDF_IIS; - break; - default: - pr_err("Unknown data format\n"); - return -EINVAL; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("hw_params w: IISMOD: %x \n", iismod); - return 0; -} - -static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - struct snd_dmaengine_dai_dma_data *dma_data; - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = i2s->dma_playback; - else - dma_data = i2s->dma_capture; - - snd_soc_dai_set_dma_data(dai, substream, dma_data); - - /* Working copies of register */ - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); - - iismod &= ~S3C64XX_IISMOD_BLC_MASK; - /* Sample size */ - switch (params_width(params)) { - case 8: - iismod |= S3C64XX_IISMOD_BLC_8BIT; - break; - case 16: - break; - case 24: - iismod |= S3C64XX_IISMOD_BLC_24BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - pr_debug("Entered %s\n", __func__); - pr_debug("%s r: IISMOD: %x\n", __func__, iismod); - - switch (clk_id) { - case S3C_I2SV2_CLKSRC_PCLK: - iismod &= ~S3C2412_IISMOD_IMS_SYSMUX; - break; - - case S3C_I2SV2_CLKSRC_AUDIOBUS: - iismod |= S3C2412_IISMOD_IMS_SYSMUX; - break; - - case S3C_I2SV2_CLKSRC_CDCLK: - /* Error if controller doesn't have the CDCLKCON bit */ - if (!(i2s->feature & S3C_FEATURE_CDCLKCON)) - return -EINVAL; - - switch (dir) { - case SND_SOC_CLOCK_IN: - iismod |= S3C64XX_IISMOD_CDCLKCON; - break; - case SND_SOC_CLOCK_OUT: - iismod &= ~S3C64XX_IISMOD_CDCLKCON; - break; - default: - return -EINVAL; - } - break; - - default: - return -EINVAL; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct s3c_i2sv2_info *i2s = to_info(asoc_rtd_to_cpu(rtd, 0)); - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - unsigned long irqs; - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - /* On start, ensure that the FIFOs are cleared and reset. */ - - writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, - i2s->regs + S3C2412_IISFIC); - - /* clear again, just in case */ - writel(0x0, i2s->regs + S3C2412_IISFIC); - - fallthrough; - - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (!i2s->master) { - ret = s3c2412_snd_lrsync(i2s); - if (ret) - goto exit_err; - } - - local_irq_save(irqs); - - if (capture) - s3c2412_snd_rxctrl(i2s, 1); - else - s3c2412_snd_txctrl(i2s, 1); - - local_irq_restore(irqs); - - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - local_irq_save(irqs); - - if (capture) - s3c2412_snd_rxctrl(i2s, 0); - else - s3c2412_snd_txctrl(i2s, 0); - - local_irq_restore(irqs); - break; - default: - ret = -EINVAL; - break; - } - -exit_err: - return ret; -} - -/* - * Set S3C2412 Clock dividers - */ -static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 reg; - - pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); - - switch (div_id) { - case S3C_I2SV2_DIV_BCLK: - switch (div) { - case 16: - div = S3C2412_IISMOD_BCLK_16FS; - break; - - case 32: - div = S3C2412_IISMOD_BCLK_32FS; - break; - - case 24: - div = S3C2412_IISMOD_BCLK_24FS; - break; - - case 48: - div = S3C2412_IISMOD_BCLK_48FS; - break; - - default: - return -EINVAL; - } - - reg = readl(i2s->regs + S3C2412_IISMOD); - reg &= ~S3C2412_IISMOD_BCLK_MASK; - writel(reg | div, i2s->regs + S3C2412_IISMOD); - - pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); - break; - - case S3C_I2SV2_DIV_RCLK: - switch (div) { - case 256: - div = S3C2412_IISMOD_RCLK_256FS; - break; - - case 384: - div = S3C2412_IISMOD_RCLK_384FS; - break; - - case 512: - div = S3C2412_IISMOD_RCLK_512FS; - break; - - case 768: - div = S3C2412_IISMOD_RCLK_768FS; - break; - - default: - return -EINVAL; - } - - reg = readl(i2s->regs + S3C2412_IISMOD); - reg &= ~S3C2412_IISMOD_RCLK_MASK; - writel(reg | div, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); - break; - - case S3C_I2SV2_DIV_PRESCALER: - if (div >= 0) { - writel((div << 8) | S3C2412_IISPSR_PSREN, - i2s->regs + S3C2412_IISPSR); - } else { - writel(0x0, i2s->regs + S3C2412_IISPSR); - } - pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - u32 reg = readl(i2s->regs + S3C2412_IISFIC); - snd_pcm_sframes_t delay; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - delay = S3C2412_IISFIC_TXCOUNT(reg); - else - delay = S3C2412_IISFIC_RXCOUNT(reg); - - return delay; -} - -struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISMOD_IMS_SYSMUX) - return i2s->iis_cclk; - else - return i2s->iis_pclk; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock); - -/* default table of all avaialable root fs divisors */ -static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; - -int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, - unsigned int *fstab, - unsigned int rate, struct clk *clk) -{ - unsigned long clkrate = clk_get_rate(clk); - unsigned int div; - unsigned int fsclk; - unsigned int actual; - unsigned int fs; - unsigned int fsdiv; - signed int deviation = 0; - unsigned int best_fs = 0; - unsigned int best_div = 0; - unsigned int best_rate = 0; - unsigned int best_deviation = INT_MAX; - - pr_debug("Input clock rate %ldHz\n", clkrate); - - if (fstab == NULL) - fstab = iis_fs_tab; - - for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) { - fsdiv = iis_fs_tab[fs]; - - fsclk = clkrate / fsdiv; - div = fsclk / rate; - - if ((fsclk % rate) > (rate / 2)) - div++; - - if (div <= 1) - continue; - - actual = clkrate / (fsdiv * div); - deviation = actual - rate; - - printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n", - fsdiv, div, actual, deviation); - - deviation = abs(deviation); - - if (deviation < best_deviation) { - best_fs = fsdiv; - best_div = div; - best_rate = actual; - best_deviation = deviation; - } - - if (deviation == 0) - break; - } - - printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n", - best_fs, best_div, best_rate); - - info->fs_div = best_fs; - info->clk_div = best_div; - - return 0; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate); - -int s3c_i2sv2_probe(struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s) -{ - struct device *dev = dai->dev; - unsigned int iismod; - - i2s->dev = dev; - - /* record our i2s structure for later use in the callbacks */ - snd_soc_dai_set_drvdata(dai, i2s); - - i2s->iis_pclk = clk_get(dev, "iis"); - if (IS_ERR(i2s->iis_pclk)) { - dev_err(dev, "failed to get iis_clock\n"); - return -ENOENT; - } - - clk_prepare_enable(i2s->iis_pclk); - - /* Mark ourselves as in TXRX mode so we can run through our cleanup - * process without warnings. */ - iismod = readl(i2s->regs + S3C2412_IISMOD); - iismod |= S3C2412_IISMOD_MODE_TXRX; - writel(iismod, i2s->regs + S3C2412_IISMOD); - s3c2412_snd_txctrl(i2s, 0); - s3c2412_snd_rxctrl(i2s, 0); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); - -void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s) -{ - clk_disable_unprepare(i2s->iis_pclk); - clk_put(i2s->iis_pclk); - i2s->iis_pclk = NULL; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_cleanup); - -int s3c_i2sv2_register_component(struct device *dev, int id, - const struct snd_soc_component_driver *cmp_drv, - struct snd_soc_dai_driver *dai_drv) -{ - struct snd_soc_dai_ops *ops = (struct snd_soc_dai_ops *)dai_drv->ops; - - ops->trigger = s3c2412_i2s_trigger; - if (!ops->hw_params) - ops->hw_params = s3c_i2sv2_hw_params; - ops->set_fmt = s3c2412_i2s_set_fmt; - ops->set_clkdiv = s3c2412_i2s_set_clkdiv; - ops->set_sysclk = s3c_i2sv2_set_sysclk; - - /* Allow overriding by (for example) IISv4 */ - if (!ops->delay) - ops->delay = s3c2412_i2s_delay; - - return devm_snd_soc_register_component(dev, cmp_drv, dai_drv, 1); -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component); - -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h deleted file mode 100644 index 8c6fc0d3d77e..000000000000 --- a/sound/soc/samsung/s3c-i2s-v2.h +++ /dev/null @@ -1,108 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver - * - * Copyright (c) 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - */ - -/* This code is the core support for the I2S block found in a number of - * Samsung SoC devices which is unofficially named I2S-V2. Currently the - * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S - * channels via configurable GPIO. - */ - -#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H -#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__ - -#define S3C_I2SV2_DIV_BCLK (1) -#define S3C_I2SV2_DIV_RCLK (2) -#define S3C_I2SV2_DIV_PRESCALER (3) - -#define S3C_I2SV2_CLKSRC_PCLK 0 -#define S3C_I2SV2_CLKSRC_AUDIOBUS 1 -#define S3C_I2SV2_CLKSRC_CDCLK 2 - -/* Set this flag for I2S controllers that have the bit IISMOD[12] - * bridge/break RCLK signal and external Xi2sCDCLK pin. - */ -#define S3C_FEATURE_CDCLKCON (1 << 0) - -/** - * struct s3c_i2sv2_info - S3C I2S-V2 information - * @dev: The parent device passed to use from the probe. - * @regs: The pointer to the device registe block. - * @feature: Set of bit-flags indicating features of the controller. - * @master: True if the I2S core is the I2S bit clock master. - * @dma_playback: DMA information for playback channel. - * @dma_capture: DMA information for capture channel. - * @suspend_iismod: PM save for the IISMOD register. - * @suspend_iiscon: PM save for the IISCON register. - * @suspend_iispsr: PM save for the IISPSR register. - * - * This is the private codec state for the hardware associated with an - * I2S channel such as the register mappings and clock sources. - */ -struct s3c_i2sv2_info { - struct device *dev; - void __iomem *regs; - - u32 feature; - - struct clk *iis_pclk; - struct clk *iis_cclk; - - unsigned char master; - - struct snd_dmaengine_dai_dma_data *dma_playback; - struct snd_dmaengine_dai_dma_data *dma_capture; - - u32 suspend_iismod; - u32 suspend_iiscon; - u32 suspend_iispsr; - - unsigned long base; -}; - -extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai); - -struct s3c_i2sv2_rate_calc { - unsigned int clk_div; /* for prescaler */ - unsigned int fs_div; /* for root frame clock */ -}; - -extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, - unsigned int *fstab, - unsigned int rate, struct clk *clk); - -/** - * s3c_i2sv2_probe - probe for i2s device helper - * @dai: The ASoC DAI structure supplied to the original probe. - * @i2s: Our local i2s structure to fill in. - * @base: The base address for the registers. - */ -extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s); - -/** - * s3c_i2sv2_cleanup - cleanup resources allocated in s3c_i2sv2_probe - * @dai: The ASoC DAI structure supplied to the original probe. - * @i2s: Our local i2s structure to fill in. - */ -extern void s3c_i2sv2_cleanup(struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s); -/** - * s3c_i2sv2_register_component - register component and dai with soc core - * @dev: DAI device - * @id: DAI ID - * @drv: The driver structure to register - * - * Fill in any missing fields and then register the given dai with the - * soc core. - */ -extern int s3c_i2sv2_register_component(struct device *dev, int id, - const struct snd_soc_component_driver *cmp_drv, - struct snd_soc_dai_driver *dai_drv); - -#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c deleted file mode 100644 index 0579a352961c..000000000000 --- a/sound/soc/samsung/s3c2412-i2s.c +++ /dev/null @@ -1,251 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// ALSA Soc Audio Layer - S3C2412 I2S driver -// -// Copyright (c) 2006 Wolfson Microelectronics PLC. -// Graeme Gregory graeme.gregory@wolfsonmicro.com -// linux@wolfsonmicro.com -// -// Copyright (c) 2007, 2004-2005 Simtec Electronics -// http://armlinux.simtec.co.uk/ -// Ben Dooks <ben@simtec.co.uk> - -#include <linux/delay.h> -#include <linux/gpio.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/module.h> - -#include <sound/soc.h> -#include <sound/pcm_params.h> - -#include "dma.h" -#include "regs-i2s-v2.h" -#include "s3c2412-i2s.h" - -#include <linux/platform_data/asoc-s3c.h> - -static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_out = { - .chan_name = "tx", - .addr_width = 4, -}; - -static struct snd_dmaengine_dai_dma_data s3c2412_i2s_pcm_stereo_in = { - .chan_name = "rx", - .addr_width = 4, -}; - -static struct s3c_i2sv2_info s3c2412_i2s; - -static int s3c2412_i2s_probe(struct snd_soc_dai *dai) -{ - int ret; - - pr_debug("Entered %s\n", __func__); - - snd_soc_dai_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out, - &s3c2412_i2s_pcm_stereo_in); - - ret = s3c_i2sv2_probe(dai, &s3c2412_i2s); - if (ret) - return ret; - - s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; - s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; - - s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk"); - if (IS_ERR(s3c2412_i2s.iis_cclk)) { - pr_err("failed to get i2sclk clock\n"); - ret = PTR_ERR(s3c2412_i2s.iis_cclk); - goto err; - } - - /* Set MPLL as the source for IIS CLK */ - - clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); - ret = clk_prepare_enable(s3c2412_i2s.iis_cclk); - if (ret) - goto err; - - return 0; - -err: - s3c_i2sv2_cleanup(dai, &s3c2412_i2s); - - return ret; -} - -static int s3c2412_i2s_remove(struct snd_soc_dai *dai) -{ - clk_disable_unprepare(s3c2412_i2s.iis_cclk); - s3c_i2sv2_cleanup(dai, &s3c2412_i2s); - - return 0; -} - -static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); - - switch (params_width(params)) { - case 8: - iismod |= S3C2412_IISMOD_8BIT; - break; - case 16: - iismod &= ~S3C2412_IISMOD_8BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c2412_i2s_suspend(struct snd_soc_component *component) -{ - struct s3c_i2sv2_info *i2s = snd_soc_component_get_drvdata(component); - u32 iismod; - - if (component->active) { - i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); - i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); - i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); - - /* some basic suspend checks */ - - iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) - pr_warn("%s: RXDMA active?\n", __func__); - - if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) - pr_warn("%s: TXDMA active?\n", __func__); - - if (iismod & S3C2412_IISCON_IIS_ACTIVE) - pr_warn("%s: IIS active\n", __func__); - } - - return 0; -} - -static int s3c2412_i2s_resume(struct snd_soc_component *component) -{ - struct s3c_i2sv2_info *i2s = snd_soc_component_get_drvdata(component); - - pr_info("component_active %d, IISMOD %08x, IISCON %08x\n", - component->active, i2s->suspend_iismod, i2s->suspend_iiscon); - - if (component->active) { - writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); - writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); - writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); - - writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, - i2s->regs + S3C2412_IISFIC); - - ndelay(250); - writel(0x0, i2s->regs + S3C2412_IISFIC); - } - - return 0; -} -#else -#define s3c2412_i2s_suspend NULL -#define s3c2412_i2s_resume NULL -#endif - -#define S3C2412_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -static const struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { - .hw_params = s3c2412_i2s_hw_params, -}; - -static struct snd_soc_dai_driver s3c2412_i2s_dai = { - .probe = s3c2412_i2s_probe, - .remove = s3c2412_i2s_remove, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C2412_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C2412_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &s3c2412_i2s_dai_ops, -}; - -static const struct snd_soc_component_driver s3c2412_i2s_component = { - .name = "s3c2412-i2s", - .suspend = s3c2412_i2s_suspend, - .resume = s3c2412_i2s_resume, - .legacy_dai_naming = 1, -}; - -static int s3c2412_iis_dev_probe(struct platform_device *pdev) -{ - int ret = 0; - struct resource *res; - struct s3c_audio_pdata *pdata = dev_get_platdata(&pdev->dev); - - if (!pdata) { - dev_err(&pdev->dev, "missing platform data"); - return -ENXIO; - } - - s3c2412_i2s.regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(s3c2412_i2s.regs)) - return PTR_ERR(s3c2412_i2s.regs); - - s3c2412_i2s_pcm_stereo_out.addr = res->start + S3C2412_IISTXD; - s3c2412_i2s_pcm_stereo_out.filter_data = pdata->dma_playback; - s3c2412_i2s_pcm_stereo_in.addr = res->start + S3C2412_IISRXD; - s3c2412_i2s_pcm_stereo_in.filter_data = pdata->dma_capture; - - ret = samsung_asoc_dma_platform_register(&pdev->dev, - pdata->dma_filter, - "tx", "rx", NULL); - if (ret) { - pr_err("failed to register the DMA: %d\n", ret); - return ret; - } - - ret = s3c_i2sv2_register_component(&pdev->dev, -1, - &s3c2412_i2s_component, - &s3c2412_i2s_dai); - if (ret) - pr_err("failed to register the dai\n"); - - return ret; -} - -static struct platform_driver s3c2412_iis_driver = { - .probe = s3c2412_iis_dev_probe, - .driver = { - .name = "s3c2412-iis", - }, -}; - -module_platform_driver(s3c2412_iis_driver); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c2412-iis"); diff --git a/sound/soc/samsung/s3c2412-i2s.h b/sound/soc/samsung/s3c2412-i2s.h deleted file mode 100644 index bff2a797cb08..000000000000 --- a/sound/soc/samsung/s3c2412-i2s.h +++ /dev/null @@ -1,22 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * ALSA Soc Audio Layer - S3C2412 I2S driver - * - * Copyright (c) 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks <ben@simtec.co.uk> - */ - -#ifndef __SND_SOC_S3C24XX_S3C2412_I2S_H -#define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__ - -#include "s3c-i2s-v2.h" - -#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK -#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK -#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER - -#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK -#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS - -#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c deleted file mode 100644 index 7b7bbe007acd..000000000000 --- a/sound/soc/samsung/s3c24xx-i2s.c +++ /dev/null @@ -1,463 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// s3c24xx-i2s.c -- ALSA Soc Audio Layer -// -// (c) 2006 Wolfson Microelectronics PLC. -// Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com -// -// Copyright 2004-2005 Simtec Electronics -// http://armlinux.simtec.co.uk/ -// Ben Dooks <ben@simtec.co.uk> - -#include <linux/delay.h> -#include <linux/clk.h> -#include <linux/io.h> -#include <linux/module.h> - -#include <sound/soc.h> -#include <sound/pcm_params.h> - -#include "regs-iis.h" -#include "dma.h" -#include "s3c24xx-i2s.h" - -static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_out = { - .chan_name = "tx", - .addr_width = 2, -}; - -static struct snd_dmaengine_dai_dma_data s3c24xx_i2s_pcm_stereo_in = { - .chan_name = "rx", - .addr_width = 2, -}; - -struct s3c24xx_i2s_info { - void __iomem *regs; - struct clk *iis_clk; - u32 iiscon; - u32 iismod; - u32 iisfcon; - u32 iispsr; -}; -static struct s3c24xx_i2s_info s3c24xx_i2s; - -static void s3c24xx_snd_txctrl(int on) -{ - u32 iisfcon; - u32 iiscon; - u32 iismod; - - iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); - iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - - pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); - - if (on) { - iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; - iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; - iiscon &= ~S3C2410_IISCON_TXIDLE; - iismod |= S3C2410_IISMOD_TXMODE; - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - } else { - /* note, we have to disable the FIFOs otherwise bad things - * seem to happen when the DMA stops. According to the - * Samsung supplied kernel, this should allow the DMA - * engine and FIFOs to reset. If this isn't allowed, the - * DMA engine will simply freeze randomly. - */ - - iisfcon &= ~S3C2410_IISFCON_TXENABLE; - iisfcon &= ~S3C2410_IISFCON_TXDMA; - iiscon |= S3C2410_IISCON_TXIDLE; - iiscon &= ~S3C2410_IISCON_TXDMAEN; - iismod &= ~S3C2410_IISMOD_TXMODE; - - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - } - - pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); -} - -static void s3c24xx_snd_rxctrl(int on) -{ - u32 iisfcon; - u32 iiscon; - u32 iismod; - - iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); - iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - - pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); - - if (on) { - iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; - iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; - iiscon &= ~S3C2410_IISCON_RXIDLE; - iismod |= S3C2410_IISMOD_RXMODE; - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - } else { - /* note, we have to disable the FIFOs otherwise bad things - * seem to happen when the DMA stops. According to the - * Samsung supplied kernel, this should allow the DMA - * engine and FIFOs to reset. If this isn't allowed, the - * DMA engine will simply freeze randomly. - */ - - iisfcon &= ~S3C2410_IISFCON_RXENABLE; - iisfcon &= ~S3C2410_IISFCON_RXDMA; - iiscon |= S3C2410_IISCON_RXIDLE; - iiscon &= ~S3C2410_IISCON_RXDMAEN; - iismod &= ~S3C2410_IISMOD_RXMODE; - - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - } - - pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); -} - -/* - * Wait for the LR signal to allow synchronisation to the L/R clock - * from the codec. May only be needed for slave mode. - */ -static int s3c24xx_snd_lrsync(void) -{ - u32 iiscon; - int timeout = 50; /* 5ms */ - - while (1) { - iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - if (iiscon & S3C2410_IISCON_LRINDEX) - break; - - if (!timeout--) - return -ETIMEDOUT; - udelay(100); - } - - return 0; -} - -/* - * Check whether CPU is the master or slave - */ -static inline int s3c24xx_snd_is_clkmaster(void) -{ - return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; -} - -/* - * Set S3C24xx I2S DAI format - */ -static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - u32 iismod; - - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params r: IISMOD: %x \n", iismod); - - switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BC_FC: - iismod |= S3C2410_IISMOD_SLAVE; - break; - case SND_SOC_DAIFMT_BP_FP: - iismod &= ~S3C2410_IISMOD_SLAVE; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_LEFT_J: - iismod |= S3C2410_IISMOD_MSB; - break; - case SND_SOC_DAIFMT_I2S: - iismod &= ~S3C2410_IISMOD_MSB; - break; - default: - return -EINVAL; - } - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params w: IISMOD: %x \n", iismod); - - return 0; -} - -static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_dmaengine_dai_dma_data *dma_data; - u32 iismod; - - dma_data = snd_soc_dai_get_dma_data(dai, substream); - - /* Working copies of register */ - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params r: IISMOD: %x\n", iismod); - - switch (params_width(params)) { - case 8: - iismod &= ~S3C2410_IISMOD_16BIT; - dma_data->addr_width = 1; - break; - case 16: - iismod |= S3C2410_IISMOD_16BIT; - dma_data->addr_width = 2; - break; - default: - return -EINVAL; - } - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params w: IISMOD: %x\n", iismod); - - return 0; -} - -static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (!s3c24xx_snd_is_clkmaster()) { - ret = s3c24xx_snd_lrsync(); - if (ret) - goto exit_err; - } - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c24xx_snd_rxctrl(1); - else - s3c24xx_snd_txctrl(1); - - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c24xx_snd_rxctrl(0); - else - s3c24xx_snd_txctrl(0); - break; - default: - ret = -EINVAL; - break; - } - -exit_err: - return ret; -} - -/* - * Set S3C24xx Clock source - */ -static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - - iismod &= ~S3C2440_IISMOD_MPLL; - - switch (clk_id) { - case S3C24XX_CLKSRC_PCLK: - break; - case S3C24XX_CLKSRC_MPLL: - iismod |= S3C2440_IISMOD_MPLL; - break; - default: - return -EINVAL; - } - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - return 0; -} - -/* - * Set S3C24xx Clock dividers - */ -static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - u32 reg; - - switch (div_id) { - case S3C24XX_DIV_BCLK: - reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; - writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); - break; - case S3C24XX_DIV_MCLK: - reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); - writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); - break; - case S3C24XX_DIV_PRESCALER: - writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR); - reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON); - break; - default: - return -EINVAL; - } - - return 0; -} - -/* - * To avoid duplicating clock code, allow machine driver to - * get the clockrate from here. - */ -u32 s3c24xx_i2s_get_clockrate(void) -{ - return clk_get_rate(s3c24xx_i2s.iis_clk); -} -EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); - -static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) -{ - int ret; - snd_soc_dai_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out, - &s3c24xx_i2s_pcm_stereo_in); - - s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis"); - if (IS_ERR(s3c24xx_i2s.iis_clk)) { - pr_err("failed to get iis_clock\n"); - return PTR_ERR(s3c24xx_i2s.iis_clk); - } - ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); - if (ret) - return ret; - - writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); - - s3c24xx_snd_txctrl(0); - s3c24xx_snd_rxctrl(0); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c24xx_i2s_suspend(struct snd_soc_component *component) -{ - s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - s3c24xx_i2s.iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); - s3c24xx_i2s.iispsr = readl(s3c24xx_i2s.regs + S3C2410_IISPSR); - - clk_disable_unprepare(s3c24xx_i2s.iis_clk); - - return 0; -} - -static int s3c24xx_i2s_resume(struct snd_soc_component *component) -{ - int ret; - - ret = clk_prepare_enable(s3c24xx_i2s.iis_clk); - if (ret) - return ret; - - writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - writel(s3c24xx_i2s.iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(s3c24xx_i2s.iispsr, s3c24xx_i2s.regs + S3C2410_IISPSR); - - return 0; -} -#else -#define s3c24xx_i2s_suspend NULL -#define s3c24xx_i2s_resume NULL -#endif - -#define S3C24XX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -static const struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { - .trigger = s3c24xx_i2s_trigger, - .hw_params = s3c24xx_i2s_hw_params, - .set_fmt = s3c24xx_i2s_set_fmt, - .set_clkdiv = s3c24xx_i2s_set_clkdiv, - .set_sysclk = s3c24xx_i2s_set_sysclk, -}; - -static struct snd_soc_dai_driver s3c24xx_i2s_dai = { - .probe = s3c24xx_i2s_probe, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C24XX_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C24XX_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c24xx_i2s_dai_ops, -}; - -static const struct snd_soc_component_driver s3c24xx_i2s_component = { - .name = "s3c24xx-i2s", - .suspend = s3c24xx_i2s_suspend, - .resume = s3c24xx_i2s_resume, - .legacy_dai_naming = 1, -}; - -static int s3c24xx_iis_dev_probe(struct platform_device *pdev) -{ - struct resource *res; - int ret; - - s3c24xx_i2s.regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res); - if (IS_ERR(s3c24xx_i2s.regs)) - return PTR_ERR(s3c24xx_i2s.regs); - - s3c24xx_i2s_pcm_stereo_out.addr = res->start + S3C2410_IISFIFO; - s3c24xx_i2s_pcm_stereo_in.addr = res->start + S3C2410_IISFIFO; - - ret = samsung_asoc_dma_platform_register(&pdev->dev, NULL, - "tx", "rx", NULL); - if (ret) { - dev_err(&pdev->dev, "Failed to register the DMA: %d\n", ret); - return ret; - } - - ret = devm_snd_soc_register_component(&pdev->dev, - &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); - if (ret) - dev_err(&pdev->dev, "Failed to register the DAI\n"); - - return ret; -} - -static struct platform_driver s3c24xx_iis_driver = { - .probe = s3c24xx_iis_dev_probe, - .driver = { - .name = "s3c24xx-iis", - }, -}; - -module_platform_driver(s3c24xx_iis_driver); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c24xx-iis"); diff --git a/sound/soc/samsung/s3c24xx-i2s.h b/sound/soc/samsung/s3c24xx-i2s.h deleted file mode 100644 index e073e31855d0..000000000000 --- a/sound/soc/samsung/s3c24xx-i2s.h +++ /dev/null @@ -1,31 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * s3c24xx-i2s.c -- ALSA Soc Audio Layer - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Revision history - * 10th Nov 2006 Initial version. - */ - -#ifndef S3C24XXI2S_H_ -#define S3C24XXI2S_H_ - -/* clock sources */ -#define S3C24XX_CLKSRC_PCLK 0 -#define S3C24XX_CLKSRC_MPLL 1 - -/* Clock dividers */ -#define S3C24XX_DIV_MCLK 0 -#define S3C24XX_DIV_BCLK 1 -#define S3C24XX_DIV_PRESCALER 2 - -/* prescaler */ -#define S3C24XX_PRESCALE(a,b) \ - (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT)) - -u32 s3c24xx_i2s_get_clockrate(void); - -#endif /*S3C24XXI2S_H_*/ diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c deleted file mode 100644 index 0cc66774b85d..000000000000 --- a/sound/soc/samsung/s3c24xx_simtec.c +++ /dev/null @@ -1,372 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright 2009 Simtec Electronics - -#include <linux/gpio.h> -#include <linux/clk.h> -#include <linux/module.h> - -#include <sound/soc.h> - -#include <linux/platform_data/asoc-s3c24xx_simtec.h> - -#include "s3c24xx-i2s.h" -#include "s3c24xx_simtec.h" - -static struct s3c24xx_audio_simtec_pdata *pdata; -static struct clk *xtal_clk; - -static int spk_gain; -static int spk_unmute; - -/** - * speaker_gain_get - read the speaker gain setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be updated. - * - * Read the value for the AMP gain control. - */ -static int speaker_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = spk_gain; - return 0; -} - -/** - * speaker_gain_set - set the value of the speaker amp gain - * @value: The value to write. - */ -static void speaker_gain_set(int value) -{ - gpio_set_value_cansleep(pdata->amp_gain[0], value & 1); - gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1); -} - -/** - * speaker_gain_put - set the speaker gain setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be set. - * - * Set the value of the speaker gain from the specified - * @ucontrol setting. - * - * Note, if the speaker amp is muted, then we do not set a gain value - * as at-least one of the ICs that is fitted will try and power up even - * if the main control is set to off. - */ -static int speaker_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int value = ucontrol->value.integer.value[0]; - - spk_gain = value; - - if (!spk_unmute) - speaker_gain_set(value); - - return 0; -} - -static const struct snd_kcontrol_new amp_gain_controls[] = { - SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0, - speaker_gain_get, speaker_gain_put), -}; - -/** - * spk_unmute_state - set the unmute state of the speaker - * @to: zero to unmute, non-zero to ununmute. - */ -static void spk_unmute_state(int to) -{ - pr_debug("%s: to=%d\n", __func__, to); - - spk_unmute = to; - gpio_set_value(pdata->amp_gpio, to); - - /* if we're umuting, also re-set the gain */ - if (to && pdata->amp_gain[0] > 0) - speaker_gain_set(spk_gain); -} - -/** - * speaker_unmute_get - read the speaker unmute setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be updated. - * - * Read the value for the AMP gain control. - */ -static int speaker_unmute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = spk_unmute; - return 0; -} - -/** - * speaker_unmute_put - set the speaker unmute setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be set. - * - * Set the value of the speaker gain from the specified - * @ucontrol setting. - */ -static int speaker_unmute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - spk_unmute_state(ucontrol->value.integer.value[0]); - return 0; -} - -/* This is added as a manual control as the speaker amps create clicks - * when their power state is changed, which are far more noticeable than - * anything produced by the CODEC itself. - */ -static const struct snd_kcontrol_new amp_unmute_controls[] = { - SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0, - speaker_unmute_get, speaker_unmute_put), -}; - -void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_card *card = rtd->card; - - if (pdata->amp_gpio > 0) { - pr_debug("%s: adding amp routes\n", __func__); - - snd_soc_add_card_controls(card, amp_unmute_controls, - ARRAY_SIZE(amp_unmute_controls)); - } - - if (pdata->amp_gain[0] > 0) { - pr_debug("%s: adding amp controls\n", __func__); - snd_soc_add_card_controls(card, amp_gain_controls, - ARRAY_SIZE(amp_gain_controls)); - } -} -EXPORT_SYMBOL_GPL(simtec_audio_init); - -#define CODEC_CLOCK 12000000 - -/** - * simtec_hw_params - update hardware parameters - * @substream: The audio substream instance. - * @params: The parameters requested. - * - * Update the codec data routing and configuration settings - * from the supplied data. - */ -static int simtec_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int ret; - - ret = snd_soc_dai_set_sysclk(codec_dai, 0, - CODEC_CLOCK, SND_SOC_CLOCK_IN); - if (ret) { - pr_err( "%s: failed setting codec sysclk\n", __func__); - return ret; - } - - if (pdata->use_mpllin) { - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL, - 0, SND_SOC_CLOCK_OUT); - - if (ret) { - pr_err("%s: failed to set MPLLin as clksrc\n", - __func__); - return ret; - } - } - - if (pdata->output_cdclk) { - int cdclk_scale; - - cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK; - cdclk_scale--; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - cdclk_scale); - if (ret) { - pr_err("%s: failed to set clock div\n", - __func__); - return ret; - } - } - - return 0; -} - -static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) -{ - /* call any board supplied startup code, this currently only - * covers the bast/vr1000 which have a CPLD in the way of the - * LRCLK */ - if (pd->startup) - pd->startup(); - - return 0; -} - -static const struct snd_soc_ops simtec_snd_ops = { - .hw_params = simtec_hw_params, -}; - -/** - * attach_gpio_amp - get and configure the necessary gpios - * @dev: The device we're probing. - * @pd: The platform data supplied by the board. - * - * If there is a GPIO based amplifier attached to the board, claim - * the necessary GPIO lines for it, and set default values. - */ -static int attach_gpio_amp(struct device *dev, - struct s3c24xx_audio_simtec_pdata *pd) -{ - int ret; - - /* attach gpio amp gain (if any) */ - if (pdata->amp_gain[0] > 0) { - ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0"); - if (ret) { - dev_err(dev, "cannot get amp gpio gain0\n"); - return ret; - } - - ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1"); - if (ret) { - dev_err(dev, "cannot get amp gpio gain1\n"); - gpio_free(pdata->amp_gain[0]); - return ret; - } - - gpio_direction_output(pd->amp_gain[0], 0); - gpio_direction_output(pd->amp_gain[1], 0); - } - - /* note, currently we assume GPA0 isn't valid amp */ - if (pdata->amp_gpio > 0) { - ret = gpio_request(pd->amp_gpio, "gpio-amp"); - if (ret) { - dev_err(dev, "cannot get amp gpio %d (%d)\n", - pd->amp_gpio, ret); - goto err_amp; - } - - /* set the amp off at startup */ - spk_unmute_state(0); - } - - return 0; - -err_amp: - if (pd->amp_gain[0] > 0) { - gpio_free(pd->amp_gain[0]); - gpio_free(pd->amp_gain[1]); - } - - return ret; -} - -static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd) -{ - if (pd->amp_gain[0] > 0) { - gpio_free(pd->amp_gain[0]); - gpio_free(pd->amp_gain[1]); - } - - if (pd->amp_gpio > 0) - gpio_free(pd->amp_gpio); -} - -#ifdef CONFIG_PM -static int simtec_audio_resume(struct device *dev) -{ - simtec_call_startup(pdata); - return 0; -} - -const struct dev_pm_ops simtec_audio_pmops = { - .resume = simtec_audio_resume, -}; -EXPORT_SYMBOL_GPL(simtec_audio_pmops); -#endif - -int simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct platform_device *snd_dev; - int ret; - - card->dai_link->ops = &simtec_snd_ops; - card->dai_link->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "no platform data supplied\n"); - return -EINVAL; - } - - simtec_call_startup(pdata); - - xtal_clk = clk_get(&pdev->dev, "xtal"); - if (IS_ERR(xtal_clk)) { - dev_err(&pdev->dev, "could not get clkout0\n"); - return -EINVAL; - } - - dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk)); - - ret = attach_gpio_amp(&pdev->dev, pdata); - if (ret) - goto err_clk; - - snd_dev = platform_device_alloc("soc-audio", -1); - if (!snd_dev) { - dev_err(&pdev->dev, "failed to alloc soc-audio device\n"); - ret = -ENOMEM; - goto err_gpio; - } - - platform_set_drvdata(snd_dev, card); - - ret = platform_device_add(snd_dev); - if (ret) { - dev_err(&pdev->dev, "failed to add soc-audio dev\n"); - goto err_pdev; - } - - platform_set_drvdata(pdev, snd_dev); - return 0; - -err_pdev: - platform_device_put(snd_dev); - -err_gpio: - detach_gpio_amp(pdata); - -err_clk: - clk_put(xtal_clk); - return ret; -} -EXPORT_SYMBOL_GPL(simtec_audio_core_probe); - -int simtec_audio_remove(struct platform_device *pdev) -{ - struct platform_device *snd_dev = platform_get_drvdata(pdev); - - platform_device_unregister(snd_dev); - - detach_gpio_amp(pdata); - clk_put(xtal_clk); - return 0; -} -EXPORT_SYMBOL_GPL(simtec_audio_remove); - -MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_simtec.h b/sound/soc/samsung/s3c24xx_simtec.h deleted file mode 100644 index 38d8384755cd..000000000000 --- a/sound/soc/samsung/s3c24xx_simtec.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright 2009 Simtec Electronics - */ - -extern void simtec_audio_init(struct snd_soc_pcm_runtime *rtd); - -extern int simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_card *card); - -extern int simtec_audio_remove(struct platform_device *pdev); - -#ifdef CONFIG_PM -extern const struct dev_pm_ops simtec_audio_pmops; -#define simtec_audio_pm &simtec_audio_pmops -#else -#define simtec_audio_pm NULL -#endif diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c deleted file mode 100644 index ed0d1b8fa2d4..000000000000 --- a/sound/soc/samsung/s3c24xx_simtec_hermes.c +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright 2009 Simtec Electronics - -#include <linux/module.h> -#include <sound/soc.h> - -#include "s3c24xx_simtec.h" - -static const struct snd_soc_dapm_widget dapm_widgets[] = { - SND_SOC_DAPM_LINE("GSM Out", NULL), - SND_SOC_DAPM_LINE("GSM In", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_LINE("ZV", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_HP("Headphone Jack", NULL), -}; - -static const struct snd_soc_dapm_route base_map[] = { - /* Headphone connected to HP{L,R}OUT and HP{L,R}COM */ - - { "Headphone Jack", NULL, "HPLOUT" }, - { "Headphone Jack", NULL, "HPLCOM" }, - { "Headphone Jack", NULL, "HPROUT" }, - { "Headphone Jack", NULL, "HPRCOM" }, - - /* ZV connected to Line1 */ - - { "LINE1L", NULL, "ZV" }, - { "LINE1R", NULL, "ZV" }, - - /* Line In connected to Line2 */ - - { "LINE2L", NULL, "Line In" }, - { "LINE2R", NULL, "Line In" }, - - /* Microphone connected to MIC3R and MIC_BIAS */ - - { "MIC3L", NULL, "Mic Jack" }, - - /* GSM connected to MONO_LOUT and MIC3L (in) */ - - { "GSM Out", NULL, "MONO_LOUT" }, - { "MIC3L", NULL, "GSM In" }, - - /* Speaker is connected to LINEOUT{LN,LP,RN,RP}, however we are - * not using the DAPM to power it up and down as there it makes - * a click when powering up. */ -}; - -/** - * simtec_hermes_init - initialise and add controls - * @codec; The codec instance to attach to. - * - * Attach our controls and configure the necessary codec - * mappings for our sound card instance. -*/ -static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) -{ - simtec_audio_init(rtd); - - return 0; -} - -SND_SOC_DAILINK_DEFS(tlv320aic33, - DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.0-001a", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); - -static struct snd_soc_dai_link simtec_dai_aic33 = { - .name = "tlv320aic33", - .stream_name = "TLV320AIC33", - .init = simtec_hermes_init, - SND_SOC_DAILINK_REG(tlv320aic33), -}; - -/* simtec audio machine driver */ -static struct snd_soc_card snd_soc_machine_simtec_aic33 = { - .name = "Simtec-Hermes", - .owner = THIS_MODULE, - .dai_link = &simtec_dai_aic33, - .num_links = 1, - - .dapm_widgets = dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), - .dapm_routes = base_map, - .num_dapm_routes = ARRAY_SIZE(base_map), -}; - -static int simtec_audio_hermes_probe(struct platform_device *pd) -{ - dev_info(&pd->dev, "probing....\n"); - return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33); -} - -static struct platform_driver simtec_audio_hermes_platdrv = { - .driver = { - .name = "s3c24xx-simtec-hermes-snd", - .pm = simtec_audio_pm, - }, - .probe = simtec_audio_hermes_probe, - .remove = simtec_audio_remove, -}; - -module_platform_driver(simtec_audio_hermes_platdrv); - -MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd"); -MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c deleted file mode 100644 index c03d52990267..000000000000 --- a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c +++ /dev/null @@ -1,100 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright 2009 Simtec Electronics - -#include <linux/module.h> -#include <sound/soc.h> - -#include "s3c24xx_simtec.h" - -/* supported machines: - * - * Machine Connections AMP - * ------- ----------- --- - * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired) - * VR1000 HPOUT, LIN None - * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) - * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) - * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R) - */ - -static const struct snd_soc_dapm_widget dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), -}; - -static const struct snd_soc_dapm_route base_map[] = { - { "Headphone Jack", NULL, "LHPOUT"}, - { "Headphone Jack", NULL, "RHPOUT"}, - - { "Line Out", NULL, "LOUT" }, - { "Line Out", NULL, "ROUT" }, - - { "LLINEIN", NULL, "Line In"}, - { "RLINEIN", NULL, "Line In"}, - - { "MICIN", NULL, "Mic Jack"}, -}; - -/** - * simtec_tlv320aic23_init - initialise and add controls - * @codec; The codec instance to attach to. - * - * Attach our controls and configure the necessary codec - * mappings for our sound card instance. -*/ -static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) -{ - simtec_audio_init(rtd); - - return 0; -} - -SND_SOC_DAILINK_DEFS(tlv320aic23, - DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.0-001a", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); - -static struct snd_soc_dai_link simtec_dai_aic23 = { - .name = "tlv320aic23", - .stream_name = "TLV320AIC23", - .init = simtec_tlv320aic23_init, - SND_SOC_DAILINK_REG(tlv320aic23), -}; - -/* simtec audio machine driver */ -static struct snd_soc_card snd_soc_machine_simtec_aic23 = { - .name = "Simtec", - .owner = THIS_MODULE, - .dai_link = &simtec_dai_aic23, - .num_links = 1, - - .dapm_widgets = dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(dapm_widgets), - .dapm_routes = base_map, - .num_dapm_routes = ARRAY_SIZE(base_map), -}; - -static int simtec_audio_tlv320aic23_probe(struct platform_device *pd) -{ - return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23); -} - -static struct platform_driver simtec_audio_tlv320aic23_driver = { - .driver = { - .name = "s3c24xx-simtec-tlv320aic23", - .pm = simtec_audio_pm, - }, - .probe = simtec_audio_tlv320aic23_probe, - .remove = simtec_audio_remove, -}; - -module_platform_driver(simtec_audio_tlv320aic23_driver); - -MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23"); -MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); -MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c deleted file mode 100644 index 6272070dcd92..000000000000 --- a/sound/soc/samsung/s3c24xx_uda134x.c +++ /dev/null @@ -1,257 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Modifications by Christian Pellegrin <chripell@evolware.org> -// -// s3c24xx_uda134x.c - S3C24XX_UDA134X ALSA SoC Audio board driver -// -// Copyright 2007 Dension Audio Systems Ltd. -// Author: Zoltan Devai - -#include <linux/clk.h> -#include <linux/gpio.h> -#include <linux/module.h> - -#include <sound/soc.h> -#include <sound/s3c24xx_uda134x.h> - -#include "regs-iis.h" -#include "s3c24xx-i2s.h" - -struct s3c24xx_uda134x { - struct clk *xtal; - struct clk *pclk; - struct mutex clk_lock; - int clk_users; -}; - -/* #define ENFORCE_RATES 1 */ -/* - Unfortunately the S3C24XX in master mode has a limited capacity of - generating the clock for the codec. If you define this only rates - that are really available will be enforced. But be careful, most - user level application just want the usual sampling frequencies (8, - 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly - operation for embedded systems. So if you aren't very lucky or your - hardware engineer wasn't very forward-looking it's better to leave - this undefined. If you do so an approximate value for the requested - sampling rate in the range -/+ 5% will be chosen. If this in not - possible an error will be returned. -*/ - -static unsigned int rates[33 * 2]; -#ifdef ENFORCE_RATES -static const struct snd_pcm_hw_constraint_list hw_constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; -#endif - -static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct s3c24xx_uda134x *priv = snd_soc_card_get_drvdata(rtd->card); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - int ret = 0; - - mutex_lock(&priv->clk_lock); - - if (priv->clk_users == 0) { - priv->xtal = clk_get(rtd->dev, "xtal"); - if (IS_ERR(priv->xtal)) { - dev_err(rtd->dev, "%s cannot get xtal\n", __func__); - ret = PTR_ERR(priv->xtal); - } else { - priv->pclk = clk_get(cpu_dai->dev, "iis"); - if (IS_ERR(priv->pclk)) { - dev_err(rtd->dev, "%s cannot get pclk\n", - __func__); - clk_put(priv->xtal); - ret = PTR_ERR(priv->pclk); - } - } - if (!ret) { - int i, j; - - for (i = 0; i < 2; i++) { - int fs = i ? 256 : 384; - - rates[i*33] = clk_get_rate(priv->xtal) / fs; - for (j = 1; j < 33; j++) - rates[i*33 + j] = clk_get_rate(priv->pclk) / - (j * fs); - } - } - } - priv->clk_users += 1; - mutex_unlock(&priv->clk_lock); - - if (!ret) { -#ifdef ENFORCE_RATES - ret = snd_pcm_hw_constraint_list(substream->runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &hw_constraints_rates); - if (ret < 0) - dev_err(rtd->dev, "%s cannot set constraints\n", - __func__); -#endif - } - return ret; -} - -static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct s3c24xx_uda134x *priv = snd_soc_card_get_drvdata(rtd->card); - - mutex_lock(&priv->clk_lock); - priv->clk_users -= 1; - if (priv->clk_users == 0) { - clk_put(priv->xtal); - priv->xtal = NULL; - clk_put(priv->pclk); - priv->pclk = NULL; - } - mutex_unlock(&priv->clk_lock); -} - -static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int clk = 0; - int ret = 0; - int clk_source, fs_mode; - unsigned long rate = params_rate(params); - long err, cerr; - unsigned int div; - int i, bi; - - err = 999999; - bi = 0; - for (i = 0; i < 2*33; i++) { - cerr = rates[i] - rate; - if (cerr < 0) - cerr = -cerr; - if (cerr < err) { - err = cerr; - bi = i; - } - } - if (bi / 33 == 1) - fs_mode = S3C2410_IISMOD_256FS; - else - fs_mode = S3C2410_IISMOD_384FS; - if (bi % 33 == 0) { - clk_source = S3C24XX_CLKSRC_MPLL; - div = 1; - } else { - clk_source = S3C24XX_CLKSRC_PCLK; - div = bi % 33; - } - - dev_dbg(rtd->dev, "%s desired rate %lu, %d\n", __func__, rate, bi); - - clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; - - dev_dbg(rtd->dev, "%s will use: %s %s %d sysclk %d err %ld\n", __func__, - fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", - clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", - div, clk, err); - - if ((err * 100 / rate) > 5) { - dev_err(rtd->dev, "effective frequency too different " - "from desired (%ld%%)\n", err * 100 / rate); - return -EINVAL; - } - - ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(div, div)); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - return 0; -} - -static const struct snd_soc_ops s3c24xx_uda134x_ops = { - .startup = s3c24xx_uda134x_startup, - .shutdown = s3c24xx_uda134x_shutdown, - .hw_params = s3c24xx_uda134x_hw_params, -}; - -SND_SOC_DAILINK_DEFS(uda134x, - DAILINK_COMP_ARRAY(COMP_CPU("s3c24xx-iis")), - DAILINK_COMP_ARRAY(COMP_CODEC("uda134x-codec", "uda134x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("s3c24xx-iis"))); - -static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { - .name = "UDA134X", - .stream_name = "UDA134X", - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &s3c24xx_uda134x_ops, - SND_SOC_DAILINK_REG(uda134x), -}; - -static struct snd_soc_card snd_soc_s3c24xx_uda134x = { - .name = "S3C24XX_UDA134X", - .owner = THIS_MODULE, - .dai_link = &s3c24xx_uda134x_dai_link, - .num_links = 1, -}; - -static int s3c24xx_uda134x_probe(struct platform_device *pdev) -{ - struct snd_soc_card *card = &snd_soc_s3c24xx_uda134x; - struct s3c24xx_uda134x *priv; - int ret; - - priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); - if (!priv) - return -ENOMEM; - - mutex_init(&priv->clk_lock); - - card->dev = &pdev->dev; - snd_soc_card_set_drvdata(card, priv); - - ret = devm_snd_soc_register_card(&pdev->dev, card); - if (ret) - dev_err(&pdev->dev, "failed to register card: %d\n", ret); - - return ret; -} - -static struct platform_driver s3c24xx_uda134x_driver = { - .probe = s3c24xx_uda134x_probe, - .driver = { - .name = "s3c24xx_uda134x", - }, -}; -module_platform_driver(s3c24xx_uda134x_driver); - -MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin <chripell@evolware.org>"); -MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c deleted file mode 100644 index 29bf917242fe..000000000000 --- a/sound/soc/samsung/smartq_wm8987.c +++ /dev/null @@ -1,224 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// Copyright 2010 Maurus Cuelenaere <mcuelenaere@gmail.com> -// -// Based on smdk6410_wm8987.c -// Copyright 2007 Wolfson Microelectronics PLC. - linux@wolfsonmicro.com -// Graeme Gregory - graeme.gregory@wolfsonmicro.com - -#include <linux/gpio/consumer.h> -#include <linux/module.h> - -#include <sound/soc.h> -#include <sound/jack.h> - -#include "i2s.h" -#include "../codecs/wm8750.h" - -/* - * WM8987 is register compatible with WM8750, so using that as base driver. - */ - -static struct snd_soc_card snd_soc_smartq; - -static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); - unsigned int clk = 0; - int ret; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 32000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - case 88200: - clk = 11289600; - break; - } - - /* Use PCLK for I2S signal generation */ - ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* Gate the RCLK output on PAD */ - ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -/* - * SmartQ WM8987 HiFi DAI operations. - */ -static const struct snd_soc_ops smartq_hifi_ops = { - .hw_params = smartq_hifi_hw_params, -}; - -static struct snd_soc_jack smartq_jack; - -static struct snd_soc_jack_pin smartq_jack_pins[] = { - /* Disable speaker when headphone is plugged in */ - { - .pin = "Internal Speaker", - .mask = SND_JACK_HEADPHONE, - }, -}; - -static struct snd_soc_jack_gpio smartq_jack_gpios[] = { - { - .gpio = -1, - .name = "headphone detect", - .report = SND_JACK_HEADPHONE, - .debounce_time = 200, - }, -}; - -static const struct snd_kcontrol_new wm8987_smartq_controls[] = { - SOC_DAPM_PIN_SWITCH("Internal Speaker"), - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Internal Mic"), -}; - -static int smartq_speaker_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, - int event) -{ - struct gpio_desc *gpio = snd_soc_card_get_drvdata(&snd_soc_smartq); - - gpiod_set_value(gpio, SND_SOC_DAPM_EVENT_OFF(event)); - - return 0; -} - -static const struct snd_soc_dapm_widget wm8987_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Internal Speaker", smartq_speaker_event), - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Internal Mic", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Jack", NULL, "LOUT2"}, - {"Headphone Jack", NULL, "ROUT2"}, - - {"Internal Speaker", NULL, "LOUT2"}, - {"Internal Speaker", NULL, "ROUT2"}, - - {"Mic Bias", NULL, "Internal Mic"}, - {"LINPUT2", NULL, "Mic Bias"}, -}; - -static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_dapm_context *dapm = &rtd->card->dapm; - int err = 0; - - /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(dapm, "LINPUT1"); - snd_soc_dapm_nc_pin(dapm, "RINPUT1"); - snd_soc_dapm_nc_pin(dapm, "OUT3"); - snd_soc_dapm_nc_pin(dapm, "ROUT1"); - - /* Headphone jack detection */ - err = snd_soc_card_jack_new_pins(rtd->card, "Headphone Jack", - SND_JACK_HEADPHONE, &smartq_jack, - smartq_jack_pins, - ARRAY_SIZE(smartq_jack_pins)); - if (err) - return err; - - err = snd_soc_jack_add_gpios(&smartq_jack, - ARRAY_SIZE(smartq_jack_gpios), - smartq_jack_gpios); - - return err; -} - -SND_SOC_DAILINK_DEFS(wm8987, - DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.0")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8750.0-0x1a", "wm8750-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0"))); - -static struct snd_soc_dai_link smartq_dai[] = { - { - .name = "wm8987", - .stream_name = "SmartQ Hi-Fi", - .init = smartq_wm8987_init, - .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &smartq_hifi_ops, - SND_SOC_DAILINK_REG(wm8987), - }, -}; - -static struct snd_soc_card snd_soc_smartq = { - .name = "SmartQ", - .owner = THIS_MODULE, - .dai_link = smartq_dai, - .num_links = ARRAY_SIZE(smartq_dai), - - .dapm_widgets = wm8987_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(wm8987_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), - .controls = wm8987_smartq_controls, - .num_controls = ARRAY_SIZE(wm8987_smartq_controls), -}; - -static int smartq_probe(struct platform_device *pdev) -{ - struct gpio_desc *gpio; - int ret; - - platform_set_drvdata(pdev, &snd_soc_smartq); - - /* Initialise GPIOs used by amplifiers */ - gpio = devm_gpiod_get(&pdev->dev, "amplifiers shutdown", - GPIOD_OUT_HIGH); - if (IS_ERR(gpio)) { - dev_err(&pdev->dev, "Failed to register GPK12\n"); - ret = PTR_ERR(gpio); - goto out; - } - snd_soc_card_set_drvdata(&snd_soc_smartq, gpio); - - ret = devm_snd_soc_register_card(&pdev->dev, &snd_soc_smartq); - if (ret) - dev_err(&pdev->dev, "Failed to register card\n"); - -out: - return ret; -} - -static struct platform_driver smartq_driver = { - .driver = { - .name = "smartq-audio", - }, - .probe = smartq_probe, -}; - -module_platform_driver(smartq_driver); - -/* Module information */ -MODULE_AUTHOR("Maurus Cuelenaere <mcuelenaere@gmail.com>"); -MODULE_DESCRIPTION("ALSA SoC SmartQ WM8987"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c deleted file mode 100644 index 78703d095a6f..000000000000 --- a/sound/soc/samsung/smdk_wm8580.c +++ /dev/null @@ -1,211 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// Copyright (c) 2009 Samsung Electronics Co. Ltd -// Author: Jaswinder Singh <jassisinghbrar@gmail.com> - -#include <linux/module.h> -#include <sound/soc.h> -#include <sound/pcm_params.h> - -#include "../codecs/wm8580.h" -#include "i2s.h" - -/* - * Default CFG switch settings to use this driver: - * - * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On - */ - -/* SMDK has a 12MHZ crystal attached to WM8580 */ -#define SMDK_WM8580_FREQ 12000000 - -static int smdk_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - unsigned int pll_out; - int rfs, ret; - - switch (params_width(params)) { - case 8: - case 16: - break; - default: - return -EINVAL; - } - - /* The Fvco for WM8580 PLLs must fall within [90,100]MHz. - * This criterion can't be met if we request PLL output - * as {8000x256, 64000x256, 11025x256}Hz. - * As a wayout, we rather change rfs to a minimum value that - * results in (params_rate(params) * rfs), and itself, acceptable - * to both - the CODEC and the CPU. - */ - switch (params_rate(params)) { - case 16000: - case 22050: - case 32000: - case 44100: - case 48000: - case 88200: - case 96000: - rfs = 256; - break; - case 64000: - rfs = 384; - break; - case 8000: - case 11025: - rfs = 512; - break; - default: - return -EINVAL; - } - pll_out = params_rate(params) * rfs; - - /* Set WM8580 to drive MCLK from its PLLA */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, - WM8580_CLKSRC_PLLA); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, - SMDK_WM8580_FREQ, pll_out); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA, - pll_out, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -/* - * SMDK WM8580 DAI operations. - */ -static const struct snd_soc_ops smdk_ops = { - .hw_params = smdk_hw_params, -}; - -/* SMDK Playback widgets */ -static const struct snd_soc_dapm_widget smdk_wm8580_dapm_widgets[] = { - SND_SOC_DAPM_HP("Front", NULL), - SND_SOC_DAPM_HP("Center+Sub", NULL), - SND_SOC_DAPM_HP("Rear", NULL), - - SND_SOC_DAPM_MIC("MicIn", NULL), - SND_SOC_DAPM_LINE("LineIn", NULL), -}; - -/* SMDK-PAIFTX connections */ -static const struct snd_soc_dapm_route smdk_wm8580_audio_map[] = { - /* MicIn feeds AINL */ - {"AINL", NULL, "MicIn"}, - - /* LineIn feeds AINL/R */ - {"AINL", NULL, "LineIn"}, - {"AINR", NULL, "LineIn"}, - - /* Front Left/Right are fed VOUT1L/R */ - {"Front", NULL, "VOUT1L"}, - {"Front", NULL, "VOUT1R"}, - - /* Center/Sub are fed VOUT2L/R */ - {"Center+Sub", NULL, "VOUT2L"}, - {"Center+Sub", NULL, "VOUT2R"}, - - /* Rear Left/Right are fed VOUT3L/R */ - {"Rear", NULL, "VOUT3L"}, - {"Rear", NULL, "VOUT3R"}, -}; - -static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) -{ - /* Enabling the microphone requires the fitting of a 0R - * resistor to connect the line from the microphone jack. - */ - snd_soc_dapm_disable_pin(&rtd->card->dapm, "MicIn"); - - return 0; -} - -enum { - PRI_PLAYBACK = 0, - PRI_CAPTURE, -}; - -#define SMDK_DAI_FMT (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | \ - SND_SOC_DAIFMT_CBM_CFM) - -SND_SOC_DAILINK_DEFS(paif_rx, - DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.2")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8580.0-001b", "wm8580-hifi-playback")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0"))); - -SND_SOC_DAILINK_DEFS(paif_tx, - DAILINK_COMP_ARRAY(COMP_CPU("samsung-i2s.2")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8580.0-001b", "wm8580-hifi-capture")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("samsung-i2s.0"))); - -static struct snd_soc_dai_link smdk_dai[] = { - [PRI_PLAYBACK] = { /* Primary Playback i/f */ - .name = "WM8580 PAIF RX", - .stream_name = "Playback", - .dai_fmt = SMDK_DAI_FMT, - .ops = &smdk_ops, - SND_SOC_DAILINK_REG(paif_rx), - }, - [PRI_CAPTURE] = { /* Primary Capture i/f */ - .name = "WM8580 PAIF TX", - .stream_name = "Capture", - .dai_fmt = SMDK_DAI_FMT, - .init = smdk_wm8580_init_paiftx, - .ops = &smdk_ops, - SND_SOC_DAILINK_REG(paif_tx), - }, -}; - -static struct snd_soc_card smdk = { - .name = "SMDK-I2S", - .owner = THIS_MODULE, - .dai_link = smdk_dai, - .num_links = ARRAY_SIZE(smdk_dai), - - .dapm_widgets = smdk_wm8580_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(smdk_wm8580_dapm_widgets), - .dapm_routes = smdk_wm8580_audio_map, - .num_dapm_routes = ARRAY_SIZE(smdk_wm8580_audio_map), -}; - -static struct platform_device *smdk_snd_device; - -static int __init smdk_audio_init(void) -{ - int ret; - - smdk_snd_device = platform_device_alloc("soc-audio", -1); - if (!smdk_snd_device) - return -ENOMEM; - - platform_set_drvdata(smdk_snd_device, &smdk); - ret = platform_device_add(smdk_snd_device); - - if (ret) - platform_device_put(smdk_snd_device); - - return ret; -} -module_init(smdk_audio_init); - -static void __exit smdk_audio_exit(void) -{ - platform_device_unregister(smdk_snd_device); -} -module_exit(smdk_audio_exit); - -MODULE_AUTHOR("Jaswinder Singh, jassisinghbrar@gmail.com"); -MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c index c3be24b2fac5..a79a2fb260b8 100644 --- a/sound/soc/soc-topology.c +++ b/sound/soc/soc-topology.c @@ -1401,13 +1401,17 @@ static int soc_tplg_dapm_widget_create(struct soc_tplg *tplg, template.num_kcontrols = le32_to_cpu(w->num_kcontrols); kc = devm_kcalloc(tplg->dev, le32_to_cpu(w->num_kcontrols), sizeof(*kc), GFP_KERNEL); - if (!kc) + if (!kc) { + ret = -ENOMEM; goto hdr_err; + } kcontrol_type = devm_kcalloc(tplg->dev, le32_to_cpu(w->num_kcontrols), sizeof(unsigned int), GFP_KERNEL); - if (!kcontrol_type) + if (!kcontrol_type) { + ret = -ENOMEM; goto hdr_err; + } for (i = 0; i < le32_to_cpu(w->num_kcontrols); i++) { control_hdr = (struct snd_soc_tplg_ctl_hdr *)tplg->pos; diff --git a/sound/soc/sof/amd/acp.c b/sound/soc/sof/amd/acp.c index 6bd2888fbb66..d5ccd4d09278 100644 --- a/sound/soc/sof/amd/acp.c +++ b/sound/soc/sof/amd/acp.c @@ -318,7 +318,6 @@ static irqreturn_t acp_irq_thread(int irq, void *context) { struct snd_sof_dev *sdev = context; const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata); - unsigned int base = desc->dsp_intr_base; unsigned int val, count = ACP_HW_SEM_RETRY_COUNT; val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->ext_intr_stat); @@ -328,28 +327,20 @@ static irqreturn_t acp_irq_thread(int irq, void *context) return IRQ_HANDLED; } - val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET); - if (val & ACP_DSP_TO_HOST_IRQ) { - while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset)) { - /* Wait until acquired HW Semaphore lock or timeout */ - count--; - if (!count) { - dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__); - return IRQ_NONE; - } + while (snd_sof_dsp_read(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset)) { + /* Wait until acquired HW Semaphore lock or timeout */ + count--; + if (!count) { + dev_err(sdev->dev, "%s: Failed to acquire HW lock\n", __func__); + return IRQ_NONE; } - - sof_ops(sdev)->irq_thread(irq, sdev); - val |= ACP_DSP_TO_HOST_IRQ; - snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, val); - - /* Unlock or Release HW Semaphore */ - snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0); - - return IRQ_HANDLED; } - return IRQ_NONE; + sof_ops(sdev)->irq_thread(irq, sdev); + /* Unlock or Release HW Semaphore */ + snd_sof_dsp_write(sdev, ACP_DSP_BAR, desc->hw_semaphore_offset, 0x0); + + return IRQ_HANDLED; }; static irqreturn_t acp_irq_handler(int irq, void *dev_id) @@ -360,8 +351,11 @@ static irqreturn_t acp_irq_handler(int irq, void *dev_id) unsigned int val; val = snd_sof_dsp_read(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET); - if (val) + if (val) { + val |= ACP_DSP_TO_HOST_IRQ; + snd_sof_dsp_write(sdev, ACP_DSP_BAR, base + DSP_SW_INTR_STAT_OFFSET, val); return IRQ_WAKE_THREAD; + } return IRQ_NONE; } diff --git a/sound/soc/sof/debug.c b/sound/soc/sof/debug.c index d9a3ce7b69e1..ade0507328af 100644 --- a/sound/soc/sof/debug.c +++ b/sound/soc/sof/debug.c @@ -353,7 +353,9 @@ int snd_sof_dbg_init(struct snd_sof_dev *sdev) return err; } - return 0; + return snd_sof_debugfs_buf_item(sdev, &sdev->fw_state, + sizeof(sdev->fw_state), + "fw_state", 0444); } EXPORT_SYMBOL_GPL(snd_sof_dbg_init); diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 1c3d4887aa30..a642c3067ec5 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -216,6 +216,10 @@ static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, sdev = snd_soc_component_get_drvdata(cpu_dai->component); bus = sof_to_bus(sdev); + hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); + if (!hlink) + return -EINVAL; + hext_stream = snd_soc_dai_get_dma_data(cpu_dai, substream); if (!hext_stream) { hext_stream = hda_link_stream_assign(bus, substream); @@ -225,10 +229,6 @@ static int hda_link_dma_hw_params(struct snd_pcm_substream *substream, snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)hext_stream); } - hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); - if (!hlink) - return -EINVAL; - /* set the hdac_stream in the codec dai */ snd_soc_dai_set_stream(codec_dai, hdac_stream(hext_stream), substream->stream); diff --git a/sound/soc/sof/ipc4-mtrace.c b/sound/soc/sof/ipc4-mtrace.c index 70dea8ae706e..0ec6ef681012 100644 --- a/sound/soc/sof/ipc4-mtrace.c +++ b/sound/soc/sof/ipc4-mtrace.c @@ -344,9 +344,10 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file, size_t count, loff_t *ppos) { struct sof_mtrace_priv *priv = file->private_data; - int id, ret; + unsigned int id; char *buf; u32 mask; + int ret; /* * To update Nth mask entry, write: @@ -357,9 +358,9 @@ static ssize_t sof_ipc4_priority_mask_dfs_write(struct file *file, if (IS_ERR(buf)) return PTR_ERR(buf); - ret = sscanf(buf, "%d,0x%x", &id, &mask); + ret = sscanf(buf, "%u,0x%x", &id, &mask); if (ret != 2) { - ret = sscanf(buf, "%d,%x", &id, &mask); + ret = sscanf(buf, "%u,%x", &id, &mask); if (ret != 2) { ret = -EINVAL; goto out; diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index c52752250565..3b3f3cf7af38 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -357,7 +357,7 @@ static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar, } static inline void snd_sof_dsp_update8(struct snd_sof_dev *sdev, u32 bar, - u32 offset, u8 value, u8 mask) + u32 offset, u8 mask, u8 value) { u8 reg; diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index df740be645e8..8722bbd7fd3d 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -182,7 +182,7 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm; const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg; pm_message_t pm_state; - u32 target_state = 0; + u32 target_state = snd_sof_dsp_power_target(sdev); int ret; /* do nothing if dsp suspend callback is not set */ @@ -192,6 +192,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) if (runtime_suspend && !sof_ops(sdev)->runtime_suspend) return 0; + if (tplg_ops && tplg_ops->tear_down_all_pipelines) + tplg_ops->tear_down_all_pipelines(sdev, false); + if (sdev->fw_state != SOF_FW_BOOT_COMPLETE) goto suspend; @@ -206,7 +209,6 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) } } - target_state = snd_sof_dsp_power_target(sdev); pm_state.event = target_state; /* Skip to platform-specific suspend if DSP is entering D0 */ @@ -217,9 +219,6 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) goto suspend; } - if (tplg_ops->tear_down_all_pipelines) - tplg_ops->tear_down_all_pipelines(sdev, false); - /* suspend DMA trace */ sof_fw_trace_suspend(sdev, pm_state); diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 7306a2649857..865c367eb2f2 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -271,9 +271,9 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg struct snd_sof_widget *swidget = widget->dobj.private; struct snd_soc_dapm_path *p; - /* return if the widget is in use or if it is already unprepared */ - if (!swidget->prepared || swidget->use_count > 1) - return; + /* skip if the widget is in use or if it is already unprepared */ + if (!swidget || !swidget->prepared || swidget->use_count > 0) + goto sink_unprepare; if (widget_ops[widget->id].ipc_unprepare) /* unprepare the source widget */ @@ -281,6 +281,7 @@ sof_unprepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widg swidget->prepared = false; +sink_unprepare: /* unprepare all widgets in the sink paths */ snd_soc_dapm_widget_for_each_sink_path(widget, p) { if (!p->walking && p->sink->dobj.private) { @@ -303,7 +304,7 @@ sof_prepare_widgets_in_path(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget struct snd_soc_dapm_path *p; int ret; - if (!widget_ops[widget->id].ipc_prepare || swidget->prepared) + if (!swidget || !widget_ops[widget->id].ipc_prepare || swidget->prepared) goto sink_prepare; /* prepare the source widget */ @@ -326,7 +327,8 @@ sink_prepare: p->walking = false; if (ret < 0) { /* unprepare the source widget */ - if (widget_ops[widget->id].ipc_unprepare && swidget->prepared) { + if (widget_ops[widget->id].ipc_unprepare && + swidget && swidget->prepared) { widget_ops[widget->id].ipc_unprepare(swidget); swidget->prepared = false; } @@ -429,11 +431,11 @@ sof_walk_widgets_in_order(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget_l for_each_dapm_widgets(list, i, widget) { /* starting widget for playback is AIF type */ - if (dir == SNDRV_PCM_STREAM_PLAYBACK && !WIDGET_IS_AIF(widget->id)) + if (dir == SNDRV_PCM_STREAM_PLAYBACK && widget->id != snd_soc_dapm_aif_in) continue; /* starting widget for capture is DAI type */ - if (dir == SNDRV_PCM_STREAM_CAPTURE && !WIDGET_IS_DAI(widget->id)) + if (dir == SNDRV_PCM_STREAM_CAPTURE && widget->id != snd_soc_dapm_dai_out) continue; switch (op) { diff --git a/sound/soc/ti/Kconfig b/sound/soc/ti/Kconfig index 40110e9a9e8a..593be22503b5 100644 --- a/sound/soc/ti/Kconfig +++ b/sound/soc/ti/Kconfig @@ -40,13 +40,6 @@ config SND_SOC_DAVINCI_MCASP - Keystone devices - K3 devices (am654, j721e) -config SND_SOC_DAVINCI_VCIF - tristate "daVinci Voice Interface (VCIF) support" - depends on ARCH_DAVINCI || COMPILE_TEST - select SND_SOC_TI_EDMA_PCM - help - Say Y or M here if you want audio support via daVinci VCIF. - config SND_SOC_OMAP_DMIC tristate "Digital Microphone Module (DMIC) support" depends on ARCH_OMAP4 || SOC_OMAP5 || COMPILE_TEST && COMMON_CLK @@ -177,14 +170,6 @@ config SND_SOC_OMAP_OSK5912 config SND_SOC_DAVINCI_EVM tristate "SoC Audio support for DaVinci EVMs" depends on ARCH_DAVINCI && I2C - select SND_SOC_DAVINCI_ASP if MACH_DAVINCI_DM355_EVM - select SND_SOC_DAVINCI_ASP if SND_SOC_DM365_AIC3X_CODEC - select SND_SOC_DAVINCI_VCIF if SND_SOC_DM365_VOICE_CODEC - select SND_SOC_DAVINCI_ASP if MACH_DAVINCI_EVM # DM6446 - select SND_SOC_DAVINCI_MCASP if MACH_DAVINCI_DM6467_EVM - select SND_SOC_SPDIF if MACH_DAVINCI_DM6467_EVM - select SND_SOC_DAVINCI_MCASP if MACH_DAVINCI_DA830_EVM - select SND_SOC_DAVINCI_MCASP if MACH_DAVINCI_DA850_EVM select SND_SOC_TLV320AIC3X help Say Y if you want to add support for SoC audio on the following TI @@ -196,31 +181,6 @@ config SND_SOC_DAVINCI_EVM - DM830 - DM850 -choice - prompt "DM365 codec select" - depends on SND_SOC_DAVINCI_EVM - depends on MACH_DAVINCI_DM365_EVM - -config SND_SOC_DM365_AIC3X_CODEC - bool "Audio Codec - AIC3101" - help - Say Y if you want to add support for AIC3101 audio codec - -config SND_SOC_DM365_VOICE_CODEC - bool "Voice Codec - CQ93VC" - help - Say Y if you want to add support for SoC On-chip voice codec -endchoice - -config SND_SOC_DM365_SELECT_VOICE_CODECS - def_tristate y - depends on SND_SOC_DM365_VOICE_CODEC && SND_SOC - select MFD_DAVINCI_VOICECODEC - select SND_SOC_CQ0093VC - help - The is an internal symbol needed to ensure that the codec - and MFD driver can be built as loadable modules if necessary. - config SND_SOC_J721E_EVM tristate "SoC Audio support for j721e EVM" depends on ARCH_K3 || COMPILE_TEST && COMMON_CLK diff --git a/sound/soc/ti/Makefile b/sound/soc/ti/Makefile index a21e5b0061de..41cdcaec770d 100644 --- a/sound/soc/ti/Makefile +++ b/sound/soc/ti/Makefile @@ -12,14 +12,12 @@ obj-$(CONFIG_SND_SOC_TI_UDMA_PCM) += snd-soc-ti-udma.o # CPU DAI drivers snd-soc-davinci-asp-objs := davinci-i2s.o snd-soc-davinci-mcasp-objs := davinci-mcasp.o -snd-soc-davinci-vcif-objs := davinci-vcif.o snd-soc-omap-dmic-objs := omap-dmic.o snd-soc-omap-mcbsp-objs := omap-mcbsp.o omap-mcbsp-st.o snd-soc-omap-mcpdm-objs := omap-mcpdm.o obj-$(CONFIG_SND_SOC_DAVINCI_ASP) += snd-soc-davinci-asp.o obj-$(CONFIG_SND_SOC_DAVINCI_MCASP) += snd-soc-davinci-mcasp.o -obj-$(CONFIG_SND_SOC_DAVINCI_VCIF) += snd-soc-davinci-vcif.o obj-$(CONFIG_SND_SOC_OMAP_DMIC) += snd-soc-omap-dmic.o obj-$(CONFIG_SND_SOC_OMAP_MCBSP) += snd-soc-omap-mcbsp.o obj-$(CONFIG_SND_SOC_OMAP_MCPDM) += snd-soc-omap-mcpdm.o diff --git a/sound/soc/ti/davinci-evm.c b/sound/soc/ti/davinci-evm.c index 68d69e32681a..983d69b951b0 100644 --- a/sound/soc/ti/davinci-evm.c +++ b/sound/soc/ti/davinci-evm.c @@ -138,214 +138,6 @@ static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) return 0; } -/* davinci-evm digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(dm6446, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcbsp")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.1-001b", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcbsp"))); - -static struct snd_soc_dai_link dm6446_evm_dai = { - .name = "TLV320AIC3X", - .stream_name = "AIC3X", - .init = evm_aic3x_init, - .ops = &evm_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(dm6446), -}; - -SND_SOC_DAILINK_DEFS(dm355, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcbsp.1")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.1-001b", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcbsp.1"))); - -static struct snd_soc_dai_link dm355_evm_dai = { - .name = "TLV320AIC3X", - .stream_name = "AIC3X", - .init = evm_aic3x_init, - .ops = &evm_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(dm355), -}; - -#ifdef CONFIG_SND_SOC_DM365_AIC3X_CODEC -SND_SOC_DAILINK_DEFS(dm365, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcbsp")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.1-0018", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcbsp"))); -#elif defined(CONFIG_SND_SOC_DM365_VOICE_CODEC) -SND_SOC_DAILINK_DEFS(dm365, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-vcif")), - DAILINK_COMP_ARRAY(COMP_CODEC("cq93vc-codec", "cq93vc-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-vcif"))); -#endif - -static struct snd_soc_dai_link dm365_evm_dai = { -#ifdef CONFIG_SND_SOC_DM365_AIC3X_CODEC - .name = "TLV320AIC3X", - .stream_name = "AIC3X", - .init = evm_aic3x_init, - .ops = &evm_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(dm365), -#elif defined(CONFIG_SND_SOC_DM365_VOICE_CODEC) - .name = "Voice Codec - CQ93VC", - .stream_name = "CQ93", - SND_SOC_DAILINK_REG(dm365), -#endif -}; - -SND_SOC_DAILINK_DEFS(dm6467_aic3x, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcasp.0")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.0-001a", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcasp.0"))); - -SND_SOC_DAILINK_DEFS(dm6467_spdif, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcasp.1")), - DAILINK_COMP_ARRAY(COMP_CODEC("spdif_dit", "dit-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcasp.1"))); - -static struct snd_soc_dai_link dm6467_evm_dai[] = { - { - .name = "TLV320AIC3X", - .stream_name = "AIC3X", - .init = evm_aic3x_init, - .ops = &evm_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(dm6467_aic3x), - }, - { - .name = "McASP", - .stream_name = "spdif", - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(dm6467_spdif), - }, -}; - -SND_SOC_DAILINK_DEFS(da830, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcasp.1")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.1-0018", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcasp.1"))); - -static struct snd_soc_dai_link da830_evm_dai = { - .name = "TLV320AIC3X", - .stream_name = "AIC3X", - .init = evm_aic3x_init, - .ops = &evm_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(da830), -}; - -SND_SOC_DAILINK_DEFS(da850, - DAILINK_COMP_ARRAY(COMP_CPU("davinci-mcasp.0")), - DAILINK_COMP_ARRAY(COMP_CODEC("tlv320aic3x-codec.1-0018", - "tlv320aic3x-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("davinci-mcasp.0"))); - -static struct snd_soc_dai_link da850_evm_dai = { - .name = "TLV320AIC3X", - .stream_name = "AIC3X", - .init = evm_aic3x_init, - .ops = &evm_ops, - .dai_fmt = SND_SOC_DAIFMT_DSP_B | SND_SOC_DAIFMT_CBM_CFM | - SND_SOC_DAIFMT_IB_NF, - SND_SOC_DAILINK_REG(da850), -}; - -/* davinci dm6446 evm audio machine driver */ -/* - * ASP0 in DM6446 EVM is clocked by U55, as configured by - * board-dm644x-evm.c using GPIOs from U18. There are six - * options; here we "know" we use a 48 KHz sample rate. - */ -static struct snd_soc_card_drvdata_davinci dm6446_snd_soc_card_drvdata = { - .sysclk = 12288000, -}; - -static struct snd_soc_card dm6446_snd_soc_card_evm = { - .name = "DaVinci DM6446 EVM", - .owner = THIS_MODULE, - .dai_link = &dm6446_evm_dai, - .num_links = 1, - .drvdata = &dm6446_snd_soc_card_drvdata, -}; - -/* davinci dm355 evm audio machine driver */ -/* ASP1 on DM355 EVM is clocked by an external oscillator */ -static struct snd_soc_card_drvdata_davinci dm355_snd_soc_card_drvdata = { - .sysclk = 27000000, -}; - -static struct snd_soc_card dm355_snd_soc_card_evm = { - .name = "DaVinci DM355 EVM", - .owner = THIS_MODULE, - .dai_link = &dm355_evm_dai, - .num_links = 1, - .drvdata = &dm355_snd_soc_card_drvdata, -}; - -/* davinci dm365 evm audio machine driver */ -static struct snd_soc_card_drvdata_davinci dm365_snd_soc_card_drvdata = { - .sysclk = 27000000, -}; - -static struct snd_soc_card dm365_snd_soc_card_evm = { - .name = "DaVinci DM365 EVM", - .owner = THIS_MODULE, - .dai_link = &dm365_evm_dai, - .num_links = 1, - .drvdata = &dm365_snd_soc_card_drvdata, -}; - -/* davinci dm6467 evm audio machine driver */ -static struct snd_soc_card_drvdata_davinci dm6467_snd_soc_card_drvdata = { - .sysclk = 27000000, -}; - -static struct snd_soc_card dm6467_snd_soc_card_evm = { - .name = "DaVinci DM6467 EVM", - .owner = THIS_MODULE, - .dai_link = dm6467_evm_dai, - .num_links = ARRAY_SIZE(dm6467_evm_dai), - .drvdata = &dm6467_snd_soc_card_drvdata, -}; - -static struct snd_soc_card_drvdata_davinci da830_snd_soc_card_drvdata = { - .sysclk = 24576000, -}; - -static struct snd_soc_card da830_snd_soc_card = { - .name = "DA830/OMAP-L137 EVM", - .owner = THIS_MODULE, - .dai_link = &da830_evm_dai, - .num_links = 1, - .drvdata = &da830_snd_soc_card_drvdata, -}; - -static struct snd_soc_card_drvdata_davinci da850_snd_soc_card_drvdata = { - .sysclk = 24576000, -}; - -static struct snd_soc_card da850_snd_soc_card = { - .name = "DA850/OMAP-L138 EVM", - .owner = THIS_MODULE, - .dai_link = &da850_evm_dai, - .num_links = 1, - .drvdata = &da850_snd_soc_card_drvdata, -}; - -#if defined(CONFIG_OF) - /* * The struct is used as place holder. It will be completely * filled with data from dt node. @@ -461,71 +253,18 @@ static struct platform_driver davinci_evm_driver = { .driver = { .name = "davinci_evm", .pm = &snd_soc_pm_ops, - .of_match_table = of_match_ptr(davinci_evm_dt_ids), + .of_match_table = davinci_evm_dt_ids, }, }; -#endif - -static struct platform_device *evm_snd_device; static int __init evm_init(void) { - struct snd_soc_card *evm_snd_dev_data; - int index; - int ret; - - /* - * If dtb is there, the devices will be created dynamically. - * Only register platfrom driver structure. - */ -#if defined(CONFIG_OF) - if (of_have_populated_dt()) - return platform_driver_register(&davinci_evm_driver); -#endif - - if (machine_is_davinci_evm()) { - evm_snd_dev_data = &dm6446_snd_soc_card_evm; - index = 0; - } else if (machine_is_davinci_dm355_evm()) { - evm_snd_dev_data = &dm355_snd_soc_card_evm; - index = 1; - } else if (machine_is_davinci_dm365_evm()) { - evm_snd_dev_data = &dm365_snd_soc_card_evm; - index = 0; - } else if (machine_is_davinci_dm6467_evm()) { - evm_snd_dev_data = &dm6467_snd_soc_card_evm; - index = 0; - } else if (machine_is_davinci_da830_evm()) { - evm_snd_dev_data = &da830_snd_soc_card; - index = 1; - } else if (machine_is_davinci_da850_evm()) { - evm_snd_dev_data = &da850_snd_soc_card; - index = 0; - } else - return -EINVAL; - - evm_snd_device = platform_device_alloc("soc-audio", index); - if (!evm_snd_device) - return -ENOMEM; - - platform_set_drvdata(evm_snd_device, evm_snd_dev_data); - ret = platform_device_add(evm_snd_device); - if (ret) - platform_device_put(evm_snd_device); - - return ret; + return platform_driver_register(&davinci_evm_driver); } static void __exit evm_exit(void) { -#if defined(CONFIG_OF) - if (of_have_populated_dt()) { - platform_driver_unregister(&davinci_evm_driver); - return; - } -#endif - - platform_device_unregister(evm_snd_device); + platform_driver_unregister(&davinci_evm_driver); } module_init(evm_init); diff --git a/sound/soc/ti/davinci-vcif.c b/sound/soc/ti/davinci-vcif.c deleted file mode 100644 index 36fa97e2b9e2..000000000000 --- a/sound/soc/ti/davinci-vcif.c +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * ALSA SoC Voice Codec Interface for TI DAVINCI processor - * - * Copyright (C) 2010 Texas Instruments. - * - * Author: Miguel Aguilar <miguel.aguilar@ridgerun.com> - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/device.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <linux/io.h> -#include <linux/mfd/davinci_voicecodec.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/initval.h> -#include <sound/soc.h> -#include <sound/dmaengine_pcm.h> - -#include "edma-pcm.h" -#include "davinci-i2s.h" - -#define MOD_REG_BIT(val, mask, set) do { \ - if (set) { \ - val |= mask; \ - } else { \ - val &= ~mask; \ - } \ -} while (0) - -struct davinci_vcif_dev { - struct davinci_vc *davinci_vc; - struct snd_dmaengine_dai_dma_data dma_data[2]; - int dma_request[2]; -}; - -static void davinci_vcif_start(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct davinci_vcif_dev *davinci_vcif_dev = - snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); - struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; - u32 w; - - /* Start the sample generator and enable transmitter/receiver */ - w = readl(davinci_vc->base + DAVINCI_VC_CTRL); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 0); - else - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 0); - - writel(w, davinci_vc->base + DAVINCI_VC_CTRL); -} - -static void davinci_vcif_stop(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct davinci_vcif_dev *davinci_vcif_dev = - snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0)); - struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; - u32 w; - - /* Reset transmitter/receiver and sample rate/frame sync generators */ - w = readl(davinci_vc->base + DAVINCI_VC_CTRL); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTDAC, 1); - else - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RSTADC, 1); - - writel(w, davinci_vc->base + DAVINCI_VC_CTRL); -} - -static int davinci_vcif_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct davinci_vcif_dev *davinci_vcif_dev = snd_soc_dai_get_drvdata(dai); - struct davinci_vc *davinci_vc = davinci_vcif_dev->davinci_vc; - u32 w; - - /* Restart the codec before setup */ - davinci_vcif_stop(substream); - davinci_vcif_start(substream); - - /* General line settings */ - writel(DAVINCI_VC_CTRL_MASK, davinci_vc->base + DAVINCI_VC_CTRL); - - writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTCLR); - - writel(DAVINCI_VC_INT_MASK, davinci_vc->base + DAVINCI_VC_INTEN); - - w = readl(davinci_vc->base + DAVINCI_VC_CTRL); - - /* Determine xfer data type */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_U8: - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | - DAVINCI_VC_CTRL_RD_UNSIGNED | - DAVINCI_VC_CTRL_WD_BITS_8 | - DAVINCI_VC_CTRL_WD_UNSIGNED, 1); - break; - case SNDRV_PCM_FORMAT_S8: - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | - DAVINCI_VC_CTRL_WD_BITS_8, 1); - - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_UNSIGNED | - DAVINCI_VC_CTRL_WD_UNSIGNED, 0); - break; - case SNDRV_PCM_FORMAT_S16_LE: - MOD_REG_BIT(w, DAVINCI_VC_CTRL_RD_BITS_8 | - DAVINCI_VC_CTRL_RD_UNSIGNED | - DAVINCI_VC_CTRL_WD_BITS_8 | - DAVINCI_VC_CTRL_WD_UNSIGNED, 0); - break; - default: - printk(KERN_WARNING "davinci-vcif: unsupported PCM format"); - return -EINVAL; - } - - writel(w, davinci_vc->base + DAVINCI_VC_CTRL); - - return 0; -} - -static int davinci_vcif_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int ret = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - davinci_vcif_start(substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - davinci_vcif_stop(substream); - break; - default: - ret = -EINVAL; - } - - return ret; -} - -#define DAVINCI_VCIF_RATES SNDRV_PCM_RATE_8000_48000 - -static const struct snd_soc_dai_ops davinci_vcif_dai_ops = { - .trigger = davinci_vcif_trigger, - .hw_params = davinci_vcif_hw_params, -}; - -static int davinci_vcif_dai_probe(struct snd_soc_dai *dai) -{ - struct davinci_vcif_dev *dev = snd_soc_dai_get_drvdata(dai); - - dai->playback_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK]; - dai->capture_dma_data = &dev->dma_data[SNDRV_PCM_STREAM_CAPTURE]; - - return 0; -} - -static struct snd_soc_dai_driver davinci_vcif_dai = { - .probe = davinci_vcif_dai_probe, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = DAVINCI_VCIF_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = DAVINCI_VCIF_RATES, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &davinci_vcif_dai_ops, - -}; - -static const struct snd_soc_component_driver davinci_vcif_component = { - .name = "davinci-vcif", - .legacy_dai_naming = 1, -}; - -static int davinci_vcif_probe(struct platform_device *pdev) -{ - struct davinci_vc *davinci_vc = pdev->dev.platform_data; - struct davinci_vcif_dev *davinci_vcif_dev; - int ret; - - davinci_vcif_dev = devm_kzalloc(&pdev->dev, - sizeof(struct davinci_vcif_dev), - GFP_KERNEL); - if (!davinci_vcif_dev) - return -ENOMEM; - - /* DMA tx params */ - davinci_vcif_dev->davinci_vc = davinci_vc; - davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].filter_data = - &davinci_vc->davinci_vcif.dma_tx_channel; - davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_PLAYBACK].addr = - davinci_vc->davinci_vcif.dma_tx_addr; - - /* DMA rx params */ - davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].filter_data = - &davinci_vc->davinci_vcif.dma_rx_channel; - davinci_vcif_dev->dma_data[SNDRV_PCM_STREAM_CAPTURE].addr = - davinci_vc->davinci_vcif.dma_rx_addr; - - dev_set_drvdata(&pdev->dev, davinci_vcif_dev); - - ret = devm_snd_soc_register_component(&pdev->dev, - &davinci_vcif_component, - &davinci_vcif_dai, 1); - if (ret != 0) { - dev_err(&pdev->dev, "could not register dai\n"); - return ret; - } - - ret = edma_pcm_platform_register(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "register PCM failed: %d\n", ret); - return ret; - } - - return 0; -} - -static struct platform_driver davinci_vcif_driver = { - .probe = davinci_vcif_probe, - .driver = { - .name = "davinci-vcif", - }, -}; - -module_platform_driver(davinci_vcif_driver); - -MODULE_AUTHOR("Miguel Aguilar"); -MODULE_DESCRIPTION("Texas Instruments DaVinci ASoC Voice Codec Interface"); -MODULE_LICENSE("GPL"); diff --git a/sound/synth/emux/emux_nrpn.c b/sound/synth/emux/emux_nrpn.c index 8056422ed7c5..0d6b82ae2955 100644 --- a/sound/synth/emux/emux_nrpn.c +++ b/sound/synth/emux/emux_nrpn.c @@ -349,6 +349,9 @@ int snd_emux_xg_control(struct snd_emux_port *port, struct snd_midi_channel *chan, int param) { + if (param >= ARRAY_SIZE(chan->control)) + return -EINVAL; + return send_converted_effect(xg_effects, ARRAY_SIZE(xg_effects), port, chan, param, chan->control[param], diff --git a/sound/usb/implicit.c b/sound/usb/implicit.c index 41ac7185b42b..4727043fd745 100644 --- a/sound/usb/implicit.c +++ b/sound/usb/implicit.c @@ -471,7 +471,7 @@ snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip, subs = find_matching_substream(chip, stream, target->sync_ep, target->fmt_type); if (!subs) - return sync_fmt; + goto end; high_score = 0; list_for_each_entry(fp, &subs->fmt_list, list) { @@ -485,6 +485,7 @@ snd_usb_find_implicit_fb_sync_format(struct snd_usb_audio *chip, } } + end: if (fixed_rate) *fixed_rate = snd_usb_pcm_has_fixed_rate(subs); return sync_fmt; diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 99a66d0ef5b2..d959da7a1afb 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c @@ -160,9 +160,12 @@ find_substream_format(struct snd_usb_substream *subs, bool snd_usb_pcm_has_fixed_rate(struct snd_usb_substream *subs) { const struct audioformat *fp; - struct snd_usb_audio *chip = subs->stream->chip; + struct snd_usb_audio *chip; int rate = -1; + if (!subs) + return false; + chip = subs->stream->chip; if (!(chip->quirk_flags & QUIRK_FLAG_FIXED_RATE)) return false; list_for_each_entry(fp, &subs->fmt_list, list) { @@ -525,6 +528,8 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, if (snd_usb_endpoint_compatible(chip, subs->data_endpoint, fmt, hw_params)) goto unlock; + if (stop_endpoints(subs, false)) + sync_pending_stops(subs); close_endpoints(chip, subs); } @@ -787,11 +792,27 @@ static int apply_hw_params_minmax(struct snd_interval *it, unsigned int rmin, return changed; } +/* get the specified endpoint object that is being used by other streams + * (i.e. the parameter is locked) + */ +static const struct snd_usb_endpoint * +get_endpoint_in_use(struct snd_usb_audio *chip, int endpoint, + const struct snd_usb_endpoint *ref_ep) +{ + const struct snd_usb_endpoint *ep; + + ep = snd_usb_get_endpoint(chip, endpoint); + if (ep && ep->cur_audiofmt && (ep != ref_ep || ep->opened > 1)) + return ep; + return NULL; +} + static int hw_rule_rate(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_usb_substream *subs = rule->private; struct snd_usb_audio *chip = subs->stream->chip; + const struct snd_usb_endpoint *ep; const struct audioformat *fp; struct snd_interval *it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); unsigned int rmin, rmax, r; @@ -803,6 +824,29 @@ static int hw_rule_rate(struct snd_pcm_hw_params *params, list_for_each_entry(fp, &subs->fmt_list, list) { if (!hw_check_valid_format(subs, params, fp)) continue; + + ep = get_endpoint_in_use(chip, fp->endpoint, + subs->data_endpoint); + if (ep) { + hwc_debug("rate limit %d for ep#%x\n", + ep->cur_rate, fp->endpoint); + rmin = min(rmin, ep->cur_rate); + rmax = max(rmax, ep->cur_rate); + continue; + } + + if (fp->implicit_fb) { + ep = get_endpoint_in_use(chip, fp->sync_ep, + subs->sync_endpoint); + if (ep) { + hwc_debug("rate limit %d for sync_ep#%x\n", + ep->cur_rate, fp->sync_ep); + rmin = min(rmin, ep->cur_rate); + rmax = max(rmax, ep->cur_rate); + continue; + } + } + r = snd_usb_endpoint_get_clock_rate(chip, fp->clock); if (r > 0) { if (!snd_interval_test(it, r)) @@ -872,6 +916,8 @@ static int hw_rule_format(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_usb_substream *subs = rule->private; + struct snd_usb_audio *chip = subs->stream->chip; + const struct snd_usb_endpoint *ep; const struct audioformat *fp; struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); u64 fbits; @@ -881,6 +927,27 @@ static int hw_rule_format(struct snd_pcm_hw_params *params, list_for_each_entry(fp, &subs->fmt_list, list) { if (!hw_check_valid_format(subs, params, fp)) continue; + + ep = get_endpoint_in_use(chip, fp->endpoint, + subs->data_endpoint); + if (ep) { + hwc_debug("format limit %d for ep#%x\n", + ep->cur_format, fp->endpoint); + fbits |= pcm_format_to_bits(ep->cur_format); + continue; + } + + if (fp->implicit_fb) { + ep = get_endpoint_in_use(chip, fp->sync_ep, + subs->sync_endpoint); + if (ep) { + hwc_debug("format limit %d for sync_ep#%x\n", + ep->cur_format, fp->sync_ep); + fbits |= pcm_format_to_bits(ep->cur_format); + continue; + } + } + fbits |= fp->formats; } return apply_hw_params_format_bits(fmt, fbits); @@ -913,98 +980,95 @@ static int hw_rule_period_time(struct snd_pcm_hw_params *params, return apply_hw_params_minmax(it, pmin, UINT_MAX); } -/* get the EP or the sync EP for implicit fb when it's already set up */ -static const struct snd_usb_endpoint * -get_sync_ep_from_substream(struct snd_usb_substream *subs) -{ - struct snd_usb_audio *chip = subs->stream->chip; - const struct audioformat *fp; - const struct snd_usb_endpoint *ep; - - list_for_each_entry(fp, &subs->fmt_list, list) { - ep = snd_usb_get_endpoint(chip, fp->endpoint); - if (ep && ep->cur_audiofmt) { - /* if EP is already opened solely for this substream, - * we still allow us to change the parameter; otherwise - * this substream has to follow the existing parameter - */ - if (ep->cur_audiofmt != subs->cur_audiofmt || ep->opened > 1) - return ep; - } - if (!fp->implicit_fb) - continue; - /* for the implicit fb, check the sync ep as well */ - ep = snd_usb_get_endpoint(chip, fp->sync_ep); - if (ep && ep->cur_audiofmt) - return ep; - } - return NULL; -} - /* additional hw constraints for implicit feedback mode */ -static int hw_rule_format_implicit_fb(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_usb_substream *subs = rule->private; - const struct snd_usb_endpoint *ep; - struct snd_mask *fmt = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT); - - ep = get_sync_ep_from_substream(subs); - if (!ep) - return 0; - - hwc_debug("applying %s\n", __func__); - return apply_hw_params_format_bits(fmt, pcm_format_to_bits(ep->cur_format)); -} - -static int hw_rule_rate_implicit_fb(struct snd_pcm_hw_params *params, - struct snd_pcm_hw_rule *rule) -{ - struct snd_usb_substream *subs = rule->private; - const struct snd_usb_endpoint *ep; - struct snd_interval *it; - - ep = get_sync_ep_from_substream(subs); - if (!ep) - return 0; - - hwc_debug("applying %s\n", __func__); - it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - return apply_hw_params_minmax(it, ep->cur_rate, ep->cur_rate); -} - static int hw_rule_period_size_implicit_fb(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_usb_substream *subs = rule->private; + struct snd_usb_audio *chip = subs->stream->chip; + const struct audioformat *fp; const struct snd_usb_endpoint *ep; struct snd_interval *it; + unsigned int rmin, rmax; - ep = get_sync_ep_from_substream(subs); - if (!ep) - return 0; - - hwc_debug("applying %s\n", __func__); it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); - return apply_hw_params_minmax(it, ep->cur_period_frames, - ep->cur_period_frames); + hwc_debug("hw_rule_period_size: (%u,%u)\n", it->min, it->max); + rmin = UINT_MAX; + rmax = 0; + list_for_each_entry(fp, &subs->fmt_list, list) { + if (!hw_check_valid_format(subs, params, fp)) + continue; + ep = get_endpoint_in_use(chip, fp->endpoint, + subs->data_endpoint); + if (ep) { + hwc_debug("period size limit %d for ep#%x\n", + ep->cur_period_frames, fp->endpoint); + rmin = min(rmin, ep->cur_period_frames); + rmax = max(rmax, ep->cur_period_frames); + continue; + } + + if (fp->implicit_fb) { + ep = get_endpoint_in_use(chip, fp->sync_ep, + subs->sync_endpoint); + if (ep) { + hwc_debug("period size limit %d for sync_ep#%x\n", + ep->cur_period_frames, fp->sync_ep); + rmin = min(rmin, ep->cur_period_frames); + rmax = max(rmax, ep->cur_period_frames); + continue; + } + } + } + + if (!rmax) + return 0; /* no limit by implicit fb */ + return apply_hw_params_minmax(it, rmin, rmax); } static int hw_rule_periods_implicit_fb(struct snd_pcm_hw_params *params, struct snd_pcm_hw_rule *rule) { struct snd_usb_substream *subs = rule->private; + struct snd_usb_audio *chip = subs->stream->chip; + const struct audioformat *fp; const struct snd_usb_endpoint *ep; struct snd_interval *it; + unsigned int rmin, rmax; - ep = get_sync_ep_from_substream(subs); - if (!ep) - return 0; - - hwc_debug("applying %s\n", __func__); it = hw_param_interval(params, SNDRV_PCM_HW_PARAM_PERIODS); - return apply_hw_params_minmax(it, ep->cur_buffer_periods, - ep->cur_buffer_periods); + hwc_debug("hw_rule_periods: (%u,%u)\n", it->min, it->max); + rmin = UINT_MAX; + rmax = 0; + list_for_each_entry(fp, &subs->fmt_list, list) { + if (!hw_check_valid_format(subs, params, fp)) + continue; + ep = get_endpoint_in_use(chip, fp->endpoint, + subs->data_endpoint); + if (ep) { + hwc_debug("periods limit %d for ep#%x\n", + ep->cur_buffer_periods, fp->endpoint); + rmin = min(rmin, ep->cur_buffer_periods); + rmax = max(rmax, ep->cur_buffer_periods); + continue; + } + + if (fp->implicit_fb) { + ep = get_endpoint_in_use(chip, fp->sync_ep, + subs->sync_endpoint); + if (ep) { + hwc_debug("periods limit %d for sync_ep#%x\n", + ep->cur_buffer_periods, fp->sync_ep); + rmin = min(rmin, ep->cur_buffer_periods); + rmax = max(rmax, ep->cur_buffer_periods); + continue; + } + } + } + + if (!rmax) + return 0; /* no limit by implicit fb */ + return apply_hw_params_minmax(it, rmin, rmax); } /* @@ -1113,16 +1177,6 @@ static int setup_hw_info(struct snd_pcm_runtime *runtime, struct snd_usb_substre return err; /* additional hw constraints for implicit fb */ - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_FORMAT, - hw_rule_format_implicit_fb, subs, - SNDRV_PCM_HW_PARAM_FORMAT, -1); - if (err < 0) - return err; - err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - hw_rule_rate_implicit_fb, subs, - SNDRV_PCM_HW_PARAM_RATE, -1); - if (err < 0) - return err; err = snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, hw_rule_period_size_implicit_fb, subs, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, -1); diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index 3d13fdf7590c..3ecd1ba7fd4b 100644 --- a/sound/usb/quirks.c +++ b/sound/usb/quirks.c @@ -2152,6 +2152,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { QUIRK_FLAG_GENERIC_IMPLICIT_FB), DEVICE_FLG(0x0525, 0xa4ad, /* Hamedal C20 usb camero */ QUIRK_FLAG_IFACE_SKIP_CLOSE), + DEVICE_FLG(0x0ecb, 0x205c, /* JBL Quantum610 Wireless */ + QUIRK_FLAG_FIXED_RATE), DEVICE_FLG(0x0ecb, 0x2069, /* JBL Quantum810 Wireless */ QUIRK_FLAG_FIXED_RATE), diff --git a/sound/usb/stream.c b/sound/usb/stream.c index f75601ca2d52..f10f4e6d3fb8 100644 --- a/sound/usb/stream.c +++ b/sound/usb/stream.c @@ -1222,6 +1222,12 @@ static int __snd_usb_parse_audio_interface(struct snd_usb_audio *chip, if (err < 0) return err; } + + /* try to set the interface... */ + usb_set_interface(chip->dev, iface_no, 0); + snd_usb_init_pitch(chip, fp); + snd_usb_init_sample_rate(chip, fp, fp->rate_max); + usb_set_interface(chip->dev, iface_no, altno); } return 0; } diff --git a/sound/xen/xen_snd_front.c b/sound/xen/xen_snd_front.c index 4041748c12e5..b66e037710d0 100644 --- a/sound/xen/xen_snd_front.c +++ b/sound/xen/xen_snd_front.c @@ -311,7 +311,7 @@ static int xen_drv_probe(struct xenbus_device *xb_dev, return xenbus_switch_state(xb_dev, XenbusStateInitialising); } -static int xen_drv_remove(struct xenbus_device *dev) +static void xen_drv_remove(struct xenbus_device *dev) { struct xen_snd_front_info *front_info = dev_get_drvdata(&dev->dev); int to = 100; @@ -345,7 +345,6 @@ static int xen_drv_remove(struct xenbus_device *dev) xen_snd_drv_fini(front_info); xenbus_frontend_closed(dev); - return 0; } static const struct xenbus_device_id xen_drv_ids[] = { |