From: Mark Brown Date: Wed, 23 Dec 2015 00:23:46 +0000 (+0000) Subject: Merge remote-tracking branches 'asoc/topic/pxa', 'asoc/topic/qcom', 'asoc/topic/rcar... X-Git-Tag: Ubuntu-4.10.0-19.21~4121^2~26^2~1^2~4 X-Git-Url: https://git.proxmox.com/?a=commitdiff_plain;h=81b6863cae0ca371ebe8bd176548be4d2741e6bb;p=mirror_ubuntu-artful-kernel.git Merge remote-tracking branches 'asoc/topic/pxa', 'asoc/topic/qcom', 'asoc/topic/rcar', 'asoc/topic/rk3036' and 'asoc/topic/rockchip' into asoc-next --- 81b6863cae0ca371ebe8bd176548be4d2741e6bb diff --cc sound/soc/codecs/Kconfig index 08433a8d9d40,cfdafc4c11ea,0c9733ecd17f,cfdafc4c11ea,89d789e3a2d0,cfdafc4c11ea..784468e1cbad --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@@@@@@ -59,8 -58,7 -57,6 -58,7 -58,7 -58,7 +59,8 @@@@@@@ config SND_SOC_ALL_CODEC select SND_SOC_CX20442 if TTY select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI select SND_SOC_DA7213 if I2C +++++ select SND_SOC_DA7218 if I2C + select SND_SOC_DA7219 if I2C select SND_SOC_DA732X if I2C select SND_SOC_DA9055 if I2C select SND_SOC_DMIC @@@@@@@ -68,8 -66,7 -64,7 -66,7 -66,8 -66,7 +68,9 @@@@@@@ select SND_SOC_ES8328_SPI if SPI_MASTER select SND_SOC_ES8328_I2C if I2C select SND_SOC_GTM601 +++++ select SND_SOC_HDAC_HDMI select SND_SOC_ICS43432 ++++ + select SND_SOC_INNO_RK3036 select SND_SOC_ISABELLE if I2C select SND_SOC_JZ4740_CODEC select SND_SOC_LM4857 if I2C @@@@@@@ -204,8 -198,7 -195,6 -198,7 -199,7 -198,7 +205,8 @@@@@@@ config SND_SOC_ARIZON default y if SND_SOC_WM5102=y default y if SND_SOC_WM5110=y default y if SND_SOC_WM8997=y + default y if SND_SOC_WM8998=y +++++ default m if SND_SOC_CS47L24=m default m if SND_SOC_WM5102=m default m if SND_SOC_WM5110=m default m if SND_SOC_WM8997=m @@@@@@@ -452,12 -439,9 -430,6 -439,9 -440,9 -439,9 +453,12 @@@@@@@ config SND_SOC_DA721 config SND_SOC_DA7213 tristate +++++config SND_SOC_DA7218 +++++ tristate +++++ + config SND_SOC_DA7219 + tristate + config SND_SOC_DA732X tristate diff --cc sound/soc/codecs/Makefile index fdf5b3146774,f632fc42f59f,4a32077954ae,f632fc42f59f,2f6bc6c01178,f632fc42f59f..44d8958bd032 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@@@@@@ -51,8 -50,7 -49,6 -50,7 -50,7 -50,7 +51,8 @@@@@@@ snd-soc-cs47l24-objs := cs47l24. snd-soc-cx20442-objs := cx20442.o snd-soc-da7210-objs := da7210.o snd-soc-da7213-objs := da7213.o +++++snd-soc-da7218-objs := da7218.o + snd-soc-da7219-objs := da7219.o da7219-aad.o snd-soc-da732x-objs := da732x.o snd-soc-da9055-objs := da9055.o snd-soc-bt-sco-objs := bt-sco.o @@@@@@@ -61,8 -59,7 -57,7 -59,7 -59,8 -59,7 +61,9 @@@@@@@ snd-soc-es8328-objs := es8328. snd-soc-es8328-i2c-objs := es8328-i2c.o snd-soc-es8328-spi-objs := es8328-spi.o snd-soc-gtm601-objs := gtm601.o +++++snd-soc-hdac-hdmi-objs := hdac_hdmi.o snd-soc-ics43432-objs := ics43432.o ++++ +snd-soc-inno-rk3036-objs := inno_rk3036.o snd-soc-isabelle-objs := isabelle.o snd-soc-jz4740-codec-objs := jz4740.o snd-soc-l3-objs := l3.o @@@@@@@ -252,8 -245,7 -241,6 -245,7 -246,7 -245,7 +253,8 @@@@@@@ obj-$(CONFIG_SND_SOC_CS47L24) += snd-so obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o obj-$(CONFIG_SND_SOC_DA7213) += snd-soc-da7213.o +++++obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o + obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o @@@@@@@ -262,8 -254,7 -249,7 -254,7 -255,8 -254,7 +263,9 @@@@@@@ obj-$(CONFIG_SND_SOC_ES8328) += snd-soc obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o obj-$(CONFIG_SND_SOC_ES8328_SPI)+= snd-soc-es8328-spi.o obj-$(CONFIG_SND_SOC_GTM601) += snd-soc-gtm601.o +++++obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o ++++ +obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o diff --cc sound/soc/sh/rcar/core.c index e1da5654fa25,deed48ef28b8,f3feed5ce9b6,ca05a0a95a4d,deed48ef28b8,deed48ef28b8..02b4b085b8d7 --- a/sound/soc/sh/rcar/core.c +++ b/sound/soc/sh/rcar/core.c @@@@@@@ -99,48 -99,48 -99,36 -99,28 -99,48 -99,48 +99,28 @@@@@@@ #define RSND_RATES SNDRV_PCM_RATE_8000_96000 #define RSND_FMTS (SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE) --- --static const struct rsnd_of_data rsnd_of_data_gen1 = { --- -- .flags = RSND_GEN1, --- --}; --- -- --- --static const struct rsnd_of_data rsnd_of_data_gen2 = { --- -- .flags = RSND_GEN2, --- --}; --- -- static const 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 }, -- -- { .compatible = "renesas,rcar_sound-gen3", .data = &rsnd_of_data_gen2 }, /* gen2 compatible */ +++ ++ { .compatible = "renesas,rcar_sound-gen1", .data = (void *)RSND_GEN1 }, +++ ++ { .compatible = "renesas,rcar_sound-gen2", .data = (void *)RSND_GEN2 }, +++ ++ { .compatible = "renesas,rcar_sound-gen3", .data = (void *)RSND_GEN2 }, /* gen2 compatible */ {}, }; MODULE_DEVICE_TABLE(of, rsnd_of_match); /* --- -- * rsnd_platform functions +++ ++ * rsnd_mod functions */ --- --#define rsnd_platform_call(priv, dai, func, param...) \ --- -- (!(priv->info->func) ? 0 : \ --- -- priv->info->func(param)) -- -- -- --#define rsnd_is_enable_path(io, name) \ -- -- ((io)->info ? (io)->info->name : NULL) -- --#define rsnd_info_id(priv, io, name) \ -- -- ((io)->info->name - priv->info->name##_info) -- -- + void rsnd_mod_make_sure(struct rsnd_mod *mod, enum rsnd_mod_type type) + { + if (mod->type != type) { + struct rsnd_priv *priv = rsnd_mod_to_priv(mod); + struct device *dev = rsnd_priv_to_dev(priv); - #define rsnd_is_enable_path(io, name) \ - ((io)->info ? (io)->info->name : NULL) - #define rsnd_info_id(priv, io, name) \ - ((io)->info->name - priv->info->name##_info) + dev_warn(dev, "%s[%d] is not your expected module\n", + rsnd_mod_name(mod), rsnd_mod_id(mod)); + } + } --- --/* --- -- * rsnd_mod functions --- -- */ char *rsnd_mod_name(struct rsnd_mod *mod) { if (!mod || !mod->ops) @@@@@@@ -300,22 -300,22 -288,24 -319,24 -300,22 -300,22 +319,24 @@@@@@@ u32 rsnd_get_dalign(struct rsnd_mod *mo /* * rsnd_dai functions */ -- --#define rsnd_mod_call(mod, io, func, param...) \ - #define __rsnd_mod_call(mod, io, func, param...) \ +++ ++#define rsnd_mod_call(idx, io, func, param...) \ ({ \ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); \ +++ ++ struct rsnd_mod *mod = (io)->mod[idx]; \ struct device *dev = rsnd_priv_to_dev(priv); \ +++ ++ u32 *status = (io)->mod_status + idx; \ u32 mask = 0xF << __rsnd_mod_shift_##func; \ --- -- u8 val = (mod->status >> __rsnd_mod_shift_##func) & 0xF; \ +++ ++ u8 val = (*status >> __rsnd_mod_shift_##func) & 0xF; \ u8 add = ((val + __rsnd_mod_add_##func) & 0xF); \ int ret = 0; \ - int called = 0; \ - if (val == __rsnd_mod_call_##func) { \ - called = 1; \ - ret = (mod)->ops->func(mod, io, param); \ - } \ - mod->status = (mod->status & ~mask) + \ + int call = (val == __rsnd_mod_call_##func) && (mod)->ops->func; \ -- -- mod->status = (mod->status & ~mask) + \ +++ ++ *status = (*status & ~mask) + \ (add << __rsnd_mod_shift_##func); \ - dev_dbg(dev, "%s[%d] 0x%08x %s\n", \ - rsnd_mod_name(mod), rsnd_mod_id(mod), mod->status, \ - called ? #func : ""); \ + dev_dbg(dev, "%s[%d]\t0x%08x %s\n", \ + rsnd_mod_name(mod), rsnd_mod_id(mod), \ -- -- mod->status, call ? #func : ""); \ +++ ++ *status, call ? #func : ""); \ + if (call) \ + ret = (mod)->ops->func(mod, io, param); \ ret; \ }) @@@@@@@ -327,7 -327,7 -322,9 -348,7 -327,7 -327,7 +348,7 @@@@@@@ mod = (io)->mod[i]; \ if (!mod) \ continue; \ -- -- ret |= rsnd_mod_call(mod, io, fn, param); \ - ret = rsnd_mod_call(mod, io, fn, param); \ - if (ret < 0) \ - break; \ +++ ++ ret |= rsnd_mod_call(i, io, fn, param); \ } \ ret; \ }) @@@@@@@ -493,11 -493,11 -490,17 -514,9 -493,11 -493,11 +514,9 @@@@@@@ static int rsnd_soc_dai_trigger(struct break; case SNDRV_PCM_TRIGGER_STOP: ret = rsnd_dai_call(stop, io, priv); - if (ret < 0) - goto dai_trigger_end; - - ret = rsnd_dai_call(quit, io, priv); - if (ret < 0) - goto dai_trigger_end; - ret = rsnd_platform_call(priv, dai, stop, ssi_id); - if (ret < 0) - goto dai_trigger_end; + ret |= rsnd_dai_call(quit, io, priv); -- -- ret |= rsnd_platform_call(priv, dai, stop, ssi_id); -- -- rsnd_dai_stream_quit(io); break; default: @@@@@@@ -567,220 -567,220 -570,220 -586,90 -567,220 -567,220 +586,90 @@@@@@@ static int rsnd_soc_dai_set_fmt(struct return 0; } --- --static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { --- -- .trigger = rsnd_soc_dai_trigger, --- -- .set_fmt = rsnd_soc_dai_set_fmt, --- --}; --- -- --- --#define rsnd_path_add(priv, io, type) \ --- --({ \ --- -- struct rsnd_mod *mod; \ --- -- int ret = 0; \ --- -- int id = -1; \ --- -- \ --- -- if (rsnd_is_enable_path(io, type)) { \ --- -- id = rsnd_info_id(priv, io, type); \ --- -- if (id >= 0) { \ --- -- mod = rsnd_##type##_mod_get(priv, id); \ --- -- ret = rsnd_dai_connect(mod, io); \ --- -- } \ --- -- } \ --- -- ret; \ --- --}) --- -- --- --#define rsnd_path_remove(priv, io, type) \ --- --{ \ --- -- struct rsnd_mod *mod; \ --- -- int id = -1; \ --- -- \ --- -- if (rsnd_is_enable_path(io, type)) { \ --- -- id = rsnd_info_id(priv, io, type); \ --- -- if (id >= 0) { \ --- -- mod = rsnd_##type##_mod_get(priv, id); \ --- -- rsnd_dai_disconnect(mod, io); \ --- -- } \ --- -- } \ --- --} --- -- --- --void rsnd_path_parse(struct rsnd_priv *priv, --- -- struct rsnd_dai_stream *io) +++ ++static int rsnd_soc_set_dai_tdm_slot(struct snd_soc_dai *dai, +++ ++ u32 tx_mask, u32 rx_mask, +++ ++ int slots, int slot_width) { --- -- struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); --- -- struct rsnd_mod *mix = rsnd_io_to_mod_mix(io); --- -- struct rsnd_mod *src = rsnd_io_to_mod_src(io); --- -- struct rsnd_mod *cmd; +++ ++ struct rsnd_priv *priv = rsnd_dai_to_priv(dai); +++ ++ struct rsnd_dai *rdai = rsnd_dai_to_rdai(dai); struct device *dev = rsnd_priv_to_dev(priv); --- -- u32 data; - - /* Gen1 is not supported */ - if (rsnd_is_gen1(priv)) - return; - - if (!mix && !dvc) - return; - - if (mix) { - struct rsnd_dai *rdai; - int i; - u32 path[] = { - [0] = 0, - [1] = 1 << 0, - [2] = 0, - [3] = 0, - [4] = 0, - [5] = 1 << 8 - }; - - /* - * it is assuming that integrater is well understanding about - * data path. Here doesn't check impossible connection, - * like src2 + src5 - */ - data = 0; - for_each_rsnd_dai(rdai, priv, i) { - io = &rdai->playback; - if (mix == rsnd_io_to_mod_mix(io)) - data |= path[rsnd_mod_id(src)]; - - io = &rdai->capture; - if (mix == rsnd_io_to_mod_mix(io)) - data |= path[rsnd_mod_id(src)]; - } -- -- /* Gen1 is not supported */ -- -- if (rsnd_is_gen1(priv)) -- -- return; -- -- -- -- if (!mix && !dvc) -- -- return; -- -- -- -- if (mix) { -- -- struct rsnd_dai *rdai; -- -- int i; -- -- u32 path[] = { -- -- [0] = 0, -- -- [1] = 1 << 0, -- -- [2] = 0, -- -- [3] = 0, -- -- [4] = 0, -- -- [5] = 1 << 8 -- -- }; -- -- -- -- /* -- -- * it is assuming that integrater is well understanding about -- -- * data path. Here doesn't check impossible connection, -- -- * like src2 + src5 -- -- */ -- -- data = 0; -- -- for_each_rsnd_dai(rdai, priv, i) { -- -- io = &rdai->playback; -- -- if (mix == rsnd_io_to_mod_mix(io)) -- -- data |= path[rsnd_mod_id(src)]; -- -- -- -- io = &rdai->capture; -- -- if (mix == rsnd_io_to_mod_mix(io)) -- -- data |= path[rsnd_mod_id(src)]; -- -- } -- -- --- -- /* --- -- * We can't use ctu = rsnd_io_ctu() here. --- -- * Since, ID of dvc/mix are 0 or 1 (= same as CMD number) --- -- * but ctu IDs are 0 - 7 (= CTU00 - CTU13) --- -- */ --- -- cmd = mix; --- -- } else { --- -- u32 path[] = { --- -- [0] = 0x30000, --- -- [1] = 0x30001, --- -- [2] = 0x40000, --- -- [3] = 0x10000, --- -- [4] = 0x20000, --- -- [5] = 0x40100 --- -- }; --- -- --- -- data = path[rsnd_mod_id(src)]; --- -- --- -- cmd = dvc; +++ ++ switch (slots) { +++ ++ case 6: +++ ++ /* TDM Extend Mode */ +++ ++ rsnd_set_slot(rdai, slots, 1); +++ ++ break; +++ ++ default: +++ ++ dev_err(dev, "unsupported TDM slots (%d)\n", slots); +++ ++ return -EINVAL; } --- -- dev_dbg(dev, "ctu/mix path = 0x%08x", data); --- -- --- -- rsnd_mod_write(cmd, CMD_ROUTE_SLCT, data); --- -- --- -- rsnd_mod_write(cmd, CMD_CTRL, 0x10); +++ ++ return 0; } --- --static int rsnd_path_init(struct rsnd_priv *priv, --- -- struct rsnd_dai *rdai, --- -- struct rsnd_dai_stream *io) --- --{ --- -- int ret; --- -- --- -- /* --- -- * Gen1 is created by SRU/SSI, and this SRU is base module of --- -- * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU) --- -- * --- -- * Easy image is.. --- -- * Gen1 SRU = Gen2 SCU + SSIU + etc --- -- * --- -- * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is --- -- * using fixed path. --- -- */ --- -- --- -- /* SSI */ --- -- ret = rsnd_path_add(priv, io, ssi); --- -- if (ret < 0) --- -- return ret; --- -- --- -- /* SRC */ --- -- ret = rsnd_path_add(priv, io, src); --- -- if (ret < 0) --- -- return ret; +++ ++static const struct snd_soc_dai_ops rsnd_soc_dai_ops = { +++ ++ .trigger = rsnd_soc_dai_trigger, +++ ++ .set_fmt = rsnd_soc_dai_set_fmt, +++ ++ .set_tdm_slot = rsnd_soc_set_dai_tdm_slot, +++ ++}; --- -- /* CTU */ --- -- ret = rsnd_path_add(priv, io, ctu); --- -- if (ret < 0) --- -- return ret; +++ ++void rsnd_parse_connect_common(struct rsnd_dai *rdai, +++ ++ struct rsnd_mod* (*mod_get)(struct rsnd_priv *priv, int id), +++ ++ struct device_node *node, +++ ++ struct device_node *playback, +++ ++ struct device_node *capture) +++ ++{ +++ ++ struct rsnd_priv *priv = rsnd_rdai_to_priv(rdai); +++ ++ struct device_node *np; +++ ++ struct rsnd_mod *mod; +++ ++ int i; --- -- /* MIX */ --- -- ret = rsnd_path_add(priv, io, mix); --- -- if (ret < 0) --- -- return ret; +++ ++ if (!node) +++ ++ return; --- -- /* DVC */ --- -- ret = rsnd_path_add(priv, io, dvc); --- -- if (ret < 0) --- -- return ret; +++ ++ i = 0; +++ ++ for_each_child_of_node(node, np) { +++ ++ mod = mod_get(priv, i); +++ ++ if (np == playback) +++ ++ rsnd_dai_connect(mod, &rdai->playback, mod->type); +++ ++ if (np == capture) +++ ++ rsnd_dai_connect(mod, &rdai->capture, mod->type); +++ ++ i++; +++ ++ } --- -- return ret; +++ ++ of_node_put(node); } --- --static void rsnd_of_parse_dai(struct platform_device *pdev, --- -- const struct rsnd_of_data *of_data, --- -- struct rsnd_priv *priv) +++ ++static int rsnd_dai_probe(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 *ctu_node, *ctu_np; --- -- struct device_node *mix_node, *mix_np; --- -- struct device_node *dvc_node, *dvc_np; +++ ++ struct device_node *dai_node; +++ ++ struct device_node *dai_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, ctu_i, mix_i, dvc_i; --- -- --- -- if (!of_data) --- -- return; --- -- --- -- dai_node = of_get_child_by_name(dev->of_node, "rcar_sound,dai"); --- -- if (!dai_node) --- -- return; +++ ++ struct rsnd_dai_stream *io_playback; +++ ++ struct rsnd_dai_stream *io_capture; +++ ++ struct snd_soc_dai_driver *rdrv, *drv; +++ ++ struct rsnd_dai *rdai; +++ ++ struct device *dev = rsnd_priv_to_dev(priv); +++ ++ int nr, dai_i, io_i; +++ ++ int ret; +++ ++ dai_node = rsnd_dai_of_node(priv); nr = of_get_child_count(dai_node); --- -- if (!nr) --- -- return; +++ ++ if (!nr) { +++ ++ ret = -EINVAL; +++ ++ goto rsnd_dai_probe_done; +++ ++ } --- -- 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; +++ ++ rdrv = devm_kzalloc(dev, sizeof(*rdrv) * nr, GFP_KERNEL); +++ ++ rdai = devm_kzalloc(dev, sizeof(*rdai) * nr, GFP_KERNEL); +++ ++ if (!rdrv || !rdai) { +++ ++ ret = -ENOMEM; +++ ++ goto rsnd_dai_probe_done; } --- -- 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"); --- -- ctu_node = of_get_child_by_name(dev->of_node, "rcar_sound,ctu"); --- -- mix_node = of_get_child_by_name(dev->of_node, "rcar_sound,mix"); --- -- dvc_node = of_get_child_by_name(dev->of_node, "rcar_sound,dvc"); --- -- --- --#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++; \ --- -- } \ --- --} +++ ++ priv->rdai_nr = nr; +++ ++ priv->daidrv = rdrv; +++ ++ priv->rdai = rdai; /* * parse all dai @@@@@@@ -808,91 -808,91 -811,91 -725,18 -808,91 -808,91 +725,18 @@@@@@@ } dai_i++; --- -- } --- --} --- -- --- --static int rsnd_dai_probe(struct platform_device *pdev, --- -- const struct rsnd_of_data *of_data, --- -- struct rsnd_priv *priv) --- --{ --- -- struct snd_soc_dai_driver *drv; --- -- struct rcar_snd_info *info = rsnd_priv_to_info(priv); --- -- struct rsnd_dai *rdai; --- -- struct rsnd_ssi_platform_info *pmod, *cmod; --- -- struct device *dev = rsnd_priv_to_dev(priv); --- -- int dai_nr; --- -- int i; -- -- -- -- rsnd_of_parse_dai(pdev, of_data, priv); - rsnd_of_parse_dai(pdev, of_data, priv); - --- -- dai_nr = info->dai_info_nr; --- -- if (!dai_nr) { --- -- dev_err(dev, "no dai\n"); --- -- return -EIO; +++ ++ dev_dbg(dev, "%s (%s/%s)\n", rdai->name, +++ ++ rsnd_io_to_mod_ssi(io_playback) ? "play" : " -- ", +++ ++ rsnd_io_to_mod_ssi(io_capture) ? "capture" : " -- "); } --- -- drv = devm_kzalloc(dev, sizeof(*drv) * dai_nr, GFP_KERNEL); --- -- rdai = devm_kzalloc(dev, sizeof(*rdai) * dai_nr, GFP_KERNEL); --- -- if (!drv || !rdai) { --- -- dev_err(dev, "dai allocate failed\n"); --- -- return -ENOMEM; --- -- } --- -- --- -- priv->rdai_nr = dai_nr; --- -- priv->daidrv = drv; --- -- priv->rdai = rdai; +++ ++ ret = 0; --- -- for (i = 0; i < dai_nr; i++) { +++ ++rsnd_dai_probe_done: +++ ++ of_node_put(dai_node); --- -- pmod = info->dai_info[i].playback.ssi; --- -- cmod = info->dai_info[i].capture.ssi; --- -- --- -- /* --- -- * init rsnd_dai --- -- */ --- -- snprintf(rdai[i].name, RSND_DAI_NAME_SIZE, "rsnd-dai.%d", i); --- -- rdai[i].priv = priv; --- -- --- -- /* --- -- * init snd_soc_dai_driver --- -- */ --- -- drv[i].name = rdai[i].name; --- -- drv[i].ops = &rsnd_soc_dai_ops; --- -- if (pmod) { --- -- snprintf(rdai[i].playback.name, RSND_DAI_NAME_SIZE, --- -- "DAI%d Playback", i); --- -- --- -- drv[i].playback.rates = RSND_RATES; --- -- drv[i].playback.formats = RSND_FMTS; --- -- drv[i].playback.channels_min = 2; --- -- drv[i].playback.channels_max = 2; --- -- drv[i].playback.stream_name = rdai[i].playback.name; --- -- --- -- rdai[i].playback.info = &info->dai_info[i].playback; --- -- rdai[i].playback.rdai = rdai + i; --- -- rsnd_path_init(priv, &rdai[i], &rdai[i].playback); --- -- } --- -- if (cmod) { --- -- snprintf(rdai[i].capture.name, RSND_DAI_NAME_SIZE, --- -- "DAI%d Capture", i); --- -- --- -- drv[i].capture.rates = RSND_RATES; --- -- drv[i].capture.formats = RSND_FMTS; --- -- drv[i].capture.channels_min = 2; --- -- drv[i].capture.channels_max = 2; --- -- drv[i].capture.stream_name = rdai[i].capture.name; --- -- --- -- rdai[i].capture.info = &info->dai_info[i].capture; --- -- rdai[i].capture.rdai = rdai + i; --- -- rsnd_path_init(priv, &rdai[i], &rdai[i].capture); --- -- } --- -- --- -- dev_dbg(dev, "%s (%s/%s)\n", rdai[i].name, --- -- pmod ? "play" : " -- ", --- -- cmod ? "capture" : " -- "); --- -- } --- -- --- -- return 0; +++ ++ return ret; } /* @@@@@@@ -1220,12 -1221,12 -1224,21 -1072,6 -1221,12 -1221,12 +1071,6 @@@@@@@ static int rsnd_probe(struct platform_d }; int ret, i; -- -- info = devm_kzalloc(&pdev->dev, sizeof(struct rcar_snd_info), -- -- GFP_KERNEL); -- -- if (!info) -- -- return -ENOMEM; -- -- of_data = of_id->data; - 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; - } - - if (!info) { - dev_err(dev, "driver needs R-Car sound information\n"); - return -ENODEV; - } --- -- /* * init priv data */ diff --cc sound/soc/sh/rcar/gen.c index edcf4cc2e84f,76da7620904c,f04d17bc6e3d,c7aee9e59e86,76da7620904c,76da7620904c..ea24247eba73 --- a/sound/soc/sh/rcar/gen.c +++ b/sound/soc/sh/rcar/gen.c @@@@@@@ -22,15 -22,15 -22,13 -22,16 -22,15 -22,15 +22,16 @@@@@@@ #include "rsnd.h" struct rsnd_gen { - void __iomem *base[RSND_BASE_MAX]; - struct rsnd_gen_ops *ops; + /* RSND_BASE_MAX base */ + void __iomem *base[RSND_BASE_MAX]; + phys_addr_t res[RSND_BASE_MAX]; struct regmap *regmap[RSND_BASE_MAX]; + + /* RSND_REG_MAX base */ struct regmap_field *regs[RSND_REG_MAX]; - phys_addr_t res[RSND_REG_MAX]; +++ ++ const char *reg_name[RSND_REG_MAX]; }; #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) @@@@@@@ -81,11 -81,11 -79,11 -85,12 -81,11 -81,11 +85,12 @@@@@@@ u32 rsnd_read(struct rsnd_priv *priv if (!rsnd_is_accessible_reg(priv, gen, reg)) return 0; - dev_dbg(dev, "r %s[%d] - %4d : %08x\n", - rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); - regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); -- -- dev_dbg(dev, "r %s[%d] - %4d : %08x\n", -- -- rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); +++ ++ dev_dbg(dev, "r %s[%d] - %-18s (%4d) : %08x\n", +++ ++ rsnd_mod_name(mod), rsnd_mod_id(mod), +++ ++ rsnd_reg_name(gen, reg), reg, val); + return val; } @@@@@@@ -201,8 -201,8 -198,7 -210,9 -201,8 -201,8 +210,9 @@@@@@@ static int _rsnd_gen_regmap_init(struc if (IS_ERR(regs)) return PTR_ERR(regs); + /* RSND_REG_MAX base */ gen->regs[conf[i].idx] = regs; +++ ++ gen->reg_name[conf[i].idx] = conf[i].reg_name; } return 0; diff --cc sound/soc/sh/rcar/src.c index 68b439ed22d7,261b50217c48,89a18e102feb,b438538a0a69,261b50217c48,261b50217c48..5eda056d9f20 --- a/sound/soc/sh/rcar/src.c +++ b/sound/soc/sh/rcar/src.c @@@@@@@ -143,99 -143,99 -143,99 -93,6 -143,99 -143,99 +93,6 @@@@@@@ static struct dma_chan *rsnd_src_dma_re is_play ? "rx" : "tx"); } --- --int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, --- -- struct rsnd_dai_stream *io, --- -- int use_busif) --- --{ --- -- struct rsnd_dai *rdai = rsnd_io_to_rdai(io); --- -- int ssi_id = rsnd_mod_id(ssi_mod); --- -- --- -- /* --- -- * SSI_MODE0 --- -- */ --- -- rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), --- -- !use_busif << ssi_id); --- -- --- -- /* --- -- * SSI_MODE1 --- -- */ -- -- if (rsnd_ssi_is_pin_sharing(io)) { - if (rsnd_ssi_is_pin_sharing(ssi_mod)) { --- -- int shift = -1; --- -- switch (ssi_id) { --- -- case 1: --- -- shift = 0; --- -- break; --- -- case 2: --- -- shift = 2; --- -- break; --- -- case 4: --- -- shift = 16; --- -- break; --- -- } --- -- --- -- if (shift >= 0) --- -- rsnd_mod_bset(ssi_mod, SSI_MODE1, --- -- 0x3 << shift, --- -- rsnd_rdai_is_clk_master(rdai) ? --- -- 0x2 << shift : 0x1 << shift); --- -- } --- -- --- -- /* --- -- * DMA settings for SSIU --- -- */ --- -- if (use_busif) { --- -- u32 val = rsnd_get_dalign(ssi_mod, io); --- -- --- -- rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, --- -- rsnd_get_adinr_bit(ssi_mod, io)); --- -- rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); --- -- rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); --- -- --- -- rsnd_mod_write(ssi_mod, SSI_BUSIF_DALIGN, val); --- -- } --- -- --- -- return 0; --- --} --- -- --- --int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, --- -- struct rsnd_dai_stream *io) --- --{ --- -- /* --- -- * DMA settings for SSIU --- -- */ --- -- rsnd_mod_write(ssi_mod, SSI_CTRL, 0); --- -- --- -- return 0; --- --} --- -- --- --int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod) --- --{ --- -- struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); --- -- --- -- if (rsnd_is_gen1(priv)) --- -- return 0; --- -- --- -- /* enable SSI interrupt if Gen2 */ --- -- rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, --- -- rsnd_ssi_is_dma_mode(ssi_mod) ? --- -- 0x0e000000 : 0x0f000000); --- -- --- -- return 0; --- --} --- -- --- --int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) --- --{ --- -- struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); --- -- --- -- if (rsnd_is_gen1(priv)) --- -- return 0; --- -- --- -- /* disable SSI interrupt if Gen2 */ --- -- rsnd_mod_write(ssi_mod, SSI_INT_ENABLE, 0x00000000); --- -- --- -- return 0; --- --} --- -- static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, struct rsnd_src *src) { @@@@@@@ -347,151 -347,151 -347,151 -173,80 -347,151 -347,151 +173,80 @@@@@@@ static int rsnd_src_hw_params(struct rs return 0; } --- --static int rsnd_src_init(struct rsnd_mod *mod, --- -- struct rsnd_priv *priv) --- --{ --- -- struct rsnd_src *src = rsnd_mod_to_src(mod); --- -- -- -- rsnd_mod_power_on(mod); - rsnd_mod_hw_start(mod); --- -- --- -- rsnd_src_soft_reset(mod); --- -- --- -- rsnd_src_initialize_lock(mod); --- -- --- -- src->err = 0; --- -- --- -- /* reset sync convert_rate */ --- -- src->sync.val = 0; --- -- --- -- return 0; --- --} --- -- --- --static int rsnd_src_quit(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io, --- -- struct rsnd_priv *priv) +++ ++static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, +++ ++ struct rsnd_mod *mod) { --- -- struct rsnd_src *src = rsnd_mod_to_src(mod); +++ ++ struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct device *dev = rsnd_priv_to_dev(priv); +++ ++ struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); +++ ++ struct rsnd_src *src = rsnd_mod_to_src(mod); +++ ++ u32 convert_rate = rsnd_src_convert_rate(io, src); +++ ++ u32 ifscr, fsrate, adinr; +++ ++ u32 cr, route; +++ ++ u32 bsdsr, bsisr; +++ ++ uint ratio; -- -- rsnd_mod_power_off(mod); - rsnd_mod_hw_stop(mod); --- -- --- -- if (src->err) --- -- dev_warn(dev, "%s[%d] under/over flow err = %d\n", --- -- rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); --- -- --- -- src->convert_rate = 0; --- -- --- -- /* reset sync convert_rate */ --- -- src->sync.val = 0; --- -- --- -- return 0; --- --} --- -- --- --static int rsnd_src_start(struct rsnd_mod *mod) --- --{ --- -- rsnd_src_initialize_unlock(mod); --- -- --- -- return 0; --- --} --- -- --- --static int rsnd_src_stop(struct rsnd_mod *mod) --- --{ --- -- /* nothing to do */ --- -- return 0; --- --} +++ ++ if (!runtime) +++ ++ return; --- --/* --- -- * Gen1 functions --- -- */ --- --static int rsnd_src_set_route_gen1(struct rsnd_dai_stream *io, --- -- struct rsnd_mod *mod) --- --{ --- -- struct src_route_config { --- -- u32 mask; --- -- int shift; --- -- } routes[] = { --- -- { 0xF, 0, }, /* 0 */ --- -- { 0xF, 4, }, /* 1 */ --- -- { 0xF, 8, }, /* 2 */ --- -- { 0x7, 12, }, /* 3 */ --- -- { 0x7, 16, }, /* 4 */ --- -- { 0x7, 20, }, /* 5 */ --- -- { 0x7, 24, }, /* 6 */ --- -- { 0x3, 28, }, /* 7 */ --- -- { 0x3, 30, }, /* 8 */ --- -- }; --- -- u32 mask; --- -- u32 val; --- -- int id; +++ ++ /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ +++ ++ if (!convert_rate) +++ ++ ratio = 0; +++ ++ else if (convert_rate > runtime->rate) +++ ++ ratio = 100 * convert_rate / runtime->rate; +++ ++ else +++ ++ ratio = 100 * runtime->rate / convert_rate; --- -- id = rsnd_mod_id(mod); --- -- if (id < 0 || id >= ARRAY_SIZE(routes)) --- -- return -EIO; +++ ++ if (ratio > 600) { +++ ++ dev_err(dev, "FSO/FSI ratio error\n"); +++ ++ return; +++ ++ } /* --- -- * SRC_ROUTE_SELECT +++ ++ * SRC_ADINR */ --- -- val = rsnd_io_is_play(io) ? 0x1 : 0x2; --- -- val = val << routes[id].shift; --- -- mask = routes[id].mask << routes[id].shift; --- -- --- -- rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val); --- -- --- -- return 0; --- --} --- -- --- --static int rsnd_src_set_convert_timing_gen1(struct rsnd_dai_stream *io, --- -- struct rsnd_mod *mod) --- --{ --- -- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); --- -- struct rsnd_src *src = rsnd_mod_to_src(mod); --- -- struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); --- -- u32 convert_rate = rsnd_src_convert_rate(io, src); --- -- u32 mask; --- -- u32 val; --- -- int shift; --- -- int id = rsnd_mod_id(mod); --- -- int ret; +++ ++ adinr = rsnd_get_adinr_bit(mod, io) | +++ ++ rsnd_get_adinr_chan(mod, io); /* --- -- * SRC_TIMING_SELECT +++ ++ * SRC_IFSCR / SRC_IFSVR */ --- -- shift = (id % 4) * 8; --- -- mask = 0x1F << shift; +++ ++ ifscr = 0; +++ ++ fsrate = 0; +++ ++ if (convert_rate) { +++ ++ ifscr = 1; +++ ++ fsrate = 0x0400000 / convert_rate * runtime->rate; +++ ++ } /* --- -- * ADG is used as source clock if SRC was used, --- -- * then, SSI WS is used as destination clock. --- -- * SSI WS is used as source clock if SRC is not used --- -- * (when playback, source/destination become reverse when capture) +++ ++ * SRC_SRCCR / SRC_ROUTE_MODE0 */ --- -- ret = 0; +++ ++ cr = 0x00011110; +++ ++ route = 0x0; if (convert_rate) { --- -- /* use ADG */ --- -- val = 0; --- -- ret = rsnd_adg_set_convert_clk_gen1(priv, mod, --- -- runtime->rate, --- -- convert_rate); --- -- } else if (8 == id) { --- -- /* use SSI WS, but SRU8 is special */ --- -- val = id << shift; --- -- } else { --- -- /* use SSI WS */ --- -- val = (id + 1) << shift; --- -- } +++ ++ route = 0x1; --- -- if (ret < 0) --- -- return ret; +++ ++ if (rsnd_enable_sync_convert(src)) { +++ ++ cr |= 0x1; +++ ++ route |= rsnd_io_is_play(io) ? +++ ++ (0x1 << 24) : (0x1 << 25); +++ ++ } +++ ++ } --- -- switch (id / 4) { --- -- case 0: --- -- rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); --- -- break; --- -- case 1: --- -- rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); +++ ++ /* +++ ++ * SRC_BSDSR / SRC_BSISR +++ ++ */ +++ ++ switch (rsnd_mod_id(mod)) { +++ ++ case 5: +++ ++ case 6: +++ ++ case 7: +++ ++ case 8: +++ ++ bsdsr = 0x02400000; /* 6 - 1/6 */ +++ ++ bsisr = 0x00100060; /* 6 - 1/6 */ break; --- -- case 2: --- -- rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); +++ ++ default: +++ ++ bsdsr = 0x01800000; /* 6 - 1/6 */ +++ ++ bsisr = 0x00100060 ;/* 6 - 1/6 */ break; } @@@@@@@ -687,138 -687,138 -687,138 -376,105 -687,138 -687,138 +376,105 @@@@@@@ static int rsnd_src_stop(struct rsnd_mo return 0; } --- --static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) +++ ++static int rsnd_src_init(struct rsnd_mod *mod, +++ ++ struct rsnd_dai_stream *io, +++ ++ struct rsnd_priv *priv) { --- -- rsnd_src_irq_disable_gen2(mod); +++ ++ struct rsnd_src *src = rsnd_mod_to_src(mod); --- -- rsnd_mod_write(mod, SRC_CTRL, 0); +++ ++ rsnd_mod_power_on(mod); + + - -- rsnd_src_error_record_gen2(mod); +++ ++ rsnd_src_activation(mod); ++ ++ - rsnd_src_error_record_gen2(mod); +++ ++ rsnd_src_set_convert_rate(io, mod); ++ ++ - rsnd_src_error_record_gen2(mod); +++ ++ rsnd_src_status_clear(mod); +++ ++ +++ ++ rsnd_src_irq_enable(mod); +++ ++ +++ ++ src->err = 0; ++ ++ - return rsnd_src_stop(mod); +++ ++ /* reset sync convert_rate */ +++ ++ src->sync.val = 0; + -- -- return rsnd_src_stop(mod); +++ ++ return 0; } --- --static void __rsnd_src_interrupt_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io) +++ ++static int rsnd_src_quit(struct rsnd_mod *mod, +++ ++ struct rsnd_dai_stream *io, +++ ++ struct rsnd_priv *priv) { --- -- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - - - - spin_lock(&priv->lock); +++ ++ struct rsnd_src *src = rsnd_mod_to_src(mod); +++ ++ struct device *dev = rsnd_priv_to_dev(priv); - - /* ignore all cases if not working */ - - if (!rsnd_io_is_working(io)) - - goto rsnd_src_interrupt_gen2_out; - -- spin_lock(&priv->lock); +++ ++ rsnd_src_irq_disable(mod); - - if (rsnd_src_error_record_gen2(mod)) { - - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - - struct rsnd_src *src = rsnd_mod_to_src(mod); - - struct device *dev = rsnd_priv_to_dev(priv); - -- /* ignore all cases if not working */ - -- if (!rsnd_io_is_working(io)) - -- goto rsnd_src_interrupt_gen2_out; +++ ++ /* stop both out/in */ +++ ++ rsnd_mod_write(mod, SRC_CTRL, 0); - - dev_dbg(dev, "%s[%d] restart\n", - - rsnd_mod_name(mod), rsnd_mod_id(mod)); - -- if (rsnd_src_error_record_gen2(mod)) { - -- struct rsnd_priv *priv = rsnd_mod_to_priv(mod); - -- struct rsnd_src *src = rsnd_mod_to_src(mod); - -- struct device *dev = rsnd_priv_to_dev(priv); +++ ++ rsnd_src_halt(mod); - -- dev_dbg(dev, "%s[%d] restart\n", - -- rsnd_mod_name(mod), rsnd_mod_id(mod)); - -- --- -- _rsnd_src_stop_gen2(mod); --- -- if (src->err < 1024) --- -- _rsnd_src_start_gen2(mod, io); --- -- else --- -- dev_warn(dev, "no more SRC restart\n"); --- -- } +++ ++ rsnd_mod_power_off(mod); --- --rsnd_src_interrupt_gen2_out: --- -- spin_unlock(&priv->lock); --- --} +++ ++ if (src->err) +++ ++ dev_warn(dev, "%s[%d] under/over flow err = %d\n", +++ ++ rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); --- --static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) --- --{ --- -- struct rsnd_mod *mod = data; +++ ++ src->convert_rate = 0; --- -- rsnd_mod_interrupt(mod, __rsnd_src_interrupt_gen2); +++ ++ /* reset sync convert_rate */ +++ ++ src->sync.val = 0; --- -- return IRQ_HANDLED; +++ ++ return 0; } --- --static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io) +++ ++static void __rsnd_src_interrupt(struct rsnd_mod *mod, +++ ++ struct rsnd_dai_stream *io) { struct rsnd_priv *priv = rsnd_mod_to_priv(mod); --- -- struct device *dev = rsnd_priv_to_dev(priv); --- -- struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); struct rsnd_src *src = rsnd_mod_to_src(mod); --- -- u32 convert_rate = rsnd_src_convert_rate(io, src); --- -- u32 cr, route; --- -- uint ratio; --- -- int ret; +++ ++ struct device *dev = rsnd_priv_to_dev(priv); --- -- /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ --- -- if (!convert_rate) --- -- ratio = 0; --- -- else if (convert_rate > runtime->rate) --- -- ratio = 100 * convert_rate / runtime->rate; --- -- else --- -- ratio = 100 * runtime->rate / convert_rate; +++ ++ spin_lock(&priv->lock); --- -- if (ratio > 600) { --- -- dev_err(dev, "FSO/FSI ratio error\n"); --- -- return -EINVAL; --- -- } +++ ++ /* ignore all cases if not working */ +++ ++ if (!rsnd_io_is_working(io)) +++ ++ goto rsnd_src_interrupt_out; --- -- ret = rsnd_src_set_convert_rate(mod, io); --- -- if (ret < 0) --- -- return ret; +++ ++ if (rsnd_src_record_error(mod)) { --- -- cr = 0x00011110; --- -- route = 0x0; --- -- if (convert_rate) { --- -- route = 0x1; +++ ++ dev_dbg(dev, "%s[%d] restart\n", +++ ++ rsnd_mod_name(mod), rsnd_mod_id(mod)); --- -- if (rsnd_enable_sync_convert(src)) { --- -- cr |= 0x1; --- -- route |= rsnd_io_is_play(io) ? --- -- (0x1 << 24) : (0x1 << 25); --- -- } +++ ++ rsnd_src_stop(mod, io, priv); +++ ++ rsnd_src_start(mod, io, priv); } --- -- rsnd_mod_write(mod, SRC_SRCCR, cr); --- -- rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); +++ ++ if (src->err > 1024) { +++ ++ rsnd_src_irq_disable(mod); --- -- switch (rsnd_mod_id(mod)) { --- -- case 5: --- -- case 6: --- -- case 7: --- -- case 8: --- -- rsnd_mod_write(mod, SRC_BSDSR, 0x02400000); --- -- break; --- -- default: --- -- rsnd_mod_write(mod, SRC_BSDSR, 0x01800000); --- -- break; +++ ++ dev_warn(dev, "no more %s[%d] restart\n", +++ ++ rsnd_mod_name(mod), rsnd_mod_id(mod)); } --- -- rsnd_mod_write(mod, SRC_BSISR, 0x00100060); +++ ++ rsnd_src_status_clear(mod); +++ ++rsnd_src_interrupt_out: --- -- return 0; +++ ++ spin_unlock(&priv->lock); } --- --static int rsnd_src_set_convert_timing_gen2(struct rsnd_dai_stream *io, --- -- struct rsnd_mod *mod) +++ ++static irqreturn_t rsnd_src_interrupt(int irq, void *data) { --- -- struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); --- -- struct rsnd_src *src = rsnd_mod_to_src(mod); --- -- u32 convert_rate = rsnd_src_convert_rate(io, src); --- -- int ret; +++ ++ struct rsnd_mod *mod = data; --- -- if (convert_rate) --- -- ret = rsnd_adg_set_convert_clk_gen2(mod, io, --- -- runtime->rate, --- -- convert_rate); --- -- else --- -- ret = rsnd_adg_set_convert_timing_gen2(mod, io); +++ ++ rsnd_mod_interrupt(mod, __rsnd_src_interrupt); --- -- return ret; +++ ++ return IRQ_HANDLED; } --- --static int rsnd_src_probe_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io, --- -- struct rsnd_priv *priv) +++ ++static int rsnd_src_probe_(struct rsnd_mod *mod, +++ ++ struct rsnd_dai_stream *io, +++ ++ struct rsnd_priv *priv) { struct rsnd_src *src = rsnd_mod_to_src(mod); struct device *dev = rsnd_priv_to_dev(priv); @@@@@@@ -846,84 -846,83 -846,84 -502,11 -846,83 -846,83 +502,12 @@@@@@@ return ret; } --- --static int rsnd_src_remove_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io, --- -- struct rsnd_priv *priv) --- --{ --- -- rsnd_dma_quit(io, rsnd_mod_to_dma(mod)); --- -- --- -- return 0; --- --} --- -- --- --static int rsnd_src_init_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io, --- -- struct rsnd_priv *priv) --- --{ --- -- int ret; --- -- --- -- ret = rsnd_src_init(mod, priv); --- -- if (ret < 0) --- -- return ret; --- -- --- -- ret = rsnd_src_set_convert_rate_gen2(mod, io); --- -- if (ret < 0) --- -- return ret; --- -- --- -- ret = rsnd_src_set_convert_timing_gen2(io, mod); --- -- if (ret < 0) --- -- return ret; --- -- --- -- return 0; --- --} --- -- --- --static int rsnd_src_start_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io, --- -- struct rsnd_priv *priv) --- --{ --- -- rsnd_dma_start(io, rsnd_mod_to_dma(mod)); --- -- --- -- return _rsnd_src_start_gen2(mod, io); --- --} --- -- --- --static int rsnd_src_stop_gen2(struct rsnd_mod *mod, --- -- struct rsnd_dai_stream *io, --- -- struct rsnd_priv *priv) --- --{ --- -- int ret; --- -- --- -- ret = _rsnd_src_stop_gen2(mod); --- -- --- -- rsnd_dma_stop(io, rsnd_mod_to_dma(mod)); --- -- --- -- return ret; --- --} --- -- --- --static void rsnd_src_reconvert_update(struct rsnd_dai_stream *io, --- -- struct rsnd_mod *mod) --- --{ --- -- struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); --- -- struct rsnd_src *src = rsnd_mod_to_src(mod); --- -- u32 convert_rate = rsnd_src_convert_rate(io, src); --- -- u32 fsrate; --- -- --- -- if (!runtime) --- -- return; --- -- --- -- if (!convert_rate) --- -- convert_rate = runtime->rate; --- -- --- -- fsrate = 0x0400000 / convert_rate * runtime->rate; --- -- --- -- /* update IFS */ --- -- rsnd_mod_write(mod, SRC_IFSVR, fsrate); --- --} --- -- -- --static int rsnd_src_pcm_new_gen2(struct rsnd_mod *mod, ++ ++static int rsnd_src_pcm_new(struct rsnd_mod *mod, struct rsnd_dai_stream *io, struct snd_soc_pcm_runtime *rtd) { - struct rsnd_priv *priv = rsnd_mod_to_priv(mod); struct rsnd_dai *rdai = rsnd_io_to_rdai(io); +++++ struct rsnd_mod *dvc = rsnd_io_to_mod_dvc(io); struct rsnd_src *src = rsnd_mod_to_src(mod); int ret; @@@@@@@ -932,17 -931,11 -932,17 -515,11 -931,11 -931,11 +516,17 @@@@@@@ */ /* - * Gen1 is not supported + * SRC sync convert needs clock master */ - if (rsnd_is_gen1(priv)) + if (!rsnd_rdai_is_clk_master(rdai)) return 0; + +++ /* - * SRC sync convert needs clock master +++++ * SRC In doesn't work if DVC was enabled + +++ */ - if (!rsnd_rdai_is_clk_master(rdai)) +++++ if (dvc && !rsnd_io_is_play(io)) + +++ return 0; + +++ /* * enable sync convert */ @@@@@@@ -965,17 -958,17 -965,17 -542,16 -958,17 -958,17 +549,16 @@@@@@@ return ret; } --- --static struct rsnd_mod_ops rsnd_src_gen2_ops = { +++ ++static struct rsnd_mod_ops rsnd_src_ops = { .name = SRC_NAME, .dma_req = rsnd_src_dma_req, --- -- .probe = rsnd_src_probe_gen2, --- -- .remove = rsnd_src_remove_gen2, --- -- .init = rsnd_src_init_gen2, +++ ++ .probe = rsnd_src_probe_, +++ ++ .init = rsnd_src_init, .quit = rsnd_src_quit, --- -- .start = rsnd_src_start_gen2, --- -- .stop = rsnd_src_stop_gen2, +++ ++ .start = rsnd_src_start, +++ ++ .stop = rsnd_src_stop, .hw_params = rsnd_src_hw_params, -- -- .pcm_new = rsnd_src_pcm_new_gen2, ++ ++ .pcm_new = rsnd_src_pcm_new, }; struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) @@@@@@@ -983,89 -976,89 -983,87 -559,38 -976,89 -976,89 +566,38 @@@@@@@ if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) id = 0; -- -- return rsnd_mod_get((struct rsnd_src *)(priv->src) + id); - return &((struct rsnd_src *)(priv->src) + id)->mod; +++ ++ return rsnd_mod_get(rsnd_src_get(priv, id)); } --- --static void rsnd_of_parse_src(struct platform_device *pdev, --- -- const struct rsnd_of_data *of_data, --- -- struct rsnd_priv *priv) +++ ++int rsnd_src_probe(struct rsnd_priv *priv) { --- -- struct device_node *src_node; +++ ++ struct device_node *node; struct device_node *np; --- -- struct rcar_snd_info *info = rsnd_priv_to_info(priv); --- -- struct rsnd_src_platform_info *src_info; --- -- struct device *dev = &pdev->dev; --- -- int nr, i; --- -- --- -- if (!of_data) --- -- return; --- -- --- -- src_node = rsnd_src_of_node(priv); --- -- if (!src_node) --- -- return; --- -- --- -- nr = of_get_child_count(src_node); --- -- if (!nr) --- -- goto rsnd_of_parse_src_end; --- -- --- -- src_info = devm_kzalloc(dev, --- -- sizeof(struct rsnd_src_platform_info) * nr, --- -- GFP_KERNEL); --- -- if (!src_info) { --- -- dev_err(dev, "src info allocation error\n"); --- -- goto rsnd_of_parse_src_end; --- -- } --- -- --- -- info->src_info = src_info; --- -- info->src_info_nr = nr; --- -- --- -- i = 0; --- -- for_each_child_of_node(src_node, np) { --- -- src_info[i].irq = irq_of_parse_and_map(np, 0); --- -- --- -- i++; --- -- } --- -- --- --rsnd_of_parse_src_end: --- -- of_node_put(src_node); --- --} --- -- --- --int rsnd_src_probe(struct platform_device *pdev, --- -- const struct rsnd_of_data *of_data, --- -- struct rsnd_priv *priv) --- --{ --- -- struct rcar_snd_info *info = rsnd_priv_to_info(priv); struct device *dev = rsnd_priv_to_dev(priv); struct rsnd_src *src; --- -- struct rsnd_mod_ops *ops; struct clk *clk; char name[RSND_SRC_NAME_SIZE]; int i, nr, ret; --- -- ops = NULL; -- -- if (rsnd_is_gen1(priv)) { -- -- ops = &rsnd_src_gen1_ops; -- -- dev_warn(dev, "Gen1 support will be removed soon\n"); -- -- } -- -- if (rsnd_is_gen2(priv)) -- -- ops = &rsnd_src_gen2_ops; -- -- if (!ops) { -- -- dev_err(dev, "unknown Generation\n"); -- -- return -EIO; -- -- } +++ ++ /* This driver doesn't support Gen1 at this point */ ++ ++ if (rsnd_is_gen1(priv)) - ops = &rsnd_src_gen1_ops; - if (rsnd_is_gen2(priv)) - ops = &rsnd_src_gen2_ops; - if (!ops) { - dev_err(dev, "unknown Generation\n"); - return -EIO; - } +++ ++ return 0; --- -- rsnd_of_parse_src(pdev, of_data, priv); +++ ++ node = rsnd_src_of_node(priv); +++ ++ if (!node) +++ ++ return 0; /* not used is not error */ --- -- /* --- -- * init SRC --- -- */ --- -- nr = info->src_info_nr; --- -- if (!nr) --- -- return 0; +++ ++ nr = of_get_child_count(node); +++ ++ if (!nr) { +++ ++ ret = -EINVAL; +++ ++ goto rsnd_src_probe_done; +++ ++ } src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); --- -- if (!src) --- -- return -ENOMEM; +++ ++ if (!src) { +++ ++ ret = -ENOMEM; +++ ++ goto rsnd_src_probe_done; +++ ++ } priv->src_nr = nr; priv->src = src; @@@@@@@ -1074,22 -1067,22 -1072,22 -602,35 -1067,22 -1067,22 +609,35 @@@@@@@ snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", SRC_NAME, i); --- -- clk = devm_clk_get(dev, name); --- -- if (IS_ERR(clk)) --- -- return PTR_ERR(clk); +++ ++ src->irq = irq_of_parse_and_map(np, 0); +++ ++ if (!src->irq) { +++ ++ ret = -EINVAL; +++ ++ goto rsnd_src_probe_done; +++ ++ } --- -- src->info = &info->src_info[i]; +++ ++ clk = devm_clk_get(dev, name); +++ ++ if (IS_ERR(clk)) { +++ ++ ret = PTR_ERR(clk); +++ ++ goto rsnd_src_probe_done; +++ ++ } -- -- ret = rsnd_mod_init(priv, rsnd_mod_get(src), ops, clk, RSND_MOD_SRC, i); - ret = rsnd_mod_init(priv, &src->mod, ops, clk, RSND_MOD_SRC, i); +++ ++ ret = rsnd_mod_init(priv, rsnd_mod_get(src), +++ ++ &rsnd_src_ops, clk, RSND_MOD_SRC, i); if (ret) --- -- return ret; +++ ++ goto rsnd_src_probe_done; +++ ++ +++ ++ i++; } --- -- return 0; +++ ++ ret = 0; +++ ++ +++ ++rsnd_src_probe_done: +++ ++ of_node_put(node); +++ ++ +++ ++ return ret; } --- --void rsnd_src_remove(struct platform_device *pdev, --- -- struct rsnd_priv *priv) +++ ++void rsnd_src_remove(struct rsnd_priv *priv) { struct rsnd_src *src; int i;