Merge remote-tracking branches 'asoc/topic/rt5670', 'asoc/topic/rt5677', 'asoc/topic/s6000', 'asoc/topic/samsung' and 'asoc/topic/sh-fsi' into asoc-next

This commit is contained in:
Mark Brown 2014-08-04 16:32:01 +01:00
31 changed files with 5147 additions and 852 deletions

View file

@ -0,0 +1,35 @@
Samsung Exynos Odroid X2/U3 audio complex with MAX98090 codec
Required properties:
- compatible : "samsung,odroidx2-audio" - for Odroid X2 board,
"samsung,odroidu3-audio" - for Odroid U3 board
- samsung,model : the user-visible name of this sound complex
- samsung,i2s-controller : the phandle of the I2S controller
- samsung,audio-codec : the phandle of the MAX98090 audio codec
- samsung,audio-routing : a list of the connections between audio
components; each entry is a pair of strings, the first being the
connection's sink, the second being the connection's source;
valid names for sources and sinks are the MAX98090's pins (as
documented in its binding), and the jacks on the board
For Odroid X2:
* Headphone Jack
* Mic Jack
* DMIC
For Odroid U3:
* Headphone Jack
* Speakers
Example:
sound {
compatible = "samsung,odroidu3-audio";
samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&max98090>;
samsung,model = "Odroid-X2";
samsung,audio-routing =
"Headphone Jack", "HPL",
"Headphone Jack", "HPR",
"IN1", "Mic Jack",
"Mic Jack", "MICBIAS";
};

View file

@ -3,15 +3,20 @@ Audio Binding for Snow boards
Required properties: Required properties:
- compatible : Can be one of the following, - compatible : Can be one of the following,
"google,snow-audio-max98090" or "google,snow-audio-max98090" or
"google,snow-audio-max98091" or
"google,snow-audio-max98095" "google,snow-audio-max98095"
- samsung,i2s-controller: The phandle of the Samsung I2S controller - samsung,i2s-controller: The phandle of the Samsung I2S controller
- samsung,audio-codec: The phandle of the audio codec - samsung,audio-codec: The phandle of the audio codec
Optional:
- samsung,model: The name of the sound-card
Example: Example:
sound { sound {
compatible = "google,snow-audio-max98095"; compatible = "google,snow-audio-max98095";
samsung,model = "Snow-I2S-MAX98095";
samsung,i2s-controller = <&i2s0>; samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&max98095>; samsung,audio-codec = <&max98095>;
}; };

View file

