aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh/fsi.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /sound/soc/sh/fsi.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r--sound/soc/sh/fsi.c483
1 files changed, 267 insertions, 216 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 44123248b630..8dc966f45c36 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -17,8 +17,9 @@
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/list.h> 19#include <linux/list.h>
20#include <linux/clk.h> 20#include <linux/pm_runtime.h>
21#include <linux/io.h> 21#include <linux/io.h>
22#include <linux/slab.h>
22#include <sound/core.h> 23#include <sound/core.h>
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/initval.h> 25#include <sound/initval.h>
@@ -26,8 +27,6 @@
26#include <sound/pcm_params.h> 27#include <sound/pcm_params.h>
27#include <sound/sh_fsi.h> 28#include <sound/sh_fsi.h>
28#include <asm/atomic.h> 29#include <asm/atomic.h>
29#include <asm/dma.h>
30#include <asm/dma-sh.h>
31 30
32#define DO_FMT 0x0000 31#define DO_FMT 0x0000
33#define DOFF_CTL 0x0004 32#define DOFF_CTL 0x0004
@@ -69,6 +68,7 @@
69/* DOFF_ST */ 68/* DOFF_ST */
70#define ERR_OVER 0x00000010 69#define ERR_OVER 0x00000010
71#define ERR_UNDER 0x00000001 70#define ERR_UNDER 0x00000001
71#define ST_ERR (ERR_OVER | ERR_UNDER)
72 72
73/* CLK_RST */ 73/* CLK_RST */
74#define B_CLK 0x00000010 74#define B_CLK 0x00000010
@@ -94,10 +94,10 @@
94struct fsi_priv { 94struct fsi_priv {
95 void __iomem *base; 95 void __iomem *base;
96 struct snd_pcm_substream *substream; 96 struct snd_pcm_substream *substream;
97 struct fsi_master *master;
97 98
98 int fifo_max; 99 int fifo_max;
99 int chan; 100 int chan;
100 int dma_chan;
101 101
102 int byte_offset; 102 int byte_offset;
103 int period_len; 103 int period_len;
@@ -108,14 +108,12 @@ struct fsi_priv {
108struct fsi_master { 108struct fsi_master {
109 void __iomem *base; 109 void __iomem *base;
110 int irq; 110 int irq;
111 struct clk *clk;
112 struct fsi_priv fsia; 111 struct fsi_priv fsia;
113 struct fsi_priv fsib; 112 struct fsi_priv fsib;
114 struct sh_fsi_platform_info *info; 113 struct sh_fsi_platform_info *info;
114 spinlock_t lock;
115}; 115};
116 116
117static struct fsi_master *master;
118
119/************************************************************************ 117/************************************************************************
120 118
121 119
@@ -123,35 +121,35 @@ static struct fsi_master *master;
123 121
124 122
125************************************************************************/ 123************************************************************************/
126static int __fsi_reg_write(u32 reg, u32 data) 124static void __fsi_reg_write(u32 reg, u32 data)
127{ 125{
128 /* valid data area is 24bit */ 126 /* valid data area is 24bit */
129 data &= 0x00ffffff; 127 data &= 0x00ffffff;
130 128
131 return ctrl_outl(data, reg); 129 __raw_writel(data, reg);
132} 130}
133 131
134static u32 __fsi_reg_read(u32 reg) 132static u32 __fsi_reg_read(u32 reg)
135{ 133{
136 return ctrl_inl(reg); 134 return __raw_readl(reg);
137} 135}
138 136
139static int __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) 137static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data)
140{ 138{
141 u32 val = __fsi_reg_read(reg); 139 u32 val = __fsi_reg_read(reg);
142 140
143 val &= ~mask; 141 val &= ~mask;
144 val |= data & mask; 142 val |= data & mask;
145 143
146 return __fsi_reg_write(reg, val); 144 __fsi_reg_write(reg, val);
147} 145}
148 146
149static int fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) 147static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data)
150{ 148{
151 if (reg > REG_END) 149 if (reg > REG_END)
152 return -1; 150 return;
153 151
154 return __fsi_reg_write((u32)(fsi->base + reg), data); 152 __fsi_reg_write((u32)(fsi->base + reg), data);
155} 153}
156 154
157static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) 155static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
@@ -162,39 +160,55 @@ static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg)
162 return __fsi_reg_read((u32)(fsi->base + reg)); 160 return __fsi_reg_read((u32)(fsi->base + reg));
163} 161}
164 162
165static int fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) 163static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data)
166{ 164{
167 if (reg > REG_END) 165 if (reg > REG_END)
168 return -1; 166 return;
169 167
170 return __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); 168 __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data);
171} 169}
172 170
173static int fsi_master_write(u32 reg, u32 data) 171static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data)
174{ 172{
173 unsigned long flags;
174
175 if ((reg < MREG_START) || 175 if ((reg < MREG_START) ||
176 (reg > MREG_END)) 176 (reg > MREG_END))
177 return -1; 177 return;
178 178
179 return __fsi_reg_write((u32)(master->base + reg), data); 179 spin_lock_irqsave(&master->lock, flags);
180 __fsi_reg_write((u32)(master->base + reg), data);
181 spin_unlock_irqrestore(&master->lock, flags);
180} 182}
181 183
182static u32 fsi_master_read(u32 reg) 184static u32 fsi_master_read(struct fsi_master *master, u32 reg)
183{ 185{
186 u32 ret;
187 unsigned long flags;
188
184 if ((reg < MREG_START) || 189 if ((reg < MREG_START) ||
185 (reg > MREG_END)) 190 (reg > MREG_END))
186 return 0; 191 return 0;
187 192
188 return __fsi_reg_read((u32)(master->base + reg)); 193 spin_lock_irqsave(&master->lock, flags);
194 ret = __fsi_reg_read((u32)(master->base + reg));
195 spin_unlock_irqrestore(&master->lock, flags);
196
197 return ret;
189} 198}
190 199
191static int fsi_master_mask_set(u32 reg, u32 mask, u32 data) 200static void fsi_master_mask_set(struct fsi_master *master,
201 u32 reg, u32 mask, u32 data)
192{ 202{
203 unsigned long flags;
204
193 if ((reg < MREG_START) || 205 if ((reg < MREG_START) ||
194 (reg > MREG_END)) 206 (reg > MREG_END))
195 return -1; 207 return;
196 208
197 return __fsi_reg_mask_set((u32)(master->base + reg), mask, data); 209 spin_lock_irqsave(&master->lock, flags);
210 __fsi_reg_mask_set((u32)(master->base + reg), mask, data);
211 spin_unlock_irqrestore(&master->lock, flags);
198} 212}
199 213
200/************************************************************************ 214/************************************************************************
@@ -204,43 +218,35 @@ static int fsi_master_mask_set(u32 reg, u32 mask, u32 data)
204 218
205 219
206************************************************************************/ 220************************************************************************/
207static struct fsi_priv *fsi_get(struct snd_pcm_substream *substream) 221static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
208{ 222{
209 struct snd_soc_pcm_runtime *rtd; 223 return fsi->master;
210 struct fsi_priv *fsi = NULL; 224}
211 225
212 if (!substream || !master) 226static int fsi_is_port_a(struct fsi_priv *fsi)
213 return NULL; 227{
228 return fsi->master->base == fsi->base;
229}
214 230
215 rtd = substream->private_data; 231static struct snd_soc_dai *fsi_get_dai(struct snd_pcm_substream *substream)
216 switch (rtd->dai->cpu_dai->id) { 232{
217 case 0: 233 struct snd_soc_pcm_runtime *rtd = substream->private_data;
218 fsi = &master->fsia; 234 struct snd_soc_dai_link *machine = rtd->dai;
219 break;
220 case 1:
221 fsi = &master->fsib;
222 break;
223 }
224 235
225 return fsi; 236 return machine->cpu_dai;
226} 237}
227 238
228static int fsi_is_port_a(struct fsi_priv *fsi) 239static struct fsi_priv *fsi_get_priv(struct snd_pcm_substream *substream)
229{ 240{
230 /* return 241 struct snd_soc_dai *dai = fsi_get_dai(substream);
231 * 1 : port a
232 * 0 : port b
233 */
234
235 if (fsi == &master->fsia)
236 return 1;
237 242
238 return 0; 243 return dai->private_data;
239} 244}
240 245
241static u32 fsi_get_info_flags(struct fsi_priv *fsi) 246static u32 fsi_get_info_flags(struct fsi_priv *fsi)
242{ 247{
243 int is_porta = fsi_is_port_a(fsi); 248 int is_porta = fsi_is_port_a(fsi);
249 struct fsi_master *master = fsi_get_master(fsi);
244 250
245 return is_porta ? master->info->porta_flags : 251 return is_porta ? master->info->porta_flags :
246 master->info->portb_flags; 252 master->info->portb_flags;
@@ -308,62 +314,6 @@ static int fsi_get_fifo_residue(struct fsi_priv *fsi, int is_play)
308 return residue; 314 return residue;
309} 315}
310 316
311static int fsi_get_residue(struct fsi_priv *fsi, int is_play)
312{
313 int residue;
314 int width;
315 struct snd_pcm_runtime *runtime;
316
317 runtime = fsi->substream->runtime;
318
319 /* get 1 channel data width */
320 width = frames_to_bytes(runtime, 1) / fsi->chan;
321
322 if (2 == width)
323 residue = fsi_get_fifo_residue(fsi, is_play);
324 else
325 residue = get_dma_residue(fsi->dma_chan);
326
327 return residue;
328}
329
330/************************************************************************
331
332
333 basic dma function
334
335
336************************************************************************/
337#define PORTA_DMA 0
338#define PORTB_DMA 1
339
340static int fsi_get_dma_chan(void)
341{
342 if (0 != request_dma(PORTA_DMA, "fsia"))
343 return -EIO;
344
345 if (0 != request_dma(PORTB_DMA, "fsib")) {
346 free_dma(PORTA_DMA);
347 return -EIO;
348 }
349
350 master->fsia.dma_chan = PORTA_DMA;
351 master->fsib.dma_chan = PORTB_DMA;
352
353 return 0;
354}
355
356static void fsi_free_dma_chan(void)
357{
358 dma_wait_for_completion(PORTA_DMA);
359 dma_wait_for_completion(PORTB_DMA);
360 free_dma(PORTA_DMA);
361 free_dma(PORTB_DMA);
362
363 master->fsia.dma_chan = -1;
364 master->fsib.dma_chan = -1;
365}
366
367/************************************************************************ 317/************************************************************************
368 318
369 319
@@ -374,27 +324,30 @@ static void fsi_free_dma_chan(void)
374static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) 324static void fsi_irq_enable(struct fsi_priv *fsi, int is_play)
375{ 325{
376 u32 data = fsi_port_ab_io_bit(fsi, is_play); 326 u32 data = fsi_port_ab_io_bit(fsi, is_play);
327 struct fsi_master *master = fsi_get_master(fsi);
377 328
378 fsi_master_mask_set(IMSK, data, data); 329 fsi_master_mask_set(master, IMSK, data, data);
379 fsi_master_mask_set(IEMSK, data, data); 330 fsi_master_mask_set(master, IEMSK, data, data);
380} 331}
381 332
382static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) 333static void fsi_irq_disable(struct fsi_priv *fsi, int is_play)
383{ 334{
384 u32 data = fsi_port_ab_io_bit(fsi, is_play); 335 u32 data = fsi_port_ab_io_bit(fsi, is_play);
336 struct fsi_master *master = fsi_get_master(fsi);
385 337
386 fsi_master_mask_set(IMSK, data, 0); 338 fsi_master_mask_set(master, IMSK, data, 0);
387 fsi_master_mask_set(IEMSK, data, 0); 339 fsi_master_mask_set(master, IEMSK, data, 0);
388} 340}
389 341
390static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable) 342static void fsi_clk_ctrl(struct fsi_priv *fsi, int enable)
391{ 343{
392 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4); 344 u32 val = fsi_is_port_a(fsi) ? (1 << 0) : (1 << 4);
345 struct fsi_master *master = fsi_get_master(fsi);
393 346
394 if (enable) 347 if (enable)
395 fsi_master_mask_set(CLK_RST, val, val); 348 fsi_master_mask_set(master, CLK_RST, val, val);
396 else 349 else
397 fsi_master_mask_set(CLK_RST, val, 0); 350 fsi_master_mask_set(master, CLK_RST, val, 0);
398} 351}
399 352
400static void fsi_irq_init(struct fsi_priv *fsi, int is_play) 353static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
@@ -415,79 +368,46 @@ static void fsi_irq_init(struct fsi_priv *fsi, int is_play)
415 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); 368 fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR);
416 369
417 /* clear interrupt factor */ 370 /* clear interrupt factor */
418 fsi_master_mask_set(INT_ST, data, 0); 371 fsi_master_mask_set(fsi_get_master(fsi), INT_ST, data, 0);
419} 372}
420 373
421static void fsi_soft_all_reset(void) 374static void fsi_soft_all_reset(struct fsi_master *master)
422{ 375{
423 u32 status = fsi_master_read(SOFT_RST); 376 u32 status = fsi_master_read(master, SOFT_RST);
424 377
425 /* port AB reset */ 378 /* port AB reset */
426 status &= 0x000000ff; 379 status &= 0x000000ff;
427 fsi_master_write(SOFT_RST, status); 380 fsi_master_write(master, SOFT_RST, status);
428 mdelay(10); 381 mdelay(10);
429 382
430 /* soft reset */ 383 /* soft reset */
431 status &= 0x000000f0; 384 status &= 0x000000f0;
432 fsi_master_write(SOFT_RST, status); 385 fsi_master_write(master, SOFT_RST, status);
433 status |= 0x00000001; 386 status |= 0x00000001;
434 fsi_master_write(SOFT_RST, status); 387 fsi_master_write(master, SOFT_RST, status);
435 mdelay(10); 388 mdelay(10);
436} 389}
437 390
438static void fsi_16data_push(struct fsi_priv *fsi,
439 struct snd_pcm_runtime *runtime,
440 int send)
441{
442 u16 *dma_start;
443 u32 snd;
444 int i;
445
446 /* get dma start position for FSI */
447 dma_start = (u16 *)runtime->dma_area;
448 dma_start += fsi->byte_offset / 2;
449
450 /*
451 * soft dma
452 * FSI can not use DMA when 16bpp
453 */
454 for (i = 0; i < send; i++) {
455 snd = (u32)dma_start[i];
456 fsi_reg_write(fsi, DODT, snd << 8);
457 }
458}
459
460static void fsi_32data_push(struct fsi_priv *fsi,
461 struct snd_pcm_runtime *runtime,
462 int send)
463{
464 u32 *dma_start;
465
466 /* get dma start position for FSI */
467 dma_start = (u32 *)runtime->dma_area;
468 dma_start += fsi->byte_offset / 4;
469
470 dma_wait_for_completion(fsi->dma_chan);
471 dma_configure_channel(fsi->dma_chan, (SM_INC|0x400|TS_32|TM_BUR));
472 dma_write(fsi->dma_chan, (u32)dma_start,
473 (u32)(fsi->base + DODT), send * 4);
474}
475
476/* playback interrupt */ 391/* playback interrupt */
477static int fsi_data_push(struct fsi_priv *fsi) 392static int fsi_data_push(struct fsi_priv *fsi, int startup)
478{ 393{
479 struct snd_pcm_runtime *runtime; 394 struct snd_pcm_runtime *runtime;
480 struct snd_pcm_substream *substream = NULL; 395 struct snd_pcm_substream *substream = NULL;
396 u32 status;
481 int send; 397 int send;
482 int fifo_free; 398 int fifo_free;
483 int width; 399 int width;
400 u8 *start;
401 int i, over_period;
484 402
485 if (!fsi || 403 if (!fsi ||
486 !fsi->substream || 404 !fsi->substream ||
487 !fsi->substream->runtime) 405 !fsi->substream->runtime)
488 return -EINVAL; 406 return -EINVAL;
489 407
490 runtime = fsi->substream->runtime; 408 over_period = 0;
409 substream = fsi->substream;
410 runtime = substream->runtime;
491 411
492 /* FSI FIFO has limit. 412 /* FSI FIFO has limit.
493 * So, this driver can not send periods data at a time 413 * So, this driver can not send periods data at a time
@@ -495,7 +415,7 @@ static int fsi_data_push(struct fsi_priv *fsi)
495 if (fsi->byte_offset >= 415 if (fsi->byte_offset >=
496 fsi->period_len * (fsi->periods + 1)) { 416 fsi->period_len * (fsi->periods + 1)) {
497 417
498 substream = fsi->substream; 418 over_period = 1;
499 fsi->periods = (fsi->periods + 1) % runtime->periods; 419 fsi->periods = (fsi->periods + 1) % runtime->periods;
500 420
501 if (0 == fsi->periods) 421 if (0 == fsi->periods)
@@ -515,18 +435,122 @@ static int fsi_data_push(struct fsi_priv *fsi)
515 if (fifo_free < send) 435 if (fifo_free < send)
516 send = fifo_free; 436 send = fifo_free;
517 437
518 if (2 == width) 438 start = runtime->dma_area;
519 fsi_16data_push(fsi, runtime, send); 439 start += fsi->byte_offset;
520 else if (4 == width) 440
521 fsi_32data_push(fsi, runtime, send); 441 switch (width) {
522 else 442 case 2:
443 for (i = 0; i < send; i++)
444 fsi_reg_write(fsi, DODT,
445 ((u32)*((u16 *)start + i) << 8));
446 break;
447 case 4:
448 for (i = 0; i < send; i++)
449 fsi_reg_write(fsi, DODT, *((u32 *)start + i));
450 break;
451 default:
523 return -EINVAL; 452 return -EINVAL;
453 }
524 454
525 fsi->byte_offset += send * width; 455 fsi->byte_offset += send * width;
526 456
457 status = fsi_reg_read(fsi, DOFF_ST);
458 if (!startup) {
459 struct snd_soc_dai *dai = fsi_get_dai(substream);
460
461 if (status & ERR_OVER)
462 dev_err(dai->dev, "over run\n");
463 if (status & ERR_UNDER)
464 dev_err(dai->dev, "under run\n");
465 }
466 fsi_reg_write(fsi, DOFF_ST, 0);
467
527 fsi_irq_enable(fsi, 1); 468 fsi_irq_enable(fsi, 1);
528 469
529 if (substream) 470 if (over_period)
471 snd_pcm_period_elapsed(substream);
472
473 return 0;
474}
475
476static int fsi_data_pop(struct fsi_priv *fsi, int startup)
477{
478 struct snd_pcm_runtime *runtime;
479 struct snd_pcm_substream *substream = NULL;
480 u32 status;
481 int free;
482 int fifo_fill;
483 int width;
484 u8 *start;
485 int i, over_period;
486
487 if (!fsi ||
488 !fsi->substream ||
489 !fsi->substream->runtime)
490 return -EINVAL;
491
492 over_period = 0;
493 substream = fsi->substream;
494 runtime = substream->runtime;
495
496 /* FSI FIFO has limit.
497 * So, this driver can not send periods data at a time
498 */
499 if (fsi->byte_offset >=
500 fsi->period_len * (fsi->periods + 1)) {
501
502 over_period = 1;
503 fsi->periods = (fsi->periods + 1) % runtime->periods;
504
505 if (0 == fsi->periods)
506 fsi->byte_offset = 0;
507 }
508
509 /* get 1 channel data width */
510 width = frames_to_bytes(runtime, 1) / fsi->chan;
511
512 /* get free space for alsa */
513 free = (fsi->buffer_len - fsi->byte_offset) / width;
514
515 /* get recv size */
516 fifo_fill = fsi_get_fifo_residue(fsi, 0);
517
518 if (free < fifo_fill)
519 fifo_fill = free;
520
521 start = runtime->dma_area;
522 start += fsi->byte_offset;
523
524 switch (width) {
525 case 2:
526 for (i = 0; i < fifo_fill; i++)
527 *((u16 *)start + i) =
528 (u16)(fsi_reg_read(fsi, DIDT) >> 8);
529 break;
530 case 4:
531 for (i = 0; i < fifo_fill; i++)
532 *((u32 *)start + i) = fsi_reg_read(fsi, DIDT);
533 break;
534 default:
535 return -EINVAL;
536 }
537
538 fsi->byte_offset += fifo_fill * width;
539
540 status = fsi_reg_read(fsi, DIFF_ST);
541 if (!startup) {
542 struct snd_soc_dai *dai = fsi_get_dai(substream);
543
544 if (status & ERR_OVER)
545 dev_err(dai->dev, "over run\n");
546 if (status & ERR_UNDER)
547 dev_err(dai->dev, "under run\n");
548 }
549 fsi_reg_write(fsi, DIFF_ST, 0);
550
551 fsi_irq_enable(fsi, 0);
552
553 if (over_period)
530 snd_pcm_period_elapsed(substream); 554 snd_pcm_period_elapsed(substream);
531 555
532 return 0; 556 return 0;
@@ -534,19 +558,24 @@ static int fsi_data_push(struct fsi_priv *fsi)
534 558
535static irqreturn_t fsi_interrupt(int irq, void *data) 559static irqreturn_t fsi_interrupt(int irq, void *data)
536{ 560{
537 u32 status = fsi_master_read(SOFT_RST) & ~0x00000010; 561 struct fsi_master *master = data;
538 u32 int_st = fsi_master_read(INT_ST); 562 u32 status = fsi_master_read(master, SOFT_RST) & ~0x00000010;
563 u32 int_st = fsi_master_read(master, INT_ST);
539 564
540 /* clear irq status */ 565 /* clear irq status */
541 fsi_master_write(SOFT_RST, status); 566 fsi_master_write(master, SOFT_RST, status);
542 fsi_master_write(SOFT_RST, status | 0x00000010); 567 fsi_master_write(master, SOFT_RST, status | 0x00000010);
543 568
544 if (int_st & INT_A_OUT) 569 if (int_st & INT_A_OUT)
545 fsi_data_push(&master->fsia); 570 fsi_data_push(&master->fsia, 0);
546 if (int_st & INT_B_OUT) 571 if (int_st & INT_B_OUT)
547 fsi_data_push(&master->fsib); 572 fsi_data_push(&master->fsib, 0);
573 if (int_st & INT_A_IN)
574 fsi_data_pop(&master->fsia, 0);
575 if (int_st & INT_B_IN)
576 fsi_data_pop(&master->fsib, 0);
548 577
549 fsi_master_write(INT_ST, 0x0000000); 578 fsi_master_write(master, INT_ST, 0x0000000);
550 579
551 return IRQ_HANDLED; 580 return IRQ_HANDLED;
552} 581}
@@ -561,7 +590,7 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
561static int fsi_dai_startup(struct snd_pcm_substream *substream, 590static int fsi_dai_startup(struct snd_pcm_substream *substream,
562 struct snd_soc_dai *dai) 591 struct snd_soc_dai *dai)
563{ 592{
564 struct fsi_priv *fsi = fsi_get(substream); 593 struct fsi_priv *fsi = fsi_get_priv(substream);
565 const char *msg; 594 const char *msg;
566 u32 flags = fsi_get_info_flags(fsi); 595 u32 flags = fsi_get_info_flags(fsi);
567 u32 fmt; 596 u32 fmt;
@@ -571,7 +600,7 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
571 int is_master; 600 int is_master;
572 int ret = 0; 601 int ret = 0;
573 602
574 clk_enable(master->clk); 603 pm_runtime_get_sync(dai->dev);
575 604
576 /* CKG1 */ 605 /* CKG1 */
577 data = is_play ? (1 << 0) : (1 << 4); 606 data = is_play ? (1 << 0) : (1 << 4);
@@ -664,8 +693,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
664 } 693 }
665 694
666 fsi_reg_write(fsi, reg, data); 695 fsi_reg_write(fsi, reg, data);
667 dev_dbg(dai->dev, "use %s format (%d channel) use %d DMAC\n",
668 msg, fsi->chan, fsi->dma_chan);
669 696
670 /* 697 /*
671 * clear clk reset if master mode 698 * clear clk reset if master mode
@@ -682,33 +709,29 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream,
682static void fsi_dai_shutdown(struct snd_pcm_substream *substream, 709static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
683 struct snd_soc_dai *dai) 710 struct snd_soc_dai *dai)
684{ 711{
685 struct fsi_priv *fsi = fsi_get(substream); 712 struct fsi_priv *fsi = fsi_get_priv(substream);
686 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 713 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
687 714
688 fsi_irq_disable(fsi, is_play); 715 fsi_irq_disable(fsi, is_play);
689 fsi_clk_ctrl(fsi, 0); 716 fsi_clk_ctrl(fsi, 0);
690 717
691 clk_disable(master->clk); 718 pm_runtime_put_sync(dai->dev);
692} 719}
693 720
694static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, 721static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
695 struct snd_soc_dai *dai) 722 struct snd_soc_dai *dai)
696{ 723{
697 struct fsi_priv *fsi = fsi_get(substream); 724 struct fsi_priv *fsi = fsi_get_priv(substream);
698 struct snd_pcm_runtime *runtime = substream->runtime; 725 struct snd_pcm_runtime *runtime = substream->runtime;
699 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 726 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
700 int ret = 0; 727 int ret = 0;
701 728
702 /* capture not supported */
703 if (!is_play)
704 return -ENODEV;
705
706 switch (cmd) { 729 switch (cmd) {
707 case SNDRV_PCM_TRIGGER_START: 730 case SNDRV_PCM_TRIGGER_START:
708 fsi_stream_push(fsi, substream, 731 fsi_stream_push(fsi, substream,
709 frames_to_bytes(runtime, runtime->buffer_size), 732 frames_to_bytes(runtime, runtime->buffer_size),
710 frames_to_bytes(runtime, runtime->period_size)); 733 frames_to_bytes(runtime, runtime->period_size));
711 ret = fsi_data_push(fsi); 734 ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1);
712 break; 735 break;
713 case SNDRV_PCM_TRIGGER_STOP: 736 case SNDRV_PCM_TRIGGER_STOP:
714 fsi_irq_disable(fsi, is_play); 737 fsi_irq_disable(fsi, is_play);
@@ -779,11 +802,10 @@ static int fsi_hw_free(struct snd_pcm_substream *substream)
779static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream) 802static snd_pcm_uframes_t fsi_pointer(struct snd_pcm_substream *substream)
780{ 803{
781 struct snd_pcm_runtime *runtime = substream->runtime; 804 struct snd_pcm_runtime *runtime = substream->runtime;
782 struct fsi_priv *fsi = fsi_get(substream); 805 struct fsi_priv *fsi = fsi_get_priv(substream);
783 int is_play = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
784 long location; 806 long location;
785 807
786 location = (fsi->byte_offset - 1) - fsi_get_residue(fsi, is_play); 808 location = (fsi->byte_offset - 1);
787 if (location < 0) 809 if (location < 0)
788 location = 0; 810 location = 0;
789 811
@@ -845,7 +867,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
845 .channels_min = 1, 867 .channels_min = 1,
846 .channels_max = 8, 868 .channels_max = 8,
847 }, 869 },
848 /* capture not supported */ 870 .capture = {
871 .rates = FSI_RATES,
872 .formats = FSI_FMTS,
873 .channels_min = 1,
874 .channels_max = 8,
875 },
849 .ops = &fsi_dai_ops, 876 .ops = &fsi_dai_ops,
850 }, 877 },
851 { 878 {
@@ -857,7 +884,12 @@ struct snd_soc_dai fsi_soc_dai[] = {
857 .channels_min = 1, 884 .channels_min = 1,
858 .channels_max = 8, 885 .channels_max = 8,
859 }, 886 },
860 /* capture not supported */ 887 .capture = {
888 .rates = FSI_RATES,
889 .formats = FSI_FMTS,
890 .channels_min = 1,
891 .channels_max = 8,
892 },
861 .ops = &fsi_dai_ops, 893 .ops = &fsi_dai_ops,
862 }, 894 },
863}; 895};
@@ -880,14 +912,19 @@ EXPORT_SYMBOL_GPL(fsi_soc_platform);
880************************************************************************/ 912************************************************************************/
881static int fsi_probe(struct platform_device *pdev) 913static int fsi_probe(struct platform_device *pdev)
882{ 914{
915 struct fsi_master *master;
883 struct resource *res; 916 struct resource *res;
884 char clk_name[8];
885 unsigned int irq; 917 unsigned int irq;
886 int ret; 918 int ret;
887 919
920 if (0 != pdev->id) {
921 dev_err(&pdev->dev, "current fsi support id 0 only now\n");
922 return -ENODEV;
923 }
924
888 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 925 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
889 irq = platform_get_irq(pdev, 0); 926 irq = platform_get_irq(pdev, 0);
890 if (!res || !irq) { 927 if (!res || (int)irq <= 0) {
891 dev_err(&pdev->dev, "Not enough FSI platform resources.\n"); 928 dev_err(&pdev->dev, "Not enough FSI platform resources.\n");
892 ret = -ENODEV; 929 ret = -ENODEV;
893 goto exit; 930 goto exit;
@@ -910,35 +947,25 @@ static int fsi_probe(struct platform_device *pdev)
910 master->irq = irq; 947 master->irq = irq;
911 master->info = pdev->dev.platform_data; 948 master->info = pdev->dev.platform_data;
912 master->fsia.base = master->base; 949 master->fsia.base = master->base;
950 master->fsia.master = master;
913 master->fsib.base = master->base + 0x40; 951 master->fsib.base = master->base + 0x40;
952 master->fsib.master = master;
953 spin_lock_init(&master->lock);
914 954
915 master->fsia.dma_chan = -1; 955 pm_runtime_enable(&pdev->dev);
916 master->fsib.dma_chan = -1; 956 pm_runtime_resume(&pdev->dev);
917
918 ret = fsi_get_dma_chan();
919 if (ret < 0) {
920 dev_err(&pdev->dev, "cannot get dma api\n");
921 goto exit_iounmap;
922 }
923
924 /* FSI is based on SPU mstp */
925 snprintf(clk_name, sizeof(clk_name), "spu%d", pdev->id);
926 master->clk = clk_get(NULL, clk_name);
927 if (IS_ERR(master->clk)) {
928 dev_err(&pdev->dev, "cannot get %s mstp\n", clk_name);
929 ret = -EIO;
930 goto exit_free_dma;
931 }
932 957
933 fsi_soc_dai[0].dev = &pdev->dev; 958 fsi_soc_dai[0].dev = &pdev->dev;
959 fsi_soc_dai[0].private_data = &master->fsia;
934 fsi_soc_dai[1].dev = &pdev->dev; 960 fsi_soc_dai[1].dev = &pdev->dev;
961 fsi_soc_dai[1].private_data = &master->fsib;
935 962
936 fsi_soft_all_reset(); 963 fsi_soft_all_reset(master);
937 964
938 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master); 965 ret = request_irq(irq, &fsi_interrupt, IRQF_DISABLED, "fsi", master);
939 if (ret) { 966 if (ret) {
940 dev_err(&pdev->dev, "irq request err\n"); 967 dev_err(&pdev->dev, "irq request err\n");
941 goto exit_free_dma; 968 goto exit_iounmap;
942 } 969 }
943 970
944 ret = snd_soc_register_platform(&fsi_soc_platform); 971 ret = snd_soc_register_platform(&fsi_soc_platform);
@@ -951,10 +978,9 @@ static int fsi_probe(struct platform_device *pdev)
951 978
952exit_free_irq: 979exit_free_irq:
953 free_irq(irq, master); 980 free_irq(irq, master);
954exit_free_dma:
955 fsi_free_dma_chan();
956exit_iounmap: 981exit_iounmap:
957 iounmap(master->base); 982 iounmap(master->base);
983 pm_runtime_disable(&pdev->dev);
958exit_kfree: 984exit_kfree:
959 kfree(master); 985 kfree(master);
960 master = NULL; 986 master = NULL;
@@ -964,24 +990,49 @@ exit:
964 990
965static int fsi_remove(struct platform_device *pdev) 991static int fsi_remove(struct platform_device *pdev)
966{ 992{
993 struct fsi_master *master;
994
995 master = fsi_get_master(fsi_soc_dai[0].private_data);
996
967 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai)); 997 snd_soc_unregister_dais(fsi_soc_dai, ARRAY_SIZE(fsi_soc_dai));
968 snd_soc_unregister_platform(&fsi_soc_platform); 998 snd_soc_unregister_platform(&fsi_soc_platform);
969 999
970 clk_put(master->clk); 1000 pm_runtime_disable(&pdev->dev);
971
972 fsi_free_dma_chan();
973 1001
974 free_irq(master->irq, master); 1002 free_irq(master->irq, master);
975 1003
976 iounmap(master->base); 1004 iounmap(master->base);
977 kfree(master); 1005 kfree(master);
978 master = NULL; 1006
1007 fsi_soc_dai[0].dev = NULL;
1008 fsi_soc_dai[0].private_data = NULL;
1009 fsi_soc_dai[1].dev = NULL;
1010 fsi_soc_dai[1].private_data = NULL;
1011
1012 return 0;
1013}
1014
1015static int fsi_runtime_nop(struct device *dev)
1016{
1017 /* Runtime PM callback shared between ->runtime_suspend()
1018 * and ->runtime_resume(). Simply returns success.
1019 *
1020 * This driver re-initializes all registers after
1021 * pm_runtime_get_sync() anyway so there is no need
1022 * to save and restore registers here.
1023 */
979 return 0; 1024 return 0;
980} 1025}
981 1026
1027static struct dev_pm_ops fsi_pm_ops = {
1028 .runtime_suspend = fsi_runtime_nop,
1029 .runtime_resume = fsi_runtime_nop,
1030};
1031
982static struct platform_driver fsi_driver = { 1032static struct platform_driver fsi_driver = {
983 .driver = { 1033 .driver = {
984 .name = "sh_fsi", 1034 .name = "sh_fsi",
1035 .pm = &fsi_pm_ops,
985 }, 1036 },
986 .probe = fsi_probe, 1037 .probe = fsi_probe,
987 .remove = fsi_remove, 1038 .remove = fsi_remove,