1ba9c949fSKuninori Morimoto /* 2ba9c949fSKuninori Morimoto * Renesas R-Car SRC support 3ba9c949fSKuninori Morimoto * 4ba9c949fSKuninori Morimoto * Copyright (C) 2013 Renesas Solutions Corp. 5ba9c949fSKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6ba9c949fSKuninori Morimoto * 7ba9c949fSKuninori Morimoto * This program is free software; you can redistribute it and/or modify 8ba9c949fSKuninori Morimoto * it under the terms of the GNU General Public License version 2 as 9ba9c949fSKuninori Morimoto * published by the Free Software Foundation. 10ba9c949fSKuninori Morimoto */ 11ba9c949fSKuninori Morimoto #include "rsnd.h" 12ba9c949fSKuninori Morimoto 138aefda50SKuninori Morimoto #define SRC_NAME "src" 148aefda50SKuninori Morimoto 15cfcefe01SKuninori Morimoto /* SRCx_STATUS */ 16cfcefe01SKuninori Morimoto #define OUF_SRCO ((1 << 12) | (1 << 13)) 17cfcefe01SKuninori Morimoto #define OUF_SRCI ((1 << 9) | (1 << 8)) 18cfcefe01SKuninori Morimoto 19cfcefe01SKuninori Morimoto /* SCU_SYSTEM_STATUS0/1 */ 20cfcefe01SKuninori Morimoto #define OUF_SRC(id) ((1 << (id + 16)) | (1 << id)) 21cfcefe01SKuninori Morimoto 22ba9c949fSKuninori Morimoto struct rsnd_src { 23ba9c949fSKuninori Morimoto struct rsnd_src_platform_info *info; /* rcar_snd.h */ 24ba9c949fSKuninori Morimoto struct rsnd_mod mod; 25940e9479SKuninori Morimoto struct rsnd_mod *dma; 2643cb6954SKuninori Morimoto struct rsnd_kctrl_cfg_s sen; /* sync convert enable */ 2743cb6954SKuninori Morimoto struct rsnd_kctrl_cfg_s sync; /* sync convert */ 283b7843ffSKuninori Morimoto u32 convert_rate; /* sampling rate convert */ 29cfcefe01SKuninori Morimoto int err; 30ba9c949fSKuninori Morimoto }; 31ba9c949fSKuninori Morimoto 32ba9c949fSKuninori Morimoto #define RSND_SRC_NAME_SIZE 16 33ba9c949fSKuninori Morimoto 34232c00b6SKuninori Morimoto #define rsnd_src_to_dma(src) ((src)->dma) 35da599fd3SKuninori Morimoto #define rsnd_src_nr(priv) ((priv)->src_nr) 3643cb6954SKuninori Morimoto #define rsnd_enable_sync_convert(src) ((src)->sen.val) 3782e76ed3SKuninori Morimoto #define rsnd_src_of_node(priv) \ 3882e76ed3SKuninori Morimoto of_get_child_by_name(rsnd_priv_to_dev(priv)->of_node, "rcar_sound,src") 3982e76ed3SKuninori Morimoto 40ba9c949fSKuninori Morimoto #define rsnd_mod_to_src(_mod) \ 41ba9c949fSKuninori Morimoto container_of((_mod), struct rsnd_src, mod) 42ba9c949fSKuninori Morimoto 43ba9c949fSKuninori Morimoto #define for_each_rsnd_src(pos, priv, i) \ 44ba9c949fSKuninori Morimoto for ((i) = 0; \ 45ba9c949fSKuninori Morimoto ((i) < rsnd_src_nr(priv)) && \ 46ba9c949fSKuninori Morimoto ((pos) = (struct rsnd_src *)(priv)->src + i); \ 47ba9c949fSKuninori Morimoto i++) 48ba9c949fSKuninori Morimoto 49ba9c949fSKuninori Morimoto 50ba9c949fSKuninori Morimoto /* 51ba9c949fSKuninori Morimoto * image of SRC (Sampling Rate Converter) 52ba9c949fSKuninori Morimoto * 53ba9c949fSKuninori Morimoto * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+ 54ba9c949fSKuninori Morimoto * 48kHz <-> | SRC | <------> | SSI | <-----> | codec | 55ba9c949fSKuninori Morimoto * 44.1kHz <-> +-----+ +-----+ +-------+ 56ba9c949fSKuninori Morimoto * ... 57ba9c949fSKuninori Morimoto * 58ba9c949fSKuninori Morimoto */ 59ba9c949fSKuninori Morimoto 60ba9c949fSKuninori Morimoto /* 61ba9c949fSKuninori Morimoto * src.c is caring... 62ba9c949fSKuninori Morimoto * 63ba9c949fSKuninori Morimoto * Gen1 64ba9c949fSKuninori Morimoto * 65ba9c949fSKuninori Morimoto * [mem] -> [SRU] -> [SSI] 66ba9c949fSKuninori Morimoto * |--------| 67ba9c949fSKuninori Morimoto * 68ba9c949fSKuninori Morimoto * Gen2 69ba9c949fSKuninori Morimoto * 70ba9c949fSKuninori Morimoto * [mem] -> [SRC] -> [SSIU] -> [SSI] 71ba9c949fSKuninori Morimoto * |-----------------| 72ba9c949fSKuninori Morimoto */ 73ba9c949fSKuninori Morimoto 74ba9c949fSKuninori Morimoto /* 75ba9c949fSKuninori Morimoto * How to use SRC bypass mode for debugging 76ba9c949fSKuninori Morimoto * 77ba9c949fSKuninori Morimoto * SRC has bypass mode, and it is useful for debugging. 78ba9c949fSKuninori Morimoto * In Gen2 case, 79ba9c949fSKuninori Morimoto * SRCm_MODE controls whether SRC is used or not 80ba9c949fSKuninori Morimoto * SSI_MODE0 controls whether SSIU which receives SRC data 81ba9c949fSKuninori Morimoto * is used or not. 82ba9c949fSKuninori Morimoto * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC, 83ba9c949fSKuninori Morimoto * but SRC bypass mode needs SSI_MODE0 only. 84ba9c949fSKuninori Morimoto * 85ba9c949fSKuninori Morimoto * This driver request 86ba9c949fSKuninori Morimoto * struct rsnd_src_platform_info { 87ba9c949fSKuninori Morimoto * u32 convert_rate; 8829e69fd2SKuninori Morimoto * int dma_id; 89ba9c949fSKuninori Morimoto * } 90ba9c949fSKuninori Morimoto * 91ba9c949fSKuninori Morimoto * rsnd_src_convert_rate() indicates 92ba9c949fSKuninori Morimoto * above convert_rate, and it controls 93ba9c949fSKuninori Morimoto * whether SRC is used or not. 94ba9c949fSKuninori Morimoto * 95ba9c949fSKuninori Morimoto * ex) doesn't use SRC 9629e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 9729e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], }, 98ba9c949fSKuninori Morimoto * }; 99ba9c949fSKuninori Morimoto * 100ba9c949fSKuninori Morimoto * ex) uses SRC 10129e69fd2SKuninori Morimoto * static struct rsnd_src_platform_info rsnd_src[] = { 10229e69fd2SKuninori Morimoto * RSND_SCU(48000, 0), 10329e69fd2SKuninori Morimoto * ... 10429e69fd2SKuninori Morimoto * }; 10529e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 10629e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, 107ba9c949fSKuninori Morimoto * }; 108ba9c949fSKuninori Morimoto * 109ba9c949fSKuninori Morimoto * ex) uses SRC bypass mode 11029e69fd2SKuninori Morimoto * static struct rsnd_src_platform_info rsnd_src[] = { 11129e69fd2SKuninori Morimoto * RSND_SCU(0, 0), 11229e69fd2SKuninori Morimoto * ... 11329e69fd2SKuninori Morimoto * }; 11429e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 11529e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, 116ba9c949fSKuninori Morimoto * }; 117ba9c949fSKuninori Morimoto * 118ba9c949fSKuninori Morimoto */ 119ba9c949fSKuninori Morimoto 120379febfdSKuninori Morimoto static void rsnd_src_soft_reset(struct rsnd_mod *mod) 121379febfdSKuninori Morimoto { 122379febfdSKuninori Morimoto rsnd_mod_write(mod, SRC_SWRSR, 0); 123379febfdSKuninori Morimoto rsnd_mod_write(mod, SRC_SWRSR, 1); 124379febfdSKuninori Morimoto } 125379febfdSKuninori Morimoto 1269b99e9a7SKuninori Morimoto static struct dma_chan *rsnd_src_dma_req(struct rsnd_dai_stream *io, 1279b99e9a7SKuninori Morimoto struct rsnd_mod *mod) 12872adc61fSKuninori Morimoto { 12972adc61fSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 13072adc61fSKuninori Morimoto int is_play = rsnd_io_is_play(io); 13172adc61fSKuninori Morimoto 13272adc61fSKuninori Morimoto return rsnd_dma_request_channel(rsnd_src_of_node(priv), 13372adc61fSKuninori Morimoto mod, 13472adc61fSKuninori Morimoto is_play ? "rx" : "tx"); 13572adc61fSKuninori Morimoto } 13672adc61fSKuninori Morimoto 13788c61cffSKuninori Morimoto static u32 rsnd_src_convert_rate(struct rsnd_dai_stream *io, 13888c61cffSKuninori Morimoto struct rsnd_src *src) 13943cb6954SKuninori Morimoto { 14043cb6954SKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 14143cb6954SKuninori Morimoto u32 convert_rate; 14243cb6954SKuninori Morimoto 14343cb6954SKuninori Morimoto if (!runtime) 14443cb6954SKuninori Morimoto return 0; 14543cb6954SKuninori Morimoto 14643cb6954SKuninori Morimoto if (!rsnd_enable_sync_convert(src)) 14743cb6954SKuninori Morimoto return src->convert_rate; 14843cb6954SKuninori Morimoto 14943cb6954SKuninori Morimoto convert_rate = src->sync.val; 15043cb6954SKuninori Morimoto 15143cb6954SKuninori Morimoto if (!convert_rate) 15243cb6954SKuninori Morimoto convert_rate = src->convert_rate; 15343cb6954SKuninori Morimoto 15443cb6954SKuninori Morimoto if (!convert_rate) 15543cb6954SKuninori Morimoto convert_rate = runtime->rate; 15643cb6954SKuninori Morimoto 15743cb6954SKuninori Morimoto return convert_rate; 15843cb6954SKuninori Morimoto } 15943cb6954SKuninori Morimoto 160ba9c949fSKuninori Morimoto unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 161ba9c949fSKuninori Morimoto struct rsnd_dai_stream *io, 162ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime) 163ba9c949fSKuninori Morimoto { 164b1eac430SKuninori Morimoto struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); 165ba9c949fSKuninori Morimoto struct rsnd_src *src; 166b1eac430SKuninori Morimoto unsigned int rate = 0; 167ba9c949fSKuninori Morimoto 168b1eac430SKuninori Morimoto if (src_mod) { 169b1eac430SKuninori Morimoto src = rsnd_mod_to_src(src_mod); 170ba9c949fSKuninori Morimoto 171ba9c949fSKuninori Morimoto /* 172ba9c949fSKuninori Morimoto * return convert rate if SRC is used, 173ba9c949fSKuninori Morimoto * otherwise, return runtime->rate as usual 174ba9c949fSKuninori Morimoto */ 17588c61cffSKuninori Morimoto rate = rsnd_src_convert_rate(io, src); 176b1eac430SKuninori Morimoto } 177b1eac430SKuninori Morimoto 178ba9c949fSKuninori Morimoto if (!rate) 179ba9c949fSKuninori Morimoto rate = runtime->rate; 180ba9c949fSKuninori Morimoto 181ba9c949fSKuninori Morimoto return rate; 182ba9c949fSKuninori Morimoto } 183ba9c949fSKuninori Morimoto 1843b7843ffSKuninori Morimoto static int rsnd_src_hw_params(struct rsnd_mod *mod, 1852c0fac19SKuninori Morimoto struct rsnd_dai_stream *io, 1863b7843ffSKuninori Morimoto struct snd_pcm_substream *substream, 1873b7843ffSKuninori Morimoto struct snd_pcm_hw_params *fe_params) 1883b7843ffSKuninori Morimoto { 1893b7843ffSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 1903b7843ffSKuninori Morimoto struct snd_soc_pcm_runtime *fe = substream->private_data; 1913b7843ffSKuninori Morimoto 1923b7843ffSKuninori Morimoto /* default value (mainly for non-DT) */ 1933b7843ffSKuninori Morimoto src->convert_rate = src->info->convert_rate; 1943b7843ffSKuninori Morimoto 1953b7843ffSKuninori Morimoto /* 1963b7843ffSKuninori Morimoto * SRC assumes that it is used under DPCM if user want to use 1973b7843ffSKuninori Morimoto * sampling rate convert. Then, SRC should be FE. 1983b7843ffSKuninori Morimoto * And then, this function will be called *after* BE settings. 1993b7843ffSKuninori Morimoto * this means, each BE already has fixuped hw_params. 2003b7843ffSKuninori Morimoto * see 2013b7843ffSKuninori Morimoto * dpcm_fe_dai_hw_params() 2023b7843ffSKuninori Morimoto * dpcm_be_dai_hw_params() 2033b7843ffSKuninori Morimoto */ 2043b7843ffSKuninori Morimoto if (fe->dai_link->dynamic) { 2053b7843ffSKuninori Morimoto int stream = substream->stream; 2063b7843ffSKuninori Morimoto struct snd_soc_dpcm *dpcm; 2073b7843ffSKuninori Morimoto struct snd_pcm_hw_params *be_params; 2083b7843ffSKuninori Morimoto 2093b7843ffSKuninori Morimoto list_for_each_entry(dpcm, &fe->dpcm[stream].be_clients, list_be) { 2103b7843ffSKuninori Morimoto be_params = &dpcm->hw_params; 2113b7843ffSKuninori Morimoto 2123b7843ffSKuninori Morimoto if (params_rate(fe_params) != params_rate(be_params)) 2133b7843ffSKuninori Morimoto src->convert_rate = params_rate(be_params); 2143b7843ffSKuninori Morimoto } 2153b7843ffSKuninori Morimoto } 2163b7843ffSKuninori Morimoto 2173b7843ffSKuninori Morimoto return 0; 2183b7843ffSKuninori Morimoto } 2193b7843ffSKuninori Morimoto 220*75916f65SKuninori Morimoto static void rsnd_src_set_convert_rate(struct rsnd_dai_stream *io, 221*75916f65SKuninori Morimoto struct rsnd_mod *mod) 222ba9c949fSKuninori Morimoto { 223*75916f65SKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 224cfcefe01SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 225*75916f65SKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 226*75916f65SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 227*75916f65SKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(io, src); 228*75916f65SKuninori Morimoto u32 ifscr, fsrate, adinr; 229*75916f65SKuninori Morimoto u32 cr, route; 230*75916f65SKuninori Morimoto u32 bsdsr, bsisr; 231*75916f65SKuninori Morimoto uint ratio; 232ba9c949fSKuninori Morimoto 233*75916f65SKuninori Morimoto if (!runtime) 234*75916f65SKuninori Morimoto return; 235ba9c949fSKuninori Morimoto 236*75916f65SKuninori Morimoto /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ 237*75916f65SKuninori Morimoto if (!convert_rate) 238*75916f65SKuninori Morimoto ratio = 0; 239*75916f65SKuninori Morimoto else if (convert_rate > runtime->rate) 240*75916f65SKuninori Morimoto ratio = 100 * convert_rate / runtime->rate; 241*75916f65SKuninori Morimoto else 242*75916f65SKuninori Morimoto ratio = 100 * runtime->rate / convert_rate; 243cfcefe01SKuninori Morimoto 244*75916f65SKuninori Morimoto if (ratio > 600) { 245*75916f65SKuninori Morimoto dev_err(dev, "FSO/FSI ratio error\n"); 246*75916f65SKuninori Morimoto return; 247ba9c949fSKuninori Morimoto } 248ba9c949fSKuninori Morimoto 249ba9c949fSKuninori Morimoto /* 250*75916f65SKuninori Morimoto * SRC_ADINR 251ba9c949fSKuninori Morimoto */ 252*75916f65SKuninori Morimoto adinr = rsnd_get_adinr_bit(mod, io); 253*75916f65SKuninori Morimoto 254*75916f65SKuninori Morimoto /* 255*75916f65SKuninori Morimoto * SRC_IFSCR / SRC_IFSVR 256*75916f65SKuninori Morimoto */ 257*75916f65SKuninori Morimoto ifscr = 0; 258*75916f65SKuninori Morimoto fsrate = 0; 259*75916f65SKuninori Morimoto if (convert_rate) { 260*75916f65SKuninori Morimoto ifscr = 1; 261*75916f65SKuninori Morimoto fsrate = 0x0400000 / convert_rate * runtime->rate; 262*75916f65SKuninori Morimoto } 263*75916f65SKuninori Morimoto 264*75916f65SKuninori Morimoto /* 265*75916f65SKuninori Morimoto * SRC_SRCCR / SRC_ROUTE_MODE0 266*75916f65SKuninori Morimoto */ 267*75916f65SKuninori Morimoto cr = 0x00011110; 268*75916f65SKuninori Morimoto route = 0x0; 269*75916f65SKuninori Morimoto if (convert_rate) { 270*75916f65SKuninori Morimoto route = 0x1; 271*75916f65SKuninori Morimoto 272*75916f65SKuninori Morimoto if (rsnd_enable_sync_convert(src)) { 273*75916f65SKuninori Morimoto cr |= 0x1; 274*75916f65SKuninori Morimoto route |= rsnd_io_is_play(io) ? 275*75916f65SKuninori Morimoto (0x1 << 24) : (0x1 << 25); 276*75916f65SKuninori Morimoto } 277*75916f65SKuninori Morimoto } 278*75916f65SKuninori Morimoto 279*75916f65SKuninori Morimoto /* 280*75916f65SKuninori Morimoto * SRC_BSDSR / SRC_BSISR 281*75916f65SKuninori Morimoto */ 282*75916f65SKuninori Morimoto switch (rsnd_mod_id(mod)) { 283*75916f65SKuninori Morimoto case 5: 284*75916f65SKuninori Morimoto case 6: 285*75916f65SKuninori Morimoto case 7: 286*75916f65SKuninori Morimoto case 8: 287*75916f65SKuninori Morimoto bsdsr = 0x02400000; /* 6 - 1/6 */ 288*75916f65SKuninori Morimoto bsisr = 0x00100060; /* 6 - 1/6 */ 289*75916f65SKuninori Morimoto break; 290*75916f65SKuninori Morimoto default: 291*75916f65SKuninori Morimoto bsdsr = 0x01800000; /* 6 - 1/6 */ 292*75916f65SKuninori Morimoto bsisr = 0x00100060 ;/* 6 - 1/6 */ 293*75916f65SKuninori Morimoto break; 294*75916f65SKuninori Morimoto } 295*75916f65SKuninori Morimoto 296*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_SRCIR, 1); /* initialize */ 297*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_ADINR, adinr); 298*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_IFSCR, ifscr); 299*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_IFSVR, fsrate); 300*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_SRCCR, cr); 301*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_BSDSR, bsdsr); 302*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_BSISR, bsisr); 303*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_SRCIR, 0); /* cancel initialize */ 304*75916f65SKuninori Morimoto 305*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_ROUTE_MODE0, route); 306*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); 307*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_BUSIF_DALIGN, rsnd_get_dalign(mod, io)); 308*75916f65SKuninori Morimoto 309*75916f65SKuninori Morimoto if (convert_rate) 310*75916f65SKuninori Morimoto rsnd_adg_set_convert_clk_gen2(mod, io, 311*75916f65SKuninori Morimoto runtime->rate, 312*75916f65SKuninori Morimoto convert_rate); 313*75916f65SKuninori Morimoto else 314*75916f65SKuninori Morimoto rsnd_adg_set_convert_timing_gen2(mod, io); 315*75916f65SKuninori Morimoto } 316*75916f65SKuninori Morimoto 317*75916f65SKuninori Morimoto #define rsnd_src_irq_enable(mod) rsnd_src_irq_ctrol(mod, 1) 318*75916f65SKuninori Morimoto #define rsnd_src_irq_disable(mod) rsnd_src_irq_ctrol(mod, 0) 319*75916f65SKuninori Morimoto static void rsnd_src_irq_ctrol(struct rsnd_mod *mod, int enable) 320cfcefe01SKuninori Morimoto { 321cfcefe01SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 322cfcefe01SKuninori Morimoto u32 sys_int_val, int_val, sys_int_mask; 323cfcefe01SKuninori Morimoto int irq = src->info->irq; 324cfcefe01SKuninori Morimoto int id = rsnd_mod_id(mod); 325cfcefe01SKuninori Morimoto 326cfcefe01SKuninori Morimoto sys_int_val = 327cfcefe01SKuninori Morimoto sys_int_mask = OUF_SRC(id); 328cfcefe01SKuninori Morimoto int_val = 0x3300; 329cfcefe01SKuninori Morimoto 330cfcefe01SKuninori Morimoto /* 331cfcefe01SKuninori Morimoto * IRQ is not supported on non-DT 332cfcefe01SKuninori Morimoto * see 333*75916f65SKuninori Morimoto * rsnd_src_probe_() 334cfcefe01SKuninori Morimoto */ 335cfcefe01SKuninori Morimoto if ((irq <= 0) || !enable) { 336cfcefe01SKuninori Morimoto sys_int_val = 0; 337cfcefe01SKuninori Morimoto int_val = 0; 338cfcefe01SKuninori Morimoto } 339cfcefe01SKuninori Morimoto 3401a1bf58aSKuninori Morimoto /* 3411a1bf58aSKuninori Morimoto * WORKAROUND 3421a1bf58aSKuninori Morimoto * 3431a1bf58aSKuninori Morimoto * ignore over flow error when rsnd_enable_sync_convert() 3441a1bf58aSKuninori Morimoto */ 3451a1bf58aSKuninori Morimoto if (rsnd_enable_sync_convert(src)) 3461a1bf58aSKuninori Morimoto sys_int_val = sys_int_val & 0xffff; 3471a1bf58aSKuninori Morimoto 348cfcefe01SKuninori Morimoto rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val); 349cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val); 350cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); 351cfcefe01SKuninori Morimoto } 352cfcefe01SKuninori Morimoto 353*75916f65SKuninori Morimoto static void rsnd_src_error_clear(struct rsnd_mod *mod) 354cfcefe01SKuninori Morimoto { 355cfcefe01SKuninori Morimoto u32 val = OUF_SRC(rsnd_mod_id(mod)); 356cfcefe01SKuninori Morimoto 357cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_STATUS0, val, val); 358cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); 359cfcefe01SKuninori Morimoto } 360cfcefe01SKuninori Morimoto 361*75916f65SKuninori Morimoto static bool rsnd_src_error_record(struct rsnd_mod *mod) 362cfcefe01SKuninori Morimoto { 3631a1bf58aSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 3641a1bf58aSKuninori Morimoto u32 val0, val1; 365cfcefe01SKuninori Morimoto bool ret = false; 366cfcefe01SKuninori Morimoto 3671a1bf58aSKuninori Morimoto val0 = val1 = OUF_SRC(rsnd_mod_id(mod)); 3681a1bf58aSKuninori Morimoto 3691a1bf58aSKuninori Morimoto /* 3701a1bf58aSKuninori Morimoto * WORKAROUND 3711a1bf58aSKuninori Morimoto * 3721a1bf58aSKuninori Morimoto * ignore over flow error when rsnd_enable_sync_convert() 3731a1bf58aSKuninori Morimoto */ 3741a1bf58aSKuninori Morimoto if (rsnd_enable_sync_convert(src)) 3751a1bf58aSKuninori Morimoto val0 = val0 & 0xffff; 3761a1bf58aSKuninori Morimoto 3771a1bf58aSKuninori Morimoto if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val0) || 3781a1bf58aSKuninori Morimoto (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val1)) { 379cfcefe01SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 380cfcefe01SKuninori Morimoto 381cfcefe01SKuninori Morimoto src->err++; 382cfcefe01SKuninori Morimoto ret = true; 383cfcefe01SKuninori Morimoto } 384cfcefe01SKuninori Morimoto 385cfcefe01SKuninori Morimoto /* clear error static */ 386*75916f65SKuninori Morimoto rsnd_src_error_clear(mod); 387cfcefe01SKuninori Morimoto 388cfcefe01SKuninori Morimoto return ret; 389cfcefe01SKuninori Morimoto } 390cfcefe01SKuninori Morimoto 391*75916f65SKuninori Morimoto static int rsnd_src_start(struct rsnd_mod *mod, 392497debaaSKuninori Morimoto struct rsnd_dai_stream *io, 393497debaaSKuninori Morimoto struct rsnd_priv *priv) 394cfcefe01SKuninori Morimoto { 3951a1bf58aSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 3961a1bf58aSKuninori Morimoto u32 val; 3971a1bf58aSKuninori Morimoto 3981a1bf58aSKuninori Morimoto /* 3991a1bf58aSKuninori Morimoto * WORKAROUND 4001a1bf58aSKuninori Morimoto * 4011a1bf58aSKuninori Morimoto * Enable SRC output if you want to use sync convert together with DVC 4021a1bf58aSKuninori Morimoto */ 4031a1bf58aSKuninori Morimoto val = (rsnd_io_to_mod_dvc(io) && !rsnd_enable_sync_convert(src)) ? 4041a1bf58aSKuninori Morimoto 0x01 : 0x11; 405cfcefe01SKuninori Morimoto 406cfcefe01SKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, val); 407cfcefe01SKuninori Morimoto 408*75916f65SKuninori Morimoto return 0; 409*75916f65SKuninori Morimoto } 410cfcefe01SKuninori Morimoto 411*75916f65SKuninori Morimoto static int rsnd_src_stop(struct rsnd_mod *mod, 412*75916f65SKuninori Morimoto struct rsnd_dai_stream *io, 413*75916f65SKuninori Morimoto struct rsnd_priv *priv) 414*75916f65SKuninori Morimoto { 415*75916f65SKuninori Morimoto /* 416*75916f65SKuninori Morimoto * stop SRC output only 417*75916f65SKuninori Morimoto * see rsnd_src_quit 418*75916f65SKuninori Morimoto */ 419*75916f65SKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, 0x01); 420cfcefe01SKuninori Morimoto 421cfcefe01SKuninori Morimoto return 0; 422cfcefe01SKuninori Morimoto } 423cfcefe01SKuninori Morimoto 424*75916f65SKuninori Morimoto static int rsnd_src_init(struct rsnd_mod *mod, 425497debaaSKuninori Morimoto struct rsnd_dai_stream *io, 426497debaaSKuninori Morimoto struct rsnd_priv *priv) 427cfcefe01SKuninori Morimoto { 428*75916f65SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 429cfcefe01SKuninori Morimoto 430*75916f65SKuninori Morimoto rsnd_mod_power_on(mod); 431cfcefe01SKuninori Morimoto 432*75916f65SKuninori Morimoto rsnd_src_soft_reset(mod); 433cfcefe01SKuninori Morimoto 434*75916f65SKuninori Morimoto rsnd_src_set_convert_rate(io, mod); 435*75916f65SKuninori Morimoto 436*75916f65SKuninori Morimoto rsnd_src_error_clear(mod); 437*75916f65SKuninori Morimoto 438*75916f65SKuninori Morimoto rsnd_src_irq_enable(mod); 439*75916f65SKuninori Morimoto 440*75916f65SKuninori Morimoto src->err = 0; 441*75916f65SKuninori Morimoto 442*75916f65SKuninori Morimoto /* reset sync convert_rate */ 443*75916f65SKuninori Morimoto src->sync.val = 0; 444*75916f65SKuninori Morimoto 445*75916f65SKuninori Morimoto return 0; 446cfcefe01SKuninori Morimoto } 447cfcefe01SKuninori Morimoto 448*75916f65SKuninori Morimoto static int rsnd_src_quit(struct rsnd_mod *mod, 449b761bf27SKuninori Morimoto struct rsnd_dai_stream *io, 450b761bf27SKuninori Morimoto struct rsnd_priv *priv) 451b761bf27SKuninori Morimoto { 452*75916f65SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 453*75916f65SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 454*75916f65SKuninori Morimoto 455*75916f65SKuninori Morimoto rsnd_src_irq_disable(mod); 456*75916f65SKuninori Morimoto 457b761bf27SKuninori Morimoto /* stop both out/in */ 458b761bf27SKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, 0); 459b761bf27SKuninori Morimoto 460*75916f65SKuninori Morimoto rsnd_mod_power_off(mod); 461*75916f65SKuninori Morimoto 462*75916f65SKuninori Morimoto if (src->err) 463*75916f65SKuninori Morimoto dev_warn(dev, "%s[%d] under/over flow err = %d\n", 464*75916f65SKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); 465*75916f65SKuninori Morimoto 466*75916f65SKuninori Morimoto src->convert_rate = 0; 467*75916f65SKuninori Morimoto 468*75916f65SKuninori Morimoto /* reset sync convert_rate */ 469*75916f65SKuninori Morimoto src->sync.val = 0; 470*75916f65SKuninori Morimoto 471*75916f65SKuninori Morimoto return 0; 472b761bf27SKuninori Morimoto } 473b761bf27SKuninori Morimoto 474*75916f65SKuninori Morimoto static void __rsnd_src_interrupt(struct rsnd_mod *mod, 47588c61cffSKuninori Morimoto struct rsnd_dai_stream *io) 476cfcefe01SKuninori Morimoto { 47702299d98SKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 47869e32a58SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 47969e32a58SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 480cfcefe01SKuninori Morimoto 48102299d98SKuninori Morimoto spin_lock(&priv->lock); 48202299d98SKuninori Morimoto 48302299d98SKuninori Morimoto /* ignore all cases if not working */ 484d5bbe7deSKuninori Morimoto if (!rsnd_io_is_working(io)) 485*75916f65SKuninori Morimoto goto rsnd_src_interrupt_out; 486cfcefe01SKuninori Morimoto 487*75916f65SKuninori Morimoto if (rsnd_src_error_record(mod)) { 488cfcefe01SKuninori Morimoto 489cfcefe01SKuninori Morimoto dev_dbg(dev, "%s[%d] restart\n", 490cfcefe01SKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 491639b231fSKuninori Morimoto 492*75916f65SKuninori Morimoto rsnd_src_stop(mod, io, priv); 493*75916f65SKuninori Morimoto rsnd_src_start(mod, io, priv); 49469e32a58SKuninori Morimoto } 49569e32a58SKuninori Morimoto 49669e32a58SKuninori Morimoto if (src->err > 1024) { 497*75916f65SKuninori Morimoto rsnd_src_irq_disable(mod); 49869e32a58SKuninori Morimoto 49969e32a58SKuninori Morimoto dev_warn(dev, "no more %s[%d] restart\n", 50069e32a58SKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 501cfcefe01SKuninori Morimoto } 50288c61cffSKuninori Morimoto 503*75916f65SKuninori Morimoto rsnd_src_interrupt_out: 50402299d98SKuninori Morimoto spin_unlock(&priv->lock); 50588c61cffSKuninori Morimoto } 50688c61cffSKuninori Morimoto 507*75916f65SKuninori Morimoto static irqreturn_t rsnd_src_interrupt(int irq, void *data) 50888c61cffSKuninori Morimoto { 50988c61cffSKuninori Morimoto struct rsnd_mod *mod = data; 51088c61cffSKuninori Morimoto 511*75916f65SKuninori Morimoto rsnd_mod_interrupt(mod, __rsnd_src_interrupt); 512cfcefe01SKuninori Morimoto 513cfcefe01SKuninori Morimoto return IRQ_HANDLED; 514cfcefe01SKuninori Morimoto } 515cfcefe01SKuninori Morimoto 516*75916f65SKuninori Morimoto static int rsnd_src_probe_(struct rsnd_mod *mod, 5172c0fac19SKuninori Morimoto struct rsnd_dai_stream *io, 518690602fcSKuninori Morimoto struct rsnd_priv *priv) 519ba9c949fSKuninori Morimoto { 520ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 521ba9c949fSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 522cfcefe01SKuninori Morimoto int irq = src->info->irq; 523ba9c949fSKuninori Morimoto int ret; 524ba9c949fSKuninori Morimoto 525cfcefe01SKuninori Morimoto if (irq > 0) { 526cfcefe01SKuninori Morimoto /* 527cfcefe01SKuninori Morimoto * IRQ is not supported on non-DT 528cfcefe01SKuninori Morimoto * see 529*75916f65SKuninori Morimoto * rsnd_src_irq_enable() 530cfcefe01SKuninori Morimoto */ 531cfcefe01SKuninori Morimoto ret = devm_request_irq(dev, irq, 532*75916f65SKuninori Morimoto rsnd_src_interrupt, 533cfcefe01SKuninori Morimoto IRQF_SHARED, 534cfcefe01SKuninori Morimoto dev_name(dev), mod); 535cfcefe01SKuninori Morimoto if (ret) 536b543b52aSKuninori Morimoto return ret; 537cfcefe01SKuninori Morimoto } 538cfcefe01SKuninori Morimoto 53981ecbb65SKuninori Morimoto src->dma = rsnd_dma_attach(io, mod, src->info->dma_id); 540232c00b6SKuninori Morimoto if (IS_ERR(src->dma)) 541232c00b6SKuninori Morimoto return PTR_ERR(src->dma); 542cfcefe01SKuninori Morimoto 543cfcefe01SKuninori Morimoto return ret; 544ba9c949fSKuninori Morimoto } 545ba9c949fSKuninori Morimoto 546*75916f65SKuninori Morimoto static int rsnd_src_pcm_new(struct rsnd_mod *mod, 5472c0fac19SKuninori Morimoto struct rsnd_dai_stream *io, 54843cb6954SKuninori Morimoto struct snd_soc_pcm_runtime *rtd) 54943cb6954SKuninori Morimoto { 55043cb6954SKuninori Morimoto struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 55143cb6954SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 55243cb6954SKuninori Morimoto int ret; 55343cb6954SKuninori Morimoto 55443cb6954SKuninori Morimoto /* 55543cb6954SKuninori Morimoto * enable SRC sync convert if possible 55643cb6954SKuninori Morimoto */ 55743cb6954SKuninori Morimoto 55843cb6954SKuninori Morimoto /* 55943cb6954SKuninori Morimoto * SRC sync convert needs clock master 56043cb6954SKuninori Morimoto */ 56143cb6954SKuninori Morimoto if (!rsnd_rdai_is_clk_master(rdai)) 56243cb6954SKuninori Morimoto return 0; 56343cb6954SKuninori Morimoto 56443cb6954SKuninori Morimoto /* 56543cb6954SKuninori Morimoto * enable sync convert 56643cb6954SKuninori Morimoto */ 567b65a7cccSKuninori Morimoto ret = rsnd_kctrl_new_s(mod, io, rtd, 56843cb6954SKuninori Morimoto rsnd_io_is_play(io) ? 56943cb6954SKuninori Morimoto "SRC Out Rate Switch" : 57043cb6954SKuninori Morimoto "SRC In Rate Switch", 571*75916f65SKuninori Morimoto rsnd_src_set_convert_rate, 57243cb6954SKuninori Morimoto &src->sen, 1); 57343cb6954SKuninori Morimoto if (ret < 0) 57443cb6954SKuninori Morimoto return ret; 57543cb6954SKuninori Morimoto 576b65a7cccSKuninori Morimoto ret = rsnd_kctrl_new_s(mod, io, rtd, 57743cb6954SKuninori Morimoto rsnd_io_is_play(io) ? 57843cb6954SKuninori Morimoto "SRC Out Rate" : 57943cb6954SKuninori Morimoto "SRC In Rate", 580*75916f65SKuninori Morimoto rsnd_src_set_convert_rate, 58143cb6954SKuninori Morimoto &src->sync, 192000); 58243cb6954SKuninori Morimoto 58343cb6954SKuninori Morimoto return ret; 58443cb6954SKuninori Morimoto } 58543cb6954SKuninori Morimoto 586*75916f65SKuninori Morimoto static struct rsnd_mod_ops rsnd_src_ops = { 5878aefda50SKuninori Morimoto .name = SRC_NAME, 58872adc61fSKuninori Morimoto .dma_req = rsnd_src_dma_req, 589*75916f65SKuninori Morimoto .probe = rsnd_src_probe_, 590*75916f65SKuninori Morimoto .init = rsnd_src_init, 591*75916f65SKuninori Morimoto .quit = rsnd_src_quit, 592*75916f65SKuninori Morimoto .start = rsnd_src_start, 593*75916f65SKuninori Morimoto .stop = rsnd_src_stop, 5943b7843ffSKuninori Morimoto .hw_params = rsnd_src_hw_params, 595*75916f65SKuninori Morimoto .pcm_new = rsnd_src_pcm_new, 596ba9c949fSKuninori Morimoto }; 597ba9c949fSKuninori Morimoto 598ba9c949fSKuninori Morimoto struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 599ba9c949fSKuninori Morimoto { 600ba9c949fSKuninori Morimoto if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 601ba9c949fSKuninori Morimoto id = 0; 602ba9c949fSKuninori Morimoto 603b76e218aSKuninori Morimoto return rsnd_mod_get((struct rsnd_src *)(priv->src) + id); 604ba9c949fSKuninori Morimoto } 605ba9c949fSKuninori Morimoto 60690e8e50fSKuninori Morimoto static void rsnd_of_parse_src(struct platform_device *pdev, 60790e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 60890e8e50fSKuninori Morimoto struct rsnd_priv *priv) 60990e8e50fSKuninori Morimoto { 61090e8e50fSKuninori Morimoto struct device_node *src_node; 611cfcefe01SKuninori Morimoto struct device_node *np; 61290e8e50fSKuninori Morimoto struct rcar_snd_info *info = rsnd_priv_to_info(priv); 61390e8e50fSKuninori Morimoto struct rsnd_src_platform_info *src_info; 61490e8e50fSKuninori Morimoto struct device *dev = &pdev->dev; 615cfcefe01SKuninori Morimoto int nr, i; 61690e8e50fSKuninori Morimoto 61790e8e50fSKuninori Morimoto if (!of_data) 61890e8e50fSKuninori Morimoto return; 61990e8e50fSKuninori Morimoto 62082e76ed3SKuninori Morimoto src_node = rsnd_src_of_node(priv); 62190e8e50fSKuninori Morimoto if (!src_node) 62290e8e50fSKuninori Morimoto return; 62390e8e50fSKuninori Morimoto 62490e8e50fSKuninori Morimoto nr = of_get_child_count(src_node); 62590e8e50fSKuninori Morimoto if (!nr) 626f451e48dSKuninori Morimoto goto rsnd_of_parse_src_end; 62790e8e50fSKuninori Morimoto 62890e8e50fSKuninori Morimoto src_info = devm_kzalloc(dev, 62990e8e50fSKuninori Morimoto sizeof(struct rsnd_src_platform_info) * nr, 63090e8e50fSKuninori Morimoto GFP_KERNEL); 63190e8e50fSKuninori Morimoto if (!src_info) { 63290e8e50fSKuninori Morimoto dev_err(dev, "src info allocation error\n"); 633f451e48dSKuninori Morimoto goto rsnd_of_parse_src_end; 63490e8e50fSKuninori Morimoto } 63590e8e50fSKuninori Morimoto 63690e8e50fSKuninori Morimoto info->src_info = src_info; 63790e8e50fSKuninori Morimoto info->src_info_nr = nr; 638f451e48dSKuninori Morimoto 639cfcefe01SKuninori Morimoto i = 0; 640cfcefe01SKuninori Morimoto for_each_child_of_node(src_node, np) { 641cfcefe01SKuninori Morimoto src_info[i].irq = irq_of_parse_and_map(np, 0); 642cfcefe01SKuninori Morimoto 643cfcefe01SKuninori Morimoto i++; 644cfcefe01SKuninori Morimoto } 645cfcefe01SKuninori Morimoto 646f451e48dSKuninori Morimoto rsnd_of_parse_src_end: 647f451e48dSKuninori Morimoto of_node_put(src_node); 64890e8e50fSKuninori Morimoto } 64990e8e50fSKuninori Morimoto 650ba9c949fSKuninori Morimoto int rsnd_src_probe(struct platform_device *pdev, 65190e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 652ba9c949fSKuninori Morimoto struct rsnd_priv *priv) 653ba9c949fSKuninori Morimoto { 654ba9c949fSKuninori Morimoto struct rcar_snd_info *info = rsnd_priv_to_info(priv); 655ba9c949fSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 656ba9c949fSKuninori Morimoto struct rsnd_src *src; 657ba9c949fSKuninori Morimoto struct clk *clk; 658ba9c949fSKuninori Morimoto char name[RSND_SRC_NAME_SIZE]; 6592f78dd7fSKuninori Morimoto int i, nr, ret; 660ba9c949fSKuninori Morimoto 661e8e7b7bdSKuninori Morimoto /* This driver doesn't support Gen1 at this point */ 662e8e7b7bdSKuninori Morimoto if (rsnd_is_gen1(priv)) 663e8e7b7bdSKuninori Morimoto return 0; 664033e7ed8SKuninori Morimoto 66590e8e50fSKuninori Morimoto rsnd_of_parse_src(pdev, of_data, priv); 66690e8e50fSKuninori Morimoto 667ba9c949fSKuninori Morimoto /* 668ba9c949fSKuninori Morimoto * init SRC 669ba9c949fSKuninori Morimoto */ 670ba9c949fSKuninori Morimoto nr = info->src_info_nr; 671ba9c949fSKuninori Morimoto if (!nr) 672ba9c949fSKuninori Morimoto return 0; 673ba9c949fSKuninori Morimoto 674ba9c949fSKuninori Morimoto src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); 67533363f7aSKuninori Morimoto if (!src) 676ba9c949fSKuninori Morimoto return -ENOMEM; 677ba9c949fSKuninori Morimoto 678ba9c949fSKuninori Morimoto priv->src_nr = nr; 679ba9c949fSKuninori Morimoto priv->src = src; 680ba9c949fSKuninori Morimoto 681ba9c949fSKuninori Morimoto for_each_rsnd_src(src, priv, i) { 6828aefda50SKuninori Morimoto snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", 6838aefda50SKuninori Morimoto SRC_NAME, i); 684ba9c949fSKuninori Morimoto 685ba9c949fSKuninori Morimoto clk = devm_clk_get(dev, name); 686ba9c949fSKuninori Morimoto if (IS_ERR(clk)) 687ba9c949fSKuninori Morimoto return PTR_ERR(clk); 688ba9c949fSKuninori Morimoto 689ba9c949fSKuninori Morimoto src->info = &info->src_info[i]; 690ba9c949fSKuninori Morimoto 691e8e7b7bdSKuninori Morimoto ret = rsnd_mod_init(priv, rsnd_mod_get(src), 692*75916f65SKuninori Morimoto &rsnd_src_ops, clk, RSND_MOD_SRC, i); 6932f78dd7fSKuninori Morimoto if (ret) 6942f78dd7fSKuninori Morimoto return ret; 695ba9c949fSKuninori Morimoto } 696ba9c949fSKuninori Morimoto 697ba9c949fSKuninori Morimoto return 0; 698ba9c949fSKuninori Morimoto } 6992f78dd7fSKuninori Morimoto 7002f78dd7fSKuninori Morimoto void rsnd_src_remove(struct platform_device *pdev, 7012f78dd7fSKuninori Morimoto struct rsnd_priv *priv) 7022f78dd7fSKuninori Morimoto { 7032f78dd7fSKuninori Morimoto struct rsnd_src *src; 7042f78dd7fSKuninori Morimoto int i; 7052f78dd7fSKuninori Morimoto 7062f78dd7fSKuninori Morimoto for_each_rsnd_src(src, priv, i) { 707b76e218aSKuninori Morimoto rsnd_mod_quit(rsnd_mod_get(src)); 7082f78dd7fSKuninori Morimoto } 7092f78dd7fSKuninori Morimoto } 710