asoc: tegra: add device tree support for audio
Nikesh Oswal [Tue, 28 May 2013 11:07:35 +0000 (16:07 +0530)]
add device tree support for audio drivers and
enable device tree for ardbeg

Bug 1256430

Change-Id: I09489e735a8e56ea664a5f47784e3fc7b53dac62
Signed-off-by: Nikesh Oswal <noswal@nvidia.com>
Reviewed-on: http://git-master/r/233299
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Sumit Bhattacharya <sumitb@nvidia.com>

arch/arm/boot/dts/tegra114-ardbeg.dts
arch/arm/boot/dts/tegra114.dtsi
arch/arm/mach-tegra/board-ardbeg.c
sound/soc/codecs/rt5645.c
sound/soc/tegra/tegra30_ahub.c
sound/soc/tegra/tegra30_dam.c
sound/soc/tegra/tegra30_spdif.c
sound/soc/tegra/tegra_rt5645.c

index 8213a59..5e918e2 100644 (file)
                status = "okay";
        };
 
+       ahub {
+               i2s@70080300 {
+                       status = "okay";
+               };
+               i2s@70080400 {
+                       status = "okay";
+               };
+               i2s@70080500 {
+                       status = "okay";
+               };
+               i2s@70080600 {
+                       status = "okay";
+               };
+               i2s@70080700 {
+                       status = "okay";
+               };
+               dam@70080800 {
+                       status = "okay";
+               };
+               dam@70080900 {
+                       status = "okay";
+               };
+               dam@70080A00 {
+                       status = "okay";
+               };
+               spdif@70080B00 {
+                       status = "okay";
+               };
+       };
+
        i2c@7000c000 {
                status = "okay";
                clock-frequency = <100000>;
+               rt5645: rt5645@1a {
+                       compatible = "realtek,rt5645";
+                       reg = <0x1a>;
+               };
        };
 
        i2c@7000c400 {
        camera {
                status = "okay";
        };
+
+       sound {
+               compatible = "nvidia,tegra-audio-rt5645";
+               nvidia,ldo-gpios = <&gpio 171 0>;
+               nvidia,hp-det-gpios = <&gpio 143 0>;
+               nvidia,i2s-param-hifi = <1 1 2 16 48000 2 1536000>;
+               nvidia,i2s-param-bt = <3 1 0 16 8000 1 512000>;
+       };
 };
index cf26689..f576e6c 100644 (file)
                nvidia,ahb = <&ahb>;
        };
 
