diff options
Diffstat (limited to 'sound/soc/sh/fsi.c')
-rw-r--r-- | sound/soc/sh/fsi.c | 48 |
1 files changed, 24 insertions, 24 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 2ef98536f1da..53486ff9c2af 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c | |||
@@ -247,7 +247,7 @@ struct fsi_priv { | |||
247 | struct fsi_stream_handler { | 247 | struct fsi_stream_handler { |
248 | int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); | 248 | int (*init)(struct fsi_priv *fsi, struct fsi_stream *io); |
249 | int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); | 249 | int (*quit)(struct fsi_priv *fsi, struct fsi_stream *io); |
250 | int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io); | 250 | int (*probe)(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev); |
251 | int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); | 251 | int (*transfer)(struct fsi_priv *fsi, struct fsi_stream *io); |
252 | int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); | 252 | int (*remove)(struct fsi_priv *fsi, struct fsi_stream *io); |
253 | void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, | 253 | void (*start_stop)(struct fsi_priv *fsi, struct fsi_stream *io, |
@@ -571,16 +571,16 @@ static int fsi_stream_transfer(struct fsi_stream *io) | |||
571 | #define fsi_stream_stop(fsi, io)\ | 571 | #define fsi_stream_stop(fsi, io)\ |
572 | fsi_stream_handler_call(io, start_stop, fsi, io, 0) | 572 | fsi_stream_handler_call(io, start_stop, fsi, io, 0) |
573 | 573 | ||
574 | static int fsi_stream_probe(struct fsi_priv *fsi) | 574 | static int fsi_stream_probe(struct fsi_priv *fsi, struct device *dev) |
575 | { | 575 | { |
576 | struct fsi_stream *io; | 576 | struct fsi_stream *io; |
577 | int ret1, ret2; | 577 | int ret1, ret2; |
578 | 578 | ||
579 | io = &fsi->playback; | 579 | io = &fsi->playback; |
580 | ret1 = fsi_stream_handler_call(io, probe, fsi, io); | 580 | ret1 = fsi_stream_handler_call(io, probe, fsi, io, dev); |
581 | 581 | ||
582 | io = &fsi->capture; | 582 | io = &fsi->capture; |
583 | ret2 = fsi_stream_handler_call(io, probe, fsi, io); | 583 | ret2 = fsi_stream_handler_call(io, probe, fsi, io, dev); |
584 | 584 | ||
585 | if (ret1 < 0) | 585 | if (ret1 < 0) |
586 | return ret1; | 586 | return ret1; |
@@ -1089,13 +1089,10 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1089 | { | 1089 | { |
1090 | struct fsi_stream *io = (struct fsi_stream *)data; | 1090 | struct fsi_stream *io = (struct fsi_stream *)data; |
1091 | struct fsi_priv *fsi = fsi_stream_to_priv(io); | 1091 | struct fsi_priv *fsi = fsi_stream_to_priv(io); |
1092 | struct dma_chan *chan; | ||
1093 | struct snd_soc_dai *dai; | 1092 | struct snd_soc_dai *dai; |
1094 | struct dma_async_tx_descriptor *desc; | 1093 | struct dma_async_tx_descriptor *desc; |
1095 | struct scatterlist sg; | ||
1096 | struct snd_pcm_runtime *runtime; | 1094 | struct snd_pcm_runtime *runtime; |
1097 | enum dma_data_direction dir; | 1095 | enum dma_data_direction dir; |
1098 | dma_cookie_t cookie; | ||
1099 | int is_play = fsi_stream_is_play(fsi, io); | 1096 | int is_play = fsi_stream_is_play(fsi, io); |
1100 | int len; | 1097 | int len; |
1101 | dma_addr_t buf; | 1098 | dma_addr_t buf; |
@@ -1104,7 +1101,6 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1104 | return; | 1101 | return; |
1105 | 1102 | ||
1106 | dai = fsi_get_dai(io->substream); | 1103 | dai = fsi_get_dai(io->substream); |
1107 | chan = io->chan; | ||
1108 | runtime = io->substream->runtime; | 1104 | runtime = io->substream->runtime; |
1109 | dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | 1105 | dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; |
1110 | len = samples_to_bytes(runtime, io->period_samples); | 1106 | len = samples_to_bytes(runtime, io->period_samples); |
@@ -1112,14 +1108,8 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1112 | 1108 | ||
1113 | dma_sync_single_for_device(dai->dev, buf, len, dir); | 1109 | dma_sync_single_for_device(dai->dev, buf, len, dir); |
1114 | 1110 | ||
1115 | sg_init_table(&sg, 1); | 1111 | desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, |
1116 | sg_set_page(&sg, pfn_to_page(PFN_DOWN(buf)), | 1112 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
1117 | len , offset_in_page(buf)); | ||
1118 | sg_dma_address(&sg) = buf; | ||
1119 | sg_dma_len(&sg) = len; | ||
1120 | |||
1121 | desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, | ||
1122 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
1123 | if (!desc) { | 1113 | if (!desc) { |
1124 | dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); | 1114 | dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); |
1125 | return; | 1115 | return; |
@@ -1128,13 +1118,12 @@ static void fsi_dma_do_tasklet(unsigned long data) | |||
1128 | desc->callback = fsi_dma_complete; | 1118 | desc->callback = fsi_dma_complete; |
1129 | desc->callback_param = io; | 1119 | desc->callback_param = io; |
1130 | 1120 | ||
1131 | cookie = desc->tx_submit(desc); | 1121 | if (dmaengine_submit(desc) < 0) { |
1132 | if (cookie < 0) { | ||
1133 | dev_err(dai->dev, "tx_submit() fail\n"); | 1122 | dev_err(dai->dev, "tx_submit() fail\n"); |
1134 | return; | 1123 | return; |
1135 | } | 1124 | } |
1136 | 1125 | ||
1137 | dma_async_issue_pending(chan); | 1126 | dma_async_issue_pending(io->chan); |
1138 | 1127 | ||
1139 | /* | 1128 | /* |
1140 | * FIXME | 1129 | * FIXME |
@@ -1184,7 +1173,7 @@ static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, | |||
1184 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); | 1173 | fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); |
1185 | } | 1174 | } |
1186 | 1175 | ||
1187 | static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) | 1176 | static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct device *dev) |
1188 | { | 1177 | { |
1189 | dma_cap_mask_t mask; | 1178 | dma_cap_mask_t mask; |
1190 | 1179 | ||
@@ -1192,8 +1181,19 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) | |||
1192 | dma_cap_set(DMA_SLAVE, mask); | 1181 | dma_cap_set(DMA_SLAVE, mask); |
1193 | 1182 | ||
1194 | io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); | 1183 | io->chan = dma_request_channel(mask, fsi_dma_filter, &io->slave); |
1195 | if (!io->chan) | 1184 | if (!io->chan) { |
1196 | return -EIO; | 1185 | |
1186 | /* switch to PIO handler */ | ||
1187 | if (fsi_stream_is_play(fsi, io)) | ||
1188 | fsi->playback.handler = &fsi_pio_push_handler; | ||
1189 | else | ||
1190 | fsi->capture.handler = &fsi_pio_pop_handler; | ||
1191 | |||
1192 | dev_info(dev, "switch handler (dma => pio)\n"); | ||
1193 | |||
1194 | /* probe again */ | ||
1195 | return fsi_stream_probe(fsi, dev); | ||
1196 | } | ||
1197 | 1197 | ||
1198 | tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); | 1198 | tasklet_init(&io->tasklet, fsi_dma_do_tasklet, (unsigned long)io); |
1199 | 1199 | ||
@@ -1683,7 +1683,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1683 | master->fsia.master = master; | 1683 | master->fsia.master = master; |
1684 | master->fsia.info = &info->port_a; | 1684 | master->fsia.info = &info->port_a; |
1685 | fsi_handler_init(&master->fsia); | 1685 | fsi_handler_init(&master->fsia); |
1686 | ret = fsi_stream_probe(&master->fsia); | 1686 | ret = fsi_stream_probe(&master->fsia, &pdev->dev); |
1687 | if (ret < 0) { | 1687 | if (ret < 0) { |
1688 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); | 1688 | dev_err(&pdev->dev, "FSIA stream probe failed\n"); |
1689 | goto exit_iounmap; | 1689 | goto exit_iounmap; |
@@ -1694,7 +1694,7 @@ static int fsi_probe(struct platform_device *pdev) | |||
1694 | master->fsib.master = master; | 1694 | master->fsib.master = master; |
1695 | master->fsib.info = &info->port_b; | 1695 | master->fsib.info = &info->port_b; |
1696 | fsi_handler_init(&master->fsib); | 1696 | fsi_handler_init(&master->fsib); |
1697 | ret = fsi_stream_probe(&master->fsib); | 1697 | ret = fsi_stream_probe(&master->fsib, &pdev->dev); |
1698 | if (ret < 0) { | 1698 | if (ret < 0) { |
1699 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); | 1699 | dev_err(&pdev->dev, "FSIB stream probe failed\n"); |
1700 | goto exit_fsia; | 1700 | goto exit_fsia; |