@ -15,15 +15,6 @@
#define S3C64XX_AC97_GPE 1 #define S3C64XX_AC97_GPE 1
extern void s3c64xx_ac97_setup_gpio(int); extern void s3c64xx_ac97_setup_gpio(int);
/*
* The machine init code calls s5p*_spdif_setup_gpio with
* one of these defines in order to select appropriate bank
* of GPIO for S/PDIF pins
*/
#define S5PC100_SPDIF_GPD 0
#define S5PC100_SPDIF_GPG3 1
extern void s5pc100_spdif_setup_gpio(int);
struct samsung_i2s { struct samsung_i2s {
/* If the Primary DAI has 5.1 Channels */ /* If the Primary DAI has 5.1 Channels */
#define QUIRK_PRI_6CHAN (1 << 0) #define QUIRK_PRI_6CHAN (1 << 0)

27
include/sound/rt5670.h Normal file
View file

@ -0,0 +1,27 @@
/*
* linux/sound/rt5670.h -- Platform data for RT5670
*
* Copyright 2014 Realtek Microelectronics
*
* 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 __LINUX_SND_RT5670_H
#define __LINUX_SND_RT5670_H
struct rt5670_platform_data {
int jd_mode;
bool in2_diff;
bool dmic_en;
unsigned int dmic1_data_pin;
/* 0 = GPIO6; 1 = IN2P; 3 = GPIO7*/
unsigned int dmic2_data_pin;
/* 0 = GPIO8; 1 = IN3N; */
unsigned int dmic3_data_pin;
/* 0 = GPIO9; 1 = GPIO10; 2 = GPIO5*/
};
#endif

View file

@ -80,6 +80,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_RT5640 if I2C select SND_SOC_RT5640 if I2C
select SND_SOC_RT5645 if I2C select SND_SOC_RT5645 if I2C
select SND_SOC_RT5651 if I2C select SND_SOC_RT5651 if I2C
select SND_SOC_RT5670 if I2C
select SND_SOC_RT5677 if I2C select SND_SOC_RT5677 if I2C
select SND_SOC_SGTL5000 if I2C select SND_SOC_SGTL5000 if I2C
select SND_SOC_SI476X if MFD_SI476X_CORE select SND_SOC_SI476X if MFD_SI476X_CORE
@ -452,9 +453,13 @@ config SND_SOC_RL6231
default y if SND_SOC_RT5640=y default y if SND_SOC_RT5640=y
default y if SND_SOC_RT5645=y default y if SND_SOC_RT5645=y
default y if SND_SOC_RT5651=y default y if SND_SOC_RT5651=y
default y if SND_SOC_RT5670=y
default y if SND_SOC_RT5677=y
default m if SND_SOC_RT5640=m default m if SND_SOC_RT5640=m
default m if SND_SOC_RT5645=m default m if SND_SOC_RT5645=m
default m if SND_SOC_RT5651=m default m if SND_SOC_RT5651=m
default m if SND_SOC_RT5670=m
default m if SND_SOC_RT5677=m
config SND_SOC_RT286 config SND_SOC_RT286
tristate tristate
@ -471,6 +476,9 @@ config SND_SOC_RT5645
config SND_SOC_RT5651 config SND_SOC_RT5651
tristate tristate
config SND_SOC_RT5670
tristate
config SND_SOC_RT5677 config SND_SOC_RT5677
tristate tristate

View file

@ -74,6 +74,7 @@ snd-soc-rt5631-objs := rt5631.o
snd-soc-rt5640-objs := rt5640.o snd-soc-rt5640-objs := rt5640.o
snd-soc-rt5645-objs := rt5645.o snd-soc-rt5645-objs := rt5645.o
snd-soc-rt5651-objs := rt5651.o snd-soc-rt5651-objs := rt5651.o
snd-soc-rt5670-objs := rt5670.o
snd-soc-rt5677-objs := rt5677.o snd-soc-rt5677-objs := rt5677.o
snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-sgtl5000-objs := sgtl5000.o
snd-soc-alc5623-objs := alc5623.o snd-soc-alc5623-objs := alc5623.o
@ -243,6 +244,7 @@ obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o

View file

@ -0,0 +1,54 @@
/*
* rt5670-dsp.h -- RT5670 ALSA SoC DSP driver
*
* Copyright 2014 Realtek Microelectronics
* Author: Bard Liao <bardliao@realtek.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 __RT5670_DSP_H__
#define __RT5670_DSP_H__
#define RT5670_DSP_CTRL1 0xe0
#define RT5670_DSP_CTRL2 0xe1
#define RT5670_DSP_CTRL3 0xe2
#define RT5670_DSP_CTRL4 0xe3
#define RT5670_DSP_CTRL5 0xe4
/* DSP Control 1 (0xe0) */
#define RT5670_DSP_CMD_MASK (0xff << 8)
#define RT5670_DSP_CMD_PE (0x0d << 8) /* Patch Entry */
#define RT5670_DSP_CMD_MW (0x3b << 8) /* Memory Write */
#define RT5670_DSP_CMD_MR (0x37 << 8) /* Memory Read */
#define RT5670_DSP_CMD_RR (0x60 << 8) /* Register Read */
#define RT5670_DSP_CMD_RW (0x68 << 8) /* Register Write */
#define RT5670_DSP_REG_DATHI (0x26 << 8) /* High Data Addr */
#define RT5670_DSP_REG_DATLO (0x25 << 8) /* Low Data Addr */
#define RT5670_DSP_CLK_MASK (0x3 << 6)
#define RT5670_DSP_CLK_SFT 6
#define RT5670_DSP_CLK_768K (0x0 << 6)
#define RT5670_DSP_CLK_384K (0x1 << 6)
#define RT5670_DSP_CLK_192K (0x2 << 6)
#define RT5670_DSP_CLK_96K (0x3 << 6)
#define RT5670_DSP_BUSY_MASK (0x1 << 5)
#define RT5670_DSP_RW_MASK (0x1 << 4)
#define RT5670_DSP_DL_MASK (0x3 << 2)
#define RT5670_DSP_DL_0 (0x0 << 2)
#define RT5670_DSP_DL_1 (0x1 << 2)
#define RT5670_DSP_DL_2 (0x2 << 2)
#define RT5670_DSP_DL_3 (0x3 << 2)
#define RT5670_DSP_I2C_AL_16 (0x1 << 1)
#define RT5670_DSP_CMD_EN (0x1)
struct rt5670_dsp_param {
u16 cmd_fmt;
u16 addr;
u16 data;
u8 cmd;
};
#endif /* __RT5670_DSP_H__ */

2657
sound/soc/codecs/rt5670.c Normal file

File diff suppressed because it is too large Load diff

2000
sound/soc/codecs/rt5670.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,7 @@
#include <sound/initval.h> #include <sound/initval.h>
#include <sound/tlv.h> #include <sound/tlv.h>
#include "rl6231.h"
#include "rt5677.h" #include "rt5677.h"
#define RT5677_DEVICE_ID 0x6327 #define RT5677_DEVICE_ID 0x6327
@ -604,19 +605,19 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
adc_vol_tlv), adc_vol_tlv),
/* ADC Boost Volume Control */ /* ADC Boost Volume Control */
SOC_DOUBLE_TLV("STO1 ADC Boost Gain", RT5677_STO1_2_ADC_BST, SOC_DOUBLE_TLV("STO1 ADC Boost Volume", RT5677_STO1_2_ADC_BST,
RT5677_STO1_ADC_L_BST_SFT, RT5677_STO1_ADC_R_BST_SFT, 3, 0, RT5677_STO1_ADC_L_BST_SFT, RT5677_STO1_ADC_R_BST_SFT, 3, 0,
adc_bst_tlv), adc_bst_tlv),
SOC_DOUBLE_TLV("STO2 ADC Boost Gain", RT5677_STO1_2_ADC_BST, SOC_DOUBLE_TLV("STO2 ADC Boost Volume", RT5677_STO1_2_ADC_BST,
RT5677_STO2_ADC_L_BST_SFT, RT5677_STO2_ADC_R_BST_SFT, 3, 0, RT5677_STO2_ADC_L_BST_SFT, RT5677_STO2_ADC_R_BST_SFT, 3, 0,
adc_bst_tlv), adc_bst_tlv),
SOC_DOUBLE_TLV("STO3 ADC Boost Gain", RT5677_STO3_4_ADC_BST, SOC_DOUBLE_TLV("STO3 ADC Boost Volume", RT5677_STO3_4_ADC_BST,
RT5677_STO3_ADC_L_BST_SFT, RT5677_STO3_ADC_R_BST_SFT, 3, 0, RT5677_STO3_ADC_L_BST_SFT, RT5677_STO3_ADC_R_BST_SFT, 3, 0,
adc_bst_tlv), adc_bst_tlv),
SOC_DOUBLE_TLV("STO4 ADC Boost Gain", RT5677_STO3_4_ADC_BST, SOC_DOUBLE_TLV("STO4 ADC Boost Volume", RT5677_STO3_4_ADC_BST,
RT5677_STO4_ADC_L_BST_SFT, RT5677_STO4_ADC_R_BST_SFT, 3, 0, RT5677_STO4_ADC_L_BST_SFT, RT5677_STO4_ADC_R_BST_SFT, 3, 0,
adc_bst_tlv), adc_bst_tlv),
SOC_DOUBLE_TLV("Mono ADC Boost Gain", RT5677_ADC_BST_CTRL2, SOC_DOUBLE_TLV("Mono ADC Boost Volume", RT5677_ADC_BST_CTRL2,
RT5677_MONO_ADC_L_BST_SFT, RT5677_MONO_ADC_R_BST_SFT, 3, 0, RT5677_MONO_ADC_L_BST_SFT, RT5677_MONO_ADC_R_BST_SFT, 3, 0,
adc_bst_tlv), adc_bst_tlv),
}; };
@ -636,21 +637,7 @@ static int set_dmic_clk(struct snd_soc_dapm_widget *w,
{ {
struct snd_soc_codec *codec = w->codec; struct snd_soc_codec *codec = w->codec;
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
int div[] = {2, 3, 4, 6, 8, 12}, idx = -EINVAL, i; int idx = rl6231_calc_dmic_clk(rt5677->sysclk);
int rate, red, bound, temp;
rate = rt5677->sysclk;
red = 3000000 * 12;
for (i = 0; i < ARRAY_SIZE(div); i++) {
bound = div[i] * 3000000;
if (rate > bound)
continue;
temp = bound - rate;
if (temp < red) {
red = temp;
idx = i;
}
}
if (idx < 0) if (idx < 0)
dev_err(codec->dev, "Failed to set DMIC clock\n"); dev_err(codec->dev, "Failed to set DMIC clock\n");
@ -951,7 +938,7 @@ static const struct snd_kcontrol_new rt5677_ob_7_mix[] = {
/* Mux */ /* Mux */
/* DAC1 L/R source */ /* MX-29 [10:8] */ /* DAC1 L/R Source */ /* MX-29 [10:8] */
static const char * const rt5677_dac1_src[] = { static const char * const rt5677_dac1_src[] = {
"IF1 DAC 01", "IF2 DAC 01", "IF3 DAC LR", "IF4 DAC LR", "SLB DAC 01", "IF1 DAC 01", "IF2 DAC 01", "IF3 DAC LR", "IF4 DAC LR", "SLB DAC 01",
"OB 01" "OB 01"
@ -962,9 +949,9 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_DAC1_L_SEL_SFT, rt5677_dac1_src); RT5677_DAC1_L_SEL_SFT, rt5677_dac1_src);
static const struct snd_kcontrol_new rt5677_dac1_mux = static const struct snd_kcontrol_new rt5677_dac1_mux =
SOC_DAPM_ENUM("DAC1 source", rt5677_dac1_enum); SOC_DAPM_ENUM("DAC1 Source", rt5677_dac1_enum);
/* ADDA1 L/R source */ /* MX-29 [1:0] */ /* ADDA1 L/R Source */ /* MX-29 [1:0] */
static const char * const rt5677_adda1_src[] = { static const char * const rt5677_adda1_src[] = {
"STO1 ADC MIX", "STO2 ADC MIX", "OB 67", "STO1 ADC MIX", "STO2 ADC MIX", "OB 67",
}; };
@ -974,10 +961,10 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_ADDA1_SEL_SFT, rt5677_adda1_src); RT5677_ADDA1_SEL_SFT, rt5677_adda1_src);
static const struct snd_kcontrol_new rt5677_adda1_mux = static const struct snd_kcontrol_new rt5677_adda1_mux =
SOC_DAPM_ENUM("ADDA1 source", rt5677_adda1_enum); SOC_DAPM_ENUM("ADDA1 Source", rt5677_adda1_enum);
/*DAC2 L/R source*/ /* MX-1B [6:4] [2:0] */ /*DAC2 L/R Source*/ /* MX-1B [6:4] [2:0] */
static const char * const rt5677_dac2l_src[] = { static const char * const rt5677_dac2l_src[] = {
"IF1 DAC 2", "IF2 DAC 2", "IF3 DAC L", "IF4 DAC L", "SLB DAC 2", "IF1 DAC 2", "IF2 DAC 2", "IF3 DAC L", "IF4 DAC L", "SLB DAC 2",
"OB 2", "OB 2",
@ -988,7 +975,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_DAC2_L_SRC_SFT, rt5677_dac2l_src); RT5677_SEL_DAC2_L_SRC_SFT, rt5677_dac2l_src);
static const struct snd_kcontrol_new rt5677_dac2_l_mux = static const struct snd_kcontrol_new rt5677_dac2_l_mux =
SOC_DAPM_ENUM("DAC2 L source", rt5677_dac2l_enum); SOC_DAPM_ENUM("DAC2 L Source", rt5677_dac2l_enum);
static const char * const rt5677_dac2r_src[] = { static const char * const rt5677_dac2r_src[] = {
"IF1 DAC 3", "IF2 DAC 3", "IF3 DAC R", "IF4 DAC R", "SLB DAC 3", "IF1 DAC 3", "IF2 DAC 3", "IF3 DAC R", "IF4 DAC R", "SLB DAC 3",
@ -1000,9 +987,9 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_DAC2_R_SRC_SFT, rt5677_dac2r_src); RT5677_SEL_DAC2_R_SRC_SFT, rt5677_dac2r_src);
static const struct snd_kcontrol_new rt5677_dac2_r_mux = static const struct snd_kcontrol_new rt5677_dac2_r_mux =
SOC_DAPM_ENUM("DAC2 R source", rt5677_dac2r_enum); SOC_DAPM_ENUM("DAC2 R Source", rt5677_dac2r_enum);
/*DAC3 L/R source*/ /* MX-16 [6:4] [2:0] */ /*DAC3 L/R Source*/ /* MX-16 [6:4] [2:0] */
static const char * const rt5677_dac3l_src[] = { static const char * const rt5677_dac3l_src[] = {
"IF1 DAC 4", "IF2 DAC 4", "IF3 DAC L", "IF4 DAC L", "IF1 DAC 4", "IF2 DAC 4", "IF3 DAC L", "IF4 DAC L",
"SLB DAC 4", "OB 4" "SLB DAC 4", "OB 4"
@ -1013,7 +1000,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_DAC3_L_SRC_SFT, rt5677_dac3l_src); RT5677_SEL_DAC3_L_SRC_SFT, rt5677_dac3l_src);
static const struct snd_kcontrol_new rt5677_dac3_l_mux = static const struct snd_kcontrol_new rt5677_dac3_l_mux =
SOC_DAPM_ENUM("DAC3 L source", rt5677_dac3l_enum); SOC_DAPM_ENUM("DAC3 L Source", rt5677_dac3l_enum);
static const char * const rt5677_dac3r_src[] = { static const char * const rt5677_dac3r_src[] = {
"IF1 DAC 5", "IF2 DAC 5", "IF3 DAC R", "IF4 DAC R", "IF1 DAC 5", "IF2 DAC 5", "IF3 DAC R", "IF4 DAC R",
@ -1025,9 +1012,9 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_DAC3_R_SRC_SFT, rt5677_dac3r_src); RT5677_SEL_DAC3_R_SRC_SFT, rt5677_dac3r_src);
static const struct snd_kcontrol_new rt5677_dac3_r_mux = static const struct snd_kcontrol_new rt5677_dac3_r_mux =
SOC_DAPM_ENUM("DAC3 R source", rt5677_dac3r_enum); SOC_DAPM_ENUM("DAC3 R Source", rt5677_dac3r_enum);
/*DAC4 L/R source*/ /* MX-16 [14:12] [10:8] */ /*DAC4 L/R Source*/ /* MX-16 [14:12] [10:8] */
static const char * const rt5677_dac4l_src[] = { static const char * const rt5677_dac4l_src[] = {
"IF1 DAC 6", "IF2 DAC 6", "IF3 DAC L", "IF4 DAC L", "IF1 DAC 6", "IF2 DAC 6", "IF3 DAC L", "IF4 DAC L",
"SLB DAC 6", "OB 6" "SLB DAC 6", "OB 6"
@ -1038,7 +1025,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_DAC4_L_SRC_SFT, rt5677_dac4l_src); RT5677_SEL_DAC4_L_SRC_SFT, rt5677_dac4l_src);
static const struct snd_kcontrol_new rt5677_dac4_l_mux = static const struct snd_kcontrol_new rt5677_dac4_l_mux =
SOC_DAPM_ENUM("DAC4 L source", rt5677_dac4l_enum); SOC_DAPM_ENUM("DAC4 L Source", rt5677_dac4l_enum);
static const char * const rt5677_dac4r_src[] = { static const char * const rt5677_dac4r_src[] = {
"IF1 DAC 7", "IF2 DAC 7", "IF3 DAC R", "IF4 DAC R", "IF1 DAC 7", "IF2 DAC 7", "IF3 DAC R", "IF4 DAC R",
@ -1050,7 +1037,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_DAC4_R_SRC_SFT, rt5677_dac4r_src); RT5677_SEL_DAC4_R_SRC_SFT, rt5677_dac4r_src);
static const struct snd_kcontrol_new rt5677_dac4_r_mux = static const struct snd_kcontrol_new rt5677_dac4_r_mux =
SOC_DAPM_ENUM("DAC4 R source", rt5677_dac4r_enum); SOC_DAPM_ENUM("DAC4 R Source", rt5677_dac4r_enum);
/* In/OutBound Source Pass SRC */ /* MX-A5 [3] [4] [0] [1] [2] */ /* In/OutBound Source Pass SRC */ /* MX-A5 [3] [4] [0] [1] [2] */
static const char * const rt5677_iob_bypass_src[] = { static const char * const rt5677_iob_bypass_src[] = {
@ -1062,35 +1049,35 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_SRC_OB01_SFT, rt5677_iob_bypass_src); RT5677_SEL_SRC_OB01_SFT, rt5677_iob_bypass_src);
static const struct snd_kcontrol_new rt5677_ob01_bypass_src_mux = static const struct snd_kcontrol_new rt5677_ob01_bypass_src_mux =
SOC_DAPM_ENUM("OB01 Bypass source", rt5677_ob01_bypass_src_enum); SOC_DAPM_ENUM("OB01 Bypass Source", rt5677_ob01_bypass_src_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_ob23_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL, rt5677_ob23_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL,
RT5677_SEL_SRC_OB23_SFT, rt5677_iob_bypass_src); RT5677_SEL_SRC_OB23_SFT, rt5677_iob_bypass_src);
static const struct snd_kcontrol_new rt5677_ob23_bypass_src_mux = static const struct snd_kcontrol_new rt5677_ob23_bypass_src_mux =
SOC_DAPM_ENUM("OB23 Bypass source", rt5677_ob23_bypass_src_enum); SOC_DAPM_ENUM("OB23 Bypass Source", rt5677_ob23_bypass_src_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_ib01_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL, rt5677_ib01_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL,
RT5677_SEL_SRC_IB01_SFT, rt5677_iob_bypass_src); RT5677_SEL_SRC_IB01_SFT, rt5677_iob_bypass_src);
static const struct snd_kcontrol_new rt5677_ib01_bypass_src_mux = static const struct snd_kcontrol_new rt5677_ib01_bypass_src_mux =
SOC_DAPM_ENUM("IB01 Bypass source", rt5677_ib01_bypass_src_enum); SOC_DAPM_ENUM("IB01 Bypass Source", rt5677_ib01_bypass_src_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_ib23_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL, rt5677_ib23_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL,
RT5677_SEL_SRC_IB23_SFT, rt5677_iob_bypass_src); RT5677_SEL_SRC_IB23_SFT, rt5677_iob_bypass_src);
static const struct snd_kcontrol_new rt5677_ib23_bypass_src_mux = static const struct snd_kcontrol_new rt5677_ib23_bypass_src_mux =
SOC_DAPM_ENUM("IB23 Bypass source", rt5677_ib23_bypass_src_enum); SOC_DAPM_ENUM("IB23 Bypass Source", rt5677_ib23_bypass_src_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_ib45_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL, rt5677_ib45_bypass_src_enum, RT5677_DSP_IN_OUTB_CTRL,
RT5677_SEL_SRC_IB45_SFT, rt5677_iob_bypass_src); RT5677_SEL_SRC_IB45_SFT, rt5677_iob_bypass_src);
static const struct snd_kcontrol_new rt5677_ib45_bypass_src_mux = static const struct snd_kcontrol_new rt5677_ib45_bypass_src_mux =
SOC_DAPM_ENUM("IB45 Bypass source", rt5677_ib45_bypass_src_enum); SOC_DAPM_ENUM("IB45 Bypass Source", rt5677_ib45_bypass_src_enum);
/* Stereo ADC Source 2 */ /* MX-27 MX26 MX25 [11:10] */ /* Stereo ADC Source 2 */ /* MX-27 MX26 MX25 [11:10] */
static const char * const rt5677_stereo_adc2_src[] = { static const char * const rt5677_stereo_adc2_src[] = {
@ -1102,21 +1089,21 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_STO1_ADC2_SFT, rt5677_stereo_adc2_src); RT5677_SEL_STO1_ADC2_SFT, rt5677_stereo_adc2_src);
static const struct snd_kcontrol_new rt5677_sto1_adc2_mux = static const struct snd_kcontrol_new rt5677_sto1_adc2_mux =
SOC_DAPM_ENUM("Stereo1 ADC2 source", rt5677_stereo1_adc2_enum); SOC_DAPM_ENUM("Stereo1 ADC2 Source", rt5677_stereo1_adc2_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo2_adc2_enum, RT5677_STO2_ADC_MIXER, rt5677_stereo2_adc2_enum, RT5677_STO2_ADC_MIXER,
RT5677_SEL_STO2_ADC2_SFT, rt5677_stereo_adc2_src); RT5677_SEL_STO2_ADC2_SFT, rt5677_stereo_adc2_src);
static const struct snd_kcontrol_new rt5677_sto2_adc2_mux = static const struct snd_kcontrol_new rt5677_sto2_adc2_mux =
SOC_DAPM_ENUM("Stereo2 ADC2 source", rt5677_stereo2_adc2_enum); SOC_DAPM_ENUM("Stereo2 ADC2 Source", rt5677_stereo2_adc2_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo3_adc2_enum, RT5677_STO3_ADC_MIXER, rt5677_stereo3_adc2_enum, RT5677_STO3_ADC_MIXER,
RT5677_SEL_STO3_ADC2_SFT, rt5677_stereo_adc2_src); RT5677_SEL_STO3_ADC2_SFT, rt5677_stereo_adc2_src);
static const struct snd_kcontrol_new rt5677_sto3_adc2_mux = static const struct snd_kcontrol_new rt5677_sto3_adc2_mux =
SOC_DAPM_ENUM("Stereo3 ADC2 source", rt5677_stereo3_adc2_enum); SOC_DAPM_ENUM("Stereo3 ADC2 Source", rt5677_stereo3_adc2_enum);
/* DMIC Source */ /* MX-28 [9:8][1:0] MX-27 MX-26 MX-25 MX-24 [9:8] */ /* DMIC Source */ /* MX-28 [9:8][1:0] MX-27 MX-26 MX-25 MX-24 [9:8] */
static const char * const rt5677_dmic_src[] = { static const char * const rt5677_dmic_src[] = {
@ -1128,44 +1115,44 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_MONO_DMIC_L_SFT, rt5677_dmic_src); RT5677_SEL_MONO_DMIC_L_SFT, rt5677_dmic_src);
static const struct snd_kcontrol_new rt5677_mono_dmic_l_mux = static const struct snd_kcontrol_new rt5677_mono_dmic_l_mux =
SOC_DAPM_ENUM("Mono DMIC L source", rt5677_mono_dmic_l_enum); SOC_DAPM_ENUM("Mono DMIC L Source", rt5677_mono_dmic_l_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_mono_dmic_r_enum, RT5677_MONO_ADC_MIXER, rt5677_mono_dmic_r_enum, RT5677_MONO_ADC_MIXER,
RT5677_SEL_MONO_DMIC_R_SFT, rt5677_dmic_src); RT5677_SEL_MONO_DMIC_R_SFT, rt5677_dmic_src);
static const struct snd_kcontrol_new rt5677_mono_dmic_r_mux = static const struct snd_kcontrol_new rt5677_mono_dmic_r_mux =
SOC_DAPM_ENUM("Mono DMIC R source", rt5677_mono_dmic_r_enum); SOC_DAPM_ENUM("Mono DMIC R Source", rt5677_mono_dmic_r_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo1_dmic_enum, RT5677_STO1_ADC_MIXER, rt5677_stereo1_dmic_enum, RT5677_STO1_ADC_MIXER,
RT5677_SEL_STO1_DMIC_SFT, rt5677_dmic_src); RT5677_SEL_STO1_DMIC_SFT, rt5677_dmic_src);
static const struct snd_kcontrol_new rt5677_sto1_dmic_mux = static const struct snd_kcontrol_new rt5677_sto1_dmic_mux =
SOC_DAPM_ENUM("Stereo1 DMIC source", rt5677_stereo1_dmic_enum); SOC_DAPM_ENUM("Stereo1 DMIC Source", rt5677_stereo1_dmic_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo2_dmic_enum, RT5677_STO2_ADC_MIXER, rt5677_stereo2_dmic_enum, RT5677_STO2_ADC_MIXER,
RT5677_SEL_STO2_DMIC_SFT, rt5677_dmic_src); RT5677_SEL_STO2_DMIC_SFT, rt5677_dmic_src);
static const struct snd_kcontrol_new rt5677_sto2_dmic_mux = static const struct snd_kcontrol_new rt5677_sto2_dmic_mux =
SOC_DAPM_ENUM("Stereo2 DMIC source", rt5677_stereo2_dmic_enum); SOC_DAPM_ENUM("Stereo2 DMIC Source", rt5677_stereo2_dmic_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo3_dmic_enum, RT5677_STO3_ADC_MIXER, rt5677_stereo3_dmic_enum, RT5677_STO3_ADC_MIXER,
RT5677_SEL_STO3_DMIC_SFT, rt5677_dmic_src); RT5677_SEL_STO3_DMIC_SFT, rt5677_dmic_src);
static const struct snd_kcontrol_new rt5677_sto3_dmic_mux = static const struct snd_kcontrol_new rt5677_sto3_dmic_mux =
SOC_DAPM_ENUM("Stereo3 DMIC source", rt5677_stereo3_dmic_enum); SOC_DAPM_ENUM("Stereo3 DMIC Source", rt5677_stereo3_dmic_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo4_dmic_enum, RT5677_STO4_ADC_MIXER, rt5677_stereo4_dmic_enum, RT5677_STO4_ADC_MIXER,
RT5677_SEL_STO4_DMIC_SFT, rt5677_dmic_src); RT5677_SEL_STO4_DMIC_SFT, rt5677_dmic_src);
static const struct snd_kcontrol_new rt5677_sto4_dmic_mux = static const struct snd_kcontrol_new rt5677_sto4_dmic_mux =
SOC_DAPM_ENUM("Stereo4 DMIC source", rt5677_stereo4_dmic_enum); SOC_DAPM_ENUM("Stereo4 DMIC Source", rt5677_stereo4_dmic_enum);
/* Stereo2 ADC source */ /* MX-26 [0] */ /* Stereo2 ADC Source */ /* MX-26 [0] */
static const char * const rt5677_stereo2_adc_lr_src[] = { static const char * const rt5677_stereo2_adc_lr_src[] = {
"L", "LR" "L", "LR"
}; };
@ -1175,7 +1162,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_STO2_LR_MIX_SFT, rt5677_stereo2_adc_lr_src); RT5677_SEL_STO2_LR_MIX_SFT, rt5677_stereo2_adc_lr_src);
static const struct snd_kcontrol_new rt5677_sto2_adc_lr_mux = static const struct snd_kcontrol_new rt5677_sto2_adc_lr_mux =
SOC_DAPM_ENUM("Stereo2 ADC LR source", rt5677_stereo2_adc_lr_enum); SOC_DAPM_ENUM("Stereo2 ADC LR Source", rt5677_stereo2_adc_lr_enum);
/* Stereo1 ADC Source 1 */ /* MX-27 MX26 MX25 [13:12] */ /* Stereo1 ADC Source 1 */ /* MX-27 MX26 MX25 [13:12] */
static const char * const rt5677_stereo_adc1_src[] = { static const char * const rt5677_stereo_adc1_src[] = {
@ -1187,23 +1174,23 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_STO1_ADC1_SFT, rt5677_stereo_adc1_src); RT5677_SEL_STO1_ADC1_SFT, rt5677_stereo_adc1_src);
static const struct snd_kcontrol_new rt5677_sto1_adc1_mux = static const struct snd_kcontrol_new rt5677_sto1_adc1_mux =
SOC_DAPM_ENUM("Stereo1 ADC1 source", rt5677_stereo1_adc1_enum); SOC_DAPM_ENUM("Stereo1 ADC1 Source", rt5677_stereo1_adc1_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo2_adc1_enum, RT5677_STO2_ADC_MIXER, rt5677_stereo2_adc1_enum, RT5677_STO2_ADC_MIXER,
RT5677_SEL_STO2_ADC1_SFT, rt5677_stereo_adc1_src); RT5677_SEL_STO2_ADC1_SFT, rt5677_stereo_adc1_src);
static const struct snd_kcontrol_new rt5677_sto2_adc1_mux = static const struct snd_kcontrol_new rt5677_sto2_adc1_mux =
SOC_DAPM_ENUM("Stereo2 ADC1 source", rt5677_stereo2_adc1_enum); SOC_DAPM_ENUM("Stereo2 ADC1 Source", rt5677_stereo2_adc1_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_stereo3_adc1_enum, RT5677_STO3_ADC_MIXER, rt5677_stereo3_adc1_enum, RT5677_STO3_ADC_MIXER,
RT5677_SEL_STO3_ADC1_SFT, rt5677_stereo_adc1_src); RT5677_SEL_STO3_ADC1_SFT, rt5677_stereo_adc1_src);
static const struct snd_kcontrol_new rt5677_sto3_adc1_mux = static const struct snd_kcontrol_new rt5677_sto3_adc1_mux =
SOC_DAPM_ENUM("Stereo3 ADC1 source", rt5677_stereo3_adc1_enum); SOC_DAPM_ENUM("Stereo3 ADC1 Source", rt5677_stereo3_adc1_enum);
/* Mono ADC Left source 2 */ /* MX-28 [11:10] */ /* Mono ADC Left Source 2 */ /* MX-28 [11:10] */
static const char * const rt5677_mono_adc2_l_src[] = { static const char * const rt5677_mono_adc2_l_src[] = {
"DD MIX1L", "DMIC", "MONO DAC MIXL" "DD MIX1L", "DMIC", "MONO DAC MIXL"
}; };
@ -1213,9 +1200,9 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_MONO_ADC_L2_SFT, rt5677_mono_adc2_l_src); RT5677_SEL_MONO_ADC_L2_SFT, rt5677_mono_adc2_l_src);
static const struct snd_kcontrol_new rt5677_mono_adc2_l_mux = static const struct snd_kcontrol_new rt5677_mono_adc2_l_mux =
SOC_DAPM_ENUM("Mono ADC2 L source", rt5677_mono_adc2_l_enum); SOC_DAPM_ENUM("Mono ADC2 L Source", rt5677_mono_adc2_l_enum);
/* Mono ADC Left source 1 */ /* MX-28 [13:12] */ /* Mono ADC Left Source 1 */ /* MX-28 [13:12] */
static const char * const rt5677_mono_adc1_l_src[] = { static const char * const rt5677_mono_adc1_l_src[] = {
"DD MIX1L", "ADC1", "MONO DAC MIXL" "DD MIX1L", "ADC1", "MONO DAC MIXL"
}; };
@ -1225,9 +1212,9 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_MONO_ADC_L1_SFT, rt5677_mono_adc1_l_src); RT5677_SEL_MONO_ADC_L1_SFT, rt5677_mono_adc1_l_src);
static const struct snd_kcontrol_new rt5677_mono_adc1_l_mux = static const struct snd_kcontrol_new rt5677_mono_adc1_l_mux =
SOC_DAPM_ENUM("Mono ADC1 L source", rt5677_mono_adc1_l_enum); SOC_DAPM_ENUM("Mono ADC1 L Source", rt5677_mono_adc1_l_enum);
/* Mono ADC Right source 2 */ /* MX-28 [3:2] */ /* Mono ADC Right Source 2 */ /* MX-28 [3:2] */
static const char * const rt5677_mono_adc2_r_src[] = { static const char * const rt5677_mono_adc2_r_src[] = {
"DD MIX1R", "DMIC", "MONO DAC MIXR" "DD MIX1R", "DMIC", "MONO DAC MIXR"
}; };
@ -1237,9 +1224,9 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_MONO_ADC_R2_SFT, rt5677_mono_adc2_r_src); RT5677_SEL_MONO_ADC_R2_SFT, rt5677_mono_adc2_r_src);
static const struct snd_kcontrol_new rt5677_mono_adc2_r_mux = static const struct snd_kcontrol_new rt5677_mono_adc2_r_mux =
SOC_DAPM_ENUM("Mono ADC2 R source", rt5677_mono_adc2_r_enum); SOC_DAPM_ENUM("Mono ADC2 R Source", rt5677_mono_adc2_r_enum);
/* Mono ADC Right source 1 */ /* MX-28 [5:4] */ /* Mono ADC Right Source 1 */ /* MX-28 [5:4] */
static const char * const rt5677_mono_adc1_r_src[] = { static const char * const rt5677_mono_adc1_r_src[] = {
"DD MIX1R", "ADC2", "MONO DAC MIXR" "DD MIX1R", "ADC2", "MONO DAC MIXR"
}; };
@ -1249,7 +1236,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_MONO_ADC_R1_SFT, rt5677_mono_adc1_r_src); RT5677_SEL_MONO_ADC_R1_SFT, rt5677_mono_adc1_r_src);
static const struct snd_kcontrol_new rt5677_mono_adc1_r_mux = static const struct snd_kcontrol_new rt5677_mono_adc1_r_mux =
SOC_DAPM_ENUM("Mono ADC1 R source", rt5677_mono_adc1_r_enum); SOC_DAPM_ENUM("Mono ADC1 R Source", rt5677_mono_adc1_r_enum);
/* Stereo4 ADC Source 2 */ /* MX-24 [11:10] */ /* Stereo4 ADC Source 2 */ /* MX-24 [11:10] */
static const char * const rt5677_stereo4_adc2_src[] = { static const char * const rt5677_stereo4_adc2_src[] = {
@ -1261,7 +1248,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_STO4_ADC2_SFT, rt5677_stereo4_adc2_src); RT5677_SEL_STO4_ADC2_SFT, rt5677_stereo4_adc2_src);
static const struct snd_kcontrol_new rt5677_sto4_adc2_mux = static const struct snd_kcontrol_new rt5677_sto4_adc2_mux =
SOC_DAPM_ENUM("Stereo4 ADC2 source", rt5677_stereo4_adc2_enum); SOC_DAPM_ENUM("Stereo4 ADC2 Source", rt5677_stereo4_adc2_enum);
/* Stereo4 ADC Source 1 */ /* MX-24 [13:12] */ /* Stereo4 ADC Source 1 */ /* MX-24 [13:12] */
@ -1274,7 +1261,7 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_STO4_ADC1_SFT, rt5677_stereo4_adc1_src); RT5677_SEL_STO4_ADC1_SFT, rt5677_stereo4_adc1_src);
static const struct snd_kcontrol_new rt5677_sto4_adc1_mux = static const struct snd_kcontrol_new rt5677_sto4_adc1_mux =
SOC_DAPM_ENUM("Stereo4 ADC1 source", rt5677_stereo4_adc1_enum); SOC_DAPM_ENUM("Stereo4 ADC1 Source", rt5677_stereo4_adc1_enum);
/* InBound0/1 Source */ /* MX-A3 [14:12] */ /* InBound0/1 Source */ /* MX-A3 [14:12] */
static const char * const rt5677_inbound01_src[] = { static const char * const rt5677_inbound01_src[] = {
@ -1416,7 +1403,7 @@ static SOC_ENUM_SINGLE_DECL(
static const struct snd_kcontrol_new rt5677_dac3_mux = static const struct snd_kcontrol_new rt5677_dac3_mux =
SOC_DAPM_ENUM("Analog DAC3 Source", rt5677_dac3_enum); SOC_DAPM_ENUM("Analog DAC3 Source", rt5677_dac3_enum);
/* PDM channel source */ /* MX-31 [13:12][9:8][5:4][1:0] */ /* PDM channel Source */ /* MX-31 [13:12][9:8][5:4][1:0] */
static const char * const rt5677_pdm_src[] = { static const char * const rt5677_pdm_src[] = {
"STO1 DAC MIX", "MONO DAC MIX", "DD MIX1", "DD MIX2" "STO1 DAC MIX", "MONO DAC MIX", "DD MIX1", "DD MIX2"
}; };
@ -1426,28 +1413,28 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_SEL_PDM1_L_SFT, rt5677_pdm_src); RT5677_SEL_PDM1_L_SFT, rt5677_pdm_src);
static const struct snd_kcontrol_new rt5677_pdm1_l_mux = static const struct snd_kcontrol_new rt5677_pdm1_l_mux =
SOC_DAPM_ENUM("PDM1 source", rt5677_pdm1_l_enum); SOC_DAPM_ENUM("PDM1 Source", rt5677_pdm1_l_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_pdm2_l_enum, RT5677_PDM_OUT_CTRL, rt5677_pdm2_l_enum, RT5677_PDM_OUT_CTRL,
RT5677_SEL_PDM2_L_SFT, rt5677_pdm_src); RT5677_SEL_PDM2_L_SFT, rt5677_pdm_src);
static const struct snd_kcontrol_new rt5677_pdm2_l_mux = static const struct snd_kcontrol_new rt5677_pdm2_l_mux =
SOC_DAPM_ENUM("PDM2 source", rt5677_pdm2_l_enum); SOC_DAPM_ENUM("PDM2 Source", rt5677_pdm2_l_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_pdm1_r_enum, RT5677_PDM_OUT_CTRL, rt5677_pdm1_r_enum, RT5677_PDM_OUT_CTRL,
RT5677_SEL_PDM1_R_SFT, rt5677_pdm_src); RT5677_SEL_PDM1_R_SFT, rt5677_pdm_src);
static const struct snd_kcontrol_new rt5677_pdm1_r_mux = static const struct snd_kcontrol_new rt5677_pdm1_r_mux =
SOC_DAPM_ENUM("PDM1 source", rt5677_pdm1_r_enum); SOC_DAPM_ENUM("PDM1 Source", rt5677_pdm1_r_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_pdm2_r_enum, RT5677_PDM_OUT_CTRL, rt5677_pdm2_r_enum, RT5677_PDM_OUT_CTRL,
RT5677_SEL_PDM2_R_SFT, rt5677_pdm_src); RT5677_SEL_PDM2_R_SFT, rt5677_pdm_src);
static const struct snd_kcontrol_new rt5677_pdm2_r_mux = static const struct snd_kcontrol_new rt5677_pdm2_r_mux =
SOC_DAPM_ENUM("PDM2 source", rt5677_pdm2_r_enum); SOC_DAPM_ENUM("PDM2 Source", rt5677_pdm2_r_enum);
/* TDM IF1/2 SLB ADC1 Data Selection */ /* MX-3C MX-41 [5:4] MX-08 [1:0]*/ /* TDM IF1/2 SLB ADC1 Data Selection */ /* MX-3C MX-41 [5:4] MX-08 [1:0]*/
static const char * const rt5677_if12_adc1_src[] = { static const char * const rt5677_if12_adc1_src[] = {
@ -1459,21 +1446,21 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_IF1_ADC1_SFT, rt5677_if12_adc1_src); RT5677_IF1_ADC1_SFT, rt5677_if12_adc1_src);
static const struct snd_kcontrol_new rt5677_if1_adc1_mux = static const struct snd_kcontrol_new rt5677_if1_adc1_mux =
SOC_DAPM_ENUM("IF1 ADC1 source", rt5677_if1_adc1_enum); SOC_DAPM_ENUM("IF1 ADC1 Source", rt5677_if1_adc1_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc1_enum, RT5677_TDM2_CTRL2, rt5677_if2_adc1_enum, RT5677_TDM2_CTRL2,
RT5677_IF2_ADC1_SFT, rt5677_if12_adc1_src); RT5677_IF2_ADC1_SFT, rt5677_if12_adc1_src);
static const struct snd_kcontrol_new rt5677_if2_adc1_mux = static const struct snd_kcontrol_new rt5677_if2_adc1_mux =
SOC_DAPM_ENUM("IF2 ADC1 source", rt5677_if2_adc1_enum); SOC_DAPM_ENUM("IF2 ADC1 Source", rt5677_if2_adc1_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_slb_adc1_enum, RT5677_SLIMBUS_RX, rt5677_slb_adc1_enum, RT5677_SLIMBUS_RX,
RT5677_SLB_ADC1_SFT, rt5677_if12_adc1_src); RT5677_SLB_ADC1_SFT, rt5677_if12_adc1_src);
static const struct snd_kcontrol_new rt5677_slb_adc1_mux = static const struct snd_kcontrol_new rt5677_slb_adc1_mux =
SOC_DAPM_ENUM("SLB ADC1 source", rt5677_slb_adc1_enum); SOC_DAPM_ENUM("SLB ADC1 Source", rt5677_slb_adc1_enum);
/* TDM IF1/2 SLB ADC2 Data Selection */ /* MX-3C MX-41 [7:6] MX-08 [3:2] */ /* TDM IF1/2 SLB ADC2 Data Selection */ /* MX-3C MX-41 [7:6] MX-08 [3:2] */
static const char * const rt5677_if12_adc2_src[] = { static const char * const rt5677_if12_adc2_src[] = {
@ -1485,21 +1472,21 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_IF1_ADC2_SFT, rt5677_if12_adc2_src); RT5677_IF1_ADC2_SFT, rt5677_if12_adc2_src);
static const struct snd_kcontrol_new rt5677_if1_adc2_mux = static const struct snd_kcontrol_new rt5677_if1_adc2_mux =
SOC_DAPM_ENUM("IF1 ADC2 source", rt5677_if1_adc2_enum); SOC_DAPM_ENUM("IF1 ADC2 Source", rt5677_if1_adc2_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc2_enum, RT5677_TDM2_CTRL2, rt5677_if2_adc2_enum, RT5677_TDM2_CTRL2,
RT5677_IF2_ADC2_SFT, rt5677_if12_adc2_src); RT5677_IF2_ADC2_SFT, rt5677_if12_adc2_src);
static const struct snd_kcontrol_new rt5677_if2_adc2_mux = static const struct snd_kcontrol_new rt5677_if2_adc2_mux =
SOC_DAPM_ENUM("IF2 ADC2 source", rt5677_if2_adc2_enum); SOC_DAPM_ENUM("IF2 ADC2 Source", rt5677_if2_adc2_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_slb_adc2_enum, RT5677_SLIMBUS_RX, rt5677_slb_adc2_enum, RT5677_SLIMBUS_RX,
RT5677_SLB_ADC2_SFT, rt5677_if12_adc2_src); RT5677_SLB_ADC2_SFT, rt5677_if12_adc2_src);
static const struct snd_kcontrol_new rt5677_slb_adc2_mux = static const struct snd_kcontrol_new rt5677_slb_adc2_mux =
SOC_DAPM_ENUM("SLB ADC2 source", rt5677_slb_adc2_enum); SOC_DAPM_ENUM("SLB ADC2 Source", rt5677_slb_adc2_enum);
/* TDM IF1/2 SLB ADC3 Data Selection */ /* MX-3C MX-41 [9:8] MX-08 [5:4] */ /* TDM IF1/2 SLB ADC3 Data Selection */ /* MX-3C MX-41 [9:8] MX-08 [5:4] */
static const char * const rt5677_if12_adc3_src[] = { static const char * const rt5677_if12_adc3_src[] = {
@ -1511,21 +1498,21 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_IF1_ADC3_SFT, rt5677_if12_adc3_src); RT5677_IF1_ADC3_SFT, rt5677_if12_adc3_src);
static const struct snd_kcontrol_new rt5677_if1_adc3_mux = static const struct snd_kcontrol_new rt5677_if1_adc3_mux =
SOC_DAPM_ENUM("IF1 ADC3 source", rt5677_if1_adc3_enum); SOC_DAPM_ENUM("IF1 ADC3 Source", rt5677_if1_adc3_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc3_enum, RT5677_TDM2_CTRL2, rt5677_if2_adc3_enum, RT5677_TDM2_CTRL2,
RT5677_IF2_ADC3_SFT, rt5677_if12_adc3_src); RT5677_IF2_ADC3_SFT, rt5677_if12_adc3_src);
static const struct snd_kcontrol_new rt5677_if2_adc3_mux = static const struct snd_kcontrol_new rt5677_if2_adc3_mux =
SOC_DAPM_ENUM("IF2 ADC3 source", rt5677_if2_adc3_enum); SOC_DAPM_ENUM("IF2 ADC3 Source", rt5677_if2_adc3_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_slb_adc3_enum, RT5677_SLIMBUS_RX, rt5677_slb_adc3_enum, RT5677_SLIMBUS_RX,
RT5677_SLB_ADC3_SFT, rt5677_if12_adc3_src); RT5677_SLB_ADC3_SFT, rt5677_if12_adc3_src);
static const struct snd_kcontrol_new rt5677_slb_adc3_mux = static const struct snd_kcontrol_new rt5677_slb_adc3_mux =
SOC_DAPM_ENUM("SLB ADC3 source", rt5677_slb_adc3_enum); SOC_DAPM_ENUM("SLB ADC3 Source", rt5677_slb_adc3_enum);
/* TDM IF1/2 SLB ADC4 Data Selection */ /* MX-3C MX-41 [11:10] MX-08 [7:6] */ /* TDM IF1/2 SLB ADC4 Data Selection */ /* MX-3C MX-41 [11:10] MX-08 [7:6] */
static const char * const rt5677_if12_adc4_src[] = { static const char * const rt5677_if12_adc4_src[] = {
@ -1537,21 +1524,21 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_IF1_ADC4_SFT, rt5677_if12_adc4_src); RT5677_IF1_ADC4_SFT, rt5677_if12_adc4_src);
static const struct snd_kcontrol_new rt5677_if1_adc4_mux = static const struct snd_kcontrol_new rt5677_if1_adc4_mux =
SOC_DAPM_ENUM("IF1 ADC4 source", rt5677_if1_adc4_enum); SOC_DAPM_ENUM("IF1 ADC4 Source", rt5677_if1_adc4_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_if2_adc4_enum, RT5677_TDM2_CTRL2, rt5677_if2_adc4_enum, RT5677_TDM2_CTRL2,
RT5677_IF2_ADC4_SFT, rt5677_if12_adc4_src); RT5677_IF2_ADC4_SFT, rt5677_if12_adc4_src);
static const struct snd_kcontrol_new rt5677_if2_adc4_mux = static const struct snd_kcontrol_new rt5677_if2_adc4_mux =
SOC_DAPM_ENUM("IF2 ADC4 source", rt5677_if2_adc4_enum); SOC_DAPM_ENUM("IF2 ADC4 Source", rt5677_if2_adc4_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_slb_adc4_enum, RT5677_SLIMBUS_RX, rt5677_slb_adc4_enum, RT5677_SLIMBUS_RX,
RT5677_SLB_ADC4_SFT, rt5677_if12_adc4_src); RT5677_SLB_ADC4_SFT, rt5677_if12_adc4_src);
static const struct snd_kcontrol_new rt5677_slb_adc4_mux = static const struct snd_kcontrol_new rt5677_slb_adc4_mux =
SOC_DAPM_ENUM("SLB ADC4 source", rt5677_slb_adc4_enum); SOC_DAPM_ENUM("SLB ADC4 Source", rt5677_slb_adc4_enum);
/* Interface3/4 ADC Data Input */ /* MX-2F [3:0] MX-30 [7:4]*/ /* Interface3/4 ADC Data Input */ /* MX-2F [3:0] MX-30 [7:4]*/
static const char * const rt5677_if34_adc_src[] = { static const char * const rt5677_if34_adc_src[] = {
@ -1564,14 +1551,14 @@ static SOC_ENUM_SINGLE_DECL(
RT5677_IF3_ADC_IN_SFT, rt5677_if34_adc_src); RT5677_IF3_ADC_IN_SFT, rt5677_if34_adc_src);
static const struct snd_kcontrol_new rt5677_if3_adc_mux = static const struct snd_kcontrol_new rt5677_if3_adc_mux =
SOC_DAPM_ENUM("IF3 ADC source", rt5677_if3_adc_enum); SOC_DAPM_ENUM("IF3 ADC Source", rt5677_if3_adc_enum);
static SOC_ENUM_SINGLE_DECL( static SOC_ENUM_SINGLE_DECL(
rt5677_if4_adc_enum, RT5677_IF4_DATA, rt5677_if4_adc_enum, RT5677_IF4_DATA,
RT5677_IF4_ADC_IN_SFT, rt5677_if34_adc_src); RT5677_IF4_ADC_IN_SFT, rt5677_if34_adc_src);
static const struct snd_kcontrol_new rt5677_if4_adc_mux = static const struct snd_kcontrol_new rt5677_if4_adc_mux =
SOC_DAPM_ENUM("IF4 ADC source", rt5677_if4_adc_enum); SOC_DAPM_ENUM("IF4 ADC Source", rt5677_if4_adc_enum);
static int rt5677_bst1_event(struct snd_soc_dapm_widget *w, static int rt5677_bst1_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event) struct snd_kcontrol *kcontrol, int event)
@ -1670,6 +1657,13 @@ static int rt5677_set_micbias1_event(struct snd_soc_dapm_widget *w,
RT5677_PWR_CLK_MB, RT5677_PWR_CLK_MB1 | RT5677_PWR_CLK_MB, RT5677_PWR_CLK_MB1 |
RT5677_PWR_PP_MB1 | RT5677_PWR_CLK_MB); RT5677_PWR_PP_MB1 | RT5677_PWR_CLK_MB);
break; break;
case SND_SOC_DAPM_PRE_PMD:
regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2,
RT5677_PWR_CLK_MB1 | RT5677_PWR_PP_MB1 |
RT5677_PWR_CLK_MB, 0);
break;
default: default:
return 0; return 0;
} }
@ -1685,8 +1679,9 @@ static const struct snd_soc_dapm_widget rt5677_dapm_widgets[] = {
/* Input Side */ /* Input Side */
/* micbias */ /* micbias */
SND_SOC_DAPM_SUPPLY("micbias1", RT5677_PWR_ANLG2, RT5677_PWR_MB1_BIT, SND_SOC_DAPM_SUPPLY("MICBIAS1", RT5677_PWR_ANLG2, RT5677_PWR_MB1_BIT,
0, rt5677_set_micbias1_event, SND_SOC_DAPM_POST_PMU), 0, rt5677_set_micbias1_event, SND_SOC_DAPM_PRE_PMD |
SND_SOC_DAPM_POST_PMU),
/* Input Lines */ /* Input Lines */
SND_SOC_DAPM_INPUT("DMIC L1"), SND_SOC_DAPM_INPUT("DMIC L1"),
@ -2798,21 +2793,6 @@ static const struct snd_soc_dapm_route rt5677_dapm_routes[] = {
{ "PDM2R", NULL, "PDM2 R Mux" }, { "PDM2R", NULL, "PDM2 R Mux" },
}; };
static int get_clk_info(int sclk, int rate)
{
int i, pd[] = {1, 2, 3, 4, 6, 8, 12, 16};
if (sclk <= 0 || rate <= 0)
return -EINVAL;
rate = rate << 8;
for (i = 0; i < ARRAY_SIZE(pd); i++)
if (sclk == rate * pd[i])
return i;
return -EINVAL;
}
static int rt5677_hw_params(struct snd_pcm_substream *substream, static int rt5677_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{ {
@ -2822,7 +2802,7 @@ static int rt5677_hw_params(struct snd_pcm_substream *substream,
int pre_div, bclk_ms, frame_size; int pre_div, bclk_ms, frame_size;
rt5677->lrck[dai->id] = params_rate(params); rt5677->lrck[dai->id] = params_rate(params);
pre_div = get_clk_info(rt5677->sysclk, rt5677->lrck[dai->id]); pre_div = rl6231_get_clk_info(rt5677->sysclk, rt5677->lrck[dai->id]);
if (pre_div < 0) { if (pre_div < 0) {
dev_err(codec->dev, "Unsupported clock setting\n"); dev_err(codec->dev, "Unsupported clock setting\n");
return -EINVAL; return -EINVAL;
@ -3016,62 +2996,12 @@ static int rt5677_set_dai_sysclk(struct snd_soc_dai *dai,
* Returns 0 for success or negative error code. * Returns 0 for success or negative error code.
*/ */
static int rt5677_pll_calc(const unsigned int freq_in, static int rt5677_pll_calc(const unsigned int freq_in,
const unsigned int freq_out, struct rt5677_pll_code *pll_code) const unsigned int freq_out, struct rl6231_pll_code *pll_code)
{ {
int max_n = RT5677_PLL_N_MAX, max_m = RT5677_PLL_M_MAX; if (RT5677_PLL_INP_MIN > freq_in)
int k, red, n_t, pll_out, in_t;
int n = 0, m = 0, m_t = 0;
int out_t, red_t = abs(freq_out - freq_in);
bool m_bp = false, k_bp = false;
if (RT5677_PLL_INP_MAX < freq_in || RT5677_PLL_INP_MIN > freq_in)
return -EINVAL; return -EINVAL;
k = 100000000 / freq_out - 2; return rl6231_pll_calc(freq_in, freq_out, pll_code);
if (k > RT5677_PLL_K_MAX)
k = RT5677_PLL_K_MAX;
for (n_t = 0; n_t <= max_n; n_t++) {
in_t = freq_in / (k + 2);
pll_out = freq_out / (n_t + 2);
if (in_t < 0)
continue;
if (in_t == pll_out) {
m_bp = true;
n = n_t;
goto code_find;
}
red = abs(in_t - pll_out);
if (red < red_t) {
m_bp = true;
n = n_t;
m = m_t;
if (red == 0)
goto code_find;
red_t = red;
}
for (m_t = 0; m_t <= max_m; m_t++) {
out_t = in_t / (m_t + 2);
red = abs(out_t - pll_out);
if (red < red_t) {
m_bp = false;
n = n_t;
m = m_t;
if (red == 0)
goto code_find;
red_t = red;
}
}
}
pr_debug("Only get approximation about PLL\n");
code_find:
pll_code->m_bp = m_bp;
pll_code->k_bp = k_bp;
pll_code->m_code = m;
pll_code->n_code = n;
pll_code->k_code = k;
return 0;
} }
static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
@ -3079,7 +3009,7 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
{ {
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
struct rt5677_pll_code pll_code; struct rl6231_pll_code pll_code;
int ret; int ret;
if (source == rt5677->pll_src && freq_in == rt5677->pll_in && if (source == rt5677->pll_src && freq_in == rt5677->pll_in &&
@ -3137,15 +3067,12 @@ static int rt5677_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source,
return ret; return ret;
} }
dev_dbg(codec->dev, "m_bypass=%d k_bypass=%d m=%d n=%d k=%d\n", dev_dbg(codec->dev, "m_bypass=%d m=%d n=%d k=%d\n",
pll_code.m_bp, pll_code.k_bp, pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code),
(pll_code.m_bp ? 0 : pll_code.m_code), pll_code.n_code, pll_code.n_code, pll_code.k_code);
(pll_code.k_bp ? 0 : pll_code.k_code));
regmap_write(rt5677->regmap, RT5677_PLL1_CTRL1, regmap_write(rt5677->regmap, RT5677_PLL1_CTRL1,
pll_code.n_code << RT5677_PLL_N_SFT | pll_code.n_code << RT5677_PLL_N_SFT | pll_code.k_code);
pll_code.k_bp << RT5677_PLL_K_BP_SFT |
(pll_code.k_bp ? 0 : pll_code.k_code));
regmap_write(rt5677->regmap, RT5677_PLL1_CTRL2, regmap_write(rt5677->regmap, RT5677_PLL1_CTRL2,
(pll_code.m_bp ? 0 : pll_code.m_code) << RT5677_PLL_M_SFT | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5677_PLL_M_SFT |
pll_code.m_bp << RT5677_PLL_M_BP_SFT); pll_code.m_bp << RT5677_PLL_M_BP_SFT);
@ -3197,7 +3124,7 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0); regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x0);
regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000); regmap_write(rt5677->regmap, RT5677_PWR_DIG1, 0x0000);
regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000); regmap_write(rt5677->regmap, RT5677_PWR_DIG2, 0x0000);
regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0000); regmap_write(rt5677->regmap, RT5677_PWR_ANLG1, 0x0022);
regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000);
regmap_update_bits(rt5677->regmap, regmap_update_bits(rt5677->regmap,
RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000);
@ -3454,14 +3381,8 @@ static int rt5677_i2c_probe(struct i2c_client *i2c,
regmap_update_bits(rt5677->regmap, RT5677_IN1, regmap_update_bits(rt5677->regmap, RT5677_IN1,
RT5677_IN_DF2, RT5677_IN_DF2); RT5677_IN_DF2, RT5677_IN_DF2);
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677, return snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5677,
rt5677_dai, ARRAY_SIZE(rt5677_dai)); rt5677_dai, ARRAY_SIZE(rt5677_dai));
if (ret < 0)
goto err;
return 0;
err:
return ret;
} }
static int rt5677_i2c_remove(struct i2c_client *i2c) static int rt5677_i2c_remove(struct i2c_client *i2c)
@ -3480,18 +3401,7 @@ static struct i2c_driver rt5677_i2c_driver = {
.remove = rt5677_i2c_remove, .remove = rt5677_i2c_remove,
.id_table = rt5677_i2c_id, .id_table = rt5677_i2c_id,
}; };
module_i2c_driver(rt5677_i2c_driver);
static int __init rt5677_modinit(void)
{
return i2c_add_driver(&rt5677_i2c_driver);
}
module_init(rt5677_modinit);
static void __exit rt5677_modexit(void)
{
i2c_del_driver(&rt5677_i2c_driver);
}
module_exit(rt5677_modexit);
MODULE_DESCRIPTION("ASoC RT5677 driver"); MODULE_DESCRIPTION("ASoC RT5677 driver");
MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>"); MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");

