aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2013-01-10 03:34:08 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-01-13 18:27:18 -0500
commit9e7b6d60d880a463b17e4eae0d61c9f9a12f22bb (patch)
tree788a9c9851944719c757344f2c0d55455e16dba5
parentfd974e52dbbdb27910d40d8feea7000f26545683 (diff)
ASoC: fsi: add device tree support
Support for loading the Renesas FSI driver via devicetree. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
-rw-r--r--Documentation/devicetree/bindings/sound/renesas,fsi.txt26
-rw-r--r--sound/soc/sh/fsi.c71
2 files changed, 89 insertions, 8 deletions
diff --git a/Documentation/devicetree/bindings/sound/renesas,fsi.txt b/Documentation/devicetree/bindings/sound/renesas,fsi.txt
new file mode 100644
index 000000000000..c5be003f413e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/renesas,fsi.txt
@@ -0,0 +1,26 @@
1Renesas FSI
2
3Required properties:
4- compatible : "renesas,sh_fsi2" or "renesas,sh_fsi"
5- reg : Should contain the register physical address and length
6- interrupts : Should contain FSI interrupt
7
8- fsia,spdif-connection : FSI is connected by S/PDFI
9- fsia,stream-mode-support : FSI supports 16bit stream mode.
10- fsia,use-internal-clock : FSI uses internal clock when master mode.
11
12- fsib,spdif-connection : same as fsia
13- fsib,stream-mode-support : same as fsia
14- fsib,use-internal-clock : same as fsia
15
16Example:
17
18sh_fsi2: sh_fsi2@0xec230000 {
19 compatible = "renesas,sh_fsi2";
20 reg = <0xec230000 0x400>;
21 interrupts = <0 146 0x4>;
22
23 fsia,spdif-connection;
24 fsia,stream-mode-support;
25 fsia,use-internal-clock;
26};
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index ef34ef8e92ed..91576120cd47 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -16,6 +16,8 @@
16#include <linux/dma-mapping.h> 16#include <linux/dma-mapping.h>
17#include <linux/pm_runtime.h> 17#include <linux/pm_runtime.h>
18#include <linux/io.h> 18#include <linux/io.h>
19#include <linux/of.h>
20#include <linux/of_device.h>
19#include <linux/scatterlist.h> 21#include <linux/scatterlist.h>
20#include <linux/sh_dma.h> 22#include <linux/sh_dma.h>
21#include <linux/slab.h> 23#include <linux/slab.h>
@@ -297,7 +299,7 @@ struct fsi_master {
297 int irq; 299 int irq;
298 struct fsi_priv fsia; 300 struct fsi_priv fsia;
299 struct fsi_priv fsib; 301 struct fsi_priv fsib;
300 struct fsi_core *core; 302 const struct fsi_core *core;
301 spinlock_t lock; 303 spinlock_t lock;
302}; 304};
303 305
@@ -1887,6 +1889,33 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
1887/* 1889/*
1888 * platform function 1890 * platform function
1889 */ 1891 */
1892static void fsi_of_parse(char *name,
1893 struct device_node *np,
1894 struct sh_fsi_port_info *info,
1895 struct device *dev)
1896{
1897 int i;
1898 char prop[128];
1899 unsigned long flags = 0;
1900 struct {
1901 char *name;
1902 unsigned int val;
1903 } of_parse_property[] = {
1904 { "spdif-connection", SH_FSI_FMT_SPDIF },
1905 { "stream-mode-support", SH_FSI_ENABLE_STREAM_MODE },
1906 { "use-internal-clock", SH_FSI_CLK_CPG },
1907 };
1908
1909 for (i = 0; i < ARRAY_SIZE(of_parse_property); i++) {
1910 sprintf(prop, "%s,%s", name, of_parse_property[i].name);
1911 if (of_get_property(np, prop, NULL))
1912 flags |= of_parse_property[i].val;
1913 }
1914 info->flags = flags;
1915
1916 dev_dbg(dev, "%s flags : %lx\n", name, info->flags);
1917}
1918
1890static void fsi_port_info_init(struct fsi_priv *fsi, 1919static void fsi_port_info_init(struct fsi_priv *fsi,
1891 struct sh_fsi_port_info *info) 1920 struct sh_fsi_port_info *info)
1892{ 1921{
@@ -1914,22 +1943,40 @@ static void fsi_handler_init(struct fsi_priv *fsi,
1914 } 1943 }
1915} 1944}
1916 1945
1946static struct of_device_id fsi_of_match[];
1917static int fsi_probe(struct platform_device *pdev) 1947static int fsi_probe(struct platform_device *pdev)
1918{ 1948{
1919 struct fsi_master *master; 1949 struct fsi_master *master;
1920 const struct platform_device_id *id_entry; 1950 struct device_node *np = pdev->dev.of_node;
1921 struct sh_fsi_platform_info info; 1951 struct sh_fsi_platform_info info;
1952 const struct fsi_core *core;
1922 struct fsi_priv *fsi; 1953 struct fsi_priv *fsi;
1923 struct resource *res; 1954 struct resource *res;
1924 unsigned int irq; 1955 unsigned int irq;
1925 int ret; 1956 int ret;
1926 1957
1927 memset(&info, 0, sizeof(info)); 1958 memset(&info, 0, sizeof(info));
1928 if (pdev->dev.platform_data)
1929 memcpy(&info, pdev->dev.platform_data, sizeof(info));
1930 1959
1931 id_entry = pdev->id_entry; 1960 core = NULL;
1932 if (!id_entry) { 1961 if (np) {
1962 const struct of_device_id *of_id;
1963
1964 of_id = of_match_device(fsi_of_match, &pdev->dev);
1965 if (of_id) {
1966 core = of_id->data;
1967 fsi_of_parse("fsia", np, &info.port_a, &pdev->dev);
1968 fsi_of_parse("fsib", np, &info.port_b, &pdev->dev);
1969 }
1970 } else {
1971 const struct platform_device_id *id_entry = pdev->id_entry;
1972 if (id_entry)
1973 core = (struct fsi_core *)id_entry->driver_data;
1974
1975 if (pdev->dev.platform_data)
1976 memcpy(&info, pdev->dev.platform_data, sizeof(info));
1977 }
1978
1979 if (!core) {
1933 dev_err(&pdev->dev, "unknown fsi device\n"); 1980 dev_err(&pdev->dev, "unknown fsi device\n");
1934 return -ENODEV; 1981 return -ENODEV;
1935 } 1982 }
@@ -1956,7 +2003,7 @@ static int fsi_probe(struct platform_device *pdev)
1956 2003
1957 /* master setting */ 2004 /* master setting */
1958 master->irq = irq; 2005 master->irq = irq;
1959 master->core = (struct fsi_core *)id_entry->driver_data; 2006 master->core = core;
1960 spin_lock_init(&master->lock); 2007 spin_lock_init(&master->lock);
1961 2008
1962 /* FSI A setting */ 2009 /* FSI A setting */
@@ -1987,7 +2034,7 @@ static int fsi_probe(struct platform_device *pdev)
1987 dev_set_drvdata(&pdev->dev, master); 2034 dev_set_drvdata(&pdev->dev, master);
1988 2035
1989 ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0, 2036 ret = devm_request_irq(&pdev->dev, irq, &fsi_interrupt, 0,
1990 id_entry->name, master); 2037 dev_name(&pdev->dev), master);
1991 if (ret) { 2038 if (ret) {
1992 dev_err(&pdev->dev, "irq request err\n"); 2039 dev_err(&pdev->dev, "irq request err\n");
1993 goto exit_fsib; 2040 goto exit_fsib;
@@ -2113,6 +2160,13 @@ static struct fsi_core fsi2_core = {
2113 .b_mclk = B_MST_CTLR, 2160 .b_mclk = B_MST_CTLR,
2114}; 2161};
2115 2162
2163static struct of_device_id fsi_of_match[] __devinitconst = {
2164 { .compatible = "renesas,sh_fsi", .data = &fsi1_core},
2165 { .compatible = "renesas,sh_fsi2", .data = &fsi2_core},
2166 {},
2167};
2168MODULE_DEVICE_TABLE(of, fsi_of_match);
2169
2116static struct platform_device_id fsi_id_table[] = { 2170static struct platform_device_id fsi_id_table[] = {
2117 { "sh_fsi", (kernel_ulong_t)&fsi1_core }, 2171 { "sh_fsi", (kernel_ulong_t)&fsi1_core },
2118 { "sh_fsi2", (kernel_ulong_t)&fsi2_core }, 2172 { "sh_fsi2", (kernel_ulong_t)&fsi2_core },
@@ -2124,6 +2178,7 @@ static struct platform_driver fsi_driver = {
2124 .driver = { 2178 .driver = {
2125 .name = "fsi-pcm-audio", 2179 .name = "fsi-pcm-audio",
2126 .pm = &fsi_pm_ops, 2180 .pm = &fsi_pm_ops,
2181 .of_match_table = fsi_of_match,
2127 }, 2182 },
2128 .probe = fsi_probe, 2183 .probe = fsi_probe,
2129 .remove = fsi_remove, 2184 .remove = fsi_remove,