-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'asoc/topic/fsl' into tmp
- Loading branch information
Showing
6 changed files
with
197 additions
and
15 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
Freescale i.MX audio complex with S/PDIF transceiver | ||
|
||
Required properties: | ||
|
||
- compatible : "fsl,imx-audio-spdif" | ||
|
||
- model : The user-visible name of this sound complex | ||
|
||
- spdif-controller : The phandle of the i.MX S/PDIF controller | ||
|
||
|
||
Optional properties: | ||
|
||
- spdif-out : This is a boolean property. If present, the transmitting | ||
function of S/PDIF will be enabled, indicating there's a physical | ||
S/PDIF out connector/jack on the board or it's connecting to some | ||
other IP block, such as an HDMI encoder/display-controller. | ||
|
||
- spdif-in : This is a boolean property. If present, the receiving | ||
function of S/PDIF will be enabled, indicating there's 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. | ||
|
||
|
||
Example: | ||
|
||
sound-spdif { | ||
compatible = "fsl,imx-audio-spdif"; | ||
model = "imx-spdif"; | ||
spdif-controller = <&spdif>; | ||
spdif-out; | ||
spdif-in; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
/* | ||
* Copyright (C) 2013 Freescale Semiconductor, Inc. | ||
* | ||
* The code contained herein is licensed under the GNU General Public | ||
* License. You may obtain a copy of the GNU General Public License | ||
* Version 2 or later at the following locations: | ||
* | ||
* http://www.opensource.org/licenses/gpl-license.html | ||
* http://www.gnu.org/copyleft/gpl.html | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/of_platform.h> | ||
#include <sound/soc.h> | ||
|
||
struct imx_spdif_data { | ||
struct snd_soc_dai_link dai[2]; | ||
struct snd_soc_card card; | ||
struct platform_device *txdev; | ||
struct platform_device *rxdev; | ||
}; | ||
|
||
static int imx_spdif_audio_probe(struct platform_device *pdev) | ||
{ | ||
struct device_node *spdif_np, *np = pdev->dev.of_node; | ||
struct imx_spdif_data *data; | ||
int ret = 0, num_links = 0; | ||
|
||
spdif_np = of_parse_phandle(np, "spdif-controller", 0); | ||
if (!spdif_np) { | ||
dev_err(&pdev->dev, "failed to find spdif-controller\n"); | ||
ret = -EINVAL; | ||
goto end; | ||
} | ||
|
||
data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); | ||
if (!data) { | ||
dev_err(&pdev->dev, "failed to allocate memory\n"); | ||
ret = -ENOMEM; | ||
goto end; | ||
} | ||
|
||
if (of_property_read_bool(np, "spdif-out")) { | ||
data->dai[num_links].name = "S/PDIF TX"; | ||
data->dai[num_links].stream_name = "S/PDIF PCM Playback"; | ||
data->dai[num_links].codec_dai_name = "dit-hifi"; | ||
data->dai[num_links].codec_name = "spdif-dit"; | ||
data->dai[num_links].cpu_of_node = spdif_np; | ||
data->dai[num_links].platform_of_node = spdif_np; | ||
num_links++; | ||
|
||
data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0); | ||
if (IS_ERR(data->txdev)) { | ||
ret = PTR_ERR(data->txdev); | ||
dev_err(&pdev->dev, "register dit failed: %d\n", ret); | ||
goto end; | ||
} | ||
} | ||
|
||
if (of_property_read_bool(np, "spdif-in")) { | ||
data->dai[num_links].name = "S/PDIF RX"; | ||
data->dai[num_links].stream_name = "S/PDIF PCM Capture"; | ||
data->dai[num_links].codec_dai_name = "dir-hifi"; | ||
data->dai[num_links].codec_name = "spdif-dir"; | ||
data->dai[num_links].cpu_of_node = spdif_np; | ||
data->dai[num_links].platform_of_node = spdif_np; | ||
num_links++; | ||
|
||
data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0); | ||
if (IS_ERR(data->rxdev)) { | ||
ret = PTR_ERR(data->rxdev); | ||
dev_err(&pdev->dev, "register dir failed: %d\n", ret); | ||
goto error_dit; | ||
} | ||
} | ||
|
||
if (!num_links) { | ||
dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n"); | ||
goto error_dir; | ||
} | ||
|
||
data->card.dev = &pdev->dev; | ||
data->card.num_links = num_links; | ||
data->card.dai_link = data->dai; | ||
|
||
ret = snd_soc_of_parse_card_name(&data->card, "model"); | ||
if (ret) | ||
goto error_dir; | ||
|
||
ret = snd_soc_register_card(&data->card); | ||
if (ret) { | ||
dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret); | ||
goto error_dir; | ||
} | ||
|
||
platform_set_drvdata(pdev, data); | ||
|
||
goto end; | ||
|
||
error_dir: | ||
if (data->rxdev) | ||
platform_device_unregister(data->rxdev); | ||
error_dit: | ||
if (data->txdev) | ||
platform_device_unregister(data->txdev); | ||
end: | ||
if (spdif_np) | ||
of_node_put(spdif_np); | ||
|
||
return ret; | ||
} | ||
|
||
static int imx_spdif_audio_remove(struct platform_device *pdev) | ||
{ | ||
struct imx_spdif_data *data = platform_get_drvdata(pdev); | ||
|
||
if (data->rxdev) | ||
platform_device_unregister(data->rxdev); | ||
if (data->txdev) | ||
platform_device_unregister(data->txdev); | ||
|
||
snd_soc_unregister_card(&data->card); | ||
|
||
return 0; | ||
} | ||
|
||
static const struct of_device_id imx_spdif_dt_ids[] = { | ||
{ .compatible = "fsl,imx-audio-spdif", }, | ||
{ /* sentinel */ } | ||
}; | ||
MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids); | ||
|
||
static struct platform_driver imx_spdif_driver = { | ||
.driver = { | ||
.name = "imx-spdif", | ||
.owner = THIS_MODULE, | ||
.of_match_table = imx_spdif_dt_ids, | ||
}, | ||
.probe = imx_spdif_audio_probe, | ||
.remove = imx_spdif_audio_remove, | ||
}; | ||
|
||
module_platform_driver(imx_spdif_driver); | ||
|
||
MODULE_AUTHOR("Freescale Semiconductor, Inc."); | ||
MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver"); | ||
MODULE_LICENSE("GPL v2"); | ||
MODULE_ALIAS("platform:imx-spdif"); |