blob: 83b4a22bf15ac0b8883f3144c55f34d5959f6012 [file] [log] [blame]
Andra Danciu6e3398c2019-04-05 14:50:08 +03001// SPDX-License-Identifier: GPL-2.0
2//
3// Phytec pcm030 driver for the PSC of the Freescale MPC52xx
4// configured as AC97 interface
5//
6// Copyright 2008 Jon Smirl, Digispeaker
7// Author: Jon Smirl <jonsmirl@gmail.com>
Jon Smirla9262c42009-05-26 08:34:12 -04008
9#include <linux/init.h>
10#include <linux/module.h>
Jon Smirla9262c42009-05-26 08:34:12 -040011#include <linux/device.h>
Jon Smirla9262c42009-05-26 08:34:12 -040012#include <linux/of_device.h>
13#include <linux/of_platform.h>
Jon Smirla9262c42009-05-26 08:34:12 -040014
Jon Smirla9262c42009-05-26 08:34:12 -040015#include <sound/soc.h>
Jon Smirla9262c42009-05-26 08:34:12 -040016
17#include "mpc5200_dma.h"
Jon Smirla9262c42009-05-26 08:34:12 -040018
Takashi Iwaiafc5e652009-08-07 16:33:53 +020019#define DRV_NAME "pcm030-audio-fabric"
20
Eric Millbrandtc912fa92012-09-20 10:36:45 -040021struct pcm030_audio_data {
22 struct snd_soc_card *card;
23 struct platform_device *codec_device;
24};
25
Kuninori Morimoto61c29312019-06-06 13:16:14 +090026SND_SOC_DAILINK_DEFS(analog,
27 DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.0")),
28 DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-hifi")),
29 DAILINK_COMP_ARRAY(COMP_EMPTY()));
30
31SND_SOC_DAILINK_DEFS(iec958,
32 DAILINK_COMP_ARRAY(COMP_CPU("mpc5200-psc-ac97.1")),
33 DAILINK_COMP_ARRAY(COMP_CODEC("wm9712-codec", "wm9712-aux")),
34 DAILINK_COMP_ARRAY(COMP_EMPTY()));
35
Jon Smirla9262c42009-05-26 08:34:12 -040036static struct snd_soc_dai_link pcm030_fabric_dai[] = {
37{
Eric Millbrandtc73adc72012-10-10 10:10:08 -040038 .name = "AC97.0",
Jon Smirla9262c42009-05-26 08:34:12 -040039 .stream_name = "AC97 Analog",
Kuninori Morimoto61c29312019-06-06 13:16:14 +090040 SND_SOC_DAILINK_REG(analog),
Jon Smirla9262c42009-05-26 08:34:12 -040041},
42{
Eric Millbrandtc73adc72012-10-10 10:10:08 -040043 .name = "AC97.1",
Jon Smirla9262c42009-05-26 08:34:12 -040044 .stream_name = "AC97 IEC958",
Kuninori Morimoto61c29312019-06-06 13:16:14 +090045 SND_SOC_DAILINK_REG(iec958),
Jon Smirla9262c42009-05-26 08:34:12 -040046},
47};
48
Eric Millbrandt08401162012-09-20 10:36:44 -040049static struct snd_soc_card pcm030_card = {
Axel Lin4c3c5df2011-12-22 21:04:54 +080050 .name = "pcm030",
51 .owner = THIS_MODULE,
52 .dai_link = pcm030_fabric_dai,
53 .num_links = ARRAY_SIZE(pcm030_fabric_dai),
54};
55
Markus Pargmann34913fd2013-03-10 19:33:06 +010056static int pcm030_fabric_probe(struct platform_device *op)
Jon Smirla9262c42009-05-26 08:34:12 -040057{
Eric Millbrandt08401162012-09-20 10:36:44 -040058 struct device_node *np = op->dev.of_node;
59 struct device_node *platform_np;
60 struct snd_soc_card *card = &pcm030_card;
Eric Millbrandtc912fa92012-09-20 10:36:45 -040061 struct pcm030_audio_data *pdata;
Kuninori Morimoto7fe072b2018-09-18 01:28:49 +000062 struct snd_soc_dai_link *dai_link;
Eric Millbrandt08401162012-09-20 10:36:44 -040063 int ret;
64 int i;
Jon Smirla9262c42009-05-26 08:34:12 -040065
Grant Likely71a157e2010-02-01 21:34:14 -070066 if (!of_machine_is_compatible("phytec,pcm030"))
Jon Smirla9262c42009-05-26 08:34:12 -040067 return -ENODEV;
68
Eric Millbrandtc912fa92012-09-20 10:36:45 -040069 pdata = devm_kzalloc(&op->dev, sizeof(struct pcm030_audio_data),
70 GFP_KERNEL);
71 if (!pdata)
72 return -ENOMEM;
73
Eric Millbrandt08401162012-09-20 10:36:44 -040074 card->dev = &op->dev;
Eric Millbrandtc912fa92012-09-20 10:36:45 -040075
76 pdata->card = card;
Eric Millbrandt08401162012-09-20 10:36:44 -040077
78 platform_np = of_parse_phandle(np, "asoc-platform", 0);
79 if (!platform_np) {
80 dev_err(&op->dev, "ac97 not registered\n");
Jon Smirla9262c42009-05-26 08:34:12 -040081 return -ENODEV;
82 }
83
Kuninori Morimoto7fe072b2018-09-18 01:28:49 +000084 for_each_card_prelinks(card, i, dai_link)
Kuninori Morimoto61c29312019-06-06 13:16:14 +090085 dai_link->platforms->of_node = platform_np;
Jon Smirla9262c42009-05-26 08:34:12 -040086
Eric Millbrandtc912fa92012-09-20 10:36:45 -040087 ret = request_module("snd-soc-wm9712");
88 if (ret)
89 dev_err(&op->dev, "request_module returned: %d\n", ret);
90
91 pdata->codec_device = platform_device_alloc("wm9712-codec", -1);
92 if (!pdata->codec_device)
93 dev_err(&op->dev, "platform_device_alloc() failed\n");
94
95 ret = platform_device_add(pdata->codec_device);
Miaoqian Linfb256212022-01-27 13:13:34 +000096 if (ret) {
Eric Millbrandtc912fa92012-09-20 10:36:45 -040097 dev_err(&op->dev, "platform_device_add() failed: %d\n", ret);
Miaoqian Linfb256212022-01-27 13:13:34 +000098 platform_device_put(pdata->codec_device);
99 }
Eric Millbrandtc912fa92012-09-20 10:36:45 -0400100
Eric Millbrandt08401162012-09-20 10:36:44 -0400101 ret = snd_soc_register_card(card);
Miaoqian Linfb256212022-01-27 13:13:34 +0000102 if (ret) {
Eric Millbrandt08401162012-09-20 10:36:44 -0400103 dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
Miaoqian Linfb256212022-01-27 13:13:34 +0000104 platform_device_del(pdata->codec_device);
105 platform_device_put(pdata->codec_device);
106 }
Eric Millbrandt08401162012-09-20 10:36:44 -0400107
Wei Yongjun6c7ef412013-11-09 08:41:14 +0800108 platform_set_drvdata(op, pdata);
Eric Millbrandt08401162012-09-20 10:36:44 -0400109 return ret;
Miaoqian Linfb256212022-01-27 13:13:34 +0000110
Jon Smirla9262c42009-05-26 08:34:12 -0400111}
112
Bill Pembertona0a3d512012-12-07 09:26:16 -0500113static int pcm030_fabric_remove(struct platform_device *op)
Eric Millbrandt08401162012-09-20 10:36:44 -0400114{
Eric Millbrandtc912fa92012-09-20 10:36:45 -0400115 struct pcm030_audio_data *pdata = platform_get_drvdata(op);
Eric Millbrandt08401162012-09-20 10:36:44 -0400116 int ret;
117
Eric Millbrandtc912fa92012-09-20 10:36:45 -0400118 ret = snd_soc_unregister_card(pdata->card);
119 platform_device_unregister(pdata->codec_device);
Eric Millbrandt08401162012-09-20 10:36:44 -0400120
121 return ret;
122}
123
Fabian Frederick6ffa84d2015-03-18 17:48:57 +0100124static const struct of_device_id pcm030_audio_match[] = {
Eric Millbrandt08401162012-09-20 10:36:44 -0400125 { .compatible = "phytec,pcm030-audio-fabric", },
126 {}
127};
128MODULE_DEVICE_TABLE(of, pcm030_audio_match);
129
130static struct platform_driver pcm030_fabric_driver = {
131 .probe = pcm030_fabric_probe,
Bill Pembertona0a3d512012-12-07 09:26:16 -0500132 .remove = pcm030_fabric_remove,
Eric Millbrandt08401162012-09-20 10:36:44 -0400133 .driver = {
134 .name = DRV_NAME,
Eric Millbrandt08401162012-09-20 10:36:44 -0400135 .of_match_table = pcm030_audio_match,
136 },
137};
138
139module_platform_driver(pcm030_fabric_driver);
Jon Smirla9262c42009-05-26 08:34:12 -0400140
141
142MODULE_AUTHOR("Jon Smirl <jonsmirl@gmail.com>");
143MODULE_DESCRIPTION(DRV_NAME ": mpc5200 pcm030 fabric driver");
144MODULE_LICENSE("GPL");
145