13337744aSKuninori Morimoto /* 23337744aSKuninori Morimoto * Renesas R-Car Gen1 SRU/SSI support 33337744aSKuninori Morimoto * 43337744aSKuninori Morimoto * Copyright (C) 2013 Renesas Solutions Corp. 53337744aSKuninori Morimoto * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 63337744aSKuninori Morimoto * 73337744aSKuninori Morimoto * This program is free software; you can redistribute it and/or modify 83337744aSKuninori Morimoto * it under the terms of the GNU General Public License version 2 as 93337744aSKuninori Morimoto * published by the Free Software Foundation. 103337744aSKuninori Morimoto */ 11ace0eb1eSKuninori Morimoto 12ace0eb1eSKuninori Morimoto /* 13ace0eb1eSKuninori Morimoto * #define DEBUG 14ace0eb1eSKuninori Morimoto * 15ace0eb1eSKuninori Morimoto * you can also add below in 16ace0eb1eSKuninori Morimoto * ${LINUX}/drivers/base/regmap/regmap.c 17ace0eb1eSKuninori Morimoto * for regmap debug 18ace0eb1eSKuninori Morimoto * 19ace0eb1eSKuninori Morimoto * #define LOG_DEVICE "xxxx.rcar_sound" 20ace0eb1eSKuninori Morimoto */ 21ace0eb1eSKuninori Morimoto 223337744aSKuninori Morimoto #include "rsnd.h" 233337744aSKuninori Morimoto 243337744aSKuninori Morimoto struct rsnd_gen { 253337744aSKuninori Morimoto void __iomem *base[RSND_BASE_MAX]; 263337744aSKuninori Morimoto 273337744aSKuninori Morimoto struct rsnd_gen_ops *ops; 2855e5b6fdSKuninori Morimoto 29b8c63786SKuninori Morimoto struct regmap *regmap[RSND_BASE_MAX]; 3055e5b6fdSKuninori Morimoto struct regmap_field *regs[RSND_REG_MAX]; 313337744aSKuninori Morimoto }; 323337744aSKuninori Morimoto 333337744aSKuninori Morimoto #define rsnd_priv_to_gen(p) ((struct rsnd_gen *)(p)->gen) 343337744aSKuninori Morimoto 35b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf { 36b8c63786SKuninori Morimoto int idx; 37b8c63786SKuninori Morimoto unsigned int reg_offset; 38b8c63786SKuninori Morimoto unsigned int id_offset; 39b8c63786SKuninori Morimoto }; 40b8c63786SKuninori Morimoto 41b8c63786SKuninori Morimoto #define RSND_REG_SET(id, offset, _id_offset) \ 42b8c63786SKuninori Morimoto { \ 43b8c63786SKuninori Morimoto .idx = id, \ 44b8c63786SKuninori Morimoto .reg_offset = offset, \ 4555e5b6fdSKuninori Morimoto .id_offset = _id_offset, \ 4655e5b6fdSKuninori Morimoto } 47b8c63786SKuninori Morimoto /* single address mapping */ 48b8c63786SKuninori Morimoto #define RSND_GEN_S_REG(id, offset) \ 49b8c63786SKuninori Morimoto RSND_REG_SET(RSND_REG_##id, offset, 0) 50b8c63786SKuninori Morimoto 51b8c63786SKuninori Morimoto /* multi address mapping */ 52b8c63786SKuninori Morimoto #define RSND_GEN_M_REG(id, offset, _id_offset) \ 53b8c63786SKuninori Morimoto RSND_REG_SET(RSND_REG_##id, offset, _id_offset) 5455e5b6fdSKuninori Morimoto 5555e5b6fdSKuninori Morimoto /* 5655e5b6fdSKuninori Morimoto * basic function 5755e5b6fdSKuninori Morimoto */ 5842ee5d22SKuninori Morimoto static int rsnd_is_accessible_reg(struct rsnd_priv *priv, 5942ee5d22SKuninori Morimoto struct rsnd_gen *gen, enum rsnd_reg reg) 6042ee5d22SKuninori Morimoto { 6142ee5d22SKuninori Morimoto if (!gen->regs[reg]) { 6242ee5d22SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 6342ee5d22SKuninori Morimoto 6442ee5d22SKuninori Morimoto dev_err(dev, "unsupported register access %x\n", reg); 6542ee5d22SKuninori Morimoto return 0; 6642ee5d22SKuninori Morimoto } 6742ee5d22SKuninori Morimoto 6842ee5d22SKuninori Morimoto return 1; 6942ee5d22SKuninori Morimoto } 7042ee5d22SKuninori Morimoto 7155e5b6fdSKuninori Morimoto u32 rsnd_read(struct rsnd_priv *priv, 7255e5b6fdSKuninori Morimoto struct rsnd_mod *mod, enum rsnd_reg reg) 7355e5b6fdSKuninori Morimoto { 74b8c63786SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 7555e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 7655e5b6fdSKuninori Morimoto u32 val; 7755e5b6fdSKuninori Morimoto 7842ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 7942ee5d22SKuninori Morimoto return 0; 8042ee5d22SKuninori Morimoto 8130cc4fafSKuninori Morimoto dev_dbg(dev, "r %s[%d] - %4d : %08x\n", 82ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, val); 8355e5b6fdSKuninori Morimoto 84ace0eb1eSKuninori Morimoto regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val); 85b8c63786SKuninori Morimoto 8655e5b6fdSKuninori Morimoto return val; 8755e5b6fdSKuninori Morimoto } 8855e5b6fdSKuninori Morimoto 8955e5b6fdSKuninori Morimoto void rsnd_write(struct rsnd_priv *priv, 9055e5b6fdSKuninori Morimoto struct rsnd_mod *mod, 9155e5b6fdSKuninori Morimoto enum rsnd_reg reg, u32 data) 9255e5b6fdSKuninori Morimoto { 93b8c63786SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 9455e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 9555e5b6fdSKuninori Morimoto 9642ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 9742ee5d22SKuninori Morimoto return; 9842ee5d22SKuninori Morimoto 9930cc4fafSKuninori Morimoto dev_dbg(dev, "w %s[%d] - %4d : %08x\n", 100ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data); 101b8c63786SKuninori Morimoto 102ace0eb1eSKuninori Morimoto regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data); 10355e5b6fdSKuninori Morimoto } 10455e5b6fdSKuninori Morimoto 10555e5b6fdSKuninori Morimoto void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, 10655e5b6fdSKuninori Morimoto enum rsnd_reg reg, u32 mask, u32 data) 10755e5b6fdSKuninori Morimoto { 1084f8f86aaSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 10955e5b6fdSKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 11055e5b6fdSKuninori Morimoto 11142ee5d22SKuninori Morimoto if (!rsnd_is_accessible_reg(priv, gen, reg)) 11242ee5d22SKuninori Morimoto return; 11342ee5d22SKuninori Morimoto 11430cc4fafSKuninori Morimoto dev_dbg(dev, "b %s[%d] - %4d : %08x/%08x\n", 115ace0eb1eSKuninori Morimoto rsnd_mod_name(mod), rsnd_mod_id(mod), reg, data, mask); 116ace0eb1eSKuninori Morimoto 11755e5b6fdSKuninori Morimoto regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod), 11855e5b6fdSKuninori Morimoto mask, data); 11955e5b6fdSKuninori Morimoto } 12055e5b6fdSKuninori Morimoto 1217277911cSKuninori Morimoto #define rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf) \ 1227277911cSKuninori Morimoto _rsnd_gen_regmap_init(priv, id_size, reg_id, name, conf, ARRAY_SIZE(conf)) 123b8c63786SKuninori Morimoto static int _rsnd_gen_regmap_init(struct rsnd_priv *priv, 124b8c63786SKuninori Morimoto int id_size, 125b8c63786SKuninori Morimoto int reg_id, 1267277911cSKuninori Morimoto const char *name, 127b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf *conf, 128b8c63786SKuninori Morimoto int conf_size) 129c1e6cc5eSKuninori Morimoto { 130b8c63786SKuninori Morimoto struct platform_device *pdev = rsnd_priv_to_pdev(priv); 131b8c63786SKuninori Morimoto struct rsnd_gen *gen = rsnd_priv_to_gen(priv); 132c1e6cc5eSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 133b8c63786SKuninori Morimoto struct resource *res; 134c1e6cc5eSKuninori Morimoto struct regmap_config regc; 135b8c63786SKuninori Morimoto struct regmap_field *regs; 136b8c63786SKuninori Morimoto struct regmap *regmap; 137b8c63786SKuninori Morimoto struct reg_field regf; 138b8c63786SKuninori Morimoto void __iomem *base; 139b8c63786SKuninori Morimoto int i; 140c1e6cc5eSKuninori Morimoto 141c1e6cc5eSKuninori Morimoto memset(®c, 0, sizeof(regc)); 142c1e6cc5eSKuninori Morimoto regc.reg_bits = 32; 143c1e6cc5eSKuninori Morimoto regc.val_bits = 32; 144b8c63786SKuninori Morimoto regc.reg_stride = 4; 145c1e6cc5eSKuninori Morimoto 1467277911cSKuninori Morimoto res = platform_get_resource_byname(pdev, IORESOURCE_MEM, name); 1477277911cSKuninori Morimoto if (!res) 148b8c63786SKuninori Morimoto res = platform_get_resource(pdev, IORESOURCE_MEM, reg_id); 149b8c63786SKuninori Morimoto if (!res) 150b8c63786SKuninori Morimoto return -ENODEV; 151c1e6cc5eSKuninori Morimoto 152b8c63786SKuninori Morimoto base = devm_ioremap_resource(dev, res); 153b8c63786SKuninori Morimoto if (IS_ERR(base)) 154b8c63786SKuninori Morimoto return PTR_ERR(base); 15542ee5d22SKuninori Morimoto 156b8c63786SKuninori Morimoto regmap = devm_regmap_init_mmio(dev, base, ®c); 157b8c63786SKuninori Morimoto if (IS_ERR(regmap)) 158b8c63786SKuninori Morimoto return PTR_ERR(regmap); 159c1e6cc5eSKuninori Morimoto 160b8c63786SKuninori Morimoto gen->base[reg_id] = base; 161b8c63786SKuninori Morimoto gen->regmap[reg_id] = regmap; 162b8c63786SKuninori Morimoto 163b8c63786SKuninori Morimoto for (i = 0; i < conf_size; i++) { 164b8c63786SKuninori Morimoto 165b8c63786SKuninori Morimoto regf.reg = conf[i].reg_offset; 166b8c63786SKuninori Morimoto regf.id_offset = conf[i].id_offset; 167b8c63786SKuninori Morimoto regf.lsb = 0; 168b8c63786SKuninori Morimoto regf.msb = 31; 169b8c63786SKuninori Morimoto regf.id_size = id_size; 170b8c63786SKuninori Morimoto 171b8c63786SKuninori Morimoto regs = devm_regmap_field_alloc(dev, regmap, regf); 172b8c63786SKuninori Morimoto if (IS_ERR(regs)) 173b8c63786SKuninori Morimoto return PTR_ERR(regs); 174b8c63786SKuninori Morimoto 175b8c63786SKuninori Morimoto gen->regs[conf[i].idx] = regs; 176c1e6cc5eSKuninori Morimoto } 177c1e6cc5eSKuninori Morimoto 178c1e6cc5eSKuninori Morimoto return 0; 179c1e6cc5eSKuninori Morimoto } 1803337744aSKuninori Morimoto 181994a9df1SKuninori Morimoto /* 182ad32d0c7SKuninori Morimoto * DMA read/write register offset 183ad32d0c7SKuninori Morimoto * 184ad32d0c7SKuninori Morimoto * RSND_xxx_I_N for Audio DMAC input 185ad32d0c7SKuninori Morimoto * RSND_xxx_O_N for Audio DMAC output 186ad32d0c7SKuninori Morimoto * RSND_xxx_I_P for Audio DMAC peri peri input 187ad32d0c7SKuninori Morimoto * RSND_xxx_O_P for Audio DMAC peri peri output 188ad32d0c7SKuninori Morimoto * 189ad32d0c7SKuninori Morimoto * ex) R-Car H2 case 190ad32d0c7SKuninori Morimoto * mod / DMAC in / DMAC out / DMAC PP in / DMAC pp out 191d9288d0bSKuninori Morimoto * SSI : 0xec541000 / 0xec241008 / 0xec24100c 192d9288d0bSKuninori Morimoto * SSIU: 0xec541000 / 0xec100000 / 0xec100000 / 0xec400000 / 0xec400000 193ad32d0c7SKuninori Morimoto * SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000 19437523034SKuninori Morimoto * CMD : 0xec500000 / / 0xec008000 0xec308000 195ad32d0c7SKuninori Morimoto */ 196ad32d0c7SKuninori Morimoto #define RDMA_SSI_I_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0x8) 197ad32d0c7SKuninori Morimoto #define RDMA_SSI_O_N(addr, i) (addr ##_reg - 0x00300000 + (0x40 * i) + 0xc) 198ad32d0c7SKuninori Morimoto 199d9288d0bSKuninori Morimoto #define RDMA_SSIU_I_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) 200d9288d0bSKuninori Morimoto #define RDMA_SSIU_O_N(addr, i) (addr ##_reg - 0x00441000 + (0x1000 * i)) 201d9288d0bSKuninori Morimoto 202d9288d0bSKuninori Morimoto #define RDMA_SSIU_I_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) 203d9288d0bSKuninori Morimoto #define RDMA_SSIU_O_P(addr, i) (addr ##_reg - 0x00141000 + (0x1000 * i)) 204ad32d0c7SKuninori Morimoto 205ad32d0c7SKuninori Morimoto #define RDMA_SRC_I_N(addr, i) (addr ##_reg - 0x00500000 + (0x400 * i)) 206ad32d0c7SKuninori Morimoto #define RDMA_SRC_O_N(addr, i) (addr ##_reg - 0x004fc000 + (0x400 * i)) 207ad32d0c7SKuninori Morimoto 208ad32d0c7SKuninori Morimoto #define RDMA_SRC_I_P(addr, i) (addr ##_reg - 0x00200000 + (0x400 * i)) 209ad32d0c7SKuninori Morimoto #define RDMA_SRC_O_P(addr, i) (addr ##_reg - 0x001fc000 + (0x400 * i)) 210ad32d0c7SKuninori Morimoto 211ad32d0c7SKuninori Morimoto #define RDMA_CMD_O_N(addr, i) (addr ##_reg - 0x004f8000 + (0x400 * i)) 212ad32d0c7SKuninori Morimoto #define RDMA_CMD_O_P(addr, i) (addr ##_reg - 0x001f8000 + (0x400 * i)) 213ad32d0c7SKuninori Morimoto 21437523034SKuninori Morimoto static dma_addr_t 21537523034SKuninori Morimoto rsnd_gen2_dma_addr(struct rsnd_priv *priv, 21637523034SKuninori Morimoto struct rsnd_mod *mod, 21737523034SKuninori Morimoto int is_play, int is_from) 218ad32d0c7SKuninori Morimoto { 219ad32d0c7SKuninori Morimoto struct platform_device *pdev = rsnd_priv_to_pdev(priv); 220ad32d0c7SKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 221ad32d0c7SKuninori Morimoto struct rsnd_dai_stream *io = rsnd_mod_to_io(mod); 222ad32d0c7SKuninori Morimoto dma_addr_t ssi_reg = platform_get_resource(pdev, 223ad32d0c7SKuninori Morimoto IORESOURCE_MEM, RSND_GEN2_SSI)->start; 224ad32d0c7SKuninori Morimoto dma_addr_t src_reg = platform_get_resource(pdev, 225ad32d0c7SKuninori Morimoto IORESOURCE_MEM, RSND_GEN2_SCU)->start; 226ad32d0c7SKuninori Morimoto int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod); 227ad32d0c7SKuninori Morimoto int use_src = !!rsnd_io_to_mod_src(io); 228ad32d0c7SKuninori Morimoto int use_dvc = !!rsnd_io_to_mod_dvc(io); 229ad32d0c7SKuninori Morimoto int id = rsnd_mod_id(mod); 230ad32d0c7SKuninori Morimoto struct dma_addr { 23137523034SKuninori Morimoto dma_addr_t out_addr; 23237523034SKuninori Morimoto dma_addr_t in_addr; 233d9288d0bSKuninori Morimoto } dma_addrs[3][2][3] = { 234d9288d0bSKuninori Morimoto /* SRC */ 235d9288d0bSKuninori Morimoto {{{ 0, 0 }, 236ad32d0c7SKuninori Morimoto /* Capture */ 23737523034SKuninori Morimoto { RDMA_SRC_O_N(src, id), RDMA_SRC_I_P(src, id) }, 23837523034SKuninori Morimoto { RDMA_CMD_O_N(src, id), RDMA_SRC_I_P(src, id) } }, 239ad32d0c7SKuninori Morimoto /* Playback */ 240ad32d0c7SKuninori Morimoto {{ 0, 0, }, 24137523034SKuninori Morimoto { RDMA_SRC_O_P(src, id), RDMA_SRC_I_N(src, id) }, 24237523034SKuninori Morimoto { RDMA_CMD_O_P(src, id), RDMA_SRC_I_N(src, id) } } 243d9288d0bSKuninori Morimoto }, 244d9288d0bSKuninori Morimoto /* SSI */ 245ad32d0c7SKuninori Morimoto /* Capture */ 246d9288d0bSKuninori Morimoto {{{ RDMA_SSI_O_N(ssi, id), 0 }, 24737523034SKuninori Morimoto { RDMA_SSIU_O_P(ssi, id), 0 }, 24837523034SKuninori Morimoto { RDMA_SSIU_O_P(ssi, id), 0 } }, 249ad32d0c7SKuninori Morimoto /* Playback */ 250ad32d0c7SKuninori Morimoto {{ 0, RDMA_SSI_I_N(ssi, id) }, 25137523034SKuninori Morimoto { 0, RDMA_SSIU_I_P(ssi, id) }, 25237523034SKuninori Morimoto { 0, RDMA_SSIU_I_P(ssi, id) } } 253d9288d0bSKuninori Morimoto }, 254d9288d0bSKuninori Morimoto /* SSIU */ 255d9288d0bSKuninori Morimoto /* Capture */ 256d9288d0bSKuninori Morimoto {{{ RDMA_SSIU_O_N(ssi, id), 0 }, 25737523034SKuninori Morimoto { RDMA_SSIU_O_P(ssi, id), 0 }, 25837523034SKuninori Morimoto { RDMA_SSIU_O_P(ssi, id), 0 } }, 259d9288d0bSKuninori Morimoto /* Playback */ 260d9288d0bSKuninori Morimoto {{ 0, RDMA_SSIU_I_N(ssi, id) }, 26137523034SKuninori Morimoto { 0, RDMA_SSIU_I_P(ssi, id) }, 26237523034SKuninori Morimoto { 0, RDMA_SSIU_I_P(ssi, id) } } }, 263ad32d0c7SKuninori Morimoto }; 264ad32d0c7SKuninori Morimoto 265ad32d0c7SKuninori Morimoto /* it shouldn't happen */ 266c8e6e960SLars-Peter Clausen if (use_dvc && !use_src) 267ad32d0c7SKuninori Morimoto dev_err(dev, "DVC is selected without SRC\n"); 268ad32d0c7SKuninori Morimoto 269d9288d0bSKuninori Morimoto /* use SSIU or SSI ? */ 270d9288d0bSKuninori Morimoto if (is_ssi && (0 == strcmp(rsnd_mod_dma_name(mod), "ssiu"))) 271d9288d0bSKuninori Morimoto is_ssi++; 272d9288d0bSKuninori Morimoto 27337523034SKuninori Morimoto return (is_from) ? 27437523034SKuninori Morimoto dma_addrs[is_ssi][is_play][use_src + use_dvc].out_addr : 27537523034SKuninori Morimoto dma_addrs[is_ssi][is_play][use_src + use_dvc].in_addr; 276ad32d0c7SKuninori Morimoto } 277ad32d0c7SKuninori Morimoto 27837523034SKuninori Morimoto dma_addr_t rsnd_gen_dma_addr(struct rsnd_priv *priv, 27937523034SKuninori Morimoto struct rsnd_mod *mod, 28037523034SKuninori Morimoto int is_play, int is_from) 28164eae986SKuninori Morimoto { 28264eae986SKuninori Morimoto /* 28364eae986SKuninori Morimoto * gen1 uses default DMA addr 28464eae986SKuninori Morimoto */ 28564eae986SKuninori Morimoto if (rsnd_is_gen1(priv)) 28637523034SKuninori Morimoto return 0; 28764eae986SKuninori Morimoto 28837523034SKuninori Morimoto if (!mod) 28937523034SKuninori Morimoto return 0; 29037523034SKuninori Morimoto 29137523034SKuninori Morimoto return rsnd_gen2_dma_addr(priv, mod, is_play, is_from); 29264eae986SKuninori Morimoto } 29364eae986SKuninori Morimoto 294ad32d0c7SKuninori Morimoto /* 295994a9df1SKuninori Morimoto * Gen2 296994a9df1SKuninori Morimoto */ 297507d466cSKuninori Morimoto static int rsnd_gen2_probe(struct platform_device *pdev, 298507d466cSKuninori Morimoto struct rsnd_priv *priv) 299507d466cSKuninori Morimoto { 300507d466cSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 301b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssiu[] = { 302b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE0, 0x800), 303b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE1, 0x804), 304b8c63786SKuninori Morimoto /* FIXME: it needs SSI_MODE2/3 in the future */ 305b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSI_BUSIF_MODE, 0x0, 0x80), 306b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSI_BUSIF_ADINR, 0x4, 0x80), 3071cc71959SKuninori Morimoto RSND_GEN_M_REG(BUSIF_DALIGN, 0x8, 0x80), 308b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSI_CTRL, 0x10, 0x80), 309b8c63786SKuninori Morimoto RSND_GEN_M_REG(INT_ENABLE, 0x18, 0x80), 310b8c63786SKuninori Morimoto }; 311b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_scu[] = { 312b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x0, 0x20), 313b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0xc, 0x20), 314b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_CTRL, 0x10, 0x20), 315cfcefe01SKuninori Morimoto RSND_GEN_M_REG(SRC_INT_ENABLE0, 0x18, 0x20), 316b8c63786SKuninori Morimoto RSND_GEN_M_REG(CMD_ROUTE_SLCT, 0x18c, 0x20), 317b8c63786SKuninori Morimoto RSND_GEN_M_REG(CMD_CTRL, 0x190, 0x20), 318cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_STATUS0, 0x1c8), 319cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_INT_EN0, 0x1cc), 320cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_STATUS1, 0x1d0), 321cfcefe01SKuninori Morimoto RSND_GEN_S_REG(SCU_SYS_INT_EN1, 0x1c4), 322b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), 323b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), 324b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), 325b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), 326b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), 327b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), 328b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BSDSR, 0x22c, 0x40), 329b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BSISR, 0x238, 0x40), 330b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_SWRSR, 0xe00, 0x100), 331b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUIR, 0xe04, 0x100), 332b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_ADINR, 0xe08, 0x100), 333b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUCR, 0xe10, 0x100), 334b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_ZCMCR, 0xe14, 0x100), 3353539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRCTR, 0xe18, 0x100), 3363539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRPDR, 0xe1c, 0x100), 3373539cacfSKuninori Morimoto RSND_GEN_M_REG(DVC_VRDBR, 0xe20, 0x100), 338b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_VOL0R, 0xe28, 0x100), 339b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_VOL1R, 0xe2c, 0x100), 340b8c63786SKuninori Morimoto RSND_GEN_M_REG(DVC_DVUER, 0xe48, 0x100), 341b8c63786SKuninori Morimoto }; 342b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_adg[] = { 343b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRA, 0x00), 344b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRB, 0x04), 345b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSICKR, 0x08), 346b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 347b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 348b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL2, 0x14), 349b8c63786SKuninori Morimoto RSND_GEN_S_REG(DIV_EN, 0x30), 350b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL0, 0x34), 351b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL1, 0x38), 352b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL2, 0x3c), 353b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL3, 0x40), 354b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCIN_TIMSEL4, 0x44), 355b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL0, 0x48), 356b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL1, 0x4c), 357b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL2, 0x50), 358b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL3, 0x54), 359b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRCOUT_TIMSEL4, 0x58), 360b8c63786SKuninori Morimoto RSND_GEN_S_REG(CMDOUT_TIMSEL, 0x5c), 361b8c63786SKuninori Morimoto }; 362b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssi[] = { 363b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSICR, 0x00, 0x40), 364b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSISR, 0x04, 0x40), 365b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 366b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 367b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 368b8c63786SKuninori Morimoto }; 369b8c63786SKuninori Morimoto int ret_ssiu; 370b8c63786SKuninori Morimoto int ret_scu; 371b8c63786SKuninori Morimoto int ret_adg; 372b8c63786SKuninori Morimoto int ret_ssi; 373507d466cSKuninori Morimoto 3747277911cSKuninori Morimoto ret_ssiu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSIU, "ssiu", conf_ssiu); 3757277911cSKuninori Morimoto ret_scu = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SCU, "scu", conf_scu); 3767277911cSKuninori Morimoto ret_adg = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_ADG, "adg", conf_adg); 3777277911cSKuninori Morimoto ret_ssi = rsnd_gen_regmap_init(priv, 10, RSND_GEN2_SSI, "ssi", conf_ssi); 378b8c63786SKuninori Morimoto if (ret_ssiu < 0 || 379b8c63786SKuninori Morimoto ret_scu < 0 || 380b8c63786SKuninori Morimoto ret_adg < 0 || 381b8c63786SKuninori Morimoto ret_ssi < 0) 382b8c63786SKuninori Morimoto return ret_ssiu | ret_scu | ret_adg | ret_ssi; 383507d466cSKuninori Morimoto 384b8c63786SKuninori Morimoto dev_dbg(dev, "Gen2 is probed\n"); 385507d466cSKuninori Morimoto 386507d466cSKuninori Morimoto return 0; 387507d466cSKuninori Morimoto } 388507d466cSKuninori Morimoto 389994a9df1SKuninori Morimoto /* 390994a9df1SKuninori Morimoto * Gen1 391994a9df1SKuninori Morimoto */ 392994a9df1SKuninori Morimoto 3933337744aSKuninori Morimoto static int rsnd_gen1_probe(struct platform_device *pdev, 3943337744aSKuninori Morimoto struct rsnd_priv *priv) 3953337744aSKuninori Morimoto { 39607539c1dSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 397b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_sru[] = { 398b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_ROUTE_SEL, 0x00), 399b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL0, 0x08), 400b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL1, 0x0c), 401b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_TMG_SEL2, 0x10), 402b8c63786SKuninori Morimoto RSND_GEN_S_REG(SRC_ROUTE_CTRL, 0xc0), 403b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE0, 0xD0), 404b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSI_MODE1, 0xD4), 405b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_BUSIF_MODE, 0x20, 0x4), 406b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ROUTE_MODE0, 0x50, 0x8), 407b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SWRSR, 0x200, 0x40), 408b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCIR, 0x204, 0x40), 409b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_ADINR, 0x214, 0x40), 410b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSCR, 0x21c, 0x40), 411b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_IFSVR, 0x220, 0x40), 412b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_SRCCR, 0x224, 0x40), 413b8c63786SKuninori Morimoto RSND_GEN_M_REG(SRC_MNFSR, 0x228, 0x40), 414cfcefe01SKuninori Morimoto /* 415cfcefe01SKuninori Morimoto * ADD US 416cfcefe01SKuninori Morimoto * 417cfcefe01SKuninori Morimoto * SRC_STATUS 418cfcefe01SKuninori Morimoto * SRC_INT_EN 419cfcefe01SKuninori Morimoto * SCU_SYS_STATUS0 420cfcefe01SKuninori Morimoto * SCU_SYS_STATUS1 421cfcefe01SKuninori Morimoto * SCU_SYS_INT_EN0 422cfcefe01SKuninori Morimoto * SCU_SYS_INT_EN1 423cfcefe01SKuninori Morimoto */ 424b8c63786SKuninori Morimoto }; 425b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_adg[] = { 426b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRA, 0x00), 427b8c63786SKuninori Morimoto RSND_GEN_S_REG(BRRB, 0x04), 428b8c63786SKuninori Morimoto RSND_GEN_S_REG(SSICKR, 0x08), 429b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL0, 0x0c), 430b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL1, 0x10), 431b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL3, 0x18), 432b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL4, 0x1c), 433b8c63786SKuninori Morimoto RSND_GEN_S_REG(AUDIO_CLK_SEL5, 0x20), 434b8c63786SKuninori Morimoto }; 435b8c63786SKuninori Morimoto struct rsnd_regmap_field_conf conf_ssi[] = { 436b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSICR, 0x00, 0x40), 437b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSISR, 0x04, 0x40), 438b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSITDR, 0x08, 0x40), 439b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIRDR, 0x0c, 0x40), 440b8c63786SKuninori Morimoto RSND_GEN_M_REG(SSIWSR, 0x20, 0x40), 441b8c63786SKuninori Morimoto }; 442b8c63786SKuninori Morimoto int ret_sru; 443b8c63786SKuninori Morimoto int ret_adg; 444b8c63786SKuninori Morimoto int ret_ssi; 44507539c1dSKuninori Morimoto 4467277911cSKuninori Morimoto ret_sru = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SRU, "sru", conf_sru); 4477277911cSKuninori Morimoto ret_adg = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_ADG, "adg", conf_adg); 4487277911cSKuninori Morimoto ret_ssi = rsnd_gen_regmap_init(priv, 9, RSND_GEN1_SSI, "ssi", conf_ssi); 449b8c63786SKuninori Morimoto if (ret_sru < 0 || 450b8c63786SKuninori Morimoto ret_adg < 0 || 451b8c63786SKuninori Morimoto ret_ssi < 0) 452b8c63786SKuninori Morimoto return ret_sru | ret_adg | ret_ssi; 45307539c1dSKuninori Morimoto 454b8c63786SKuninori Morimoto dev_dbg(dev, "Gen1 is probed\n"); 45507539c1dSKuninori Morimoto 4563337744aSKuninori Morimoto return 0; 4573337744aSKuninori Morimoto } 4583337744aSKuninori Morimoto 4593337744aSKuninori Morimoto /* 4603337744aSKuninori Morimoto * Gen 4613337744aSKuninori Morimoto */ 46290e8e50fSKuninori Morimoto static void rsnd_of_parse_gen(struct platform_device *pdev, 46390e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 46490e8e50fSKuninori Morimoto struct rsnd_priv *priv) 46590e8e50fSKuninori Morimoto { 46690e8e50fSKuninori Morimoto struct rcar_snd_info *info = priv->info; 46790e8e50fSKuninori Morimoto 46890e8e50fSKuninori Morimoto if (!of_data) 46990e8e50fSKuninori Morimoto return; 47090e8e50fSKuninori Morimoto 47190e8e50fSKuninori Morimoto info->flags = of_data->flags; 47290e8e50fSKuninori Morimoto } 47390e8e50fSKuninori Morimoto 4743337744aSKuninori Morimoto int rsnd_gen_probe(struct platform_device *pdev, 47590e8e50fSKuninori Morimoto const struct rsnd_of_data *of_data, 4763337744aSKuninori Morimoto struct rsnd_priv *priv) 4773337744aSKuninori Morimoto { 4783337744aSKuninori Morimoto struct device *dev = rsnd_priv_to_dev(priv); 4793337744aSKuninori Morimoto struct rsnd_gen *gen; 480531eaf49SKuninori Morimoto int ret; 4813337744aSKuninori Morimoto 48290e8e50fSKuninori Morimoto rsnd_of_parse_gen(pdev, of_data, priv); 48390e8e50fSKuninori Morimoto 4843337744aSKuninori Morimoto gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL); 4853337744aSKuninori Morimoto if (!gen) { 4863337744aSKuninori Morimoto dev_err(dev, "GEN allocate failed\n"); 4873337744aSKuninori Morimoto return -ENOMEM; 4883337744aSKuninori Morimoto } 4893337744aSKuninori Morimoto 490531eaf49SKuninori Morimoto priv->gen = gen; 491072188b6SKuninori Morimoto 492507d466cSKuninori Morimoto ret = -ENODEV; 493507d466cSKuninori Morimoto if (rsnd_is_gen1(priv)) 4945da39cf3SKuninori Morimoto ret = rsnd_gen1_probe(pdev, priv); 495507d466cSKuninori Morimoto else if (rsnd_is_gen2(priv)) 4965da39cf3SKuninori Morimoto ret = rsnd_gen2_probe(pdev, priv); 497507d466cSKuninori Morimoto 498507d466cSKuninori Morimoto if (ret < 0) 499072188b6SKuninori Morimoto dev_err(dev, "unknown generation R-Car sound device\n"); 500072188b6SKuninori Morimoto 501531eaf49SKuninori Morimoto return ret; 5023337744aSKuninori Morimoto } 503