ARM: imx: convert audmux to a platform driver
authorRichard Zhao <richard.zhao@linaro.org>
Mon, 5 Mar 2012 14:30:52 +0000 (22:30 +0800)
committerMark Brown <broonie@opensource.wolfsonmicro.com>
Tue, 6 Mar 2012 00:02:55 +0000 (00:02 +0000)
It coverts audmux to a platform driver, so that it can be moved into
sound/soc/imx and adopt device tree support later.

Signed-off-by: Richard Zhao <richard.zhao@linaro.org>
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
arch/arm/mach-imx/mm-imx21.c
arch/arm/mach-imx/mm-imx25.c
arch/arm/mach-imx/mm-imx27.c
arch/arm/mach-imx/mm-imx3.c
arch/arm/mach-imx/mm-imx5.c
arch/arm/plat-mxc/audmux.c

index 3f05dfebacc9f7c2bb7df18c0646b7a775100097..14d540edfd1e6d9817ecf0f624de8d710b6dfa4d 100644 (file)
@@ -75,6 +75,10 @@ void __init mx21_init_irq(void)
        mxc_init_irq(MX21_IO_ADDRESS(MX21_AVIC_BASE_ADDR));
 }
 
+static const struct resource imx21_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX21_AUDMUX_BASE_ADDR, SZ_4K),
+};
+
 void __init imx21_soc_init(void)
 {
        mxc_register_gpio("imx21-gpio", 0, MX21_GPIO1_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
@@ -85,4 +89,6 @@ void __init imx21_soc_init(void)
        mxc_register_gpio("imx21-gpio", 5, MX21_GPIO6_BASE_ADDR, SZ_256, MX21_INT_GPIO, 0);
 
        imx_add_imx_dma();
+       platform_device_register_simple("imx21-audmux", 0, imx21_audmux_res,
+                                       ARRAY_SIZE(imx21_audmux_res));
 }
index cc4d152bd9bd9342d1c0ff53e6b9cfd0a52c9a90..153b457acdc02db153b520540093860dd768df14 100644 (file)
@@ -83,6 +83,10 @@ static struct sdma_platform_data imx25_sdma_pdata __initdata = {
        .script_addrs = &imx25_sdma_script,
 };
 
+static const struct resource imx25_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX25_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx25_soc_init(void)
 {
        /* i.mx25 has the i.mx31 type gpio */
@@ -93,4 +97,7 @@ void __init imx25_soc_init(void)
 
        /* i.mx25 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX25_SDMA_BASE_ADDR, MX25_INT_SDMA, &imx25_sdma_pdata);
+       /* i.mx25 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx25_audmux_res,
+                                       ARRAY_SIZE(imx25_audmux_res));
 }
index 96dd1f5ea7bddc32d8745b7447b56cf20402640e..8cb3f5e3e56901b04228408407f2d7ecb34bee7d 100644 (file)
@@ -75,6 +75,10 @@ void __init mx27_init_irq(void)
        mxc_init_irq(MX27_IO_ADDRESS(MX27_AVIC_BASE_ADDR));
 }
 
+static const struct resource imx27_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX27_AUDMUX_BASE_ADDR, SZ_4K),
+};
+
 void __init imx27_soc_init(void)
 {
        /* i.mx27 has the i.mx21 type gpio */
@@ -86,4 +90,7 @@ void __init imx27_soc_init(void)
        mxc_register_gpio("imx21-gpio", 5, MX27_GPIO6_BASE_ADDR, SZ_256, MX27_INT_GPIO, 0);
 
        imx_add_imx_dma();
+       /* imx27 has the imx21 type audmux */
+       platform_device_register_simple("imx21-audmux", 0, imx27_audmux_res,
+                                       ARRAY_SIZE(imx27_audmux_res));
 }
index 31807d2a8b7bf1a65d57c8f4cb748bb9e6697934..2530c151b7b3d5aa50a1731c9ceaf1a3cc949ab8 100644 (file)
@@ -158,6 +158,10 @@ static struct sdma_platform_data imx31_sdma_pdata __initdata = {
        .script_addrs = &imx31_to2_sdma_script,
 };
 
+static const struct resource imx31_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX31_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx31_soc_init(void)
 {
        int to_version = mx31_revision() >> 4;
@@ -175,6 +179,8 @@ void __init imx31_soc_init(void)
        }
 
        imx_add_imx_sdma("imx31-sdma", MX31_SDMA_BASE_ADDR, MX31_INT_SDMA, &imx31_sdma_pdata);
+       platform_device_register_simple("imx31-audmux", 0, imx31_audmux_res,
+                                       ARRAY_SIZE(imx31_audmux_res));
 }
 #endif /* ifdef CONFIG_SOC_IMX31 */
 
