Commit e5fadb72 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/rk3036', 'asoc/topic/rockchip',...

Merge remote-tracking branches 'asoc/topic/rk3036', 'asoc/topic/rockchip', 'asoc/topic/rt274' and 'asoc/topic/rt5514' into asoc-next
......@@ -29,11 +29,14 @@ pdm: pdm@ff040000 {
dma-names = "rx";
pinctrl-names = "default", "sleep";
pinctrl-0 = <&pdmm0_clk
&pdmm0_fsync
&pdmm0_sdi0
&pdmm0_sdi1
&pdmm0_sdi2
&pdmm0_sdi3>;
pinctrl-1 = <&pdmm0_sleep>;
pinctrl-1 = <&pdmm0_clk_sleep
&pdmm0_sdi0_sleep
&pdmm0_sdi1_sleep
&pdmm0_sdi2_sleep
&pdmm0_sdi3_sleep>;
status = "disabled";
};
......@@ -4,7 +4,7 @@ Required properties:
- compatible: "rockchip,rk3399-gru-sound"
- rockchip,cpu: The phandle of the Rockchip I2S controller that's
connected to the codecs
- rockchip,codec: The phandle of the MAX98357A/RT5514/DA7219 codecs
- rockchip,codec: The phandle of the audio codecs
Optional properties:
- dmic-wakeup-delay-ms : specify delay time (ms) for DMIC ready.
......
......@@ -7,8 +7,12 @@ Required properties:
- compatible: should be one of the following:
- "rockchip,rk3066-i2s": for rk3066
- "rockchip,rk3036-i2s", "rockchip,rk3066-i2s": for rk3036
- "rockchip,rk3188-i2s", "rockchip,rk3066-i2s": for rk3188
- "rockchip,rk3228-i2s", "rockchip,rk3066-i2s": for rk3228
- "rockchip,rk3288-i2s", "rockchip,rk3066-i2s": for rk3288
- "rockchip,rk3328-i2s", "rockchip,rk3066-i2s": for rk3328
- "rockchip,rk3366-i2s", "rockchip,rk3066-i2s": for rk3366
- "rockchip,rk3368-i2s", "rockchip,rk3066-i2s": for rk3368
- "rockchip,rk3399-i2s", "rockchip,rk3066-i2s": for rk3399
- reg: physical base address of the controller and length of memory mapped
......
......@@ -1102,6 +1102,7 @@ MODULE_DEVICE_TABLE(i2c, rt274_i2c_id);
static const struct acpi_device_id rt274_acpi_match[] = {
{ "10EC0274", 0 },
{ "INT34C2", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, rt274_acpi_match);
......
......@@ -43,9 +43,7 @@ struct rt5514_dsp {
struct mutex dma_lock;
struct snd_pcm_substream *substream;
unsigned int buf_base, buf_limit, buf_rp;
size_t buf_size;
size_t dma_offset;
size_t dsp_offset;
size_t buf_size, get_size, dma_offset;
};
static const struct snd_pcm_hardware rt5514_spi_pcm_hardware = {
......@@ -80,6 +78,8 @@ static void rt5514_spi_copy_work(struct work_struct *work)
container_of(work, struct rt5514_dsp, copy_work.work);
struct snd_pcm_runtime *runtime;
size_t period_bytes, truncated_bytes = 0;
unsigned int cur_wp, remain_data;
u8 buf[8];
mutex_lock(&rt5514_dsp->dma_lock);
if (!rt5514_dsp->substream) {
......@@ -90,8 +90,24 @@ static void rt5514_spi_copy_work(struct work_struct *work)
runtime = rt5514_dsp->substream->runtime;
period_bytes = snd_pcm_lib_period_bytes(rt5514_dsp->substream);
if (rt5514_dsp->buf_size - rt5514_dsp->dsp_offset < period_bytes)
period_bytes = rt5514_dsp->buf_size - rt5514_dsp->dsp_offset;
if (rt5514_dsp->get_size >= rt5514_dsp->buf_size) {
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf,
sizeof(buf));
cur_wp = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
if (cur_wp >= rt5514_dsp->buf_rp)
remain_data = (cur_wp - rt5514_dsp->buf_rp);
else
remain_data =
(rt5514_dsp->buf_limit - rt5514_dsp->buf_rp) +
(cur_wp - rt5514_dsp->buf_base);
if (remain_data < period_bytes) {
schedule_delayed_work(&rt5514_dsp->copy_work, 5);
goto done;
}
}
if (rt5514_dsp->buf_rp + period_bytes <= rt5514_dsp->buf_limit) {
rt5514_spi_burst_read(rt5514_dsp->buf_rp,
......@@ -112,24 +128,62 @@ static void rt5514_spi_copy_work(struct work_struct *work)
runtime->dma_area + rt5514_dsp->dma_offset +
truncated_bytes, period_bytes - truncated_bytes);
rt5514_dsp->buf_rp = rt5514_dsp->buf_base +
period_bytes - truncated_bytes;
rt5514_dsp->buf_rp = rt5514_dsp->buf_base + period_bytes -
truncated_bytes;
}
rt5514_dsp->get_size += period_bytes;
rt5514_dsp->dma_offset += period_bytes;
if (rt5514_dsp->dma_offset >= runtime->dma_bytes)
rt5514_dsp->dma_offset = 0;
rt5514_dsp->dsp_offset += period_bytes;
snd_pcm_period_elapsed(rt5514_dsp->substream);
if (rt5514_dsp->dsp_offset < rt5514_dsp->buf_size)
schedule_delayed_work(&rt5514_dsp->copy_work, 5);
schedule_delayed_work(&rt5514_dsp->copy_work, 5);
done:
mutex_unlock(&rt5514_dsp->dma_lock);
}
static irqreturn_t rt5514_spi_irq(int irq, void *data)
{
struct rt5514_dsp *rt5514_dsp = data;
u8 buf[8];
rt5514_dsp->get_size = 0;
/**
* The address area x1800XXXX is the register address, and it cannot
* support spi burst read perfectly. So we use the spi burst read
* individually to make sure the data correctly.
*/
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_WP, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
if (rt5514_dsp->buf_rp % 8)
rt5514_dsp->buf_rp = (rt5514_dsp->buf_rp / 8) * 8;
rt5514_dsp->buf_size = rt5514_dsp->buf_limit - rt5514_dsp->buf_base;
if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
schedule_delayed_work(&rt5514_dsp->copy_work, 0);
return IRQ_HANDLED;
}
/* PCM for streaming audio from the DSP buffer */
static int rt5514_spi_pcm_open(struct snd_pcm_substream *substream)
{
......@@ -150,6 +204,7 @@ static int rt5514_spi_hw_params(struct snd_pcm_substream *substream,
ret = snd_pcm_lib_alloc_vmalloc_buffer(substream,
params_buffer_bytes(hw_params));
rt5514_dsp->substream = substream;
rt5514_dsp->dma_offset = 0;
mutex_unlock(&rt5514_dsp->dma_lock);
return ret;
......@@ -170,59 +225,6 @@ static int rt5514_spi_hw_free(struct snd_pcm_substream *substream)
return snd_pcm_lib_free_vmalloc_buffer(substream);
}
static int rt5514_spi_prepare(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct rt5514_dsp *rt5514_dsp =
snd_soc_platform_get_drvdata(rtd->platform);
u8 buf[8];
rt5514_dsp->dma_offset = 0;
rt5514_dsp->dsp_offset = 0;
/**
* The address area x1800XXXX is the register address, and it cannot
* support spi burst read perfectly. So we use the spi burst read
* individually to make sure the data correctly.
*/
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_BASE, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_base = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_LIMIT, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_limit = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_RP, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_rp = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
rt5514_spi_burst_read(RT5514_BUFFER_VOICE_SIZE, (u8 *)&buf,
sizeof(buf));
rt5514_dsp->buf_size = buf[0] | buf[1] << 8 | buf[2] << 16 |
buf[3] << 24;
return 0;
}
static int rt5514_spi_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct rt5514_dsp *rt5514_dsp =
snd_soc_platform_get_drvdata(rtd->platform);
if (cmd == SNDRV_PCM_TRIGGER_START) {
if (rt5514_dsp->buf_base && rt5514_dsp->buf_limit &&
rt5514_dsp->buf_rp && rt5514_dsp->buf_size)
schedule_delayed_work(&rt5514_dsp->copy_work, 0);
}
return 0;
}
static snd_pcm_uframes_t rt5514_spi_pcm_pointer(
struct snd_pcm_substream *substream)
{
......@@ -238,8 +240,6 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
.open = rt5514_spi_pcm_open,
.hw_params = rt5514_spi_hw_params,
.hw_free = rt5514_spi_hw_free,
.trigger = rt5514_spi_trigger,
.prepare = rt5514_spi_prepare,
.pointer = rt5514_spi_pcm_pointer,
.mmap = snd_pcm_lib_mmap_vmalloc,
.page = snd_pcm_lib_get_vmalloc_page,
......@@ -248,6 +248,7 @@ static const struct snd_pcm_ops rt5514_spi_pcm_ops = {
static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
{
struct rt5514_dsp *rt5514_dsp;
int ret;
rt5514_dsp = devm_kzalloc(platform->dev, sizeof(*rt5514_dsp),
GFP_KERNEL);
......@@ -257,6 +258,17 @@ static int rt5514_spi_pcm_probe(struct snd_soc_platform *platform)
INIT_DELAYED_WORK(&rt5514_dsp->copy_work, rt5514_spi_copy_work);
snd_soc_platform_set_drvdata(platform, rt5514_dsp);
if (rt5514_spi->irq) {
ret = devm_request_threaded_irq(&rt5514_spi->dev,
rt5514_spi->irq, NULL, rt5514_spi_irq,
IRQF_TRIGGER_RISING | IRQF_ONESHOT, "rt5514-spi",
rt5514_dsp);
if (ret)
dev_err(&rt5514_spi->dev,
"%s Failed to reguest IRQ: %d\n", __func__,
ret);
}
return 0;
}
......
......@@ -17,10 +17,9 @@
*/
#define RT5514_SPI_BUF_LEN 240
#define RT5514_BUFFER_VOICE_BASE 0x18001034
#define RT5514_BUFFER_VOICE_LIMIT 0x18001038
#define RT5514_BUFFER_VOICE_RP 0x1800103c
#define RT5514_BUFFER_VOICE_SIZE 0x18001040
#define RT5514_BUFFER_VOICE_BASE 0x18000200
#define RT5514_BUFFER_VOICE_LIMIT 0x18000204
#define RT5514_BUFFER_VOICE_WP 0x1800020c
/* SPI Command */
enum {
......
This diff is collapsed.
......@@ -37,6 +37,7 @@
#define RT5514_PLL3_CALIB_CTRL5 0x2124
#define RT5514_DELAY_BUF_CTRL1 0x2140
#define RT5514_DELAY_BUF_CTRL3 0x2148
#define RT5514_ASRC_IN_CTRL1 0x2180
#define RT5514_DOWNFILTER0_CTRL1 0x2190
#define RT5514_DOWNFILTER0_CTRL2 0x2194
#define RT5514_DOWNFILTER0_CTRL3 0x2198
......@@ -164,6 +165,18 @@
#define RT5514_I2S_DL_24 (0x2 << 0)
#define RT5514_I2S_DL_8 (0x3 << 0)
/* RT5514_I2S_CTRL2 (0x2014) */
#define RT5514_TDM_DOCKING_MODE (0x1 << 31)
#define RT5514_TDM_DOCKING_MODE_SFT 31
#define RT5514_TDM_DOCKING_VALID_CH_MASK (0x1 << 29)
#define RT5514_TDM_DOCKING_VALID_CH_SFT 29
#define RT5514_TDM_DOCKING_VALID_CH2 (0x0 << 29)
#define RT5514_TDM_DOCKING_VALID_CH4 (0x1 << 29)
#define RT5514_TDM_DOCKING_START_MASK (0x1 << 28)
#define RT5514_TDM_DOCKING_START_SFT 28
#define RT5514_TDM_DOCKING_START_SLOT0 (0x0 << 28)
#define RT5514_TDM_DOCKING_START_SLOT4 (0x1 << 28)
/* RT5514_DIG_SOURCE_CTRL (0x20a4) */
#define RT5514_AD1_DMIC_INPUT_SEL (0x1 << 1)
#define RT5514_AD1_DMIC_INPUT_SEL_SFT 1
......@@ -185,8 +198,14 @@
#define RT5514_CLK_AD0_EN_BIT 23
#define RT5514_CLK_DMIC_OUT_SEL_MASK (0x7 << 8)
#define RT5514_CLK_DMIC_OUT_SEL_SFT 8
#define RT5514_CLK_AD_ANA1_SEL_MASK (0xf << 0)
#define RT5514_CLK_AD_ANA1_SEL_SFT 0
/* RT5514_CLK_CTRL2 (0x2108) */
#define RT5514_CLK_AD1_ASRC_EN (0x1 << 17)
#define RT5514_CLK_AD1_ASRC_EN_BIT 17
#define RT5514_CLK_AD0_ASRC_EN (0x1 << 16)
#define RT5514_CLK_AD0_ASRC_EN_BIT 16
#define RT5514_CLK_SYS_DIV_OUT_MASK (0x7 << 8)
#define RT5514_CLK_SYS_DIV_OUT_SFT 8
#define RT5514_SEL_ADC_OSR_MASK (0x7 << 4)
......@@ -236,6 +255,7 @@
#define RT5514_FIRMWARE1 "rt5514_dsp_fw1.bin"
#define RT5514_FIRMWARE2 "rt5514_dsp_fw2.bin"
#define RT5514_FIRMWARE3 "rt5514_dsp_fw3.bin"
/* System Clock Source */
enum {
......@@ -262,6 +282,8 @@ struct rt5514_priv {
int pll_in;
int pll_out;
int dsp_enabled;
u8 *model_buf;
unsigned int model_len;
};
#endif /* __RT5514_H__ */
......@@ -68,6 +68,8 @@ config SND_SOC_RK3399_GRU_SOUND
select SND_SOC_RT5514
select SND_SOC_DA7219
select SND_SOC_RT5514_SPI
select SND_SOC_HDMI_CODEC
select SND_SOC_DMIC
help
Say Y or M here if you want to add support multiple codecs for SoC
audio on Rockchip RK3399 GRU boards.
......@@ -147,7 +147,7 @@ static int rk_init(struct snd_soc_pcm_runtime *runtime)
return 0;
}
static struct snd_soc_ops rk_ops = {
static const struct snd_soc_ops rk_ops = {
.hw_params = rk_hw_params,
};
......@@ -272,8 +272,6 @@ static int snd_rk_mc_probe(struct platform_device *pdev)
return ret;
}
platform_set_drvdata(pdev, card);
return ret;
}
......
......@@ -38,7 +38,7 @@
#define SOUND_FS 256
static unsigned int rt5514_dmic_delay;
static unsigned int dmic_wakeup_delay;
static struct snd_soc_jack rockchip_sound_jack;
......@@ -126,7 +126,7 @@ static int rockchip_sound_rt5514_hw_params(struct snd_pcm_substream *substream,
}
/* Wait for DMIC stable */
msleep(rt5514_dmic_delay);
msleep(dmic_wakeup_delay);
return 0;
}
......@@ -228,6 +228,67 @@ static int rockchip_sound_da7219_init(struct snd_soc_pcm_runtime *rtd)
return 0;
}
static int rockchip_sound_cdndp_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct snd_soc_dai *codec_dai = rtd->codec_dai;
int mclk, ret;
/* in bypass mode, the mclk has to be one of the frequencies below */
switch (params_rate(params)) {
case 8000:
case 16000:
case 24000:
case 32000:
case 48000:
case 64000:
case 96000:
mclk = 12288000;
break;
case 11025:
case 22050:
case 44100:
case 88200:
mclk = 11289600;
break;
default:
return -EINVAL;
}
ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
SND_SOC_CLOCK_OUT);
if (ret < 0) {
dev_err(codec_dai->dev, "Can't set cpu clock out %d\n", ret);
return ret;
}
return 0;
}
static int rockchip_sound_dmic_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned int mclk;
int ret;
mclk = params_rate(params) * SOUND_FS;
ret = snd_soc_dai_set_sysclk(rtd->cpu_dai, 0, mclk, 0);
if (ret) {
dev_err(rtd->card->dev, "%s() error setting sysclk to %u: %d\n",
__func__, mclk, ret);
return ret;
}
/* Wait for DMIC stable */
msleep(dmic_wakeup_delay);
return 0;
}
static const struct snd_soc_ops rockchip_sound_max98357a_ops = {
.hw_params = rockchip_sound_max98357a_hw_params,
};
......@@ -240,16 +301,70 @@ static const struct snd_soc_ops rockchip_sound_da7219_ops = {
.hw_params = rockchip_sound_da7219_hw_params,
};
static const struct snd_soc_ops rockchip_sound_cdndp_ops = {
.hw_params = rockchip_sound_cdndp_hw_params,
};
static const struct snd_soc_ops rockchip_sound_dmic_ops = {
.hw_params = rockchip_sound_dmic_hw_params,
};
static struct snd_soc_card rockchip_sound_card = {
.name = "rk3399-gru-sound",
.owner = THIS_MODULE,
.dapm_widgets = rockchip_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
.dapm_routes = rockchip_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes),
.controls = rockchip_controls,
.num_controls = ARRAY_SIZE(rockchip_controls),
};
enum {
DAILINK_CDNDP,
DAILINK_DA7219,
DAILINK_DMIC,
DAILINK_MAX98357A,
DAILINK_RT5514,
DAILINK_DA7219,
DAILINK_RT5514_DSP,
};
#define DAILINK_ENTITIES (DAILINK_DA7219 + 1)
static const char * const dailink_compat[] = {
[DAILINK_CDNDP] = "rockchip,rk3399-cdn-dp",
[DAILINK_DA7219] = "dlg,da7219",
[DAILINK_DMIC] = "dmic-codec",
[DAILINK_MAX98357A] = "maxim,max98357a",
[DAILINK_RT5514] = "realtek,rt5514-i2c",
[DAILINK_RT5514_DSP] = "realtek,rt5514-spi",
};
static struct snd_soc_dai_link rockchip_dailinks[] = {
static const struct snd_soc_dai_link rockchip_dais[] = {
[DAILINK_CDNDP] = {
.name = "DP",
.stream_name = "DP PCM",
.codec_dai_name = "i2s-hifi",
.ops = &rockchip_sound_cdndp_ops,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
[DAILINK_DA7219] = {
.name = "DA7219",
.stream_name = "DA7219 PCM",
.codec_dai_name = "da7219-hifi",
.init = rockchip_sound_da7219_init,
.ops = &rockchip_sound_da7219_ops,
/* set da7219 as slave */
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
[DAILINK_DMIC] = {
.name = "DMIC",
.stream_name = "DMIC PCM",
.codec_dai_name = "dmic-hifi",
.ops = &rockchip_sound_dmic_ops,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
[DAILINK_MAX98357A] = {
.name = "MAX98357A",
.stream_name = "MAX98357A PCM",
......@@ -268,108 +383,95 @@ static struct snd_soc_dai_link rockchip_dailinks[] = {
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
[DAILINK_DA7219] = {
.name = "DA7219",
.stream_name = "DA7219 PCM",
.codec_dai_name = "da7219-hifi",
.init = rockchip_sound_da7219_init,
.ops = &rockchip_sound_da7219_ops,
/* set da7219 as slave */
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
/* RT5514 DSP for voice wakeup via spi bus */
[DAILINK_RT5514_DSP] = {
.name = "RT5514 DSP",
.stream_name = "Wake on Voice",
.codec_name = "snd-soc-dummy",
.codec_dai_name = "snd-soc-dummy-dai",
.codec_dai_name = "rt5514-dsp-cpu-dai",
},
};
static struct snd_soc_card rockchip_sound_card = {
.name = "rk3399-gru-sound",
.owner = THIS_MODULE,
.dai_link = rockchip_dailinks,
.num_links = ARRAY_SIZE(rockchip_dailinks),
.dapm_widgets = rockchip_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(rockchip_dapm_widgets),
.dapm_routes = rockchip_dapm_routes,
.num_dapm_routes = ARRAY_SIZE(rockchip_dapm_routes),
.controls = rockchip_controls,
.num_controls = ARRAY_SIZE(rockchip_controls),
};
static int rockchip_sound_match_stub(struct device *dev, void *data)
static int rockchip_sound_codec_node_match(struct device_node *np_codec)
{
return 1;
}
int i;
static int rockchip_sound_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &rockchip_sound_card;
struct device_node *cpu_node;
struct device *dev;
struct device_driver *drv;
int i, ret;
cpu_node = of_parse_phandle(pdev->dev.of_node, "rockchip,cpu", 0);
if (!cpu_node) {
dev_err(&pdev->dev, "Property 'rockchip,cpu' missing or invalid\n");
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(dailink_compat); i++) {
if (of_device_is_compatible(np_codec, dailink_compat[i]))
return i;
}
return -1;
}
for (i = 0; i < DAILINK_ENTITIES; i++) {
rockchip_dailinks[i].platform_of_node = cpu_node;
rockchip_dailinks[i].cpu_of_node = cpu_node;
rockchip_dailinks[i].codec_of_node =
of_parse_phandle(pdev->dev.of_node, "rockchip,codec", i);
if (!rockchip_dailinks[i].codec_of_node) {
dev_err(&pdev->dev,
"Property[%d] 'rockchip,codec' missing or invalid\n", i);
static int rockchip_sound_of_parse_dais(struct device *dev,
struct snd_soc_card *card)
{
struct device_node *np_cpu, *np_cpu0, *np_cpu1;
struct device_node *np_codec;
struct snd_soc_dai_link *dai;
int i, index;
card->dai_link = devm_kzalloc(dev, sizeof(rockchip_dais),
GFP_KERNEL);
if (!card->dai_link)
return -ENOMEM;
np_cpu0 = of_parse_phandle(dev->of_node, "rockchip,cpu", 0);
np_cpu1 = of_parse_phandle(dev->of_node, "rockchip,cpu", 1);
card->num_links = 0;
for (i = 0; i < ARRAY_SIZE(rockchip_dais); i++) {
np_codec = of_parse_phandle(dev->of_node,
"rockchip,codec", i);
if (!np_codec)
break;
if (!of_device_is_available(np_codec))
continue;
index = rockchip_sound_codec_node_match(np_codec);
if (index < 0)
continue;
np_cpu = (index == DAILINK_CDNDP) ? np_cpu1 : np_cpu0;
if (!np_cpu) {
dev_err(dev, "Missing 'rockchip,cpu' for %s\n",
rockchip_dais[index].name);
return -EINVAL;
}
}
/**
* To acquire the spi driver of the rt5514 and set the dai-links names
* for soc_bind_dai_link
*/
drv = driver_find("rt5514", &spi_bus_type);
if (!drv) {
dev_err(&pdev->dev, "Can not find the rt5514 driver at the spi bus\n");
return -EINVAL;
dai = &card->dai_link[card->num_links++];
*dai = rockchip_dais[index];
dai->codec_of_node = np_codec;
dai->platform_of_node = np_cpu;
dai->cpu_of_node = np_cpu;
}
dev = driver_find_device(drv, NULL, NULL, rockchip_sound_match_stub);
if (!dev) {
dev_err(&pdev->dev, "Can not find the rt5514 device\n");
return -ENODEV;
return 0;
}
static int rockchip_sound_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &rockchip_sound_card;
int ret;
ret = rockchip_sound_of_parse_dais(&pdev->dev, card);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to parse dais: %d\n", ret);
return ret;
}
/* Set DMIC delay */
ret = device_property_read_u32(&pdev->dev, "dmic-delay",
&rt5514_dmic_delay);
/* Set DMIC wakeup delay */
ret = device_property_read_u32(&pdev->dev, "dmic-wakeup-delay-ms",
&dmic_wakeup_delay);
if (ret) {
rt5514_dmic_delay = 0;
dmic_wakeup_delay = 0;
dev_dbg(&pdev->dev,
"no optional property 'dmic-delay' found, default: no delay\n");
"no optional property 'dmic-wakeup-delay-ms' found, default: no delay\n");
}
rockchip_dailinks[DAILINK_RT5514_DSP].cpu_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
rockchip_dailinks[DAILINK_RT5514_DSP].cpu_dai_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
rockchip_dailinks[DAILINK_RT5514_DSP].platform_name = kstrdup_const(dev_name(dev), GFP_KERNEL);
card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret)
dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n",
__func__, ret);
return ret;
return devm_snd_soc_register_card(&pdev->dev, card);
}
static const struct of_device_id rockchip_sound_of_match[] = {
......
......@@ -579,10 +579,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
int val;
i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL);
if (!i2s) {
dev_err(&pdev->dev, "Can't allocate rk_i2s_dev\n");
if (!i2s)
return -ENOMEM;
}
i2s->dev = &pdev->dev;
......
......@@ -249,7 +249,7 @@ static int rockchip_pdm_dai_probe(struct snd_soc_dai *dai)
return 0;
}
static struct snd_soc_dai_ops rockchip_pdm_dai_ops = {
static const struct snd_soc_dai_ops rockchip_pdm_dai_ops = {
.set_fmt = rockchip_pdm_set_fmt,
.trigger = rockchip_pdm_trigger,
.hw_params = rockchip_pdm_hw_params,
......
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