aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/sh
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-02-03 03:55:55 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-02-03 06:55:39 -0500
commit5e97313ac483f03a9af661aada356980fe310e0d (patch)
tree884c2d0140c581dcbf38c3ff4fc11abf7e11f7c1 /sound/soc/sh
parent7b1b3331e65e47b6abb32be0a3db46bcf423145a (diff)
ASoC: fsi: add fsi_stream_handler and PIO handler
This patch adds struct fsi_stream_handler and defined fsi_pio_push/pop_handler. these are controled by fsi_steam_xxx() function. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/sh')
-rw-r--r--sound/soc/sh/fsi.c133
1 files changed, 118 insertions, 15 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 24dbe165eda8..b02886ad6f87 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -159,18 +159,27 @@ typedef int (*set_rate_func)(struct device *dev, int is_porta, int rate, int ena
159 * struct 159 * struct
160 */ 160 */
161 161
162struct fsi_stream_handler;
162struct fsi_stream { 163struct fsi_stream {
163 struct snd_pcm_substream *substream;
164 164
165 /*
166 * these are initialized by fsi_stream_init()
167 */
168 struct snd_pcm_substream *substream;
165 int fifo_sample_capa; /* sample capacity of FSI FIFO */ 169 int fifo_sample_capa; /* sample capacity of FSI FIFO */
166 int buff_sample_capa; /* sample capacity of ALSA buffer */ 170 int buff_sample_capa; /* sample capacity of ALSA buffer */
167 int buff_sample_pos; /* sample position of ALSA buffer */ 171 int buff_sample_pos; /* sample position of ALSA buffer */
168 int period_samples; /* sample number / 1 period */ 172 int period_samples; /* sample number / 1 period */
169 int period_pos; /* current period position */ 173 int period_pos; /* current period position */
170 int sample_width; /* sample width */ 174 int sample_width; /* sample width */
171
172 int uerr_num; 175 int uerr_num;
173 int oerr_num; 176 int oerr_num;
177
178 /*
179 * thse are initialized by fsi_handler_init()
180 */
181 struct fsi_stream_handler *handler;
182 struct fsi_priv *priv;
174}; 183};
175 184
176struct fsi_priv { 185struct fsi_priv {
@@ -190,6 +199,16 @@ struct fsi_priv {
190 long rate; 199 long rate;
191}; 200};
192 201
202struct fsi_stream_handler {
203 int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io);
204 int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io);
205 int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io);
206};
207#define fsi_stream_handler_call(io, func, args...) \
208 (!(io) ? -ENODEV : \
209 !((io)->handler->func) ? 0 : \
210 (io)->handler->func(args))
211
193struct fsi_core { 212struct fsi_core {
194 int ver; 213 int ver;
195 214
@@ -435,6 +454,11 @@ static int fsi_stream_is_working(struct fsi_priv *fsi,
435 return ret; 454 return ret;
436} 455}
437 456
457static struct fsi_priv *fsi_stream_to_priv(struct fsi_stream *io)
458{
459 return io->priv;
460}
461
438static void fsi_stream_init(struct fsi_priv *fsi, 462static void fsi_stream_init(struct fsi_priv *fsi,
439 int is_play, 463 int is_play,
440 struct snd_pcm_substream *substream) 464 struct snd_pcm_substream *substream)
@@ -482,6 +506,53 @@ static void fsi_stream_quit(struct fsi_priv *fsi, int is_play)
482 spin_unlock_irqrestore(&master->lock, flags); 506 spin_unlock_irqrestore(&master->lock, flags);
483} 507}
484 508
509static int fsi_stream_transfer(struct fsi_stream *io)
510{
511 struct fsi_priv *fsi = fsi_stream_to_priv(io);
512 if (!fsi)
513 return -EIO;
514
515 return fsi_stream_handler_call(io, transfer, fsi, io);
516}
517
518static int fsi_stream_probe(struct fsi_priv *fsi)
519{
520 struct fsi_stream *io;
521 int ret1, ret2;
522
523 io = &fsi->playback;
524 ret1 = fsi_stream_handler_call(io, probe, fsi, io);
525
526 io = &fsi->capture;
527 ret2 = fsi_stream_handler_call(io, probe, fsi, io);
528
529 if (ret1 < 0)
530 return ret1;
531 if (ret2 < 0)
532 return ret2;
533
534 return 0;
535}
536
537static int fsi_stream_remove(struct fsi_priv *fsi)
538{
539 struct fsi_stream *io;
540 int ret1, ret2;
541
542 io = &fsi->playback;
543 ret1 = fsi_stream_handler_call(io, remove, fsi, io);
544
545 io = &fsi->capture;
546 ret2 = fsi_stream_handler_call(io, remove, fsi, io);
547
548 if (ret1 < 0)
549 return ret1;
550 if (ret2 < 0)
551 return ret2;
552
553 return 0;
554}
555
485/* 556/*
486 * pio function 557 * pio function
487 */ 558 */
@@ -743,13 +814,11 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, struct fsi_stream *io,
743 return 0; 814 return 0;
744} 815}
745 816
746static int fsi_data_pop(struct fsi_priv *fsi) 817static int fsi_pio_pop(struct fsi_priv *fsi, struct fsi_stream *io)
747{ 818{
748 int is_play = 0;
749 int sample_residues; /* samples in FSI fifo */ 819 int sample_residues; /* samples in FSI fifo */
750 int sample_space; /* ALSA free samples space */ 820 int sample_space; /* ALSA free samples space */
751 int samples; 821 int samples;
752 struct fsi_stream *io = fsi_stream_get(fsi, is_play);
753 822
754 sample_residues = fsi_get_current_fifo_samples(fsi, io); 823 sample_residues = fsi_get_current_fifo_samples(fsi, io);
755 sample_space = io->buff_sample_capa - io->buff_sample_pos; 824 sample_space = io->buff_sample_capa - io->buff_sample_pos;
@@ -762,13 +831,11 @@ static int fsi_data_pop(struct fsi_priv *fsi)
762 samples); 831 samples);
763} 832}
764 833
765static int fsi_data_push(struct fsi_priv *fsi) 834static int fsi_pio_push(struct fsi_priv *fsi, struct fsi_stream *io)
766{ 835{
767 int is_play = 1;
768 int sample_residues; /* ALSA residue samples */ 836 int sample_residues; /* ALSA residue samples */
769 int sample_space; /* FSI fifo free samples space */ 837 int sample_space; /* FSI fifo free samples space */
770 int samples; 838 int samples;
771 struct fsi_stream *io = fsi_stream_get(fsi, is_play);
772 839
773 sample_residues = io->buff_sample_capa - io->buff_sample_pos; 840 sample_residues = io->buff_sample_capa - io->buff_sample_pos;
774 sample_space = io->fifo_sample_capa - 841 sample_space = io->fifo_sample_capa -
@@ -782,6 +849,14 @@ static int fsi_data_push(struct fsi_priv *fsi)
782 samples); 849 samples);
783} 850}
784 851
852static struct fsi_stream_handler fsi_pio_push_handler = {
853 .transfer = fsi_pio_push,
854};
855
856static struct fsi_stream_handler fsi_pio_pop_handler = {
857 .transfer = fsi_pio_pop,
858};
859
785static irqreturn_t fsi_interrupt(int irq, void *data) 860static irqreturn_t fsi_interrupt(int irq, void *data)
786{ 861{
787 struct fsi_master *master = data; 862 struct fsi_master *master = data;
@@ -792,13 +867,13 @@ static irqreturn_t fsi_interrupt(int irq, void *data)
792 fsi_master_mask_set(master, SOFT_RST, IR, IR); 867 fsi_master_mask_set(master, SOFT_RST, IR, IR);
793 868
794 if (int_st & AB_IO(1, AO_SHIFT)) 869 if (int_st & AB_IO(1, AO_SHIFT))
795 fsi_data_push(&master->fsia); 870 fsi_stream_transfer(&master->fsia.playback);
796 if (int_st & AB_IO(1, BO_SHIFT)) 871 if (int_st & AB_IO(1, BO_SHIFT))
797 fsi_data_push(&master->fsib); 872 fsi_stream_transfer(&master->fsib.playback);
798 if (int_st & AB_IO(1, AI_SHIFT)) 873 if (int_st & AB_IO(1, AI_SHIFT))
799 fsi_data_pop(&master->fsia); 874 fsi_stream_transfer(&master->fsia.capture);
800 if (int_st & AB_IO(1, BI_SHIFT)) 875 if (int_st & AB_IO(1, BI_SHIFT))
801 fsi_data_pop(&master->fsib); 876 fsi_stream_transfer(&master->fsib.capture);
802 877
803 fsi_count_fifo_err(&master->fsia); 878 fsi_count_fifo_err(&master->fsia);
804 fsi_count_fifo_err(&master->fsib); 879 fsi_count_fifo_err(&master->fsib);
@@ -955,14 +1030,16 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd,
955 struct snd_soc_dai *dai) 1030 struct snd_soc_dai *dai)
956{ 1031{
957 struct fsi_priv *fsi = fsi_get_priv(substream); 1032 struct fsi_priv *fsi = fsi_get_priv(substream);
1033 struct fsi_stream *io = fsi_stream_get(fsi, fsi_is_play(substream));
958 int is_play = fsi_is_play(substream); 1034 int is_play = fsi_is_play(substream);
959 int ret = 0; 1035 int ret = 0;
960 1036
961 switch (cmd) { 1037 switch (cmd) {
962 case SNDRV_PCM_TRIGGER_START: 1038 case SNDRV_PCM_TRIGGER_START:
963 fsi_stream_init(fsi, is_play, substream); 1039 fsi_stream_init(fsi, is_play, substream);
964 ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); 1040 ret = fsi_stream_transfer(io);
965 fsi_port_start(fsi, is_play); 1041 if (0 == ret)
1042 fsi_port_start(fsi, is_play);
966 break; 1043 break;
967 case SNDRV_PCM_TRIGGER_STOP: 1044 case SNDRV_PCM_TRIGGER_STOP:
968 fsi_port_stop(fsi, is_play); 1045 fsi_port_stop(fsi, is_play);
@@ -1224,6 +1301,13 @@ static struct snd_soc_platform_driver fsi_soc_platform = {
1224/* 1301/*
1225 * platform function 1302 * platform function
1226 */ 1303 */
1304static void fsi_handler_init(struct fsi_priv *fsi)
1305{
1306 fsi->playback.handler = &fsi_pio_push_handler; /* default PIO */
1307 fsi->playback.priv = fsi;
1308 fsi->capture.handler = &fsi_pio_pop_handler; /* default PIO */
1309 fsi->capture.priv = fsi;
1310}
1227 1311
1228static int fsi_probe(struct platform_device *pdev) 1312static int fsi_probe(struct platform_device *pdev)
1229{ 1313{
@@ -1270,10 +1354,22 @@ static int fsi_probe(struct platform_device *pdev)
1270 /* FSI A setting */ 1354 /* FSI A setting */
1271 master->fsia.base = master->base; 1355 master->fsia.base = master->base;
1272 master->fsia.master = master; 1356 master->fsia.master = master;
1357 fsi_handler_init(&master->fsia);
1358 ret = fsi_stream_probe(&master->fsia);
1359 if (ret < 0) {
1360 dev_err(&pdev->dev, "FSIA stream probe failed\n");
1361 goto exit_iounmap;
1362 }
1273 1363
1274 /* FSI B setting */ 1364 /* FSI B setting */
1275 master->fsib.base = master->base + 0x40; 1365 master->fsib.base = master->base + 0x40;
1276 master->fsib.master = master; 1366 master->fsib.master = master;
1367 fsi_handler_init(&master->fsib);
1368 ret = fsi_stream_probe(&master->fsib);
1369 if (ret < 0) {
1370 dev_err(&pdev->dev, "FSIB stream probe failed\n");
1371 goto exit_fsia;
1372 }
1277 1373
1278 pm_runtime_enable(&pdev->dev); 1374 pm_runtime_enable(&pdev->dev);
1279 dev_set_drvdata(&pdev->dev, master); 1375 dev_set_drvdata(&pdev->dev, master);
@@ -1282,7 +1378,7 @@ static int fsi_probe(struct platform_device *pdev)
1282 id_entry->name, master); 1378 id_entry->name, master);
1283 if (ret) { 1379 if (ret) {
1284 dev_err(&pdev->dev, "irq request err\n"); 1380 dev_err(&pdev->dev, "irq request err\n");
1285 goto exit_iounmap; 1381 goto exit_fsib;
1286 } 1382 }
1287 1383
1288 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform); 1384 ret = snd_soc_register_platform(&pdev->dev, &fsi_soc_platform);
@@ -1304,6 +1400,10 @@ exit_snd_soc:
1304 snd_soc_unregister_platform(&pdev->dev); 1400 snd_soc_unregister_platform(&pdev->dev);
1305exit_free_irq: 1401exit_free_irq:
1306 free_irq(irq, master); 1402 free_irq(irq, master);
1403exit_fsib:
1404 fsi_stream_remove(&master->fsib);
1405exit_fsia:
1406 fsi_stream_remove(&master->fsia);
1307exit_iounmap: 1407exit_iounmap:
1308 iounmap(master->base); 1408 iounmap(master->base);
1309 pm_runtime_disable(&pdev->dev); 1409 pm_runtime_disable(&pdev->dev);
@@ -1326,6 +1426,9 @@ static int fsi_remove(struct platform_device *pdev)
1326 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai)); 1426 snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(fsi_soc_dai));
1327 snd_soc_unregister_platform(&pdev->dev); 1427 snd_soc_unregister_platform(&pdev->dev);
1328 1428
1429 fsi_stream_remove(&master->fsia);
1430 fsi_stream_remove(&master->fsib);
1431
1329 iounmap(master->base); 1432 iounmap(master->base);
1330 kfree(master); 1433 kfree(master);
1331 1434