Commit f3413783 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/omap', 'asoc/topic/rcar' and...

Merge remote-tracking branches 'asoc/topic/omap', 'asoc/topic/rcar' and 'asoc/topic/rockchip' into asoc-next
...@@ -8,6 +8,8 @@ Required properties: ...@@ -8,6 +8,8 @@ Required properties:
- interrupts: Interrupt number for McPDM - interrupts: Interrupt number for McPDM
- interrupt-parent: The parent interrupt controller - interrupt-parent: The parent interrupt controller
- ti,hwmods: Name of the hwmod associated to the McPDM - ti,hwmods: Name of the hwmod associated to the McPDM
- clocks: phandle for the pdmclk provider, likely <&twl6040>
- clock-names: Must be "pdmclk"
Example: Example:
...@@ -19,3 +21,11 @@ mcpdm: mcpdm@40132000 { ...@@ -19,3 +21,11 @@ mcpdm: mcpdm@40132000 {
interrupt-parent = <&gic>; interrupt-parent = <&gic>;
ti,hwmods = "mcpdm"; ti,hwmods = "mcpdm";
}; };
In board DTS file the pdmclk needs to be added:
&mcpdm {
clocks = <&twl6040>;
clock-names = "pdmclk";
status = "okay";
};
...@@ -373,6 +373,8 @@ Optional properties: ...@@ -373,6 +373,8 @@ Optional properties:
- #clock-cells : it must be 0 if your system has audio_clkout - #clock-cells : it must be 0 if your system has audio_clkout
it must be 1 if your system has audio_clkout0/1/2/3 it must be 1 if your system has audio_clkout0/1/2/3
- clock-frequency : for all audio_clkout0/1/2/3 - clock-frequency : for all audio_clkout0/1/2/3
- clkout-lr-asynchronous : boolean property. it indicates that audio_clkoutn
is asynchronizes with lr-clock.
SSI subnode properties: SSI subnode properties:
- interrupts : Should contain SSI interrupt for PIO transfer - interrupts : Should contain SSI interrupt for PIO transfer
......
...@@ -23,6 +23,11 @@ Required properties: ...@@ -23,6 +23,11 @@ Required properties:
- rockchip,playback-channels: max playback channels, if not set, 8 channels default. - rockchip,playback-channels: max playback channels, if not set, 8 channels default.
- rockchip,capture-channels: max capture channels, if not set, 2 channels default. - rockchip,capture-channels: max capture channels, if not set, 2 channels default.
Required properties for controller which support multi channels
playback/capture:
- rockchip,grf: the phandle of the syscon node for GRF register.
Example for rk3288 I2S controller: Example for rk3288 I2S controller:
i2s@ff890000 { i2s@ff890000 {
......
...@@ -13,16 +13,7 @@ ...@@ -13,16 +13,7 @@
#define __SIMPLE_CARD_H #define __SIMPLE_CARD_H
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/simple_card_utils.h>
struct asoc_simple_dai {
const char *name;
unsigned int sysclk;
int slots;
int slot_width;
unsigned int tx_slot_mask;
unsigned int rx_slot_mask;
struct clk *clk;
};
struct asoc_simple_card_info { struct asoc_simple_card_info {
const char *name; const char *name;
......
/*
* simple_card_core.h
*
* Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __SIMPLE_CARD_CORE_H
#define __SIMPLE_CARD_CORE_H
#include <sound/soc.h>
struct asoc_simple_dai {
const char *name;
unsigned int sysclk;
int slots;
int slot_width;
unsigned int tx_slot_mask;
unsigned int rx_slot_mask;
struct clk *clk;
};
int asoc_simple_card_parse_daifmt(struct device *dev,
struct device_node *node,
struct device_node *codec,
char *prefix,
unsigned int *retfmt);
int asoc_simple_card_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link,
const char *fmt, ...);
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix);
#endif /* __SIMPLE_CARD_CORE_H */
config SND_SIMPLE_CARD_UTILS
tristate
config SND_SIMPLE_CARD config SND_SIMPLE_CARD
tristate "ASoC Simple sound card support" tristate "ASoC Simple sound card support"
select SND_SIMPLE_CARD_UTILS
help help
This option enables generic simple sound card support This option enables generic simple sound card support
obj-$(CONFIG_SND_SIMPLE_CARD_UTILS) := simple-card-utils.o
snd-soc-simple-card-objs := simple-card.o snd-soc-simple-card-objs := simple-card.o
obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o obj-$(CONFIG_SND_SIMPLE_CARD) += snd-soc-simple-card.o
/*
* simple-card-core.c
*
* Copyright (c) 2016 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/of.h>
#include <sound/simple_card_utils.h>
int asoc_simple_card_parse_daifmt(struct device *dev,
struct device_node *node,
struct device_node *codec,
char *prefix,
unsigned int *retfmt)
{
struct device_node *bitclkmaster = NULL;
struct device_node *framemaster = NULL;
int prefix_len = prefix ? strlen(prefix) : 0;
unsigned int daifmt;
daifmt = snd_soc_of_parse_daifmt(node, prefix,
&bitclkmaster, &framemaster);
daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
if (prefix_len && !bitclkmaster && !framemaster) {
/*
* No dai-link level and master setting was not found from
* sound node level, revert back to legacy DT parsing and
* take the settings from codec node.
*/
dev_dbg(dev, "Revert to legacy daifmt parsing\n");
daifmt = snd_soc_of_parse_daifmt(codec, NULL, NULL, NULL) |
(daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
} else {
if (codec == bitclkmaster)
daifmt |= (codec == framemaster) ?
SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
else
daifmt |= (codec == framemaster) ?
SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
}
of_node_put(bitclkmaster);
of_node_put(framemaster);
*retfmt = daifmt;
return 0;
}
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_daifmt);
int asoc_simple_card_set_dailink_name(struct device *dev,
struct snd_soc_dai_link *dai_link,
const char *fmt, ...)
{
va_list ap;
char *name = NULL;
int ret = -ENOMEM;
va_start(ap, fmt);
name = devm_kvasprintf(dev, GFP_KERNEL, fmt, ap);
va_end(ap);
if (name) {
ret = 0;
dai_link->name = name;
dai_link->stream_name = name;
}
return ret;
}
EXPORT_SYMBOL_GPL(asoc_simple_card_set_dailink_name);
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix)
{
char prop[128];
int ret;
snprintf(prop, sizeof(prop), "%sname", prefix);
/* Parse the card name from DT */
ret = snd_soc_of_parse_card_name(card, prop);
if (ret < 0)
return ret;
if (!card->name && card->dai_link)
card->name = card->dai_link->name;
return 0;
}
EXPORT_SYMBOL_GPL(asoc_simple_card_parse_card_name);
This diff is collapsed.
...@@ -107,6 +107,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040 ...@@ -107,6 +107,7 @@ config SND_OMAP_SOC_OMAP_ABE_TWL6040
select SND_SOC_TWL6040 select SND_SOC_TWL6040
select SND_SOC_DMIC select SND_SOC_DMIC
select COMMON_CLK_PALMAS if (SOC_OMAP5 && MFD_PALMAS) select COMMON_CLK_PALMAS if (SOC_OMAP5 && MFD_PALMAS)
select CLK_TWL6040
help help
Say Y if you want to add support for SoC audio on OMAP boards using Say Y if you want to add support for SoC audio on OMAP boards using
ABE and twl6040 codec. This driver currently supports: ABE and twl6040 codec. This driver currently supports:
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/irq.h> #include <linux/irq.h>
#include <linux/clk.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/of_device.h> #include <linux/of_device.h>
...@@ -54,6 +55,7 @@ struct omap_mcpdm { ...@@ -54,6 +55,7 @@ struct omap_mcpdm {
unsigned long phys_base; unsigned long phys_base;
void __iomem *io_base; void __iomem *io_base;
int irq; int irq;
struct clk *pdmclk;
struct mutex mutex; struct mutex mutex;
...@@ -66,6 +68,9 @@ struct omap_mcpdm { ...@@ -66,6 +68,9 @@ struct omap_mcpdm {
/* McPDM needs to be restarted due to runtime reconfiguration */ /* McPDM needs to be restarted due to runtime reconfiguration */
bool restart; bool restart;
/* pm state for suspend/resume handling */
int pm_active_count;
struct snd_dmaengine_dai_dma_data dma_data[2]; struct snd_dmaengine_dai_dma_data dma_data[2];
}; };
...@@ -173,6 +178,10 @@ static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm) ...@@ -173,6 +178,10 @@ static inline int omap_mcpdm_active(struct omap_mcpdm *mcpdm)
*/ */
static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm) static void omap_mcpdm_open_streams(struct omap_mcpdm *mcpdm)
{ {
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl | MCPDM_WD_EN);
omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET, omap_mcpdm_write(mcpdm, MCPDM_REG_IRQENABLE_SET,
MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL | MCPDM_DN_IRQ_EMPTY | MCPDM_DN_IRQ_FULL |
MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL); MCPDM_UP_IRQ_EMPTY | MCPDM_UP_IRQ_FULL);
...@@ -258,12 +267,9 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream, ...@@ -258,12 +267,9 @@ static int omap_mcpdm_dai_startup(struct snd_pcm_substream *substream,
mutex_lock(&mcpdm->mutex); mutex_lock(&mcpdm->mutex);
if (!dai->active) { if (!dai->active)
u32 ctrl = omap_mcpdm_read(mcpdm, MCPDM_REG_CTRL);
omap_mcpdm_write(mcpdm, MCPDM_REG_CTRL, ctrl | MCPDM_WD_EN);
omap_mcpdm_open_streams(mcpdm); omap_mcpdm_open_streams(mcpdm);
}
mutex_unlock(&mcpdm->mutex); mutex_unlock(&mcpdm->mutex);
return 0; return 0;
...@@ -384,6 +390,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai) ...@@ -384,6 +390,7 @@ static int omap_mcpdm_probe(struct snd_soc_dai *dai)
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai); struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
int ret; int ret;
clk_prepare_enable(mcpdm->pdmclk);
pm_runtime_enable(mcpdm->dev); pm_runtime_enable(mcpdm->dev);
/* Disable lines while request is ongoing */ /* Disable lines while request is ongoing */
...@@ -418,8 +425,54 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) ...@@ -418,8 +425,54 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
pm_runtime_disable(mcpdm->dev); pm_runtime_disable(mcpdm->dev);
clk_disable_unprepare(mcpdm->pdmclk);
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int omap_mcpdm_suspend(struct snd_soc_dai *dai)
{
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
if (dai->active) {
omap_mcpdm_stop(mcpdm);
omap_mcpdm_close_streams(mcpdm);
}
mcpdm->pm_active_count = 0;
while (pm_runtime_active(mcpdm->dev)) {
pm_runtime_put_sync(mcpdm->dev);
mcpdm->pm_active_count++;
}
clk_disable_unprepare(mcpdm->pdmclk);
return 0;
}
static int omap_mcpdm_resume(struct snd_soc_dai *dai)
{
struct omap_mcpdm *mcpdm = snd_soc_dai_get_drvdata(dai);
clk_prepare_enable(mcpdm->pdmclk);
if (mcpdm->pm_active_count) {
while (mcpdm->pm_active_count--)
pm_runtime_get_sync(mcpdm->dev);
if (dai->active) {
omap_mcpdm_open_streams(mcpdm);
omap_mcpdm_start(mcpdm);
}
}
return 0; return 0;
} }
#else
#define omap_mcpdm_suspend NULL
#define omap_mcpdm_resume NULL
#endif
#define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) #define OMAP_MCPDM_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000)
#define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE #define OMAP_MCPDM_FORMATS SNDRV_PCM_FMTBIT_S32_LE
...@@ -427,6 +480,8 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai) ...@@ -427,6 +480,8 @@ static int omap_mcpdm_remove(struct snd_soc_dai *dai)
static struct snd_soc_dai_driver omap_mcpdm_dai = { static struct snd_soc_dai_driver omap_mcpdm_dai = {
.probe = omap_mcpdm_probe, .probe = omap_mcpdm_probe,
.remove = omap_mcpdm_remove, .remove = omap_mcpdm_remove,
.suspend = omap_mcpdm_suspend,
.resume = omap_mcpdm_resume,
.probe_order = SND_SOC_COMP_ORDER_LATE, .probe_order = SND_SOC_COMP_ORDER_LATE,
.remove_order = SND_SOC_COMP_ORDER_EARLY, .remove_order = SND_SOC_COMP_ORDER_EARLY,
.playback = { .playback = {
...@@ -494,6 +549,15 @@ static int asoc_mcpdm_probe(struct platform_device *pdev) ...@@ -494,6 +549,15 @@ static int asoc_mcpdm_probe(struct platform_device *pdev)
mcpdm->dev = &pdev->dev; mcpdm->dev = &pdev->dev;
mcpdm->pdmclk = devm_clk_get(&pdev->dev, "pdmclk");
if (IS_ERR(mcpdm->pdmclk)) {
if (PTR_ERR(mcpdm->pdmclk) == -EPROBE_DEFER)
return -EPROBE_DEFER;
dev_warn(&pdev->dev, "Error getting pdmclk (%ld)!\n",
PTR_ERR(mcpdm->pdmclk));
mcpdm->pdmclk = NULL;
}
ret = devm_snd_soc_register_component(&pdev->dev, ret = devm_snd_soc_register_component(&pdev->dev,
&omap_mcpdm_component, &omap_mcpdm_component,
&omap_mcpdm_dai, 1); &omap_mcpdm_dai, 1);
......
...@@ -11,8 +11,10 @@ ...@@ -11,8 +11,10 @@
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/mfd/syscon.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/of_gpio.h> #include <linux/of_gpio.h>
#include <linux/of_device.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include <linux/regmap.h> #include <linux/regmap.h>
...@@ -23,6 +25,11 @@ ...@@ -23,6 +25,11 @@
#define DRV_NAME "rockchip-i2s" #define DRV_NAME "rockchip-i2s"
struct rk_i2s_pins {
u32 reg_offset;
u32 shift;
};
struct rk_i2s_dev { struct rk_i2s_dev {
struct device *dev; struct device *dev;
...@@ -33,6 +40,7 @@ struct rk_i2s_dev { ...@@ -33,6 +40,7 @@ struct rk_i2s_dev {
struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data;
struct regmap *regmap; struct regmap *regmap;
struct regmap *grf;
/* /*
* Used to indicate the tx/rx status. * Used to indicate the tx/rx status.
...@@ -42,6 +50,7 @@ struct rk_i2s_dev { ...@@ -42,6 +50,7 @@ struct rk_i2s_dev {
bool tx_start; bool tx_start;
bool rx_start; bool rx_start;
bool is_master_mode; bool is_master_mode;
const struct rk_i2s_pins *pins;
}; };
static int i2s_runtime_suspend(struct device *dev) static int i2s_runtime_suspend(struct device *dev)
...@@ -300,14 +309,38 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -300,14 +309,38 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream,
I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK, I2S_TXCR_VDW_MASK | I2S_TXCR_CSR_MASK,
val); val);
if (!IS_ERR(i2s->grf) && i2s->pins) {
regmap_read(i2s->regmap, I2S_TXCR, &val);
val &= I2S_TXCR_CSR_MASK;
switch (val) {
case I2S_CHN_4:
val = I2S_IO_4CH_OUT_6CH_IN;
break;
case I2S_CHN_6:
val = I2S_IO_6CH_OUT_4CH_IN;
break;
case I2S_CHN_8:
val = I2S_IO_8CH_OUT_2CH_IN;
break;
default:
val = I2S_IO_2CH_OUT_8CH_IN;
break;
}
val <<= i2s->pins->shift;
val |= (I2S_IO_DIRECTION_MASK << i2s->pins->shift) << 16;
regmap_write(i2s->grf, i2s->pins->reg_offset, val);
}
regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK, regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_TDL_MASK,
I2S_DMACR_TDL(16)); I2S_DMACR_TDL(16));
regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK, regmap_update_bits(i2s->regmap, I2S_DMACR, I2S_DMACR_RDL_MASK,
I2S_DMACR_RDL(16)); I2S_DMACR_RDL(16));
val = I2S_CKR_TRCM_TXRX; val = I2S_CKR_TRCM_TXRX;
if (dai->driver->symmetric_rates || rtd->dai_link->symmetric_rates) if (dai->driver->symmetric_rates && rtd->dai_link->symmetric_rates)
val = I2S_CKR_TRCM_TXSHARE; val = I2S_CKR_TRCM_TXONLY;
regmap_update_bits(i2s->regmap, I2S_CKR, regmap_update_bits(i2s->regmap, I2S_CKR,
I2S_CKR_TRCM_MASK, I2S_CKR_TRCM_MASK,
...@@ -485,9 +518,23 @@ static const struct regmap_config rockchip_i2s_regmap_config = { ...@@ -485,9 +518,23 @@ static const struct regmap_config rockchip_i2s_regmap_config = {
.cache_type = REGCACHE_FLAT, .cache_type = REGCACHE_FLAT,
}; };
static const struct rk_i2s_pins rk3399_i2s_pins = {
.reg_offset = 0xe220,
.shift = 11,
};
static const struct of_device_id rockchip_i2s_match[] = {
{ .compatible = "rockchip,rk3066-i2s", },
{ .compatible = "rockchip,rk3188-i2s", },
{ .compatible = "rockchip,rk3288-i2s", },
{ .compatible = "rockchip,rk3399-i2s", .data = &rk3399_i2s_pins },
{},
};
static int rockchip_i2s_probe(struct platform_device *pdev) static int rockchip_i2s_probe(struct platform_device *pdev)
{ {
struct device_node *node = pdev->dev.of_node; struct device_node *node = pdev->dev.of_node;
const struct of_device_id *of_id;
struct rk_i2s_dev *i2s; struct rk_i2s_dev *i2s;
struct snd_soc_dai_driver *soc_dai; struct snd_soc_dai_driver *soc_dai;
struct resource *res; struct resource *res;
...@@ -501,6 +548,17 @@ static int rockchip_i2s_probe(struct platform_device *pdev) ...@@ -501,6 +548,17 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
i2s->dev = &pdev->dev;
i2s->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
if (!IS_ERR(i2s->grf)) {
of_id = of_match_device(rockchip_i2s_match, &pdev->dev);
if (!of_id || !of_id->data)
return -EINVAL;
i2s->pins = of_id->data;
}
/* try to prepare related clocks */ /* try to prepare related clocks */
i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk"); i2s->hclk = devm_clk_get(&pdev->dev, "i2s_hclk");
if (IS_ERR(i2s->hclk)) { if (IS_ERR(i2s->hclk)) {
...@@ -540,7 +598,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev) ...@@ -540,7 +598,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
i2s->capture_dma_data.maxburst = 4; i2s->capture_dma_data.maxburst = 4;
i2s->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, i2s); dev_set_drvdata(&pdev->dev, i2s);
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
...@@ -606,14 +663,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev) ...@@ -606,14 +663,6 @@ static int rockchip_i2s_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id rockchip_i2s_match[] = {
{ .compatible = "rockchip,rk3066-i2s", },
{ .compatible = "rockchip,rk3188-i2s", },
{ .compatible = "rockchip,rk3288-i2s", },
{ .compatible = "rockchip,rk3399-i2s", },
{},
};
static const struct dev_pm_ops rockchip_i2s_pm_ops = { static const struct dev_pm_ops rockchip_i2s_pm_ops = {
SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume, SET_RUNTIME_PM_OPS(i2s_runtime_suspend, i2s_runtime_resume,
NULL) NULL)
......
...@@ -81,8 +81,8 @@ ...@@ -81,8 +81,8 @@
#define I2S_CKR_TRCM_SHIFT 28 #define I2S_CKR_TRCM_SHIFT 28
#define I2S_CKR_TRCM(x) (x << I2S_CKR_TRCM_SHIFT) #define I2S_CKR_TRCM(x) (x << I2S_CKR_TRCM_SHIFT)
#define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT) #define I2S_CKR_TRCM_TXRX (0 << I2S_CKR_TRCM_SHIFT)
#define I2S_CKR_TRCM_TXSHARE (1 << I2S_CKR_TRCM_SHIFT) #define I2S_CKR_TRCM_TXONLY (1 << I2S_CKR_TRCM_SHIFT)
#define I2S_CKR_TRCM_RXSHARE (2 << I2S_CKR_TRCM_SHIFT) #define I2S_CKR_TRCM_RXONLY (2 << I2S_CKR_TRCM_SHIFT)
#define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT) #define I2S_CKR_TRCM_MASK (3 << I2S_CKR_TRCM_SHIFT)
#define I2S_CKR_MSS_SHIFT 27 #define I2S_CKR_MSS_SHIFT 27
#define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT) #define I2S_CKR_MSS_MASTER (0 << I2S_CKR_MSS_SHIFT)
...@@ -236,4 +236,11 @@ enum { ...@@ -236,4 +236,11 @@ enum {
#define I2S_TXDR (0x0024) #define I2S_TXDR (0x0024)
#define I2S_RXDR (0x0028) #define I2S_RXDR (0x0028)
/* io direction cfg register */
#define I2S_IO_DIRECTION_MASK (7)
#define I2S_IO_8CH_OUT_2CH_IN (0)
#define I2S_IO_6CH_OUT_4CH_IN (4)
#define I2S_IO_4CH_OUT_6CH_IN (6)
#define I2S_IO_2CH_OUT_8CH_IN (7)
#endif /* _ROCKCHIP_IIS_H */ #endif /* _ROCKCHIP_IIS_H */
...@@ -34,13 +34,18 @@ ...@@ -34,13 +34,18 @@
#define DRV_NAME "rockchip-snd-max98090" #define DRV_NAME "rockchip-snd-max98090"
static struct snd_soc_jack headset_jack; static struct snd_soc_jack headset_jack;
/* Headset jack detection DAPM pins */
static struct snd_soc_jack_pin headset_jack_pins[] = { static struct snd_soc_jack_pin headset_jack_pins[] = {
{ {
.pin = "Headset Jack", .pin = "Headphone",
.mask = SND_JACK_HEADPHONE | SND_JACK_MICROPHONE | .mask = SND_JACK_HEADPHONE,
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3,
}, },
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
}; };
static const struct snd_soc_dapm_widget rk_dapm_widgets[] = { static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
...@@ -53,7 +58,7 @@ static const struct snd_soc_dapm_widget rk_dapm_widgets[] = { ...@@ -53,7 +58,7 @@ static const struct snd_soc_dapm_widget rk_dapm_widgets[] = {
static const struct snd_soc_dapm_route rk_audio_map[] = { static const struct snd_soc_dapm_route rk_audio_map[] = {
{"IN34", NULL, "Headset Mic"}, {"IN34", NULL, "Headset Mic"},
{"IN34", NULL, "MICBIAS"}, {"IN34", NULL, "MICBIAS"},
{"MICBIAS", NULL, "Headset Mic"}, {"Headset Mic", NULL, "MICBIAS"},
{"DMICL", NULL, "Int Mic"}, {"DMICL", NULL, "Int Mic"},
{"Headphone", NULL, "HPL"}, {"Headphone", NULL, "HPL"},
{"Headphone", NULL, "HPR"}, {"Headphone", NULL, "HPR"},
...@@ -114,43 +119,27 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream, ...@@ -114,43 +119,27 @@ static int rk_aif1_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
static int rk_init(struct snd_soc_pcm_runtime *runtime)
{
/* Enable Headset and 4 Buttons Jack detection */
return snd_soc_card_jack_new(runtime->card, "Headset Jack",
SND_JACK_HEADSET |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3,
&headset_jack,
headset_jack_pins,
ARRAY_SIZE(headset_jack_pins));
}
static int rk_98090_headset_init(struct snd_soc_component *component)
{
return ts3a227e_enable_jack_detect(component, &headset_jack);
}
static struct snd_soc_ops rk_aif1_ops = { static struct snd_soc_ops rk_aif1_ops = {
.hw_params = rk_aif1_hw_params, .hw_params = rk_aif1_hw_params,
}; };
static struct snd_soc_aux_dev rk_98090_headset_dev = {
.name = "Headset Chip",
.init = rk_98090_headset_init,
};
static struct snd_soc_dai_link rk_dailink = { static struct snd_soc_dai_link rk_dailink = {
.name = "max98090", .name = "max98090",
.stream_name = "Audio", .stream_name = "Audio",
.codec_dai_name = "HiFi", .codec_dai_name = "HiFi",
.init = rk_init,
.ops = &rk_aif1_ops, .ops = &rk_aif1_ops,
/* set max98090 as slave */ /* set max98090 as slave */
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS, SND_SOC_DAIFMT_CBS_CFS,
}; };
static int rk_98090_headset_init(struct snd_soc_component *component);
static struct snd_soc_aux_dev rk_98090_headset_dev = {
.name = "Headset Chip",
.init = rk_98090_headset_init,
};
static struct snd_soc_card snd_soc_card_rk = { static struct snd_soc_card snd_soc_card_rk = {
.name = "ROCKCHIP-I2S", .name = "ROCKCHIP-I2S",
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -166,6 +155,26 @@ static struct snd_soc_card snd_soc_card_rk = { ...@@ -166,6 +155,26 @@ static struct snd_soc_card snd_soc_card_rk = {
.num_controls = ARRAY_SIZE(rk_mc_controls), .num_controls = ARRAY_SIZE(rk_mc_controls),
}; };
static int rk_98090_headset_init(struct snd_soc_component *component)
{
int ret;
/* Enable Headset and 4 Buttons Jack detection */
ret = snd_soc_card_jack_new(&snd_soc_card_rk, "Headset Jack",
SND_JACK_HEADSET |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3,
&headset_jack,
headset_jack_pins,
ARRAY_SIZE(headset_jack_pins));
if (ret)
return ret;
ret = ts3a227e_enable_jack_detect(component, &headset_jack);
return ret;
}
static int snd_rk_mc_probe(struct platform_device *pdev) static int snd_rk_mc_probe(struct platform_device *pdev)
{ {
int ret = 0; int ret = 0;
......
...@@ -101,21 +101,7 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, ...@@ -101,21 +101,7 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
int ret; int ret;
srate = params_rate(params); srate = params_rate(params);
switch (srate) { mclk = srate * 128;
case 32000:
case 48000:
case 96000:
mclk = 96000 * 128; /* 12288000 hz */
break;
case 44100:
mclk = 44100 * 256; /* 11289600 hz */
break;
case 192000:
mclk = 192000 * 128; /* 24576000 hz */
break;
default:
return -EINVAL;
}
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
...@@ -139,7 +125,6 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream, ...@@ -139,7 +125,6 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
val |= SPDIF_CFGR_CLK_DIV(mclk/(srate * 256));
ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR, ret = regmap_update_bits(spdif->regmap, SPDIF_CFGR,
SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE | SPDIF_CFGR_CLK_DIV_MASK | SPDIF_CFGR_HALFWORD_ENABLE |
SDPIF_CFGR_VDW_MASK, SDPIF_CFGR_VDW_MASK,
......
...@@ -44,6 +44,7 @@ config SND_SOC_RCAR ...@@ -44,6 +44,7 @@ config SND_SOC_RCAR
config SND_SOC_RSRC_CARD config SND_SOC_RSRC_CARD
tristate "Renesas Sampling Rate Convert Sound Card" tristate "Renesas Sampling Rate Convert Sound Card"
select SND_SIMPLE_CARD_UTILS
help help
This option enables simple sound if you need sampling rate convert This option enables simple sound if you need sampling rate convert
......
...@@ -33,11 +33,15 @@ struct rsnd_adg { ...@@ -33,11 +33,15 @@ struct rsnd_adg {
struct clk *clkout[CLKOUTMAX]; struct clk *clkout[CLKOUTMAX];
struct clk_onecell_data onecell; struct clk_onecell_data onecell;
struct rsnd_mod mod; struct rsnd_mod mod;
u32 flags;
int rbga_rate_for_441khz; /* RBGA */ int rbga_rate_for_441khz; /* RBGA */
int rbgb_rate_for_48khz; /* RBGB */ int rbgb_rate_for_48khz; /* RBGB */
}; };
#define LRCLK_ASYNC (1 << 0)
#define adg_mode_flags(adg) (adg->flags)
#define for_each_rsnd_clk(pos, adg, i) \ #define for_each_rsnd_clk(pos, adg, i) \
for (i = 0; \ for (i = 0; \
(i < CLKMAX) && \ (i < CLKMAX) && \
...@@ -355,6 +359,16 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate) ...@@ -355,6 +359,16 @@ int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *ssi_mod, unsigned int rate)
rsnd_adg_set_ssi_clk(ssi_mod, data); rsnd_adg_set_ssi_clk(ssi_mod, data);
if (!(adg_mode_flags(adg) & LRCLK_ASYNC)) {
struct rsnd_mod *adg_mod = rsnd_mod_get(adg);
u32 ckr = 0;
if (0 == (rate % 8000))
ckr = 0x80000000;
rsnd_mod_bset(adg_mod, SSICKR, 0x80000000, ckr);
}
dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n", dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",
rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod), rsnd_mod_name(ssi_mod), rsnd_mod_id(ssi_mod),
data, rate); data, rate);
...@@ -532,6 +546,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv) ...@@ -532,6 +546,7 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
{ {
struct rsnd_adg *adg; struct rsnd_adg *adg;
struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv);
struct device_node *np = dev->of_node;
adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL); adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);
if (!adg) { if (!adg) {
...@@ -545,6 +560,9 @@ int rsnd_adg_probe(struct rsnd_priv *priv) ...@@ -545,6 +560,9 @@ int rsnd_adg_probe(struct rsnd_priv *priv)
rsnd_adg_get_clkin(priv, adg); rsnd_adg_get_clkin(priv, adg);
rsnd_adg_get_clkout(priv, adg); rsnd_adg_get_clkout(priv, adg);
if (of_get_property(np, "clkout-lr-asynchronous", NULL))
adg->flags = LRCLK_ASYNC;
priv->adg = adg; priv->adg = adg;
return 0; return 0;
......
...@@ -206,7 +206,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, ...@@ -206,7 +206,7 @@ static int _rsnd_gen_regmap_init(struct rsnd_priv *priv,
*/ */
static int rsnd_gen2_probe(struct rsnd_priv *priv) static int rsnd_gen2_probe(struct rsnd_priv *priv)
{ {
const static struct rsnd_regmap_field_conf conf_ssiu[] = { static const struct rsnd_regmap_field_conf conf_ssiu[] = {
RSND_GEN_S_REG(SSI_MODE0, 0x800), RSND_GEN_S_REG(SSI_MODE0, 0x800),
RSND_GEN_S_REG(SSI_MODE1, 0x804), RSND_GEN_S_REG(SSI_MODE1, 0x804),
RSND_GEN_S_REG(SSI_MODE2, 0x808), RSND_GEN_S_REG(SSI_MODE2, 0x808),
...@@ -221,7 +221,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) ...@@ -221,7 +221,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80), RSND_GEN_M_REG(SSI_INT_ENABLE, 0x18, 0x80),
}; };
const static struct rsnd_regmap_field_conf conf_scu[] = { static const struct rsnd_regmap_field_conf conf_scu[] = {
RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20), RSND_GEN_M_REG(SRC_I_BUSIF_MODE,0x0, 0x20),
RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20), RSND_GEN_M_REG(SRC_O_BUSIF_MODE,0x4, 0x20),
RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20), RSND_GEN_M_REG(SRC_BUSIF_DALIGN,0x8, 0x20),
...@@ -308,7 +308,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) ...@@ -308,7 +308,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100), RSND_GEN_M_REG(DVC_VOL7R, 0xe44, 0x100),
RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100),
}; };
const static struct rsnd_regmap_field_conf conf_adg[] = { static const struct rsnd_regmap_field_conf conf_adg[] = {
RSND_GEN_S_REG(BRRA, 0x00), RSND_GEN_S_REG(BRRA, 0x00),
RSND_GEN_S_REG(BRRB, 0x04), RSND_GEN_S_REG(BRRB, 0x04),
RSND_GEN_S_REG(SSICKR, 0x08), RSND_GEN_S_REG(SSICKR, 0x08),
...@@ -328,7 +328,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) ...@@ -328,7 +328,7 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58),
RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c),
}; };
const static struct rsnd_regmap_field_conf conf_ssi[] = { static const struct rsnd_regmap_field_conf conf_ssi[] = {
RSND_GEN_M_REG(SSICR, 0x00, 0x40), RSND_GEN_M_REG(SSICR, 0x00, 0x40),
RSND_GEN_M_REG(SSISR, 0x04, 0x40), RSND_GEN_M_REG(SSISR, 0x04, 0x40),
RSND_GEN_M_REG(SSITDR, 0x08, 0x40), RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
...@@ -359,14 +359,14 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv) ...@@ -359,14 +359,14 @@ static int rsnd_gen2_probe(struct rsnd_priv *priv)
static int rsnd_gen1_probe(struct rsnd_priv *priv) static int rsnd_gen1_probe(struct rsnd_priv *priv)
{ {
const static struct rsnd_regmap_field_conf conf_adg[] = { static const struct rsnd_regmap_field_conf conf_adg[] = {
RSND_GEN_S_REG(BRRA, 0x00), RSND_GEN_S_REG(BRRA, 0x00),
RSND_GEN_S_REG(BRRB, 0x04), RSND_GEN_S_REG(BRRB, 0x04),
RSND_GEN_S_REG(SSICKR, 0x08), RSND_GEN_S_REG(SSICKR, 0x08),
RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c),
RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10),
}; };
const static struct rsnd_regmap_field_conf conf_ssi[] = { static const struct rsnd_regmap_field_conf conf_ssi[] = {
RSND_GEN_M_REG(SSICR, 0x00, 0x40), RSND_GEN_M_REG(SSICR, 0x00, 0x40),
RSND_GEN_M_REG(SSISR, 0x04, 0x40), RSND_GEN_M_REG(SSISR, 0x04, 0x40),
RSND_GEN_M_REG(SSITDR, 0x08, 0x40), RSND_GEN_M_REG(SSITDR, 0x08, 0x40),
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <sound/jack.h> #include <sound/jack.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/soc-dai.h> #include <sound/soc-dai.h>
#include <sound/simple_card_utils.h>
struct rsrc_card_of_data { struct rsrc_card_of_data {
const char *prefix; const char *prefix;
...@@ -46,25 +47,13 @@ static const struct of_device_id rsrc_card_of_match[] = { ...@@ -46,25 +47,13 @@ static const struct of_device_id rsrc_card_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, rsrc_card_of_match); MODULE_DEVICE_TABLE(of, rsrc_card_of_match);
#define DAI_NAME_NUM 32
struct rsrc_card_dai {
unsigned int sysclk;
unsigned int tx_slot_mask;
unsigned int rx_slot_mask;
int slots;
int slot_width;
struct clk *clk;
char dai_name[DAI_NAME_NUM];
};
#define IDX_CPU 0 #define IDX_CPU 0
#define IDX_CODEC 1 #define IDX_CODEC 1
struct rsrc_card_priv { struct rsrc_card_priv {
struct snd_soc_card snd_card; struct snd_soc_card snd_card;
struct snd_soc_codec_conf codec_conf; struct snd_soc_codec_conf codec_conf;
struct rsrc_card_dai *dai_props; struct asoc_simple_dai *dai_props;
struct snd_soc_dai_link *dai_link; struct snd_soc_dai_link *dai_link;
int dai_num;
u32 convert_rate; u32 convert_rate;
u32 convert_channels; u32 convert_channels;
}; };
...@@ -77,7 +66,7 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream) ...@@ -77,7 +66,7 @@ static int rsrc_card_startup(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
struct rsrc_card_dai *dai_props = struct asoc_simple_dai *dai_props =
rsrc_priv_to_props(priv, rtd->num); rsrc_priv_to_props(priv, rtd->num);
return clk_prepare_enable(dai_props->clk); return clk_prepare_enable(dai_props->clk);
...@@ -87,7 +76,7 @@ static void rsrc_card_shutdown(struct snd_pcm_substream *substream) ...@@ -87,7 +76,7 @@ static void rsrc_card_shutdown(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
struct rsrc_card_dai *dai_props = struct asoc_simple_dai *dai_props =
rsrc_priv_to_props(priv, rtd->num); rsrc_priv_to_props(priv, rtd->num);
clk_disable_unprepare(dai_props->clk); clk_disable_unprepare(dai_props->clk);
...@@ -103,7 +92,7 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd) ...@@ -103,7 +92,7 @@ static int rsrc_card_dai_init(struct snd_soc_pcm_runtime *rtd)
struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card); struct rsrc_card_priv *priv = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *dai; struct snd_soc_dai *dai;
struct snd_soc_dai_link *dai_link; struct snd_soc_dai_link *dai_link;
struct rsrc_card_dai *dai_props; struct asoc_simple_dai *dai_props;
int num = rtd->num; int num = rtd->num;
int ret; int ret;
...@@ -159,44 +148,13 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, ...@@ -159,44 +148,13 @@ static int rsrc_card_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0; return 0;
} }
static int rsrc_card_parse_daifmt(struct device_node *node,
struct device_node *codec,
struct rsrc_card_priv *priv,
struct snd_soc_dai_link *dai_link,
unsigned int *retfmt)
{
struct device_node *bitclkmaster = NULL;
struct device_node *framemaster = NULL;
unsigned int daifmt;
daifmt = snd_soc_of_parse_daifmt(node, NULL,
&bitclkmaster, &framemaster);
daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
if (!bitclkmaster && !framemaster)
return -EINVAL;
if (codec == bitclkmaster)
daifmt |= (codec == framemaster) ?
SND_SOC_DAIFMT_CBM_CFM : SND_SOC_DAIFMT_CBM_CFS;
else
daifmt |= (codec == framemaster) ?
SND_SOC_DAIFMT_CBS_CFM : SND_SOC_DAIFMT_CBS_CFS;
of_node_put(bitclkmaster);
of_node_put(framemaster);
*retfmt = daifmt;
return 0;
}
static int rsrc_card_parse_links(struct device_node *np, static int rsrc_card_parse_links(struct device_node *np,
struct rsrc_card_priv *priv, struct rsrc_card_priv *priv,
int idx, bool is_fe) int idx, bool is_fe)
{ {
struct device *dev = rsrc_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
struct of_phandle_args args; struct of_phandle_args args;
int ret; int ret;
...@@ -232,9 +190,11 @@ static int rsrc_card_parse_links(struct device_node *np, ...@@ -232,9 +190,11 @@ static int rsrc_card_parse_links(struct device_node *np,
if (ret < 0) if (ret < 0)
return ret; return ret;
/* set dai_name */ ret = asoc_simple_card_set_dailink_name(dev, dai_link,
snprintf(dai_props->dai_name, DAI_NAME_NUM, "fe.%s", "fe.%s",
dai_link->cpu_dai_name); dai_link->cpu_dai_name);
if (ret < 0)
return ret;
/* /*
* In soc_bind_dai_link() will check cpu name after * In soc_bind_dai_link() will check cpu name after
...@@ -248,7 +208,6 @@ static int rsrc_card_parse_links(struct device_node *np, ...@@ -248,7 +208,6 @@ static int rsrc_card_parse_links(struct device_node *np,
if (!args.args_count) if (!args.args_count)
dai_link->cpu_dai_name = NULL; dai_link->cpu_dai_name = NULL;
} else { } else {
struct device *dev = rsrc_priv_to_dev(priv);
const struct rsrc_card_of_data *of_data; const struct rsrc_card_of_data *of_data;
of_data = of_device_get_match_data(dev); of_data = of_device_get_match_data(dev);
...@@ -266,6 +225,12 @@ static int rsrc_card_parse_links(struct device_node *np, ...@@ -266,6 +225,12 @@ static int rsrc_card_parse_links(struct device_node *np,
if (ret < 0) if (ret < 0)
return ret; return ret;
ret = asoc_simple_card_set_dailink_name(dev, dai_link,
"be.%s",
dai_link->codec_dai_name);
if (ret < 0)
return ret;
/* additional name prefix */ /* additional name prefix */
if (of_data) { if (of_data) {
priv->codec_conf.of_node = dai_link->codec_of_node; priv->codec_conf.of_node = dai_link->codec_of_node;
...@@ -276,18 +241,12 @@ static int rsrc_card_parse_links(struct device_node *np, ...@@ -276,18 +241,12 @@ static int rsrc_card_parse_links(struct device_node *np,
dai_link->codec_of_node, dai_link->codec_of_node,
"audio-prefix"); "audio-prefix");
} }
/* set dai_name */
snprintf(dai_props->dai_name, DAI_NAME_NUM, "be.%s",
dai_link->codec_dai_name);
} }
/* Simple Card assumes platform == cpu */ /* Simple Card assumes platform == cpu */
dai_link->platform_of_node = dai_link->cpu_of_node; dai_link->platform_of_node = dai_link->cpu_of_node;
dai_link->dpcm_playback = 1; dai_link->dpcm_playback = 1;
dai_link->dpcm_capture = 1; dai_link->dpcm_capture = 1;
dai_link->name = dai_props->dai_name;
dai_link->stream_name = dai_props->dai_name;
dai_link->ops = &rsrc_card_ops; dai_link->ops = &rsrc_card_ops;
dai_link->init = rsrc_card_dai_init; dai_link->init = rsrc_card_dai_init;
...@@ -299,7 +258,7 @@ static int rsrc_card_parse_clk(struct device_node *np, ...@@ -299,7 +258,7 @@ static int rsrc_card_parse_clk(struct device_node *np,
int idx, bool is_fe) int idx, bool is_fe)
{ {
struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
struct clk *clk; struct clk *clk;
struct device_node *of_np = is_fe ? dai_link->cpu_of_node : struct device_node *of_np = is_fe ? dai_link->cpu_of_node :
dai_link->codec_of_node; dai_link->codec_of_node;
...@@ -336,7 +295,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node, ...@@ -336,7 +295,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node,
{ {
struct device *dev = rsrc_priv_to_dev(priv); struct device *dev = rsrc_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx); struct snd_soc_dai_link *dai_link = rsrc_priv_to_link(priv, idx);
struct rsrc_card_dai *dai_props = rsrc_priv_to_props(priv, idx); struct asoc_simple_dai *dai_props = rsrc_priv_to_props(priv, idx);
int ret; int ret;
ret = rsrc_card_parse_links(np, priv, idx, is_fe); ret = rsrc_card_parse_links(np, priv, idx, is_fe);
...@@ -348,7 +307,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node, ...@@ -348,7 +307,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node,
return ret; return ret;
dev_dbg(dev, "\t%s / %04x / %d\n", dev_dbg(dev, "\t%s / %04x / %d\n",
dai_props->dai_name, dai_link->name,
dai_link->dai_fmt, dai_link->dai_fmt,
dai_props->sysclk); dai_props->sysclk);
...@@ -358,6 +317,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node, ...@@ -358,6 +317,7 @@ static int rsrc_card_dai_sub_link_of(struct device_node *node,
static int rsrc_card_dai_link_of(struct device_node *node, static int rsrc_card_dai_link_of(struct device_node *node,
struct rsrc_card_priv *priv) struct rsrc_card_priv *priv)
{ {
struct device *dev = rsrc_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link; struct snd_soc_dai_link *dai_link;
struct device_node *np; struct device_node *np;
unsigned int daifmt = 0; unsigned int daifmt = 0;
...@@ -370,8 +330,8 @@ static int rsrc_card_dai_link_of(struct device_node *node, ...@@ -370,8 +330,8 @@ static int rsrc_card_dai_link_of(struct device_node *node,
dai_link = rsrc_priv_to_link(priv, i); dai_link = rsrc_priv_to_link(priv, i);
if (strcmp(np->name, "codec") == 0) { if (strcmp(np->name, "codec") == 0) {
ret = rsrc_card_parse_daifmt(node, np, priv, ret = asoc_simple_card_parse_daifmt(dev, node, np,
dai_link, &daifmt); NULL, &daifmt);
if (ret < 0) if (ret < 0)
return ret; return ret;
break; break;
...@@ -402,7 +362,7 @@ static int rsrc_card_parse_of(struct device_node *node, ...@@ -402,7 +362,7 @@ static int rsrc_card_parse_of(struct device_node *node,
struct device *dev) struct device *dev)
{ {
const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev); const struct rsrc_card_of_data *of_data = of_device_get_match_data(dev);
struct rsrc_card_dai *props; struct asoc_simple_dai *props;
struct snd_soc_dai_link *links; struct snd_soc_dai_link *links;
int ret; int ret;
int num; int num;
...@@ -418,7 +378,6 @@ static int rsrc_card_parse_of(struct device_node *node, ...@@ -418,7 +378,6 @@ static int rsrc_card_parse_of(struct device_node *node,
priv->dai_props = props; priv->dai_props = props;
priv->dai_link = links; priv->dai_link = links;
priv->dai_num = num;
/* Init snd_soc_card */ /* Init snd_soc_card */
priv->snd_card.owner = THIS_MODULE; priv->snd_card.owner = THIS_MODULE;
...@@ -436,9 +395,6 @@ static int rsrc_card_parse_of(struct device_node *node, ...@@ -436,9 +395,6 @@ static int rsrc_card_parse_of(struct device_node *node,
"audio-routing"); "audio-routing");
} }
/* Parse the card name from DT */
snd_soc_of_parse_card_name(&priv->snd_card, "card-name");
/* sampling rate convert */ /* sampling rate convert */
of_property_read_u32(node, "convert-rate", &priv->convert_rate); of_property_read_u32(node, "convert-rate", &priv->convert_rate);
...@@ -454,8 +410,9 @@ static int rsrc_card_parse_of(struct device_node *node, ...@@ -454,8 +410,9 @@ static int rsrc_card_parse_of(struct device_node *node,
if (ret < 0) if (ret < 0)
return ret; return ret;
if (!priv->snd_card.name) ret = asoc_simple_card_parse_card_name(&priv->snd_card, "card-");
priv->snd_card.name = priv->snd_card.dai_link->name; if (ret < 0)
return ret;
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment