Commit 04f87446 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/rt5651', 'asoc/topic/samsung',...

Merge remote-tracking branches 'asoc/topic/rt5651', 'asoc/topic/samsung', 'asoc/topic/sgtl5000', 'asoc/topic/sh', 'asoc/topic/simple', 'asoc/topic/sirf', 'asoc/topic/sta350' and 'asoc/topic/tlv320dac33' into asoc-next
Simple-Card: Simple-Card:
Simple-Card specifies audio DAI connection of SoC <-> codec. Simple-Card specifies audio DAI connections of SoC <-> codec.
Required properties: Required properties:
...@@ -10,26 +10,51 @@ Optional properties: ...@@ -10,26 +10,51 @@ Optional properties:
- simple-audio-card,name : User specified audio sound card name, one string - simple-audio-card,name : User specified audio sound card name, one string
property. property.
- simple-audio-card,format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
- simple-audio-card,widgets : Please refer to widgets.txt. - simple-audio-card,widgets : Please refer to widgets.txt.
- simple-audio-card,routing : A list of the connections between audio components. - simple-audio-card,routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's connection's sink, the second being the connection's
source. source.
- dai-tdm-slot-num : Please refer to tdm-slot.txt. Optional subnodes:
- dai-tdm-slot-width : Please refer to tdm-slot.txt.
- simple-audio-card,dai-link : Container for dai-link level
properties and the CPU and CODEC
sub-nodes. This container may be
omitted when the card has only one
DAI link. See the examples and the
section bellow.
Dai-link subnode properties and subnodes:
If dai-link subnode is omitted and the subnode properties are directly
under "sound"-node the subnode property and subnode names have to be
prefixed with "simple-audio-card,"-prefix.
Required subnodes: Required dai-link subnodes:
- simple-audio-card,dai-link : container for the CPU and CODEC sub-nodes - cpu : CPU sub-node
This container may be omitted when the - codec : CODEC sub-node
card has only one DAI link.
See the examples.
- simple-audio-card,cpu : CPU sub-node Optional dai-link subnode properties:
- simple-audio-card,codec : CODEC sub-node
- format : CPU/CODEC common audio format.
"i2s", "right_j", "left_j" , "dsp_a"
"dsp_b", "ac97", "pdm", "msb", "lsb"
- frame-master : Indicates dai-link frame master.
phandle to a cpu or codec subnode.
- bitclock-master : Indicates dai-link bit clock master.
phandle to a cpu or codec subnode.
- bitclock-inversion : bool property. Add this if the
dai-link uses bit clock inversion.
- frame-inversion : bool property. Add this if the
dai-link uses frame clock inversion.
For backward compatibility the frame-master and bitclock-master
properties can be used as booleans in codec subnode to indicate if the
codec is the dai-link frame or bit clock master. In this case there
should be no dai-link node, the same properties should not be present
at sound-node level, and the bitclock-inversion and frame-inversion
properties should also be placed in the codec node if needed.
Required CPU/CODEC subnodes properties: Required CPU/CODEC subnodes properties:
...@@ -37,29 +62,21 @@ Required CPU/CODEC subnodes properties: ...@@ -37,29 +62,21 @@ Required CPU/CODEC subnodes properties:
Optional CPU/CODEC subnodes properties: Optional CPU/CODEC subnodes properties:
- format : CPU/CODEC specific audio format if needed. - dai-tdm-slot-num : Please refer to tdm-slot.txt.
see simple-audio-card,format - dai-tdm-slot-width : Please refer to tdm-slot.txt.
- frame-master : bool property. add this if subnode is frame master
- bitclock-master : bool property. add this if subnode is bitclock master
- bitclock-inversion : bool property. add this if subnode has clock inversion
- frame-inversion : bool property. add this if subnode has frame inversion
- clocks / system-clock-frequency : specify subnode's clock if needed. - clocks / system-clock-frequency : specify subnode's clock if needed.
it can be specified via "clocks" if system has it can be specified via "clocks" if system has
clock node (= common clock), or "system-clock-frequency" clock node (= common clock), or "system-clock-frequency"
(if system doens't support common clock) (if system doens't support common clock)
Note:
* For 'format', 'frame-master', 'bitclock-master', 'bitclock-inversion' and
'frame-inversion', the simple card will use the settings of CODEC for both
CPU and CODEC sides as we need to keep the settings identical for both ends
of the link.
Example 1 - single DAI link: Example 1 - single DAI link:
sound { sound {
compatible = "simple-audio-card"; compatible = "simple-audio-card";
simple-audio-card,name = "VF610-Tower-Sound-Card"; simple-audio-card,name = "VF610-Tower-Sound-Card";
simple-audio-card,format = "left_j"; simple-audio-card,format = "left_j";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
simple-audio-card,widgets = simple-audio-card,widgets =
"Microphone", "Microphone Jack", "Microphone", "Microphone Jack",
"Headphone", "Headphone Jack", "Headphone", "Headphone Jack",
...@@ -69,17 +86,12 @@ sound { ...@@ -69,17 +86,12 @@ sound {
"Headphone Jack", "HP_OUT", "Headphone Jack", "HP_OUT",
"External Speaker", "LINE_OUT"; "External Speaker", "LINE_OUT";
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <8>;
simple-audio-card,cpu { simple-audio-card,cpu {
sound-dai = <&sh_fsi2 0>; sound-dai = <&sh_fsi2 0>;
}; };
simple-audio-card,codec { dailink0_master: simple-audio-card,codec {
sound-dai = <&ak4648>; sound-dai = <&ak4648>;
bitclock-master;
frame-master;
clocks = <&osc>; clocks = <&osc>;
}; };
}; };
...@@ -105,31 +117,31 @@ Example 2 - many DAI links: ...@@ -105,31 +117,31 @@ Example 2 - many DAI links:
sound { sound {
compatible = "simple-audio-card"; compatible = "simple-audio-card";
simple-audio-card,name = "Cubox Audio"; simple-audio-card,name = "Cubox Audio";
simple-audio-card,format = "i2s";
simple-audio-card,dai-link@0 { /* I2S - HDMI */ simple-audio-card,dai-link@0 { /* I2S - HDMI */
simple-audio-card,cpu { format = "i2s";
cpu {
sound-dai = <&audio1 0>; sound-dai = <&audio1 0>;
}; };
simple-audio-card,codec { codec {
sound-dai = <&tda998x 0>; sound-dai = <&tda998x 0>;
}; };
}; };
simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */ simple-audio-card,dai-link@1 { /* S/PDIF - HDMI */
simple-audio-card,cpu { cpu {
sound-dai = <&audio1 1>; sound-dai = <&audio1 1>;
}; };
simple-audio-card,codec { codec {
sound-dai = <&tda998x 1>; sound-dai = <&tda998x 1>;
}; };
}; };
simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */ simple-audio-card,dai-link@2 { /* S/PDIF - S/PDIF */
simple-audio-card,cpu { cpu {
sound-dai = <&audio1 1>; sound-dai = <&audio1 1>;
}; };
simple-audio-card,codec { codec {
sound-dai = <&spdif_codec>; sound-dai = <&spdif_codec>;
}; };
}; };
......
Audio Binding for Snow boards
Required properties:
- compatible : Can be one of the following,
"google,snow-audio-max98090" or
"google,snow-audio-max98095"
- samsung,i2s-controller: The phandle of the Samsung I2S controller
- samsung,audio-codec: The phandle of the audio codec
Example:
sound {
compatible = "google,snow-audio-max98095";
samsung,i2s-controller = <&i2s0>;
samsung,audio-codec = <&max98095>;
};
...@@ -25,6 +25,7 @@ Optional properties: ...@@ -25,6 +25,7 @@ Optional properties:
2: 2 Channel (Full-Bridge) Power, 1 Channel FFX 2: 2 Channel (Full-Bridge) Power, 1 Channel FFX
3: 1 Channel Mono-Parallel 3: 1 Channel Mono-Parallel
If parameter is missing, mode 0 will be enabled. If parameter is missing, mode 0 will be enabled.
This property has to be specified as '/bits/ 8' value.
- st,ch1-output-mapping: Channel 1 output mapping - st,ch1-output-mapping: Channel 1 output mapping
- st,ch2-output-mapping: Channel 2 output mapping - st,ch2-output-mapping: Channel 2 output mapping
...@@ -33,6 +34,7 @@ Optional properties: ...@@ -33,6 +34,7 @@ Optional properties:
1: Channel 2 1: Channel 2
2: Channel 3 2: Channel 3
If parameter is missing, channel 1 is choosen. If parameter is missing, channel 1 is choosen.
This properties have to be specified as '/bits/ 8' values.
- st,thermal-warning-recover: - st,thermal-warning-recover:
If present, thermal warning recovery is enabled. If present, thermal warning recovery is enabled.
...@@ -82,9 +84,31 @@ Optional properties: ...@@ -82,9 +84,31 @@ Optional properties:
If not present, preset DC coefficient is used. If not present, preset DC coefficient is used.
- st,invalid-input-detect-mute: - st,invalid-input-detect-mute:
If not present, automatic invalid input detect mute is enabled. If present, automatic invalid input detect mute is enabled.
- st,activate-mute-output:
If present, a mute output will be activated in ase the volume will
reach a value lower than -76 dBFS.
- st,bridge-immediate-off:
If present, the bridge will be switched off immediately after the
power-down-gpio goes low. Otherwise, the bridge will wait for 13
million clock cycles to pass before shutting down.
- st,noise-shape-dc-cut:
If present, the noise-shaping technique on the DC cutoff filter are
enabled.
- st,powerdown-master-volume:
If present, the power-down pin and I2C power-down functions will
act on the master volume. Otherwise, the functions will act on the
mute commands.
- st,powerdown-delay-divider:
If present, the bridge power-down time will be divided by the provided
value. If not specified, a divider of 1 will be used. Allowed values
are 1, 2, 4, 8, 16, 32, 64 and 128.
This property has to be specified as '/bits/ 8' value.
Example: Example:
...@@ -93,12 +117,12 @@ codec: sta350@38 { ...@@ -93,12 +117,12 @@ codec: sta350@38 {
reg = <0x1c>; reg = <0x1c>;
reset-gpios = <&gpio1 19 0>; reset-gpios = <&gpio1 19 0>;
power-down-gpios = <&gpio1 16 0>; power-down-gpios = <&gpio1 16 0>;
st,output-conf = <0x3>; // set output to 2-channel st,output-conf = /bits/ 8 <0x3>; // set output to 2-channel
// (full-bridge) power, // (full-bridge) power,
// 2-channel data-out // 2-channel data-out
st,ch1-output-mapping = <0>; // set channel 1 output ch 1 st,ch1-output-mapping = /bits/ 8 <0>; // set channel 1 output ch 1
st,ch2-output-mapping = <0>; // set channel 2 output ch 1 st,ch2-output-mapping = /bits/ 8 <0>; // set channel 2 output ch 1
st,ch3-output-mapping = <0>; // set channel 3 output ch 1 st,ch3-output-mapping = /bits/ 8 <0>; // set channel 3 output ch 1
st,max-power-correction; // enables power bridge st,max-power-correction; // enables power bridge
// correction for THD reduction // correction for THD reduction
// near maximum power output // near maximum power output
......
...@@ -1326,7 +1326,9 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, ...@@ -1326,7 +1326,9 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np,
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
const char *propname); const char *propname);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np, unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix); const char *prefix,
struct device_node **bitclkmaster,
struct device_node **framemaster);
int snd_soc_of_get_dai_name(struct device_node *of_node, int snd_soc_of_get_dai_name(struct device_node *of_node,
const char **dai_name); const char **dai_name);
......
...@@ -37,6 +37,7 @@ struct sta350_platform_data { ...@@ -37,6 +37,7 @@ struct sta350_platform_data {
u8 ch3_output_mapping; u8 ch3_output_mapping;
u8 ffx_power_output_mode; u8 ffx_power_output_mode;
u8 drop_compensation_ns; u8 drop_compensation_ns;
u8 powerdown_delay_divider;
unsigned int thermal_warning_recovery:1; unsigned int thermal_warning_recovery:1;
unsigned int thermal_warning_adjustment:1; unsigned int thermal_warning_adjustment:1;
unsigned int fault_detect_recovery:1; unsigned int fault_detect_recovery:1;
...@@ -47,6 +48,10 @@ struct sta350_platform_data { ...@@ -47,6 +48,10 @@ struct sta350_platform_data {
unsigned int odd_pwm_speed_mode:1; unsigned int odd_pwm_speed_mode:1;
unsigned int distortion_compensation:1; unsigned int distortion_compensation:1;
unsigned int invalid_input_detect_mute:1; unsigned int invalid_input_detect_mute:1;
unsigned int activate_mute_output:1;
unsigned int bridge_immediate_off:1;
unsigned int noise_shape_dc_cut:1;
unsigned int powerdown_master_vol:1;
}; };
#endif /* __LINUX_SND__STA350_H */ #endif /* __LINUX_SND__STA350_H */
...@@ -1368,8 +1368,7 @@ static int get_clk_info(int sclk, int rate) ...@@ -1368,8 +1368,7 @@ static int get_clk_info(int sclk, int rate)
static int rt5651_hw_params(struct snd_pcm_substream *substream, static int rt5651_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)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = dai->codec;
struct snd_soc_codec *codec = rtd->codec;
struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec); struct rt5651_priv *rt5651 = snd_soc_codec_get_drvdata(codec);
unsigned int val_len = 0, val_clk, mask_clk; unsigned int val_len = 0, val_clk, mask_clk;
int pre_div, bclk_ms, frame_size; int pre_div, bclk_ms, frame_size;
......
...@@ -1322,7 +1322,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) ...@@ -1322,7 +1322,7 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
return ret; return ret;
} }
ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies), ret = devm_regulator_bulk_get(codec->dev, ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies); sgtl5000->supplies);
if (ret) if (ret)
goto err_ldo_remove; goto err_ldo_remove;
...@@ -1330,16 +1330,13 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec) ...@@ -1330,16 +1330,13 @@ static int sgtl5000_enable_regulators(struct snd_soc_codec *codec)
ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies), ret = regulator_bulk_enable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies); sgtl5000->supplies);
if (ret) if (ret)
goto err_regulator_free; goto err_ldo_remove;
/* wait for all power rails bring up */ /* wait for all power rails bring up */
udelay(10); udelay(10);
return 0; return 0;
err_regulator_free:
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
err_ldo_remove: err_ldo_remove:
if (!external_vddd) if (!external_vddd)
ldo_regulator_remove(codec); ldo_regulator_remove(codec);
...@@ -1409,8 +1406,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) ...@@ -1409,8 +1406,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec)
err: err:
regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies); sgtl5000->supplies);
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
ldo_regulator_remove(codec); ldo_regulator_remove(codec);
return ret; return ret;
...@@ -1424,8 +1419,6 @@ static int sgtl5000_remove(struct snd_soc_codec *codec) ...@@ -1424,8 +1419,6 @@ static int sgtl5000_remove(struct snd_soc_codec *codec)
regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies), regulator_bulk_disable(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies); sgtl5000->supplies);
regulator_bulk_free(ARRAY_SIZE(sgtl5000->supplies),
sgtl5000->supplies);
ldo_regulator_remove(codec); ldo_regulator_remove(codec);
return 0; return 0;
......
...@@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = { ...@@ -279,13 +279,63 @@ static const struct snd_soc_dapm_route sirf_audio_codec_map[] = {
{"Mic input mode mux", "Differential", "MICIN1"}, {"Mic input mode mux", "Differential", "MICIN1"},
}; };
static void sirf_audio_codec_tx_enable(struct sirf_audio_codec *sirf_audio_codec)
{
regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP,
AUDIO_FIFO_START, AUDIO_FIFO_START);
regmap_update_bits(sirf_audio_codec->regmap,
AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, IC_TX_ENABLE);
}
static void sirf_audio_codec_tx_disable(struct sirf_audio_codec *sirf_audio_codec)
{
regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
regmap_update_bits(sirf_audio_codec->regmap,
AUDIO_PORT_IC_CODEC_TX_CTRL, IC_TX_ENABLE, ~IC_TX_ENABLE);
}
static void sirf_audio_codec_rx_enable(struct sirf_audio_codec *sirf_audio_codec,
int channels)
{
regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
AUDIO_FIFO_RESET, ~AUDIO_FIFO_RESET);
regmap_write(sirf_audio_codec->regmap,
AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
regmap_write(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
regmap_update_bits(sirf_audio_codec->regmap, AUDIO_PORT_IC_RXFIFO_OP,
AUDIO_FIFO_START, AUDIO_FIFO_START);
if (channels == 1)
regmap_update_bits(sirf_audio_codec->regmap,
AUDIO_PORT_IC_CODEC_RX_CTRL,
IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
else
regmap_update_bits(sirf_audio_codec->regmap,
AUDIO_PORT_IC_CODEC_RX_CTRL,
IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
}
static void sirf_audio_codec_rx_disable(struct sirf_audio_codec *sirf_audio_codec)
{
regmap_update_bits(sirf_audio_codec->regmap,
AUDIO_PORT_IC_CODEC_RX_CTRL,
IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
}
static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
int cmd, int cmd,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct snd_soc_codec *codec = dai->codec; struct snd_soc_codec *codec = dai->codec;
u32 val = 0; struct sirf_audio_codec *sirf_audio_codec = snd_soc_codec_get_drvdata(codec);
int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
/* /*
* This is a workaround, When stop playback, * This is a workaround, When stop playback,
...@@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, ...@@ -295,20 +345,28 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream,
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if (playback) {
snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
IC_HSLEN | IC_HSREN, 0);
sirf_audio_codec_tx_disable(sirf_audio_codec);
} else
sirf_audio_codec_rx_disable(sirf_audio_codec);
break; break;
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME: case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (playback) if (playback) {
val = IC_HSLEN | IC_HSREN; sirf_audio_codec_tx_enable(sirf_audio_codec);
snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
IC_HSLEN | IC_HSREN, IC_HSLEN | IC_HSREN);
} else
sirf_audio_codec_rx_enable(sirf_audio_codec,
substream->runtime->channels);
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
if (playback)
snd_soc_update_bits(codec, AUDIO_IC_CODEC_CTRL0,
IC_HSLEN | IC_HSREN, val);
return 0; return 0;
} }
...@@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = { ...@@ -392,7 +450,7 @@ static const struct regmap_config sirf_audio_codec_regmap_config = {
.reg_bits = 32, .reg_bits = 32,
.reg_stride = 4, .reg_stride = 4,
.val_bits = 32, .val_bits = 32,
.max_register = AUDIO_IC_CODEC_CTRL3, .max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
.cache_type = REGCACHE_NONE, .cache_type = REGCACHE_NONE,
}; };
......
...@@ -72,4 +72,54 @@ ...@@ -72,4 +72,54 @@
#define IC_RXPGAR 0x7B #define IC_RXPGAR 0x7B
#define IC_RXPGAL 0x7B #define IC_RXPGAL 0x7B
#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F
#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0
#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10
#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20
#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_TX_FIFO_SC_OFFSET)
#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_TX_FIFO_LC_OFFSET)
#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_TX_FIFO_HC_OFFSET)
#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F
#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0
#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10
#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20
#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_RX_FIFO_SC_OFFSET)
#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_RX_FIFO_LC_OFFSET)
#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_RX_FIFO_HC_OFFSET)
#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4)
#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8)
#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC)
#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100)
#define AUDIO_PORT_IC_TXFIFO_STS (0x0104)
#define AUDIO_PORT_IC_TXFIFO_INT (0x0108)
#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C)
#define AUDIO_PORT_IC_RXFIFO_OP (0x0110)
#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114)
#define AUDIO_PORT_IC_RXFIFO_STS (0x0118)
#define AUDIO_PORT_IC_RXFIFO_INT (0x011C)
#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120)
#define AUDIO_FIFO_START (1 << 0)
#define AUDIO_FIFO_RESET (1 << 1)
#define AUDIO_FIFO_FULL (1 << 0)
#define AUDIO_FIFO_EMPTY (1 << 1)
#define AUDIO_FIFO_OFLOW (1 << 2)
#define AUDIO_FIFO_UFLOW (1 << 3)
#define IC_TX_ENABLE (0x03)
#define IC_RX_ENABLE_MONO (0x01)
#define IC_RX_ENABLE_STEREO (0x03)
#endif /*__SIRF_AUDIO_CODEC_H*/ #endif /*__SIRF_AUDIO_CODEC_H*/
...@@ -1020,6 +1020,29 @@ static int sta350_probe(struct snd_soc_codec *codec) ...@@ -1020,6 +1020,29 @@ static int sta350_probe(struct snd_soc_codec *codec)
pdata->ch3_output_mapping pdata->ch3_output_mapping
<< STA350_CxCFG_OM_SHIFT); << STA350_CxCFG_OM_SHIFT);
/* miscellaneous registers */
regmap_update_bits(sta350->regmap, STA350_MISC1,
STA350_MISC1_CPWMEN,
pdata->activate_mute_output ?
STA350_MISC1_CPWMEN : 0);
regmap_update_bits(sta350->regmap, STA350_MISC1,
STA350_MISC1_BRIDGOFF,
pdata->bridge_immediate_off ?
STA350_MISC1_BRIDGOFF : 0);
regmap_update_bits(sta350->regmap, STA350_MISC1,
STA350_MISC1_NSHHPEN,
pdata->noise_shape_dc_cut ?
STA350_MISC1_NSHHPEN : 0);
regmap_update_bits(sta350->regmap, STA350_MISC1,
STA350_MISC1_RPDNEN,
pdata->powerdown_master_vol ?
STA350_MISC1_RPDNEN: 0);
regmap_update_bits(sta350->regmap, STA350_MISC2,
STA350_MISC2_PNDLSL_MASK,
pdata->powerdown_delay_divider
<< STA350_MISC2_PNDLSL_SHIFT);
/* initialize coefficient shadow RAM with reset values */ /* initialize coefficient shadow RAM with reset values */
for (i = 4; i <= 49; i += 5) for (i = 4; i <= 49; i += 5)
sta350->coef_shadow[i] = 0x400000; sta350->coef_shadow[i] = 0x400000;
...@@ -1094,6 +1117,7 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) ...@@ -1094,6 +1117,7 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350)
struct sta350_platform_data *pdata; struct sta350_platform_data *pdata;
const char *ffx_power_mode; const char *ffx_power_mode;
u16 tmp; u16 tmp;
u8 tmp8;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) if (!pdata)
...@@ -1158,6 +1182,27 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350) ...@@ -1158,6 +1182,27 @@ static int sta350_probe_dt(struct device *dev, struct sta350_priv *sta350)
if (of_get_property(np, "st,invalid-input-detect-mute", NULL)) if (of_get_property(np, "st,invalid-input-detect-mute", NULL))
pdata->invalid_input_detect_mute = 1; pdata->invalid_input_detect_mute = 1;
/* MISC */
if (of_get_property(np, "st,activate-mute-output", NULL))
pdata->activate_mute_output = 1;
if (of_get_property(np, "st,bridge-immediate-off", NULL))
pdata->bridge_immediate_off = 1;
if (of_get_property(np, "st,noise-shape-dc-cut", NULL))
pdata->noise_shape_dc_cut = 1;
if (of_get_property(np, "st,powerdown-master-volume", NULL))
pdata->powerdown_master_vol = 1;
if (!of_property_read_u8(np, "st,powerdown-delay-divider", &tmp8)) {
if (is_power_of_2(tmp8) && tmp8 >= 1 && tmp8 <= 128)
pdata->powerdown_delay_divider = ilog2(tmp8);
else
dev_warn(dev, "Unsupported powerdown delay divider %d\n",
tmp8);
}
sta350->pdata = pdata; sta350->pdata = pdata;
return 0; return 0;
......
...@@ -225,4 +225,14 @@ ...@@ -225,4 +225,14 @@
#define STA350_C3_MIX1 60 #define STA350_C3_MIX1 60
#define STA350_C3_MIX2 61 #define STA350_C3_MIX2 61
/* miscellaneous register 1 */
#define STA350_MISC1_CPWMEN BIT(2)
#define STA350_MISC1_BRIDGOFF BIT(5)
#define STA350_MISC1_NSHHPEN BIT(6)
#define STA350_MISC1_RPDNEN BIT(7)
/* miscellaneous register 2 */
#define STA350_MISC2_PNDLSL_MASK 0x1c
#define STA350_MISC2_PNDLSL_SHIFT 2
#endif /* _ASOC_STA_350_H */ #endif /* _ASOC_STA_350_H */
...@@ -1540,7 +1540,7 @@ static int dac33_i2c_probe(struct i2c_client *client, ...@@ -1540,7 +1540,7 @@ static int dac33_i2c_probe(struct i2c_client *client,
for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++) for (i = 0; i < ARRAY_SIZE(dac33->supplies); i++)
dac33->supplies[i].supply = dac33_supply_names[i]; dac33->supplies[i].supply = dac33_supply_names[i];
ret = regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies), ret = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(dac33->supplies),
dac33->supplies); dac33->supplies);
if (ret != 0) { if (ret != 0) {
...@@ -1551,11 +1551,9 @@ static int dac33_i2c_probe(struct i2c_client *client, ...@@ -1551,11 +1551,9 @@ static int dac33_i2c_probe(struct i2c_client *client,
ret = snd_soc_register_codec(&client->dev, ret = snd_soc_register_codec(&client->dev,
&soc_codec_dev_tlv320dac33, &dac33_dai, 1); &soc_codec_dev_tlv320dac33, &dac33_dai, 1);
if (ret < 0) if (ret < 0)
goto err_register; goto err_get;
return ret; return ret;
err_register:
regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
err_get: err_get:
if (dac33->power_gpio >= 0) if (dac33->power_gpio >= 0)
gpio_free(dac33->power_gpio); gpio_free(dac33->power_gpio);
...@@ -1573,8 +1571,6 @@ static int dac33_i2c_remove(struct i2c_client *client) ...@@ -1573,8 +1571,6 @@ static int dac33_i2c_remove(struct i2c_client *client)
if (dac33->power_gpio >= 0) if (dac33->power_gpio >= 0)
gpio_free(dac33->power_gpio); gpio_free(dac33->power_gpio);
regulator_bulk_free(ARRAY_SIZE(dac33->supplies), dac33->supplies);
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);
return 0; return 0;
} }
......
...@@ -66,8 +66,7 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai, ...@@ -66,8 +66,7 @@ static int __asoc_simple_card_dai_init(struct snd_soc_dai *dai,
static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct simple_card_data *priv = struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec = rtd->codec_dai; struct snd_soc_dai *codec = rtd->codec_dai;
struct snd_soc_dai *cpu = rtd->cpu_dai; struct snd_soc_dai *cpu = rtd->cpu_dai;
struct simple_dai_props *dai_props; struct simple_dai_props *dai_props;
...@@ -88,7 +87,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd) ...@@ -88,7 +87,6 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
static int static int
asoc_simple_card_sub_parse_of(struct device_node *np, asoc_simple_card_sub_parse_of(struct device_node *np,
unsigned int daifmt,
struct asoc_simple_dai *dai, struct asoc_simple_dai *dai,
const struct device_node **p_node, const struct device_node **p_node,
const char **name) const char **name)
...@@ -116,14 +114,6 @@ asoc_simple_card_sub_parse_of(struct device_node *np, ...@@ -116,14 +114,6 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
if (ret) if (ret)
return ret; return ret;
/*
* bitclock-inversion, frame-inversion
* bitclock-master, frame-master
* and specific "format" if it has
*/
dai->fmt = snd_soc_of_parse_daifmt(np, NULL);
dai->fmt |= daifmt;
/* /*
* dai->sysclk come from * dai->sysclk come from
* "clocks = <&xxx>" (if system has common clock) * "clocks = <&xxx>" (if system has common clock)
...@@ -151,37 +141,132 @@ asoc_simple_card_sub_parse_of(struct device_node *np, ...@@ -151,37 +141,132 @@ asoc_simple_card_sub_parse_of(struct device_node *np,
return 0; return 0;
} }
static int simple_card_cpu_codec_of(struct device_node *node, static int simple_card_dai_link_of(struct device_node *node,
int daifmt, struct device *dev,
struct snd_soc_dai_link *dai_link, struct snd_soc_dai_link *dai_link,
struct simple_dai_props *dai_props) struct simple_dai_props *dai_props)
{ {
struct device_node *np; struct device_node *np = NULL;
struct device_node *bitclkmaster = NULL;
struct device_node *framemaster = NULL;
unsigned int daifmt;
char *name;
char prop[128];
char *prefix = "";
int ret; int ret;
/* CPU sub-node */ prefix = "simple-audio-card,";
ret = -EINVAL;
np = of_get_child_by_name(node, "simple-audio-card,cpu"); daifmt = snd_soc_of_parse_daifmt(node, prefix,
if (np) { &bitclkmaster, &framemaster);
ret = asoc_simple_card_sub_parse_of(np, daifmt, daifmt &= ~SND_SOC_DAIFMT_MASTER_MASK;
&dai_props->cpu_dai,
&dai_link->cpu_of_node, snprintf(prop, sizeof(prop), "%scpu", prefix);
&dai_link->cpu_dai_name); np = of_get_child_by_name(node, prop);
of_node_put(np); if (!np) {
ret = -EINVAL;
dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
goto dai_link_of_err;
} }
ret = asoc_simple_card_sub_parse_of(np, &dai_props->cpu_dai,
&dai_link->cpu_of_node,
&dai_link->cpu_dai_name);
if (ret < 0) if (ret < 0)
return ret; goto dai_link_of_err;
dai_props->cpu_dai.fmt = daifmt;
switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
case 0x11:
dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
break;
case 0x10:
dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
break;
case 0x01:
dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
break;
default:
dai_props->cpu_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
break;
}
/* CODEC sub-node */ of_node_put(np);
ret = -EINVAL; snprintf(prop, sizeof(prop), "%scodec", prefix);
np = of_get_child_by_name(node, "simple-audio-card,codec"); np = of_get_child_by_name(node, prop);
if (np) { if (!np) {
ret = asoc_simple_card_sub_parse_of(np, daifmt, ret = -EINVAL;
&dai_props->codec_dai, dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
&dai_link->codec_of_node, goto dai_link_of_err;
&dai_link->codec_dai_name);
of_node_put(np);
} }
ret = asoc_simple_card_sub_parse_of(np, &dai_props->codec_dai,
&dai_link->codec_of_node,
&dai_link->codec_dai_name);
if (ret < 0)
goto dai_link_of_err;
if (strlen(prefix) && !bitclkmaster && !framemaster) {
/* No dai-link level and master setting was not found from
sound node level, revert back to legacy DT parsing and
take the settings from codec node. */
dev_dbg(dev, "%s: Revert to legacy daifmt parsing\n",
__func__);
dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt =
snd_soc_of_parse_daifmt(np, NULL, NULL, NULL) |
(daifmt & ~SND_SOC_DAIFMT_CLOCK_MASK);
} else {
dai_props->codec_dai.fmt = daifmt;
switch (((np == bitclkmaster) << 4) | (np == framemaster)) {
case 0x11:
dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFM;
break;
case 0x10:
dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBM_CFS;
break;
case 0x01:
dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFM;
break;
default:
dai_props->codec_dai.fmt |= SND_SOC_DAIFMT_CBS_CFS;
break;
}
}
if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
ret = -EINVAL;
goto dai_link_of_err;
}
/* simple-card assumes platform == cpu */
dai_link->platform_of_node = dai_link->cpu_of_node;
/* Link name is created from CPU/CODEC dai name */
name = devm_kzalloc(dev,
strlen(dai_link->cpu_dai_name) +
strlen(dai_link->codec_dai_name) + 2,
GFP_KERNEL);
sprintf(name, "%s-%s", dai_link->cpu_dai_name,
dai_link->codec_dai_name);
dai_link->name = dai_link->stream_name = name;
dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
dev_dbg(dev, "\tcpu : %s / %04x / %d\n",
dai_link->cpu_dai_name,
dai_props->cpu_dai.fmt,
dai_props->cpu_dai.sysclk);
dev_dbg(dev, "\tcodec : %s / %04x / %d\n",
dai_link->codec_dai_name,
dai_props->codec_dai.fmt,
dai_props->codec_dai.sysclk);
dai_link_of_err:
if (np)
of_node_put(np);
if (bitclkmaster)
of_node_put(bitclkmaster);
if (framemaster)
of_node_put(framemaster);
return ret; return ret;
} }
...@@ -192,18 +277,11 @@ static int asoc_simple_card_parse_of(struct device_node *node, ...@@ -192,18 +277,11 @@ static int asoc_simple_card_parse_of(struct device_node *node,
{ {
struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link; struct snd_soc_dai_link *dai_link = priv->snd_card.dai_link;
struct simple_dai_props *dai_props = priv->dai_props; struct simple_dai_props *dai_props = priv->dai_props;
struct device_node *np;
char *name;
unsigned int daifmt;
int ret; int ret;
/* parsing the card name from DT */ /* parsing the card name from DT */
snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name"); snd_soc_of_parse_card_name(&priv->snd_card, "simple-audio-card,name");
/* get CPU/CODEC common format via simple-audio-card,format */
daifmt = snd_soc_of_parse_daifmt(node, "simple-audio-card,") &
(SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_INV_MASK);
/* off-codec widgets */ /* off-codec widgets */
if (of_property_read_bool(node, "simple-audio-card,widgets")) { if (of_property_read_bool(node, "simple-audio-card,widgets")) {
ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card, ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
...@@ -220,71 +298,31 @@ static int asoc_simple_card_parse_of(struct device_node *node, ...@@ -220,71 +298,31 @@ static int asoc_simple_card_parse_of(struct device_node *node,
return ret; return ret;
} }
/* loop on the DAI links */ dev_dbg(dev, "New simple-card: %s\n", priv->snd_card.name ?
np = NULL; priv->snd_card.name : "");
for (;;) {
if (multi) { if (multi) {
np = of_get_next_child(node, np); struct device_node *np = NULL;
if (!np) int i;
break; for (i = 0; (np = of_get_next_child(node, np)); i++) {
dev_dbg(dev, "\tlink %d:\n", i);
ret = simple_card_dai_link_of(np, dev, dai_link + i,
dai_props + i);
if (ret < 0) {
of_node_put(np);
return ret;
}
} }
} else {
ret = simple_card_cpu_codec_of(multi ? np : node, ret = simple_card_dai_link_of(node, dev, dai_link, dai_props);
daifmt, dai_link, dai_props);
if (ret < 0) if (ret < 0)
goto err; return ret;
/*
* overwrite cpu_dai->fmt as its DAIFMT_MASTER bit is based on CODEC
* while the other bits should be identical unless buggy SW/HW design.
*/
dai_props->cpu_dai.fmt = dai_props->codec_dai.fmt;
if (!dai_link->cpu_dai_name || !dai_link->codec_dai_name) {
ret = -EINVAL;
goto err;
}
/* simple-card assumes platform == cpu */
dai_link->platform_of_node = dai_link->cpu_of_node;
name = devm_kzalloc(dev,
strlen(dai_link->cpu_dai_name) +
strlen(dai_link->codec_dai_name) + 2,
GFP_KERNEL);
sprintf(name, "%s-%s", dai_link->cpu_dai_name,
dai_link->codec_dai_name);
dai_link->name = dai_link->stream_name = name;
if (!multi)
break;
dai_link++;
dai_props++;
} }
/* card name is created from CPU/CODEC dai name */
dai_link = priv->snd_card.dai_link;
if (!priv->snd_card.name) if (!priv->snd_card.name)
priv->snd_card.name = dai_link->name; priv->snd_card.name = priv->snd_card.dai_link->name;
dev_dbg(dev, "card-name : %s\n", priv->snd_card.name);
dev_dbg(dev, "platform : %04x\n", daifmt);
dai_props = priv->dai_props;
dev_dbg(dev, "cpu : %s / %04x / %d\n",
dai_link->cpu_dai_name,
dai_props->cpu_dai.fmt,
dai_props->cpu_dai.sysclk);
dev_dbg(dev, "codec : %s / %04x / %d\n",
dai_link->codec_dai_name,
dai_props->codec_dai.fmt,
dai_props->codec_dai.sysclk);
return 0; return 0;
err:
of_node_put(np);
return ret;
} }
/* update the reference count of the devices nodes at end of probe */ /* update the reference count of the devices nodes at end of probe */
...@@ -378,10 +416,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev) ...@@ -378,10 +416,10 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
if (!cinfo->name || if (!cinfo->name ||
!cinfo->codec_dai.name || !cinfo->codec_dai.name ||
!cinfo->codec || !cinfo->codec ||
!cinfo->platform || !cinfo->platform ||
!cinfo->cpu_dai.name) { !cinfo->cpu_dai.name) {
dev_err(dev, "insufficient asoc_simple_card_info settings\n"); dev_err(dev, "insufficient asoc_simple_card_info settings\n");
return -EINVAL; return -EINVAL;
...@@ -425,11 +463,11 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match); ...@@ -425,11 +463,11 @@ MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
static struct platform_driver asoc_simple_card = { static struct platform_driver asoc_simple_card = {
.driver = { .driver = {
.name = "asoc-simple-card", .name = "asoc-simple-card",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = asoc_simple_of_match, .of_match_table = asoc_simple_of_match,
}, },
.probe = asoc_simple_card_probe, .probe = asoc_simple_card_probe,
}; };
module_platform_driver(asoc_simple_card); module_platform_driver(asoc_simple_card);
......
...@@ -64,6 +64,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 ...@@ -64,6 +64,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_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
depends on REGMAP_I2C
select SND_SOC_WM8580 select SND_SOC_WM8580
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
help help
...@@ -115,21 +116,21 @@ config SND_SOC_SAMSUNG_SIMTEC ...@@ -115,21 +116,21 @@ config SND_SOC_SAMSUNG_SIMTEC
config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23 config SND_SOC_SAMSUNG_SIMTEC_TLV320AIC23
tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C
select SND_S3C24XX_I2S select SND_S3C24XX_I2S
select SND_SOC_TLV320AIC23_I2C select SND_SOC_TLV320AIC23_I2C
select SND_SOC_SAMSUNG_SIMTEC select SND_SOC_SAMSUNG_SIMTEC
config SND_SOC_SAMSUNG_SIMTEC_HERMES config SND_SOC_SAMSUNG_SIMTEC_HERMES
tristate "SoC I2S Audio support for Simtec Hermes board" tristate "SoC I2S Audio support for Simtec Hermes board"
depends on SND_SOC_SAMSUNG && ARCH_S3C24XX depends on SND_SOC_SAMSUNG && ARCH_S3C24XX && I2C
select SND_S3C24XX_I2S select SND_S3C24XX_I2S
select SND_SOC_TLV320AIC3X select SND_SOC_TLV320AIC3X
select SND_SOC_SAMSUNG_SIMTEC select SND_SOC_SAMSUNG_SIMTEC
config SND_SOC_SAMSUNG_H1940_UDA1380 config SND_SOC_SAMSUNG_H1940_UDA1380
tristate "Audio support for the HP iPAQ H1940" tristate "Audio support for the HP iPAQ H1940"
depends on SND_SOC_SAMSUNG && ARCH_H1940 depends on SND_SOC_SAMSUNG && ARCH_H1940 && I2C
select SND_S3C24XX_I2S select SND_S3C24XX_I2S
select SND_SOC_UDA1380 select SND_SOC_UDA1380
help help
...@@ -137,7 +138,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380 ...@@ -137,7 +138,7 @@ config SND_SOC_SAMSUNG_H1940_UDA1380
config SND_SOC_SAMSUNG_RX1950_UDA1380 config SND_SOC_SAMSUNG_RX1950_UDA1380
tristate "Audio support for the HP iPAQ RX1950" tristate "Audio support for the HP iPAQ RX1950"
depends on SND_SOC_SAMSUNG && MACH_RX1950 depends on SND_SOC_SAMSUNG && MACH_RX1950 && I2C
select SND_S3C24XX_I2S select SND_S3C24XX_I2S
select SND_SOC_UDA1380 select SND_SOC_UDA1380
help help
...@@ -178,6 +179,7 @@ config SND_SOC_SAMSUNG_SMDK_SPDIF ...@@ -178,6 +179,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_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110)
depends on REGMAP_I2C
select SND_SOC_WM8580 select SND_SOC_WM8580
select SND_SAMSUNG_PCM select SND_SAMSUNG_PCM
help help
...@@ -231,3 +233,13 @@ config SND_SOC_LITTLEMILL ...@@ -231,3 +233,13 @@ config SND_SOC_LITTLEMILL
select SND_SAMSUNG_I2S select SND_SAMSUNG_I2S
select MFD_WM8994 select MFD_WM8994
select SND_SOC_WM8994 select SND_SOC_WM8994
config SND_SOC_SNOW
tristate "Audio support for Google Snow boards"
depends on SND_SOC_SAMSUNG
select SND_SOC_MAX98090
select SND_SOC_MAX98095
select SND_SAMSUNG_I2S
help
Say Y if you want to add audio support for various Snow
boards based on Exynos5 series of SoCs.
...@@ -34,6 +34,7 @@ snd-soc-h1940-uda1380-objs := h1940_uda1380.o ...@@ -34,6 +34,7 @@ snd-soc-h1940-uda1380-objs := h1940_uda1380.o
snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o
snd-soc-smdk-wm8580-objs := smdk_wm8580.o snd-soc-smdk-wm8580-objs := smdk_wm8580.o
snd-soc-smdk-wm8994-objs := smdk_wm8994.o snd-soc-smdk-wm8994-objs := smdk_wm8994.o
snd-soc-snow-objs := snow.o
snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o
snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o
snd-soc-goni-wm8994-objs := goni_wm8994.o snd-soc-goni-wm8994-objs := goni_wm8994.o
...@@ -58,6 +59,7 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o ...@@ -58,6 +59,7 @@ obj-$(CONFIG_SND_SOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o
obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o obj-$(CONFIG_SND_SOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o
obj-$(CONFIG_SND_SOC_SNOW) += snd-soc-snow.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o
obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_SND_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o
obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o obj-$(CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o
......
...@@ -433,7 +433,7 @@ static int s3c_ac97_probe(struct platform_device *pdev) ...@@ -433,7 +433,7 @@ static int s3c_ac97_probe(struct platform_device *pdev)
goto err4; goto err4;
} }
ret = snd_soc_register_component(&pdev->dev, &s3c_ac97_component, ret = devm_snd_soc_register_component(&pdev->dev, &s3c_ac97_component,
s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai)); s3c_ac97_dai, ARRAY_SIZE(s3c_ac97_dai));
if (ret) if (ret)
goto err5; goto err5;
...@@ -441,12 +441,10 @@ static int s3c_ac97_probe(struct platform_device *pdev) ...@@ -441,12 +441,10 @@ static int s3c_ac97_probe(struct platform_device *pdev)
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
goto err6; goto err5;
} }
return 0; return 0;
err6:
snd_soc_unregister_component(&pdev->dev);
err5: err5:
free_irq(irq_res->start, NULL); free_irq(irq_res->start, NULL);
err4: err4:
...@@ -461,9 +459,6 @@ static int s3c_ac97_remove(struct platform_device *pdev) ...@@ -461,9 +459,6 @@ static int s3c_ac97_remove(struct platform_device *pdev)
{ {
struct resource *irq_res; struct resource *irq_res;
samsung_asoc_dma_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq_res) if (irq_res)
free_irq(irq_res->start, NULL); free_irq(irq_res->start, NULL);
......
...@@ -433,22 +433,13 @@ static int bells_probe(struct platform_device *pdev) ...@@ -433,22 +433,13 @@ static int bells_probe(struct platform_device *pdev)
bells_cards[pdev->id].dev = &pdev->dev; bells_cards[pdev->id].dev = &pdev->dev;
ret = snd_soc_register_card(&bells_cards[pdev->id]); ret = devm_snd_soc_register_card(&pdev->dev, &bells_cards[pdev->id]);
if (ret) { if (ret)
dev_err(&pdev->dev, dev_err(&pdev->dev,
"snd_soc_register_card(%s) failed: %d\n", "snd_soc_register_card(%s) failed: %d\n",
bells_cards[pdev->id].name, ret); bells_cards[pdev->id].name, ret);
return ret;
}
return 0;
}
static int bells_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&bells_cards[pdev->id]);
return 0; return ret;
} }
static struct platform_driver bells_driver = { static struct platform_driver bells_driver = {
...@@ -458,7 +449,6 @@ static struct platform_driver bells_driver = { ...@@ -458,7 +449,6 @@ static struct platform_driver bells_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = bells_probe, .probe = bells_probe,
.remove = bells_remove,
}; };
module_platform_driver(bells_driver); module_platform_driver(bells_driver);
......
...@@ -445,16 +445,10 @@ EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); ...@@ -445,16 +445,10 @@ EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
int samsung_asoc_dma_platform_register(struct device *dev) int samsung_asoc_dma_platform_register(struct device *dev)
{ {
return snd_soc_register_platform(dev, &samsung_asoc_platform); return devm_snd_soc_register_platform(dev, &samsung_asoc_platform);
} }
EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
void samsung_asoc_dma_platform_unregister(struct device *dev)
{
snd_soc_unregister_platform(dev);
}
EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister);
MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>"); MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); MODULE_DESCRIPTION("Samsung ASoC DMA Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -33,6 +33,5 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai, ...@@ -33,6 +33,5 @@ void samsung_asoc_init_dma_data(struct snd_soc_dai *dai,
struct s3c_dma_params *playback, struct s3c_dma_params *playback,
struct s3c_dma_params *capture); struct s3c_dma_params *capture);
int samsung_asoc_dma_platform_register(struct device *dev); int samsung_asoc_dma_platform_register(struct device *dev);
void samsung_asoc_dma_platform_unregister(struct device *dev);
#endif #endif
...@@ -66,18 +66,13 @@ EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data); ...@@ -66,18 +66,13 @@ EXPORT_SYMBOL_GPL(samsung_asoc_init_dma_data);
int samsung_asoc_dma_platform_register(struct device *dev) int samsung_asoc_dma_platform_register(struct device *dev)
{ {
return snd_dmaengine_pcm_register(dev, &samsung_dmaengine_pcm_config, return devm_snd_dmaengine_pcm_register(dev,
SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME | &samsung_dmaengine_pcm_config,
SND_DMAENGINE_PCM_FLAG_COMPAT); SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME |
SND_DMAENGINE_PCM_FLAG_COMPAT);
} }
EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register); EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_register);
void samsung_asoc_dma_platform_unregister(struct device *dev)
{
return snd_dmaengine_pcm_unregister(dev);
}
EXPORT_SYMBOL_GPL(samsung_asoc_dma_platform_unregister);
MODULE_AUTHOR("Mark Brown <broonie@linaro.org>"); MODULE_AUTHOR("Mark Brown <broonie@linaro.org>");
MODULE_DESCRIPTION("Samsung dmaengine ASoC driver"); MODULE_DESCRIPTION("Samsung dmaengine ASoC driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -274,8 +274,8 @@ static int __init goni_init(void) ...@@ -274,8 +274,8 @@ static int __init goni_init(void)
return -ENOMEM; return -ENOMEM;
/* register voice DAI here */ /* register voice DAI here */
ret = snd_soc_register_component(&goni_snd_device->dev, &voice_component, ret = devm_snd_soc_register_component(&goni_snd_device->dev,
&voice_dai, 1); &voice_component, &voice_dai, 1);
if (ret) { if (ret) {
platform_device_put(goni_snd_device); platform_device_put(goni_snd_device);
return ret; return ret;
...@@ -284,17 +284,14 @@ static int __init goni_init(void) ...@@ -284,17 +284,14 @@ static int __init goni_init(void)
platform_set_drvdata(goni_snd_device, &goni); platform_set_drvdata(goni_snd_device, &goni);
ret = platform_device_add(goni_snd_device); ret = platform_device_add(goni_snd_device);
if (ret) { if (ret)
snd_soc_unregister_component(&goni_snd_device->dev);
platform_device_put(goni_snd_device); platform_device_put(goni_snd_device);
}
return ret; return ret;
} }
static void __exit goni_exit(void) static void __exit goni_exit(void)
{ {
snd_soc_unregister_component(&goni_snd_device->dev);
platform_device_unregister(goni_snd_device); platform_device_unregister(goni_snd_device);
} }
......
...@@ -451,6 +451,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, ...@@ -451,6 +451,10 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai,
u32 mod = readl(i2s->addr + I2SMOD); u32 mod = readl(i2s->addr + I2SMOD);
switch (clk_id) { switch (clk_id) {
case SAMSUNG_I2S_OPCLK:
mod &= ~MOD_OPCLK_MASK;
mod |= dir;
break;
case SAMSUNG_I2S_CDCLK: case SAMSUNG_I2S_CDCLK:
/* Shouldn't matter in GATING(CLOCK_IN) mode */ /* Shouldn't matter in GATING(CLOCK_IN) mode */
if (dir == SND_SOC_CLOCK_IN) if (dir == SND_SOC_CLOCK_IN)
...@@ -724,9 +728,6 @@ static int i2s_startup(struct snd_pcm_substream *substream, ...@@ -724,9 +728,6 @@ static int i2s_startup(struct snd_pcm_substream *substream,
else else
i2s->mode |= DAI_MANAGER; i2s->mode |= DAI_MANAGER;
/* Enforce set_sysclk in Master mode */
i2s->rclk_srcrate = 0;
if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR)) if (!any_active(i2s) && (i2s->quirks & QUIRK_NEED_RSTCLR))
writel(CON_RSTCLR, i2s->addr + I2SCON); writel(CON_RSTCLR, i2s->addr + I2SCON);
...@@ -984,6 +985,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) ...@@ -984,6 +985,7 @@ static int samsung_i2s_dai_probe(struct snd_soc_dai *dai)
/* Reset any constraint on RFS and BFS */ /* Reset any constraint on RFS and BFS */
i2s->rfs = 0; i2s->rfs = 0;
i2s->bfs = 0; i2s->bfs = 0;
i2s->rclk_srcrate = 0;
i2s_txctrl(i2s, 0); i2s_txctrl(i2s, 0);
i2s_rxctrl(i2s, 0); i2s_rxctrl(i2s, 0);
i2s_fifo(i2s, FIC_TXFLUSH); i2s_fifo(i2s, FIC_TXFLUSH);
...@@ -1293,8 +1295,6 @@ static int samsung_i2s_remove(struct platform_device *pdev) ...@@ -1293,8 +1295,6 @@ static int samsung_i2s_remove(struct platform_device *pdev)
i2s->pri_dai = NULL; i2s->pri_dai = NULL;
i2s->sec_dai = NULL; i2s->sec_dai = NULL;
samsung_asoc_dma_platform_unregister(&pdev->dev);
return 0; return 0;
} }
......
...@@ -18,5 +18,6 @@ ...@@ -18,5 +18,6 @@
#define SAMSUNG_I2S_RCLKSRC_0 0 #define SAMSUNG_I2S_RCLKSRC_0 0
#define SAMSUNG_I2S_RCLKSRC_1 1 #define SAMSUNG_I2S_RCLKSRC_1 1
#define SAMSUNG_I2S_CDCLK 2 #define SAMSUNG_I2S_CDCLK 2
#define SAMSUNG_I2S_OPCLK 3
#endif /* __SND_SOC_SAMSUNG_I2S_H */ #endif /* __SND_SOC_SAMSUNG_I2S_H */
...@@ -274,7 +274,7 @@ static irqreturn_t iis_irq(int irqno, void *dev_id) ...@@ -274,7 +274,7 @@ static irqreturn_t iis_irq(int irqno, void *dev_id)
addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr; addr = readl(idma.regs + I2SLVL0ADDR) - idma.lp_tx_addr;
addr += prtd->periodsz; addr += prtd->periodsz;
addr %= (prtd->end - prtd->start); addr %= (u32)(prtd->end - prtd->start);
addr += idma.lp_tx_addr; addr += idma.lp_tx_addr;
writel(addr, idma.regs + I2SLVL0ADDR); writel(addr, idma.regs + I2SLVL0ADDR);
...@@ -413,13 +413,7 @@ static int asoc_idma_platform_probe(struct platform_device *pdev) ...@@ -413,13 +413,7 @@ static int asoc_idma_platform_probe(struct platform_device *pdev)
if (idma_irq < 0) if (idma_irq < 0)
return idma_irq; return idma_irq;
return snd_soc_register_platform(&pdev->dev, &asoc_idma_platform); return devm_snd_soc_register_platform(&pdev->dev, &asoc_idma_platform);
}
static int asoc_idma_platform_remove(struct platform_device *pdev)
{
snd_soc_unregister_platform(&pdev->dev);
return 0;
} }
static struct platform_driver asoc_idma_driver = { static struct platform_driver asoc_idma_driver = {
...@@ -429,7 +423,6 @@ static struct platform_driver asoc_idma_driver = { ...@@ -429,7 +423,6 @@ static struct platform_driver asoc_idma_driver = {
}, },
.probe = asoc_idma_platform_probe, .probe = asoc_idma_platform_probe,
.remove = asoc_idma_platform_remove,
}; };
module_platform_driver(asoc_idma_driver); module_platform_driver(asoc_idma_driver);
......
...@@ -304,23 +304,12 @@ static int littlemill_probe(struct platform_device *pdev) ...@@ -304,23 +304,12 @@ static int littlemill_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(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", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret;
}
return 0;
}
static int littlemill_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card); return ret;
return 0;
} }
static struct platform_driver littlemill_driver = { static struct platform_driver littlemill_driver = {
...@@ -330,7 +319,6 @@ static struct platform_driver littlemill_driver = { ...@@ -330,7 +319,6 @@ static struct platform_driver littlemill_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = littlemill_probe, .probe = littlemill_probe,
.remove = littlemill_remove,
}; };
module_platform_driver(littlemill_driver); module_platform_driver(littlemill_driver);
......
...@@ -187,23 +187,12 @@ static int lowland_probe(struct platform_device *pdev) ...@@ -187,23 +187,12 @@ static int lowland_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(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", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret;
}
return 0;
}
static int lowland_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card); return ret;
return 0;
} }
static struct platform_driver lowland_driver = { static struct platform_driver lowland_driver = {
...@@ -213,7 +202,6 @@ static struct platform_driver lowland_driver = { ...@@ -213,7 +202,6 @@ static struct platform_driver lowland_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = lowland_probe, .probe = lowland_probe,
.remove = lowland_remove,
}; };
module_platform_driver(lowland_driver); module_platform_driver(lowland_driver);
......
...@@ -271,15 +271,8 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = { ...@@ -271,15 +271,8 @@ static const struct snd_kcontrol_new neo1973_wm8753_controls[] = {
static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd)
{ {
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_card *card = rtd->card; struct snd_soc_card *card = rtd->card;
/* set up NC codec pins */
snd_soc_dapm_nc_pin(&codec->dapm, "OUT3");
snd_soc_dapm_nc_pin(&codec->dapm, "OUT4");
snd_soc_dapm_nc_pin(&codec->dapm, "LINE1");
snd_soc_dapm_nc_pin(&codec->dapm, "LINE2");
/* set endpoints to default off mode */ /* set endpoints to default off mode */
snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out"); snd_soc_dapm_disable_pin(&card->dapm, "GSM Line Out");
snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In"); snd_soc_dapm_disable_pin(&card->dapm, "GSM Line In");
...@@ -355,6 +348,7 @@ static struct snd_soc_card neo1973 = { ...@@ -355,6 +348,7 @@ static struct snd_soc_card neo1973 = {
.num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets), .num_dapm_widgets = ARRAY_SIZE(neo1973_wm8753_dapm_widgets),
.dapm_routes = neo1973_wm8753_routes, .dapm_routes = neo1973_wm8753_routes,
.num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes), .num_dapm_routes = ARRAY_SIZE(neo1973_wm8753_routes),
.fully_routed = true,
}; };
static struct platform_device *neo1973_snd_device; static struct platform_device *neo1973_snd_device;
......
...@@ -542,7 +542,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) ...@@ -542,7 +542,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
/* Default is 128fs */ /* Default is 128fs */
pcm->sclk_per_fs = 128; pcm->sclk_per_fs = 128;
pcm->cclk = clk_get(&pdev->dev, "audio-bus"); pcm->cclk = devm_clk_get(&pdev->dev, "audio-bus");
if (IS_ERR(pcm->cclk)) { if (IS_ERR(pcm->cclk)) {
dev_err(&pdev->dev, "failed to get audio-bus\n"); dev_err(&pdev->dev, "failed to get audio-bus\n");
ret = PTR_ERR(pcm->cclk); ret = PTR_ERR(pcm->cclk);
...@@ -567,7 +567,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) ...@@ -567,7 +567,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
goto err3; goto err3;
} }
pcm->pclk = clk_get(&pdev->dev, "pcm"); pcm->pclk = devm_clk_get(&pdev->dev, "pcm");
if (IS_ERR(pcm->pclk)) { if (IS_ERR(pcm->pclk)) {
dev_err(&pdev->dev, "failed to get pcm_clock\n"); dev_err(&pdev->dev, "failed to get pcm_clock\n");
ret = -ENOENT; ret = -ENOENT;
...@@ -588,7 +588,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) ...@@ -588,7 +588,7 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev); pm_runtime_enable(&pdev->dev);
ret = snd_soc_register_component(&pdev->dev, &s3c_pcm_component, ret = devm_snd_soc_register_component(&pdev->dev, &s3c_pcm_component,
&s3c_pcm_dai[pdev->id], 1); &s3c_pcm_dai[pdev->id], 1);
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret); dev_err(&pdev->dev, "failed to get register DAI: %d\n", ret);
...@@ -598,23 +598,19 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev) ...@@ -598,23 +598,19 @@ static int s3c_pcm_dev_probe(struct platform_device *pdev)
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret); dev_err(&pdev->dev, "failed to get register DMA: %d\n", ret);
goto err6; goto err5;
} }
return 0; return 0;
err6:
snd_soc_unregister_component(&pdev->dev);
err5: err5:
clk_disable_unprepare(pcm->pclk); clk_disable_unprepare(pcm->pclk);
clk_put(pcm->pclk);
err4: err4:
iounmap(pcm->regs); iounmap(pcm->regs);
err3: err3:
release_mem_region(mem_res->start, resource_size(mem_res)); release_mem_region(mem_res->start, resource_size(mem_res));
err2: err2:
clk_disable_unprepare(pcm->cclk); clk_disable_unprepare(pcm->cclk);
clk_put(pcm->cclk);
err1: err1:
return ret; return ret;
} }
...@@ -624,9 +620,6 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev) ...@@ -624,9 +620,6 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev)
struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id];
struct resource *mem_res; struct resource *mem_res;
samsung_asoc_dma_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
iounmap(pcm->regs); iounmap(pcm->regs);
...@@ -636,8 +629,6 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev) ...@@ -636,8 +629,6 @@ static int s3c_pcm_dev_remove(struct platform_device *pdev)
clk_disable_unprepare(pcm->cclk); clk_disable_unprepare(pcm->cclk);
clk_disable_unprepare(pcm->pclk); clk_disable_unprepare(pcm->pclk);
clk_put(pcm->pclk);
clk_put(pcm->cclk);
return 0; return 0;
} }
......
...@@ -745,7 +745,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id, ...@@ -745,7 +745,7 @@ int s3c_i2sv2_register_component(struct device *dev, int id,
dai_drv->suspend = s3c2412_i2s_suspend; dai_drv->suspend = s3c2412_i2s_suspend;
dai_drv->resume = s3c2412_i2s_resume; dai_drv->resume = s3c2412_i2s_resume;
return snd_soc_register_component(dev, cmp_drv, dai_drv, 1); return devm_snd_soc_register_component(dev, cmp_drv, dai_drv, 1);
} }
EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component); EXPORT_SYMBOL_GPL(s3c_i2sv2_register_component);
......
...@@ -179,27 +179,14 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev) ...@@ -179,27 +179,14 @@ static int s3c2412_iis_dev_probe(struct platform_device *pdev)
} }
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev);
if (ret) { if (ret)
pr_err("failed to register the DMA: %d\n", ret); pr_err("failed to register the DMA: %d\n", ret);
goto err;
}
return 0;
err:
snd_soc_unregister_component(&pdev->dev);
return ret; return ret;
} }
static int s3c2412_iis_dev_remove(struct platform_device *pdev)
{
samsung_asoc_dma_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
return 0;
}
static struct platform_driver s3c2412_iis_driver = { static struct platform_driver s3c2412_iis_driver = {
.probe = s3c2412_iis_dev_probe, .probe = s3c2412_iis_dev_probe,
.remove = s3c2412_iis_dev_remove,
.driver = { .driver = {
.name = "s3c2412-iis", .name = "s3c2412-iis",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -475,35 +475,22 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev) ...@@ -475,35 +475,22 @@ static int s3c24xx_iis_dev_probe(struct platform_device *pdev)
{ {
int ret = 0; int ret = 0;
ret = snd_soc_register_component(&pdev->dev, &s3c24xx_i2s_component, ret = devm_snd_soc_register_component(&pdev->dev,
&s3c24xx_i2s_dai, 1); &s3c24xx_i2s_component, &s3c24xx_i2s_dai, 1);
if (ret) { if (ret) {
pr_err("failed to register the dai\n"); pr_err("failed to register the dai\n");
return ret; return ret;
} }
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev);
if (ret) { if (ret)
pr_err("failed to register the dma: %d\n", ret); pr_err("failed to register the dma: %d\n", ret);
goto err;
}
return 0;
err:
snd_soc_unregister_component(&pdev->dev);
return ret; return ret;
} }
static int s3c24xx_iis_dev_remove(struct platform_device *pdev)
{
samsung_asoc_dma_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
return 0;
}
static struct platform_driver s3c24xx_iis_driver = { static struct platform_driver s3c24xx_iis_driver = {
.probe = s3c24xx_iis_dev_probe, .probe = s3c24xx_iis_dev_probe,
.remove = s3c24xx_iis_dev_remove,
.driver = { .driver = {
.name = "s3c24xx-iis", .name = "s3c24xx-iis",
.owner = THIS_MODULE, .owner = THIS_MODULE,
......
...@@ -164,19 +164,11 @@ static int snd_smdk_probe(struct platform_device *pdev) ...@@ -164,19 +164,11 @@ static int snd_smdk_probe(struct platform_device *pdev)
xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE; xtal_freq = mclk_freq = SMDK_WM8580_EXT_VOICE;
smdk_pcm.dev = &pdev->dev; smdk_pcm.dev = &pdev->dev;
ret = snd_soc_register_card(&smdk_pcm); ret = devm_snd_soc_register_card(&pdev->dev, &smdk_pcm);
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);
return ret;
}
return 0; return ret;
}
static int snd_smdk_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&smdk_pcm);
return 0;
} }
static struct platform_driver snd_smdk_driver = { static struct platform_driver snd_smdk_driver = {
...@@ -185,7 +177,6 @@ static struct platform_driver snd_smdk_driver = { ...@@ -185,7 +177,6 @@ static struct platform_driver snd_smdk_driver = {
.name = "samsung-smdk-pcm", .name = "samsung-smdk-pcm",
}, },
.probe = snd_smdk_probe, .probe = snd_smdk_probe,
.remove = snd_smdk_remove,
}; };
module_platform_driver(snd_smdk_driver); module_platform_driver(snd_smdk_driver);
......
...@@ -134,19 +134,11 @@ static int snd_smdk_probe(struct platform_device *pdev) ...@@ -134,19 +134,11 @@ static int snd_smdk_probe(struct platform_device *pdev)
int ret = 0; int ret = 0;
smdk_pcm.dev = &pdev->dev; smdk_pcm.dev = &pdev->dev;
ret = snd_soc_register_card(&smdk_pcm); ret = devm_snd_soc_register_card(&pdev->dev, &smdk_pcm);
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);
return ret;
}
return 0; return ret;
}
static int snd_smdk_remove(struct platform_device *pdev)
{
snd_soc_unregister_card(&smdk_pcm);
return 0;
} }
static struct platform_driver snd_smdk_driver = { static struct platform_driver snd_smdk_driver = {
...@@ -155,7 +147,6 @@ static struct platform_driver snd_smdk_driver = { ...@@ -155,7 +147,6 @@ static struct platform_driver snd_smdk_driver = {
.name = "samsung-smdk-pcm", .name = "samsung-smdk-pcm",
}, },
.probe = snd_smdk_probe, .probe = snd_smdk_probe,
.remove = snd_smdk_remove,
}; };
module_platform_driver(snd_smdk_driver); module_platform_driver(snd_smdk_driver);
......
/*
* ASoC machine driver for Snow boards
*
* 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.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <sound/soc.h>
#include "i2s.h"
#define FIN_PLL_RATE 24000000
static struct snd_soc_dai_link snow_dai[] = {
{
.name = "Primary",
.stream_name = "Primary",
.codec_dai_name = "HiFi",
.dai_fmt = SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
},
};
static int snow_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;
/* Set the MCLK rate for the codec */
ret = snd_soc_dai_set_sysclk(codec_dai, 0,
FIN_PLL_RATE, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
/* Select I2S Bus clock to set RCLK and BCLK */
ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0,
0, SND_SOC_CLOCK_IN);
if (ret < 0)
return ret;
return 0;
}
static struct snd_soc_card snow_snd = {
.name = "Snow-I2S",
.dai_link = snow_dai,
.num_links = ARRAY_SIZE(snow_dai),
.late_probe = snow_late_probe,
};
static int snow_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &snow_snd;
struct device_node *i2s_node, *codec_node;
int i, ret;
i2s_node = of_parse_phandle(pdev->dev.of_node,
"samsung,i2s-controller", 0);
if (!i2s_node) {
dev_err(&pdev->dev,
"Property 'i2s-controller' missing or invalid\n");
return -EINVAL;
}
codec_node = of_parse_phandle(pdev->dev.of_node,
"samsung,audio-codec", 0);
if (!codec_node) {
dev_err(&pdev->dev,
"Property 'audio-codec' missing or invalid\n");
return -EINVAL;
}
for (i = 0; i < ARRAY_SIZE(snow_dai); i++) {
snow_dai[i].codec_of_node = codec_node;
snow_dai[i].cpu_of_node = i2s_node;
snow_dai[i].platform_of_node = i2s_node;
}
card->dev = &pdev->dev;
ret = devm_snd_soc_register_card(&pdev->dev, card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n", ret);
return ret;
}
return ret;
}
static const struct of_device_id snow_of_match[] = {
{ .compatible = "google,snow-audio-max98090", },
{ .compatible = "google,snow-audio-max98095", },
{},
};
static struct platform_driver snow_driver = {
.driver = {
.name = "snow-audio",
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
.of_match_table = snow_of_match,
},
.probe = snow_probe,
};
module_platform_driver(snow_driver);
MODULE_DESCRIPTION("ALSA SoC Audio machine driver for Snow");
MODULE_LICENSE("GPL");
...@@ -427,8 +427,8 @@ static int spdif_probe(struct platform_device *pdev) ...@@ -427,8 +427,8 @@ static int spdif_probe(struct platform_device *pdev)
dev_set_drvdata(&pdev->dev, spdif); dev_set_drvdata(&pdev->dev, spdif);
ret = snd_soc_register_component(&pdev->dev, &samsung_spdif_component, ret = devm_snd_soc_register_component(&pdev->dev,
&samsung_spdif_dai, 1); &samsung_spdif_component, &samsung_spdif_dai, 1);
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "fail to register dai\n"); dev_err(&pdev->dev, "fail to register dai\n");
goto err4; goto err4;
...@@ -444,12 +444,10 @@ static int spdif_probe(struct platform_device *pdev) ...@@ -444,12 +444,10 @@ static int spdif_probe(struct platform_device *pdev)
ret = samsung_asoc_dma_platform_register(&pdev->dev); ret = samsung_asoc_dma_platform_register(&pdev->dev);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to register DMA: %d\n", ret); dev_err(&pdev->dev, "failed to register DMA: %d\n", ret);
goto err5; goto err4;
} }
return 0; return 0;
err5:
snd_soc_unregister_component(&pdev->dev);
err4: err4:
iounmap(spdif->regs); iounmap(spdif->regs);
err3: err3:
...@@ -467,9 +465,6 @@ static int spdif_remove(struct platform_device *pdev) ...@@ -467,9 +465,6 @@ static int spdif_remove(struct platform_device *pdev)
struct samsung_spdif_info *spdif = &spdif_info; struct samsung_spdif_info *spdif = &spdif_info;
struct resource *mem_res; struct resource *mem_res;
samsung_asoc_dma_platform_unregister(&pdev->dev);
snd_soc_unregister_component(&pdev->dev);
iounmap(spdif->regs); iounmap(spdif->regs);
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......
...@@ -327,23 +327,12 @@ static int speyside_probe(struct platform_device *pdev) ...@@ -327,23 +327,12 @@ static int speyside_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(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", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret;
}
return 0;
}
static int speyside_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card); return ret;
return 0;
} }
static struct platform_driver speyside_driver = { static struct platform_driver speyside_driver = {
...@@ -353,7 +342,6 @@ static struct platform_driver speyside_driver = { ...@@ -353,7 +342,6 @@ static struct platform_driver speyside_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = speyside_probe, .probe = speyside_probe,
.remove = speyside_remove,
}; };
module_platform_driver(speyside_driver); module_platform_driver(speyside_driver);
......
...@@ -223,23 +223,12 @@ static int tobermory_probe(struct platform_device *pdev) ...@@ -223,23 +223,12 @@ static int tobermory_probe(struct platform_device *pdev)
card->dev = &pdev->dev; card->dev = &pdev->dev;
ret = snd_soc_register_card(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", dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
ret); ret);
return ret;
}
return 0;
}
static int tobermory_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
snd_soc_unregister_card(card); return ret;
return 0;
} }
static struct platform_driver tobermory_driver = { static struct platform_driver tobermory_driver = {
...@@ -249,7 +238,6 @@ static struct platform_driver tobermory_driver = { ...@@ -249,7 +238,6 @@ static struct platform_driver tobermory_driver = {
.pm = &snd_soc_pm_ops, .pm = &snd_soc_pm_ops,
}, },
.probe = tobermory_probe, .probe = tobermory_probe,
.remove = tobermory_remove,
}; };
module_platform_driver(tobermory_driver); module_platform_driver(tobermory_driver);
......
...@@ -56,7 +56,7 @@ config SND_SH7760_AC97 ...@@ -56,7 +56,7 @@ config SND_SH7760_AC97
config SND_SIU_MIGOR config SND_SIU_MIGOR
tristate "SIU sound support on Migo-R" tristate "SIU sound support on Migo-R"
depends on SH_MIGOR depends on SH_MIGOR && I2C
select SND_SOC_SH4_SIU select SND_SOC_SH4_SIU
select SND_SOC_WM8978 select SND_SOC_WM8978
help help
......
...@@ -6,60 +6,15 @@ ...@@ -6,60 +6,15 @@
* Licensed under GPLv2 or later. * Licensed under GPLv2 or later.
*/ */
#include <linux/module.h> #include <linux/module.h>
#include <linux/io.h>
#include <linux/regmap.h>
#include <sound/soc.h> #include <sound/soc.h>
#include <sound/dmaengine_pcm.h> #include <sound/dmaengine_pcm.h>
#include "sirf-audio-port.h"
struct sirf_audio_port { struct sirf_audio_port {
struct regmap *regmap; struct regmap *regmap;
struct snd_dmaengine_dai_dma_data playback_dma_data; struct snd_dmaengine_dai_dma_data playback_dma_data;
struct snd_dmaengine_dai_dma_data capture_dma_data; struct snd_dmaengine_dai_dma_data capture_dma_data;
}; };
static void sirf_audio_port_tx_enable(struct sirf_audio_port *port)
{
regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP,
AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_INT_MSK, 0);
regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
regmap_update_bits(port->regmap, AUDIO_PORT_IC_TXFIFO_OP,
AUDIO_FIFO_START, AUDIO_FIFO_START);
regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL,
IC_TX_ENABLE, IC_TX_ENABLE);
}
static void sirf_audio_port_tx_disable(struct sirf_audio_port *port)
{
regmap_write(port->regmap, AUDIO_PORT_IC_TXFIFO_OP, 0);
regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_TX_CTRL,
IC_TX_ENABLE, ~IC_TX_ENABLE);
}
static void sirf_audio_port_rx_enable(struct sirf_audio_port *port,
int channels)
{
regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP,
AUDIO_FIFO_RESET, AUDIO_FIFO_RESET);
regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_INT_MSK, 0);
regmap_write(port->regmap, AUDIO_PORT_IC_RXFIFO_OP, 0);
regmap_update_bits(port->regmap, AUDIO_PORT_IC_RXFIFO_OP,
AUDIO_FIFO_START, AUDIO_FIFO_START);
if (channels == 1)
regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
IC_RX_ENABLE_MONO, IC_RX_ENABLE_MONO);
else
regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
IC_RX_ENABLE_STEREO, IC_RX_ENABLE_STEREO);
}
static void sirf_audio_port_rx_disable(struct sirf_audio_port *port)
{
regmap_update_bits(port->regmap, AUDIO_PORT_IC_CODEC_RX_CTRL,
IC_RX_ENABLE_STEREO, ~IC_RX_ENABLE_STEREO);
}
static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
{ {
...@@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai) ...@@ -69,41 +24,6 @@ static int sirf_audio_port_dai_probe(struct snd_soc_dai *dai)
return 0; return 0;
} }
static int sirf_audio_port_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai)
{
struct sirf_audio_port *port = snd_soc_dai_get_drvdata(dai);
int playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
switch (cmd) {
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
if (playback)
sirf_audio_port_tx_disable(port);
else
sirf_audio_port_rx_disable(port);
break;
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (playback)
sirf_audio_port_tx_enable(port);
else
sirf_audio_port_rx_enable(port,
substream->runtime->channels);
break;
default:
return -EINVAL;
}
return 0;
}
static const struct snd_soc_dai_ops sirf_audio_port_dai_ops = {
.trigger = sirf_audio_port_trigger,
};
static struct snd_soc_dai_driver sirf_audio_port_dai = { static struct snd_soc_dai_driver sirf_audio_port_dai = {
.probe = sirf_audio_port_dai_probe, .probe = sirf_audio_port_dai_probe,
.name = "sirf-audio-port", .name = "sirf-audio-port",
...@@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = { ...@@ -120,49 +40,22 @@ static struct snd_soc_dai_driver sirf_audio_port_dai = {
.rates = SNDRV_PCM_RATE_48000, .rates = SNDRV_PCM_RATE_48000,
.formats = SNDRV_PCM_FMTBIT_S16_LE, .formats = SNDRV_PCM_FMTBIT_S16_LE,
}, },
.ops = &sirf_audio_port_dai_ops,
}; };
static const struct snd_soc_component_driver sirf_audio_port_component = { static const struct snd_soc_component_driver sirf_audio_port_component = {
.name = "sirf-audio-port", .name = "sirf-audio-port",
}; };
static const struct regmap_config sirf_audio_port_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = AUDIO_PORT_IC_RXFIFO_INT_MSK,
.cache_type = REGCACHE_NONE,
};
static int sirf_audio_port_probe(struct platform_device *pdev) static int sirf_audio_port_probe(struct platform_device *pdev)
{ {
int ret; int ret;
struct sirf_audio_port *port; struct sirf_audio_port *port;
void __iomem *base;
struct resource *mem_res;
port = devm_kzalloc(&pdev->dev, port = devm_kzalloc(&pdev->dev,
sizeof(struct sirf_audio_port), GFP_KERNEL); sizeof(struct sirf_audio_port), GFP_KERNEL);
if (!port) if (!port)
return -ENOMEM; return -ENOMEM;
mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!mem_res) {
dev_err(&pdev->dev, "no mem resource?\n");
return -ENODEV;
}
base = devm_ioremap(&pdev->dev, mem_res->start,
resource_size(mem_res));
if (base == NULL)
return -ENOMEM;
port->regmap = devm_regmap_init_mmio(&pdev->dev, base,
&sirf_audio_port_regmap_config);
if (IS_ERR(port->regmap))
return PTR_ERR(port->regmap);
ret = devm_snd_soc_register_component(&pdev->dev, ret = devm_snd_soc_register_component(&pdev->dev,
&sirf_audio_port_component, &sirf_audio_port_dai, 1); &sirf_audio_port_component, &sirf_audio_port_dai, 1);
if (ret) if (ret)
......
/*
* SiRF Audio port controllers define
*
* Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
*
* Licensed under GPLv2 or later.
*/
#ifndef _SIRF_AUDIO_PORT_H
#define _SIRF_AUDIO_PORT_H
#define AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK 0x3F
#define AUDIO_PORT_TX_FIFO_SC_OFFSET 0
#define AUDIO_PORT_TX_FIFO_LC_OFFSET 10
#define AUDIO_PORT_TX_FIFO_HC_OFFSET 20
#define TX_FIFO_SC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_TX_FIFO_SC_OFFSET)
#define TX_FIFO_LC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_TX_FIFO_LC_OFFSET)
#define TX_FIFO_HC(x) (((x) & AUDIO_PORT_TX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_TX_FIFO_HC_OFFSET)
#define AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK 0x0F
#define AUDIO_PORT_RX_FIFO_SC_OFFSET 0
#define AUDIO_PORT_RX_FIFO_LC_OFFSET 10
#define AUDIO_PORT_RX_FIFO_HC_OFFSET 20
#define RX_FIFO_SC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_RX_FIFO_SC_OFFSET)
#define RX_FIFO_LC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_RX_FIFO_LC_OFFSET)
#define RX_FIFO_HC(x) (((x) & AUDIO_PORT_RX_FIFO_LEVEL_CHECK_MASK) \
<< AUDIO_PORT_RX_FIFO_HC_OFFSET)
#define AUDIO_PORT_IC_CODEC_TX_CTRL (0x00F4)
#define AUDIO_PORT_IC_CODEC_RX_CTRL (0x00F8)
#define AUDIO_PORT_IC_TXFIFO_OP (0x00FC)
#define AUDIO_PORT_IC_TXFIFO_LEV_CHK (0x0100)
#define AUDIO_PORT_IC_TXFIFO_STS (0x0104)
#define AUDIO_PORT_IC_TXFIFO_INT (0x0108)
#define AUDIO_PORT_IC_TXFIFO_INT_MSK (0x010C)
#define AUDIO_PORT_IC_RXFIFO_OP (0x0110)
#define AUDIO_PORT_IC_RXFIFO_LEV_CHK (0x0114)
#define AUDIO_PORT_IC_RXFIFO_STS (0x0118)
#define AUDIO_PORT_IC_RXFIFO_INT (0x011C)
#define AUDIO_PORT_IC_RXFIFO_INT_MSK (0x0120)
#define AUDIO_FIFO_START (1 << 0)
#define AUDIO_FIFO_RESET (1 << 1)
#define AUDIO_FIFO_FULL (1 << 0)
#define AUDIO_FIFO_EMPTY (1 << 1)
#define AUDIO_FIFO_OFLOW (1 << 2)
#define AUDIO_FIFO_UFLOW (1 << 3)
#define IC_TX_ENABLE (0x03)
#define IC_RX_ENABLE_MONO (0x01)
#define IC_RX_ENABLE_STEREO (0x03)
#endif /*__SIRF_AUDIO_PORT_H*/
...@@ -4613,7 +4613,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card, ...@@ -4613,7 +4613,9 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing); EXPORT_SYMBOL_GPL(snd_soc_of_parse_audio_routing);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np, unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix) const char *prefix,
struct device_node **bitclkmaster,
struct device_node **framemaster)
{ {
int ret, i; int ret, i;
char prop[128]; char prop[128];
...@@ -4696,9 +4698,13 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np, ...@@ -4696,9 +4698,13 @@ unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
*/ */
snprintf(prop, sizeof(prop), "%sbitclock-master", prefix); snprintf(prop, sizeof(prop), "%sbitclock-master", prefix);
bit = !!of_get_property(np, prop, NULL); bit = !!of_get_property(np, prop, NULL);
if (bit && bitclkmaster)
*bitclkmaster = of_parse_phandle(np, prop, 0);
snprintf(prop, sizeof(prop), "%sframe-master", prefix); snprintf(prop, sizeof(prop), "%sframe-master", prefix);
frame = !!of_get_property(np, prop, NULL); frame = !!of_get_property(np, prop, NULL);
if (frame && framemaster)
*framemaster = of_parse_phandle(np, prop, 0);
switch ((bit << 4) + frame) { switch ((bit << 4) + frame) {
case 0x11: case 0x11:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment