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 15ba9c949fSKuninori Morimoto struct rsnd_src { 16ba9c949fSKuninori Morimoto struct rsnd_src_platform_info *info; /* rcar_snd.h */ 17ba9c949fSKuninori Morimoto struct rsnd_mod mod; 18ba9c949fSKuninori Morimoto struct clk *clk; 19ba9c949fSKuninori Morimoto }; 20ba9c949fSKuninori Morimoto 21ba9c949fSKuninori Morimoto #define RSND_SRC_NAME_SIZE 16 22ba9c949fSKuninori Morimoto 23ba9c949fSKuninori Morimoto #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) 24ba9c949fSKuninori Morimoto #define rsnd_mod_to_src(_mod) \ 25ba9c949fSKuninori Morimoto container_of((_mod), struct rsnd_src, mod) 26ba9c949fSKuninori Morimoto #define rsnd_src_dma_available(src) \ 27ba9c949fSKuninori Morimoto rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) 28ba9c949fSKuninori Morimoto 29ba9c949fSKuninori Morimoto #define for_each_rsnd_src(pos, priv, i) \ 30ba9c949fSKuninori Morimoto for ((i) = 0; \ 31ba9c949fSKuninori Morimoto ((i) < rsnd_src_nr(priv)) && \ 32ba9c949fSKuninori Morimoto ((pos) = (struct rsnd_src *)(priv)->src + i); \ 33ba9c949fSKuninori Morimoto i++) 34ba9c949fSKuninori Morimoto 35ba9c949fSKuninori Morimoto 36ba9c949fSKuninori Morimoto /* 37ba9c949fSKuninori Morimoto * image of SRC (Sampling Rate Converter) 38ba9c949fSKuninori Morimoto * 39ba9c949fSKuninori Morimoto * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+ 40ba9c949fSKuninori Morimoto * 48kHz <-> | SRC | <------> | SSI | <-----> | codec | 41ba9c949fSKuninori Morimoto * 44.1kHz <-> +-----+ +-----+ +-------+ 42ba9c949fSKuninori Morimoto * ... 43ba9c949fSKuninori Morimoto * 44ba9c949fSKuninori Morimoto */ 45ba9c949fSKuninori Morimoto 46ba9c949fSKuninori Morimoto /* 47ba9c949fSKuninori Morimoto * src.c is caring... 48ba9c949fSKuninori Morimoto * 49ba9c949fSKuninori Morimoto * Gen1 50ba9c949fSKuninori Morimoto * 51ba9c949fSKuninori Morimoto * [mem] -> [SRU] -> [SSI] 52ba9c949fSKuninori Morimoto * |--------| 53ba9c949fSKuninori Morimoto * 54ba9c949fSKuninori Morimoto * Gen2 55ba9c949fSKuninori Morimoto * 56ba9c949fSKuninori Morimoto * [mem] -> [SRC] -> [SSIU] -> [SSI] 57ba9c949fSKuninori Morimoto * |-----------------| 58ba9c949fSKuninori Morimoto */ 59ba9c949fSKuninori Morimoto 60ba9c949fSKuninori Morimoto /* 61ba9c949fSKuninori Morimoto * How to use SRC bypass mode for debugging 62ba9c949fSKuninori Morimoto * 63ba9c949fSKuninori Morimoto * SRC has bypass mode, and it is useful for debugging. 64ba9c949fSKuninori Morimoto * In Gen2 case, 65ba9c949fSKuninori Morimoto * SRCm_MODE controls whether SRC is used or not 66ba9c949fSKuninori Morimoto * SSI_MODE0 controls whether SSIU which receives SRC data 67ba9c949fSKuninori Morimoto * is used or not. 68ba9c949fSKuninori Morimoto * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC, 69ba9c949fSKuninori Morimoto * but SRC bypass mode needs SSI_MODE0 only. 70ba9c949fSKuninori Morimoto * 71ba9c949fSKuninori Morimoto * This driver request 72ba9c949fSKuninori Morimoto * struct rsnd_src_platform_info { 73ba9c949fSKuninori Morimoto * u32 convert_rate; 7429e69fd2SKuninori Morimoto * int dma_id; 75ba9c949fSKuninori Morimoto * } 76ba9c949fSKuninori Morimoto * 77ba9c949fSKuninori Morimoto * rsnd_src_convert_rate() indicates 78ba9c949fSKuninori Morimoto * above convert_rate, and it controls 79ba9c949fSKuninori Morimoto * whether SRC is used or not. 80ba9c949fSKuninori Morimoto * 81ba9c949fSKuninori Morimoto * ex) doesn't use SRC 8229e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 8329e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], }, 84ba9c949fSKuninori Morimoto * }; 85ba9c949fSKuninori Morimoto * 86ba9c949fSKuninori Morimoto * ex) uses SRC 8729e69fd2SKuninori Morimoto * static struct rsnd_src_platform_info rsnd_src[] = { 8829e69fd2SKuninori Morimoto * RSND_SCU(48000, 0), 8929e69fd2SKuninori Morimoto * ... 9029e69fd2SKuninori Morimoto * }; 9129e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 9229e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, 93ba9c949fSKuninori Morimoto * }; 94ba9c949fSKuninori Morimoto * 95ba9c949fSKuninori Morimoto * ex) uses SRC bypass mode 9629e69fd2SKuninori Morimoto * static struct rsnd_src_platform_info rsnd_src[] = { 9729e69fd2SKuninori Morimoto * RSND_SCU(0, 0), 9829e69fd2SKuninori Morimoto * ... 9929e69fd2SKuninori Morimoto * }; 10029e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 10129e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, 102ba9c949fSKuninori Morimoto * }; 103ba9c949fSKuninori Morimoto * 104ba9c949fSKuninori Morimoto */ 105ba9c949fSKuninori Morimoto 106ba9c949fSKuninori Morimoto /* 107ba9c949fSKuninori Morimoto * Gen1/Gen2 common functions 108ba9c949fSKuninori Morimoto */ 109d9288d0bSKuninori Morimoto int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 110d9288d0bSKuninori Morimoto struct rsnd_dai *rdai, 111d9288d0bSKuninori Morimoto int use_busif) 112ba9c949fSKuninori Morimoto { 1131cc71959SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); 1141cc71959SKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 115ba9c949fSKuninori Morimoto int ssi_id = rsnd_mod_id(ssi_mod); 116ba9c949fSKuninori Morimoto 117ba9c949fSKuninori Morimoto /* 118ba9c949fSKuninori Morimoto * SSI_MODE0 119ba9c949fSKuninori Morimoto */ 120ba9c949fSKuninori Morimoto rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), 121d9288d0bSKuninori Morimoto !use_busif << ssi_id); 122ba9c949fSKuninori Morimoto 123ba9c949fSKuninori Morimoto /* 124ba9c949fSKuninori Morimoto * SSI_MODE1 125ba9c949fSKuninori Morimoto */ 126ba9c949fSKuninori Morimoto if (rsnd_ssi_is_pin_sharing(ssi_mod)) { 127ba9c949fSKuninori Morimoto int shift = -1; 128ba9c949fSKuninori Morimoto switch (ssi_id) { 129ba9c949fSKuninori Morimoto case 1: 130ba9c949fSKuninori Morimoto shift = 0; 131ba9c949fSKuninori Morimoto break; 132ba9c949fSKuninori Morimoto case 2: 133ba9c949fSKuninori Morimoto shift = 2; 134ba9c949fSKuninori Morimoto break; 135ba9c949fSKuninori Morimoto case 4: 136ba9c949fSKuninori Morimoto shift = 16; 137ba9c949fSKuninori Morimoto break; 138ba9c949fSKuninori Morimoto } 139ba9c949fSKuninori Morimoto 140ba9c949fSKuninori Morimoto if (shift >= 0) 141ba9c949fSKuninori Morimoto rsnd_mod_bset(ssi_mod, SSI_MODE1, 142ba9c949fSKuninori Morimoto 0x3 << shift, 143ba9c949fSKuninori Morimoto rsnd_dai_is_clk_master(rdai) ? 144ba9c949fSKuninori Morimoto 0x2 << shift : 0x1 << shift); 145ba9c949fSKuninori Morimoto } 146ba9c949fSKuninori Morimoto 147d9288d0bSKuninori Morimoto /* 148d9288d0bSKuninori Morimoto * DMA settings for SSIU 149d9288d0bSKuninori Morimoto */ 150d9288d0bSKuninori Morimoto if (use_busif) { 1511cc71959SKuninori Morimoto u32 val = 0x76543210; 1521cc71959SKuninori Morimoto u32 mask = ~0; 1531cc71959SKuninori Morimoto 154d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, 155d9288d0bSKuninori Morimoto rsnd_get_adinr(ssi_mod)); 156d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); 157d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); 1581cc71959SKuninori Morimoto 1591cc71959SKuninori Morimoto mask <<= runtime->channels * 4; 1601cc71959SKuninori Morimoto val = val & mask; 1611cc71959SKuninori Morimoto 1621cc71959SKuninori Morimoto switch (runtime->sample_bits) { 1631cc71959SKuninori Morimoto case 16: 1641cc71959SKuninori Morimoto val |= 0x67452301 & ~mask; 1651cc71959SKuninori Morimoto break; 1661cc71959SKuninori Morimoto case 32: 1671cc71959SKuninori Morimoto val |= 0x76543210 & ~mask; 1681cc71959SKuninori Morimoto break; 1691cc71959SKuninori Morimoto } 1701cc71959SKuninori Morimoto rsnd_mod_write(ssi_mod, BUSIF_DALIGN, val); 1711cc71959SKuninori Morimoto 172d9288d0bSKuninori Morimoto } 173d9288d0bSKuninori Morimoto 174d9288d0bSKuninori Morimoto return 0; 175d9288d0bSKuninori Morimoto } 176d9288d0bSKuninori Morimoto 177d9288d0bSKuninori Morimoto int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod, 178660cdce2SKuninori Morimoto struct rsnd_dai *rdai) 179d9288d0bSKuninori Morimoto { 180d9288d0bSKuninori Morimoto /* 181d9288d0bSKuninori Morimoto * DMA settings for SSIU 182d9288d0bSKuninori Morimoto */ 183d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_CTRL, 0); 184d9288d0bSKuninori Morimoto 185ba9c949fSKuninori Morimoto return 0; 186ba9c949fSKuninori Morimoto } 187ba9c949fSKuninori Morimoto 188*c17dba8bSKuninori Morimoto int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod, 189b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 190ba9c949fSKuninori Morimoto { 191ba9c949fSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); 192ba9c949fSKuninori Morimoto 193*c17dba8bSKuninori Morimoto if (rsnd_is_gen1(priv)) 194*c17dba8bSKuninori Morimoto return 0; 195*c17dba8bSKuninori Morimoto 196*c17dba8bSKuninori Morimoto /* enable SSI interrupt if Gen2 */ 197*c17dba8bSKuninori Morimoto if (rsnd_ssi_is_dma_mode(ssi_mod)) 198*c17dba8bSKuninori Morimoto rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0e000000); 199*c17dba8bSKuninori Morimoto else 200ba9c949fSKuninori Morimoto rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000); 201ba9c949fSKuninori Morimoto 202ba9c949fSKuninori Morimoto return 0; 203ba9c949fSKuninori Morimoto } 204ba9c949fSKuninori Morimoto 205*c17dba8bSKuninori Morimoto int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod, 206*c17dba8bSKuninori Morimoto struct rsnd_dai *rdai) 207*c17dba8bSKuninori Morimoto { 208*c17dba8bSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); 209*c17dba8bSKuninori Morimoto 210*c17dba8bSKuninori Morimoto if (rsnd_is_gen1(priv)) 211*c17dba8bSKuninori Morimoto return 0; 212*c17dba8bSKuninori Morimoto 213*c17dba8bSKuninori Morimoto /* disable SSI interrupt if Gen2 */ 214*c17dba8bSKuninori Morimoto rsnd_mod_write(ssi_mod, INT_ENABLE, 0x00000000); 215*c17dba8bSKuninori Morimoto 216*c17dba8bSKuninori Morimoto return 0; 217*c17dba8bSKuninori Morimoto } 218*c17dba8bSKuninori Morimoto 219ba9c949fSKuninori Morimoto unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 220ba9c949fSKuninori Morimoto struct rsnd_dai_stream *io, 221ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime) 222ba9c949fSKuninori Morimoto { 223b1eac430SKuninori Morimoto struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); 224ba9c949fSKuninori Morimoto struct rsnd_src *src; 225b1eac430SKuninori Morimoto unsigned int rate = 0; 226ba9c949fSKuninori Morimoto 227b1eac430SKuninori Morimoto if (src_mod) { 228b1eac430SKuninori Morimoto src = rsnd_mod_to_src(src_mod); 229ba9c949fSKuninori Morimoto 230ba9c949fSKuninori Morimoto /* 231ba9c949fSKuninori Morimoto * return convert rate if SRC is used, 232ba9c949fSKuninori Morimoto * otherwise, return runtime->rate as usual 233ba9c949fSKuninori Morimoto */ 234ba9c949fSKuninori Morimoto rate = rsnd_src_convert_rate(src); 235b1eac430SKuninori Morimoto } 236b1eac430SKuninori Morimoto 237ba9c949fSKuninori Morimoto if (!rate) 238ba9c949fSKuninori Morimoto rate = runtime->rate; 239ba9c949fSKuninori Morimoto 240ba9c949fSKuninori Morimoto return rate; 241ba9c949fSKuninori Morimoto } 242ba9c949fSKuninori Morimoto 243ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_rate(struct rsnd_mod *mod, 244b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 245ba9c949fSKuninori Morimoto { 246b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 247ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 248ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 249ba9c949fSKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 250ba9c949fSKuninori Morimoto u32 fsrate = 0; 251ba9c949fSKuninori Morimoto 252ba9c949fSKuninori Morimoto if (convert_rate) 253ba9c949fSKuninori Morimoto fsrate = 0x0400000 / convert_rate * runtime->rate; 254ba9c949fSKuninori Morimoto 255ba9c949fSKuninori Morimoto /* set/clear soft reset */ 256ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SWRSR, 0); 257ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SWRSR, 1); 258ba9c949fSKuninori Morimoto 259ba9c949fSKuninori Morimoto /* 260ba9c949fSKuninori Morimoto * Initialize the operation of the SRC internal circuits 261ba9c949fSKuninori Morimoto * see rsnd_src_start() 262ba9c949fSKuninori Morimoto */ 263ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCIR, 1); 264ba9c949fSKuninori Morimoto 265ba9c949fSKuninori Morimoto /* Set channel number and output bit length */ 266d7bdbc5dSKuninori Morimoto rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); 267ba9c949fSKuninori Morimoto 268ba9c949fSKuninori Morimoto /* Enable the initial value of IFS */ 269ba9c949fSKuninori Morimoto if (fsrate) { 270ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_IFSCR, 1); 271ba9c949fSKuninori Morimoto 272ba9c949fSKuninori Morimoto /* Set initial value of IFS */ 273ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_IFSVR, fsrate); 274ba9c949fSKuninori Morimoto } 275ba9c949fSKuninori Morimoto 276ba9c949fSKuninori Morimoto /* use DMA transfer */ 277ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); 278ba9c949fSKuninori Morimoto 279ba9c949fSKuninori Morimoto return 0; 280ba9c949fSKuninori Morimoto } 281ba9c949fSKuninori Morimoto 282ba9c949fSKuninori Morimoto static int rsnd_src_init(struct rsnd_mod *mod, 283b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 284ba9c949fSKuninori Morimoto { 285ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 286ba9c949fSKuninori Morimoto 28779861bbbSBen Dooks clk_prepare_enable(src->clk); 288ba9c949fSKuninori Morimoto 289ba9c949fSKuninori Morimoto return 0; 290ba9c949fSKuninori Morimoto } 291ba9c949fSKuninori Morimoto 292ba9c949fSKuninori Morimoto static int rsnd_src_quit(struct rsnd_mod *mod, 293b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 294ba9c949fSKuninori Morimoto { 295ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 296ba9c949fSKuninori Morimoto 29779861bbbSBen Dooks clk_disable_unprepare(src->clk); 298ba9c949fSKuninori Morimoto 299ba9c949fSKuninori Morimoto return 0; 300ba9c949fSKuninori Morimoto } 301ba9c949fSKuninori Morimoto 302ba9c949fSKuninori Morimoto static int rsnd_src_start(struct rsnd_mod *mod, 303b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 304ba9c949fSKuninori Morimoto { 305ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 306ba9c949fSKuninori Morimoto 307ba9c949fSKuninori Morimoto /* 308ba9c949fSKuninori Morimoto * Cancel the initialization and operate the SRC function 309ba9c949fSKuninori Morimoto * see rsnd_src_set_convert_rate() 310ba9c949fSKuninori Morimoto */ 311ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCIR, 0); 312ba9c949fSKuninori Morimoto 313ba9c949fSKuninori Morimoto if (rsnd_src_convert_rate(src)) 314ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 315ba9c949fSKuninori Morimoto 316ba9c949fSKuninori Morimoto return 0; 317ba9c949fSKuninori Morimoto } 318ba9c949fSKuninori Morimoto 319ba9c949fSKuninori Morimoto 320ba9c949fSKuninori Morimoto static int rsnd_src_stop(struct rsnd_mod *mod, 321b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 322ba9c949fSKuninori Morimoto { 323ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 324ba9c949fSKuninori Morimoto 325ba9c949fSKuninori Morimoto if (rsnd_src_convert_rate(src)) 326ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_ROUTE_MODE0, 0); 327ba9c949fSKuninori Morimoto 328ba9c949fSKuninori Morimoto return 0; 329ba9c949fSKuninori Morimoto } 330ba9c949fSKuninori Morimoto 331ba9c949fSKuninori Morimoto /* 332ba9c949fSKuninori Morimoto * Gen1 functions 333ba9c949fSKuninori Morimoto */ 334ba9c949fSKuninori Morimoto static int rsnd_src_set_route_gen1(struct rsnd_mod *mod, 335b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 336ba9c949fSKuninori Morimoto { 337b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 338ba9c949fSKuninori Morimoto struct src_route_config { 339ba9c949fSKuninori Morimoto u32 mask; 340ba9c949fSKuninori Morimoto int shift; 341ba9c949fSKuninori Morimoto } routes[] = { 342ba9c949fSKuninori Morimoto { 0xF, 0, }, /* 0 */ 343ba9c949fSKuninori Morimoto { 0xF, 4, }, /* 1 */ 344ba9c949fSKuninori Morimoto { 0xF, 8, }, /* 2 */ 345ba9c949fSKuninori Morimoto { 0x7, 12, }, /* 3 */ 346ba9c949fSKuninori Morimoto { 0x7, 16, }, /* 4 */ 347ba9c949fSKuninori Morimoto { 0x7, 20, }, /* 5 */ 348ba9c949fSKuninori Morimoto { 0x7, 24, }, /* 6 */ 349ba9c949fSKuninori Morimoto { 0x3, 28, }, /* 7 */ 350ba9c949fSKuninori Morimoto { 0x3, 30, }, /* 8 */ 351ba9c949fSKuninori Morimoto }; 352ba9c949fSKuninori Morimoto u32 mask; 353ba9c949fSKuninori Morimoto u32 val; 354ba9c949fSKuninori Morimoto int id; 355ba9c949fSKuninori Morimoto 356ba9c949fSKuninori Morimoto id = rsnd_mod_id(mod); 357ba9c949fSKuninori Morimoto if (id < 0 || id >= ARRAY_SIZE(routes)) 358ba9c949fSKuninori Morimoto return -EIO; 359ba9c949fSKuninori Morimoto 360ba9c949fSKuninori Morimoto /* 361ba9c949fSKuninori Morimoto * SRC_ROUTE_SELECT 362ba9c949fSKuninori Morimoto */ 363ba9c949fSKuninori Morimoto val = rsnd_dai_is_play(rdai, io) ? 0x1 : 0x2; 364ba9c949fSKuninori Morimoto val = val << routes[id].shift; 365ba9c949fSKuninori Morimoto mask = routes[id].mask << routes[id].shift; 366ba9c949fSKuninori Morimoto 367ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val); 368ba9c949fSKuninori Morimoto 369ba9c949fSKuninori Morimoto return 0; 370ba9c949fSKuninori Morimoto } 371ba9c949fSKuninori Morimoto 372ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod, 373b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 374ba9c949fSKuninori Morimoto { 375b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 376ba9c949fSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 377ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 378ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 379ba9c949fSKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 380ba9c949fSKuninori Morimoto u32 mask; 381ba9c949fSKuninori Morimoto u32 val; 382ba9c949fSKuninori Morimoto int shift; 383ba9c949fSKuninori Morimoto int id = rsnd_mod_id(mod); 384ba9c949fSKuninori Morimoto int ret; 385ba9c949fSKuninori Morimoto 386ba9c949fSKuninori Morimoto /* 387ba9c949fSKuninori Morimoto * SRC_TIMING_SELECT 388ba9c949fSKuninori Morimoto */ 389ba9c949fSKuninori Morimoto shift = (id % 4) * 8; 390ba9c949fSKuninori Morimoto mask = 0x1F << shift; 391ba9c949fSKuninori Morimoto 392ba9c949fSKuninori Morimoto /* 393ba9c949fSKuninori Morimoto * ADG is used as source clock if SRC was used, 394ba9c949fSKuninori Morimoto * then, SSI WS is used as destination clock. 395ba9c949fSKuninori Morimoto * SSI WS is used as source clock if SRC is not used 396ba9c949fSKuninori Morimoto * (when playback, source/destination become reverse when capture) 397ba9c949fSKuninori Morimoto */ 398ba9c949fSKuninori Morimoto ret = 0; 399ba9c949fSKuninori Morimoto if (convert_rate) { 400ba9c949fSKuninori Morimoto /* use ADG */ 401ba9c949fSKuninori Morimoto val = 0; 402ba9c949fSKuninori Morimoto ret = rsnd_adg_set_convert_clk_gen1(priv, mod, 403ba9c949fSKuninori Morimoto runtime->rate, 404ba9c949fSKuninori Morimoto convert_rate); 405ba9c949fSKuninori Morimoto } else if (8 == id) { 406ba9c949fSKuninori Morimoto /* use SSI WS, but SRU8 is special */ 407ba9c949fSKuninori Morimoto val = id << shift; 408ba9c949fSKuninori Morimoto } else { 409ba9c949fSKuninori Morimoto /* use SSI WS */ 410ba9c949fSKuninori Morimoto val = (id + 1) << shift; 411ba9c949fSKuninori Morimoto } 412ba9c949fSKuninori Morimoto 413ba9c949fSKuninori Morimoto if (ret < 0) 414ba9c949fSKuninori Morimoto return ret; 415ba9c949fSKuninori Morimoto 416ba9c949fSKuninori Morimoto switch (id / 4) { 417ba9c949fSKuninori Morimoto case 0: 418ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); 419ba9c949fSKuninori Morimoto break; 420ba9c949fSKuninori Morimoto case 1: 421ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); 422ba9c949fSKuninori Morimoto break; 423ba9c949fSKuninori Morimoto case 2: 424ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); 425ba9c949fSKuninori Morimoto break; 426ba9c949fSKuninori Morimoto } 427ba9c949fSKuninori Morimoto 428ba9c949fSKuninori Morimoto return 0; 429ba9c949fSKuninori Morimoto } 430ba9c949fSKuninori Morimoto 431ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod, 432b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 433ba9c949fSKuninori Morimoto { 434ba9c949fSKuninori Morimoto int ret; 435ba9c949fSKuninori Morimoto 436b42fccf6SKuninori Morimoto ret = rsnd_src_set_convert_rate(mod, rdai); 437ba9c949fSKuninori Morimoto if (ret < 0) 438ba9c949fSKuninori Morimoto return ret; 439ba9c949fSKuninori Morimoto 440ba9c949fSKuninori Morimoto /* Select SRC mode (fixed value) */ 441ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCCR, 0x00010110); 442ba9c949fSKuninori Morimoto 443ba9c949fSKuninori Morimoto /* Set the restriction value of the FS ratio (98%) */ 444ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_MNFSR, 445ba9c949fSKuninori Morimoto rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); 446ba9c949fSKuninori Morimoto 447ba9c949fSKuninori Morimoto /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ 448ba9c949fSKuninori Morimoto 449ba9c949fSKuninori Morimoto return 0; 450ba9c949fSKuninori Morimoto } 451ba9c949fSKuninori Morimoto 4528aefda50SKuninori Morimoto static int rsnd_src_probe_gen1(struct rsnd_mod *mod, 4538aefda50SKuninori Morimoto struct rsnd_dai *rdai) 4548aefda50SKuninori Morimoto { 4558aefda50SKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 4568aefda50SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 4578aefda50SKuninori Morimoto 45830cc4fafSKuninori Morimoto dev_dbg(dev, "%s[%d] (Gen1) is probed\n", 45930cc4fafSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 4608aefda50SKuninori Morimoto 4618aefda50SKuninori Morimoto return 0; 4628aefda50SKuninori Morimoto } 4638aefda50SKuninori Morimoto 464ba9c949fSKuninori Morimoto static int rsnd_src_init_gen1(struct rsnd_mod *mod, 465b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 466ba9c949fSKuninori Morimoto { 467ba9c949fSKuninori Morimoto int ret; 468ba9c949fSKuninori Morimoto 469b42fccf6SKuninori Morimoto ret = rsnd_src_init(mod, rdai); 470ba9c949fSKuninori Morimoto if (ret < 0) 471ba9c949fSKuninori Morimoto return ret; 472ba9c949fSKuninori Morimoto 473b42fccf6SKuninori Morimoto ret = rsnd_src_set_route_gen1(mod, rdai); 474ba9c949fSKuninori Morimoto if (ret < 0) 475ba9c949fSKuninori Morimoto return ret; 476ba9c949fSKuninori Morimoto 477b42fccf6SKuninori Morimoto ret = rsnd_src_set_convert_rate_gen1(mod, rdai); 478ba9c949fSKuninori Morimoto if (ret < 0) 479ba9c949fSKuninori Morimoto return ret; 480ba9c949fSKuninori Morimoto 481b42fccf6SKuninori Morimoto ret = rsnd_src_set_convert_timing_gen1(mod, rdai); 482ba9c949fSKuninori Morimoto if (ret < 0) 483ba9c949fSKuninori Morimoto return ret; 484ba9c949fSKuninori Morimoto 485ba9c949fSKuninori Morimoto return 0; 486ba9c949fSKuninori Morimoto } 487ba9c949fSKuninori Morimoto 488ba9c949fSKuninori Morimoto static int rsnd_src_start_gen1(struct rsnd_mod *mod, 489b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 490ba9c949fSKuninori Morimoto { 491ba9c949fSKuninori Morimoto int id = rsnd_mod_id(mod); 492ba9c949fSKuninori Morimoto 493ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); 494ba9c949fSKuninori Morimoto 495b42fccf6SKuninori Morimoto return rsnd_src_start(mod, rdai); 496ba9c949fSKuninori Morimoto } 497ba9c949fSKuninori Morimoto 498ba9c949fSKuninori Morimoto static int rsnd_src_stop_gen1(struct rsnd_mod *mod, 499b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 500ba9c949fSKuninori Morimoto { 501ba9c949fSKuninori Morimoto int id = rsnd_mod_id(mod); 502ba9c949fSKuninori Morimoto 503ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); 504ba9c949fSKuninori Morimoto 505b42fccf6SKuninori Morimoto return rsnd_src_stop(mod, rdai); 506ba9c949fSKuninori Morimoto } 507ba9c949fSKuninori Morimoto 508ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_gen1_ops = { 5098aefda50SKuninori Morimoto .name = SRC_NAME, 5108aefda50SKuninori Morimoto .probe = rsnd_src_probe_gen1, 511ba9c949fSKuninori Morimoto .init = rsnd_src_init_gen1, 512ba9c949fSKuninori Morimoto .quit = rsnd_src_quit, 513ba9c949fSKuninori Morimoto .start = rsnd_src_start_gen1, 514ba9c949fSKuninori Morimoto .stop = rsnd_src_stop_gen1, 515ba9c949fSKuninori Morimoto }; 516ba9c949fSKuninori Morimoto 517ba9c949fSKuninori Morimoto /* 518ba9c949fSKuninori Morimoto * Gen2 functions 519ba9c949fSKuninori Morimoto */ 520ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod, 521b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 522ba9c949fSKuninori Morimoto { 523054cd7f4SKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 524054cd7f4SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 525054cd7f4SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 526054cd7f4SKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 527054cd7f4SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 528054cd7f4SKuninori Morimoto uint ratio; 529ba9c949fSKuninori Morimoto int ret; 530ba9c949fSKuninori Morimoto 531054cd7f4SKuninori Morimoto /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ 532054cd7f4SKuninori Morimoto if (!rsnd_src_convert_rate(src)) 533054cd7f4SKuninori Morimoto ratio = 0; 534054cd7f4SKuninori Morimoto else if (rsnd_src_convert_rate(src) > runtime->rate) 535054cd7f4SKuninori Morimoto ratio = 100 * rsnd_src_convert_rate(src) / runtime->rate; 536054cd7f4SKuninori Morimoto else 537054cd7f4SKuninori Morimoto ratio = 100 * runtime->rate / rsnd_src_convert_rate(src); 538054cd7f4SKuninori Morimoto 539054cd7f4SKuninori Morimoto if (ratio > 600) { 540054cd7f4SKuninori Morimoto dev_err(dev, "FSO/FSI ratio error\n"); 541054cd7f4SKuninori Morimoto return -EINVAL; 542054cd7f4SKuninori Morimoto } 543054cd7f4SKuninori Morimoto 544b42fccf6SKuninori Morimoto ret = rsnd_src_set_convert_rate(mod, rdai); 545ba9c949fSKuninori Morimoto if (ret < 0) 546ba9c949fSKuninori Morimoto return ret; 547ba9c949fSKuninori Morimoto 548ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); 549ba9c949fSKuninori Morimoto 550054cd7f4SKuninori Morimoto switch (rsnd_mod_id(mod)) { 551054cd7f4SKuninori Morimoto case 5: 552054cd7f4SKuninori Morimoto case 6: 553054cd7f4SKuninori Morimoto case 7: 554054cd7f4SKuninori Morimoto case 8: 555054cd7f4SKuninori Morimoto rsnd_mod_write(mod, SRC_BSDSR, 0x02400000); 556054cd7f4SKuninori Morimoto break; 557054cd7f4SKuninori Morimoto default: 558ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_BSDSR, 0x01800000); 559054cd7f4SKuninori Morimoto break; 560054cd7f4SKuninori Morimoto } 561054cd7f4SKuninori Morimoto 562ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_BSISR, 0x00100060); 563ba9c949fSKuninori Morimoto 564ba9c949fSKuninori Morimoto return 0; 565ba9c949fSKuninori Morimoto } 566ba9c949fSKuninori Morimoto 567ba9c949fSKuninori Morimoto static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod, 568b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 569ba9c949fSKuninori Morimoto { 570b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 571ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 572ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 573ba9c949fSKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 574ba9c949fSKuninori Morimoto int ret; 575ba9c949fSKuninori Morimoto 576ba9c949fSKuninori Morimoto if (convert_rate) 577ba9c949fSKuninori Morimoto ret = rsnd_adg_set_convert_clk_gen2(mod, rdai, io, 578ba9c949fSKuninori Morimoto runtime->rate, 579ba9c949fSKuninori Morimoto convert_rate); 580ba9c949fSKuninori Morimoto else 581ba9c949fSKuninori Morimoto ret = rsnd_adg_set_convert_timing_gen2(mod, rdai, io); 582ba9c949fSKuninori Morimoto 583ba9c949fSKuninori Morimoto return ret; 584ba9c949fSKuninori Morimoto } 585ba9c949fSKuninori Morimoto 586ba9c949fSKuninori Morimoto static int rsnd_src_probe_gen2(struct rsnd_mod *mod, 587b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 588ba9c949fSKuninori Morimoto { 589ba9c949fSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 590ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 591ba9c949fSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 592ba9c949fSKuninori Morimoto int ret; 593ba9c949fSKuninori Morimoto 594ba9c949fSKuninori Morimoto ret = rsnd_dma_init(priv, 595ba9c949fSKuninori Morimoto rsnd_mod_to_dma(mod), 59629e69fd2SKuninori Morimoto rsnd_info_is_playback(priv, src), 597ba9c949fSKuninori Morimoto src->info->dma_id); 598ba9c949fSKuninori Morimoto if (ret < 0) 59930cc4fafSKuninori Morimoto dev_err(dev, "%s[%d] (Gen2) failed\n", 60030cc4fafSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 60130cc4fafSKuninori Morimoto else 60230cc4fafSKuninori Morimoto dev_dbg(dev, "%s[%d] (Gen2) is probed\n", 60330cc4fafSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 6048aefda50SKuninori Morimoto 605ba9c949fSKuninori Morimoto return ret; 606ba9c949fSKuninori Morimoto } 607ba9c949fSKuninori Morimoto 608ba9c949fSKuninori Morimoto static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 609b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 610ba9c949fSKuninori Morimoto { 611ba9c949fSKuninori Morimoto rsnd_dma_quit(rsnd_mod_to_priv(mod), rsnd_mod_to_dma(mod)); 612ba9c949fSKuninori Morimoto 613ba9c949fSKuninori Morimoto return 0; 614ba9c949fSKuninori Morimoto } 615ba9c949fSKuninori Morimoto 616ba9c949fSKuninori Morimoto static int rsnd_src_init_gen2(struct rsnd_mod *mod, 617b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 618ba9c949fSKuninori Morimoto { 619ba9c949fSKuninori Morimoto int ret; 620ba9c949fSKuninori Morimoto 621b42fccf6SKuninori Morimoto ret = rsnd_src_init(mod, rdai); 622ba9c949fSKuninori Morimoto if (ret < 0) 623ba9c949fSKuninori Morimoto return ret; 624ba9c949fSKuninori Morimoto 625b42fccf6SKuninori Morimoto ret = rsnd_src_set_convert_rate_gen2(mod, rdai); 626ba9c949fSKuninori Morimoto if (ret < 0) 627ba9c949fSKuninori Morimoto return ret; 628ba9c949fSKuninori Morimoto 629b42fccf6SKuninori Morimoto ret = rsnd_src_set_convert_timing_gen2(mod, rdai); 630ba9c949fSKuninori Morimoto if (ret < 0) 631ba9c949fSKuninori Morimoto return ret; 632ba9c949fSKuninori Morimoto 633ba9c949fSKuninori Morimoto return 0; 634ba9c949fSKuninori Morimoto } 635ba9c949fSKuninori Morimoto 636ba9c949fSKuninori Morimoto static int rsnd_src_start_gen2(struct rsnd_mod *mod, 637b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 638ba9c949fSKuninori Morimoto { 639bff58ea4SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 640ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 641bff58ea4SKuninori Morimoto u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; 642ba9c949fSKuninori Morimoto 643ba9c949fSKuninori Morimoto rsnd_dma_start(rsnd_mod_to_dma(&src->mod)); 644ba9c949fSKuninori Morimoto 645bff58ea4SKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, val); 646ba9c949fSKuninori Morimoto 647b42fccf6SKuninori Morimoto return rsnd_src_start(mod, rdai); 648ba9c949fSKuninori Morimoto } 649ba9c949fSKuninori Morimoto 650ba9c949fSKuninori Morimoto static int rsnd_src_stop_gen2(struct rsnd_mod *mod, 651b42fccf6SKuninori Morimoto struct rsnd_dai *rdai) 652ba9c949fSKuninori Morimoto { 653ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 654ba9c949fSKuninori Morimoto 655ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, 0); 656ba9c949fSKuninori Morimoto 657ba9c949fSKuninori Morimoto rsnd_dma_stop(rsnd_mod_to_dma(&src->mod)); 658ba9c949fSKuninori Morimoto 659b42fccf6SKuninori Morimoto return rsnd_src_stop(mod, rdai); 660ba9c949fSKuninori Morimoto } 661ba9c949fSKuninori Morimoto 662ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_gen2_ops = { 6638aefda50SKuninori Morimoto .name = SRC_NAME, 664ba9c949fSKuninori Morimoto .probe = rsnd_src_probe_gen2, 665ba9c949fSKuninori Morimoto .remove = rsnd_src_remove_gen2, 666ba9c949fSKuninori Morimoto .init = rsnd_src_init_gen2, 667ba9c949fSKuninori Morimoto .quit = rsnd_src_quit, 668ba9c949fSKuninori Morimoto .start = rsnd_src_start_gen2, 669ba9c949fSKuninori Morimoto .stop = rsnd_src_stop_gen2, 670ba9c949fSKuninori Morimoto }; 671ba9c949fSKuninori Morimoto 672ba9c949fSKuninori Morimoto struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 673ba9c949fSKuninori Morimoto { 674ba9c949fSKuninori Morimoto if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 675ba9c949fSKuninori Morimoto id = 0; 676ba9c949fSKuninori Morimoto 677ba9c949fSKuninori Morimoto return &((struct rsnd_src *)(priv->src) + id)->mod; 678ba9c949fSKuninori Morimoto } 679ba9c949fSKuninori Morimoto 68090e8e50fSKuninori Morimoto static void rsnd_of_parse_src(struct platform_device *pdev, 68190e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 68290e8e50fSKuninori Morimoto struct rsnd_priv *priv) 68390e8e50fSKuninori Morimoto { 68490e8e50fSKuninori Morimoto struct device_node *src_node; 68590e8e50fSKuninori Morimoto struct rcar_snd_info *info = rsnd_priv_to_info(priv); 68690e8e50fSKuninori Morimoto struct rsnd_src_platform_info *src_info; 68790e8e50fSKuninori Morimoto struct device *dev = &pdev->dev; 68890e8e50fSKuninori Morimoto int nr; 68990e8e50fSKuninori Morimoto 69090e8e50fSKuninori Morimoto if (!of_data) 69190e8e50fSKuninori Morimoto return; 69290e8e50fSKuninori Morimoto 69390e8e50fSKuninori Morimoto src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); 69490e8e50fSKuninori Morimoto if (!src_node) 69590e8e50fSKuninori Morimoto return; 69690e8e50fSKuninori Morimoto 69790e8e50fSKuninori Morimoto nr = of_get_child_count(src_node); 69890e8e50fSKuninori Morimoto if (!nr) 699f451e48dSKuninori Morimoto goto rsnd_of_parse_src_end; 70090e8e50fSKuninori Morimoto 70190e8e50fSKuninori Morimoto src_info = devm_kzalloc(dev, 70290e8e50fSKuninori Morimoto sizeof(struct rsnd_src_platform_info) * nr, 70390e8e50fSKuninori Morimoto GFP_KERNEL); 70490e8e50fSKuninori Morimoto if (!src_info) { 70590e8e50fSKuninori Morimoto dev_err(dev, "src info allocation error\n"); 706f451e48dSKuninori Morimoto goto rsnd_of_parse_src_end; 70790e8e50fSKuninori Morimoto } 70890e8e50fSKuninori Morimoto 70990e8e50fSKuninori Morimoto info->src_info = src_info; 71090e8e50fSKuninori Morimoto info->src_info_nr = nr; 711f451e48dSKuninori Morimoto 712f451e48dSKuninori Morimoto rsnd_of_parse_src_end: 713f451e48dSKuninori Morimoto of_node_put(src_node); 71490e8e50fSKuninori Morimoto } 71590e8e50fSKuninori Morimoto 716ba9c949fSKuninori Morimoto int rsnd_src_probe(struct platform_device *pdev, 71790e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 718ba9c949fSKuninori Morimoto struct rsnd_priv *priv) 719ba9c949fSKuninori Morimoto { 720ba9c949fSKuninori Morimoto struct rcar_snd_info *info = rsnd_priv_to_info(priv); 721ba9c949fSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 722ba9c949fSKuninori Morimoto struct rsnd_src *src; 723ba9c949fSKuninori Morimoto struct rsnd_mod_ops *ops; 724ba9c949fSKuninori Morimoto struct clk *clk; 725ba9c949fSKuninori Morimoto char name[RSND_SRC_NAME_SIZE]; 726ba9c949fSKuninori Morimoto int i, nr; 727ba9c949fSKuninori Morimoto 728033e7ed8SKuninori Morimoto ops = NULL; 729033e7ed8SKuninori Morimoto if (rsnd_is_gen1(priv)) 730033e7ed8SKuninori Morimoto ops = &rsnd_src_gen1_ops; 731033e7ed8SKuninori Morimoto if (rsnd_is_gen2(priv)) 732033e7ed8SKuninori Morimoto ops = &rsnd_src_gen2_ops; 733033e7ed8SKuninori Morimoto if (!ops) { 734033e7ed8SKuninori Morimoto dev_err(dev, "unknown Generation\n"); 735033e7ed8SKuninori Morimoto return -EIO; 736033e7ed8SKuninori Morimoto } 737033e7ed8SKuninori Morimoto 73890e8e50fSKuninori Morimoto rsnd_of_parse_src(pdev, of_data, priv); 73990e8e50fSKuninori Morimoto 740ba9c949fSKuninori Morimoto /* 741ba9c949fSKuninori Morimoto * init SRC 742ba9c949fSKuninori Morimoto */ 743ba9c949fSKuninori Morimoto nr = info->src_info_nr; 744ba9c949fSKuninori Morimoto if (!nr) 745ba9c949fSKuninori Morimoto return 0; 746ba9c949fSKuninori Morimoto 747ba9c949fSKuninori Morimoto src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); 748ba9c949fSKuninori Morimoto if (!src) { 749ba9c949fSKuninori Morimoto dev_err(dev, "SRC allocate failed\n"); 750ba9c949fSKuninori Morimoto return -ENOMEM; 751ba9c949fSKuninori Morimoto } 752ba9c949fSKuninori Morimoto 753ba9c949fSKuninori Morimoto priv->src_nr = nr; 754ba9c949fSKuninori Morimoto priv->src = src; 755ba9c949fSKuninori Morimoto 756ba9c949fSKuninori Morimoto for_each_rsnd_src(src, priv, i) { 7578aefda50SKuninori Morimoto snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", 7588aefda50SKuninori Morimoto SRC_NAME, i); 759ba9c949fSKuninori Morimoto 760ba9c949fSKuninori Morimoto clk = devm_clk_get(dev, name); 761ba9c949fSKuninori Morimoto if (IS_ERR(clk)) 762ba9c949fSKuninori Morimoto return PTR_ERR(clk); 763ba9c949fSKuninori Morimoto 764ba9c949fSKuninori Morimoto src->info = &info->src_info[i]; 765ba9c949fSKuninori Morimoto src->clk = clk; 766ba9c949fSKuninori Morimoto 767ba9c949fSKuninori Morimoto rsnd_mod_init(priv, &src->mod, ops, RSND_MOD_SRC, i); 768ba9c949fSKuninori Morimoto 769ba9c949fSKuninori Morimoto dev_dbg(dev, "SRC%d probed\n", i); 770ba9c949fSKuninori Morimoto } 771ba9c949fSKuninori Morimoto 772ba9c949fSKuninori Morimoto return 0; 773ba9c949fSKuninori Morimoto } 774