blob: e38f164eb12e69205f0c74c72c29cb46ac66bc0e [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009,2011 Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13
14#include <linux/module.h>
15#include <linux/mutex.h>
16#include <linux/platform_device.h>
17#include <linux/io.h>
18#include <linux/err.h>
19
20#include <mach/qdsp5v2/mi2s.h>
21#include <mach/qdsp5v2/audio_dev_ctl.h>
22
23#define DEBUG
24#ifdef DEBUG
25#define dprintk(format, arg...) \
26printk(KERN_DEBUG format, ## arg)
27#else
28#define dprintk(format, arg...) do {} while (0)
29#endif
30
31/*----------------------------------------------------------------------------
32 * Preprocessor Definitions and Constants
33 * -------------------------------------------------------------------------*/
34
35/* Device Types */
36#define HDMI 0
37#define CODEC_RX 1
38#define CODEC_TX 2
39
40/* Static offset for now. If different target have different
41 * offset, update to platform data model
42 */
43#define MI2S_RESET_OFFSET 0x0
44#define MI2S_MODE_OFFSET 0x4
45#define MI2S_TX_MODE_OFFSET 0x8
46#define MI2S_RX_MODE_OFFSET 0xc
47
48#define MI2S_SD_N_EN_MASK 0xF0
49#define MI2S_TX_RX_N_MASK 0x0F
50
51#define MI2S_RESET__MI2S_RESET__RESET 0x1
52#define MI2S_RESET__MI2S_RESET__ACTIVE 0x0
53#define MI2S_MODE__MI2S_MASTER__MASTER 0x1
54#define MI2S_MODE__MI2S_MASTER__SLAVE 0x0
55#define MI2S_MODE__MI2S_TX_RX_WORD_TYPE__16_BIT 0x1
56#define MI2S_MODE__MI2S_TX_RX_WORD_TYPE__24_BIT 0x2
57#define MI2S_MODE__MI2S_TX_RX_WORD_TYPE__32_BIT 0x3
58#define MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__RAW 0x0
59#define MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__PACKED 0x1
60#define MI2S_TX_MODE__MI2S_TX_STEREO_MODE__MONO_SAMPLE 0x0
61#define MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE 0x1
62#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__2_CHANNEL 0x0
63#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__4_CHANNEL 0x1
64#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__6_CHANNEL 0x2
65#define MI2S_TX_MODE__MI2S_TX_CH_TYPE__8_CHANNEL 0x3
66#define MI2S_TX_MODE__MI2S_TX_DMA_ACK_SYNCH_EN__SYNC_ENABLE 0x1
67#define MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__RAW 0x0
68#define MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__PACKED 0x1
69#define MI2S_RX_MODE__MI2S_RX_STEREO_MODE__MONO_SAMPLE 0x0
70#define MI2S_RX_MODE__MI2S_RX_STEREO_MODE__STEREO_SAMPLE 0x1
71#define MI2S_RX_MODE__MI2S_RX_CH_TYPE__2_CH 0x0
72#define MI2S_RX_MODE__MI2S_RX_DMA_ACK_SYNCH_EN__SYNC_ENABLE 0x1
73
74#define HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_BMSK 0x1000
75#define HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_SHFT 0xC
76#define HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK 0x300
77#define HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT 0x8
78#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK 0x4
79#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT 0x2
80#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_BMSK 0x2
81#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_SHFT 0x1
82#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK 0x18
83#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT 0x3
84#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_BMSK 0x80
85#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_SHFT 0x7
86#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_BMSK 0x60
87#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_SHFT 0x5
88#define HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_DMA_ACK_SYNCH_EN_BMSK 0x1
89#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_BMSK 0x60
90#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_SHFT 0x5
91#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK 0x4
92#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT 0x2
93#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_BMSK 0x2
94#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT 0x1
95#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_BMSK 0x18
96#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_SHFT 0x3
97#define HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_DMA_ACK_SYNCH_EN_BMSK 0x1
98
99/* Max number of channels */
100#define MAX_NUM_CHANNELS_OUT 8
101#define MAX_NUM_CHANNELS_IN 2
102
103/* Num of SD Lines */
104#define MAX_SD_LINES 4
105
106#define MI2S_SD_0_EN_MAP 0x10
107#define MI2S_SD_1_EN_MAP 0x20
108#define MI2S_SD_2_EN_MAP 0x40
109#define MI2S_SD_3_EN_MAP 0x80
110#define MI2S_SD_0_TX_MAP 0x01
111#define MI2S_SD_1_TX_MAP 0x02
112#define MI2S_SD_2_TX_MAP 0x04
113#define MI2S_SD_3_TX_MAP 0x08
114
115struct mi2s_state {
116 void __iomem *mi2s_hdmi_base;
117 void __iomem *mi2s_rx_base;
118 void __iomem *mi2s_tx_base;
119 struct mutex mutex_lock;
120
121};
122
123static struct mi2s_state the_mi2s_state;
124
125static void __iomem *get_base_addr(struct mi2s_state *mi2s, uint8_t dev_id)
126{
127 switch (dev_id) {
128 case HDMI:
129 return mi2s->mi2s_hdmi_base;
130 case CODEC_RX:
131 return mi2s->mi2s_rx_base;
132 case CODEC_TX:
133 return mi2s->mi2s_tx_base;
134 default:
135 break;
136 }
137 return ERR_PTR(-ENODEV);
138}
139
140static void mi2s_reset(struct mi2s_state *mi2s, uint8_t dev_id)
141{
142 void __iomem *baddr = get_base_addr(mi2s, dev_id);
143 if (!IS_ERR(baddr))
144 writel(MI2S_RESET__MI2S_RESET__RESET,
145 baddr + MI2S_RESET_OFFSET);
146}
147
148static void mi2s_release(struct mi2s_state *mi2s, uint8_t dev_id)
149{
150 void __iomem *baddr = get_base_addr(mi2s, dev_id);
151 if (!IS_ERR(baddr))
152 writel(MI2S_RESET__MI2S_RESET__ACTIVE,
153 baddr + MI2S_RESET_OFFSET);
154}
155
156static void mi2s_master(struct mi2s_state *mi2s, uint8_t dev_id, bool master)
157{
158 void __iomem *baddr = get_base_addr(mi2s, dev_id);
159 uint32_t val;
160 if (!IS_ERR(baddr)) {
161 val = readl(baddr + MI2S_MODE_OFFSET);
162 if (master) {
163 writel(
164 ((val & ~HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_BMSK) |
165 (MI2S_MODE__MI2S_MASTER__MASTER <<
166 HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_SHFT)),
167 baddr + MI2S_MODE_OFFSET);
168 } else {
169 writel(
170 ((val & ~HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_BMSK) |
171 (MI2S_MODE__MI2S_MASTER__SLAVE <<
172 HWIO_AUDIO1_MI2S_MODE_MI2S_MASTER_SHFT)),
173 baddr + MI2S_MODE_OFFSET);
174 }
175 }
176}
177
178static void mi2s_set_word_type(struct mi2s_state *mi2s, uint8_t dev_id,
179 uint8_t size)
180{
181 void __iomem *baddr = get_base_addr(mi2s, dev_id);
182 uint32_t val;
183 if (!IS_ERR(baddr)) {
184 val = readl(baddr + MI2S_MODE_OFFSET);
185 switch (size) {
186 case WT_16_BIT:
187 writel(
188 ((val &
189 ~HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK) |
190 (MI2S_MODE__MI2S_TX_RX_WORD_TYPE__16_BIT <<
191 HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT)),
192 baddr + MI2S_MODE_OFFSET);
193 break;
194 case WT_24_BIT:
195 writel(
196 ((val &
197 ~HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK) |
198 (MI2S_MODE__MI2S_TX_RX_WORD_TYPE__24_BIT <<
199 HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT)),
200 baddr + MI2S_MODE_OFFSET);
201 break;
202 case WT_32_BIT:
203 writel(
204 ((val &
205 ~HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_BMSK) |
206 (MI2S_MODE__MI2S_TX_RX_WORD_TYPE__32_BIT <<
207 HWIO_AUDIO1_MI2S_MODE_MI2S_TX_RX_WORD_TYPE_SHFT)),
208 baddr + MI2S_MODE_OFFSET);
209 break;
210 default:
211 break;
212 }
213 }
214}
215
216static void mi2s_set_sd(struct mi2s_state *mi2s, uint8_t dev_id, uint8_t sd_map)
217{
218 void __iomem *baddr = get_base_addr(mi2s, dev_id);
219 uint32_t val;
220 if (!IS_ERR(baddr)) {
221 val = readl(baddr + MI2S_MODE_OFFSET) &
222 ~(MI2S_SD_N_EN_MASK | MI2S_TX_RX_N_MASK);
223 writel(val | sd_map, baddr + MI2S_MODE_OFFSET);
224 }
225}
226
227static void mi2s_set_output_num_channels(struct mi2s_state *mi2s,
228 uint8_t dev_id, uint8_t channels)
229{
230 void __iomem *baddr = get_base_addr(mi2s, dev_id);
231 uint32_t val;
232 if (!IS_ERR(baddr)) {
233 val = readl(baddr + MI2S_TX_MODE_OFFSET);
234 if (channels == MI2S_CHAN_MONO_RAW) {
235 val = (val &
236 ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK |
237 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_BMSK)) |
238 ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__MONO_SAMPLE <<
239 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) |
240 (MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__RAW <<
241 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_SHFT));
242 } else if (channels == MI2S_CHAN_MONO_PACKED) {
243 val = (val &
244 ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK |
245 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_BMSK)) |
246 ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__MONO_SAMPLE <<
247 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) |
248 (MI2S_TX_MODE__MI2S_TX_CODEC_16_MONO_MODE__PACKED <<
249 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_P_MONO_SHFT));
250 } else if (channels == MI2S_CHAN_STEREO) {
251 val = (val &
252 ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK |
253 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) |
254 ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE <<
255 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) |
256 (MI2S_TX_MODE__MI2S_TX_CH_TYPE__2_CHANNEL <<
257 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT));
258 } else if (channels == MI2S_CHAN_4CHANNELS) {
259 val = (val &
260 ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK |
261 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) |
262 ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE <<
263 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) |
264 (MI2S_TX_MODE__MI2S_TX_CH_TYPE__4_CHANNEL <<
265 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT));
266 } else if (channels == MI2S_CHAN_6CHANNELS) {
267 val = (val &
268 ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK |
269 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) |
270 ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE <<
271 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) |
272 (MI2S_TX_MODE__MI2S_TX_CH_TYPE__6_CHANNEL <<
273 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT));
274 } else if (channels == MI2S_CHAN_8CHANNELS) {
275 val = (val &
276 ~(HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_BMSK |
277 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_BMSK)) |
278 ((MI2S_TX_MODE__MI2S_TX_STEREO_MODE__STEREO_SAMPLE <<
279 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_STEREO_MODE_SHFT) |
280 (MI2S_TX_MODE__MI2S_TX_CH_TYPE__8_CHANNEL <<
281 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_CH_TYPE_SHFT));
282 }
283 writel(val, baddr + MI2S_TX_MODE_OFFSET);
284 }
285}
286
287static void mi2s_set_output_4ch_map(struct mi2s_state *mi2s, uint8_t dev_id,
288 bool high_low)
289{
290 void __iomem *baddr = get_base_addr(mi2s, dev_id);
291 uint32_t val;
292 if (!IS_ERR(baddr)) {
293 val = readl(baddr + MI2S_TX_MODE_OFFSET);
294 val = (val & ~HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_BMSK) |
295 (high_low <<
296 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_4_0_CH_MAP_SHFT);
297 writel(val, baddr + MI2S_TX_MODE_OFFSET);
298 }
299}
300
301static void mi2s_set_output_2ch_map(struct mi2s_state *mi2s, uint8_t dev_id,
302 uint8_t sd_line)
303{
304 void __iomem *baddr = get_base_addr(mi2s, dev_id);
305 uint32_t val;
306
307 if (!IS_ERR(baddr)) {
308 val = readl(baddr + MI2S_TX_MODE_OFFSET);
309 if (sd_line < 4) {
310 val = (val &
311 ~HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_BMSK) |
312 (sd_line <<
313 HWIO_AUDIO1_MI2S_TX_MODE_MI2S_2_0_CH_MAP_SHFT);
314 writel(val, baddr + MI2S_TX_MODE_OFFSET);
315 }
316 }
317}
318
319static void mi2s_set_output_clk_synch(struct mi2s_state *mi2s, uint8_t dev_id)
320{
321 void __iomem *baddr = get_base_addr(mi2s, dev_id);
322 uint32_t val;
323
324 if (!IS_ERR(baddr)) {
325 val = readl(baddr + MI2S_TX_MODE_OFFSET);
326 writel(((val &
327 ~HWIO_AUDIO1_MI2S_TX_MODE_MI2S_TX_DMA_ACK_SYNCH_EN_BMSK) |
328 MI2S_TX_MODE__MI2S_TX_DMA_ACK_SYNCH_EN__SYNC_ENABLE),
329 baddr + MI2S_TX_MODE_OFFSET);
330 }
331}
332
333static void mi2s_set_input_sd_line(struct mi2s_state *mi2s, uint8_t dev_id,
334 uint8_t sd_line)
335{
336 void __iomem *baddr = get_base_addr(mi2s, dev_id);
337 uint32_t val;
338
339 if (!IS_ERR(baddr)) {
340 val = readl(baddr + MI2S_RX_MODE_OFFSET);
341 if (sd_line < 4) {
342 val = (val &
343 ~HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_BMSK) |
344 (sd_line <<
345 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_I2S_LINE_SHFT);
346 writel(val, baddr + MI2S_RX_MODE_OFFSET);
347 }
348 }
349}
350
351static void mi2s_set_input_num_channels(struct mi2s_state *mi2s, uint8_t dev_id,
352 uint8_t channels)
353{
354 void __iomem *baddr = get_base_addr(mi2s, dev_id);
355 uint32_t val;
356
357 if (!IS_ERR(baddr)) {
358 val = readl(baddr + MI2S_RX_MODE_OFFSET);
359 if (channels == MI2S_CHAN_MONO_RAW) {
360 val = (val &
361 ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK |
362 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_BMSK)) |
363 ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__MONO_SAMPLE <<
364 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) |
365 (MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__RAW <<
366 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT));
367 } else if (channels == MI2S_CHAN_MONO_PACKED) {
368 val = (val &
369 ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK |
370 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_BMSK)) |
371 ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__MONO_SAMPLE <<
372 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) |
373 (MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__PACKED <<
374 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT));
375 } else if (channels == MI2S_CHAN_STEREO) {
376
377 if (dev_id == HDMI)
378 val = (val &
379 ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK |
380 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_BMSK)) |
381 ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__STEREO_SAMPLE <<
382 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) |
383 (MI2S_RX_MODE__MI2S_RX_CH_TYPE__2_CH <<
384 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_SHFT));
385
386 else
387 val = (val &
388 ~(HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_BMSK |
389 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_BMSK)) |
390 ((MI2S_RX_MODE__MI2S_RX_STEREO_MODE__STEREO_SAMPLE <<
391 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_STEREO_MODE_SHFT) |
392 (MI2S_RX_MODE__MI2S_RX_CODEC_16_MONO_MODE__PACKED <<
393 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CODEC_P_MONO_SHFT) |
394 (MI2S_RX_MODE__MI2S_RX_CH_TYPE__2_CH <<
395 HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_CH_TYPE_SHFT));
396
397
398 }
399 writel(val, baddr + MI2S_RX_MODE_OFFSET);
400 }
401}
402
403static void mi2s_set_input_clk_synch(struct mi2s_state *mi2s, uint8_t dev_id)
404{
405 void __iomem *baddr = get_base_addr(mi2s, dev_id);
406 uint32_t val;
407
408 if (!IS_ERR(baddr)) {
409 val = readl(baddr + MI2S_RX_MODE_OFFSET);
410 writel(
411 ((val &
412 ~HWIO_AUDIO1_MI2S_RX_MODE_MI2S_RX_DMA_ACK_SYNCH_EN_BMSK) |
413 MI2S_RX_MODE__MI2S_RX_DMA_ACK_SYNCH_EN__SYNC_ENABLE),
414 baddr + MI2S_RX_MODE_OFFSET);
415 }
416}
417
418
419static u8 num_of_bits_set(u8 sd_line_mask)
420{
421 u8 num_bits_set = 0;
422
423 while (sd_line_mask) {
424
425 if (sd_line_mask & 1)
426 num_bits_set++;
427 sd_line_mask = sd_line_mask >> 1;
428 }
429 return num_bits_set;
430}
431
432
433bool mi2s_set_hdmi_output_path(uint8_t channels, uint8_t size,
434 uint8_t sd_line_mask)
435{
436 bool ret_val = MI2S_TRUE;
437 struct mi2s_state *mi2s = &the_mi2s_state;
438 u8 sd_line, num_of_sd_lines = 0;
439 void __iomem *baddr;
440 uint32_t val;
441
442 pr_debug("%s: channels = %u size = %u sd_line_mask = 0x%x\n", __func__,
443 channels, size, sd_line_mask);
444
445 if ((channels == 0) || (channels > MAX_NUM_CHANNELS_OUT) ||
446 ((channels != 1) && (channels % 2 != 0))) {
447
448 pr_err("%s: invalid number of channels. channels = %u\n",
449 __func__, channels);
450 return MI2S_FALSE;
451 }
452
453 sd_line_mask &= MI2S_SD_LINE_MASK;
454
455 if (!sd_line_mask) {
456 pr_err("%s: Did not set any data lines to use "
457 " sd_line_mask =0x%x\n", __func__, sd_line_mask);
458 return MI2S_FALSE;
459 }
460
461 mutex_lock(&mi2s->mutex_lock);
462 /* Put device in reset */
463 mi2s_reset(mi2s, HDMI);
464
465 mi2s_master(mi2s, HDMI, 1);
466
467 /* Set word type */
468 if (size <= WT_MAX)
469 mi2s_set_word_type(mi2s, HDMI, size);
470 else
471 ret_val = MI2S_FALSE;
472
473 /* Enable clock crossing synchronization of RD DMA ACK */
474 mi2s_set_output_clk_synch(mi2s, HDMI);
475
476 mi2s_set_output_num_channels(mi2s, HDMI, channels);
477
478 num_of_sd_lines = num_of_bits_set(sd_line_mask);
479 /*Second argument to find_first_bit should be maximum number of
480 bit*/
481
482 sd_line = find_first_bit((unsigned long *)&sd_line_mask,
483 sizeof(sd_line_mask) * 8);
484 pr_debug("sd_line = %d\n", sd_line);
485
486 if (channels == 1) {
487
488 if (num_of_sd_lines != 1) {
489 pr_err("%s: for one channel only one SD lines is"
490 " needed. num_of_sd_lines = %u\n",
491 __func__, num_of_sd_lines);
492
493 ret_val = MI2S_FALSE;
494 goto error;
495 }
496
497 if (sd_line != 0) {
498 pr_err("%s: for one channel tx, need to use SD_0 "
499 "sd_line = %u\n", __func__, sd_line);
500
501 ret_val = MI2S_FALSE;
502 goto error;
503 }
504
505 /* Enable SD line 0 for Tx (only option for
506 * mono audio)
507 */
508 mi2s_set_sd(mi2s, HDMI, MI2S_SD_0_EN_MAP | MI2S_SD_0_TX_MAP);
509
510 } else if (channels == 2) {
511
512 if (num_of_sd_lines != 1) {
513 pr_err("%s: for two channel only one SD lines is"
514 " needed. num_of_sd_lines = %u\n",
515 __func__, num_of_sd_lines);
516 ret_val = MI2S_FALSE;
517 goto error;
518 }
519
520 /* Enable single SD line for Tx */
521 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP << sd_line) |
522 (MI2S_SD_0_TX_MAP << sd_line));
523
524 /* Set 2-channel mapping */
525 mi2s_set_output_2ch_map(mi2s, HDMI, sd_line);
526
527 } else if (channels == 4) {
528
529 if (num_of_sd_lines != 2) {
530 pr_err("%s: for 4 channels two SD lines are"
531 " needed. num_of_sd_lines = %u\\n",
532 __func__, num_of_sd_lines);
533 ret_val = MI2S_FALSE;
534 goto error;
535 }
536
537 if ((sd_line_mask && MI2S_SD_0) &&
538 (sd_line_mask && MI2S_SD_1)) {
539
540 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP |
541 MI2S_SD_1_EN_MAP) | (MI2S_SD_0_TX_MAP |
542 MI2S_SD_1_TX_MAP));
543 mi2s_set_output_4ch_map(mi2s, HDMI, MI2S_FALSE);
544
545 } else if ((sd_line_mask && MI2S_SD_2) &&
546 (sd_line_mask && MI2S_SD_3)) {
547
548 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_2_EN_MAP |
549 MI2S_SD_3_EN_MAP) | (MI2S_SD_2_TX_MAP |
550 MI2S_SD_3_TX_MAP));
551
552 mi2s_set_output_4ch_map(mi2s, HDMI, MI2S_TRUE);
553 } else {
554
555 pr_err("%s: for 4 channels invalid SD lines usage"
556 " sd_line_mask = 0x%x\n",
557 __func__, sd_line_mask);
558 ret_val = MI2S_FALSE;
559 goto error;
560 }
561 } else if (channels == 6) {
562
563 if (num_of_sd_lines != 3) {
564 pr_err("%s: for 6 channels three SD lines are"
565 " needed. num_of_sd_lines = %u\n",
566 __func__, num_of_sd_lines);
567 ret_val = MI2S_FALSE;
568 goto error;
569 }
570
571 if ((sd_line_mask && MI2S_SD_0) &&
572 (sd_line_mask && MI2S_SD_1) &&
573 (sd_line_mask && MI2S_SD_2)) {
574
575 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP |
576 MI2S_SD_1_EN_MAP | MI2S_SD_2_EN_MAP) |
577 (MI2S_SD_0_TX_MAP | MI2S_SD_1_TX_MAP |
578 MI2S_SD_2_TX_MAP));
579
580 } else if ((sd_line_mask && MI2S_SD_1) &&
581 (sd_line_mask && MI2S_SD_2) &&
582 (sd_line_mask && MI2S_SD_3)) {
583
584 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_1_EN_MAP |
585 MI2S_SD_2_EN_MAP | MI2S_SD_3_EN_MAP) |
586 (MI2S_SD_1_TX_MAP | MI2S_SD_2_TX_MAP |
587 MI2S_SD_3_TX_MAP));
588
589 } else {
590
591 pr_err("%s: for 6 channels invalid SD lines usage"
592 " sd_line_mask = 0x%x\n",
593 __func__, sd_line_mask);
594 ret_val = MI2S_FALSE;
595 goto error;
596 }
597 } else if (channels == 8) {
598
599 if (num_of_sd_lines != 4) {
600 pr_err("%s: for 8 channels four SD lines are"
601 " needed. num_of_sd_lines = %u\n",
602 __func__, num_of_sd_lines);
603 ret_val = MI2S_FALSE;
604 goto error;
605 }
606
607 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP |
608 MI2S_SD_1_EN_MAP | MI2S_SD_2_EN_MAP |
609 MI2S_SD_3_EN_MAP) | (MI2S_SD_0_TX_MAP |
610 MI2S_SD_1_TX_MAP | MI2S_SD_2_TX_MAP |
611 MI2S_SD_3_TX_MAP));
612 } else {
613 pr_err("%s: invalid number channels = %u\n",
614 __func__, channels);
615 ret_val = MI2S_FALSE;
616 goto error;
617 }
618
619 baddr = get_base_addr(mi2s, HDMI);
620
621 val = readl(baddr + MI2S_MODE_OFFSET);
622 pr_debug("%s(): MI2S_MODE = 0x%x\n", __func__, val);
623
624 val = readl(baddr + MI2S_TX_MODE_OFFSET);
625 pr_debug("%s(): MI2S_TX_MODE = 0x%x\n", __func__, val);
626
627
628error:
629 /* Release device from reset */
630 mi2s_release(mi2s, HDMI);
631
632 mutex_unlock(&mi2s->mutex_lock);
633 mb();
634 return ret_val;
635}
636EXPORT_SYMBOL(mi2s_set_hdmi_output_path);
637
638bool mi2s_set_hdmi_input_path(uint8_t channels, uint8_t size,
639 uint8_t sd_line_mask)
640{
641 bool ret_val = MI2S_TRUE;
642 struct mi2s_state *mi2s = &the_mi2s_state;
643 u8 sd_line, num_of_sd_lines = 0;
644 void __iomem *baddr;
645 uint32_t val;
646
647 pr_debug("%s: channels = %u size = %u sd_line_mask = 0x%x\n", __func__,
648 channels, size, sd_line_mask);
649
650 if ((channels != 1) && (channels != MAX_NUM_CHANNELS_IN)) {
651
652 pr_err("%s: invalid number of channels. channels = %u\n",
653 __func__, channels);
654 return MI2S_FALSE;
655 }
656
657 if (size > WT_MAX) {
658
659 pr_err("%s: mi2s word size can not be greater than 32 bits\n",
660 __func__);
661 return MI2S_FALSE;
662 }
663
664 sd_line_mask &= MI2S_SD_LINE_MASK;
665
666 if (!sd_line_mask) {
667 pr_err("%s: Did not set any data lines to use "
668 " sd_line_mask =0x%x\n", __func__, sd_line_mask);
669 return MI2S_FALSE;
670 }
671
672 num_of_sd_lines = num_of_bits_set(sd_line_mask);
673
674 if (num_of_sd_lines != 1) {
675 pr_err("%s: for two channel input only one SD lines is"
676 " needed. num_of_sd_lines = %u sd_line_mask = 0x%x\n",
677 __func__, num_of_sd_lines, sd_line_mask);
678 return MI2S_FALSE;
679 }
680
681 /*Second argument to find_first_bit should be maximum number of
682 bits interested*/
683 sd_line = find_first_bit((unsigned long *)&sd_line_mask,
684 sizeof(sd_line_mask) * 8);
685 pr_debug("sd_line = %d\n", sd_line);
686
687 /* Ensure sd_line parameter is valid (0-max) */
688 if (sd_line > MAX_SD_LINES) {
689 pr_err("%s: Line number can not be greater than = %u\n",
690 __func__, MAX_SD_LINES);
691 return MI2S_FALSE;
692 }
693
694 mutex_lock(&mi2s->mutex_lock);
695 /* Put device in reset */
696 mi2s_reset(mi2s, HDMI);
697
698 mi2s_master(mi2s, HDMI, 1);
699
700 /* Set word type */
701 mi2s_set_word_type(mi2s, HDMI, size);
702
703 /* Enable clock crossing synchronization of WR DMA ACK */
704 mi2s_set_input_clk_synch(mi2s, HDMI);
705
706 /* Ensure channels parameter is valid (non-zero, less than max,
707 * and even or mono)
708 */
709 mi2s_set_input_num_channels(mi2s, HDMI, channels);
710
711 mi2s_set_input_sd_line(mi2s, HDMI, sd_line);
712
713 mi2s_set_sd(mi2s, HDMI, (MI2S_SD_0_EN_MAP << sd_line));
714
715 baddr = get_base_addr(mi2s, HDMI);
716
717 val = readl(baddr + MI2S_MODE_OFFSET);
718 pr_debug("%s(): MI2S_MODE = 0x%x\n", __func__, val);
719
720 val = readl(baddr + MI2S_RX_MODE_OFFSET);
721 pr_debug("%s(): MI2S_RX_MODE = 0x%x\n", __func__, val);
722
723 /* Release device from reset */
724 mi2s_release(mi2s, HDMI);
725
726 mutex_unlock(&mi2s->mutex_lock);
727 mb();
728 return ret_val;
729}
730EXPORT_SYMBOL(mi2s_set_hdmi_input_path);
731
732bool mi2s_set_codec_output_path(uint8_t channels, uint8_t size)
733{
734 bool ret_val = MI2S_TRUE;
735 struct mi2s_state *mi2s = &the_mi2s_state;
736
737 mutex_lock(&mi2s->mutex_lock);
738 /* Put device in reset */
739 mi2s_reset(mi2s, CODEC_TX);
740
741 mi2s_master(mi2s, CODEC_TX, 1);
742
743 /* Enable clock crossing synchronization of RD DMA ACK */
744 mi2s_set_output_clk_synch(mi2s, CODEC_TX);
745
746 /* Set word type */
747 if (size <= WT_MAX)
748 mi2s_set_word_type(mi2s, CODEC_TX, size);
749 else
750 ret_val = MI2S_FALSE;
751
752 mi2s_set_output_num_channels(mi2s, CODEC_TX, channels);
753
754 /* Enable SD line */
755 mi2s_set_sd(mi2s, CODEC_TX, MI2S_SD_0_EN_MAP | MI2S_SD_0_TX_MAP);
756
757 /* Release device from reset */
758 mi2s_release(mi2s, CODEC_TX);
759
760 mutex_unlock(&mi2s->mutex_lock);
761 mb();
762 return ret_val;
763}
764EXPORT_SYMBOL(mi2s_set_codec_output_path);
765
766bool mi2s_set_codec_input_path(uint8_t channels, uint8_t size)
767{
768 bool ret_val = MI2S_TRUE;
769 struct mi2s_state *mi2s = &the_mi2s_state;
770
771 mutex_lock(&the_mi2s_state.mutex_lock);
772 /* Put device in reset */
773 mi2s_reset(mi2s, CODEC_RX);
774
775 mi2s_master(mi2s, CODEC_RX, 1);
776
777 /* Enable clock crossing synchronization of WR DMA ACK */
778 mi2s_set_input_clk_synch(mi2s, CODEC_RX);
779
780 /* Set word type */
781 if (size <= WT_MAX)
782 mi2s_set_word_type(mi2s, CODEC_RX, size);
783 else
784 ret_val = MI2S_FALSE;
785
786 mi2s_set_input_num_channels(mi2s, CODEC_RX, channels);
787
788 /* Enable SD line */
789 mi2s_set_sd(mi2s, CODEC_RX, MI2S_SD_0_EN_MAP);
790
791 /* Release device from reset */
792 mi2s_release(mi2s, CODEC_RX);
793
794 mutex_unlock(&mi2s->mutex_lock);
795 mb();
796 return ret_val;
797}
798EXPORT_SYMBOL(mi2s_set_codec_input_path);
799
800
801static int mi2s_probe(struct platform_device *pdev)
802{
803 int rc = 0;
804 struct resource *mem_src;
805
806 mem_src = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
807 if (!mem_src) {
808 rc = -ENODEV;
809 goto error_hdmi;
810 }
811 the_mi2s_state.mi2s_hdmi_base = ioremap(mem_src->start,
812 (mem_src->end - mem_src->start) + 1);
813 if (!the_mi2s_state.mi2s_hdmi_base) {
814 rc = -ENOMEM;
815 goto error_hdmi;
816 }
817 mem_src = platform_get_resource_byname(pdev,
818 IORESOURCE_MEM, "codec_rx");
819 if (!mem_src) {
820 rc = -ENODEV;
821 goto error_codec_rx;
822 }
823 the_mi2s_state.mi2s_rx_base = ioremap(mem_src->start,
824 (mem_src->end - mem_src->start) + 1);
825 if (!the_mi2s_state.mi2s_rx_base) {
826 rc = -ENOMEM;
827 goto error_codec_rx;
828 }
829 mem_src = platform_get_resource_byname(pdev,
830 IORESOURCE_MEM, "codec_tx");
831 if (!mem_src) {
832 rc = -ENODEV;
833 goto error_codec_tx;
834 }
835 the_mi2s_state.mi2s_tx_base = ioremap(mem_src->start,
836 (mem_src->end - mem_src->start) + 1);
837 if (!the_mi2s_state.mi2s_tx_base) {
838 rc = -ENOMEM;
839 goto error_codec_tx;
840 }
841 mutex_init(&the_mi2s_state.mutex_lock);
842
843 return rc;
844
845error_codec_tx:
846 iounmap(the_mi2s_state.mi2s_rx_base);
847error_codec_rx:
848 iounmap(the_mi2s_state.mi2s_hdmi_base);
849error_hdmi:
850 return rc;
851
852}
853
854static int mi2s_remove(struct platform_device *pdev)
855{
856 iounmap(the_mi2s_state.mi2s_tx_base);
857 iounmap(the_mi2s_state.mi2s_rx_base);
858 iounmap(the_mi2s_state.mi2s_hdmi_base);
859 return 0;
860}
861
862static struct platform_driver mi2s_driver = {
863 .probe = mi2s_probe,
864 .remove = mi2s_remove,
865 .driver = {
866 .name = "mi2s",
867 .owner = THIS_MODULE,
868 },
869};
870
871static int __init mi2s_init(void)
872{
873 return platform_driver_register(&mi2s_driver);
874}
875
876static void __exit mi2s_exit(void)
877{
878 platform_driver_unregister(&mi2s_driver);
879}
880
881module_init(mi2s_init);
882module_exit(mi2s_exit);
883
884MODULE_DESCRIPTION("MSM MI2S driver");
885MODULE_LICENSE("GPL v2");