xref: /openbmc/linux/sound/soc/sh/rcar/gen.c (revision 7277911c)
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(&regc, 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, &regc);
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