···44- compatible : "renesas,rcar_sound-<soctype>", fallbacks55 "renesas,rcar_sound-gen1" if generation1, and66 "renesas,rcar_sound-gen2" if generation277+ "renesas,rcar_sound-gen3" if generation378 Examples with soctypes are:89 - "renesas,rcar_sound-r8a7778" (R-Car M1A)910 - "renesas,rcar_sound-r8a7790" (R-Car H2)1011 - "renesas,rcar_sound-r8a7791" (R-Car M2-W)1212+ - "renesas,rcar_sound-r8a7795" (R-Car H3)1113- reg : Should contain the register physical address.1214 required register is1315 SRU/ADG/SSI if generation1···3230- rcar_sound,dai : DAI contents.3331 The number of DAI subnode should be same as HW.3432 see below for detail.3333+- #sound-dai-cells : it must be 0 if your system is using single DAI3434+ it must be 1 if your system is using multi DAI3535+- #clock-cells : it must be 0 if your system has audio_clkout3636+ it must be 1 if your system has audio_clkout0/1/2/33737+- clock-frequency : for all audio_clkout0/1/2/335383639SSI subnode properties:3740- interrupts : Should contain SSI interrupt for PIO transfer
···17171818config SND_SOC_ROCKCHIP_MAX980901919 tristate "ASoC support for Rockchip boards using a MAX98090 codec"2020- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB2020+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP2121 select SND_SOC_ROCKCHIP_I2S2222 select SND_SOC_MAX980902323 select SND_SOC_TS3A227E···27272828config SND_SOC_ROCKCHIP_RT56452929 tristate "ASoC support for Rockchip boards using a RT5645/RT5650 codec"3030- depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB3030+ depends on SND_SOC_ROCKCHIP && I2C && GPIOLIB && CLKDEV_LOOKUP3131 select SND_SOC_ROCKCHIP_I2S3232 select SND_SOC_RT56453333 help
+1
sound/soc/sh/Kconfig
···3737config SND_SOC_RCAR3838 tristate "R-Car series SRU/SCU/SSIU/SSI support"3939 depends on DMA_OF4040+ depends on COMMON_CLK4041 select SND_SIMPLE_CARD4142 select REGMAP_MMIO4243 help
+234-69
sound/soc/sh/rcar/adg.c
···77 * License. See the file "COPYING" in the main directory of this archive88 * for more details.99 */1010-#include <linux/sh_clk.h>1010+#include <linux/clk-provider.h>1111#include "rsnd.h"12121313#define CLKA 0···1616#define CLKI 31717#define CLKMAX 418181919+#define CLKOUT 02020+#define CLKOUT1 12121+#define CLKOUT2 22222+#define CLKOUT3 32323+#define CLKOUTMAX 42424+2525+#define BRRx_MASK(x) (0x3FF & x)2626+2727+static struct rsnd_mod_ops adg_ops = {2828+ .name = "adg",2929+};3030+1931struct rsnd_adg {2032 struct clk *clk[CLKMAX];3333+ struct clk *clkout[CLKOUTMAX];3434+ struct clk_onecell_data onecell;3535+ struct rsnd_mod mod;21362222- int rbga_rate_for_441khz_div_6; /* RBGA */2323- int rbgb_rate_for_48khz_div_6; /* RBGB */2424- u32 ckr;3737+ int rbga_rate_for_441khz; /* RBGA */3838+ int rbgb_rate_for_48khz; /* RBGB */2539};26402741#define for_each_rsnd_clk(pos, adg, i) \···4329 (i < CLKMAX) && \4430 ((pos) = adg->clk[i]); \4531 i++)3232+#define for_each_rsnd_clkout(pos, adg, i) \3333+ for (i = 0; \3434+ (i < CLKOUTMAX) && \3535+ ((pos) = adg->clkout[i]); \3636+ i++)4637#define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)47383939+static u32 rsnd_adg_calculate_rbgx(unsigned long div)4040+{4141+ int i, ratio;4242+4343+ if (!div)4444+ return 0;4545+4646+ for (i = 3; i >= 0; i--) {4747+ ratio = 2 << (i * 2);4848+ if (0 == (div % ratio))4949+ return (u32)((i << 8) | ((div / ratio) - 1));5050+ }5151+5252+ return ~0;5353+}48544955static u32 rsnd_adg_ssi_ws_timing_gen2(struct rsnd_dai_stream *io)5056{···9460int rsnd_adg_set_cmd_timsel_gen2(struct rsnd_mod *mod,9561 struct rsnd_dai_stream *io)9662{6363+ struct rsnd_priv *priv = rsnd_mod_to_priv(mod);6464+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);6565+ struct rsnd_mod *adg_mod = rsnd_mod_get(adg);9766 int id = rsnd_mod_id(mod);9867 int shift = (id % 2) ? 16 : 0;9968 u32 mask, val;···10669 val = val << shift;10770 mask = 0xffff << shift;10871109109- rsnd_mod_bset(mod, CMDOUT_TIMSEL, mask, val);7272+ rsnd_mod_bset(adg_mod, CMDOUT_TIMSEL, mask, val);1107311174 return 0;11275}11376114114-static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *mod,7777+static int rsnd_adg_set_src_timsel_gen2(struct rsnd_mod *src_mod,11578 struct rsnd_dai_stream *io,11679 u32 timsel)11780{8181+ struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);8282+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);8383+ struct rsnd_mod *adg_mod = rsnd_mod_get(adg);11884 int is_play = rsnd_io_is_play(io);119119- int id = rsnd_mod_id(mod);8585+ int id = rsnd_mod_id(src_mod);12086 int shift = (id % 2) ? 16 : 0;12187 u32 mask, ws;12288 u32 in, out;8989+9090+ rsnd_mod_confirm_src(src_mod);1239112492 ws = rsnd_adg_ssi_ws_timing_gen2(io);12593···1379513896 switch (id / 2) {13997 case 0:140140- rsnd_mod_bset(mod, SRCIN_TIMSEL0, mask, in);141141- rsnd_mod_bset(mod, SRCOUT_TIMSEL0, mask, out);9898+ rsnd_mod_bset(adg_mod, SRCIN_TIMSEL0, mask, in);9999+ rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL0, mask, out);142100 break;143101 case 1:144144- rsnd_mod_bset(mod, SRCIN_TIMSEL1, mask, in);145145- rsnd_mod_bset(mod, SRCOUT_TIMSEL1, mask, out);102102+ rsnd_mod_bset(adg_mod, SRCIN_TIMSEL1, mask, in);103103+ rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL1, mask, out);146104 break;147105 case 2:148148- rsnd_mod_bset(mod, SRCIN_TIMSEL2, mask, in);149149- rsnd_mod_bset(mod, SRCOUT_TIMSEL2, mask, out);106106+ rsnd_mod_bset(adg_mod, SRCIN_TIMSEL2, mask, in);107107+ rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL2, mask, out);150108 break;151109 case 3:152152- rsnd_mod_bset(mod, SRCIN_TIMSEL3, mask, in);153153- rsnd_mod_bset(mod, SRCOUT_TIMSEL3, mask, out);110110+ rsnd_mod_bset(adg_mod, SRCIN_TIMSEL3, mask, in);111111+ rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL3, mask, out);154112 break;155113 case 4:156156- rsnd_mod_bset(mod, SRCIN_TIMSEL4, mask, in);157157- rsnd_mod_bset(mod, SRCOUT_TIMSEL4, mask, out);114114+ rsnd_mod_bset(adg_mod, SRCIN_TIMSEL4, mask, in);115115+ rsnd_mod_bset(adg_mod, SRCOUT_TIMSEL4, mask, out);158116 break;159117 }160118161119 return 0;162120}163121164164-int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *mod,122122+int rsnd_adg_set_convert_clk_gen2(struct rsnd_mod *src_mod,165123 struct rsnd_dai_stream *io,166124 unsigned int src_rate,167125 unsigned int dst_rate)168126{169169- struct rsnd_priv *priv = rsnd_mod_to_priv(mod);127127+ struct rsnd_priv *priv = rsnd_mod_to_priv(src_mod);170128 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);129129+ struct rsnd_mod *adg_mod = rsnd_mod_get(adg);171130 struct device *dev = rsnd_priv_to_dev(priv);172131 int idx, sel, div, step, ret;173132 u32 val, en;···177134 clk_get_rate(adg->clk[CLKA]), /* 0000: CLKA */178135 clk_get_rate(adg->clk[CLKB]), /* 0001: CLKB */179136 clk_get_rate(adg->clk[CLKC]), /* 0010: CLKC */180180- adg->rbga_rate_for_441khz_div_6,/* 0011: RBGA */181181- adg->rbgb_rate_for_48khz_div_6, /* 0100: RBGB */137137+ adg->rbga_rate_for_441khz, /* 0011: RBGA */138138+ adg->rbgb_rate_for_48khz, /* 0100: RBGB */182139 };140140+141141+ rsnd_mod_confirm_src(src_mod);183142184143 min = ~0;185144 val = 0;···220175 return -EIO;221176 }222177223223- ret = rsnd_adg_set_src_timsel_gen2(mod, io, val);178178+ ret = rsnd_adg_set_src_timsel_gen2(src_mod, io, val);224179 if (ret < 0) {225180 dev_err(dev, "timsel error\n");226181 return ret;227182 }228183229229- rsnd_mod_bset(mod, DIV_EN, en, en);184184+ rsnd_mod_bset(adg_mod, DIV_EN, en, en);230185231186 dev_dbg(dev, "convert rate %d <-> %d\n", src_rate, dst_rate);232187233188 return 0;234189}235190236236-int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *mod,191191+int rsnd_adg_set_convert_timing_gen2(struct rsnd_mod *src_mod,237192 struct rsnd_dai_stream *io)238193{239194 u32 val = rsnd_adg_ssi_ws_timing_gen2(io);240195241241- return rsnd_adg_set_src_timsel_gen2(mod, io, val);196196+ rsnd_mod_confirm_src(src_mod);197197+198198+ return rsnd_adg_set_src_timsel_gen2(src_mod, io, val);242199}243200244201int rsnd_adg_set_convert_clk_gen1(struct rsnd_priv *priv,···249202 unsigned int dst_rate)250203{251204 struct rsnd_adg *adg = rsnd_priv_to_adg(priv);205205+ struct rsnd_mod *adg_mod = rsnd_mod_get(adg);252206 struct device *dev = rsnd_priv_to_dev(priv);253207 int idx, sel, div, shift;254208 u32 mask, val;···259211 clk_get_rate(adg->clk[CLKB]), /* 001: CLKB */260212 clk_get_rate(adg->clk[CLKC]), /* 010: CLKC */261213 0, /* 011: MLBCLK (not used) */262262- adg->rbga_rate_for_441khz_div_6,/* 100: RBGA */263263- adg->rbgb_rate_for_48khz_div_6, /* 101: RBGB */214214+ adg->rbga_rate_for_441khz, /* 100: RBGA */215215+ adg->rbgb_rate_for_48khz, /* 101: RBGB */264216 };265217266218 /* find div (= 1/128, 1/256, 1/512, 1/1024, 1/2048 */···286238287239 switch (id / 4) {288240 case 0:289289- rsnd_mod_bset(mod, AUDIO_CLK_SEL3, mask, val);241241+ rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL3, mask, val);290242 break;291243 case 1:292292- rsnd_mod_bset(mod, AUDIO_CLK_SEL4, mask, val);244244+ rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL4, mask, val);293245 break;294246 case 2:295295- rsnd_mod_bset(mod, AUDIO_CLK_SEL5, mask, val);247247+ rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL5, mask, val);296248 break;297249 }298250···305257 return 0;306258}307259308308-static void rsnd_adg_set_ssi_clk(struct rsnd_mod *mod, u32 val)260260+static void rsnd_adg_set_ssi_clk(struct rsnd_mod *ssi_mod, u32 val)309261{310310- int id = rsnd_mod_id(mod);262262+ struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod);263263+ struct rsnd_adg *adg = rsnd_priv_to_adg(priv);264264+ struct rsnd_mod *adg_mod = rsnd_mod_get(adg);265265+ int id = rsnd_mod_id(ssi_mod);311266 int shift = (id % 4) * 8;312267 u32 mask = 0xFF << shift;268268+269269+ rsnd_mod_confirm_ssi(ssi_mod);313270314271 val = val << shift;315272···327274328275 switch (id / 4) {329276 case 0:330330- rsnd_mod_bset(mod, AUDIO_CLK_SEL0, mask, val);277277+ rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL0, mask, val);331278 break;332279 case 1:333333- rsnd_mod_bset(mod, AUDIO_CLK_SEL1, mask, val);280280+ rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL1, mask, val);334281 break;335282 case 2:336336- rsnd_mod_bset(mod, AUDIO_CLK_SEL2, mask, val);283283+ rsnd_mod_bset(adg_mod, AUDIO_CLK_SEL2, mask, val);337284 break;338285 }339286}···379326 }380327381328 /*382382- * find 1/6 clock from BRGA/BRGB329329+ * find divided clock from BRGA/BRGB383330 */384384- if (rate == adg->rbga_rate_for_441khz_div_6) {331331+ if (rate == adg->rbga_rate_for_441khz) {385332 data = 0x10;386333 goto found_clock;387334 }388335389389- if (rate == adg->rbgb_rate_for_48khz_div_6) {336336+ if (rate == adg->rbgb_rate_for_48khz) {390337 data = 0x20;391338 goto found_clock;392339 }···395342396343found_clock:397344398398- /* see rsnd_adg_ssi_clk_init() */399399- rsnd_mod_bset(mod, SSICKR, 0x00FF0000, adg->ckr);400400- rsnd_mod_write(mod, BRRA, 0x00000002); /* 1/6 */401401- rsnd_mod_write(mod, BRRB, 0x00000002); /* 1/6 */402402-403345 /*404346 * This "mod" = "ssi" here.405347 * we can get "ssi id" from mod406348 */407349 rsnd_adg_set_ssi_clk(mod, data);408350409409- dev_dbg(dev, "ADG: ssi%d selects clk%d = %d",410410- rsnd_mod_id(mod), i, rate);351351+ dev_dbg(dev, "ADG: %s[%d] selects 0x%x for %d\n",352352+ rsnd_mod_name(mod), rsnd_mod_id(mod),353353+ data, rate);411354412355 return 0;413356}414357415415-static void rsnd_adg_ssi_clk_init(struct rsnd_priv *priv, struct rsnd_adg *adg)358358+static void rsnd_adg_get_clkin(struct rsnd_priv *priv,359359+ struct rsnd_adg *adg)360360+{361361+ struct device *dev = rsnd_priv_to_dev(priv);362362+ struct clk *clk;363363+ static const char * const clk_name[] = {364364+ [CLKA] = "clk_a",365365+ [CLKB] = "clk_b",366366+ [CLKC] = "clk_c",367367+ [CLKI] = "clk_i",368368+ };369369+ int i;370370+371371+ for (i = 0; i < CLKMAX; i++) {372372+ clk = devm_clk_get(dev, clk_name[i]);373373+ adg->clk[i] = IS_ERR(clk) ? NULL : clk;374374+ }375375+376376+ for_each_rsnd_clk(clk, adg, i)377377+ dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));378378+}379379+380380+static void rsnd_adg_get_clkout(struct rsnd_priv *priv,381381+ struct rsnd_adg *adg)416382{417383 struct clk *clk;418418- unsigned long rate;419419- u32 ckr;384384+ struct rsnd_mod *adg_mod = rsnd_mod_get(adg);385385+ struct device *dev = rsnd_priv_to_dev(priv);386386+ struct device_node *np = dev->of_node;387387+ u32 ckr, rbgx, rbga, rbgb;388388+ u32 rate, req_rate, div;389389+ uint32_t count = 0;390390+ unsigned long req_48kHz_rate, req_441kHz_rate;420391 int i;392392+ const char *parent_clk_name = NULL;393393+ static const char * const clkout_name[] = {394394+ [CLKOUT] = "audio_clkout",395395+ [CLKOUT1] = "audio_clkout1",396396+ [CLKOUT2] = "audio_clkout2",397397+ [CLKOUT3] = "audio_clkout3",398398+ };421399 int brg_table[] = {422400 [CLKA] = 0x0,423401 [CLKB] = 0x1,···456372 [CLKI] = 0x2,457373 };458374375375+ of_property_read_u32(np, "#clock-cells", &count);376376+377377+ /*378378+ * ADG supports BRRA/BRRB output only379379+ * this means all clkout0/1/2/3 will be same rate380380+ */381381+ of_property_read_u32(np, "clock-frequency", &req_rate);382382+ req_48kHz_rate = 0;383383+ req_441kHz_rate = 0;384384+ if (0 == (req_rate % 44100))385385+ req_441kHz_rate = req_rate;386386+ if (0 == (req_rate % 48000))387387+ req_48kHz_rate = req_rate;388388+459389 /*460390 * This driver is assuming that AUDIO_CLKA/AUDIO_CLKB/AUDIO_CLKC461391 * have 44.1kHz or 48kHz base clocks for now.462392 *463393 * SSI itself can divide parent clock by 1/1 - 1/16464464- * So, BRGA outputs 44.1kHz base parent clock 1/32,465465- * and, BRGB outputs 48.0kHz base parent clock 1/32 here.466394 * see467395 * rsnd_adg_ssi_clk_try_start()396396+ * rsnd_ssi_master_clk_start()468397 */469398 ckr = 0;470470- adg->rbga_rate_for_441khz_div_6 = 0;471471- adg->rbgb_rate_for_48khz_div_6 = 0;399399+ rbga = 2; /* default 1/6 */400400+ rbgb = 2; /* default 1/6 */401401+ adg->rbga_rate_for_441khz = 0;402402+ adg->rbgb_rate_for_48khz = 0;472403 for_each_rsnd_clk(clk, adg, i) {473404 rate = clk_get_rate(clk);474405···491392 continue;492393493394 /* RBGA */494494- if (!adg->rbga_rate_for_441khz_div_6 && (0 == rate % 44100)) {495495- adg->rbga_rate_for_441khz_div_6 = rate / 6;496496- ckr |= brg_table[i] << 20;395395+ if (!adg->rbga_rate_for_441khz && (0 == rate % 44100)) {396396+ div = 6;397397+ if (req_441kHz_rate)398398+ div = rate / req_441kHz_rate;399399+ rbgx = rsnd_adg_calculate_rbgx(div);400400+ if (BRRx_MASK(rbgx) == rbgx) {401401+ rbga = rbgx;402402+ adg->rbga_rate_for_441khz = rate / div;403403+ ckr |= brg_table[i] << 20;404404+ if (req_441kHz_rate)405405+ parent_clk_name = __clk_get_name(clk);406406+ }497407 }498408499409 /* RBGB */500500- if (!adg->rbgb_rate_for_48khz_div_6 && (0 == rate % 48000)) {501501- adg->rbgb_rate_for_48khz_div_6 = rate / 6;502502- ckr |= brg_table[i] << 16;410410+ if (!adg->rbgb_rate_for_48khz && (0 == rate % 48000)) {411411+ div = 6;412412+ if (req_48kHz_rate)413413+ div = rate / req_48kHz_rate;414414+ rbgx = rsnd_adg_calculate_rbgx(div);415415+ if (BRRx_MASK(rbgx) == rbgx) {416416+ rbgb = rbgx;417417+ adg->rbgb_rate_for_48khz = rate / div;418418+ ckr |= brg_table[i] << 16;419419+ if (req_48kHz_rate) {420420+ parent_clk_name = __clk_get_name(clk);421421+ ckr |= 0x80000000;422422+ }423423+ }503424 }504425 }505426506506- adg->ckr = ckr;427427+ /*428428+ * ADG supports BRRA/BRRB output only.429429+ * this means all clkout0/1/2/3 will be * same rate430430+ */431431+432432+ /*433433+ * for clkout434434+ */435435+ if (!count) {436436+ clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT],437437+ parent_clk_name,438438+ (parent_clk_name) ?439439+ 0 : CLK_IS_ROOT, req_rate);440440+ if (!IS_ERR(clk)) {441441+ adg->clkout[CLKOUT] = clk;442442+ of_clk_add_provider(np, of_clk_src_simple_get, clk);443443+ }444444+ }445445+ /*446446+ * for clkout0/1/2/3447447+ */448448+ else {449449+ for (i = 0; i < CLKOUTMAX; i++) {450450+ clk = clk_register_fixed_rate(dev, clkout_name[i],451451+ parent_clk_name,452452+ (parent_clk_name) ?453453+ 0 : CLK_IS_ROOT,454454+ req_rate);455455+ if (!IS_ERR(clk)) {456456+ adg->onecell.clks = adg->clkout;457457+ adg->onecell.clk_num = CLKOUTMAX;458458+459459+ adg->clkout[i] = clk;460460+461461+ of_clk_add_provider(np, of_clk_src_onecell_get,462462+ &adg->onecell);463463+ }464464+ }465465+ }466466+467467+ rsnd_mod_bset(adg_mod, SSICKR, 0x00FF0000, ckr);468468+ rsnd_mod_write(adg_mod, BRRA, rbga);469469+ rsnd_mod_write(adg_mod, BRRB, rbgb);470470+471471+ for_each_rsnd_clkout(clk, adg, i)472472+ dev_dbg(dev, "clkout %d : %p : %ld\n", i, clk, clk_get_rate(clk));473473+ dev_dbg(dev, "SSICKR = 0x%08x, BRRA/BRRB = 0x%x/0x%x\n",474474+ ckr, rbga, rbgb);507475}508476509477int rsnd_adg_probe(struct platform_device *pdev,···579413{580414 struct rsnd_adg *adg;581415 struct device *dev = rsnd_priv_to_dev(priv);582582- struct clk *clk;583583- int i;584416585417 adg = devm_kzalloc(dev, sizeof(*adg), GFP_KERNEL);586418 if (!adg) {···586422 return -ENOMEM;587423 }588424589589- adg->clk[CLKA] = devm_clk_get(dev, "clk_a");590590- adg->clk[CLKB] = devm_clk_get(dev, "clk_b");591591- adg->clk[CLKC] = devm_clk_get(dev, "clk_c");592592- adg->clk[CLKI] = devm_clk_get(dev, "clk_i");425425+ /*426426+ * ADG is special module.427427+ * Use ADG mod without rsnd_mod_init() to make debug easy428428+ * for rsnd_write/rsnd_read429429+ */430430+ adg->mod.ops = &adg_ops;431431+ adg->mod.priv = priv;593432594594- for_each_rsnd_clk(clk, adg, i)595595- dev_dbg(dev, "clk %d : %p : %ld\n", i, clk, clk_get_rate(clk));596596-597597- rsnd_adg_ssi_clk_init(priv, adg);433433+ rsnd_adg_get_clkin(priv, adg);434434+ rsnd_adg_get_clkout(priv, adg);598435599436 priv->adg = adg;600437