View file

@ -1393,13 +1393,6 @@
#define RT5677_DSP_IB_9_L (0x1 << 1) #define RT5677_DSP_IB_9_L (0x1 << 1)
#define RT5677_DSP_IB_9_L_SFT 1 #define RT5677_DSP_IB_9_L_SFT 1
/* Debug String Length */
#define RT5677_REG_DISP_LEN 23
#define RT5677_NO_JACK BIT(0)
#define RT5677_HEADSET_DET BIT(1)
#define RT5677_HEADPHO_DET BIT(2)
/* System Clock Source */ /* System Clock Source */
enum { enum {
RT5677_SCLK_S_MCLK, RT5677_SCLK_S_MCLK,
@ -1425,14 +1418,6 @@ enum {
RT5677_AIFS, RT5677_AIFS,
}; };
struct rt5677_pll_code {
bool m_bp; /* Indicates bypass m code or not. */
bool k_bp; /* Indicates bypass k code or not. */
int m_code;
int n_code;
int k_code;
};
struct rt5677_priv { struct rt5677_priv {
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct rt5677_platform_data pdata; struct rt5677_platform_data pdata;

View file

@ -1,17 +1,24 @@
config SND_S6000_SOC config SND_S6000_SOC
tristate "SoC Audio for the Stretch s6000 family" tristate "SoC Audio for the Stretch s6000 family"
depends on XTENSA_VARIANT_S6000 depends on XTENSA_VARIANT_S6000 || COMPILE_TEST
depends on HAS_IOMEM
select SND_S6000_SOC_PCM if XTENSA_VARIANT_S6000
help help
Say Y or M if you want to add support for codecs attached to Say Y or M if you want to add support for codecs attached to
s6000 family chips. You will also need to select the platform s6000 family chips. You will also need to select the platform
to support below. to support below.
config SND_S6000_SOC_PCM
tristate
config SND_S6000_SOC_I2S config SND_S6000_SOC_I2S
tristate tristate
config SND_S6000_SOC_S6IPCAM config SND_S6000_SOC_S6IPCAM
tristate "SoC Audio support for Stretch 6105 IP Camera" bool "SoC Audio support for Stretch 6105 IP Camera"
depends on SND_S6000_SOC && XTENSA_PLATFORM_S6105 depends on SND_S6000_SOC=y
depends on I2C=y
depends on XTENSA_PLATFORM_S6105 || COMPILE_TEST
select SND_S6000_SOC_I2S select SND_S6000_SOC_I2S
select SND_SOC_TLV320AIC3X select SND_SOC_TLV320AIC3X
help help

View file

@ -2,7 +2,7 @@
snd-soc-s6000-objs := s6000-pcm.o snd-soc-s6000-objs := s6000-pcm.o
snd-soc-s6000-i2s-objs := s6000-i2s.o snd-soc-s6000-i2s-objs := s6000-i2s.o
obj-$(CONFIG_SND_S6000_SOC) += snd-soc-s6000.o obj-$(CONFIG_SND_S6000_SOC_PCM) += snd-soc-s6000.o
obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o obj-$(CONFIG_SND_S6000_SOC_I2S) += snd-soc-s6000-i2s.o
# s6105 Machine Support # s6105 Machine Support

View file

@ -19,8 +19,6 @@
#include <sound/pcm.h> #include <sound/pcm.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <variant/dmac.h>
#include "s6000-pcm.h" #include "s6000-pcm.h"
#include "s6000-i2s.h" #include "s6000-i2s.h"
@ -135,22 +133,8 @@ static const struct snd_kcontrol_new audio_out_mux = {
/* Logic for a aic3x as connected on the s6105 ip camera ref design */ /* Logic for a aic3x as connected on the s6105 ip camera ref design */
static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd) static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
/* not present */
snd_soc_dapm_nc_pin(dapm, "MONO_LOUT");
snd_soc_dapm_nc_pin(dapm, "LINE2L");
snd_soc_dapm_nc_pin(dapm, "LINE2R");
/* not connected */
snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */
snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */
snd_soc_dapm_nc_pin(dapm, "LLOUT");
snd_soc_dapm_nc_pin(dapm, "RLOUT");
snd_soc_dapm_nc_pin(dapm, "HPRCOM");
/* must correspond to audio_out_mux.private_value initializer */ /* must correspond to audio_out_mux.private_value initializer */
snd_soc_dapm_disable_pin(&card->dapm, "Audio Out Differential"); snd_soc_dapm_disable_pin(&card->dapm, "Audio Out Differential");
@ -182,6 +166,7 @@ static struct snd_soc_card snd_soc_card_s6105 = {
.num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(aic3x_dapm_widgets),
.dapm_routes = audio_map, .dapm_routes = audio_map,
.num_dapm_routes = ARRAY_SIZE(audio_map), .num_dapm_routes = ARRAY_SIZE(audio_map),
.fully_routed = true,
}; };
static struct s6000_snd_platform_data s6105_snd_data __initdata = { static struct s6000_snd_platform_data s6105_snd_data __initdata = {

View file

@ -1,25 +1,16 @@
config SND_SOC_SAMSUNG config SND_SOC_SAMSUNG
tristate "ASoC support for Samsung" tristate "ASoC support for Samsung"
depends on PLAT_SAMSUNG depends on PLAT_SAMSUNG
select S3C2410_DMA if ARCH_S3C24XX depends on S3C64XX_PL080 || !ARCH_S3C64XX
select S3C64XX_PL080 if ARCH_S3C64XX depends on S3C24XX_DMAC || !ARCH_S3C24XX
select SND_S3C_DMA if !ARCH_S3C24XX select SND_SOC_GENERIC_DMAENGINE_PCM
select SND_S3C_DMA_LEGACY if ARCH_S3C24XX
select SND_SOC_GENERIC_DMAENGINE_PCM if !ARCH_S3C24XX
help help
Say Y or M if you want to add support for codecs attached to Say Y or M if you want to add support for codecs attached to
the Samsung SoCs' Audio interfaces. You will also need to the Samsung SoCs' Audio interfaces. You will also need to
select the audio interfaces to support below. select the audio interfaces to support below.
config SND_S3C_DMA
tristate
config SND_S3C_DMA_LEGACY
tristate
config SND_S3C24XX_I2S config SND_S3C24XX_I2S
tristate tristate
select S3C24XX_DMA
config SND_S3C_I2SV2_SOC config SND_S3C_I2SV2_SOC
tristate tristate
@ -27,7 +18,6 @@ config SND_S3C_I2SV2_SOC
config SND_S3C2412_SOC_I2S config SND_S3C2412_SOC_I2S
tristate tristate
select SND_S3C_I2SV2_SOC select SND_S3C_I2SV2_SOC
select S3C2410_DMA
config SND_SAMSUNG_PCM config SND_SAMSUNG_PCM
tristate tristate
@ -55,7 +45,7 @@ config SND_SOC_SAMSUNG_NEO1973_WM8753
config SND_SOC_SAMSUNG_JIVE_WM8750 config SND_SOC_SAMSUNG_JIVE_WM8750
tristate "SoC I2S Audio support for Jive" tristate "SoC I2S Audio support for Jive"
depends on SND_SOC_SAMSUNG && MACH_JIVE depends on SND_SOC_SAMSUNG && MACH_JIVE && I2C
select SND_SOC_WM8750 select SND_SOC_WM8750
select SND_S3C2412_SOC_I2S select SND_S3C2412_SOC_I2S
help help
@ -63,7 +53,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750
config SND_SOC_SAMSUNG_SMDK_WM8580 config SND_SOC_SAMSUNG_SMDK_WM8580
tristate "SoC I2S Audio support for WM8580 on SMDK" tristate "SoC I2S Audio support for WM8580 on SMDK"
depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110)
depends on REGMAP_I2C depends on REGMAP_I2C
select SND_SOC_WM8580 select SND_SOC_WM8580
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
@ -83,7 +73,6 @@ config SND_SOC_SAMSUNG_SMDK_WM8994
config SND_SOC_SAMSUNG_SMDK2443_WM9710 config SND_SOC_SAMSUNG_SMDK2443_WM9710
tristate "SoC AC97 Audio support for SMDK2443 - WM9710" tristate "SoC AC97 Audio support for SMDK2443 - WM9710"
depends on SND_SOC_SAMSUNG && MACH_SMDK2443 depends on SND_SOC_SAMSUNG && MACH_SMDK2443
select S3C2410_DMA
select AC97_BUS select AC97_BUS
select SND_SOC_AC97_CODEC select SND_SOC_AC97_CODEC
select SND_SAMSUNG_AC97 select SND_SAMSUNG_AC97
@ -94,7 +83,6 @@ config SND_SOC_SAMSUNG_SMDK2443_WM9710
config SND_SOC_SAMSUNG_LN2440SBC_ALC650 config SND_SOC_SAMSUNG_LN2440SBC_ALC650
tristate "SoC AC97 Audio support for LN2440SBC - ALC650" tristate "SoC AC97 Audio support for LN2440SBC - ALC650"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX depends on SND_SOC_SAMSUNG && ARCH_S3C24XX
select S3C2410_DMA
select AC97_BUS select AC97_BUS
select SND_SOC_AC97_CODEC select SND_SOC_AC97_CODEC
select SND_SAMSUNG_AC97 select SND_SAMSUNG_AC97
@ -154,7 +142,7 @@ config SND_SOC_SAMSUNG_SMDK_WM9713
config SND_SOC_SMARTQ config SND_SOC_SMARTQ
tristate "SoC I2S Audio support for SmartQ board" tristate "SoC I2S Audio support for SmartQ board"
depends on SND_SOC_SAMSUNG && MACH_SMARTQ depends on SND_SOC_SAMSUNG && MACH_SMARTQ && I2C
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
select SND_SOC_WM8750 select SND_SOC_WM8750
@ -178,7 +166,7 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF
config SND_SOC_SMDK_WM8580_PCM config SND_SOC_SMDK_WM8580_PCM
tristate "SoC PCM Audio support for WM8580 on SMDK" tristate "SoC PCM Audio support for WM8580 on SMDK"
depends on SND_SOC_SAMSUNG && (MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) depends on SND_SOC_SAMSUNG && (MACH_SMDKV210 || MACH_SMDKC110)
depends on REGMAP_I2C depends on REGMAP_I2C
select SND_SOC_WM8580 select SND_SOC_WM8580
select SND_SAMSUNG_PCM select SND_SAMSUNG_PCM
@ -206,7 +194,7 @@ config SND_SOC_SPEYSIDE
config SND_SOC_TOBERMORY config SND_SOC_TOBERMORY
tristate "Audio support for Wolfson Tobermory" tristate "Audio support for Wolfson Tobermory"
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && INPUT depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && INPUT && I2C
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
select SND_SOC_WM8962 select SND_SOC_WM8962
@ -222,7 +210,7 @@ config SND_SOC_BELLS
config SND_SOC_LOWLAND config SND_SOC_LOWLAND
tristate "Audio support for Wolfson Lowland" tristate "Audio support for Wolfson Lowland"
depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 depends on SND_SOC_SAMSUNG && MACH_WLF_CRAGG_6410 && I2C
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
select SND_SOC_WM5100 select SND_SOC_WM5100
select SND_SOC_WM9081 select SND_SOC_WM9081
@ -236,10 +224,18 @@ config SND_SOC_LITTLEMILL
config SND_SOC_SNOW config SND_SOC_SNOW
tristate "Audio support for Google Snow boards" tristate "Audio support for Google Snow boards"
depends on SND_SOC_SAMSUNG depends on SND_SOC_SAMSUNG && I2C
select SND_SOC_MAX98090 select SND_SOC_MAX98090
select SND_SOC_MAX98095 select SND_SOC_MAX98095
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
help help
Say Y if you want to add audio support for various Snow Say Y if you want to add audio support for various Snow
boards based on Exynos5 series of SoCs. boards based on Exynos5 series of SoCs.
config SND_SOC_ODROIDX2
tristate "Audio support for Odroid-X2 and Odroid-U3"
depends on SND_SOC_SAMSUNG
select SND_SOC_MAX98090
select SND_SAMSUNG_I2S
help
Say Y here to enable audio support for the Odroid-X2/U3.

View file

@ -1,6 +1,5 @@
# S3c24XX Platform Support # S3c24XX Platform Support
snd-soc-s3c-dma-objs := dmaengine.o snd-soc-s3c-dma-objs := dmaengine.o
snd-soc-s3c-dma-legacy-objs := dma.o
snd-soc-idma-objs := idma.o snd-soc-idma-objs := idma.o
snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o
snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o
@ -10,8 +9,7 @@ snd-soc-samsung-spdif-objs := spdif.o
snd-soc-pcm-objs := pcm.o snd-soc-pcm-objs := pcm.o
snd-soc-i2s-objs := i2s.o snd-soc-i2s-objs := i2s.o
obj-$(CONFIG_SND_S3C_DMA) += snd-soc-s3c-dma.o obj-$(CONFIG_SND_SOC_SAMSUNG) += snd-soc-s3c-dma.o
obj-$(CONFIG_SND_S3C_DMA_LEGACY) += snd-soc-s3c-dma-legacy.o
obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o
obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o
obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o
@ -46,6 +44,7 @@ snd-soc-tobermory-objs := tobermory.o
snd-soc-lowland-objs := lowland.o snd-soc-lowland-objs := lowland.o
snd-soc-littlemill-objs := littlemill.o snd-soc-littlemill-objs := littlemill.o
snd-soc-bells-objs := bells.o snd-soc-bells-objs := bells.o
snd-soc-odroidx2-max98090-objs := odroidx2_max98090.o
obj-$(CONFIG_SND_SOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.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_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o
@ -71,3 +70,4 @@ obj-$(CONFIG_SND_SOC_TOBERMORY) += snd-soc-tobermory.o
obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o obj-$(CONFIG_SND_SOC_LOWLAND) += snd-soc-lowland.o
obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o obj-$(CONFIG_SND_SOC_LITTLEMILL) += snd-soc-littlemill.o
obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o obj-$(CONFIG_SND_SOC_BELLS) += snd-soc-bells.o
obj-$(CONFIG_SND_SOC_ODROIDX2) += snd-soc-odroidx2-max98090.o

View file

@ -19,7 +19,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <mach/dma.h>
#include "regs-ac97.h" #include "regs-ac97.h"
#include <linux/platform_data/asoc-s3c.h> #include <linux/platform_data/asoc-s3c.h>
@ -39,30 +38,15 @@ struct s3c_ac97_info {
}; };
static struct s3c_ac97_info s3c_ac97; static struct s3c_ac97_info s3c_ac97;
static struct s3c_dma_client s3c_dma_client_out = {
.name = "AC97 PCMOut"
};
static struct s3c_dma_client s3c_dma_client_in = {
.name = "AC97 PCMIn"
};
static struct s3c_dma_client s3c_dma_client_micin = {
.name = "AC97 MicIn"
};
static struct s3c_dma_params s3c_ac97_pcm_out = { static struct s3c_dma_params s3c_ac97_pcm_out = {
.client = &s3c_dma_client_out,
.dma_size = 4, .dma_size = 4,
}; };
static struct s3c_dma_params s3c_ac97_pcm_in = { static struct s3c_dma_params s3c_ac97_pcm_in = {
.client = &s3c_dma_client_in,
.dma_size = 4, .dma_size = 4,
}; };
static struct s3c_dma_params s3c_ac97_mic_in = { static struct s3c_dma_params s3c_ac97_mic_in = {
.client = &s3c_dma_client_micin,
.dma_size = 4, .dma_size = 4,
}; };
@ -225,9 +209,6 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
u32 ac_glbctrl; u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct s3c_dma_params *dma_data =
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
@ -253,11 +234,6 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (!dma_data->ops)
dma_data->ops = samsung_dma_get_ops();
dma_data->ops->started(dma_data->channel);
return 0; return 0;
} }
@ -265,9 +241,6 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai) int cmd, struct snd_soc_dai *dai)
{ {
u32 ac_glbctrl; u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct s3c_dma_params *dma_data =
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
@ -287,11 +260,6 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (!dma_data->ops)
dma_data->ops = samsung_dma_get_ops();
dma_data->ops->started(dma_data->channel);
return 0; return 0;
} }

