aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-05-17 20:36:47 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-05-19 14:41:45 -0400
commit766812e6d5e2e23be1e212cf84902d5e834dd865 (patch)
treefb8cdf68c82b9652e5a96b8eab444c7f22d86f3f /sound
parentf33238e96f619d9888713c07dcd92e4518879282 (diff)
ASoC: sh: fsi: enable chip specific data transfer mode
SupherH FSI2 can use special data transfer, but it depends on CPU-FSI2 connection style. We can use 16bit data stream mode if it was valid connection, and it is required for 16bit data DMA transfer / SPDIF sound output. We can use 24bit data transfer if it was invalid connection. We can select connection type if CPU is SH7372, and it is always valid connection if latest SuperH. This patch adds new bus_option and fsi_bus_setup() for supporting these feature. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/sh/fsi.c177
1 files changed, 143 insertions, 34 deletions
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index e52a95d44a6b..7cee22515d9d 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -132,6 +132,25 @@
132typedef int (*set_rate_func)(struct device *dev, int rate, int enable); 132typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
133 133
134/* 134/*
135 * bus options
136 *
137 * 0x000000BA
138 *
139 * A : sample widtht 16bit setting
140 * B : sample widtht 24bit setting
141 */
142
143#define SHIFT_16DATA 0
144#define SHIFT_24DATA 4
145
146#define PACKAGE_24BITBUS_BACK 0
147#define PACKAGE_24BITBUS_FRONT 1
148#define PACKAGE_16BITBUS_STREAM 2
149
150#define BUSOP_SET(s, a) ((a) << SHIFT_ ## s ## DATA)
151#define BUSOP_GET(s, a) (((a) >> SHIFT_ ## s ## DATA) & 0xF)
152
153/*
135 * FSI driver use below type name for variable 154 * FSI driver use below type name for variable
136 * 155 *
137 * xxx_num : number of data 156 * xxx_num : number of data
@@ -189,6 +208,11 @@ struct fsi_stream {
189 int oerr_num; 208 int oerr_num;
190 209
191 /* 210 /*
211 * bus options
212 */
213 u32 bus_option;
214
215 /*
192 * thse are initialized by fsi_handler_init() 216 * thse are initialized by fsi_handler_init()
193 */ 217 */
194 struct fsi_stream_handler *handler; 218 struct fsi_stream_handler *handler;
@@ -498,6 +522,7 @@ static void fsi_stream_init(struct fsi_priv *fsi,
498 io->period_samples = fsi_frame2sample(fsi, runtime->period_size); 522 io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
499 io->period_pos = 0; 523 io->period_pos = 0;
500 io->sample_width = samples_to_bytes(runtime, 1); 524 io->sample_width = samples_to_bytes(runtime, 1);
525 io->bus_option = 0;
501 io->oerr_num = -1; /* ignore 1st err */ 526 io->oerr_num = -1; /* ignore 1st err */
502 io->uerr_num = -1; /* ignore 1st err */ 527 io->uerr_num = -1; /* ignore 1st err */
503 fsi_stream_handler_call(io, init, fsi, io); 528 fsi_stream_handler_call(io, init, fsi, io);
@@ -525,6 +550,7 @@ static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io)
525 io->period_samples = 0; 550 io->period_samples = 0;
526 io->period_pos = 0; 551 io->period_pos = 0;
527 io->sample_width = 0; 552 io->sample_width = 0;
553 io->bus_option = 0;
528 io->oerr_num = 0; 554 io->oerr_num = 0;
529 io->uerr_num = 0; 555 io->uerr_num = 0;
530 spin_unlock_irqrestore(&master->lock, flags); 556 spin_unlock_irqrestore(&master->lock, flags);
@@ -584,6 +610,53 @@ static int fsi_stream_remove(struct fsi_priv *fsi)
584} 610}
585 611
586/* 612/*
613 * format/bus/dma setting
614 */
615static void fsi_format_bus_setup(struct fsi_priv *fsi, struct fsi_stream *io,
616 u32 bus, struct device *dev)
617{
618 struct fsi_master *master = fsi_get_master(fsi);
619 int is_play = fsi_stream_is_play(fsi, io);
620 u32 fmt = fsi->fmt;
621
622 if (fsi_version(master) >= 2) {
623 u32 dma = 0;
624
625 /*
626 * FSI2 needs DMA/Bus setting
627 */
628 switch (bus) {
629 case PACKAGE_24BITBUS_FRONT:
630 fmt |= CR_BWS_24;
631 dma |= VDMD_FRONT;
632 dev_dbg(dev, "24bit bus / package in front\n");
633 break;
634 case PACKAGE_16BITBUS_STREAM:
635 fmt |= CR_BWS_16;
636 dma |= VDMD_STREAM;
637 dev_dbg(dev, "16bit bus / stream mode\n");
638 break;
639 case PACKAGE_24BITBUS_BACK:
640 default:
641 fmt |= CR_BWS_24;
642 dma |= VDMD_BACK;
643 dev_dbg(dev, "24bit bus / package in back\n");
644 break;
645 }
646
647 if (is_play)
648 fsi_reg_write(fsi, OUT_DMAC, dma);
649 else
650 fsi_reg_write(fsi, IN_DMAC, dma);
651 }
652
653 if (is_play)
654 fsi_reg_write(fsi, DO_FMT, fmt);
655 else
656 fsi_reg_write(fsi, DI_FMT, fmt);
657}
658
659/*
587 * irq function 660 * irq function
588 */ 661 */
589 662
@@ -718,11 +791,26 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
718 */ 791 */
719static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) 792static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
720{ 793{
721 u16 *buf = (u16 *)_buf; 794 u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
722 int i; 795 int i;
723 796
724 for (i = 0; i < samples; i++) 797 if (enable_stream) {
725 fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); 798 /*
799 * stream mode
800 * see
801 * fsi_pio_push_init()
802 */
803 u32 *buf = (u32 *)_buf;
804
805 for (i = 0; i < samples / 2; i++)
806 fsi_reg_write(fsi, DODT, buf[i]);
807 } else {
808 /* normal mode */
809 u16 *buf = (u16 *)_buf;
810
811 for (i = 0; i < samples; i++)
812 fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
813 }
726} 814}
727 815
728static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples) 816static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
@@ -862,12 +950,44 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
862 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 950 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
863} 951}
864 952
953static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io)
954{
955 u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
956
957 /*
958 * we can use 16bit stream mode
959 * when "playback" and "16bit data"
960 * and platform allows "stream mode"
961 * see
962 * fsi_pio_push16()
963 */
964 if (enable_stream)
965 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
966 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
967 else
968 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
969 BUSOP_SET(16, PACKAGE_24BITBUS_BACK);
970 return 0;
971}
972
973static int fsi_pio_pop_init(struct fsi_priv *fsi, struct fsi_stream *io)
974{
975 /*
976 * always 24bit bus, package back when "capture"
977 */
978 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
979 BUSOP_SET(16, PACKAGE_24BITBUS_BACK);
980 return 0;
981}
982
865static struct fsi_stream_handler fsi_pio_push_handler = { 983static struct fsi_stream_handler fsi_pio_push_handler = {
984 .init = fsi_pio_push_init,
866 .transfer = fsi_pio_push, 985 .transfer = fsi_pio_push,
867 .start_stop = fsi_pio_start_stop, 986 .start_stop = fsi_pio_start_stop,
868}; 987};
869 988
870static struct fsi_stream_handler fsi_pio_pop_handler = { 989static struct fsi_stream_handler fsi_pio_pop_handler = {
990 .init = fsi_pio_pop_init,
871 .transfer = fsi_pio_pop, 991 .transfer = fsi_pio_pop,
872 .start_stop = fsi_pio_start_stop, 992 .start_stop = fsi_pio_start_stop,
873}; 993};
@@ -909,6 +1029,13 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
909 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? 1029 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
910 DMA_TO_DEVICE : DMA_FROM_DEVICE; 1030 DMA_TO_DEVICE : DMA_FROM_DEVICE;
911 1031
1032 /*
1033 * 24bit data : 24bit bus / package in back
1034 * 16bit data : 16bit bus / stream mode
1035 */
1036 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
1037 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
1038
912 io->dma = dma_map_single(dai->dev, runtime->dma_area, 1039 io->dma = dma_map_single(dai->dev, runtime->dma_area,
913 snd_pcm_lib_buffer_bytes(io->substream), dir); 1040 snd_pcm_lib_buffer_bytes(io->substream), dir);
914 return 0; 1041 return 0;
@@ -1045,25 +1172,9 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io)
1045static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, 1172static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
1046 int start) 1173 int start)
1047{ 1174{
1048 u32 bws; 1175 u32 enable = start ? DMA_ON : 0;
1049 u32 dma;
1050 1176
1051 switch (io->sample_width * start) { 1177 fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
1052 case 2:
1053 bws = CR_BWS_16;
1054 dma = VDMD_STREAM | DMA_ON;
1055 break;
1056 case 4:
1057 bws = CR_BWS_24;
1058 dma = VDMD_BACK | DMA_ON;
1059 break;
1060 default:
1061 bws = 0;
1062 dma = 0;
1063 }
1064
1065 fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
1066 fsi_reg_write(fsi, OUT_DMAC, dma);
1067} 1178}
1068 1179
1069static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) 1180static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
@@ -1166,7 +1277,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1166 struct fsi_stream *io, 1277 struct fsi_stream *io,
1167 struct device *dev) 1278 struct device *dev)
1168{ 1279{
1169 struct fsi_master *master = fsi_get_master(fsi);
1170 u32 flags = fsi_get_info_flags(fsi); 1280 u32 flags = fsi_get_info_flags(fsi);
1171 u32 data = 0; 1281 u32 data = 0;
1172 1282
@@ -1189,10 +1299,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1189 1299
1190 fsi_reg_write(fsi, CKG2, data); 1300 fsi_reg_write(fsi, CKG2, data);
1191 1301
1192 /* set format */
1193 fsi_reg_write(fsi, DO_FMT, fsi->fmt);
1194 fsi_reg_write(fsi, DI_FMT, fsi->fmt);
1195
1196 /* spdif ? */ 1302 /* spdif ? */
1197 if (fsi_is_spdif(fsi)) { 1303 if (fsi_is_spdif(fsi)) {
1198 fsi_spdif_clk_ctrl(fsi, 1); 1304 fsi_spdif_clk_ctrl(fsi, 1);
@@ -1200,15 +1306,18 @@ static int fsi_hw_startup(struct fsi_priv *fsi,
1200 } 1306 }
1201 1307
1202 /* 1308 /*
1203 * FIXME 1309 * get bus settings
1204 *
1205 * FSI driver assumed that data package is in-back.
1206 * FSI2 chip can select it.
1207 */ 1310 */
1208 if (fsi_version(master) >= 2) { 1311 data = 0;
1209 fsi_reg_write(fsi, OUT_DMAC, VDMD_BACK); 1312 switch (io->sample_width) {
1210 fsi_reg_write(fsi, IN_DMAC, VDMD_BACK); 1313 case 2:
1314 data = BUSOP_GET(16, io->bus_option);
1315 break;
1316 case 4:
1317 data = BUSOP_GET(24, io->bus_option);
1318 break;
1211 } 1319 }
1320 fsi_format_bus_setup(fsi, io, data, dev);
1212 1321
1213 /* irq clear */ 1322 /* irq clear */
1214 fsi_irq_disable(fsi, io); 1323 fsi_irq_disable(fsi, io);
@@ -1295,7 +1404,7 @@ static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
1295 if (fsi_version(master) < 2) 1404 if (fsi_version(master) < 2)
1296 return -EINVAL; 1405 return -EINVAL;
1297 1406
1298 fsi->fmt = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; 1407 fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM;
1299 fsi->chan_num = 2; 1408 fsi->chan_num = 2;
1300 fsi->spdif = 1; 1409 fsi->spdif = 1;
1301 1410