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; 25cfcefe01SKuninori Morimoto int err; 26ba9c949fSKuninori Morimoto }; 27ba9c949fSKuninori Morimoto 28ba9c949fSKuninori Morimoto #define RSND_SRC_NAME_SIZE 16 29ba9c949fSKuninori Morimoto 30ba9c949fSKuninori Morimoto #define rsnd_src_convert_rate(p) ((p)->info->convert_rate) 31ba9c949fSKuninori Morimoto #define rsnd_mod_to_src(_mod) \ 32ba9c949fSKuninori Morimoto container_of((_mod), struct rsnd_src, mod) 33ba9c949fSKuninori Morimoto #define rsnd_src_dma_available(src) \ 34ba9c949fSKuninori Morimoto rsnd_dma_available(rsnd_mod_to_dma(&(src)->mod)) 35ba9c949fSKuninori Morimoto 36ba9c949fSKuninori Morimoto #define for_each_rsnd_src(pos, priv, i) \ 37ba9c949fSKuninori Morimoto for ((i) = 0; \ 38ba9c949fSKuninori Morimoto ((i) < rsnd_src_nr(priv)) && \ 39ba9c949fSKuninori Morimoto ((pos) = (struct rsnd_src *)(priv)->src + i); \ 40ba9c949fSKuninori Morimoto i++) 41ba9c949fSKuninori Morimoto 42ba9c949fSKuninori Morimoto 43ba9c949fSKuninori Morimoto /* 44ba9c949fSKuninori Morimoto * image of SRC (Sampling Rate Converter) 45ba9c949fSKuninori Morimoto * 46ba9c949fSKuninori Morimoto * 96kHz <-> +-----+ 48kHz +-----+ 48kHz +-------+ 47ba9c949fSKuninori Morimoto * 48kHz <-> | SRC | <------> | SSI | <-----> | codec | 48ba9c949fSKuninori Morimoto * 44.1kHz <-> +-----+ +-----+ +-------+ 49ba9c949fSKuninori Morimoto * ... 50ba9c949fSKuninori Morimoto * 51ba9c949fSKuninori Morimoto */ 52ba9c949fSKuninori Morimoto 53ba9c949fSKuninori Morimoto /* 54ba9c949fSKuninori Morimoto * src.c is caring... 55ba9c949fSKuninori Morimoto * 56ba9c949fSKuninori Morimoto * Gen1 57ba9c949fSKuninori Morimoto * 58ba9c949fSKuninori Morimoto * [mem] -> [SRU] -> [SSI] 59ba9c949fSKuninori Morimoto * |--------| 60ba9c949fSKuninori Morimoto * 61ba9c949fSKuninori Morimoto * Gen2 62ba9c949fSKuninori Morimoto * 63ba9c949fSKuninori Morimoto * [mem] -> [SRC] -> [SSIU] -> [SSI] 64ba9c949fSKuninori Morimoto * |-----------------| 65ba9c949fSKuninori Morimoto */ 66ba9c949fSKuninori Morimoto 67ba9c949fSKuninori Morimoto /* 68ba9c949fSKuninori Morimoto * How to use SRC bypass mode for debugging 69ba9c949fSKuninori Morimoto * 70ba9c949fSKuninori Morimoto * SRC has bypass mode, and it is useful for debugging. 71ba9c949fSKuninori Morimoto * In Gen2 case, 72ba9c949fSKuninori Morimoto * SRCm_MODE controls whether SRC is used or not 73ba9c949fSKuninori Morimoto * SSI_MODE0 controls whether SSIU which receives SRC data 74ba9c949fSKuninori Morimoto * is used or not. 75ba9c949fSKuninori Morimoto * Both SRCm_MODE/SSI_MODE0 settings are needed if you use SRC, 76ba9c949fSKuninori Morimoto * but SRC bypass mode needs SSI_MODE0 only. 77ba9c949fSKuninori Morimoto * 78ba9c949fSKuninori Morimoto * This driver request 79ba9c949fSKuninori Morimoto * struct rsnd_src_platform_info { 80ba9c949fSKuninori Morimoto * u32 convert_rate; 8129e69fd2SKuninori Morimoto * int dma_id; 82ba9c949fSKuninori Morimoto * } 83ba9c949fSKuninori Morimoto * 84ba9c949fSKuninori Morimoto * rsnd_src_convert_rate() indicates 85ba9c949fSKuninori Morimoto * above convert_rate, and it controls 86ba9c949fSKuninori Morimoto * whether SRC is used or not. 87ba9c949fSKuninori Morimoto * 88ba9c949fSKuninori Morimoto * ex) doesn't use SRC 8929e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 9029e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], }, 91ba9c949fSKuninori Morimoto * }; 92ba9c949fSKuninori Morimoto * 93ba9c949fSKuninori Morimoto * ex) uses SRC 9429e69fd2SKuninori Morimoto * static struct rsnd_src_platform_info rsnd_src[] = { 9529e69fd2SKuninori Morimoto * RSND_SCU(48000, 0), 9629e69fd2SKuninori Morimoto * ... 9729e69fd2SKuninori Morimoto * }; 9829e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 9929e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, 100ba9c949fSKuninori Morimoto * }; 101ba9c949fSKuninori Morimoto * 102ba9c949fSKuninori Morimoto * ex) uses SRC bypass mode 10329e69fd2SKuninori Morimoto * static struct rsnd_src_platform_info rsnd_src[] = { 10429e69fd2SKuninori Morimoto * RSND_SCU(0, 0), 10529e69fd2SKuninori Morimoto * ... 10629e69fd2SKuninori Morimoto * }; 10729e69fd2SKuninori Morimoto * static struct rsnd_dai_platform_info rsnd_dai = { 10829e69fd2SKuninori Morimoto * .playback = { .ssi = &rsnd_ssi[0], .src = &rsnd_src[0] }, 109ba9c949fSKuninori Morimoto * }; 110ba9c949fSKuninori Morimoto * 111ba9c949fSKuninori Morimoto */ 112ba9c949fSKuninori Morimoto 113ba9c949fSKuninori Morimoto /* 114ba9c949fSKuninori Morimoto * Gen1/Gen2 common functions 115ba9c949fSKuninori Morimoto */ 116d9288d0bSKuninori Morimoto int rsnd_src_ssiu_start(struct rsnd_mod *ssi_mod, 117d9288d0bSKuninori Morimoto int use_busif) 118ba9c949fSKuninori Morimoto { 1191cc71959SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(ssi_mod); 120f708d944SKuninori Morimoto struct rsnd_dai *rdai = rsnd_io_to_rdai(io); 1211cc71959SKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 122ba9c949fSKuninori Morimoto int ssi_id = rsnd_mod_id(ssi_mod); 123ba9c949fSKuninori Morimoto 124ba9c949fSKuninori Morimoto /* 125ba9c949fSKuninori Morimoto * SSI_MODE0 126ba9c949fSKuninori Morimoto */ 127ba9c949fSKuninori Morimoto rsnd_mod_bset(ssi_mod, SSI_MODE0, (1 << ssi_id), 128d9288d0bSKuninori Morimoto !use_busif << ssi_id); 129ba9c949fSKuninori Morimoto 130ba9c949fSKuninori Morimoto /* 131ba9c949fSKuninori Morimoto * SSI_MODE1 132ba9c949fSKuninori Morimoto */ 133ba9c949fSKuninori Morimoto if (rsnd_ssi_is_pin_sharing(ssi_mod)) { 134ba9c949fSKuninori Morimoto int shift = -1; 135ba9c949fSKuninori Morimoto switch (ssi_id) { 136ba9c949fSKuninori Morimoto case 1: 137ba9c949fSKuninori Morimoto shift = 0; 138ba9c949fSKuninori Morimoto break; 139ba9c949fSKuninori Morimoto case 2: 140ba9c949fSKuninori Morimoto shift = 2; 141ba9c949fSKuninori Morimoto break; 142ba9c949fSKuninori Morimoto case 4: 143ba9c949fSKuninori Morimoto shift = 16; 144ba9c949fSKuninori Morimoto break; 145ba9c949fSKuninori Morimoto } 146ba9c949fSKuninori Morimoto 147ba9c949fSKuninori Morimoto if (shift >= 0) 148ba9c949fSKuninori Morimoto rsnd_mod_bset(ssi_mod, SSI_MODE1, 149ba9c949fSKuninori Morimoto 0x3 << shift, 1503ed6448cSKuninori Morimoto rsnd_rdai_is_clk_master(rdai) ? 151ba9c949fSKuninori Morimoto 0x2 << shift : 0x1 << shift); 152ba9c949fSKuninori Morimoto } 153ba9c949fSKuninori Morimoto 154d9288d0bSKuninori Morimoto /* 155d9288d0bSKuninori Morimoto * DMA settings for SSIU 156d9288d0bSKuninori Morimoto */ 157d9288d0bSKuninori Morimoto if (use_busif) { 1581cc71959SKuninori Morimoto u32 val = 0x76543210; 1591cc71959SKuninori Morimoto u32 mask = ~0; 1601cc71959SKuninori Morimoto 161d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_BUSIF_ADINR, 162d9288d0bSKuninori Morimoto rsnd_get_adinr(ssi_mod)); 163d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_BUSIF_MODE, 1); 164d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_CTRL, 0x1); 1651cc71959SKuninori Morimoto 1661cc71959SKuninori Morimoto mask <<= runtime->channels * 4; 1671cc71959SKuninori Morimoto val = val & mask; 1681cc71959SKuninori Morimoto 1691cc71959SKuninori Morimoto switch (runtime->sample_bits) { 1701cc71959SKuninori Morimoto case 16: 1711cc71959SKuninori Morimoto val |= 0x67452301 & ~mask; 1721cc71959SKuninori Morimoto break; 1731cc71959SKuninori Morimoto case 32: 1741cc71959SKuninori Morimoto val |= 0x76543210 & ~mask; 1751cc71959SKuninori Morimoto break; 1761cc71959SKuninori Morimoto } 1771cc71959SKuninori Morimoto rsnd_mod_write(ssi_mod, BUSIF_DALIGN, val); 1781cc71959SKuninori Morimoto 179d9288d0bSKuninori Morimoto } 180d9288d0bSKuninori Morimoto 181d9288d0bSKuninori Morimoto return 0; 182d9288d0bSKuninori Morimoto } 183d9288d0bSKuninori Morimoto 184f708d944SKuninori Morimoto int rsnd_src_ssiu_stop(struct rsnd_mod *ssi_mod) 185d9288d0bSKuninori Morimoto { 186d9288d0bSKuninori Morimoto /* 187d9288d0bSKuninori Morimoto * DMA settings for SSIU 188d9288d0bSKuninori Morimoto */ 189d9288d0bSKuninori Morimoto rsnd_mod_write(ssi_mod, SSI_CTRL, 0); 190d9288d0bSKuninori Morimoto 191ba9c949fSKuninori Morimoto return 0; 192ba9c949fSKuninori Morimoto } 193ba9c949fSKuninori Morimoto 194f708d944SKuninori Morimoto int rsnd_src_ssi_irq_enable(struct rsnd_mod *ssi_mod) 195ba9c949fSKuninori Morimoto { 196ba9c949fSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); 197ba9c949fSKuninori Morimoto 198c17dba8bSKuninori Morimoto if (rsnd_is_gen1(priv)) 199c17dba8bSKuninori Morimoto return 0; 200c17dba8bSKuninori Morimoto 201c17dba8bSKuninori Morimoto /* enable SSI interrupt if Gen2 */ 202c17dba8bSKuninori Morimoto if (rsnd_ssi_is_dma_mode(ssi_mod)) 203c17dba8bSKuninori Morimoto rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0e000000); 204c17dba8bSKuninori Morimoto else 205ba9c949fSKuninori Morimoto rsnd_mod_write(ssi_mod, INT_ENABLE, 0x0f000000); 206ba9c949fSKuninori Morimoto 207ba9c949fSKuninori Morimoto return 0; 208ba9c949fSKuninori Morimoto } 209ba9c949fSKuninori Morimoto 210f708d944SKuninori Morimoto int rsnd_src_ssi_irq_disable(struct rsnd_mod *ssi_mod) 211c17dba8bSKuninori Morimoto { 212c17dba8bSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(ssi_mod); 213c17dba8bSKuninori Morimoto 214c17dba8bSKuninori Morimoto if (rsnd_is_gen1(priv)) 215c17dba8bSKuninori Morimoto return 0; 216c17dba8bSKuninori Morimoto 217c17dba8bSKuninori Morimoto /* disable SSI interrupt if Gen2 */ 218c17dba8bSKuninori Morimoto rsnd_mod_write(ssi_mod, INT_ENABLE, 0x00000000); 219c17dba8bSKuninori Morimoto 220c17dba8bSKuninori Morimoto return 0; 221c17dba8bSKuninori Morimoto } 222c17dba8bSKuninori Morimoto 223ba9c949fSKuninori Morimoto unsigned int rsnd_src_get_ssi_rate(struct rsnd_priv *priv, 224ba9c949fSKuninori Morimoto struct rsnd_dai_stream *io, 225ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime) 226ba9c949fSKuninori Morimoto { 227b1eac430SKuninori Morimoto struct rsnd_mod *src_mod = rsnd_io_to_mod_src(io); 228ba9c949fSKuninori Morimoto struct rsnd_src *src; 229b1eac430SKuninori Morimoto unsigned int rate = 0; 230ba9c949fSKuninori Morimoto 231b1eac430SKuninori Morimoto if (src_mod) { 232b1eac430SKuninori Morimoto src = rsnd_mod_to_src(src_mod); 233ba9c949fSKuninori Morimoto 234ba9c949fSKuninori Morimoto /* 235ba9c949fSKuninori Morimoto * return convert rate if SRC is used, 236ba9c949fSKuninori Morimoto * otherwise, return runtime->rate as usual 237ba9c949fSKuninori Morimoto */ 238ba9c949fSKuninori Morimoto rate = rsnd_src_convert_rate(src); 239b1eac430SKuninori Morimoto } 240b1eac430SKuninori Morimoto 241ba9c949fSKuninori Morimoto if (!rate) 242ba9c949fSKuninori Morimoto rate = runtime->rate; 243ba9c949fSKuninori Morimoto 244ba9c949fSKuninori Morimoto return rate; 245ba9c949fSKuninori Morimoto } 246ba9c949fSKuninori Morimoto 247f708d944SKuninori Morimoto static int rsnd_src_set_convert_rate(struct rsnd_mod *mod) 248ba9c949fSKuninori Morimoto { 249b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 250ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 251ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 252ba9c949fSKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 253ba9c949fSKuninori Morimoto u32 fsrate = 0; 254ba9c949fSKuninori Morimoto 255ba9c949fSKuninori Morimoto if (convert_rate) 256ba9c949fSKuninori Morimoto fsrate = 0x0400000 / convert_rate * runtime->rate; 257ba9c949fSKuninori Morimoto 258ba9c949fSKuninori Morimoto /* set/clear soft reset */ 259ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SWRSR, 0); 260ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SWRSR, 1); 261ba9c949fSKuninori Morimoto 262ba9c949fSKuninori Morimoto /* Set channel number and output bit length */ 263d7bdbc5dSKuninori Morimoto rsnd_mod_write(mod, SRC_ADINR, rsnd_get_adinr(mod)); 264ba9c949fSKuninori Morimoto 265ba9c949fSKuninori Morimoto /* Enable the initial value of IFS */ 266ba9c949fSKuninori Morimoto if (fsrate) { 267ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_IFSCR, 1); 268ba9c949fSKuninori Morimoto 269ba9c949fSKuninori Morimoto /* Set initial value of IFS */ 270ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_IFSVR, fsrate); 271ba9c949fSKuninori Morimoto } 272ba9c949fSKuninori Morimoto 273ba9c949fSKuninori Morimoto /* use DMA transfer */ 274ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_BUSIF_MODE, 1); 275ba9c949fSKuninori Morimoto 276ba9c949fSKuninori Morimoto return 0; 277ba9c949fSKuninori Morimoto } 278ba9c949fSKuninori Morimoto 279f708d944SKuninori Morimoto static int rsnd_src_init(struct rsnd_mod *mod) 280ba9c949fSKuninori Morimoto { 281ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 282ba9c949fSKuninori Morimoto 28385642952SKuninori Morimoto rsnd_mod_hw_start(mod); 284ba9c949fSKuninori Morimoto 285cfcefe01SKuninori Morimoto src->err = 0; 286cfcefe01SKuninori Morimoto 287603cefa5SKuninori Morimoto /* 288603cefa5SKuninori Morimoto * Initialize the operation of the SRC internal circuits 289603cefa5SKuninori Morimoto * see rsnd_src_start() 290603cefa5SKuninori Morimoto */ 291603cefa5SKuninori Morimoto rsnd_mod_write(mod, SRC_SRCIR, 1); 292603cefa5SKuninori Morimoto 293ba9c949fSKuninori Morimoto return 0; 294ba9c949fSKuninori Morimoto } 295ba9c949fSKuninori Morimoto 296ba9c949fSKuninori Morimoto static int rsnd_src_quit(struct rsnd_mod *mod, 297690602fcSKuninori Morimoto struct rsnd_priv *priv) 298ba9c949fSKuninori Morimoto { 299ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 300cfcefe01SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 301ba9c949fSKuninori Morimoto 30285642952SKuninori Morimoto rsnd_mod_hw_stop(mod); 303ba9c949fSKuninori Morimoto 304cfcefe01SKuninori Morimoto if (src->err) 305337b0b4cSKuninori Morimoto dev_warn(dev, "%s[%d] under/over flow err = %d\n", 306337b0b4cSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), src->err); 307cfcefe01SKuninori Morimoto 308ba9c949fSKuninori Morimoto return 0; 309ba9c949fSKuninori Morimoto } 310ba9c949fSKuninori Morimoto 311f0ef0cb8SKuninori Morimoto static int rsnd_src_start(struct rsnd_mod *mod) 312ba9c949fSKuninori Morimoto { 313ba9c949fSKuninori Morimoto /* 314ba9c949fSKuninori Morimoto * Cancel the initialization and operate the SRC function 315603cefa5SKuninori Morimoto * see rsnd_src_init() 316ba9c949fSKuninori Morimoto */ 317ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCIR, 0); 318ba9c949fSKuninori Morimoto 319ba9c949fSKuninori Morimoto return 0; 320ba9c949fSKuninori Morimoto } 321ba9c949fSKuninori Morimoto 322f0ef0cb8SKuninori Morimoto static int rsnd_src_stop(struct rsnd_mod *mod) 323ba9c949fSKuninori Morimoto { 324933cc8cbSKuninori Morimoto /* nothing to do */ 325ba9c949fSKuninori Morimoto return 0; 326ba9c949fSKuninori Morimoto } 327ba9c949fSKuninori Morimoto 328ba9c949fSKuninori Morimoto /* 329ba9c949fSKuninori Morimoto * Gen1 functions 330ba9c949fSKuninori Morimoto */ 331f708d944SKuninori Morimoto static int rsnd_src_set_route_gen1(struct rsnd_mod *mod) 332ba9c949fSKuninori Morimoto { 333b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 334ba9c949fSKuninori Morimoto struct src_route_config { 335ba9c949fSKuninori Morimoto u32 mask; 336ba9c949fSKuninori Morimoto int shift; 337ba9c949fSKuninori Morimoto } routes[] = { 338ba9c949fSKuninori Morimoto { 0xF, 0, }, /* 0 */ 339ba9c949fSKuninori Morimoto { 0xF, 4, }, /* 1 */ 340ba9c949fSKuninori Morimoto { 0xF, 8, }, /* 2 */ 341ba9c949fSKuninori Morimoto { 0x7, 12, }, /* 3 */ 342ba9c949fSKuninori Morimoto { 0x7, 16, }, /* 4 */ 343ba9c949fSKuninori Morimoto { 0x7, 20, }, /* 5 */ 344ba9c949fSKuninori Morimoto { 0x7, 24, }, /* 6 */ 345ba9c949fSKuninori Morimoto { 0x3, 28, }, /* 7 */ 346ba9c949fSKuninori Morimoto { 0x3, 30, }, /* 8 */ 347ba9c949fSKuninori Morimoto }; 348ba9c949fSKuninori Morimoto u32 mask; 349ba9c949fSKuninori Morimoto u32 val; 350ba9c949fSKuninori Morimoto int id; 351ba9c949fSKuninori Morimoto 352ba9c949fSKuninori Morimoto id = rsnd_mod_id(mod); 353ba9c949fSKuninori Morimoto if (id < 0 || id >= ARRAY_SIZE(routes)) 354ba9c949fSKuninori Morimoto return -EIO; 355ba9c949fSKuninori Morimoto 356ba9c949fSKuninori Morimoto /* 357ba9c949fSKuninori Morimoto * SRC_ROUTE_SELECT 358ba9c949fSKuninori Morimoto */ 359985a4f6eSKuninori Morimoto val = rsnd_io_is_play(io) ? 0x1 : 0x2; 360ba9c949fSKuninori Morimoto val = val << routes[id].shift; 361ba9c949fSKuninori Morimoto mask = routes[id].mask << routes[id].shift; 362ba9c949fSKuninori Morimoto 363ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_ROUTE_SEL, mask, val); 364ba9c949fSKuninori Morimoto 365ba9c949fSKuninori Morimoto return 0; 366ba9c949fSKuninori Morimoto } 367ba9c949fSKuninori Morimoto 368f708d944SKuninori Morimoto static int rsnd_src_set_convert_timing_gen1(struct rsnd_mod *mod) 369ba9c949fSKuninori Morimoto { 370b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 371ba9c949fSKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 372ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 373ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 374ba9c949fSKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 375ba9c949fSKuninori Morimoto u32 mask; 376ba9c949fSKuninori Morimoto u32 val; 377ba9c949fSKuninori Morimoto int shift; 378ba9c949fSKuninori Morimoto int id = rsnd_mod_id(mod); 379ba9c949fSKuninori Morimoto int ret; 380ba9c949fSKuninori Morimoto 381ba9c949fSKuninori Morimoto /* 382ba9c949fSKuninori Morimoto * SRC_TIMING_SELECT 383ba9c949fSKuninori Morimoto */ 384ba9c949fSKuninori Morimoto shift = (id % 4) * 8; 385ba9c949fSKuninori Morimoto mask = 0x1F << shift; 386ba9c949fSKuninori Morimoto 387ba9c949fSKuninori Morimoto /* 388ba9c949fSKuninori Morimoto * ADG is used as source clock if SRC was used, 389ba9c949fSKuninori Morimoto * then, SSI WS is used as destination clock. 390ba9c949fSKuninori Morimoto * SSI WS is used as source clock if SRC is not used 391ba9c949fSKuninori Morimoto * (when playback, source/destination become reverse when capture) 392ba9c949fSKuninori Morimoto */ 393ba9c949fSKuninori Morimoto ret = 0; 394ba9c949fSKuninori Morimoto if (convert_rate) { 395ba9c949fSKuninori Morimoto /* use ADG */ 396ba9c949fSKuninori Morimoto val = 0; 397ba9c949fSKuninori Morimoto ret = rsnd_adg_set_convert_clk_gen1(priv, mod, 398ba9c949fSKuninori Morimoto runtime->rate, 399ba9c949fSKuninori Morimoto convert_rate); 400ba9c949fSKuninori Morimoto } else if (8 == id) { 401ba9c949fSKuninori Morimoto /* use SSI WS, but SRU8 is special */ 402ba9c949fSKuninori Morimoto val = id << shift; 403ba9c949fSKuninori Morimoto } else { 404ba9c949fSKuninori Morimoto /* use SSI WS */ 405ba9c949fSKuninori Morimoto val = (id + 1) << shift; 406ba9c949fSKuninori Morimoto } 407ba9c949fSKuninori Morimoto 408ba9c949fSKuninori Morimoto if (ret < 0) 409ba9c949fSKuninori Morimoto return ret; 410ba9c949fSKuninori Morimoto 411ba9c949fSKuninori Morimoto switch (id / 4) { 412ba9c949fSKuninori Morimoto case 0: 413ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_TMG_SEL0, mask, val); 414ba9c949fSKuninori Morimoto break; 415ba9c949fSKuninori Morimoto case 1: 416ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_TMG_SEL1, mask, val); 417ba9c949fSKuninori Morimoto break; 418ba9c949fSKuninori Morimoto case 2: 419ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_TMG_SEL2, mask, val); 420ba9c949fSKuninori Morimoto break; 421ba9c949fSKuninori Morimoto } 422ba9c949fSKuninori Morimoto 423ba9c949fSKuninori Morimoto return 0; 424ba9c949fSKuninori Morimoto } 425ba9c949fSKuninori Morimoto 426f708d944SKuninori Morimoto static int rsnd_src_set_convert_rate_gen1(struct rsnd_mod *mod) 427ba9c949fSKuninori Morimoto { 428933cc8cbSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 429ba9c949fSKuninori Morimoto int ret; 430ba9c949fSKuninori Morimoto 431f708d944SKuninori Morimoto ret = rsnd_src_set_convert_rate(mod); 432ba9c949fSKuninori Morimoto if (ret < 0) 433ba9c949fSKuninori Morimoto return ret; 434ba9c949fSKuninori Morimoto 435ba9c949fSKuninori Morimoto /* Select SRC mode (fixed value) */ 436ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCCR, 0x00010110); 437ba9c949fSKuninori Morimoto 438ba9c949fSKuninori Morimoto /* Set the restriction value of the FS ratio (98%) */ 439ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_MNFSR, 440ba9c949fSKuninori Morimoto rsnd_mod_read(mod, SRC_IFSVR) / 100 * 98); 441ba9c949fSKuninori Morimoto 442933cc8cbSKuninori Morimoto /* Gen1/Gen2 are not compatible */ 443933cc8cbSKuninori Morimoto if (rsnd_src_convert_rate(src)) 444933cc8cbSKuninori Morimoto rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 445933cc8cbSKuninori Morimoto 446ba9c949fSKuninori Morimoto /* no SRC_BFSSR settings, since SRC_SRCCR::BUFMD is 0 */ 447ba9c949fSKuninori Morimoto 448ba9c949fSKuninori Morimoto return 0; 449ba9c949fSKuninori Morimoto } 450ba9c949fSKuninori Morimoto 4518aefda50SKuninori Morimoto static int rsnd_src_probe_gen1(struct rsnd_mod *mod, 452690602fcSKuninori Morimoto struct rsnd_priv *priv) 4538aefda50SKuninori Morimoto { 4548aefda50SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 4558aefda50SKuninori Morimoto 45630cc4fafSKuninori Morimoto dev_dbg(dev, "%s[%d] (Gen1) is probed\n", 45730cc4fafSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 4588aefda50SKuninori Morimoto 4598aefda50SKuninori Morimoto return 0; 4608aefda50SKuninori Morimoto } 4618aefda50SKuninori Morimoto 462ba9c949fSKuninori Morimoto static int rsnd_src_init_gen1(struct rsnd_mod *mod, 463690602fcSKuninori Morimoto struct rsnd_priv *priv) 464ba9c949fSKuninori Morimoto { 465ba9c949fSKuninori Morimoto int ret; 466ba9c949fSKuninori Morimoto 467f708d944SKuninori Morimoto ret = rsnd_src_init(mod); 468ba9c949fSKuninori Morimoto if (ret < 0) 469ba9c949fSKuninori Morimoto return ret; 470ba9c949fSKuninori Morimoto 471f708d944SKuninori Morimoto ret = rsnd_src_set_route_gen1(mod); 472ba9c949fSKuninori Morimoto if (ret < 0) 473ba9c949fSKuninori Morimoto return ret; 474ba9c949fSKuninori Morimoto 475f708d944SKuninori Morimoto ret = rsnd_src_set_convert_rate_gen1(mod); 476ba9c949fSKuninori Morimoto if (ret < 0) 477ba9c949fSKuninori Morimoto return ret; 478ba9c949fSKuninori Morimoto 479f708d944SKuninori Morimoto ret = rsnd_src_set_convert_timing_gen1(mod); 480ba9c949fSKuninori Morimoto if (ret < 0) 481ba9c949fSKuninori Morimoto return ret; 482ba9c949fSKuninori Morimoto 483ba9c949fSKuninori Morimoto return 0; 484ba9c949fSKuninori Morimoto } 485ba9c949fSKuninori Morimoto 486ba9c949fSKuninori Morimoto static int rsnd_src_start_gen1(struct rsnd_mod *mod, 487690602fcSKuninori Morimoto struct rsnd_priv *priv) 488ba9c949fSKuninori Morimoto { 489ba9c949fSKuninori Morimoto int id = rsnd_mod_id(mod); 490ba9c949fSKuninori Morimoto 491ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), (1 << id)); 492ba9c949fSKuninori Morimoto 493f0ef0cb8SKuninori Morimoto return rsnd_src_start(mod); 494ba9c949fSKuninori Morimoto } 495ba9c949fSKuninori Morimoto 496ba9c949fSKuninori Morimoto static int rsnd_src_stop_gen1(struct rsnd_mod *mod, 497690602fcSKuninori Morimoto struct rsnd_priv *priv) 498ba9c949fSKuninori Morimoto { 499ba9c949fSKuninori Morimoto int id = rsnd_mod_id(mod); 500ba9c949fSKuninori Morimoto 501ba9c949fSKuninori Morimoto rsnd_mod_bset(mod, SRC_ROUTE_CTRL, (1 << id), 0); 502ba9c949fSKuninori Morimoto 503f0ef0cb8SKuninori Morimoto return rsnd_src_stop(mod); 504ba9c949fSKuninori Morimoto } 505ba9c949fSKuninori Morimoto 506ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_gen1_ops = { 5078aefda50SKuninori Morimoto .name = SRC_NAME, 5088aefda50SKuninori Morimoto .probe = rsnd_src_probe_gen1, 509ba9c949fSKuninori Morimoto .init = rsnd_src_init_gen1, 510ba9c949fSKuninori Morimoto .quit = rsnd_src_quit, 511ba9c949fSKuninori Morimoto .start = rsnd_src_start_gen1, 512ba9c949fSKuninori Morimoto .stop = rsnd_src_stop_gen1, 513ba9c949fSKuninori Morimoto }; 514ba9c949fSKuninori Morimoto 515ba9c949fSKuninori Morimoto /* 516ba9c949fSKuninori Morimoto * Gen2 functions 517ba9c949fSKuninori Morimoto */ 518cfcefe01SKuninori Morimoto #define rsnd_src_irq_enable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 1) 519cfcefe01SKuninori Morimoto #define rsnd_src_irq_disable_gen2(mod) rsnd_src_irq_ctrol_gen2(mod, 0) 520cfcefe01SKuninori Morimoto static void rsnd_src_irq_ctrol_gen2(struct rsnd_mod *mod, int enable) 521cfcefe01SKuninori Morimoto { 522cfcefe01SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 523cfcefe01SKuninori Morimoto u32 sys_int_val, int_val, sys_int_mask; 524cfcefe01SKuninori Morimoto int irq = src->info->irq; 525cfcefe01SKuninori Morimoto int id = rsnd_mod_id(mod); 526cfcefe01SKuninori Morimoto 527cfcefe01SKuninori Morimoto sys_int_val = 528cfcefe01SKuninori Morimoto sys_int_mask = OUF_SRC(id); 529cfcefe01SKuninori Morimoto int_val = 0x3300; 530cfcefe01SKuninori Morimoto 531cfcefe01SKuninori Morimoto /* 532cfcefe01SKuninori Morimoto * IRQ is not supported on non-DT 533cfcefe01SKuninori Morimoto * see 534cfcefe01SKuninori Morimoto * rsnd_src_probe_gen2() 535cfcefe01SKuninori Morimoto */ 536cfcefe01SKuninori Morimoto if ((irq <= 0) || !enable) { 537cfcefe01SKuninori Morimoto sys_int_val = 0; 538cfcefe01SKuninori Morimoto int_val = 0; 539cfcefe01SKuninori Morimoto } 540cfcefe01SKuninori Morimoto 541cfcefe01SKuninori Morimoto rsnd_mod_write(mod, SRC_INT_ENABLE0, int_val); 542cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_INT_EN0, sys_int_mask, sys_int_val); 543cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_INT_EN1, sys_int_mask, sys_int_val); 544cfcefe01SKuninori Morimoto } 545cfcefe01SKuninori Morimoto 546cfcefe01SKuninori Morimoto static void rsnd_src_error_clear_gen2(struct rsnd_mod *mod) 547cfcefe01SKuninori Morimoto { 548cfcefe01SKuninori Morimoto u32 val = OUF_SRC(rsnd_mod_id(mod)); 549cfcefe01SKuninori Morimoto 550cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_STATUS0, val, val); 551cfcefe01SKuninori Morimoto rsnd_mod_bset(mod, SCU_SYS_STATUS1, val, val); 552cfcefe01SKuninori Morimoto } 553cfcefe01SKuninori Morimoto 554cfcefe01SKuninori Morimoto static bool rsnd_src_error_record_gen2(struct rsnd_mod *mod) 555cfcefe01SKuninori Morimoto { 556cfcefe01SKuninori Morimoto u32 val = OUF_SRC(rsnd_mod_id(mod)); 557cfcefe01SKuninori Morimoto bool ret = false; 558cfcefe01SKuninori Morimoto 559cfcefe01SKuninori Morimoto if ((rsnd_mod_read(mod, SCU_SYS_STATUS0) & val) || 560cfcefe01SKuninori Morimoto (rsnd_mod_read(mod, SCU_SYS_STATUS1) & val)) { 561cfcefe01SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 562cfcefe01SKuninori Morimoto 563cfcefe01SKuninori Morimoto src->err++; 564cfcefe01SKuninori Morimoto ret = true; 565cfcefe01SKuninori Morimoto } 566cfcefe01SKuninori Morimoto 567cfcefe01SKuninori Morimoto /* clear error static */ 568cfcefe01SKuninori Morimoto rsnd_src_error_clear_gen2(mod); 569cfcefe01SKuninori Morimoto 570cfcefe01SKuninori Morimoto return ret; 571cfcefe01SKuninori Morimoto } 572cfcefe01SKuninori Morimoto 573cfcefe01SKuninori Morimoto static int _rsnd_src_start_gen2(struct rsnd_mod *mod) 574cfcefe01SKuninori Morimoto { 575cfcefe01SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 576cfcefe01SKuninori Morimoto u32 val = rsnd_io_to_mod_dvc(io) ? 0x01 : 0x11; 577cfcefe01SKuninori Morimoto 578cfcefe01SKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, val); 579cfcefe01SKuninori Morimoto 580cfcefe01SKuninori Morimoto rsnd_src_error_clear_gen2(mod); 581cfcefe01SKuninori Morimoto 582cfcefe01SKuninori Morimoto rsnd_src_start(mod); 583cfcefe01SKuninori Morimoto 584cfcefe01SKuninori Morimoto rsnd_src_irq_enable_gen2(mod); 585cfcefe01SKuninori Morimoto 586cfcefe01SKuninori Morimoto return 0; 587cfcefe01SKuninori Morimoto } 588cfcefe01SKuninori Morimoto 589cfcefe01SKuninori Morimoto static int _rsnd_src_stop_gen2(struct rsnd_mod *mod) 590cfcefe01SKuninori Morimoto { 591cfcefe01SKuninori Morimoto rsnd_src_irq_disable_gen2(mod); 592cfcefe01SKuninori Morimoto 593cfcefe01SKuninori Morimoto rsnd_mod_write(mod, SRC_CTRL, 0); 594cfcefe01SKuninori Morimoto 595cfcefe01SKuninori Morimoto rsnd_src_error_record_gen2(mod); 596cfcefe01SKuninori Morimoto 597cfcefe01SKuninori Morimoto return rsnd_src_stop(mod); 598cfcefe01SKuninori Morimoto } 599cfcefe01SKuninori Morimoto 600cfcefe01SKuninori Morimoto static irqreturn_t rsnd_src_interrupt_gen2(int irq, void *data) 601cfcefe01SKuninori Morimoto { 602cfcefe01SKuninori Morimoto struct rsnd_mod *mod = data; 603cfcefe01SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 604cfcefe01SKuninori Morimoto 605cfcefe01SKuninori Morimoto if (!io) 606cfcefe01SKuninori Morimoto return IRQ_NONE; 607cfcefe01SKuninori Morimoto 608cfcefe01SKuninori Morimoto if (rsnd_src_error_record_gen2(mod)) { 609cfcefe01SKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 610cfcefe01SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 611cfcefe01SKuninori Morimoto 612cfcefe01SKuninori Morimoto _rsnd_src_stop_gen2(mod); 613cfcefe01SKuninori Morimoto _rsnd_src_start_gen2(mod); 614cfcefe01SKuninori Morimoto 615cfcefe01SKuninori Morimoto dev_dbg(dev, "%s[%d] restart\n", 616cfcefe01SKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 617cfcefe01SKuninori Morimoto } 618cfcefe01SKuninori Morimoto 619cfcefe01SKuninori Morimoto return IRQ_HANDLED; 620cfcefe01SKuninori Morimoto } 621cfcefe01SKuninori Morimoto 622f708d944SKuninori Morimoto static int rsnd_src_set_convert_rate_gen2(struct rsnd_mod *mod) 623ba9c949fSKuninori Morimoto { 624054cd7f4SKuninori Morimoto struct rsnd_priv *priv = rsnd_mod_to_priv(mod); 625054cd7f4SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 626054cd7f4SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 627054cd7f4SKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 628054cd7f4SKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 629b167a578SKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 630054cd7f4SKuninori Morimoto uint ratio; 631ba9c949fSKuninori Morimoto int ret; 632ba9c949fSKuninori Morimoto 633054cd7f4SKuninori Morimoto /* 6 - 1/6 are very enough ratio for SRC_BSDSR */ 634b167a578SKuninori Morimoto if (!convert_rate) 635054cd7f4SKuninori Morimoto ratio = 0; 636b167a578SKuninori Morimoto else if (convert_rate > runtime->rate) 637b167a578SKuninori Morimoto ratio = 100 * convert_rate / runtime->rate; 638054cd7f4SKuninori Morimoto else 639b167a578SKuninori Morimoto ratio = 100 * runtime->rate / convert_rate; 640054cd7f4SKuninori Morimoto 641054cd7f4SKuninori Morimoto if (ratio > 600) { 642054cd7f4SKuninori Morimoto dev_err(dev, "FSO/FSI ratio error\n"); 643054cd7f4SKuninori Morimoto return -EINVAL; 644054cd7f4SKuninori Morimoto } 645054cd7f4SKuninori Morimoto 646f708d944SKuninori Morimoto ret = rsnd_src_set_convert_rate(mod); 647ba9c949fSKuninori Morimoto if (ret < 0) 648ba9c949fSKuninori Morimoto return ret; 649ba9c949fSKuninori Morimoto 650ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_SRCCR, 0x00011110); 651ba9c949fSKuninori Morimoto 652933cc8cbSKuninori Morimoto if (convert_rate) { 653933cc8cbSKuninori Morimoto /* Gen1/Gen2 are not compatible */ 654933cc8cbSKuninori Morimoto rsnd_mod_write(mod, SRC_ROUTE_MODE0, 1); 655933cc8cbSKuninori Morimoto } 656933cc8cbSKuninori Morimoto 657054cd7f4SKuninori Morimoto switch (rsnd_mod_id(mod)) { 658054cd7f4SKuninori Morimoto case 5: 659054cd7f4SKuninori Morimoto case 6: 660054cd7f4SKuninori Morimoto case 7: 661054cd7f4SKuninori Morimoto case 8: 662054cd7f4SKuninori Morimoto rsnd_mod_write(mod, SRC_BSDSR, 0x02400000); 663054cd7f4SKuninori Morimoto break; 664054cd7f4SKuninori Morimoto default: 665ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_BSDSR, 0x01800000); 666054cd7f4SKuninori Morimoto break; 667054cd7f4SKuninori Morimoto } 668054cd7f4SKuninori Morimoto 669ba9c949fSKuninori Morimoto rsnd_mod_write(mod, SRC_BSISR, 0x00100060); 670ba9c949fSKuninori Morimoto 671ba9c949fSKuninori Morimoto return 0; 672ba9c949fSKuninori Morimoto } 673ba9c949fSKuninori Morimoto 674f708d944SKuninori Morimoto static int rsnd_src_set_convert_timing_gen2(struct rsnd_mod *mod) 675ba9c949fSKuninori Morimoto { 676b42fccf6SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 677ba9c949fSKuninori Morimoto struct snd_pcm_runtime *runtime = rsnd_io_to_runtime(io); 678ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 679ba9c949fSKuninori Morimoto u32 convert_rate = rsnd_src_convert_rate(src); 680ba9c949fSKuninori Morimoto int ret; 681ba9c949fSKuninori Morimoto 682ba9c949fSKuninori Morimoto if (convert_rate) 683f708d944SKuninori Morimoto ret = rsnd_adg_set_convert_clk_gen2(mod, io, 684ba9c949fSKuninori Morimoto runtime->rate, 685ba9c949fSKuninori Morimoto convert_rate); 686ba9c949fSKuninori Morimoto else 687f708d944SKuninori Morimoto ret = rsnd_adg_set_convert_timing_gen2(mod, io); 688ba9c949fSKuninori Morimoto 689ba9c949fSKuninori Morimoto return ret; 690ba9c949fSKuninori Morimoto } 691ba9c949fSKuninori Morimoto 692ba9c949fSKuninori Morimoto static int rsnd_src_probe_gen2(struct rsnd_mod *mod, 693690602fcSKuninori Morimoto struct rsnd_priv *priv) 694ba9c949fSKuninori Morimoto { 695ba9c949fSKuninori Morimoto struct rsnd_src *src = rsnd_mod_to_src(mod); 696ba9c949fSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 697cfcefe01SKuninori Morimoto int irq = src->info->irq; 698ba9c949fSKuninori Morimoto int ret; 699ba9c949fSKuninori Morimoto 700cfcefe01SKuninori Morimoto if (irq > 0) { 701cfcefe01SKuninori Morimoto /* 702cfcefe01SKuninori Morimoto * IRQ is not supported on non-DT 703cfcefe01SKuninori Morimoto * see 704cfcefe01SKuninori Morimoto * rsnd_src_irq_enable_gen2() 705cfcefe01SKuninori Morimoto */ 706cfcefe01SKuninori Morimoto ret = devm_request_irq(dev, irq, 707cfcefe01SKuninori Morimoto rsnd_src_interrupt_gen2, 708cfcefe01SKuninori Morimoto IRQF_SHARED, 709cfcefe01SKuninori Morimoto dev_name(dev), mod); 710cfcefe01SKuninori Morimoto if (ret) 711cfcefe01SKuninori Morimoto goto rsnd_src_probe_gen2_fail; 712cfcefe01SKuninori Morimoto } 713cfcefe01SKuninori Morimoto 714ba9c949fSKuninori Morimoto ret = rsnd_dma_init(priv, 715ba9c949fSKuninori Morimoto rsnd_mod_to_dma(mod), 71629e69fd2SKuninori Morimoto rsnd_info_is_playback(priv, src), 717ba9c949fSKuninori Morimoto src->info->dma_id); 718cfcefe01SKuninori Morimoto if (ret) 719cfcefe01SKuninori Morimoto goto rsnd_src_probe_gen2_fail; 720cfcefe01SKuninori Morimoto 72130cc4fafSKuninori Morimoto dev_dbg(dev, "%s[%d] (Gen2) is probed\n", 72230cc4fafSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 7238aefda50SKuninori Morimoto 724ba9c949fSKuninori Morimoto return ret; 725cfcefe01SKuninori Morimoto 726cfcefe01SKuninori Morimoto rsnd_src_probe_gen2_fail: 727cfcefe01SKuninori Morimoto dev_err(dev, "%s[%d] (Gen2) failed\n", 728cfcefe01SKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod)); 729cfcefe01SKuninori Morimoto 730cfcefe01SKuninori Morimoto return ret; 731ba9c949fSKuninori Morimoto } 732ba9c949fSKuninori Morimoto 733ba9c949fSKuninori Morimoto static int rsnd_src_remove_gen2(struct rsnd_mod *mod, 734690602fcSKuninori Morimoto struct rsnd_priv *priv) 735ba9c949fSKuninori Morimoto { 736690602fcSKuninori Morimoto rsnd_dma_quit(priv, rsnd_mod_to_dma(mod)); 737ba9c949fSKuninori Morimoto 738ba9c949fSKuninori Morimoto return 0; 739ba9c949fSKuninori Morimoto } 740ba9c949fSKuninori Morimoto 741ba9c949fSKuninori Morimoto static int rsnd_src_init_gen2(struct rsnd_mod *mod, 742690602fcSKuninori Morimoto struct rsnd_priv *priv) 743ba9c949fSKuninori Morimoto { 744ba9c949fSKuninori Morimoto int ret; 745ba9c949fSKuninori Morimoto 746f708d944SKuninori Morimoto ret = rsnd_src_init(mod); 747ba9c949fSKuninori Morimoto if (ret < 0) 748ba9c949fSKuninori Morimoto return ret; 749ba9c949fSKuninori Morimoto 750f708d944SKuninori Morimoto ret = rsnd_src_set_convert_rate_gen2(mod); 751ba9c949fSKuninori Morimoto if (ret < 0) 752ba9c949fSKuninori Morimoto return ret; 753ba9c949fSKuninori Morimoto 754f708d944SKuninori Morimoto ret = rsnd_src_set_convert_timing_gen2(mod); 755ba9c949fSKuninori Morimoto if (ret < 0) 756ba9c949fSKuninori Morimoto return ret; 757ba9c949fSKuninori Morimoto 758ba9c949fSKuninori Morimoto return 0; 759ba9c949fSKuninori Morimoto } 760ba9c949fSKuninori Morimoto 761ba9c949fSKuninori Morimoto static int rsnd_src_start_gen2(struct rsnd_mod *mod, 762690602fcSKuninori Morimoto struct rsnd_priv *priv) 763ba9c949fSKuninori Morimoto { 764cfcefe01SKuninori Morimoto rsnd_dma_start(rsnd_mod_to_dma(mod)); 765ba9c949fSKuninori Morimoto 766cfcefe01SKuninori Morimoto return _rsnd_src_start_gen2(mod); 767ba9c949fSKuninori Morimoto } 768ba9c949fSKuninori Morimoto 769ba9c949fSKuninori Morimoto static int rsnd_src_stop_gen2(struct rsnd_mod *mod, 770690602fcSKuninori Morimoto struct rsnd_priv *priv) 771ba9c949fSKuninori Morimoto { 772cfcefe01SKuninori Morimoto int ret; 773ba9c949fSKuninori Morimoto 774cfcefe01SKuninori Morimoto ret = _rsnd_src_stop_gen2(mod); 775ba9c949fSKuninori Morimoto 776cfcefe01SKuninori Morimoto rsnd_dma_stop(rsnd_mod_to_dma(mod)); 777ba9c949fSKuninori Morimoto 778cfcefe01SKuninori Morimoto return ret; 779ba9c949fSKuninori Morimoto } 780ba9c949fSKuninori Morimoto 781ba9c949fSKuninori Morimoto static struct rsnd_mod_ops rsnd_src_gen2_ops = { 7828aefda50SKuninori Morimoto .name = SRC_NAME, 783ba9c949fSKuninori Morimoto .probe = rsnd_src_probe_gen2, 784ba9c949fSKuninori Morimoto .remove = rsnd_src_remove_gen2, 785ba9c949fSKuninori Morimoto .init = rsnd_src_init_gen2, 786ba9c949fSKuninori Morimoto .quit = rsnd_src_quit, 787ba9c949fSKuninori Morimoto .start = rsnd_src_start_gen2, 788ba9c949fSKuninori Morimoto .stop = rsnd_src_stop_gen2, 789ba9c949fSKuninori Morimoto }; 790ba9c949fSKuninori Morimoto 791ba9c949fSKuninori Morimoto struct rsnd_mod *rsnd_src_mod_get(struct rsnd_priv *priv, int id) 792ba9c949fSKuninori Morimoto { 793ba9c949fSKuninori Morimoto if (WARN_ON(id < 0 || id >= rsnd_src_nr(priv))) 794ba9c949fSKuninori Morimoto id = 0; 795ba9c949fSKuninori Morimoto 796ba9c949fSKuninori Morimoto return &((struct rsnd_src *)(priv->src) + id)->mod; 797ba9c949fSKuninori Morimoto } 798ba9c949fSKuninori Morimoto 79990e8e50fSKuninori Morimoto static void rsnd_of_parse_src(struct platform_device *pdev, 80090e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 80190e8e50fSKuninori Morimoto struct rsnd_priv *priv) 80290e8e50fSKuninori Morimoto { 80390e8e50fSKuninori Morimoto struct device_node *src_node; 804cfcefe01SKuninori Morimoto struct device_node *np; 80590e8e50fSKuninori Morimoto struct rcar_snd_info *info = rsnd_priv_to_info(priv); 80690e8e50fSKuninori Morimoto struct rsnd_src_platform_info *src_info; 80790e8e50fSKuninori Morimoto struct device *dev = &pdev->dev; 808cfcefe01SKuninori Morimoto int nr, i; 80990e8e50fSKuninori Morimoto 81090e8e50fSKuninori Morimoto if (!of_data) 81190e8e50fSKuninori Morimoto return; 81290e8e50fSKuninori Morimoto 81390e8e50fSKuninori Morimoto src_node = of_get_child_by_name(dev->of_node, "rcar_sound,src"); 81490e8e50fSKuninori Morimoto if (!src_node) 81590e8e50fSKuninori Morimoto return; 81690e8e50fSKuninori Morimoto 81790e8e50fSKuninori Morimoto nr = of_get_child_count(src_node); 81890e8e50fSKuninori Morimoto if (!nr) 819f451e48dSKuninori Morimoto goto rsnd_of_parse_src_end; 82090e8e50fSKuninori Morimoto 82190e8e50fSKuninori Morimoto src_info = devm_kzalloc(dev, 82290e8e50fSKuninori Morimoto sizeof(struct rsnd_src_platform_info) * nr, 82390e8e50fSKuninori Morimoto GFP_KERNEL); 82490e8e50fSKuninori Morimoto if (!src_info) { 82590e8e50fSKuninori Morimoto dev_err(dev, "src info allocation error\n"); 826f451e48dSKuninori Morimoto goto rsnd_of_parse_src_end; 82790e8e50fSKuninori Morimoto } 82890e8e50fSKuninori Morimoto 82990e8e50fSKuninori Morimoto info->src_info = src_info; 83090e8e50fSKuninori Morimoto info->src_info_nr = nr; 831f451e48dSKuninori Morimoto 832cfcefe01SKuninori Morimoto i = 0; 833cfcefe01SKuninori Morimoto for_each_child_of_node(src_node, np) { 834cfcefe01SKuninori Morimoto src_info[i].irq = irq_of_parse_and_map(np, 0); 835cfcefe01SKuninori Morimoto 836cfcefe01SKuninori Morimoto i++; 837cfcefe01SKuninori Morimoto } 838cfcefe01SKuninori Morimoto 839f451e48dSKuninori Morimoto rsnd_of_parse_src_end: 840f451e48dSKuninori Morimoto of_node_put(src_node); 84190e8e50fSKuninori Morimoto } 84290e8e50fSKuninori Morimoto 843ba9c949fSKuninori Morimoto int rsnd_src_probe(struct platform_device *pdev, 84490e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 845ba9c949fSKuninori Morimoto struct rsnd_priv *priv) 846ba9c949fSKuninori Morimoto { 847ba9c949fSKuninori Morimoto struct rcar_snd_info *info = rsnd_priv_to_info(priv); 848ba9c949fSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 849ba9c949fSKuninori Morimoto struct rsnd_src *src; 850ba9c949fSKuninori Morimoto struct rsnd_mod_ops *ops; 851ba9c949fSKuninori Morimoto struct clk *clk; 852ba9c949fSKuninori Morimoto char name[RSND_SRC_NAME_SIZE]; 853*2f78dd7fSKuninori Morimoto int i, nr, ret; 854ba9c949fSKuninori Morimoto 855033e7ed8SKuninori Morimoto ops = NULL; 856033e7ed8SKuninori Morimoto if (rsnd_is_gen1(priv)) 857033e7ed8SKuninori Morimoto ops = &rsnd_src_gen1_ops; 858033e7ed8SKuninori Morimoto if (rsnd_is_gen2(priv)) 859033e7ed8SKuninori Morimoto ops = &rsnd_src_gen2_ops; 860033e7ed8SKuninori Morimoto if (!ops) { 861033e7ed8SKuninori Morimoto dev_err(dev, "unknown Generation\n"); 862033e7ed8SKuninori Morimoto return -EIO; 863033e7ed8SKuninori Morimoto } 864033e7ed8SKuninori Morimoto 86590e8e50fSKuninori Morimoto rsnd_of_parse_src(pdev, of_data, priv); 86690e8e50fSKuninori Morimoto 867ba9c949fSKuninori Morimoto /* 868ba9c949fSKuninori Morimoto * init SRC 869ba9c949fSKuninori Morimoto */ 870ba9c949fSKuninori Morimoto nr = info->src_info_nr; 871ba9c949fSKuninori Morimoto if (!nr) 872ba9c949fSKuninori Morimoto return 0; 873ba9c949fSKuninori Morimoto 874ba9c949fSKuninori Morimoto src = devm_kzalloc(dev, sizeof(*src) * nr, GFP_KERNEL); 875ba9c949fSKuninori Morimoto if (!src) { 876ba9c949fSKuninori Morimoto dev_err(dev, "SRC allocate failed\n"); 877ba9c949fSKuninori Morimoto return -ENOMEM; 878ba9c949fSKuninori Morimoto } 879ba9c949fSKuninori Morimoto 880ba9c949fSKuninori Morimoto priv->src_nr = nr; 881ba9c949fSKuninori Morimoto priv->src = src; 882ba9c949fSKuninori Morimoto 883ba9c949fSKuninori Morimoto for_each_rsnd_src(src, priv, i) { 8848aefda50SKuninori Morimoto snprintf(name, RSND_SRC_NAME_SIZE, "%s.%d", 8858aefda50SKuninori Morimoto SRC_NAME, i); 886ba9c949fSKuninori Morimoto 887ba9c949fSKuninori Morimoto clk = devm_clk_get(dev, name); 888ba9c949fSKuninori Morimoto if (IS_ERR(clk)) 889ba9c949fSKuninori Morimoto return PTR_ERR(clk); 890ba9c949fSKuninori Morimoto 891ba9c949fSKuninori Morimoto src->info = &info->src_info[i]; 892ba9c949fSKuninori Morimoto 893*2f78dd7fSKuninori Morimoto ret = rsnd_mod_init(&src->mod, ops, clk, RSND_MOD_SRC, i); 894*2f78dd7fSKuninori Morimoto if (ret) 895*2f78dd7fSKuninori Morimoto return ret; 896ba9c949fSKuninori Morimoto 897ba9c949fSKuninori Morimoto dev_dbg(dev, "SRC%d probed\n", i); 898ba9c949fSKuninori Morimoto } 899ba9c949fSKuninori Morimoto 900ba9c949fSKuninori Morimoto return 0; 901ba9c949fSKuninori Morimoto } 902*2f78dd7fSKuninori Morimoto 903*2f78dd7fSKuninori Morimoto void rsnd_src_remove(struct platform_device *pdev, 904*2f78dd7fSKuninori Morimoto struct rsnd_priv *priv) 905*2f78dd7fSKuninori Morimoto { 906*2f78dd7fSKuninori Morimoto struct rsnd_src *src; 907*2f78dd7fSKuninori Morimoto int i; 908*2f78dd7fSKuninori Morimoto 909*2f78dd7fSKuninori Morimoto for_each_rsnd_src(src, priv, i) { 910*2f78dd7fSKuninori Morimoto rsnd_mod_quit(&src->mod); 911*2f78dd7fSKuninori Morimoto } 912*2f78dd7fSKuninori Morimoto } 913