View file

@ -1,454 +0,0 @@
/*
* dma.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>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/slab.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <asm/dma.h>
#include <mach/hardware.h>
#include <mach/dma.h>
#include "dma.h"
#define ST_RUNNING (1<<0)
#define ST_OPENED (1<<1)
static const struct snd_pcm_hardware dma_hardware = {
.info = SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER |
SNDRV_PCM_INFO_MMAP |
SNDRV_PCM_INFO_MMAP_VALID,
.buffer_bytes_max = 128*1024,
.period_bytes_min = PAGE_SIZE,
.period_bytes_max = PAGE_SIZE*2,
.periods_min = 2,
.periods_max = 128,
.fifo_size = 32,
};
struct runtime_data {
spinlock_t lock;
int state;
unsigned int dma_loaded;
unsigned int dma_period;
dma_addr_t dma_start;
dma_addr_t dma_pos;
dma_addr_t dma_end;
struct s3c_dma_params *params;
};
static void audio_buffdone(void *data);
/* dma_enqueue
*
* place a dma buffer onto the queue for the dma system
* to handle.
*/
static void dma_enqueue(struct snd_pcm_substream *substream)
{
struct runtime_data *prtd = substream->runtime->private_data;
dma_addr_t pos = prtd->dma_pos;
unsigned int limit;
struct samsung_dma_prep dma_info;
pr_debug("Entered %s\n", __func__);
limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period;
pr_debug("%s: loaded %d, limit %d\n",
__func__, prtd->dma_loaded, limit);
dma_info.cap = (samsung_dma_has_circular() ? DMA_CYCLIC : DMA_SLAVE);
dma_info.direction =
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK
? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
dma_info.fp = audio_buffdone;
dma_info.fp_param = substream;
dma_info.period = prtd->dma_period;
dma_info.len = prtd->dma_period*limit;
if (dma_info.cap == DMA_CYCLIC) {
dma_info.buf = pos;
prtd->params->ops->prepare(prtd->params->ch, &dma_info);
prtd->dma_loaded += limit;
return;
}
while (prtd->dma_loaded < limit) {
pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
if ((pos + dma_info.period) > prtd->dma_end) {
dma_info.period = prtd->dma_end - pos;
pr_debug("%s: corrected dma len %ld\n",
__func__, dma_info.period);
}
dma_info.buf = pos;
prtd->params->ops->prepare(prtd->params->ch, &dma_info);
prtd->dma_loaded++;
pos += prtd->dma_period;
if (pos >= prtd->dma_end)
pos = prtd->dma_start;
}
prtd->dma_pos = pos;
}
static void audio_buffdone(void *data)
{
struct snd_pcm_substream *substream = data;
struct runtime_data *prtd = substream->runtime->private_data;
pr_debug("Entered %s\n", __func__);
if (prtd->state & ST_RUNNING) {
prtd->dma_pos += prtd->dma_period;
if (prtd->dma_pos >= prtd->dma_end)
prtd->dma_pos = prtd->dma_start;
if (substream)
snd_pcm_period_elapsed(substream);
spin_lock(&prtd->lock);
if (!samsung_dma_has_circular()) {
prtd->dma_loaded--;
dma_enqueue(substream);
}
spin_unlock(&prtd->lock);
}
}
static int dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data;
unsigned long totbytes = params_buffer_bytes(params);
struct s3c_dma_params *dma =
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
struct samsung_dma_req req;
struct samsung_dma_config config;
pr_debug("Entered %s\n", __func__);
/* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma)
return 0;
/* this may get called several times by oss emulation
* with different params -HW */
if (prtd->params == NULL) {
/* prepare DMA */
prtd->params = dma;
pr_debug("params %p, client %p, channel %d\n", prtd->params,
prtd->params->client, prtd->params->channel);
prtd->params->ops = samsung_dma_get_ops();
req.cap = (samsung_dma_has_circular() ?
DMA_CYCLIC : DMA_SLAVE);
req.client = prtd->params->client;
config.direction =
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK
? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
config.width = prtd->params->dma_size;
config.fifo = prtd->params->dma_addr;
prtd->params->ch = prtd->params->ops->request(
prtd->params->channel, &req, rtd->cpu_dai->dev,
prtd->params->ch_name);
if (!prtd->params->ch) {
pr_err("Failed to allocate DMA channel\n");
return -ENXIO;
}
prtd->params->ops->config(prtd->params->ch, &config);
}
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = totbytes;
spin_lock_irq(&prtd->lock);
prtd->dma_loaded = 0;
prtd->dma_period = params_period_bytes(params);
prtd->dma_start = runtime->dma_addr;
prtd->dma_pos = prtd->dma_start;
prtd->dma_end = prtd->dma_start + totbytes;
spin_unlock_irq(&prtd->lock);
return 0;
}
static int dma_hw_free(struct snd_pcm_substream *substream)
{
struct runtime_data *prtd = substream->runtime->private_data;
pr_debug("Entered %s\n", __func__);
snd_pcm_set_runtime_buffer(substream, NULL);
if (prtd->params) {
prtd->params->ops->flush(prtd->params->ch);
prtd->params->ops->release(prtd->params->ch,
prtd->params->client);
prtd->params = NULL;
}
return 0;
}
static int dma_prepare(struct snd_pcm_substream *substream)
{
struct runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
pr_debug("Entered %s\n", __func__);
/* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */
if (!prtd->params)
return 0;
/* flush the DMA channel */
prtd->params->ops->flush(prtd->params->ch);
prtd->dma_loaded = 0;
prtd->dma_pos = prtd->dma_start;
/* enqueue dma buffers */
dma_enqueue(substream);
return ret;
}
static int dma_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct runtime_data *prtd = substream->runtime->private_data;
int ret = 0;
pr_debug("Entered %s\n", __func__);
spin_lock(&prtd->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
prtd->state |= ST_RUNNING;
prtd->params->ops->trigger(prtd->params->ch);
break;
case SNDRV_PCM_TRIGGER_STOP:
prtd->state &= ~ST_RUNNING;
prtd->params->ops->stop(prtd->params->ch);
break;
default:
ret = -EINVAL;
break;
}
spin_unlock(&prtd->lock);
return ret;
}
static snd_pcm_uframes_t
dma_pointer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct runtime_data *prtd = runtime->private_data;
unsigned long res;
pr_debug("Entered %s\n", __func__);
res = prtd->dma_pos - prtd->dma_start;
pr_debug("Pointer offset: %lu\n", res);
/* we seem to be getting the odd error from the pcm library due
* to out-of-bounds pointers. this is maybe due to the dma engine
* not having loaded the new values for the channel before being
* called... (todo - fix )
*/
if (res >= snd_pcm_lib_buffer_bytes(substream)) {
if (res == snd_pcm_lib_buffer_bytes(substream))
res = 0;
}
return bytes_to_frames(substream->runtime, res);
}
static int dma_open(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct runtime_data *prtd;
pr_debug("Entered %s\n", __func__);
snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS);
snd_soc_set_runtime_hwparams(substream, &dma_hardware);
prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL);
if (prtd == NULL)
return -ENOMEM;
spin_lock_init(&prtd->lock);
runtime->private_data = prtd;
return 0;
}
static int dma_close(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime = substream->runtime;
struct runtime_data *prtd = runtime->private_data;
pr_debug("Entered %s\n", __func__);
if (!prtd)
pr_debug("dma_close called with prtd == NULL\n");
kfree(prtd);
return 0;
}
static int dma_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *vma)
{
struct snd_pcm_runtime *runtime = substream->runtime;
pr_debug("Entered %s\n", __func__);
return dma_mmap_writecombine(substream->pcm->card->dev, vma,
runtime->dma_area,
runtime->dma_addr,
runtime->dma_bytes);
}
static struct snd_pcm_ops dma_ops = {
.open = dma_open,
.close = dma_close,
.ioctl = snd_pcm_lib_ioctl,
.hw_params = dma_hw_params,
.hw_free = dma_hw_free,
.prepare = dma_prepare,
.trigger = dma_trigger,
.pointer = dma_pointer,
.mmap = dma_mmap,
};
static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
{
struct snd_pcm_substream *substream = pcm->streams[stream].substream;
struct snd_dma_buffer *buf = &substream->dma_buffer;
size_t size = dma_hardware.buffer_bytes_max;
pr_debug("Entered %s\n", __func__);
buf->dev.type = SNDRV_DMA_TYPE_DEV;
buf->dev.dev = pcm->card->dev;
buf->private_data = NULL;
buf->area = dma_alloc_writecombine(pcm->card->dev, size,
&buf->addr, GFP_KERNEL);
if (!buf->area)
return -ENOMEM;
buf->bytes = size;
return 0;
}
static void dma_free_dma_buffers(struct snd_pcm *pcm)
{
struct snd_pcm_substream *substream;
struct snd_dma_buffer *buf;
int stream;
pr_debug("Entered %s\n", __func__);
for (stream = 0; stream < 2; stream++) {
substream = pcm->streams[stream].substream;
if (!substream)
continue;
buf = &substream->dma_buffer;
if (!buf->area)
continue;
dma_free_writecombine(pcm->card->dev, buf->bytes,
buf->area, buf->addr);
buf->area = NULL;
}
}
static int dma_new(struct snd_soc_pcm_runtime *rtd)
{
struct snd_card *card = rtd->card->snd_card;
struct snd_pcm *pcm = rtd->pcm;
int ret;
pr_debug("Entered %s\n", __func__);
ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32));
if (ret)
return ret;
if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) {
ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_PLAYBACK);
if (ret)
goto out;
}
if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) {
ret = preallocate_dma_buffer(pcm,
SNDRV_PCM_STREAM_CAPTURE);
if (ret)
goto out;
}
out:
return ret;
}
static struct snd_soc_platform_driver samsung_asoc_platform = {
.ops = &dma_ops,
.pcm_new = dma_new,
.pcm_free = dma_free_dma_buffers,
};
void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
struct s3c_dma_params *playback,
struct s3c_dma_params *capture)
{
snd_soc_dai_init_dma_data(dai, playback, capture);
}
EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
int samsung_asoc_dma_platform_register(struct device *dev)
{
return devm_snd_soc_register_platform(dev, &samsung_asoc_platform);
}
EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
MODULE_LICENSE("GPL");

