Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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.

+529 -67
+54
Documentation/devicetree/bindings/sound/tegra-audio-wm8753.txt
··· 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 +
+5 -1
include/sound/sh_fsi.h
··· 21 21 /* 22 22 * flags format 23 23 * 24 - * 0x000000BA 24 + * 0x00000CBA 25 25 * 26 26 * A: inversion 27 27 * B: format mode 28 + * C: chip specific 28 29 */ 29 30 30 31 /* A: clock inversion */ ··· 40 39 #define SH_FSI_FMT_DAI (0 << 4) 41 40 #define SH_FSI_FMT_SPDIF (1 << 4) 42 41 42 + /* C: chip specific */ 43 + #define SH_FSI_OPTION_MASK 0x00000F00 44 + #define SH_FSI_ENABLE_STREAM_MODE (1 << 8) /* for 16bit data */ 43 45 44 46 /* 45 47 * set_rate return value
+4
sound/soc/codecs/Kconfig
··· 46 46 select SND_SOC_MAX9877 if I2C 47 47 select SND_SOC_MC13783 if MFD_MC13XXX 48 48 select SND_SOC_ML26124 if I2C 49 + select SND_SOC_OMAP_HDMI_CODEC if OMAP4_DSS_HDMI 49 50 select SND_SOC_PCM3008 50 51 select SND_SOC_RT5631 if I2C 51 52 select SND_SOC_SGTL5000 if I2C ··· 236 235 237 236 config SND_SOC_MAX9850 238 237 tristate 238 + 239 + config SND_SOC_OMAP_HDMI_CODEC 240 + tristate 239 241 240 242 config SND_SOC_PCM3008 241 243 tristate
+2
sound/soc/codecs/Makefile
··· 33 33 snd-soc-max9850-objs := max9850.o 34 34 snd-soc-mc13783-objs := mc13783.o 35 35 snd-soc-ml26124-objs := ml26124.o 36 + snd-soc-omap-hdmi-codec-objs := omap-hdmi.o 36 37 snd-soc-pcm3008-objs := pcm3008.o 37 38 snd-soc-rt5631-objs := rt5631.o 38 39 snd-soc-sgtl5000-objs := sgtl5000.o ··· 144 143 obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o 145 144 obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o 146 145 obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o 146 + obj-$(CONFIG_SND_SOC_OMAP_HDMI_CODEC) += snd-soc-omap-hdmi-codec.o 147 147 obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o 148 148 obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o 149 149 obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
+69
sound/soc/codecs/omap-hdmi.c
··· 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);
+1
sound/soc/omap/Kconfig
··· 113 113 tristate "SoC Audio support for Texas Instruments OMAP4 HDMI" 114 114 depends on SND_OMAP_SOC && OMAP4_DSS_HDMI && OMAP2_DSS && ARCH_OMAP4 115 115 select SND_OMAP_SOC_HDMI 116 + select SND_SOC_OMAP_HDMI_CODEC 116 117 help 117 118 Say Y if you want to add support for SoC HDMI audio on Texas Instruments 118 119 OMAP4 chips
+158 -66
sound/soc/sh/fsi.c
··· 132 132 typedef 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 154 * FSI driver use below type name for variable 136 155 * 137 156 * xxx_num : number of data ··· 208 189 int oerr_num; 209 190 210 191 /* 192 + * bus options 193 + */ 194 + u32 bus_option; 195 + 196 + /* 211 197 * thse are initialized by fsi_handler_init() 212 198 */ 213 199 struct fsi_stream_handler *handler; ··· 235 211 struct fsi_stream playback; 236 212 struct fsi_stream capture; 237 213 238 - u32 do_fmt; 239 - u32 di_fmt; 214 + u32 fmt; 240 215 241 216 int chan_num:16; 242 217 int clk_master:1; ··· 344 321 /* 345 322 * basic function 346 323 */ 324 + static int fsi_version(struct fsi_master *master) 325 + { 326 + return master->core->ver; 327 + } 347 328 348 329 static struct fsi_master *fsi_get_master(struct fsi_priv *fsi) 349 330 { ··· 522 495 io->period_samples = fsi_frame2sample(fsi, runtime->period_size); 523 496 io->period_pos = 0; 524 497 io->sample_width = samples_to_bytes(runtime, 1); 498 + io->bus_option = 0; 525 499 io->oerr_num = -1; /* ignore 1st err */ 526 500 io->uerr_num = -1; /* ignore 1st err */ 527 501 fsi_stream_handler_call(io, init, fsi, io); ··· 550 522 io->period_samples = 0; 551 523 io->period_pos = 0; 552 524 io->sample_width = 0; 525 + io->bus_option = 0; 553 526 io->oerr_num = 0; 554 527 io->uerr_num = 0; 555 528 spin_unlock_irqrestore(&master->lock, flags); ··· 610 581 } 611 582 612 583 /* 584 + * format/bus/dma setting 585 + */ 586 + static void fsi_format_bus_setup(struct fsi_priv *fsi, struct fsi_stream *io, 587 + u32 bus, struct device *dev) 588 + { 589 + struct fsi_master *master = fsi_get_master(fsi); 590 + int is_play = fsi_stream_is_play(fsi, io); 591 + u32 fmt = fsi->fmt; 592 + 593 + if (fsi_version(master) >= 2) { 594 + u32 dma = 0; 595 + 596 + /* 597 + * FSI2 needs DMA/Bus setting 598 + */ 599 + switch (bus) { 600 + case PACKAGE_24BITBUS_FRONT: 601 + fmt |= CR_BWS_24; 602 + dma |= VDMD_FRONT; 603 + dev_dbg(dev, "24bit bus / package in front\n"); 604 + break; 605 + case PACKAGE_16BITBUS_STREAM: 606 + fmt |= CR_BWS_16; 607 + dma |= VDMD_STREAM; 608 + dev_dbg(dev, "16bit bus / stream mode\n"); 609 + break; 610 + case PACKAGE_24BITBUS_BACK: 611 + default: 612 + fmt |= CR_BWS_24; 613 + dma |= VDMD_BACK; 614 + dev_dbg(dev, "24bit bus / package in back\n"); 615 + break; 616 + } 617 + 618 + if (is_play) 619 + fsi_reg_write(fsi, OUT_DMAC, dma); 620 + else 621 + fsi_reg_write(fsi, IN_DMAC, dma); 622 + } 623 + 624 + if (is_play) 625 + fsi_reg_write(fsi, DO_FMT, fmt); 626 + else 627 + fsi_reg_write(fsi, DI_FMT, fmt); 628 + } 629 + 630 + /* 613 631 * irq function 614 632 */ 615 633 ··· 705 629 struct fsi_master *master = fsi_get_master(fsi); 706 630 u32 mask, val; 707 631 708 - if (master->core->ver < 2) { 709 - pr_err("fsi: register access err (%s)\n", __func__); 710 - return; 711 - } 712 - 713 632 mask = BP | SE; 714 633 val = enable ? mask : 0; 715 634 ··· 719 648 static int fsi_set_master_clk(struct device *dev, struct fsi_priv *fsi, 720 649 long rate, int enable) 721 650 { 722 - struct fsi_master *master = fsi_get_master(fsi); 723 651 set_rate_func set_rate = fsi_get_info_set_rate(fsi); 724 - int fsi_ver = master->core->ver; 725 652 int ret; 726 653 727 654 if (!set_rate) ··· 751 682 data |= (0x3 << 12); 752 683 break; 753 684 case SH_FSI_ACKMD_32: 754 - if (fsi_ver < 2) 755 - dev_err(dev, "unsupported ACKMD\n"); 756 - else 757 - data |= (0x4 << 12); 685 + data |= (0x4 << 12); 758 686 break; 759 687 } 760 688 ··· 774 708 data |= (0x4 << 8); 775 709 break; 776 710 case SH_FSI_BPFMD_16: 777 - if (fsi_ver < 2) 778 - dev_err(dev, "unsupported ACKMD\n"); 779 - else 780 - data |= (0x7 << 8); 711 + data |= (0x7 << 8); 781 712 break; 782 713 } 783 714 ··· 791 728 */ 792 729 static void fsi_pio_push16(struct fsi_priv *fsi, u8 *_buf, int samples) 793 730 { 794 - u16 *buf = (u16 *)_buf; 731 + u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; 795 732 int i; 796 733 797 - for (i = 0; i < samples; i++) 798 - fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); 734 + if (enable_stream) { 735 + /* 736 + * stream mode 737 + * see 738 + * fsi_pio_push_init() 739 + */ 740 + u32 *buf = (u32 *)_buf; 741 + 742 + for (i = 0; i < samples / 2; i++) 743 + fsi_reg_write(fsi, DODT, buf[i]); 744 + } else { 745 + /* normal mode */ 746 + u16 *buf = (u16 *)_buf; 747 + 748 + for (i = 0; i < samples; i++) 749 + fsi_reg_write(fsi, DODT, ((u32)*(buf + i) << 8)); 750 + } 799 751 } 800 752 801 753 static void fsi_pio_pop16(struct fsi_priv *fsi, u8 *_buf, int samples) ··· 950 872 fsi_master_mask_set(master, CLK_RST, clk, (enable) ? clk : 0); 951 873 } 952 874 875 + static int fsi_pio_push_init(struct fsi_priv *fsi, struct fsi_stream *io) 876 + { 877 + u32 enable_stream = fsi_get_info_flags(fsi) & SH_FSI_ENABLE_STREAM_MODE; 878 + 879 + /* 880 + * we can use 16bit stream mode 881 + * when "playback" and "16bit data" 882 + * and platform allows "stream mode" 883 + * see 884 + * fsi_pio_push16() 885 + */ 886 + if (enable_stream) 887 + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 888 + BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); 889 + else 890 + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 891 + BUSOP_SET(16, PACKAGE_24BITBUS_BACK); 892 + return 0; 893 + } 894 + 895 + static int fsi_pio_pop_init(struct fsi_priv *fsi, struct fsi_stream *io) 896 + { 897 + /* 898 + * always 24bit bus, package back when "capture" 899 + */ 900 + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 901 + BUSOP_SET(16, PACKAGE_24BITBUS_BACK); 902 + return 0; 903 + } 904 + 953 905 static struct fsi_stream_handler fsi_pio_push_handler = { 906 + .init = fsi_pio_push_init, 954 907 .transfer = fsi_pio_push, 955 908 .start_stop = fsi_pio_start_stop, 956 909 }; 957 910 958 911 static struct fsi_stream_handler fsi_pio_pop_handler = { 912 + .init = fsi_pio_pop_init, 959 913 .transfer = fsi_pio_pop, 960 914 .start_stop = fsi_pio_start_stop, 961 915 }; ··· 1028 918 struct snd_soc_dai *dai = fsi_get_dai(io->substream); 1029 919 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? 1030 920 DMA_TO_DEVICE : DMA_FROM_DEVICE; 921 + 922 + /* 923 + * 24bit data : 24bit bus / package in back 924 + * 16bit data : 16bit bus / stream mode 925 + */ 926 + io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 927 + BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); 1031 928 1032 929 io->dma = dma_map_single(dai->dev, runtime->dma_area, 1033 930 snd_pcm_lib_buffer_bytes(io->substream), dir); ··· 1172 1055 static void fsi_dma_push_start_stop(struct fsi_priv *fsi, struct fsi_stream *io, 1173 1056 int start) 1174 1057 { 1175 - u32 bws; 1176 - u32 dma; 1058 + u32 enable = start ? DMA_ON : 0; 1177 1059 1178 - switch (io->sample_width * start) { 1179 - case 2: 1180 - bws = CR_BWS_16; 1181 - dma = VDMD_STREAM | DMA_ON; 1182 - break; 1183 - case 4: 1184 - bws = CR_BWS_24; 1185 - dma = VDMD_BACK | DMA_ON; 1186 - break; 1187 - default: 1188 - bws = 0; 1189 - dma = 0; 1190 - } 1191 - 1192 - fsi_reg_mask_set(fsi, DO_FMT, CR_BWS_MASK, bws); 1193 - fsi_reg_write(fsi, OUT_DMAC, dma); 1060 + fsi_reg_mask_set(fsi, OUT_DMAC, DMA_ON, enable); 1194 1061 } 1195 1062 1196 1063 static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) ··· 1277 1176 struct fsi_stream *io, 1278 1177 struct device *dev) 1279 1178 { 1280 - struct fsi_master *master = fsi_get_master(fsi); 1281 - int fsi_ver = master->core->ver; 1282 1179 u32 flags = fsi_get_info_flags(fsi); 1283 1180 u32 data = 0; 1284 1181 ··· 1299 1200 1300 1201 fsi_reg_write(fsi, CKG2, data); 1301 1202 1302 - /* set format */ 1303 - fsi_reg_write(fsi, DO_FMT, fsi->do_fmt); 1304 - fsi_reg_write(fsi, DI_FMT, fsi->di_fmt); 1305 - 1306 1203 /* spdif ? */ 1307 1204 if (fsi_is_spdif(fsi)) { 1308 1205 fsi_spdif_clk_ctrl(fsi, 1); ··· 1306 1211 } 1307 1212 1308 1213 /* 1309 - * FIXME 1310 - * 1311 - * FSI driver assumed that data package is in-back. 1312 - * FSI2 chip can select it. 1214 + * get bus settings 1313 1215 */ 1314 - if (fsi_ver >= 2) { 1315 - fsi_reg_write(fsi, OUT_DMAC, (1 << 4)); 1316 - fsi_reg_write(fsi, IN_DMAC, (1 << 4)); 1216 + data = 0; 1217 + switch (io->sample_width) { 1218 + case 2: 1219 + data = BUSOP_GET(16, io->bus_option); 1220 + break; 1221 + case 4: 1222 + data = BUSOP_GET(24, io->bus_option); 1223 + break; 1317 1224 } 1225 + fsi_format_bus_setup(fsi, io, data, dev); 1318 1226 1319 1227 /* irq clear */ 1320 1228 fsi_irq_disable(fsi, io); ··· 1341 1243 { 1342 1244 struct fsi_priv *fsi = fsi_get_priv(substream); 1343 1245 1344 - return fsi_hw_startup(fsi, fsi_stream_get(fsi, substream), dai->dev); 1246 + fsi->rate = 0; 1247 + 1248 + return 0; 1345 1249 } 1346 1250 1347 1251 static void fsi_dai_shutdown(struct snd_pcm_substream *substream, ··· 1351 1251 { 1352 1252 struct fsi_priv *fsi = fsi_get_priv(substream); 1353 1253 1354 - fsi_hw_shutdown(fsi, dai->dev); 1355 1254 fsi->rate = 0; 1356 1255 } 1357 1256 ··· 1364 1265 switch (cmd) { 1365 1266 case SNDRV_PCM_TRIGGER_START: 1366 1267 fsi_stream_init(fsi, io, substream); 1268 + fsi_hw_startup(fsi, io, dai->dev); 1367 1269 ret = fsi_stream_transfer(io); 1368 1270 if (0 == ret) 1369 1271 fsi_stream_start(fsi, io); 1370 1272 break; 1371 1273 case SNDRV_PCM_TRIGGER_STOP: 1274 + fsi_hw_shutdown(fsi, dai->dev); 1372 1275 fsi_stream_stop(fsi, io); 1373 1276 fsi_stream_quit(fsi, io); 1374 1277 break; ··· 1381 1280 1382 1281 static int fsi_set_fmt_dai(struct fsi_priv *fsi, unsigned int fmt) 1383 1282 { 1384 - u32 data = 0; 1385 - 1386 1283 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1387 1284 case SND_SOC_DAIFMT_I2S: 1388 - data = CR_I2S; 1285 + fsi->fmt = CR_I2S; 1389 1286 fsi->chan_num = 2; 1390 1287 break; 1391 1288 case SND_SOC_DAIFMT_LEFT_J: 1392 - data = CR_PCM; 1289 + fsi->fmt = CR_PCM; 1393 1290 fsi->chan_num = 2; 1394 1291 break; 1395 1292 default: 1396 1293 return -EINVAL; 1397 1294 } 1398 - 1399 - fsi->do_fmt = data; 1400 - fsi->di_fmt = data; 1401 1295 1402 1296 return 0; 1403 1297 } ··· 1400 1304 static int fsi_set_fmt_spdif(struct fsi_priv *fsi) 1401 1305 { 1402 1306 struct fsi_master *master = fsi_get_master(fsi); 1403 - u32 data = 0; 1404 1307 1405 - if (master->core->ver < 2) 1308 + if (fsi_version(master) < 2) 1406 1309 return -EINVAL; 1407 1310 1408 - data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; 1311 + fsi->fmt = CR_DTMD_SPDIF_PCM | CR_PCM; 1409 1312 fsi->chan_num = 2; 1410 1313 fsi->spdif = 1; 1411 - 1412 - fsi->do_fmt = data; 1413 - fsi->di_fmt = data; 1414 1314 1415 1315 return 0; 1416 1316 }
+10
sound/soc/tegra/Kconfig
··· 48 48 Tegra30 I2S interface. You will also need to select the individual 49 49 machine drivers to support below. 50 50 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 + 51 61 config MACH_HAS_SND_SOC_TEGRA_WM8903 52 62 bool 53 63 help
+2
sound/soc/tegra/Makefile
··· 16 16 obj-$(CONFIG_SND_SOC_TEGRA30_I2S) += snd-soc-tegra30-i2s.o 17 17 18 18 # Tegra machine Support 19 + snd-soc-tegra-wm8753-objs := tegra_wm8753.o 19 20 snd-soc-tegra-wm8903-objs := tegra_wm8903.o 20 21 snd-soc-tegra-trimslice-objs := trimslice.o 21 22 snd-soc-tegra-alc5632-objs := tegra_alc5632.o 22 23 24 + obj-$(CONFIG_SND_SOC_TEGRA_WM8753) += snd-soc-tegra-wm8753.o 23 25 obj-$(CONFIG_SND_SOC_TEGRA_WM8903) += snd-soc-tegra-wm8903.o 24 26 obj-$(CONFIG_SND_SOC_TEGRA_TRIMSLICE) += snd-soc-tegra-trimslice.o 25 27 obj-$(CONFIG_SND_SOC_TEGRA_ALC5632) += snd-soc-tegra-alc5632.o
+224
sound/soc/tegra/tegra_wm8753.c
··· 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);