@@ -241,6 +247,10 @@ static struct sdma_platform_data imx35_sdma_pdata __initdata = {
        .script_addrs = &imx35_to2_sdma_script,
 };
 
+static const struct resource imx35_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX35_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx35_soc_init(void)
 {
        int to_version = mx35_revision() >> 4;
@@ -259,5 +269,8 @@ void __init imx35_soc_init(void)
        }
 
        imx_add_imx_sdma("imx35-sdma", MX35_SDMA_BASE_ADDR, MX35_INT_SDMA, &imx35_sdma_pdata);
+       /* i.mx35 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx35_audmux_res,
+                                       ARRAY_SIZE(imx35_audmux_res));
 }
 #endif /* ifdef CONFIG_SOC_IMX35 */
index bc17dfea38170872c24216165715e8af60144feb..90d7880bb372a95a7ae5b0f57f897311215dbaf8 100644 (file)
@@ -170,6 +170,18 @@ static struct sdma_platform_data imx53_sdma_pdata __initdata = {
        .script_addrs = &imx53_sdma_script,
 };
 
+static const struct resource imx50_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX50_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
+static const struct resource imx51_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX51_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
+static const struct resource imx53_audmux_res[] __initconst = {
+       DEFINE_RES_MEM(MX53_AUDMUX_BASE_ADDR, SZ_16K),
+};
+
 void __init imx50_soc_init(void)
 {
        /* i.mx50 has the i.mx31 type gpio */
@@ -179,6 +191,10 @@ void __init imx50_soc_init(void)
        mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
        mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
        mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+
+       /* i.mx50 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
+                                       ARRAY_SIZE(imx50_audmux_res));
 }
 
 void __init imx51_soc_init(void)
@@ -191,6 +207,9 @@ void __init imx51_soc_init(void)
 
        /* i.mx51 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX51_SDMA_BASE_ADDR, MX51_INT_SDMA, &imx51_sdma_pdata);
+       /* i.mx51 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx51_audmux_res,
+                                       ARRAY_SIZE(imx51_audmux_res));
 }
 
 void __init imx53_soc_init(void)
@@ -206,4 +225,7 @@ void __init imx53_soc_init(void)
 
        /* i.mx53 has the i.mx35 type sdma */
        imx_add_imx_sdma("imx35-sdma", MX53_SDMA_BASE_ADDR, MX53_INT_SDMA, &imx53_sdma_pdata);
+       /* i.mx53 has the i.mx31 type audmux */
+       platform_device_register_simple("imx31-audmux", 0, imx53_audmux_res,
+                                       ARRAY_SIZE(imx53_audmux_res));
 }
index b49a39ff99da6e25eb8a2e4c1e5fa1a278a71961..a8c9e04771bff14b2d18b6840f8f41af70d4dd90 100644 (file)
@@ -1,4 +1,6 @@
 /*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2012 Linaro Ltd.
  * Copyright 2009 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  *
  * Initial development of this code was funded by
  * GNU General Public License for more details.
  */
 
-#include <linux/module.h>
-#include <linux/err.h>
-#include <linux/io.h>
 #include <linux/clk.h>
 #include <linux/debugfs.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <mach/audmux.h>
-#include <mach/hardware.h>
+
+#define DRIVER_NAME "imx-audmux"
 
 static struct clk *audmux_clk;
 static void __iomem *audmux_base;
@@ -140,7 +144,7 @@ static const struct file_operations audmux_debugfs_fops = {
        .llseek = default_llseek,
 };
 
-static void audmux_debugfs_init(void)
+static void __init audmux_debugfs_init(void)
 {
        int i;
        char buf[20];
@@ -159,18 +163,48 @@ static void audmux_debugfs_init(void)
                                   i);
        }
 }
+
+static void __exit audmux_debugfs_remove(void)
+{
+       debugfs_remove_recursive(audmux_debugfs_root);
+}
 #else
 static inline void audmux_debugfs_init(void)
 {
 }
+
+static inline void audmux_debugfs_remove(void)
+{
+}
 #endif
 