View file

@ -14,17 +14,10 @@
#include <sound/dmaengine_pcm.h> #include <sound/dmaengine_pcm.h>
struct s3c_dma_client {
char *name;
};
struct s3c_dma_params { struct s3c_dma_params {
struct s3c_dma_client *client; /* stream identifier */
int channel; /* Channel ID */ int channel; /* Channel ID */
dma_addr_t dma_addr; dma_addr_t dma_addr;
int dma_size; /* Size of the DMA transfer */ int dma_size; /* Size of the DMA transfer */
unsigned ch;
struct samsung_dma_ops *ops;
char *ch_name; char *ch_name;
struct snd_dmaengine_dai_dma_data dma_data; struct snd_dmaengine_dai_dma_data dma_data;
}; };

View file

@ -17,6 +17,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/amba/pl08x.h> #include <linux/amba/pl08x.h>
#include <linux/platform_data/dma-s3c24xx.h>
#include <sound/core.h> #include <sound/core.h>
#include <sound/pcm.h> #include <sound/pcm.h>
@ -29,6 +30,8 @@
#ifdef CONFIG_ARCH_S3C64XX #ifdef CONFIG_ARCH_S3C64XX
#define filter_fn pl08x_filter_id #define filter_fn pl08x_filter_id
#elif defined(CONFIG_ARCH_S3C24XX)
#define filter_fn s3c24xx_dma_filter
#else #else
#define filter_fn NULL #define filter_fn NULL
#endif #endif

