History

Merge tag 'asoc-3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Last minute updates These are all new code, they've been in -next already so should be OK for merge this time round. I'd been planning to send a pull request today after they'd had a bit of exposure there to make sure breakage didn't propagate into your tree.

Takashi Iwai committed 14 years ago

Commit 85e184e2 parents 382e6a8 766812e10 files · +529 −67Browse files

Unified · Split

10 files
  1. Documentation/devicetree/bindings/sound/tegra-audio-wm8753.txt +54 −0
  2. include/sound/sh_fsi.h +5 −1
  3. sound/soc/codecs/Kconfig +4 −0
  4. sound/soc/codecs/Makefile +2 −0
  5. sound/soc/codecs/omap-hdmi.c +69 −0
  6. sound/soc/omap/Kconfig +1 −0
  7. sound/soc/sh/fsi.c +158 −66
  8. sound/soc/tegra/Kconfig +10 −0
  9. sound/soc/tegra/Makefile +2 −0
  10. sound/soc/tegra/tegra_wm8753.c +224 −0
Documentation/devicetree/bindings/sound/tegra-audio-wm8753.txt+54−0
@@ -0,0 +1,54 @@
1+NVIDIA Tegra audio complex
2+
3+Required properties:
4+- compatible : "nvidia,tegra-audio-wm8753"
5+- nvidia,model : The user-visible name of this sound complex.
6+- nvidia,audio-routing : A list of the connections between audio components.
7+ Each entry is a pair of strings, the first being the connection's sink,
8+ the second being the connection's source. Valid names for sources and
9+ sinks are the WM8753's pins, and the jacks on the board:
10+
11+ WM8753 pins:
12+
13+ * LOUT1
14+ * LOUT2
15+ * ROUT1
16+ * ROUT2
17+ * MONO1
18+ * MONO2
19+ * OUT3
20+ * OUT4
21+ * LINE1
22+ * LINE2
23+ * RXP
24+ * RXN
25+ * ACIN
26+ * ACOP
27+ * MIC1N
28+ * MIC1
29+ * MIC2N
30+ * MIC2
31+ * Mic Bias
32+
33+ Board connectors:
34+
35+ * Headphone Jack
36+ * Mic Jack
37+
38+- nvidia,i2s-controller : The phandle of the Tegra I2S1 controller
39+- nvidia,audio-codec : The phandle of the WM8753 audio codec
40+Example:
41+
42+sound {
43+ compatible = "nvidia,tegra-audio-wm8753-whistler",
44+ "nvidia,tegra-audio-wm8753"
45+ nvidia,model = "tegra-wm8753-harmony";
46+
47+ nvidia,audio-routing =
48+ "Headphone Jack", "LOUT1",
49+ "Headphone Jack", "ROUT1";
50+
51+ nvidia,i2s-controller = <&i2s1>;
52+ nvidia,audio-codec = <&wm8753>;
53+};
54+
include/sound/sh_fsi.h+5−1
@@ -21,10 +21,11 @@ · 20 unmodified lines
2121 /*
2222 * flags format
2323 *
24− * 0x000000BA
24+ * 0x00000CBA
2525 *
2626 * A: inversion
2727 * B: format mode
28+ * C: chip specific
2829 */
2930
3031 /* A: clock inversion */
@@ -39,6 +40,9 @@ · 8 unmodified lines
3940 #define SH_FSI_FMT_DAI (0 << 4)
4041 #define SH_FSI_FMT_SPDIF (1 << 4)
4142
43+/* C: chip specific */
44+#define SH_FSI_OPTION_MASK 0x00000F00
45+#define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */
4246
4347 /*
4448 * set_rate return value
sound/soc/codecs/Kconfig+4−0
@@ -46,6 +46,7 @@ config SND_SOC_ALL_CODECS · 45 unmodified lines
4646 select SND_SOC_MAX9877 if I2C
4747 select SND_SOC_MC13783 if MFD_MC13XXX
4848 select SND_SOC_ML26124 if I2C
49+ select SND_SOC_OMAP_HDMI_CODEC if OMAP4_DSS_HDMI
4950 select SND_SOC_PCM3008
5051 select SND_SOC_RT5631 if I2C
5152 select SND_SOC_SGTL5000 if I2C
@@ -236,6 +237,9 @@ config SND_SOC_MAX98095 · 184 unmodified lines
236237 config SND_SOC_MAX9850
237238 tristate
238239
240+config SND_SOC_OMAP_HDMI_CODEC
241+ tristate
242+
239243 config SND_SOC_PCM3008
240244 tristate
241245
sound/soc/codecs/Makefile+2−0
@@ -33,6 +33,7 @@ snd-soc-max98095-objs := max98095.o · 32 unmodified lines
3333 snd-soc-max9850-objs := max9850.o
3434 snd-soc-mc13783-objs := mc13783.o
3535 snd-soc-ml26124-objs := ml26124.o
36+snd-soc-omap-hdmi-codec-objs := omap-hdmi.o
3637 snd-soc-pcm3008-objs := pcm3008.o
3738 snd-soc-rt5631-objs := rt5631.o
3839 snd-soc-sgtl5000-objs := sgtl5000.o
@@ -143,6 +144,7 @@ obj-$(CONFIG_SND_SOC_MAX98095) += snd-soc-max98095.o · 104 unmodified lines
143144 obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
144145 obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
145146 obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
147+obj-$(CONFIG_SND_SOC_OMAP_HDMI_CODEC) += snd-soc-omap-hdmi-codec.o
146148 obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
147149 obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
148150 obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
sound/soc/codecs/omap-hdmi.c+69−0
@@ -0,0 +1,69 @@
1+/*
2+ * ALSA SoC codec driver for HDMI audio on OMAP processors.
3+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
4+ * Author: Ricardo Neri <ricardo.neri@ti.com>
5+ *
6+ * This program is free software; you can redistribute it and/or
7+ * modify it under the terms of the GNU General Public License
8+ * version 2 as published by the Free Software Foundation.
9+ *
10+ * This program is distributed in the hope that it will be useful, but
11+ * WITHOUT ANY WARRANTY; without even the implied warranty of
12+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+ * General Public License for more details.
14+ *
15+ * You should have received a copy of the GNU General Public License
16+ * along with this program; if not, write to the Free Software
17+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18+ * 02110-1301 USA
19+ *
20+ */
21+#include <linux/module.h>
22+#include <sound/soc.h>
23+
24+#define DRV_NAME "hdmi-audio-codec"
25+
26+static struct snd_soc_codec_driver omap_hdmi_codec;
27+
28+static struct snd_soc_dai_driver omap_hdmi_codec_dai = {
29+ .name = "omap-hdmi-hifi",
30+ .playback = {
31+ .channels_min = 2,
32+ .channels_max = 8,
33+ .rates = SNDRV_PCM_RATE_32000 |
34+ SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
35+ SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000 |
36+ SNDRV_PCM_RATE_176400 | SNDRV_PCM_RATE_192000,
37+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
38+ SNDRV_PCM_FMTBIT_S24_LE,
39+ },
40+};
41+
42+static __devinit int omap_hdmi_codec_probe(struct platform_device *pdev)
43+{
44+ return snd_soc_register_codec(&pdev->dev, &omap_hdmi_codec,
45+ &omap_hdmi_codec_dai, 1);
46+}
47+
48+static __devexit int omap_hdmi_codec_remove(struct platform_device *pdev)
49+{
50+ snd_soc_unregister_codec(&pdev->dev);
51+ return 0;
52+}
53+
54+static struct platform_driver omap_hdmi_codec_driver = {
55+ .driver = {
56+ .name = DRV_NAME,
57+ .owner = THIS_MODULE,
58+ },
59+
60+ .probe = omap_hdmi_codec_probe,
61+ .remove = __devexit_p(omap_hdmi_codec_remove),
62+};
63+
64+module_platform_driver(omap_hdmi_codec_driver);
65+
66+MODULE_AUTHOR("Ricardo Neri <ricardo.neri@ti.com>");
67+MODULE_DESCRIPTION("ASoC OMAP HDMI codec driver");
68+MODULE_LICENSE("GPL");
69+MODULE_ALIAS("platform:" DRV_NAME);
sound/soc/omap/Kconfig+1−0
@@ -113,6 +113,7 @@ config SND_OMAP_SOC_OMAP4_HDMI · 112 unmodified lines
113113 tristate "SoC Audio support for Texas Instruments OMAP4 HDMI"
114114 depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS && ARCH_OMAP4
115115 select SND_OMAP_SOC_HDMI
116+ select SND_SOC_OMAP_HDMI_CODEC
116117 help
117118 Say Y if you want to add support for SoC HDMI audio on Texas Instruments
118119 OMAP4 chips
sound/soc/sh/fsi.c+158−66
@@ -131,6 +131,25 @@ · 130 unmodified lines
131131
132132 typedef int (*set_rate_func)(struct device *dev, int rate, int enable);
133133
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+
134153 /*
135154 * FSI driver use below type name for variable
136155 *
@@ -188,6 +207,11 @@ struct fsi_stream { · 51 unmodified lines
188207 int uerr_num;
189208 int oerr_num;
190209
210+ /*
211+ * bus options
212+ */
213+ u32 bus_option;
214+
191215 /*
192216 * thse are initialized by fsi_handler_init()
193217 */
@@ -211,8 +235,7 @@ struct fsi_priv { · 17 unmodified lines
211235 struct fsi_stream playback;
212236 struct fsi_stream capture;
213237
214− u32 do_fmt;
215− u32 di_fmt;
238+ u32 fmt;
216239
217240 int chan_num:16;
218241 int clk_master:1;
@@ -321,6 +344,10 @@ static void _fsi_master_mask_set(struct fsi_master *master, · 102 unmodified lines
321344 /*
322345 * basic function
323346 */
347+static int fsi_version(struct fsi_master *master)
348+{
349+ return master->core->ver;
350+}
324351
325352 static struct fsi_master *fsi_get_master(struct fsi_priv *fsi)
326353 {
@@ -495,6 +522,7 @@ static void fsi_stream_init(struct fsi_priv *fsi, · 168 unmodified lines
495522 io->period_samples = fsi_frame2sample(fsi, runtime->period_size);
496523 io->period_pos = 0;
497524 io->sample_width = samples_to_bytes(runtime, 1);
525+ io->bus_option = 0;
498526 io->oerr_num = -1; /* ignore 1st err */
499527 io->uerr_num = -1; /* ignore 1st err */
500528 fsi_stream_handler_call(io, init, fsi, io);
@@ -522,6 +550,7 @@ static void fsi_stream_quit(struct fsi_priv *fsi, struct fsi_stream *io) · 21 unmodified lines
522550 io->period_samples = 0;
523551 io->period_pos = 0;
524552 io->sample_width = 0;
553+ io->bus_option = 0;
525554 io->oerr_num = 0;
526555 io->uerr_num = 0;
527556 spin_unlock_irqrestore(&master->lock, flags);
@@ -580,6 +609,53 @@ static int fsi_stream_remove(struct fsi_priv *fsi) · 52 unmodified lines
580609 return 0;
581610 }
582611
612+/*
613+ * format/bus/dma setting
614+ */
615+static 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+
583659 /*
584660 * irq function
585661 */
@@ -629,11 +705,6 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) · 43 unmodified lines
629705 struct fsi_master *master = fsi_get_master(fsi);
630706 u32 mask, val;
631707
632− if (master->core->ver < 2) {
633− pr_err("fsi: register access err (%s)\n", __func__);
634− return;
635− }
636−
637708 mask = BP | SE;
638709 val = enable ? mask : 0;
639710
@@ -648,9 +719,7 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) · 8 unmodified lines
648719 static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi,
649720 long rate, int enable)
650721 {
651− struct fsi_master *master = fsi_get_master(fsi);
652722 set_rate_func set_rate = fsi_get_info_set_rate(fsi);
653− int fsi_ver = master->core->ver;
654723 int ret;
655724
656725 if (!set_rate)
@@ -682,10 +751,7 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, · 25 unmodified lines
682751 data |= (0x3 << 12);
683752 break;
684753 case SH_FSI_ACKMD_32:
685− if (fsi_ver < 2)
686− dev_err(dev, "unsupported ACKMD\n");
687− else
688− data |= (0x4 << 12);
754+ data |= (0x4 << 12);
689755 break;
690756 }
691757
@@ -708,10 +774,7 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, · 16 unmodified lines
708774 data |= (0x4 << 8);
709775 break;
710776 case SH_FSI_BPFMD_16:
711− if (fsi_ver < 2)
712− dev_err(dev, "unsupported ACKMD\n");
713− else
714− data |= (0x7 << 8);
777+ data |= (0x7 << 8);
715778 break;
716779 }
717780
@@ -728,11 +791,26 @@ static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, · 10 unmodified lines
728791 */
729792 static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples)
730793 {
731− u16 *buf = (u16 *)_buf;
794+ u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE;
732795 int i;
733796
734− for (i = 0; i < samples; i++)
735− fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8));
797+ if (enable_stream) {
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+ }
736814 }
737815
738816 static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples)
@@ -872,12 +950,44 @@ static void fsi_pio_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, · 133 unmodified lines
872950 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0);
873951 }
874952
953+static 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+
973+static 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+
875983 static struct fsi_stream_handler fsi_pio_push_handler = {
984+ .init = fsi_pio_push_init,
876985 .transfer = fsi_pio_push,
877986 .start_stop = fsi_pio_start_stop,
878987 };
879988
880989 static struct fsi_stream_handler fsi_pio_pop_handler = {
990+ .init = fsi_pio_pop_init,
881991 .transfer = fsi_pio_pop,
882992 .start_stop = fsi_pio_start_stop,
883993 };
@@ -919,6 +1029,13 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io) · 35 unmodified lines
9191029 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
9201030 DMA_TO_DEVICE : DMA_FROM_DEVICE;
9211031
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+
9221039 io->dma = dma_map_single(dai->dev, runtime->dma_area,
9231040 snd_pcm_lib_buffer_bytes(io->substream), dir);
9241041 return 0;
@@ -1055,25 +1172,9 @@ static int fsi_dma_transfer(struct fsi_priv *fsi, struct fsi_stream *io) · 130 unmodified lines
10551172 static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io,
10561173 int start)
10571174 {
1058− u32 bws;
1059− u32 dma;
1175+ u32 enable = start ? DMA_ON : 0;
10601176
1061− switch (io->sample_width * start) {
1062− case 2:
1063− bws = CR_BWS_16;
1064− dma = VDMD_STREAM | DMA_ON;
1065− break;
1066− case 4:
1067− bws = CR_BWS_24;
1068− dma = VDMD_BACK | DMA_ON;
1069− break;
1070− default:
1071− bws = 0;
1072− dma = 0;
1073− }
1074−
1075− fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws);
1076− fsi_reg_write(fsi, OUT_DMAC, dma);
1177+ fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable);
10771178 }
10781179
10791180 static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io)
@@ -1176,8 +1277,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi, · 96 unmodified lines
11761277 struct fsi_stream *io,
11771278 struct device *dev)
11781279 {
1179− struct fsi_master *master = fsi_get_master(fsi);
1180− int fsi_ver = master->core->ver;
11811280 u32 flags = fsi_get_info_flags(fsi);
11821281 u32 data = 0;
11831282
@@ -1200,10 +1299,6 @@ static int fsi_hw_startup(struct fsi_priv *fsi, · 16 unmodified lines
12001299
12011300 fsi_reg_write(fsi, CKG2, data);
12021301
1203− /* set format */
1204− fsi_reg_write(fsi, DO_FMT, fsi->do_fmt);
1205− fsi_reg_write(fsi, DI_FMT, fsi->di_fmt);
1206−
12071302 /* spdif ? */
12081303 if (fsi_is_spdif(fsi)) {
12091304 fsi_spdif_clk_ctrl(fsi, 1);
@@ -1211,15 +1306,18 @@ static int fsi_hw_startup(struct fsi_priv *fsi, · 1 unmodified line
12111306 }
12121307
12131308 /*
1214− * FIXME
1215− *
1216− * FSI driver assumed that data package is in-back.
1217− * FSI2 chip can select it.
1309+ * get bus settings
12181310 */
1219− if (fsi_ver >= 2) {
1220− fsi_reg_write(fsi, OUT_DMAC, (1 << 4));
1221− fsi_reg_write(fsi, IN_DMAC, (1 << 4));
1311+ data = 0;
1312+ switch (io->sample_width) {
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;
12221319 }
1320+ fsi_format_bus_setup(fsi, io, data, dev);
12231321
12241322 /* irq clear */
12251323 fsi_irq_disable(fsi, io);
@@ -1243,7 +1341,9 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, · 17 unmodified lines
12431341 {
12441342 struct fsi_priv *fsi = fsi_get_priv(substream);
12451343
1246− return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev);
1344+ fsi->rate = 0;
1345+
1346+ return 0;
12471347 }
12481348
12491349 static void fsi_dai_shutdown(struct snd_pcm_substream *substream,
@@ -1251,7 +1351,6 @@ static void fsi_dai_shutdown(struct snd_pcm_substream *substream, · 1 unmodified line
12511351 {
12521352 struct fsi_priv *fsi = fsi_get_priv(substream);
12531353
1254− fsi_hw_shutdown(fsi, dai->dev);
12551354 fsi->rate = 0;
12561355 }
12571356
@@ -1265,11 +1364,13 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, · 7 unmodified lines
12651364 switch (cmd) {
12661365 case SNDRV_PCM_TRIGGER_START:
12671366 fsi_stream_init(fsi, io, substream);
1367+ fsi_hw_startup(fsi, io, dai->dev);
12681368 ret = fsi_stream_transfer(io);
12691369 if (0 == ret)
12701370 fsi_stream_start(fsi, io);
12711371 break;
12721372 case SNDRV_PCM_TRIGGER_STOP:
1373+ fsi_hw_shutdown(fsi, dai->dev);
12731374 fsi_stream_stop(fsi, io);
12741375 fsi_stream_quit(fsi, io);
12751376 break;
@@ -1280,42 +1381,33 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, · 4 unmodified lines
12801381
12811382 static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt)
12821383 {
1283− u32 data = 0;
1284−
12851384 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
12861385 case SND_SOC_DAIFMT_I2S:
1287− data = CR_I2S;
1386+ fsi->fmt = CR_I2S;
12881387 fsi->chan_num = 2;
12891388 break;
12901389 case SND_SOC_DAIFMT_LEFT_J:
1291− data = CR_PCM;
1390+ fsi->fmt = CR_PCM;
12921391 fsi->chan_num = 2;
12931392 break;
12941393 default:
12951394 return -EINVAL;
12961395 }
12971396
1298− fsi->do_fmt = data;
1299− fsi->di_fmt = data;
1300−
13011397 return 0;
13021398 }
13031399
13041400 static int fsi_set_fmt_spdif(struct fsi_priv *fsi)
13051401 {
13061402 struct fsi_master *master = fsi_get_master(fsi);
1307− u32 data = 0;
13081403
1309− if (master->core->ver < 2)
1404+ if (fsi_version(master) < 2)
13101405 return -EINVAL;
13111406
1312− data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM;
1407+ fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM;
13131408 fsi->chan_num = 2;
13141409 fsi->spdif = 1;
13151410
1316− fsi->do_fmt = data;
1317− fsi->di_fmt = data;
1318−
13191411 return 0;
13201412 }
13211413
sound/soc/tegra/Kconfig+10−0
@@ -48,6 +48,16 @@ config SND_SOC_TEGRA30_I2S · 47 unmodified lines
4848 Tegra30 I2S interface. You will also need to select the individual
4949 machine drivers to support below.
5050
51+config SND_SOC_TEGRA_WM8753
52+ tristate "SoC Audio support for Tegra boards using a WM8753 codec"
53+ depends on SND_SOC_TEGRA && I2C
54+ select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
55+ select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
56+ select SND_SOC_WM8753
57+ help
58+ Say Y or M here if you want to add support for SoC audio on Tegra
59+ boards using the WM8753 codec, such as Whistler.
60+
5161 config MACH_HAS_SND_SOC_TEGRA_WM8903
5262 bool
5363 help
sound/soc/tegra/Makefile+2−0
@@ -16,10 +16,12 @@ obj-$(CONFIG_SND_SOC_TEGRA30_AHUB) += snd-soc-tegra30-ahub.o · 15 unmodified lines
1616 obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o
1717
1818 # Tegra machine Support
19+snd-soc-tegra-wm8753-objs := tegra_wm8753.o
1920 snd-soc-tegra-wm8903-objs := tegra_wm8903.o
2021 snd-soc-tegra-trimslice-objs := trimslice.o
2122 snd-soc-tegra-alc5632-objs := tegra_alc5632.o
2223
24+obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o
2325 obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o
2426 obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o
2527 obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
sound/soc/tegra/tegra_wm8753.c+224−0
@@ -0,0 +1,224 @@
1+/*
2+ * tegra_wm8753.c - Tegra machine ASoC driver for boards using WM8753 codec.
3+ *
4+ * Author: Stephen Warren <swarren@nvidia.com>
5+ * Copyright (C) 2010-2012 - NVIDIA, Inc.
6+ *
7+ * Based on code copyright/by:
8+ *
9+ * (c) 2009, 2010 Nvidia Graphics Pvt. Ltd.
10+ *
11+ * Copyright 2007 Wolfson Microelectronics PLC.
12+ * Author: Graeme Gregory
13+ * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com
14+ *
15+ * This program is free software; you can redistribute it and/or
16+ * modify it under the terms of the GNU General Public License
17+ * version 2 as published by the Free Software Foundation.
18+ *
19+ * This program is distributed in the hope that it will be useful, but
20+ * WITHOUT ANY WARRANTY; without even the implied warranty of
21+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22+ * General Public License for more details.
23+ *
24+ * You should have received a copy of the GNU General Public License
25+ * along with this program; if not, write to the Free Software
26+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27+ * 02110-1301 USA
28+ *
29+ */
30+
31+#include <asm/mach-types.h>
32+
33+#include <linux/module.h>
34+#include <linux/platform_device.h>
35+#include <linux/slab.h>
36+#include <linux/gpio.h>
37+#include <linux/of_gpio.h>
38+
39+#include <sound/core.h>
40+#include <sound/jack.h>
41+#include <sound/pcm.h>
42+#include <sound/pcm_params.h>
43+#include <sound/soc.h>
44+
45+#include "../codecs/wm8753.h"
46+
47+#include "tegra_asoc_utils.h"
48+
49+#define DRV_NAME "tegra-snd-wm8753"
50+
51+struct tegra_wm8753 {
52+ struct tegra_asoc_utils_data util_data;
53+};
54+
55+static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream,
56+ struct snd_pcm_hw_params *params)
57+{
58+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
59+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
60+ struct snd_soc_codec *codec = rtd->codec;
61+ struct snd_soc_card *card = codec->card;
62+ struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
63+ int srate, mclk;
64+ int err;
65+
66+ srate = params_rate(params);
67+ switch (srate) {
68+ case 11025:
69+ case 22050:
70+ case 44100:
71+ case 88200:
72+ mclk = 11289600;
73+ break;
74+ default:
75+ mclk = 12288000;
76+ break;
77+ }
78+
79+ err = tegra_asoc_utils_set_rate(&machine->util_data, srate, mclk);
80+ if (err < 0) {
81+ dev_err(card->dev, "Can't configure clocks\n");
82+ return err;
83+ }
84+
85+ err = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, mclk,
86+ SND_SOC_CLOCK_IN);
87+ if (err < 0) {
88+ dev_err(card->dev, "codec_dai clock not set\n");
89+ return err;
90+ }
91+
92+ return 0;
93+}
94+
95+static struct snd_soc_ops tegra_wm8753_ops = {
96+ .hw_params = tegra_wm8753_hw_params,
97+};
98+
99+static const struct snd_soc_dapm_widget tegra_wm8753_dapm_widgets[] = {
100+ SND_SOC_DAPM_HP("Headphone Jack", NULL),
101+ SND_SOC_DAPM_MIC("Mic Jack", NULL),
102+};
103+
104+static struct snd_soc_dai_link tegra_wm8753_dai = {
105+ .name = "WM8753",
106+ .stream_name = "WM8753 PCM",
107+ .codec_dai_name = "wm8753-hifi",
108+ .ops = &tegra_wm8753_ops,
109+ .dai_fmt = SND_SOC_DAIFMT_I2S |
110+ SND_SOC_DAIFMT_NB_NF |
111+ SND_SOC_DAIFMT_CBS_CFS,
112+};
113+
114+static struct snd_soc_card snd_soc_tegra_wm8753 = {
115+ .name = "tegra-wm8753",
116+ .owner = THIS_MODULE,
117+ .dai_link = &tegra_wm8753_dai,
118+ .num_links = 1,
119+
120+ .dapm_widgets = tegra_wm8753_dapm_widgets,
121+ .num_dapm_widgets = ARRAY_SIZE(tegra_wm8753_dapm_widgets),
122+ .fully_routed = true,
123+};
124+
125+static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
126+{
127+ struct snd_soc_card *card = &snd_soc_tegra_wm8753;
128+ struct tegra_wm8753 *machine;
129+ int ret;
130+
131+ machine = devm_kzalloc(&pdev->dev, sizeof(struct tegra_wm8753),
132+ GFP_KERNEL);
133+ if (!machine) {
134+ dev_err(&pdev->dev, "Can't allocate tegra_wm8753 struct\n");
135+ ret = -ENOMEM;
136+ goto err;
137+ }
138+
139+ card->dev = &pdev->dev;
140+ platform_set_drvdata(pdev, card);
141+ snd_soc_card_set_drvdata(card, machine);
142+
143+ ret = snd_soc_of_parse_card_name(card, "nvidia,model");
144+ if (ret)
145+ goto err;
146+
147+ ret = snd_soc_of_parse_audio_routing(card, "nvidia,audio-routing");
148+ if (ret)
149+ goto err;
150+
151+ tegra_wm8753_dai.codec_of_node = of_parse_phandle(
152+ pdev->dev.of_node, "nvidia,audio-codec", 0);
153+ if (!tegra_wm8753_dai.codec_of_node) {
154+ dev_err(&pdev->dev,
155+ "Property 'nvidia,audio-codec' missing or invalid\n");
156+ ret = -EINVAL;
157+ goto err;
158+ }
159+
160+ tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle(
161+ pdev->dev.of_node, "nvidia,i2s-controller", 0);
162+ if (!tegra_wm8753_dai.cpu_dai_of_node) {
163+ dev_err(&pdev->dev,
164+ "Property 'nvidia,i2s-controller' missing or invalid\n");
165+ ret = -EINVAL;
166+ goto err;
167+ }
168+
169+ tegra_wm8753_dai.platform_of_node =
170+ tegra_wm8753_dai.cpu_dai_of_node;
171+
172+ ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
173+ if (ret)
174+ goto err;
175+
176+ ret = snd_soc_register_card(card);
177+ if (ret) {
178+ dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
179+ ret);
180+ goto err_fini_utils;
181+ }
182+
183+ return 0;
184+
185+err_fini_utils:
186+ tegra_asoc_utils_fini(&machine->util_data);
187+err:
188+ return ret;
189+}
190+
191+static int __devexit tegra_wm8753_driver_remove(struct platform_device *pdev)
192+{
193+ struct snd_soc_card *card = platform_get_drvdata(pdev);
194+ struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
195+
196+ snd_soc_unregister_card(card);
197+
198+ tegra_asoc_utils_fini(&machine->util_data);
199+
200+ return 0;
201+}
202+
203+static const struct of_device_id tegra_wm8753_of_match[] __devinitconst = {
204+ { .compatible = "nvidia,tegra-audio-wm8753", },
205+ {},
206+};
207+
208+static struct platform_driver tegra_wm8753_driver = {
209+ .driver = {
210+ .name = DRV_NAME,
211+ .owner = THIS_MODULE,
212+ .pm = &snd_soc_pm_ops,
213+ .of_match_table = tegra_wm8753_of_match,
214+ },
215+ .probe = tegra_wm8753_driver_probe,
216+ .remove = __devexit_p(tegra_wm8753_driver_remove),
217+};
218+module_platform_driver(tegra_wm8753_driver);
219+
220+MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
221+MODULE_DESCRIPTION("Tegra+WM8753 machine ASoC driver");
222+MODULE_LICENSE("GPL");
223+MODULE_ALIAS("platform:" DRV_NAME);
224+MODULE_DEVICE_TABLE(of, tegra_wm8753_of_match);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t