+enum imx_audmux_type {
+       IMX21_AUDMUX,
+       IMX31_AUDMUX,
+} audmux_type;
+
+static struct platform_device_id imx_audmux_ids[] = {
+       {
+               .name = "imx21-audmux",
+               .driver_data = IMX21_AUDMUX,
+       }, {
+               .name = "imx31-audmux",
+               .driver_data = IMX31_AUDMUX,
+       }, {
+               /* sentinel */
+       }
+};
+MODULE_DEVICE_TABLE(platform, imx_audmux_ids);
+
 static const uint8_t port_mapping[] = {
        0x0, 0x4, 0x8, 0x10, 0x14, 0x1c,
 };
 
 int mxc_audmux_v1_configure_port(unsigned int port, unsigned int pcr)
 {
+       if (audmux_type != IMX21_AUDMUX)
+               return -EINVAL;
+
        if (!audmux_base)
                return -ENOSYS;
 
@@ -186,6 +220,9 @@ EXPORT_SYMBOL_GPL(mxc_audmux_v1_configure_port);
 int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
                unsigned int pdcr)
 {
+       if (audmux_type != IMX31_AUDMUX)
+               return -EINVAL;
+
        if (!audmux_base)
                return -ENOSYS;
 
@@ -202,41 +239,61 @@ int mxc_audmux_v2_configure_port(unsigned int port, unsigned int ptcr,
 }
 EXPORT_SYMBOL_GPL(mxc_audmux_v2_configure_port);
 
-static int mxc_audmux_init(void)
+static int __init imx_audmux_probe(struct platform_device *pdev)
 {
-       int ret;
-       if (cpu_is_mx51()) {
-               audmux_base = MX51_IO_ADDRESS(MX51_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx31()) {
-               audmux_base = MX31_IO_ADDRESS(MX31_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx35()) {
-               audmux_clk = clk_get(NULL, "audmux");
-               if (IS_ERR(audmux_clk)) {
-                       ret = PTR_ERR(audmux_clk);
-                       printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
-                                       ret);
-                       return ret;
-               }
-               audmux_base = MX35_IO_ADDRESS(MX35_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx25()) {
-               audmux_clk = clk_get(NULL, "audmux");
-               if (IS_ERR(audmux_clk)) {
-                       ret = PTR_ERR(audmux_clk);
-                       printk(KERN_ERR "%s: cannot get clock: %d\n", __func__,
-                                       ret);
-                       return ret;
-               }
-               audmux_base = MX25_IO_ADDRESS(MX25_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx27()) {
-               audmux_base = MX27_IO_ADDRESS(MX27_AUDMUX_BASE_ADDR);
-       } else if (cpu_is_mx21()) {
-               audmux_base = MX21_IO_ADDRESS(MX21_AUDMUX_BASE_ADDR);
+       struct resource *res;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       audmux_base = devm_request_and_ioremap(&pdev->dev, res);
+       if (!audmux_base)
+               return -EADDRNOTAVAIL;
+
+       audmux_clk = clk_get(&pdev->dev, "audmux");
+       if (IS_ERR(audmux_clk)) {
+               dev_dbg(&pdev->dev, "cannot get clock: %ld\n",
+                               PTR_ERR(audmux_clk));
+               audmux_clk = NULL;
        }
 
-       if (!cpu_is_mx2())
+       audmux_type = pdev->id_entry->driver_data;
+       if (audmux_type == IMX31_AUDMUX)
                audmux_debugfs_init();
 
        return 0;
 }
 
-postcore_initcall(mxc_audmux_init);
+static int __exit imx_audmux_remove(struct platform_device *pdev)
+{
+       if (audmux_type == IMX31_AUDMUX)
+               audmux_debugfs_remove();
+       clk_put(audmux_clk);
+
+       return 0;
+}
+
+static struct platform_driver imx_audmux_driver = {
+       .probe          = imx_audmux_probe,
+       .remove         = __exit_p(imx_audmux_remove),
+       .id_table       = imx_audmux_ids,
+       .driver = {
+               .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
+       }
+};
+
+static int __init imx_audmux_init(void)
+{
+       return platform_driver_register(&imx_audmux_driver);
+}
+subsys_initcall(imx_audmux_init);
+
+static void __exit imx_audmux_exit(void)
+{
+       platform_driver_unregister(&imx_audmux_driver);
+}
+module_exit(imx_audmux_exit);
+
+MODULE_DESCRIPTION("Freescale i.MX AUDMUX driver");
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);