View file

@ -1221,11 +1221,7 @@ static int samsung_i2s_probe(struct platform_device *pdev)
pri_dai->dma_playback.dma_addr = regs_base + I2STXD; pri_dai->dma_playback.dma_addr = regs_base + I2STXD;
pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; pri_dai->dma_capture.dma_addr = regs_base + I2SRXD;
pri_dai->dma_playback.client =
(struct s3c_dma_client *)&pri_dai->dma_playback;
pri_dai->dma_playback.ch_name = "tx"; pri_dai->dma_playback.ch_name = "tx";
pri_dai->dma_capture.client =
(struct s3c_dma_client *)&pri_dai->dma_capture;
pri_dai->dma_capture.ch_name = "rx"; pri_dai->dma_capture.ch_name = "rx";
pri_dai->dma_playback.dma_size = 4; pri_dai->dma_playback.dma_size = 4;
pri_dai->dma_capture.dma_size = 4; pri_dai->dma_capture.dma_size = 4;
@ -1243,8 +1239,6 @@ static int samsung_i2s_probe(struct platform_device *pdev)
goto err; goto err;
} }
sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; sec_dai->dma_playback.dma_addr = regs_base + I2STXDS;
sec_dai->dma_playback.client =
(struct s3c_dma_client *)&sec_dai->dma_playback;
sec_dai->dma_playback.ch_name = "tx-sec"; sec_dai->dma_playback.ch_name = "tx-sec";
if (!np) { if (!np) {

View file

@ -261,10 +261,9 @@ static int idma_mmap(struct snd_pcm_substream *substream,
static irqreturn_t iis_irq(int irqno, void *dev_id) static irqreturn_t iis_irq(int irqno, void *dev_id)
{ {
struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id; struct idma_ctrl *prtd = (struct idma_ctrl *)dev_id;
u32 iiscon, iisahb, val, addr; u32 iisahb, val, addr;
iisahb = readl(idma.regs + I2SAHB); iisahb = readl(idma.regs + I2SAHB);
iiscon = readl(idma.regs + I2SCON);
val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0; val = (iisahb & AHB_LVL0INT) ? AHB_CLRLVL0INT : 0;

View file

@ -0,0 +1,177 @@
/*
* Copyright (C) 2014 Samsung Electronics Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/of.h>
#include <linux/module.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include "i2s.h"
struct odroidx2_drv_data {
const struct snd_soc_dapm_widget *dapm_widgets;
unsigned int num_dapm_widgets;
};
/* The I2S CDCLK output clock frequency for the MAX98090 codec */
#define MAX98090_MCLK 19200000
static int odroidx2_late_probe(struct snd_soc_card *card)
{
struct snd_soc_dai *codec_dai = card->rtd[0].codec_dai;
struct snd_soc_dai *cpu_dai = card->rtd[0].cpu_dai;
int ret;
ret = snd_soc_dai_set_sysclk(codec_dai, 0, MAX98090_MCLK,
SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
/* Set the cpu DAI configuration in order to use CDCLK */
return snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK,
0, SND_SOC_CLOCK_OUT);
}
static const struct snd_soc_dapm_widget odroidx2_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_MIC("Mic Jack", NULL),
SND_SOC_DAPM_MIC("DMIC", NULL),
};
static const struct snd_soc_dapm_widget odroidu3_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", NULL),
SND_SOC_DAPM_SPK("Speakers", NULL),
};
static struct snd_soc_dai_link odroidx2_dai[] = {
{
.name = "MAX98090",
.stream_name = "MAX98090 PCM",
.codec_dai_name = "HiFi",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBM_CFM,
}
};
static struct snd_soc_card odroidx2 = {
.owner = THIS_MODULE,
.dai_link = odroidx2_dai,
.num_links = ARRAY_SIZE(odroidx2_dai),
.fully_routed = true,
.late_probe = odroidx2_late_probe,
};
struct odroidx2_drv_data odroidx2_drvdata = {
.dapm_widgets = odroidx2_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(odroidx2_dapm_widgets),
};
struct odroidx2_drv_data odroidu3_drvdata = {
.dapm_widgets = odroidu3_dapm_widgets,
.num_dapm_widgets = ARRAY_SIZE(odroidu3_dapm_widgets),
};
static const struct of_device_id odroidx2_audio_of_match[] = {
{
.compatible = "samsung,odroidx2-audio",
.data = &odroidx2_drvdata,
}, {
.compatible = "samsung,odroidu3-audio",
.data = &odroidu3_drvdata,
},
{ },
};
MODULE_DEVICE_TABLE(of, odroidx2_audio_of_match);
static int odroidx2_audio_probe(struct platform_device *pdev)
{
struct device_node *snd_node = pdev->dev.of_node;
struct snd_soc_card *card = &odroidx2;
struct device_node *i2s_node, *codec_node;
struct odroidx2_drv_data *dd;
const struct of_device_id *of_id;
int ret;
of_id = of_match_node(odroidx2_audio_of_match, snd_node);
dd = (struct odroidx2_drv_data *)of_id->data;
card->num_dapm_widgets = dd->num_dapm_widgets;
card->dapm_widgets = dd->dapm_widgets;
card->dev = &pdev->dev;
ret = snd_soc_of_parse_card_name(card, "samsung,model");
if (ret < 0)
return ret;
ret = snd_soc_of_parse_audio_routing(card, "samsung,audio-routing");
if (ret < 0)
return ret;
codec_node = of_parse_phandle(snd_node, "samsung,audio-codec", 0);
if (!codec_node) {
dev_err(&pdev->dev,
"Failed parsing samsung,i2s-codec property\n");
return -EINVAL;
}
i2s_node = of_parse_phandle(snd_node, "samsung,i2s-controller", 0);
if (!i2s_node) {
dev_err(&pdev->dev,
"Failed parsing samsung,i2s-controller property\n");
ret = -EINVAL;
goto err_put_codec_n;
}
odroidx2_dai[0].codec_of_node = codec_node;
odroidx2_dai[0].cpu_of_node = i2s_node;
odroidx2_dai[0].platform_of_node = i2s_node;
ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret);
goto err_put_i2s_n;
}
return 0;
err_put_i2s_n:
of_node_put(i2s_node);
err_put_codec_n:
of_node_put(codec_node);
return ret;
}
static int odroidx2_audio_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card);
of_node_put((struct device_node *)odroidx2_dai[0].cpu_of_node);
of_node_put((struct device_node *)odroidx2_dai[0].codec_of_node);
return 0;
}
static struct platform_driver odroidx2_audio_driver = {
.driver = {
.name = "odroidx2-audio",
.owner = THIS_MODULE,
.of_match_table = odroidx2_audio_of_match,
.pm = &snd_soc_pm_ops,
},
.probe = odroidx2_audio_probe,
.remove = odroidx2_audio_remove,
};
module_platform_driver(odroidx2_audio_driver);
MODULE_AUTHOR("Chen Zhen <zhen1.chen@samsung.com>");
MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
MODULE_DESCRIPTION("ALSA SoC Odroid X2/U3 Audio Support");
MODULE_LICENSE("GPL v2");

