Commit | Line | Data |
---|---|---|
1536a968 KM |
1 | /* |
2 | * Renesas R-Car | |
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 | #ifndef RSND_H | |
12 | #define RSND_H | |
13 | ||
14 | #include <linux/clk.h> | |
15 | #include <linux/device.h> | |
16 | #include <linux/io.h> | |
17 | #include <linux/list.h> | |
18 | #include <linux/module.h> | |
19 | #include <sound/rcar_snd.h> | |
20 | #include <sound/soc.h> | |
21 | #include <sound/pcm_params.h> | |
22 | ||
23 | /* | |
24 | * pseudo register | |
25 | * | |
26 | * The register address offsets SRU/SCU/SSIU on Gen1/Gen2 are very different. | |
27 | * This driver uses pseudo register in order to hide it. | |
28 | * see gen1/gen2 for detail | |
29 | */ | |
3337744a KM |
30 | enum rsnd_reg { |
31 | RSND_REG_MAX, | |
32 | }; | |
33 | ||
1536a968 | 34 | struct rsnd_priv; |
cdaa3cdf | 35 | struct rsnd_mod; |
1536a968 KM |
36 | struct rsnd_dai; |
37 | struct rsnd_dai_stream; | |
38 | ||
3337744a KM |
39 | /* |
40 | * R-Car basic functions | |
41 | */ | |
42 | #define rsnd_mod_read(m, r) \ | |
43 | rsnd_read(rsnd_mod_to_priv(m), m, RSND_REG_##r) | |
44 | #define rsnd_mod_write(m, r, d) \ | |
45 | rsnd_write(rsnd_mod_to_priv(m), m, RSND_REG_##r, d) | |
46 | #define rsnd_mod_bset(m, r, s, d) \ | |
47 | rsnd_bset(rsnd_mod_to_priv(m), m, RSND_REG_##r, s, d) | |
48 | ||
49 | #define rsnd_priv_read(p, r) rsnd_read(p, NULL, RSND_REG_##r) | |
50 | #define rsnd_priv_write(p, r, d) rsnd_write(p, NULL, RSND_REG_##r, d) | |
51 | #define rsnd_priv_bset(p, r, s, d) rsnd_bset(p, NULL, RSND_REG_##r, s, d) | |
52 | ||
53 | u32 rsnd_read(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg); | |
54 | void rsnd_write(struct rsnd_priv *priv, struct rsnd_mod *mod, | |
55 | enum rsnd_reg reg, u32 data); | |
56 | void rsnd_bset(struct rsnd_priv *priv, struct rsnd_mod *mod, enum rsnd_reg reg, | |
57 | u32 mask, u32 data); | |
58 | ||
cdaa3cdf KM |
59 | /* |
60 | * R-Car sound mod | |
61 | */ | |
62 | ||
63 | struct rsnd_mod_ops { | |
64 | char *name; | |
65 | int (*init)(struct rsnd_mod *mod, | |
66 | struct rsnd_dai *rdai, | |
67 | struct rsnd_dai_stream *io); | |
68 | int (*quit)(struct rsnd_mod *mod, | |
69 | struct rsnd_dai *rdai, | |
70 | struct rsnd_dai_stream *io); | |
71 | int (*start)(struct rsnd_mod *mod, | |
72 | struct rsnd_dai *rdai, | |
73 | struct rsnd_dai_stream *io); | |
74 | int (*stop)(struct rsnd_mod *mod, | |
75 | struct rsnd_dai *rdai, | |
76 | struct rsnd_dai_stream *io); | |
77 | }; | |
78 | ||
79 | struct rsnd_mod { | |
80 | int id; | |
81 | struct rsnd_priv *priv; | |
82 | struct rsnd_mod_ops *ops; | |
83 | struct list_head list; /* connect to rsnd_dai playback/capture */ | |
84 | }; | |
85 | ||
86 | #define rsnd_mod_to_priv(mod) ((mod)->priv) | |
87 | #define rsnd_mod_id(mod) ((mod)->id) | |
88 | #define for_each_rsnd_mod(pos, n, io) \ | |
89 | list_for_each_entry_safe(pos, n, &(io)->head, list) | |
90 | #define rsnd_mod_call(mod, func, rdai, io) \ | |
91 | (!(mod) ? -ENODEV : \ | |
92 | !((mod)->ops->func) ? 0 : \ | |
93 | (mod)->ops->func(mod, rdai, io)) | |
94 | ||
95 | void rsnd_mod_init(struct rsnd_priv *priv, | |
96 | struct rsnd_mod *mod, | |
97 | struct rsnd_mod_ops *ops, | |
98 | int id); | |
99 | char *rsnd_mod_name(struct rsnd_mod *mod); | |
100 | ||
1536a968 KM |
101 | /* |
102 | * R-Car sound DAI | |
103 | */ | |
104 | #define RSND_DAI_NAME_SIZE 16 | |
105 | struct rsnd_dai_stream { | |
106 | struct list_head head; /* head of rsnd_mod list */ | |
107 | struct snd_pcm_substream *substream; | |
108 | int byte_pos; | |
109 | int period_pos; | |
110 | int byte_per_period; | |
111 | int next_period_byte; | |
112 | }; | |
113 | ||
114 | struct rsnd_dai { | |
115 | char name[RSND_DAI_NAME_SIZE]; | |
116 | struct rsnd_dai_platform_info *info; /* rcar_snd.h */ | |
117 | struct rsnd_dai_stream playback; | |
118 | struct rsnd_dai_stream capture; | |
119 | ||
120 | int clk_master:1; | |
121 | int bit_clk_inv:1; | |
122 | int frm_clk_inv:1; | |
123 | int sys_delay:1; | |
124 | int data_alignment:1; | |
125 | }; | |
126 | ||
127 | #define rsnd_dai_nr(priv) ((priv)->dai_nr) | |
128 | #define for_each_rsnd_dai(rdai, priv, i) \ | |
129 | for (i = 0, (rdai) = rsnd_dai_get(priv, i); \ | |
130 | i < rsnd_dai_nr(priv); \ | |
131 | i++, (rdai) = rsnd_dai_get(priv, i)) | |
132 | ||
133 | struct rsnd_dai *rsnd_dai_get(struct rsnd_priv *priv, int id); | |
cdaa3cdf KM |
134 | int rsnd_dai_disconnect(struct rsnd_mod *mod); |
135 | int rsnd_dai_connect(struct rsnd_dai *rdai, struct rsnd_mod *mod, | |
136 | struct rsnd_dai_stream *io); | |
1536a968 KM |
137 | int rsnd_dai_is_play(struct rsnd_dai *rdai, struct rsnd_dai_stream *io); |
138 | #define rsnd_dai_get_platform_info(rdai) ((rdai)->info) | |
139 | ||
140 | void rsnd_dai_pointer_update(struct rsnd_dai_stream *io, int cnt); | |
141 | int rsnd_dai_pointer_offset(struct rsnd_dai_stream *io, int additional); | |
142 | ||
3337744a KM |
143 | /* |
144 | * R-Car Gen1/Gen2 | |
145 | */ | |
146 | int rsnd_gen_probe(struct platform_device *pdev, | |
147 | struct rcar_snd_info *info, | |
148 | struct rsnd_priv *priv); | |
149 | void rsnd_gen_remove(struct platform_device *pdev, | |
150 | struct rsnd_priv *priv); | |
151 | int rsnd_gen_path_init(struct rsnd_priv *priv, | |
152 | struct rsnd_dai *rdai, | |
153 | struct rsnd_dai_stream *io); | |
154 | int rsnd_gen_path_exit(struct rsnd_priv *priv, | |
155 | struct rsnd_dai *rdai, | |
156 | struct rsnd_dai_stream *io); | |
157 | void __iomem *rsnd_gen_reg_get(struct rsnd_priv *priv, | |
158 | struct rsnd_mod *mod, | |
159 | enum rsnd_reg reg); | |
160 | ||
1536a968 KM |
161 | /* |
162 | * R-Car sound priv | |
163 | */ | |
164 | struct rsnd_priv { | |
165 | ||
166 | struct device *dev; | |
167 | struct rcar_snd_info *info; | |
168 | spinlock_t lock; | |
169 | ||
3337744a KM |
170 | /* |
171 | * below value will be filled on rsnd_gen_probe() | |
172 | */ | |
173 | void *gen; | |
174 | ||
1536a968 KM |
175 | /* |
176 | * below value will be filled on rsnd_dai_probe() | |
177 | */ | |
178 | struct snd_soc_dai_driver *daidrv; | |
179 | struct rsnd_dai *rdai; | |
180 | int dai_nr; | |
181 | }; | |
182 | ||
183 | #define rsnd_priv_to_dev(priv) ((priv)->dev) | |
184 | #define rsnd_lock(priv, flags) spin_lock_irqsave(&priv->lock, flags) | |
185 | #define rsnd_unlock(priv, flags) spin_unlock_irqrestore(&priv->lock, flags) | |
186 | ||
187 | #endif |