1 /*
2  * FSI - HDMI sound support
3  *
4  * Copyright (C) 2010 Renesas Solutions Corp.
5  * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
6  *
7  * This file is subject to the terms and conditions of the GNU General Public
8  * License.  See the file "COPYING" in the main directory of this archive
9  * for more details.
10  */
11 
12 #include <linux/platform_device.h>
13 #include <linux/module.h>
14 #include <sound/sh_fsi.h>
15 
16 struct fsi_hdmi_data {
17 	const char *cpu_dai;
18 	const char *card;
19 	int id;
20 };
21 
fsi_hdmi_dai_init(struct snd_soc_pcm_runtime * rtd)22 static int fsi_hdmi_dai_init(struct snd_soc_pcm_runtime *rtd)
23 {
24 	struct snd_soc_dai *cpu = rtd->cpu_dai;
25 	int ret;
26 
27 	ret = snd_soc_dai_set_fmt(cpu, SND_SOC_DAIFMT_CBM_CFM);
28 
29 	return ret;
30 }
31 
32 static struct snd_soc_dai_link fsi_dai_link = {
33 	.name		= "HDMI",
34 	.stream_name	= "HDMI",
35 	.codec_dai_name	= "sh_mobile_hdmi-hifi",
36 	.platform_name	= "sh_fsi2",
37 	.codec_name	= "sh-mobile-hdmi",
38 	.init		= fsi_hdmi_dai_init,
39 };
40 
41 static struct snd_soc_card fsi_soc_card  = {
42 	.owner		= THIS_MODULE,
43 	.dai_link	= &fsi_dai_link,
44 	.num_links	= 1,
45 };
46 
47 static struct platform_device *fsi_snd_device;
48 
fsi_hdmi_probe(struct platform_device * pdev)49 static int fsi_hdmi_probe(struct platform_device *pdev)
50 {
51 	int ret = -ENOMEM;
52 	const struct platform_device_id	*id_entry;
53 	struct fsi_hdmi_data *pdata;
54 
55 	id_entry = pdev->id_entry;
56 	if (!id_entry) {
57 		dev_err(&pdev->dev, "unknown fsi hdmi\n");
58 		return -ENODEV;
59 	}
60 
61 	pdata = (struct fsi_hdmi_data *)id_entry->driver_data;
62 
63 	fsi_snd_device = platform_device_alloc("soc-audio", pdata->id);
64 	if (!fsi_snd_device)
65 		goto out;
66 
67 	fsi_dai_link.cpu_dai_name	= pdata->cpu_dai;
68 	fsi_soc_card.name		= pdata->card;
69 
70 	platform_set_drvdata(fsi_snd_device, &fsi_soc_card);
71 	ret = platform_device_add(fsi_snd_device);
72 
73 	if (ret)
74 		platform_device_put(fsi_snd_device);
75 
76 out:
77 	return ret;
78 }
79 
fsi_hdmi_remove(struct platform_device * pdev)80 static int fsi_hdmi_remove(struct platform_device *pdev)
81 {
82 	platform_device_unregister(fsi_snd_device);
83 	return 0;
84 }
85 
86 static struct fsi_hdmi_data fsi2_a_hdmi = {
87 	.cpu_dai	= "fsia-dai",
88 	.card		= "FSI2A-HDMI",
89 	.id		= FSI_PORT_A,
90 };
91 
92 static struct fsi_hdmi_data fsi2_b_hdmi = {
93 	.cpu_dai	= "fsib-dai",
94 	.card		= "FSI2B-HDMI",
95 	.id		= FSI_PORT_B,
96 };
97 
98 static struct platform_device_id fsi_id_table[] = {
99 	/* FSI 2 */
100 	{ "sh_fsi2_a_hdmi",	(kernel_ulong_t)&fsi2_a_hdmi },
101 	{ "sh_fsi2_b_hdmi",	(kernel_ulong_t)&fsi2_b_hdmi },
102 	{},
103 };
104 
105 static struct platform_driver fsi_hdmi = {
106 	.driver = {
107 		.name	= "fsi-hdmi-audio",
108 	},
109 	.probe		= fsi_hdmi_probe,
110 	.remove		= fsi_hdmi_remove,
111 	.id_table	= fsi_id_table,
112 };
113 
114 module_platform_driver(fsi_hdmi);
115 
116 MODULE_LICENSE("GPL");
117 MODULE_DESCRIPTION("Generic SH4 FSI-HDMI sound card");
118 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
119