1 /* 2 * Renesas R-Car Gen1 SRU/SSI support 3 * 4 * Copyright (C) 2013 Renesas Solutions Corp. 5 * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 */ 11 #include "rsnd.h" 12 13 struct rsnd_gen_ops { 14 int (*probe)(struct platform_device *pdev, 15 struct rcar_snd_info *info, 16 struct rsnd_priv *priv); 17 void (*remove)(struct platform_device *pdev, 18 struct rsnd_priv *priv); 19 int (*path_init)(struct rsnd_priv *priv, 20 struct rsnd_dai *rdai, 21 struct rsnd_dai_stream *io); 22 int (*path_exit)(struct rsnd_priv *priv, 23 struct rsnd_dai *rdai, 24 struct rsnd_dai_stream *io); 25 }; 26 27 struct rsnd_gen { 28 void __iomem *base[RSND_BASE_MAX]; 29 30 struct rsnd_gen_ops *ops; 31 32 struct regmap *regmap; 33 struct regmap_field *regs[RSND_REG_MAX]; 34 }; 35 36 #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 37 38 #define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size) \ 39 [id] = { \ 40 .reg = (unsigned int)gen->base[reg_id] + offset, \ 41 .lsb = 0, \ 42 .msb = 31, \ 43 .id_size = _id_size, \ 44 .id_offset = _id_offset, \ 45 } 46 47 /* 48 * basic function 49 */ 50 static int rsnd_regmap_write32(void *context, const void *_data, size_t count) 51 { 52 struct rsnd_priv *priv = context; 53 struct device *dev = rsnd_priv_to_dev(priv); 54 u32 *data = (u32 *)_data; 55 u32 val = data[1]; 56 void __iomem *reg = (void *)data[0]; 57 58 iowrite32(val, reg); 59 60 dev_dbg(dev, "w %p : %08x\n", reg, val); 61 62 return 0; 63 } 64 65 static int rsnd_regmap_read32(void *context, 66 const void *_data, size_t reg_size, 67 void *_val, size_t val_size) 68 { 69 struct rsnd_priv *priv = context; 70 struct device *dev = rsnd_priv_to_dev(priv); 71 u32 *data = (u32 *)_data; 72 u32 *val = (u32 *)_val; 73 void __iomem *reg = (void *)data[0]; 74 75 *val = ioread32(reg); 76 77 dev_dbg(dev, "r %p : %08x\n", reg, *val); 78 79 return 0; 80 } 81 82 static struct regmap_bus rsnd_regmap_bus = { 83 .write = rsnd_regmap_write32, 84 .read = rsnd_regmap_read32, 85 .reg_format_endian_default = REGMAP_ENDIAN_NATIVE, 86 .val_format_endian_default = REGMAP_ENDIAN_NATIVE, 87 }; 88 89 u32 rsnd_read(struct rsnd_priv *priv, 90 struct rsnd_mod *mod, enum rsnd_reg reg) 91 { 92 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 93 u32 val; 94 95 regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 96 97 return val; 98 } 99 100 void rsnd_write(struct rsnd_priv *priv, 101 struct rsnd_mod *mod, 102 enum rsnd_reg reg, u32 data) 103 { 104 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 105 106 regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); 107 } 108 109 void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 110 enum rsnd_reg reg, u32 mask, u32 data) 111 { 112 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 113 114 regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), 115 mask, data); 116 } 117 118 /* 119 * Gen2 120 * will be filled in the future 121 */ 122 123 /* 124 * Gen1 125 */ 126 static int rsnd_gen1_path_init(struct rsnd_priv *priv, 127 struct rsnd_dai *rdai, 128 struct rsnd_dai_stream *io) 129 { 130 struct rsnd_mod *mod; 131 int ret; 132 int id; 133 134 /* 135 * Gen1 is created by SRU/SSI, and this SRU is base module of 136 * Gen2's SCU/SSIU/SSI. (Gen2 SCU/SSIU came from SRU) 137 * 138 * Easy image is.. 139 * Gen1 SRU = Gen2 SCU + SSIU + etc 140 * 141 * Gen2 SCU path is very flexible, but, Gen1 SRU (SCU parts) is 142 * using fixed path. 143 * 144 * Then, SSI id = SCU id here 145 */ 146 147 /* get SSI's ID */ 148 mod = rsnd_ssi_mod_get_frm_dai(priv, 149 rsnd_dai_id(priv, rdai), 150 rsnd_dai_is_play(rdai, io)); 151 id = rsnd_mod_id(mod); 152 153 /* SSI */ 154 mod = rsnd_ssi_mod_get(priv, id); 155 ret = rsnd_dai_connect(rdai, mod, io); 156 if (ret < 0) 157 return ret; 158 159 /* SCU */ 160 mod = rsnd_scu_mod_get(priv, id); 161 ret = rsnd_dai_connect(rdai, mod, io); 162 163 return ret; 164 } 165 166 static int rsnd_gen1_path_exit(struct rsnd_priv *priv, 167 struct rsnd_dai *rdai, 168 struct rsnd_dai_stream *io) 169 { 170 struct rsnd_mod *mod, *n; 171 int ret = 0; 172 173 /* 174 * remove all mod from rdai 175 */ 176 for_each_rsnd_mod(mod, n, io) 177 ret |= rsnd_dai_disconnect(mod); 178 179 return ret; 180 } 181 182 /* single address mapping */ 183 #define RSND_GEN1_S_REG(gen, reg, id, offset) \ 184 RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9) 185 186 /* multi address mapping */ 187 #define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset) \ 188 RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9) 189 190 static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen) 191 { 192 int i; 193 struct device *dev = rsnd_priv_to_dev(priv); 194 struct regmap_config regc; 195 struct reg_field regf[RSND_REG_MAX] = { 196 RSND_GEN1_S_REG(gen, SRU, SRC_ROUTE_SEL, 0x00), 197 RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL0, 0x08), 198 RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL1, 0x0c), 199 RSND_GEN1_S_REG(gen, SRU, SRC_TMG_SEL2, 0x10), 200 RSND_GEN1_S_REG(gen, SRU, SRC_CTRL, 0xc0), 201 RSND_GEN1_S_REG(gen, SRU, SSI_MODE0, 0xD0), 202 RSND_GEN1_S_REG(gen, SRU, SSI_MODE1, 0xD4), 203 RSND_GEN1_M_REG(gen, SRU, BUSIF_MODE, 0x20, 0x4), 204 RSND_GEN1_M_REG(gen, SRU, BUSIF_ADINR, 0x214, 0x40), 205 206 RSND_GEN1_S_REG(gen, ADG, BRRA, 0x00), 207 RSND_GEN1_S_REG(gen, ADG, BRRB, 0x04), 208 RSND_GEN1_S_REG(gen, ADG, SSICKR, 0x08), 209 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL0, 0x0c), 210 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL1, 0x10), 211 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL3, 0x18), 212 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL4, 0x1c), 213 RSND_GEN1_S_REG(gen, ADG, AUDIO_CLK_SEL5, 0x20), 214 215 RSND_GEN1_M_REG(gen, SSI, SSICR, 0x00, 0x40), 216 RSND_GEN1_M_REG(gen, SSI, SSISR, 0x04, 0x40), 217 RSND_GEN1_M_REG(gen, SSI, SSITDR, 0x08, 0x40), 218 RSND_GEN1_M_REG(gen, SSI, SSIRDR, 0x0c, 0x40), 219 RSND_GEN1_M_REG(gen, SSI, SSIWSR, 0x20, 0x40), 220 }; 221 222 memset(®c, 0, sizeof(regc)); 223 regc.reg_bits = 32; 224 regc.val_bits = 32; 225 226 gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, ®c); 227 if (IS_ERR(gen->regmap)) { 228 dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap)); 229 return PTR_ERR(gen->regmap); 230 } 231 232 for (i = 0; i < RSND_REG_MAX; i++) { 233 gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]); 234 if (IS_ERR(gen->regs[i])) 235 return PTR_ERR(gen->regs[i]); 236 237 } 238 239 return 0; 240 } 241 242 static int rsnd_gen1_probe(struct platform_device *pdev, 243 struct rcar_snd_info *info, 244 struct rsnd_priv *priv) 245 { 246 struct device *dev = rsnd_priv_to_dev(priv); 247 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 248 struct resource *sru_res; 249 struct resource *adg_res; 250 struct resource *ssi_res; 251 int ret; 252 253 /* 254 * map address 255 */ 256 sru_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU); 257 adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG); 258 ssi_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI); 259 260 gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res); 261 gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res); 262 gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res); 263 if (IS_ERR(gen->base[RSND_GEN1_SRU]) || 264 IS_ERR(gen->base[RSND_GEN1_ADG]) || 265 IS_ERR(gen->base[RSND_GEN1_SSI])) 266 return -ENODEV; 267 268 ret = rsnd_gen1_regmap_init(priv, gen); 269 if (ret < 0) 270 return ret; 271 272 dev_dbg(dev, "Gen1 device probed\n"); 273 dev_dbg(dev, "SRU : %08x => %p\n", sru_res->start, 274 gen->base[RSND_GEN1_SRU]); 275 dev_dbg(dev, "ADG : %08x => %p\n", adg_res->start, 276 gen->base[RSND_GEN1_ADG]); 277 dev_dbg(dev, "SSI : %08x => %p\n", ssi_res->start, 278 gen->base[RSND_GEN1_SSI]); 279 280 return 0; 281 282 } 283 284 static void rsnd_gen1_remove(struct platform_device *pdev, 285 struct rsnd_priv *priv) 286 { 287 } 288 289 static struct rsnd_gen_ops rsnd_gen1_ops = { 290 .probe = rsnd_gen1_probe, 291 .remove = rsnd_gen1_remove, 292 .path_init = rsnd_gen1_path_init, 293 .path_exit = rsnd_gen1_path_exit, 294 }; 295 296 /* 297 * Gen 298 */ 299 int rsnd_gen_path_init(struct rsnd_priv *priv, 300 struct rsnd_dai *rdai, 301 struct rsnd_dai_stream *io) 302 { 303 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 304 305 return gen->ops->path_init(priv, rdai, io); 306 } 307 308 int rsnd_gen_path_exit(struct rsnd_priv *priv, 309 struct rsnd_dai *rdai, 310 struct rsnd_dai_stream *io) 311 { 312 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 313 314 return gen->ops->path_exit(priv, rdai, io); 315 } 316 317 int rsnd_gen_probe(struct platform_device *pdev, 318 struct rcar_snd_info *info, 319 struct rsnd_priv *priv) 320 { 321 struct device *dev = rsnd_priv_to_dev(priv); 322 struct rsnd_gen *gen; 323 324 gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 325 if (!gen) { 326 dev_err(dev, "GEN allocate failed\n"); 327 return -ENOMEM; 328 } 329 330 if (rsnd_is_gen1(priv)) 331 gen->ops = &rsnd_gen1_ops; 332 333 if (!gen->ops) { 334 dev_err(dev, "unknown generation R-Car sound device\n"); 335 return -ENODEV; 336 } 337 338 priv->gen = gen; 339 340 return gen->ops->probe(pdev, info, priv); 341 } 342 343 void rsnd_gen_remove(struct platform_device *pdev, 344 struct rsnd_priv *priv) 345 { 346 struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 347 348 gen->ops->remove(pdev, priv); 349 } 350