Loading Documentation/devicetree/bindings/sound/renesas,rsnd.txt 0 → 100644 +96 −0 Original line number Original line Diff line number Diff line Renesas R-Car sound Required properties: - compatible : "renesas,rcar_sound-gen1" if generation1 "renesas,rcar_sound-gen2" if generation2 - reg : Should contain the register physical address. required register is SRU/ADG/SSI if generation1 SRU/ADG/SSIU/SSI if generation2 - rcar_sound,ssi : SSI subnode - rcar_sound,scu : SCU subnode - rcar_sound,dai : DAI subnode SSI subnode properties: - interrupts : Should contain SSI interrupt for PIO transfer - shared-pin : if shared clock pin DAI subnode properties: - playback : list of playback modules - capture : list of capture modules Example: rcar_sound: rcar_sound@0xffd90000 { #sound-dai-cells = <1>; compatible = "renesas,rcar_sound-gen2"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ <0 0xec541000 0 0x1280>; /* SSI */ rcar_sound,src { src0: src@0 { }; src1: src@1 { }; src2: src@2 { }; src3: src@3 { }; src4: src@4 { }; src5: src@5 { }; src6: src@6 { }; src7: src@7 { }; src8: src@8 { }; src9: src@9 { }; }; rcar_sound,ssi { ssi0: ssi@0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; }; ssi1: ssi@1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; }; ssi2: ssi@2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; }; ssi3: ssi@3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; }; ssi4: ssi@4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; }; ssi5: ssi@5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; }; ssi6: ssi@6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; }; ssi7: ssi@7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; }; ssi8: ssi@8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; }; ssi9: ssi@9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; }; }; rcar_sound,dai { dai0 { playback = <&ssi5 &src5>; capture = <&ssi6>; }; dai1 { playback = <&ssi3>; }; dai2 { capture = <&ssi4>; }; dai3 { playback = <&ssi7>; }; dai4 { capture = <&ssi8>; }; }; }; sound/soc/sh/rcar/adg.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -392,6 +392,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) } } int rsnd_adg_probe(struct platform_device *pdev, int rsnd_adg_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) struct rsnd_priv *priv) { { struct rsnd_adg *adg; struct rsnd_adg *adg; Loading sound/soc/sh/rcar/core.c +119 −3 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,21 @@ #define RSND_RATES SNDRV_PCM_RATE_8000_96000 #define RSND_RATES SNDRV_PCM_RATE_8000_96000 #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) static struct rsnd_of_data rsnd_of_data_gen1 = { .flags = RSND_GEN1, }; static struct rsnd_of_data rsnd_of_data_gen2 = { .flags = RSND_GEN2, }; static struct of_device_id rsnd_of_match[] = { { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, {}, }; MODULE_DEVICE_TABLE(of, rsnd_of_match); /* /* * rsnd_platform functions * rsnd_platform functions */ */ Loading Loading @@ -620,7 +635,92 @@ static int rsnd_path_init(struct rsnd_priv *priv, return ret; return ret; } } static void rsnd_of_parse_dai(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *dai_node, *dai_np; struct device_node *ssi_node, *ssi_np; struct device_node *src_node, *src_np; struct device_node *playback, *capture; struct rsnd_dai_platform_info *dai_info; struct rcar_snd_info *info = rsnd_priv_to_info(priv); struct device *dev = &pdev->dev; int nr, i; int dai_i, ssi_i, src_i; if (!of_data) return; dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai"); if (!dai_node) return; nr = of_get_child_count(dai_node); if (!nr) return; dai_info = devm_kzalloc(dev, sizeof(struct rsnd_dai_platform_info) * nr, GFP_KERNEL); if (!dai_info) { dev_err(dev, "dai info allocation error\n"); return; } info->dai_info_nr = nr; info->dai_info = dai_info; ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); #define mod_parse(name) \ if (name##_node) { \ struct rsnd_##name##_platform_info *name##_info; \ \ name##_i = 0; \ for_each_child_of_node(name##_node, name##_np) { \ name##_info = info->name##_info + name##_i; \ \ if (name##_np == playback) \ dai_info->playback.name = name##_info; \ if (name##_np == capture) \ dai_info->capture.name = name##_info; \ \ name##_i++; \ } \ } /* * parse all dai */ dai_i = 0; for_each_child_of_node(dai_node, dai_np) { dai_info = info->dai_info + dai_i; for (i = 0;; i++) { playback = of_parse_phandle(dai_np, "playback", i); capture = of_parse_phandle(dai_np, "capture", i); if (!playback && !capture) break; mod_parse(ssi); mod_parse(src); if (playback) of_node_put(playback); if (capture) of_node_put(capture); } dai_i++; } } static int rsnd_dai_probe(struct platform_device *pdev, static int rsnd_dai_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) struct rsnd_priv *priv) { { struct snd_soc_dai_driver *drv; struct snd_soc_dai_driver *drv; Loading @@ -628,13 +728,16 @@ static int rsnd_dai_probe(struct platform_device *pdev, struct rsnd_dai *rdai; struct rsnd_dai *rdai; struct rsnd_mod *pmod, *cmod; struct rsnd_mod *pmod, *cmod; struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv); int dai_nr = info->dai_info_nr; int dai_nr; int i; int i; rsnd_of_parse_dai(pdev, of_data, priv); /* /* * dai_nr should be set via dai_info_nr, * dai_nr should be set via dai_info_nr, * but allow it to keeping compatible * but allow it to keeping compatible */ */ dai_nr = info->dai_info_nr; if (!dai_nr) { if (!dai_nr) { /* get max dai nr */ /* get max dai nr */ for (dai_nr = 0; dai_nr < 32; dai_nr++) { for (dai_nr = 0; dai_nr < 32; dai_nr++) { Loading Loading @@ -802,7 +905,10 @@ static int rsnd_probe(struct platform_device *pdev) struct rsnd_priv *priv; struct rsnd_priv *priv; struct device *dev = &pdev->dev; struct device *dev = &pdev->dev; struct rsnd_dai *rdai; struct rsnd_dai *rdai; const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev); const struct rsnd_of_data *of_data; int (*probe_func[])(struct platform_device *pdev, int (*probe_func[])(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) = { struct rsnd_priv *priv) = { rsnd_gen_probe, rsnd_gen_probe, rsnd_ssi_probe, rsnd_ssi_probe, Loading @@ -812,7 +918,16 @@ static int rsnd_probe(struct platform_device *pdev) }; }; int ret, i; int ret, i; info = NULL; of_data = NULL; if (of_id) { info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info), GFP_KERNEL); of_data = of_id->data; } else { info = pdev->dev.platform_data; info = pdev->dev.platform_data; } if (!info) { if (!info) { dev_err(dev, "driver needs R-Car sound information\n"); dev_err(dev, "driver needs R-Car sound information\n"); return -ENODEV; return -ENODEV; Loading @@ -835,7 +950,7 @@ static int rsnd_probe(struct platform_device *pdev) * init each module * init each module */ */ for (i = 0; i < ARRAY_SIZE(probe_func); i++) { for (i = 0; i < ARRAY_SIZE(probe_func); i++) { ret = probe_func[i](pdev, priv); ret = probe_func[i](pdev, of_data, priv); if (ret) if (ret) return ret; return ret; } } Loading Loading @@ -903,6 +1018,7 @@ static int rsnd_remove(struct platform_device *pdev) static struct platform_driver rsnd_driver = { static struct platform_driver rsnd_driver = { .driver = { .driver = { .name = "rcar_sound", .name = "rcar_sound", .of_match_table = rsnd_of_match, }, }, .probe = rsnd_probe, .probe = rsnd_probe, .remove = rsnd_remove, .remove = rsnd_remove, Loading sound/soc/sh/rcar/gen.c +15 −0 Original line number Original line Diff line number Diff line Loading @@ -359,13 +359,28 @@ static int rsnd_gen1_probe(struct platform_device *pdev, /* /* * Gen * Gen */ */ static void rsnd_of_parse_gen(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct rcar_snd_info *info = priv->info; if (!of_data) return; info->flags = of_data->flags; } int rsnd_gen_probe(struct platform_device *pdev, int rsnd_gen_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) struct rsnd_priv *priv) { { struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_gen *gen; struct rsnd_gen *gen; int ret; int ret; rsnd_of_parse_gen(pdev, of_data, priv); gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); if (!gen) { if (!gen) { dev_err(dev, "GEN allocate failed\n"); dev_err(dev, "GEN allocate failed\n"); Loading sound/soc/sh/rcar/rsnd.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,8 @@ #include <linux/io.h> #include <linux/io.h> #include <linux/list.h> #include <linux/list.h> #include <linux/module.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/sh_dma.h> #include <linux/sh_dma.h> #include <linux/workqueue.h> #include <linux/workqueue.h> #include <sound/rcar_snd.h> #include <sound/rcar_snd.h> Loading Loading @@ -113,6 +115,7 @@ enum rsnd_reg { #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 struct rsnd_of_data; struct rsnd_priv; struct rsnd_priv; struct rsnd_mod; struct rsnd_mod; struct rsnd_dai; struct rsnd_dai; Loading Loading @@ -260,6 +263,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); * R-Car Gen1/Gen2 * R-Car Gen1/Gen2 */ */ int rsnd_gen_probe(struct platform_device *pdev, int rsnd_gen_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_mod *mod, Loading @@ -273,6 +277,7 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); int rsnd_adg_probe(struct platform_device *pdev, int rsnd_adg_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_mod *mod, Loading @@ -290,6 +295,10 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, /* /* * R-Car sound priv * R-Car sound priv */ */ struct rsnd_of_data { u32 flags; }; struct rsnd_priv { struct rsnd_priv { struct device *dev; struct device *dev; Loading Loading @@ -348,6 +357,7 @@ struct rsnd_priv { * R-Car SRC * R-Car SRC */ */ int rsnd_src_probe(struct platform_device *pdev, int rsnd_src_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, Loading @@ -366,6 +376,7 @@ int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, * R-Car SSI * R-Car SSI */ */ int rsnd_ssi_probe(struct platform_device *pdev, int rsnd_ssi_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, Loading Loading
Documentation/devicetree/bindings/sound/renesas,rsnd.txt 0 → 100644 +96 −0 Original line number Original line Diff line number Diff line Renesas R-Car sound Required properties: - compatible : "renesas,rcar_sound-gen1" if generation1 "renesas,rcar_sound-gen2" if generation2 - reg : Should contain the register physical address. required register is SRU/ADG/SSI if generation1 SRU/ADG/SSIU/SSI if generation2 - rcar_sound,ssi : SSI subnode - rcar_sound,scu : SCU subnode - rcar_sound,dai : DAI subnode SSI subnode properties: - interrupts : Should contain SSI interrupt for PIO transfer - shared-pin : if shared clock pin DAI subnode properties: - playback : list of playback modules - capture : list of capture modules Example: rcar_sound: rcar_sound@0xffd90000 { #sound-dai-cells = <1>; compatible = "renesas,rcar_sound-gen2"; reg = <0 0xec500000 0 0x1000>, /* SCU */ <0 0xec5a0000 0 0x100>, /* ADG */ <0 0xec540000 0 0x1000>, /* SSIU */ <0 0xec541000 0 0x1280>; /* SSI */ rcar_sound,src { src0: src@0 { }; src1: src@1 { }; src2: src@2 { }; src3: src@3 { }; src4: src@4 { }; src5: src@5 { }; src6: src@6 { }; src7: src@7 { }; src8: src@8 { }; src9: src@9 { }; }; rcar_sound,ssi { ssi0: ssi@0 { interrupts = <0 370 IRQ_TYPE_LEVEL_HIGH>; }; ssi1: ssi@1 { interrupts = <0 371 IRQ_TYPE_LEVEL_HIGH>; }; ssi2: ssi@2 { interrupts = <0 372 IRQ_TYPE_LEVEL_HIGH>; }; ssi3: ssi@3 { interrupts = <0 373 IRQ_TYPE_LEVEL_HIGH>; }; ssi4: ssi@4 { interrupts = <0 374 IRQ_TYPE_LEVEL_HIGH>; }; ssi5: ssi@5 { interrupts = <0 375 IRQ_TYPE_LEVEL_HIGH>; }; ssi6: ssi@6 { interrupts = <0 376 IRQ_TYPE_LEVEL_HIGH>; }; ssi7: ssi@7 { interrupts = <0 377 IRQ_TYPE_LEVEL_HIGH>; }; ssi8: ssi@8 { interrupts = <0 378 IRQ_TYPE_LEVEL_HIGH>; }; ssi9: ssi@9 { interrupts = <0 379 IRQ_TYPE_LEVEL_HIGH>; }; }; rcar_sound,dai { dai0 { playback = <&ssi5 &src5>; capture = <&ssi6>; }; dai1 { playback = <&ssi3>; }; dai2 { capture = <&ssi4>; }; dai3 { playback = <&ssi7>; }; dai4 { capture = <&ssi8>; }; }; };
sound/soc/sh/rcar/adg.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -392,6 +392,7 @@ static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg) } } int rsnd_adg_probe(struct platform_device *pdev, int rsnd_adg_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) struct rsnd_priv *priv) { { struct rsnd_adg *adg; struct rsnd_adg *adg; Loading
sound/soc/sh/rcar/core.c +119 −3 Original line number Original line Diff line number Diff line Loading @@ -100,6 +100,21 @@ #define RSND_RATES SNDRV_PCM_RATE_8000_96000 #define RSND_RATES SNDRV_PCM_RATE_8000_96000 #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) static struct rsnd_of_data rsnd_of_data_gen1 = { .flags = RSND_GEN1, }; static struct rsnd_of_data rsnd_of_data_gen2 = { .flags = RSND_GEN2, }; static struct of_device_id rsnd_of_match[] = { { .compatible = "renesas,rcar_sound-gen1", .data = &rsnd_of_data_gen1 }, { .compatible = "renesas,rcar_sound-gen2", .data = &rsnd_of_data_gen2 }, {}, }; MODULE_DEVICE_TABLE(of, rsnd_of_match); /* /* * rsnd_platform functions * rsnd_platform functions */ */ Loading Loading @@ -620,7 +635,92 @@ static int rsnd_path_init(struct rsnd_priv *priv, return ret; return ret; } } static void rsnd_of_parse_dai(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct device_node *dai_node, *dai_np; struct device_node *ssi_node, *ssi_np; struct device_node *src_node, *src_np; struct device_node *playback, *capture; struct rsnd_dai_platform_info *dai_info; struct rcar_snd_info *info = rsnd_priv_to_info(priv); struct device *dev = &pdev->dev; int nr, i; int dai_i, ssi_i, src_i; if (!of_data) return; dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai"); if (!dai_node) return; nr = of_get_child_count(dai_node); if (!nr) return; dai_info = devm_kzalloc(dev, sizeof(struct rsnd_dai_platform_info) * nr, GFP_KERNEL); if (!dai_info) { dev_err(dev, "dai info allocation error\n"); return; } info->dai_info_nr = nr; info->dai_info = dai_info; ssi_node = of_get_child_by_name(dev->of_node, "rcar_sound,ssi"); src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); #define mod_parse(name) \ if (name##_node) { \ struct rsnd_##name##_platform_info *name##_info; \ \ name##_i = 0; \ for_each_child_of_node(name##_node, name##_np) { \ name##_info = info->name##_info + name##_i; \ \ if (name##_np == playback) \ dai_info->playback.name = name##_info; \ if (name##_np == capture) \ dai_info->capture.name = name##_info; \ \ name##_i++; \ } \ } /* * parse all dai */ dai_i = 0; for_each_child_of_node(dai_node, dai_np) { dai_info = info->dai_info + dai_i; for (i = 0;; i++) { playback = of_parse_phandle(dai_np, "playback", i); capture = of_parse_phandle(dai_np, "capture", i); if (!playback && !capture) break; mod_parse(ssi); mod_parse(src); if (playback) of_node_put(playback); if (capture) of_node_put(capture); } dai_i++; } } static int rsnd_dai_probe(struct platform_device *pdev, static int rsnd_dai_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) struct rsnd_priv *priv) { { struct snd_soc_dai_driver *drv; struct snd_soc_dai_driver *drv; Loading @@ -628,13 +728,16 @@ static int rsnd_dai_probe(struct platform_device *pdev, struct rsnd_dai *rdai; struct rsnd_dai *rdai; struct rsnd_mod *pmod, *cmod; struct rsnd_mod *pmod, *cmod; struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv); int dai_nr = info->dai_info_nr; int dai_nr; int i; int i; rsnd_of_parse_dai(pdev, of_data, priv); /* /* * dai_nr should be set via dai_info_nr, * dai_nr should be set via dai_info_nr, * but allow it to keeping compatible * but allow it to keeping compatible */ */ dai_nr = info->dai_info_nr; if (!dai_nr) { if (!dai_nr) { /* get max dai nr */ /* get max dai nr */ for (dai_nr = 0; dai_nr < 32; dai_nr++) { for (dai_nr = 0; dai_nr < 32; dai_nr++) { Loading Loading @@ -802,7 +905,10 @@ static int rsnd_probe(struct platform_device *pdev) struct rsnd_priv *priv; struct rsnd_priv *priv; struct device *dev = &pdev->dev; struct device *dev = &pdev->dev; struct rsnd_dai *rdai; struct rsnd_dai *rdai; const struct of_device_id *of_id = of_match_device(rsnd_of_match, dev); const struct rsnd_of_data *of_data; int (*probe_func[])(struct platform_device *pdev, int (*probe_func[])(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) = { struct rsnd_priv *priv) = { rsnd_gen_probe, rsnd_gen_probe, rsnd_ssi_probe, rsnd_ssi_probe, Loading @@ -812,7 +918,16 @@ static int rsnd_probe(struct platform_device *pdev) }; }; int ret, i; int ret, i; info = NULL; of_data = NULL; if (of_id) { info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info), GFP_KERNEL); of_data = of_id->data; } else { info = pdev->dev.platform_data; info = pdev->dev.platform_data; } if (!info) { if (!info) { dev_err(dev, "driver needs R-Car sound information\n"); dev_err(dev, "driver needs R-Car sound information\n"); return -ENODEV; return -ENODEV; Loading @@ -835,7 +950,7 @@ static int rsnd_probe(struct platform_device *pdev) * init each module * init each module */ */ for (i = 0; i < ARRAY_SIZE(probe_func); i++) { for (i = 0; i < ARRAY_SIZE(probe_func); i++) { ret = probe_func[i](pdev, priv); ret = probe_func[i](pdev, of_data, priv); if (ret) if (ret) return ret; return ret; } } Loading Loading @@ -903,6 +1018,7 @@ static int rsnd_remove(struct platform_device *pdev) static struct platform_driver rsnd_driver = { static struct platform_driver rsnd_driver = { .driver = { .driver = { .name = "rcar_sound", .name = "rcar_sound", .of_match_table = rsnd_of_match, }, }, .probe = rsnd_probe, .probe = rsnd_probe, .remove = rsnd_remove, .remove = rsnd_remove, Loading
sound/soc/sh/rcar/gen.c +15 −0 Original line number Original line Diff line number Diff line Loading @@ -359,13 +359,28 @@ static int rsnd_gen1_probe(struct platform_device *pdev, /* /* * Gen * Gen */ */ static void rsnd_of_parse_gen(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) { struct rcar_snd_info *info = priv->info; if (!of_data) return; info->flags = of_data->flags; } int rsnd_gen_probe(struct platform_device *pdev, int rsnd_gen_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv) struct rsnd_priv *priv) { { struct device *dev = rsnd_priv_to_dev(priv); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_gen *gen; struct rsnd_gen *gen; int ret; int ret; rsnd_of_parse_gen(pdev, of_data, priv); gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); if (!gen) { if (!gen) { dev_err(dev, "GEN allocate failed\n"); dev_err(dev, "GEN allocate failed\n"); Loading
sound/soc/sh/rcar/rsnd.h +11 −0 Original line number Original line Diff line number Diff line Loading @@ -17,6 +17,8 @@ #include <linux/io.h> #include <linux/io.h> #include <linux/list.h> #include <linux/list.h> #include <linux/module.h> #include <linux/module.h> #include <linux/of_device.h> #include <linux/of_irq.h> #include <linux/sh_dma.h> #include <linux/sh_dma.h> #include <linux/workqueue.h> #include <linux/workqueue.h> #include <sound/rcar_snd.h> #include <sound/rcar_snd.h> Loading Loading @@ -113,6 +115,7 @@ enum rsnd_reg { #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 #define RSND_REG_SRCOUT_TIMSEL4 RSND_REG_SHARE18 #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 #define RSND_REG_AUDIO_CLK_SEL2 RSND_REG_SHARE19 struct rsnd_of_data; struct rsnd_priv; struct rsnd_priv; struct rsnd_mod; struct rsnd_mod; struct rsnd_dai; struct rsnd_dai; Loading Loading @@ -260,6 +263,7 @@ int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); * R-Car Gen1/Gen2 * R-Car Gen1/Gen2 */ */ int rsnd_gen_probe(struct platform_device *pdev, int rsnd_gen_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_mod *mod, Loading @@ -273,6 +277,7 @@ void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); int rsnd_adg_ssi_clk_stop(struct rsnd_mod *mod); int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); int rsnd_adg_ssi_clk_try_start(struct rsnd_mod *mod, unsigned int rate); int rsnd_adg_probe(struct platform_device *pdev, int rsnd_adg_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv, struct rsnd_mod *mod, struct rsnd_mod *mod, Loading @@ -290,6 +295,10 @@ int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod, /* /* * R-Car sound priv * R-Car sound priv */ */ struct rsnd_of_data { u32 flags; }; struct rsnd_priv { struct rsnd_priv { struct device *dev; struct device *dev; Loading Loading @@ -348,6 +357,7 @@ struct rsnd_priv { * R-Car SRC * R-Car SRC */ */ int rsnd_src_probe(struct platform_device *pdev, int rsnd_src_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id); unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, Loading @@ -366,6 +376,7 @@ int rsnd_src_enable_ssi_irq(struct rsnd_mod *ssi_mod, * R-Car SSI * R-Car SSI */ */ int rsnd_ssi_probe(struct platform_device *pdev, int rsnd_ssi_probe(struct platform_device *pdev, const struct rsnd_of_data *of_data, struct rsnd_priv *priv); struct rsnd_priv *priv); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_ssi_mod_get(struct rsnd_priv *priv, int id); struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, struct rsnd_mod *rsnd_ssi_mod_get_frm_dai(struct rsnd_priv *priv, Loading