xref: /openbmc/linux/sound/soc/sh/rcar/gen.c (revision ad32d0c7)
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  */
113337744aSKuninori Morimoto #include "rsnd.h"
123337744aSKuninori Morimoto 
133337744aSKuninori Morimoto struct rsnd_gen {
143337744aSKuninori Morimoto 	void __iomem *base[RSND_BASE_MAX];
153337744aSKuninori Morimoto 
163337744aSKuninori Morimoto 	struct rsnd_gen_ops *ops;
1755e5b6fdSKuninori Morimoto 
1855e5b6fdSKuninori Morimoto 	struct regmap *regmap;
1955e5b6fdSKuninori Morimoto 	struct regmap_field *regs[RSND_REG_MAX];
203337744aSKuninori Morimoto };
213337744aSKuninori Morimoto 
223337744aSKuninori Morimoto #define rsnd_priv_to_gen(p)	((struct rsnd_gen *)(p)->gen)
233337744aSKuninori Morimoto 
2455e5b6fdSKuninori Morimoto #define RSND_REG_SET(gen, id, reg_id, offset, _id_offset, _id_size)	\
2555e5b6fdSKuninori Morimoto 	[id] = {							\
2655e5b6fdSKuninori Morimoto 		.reg = (unsigned int)gen->base[reg_id] + offset,	\
2755e5b6fdSKuninori Morimoto 		.lsb = 0,						\
2855e5b6fdSKuninori Morimoto 		.msb = 31,						\
2955e5b6fdSKuninori Morimoto 		.id_size = _id_size,					\
3055e5b6fdSKuninori Morimoto 		.id_offset = _id_offset,				\
3155e5b6fdSKuninori Morimoto 	}
3255e5b6fdSKuninori Morimoto 
3355e5b6fdSKuninori Morimoto /*
3455e5b6fdSKuninori Morimoto  *		basic function
3555e5b6fdSKuninori Morimoto  */
3655e5b6fdSKuninori Morimoto static int rsnd_regmap_write32(void *context, const void *_data, size_t count)
3755e5b6fdSKuninori Morimoto {
3855e5b6fdSKuninori Morimoto 	struct rsnd_priv *priv = context;
3955e5b6fdSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
4055e5b6fdSKuninori Morimoto 	u32 *data = (u32 *)_data;
4155e5b6fdSKuninori Morimoto 	u32 val = data[1];
4255e5b6fdSKuninori Morimoto 	void __iomem *reg = (void *)data[0];
4355e5b6fdSKuninori Morimoto 
4455e5b6fdSKuninori Morimoto 	iowrite32(val, reg);
4555e5b6fdSKuninori Morimoto 
4655e5b6fdSKuninori Morimoto 	dev_dbg(dev, "w %p : %08x\n", reg, val);
4755e5b6fdSKuninori Morimoto 
4855e5b6fdSKuninori Morimoto 	return 0;
4955e5b6fdSKuninori Morimoto }
5055e5b6fdSKuninori Morimoto 
5155e5b6fdSKuninori Morimoto static int rsnd_regmap_read32(void *context,
5255e5b6fdSKuninori Morimoto 			      const void *_data, size_t reg_size,
5355e5b6fdSKuninori Morimoto 			      void *_val, size_t val_size)
5455e5b6fdSKuninori Morimoto {
5555e5b6fdSKuninori Morimoto 	struct rsnd_priv *priv = context;
5655e5b6fdSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
5755e5b6fdSKuninori Morimoto 	u32 *data = (u32 *)_data;
5855e5b6fdSKuninori Morimoto 	u32 *val = (u32 *)_val;
5955e5b6fdSKuninori Morimoto 	void __iomem *reg = (void *)data[0];
6055e5b6fdSKuninori Morimoto 
6155e5b6fdSKuninori Morimoto 	*val = ioread32(reg);
6255e5b6fdSKuninori Morimoto 
6355e5b6fdSKuninori Morimoto 	dev_dbg(dev, "r %p : %08x\n", reg, *val);
6455e5b6fdSKuninori Morimoto 
6555e5b6fdSKuninori Morimoto 	return 0;
6655e5b6fdSKuninori Morimoto }
6755e5b6fdSKuninori Morimoto 
6855e5b6fdSKuninori Morimoto static struct regmap_bus rsnd_regmap_bus = {
6955e5b6fdSKuninori Morimoto 	.write				= rsnd_regmap_write32,
7055e5b6fdSKuninori Morimoto 	.read				= rsnd_regmap_read32,
7155e5b6fdSKuninori Morimoto 	.reg_format_endian_default	= REGMAP_ENDIAN_NATIVE,
7255e5b6fdSKuninori Morimoto 	.val_format_endian_default	= REGMAP_ENDIAN_NATIVE,
7355e5b6fdSKuninori Morimoto };
7455e5b6fdSKuninori Morimoto 
7542ee5d22SKuninori Morimoto static int rsnd_is_accessible_reg(struct rsnd_priv *priv,
7642ee5d22SKuninori Morimoto 				  struct rsnd_gen *gen, enum rsnd_reg reg)
7742ee5d22SKuninori Morimoto {
7842ee5d22SKuninori Morimoto 	if (!gen->regs[reg]) {
7942ee5d22SKuninori Morimoto 		struct device *dev = rsnd_priv_to_dev(priv);
8042ee5d22SKuninori Morimoto 
8142ee5d22SKuninori Morimoto 		dev_err(dev, "unsupported register access %x\n", reg);
8242ee5d22SKuninori Morimoto 		return 0;
8342ee5d22SKuninori Morimoto 	}
8442ee5d22SKuninori Morimoto 
8542ee5d22SKuninori Morimoto 	return 1;
8642ee5d22SKuninori Morimoto }
8742ee5d22SKuninori Morimoto 
8855e5b6fdSKuninori Morimoto u32 rsnd_read(struct rsnd_priv *priv,
8955e5b6fdSKuninori Morimoto 	      struct rsnd_mod *mod, enum rsnd_reg reg)
9055e5b6fdSKuninori Morimoto {
9155e5b6fdSKuninori Morimoto 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
9255e5b6fdSKuninori Morimoto 	u32 val;
9355e5b6fdSKuninori Morimoto 
9442ee5d22SKuninori Morimoto 	if (!rsnd_is_accessible_reg(priv, gen, reg))
9542ee5d22SKuninori Morimoto 		return 0;
9642ee5d22SKuninori Morimoto 
9755e5b6fdSKuninori Morimoto 	regmap_fields_read(gen->regs[reg], rsnd_mod_id(mod), &val);
9855e5b6fdSKuninori Morimoto 
9955e5b6fdSKuninori Morimoto 	return val;
10055e5b6fdSKuninori Morimoto }
10155e5b6fdSKuninori Morimoto 
10255e5b6fdSKuninori Morimoto void rsnd_write(struct rsnd_priv *priv,
10355e5b6fdSKuninori Morimoto 		struct rsnd_mod *mod,
10455e5b6fdSKuninori Morimoto 		enum rsnd_reg reg, u32 data)
10555e5b6fdSKuninori Morimoto {
10655e5b6fdSKuninori Morimoto 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
10755e5b6fdSKuninori Morimoto 
10842ee5d22SKuninori Morimoto 	if (!rsnd_is_accessible_reg(priv, gen, reg))
10942ee5d22SKuninori Morimoto 		return;
11042ee5d22SKuninori Morimoto 
11155e5b6fdSKuninori Morimoto 	regmap_fields_write(gen->regs[reg], rsnd_mod_id(mod), data);
11255e5b6fdSKuninori Morimoto }
11355e5b6fdSKuninori Morimoto 
11455e5b6fdSKuninori Morimoto void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod,
11555e5b6fdSKuninori Morimoto 	       enum rsnd_reg reg, u32 mask, u32 data)
11655e5b6fdSKuninori Morimoto {
11755e5b6fdSKuninori Morimoto 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
11855e5b6fdSKuninori Morimoto 
11942ee5d22SKuninori Morimoto 	if (!rsnd_is_accessible_reg(priv, gen, reg))
12042ee5d22SKuninori Morimoto 		return;
12142ee5d22SKuninori Morimoto 
12255e5b6fdSKuninori Morimoto 	regmap_fields_update_bits(gen->regs[reg], rsnd_mod_id(mod),
12355e5b6fdSKuninori Morimoto 				  mask, data);
12455e5b6fdSKuninori Morimoto }
12555e5b6fdSKuninori Morimoto 
126c1e6cc5eSKuninori Morimoto static int rsnd_gen_regmap_init(struct rsnd_priv *priv,
127c1e6cc5eSKuninori Morimoto 				struct rsnd_gen  *gen,
128c1e6cc5eSKuninori Morimoto 				struct reg_field *regf)
129c1e6cc5eSKuninori Morimoto {
130c1e6cc5eSKuninori Morimoto 	int i;
131c1e6cc5eSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
132c1e6cc5eSKuninori Morimoto 	struct regmap_config regc;
133c1e6cc5eSKuninori Morimoto 
134c1e6cc5eSKuninori Morimoto 	memset(&regc, 0, sizeof(regc));
135c1e6cc5eSKuninori Morimoto 	regc.reg_bits = 32;
136c1e6cc5eSKuninori Morimoto 	regc.val_bits = 32;
137c1e6cc5eSKuninori Morimoto 
138c1e6cc5eSKuninori Morimoto 	gen->regmap = devm_regmap_init(dev, &rsnd_regmap_bus, priv, &regc);
139c1e6cc5eSKuninori Morimoto 	if (IS_ERR(gen->regmap)) {
140c1e6cc5eSKuninori Morimoto 		dev_err(dev, "regmap error %ld\n", PTR_ERR(gen->regmap));
141c1e6cc5eSKuninori Morimoto 		return PTR_ERR(gen->regmap);
142c1e6cc5eSKuninori Morimoto 	}
143c1e6cc5eSKuninori Morimoto 
144c1e6cc5eSKuninori Morimoto 	for (i = 0; i < RSND_REG_MAX; i++) {
14542ee5d22SKuninori Morimoto 		gen->regs[i] = NULL;
14642ee5d22SKuninori Morimoto 		if (!regf[i].reg)
14742ee5d22SKuninori Morimoto 			continue;
14842ee5d22SKuninori Morimoto 
149c1e6cc5eSKuninori Morimoto 		gen->regs[i] = devm_regmap_field_alloc(dev, gen->regmap, regf[i]);
150c1e6cc5eSKuninori Morimoto 		if (IS_ERR(gen->regs[i]))
151c1e6cc5eSKuninori Morimoto 			return PTR_ERR(gen->regs[i]);
152c1e6cc5eSKuninori Morimoto 
153c1e6cc5eSKuninori Morimoto 	}
154c1e6cc5eSKuninori Morimoto 
155c1e6cc5eSKuninori Morimoto 	return 0;
156c1e6cc5eSKuninori Morimoto }
1573337744aSKuninori Morimoto 
158994a9df1SKuninori Morimoto /*
159ad32d0c7SKuninori Morimoto  *	DMA read/write register offset
160ad32d0c7SKuninori Morimoto  *
161ad32d0c7SKuninori Morimoto  *	RSND_xxx_I_N	for Audio DMAC input
162ad32d0c7SKuninori Morimoto  *	RSND_xxx_O_N	for Audio DMAC output
163ad32d0c7SKuninori Morimoto  *	RSND_xxx_I_P	for Audio DMAC peri peri input
164ad32d0c7SKuninori Morimoto  *	RSND_xxx_O_P	for Audio DMAC peri peri output
165ad32d0c7SKuninori Morimoto  *
166ad32d0c7SKuninori Morimoto  *	ex) R-Car H2 case
167ad32d0c7SKuninori Morimoto  *	      mod        / DMAC in    / DMAC out   / DMAC PP in / DMAC pp out
168ad32d0c7SKuninori Morimoto  *	SSI : 0xec541000 / 0xec241008 / 0xec24100c / 0xec400000 / 0xec400000
169ad32d0c7SKuninori Morimoto  *	SCU : 0xec500000 / 0xec000000 / 0xec004000 / 0xec300000 / 0xec304000
170ad32d0c7SKuninori Morimoto  *	CMD : 0xec500000 / 0xec008000                             0xec308000
171ad32d0c7SKuninori Morimoto  */
172ad32d0c7SKuninori Morimoto #define RDMA_SSI_I_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0x8)
173ad32d0c7SKuninori Morimoto #define RDMA_SSI_O_N(addr, i)	(addr ##_reg - 0x00300000 + (0x40 * i) + 0xc)
174ad32d0c7SKuninori Morimoto 
175ad32d0c7SKuninori Morimoto #define RDMA_SSI_I_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
176ad32d0c7SKuninori Morimoto #define RDMA_SSI_O_P(addr, i)	(addr ##_reg - 0x00141000 + (0x1000 * i))
177ad32d0c7SKuninori Morimoto 
178ad32d0c7SKuninori Morimoto #define RDMA_SRC_I_N(addr, i)	(addr ##_reg - 0x00500000 + (0x400 * i))
179ad32d0c7SKuninori Morimoto #define RDMA_SRC_O_N(addr, i)	(addr ##_reg - 0x004fc000 + (0x400 * i))
180ad32d0c7SKuninori Morimoto 
181ad32d0c7SKuninori Morimoto #define RDMA_SRC_I_P(addr, i)	(addr ##_reg - 0x00200000 + (0x400 * i))
182ad32d0c7SKuninori Morimoto #define RDMA_SRC_O_P(addr, i)	(addr ##_reg - 0x001fc000 + (0x400 * i))
183ad32d0c7SKuninori Morimoto 
184ad32d0c7SKuninori Morimoto #define RDMA_CMD_O_N(addr, i)	(addr ##_reg - 0x004f8000 + (0x400 * i))
185ad32d0c7SKuninori Morimoto #define RDMA_CMD_O_P(addr, i)	(addr ##_reg - 0x001f8000 + (0x400 * i))
186ad32d0c7SKuninori Morimoto 
187ad32d0c7SKuninori Morimoto void rsnd_gen_dma_addr(struct rsnd_priv *priv,
188ad32d0c7SKuninori Morimoto 		       struct rsnd_dma *dma,
189ad32d0c7SKuninori Morimoto 		       struct dma_slave_config *cfg,
190ad32d0c7SKuninori Morimoto 		       int is_play, int slave_id)
191ad32d0c7SKuninori Morimoto {
192ad32d0c7SKuninori Morimoto 	struct platform_device *pdev = rsnd_priv_to_pdev(priv);
193ad32d0c7SKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
194ad32d0c7SKuninori Morimoto 	struct rsnd_mod *mod = rsnd_dma_to_mod(dma);
195ad32d0c7SKuninori Morimoto 	struct rsnd_dai_stream *io = rsnd_mod_to_io(mod);
196ad32d0c7SKuninori Morimoto 	dma_addr_t ssi_reg = platform_get_resource(pdev,
197ad32d0c7SKuninori Morimoto 				IORESOURCE_MEM, RSND_GEN2_SSI)->start;
198ad32d0c7SKuninori Morimoto 	dma_addr_t src_reg = platform_get_resource(pdev,
199ad32d0c7SKuninori Morimoto 				IORESOURCE_MEM, RSND_GEN2_SCU)->start;
200ad32d0c7SKuninori Morimoto 	int is_ssi = !!(rsnd_io_to_mod_ssi(io) == mod);
201ad32d0c7SKuninori Morimoto 	int use_src = !!rsnd_io_to_mod_src(io);
202ad32d0c7SKuninori Morimoto 	int use_dvc = !!rsnd_io_to_mod_dvc(io);
203ad32d0c7SKuninori Morimoto 	int id = rsnd_mod_id(mod);
204ad32d0c7SKuninori Morimoto 	struct dma_addr {
205ad32d0c7SKuninori Morimoto 		dma_addr_t src_addr;
206ad32d0c7SKuninori Morimoto 		dma_addr_t dst_addr;
207ad32d0c7SKuninori Morimoto 	} dma_addrs[2][2][3] = {
208ad32d0c7SKuninori Morimoto 		{ /* SRC */
209ad32d0c7SKuninori Morimoto 			/* Capture */
210ad32d0c7SKuninori Morimoto 			{{ 0,				0 },
211ad32d0c7SKuninori Morimoto 			 { RDMA_SRC_O_N(src, id),	0 },
212ad32d0c7SKuninori Morimoto 			 { RDMA_CMD_O_N(src, id),	0 }},
213ad32d0c7SKuninori Morimoto 			/* Playback */
214ad32d0c7SKuninori Morimoto 			{{ 0,				0, },
215ad32d0c7SKuninori Morimoto 			 { 0,				RDMA_SRC_I_N(src, id) },
216ad32d0c7SKuninori Morimoto 			 { 0,				RDMA_SRC_I_N(src, id) }}
217ad32d0c7SKuninori Morimoto 		}, { /* SSI */
218ad32d0c7SKuninori Morimoto 			/* Capture */
219ad32d0c7SKuninori Morimoto 			{{ RDMA_SSI_O_N(ssi, id),	0 },
220ad32d0c7SKuninori Morimoto 			 { RDMA_SSI_O_P(ssi, id),	RDMA_SRC_I_P(src, id) },
221ad32d0c7SKuninori Morimoto 			 { RDMA_SSI_O_P(ssi, id),	RDMA_SRC_I_P(src, id) }},
222ad32d0c7SKuninori Morimoto 			/* Playback */
223ad32d0c7SKuninori Morimoto 			{{ 0,				RDMA_SSI_I_N(ssi, id) },
224ad32d0c7SKuninori Morimoto 			 { RDMA_SRC_O_P(src, id),	RDMA_SSI_I_P(ssi, id) },
225ad32d0c7SKuninori Morimoto 			 { RDMA_CMD_O_P(src, id),	RDMA_SSI_I_P(ssi, id) }}
226ad32d0c7SKuninori Morimoto 		}
227ad32d0c7SKuninori Morimoto 	};
228ad32d0c7SKuninori Morimoto 
229ad32d0c7SKuninori Morimoto 	cfg->slave_id	= slave_id;
230ad32d0c7SKuninori Morimoto 	cfg->src_addr	= 0;
231ad32d0c7SKuninori Morimoto 	cfg->dst_addr	= 0;
232ad32d0c7SKuninori Morimoto 	cfg->direction	= is_play ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM;
233ad32d0c7SKuninori Morimoto 
234ad32d0c7SKuninori Morimoto 	/*
235ad32d0c7SKuninori Morimoto 	 * gen1 uses default DMA addr
236ad32d0c7SKuninori Morimoto 	 */
237ad32d0c7SKuninori Morimoto 	if (rsnd_is_gen1(priv))
238ad32d0c7SKuninori Morimoto 		return;
239ad32d0c7SKuninori Morimoto 
240ad32d0c7SKuninori Morimoto 	/* it shouldn't happen */
241ad32d0c7SKuninori Morimoto 	if (use_dvc & !use_src) {
242ad32d0c7SKuninori Morimoto 		dev_err(dev, "DVC is selected without SRC\n");
243ad32d0c7SKuninori Morimoto 		return;
244ad32d0c7SKuninori Morimoto 	}
245ad32d0c7SKuninori Morimoto 
246ad32d0c7SKuninori Morimoto 	cfg->src_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].src_addr;
247ad32d0c7SKuninori Morimoto 	cfg->dst_addr = dma_addrs[is_ssi][is_play][use_src + use_dvc].dst_addr;
248ad32d0c7SKuninori Morimoto 
249ad32d0c7SKuninori Morimoto 	dev_dbg(dev, "dma%d addr - src : %x / dst : %x\n",
250ad32d0c7SKuninori Morimoto 		id, cfg->src_addr, cfg->dst_addr);
251ad32d0c7SKuninori Morimoto }
252ad32d0c7SKuninori Morimoto 
253ad32d0c7SKuninori Morimoto /*
254994a9df1SKuninori Morimoto  *		Gen2
255994a9df1SKuninori Morimoto  */
256994a9df1SKuninori Morimoto 
257507d466cSKuninori Morimoto /* single address mapping */
258507d466cSKuninori Morimoto #define RSND_GEN2_S_REG(gen, reg, id, offset)				\
2591a1c75a7SKuninori Morimoto 	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, 0, 10)
260507d466cSKuninori Morimoto 
261507d466cSKuninori Morimoto /* multi address mapping */
262507d466cSKuninori Morimoto #define RSND_GEN2_M_REG(gen, reg, id, offset, _id_offset)		\
2631a1c75a7SKuninori Morimoto 	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN2_##reg, offset, _id_offset, 10)
264507d466cSKuninori Morimoto 
265507d466cSKuninori Morimoto static int rsnd_gen2_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
266507d466cSKuninori Morimoto {
267507d466cSKuninori Morimoto 	struct reg_field regf[RSND_REG_MAX] = {
268507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, SSIU,	SSI_MODE0,	0x800),
269507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, SSIU,	SSI_MODE1,	0x804),
270507d466cSKuninori Morimoto 		/* FIXME: it needs SSI_MODE2/3 in the future */
271629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSIU,	SSI_BUSIF_MODE,	0x0,	0x80),
272629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSIU,	SSI_BUSIF_ADINR,0x4,	0x80),
273629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSIU,	SSI_CTRL,	0x10,	0x80),
274507d466cSKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSIU,	INT_ENABLE,	0x18,	0x80),
275507d466cSKuninori Morimoto 
276629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_BUSIF_MODE,	0x0,	0x20),
277629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_ROUTE_MODE0,0xc,	0x20),
278629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_CTRL,	0x10,	0x20),
279bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	CMD_ROUTE_SLCT,	0x18c,	0x20),
280bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	CMD_CTRL,	0x190,	0x20),
281629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_SWRSR,	0x200,	0x40),
282629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_SRCIR,	0x204,	0x40),
283629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_ADINR,	0x214,	0x40),
284629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_IFSCR,	0x21c,	0x40),
285629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_IFSVR,	0x220,	0x40),
286629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_SRCCR,	0x224,	0x40),
287629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_BSDSR,	0x22c,	0x40),
288629509c5SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	SRC_BSISR,	0x238,	0x40),
289bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_SWRSR,	0xe00,	0x100),
290bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_DVUIR,	0xe04,	0x100),
291bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_ADINR,	0xe08,	0x100),
292bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_DVUCR,	0xe10,	0x100),
293bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_ZCMCR,	0xe14,	0x100),
294bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_VOL0R,	0xe28,	0x100),
295bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_VOL1R,	0xe2c,	0x100),
296bff58ea4SKuninori Morimoto 		RSND_GEN2_M_REG(gen, SCU,	DVC_DVUER,	0xe48,	0x100),
297629509c5SKuninori Morimoto 
298507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	BRRA,		0x00),
299507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	BRRB,		0x04),
300507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SSICKR,		0x08),
301507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	AUDIO_CLK_SEL0,	0x0c),
302507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	AUDIO_CLK_SEL1,	0x10),
303507d466cSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	AUDIO_CLK_SEL2,	0x14),
304ee2c828dSKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	DIV_EN,		0x30),
305629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCIN_TIMSEL0,	0x34),
306629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCIN_TIMSEL1,	0x38),
307629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCIN_TIMSEL2,	0x3c),
308629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCIN_TIMSEL3,	0x40),
309629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCIN_TIMSEL4,	0x44),
310629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCOUT_TIMSEL0,	0x48),
311629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCOUT_TIMSEL1,	0x4c),
312629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCOUT_TIMSEL2,	0x50),
313629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCOUT_TIMSEL3,	0x54),
314629509c5SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	SRCOUT_TIMSEL4,	0x58),
315bff58ea4SKuninori Morimoto 		RSND_GEN2_S_REG(gen, ADG,	CMDOUT_TIMSEL,	0x5c),
316507d466cSKuninori Morimoto 
317507d466cSKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSI,	SSICR,		0x00,	0x40),
318507d466cSKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSI,	SSISR,		0x04,	0x40),
319507d466cSKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSI,	SSITDR,		0x08,	0x40),
320507d466cSKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSI,	SSIRDR,		0x0c,	0x40),
321507d466cSKuninori Morimoto 		RSND_GEN2_M_REG(gen, SSI,	SSIWSR,		0x20,	0x40),
322507d466cSKuninori Morimoto 	};
323507d466cSKuninori Morimoto 
324507d466cSKuninori Morimoto 	return rsnd_gen_regmap_init(priv, gen, regf);
325507d466cSKuninori Morimoto }
326507d466cSKuninori Morimoto 
327507d466cSKuninori Morimoto static int rsnd_gen2_probe(struct platform_device *pdev,
328507d466cSKuninori Morimoto 			   struct rsnd_priv *priv)
329507d466cSKuninori Morimoto {
330507d466cSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
331507d466cSKuninori Morimoto 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
332507d466cSKuninori Morimoto 	struct resource *scu_res;
333507d466cSKuninori Morimoto 	struct resource *adg_res;
334507d466cSKuninori Morimoto 	struct resource *ssiu_res;
335507d466cSKuninori Morimoto 	struct resource *ssi_res;
336507d466cSKuninori Morimoto 	int ret;
337507d466cSKuninori Morimoto 
338507d466cSKuninori Morimoto 	/*
339507d466cSKuninori Morimoto 	 * map address
340507d466cSKuninori Morimoto 	 */
341507d466cSKuninori Morimoto 	scu_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SCU);
342507d466cSKuninori Morimoto 	adg_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_ADG);
343507d466cSKuninori Morimoto 	ssiu_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSIU);
344507d466cSKuninori Morimoto 	ssi_res  = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN2_SSI);
345507d466cSKuninori Morimoto 
346507d466cSKuninori Morimoto 	gen->base[RSND_GEN2_SCU]  = devm_ioremap_resource(dev, scu_res);
347507d466cSKuninori Morimoto 	gen->base[RSND_GEN2_ADG]  = devm_ioremap_resource(dev, adg_res);
348507d466cSKuninori Morimoto 	gen->base[RSND_GEN2_SSIU] = devm_ioremap_resource(dev, ssiu_res);
349507d466cSKuninori Morimoto 	gen->base[RSND_GEN2_SSI]  = devm_ioremap_resource(dev, ssi_res);
350507d466cSKuninori Morimoto 	if (IS_ERR(gen->base[RSND_GEN2_SCU])  ||
351507d466cSKuninori Morimoto 	    IS_ERR(gen->base[RSND_GEN2_ADG])  ||
352507d466cSKuninori Morimoto 	    IS_ERR(gen->base[RSND_GEN2_SSIU]) ||
353507d466cSKuninori Morimoto 	    IS_ERR(gen->base[RSND_GEN2_SSI]))
354507d466cSKuninori Morimoto 		return -ENODEV;
355507d466cSKuninori Morimoto 
356507d466cSKuninori Morimoto 	ret = rsnd_gen2_regmap_init(priv, gen);
357507d466cSKuninori Morimoto 	if (ret < 0)
358507d466cSKuninori Morimoto 		return ret;
359507d466cSKuninori Morimoto 
360507d466cSKuninori Morimoto 	dev_dbg(dev, "Gen2 device probed\n");
361e6b0d896SLaurent Pinchart 	dev_dbg(dev, "SCU  : %pap => %p\n", &scu_res->start,
362507d466cSKuninori Morimoto 		gen->base[RSND_GEN2_SCU]);
363e6b0d896SLaurent Pinchart 	dev_dbg(dev, "ADG  : %pap => %p\n", &adg_res->start,
364507d466cSKuninori Morimoto 		gen->base[RSND_GEN2_ADG]);
365e6b0d896SLaurent Pinchart 	dev_dbg(dev, "SSIU : %pap => %p\n", &ssiu_res->start,
366507d466cSKuninori Morimoto 		gen->base[RSND_GEN2_SSIU]);
367e6b0d896SLaurent Pinchart 	dev_dbg(dev, "SSI  : %pap => %p\n", &ssi_res->start,
368507d466cSKuninori Morimoto 		gen->base[RSND_GEN2_SSI]);
369507d466cSKuninori Morimoto 
370507d466cSKuninori Morimoto 	return 0;
371507d466cSKuninori Morimoto }
372507d466cSKuninori Morimoto 
373994a9df1SKuninori Morimoto /*
374994a9df1SKuninori Morimoto  *		Gen1
375994a9df1SKuninori Morimoto  */
376994a9df1SKuninori Morimoto 
37755e5b6fdSKuninori Morimoto /* single address mapping */
37855e5b6fdSKuninori Morimoto #define RSND_GEN1_S_REG(gen, reg, id, offset)	\
37955e5b6fdSKuninori Morimoto 	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, 0, 9)
38007539c1dSKuninori Morimoto 
38155e5b6fdSKuninori Morimoto /* multi address mapping */
38255e5b6fdSKuninori Morimoto #define RSND_GEN1_M_REG(gen, reg, id, offset, _id_offset)	\
38355e5b6fdSKuninori Morimoto 	RSND_REG_SET(gen, RSND_REG_##id, RSND_GEN1_##reg, offset, _id_offset, 9)
38455e5b6fdSKuninori Morimoto 
38555e5b6fdSKuninori Morimoto static int rsnd_gen1_regmap_init(struct rsnd_priv *priv, struct rsnd_gen *gen)
38607539c1dSKuninori Morimoto {
38755e5b6fdSKuninori Morimoto 	struct reg_field regf[RSND_REG_MAX] = {
38855e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SRC_ROUTE_SEL,	0x00),
38955e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL0,	0x08),
39055e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL1,	0x0c),
39155e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SRC_TMG_SEL2,	0x10),
392690ef81eSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SRC_ROUTE_CTRL,	0xc0),
39355e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SSI_MODE0,	0xD0),
39455e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, SRU,	SSI_MODE1,	0xD4),
3950290d2a4SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_BUSIF_MODE,	0x20,	0x4),
396ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_ROUTE_MODE0,0x50,	0x8),
397ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_SWRSR,	0x200,	0x40),
398ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_SRCIR,	0x204,	0x40),
399690ef81eSKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_ADINR,	0x214,	0x40),
400ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_IFSCR,	0x21c,	0x40),
401ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_IFSVR,	0x220,	0x40),
402ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_SRCCR,	0x224,	0x40),
403ef749400SKuninori Morimoto 		RSND_GEN1_M_REG(gen, SRU,	SRC_MNFSR,	0x228,	0x40),
404dfc9403bSKuninori Morimoto 
40555e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	BRRA,		0x00),
40655e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	BRRB,		0x04),
40755e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	SSICKR,		0x08),
40855e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL0,	0x0c),
40955e5b6fdSKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL1,	0x10),
410ef749400SKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL3,	0x18),
411ef749400SKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL4,	0x1c),
412ef749400SKuninori Morimoto 		RSND_GEN1_S_REG(gen, ADG,	AUDIO_CLK_SEL5,	0x20),
413ae5c3223SKuninori Morimoto 
41455e5b6fdSKuninori Morimoto 		RSND_GEN1_M_REG(gen, SSI,	SSICR,		0x00,	0x40),
41555e5b6fdSKuninori Morimoto 		RSND_GEN1_M_REG(gen, SSI,	SSISR,		0x04,	0x40),
41655e5b6fdSKuninori Morimoto 		RSND_GEN1_M_REG(gen, SSI,	SSITDR,		0x08,	0x40),
41755e5b6fdSKuninori Morimoto 		RSND_GEN1_M_REG(gen, SSI,	SSIRDR,		0x0c,	0x40),
41855e5b6fdSKuninori Morimoto 		RSND_GEN1_M_REG(gen, SSI,	SSIWSR,		0x20,	0x40),
41955e5b6fdSKuninori Morimoto 	};
42055e5b6fdSKuninori Morimoto 
421c1e6cc5eSKuninori Morimoto 	return rsnd_gen_regmap_init(priv, gen, regf);
42207539c1dSKuninori Morimoto }
42307539c1dSKuninori Morimoto 
4243337744aSKuninori Morimoto static int rsnd_gen1_probe(struct platform_device *pdev,
4253337744aSKuninori Morimoto 			   struct rsnd_priv *priv)
4263337744aSKuninori Morimoto {
42707539c1dSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
42807539c1dSKuninori Morimoto 	struct rsnd_gen *gen = rsnd_priv_to_gen(priv);
42907539c1dSKuninori Morimoto 	struct resource *sru_res;
430dfc9403bSKuninori Morimoto 	struct resource *adg_res;
431ae5c3223SKuninori Morimoto 	struct resource *ssi_res;
43255e5b6fdSKuninori Morimoto 	int ret;
43307539c1dSKuninori Morimoto 
43407539c1dSKuninori Morimoto 	/*
43507539c1dSKuninori Morimoto 	 * map address
43607539c1dSKuninori Morimoto 	 */
43707539c1dSKuninori Morimoto 	sru_res	= platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SRU);
438dfc9403bSKuninori Morimoto 	adg_res = platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_ADG);
439ae5c3223SKuninori Morimoto 	ssi_res	= platform_get_resource(pdev, IORESOURCE_MEM, RSND_GEN1_SSI);
44007539c1dSKuninori Morimoto 
44107539c1dSKuninori Morimoto 	gen->base[RSND_GEN1_SRU] = devm_ioremap_resource(dev, sru_res);
442dfc9403bSKuninori Morimoto 	gen->base[RSND_GEN1_ADG] = devm_ioremap_resource(dev, adg_res);
443ae5c3223SKuninori Morimoto 	gen->base[RSND_GEN1_SSI] = devm_ioremap_resource(dev, ssi_res);
44470263cb4SWei Yongjun 	if (IS_ERR(gen->base[RSND_GEN1_SRU]) ||
44570263cb4SWei Yongjun 	    IS_ERR(gen->base[RSND_GEN1_ADG]) ||
44670263cb4SWei Yongjun 	    IS_ERR(gen->base[RSND_GEN1_SSI]))
44707539c1dSKuninori Morimoto 		return -ENODEV;
44807539c1dSKuninori Morimoto 
44955e5b6fdSKuninori Morimoto 	ret = rsnd_gen1_regmap_init(priv, gen);
45055e5b6fdSKuninori Morimoto 	if (ret < 0)
45155e5b6fdSKuninori Morimoto 		return ret;
45207539c1dSKuninori Morimoto 
45307539c1dSKuninori Morimoto 	dev_dbg(dev, "Gen1 device probed\n");
454e6b0d896SLaurent Pinchart 	dev_dbg(dev, "SRU : %pap => %p\n",	&sru_res->start,
45507539c1dSKuninori Morimoto 						gen->base[RSND_GEN1_SRU]);
456e6b0d896SLaurent Pinchart 	dev_dbg(dev, "ADG : %pap => %p\n",	&adg_res->start,
457dfc9403bSKuninori Morimoto 						gen->base[RSND_GEN1_ADG]);
458e6b0d896SLaurent Pinchart 	dev_dbg(dev, "SSI : %pap => %p\n",	&ssi_res->start,
459ae5c3223SKuninori Morimoto 						gen->base[RSND_GEN1_SSI]);
46007539c1dSKuninori Morimoto 
4613337744aSKuninori Morimoto 	return 0;
462ae5c3223SKuninori Morimoto 
4633337744aSKuninori Morimoto }
4643337744aSKuninori Morimoto 
4653337744aSKuninori Morimoto /*
4663337744aSKuninori Morimoto  *		Gen
4673337744aSKuninori Morimoto  */
46890e8e50fSKuninori Morimoto static void rsnd_of_parse_gen(struct platform_device *pdev,
46990e8e50fSKuninori Morimoto 			      const struct rsnd_of_data *of_data,
47090e8e50fSKuninori Morimoto 			      struct rsnd_priv *priv)
47190e8e50fSKuninori Morimoto {
47290e8e50fSKuninori Morimoto 	struct rcar_snd_info *info = priv->info;
47390e8e50fSKuninori Morimoto 
47490e8e50fSKuninori Morimoto 	if (!of_data)
47590e8e50fSKuninori Morimoto 		return;
47690e8e50fSKuninori Morimoto 
47790e8e50fSKuninori Morimoto 	info->flags = of_data->flags;
47890e8e50fSKuninori Morimoto }
47990e8e50fSKuninori Morimoto 
4803337744aSKuninori Morimoto int rsnd_gen_probe(struct platform_device *pdev,
48190e8e50fSKuninori Morimoto 		   const struct rsnd_of_data *of_data,
4823337744aSKuninori Morimoto 		   struct rsnd_priv *priv)
4833337744aSKuninori Morimoto {
4843337744aSKuninori Morimoto 	struct device *dev = rsnd_priv_to_dev(priv);
4853337744aSKuninori Morimoto 	struct rsnd_gen *gen;
486531eaf49SKuninori Morimoto 	int ret;
4873337744aSKuninori Morimoto 
48890e8e50fSKuninori Morimoto 	rsnd_of_parse_gen(pdev, of_data, priv);
48990e8e50fSKuninori Morimoto 
4903337744aSKuninori Morimoto 	gen = devm_kzalloc(dev, sizeof(*gen), GFP_KERNEL);
4913337744aSKuninori Morimoto 	if (!gen) {
4923337744aSKuninori Morimoto 		dev_err(dev, "GEN allocate failed\n");
4933337744aSKuninori Morimoto 		return -ENOMEM;
4943337744aSKuninori Morimoto 	}
4953337744aSKuninori Morimoto 
496531eaf49SKuninori Morimoto 	priv->gen = gen;
497072188b6SKuninori Morimoto 
498507d466cSKuninori Morimoto 	ret = -ENODEV;
499507d466cSKuninori Morimoto 	if (rsnd_is_gen1(priv))
5005da39cf3SKuninori Morimoto 		ret = rsnd_gen1_probe(pdev, priv);
501507d466cSKuninori Morimoto 	else if (rsnd_is_gen2(priv))
5025da39cf3SKuninori Morimoto 		ret = rsnd_gen2_probe(pdev, priv);
503507d466cSKuninori Morimoto 
504507d466cSKuninori Morimoto 	if (ret < 0)
505072188b6SKuninori Morimoto 		dev_err(dev, "unknown generation R-Car sound device\n");
506072188b6SKuninori Morimoto 
507531eaf49SKuninori Morimoto 	return ret;
5083337744aSKuninori Morimoto }
509