+       ahub {
+               compatible = "nvidia,tegra30-ahub";
+               reg = <0x70080000 0x200
+                      0x70080200 0x100>;
+               interrupts = <0 103 0x04>;
+               nvidia,dma-request-selector = <&apbdma 1>;
+
+               ranges;
+               #address-cells = <1>;
+               #size-cells = <1>;
+
+               tegra_i2s0: i2s@70080300 {
+                       compatible = "nvidia,tegra30-i2s";
+                       reg = <0x70080300 0x100>;
+                       nvidia,ahub-cif-ids = <4 4>;
+                       status = "disabled";
+               };
+
+               tegra_i2s1: i2s@70080400 {
+                       compatible = "nvidia,tegra30-i2s";
+                       reg = <0x70080400 0x100>;
+                       nvidia,ahub-cif-ids = <5 5>;
+                       status = "disabled";
+               };
+
+               tegra_i2s2: i2s@70080500 {
+                       compatible = "nvidia,tegra30-i2s";
+                       reg = <0x70080500 0x100>;
+                       nvidia,ahub-cif-ids = <6 6>;
+                       status = "disabled";
+               };
+
+               tegra_i2s3: i2s@70080600 {
+                       compatible = "nvidia,tegra30-i2s";
+                       reg = <0x70080600 0x100>;
+                       nvidia,ahub-cif-ids = <7 7>;
+                       status = "disabled";
+               };
+
+               tegra_i2s4: i2s@70080700 {
+                       compatible = "nvidia,tegra30-i2s";
+                       reg = <0x70080700 0x100>;
+                       nvidia,ahub-cif-ids = <8 8>;
+                       status = "disabled";
+               };
+
+               tegra_dam0: dam@70080800 {
+                       compatible = "nvidia,tegra30-dam";
+                       reg = <0x70080800 0x100>;
+                       nvidia,ahub-dam-id = <0>;
+                       status = "disabled";
+               };
+
+               tegra_dam1: dam@70080900 {
+                       compatible = "nvidia,tegra30-dam";
+                       reg = <0x70080900 0x100>;
+                       nvidia,ahub-dam-id = <1>;
+                       status = "disabled";
+               };
+
+               tegra_dam2: dam@70080A00 {
+                       compatible = "nvidia,tegra30-dam";
+                       reg = <0x70080A00 0x100>;
+                       nvidia,ahub-dam-id = <2>;
+                       status = "disabled";
+               };
+
+               tegra_spdif: spdif@70080B00 {
+                       compatible = "nvidia,tegra30-spdif";
+                       reg = <0x70080B00 0x100>;
+                       status = "disabled";
+               };
+       };
+
        sdhci@78000000 {
                compatible = "nvidia,tegra114-sdhci", "nvidia,tegra30-sdhci";
                reg = <0x78000000 0x200>;
index d21e19f..b040a52 100644 (file)
 
 static struct board_info board_info, display_board_info;
 
+/*use board file for T12x*/
+#if defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_USE_OF)
 static struct i2c_board_info __initdata rt5645_board_info = {
        I2C_BOARD_INFO("rt5645", 0x1a),
 };
+#endif
 
 static __initdata struct tegra_clk_init_table ardbeg_clk_init_table[] = {
        /* name         parent          rate            enabled */
@@ -175,7 +178,10 @@ static void ardbeg_i2c_init(void)
        platform_device_register(&tegra11_i2c_device2);
        platform_device_register(&tegra11_i2c_device1);
 #endif
+/*use board file for T12x*/
+#if defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_USE_OF)
        i2c_register_board_info(0, &rt5645_board_info, 1);
+#endif
 }
 
 static struct platform_device *ardbeg_uart_devices[] __initdata = {
@@ -215,6 +221,8 @@ static struct uart_clk_parent uart_parent_clk[] = {
 
 static struct tegra_uart_platform_data ardbeg_uart_pdata;
 
+/*use board file for T12x*/
+#if defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_USE_OF)
 static struct tegra_asoc_platform_data ardbeg_audio_pdata = {
        .gpio_spkr_en = TEGRA_GPIO_SPKR_EN,
        .gpio_hp_det = TEGRA_GPIO_HP_DET,
@@ -250,6 +258,7 @@ static struct platform_device ardbeg_audio_device = {
                .platform_data = &ardbeg_audio_pdata,
        },
 };
+#endif
 
 static struct tegra_uart_platform_data ardbeg_loopback_uart_pdata;
 
@@ -333,6 +342,8 @@ static struct platform_device *ardbeg_devices[] __initdata = {
        &tegra11_se_device,
 #endif
 #endif
+/*use board file for T12x*/
+#if defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_USE_OF)
        &tegra_ahub_device,
        &tegra_dam_device0,
        &tegra_dam_device1,
@@ -342,9 +353,9 @@ static struct platform_device *ardbeg_devices[] __initdata = {
        &tegra_i2s_device4,
        &ardbeg_audio_device,
        &tegra_spdif_device,
+#endif
        &spdif_dit_device,
        &bluetooth_dit_device,
-       &tegra_pcm_device,
        &tegra_hda_device,
 #if defined(CONFIG_CRYPTO_DEV_TEGRA_AES)
        &tegra_aes_device,
@@ -560,6 +571,10 @@ struct of_dev_auxdata ardbeg_auxdata_lookup[] __initdata = {
                                NULL),
        OF_DEV_AUXDATA("nvidia,tegra114-apbdma", 0x6000a000, "tegra-apbdma",
                                NULL),
+       OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub",
+                               NULL),
+       OF_DEV_AUXDATA("nvidia,tegra-audio-rt5645", 0x0, "tegra-snd-rt5645",
+                               NULL),
        {}
 };
 #endif
@@ -625,7 +640,10 @@ static void __init tegra_ardbeg_late_init(void)
        ardbeg_i2c_init();
        ardbeg_spi_init();
        ardbeg_uart_init();
+/*use board file for T12x*/
+#if defined(CONFIG_ARCH_TEGRA_12x_SOC) || !defined(CONFIG_USE_OF)
        ardbeg_audio_init();
+#endif
        platform_add_devices(ardbeg_devices, ARRAY_SIZE(ardbeg_devices));
        //tegra_ram_console_debug_init();
        tegra_io_dpd_init();
index 005e667..1fd1c3e 100644 (file)
@@ -3745,10 +3745,16 @@ void rt5645_i2c_shutdown(struct i2c_client *client)
                rt5645_set_bias_level(codec, SND_SOC_BIAS_OFF);
 }
 
+static const struct of_device_id rt5645_of_match[] = {
+       { .compatible = "realtek,rt5645", },
+       {},
+};
+
 struct i2c_driver rt5645_i2c_driver = {
        .driver = {
                .name = "rt5645",
                .owner = THIS_MODULE,
+               .of_match_table = rt5645_of_match,
        },
        .probe = rt5645_i2c_probe,
        .remove   = rt5645_i2c_remove,
index ce0b161..b8c5e69 100644 (file)
@@ -492,6 +492,11 @@ struct of_dev_auxdata ahub_auxdata[] = {
        OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080500, "tegra30-i2s.2", NULL),
        OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080600, "tegra30-i2s.3", NULL),
        OF_DEV_AUXDATA("nvidia,tegra30-i2s", 0x70080700, "tegra30-i2s.4", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra30-dam", 0x70080800, "tegra30-dam.0", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra30-dam", 0x70080900, "tegra30-dam.1", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra30-dam", 0x70080A00, "tegra30-dam.2", NULL),
+       OF_DEV_AUXDATA("nvidia,tegra30-spdif", 0x70080B00, "tegra30-spdif",
+               NULL),
        {}
 };
 
index 0f64886..31becc5 100644 (file)
@@ -22,6 +22,7 @@
  */
 
 #include <linux/clk.h>
+#include <linux/of.h>
 #include <linux/module.h>
 #include <linux/debugfs.h>
 #include <linux/device.h>
@@ -1077,6 +1078,13 @@ static int tegra30_dam_probe(struct platform_device *pdev)
        int i;
 #endif
        int clkm_rate;
+       u32 val32;
+
+       if (pdev->dev.of_node) {
+               of_property_read_u32(pdev->dev.of_node, "nvidia,ahub-dam-id",
+                       &val32);
+               pdev->id = (int)val32;
+       }
 
        if ((pdev->id < 0) ||
                (pdev->id >= TEGRA30_NR_DAM_IFC)) {
index e3e54bd..d968089 100644 (file)
@@ -476,10 +476,16 @@ static int tegra30_spdif_platform_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct of_device_id tegra30_spdif_of_match[] = {
+       { .compatible = "nvidia,tegra30-spdif",},
+       {},
+};
+
 static struct platform_driver tegra30_spdif_driver = {
        .driver = {
                .name = DRV_NAME,
                .owner = THIS_MODULE,
+               .of_match_table = tegra30_spdif_of_match,
        },
        .probe = tegra30_spdif_platform_probe,
        .remove = tegra30_spdif_platform_remove,
index c0a776e..2bd16a2 100644 (file)
  */
 
 #include <asm/mach-types.h>
-
+#include <linux/of.h>
 #include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/gpio.h>
+#include <linux/of_gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/delay.h>
 #ifdef CONFIG_SWITCH
@@ -501,7 +502,7 @@ static int tegra_rt5645_event_ext_mic(struct snd_soc_dapm_widget *w,
        return 0;
 }
 
-static const struct snd_soc_dapm_widget cardhu_dapm_widgets[] = {
+static const struct snd_soc_dapm_widget ardbeg_dapm_widgets[] = {
        SND_SOC_DAPM_SPK("Int Spk", tegra_rt5645_event_int_spk),
        SND_SOC_DAPM_HP("Headphone Jack", tegra_rt5645_event_hp),
        SND_SOC_DAPM_MIC("Mic Jack", tegra_rt5645_event_ext_mic),
@@ -526,7 +527,7 @@ static const struct snd_soc_dapm_route ardbeg_audio_map[] = {
 #endif
 };
 
-static const struct snd_kcontrol_new cardhu_controls[] = {
+static const struct snd_kcontrol_new ardbeg_controls[] = {
        SOC_DAPM_PIN_SWITCH("Int Spk"),
        SOC_DAPM_PIN_SWITCH("Headphone Jack"),
        SOC_DAPM_PIN_SWITCH("Mic Jack"),
@@ -705,10 +706,10 @@ static struct snd_soc_card snd_soc_tegra_rt5645 = {
        .resume_pre = tegra_rt5645_resume_pre,
        .set_bias_level = tegra_rt5645_set_bias_level,
        .set_bias_level_post = tegra_rt5645_set_bias_level_post,
-       .controls = cardhu_controls,
-       .num_controls = ARRAY_SIZE(cardhu_controls),
-       .dapm_widgets = cardhu_dapm_widgets,
-       .num_dapm_widgets = ARRAY_SIZE(cardhu_dapm_widgets),
+       .controls = ardbeg_controls,
+       .num_controls = ARRAY_SIZE(ardbeg_controls),
+       .dapm_widgets = ardbeg_dapm_widgets,
+       .num_dapm_widgets = ARRAY_SIZE(ardbeg_dapm_widgets),
        .dapm_routes = ardbeg_audio_map,
        .num_dapm_routes = ARRAY_SIZE(ardbeg_audio_map),
        .fully_routed = true,
@@ -717,16 +718,59 @@ static struct snd_soc_card snd_soc_tegra_rt5645 = {
 static int tegra_rt5645_driver_probe(struct platform_device *pdev)
 {
        struct snd_soc_card *card = &snd_soc_tegra_rt5645;
+       struct device_node *np = pdev->dev.of_node;
        struct tegra_rt5645 *machine;
-       struct tegra_asoc_platform_data *pdata;
+       struct tegra_asoc_platform_data *pdata = NULL;
        int ret;
        int codec_id;
+       u32 val32[7];
+
+       if (!pdev->dev.platform_data && !pdev->dev.of_node) {
+               dev_err(&pdev->dev, "No platform data supplied\n");
+               return -EINVAL;
+       }
+       if (pdev->dev.platform_data) {
+               pdata = pdev->dev.platform_data;
+       } else if (np) {
+               pdata = kzalloc(sizeof(struct tegra_asoc_platform_data),
+                       GFP_KERNEL);
+               if (!pdata) {
+                       dev_err(&pdev->dev, "Can't allocate tegra_asoc_platform_data struct\n");
+                       return -ENOMEM;
+               }
+
+               pdata->gpio_ldo1_en = of_get_named_gpio(np,
+                                               "nvidia,ldo-gpios", 0);
+               if (pdata->gpio_ldo1_en == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+
+               pdata->gpio_hp_det = of_get_named_gpio(np,
+                                               "nvidia,hp-det-gpios", 0);
+               if (pdata->gpio_hp_det == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+
+               pdata->gpio_codec1 = pdata->gpio_codec2 = pdata->gpio_codec3 =
+               pdata->gpio_spkr_en = pdata->gpio_hp_mute =
+               pdata->gpio_int_mic_en = pdata->gpio_ext_mic_en = -1;
+
+               of_property_read_u32_array(np, "nvidia,i2s-param-hifi", val32,
+                                                          ARRAY_SIZE(val32));
+               pdata->i2s_param[HIFI_CODEC].audio_port_id = (int)val32[0];
+               pdata->i2s_param[HIFI_CODEC].is_i2s_master = (int)val32[1];
+               pdata->i2s_param[HIFI_CODEC].i2s_mode = (int)val32[2];
+
+               of_property_read_u32_array(np, "nvidia,i2s-param-bt", val32,
+                                                          ARRAY_SIZE(val32));
+               pdata->i2s_param[BT_SCO].audio_port_id = (int)val32[0];
+               pdata->i2s_param[BT_SCO].is_i2s_master = (int)val32[1];
+               pdata->i2s_param[BT_SCO].i2s_mode = (int)val32[2];
+       }
 
-       pdata = pdev->dev.platform_data;
        if (!pdata) {
                dev_err(&pdev->dev, "No platform data supplied\n");
                return -EINVAL;
        }
+
        if (pdata->codec_name)
                card->dai_link->codec_name = pdata->codec_name;
 
@@ -874,7 +918,11 @@ err_fini_utils:
 #endif
        tegra_asoc_utils_fini(&machine->util_data);
 err_free_machine:
+       if (np)
+               kfree(machine->pdata);
+
        kfree(machine);
+
        return ret;
 }
 
@@ -883,6 +931,7 @@ static int tegra_rt5645_driver_remove(struct platform_device *pdev)
        struct snd_soc_card *card = platform_get_drvdata(pdev);
        struct tegra_rt5645 *machine = snd_soc_card_get_drvdata(card);
        struct tegra_asoc_platform_data *pdata = machine->pdata;
+       struct device_node *np = pdev->dev.of_node;
 
        if (machine->gpio_requested & GPIO_HP_DET)
                snd_soc_jack_free_gpios(&tegra_rt5645_hp_jack,
@@ -920,16 +969,25 @@ static int tegra_rt5645_driver_remove(struct platform_device *pdev)
 #ifdef CONFIG_SWITCH
        tegra_asoc_switch_unregister(&tegra_rt5645_headset_switch);
 #endif
+       if (np)
+               kfree(machine->pdata);
+
        kfree(machine);
 
        return 0;
 }
 
+static const struct of_device_id tegra_rt5645_of_match[] = {
+       { .compatible = "nvidia,tegra-audio-rt5645", },
+       {},
+};
+
 static struct platform_driver tegra_rt5645_driver = {
        .driver = {
                .name = DRV_NAME,
                .owner = THIS_MODULE,
                .pm = &snd_soc_pm_ops,
+               .of_match_table = tegra_rt5645_of_match,
        },
        .probe = tegra_rt5645_driver_probe,
        .remove = tegra_rt5645_driver_remove,