Commit a6a21e6b authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'asoc/topic/fsl', 'asoc/topic/fsl-card',...

Merge remote-tracking branches 'asoc/topic/fsl', 'asoc/topic/fsl-card', 'asoc/topic/fsl-dt' and 'asoc/topic/fsl-ssi' into asoc-next
Audio complex for Eukrea boards with tlv320aic23 codec. Audio complex for Eukrea boards with tlv320aic23 codec.
Required properties: Required properties:
- compatible : "eukrea,asoc-tlv320"
- eukrea,model : The user-visible name of this sound complex. - compatible : "eukrea,asoc-tlv320"
- ssi-controller : The phandle of the SSI controller.
- fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX). - eukrea,model : The user-visible name of this sound complex.
- fsl,mux-ext-port : The external port of the i.MX audio muxer.
- ssi-controller : The phandle of the SSI controller.
- fsl,mux-int-port : The internal port of the i.MX audio muxer (AUDMUX).
- fsl,mux-ext-port : The external port of the i.MX audio muxer.
Note: The AUDMUX port numbering should start at 1, which is consistent with Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual. hardware manual.
......
...@@ -7,37 +7,39 @@ other DSPs. It has up to six transmitters and four receivers. ...@@ -7,37 +7,39 @@ other DSPs. It has up to six transmitters and four receivers.
Required properties: Required properties:
- compatible : Compatible list, must contain "fsl,imx35-esai" or - compatible : Compatible list, must contain "fsl,imx35-esai" or
"fsl,vf610-esai" "fsl,vf610-esai"
- reg : Offset and length of the register set for the device. - reg : Offset and length of the register set for the device.
- interrupts : Contains the spdif interrupt. - interrupts : Contains the spdif interrupt.
- dmas : Generic dma devicetree binding as described in - dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt. Documentation/devicetree/bindings/dma/dma.txt.
- dma-names : Two dmas have to be defined, "tx" and "rx". - dma-names : Two dmas have to be defined, "tx" and "rx".
- clocks: Contains an entry for each entry in clock-names. - clocks : Contains an entry for each entry in clock-names.
- clock-names : Includes the following entries: - clock-names : Includes the following entries:
"core" The core clock used to access registers "core" The core clock used to access registers
"extal" The esai baud clock for esai controller used to derive "extal" The esai baud clock for esai controller used to
HCK, SCK and FS. derive HCK, SCK and FS.
"fsys" The system clock derived from ahb clock used to derive "fsys" The system clock derived from ahb clock used to
HCK, SCK and FS. derive HCK, SCK and FS.
- fsl,fifo-depth: The number of elements in the transmit and receive FIFOs. - fsl,fifo-depth : The number of elements in the transmit and receive
This number is the maximum allowed value for TFCR[TFWM] or RFCR[RFWM]. FIFOs. This number is the maximum allowed value for
TFCR[TFWM] or RFCR[RFWM].
- fsl,esai-synchronous: This is a boolean property. If present, indicating - fsl,esai-synchronous: This is a boolean property. If present, indicating
that ESAI would work in the synchronous mode, which means all the settings that ESAI would work in the synchronous mode, which
for Receiving would be duplicated from Transmition related registers. means all the settings for Receiving would be
duplicated from Transmition related registers.
- big-endian : If this property is absent, the native endian mode will - big-endian : If this property is absent, the native endian mode
be in use as default, or the big endian mode will be in use for all the will be in use as default, or the big endian mode
device registers. will be in use for all the device registers.
Example: Example:
......
...@@ -6,32 +6,31 @@ a fibre cable. ...@@ -6,32 +6,31 @@ a fibre cable.
Required properties: Required properties:
- compatible : Compatible list, must contain "fsl,imx35-spdif". - compatible : Compatible list, must contain "fsl,imx35-spdif".
- reg : Offset and length of the register set for the device. - reg : Offset and length of the register set for the device.
- interrupts : Contains the spdif interrupt. - interrupts : Contains the spdif interrupt.
- dmas : Generic dma devicetree binding as described in - dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt. Documentation/devicetree/bindings/dma/dma.txt.
- dma-names : Two dmas have to be defined, "tx" and "rx". - dma-names : Two dmas have to be defined, "tx" and "rx".
- clocks : Contains an entry for each entry in clock-names. - clocks : Contains an entry for each entry in clock-names.
- clock-names : Includes the following entries: - clock-names : Includes the following entries:
"core" The core clock of spdif controller "core" The core clock of spdif controller.
"rxtx<0-7>" Clock source list for tx and rx clock. "rxtx<0-7>" Clock source list for tx and rx clock.
This clock list should be identical to This clock list should be identical to the source
the source list connecting to the spdif list connecting to the spdif clock mux in "SPDIF
clock mux in "SPDIF Transceiver Clock Transceiver Clock Diagram" of SoC reference manual.
Diagram" of SoC reference manual. It It can also be referred to TxClk_Source bit of
can also be referred to TxClk_Source register SPDIF_STC.
bit of register SPDIF_STC.
- big-endian : If this property is absent, the native endian mode will - big-endian : If this property is absent, the native endian mode
be in use as default, or the big endian mode will be in use for all the will be in use as default, or the big endian mode
device registers. will be in use for all the device registers.
Example: Example:
......
...@@ -5,32 +5,48 @@ which provides a synchronous audio interface that supports fullduplex ...@@ -5,32 +5,48 @@ which provides a synchronous audio interface that supports fullduplex
serial interfaces with frame synchronization such as I2S, AC97, TDM, and serial interfaces with frame synchronization such as I2S, AC97, TDM, and
codec/DSP interfaces. codec/DSP interfaces.
Required properties: Required properties:
- compatible: Compatible list, contains "fsl,vf610-sai" or "fsl,imx6sx-sai".
- reg: Offset and length of the register set for the device. - compatible : Compatible list, contains "fsl,vf610-sai" or
- clocks: Must contain an entry for each entry in clock-names. "fsl,imx6sx-sai".
- clock-names : Must include the "bus" for register access and "mclk1" "mclk2"
"mclk3" for bit clock and frame clock providing. - reg : Offset and length of the register set for the device.
- dmas : Generic dma devicetree binding as described in
Documentation/devicetree/bindings/dma/dma.txt. - clocks : Must contain an entry for each entry in clock-names.
- dma-names : Two dmas have to be defined, "tx" and "rx".
- pinctrl-names: Must contain a "default" entry. - clock-names : Must include the "bus" for register access and
- pinctrl-NNN: One property must exist for each entry in pinctrl-names. "mclk1", "mclk2", "mclk3" for bit clock and frame
See ../pinctrl/pinctrl-bindings.txt for details of the property values. clock providing.
- big-endian: Boolean property, required if all the FTM_PWM registers - dmas : Generic dma devicetree binding as described in
are big-endian rather than little-endian. Documentation/devicetree/bindings/dma/dma.txt.
- lsb-first: Configures whether the LSB or the MSB is transmitted first for
the fifo data. If this property is absent, the MSB is transmitted first as - dma-names : Two dmas have to be defined, "tx" and "rx".
default, or the LSB is transmitted first.
- fsl,sai-synchronous-rx: This is a boolean property. If present, indicating - pinctrl-names : Must contain a "default" entry.
that SAI will work in the synchronous mode (sync Tx with Rx) which means
both the transimitter and receiver will send and receive data by following - pinctrl-NNN : One property must exist for each entry in
receiver's bit clocks and frame sync clocks. pinctrl-names. See ../pinctrl/pinctrl-bindings.txt
- fsl,sai-asynchronous: This is a boolean property. If present, indicating for details of the property values.
that SAI will work in the asynchronous mode, which means both transimitter
and receiver will send and receive data by following their own bit clocks - big-endian : Boolean property, required if all the FTM_PWM
and frame sync clocks separately. registers are big-endian rather than little-endian.
- lsb-first : Configures whether the LSB or the MSB is transmitted
first for the fifo data. If this property is absent,
the MSB is transmitted first as default, or the LSB
is transmitted first.
- fsl,sai-synchronous-rx: This is a boolean property. If present, indicating
that SAI will work in the synchronous mode (sync Tx
with Rx) which means both the transimitter and the
receiver will send and receive data by following
receiver's bit clocks and frame sync clocks.
- fsl,sai-asynchronous: This is a boolean property. If present, indicating
that SAI will work in the asynchronous mode, which
means both transimitter and receiver will send and
receive data by following their own bit clocks and
frame sync clocks separately.
Note: Note:
- If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the - If both fsl,sai-asynchronous and fsl,sai-synchronous-rx are absent, the
......
Freescale i.MX audio complex with SGTL5000 codec Freescale i.MX audio complex with SGTL5000 codec
Required properties: Required properties:
- compatible : "fsl,imx-audio-sgtl5000"
- model : The user-visible name of this sound complex - compatible : "fsl,imx-audio-sgtl5000"
- ssi-controller : The phandle of the i.MX SSI controller
- audio-codec : The phandle of the SGTL5000 audio codec - model : The user-visible name of this sound complex
- audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, - ssi-controller : The phandle of the i.MX SSI controller
the second being the connection's source. Valid names could be power
supplies, SGTL5000 pins, and the jacks on the board: - audio-codec : The phandle of the SGTL5000 audio codec
Power supplies: - audio-routing : A list of the connections between audio components.
* Mic Bias Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
SGTL5000 pins: source. Valid names could be power supplies, SGTL5000
* MIC_IN pins, and the jacks on the board:
* LINE_IN
* HP_OUT Power supplies:
* LINE_OUT * Mic Bias
Board connectors: SGTL5000 pins:
* Mic Jack * MIC_IN
* Line In Jack * LINE_IN
* Headphone Jack * HP_OUT
* Line Out Jack * LINE_OUT
* Ext Spk
Board connectors:
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX) * Mic Jack
- mux-ext-port : The external port of the i.MX audio muxer * Line In Jack
* Headphone Jack
* Line Out Jack
* Ext Spk
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
- mux-ext-port : The external port of the i.MX audio muxer
Note: The AUDMUX port numbering should start at 1, which is consistent with Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual. hardware manual.
......
...@@ -2,23 +2,25 @@ Freescale i.MX audio complex with S/PDIF transceiver ...@@ -2,23 +2,25 @@ Freescale i.MX audio complex with S/PDIF transceiver
Required properties: Required properties:
- compatible : "fsl,imx-audio-spdif" - compatible : "fsl,imx-audio-spdif"
- model : The user-visible name of this sound complex - model : The user-visible name of this sound complex
- spdif-controller : The phandle of the i.MX S/PDIF controller - spdif-controller : The phandle of the i.MX S/PDIF controller
Optional properties: Optional properties:
- spdif-out : This is a boolean property. If present, the transmitting - spdif-out : This is a boolean property. If present, the
function of S/PDIF will be enabled, indicating there's a physical transmitting function of S/PDIF will be enabled,
S/PDIF out connector/jack on the board or it's connecting to some indicating there's a physical S/PDIF out connector
other IP block, such as an HDMI encoder/display-controller. or jack on the board or it's connecting to some
other IP block, such as an HDMI encoder or
display-controller.
- spdif-in : This is a boolean property. If present, the receiving - spdif-in : This is a boolean property. If present, the receiving
function of S/PDIF will be enabled, indicating there's a physical function of S/PDIF will be enabled, indicating there
S/PDIF in connector/jack on the board. is a physical S/PDIF in connector/jack on the board.
* Note: At least one of these two properties should be set in the DT binding. * Note: At least one of these two properties should be set in the DT binding.
......
Freescale i.MX audio complex with WM8962 codec Freescale i.MX audio complex with WM8962 codec
Required properties: Required properties:
- compatible : "fsl,imx-audio-wm8962"
- model : The user-visible name of this sound complex - compatible : "fsl,imx-audio-wm8962"
- ssi-controller : The phandle of the i.MX SSI controller
- audio-codec : The phandle of the WM8962 audio codec - model : The user-visible name of this sound complex
- audio-routing : A list of the connections between audio components.
Each entry is a pair of strings, the first being the connection's sink, - ssi-controller : The phandle of the i.MX SSI controller
the second being the connection's source. Valid names could be power
supplies, WM8962 pins, and the jacks on the board: - audio-codec : The phandle of the WM8962 audio codec
Power supplies: - audio-routing : A list of the connections between audio components.
* Mic Bias Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
Board connectors: source. Valid names could be power supplies, WM8962
* Mic Jack pins, and the jacks on the board:
* Headphone Jack
* Ext Spk Power supplies:
* Mic Bias
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
- mux-ext-port : The external port of the i.MX audio muxer Board connectors:
* Mic Jack
* Headphone Jack
* Ext Spk
- mux-int-port : The internal port of the i.MX audio muxer (AUDMUX)
- mux-ext-port : The external port of the i.MX audio muxer
Note: The AUDMUX port numbering should start at 1, which is consistent with Note: The AUDMUX port numbering should start at 1, which is consistent with
hardware manual. hardware manual.
......
Freescale Digital Audio Mux (AUDMUX) device Freescale Digital Audio Mux (AUDMUX) device
Required properties: Required properties:
- compatible : "fsl,imx21-audmux" for AUDMUX version firstly used on i.MX21,
or "fsl,imx31-audmux" for the version firstly used on i.MX31. - compatible : "fsl,imx21-audmux" for AUDMUX version firstly used
- reg : Should contain AUDMUX registers location and length on i.MX21, or "fsl,imx31-audmux" for the version
firstly used on i.MX31.
- reg : Should contain AUDMUX registers location and length.
An initial configuration can be setup using child nodes. An initial configuration can be setup using child nodes.
Required properties of optional child nodes: Required properties of optional child nodes:
- fsl,audmux-port : Integer of the audmux port that is configured by this
child node. - fsl,audmux-port : Integer of the audmux port that is configured by this
- fsl,port-config : List of configuration options for the specific port. For child node.
imx31-audmux and above, it is a list of tuples <ptcr pdcr>. For
imx21-audmux it is a list of pcr values. - fsl,port-config : List of configuration options for the specific port.
For imx31-audmux and above, it is a list of tuples
<ptcr pdcr>. For imx21-audmux it is a list of pcr
values.
Example: Example:
......
...@@ -105,7 +105,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) ...@@ -105,7 +105,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
int ret; int ret;
int int_port = 0, ext_port; int int_port = 0, ext_port;
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct device_node *ssi_np, *codec_np; struct device_node *ssi_np = NULL, *codec_np = NULL;
eukrea_tlv320.dev = &pdev->dev; eukrea_tlv320.dev = &pdev->dev;
if (np) { if (np) {
...@@ -217,8 +217,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev) ...@@ -217,8 +217,7 @@ static int eukrea_tlv320_probe(struct platform_device *pdev)
err: err:
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);
if (np) of_node_put(ssi_np);
of_node_put(ssi_np);
return ret; return ret;
} }
......
...@@ -51,6 +51,7 @@ struct codec_priv { ...@@ -51,6 +51,7 @@ struct codec_priv {
* @sysclk_freq[2]: SYSCLK rates for set_sysclk() * @sysclk_freq[2]: SYSCLK rates for set_sysclk()
* @sysclk_dir[2]: SYSCLK directions for set_sysclk() * @sysclk_dir[2]: SYSCLK directions for set_sysclk()
* @sysclk_id[2]: SYSCLK ids for set_sysclk() * @sysclk_id[2]: SYSCLK ids for set_sysclk()
* @slot_width: Slot width of each frame
* *
* Note: [1] for tx and [0] for rx * Note: [1] for tx and [0] for rx
*/ */
...@@ -58,6 +59,7 @@ struct cpu_priv { ...@@ -58,6 +59,7 @@ struct cpu_priv {
unsigned long sysclk_freq[2]; unsigned long sysclk_freq[2];
u32 sysclk_dir[2]; u32 sysclk_dir[2];
u32 sysclk_id[2]; u32 sysclk_id[2];
u32 slot_width;
}; };
/** /**
...@@ -125,7 +127,12 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, ...@@ -125,7 +127,12 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
priv->sample_rate = params_rate(params); priv->sample_rate = params_rate(params);
priv->sample_format = params_format(params); priv->sample_format = params_format(params);
if (priv->card.set_bias_level) /*
* If codec-dai is DAI Master and all configurations are already in the
* set_bias_level(), bypass the remaining settings in hw_params().
* Note: (dai_fmt & CBM_CFM) includes CBM_CFM and CBM_CFS.
*/
if (priv->card.set_bias_level && priv->dai_fmt & SND_SOC_DAIFMT_CBM_CFM)
return 0; return 0;
/* Specific configurations of DAIs starts from here */ /* Specific configurations of DAIs starts from here */
...@@ -137,6 +144,15 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream, ...@@ -137,6 +144,15 @@ static int fsl_asoc_card_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
if (cpu_priv->slot_width) {
ret = snd_soc_dai_set_tdm_slot(rtd->cpu_dai, 0x3, 0x3, 2,
cpu_priv->slot_width);
if (ret) {
dev_err(dev, "failed to set TDM slot for cpu dai\n");
return ret;
}
}
return 0; return 0;
} }
...@@ -448,6 +464,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev) ...@@ -448,6 +464,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq; priv->cpu_priv.sysclk_freq[RX] = priv->codec_priv.mclk_freq;
priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT; priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT;
priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT; priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
priv->cpu_priv.slot_width = 32;
priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS; priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
} else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) { } else if (of_device_is_compatible(np, "fsl,imx-audio-sgtl5000")) {
priv->codec_priv.mclk_id = SGTL5000_SYSCLK; priv->codec_priv.mclk_id = SGTL5000_SYSCLK;
......
...@@ -67,8 +67,6 @@ ...@@ -67,8 +67,6 @@
/** /**
* FSLSSI_I2S_FORMATS: audio formats supported by the SSI * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
* *
* This driver currently only supports the SSI running in I2S slave mode.
*
* The SSI has a limitation in that the samples must be in the same byte * The SSI has a limitation in that the samples must be in the same byte
* order as the host CPU. This is because when multiple bytes are written * order as the host CPU. This is because when multiple bytes are written
* to the STX register, the bytes and bits must be written in the same * to the STX register, the bytes and bits must be written in the same
...@@ -1363,7 +1361,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ...@@ -1363,7 +1361,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
return PTR_ERR(ssi_private->regs); return PTR_ERR(ssi_private->regs);
} }
ssi_private->irq = irq_of_parse_and_map(np, 0); ssi_private->irq = platform_get_irq(pdev, 0);
if (!ssi_private->irq) { if (!ssi_private->irq) {
dev_err(&pdev->dev, "no irq for node %s\n", np->full_name); dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
return -ENXIO; return -ENXIO;
...@@ -1389,7 +1387,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ...@@ -1389,7 +1387,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
if (ssi_private->soc->imx) { if (ssi_private->soc->imx) {
ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem); ret = fsl_ssi_imx_probe(pdev, ssi_private, iomem);
if (ret) if (ret)
goto error_irqmap; return ret;
} }
ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component, ret = snd_soc_register_component(&pdev->dev, &fsl_ssi_component,
...@@ -1412,7 +1410,7 @@ static int fsl_ssi_probe(struct platform_device *pdev) ...@@ -1412,7 +1410,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev); ret = fsl_ssi_debugfs_create(&ssi_private->dbg_stats, &pdev->dev);
if (ret) if (ret)
goto error_asoc_register; goto error_irq;
/* /*
* If codec-handle property is missing from SSI node, we assume * If codec-handle property is missing from SSI node, we assume
...@@ -1460,10 +1458,6 @@ static int fsl_ssi_probe(struct platform_device *pdev) ...@@ -1460,10 +1458,6 @@ static int fsl_ssi_probe(struct platform_device *pdev)
if (ssi_private->soc->imx) if (ssi_private->soc->imx)
fsl_ssi_imx_clean(pdev, ssi_private); fsl_ssi_imx_clean(pdev, ssi_private);
error_irqmap:
if (ssi_private->use_dma)
irq_dispose_mapping(ssi_private->irq);
return ret; return ret;
} }
...@@ -1480,9 +1474,6 @@ static int fsl_ssi_remove(struct platform_device *pdev) ...@@ -1480,9 +1474,6 @@ static int fsl_ssi_remove(struct platform_device *pdev)
if (ssi_private->soc->imx) if (ssi_private->soc->imx)
fsl_ssi_imx_clean(pdev, ssi_private); fsl_ssi_imx_clean(pdev, ssi_private);
if (ssi_private->use_dma)
irq_dispose_mapping(ssi_private->irq);
return 0; return 0;
} }
......
...@@ -175,10 +175,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev) ...@@ -175,10 +175,8 @@ static int imx_sgtl5000_probe(struct platform_device *pdev)
fail: fail:
if (data && !IS_ERR(data->codec_clk)) if (data && !IS_ERR(data->codec_clk))
clk_put(data->codec_clk); clk_put(data->codec_clk);
if (ssi_np) of_node_put(ssi_np);
of_node_put(ssi_np); of_node_put(codec_np);
if (codec_np)
of_node_put(codec_np);
return ret; return ret;
} }
......
...@@ -74,8 +74,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev) ...@@ -74,8 +74,7 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, data); platform_set_drvdata(pdev, data);
end: end:
if (spdif_np) of_node_put(spdif_np);
of_node_put(spdif_np);
return ret; return ret;
} }
......
...@@ -281,10 +281,8 @@ static int imx_wm8962_probe(struct platform_device *pdev) ...@@ -281,10 +281,8 @@ static int imx_wm8962_probe(struct platform_device *pdev)
clk_fail: clk_fail:
clk_disable_unprepare(data->codec_clk); clk_disable_unprepare(data->codec_clk);
fail: fail:
if (ssi_np) of_node_put(ssi_np);
of_node_put(ssi_np); of_node_put(codec_np);
if (codec_np)
of_node_put(codec_np);
return ret; return ret;
} }
......
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