View file

@ -131,32 +131,20 @@ struct s3c_pcm_info {
struct s3c_dma_params *dma_capture; struct s3c_dma_params *dma_capture;
}; };
static struct s3c_dma_client s3c_pcm_dma_client_out = {
.name = "PCM Stereo out"
};
static struct s3c_dma_client s3c_pcm_dma_client_in = {
.name = "PCM Stereo in"
};
static struct s3c_dma_params s3c_pcm_stereo_out[] = { static struct s3c_dma_params s3c_pcm_stereo_out[] = {
[0] = { [0] = {
.client = &s3c_pcm_dma_client_out,
.dma_size = 4, .dma_size = 4,
}, },
[1] = { [1] = {
.client = &s3c_pcm_dma_client_out,
.dma_size = 4, .dma_size = 4,
}, },
}; };
static struct s3c_dma_params s3c_pcm_stereo_in[] = { static struct s3c_dma_params s3c_pcm_stereo_in[] = {
[0] = { [0] = {
.client = &s3c_pcm_dma_client_in,
.dma_size = 4, .dma_size = 4,
}, },
[1] = { [1] = {
.client = &s3c_pcm_dma_client_in,
.dma_size = 4, .dma_size = 4,
}, },
}; };

View file

@ -22,8 +22,6 @@
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/pcm_params.h> #include <sound/pcm_params.h>
#include <mach/dma.h>
#include "regs-i2s-v2.h" #include "regs-i2s-v2.h"
#include "s3c-i2s-v2.h" #include "s3c-i2s-v2.h"
#include "dma.h" #include "dma.h"
@ -392,8 +390,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
unsigned long irqs; unsigned long irqs;
int ret = 0; int ret = 0;
struct s3c_dma_params *dma_data =
snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
@ -424,13 +420,6 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
local_irq_restore(irqs); local_irq_restore(irqs);
/*
* Load the next buffer to DMA to meet the reqirement
* of the auto reload mechanism of S3C24XX.
* This call won't bother S3C64XX.
*/
s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
@ -644,12 +633,6 @@ int s3c_i2sv2_probe(struct snd_soc_dai *dai,
/* record our i2s structure for later use in the callbacks */ /* record our i2s structure for later use in the callbacks */
snd_soc_dai_set_drvdata(dai, i2s); snd_soc_dai_set_drvdata(dai, i2s);
i2s->regs = ioremap(base, 0x100);
if (i2s->regs == NULL) {
dev_err(dev, "cannot ioremap registers\n");
return -ENXIO;
}
i2s->iis_pclk = clk_get(dev, "iis"); i2s->iis_pclk = clk_get(dev, "iis");
if (IS_ERR(i2s->iis_pclk)) { if (IS_ERR(i2s->iis_pclk)) {
dev_err(dev, "failed to get iis_clock\n"); dev_err(dev, "failed to get iis_clock\n");
@ -729,7 +712,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
struct snd_soc_component_driver *cmp_drv, struct snd_soc_component_driver *cmp_drv,
struct snd_soc_dai_driver *dai_drv) struct snd_soc_dai_driver *dai_drv)
{ {
struct snd_soc_dai_ops *ops = dai_drv->ops; struct snd_soc_dai_ops *ops = (struct snd_soc_dai_ops *)dai_drv->ops;
ops->trigger = s3c2412_i2s_trigger; ops->trigger = s3c2412_i2s_trigger;
if (!ops->hw_params) if (!ops->hw_params)

View file

@ -33,25 +33,15 @@
#include "regs-i2s-v2.h" #include "regs-i2s-v2.h"
#include "s3c2412-i2s.h" #include "s3c2412-i2s.h"
static struct s3c_dma_client s3c2412_dma_client_out = {
.name = "I2S PCM Stereo out"
};
static struct s3c_dma_client s3c2412_dma_client_in = {
.name = "I2S PCM Stereo in"
};
static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = {
.client = &s3c2412_dma_client_out,
.channel = DMACH_I2S_OUT, .channel = DMACH_I2S_OUT,
.dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, .ch_name = "tx",
.dma_size = 4, .dma_size = 4,
}; };
static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = {
.client = &s3c2412_dma_client_in,
.channel = DMACH_I2S_IN, .channel = DMACH_I2S_IN,
.dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, .ch_name = "rx",
.dma_size = 4, .dma_size = 4,
}; };
@ -63,6 +53,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
samsung_asoc_init_dma_data(dai, &s3c2412_i2s_pcm_stereo_out,
&s3c2412_i2s_pcm_stereo_in);
ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS);
if (ret) if (ret)
return ret; return ret;
@ -70,17 +63,16 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in;
s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out;
s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); s3c2412_i2s.iis_cclk = devm_clk_get(dai->dev, "i2sclk");
if (IS_ERR(s3c2412_i2s.iis_cclk)) { if (IS_ERR(s3c2412_i2s.iis_cclk)) {
pr_err("failed to get i2sclk clock\n"); pr_err("failed to get i2sclk clock\n");
iounmap(s3c2412_i2s.regs);
return PTR_ERR(s3c2412_i2s.iis_cclk); return PTR_ERR(s3c2412_i2s.iis_cclk);
} }
/* Set MPLL as the source for IIS CLK */ /* Set MPLL as the source for IIS CLK */
clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll"));
clk_enable(s3c2412_i2s.iis_cclk); clk_prepare_enable(s3c2412_i2s.iis_cclk);
s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;
@ -93,9 +85,7 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
static int s3c2412_i2s_remove(struct snd_soc_dai *dai) static int s3c2412_i2s_remove(struct snd_soc_dai *dai)
{ {
clk_disable(s3c2412_i2s.iis_cclk); clk_disable_unprepare(s3c2412_i2s.iis_cclk);
clk_put(s3c2412_i2s.iis_cclk);
iounmap(s3c2412_i2s.regs);
return 0; return 0;
} }
@ -105,18 +95,10 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai) struct snd_soc_dai *cpu_dai)
{ {
struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai);
struct s3c_dma_params *dma_data;
u32 iismod; u32 iismod;
pr_debug("Entered %s\n", __func__); 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(cpu_dai, substream, dma_data);
iismod = readl(i2s->regs + S3C2412_IISMOD); iismod = readl(i2s->regs + S3C2412_IISMOD);
pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); pr_debug("%s: r: IISMOD: %x\n", __func__, iismod);
@ -169,6 +151,15 @@ static const struct snd_soc_component_driver s3c2412_i2s_component = {
static int s3c2412_iis_dev_probe(struct platform_device *pdev) static int s3c2412_iis_dev_probe(struct platform_device *pdev)
{ {
int ret = 0; int ret = 0;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
s3c2412_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(s3c2412_i2s.regs))
return PTR_ERR(s3c2412_i2s.regs);
s3c2412_i2s_pcm_stereo_out.dma_addr = res->start + S3C2412_IISTXD;
s3c2412_i2s_pcm_stereo_in.dma_addr = res->start + S3C2412_IISRXD;
ret = s3c_i2sv2_register_component(&pdev->dev, -1, ret = s3c_i2sv2_register_component(&pdev->dev, -1,
&s3c2412_i2s_component, &s3c2412_i2s_component,

View file

@ -31,25 +31,15 @@
#include "dma.h" #include "dma.h"
#include "s3c24xx-i2s.h" #include "s3c24xx-i2s.h"
static struct s3c_dma_client s3c24xx_dma_client_out = {
.name = "I2S PCM Stereo out"
};
static struct s3c_dma_client s3c24xx_dma_client_in = {
.name = "I2S PCM Stereo in"
};
static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = {
.client = &s3c24xx_dma_client_out,
.channel = DMACH_I2S_OUT, .channel = DMACH_I2S_OUT,
.dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, .ch_name = "tx",
.dma_size = 2, .dma_size = 2,
}; };
static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = {
.client = &s3c24xx_dma_client_in,
.channel = DMACH_I2S_IN, .channel = DMACH_I2S_IN,
.dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, .ch_name = "rx",
.dma_size = 2, .dma_size = 2,
}; };
@ -231,18 +221,12 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_dmaengine_dai_dma_data *dma_data;
struct s3c_dma_params *dma_data;
u32 iismod; u32 iismod;
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) dma_data = snd_soc_dai_get_dma_data(dai, substream);
dma_data = &s3c24xx_i2s_pcm_stereo_out;
else
dma_data = &s3c24xx_i2s_pcm_stereo_in;
snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data);
/* Working copies of register */ /* Working copies of register */
iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
@ -251,11 +235,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_width(params)) { switch (params_width(params)) {
case 8: case 8:
iismod &= ~S3C2410_IISMOD_16BIT; iismod &= ~S3C2410_IISMOD_16BIT;
dma_data->dma_size = 1; dma_data->addr_width = 1;
break; break;
case 16: case 16:
iismod |= S3C2410_IISMOD_16BIT; iismod |= S3C2410_IISMOD_16BIT;
dma_data->dma_size = 2; dma_data->addr_width = 2;
break; break;
default: default:
return -EINVAL; return -EINVAL;
@ -270,8 +254,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
int ret = 0; int ret = 0;
struct s3c_dma_params *dma_data =
snd_soc_dai_get_dma_data(dai, substream);
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
@ -290,7 +272,6 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
else else
s3c24xx_snd_txctrl(1); s3c24xx_snd_txctrl(1);
s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
@ -380,17 +361,15 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
{ {
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); samsung_asoc_init_dma_data(dai, &s3c24xx_i2s_pcm_stereo_out,
if (s3c24xx_i2s.regs == NULL) &s3c24xx_i2s_pcm_stereo_in);
return -ENXIO;
s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); s3c24xx_i2s.iis_clk = devm_clk_get(dai->dev, "iis");
if (IS_ERR(s3c24xx_i2s.iis_clk)) { if (IS_ERR(s3c24xx_i2s.iis_clk)) {
pr_err("failed to get iis_clock\n"); pr_err("failed to get iis_clock\n");
iounmap(s3c24xx_i2s.regs);
return PTR_ERR(s3c24xx_i2s.iis_clk); return PTR_ERR(s3c24xx_i2s.iis_clk);
} }
clk_enable(s3c24xx_i2s.iis_clk); clk_prepare_enable(s3c24xx_i2s.iis_clk);
/* Configure the I2S pins (GPE0...GPE4) in correct mode */ /* Configure the I2S pins (GPE0...GPE4) in correct mode */
s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2), s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
@ -414,7 +393,7 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
s3c24xx_i2s.iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); s3c24xx_i2s.iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON);
s3c24xx_i2s.iispsr = readl(s3c24xx_i2s.regs + S3C2410_IISPSR); s3c24xx_i2s.iispsr = readl(s3c24xx_i2s.regs + S3C2410_IISPSR);
clk_disable(s3c24xx_i2s.iis_clk); clk_disable_unprepare(s3c24xx_i2s.iis_clk);
return 0; return 0;
} }
@ -422,7 +401,7 @@ static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai)
static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai)
{ {
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
clk_enable(s3c24xx_i2s.iis_clk); clk_prepare_enable(s3c24xx_i2s.iis_clk);
writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON);
writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD);
@ -474,6 +453,19 @@ static const struct snd_soc_component_driver s3c24xx_i2s_component = {
static int s3c24xx_iis_dev_probe(struct platform_device *pdev) static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
{ {
int ret = 0; int ret = 0;
struct resource *res;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(&pdev->dev, "Can't get IO resource.\n");
return -ENOENT;
}
s3c24xx_i2s.regs = devm_ioremap_resource(&pdev->dev, res);
if (s3c24xx_i2s.regs == NULL)
return -ENXIO;
s3c24xx_i2s_pcm_stereo_out.dma_addr = res->start + S3C2410_IISFIFO;
s3c24xx_i2s_pcm_stereo_in.dma_addr = res->start + S3C2410_IISFIFO;
ret = devm_snd_soc_register_component(&pdev->dev, ret = devm_snd_soc_register_component(&pdev->dev,
&s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1); &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);

View file

@ -25,7 +25,7 @@
* o '0' means 'OFF' * o '0' means 'OFF'
* o 'X' means 'Don't care' * o 'X' means 'Don't care'
* *
* SMDK6410, SMDK6440, SMDK6450 Base B/D: CFG1-0000, CFG2-1111 * SMDK6410 Base B/D: CFG1-0000, CFG2-1111
* SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000 * SMDKC110, SMDKV210: CFGB11-100100, CFGB12-0000
*/ */

View file

@ -92,6 +92,9 @@ static int snow_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
/* Update card-name if provided through DT, else use default name */
snd_soc_of_parse_card_name(card, "samsung,model");
ret = devm_snd_soc_register_card(&pdev->dev, card); ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) { if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret); dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
@ -103,6 +106,7 @@ static int snow_probe(struct platform_device *pdev)
static const struct of_device_id snow_of_match[] = { static const struct of_device_id snow_of_match[] = {
{ .compatible = "google,snow-audio-max98090", }, { .compatible = "google,snow-audio-max98090", },
{ .compatible = "google,snow-audio-max98091", },
{ .compatible = "google,snow-audio-max98095", }, { .compatible = "google,snow-audio-max98095", },
{}, {},
}; };

View file

@ -93,10 +93,6 @@ struct samsung_spdif_info {
struct s3c_dma_params *dma_playback; struct s3c_dma_params *dma_playback;
}; };
static struct s3c_dma_client spdif_dma_client_out = {
.name = "S/PDIF Stereo out",
};
static struct s3c_dma_params spdif_stereo_out; static struct s3c_dma_params spdif_stereo_out;
static struct samsung_spdif_info spdif_info; static struct samsung_spdif_info spdif_info;
@ -435,7 +431,6 @@ static int spdif_probe(struct platform_device *pdev)
} }
spdif_stereo_out.dma_size = 2; spdif_stereo_out.dma_size = 2;
spdif_stereo_out.client = &spdif_dma_client_out;
spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF;
spdif_stereo_out.channel = dma_res->start; spdif_stereo_out.channel = dma_res->start;

View file

@ -260,12 +260,12 @@ struct fsi_priv {
u32 fmt; u32 fmt;
int chan_num:16; int chan_num:16;
int clk_master:1; unsigned int clk_master:1;
int clk_cpg:1; unsigned int clk_cpg:1;
int spdif:1; unsigned int spdif:1;
int enable_stream:1; unsigned int enable_stream:1;
int bit_clk_inv:1; unsigned int bit_clk_inv:1;
int lr_clk_inv:1; unsigned int lr_clk_inv:1;
}; };
struct fsi_stream_handler { struct fsi_stream_handler {