aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/aoa/codecs/onyx.c75
-rw-r--r--sound/aoa/codecs/tas.c80
-rw-r--r--sound/arm/pxa2xx-ac97.c9
-rw-r--r--sound/atmel/abdac.c18
-rw-r--r--sound/atmel/ac97c.c18
-rw-r--r--sound/core/pcm_lib.c4
-rw-r--r--sound/core/pcm_misc.c18
-rw-r--r--sound/drivers/aloop.c22
-rw-r--r--sound/drivers/dummy.c21
-rw-r--r--sound/drivers/mpu401/mpu401.c3
-rw-r--r--sound/drivers/mtpav.c3
-rw-r--r--sound/drivers/mts64.c3
-rw-r--r--sound/drivers/pcsp/pcsp.c11
-rw-r--r--sound/drivers/portman2x4.c3
-rw-r--r--sound/drivers/serial-u16550.c3
-rw-r--r--sound/drivers/virmidi.c3
-rw-r--r--sound/drivers/vx/vx_core.c2
-rw-r--r--sound/isa/opti9xx/opti92x-ad1848.c86
-rw-r--r--sound/isa/wss/wss_lib.c5
-rw-r--r--sound/oss/swarm_cs4297a.c17
-rw-r--r--sound/oss/vwsnd.c2
-rw-r--r--sound/pci/ali5451/ali5451.c24
-rw-r--r--sound/pci/als300.c24
-rw-r--r--sound/pci/als4000.c25
-rw-r--r--sound/pci/atiixp.c24
-rw-r--r--sound/pci/atiixp_modem.c25
-rw-r--r--sound/pci/au88x0/au88x0_mixer.c11
-rw-r--r--sound/pci/azt3328.c25
-rw-r--r--sound/pci/ca0106/ca0106_main.c24
-rw-r--r--sound/pci/cmipci.c24
-rw-r--r--sound/pci/cs4281.c24
-rw-r--r--sound/pci/cs46xx/cs46xx.c7
-rw-r--r--sound/pci/cs46xx/cs46xx.h1744
-rw-r--r--sound/pci/cs46xx/cs46xx_dsp_scb_types.h1213
-rw-r--r--sound/pci/cs46xx/cs46xx_dsp_spos.h234
-rw-r--r--sound/pci/cs46xx/cs46xx_dsp_task_types.h252
-rw-r--r--sound/pci/cs46xx/cs46xx_lib.c16
-rw-r--r--sound/pci/cs46xx/dsp_spos.c2
-rw-r--r--sound/pci/cs46xx/dsp_spos_scb_lib.c2
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c5
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h5
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c13
-rw-r--r--sound/pci/ctxfi/ctatc.c4
-rw-r--r--sound/pci/ctxfi/ctatc.h2
-rw-r--r--sound/pci/ctxfi/cthardware.h2
-rw-r--r--sound/pci/ctxfi/cthw20k1.c4
-rw-r--r--sound/pci/ctxfi/cthw20k2.c4
-rw-r--r--sound/pci/ctxfi/xfi.c22
-rw-r--r--sound/pci/echoaudio/echoaudio.c22
-rw-r--r--sound/pci/emu10k1/emu10k1.c26
-rw-r--r--sound/pci/ens1370.c25
-rw-r--r--sound/pci/es1938.c49
-rw-r--r--sound/pci/es1968.c24
-rw-r--r--sound/pci/fm801.c26
-rw-r--r--sound/pci/hda/Kconfig7
-rw-r--r--sound/pci/hda/hda_auto_parser.c4
-rw-r--r--sound/pci/hda/hda_beep.c82
-rw-r--r--sound/pci/hda/hda_beep.h5
-rw-r--r--sound/pci/hda/hda_codec.c68
-rw-r--r--sound/pci/hda/hda_codec.h5
-rw-r--r--sound/pci/hda/hda_intel.c55
-rw-r--r--sound/pci/hda/hda_jack.c102
-rw-r--r--sound/pci/hda/hda_jack.h1
-rw-r--r--sound/pci/hda/hda_local.h4
-rw-r--r--sound/pci/hda/hda_proc.c17
-rw-r--r--sound/pci/hda/patch_analog.c2
-rw-r--r--sound/pci/hda/patch_cirrus.c2
-rw-r--r--sound/pci/hda/patch_conexant.c2
-rw-r--r--sound/pci/hda/patch_hdmi.c310
-rw-r--r--sound/pci/hda/patch_realtek.c313
-rw-r--r--sound/pci/hda/patch_sigmatel.c2
-rw-r--r--sound/pci/hda/patch_via.c2
-rw-r--r--sound/pci/ice1712/ice1724.c26
-rw-r--r--sound/pci/intel8x0.c24
-rw-r--r--sound/pci/intel8x0m.c24
-rw-r--r--sound/pci/maestro3.c92
-rw-r--r--sound/pci/nm256/nm256.c24
-rw-r--r--sound/pci/oxygen/oxygen.c5
-rw-r--r--sound/pci/oxygen/oxygen.h3
-rw-r--r--sound/pci/oxygen/oxygen_lib.c17
-rw-r--r--sound/pci/oxygen/virtuoso.c5
-rw-r--r--sound/pci/pcxhr/pcxhr.c63
-rw-r--r--sound/pci/pcxhr/pcxhr.h1
-rw-r--r--sound/pci/pcxhr/pcxhr_core.c27
-rw-r--r--sound/pci/pcxhr/pcxhr_core.h4
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.c11
-rw-r--r--sound/pci/pcxhr/pcxhr_mix22.h1
-rw-r--r--sound/pci/riptide/riptide.c26
-rw-r--r--sound/pci/sis7019.c25
-rw-r--r--sound/pci/trident/trident.c7
-rw-r--r--sound/pci/trident/trident.h444
-rw-r--r--sound/pci/trident/trident_main.c16
-rw-r--r--sound/pci/trident/trident_memory.c2
-rw-r--r--sound/pci/via82xx.c24
-rw-r--r--sound/pci/via82xx_modem.c24
-rw-r--r--sound/pci/vx222/vx222.c26
-rw-r--r--sound/pci/ymfpci/ymfpci.c7
-rw-r--r--sound/pci/ymfpci/ymfpci.h389
-rw-r--r--sound/pci/ymfpci/ymfpci_main.c16
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.c2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf.h2
-rw-r--r--sound/pcmcia/pdaudiocf/pdaudiocf_core.c2
-rw-r--r--sound/pcmcia/vx/vxpocket.c2
-rw-r--r--sound/ppc/powermac.c21
-rw-r--r--sound/sh/aica.c4
-rw-r--r--sound/sh/sh_dac_audio.c1
-rw-r--r--sound/soc/Kconfig1
-rw-r--r--sound/soc/Makefile1
-rw-r--r--sound/soc/blackfin/Kconfig21
-rw-r--r--sound/soc/blackfin/Makefile4
-rw-r--r--sound/soc/blackfin/bf6xx-i2s.c234
-rw-r--r--sound/soc/blackfin/bf6xx-sport.c422
-rw-r--r--sound/soc/blackfin/bf6xx-sport.h82
-rw-r--r--sound/soc/codecs/Kconfig31
-rw-r--r--sound/soc/codecs/Makefile19
-rw-r--r--sound/soc/codecs/ab8500-codec.c2522
-rw-r--r--sound/soc/codecs/ab8500-codec.h590
-rw-r--r--sound/soc/codecs/ac97.c6
-rw-r--r--sound/soc/codecs/arizona.c937
-rw-r--r--sound/soc/codecs/arizona.h159
-rw-r--r--sound/soc/codecs/cs42l52.c19
-rw-r--r--sound/soc/codecs/cs42l73.c20
-rw-r--r--sound/soc/codecs/da732x.c1627
-rw-r--r--sound/soc/codecs/da732x.h133
-rw-r--r--sound/soc/codecs/da732x_reg.h654
-rw-r--r--sound/soc/codecs/isabelle.c1176
-rw-r--r--sound/soc/codecs/isabelle.h143
-rw-r--r--sound/soc/codecs/lm49453.c3
-rw-r--r--sound/soc/codecs/max98095.c5
-rw-r--r--sound/soc/codecs/ml26124.c5
-rw-r--r--sound/soc/codecs/spdif_receiver.c67
-rw-r--r--sound/soc/codecs/sta529.c442
-rw-r--r--sound/soc/codecs/tlv320aic3x.c40
-rw-r--r--sound/soc/codecs/tlv320aic3x.h27
-rw-r--r--sound/soc/codecs/twl6040.c2
-rw-r--r--sound/soc/codecs/wm1250-ev1.c7
-rw-r--r--sound/soc/codecs/wm2000.c32
-rw-r--r--sound/soc/codecs/wm5100-tables.c2
-rw-r--r--sound/soc/codecs/wm5100.c11
-rw-r--r--sound/soc/codecs/wm5102.c903
-rw-r--r--sound/soc/codecs/wm5102.h21
-rw-r--r--sound/soc/codecs/wm5110.c950
-rw-r--r--sound/soc/codecs/wm5110.h21
-rw-r--r--sound/soc/codecs/wm8350.c22
-rw-r--r--sound/soc/codecs/wm8400.c2
-rw-r--r--sound/soc/codecs/wm8580.c2
-rw-r--r--sound/soc/codecs/wm8731.c1
-rw-r--r--sound/soc/codecs/wm8741.c2
-rw-r--r--sound/soc/codecs/wm8753.c2
-rw-r--r--sound/soc/codecs/wm8776.c2
-rw-r--r--sound/soc/codecs/wm8804.c2
-rw-r--r--sound/soc/codecs/wm8903.c316
-rw-r--r--sound/soc/codecs/wm8904.c272
-rw-r--r--sound/soc/codecs/wm8960.c2
-rw-r--r--sound/soc/codecs/wm8961.c2
-rw-r--r--sound/soc/codecs/wm8962.c8
-rw-r--r--sound/soc/codecs/wm8993.c2
-rw-r--r--sound/soc/codecs/wm8994.c46
-rw-r--r--sound/soc/codecs/wm8996.c587
-rw-r--r--sound/soc/codecs/wm9081.c2
-rw-r--r--sound/soc/codecs/wm9090.c2
-rw-r--r--sound/soc/codecs/wm9712.c2
-rw-r--r--sound/soc/codecs/wm9713.c2
-rw-r--r--sound/soc/codecs/wm_hubs.c2
-rw-r--r--sound/soc/dwc/Kconfig9
-rw-r--r--sound/soc/dwc/Makefile3
-rw-r--r--sound/soc/dwc/designware_i2s.c455
-rw-r--r--sound/soc/ep93xx/ep93xx-pcm.c2
-rw-r--r--sound/soc/fsl/imx-audmux.c2
-rw-r--r--sound/soc/fsl/imx-audmux.h1
-rw-r--r--sound/soc/fsl/imx-mc13783.c49
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c2
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c1
-rw-r--r--sound/soc/fsl/imx-sgtl5000.c3
-rw-r--r--sound/soc/mxs/mxs-pcm.c2
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c2
-rw-r--r--sound/soc/omap/omap-mcpdm.c1
-rw-r--r--sound/soc/pxa/Kconfig42
-rw-r--r--sound/soc/pxa/Makefile8
-rw-r--r--sound/soc/pxa/brownstone.c174
-rw-r--r--sound/soc/pxa/mioa701_wm9713.c33
-rw-r--r--sound/soc/pxa/mmp-pcm.c297
-rw-r--r--sound/soc/pxa/mmp-sspa.c480
-rw-r--r--sound/soc/pxa/mmp-sspa.h92
-rw-r--r--sound/soc/pxa/ttc-dkb.c173
-rw-r--r--sound/soc/samsung/dma.c18
-rw-r--r--sound/soc/samsung/littlemill.c7
-rw-r--r--sound/soc/samsung/s3c2412-i2s.c10
-rw-r--r--sound/soc/samsung/s3c24xx-i2s.c10
-rw-r--r--sound/soc/samsung/smdk_wm8994.c36
-rw-r--r--sound/soc/sh/fsi.c52
-rw-r--r--sound/soc/sh/siu_pcm.c12
-rw-r--r--sound/soc/soc-core.c328
-rw-r--r--sound/soc/soc-dapm.c192
-rw-r--r--sound/soc/soc-dmaengine-pcm.c33
-rw-r--r--sound/soc/soc-io.c15
-rw-r--r--sound/soc/soc-pcm.c12
-rw-r--r--sound/soc/spear/spdif_in.c297
-rw-r--r--sound/soc/spear/spdif_in_regs.h60
-rw-r--r--sound/soc/spear/spdif_out.c389
-rw-r--r--sound/soc/spear/spdif_out_regs.h79
-rw-r--r--sound/soc/spear/spear_pcm.c214
-rw-r--r--sound/soc/tegra/Kconfig13
-rw-r--r--sound/soc/tegra/tegra20_i2s.c98
-rw-r--r--sound/soc/tegra/tegra20_i2s.h1
-rw-r--r--sound/soc/tegra/tegra20_spdif.c40
-rw-r--r--sound/soc/tegra/tegra20_spdif.h1
-rw-r--r--sound/soc/tegra/tegra30_ahub.c8
-rw-r--r--sound/soc/tegra/tegra30_i2s.c89
-rw-r--r--sound/soc/tegra/tegra30_i2s.h1
-rw-r--r--sound/soc/tegra/tegra_alc5632.c32
-rw-r--r--sound/soc/tegra/tegra_asoc_utils.c12
-rw-r--r--sound/soc/tegra/tegra_pcm.c115
-rw-r--r--sound/soc/tegra/tegra_pcm.h2
-rw-r--r--sound/soc/tegra/tegra_wm8753.c8
-rw-r--r--sound/soc/tegra/tegra_wm8903.c259
-rw-r--r--sound/soc/tegra/trimslice.c30
-rw-r--r--sound/soc/ux500/Kconfig18
-rw-r--r--sound/soc/ux500/Makefile6
-rw-r--r--sound/soc/ux500/mop500.c113
-rw-r--r--sound/soc/ux500/mop500_ab8500.c431
-rw-r--r--sound/soc/ux500/mop500_ab8500.h22
-rw-r--r--sound/soc/ux500/ux500_msp_dai.c2
-rw-r--r--sound/soc/ux500/ux500_msp_i2s.c2
-rw-r--r--sound/soc/ux500/ux500_pcm.c318
-rw-r--r--sound/soc/ux500/ux500_pcm.h35
-rw-r--r--sound/usb/caiaq/device.c2
-rw-r--r--sound/usb/mixer_quirks.c159
228 files changed, 22285 insertions, 2435 deletions
diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c
index 270790d384e..4cedc6950d7 100644
--- a/sound/aoa/codecs/onyx.c
+++ b/sound/aoa/codecs/onyx.c
@@ -997,45 +997,10 @@ static void onyx_exit_codec(struct aoa_codec *codec)
997 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx); 997 onyx->codec.soundbus_dev->detach_codec(onyx->codec.soundbus_dev, onyx);
998} 998}
999 999
1000static int onyx_create(struct i2c_adapter *adapter,
1001 struct device_node *node,
1002 int addr)
1003{
1004 struct i2c_board_info info;
1005 struct i2c_client *client;
1006
1007 memset(&info, 0, sizeof(struct i2c_board_info));
1008 strlcpy(info.type, "aoa_codec_onyx", I2C_NAME_SIZE);
1009 info.addr = addr;
1010 info.platform_data = node;
1011 client = i2c_new_device(adapter, &info);
1012 if (!client)
1013 return -ENODEV;
1014
1015 /*
1016 * We know the driver is already loaded, so the device should be
1017 * already bound. If not it means binding failed, which suggests
1018 * the device doesn't really exist and should be deleted.
1019 * Ideally this would be replaced by better checks _before_
1020 * instantiating the device.
1021 */
1022 if (!client->driver) {
1023 i2c_unregister_device(client);
1024 return -ENODEV;
1025 }
1026
1027 /*
1028 * Let i2c-core delete that device on driver removal.
1029 * This is safe because i2c-core holds the core_lock mutex for us.
1030 */
1031 list_add_tail(&client->detected, &client->driver->clients);
1032 return 0;
1033}
1034
1035static int onyx_i2c_probe(struct i2c_client *client, 1000static int onyx_i2c_probe(struct i2c_client *client,
1036 const struct i2c_device_id *id) 1001 const struct i2c_device_id *id)
1037{ 1002{
1038 struct device_node *node = client->dev.platform_data; 1003 struct device_node *node = client->dev.of_node;
1039 struct onyx *onyx; 1004 struct onyx *onyx;
1040 u8 dummy; 1005 u8 dummy;
1041 1006
@@ -1071,40 +1036,6 @@ static int onyx_i2c_probe(struct i2c_client *client,
1071 return -ENODEV; 1036 return -ENODEV;
1072} 1037}
1073 1038
1074static int onyx_i2c_attach(struct i2c_adapter *adapter)
1075{
1076 struct device_node *busnode, *dev = NULL;
1077 struct pmac_i2c_bus *bus;
1078
1079 bus = pmac_i2c_adapter_to_bus(adapter);
1080 if (bus == NULL)
1081 return -ENODEV;
1082 busnode = pmac_i2c_get_bus_node(bus);
1083
1084 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
1085 if (of_device_is_compatible(dev, "pcm3052")) {
1086 const u32 *addr;
1087 printk(KERN_DEBUG PFX "found pcm3052\n");
1088 addr = of_get_property(dev, "reg", NULL);
1089 if (!addr)
1090 return -ENODEV;
1091 return onyx_create(adapter, dev, (*addr)>>1);
1092 }
1093 }
1094
1095 /* if that didn't work, try desperate mode for older
1096 * machines that have stuff missing from the device tree */
1097
1098 if (!of_device_is_compatible(busnode, "k2-i2c"))
1099 return -ENODEV;
1100
1101 printk(KERN_DEBUG PFX "found k2-i2c, checking if onyx chip is on it\n");
1102 /* probe both possible addresses for the onyx chip */
1103 if (onyx_create(adapter, NULL, 0x46) == 0)
1104 return 0;
1105 return onyx_create(adapter, NULL, 0x47);
1106}
1107
1108static int onyx_i2c_remove(struct i2c_client *client) 1039static int onyx_i2c_remove(struct i2c_client *client)
1109{ 1040{
1110 struct onyx *onyx = i2c_get_clientdata(client); 1041 struct onyx *onyx = i2c_get_clientdata(client);
@@ -1117,16 +1048,16 @@ static int onyx_i2c_remove(struct i2c_client *client)
1117} 1048}
1118 1049
1119static const struct i2c_device_id onyx_i2c_id[] = { 1050static const struct i2c_device_id onyx_i2c_id[] = {
1120 { "aoa_codec_onyx", 0 }, 1051 { "MAC,pcm3052", 0 },
1121 { } 1052 { }
1122}; 1053};
1054MODULE_DEVICE_TABLE(i2c,onyx_i2c_id);
1123 1055
1124static struct i2c_driver onyx_driver = { 1056static struct i2c_driver onyx_driver = {
1125 .driver = { 1057 .driver = {
1126 .name = "aoa_codec_onyx", 1058 .name = "aoa_codec_onyx",
1127 .owner = THIS_MODULE, 1059 .owner = THIS_MODULE,
1128 }, 1060 },
1129 .attach_adapter = onyx_i2c_attach,
1130 .probe = onyx_i2c_probe, 1061 .probe = onyx_i2c_probe,
1131 .remove = onyx_i2c_remove, 1062 .remove = onyx_i2c_remove,
1132 .id_table = onyx_i2c_id, 1063 .id_table = onyx_i2c_id,
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c
index 8e63d1f35ce..c491ae0f749 100644
--- a/sound/aoa/codecs/tas.c
+++ b/sound/aoa/codecs/tas.c
@@ -883,43 +883,10 @@ static void tas_exit_codec(struct aoa_codec *codec)
883} 883}
884 884
885 885
886static int tas_create(struct i2c_adapter *adapter,
887 struct device_node *node,
888 int addr)
889{
890 struct i2c_board_info info;
891 struct i2c_client *client;
892
893 memset(&info, 0, sizeof(struct i2c_board_info));
894 strlcpy(info.type, "aoa_codec_tas", I2C_NAME_SIZE);
895 info.addr = addr;
896 info.platform_data = node;
897
898 client = i2c_new_device(adapter, &info);
899 if (!client)
900 return -ENODEV;
901 /*
902 * We know the driver is already loaded, so the device should be
903 * already bound. If not it means binding failed, and then there
904 * is no point in keeping the device instantiated.
905 */
906 if (!client->driver) {
907 i2c_unregister_device(client);
908 return -ENODEV;
909 }
910
911 /*
912 * Let i2c-core delete that device on driver removal.
913 * This is safe because i2c-core holds the core_lock mutex for us.
914 */
915 list_add_tail(&client->detected, &client->driver->clients);
916 return 0;
917}
918
919static int tas_i2c_probe(struct i2c_client *client, 886static int tas_i2c_probe(struct i2c_client *client,
920 const struct i2c_device_id *id) 887 const struct i2c_device_id *id)
921{ 888{
922 struct device_node *node = client->dev.platform_data; 889 struct device_node *node = client->dev.of_node;
923 struct tas *tas; 890 struct tas *tas;
924 891
925 tas = kzalloc(sizeof(struct tas), GFP_KERNEL); 892 tas = kzalloc(sizeof(struct tas), GFP_KERNEL);
@@ -953,47 +920,6 @@ static int tas_i2c_probe(struct i2c_client *client,
953 return -EINVAL; 920 return -EINVAL;
954} 921}
955 922
956static int tas_i2c_attach(struct i2c_adapter *adapter)
957{
958 struct device_node *busnode, *dev = NULL;
959 struct pmac_i2c_bus *bus;
960
961 bus = pmac_i2c_adapter_to_bus(adapter);
962 if (bus == NULL)
963 return -ENODEV;
964 busnode = pmac_i2c_get_bus_node(bus);
965
966 while ((dev = of_get_next_child(busnode, dev)) != NULL) {
967 if (of_device_is_compatible(dev, "tas3004")) {
968 const u32 *addr;
969 printk(KERN_DEBUG PFX "found tas3004\n");
970 addr = of_get_property(dev, "reg", NULL);
971 if (!addr)
972 continue;
973 return tas_create(adapter, dev, ((*addr) >> 1) & 0x7f);
974 }
975 /* older machines have no 'codec' node with a 'compatible'
976 * property that says 'tas3004', they just have a 'deq'
977 * node without any such property... */
978 if (strcmp(dev->name, "deq") == 0) {
979 const u32 *_addr;
980 u32 addr;
981 printk(KERN_DEBUG PFX "found 'deq' node\n");
982 _addr = of_get_property(dev, "i2c-address", NULL);
983 if (!_addr)
984 continue;
985 addr = ((*_addr) >> 1) & 0x7f;
986 /* now, if the address doesn't match any of the two
987 * that a tas3004 can have, we cannot handle this.
988 * I doubt it ever happens but hey. */
989 if (addr != 0x34 && addr != 0x35)
990 continue;
991 return tas_create(adapter, dev, addr);
992 }
993 }
994 return -ENODEV;
995}
996
997static int tas_i2c_remove(struct i2c_client *client) 923static int tas_i2c_remove(struct i2c_client *client)
998{ 924{
999 struct tas *tas = i2c_get_clientdata(client); 925 struct tas *tas = i2c_get_clientdata(client);
@@ -1011,16 +937,16 @@ static int tas_i2c_remove(struct i2c_client *client)
1011} 937}
1012 938
1013static const struct i2c_device_id tas_i2c_id[] = { 939static const struct i2c_device_id tas_i2c_id[] = {
1014 { "aoa_codec_tas", 0 }, 940 { "MAC,tas3004", 0 },
1015 { } 941 { }
1016}; 942};
943MODULE_DEVICE_TABLE(i2c,tas_i2c_id);
1017 944
1018static struct i2c_driver tas_driver = { 945static struct i2c_driver tas_driver = {
1019 .driver = { 946 .driver = {
1020 .name = "aoa_codec_tas", 947 .name = "aoa_codec_tas",
1021 .owner = THIS_MODULE, 948 .owner = THIS_MODULE,
1022 }, 949 },
1023 .attach_adapter = tas_i2c_attach,
1024 .probe = tas_i2c_probe, 950 .probe = tas_i2c_probe,
1025 .remove = tas_i2c_remove, 951 .remove = tas_i2c_remove,
1026 .id_table = tas_i2c_id, 952 .id_table = tas_i2c_id,
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index afef72c4f0d..0d7b25e8164 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -108,7 +108,7 @@ static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = {
108 108
109#ifdef CONFIG_PM 109#ifdef CONFIG_PM
110 110
111static int pxa2xx_ac97_do_suspend(struct snd_card *card, pm_message_t state) 111static int pxa2xx_ac97_do_suspend(struct snd_card *card)
112{ 112{
113 pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data; 113 pxa2xx_audio_ops_t *platform_ops = card->dev->platform_data;
114 114
@@ -144,7 +144,7 @@ static int pxa2xx_ac97_suspend(struct device *dev)
144 int ret = 0; 144 int ret = 0;
145 145
146 if (card) 146 if (card)
147 ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND); 147 ret = pxa2xx_ac97_do_suspend(card);
148 148
149 return ret; 149 return ret;
150} 150}
@@ -160,10 +160,7 @@ static int pxa2xx_ac97_resume(struct device *dev)
160 return ret; 160 return ret;
161} 161}
162 162
163static const struct dev_pm_ops pxa2xx_ac97_pm_ops = { 163static SIMPLE_DEV_PM_OPS(pxa2xx_ac97_pm_ops, pxa2xx_ac97_suspend, pxa2xx_ac97_resume);
164 .suspend = pxa2xx_ac97_suspend,
165 .resume = pxa2xx_ac97_resume,
166};
167#endif 164#endif
168 165
169static int __devinit pxa2xx_ac97_probe(struct platform_device *dev) 166static int __devinit pxa2xx_ac97_probe(struct platform_device *dev)
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c
index f7c2bb08055..eb4ceb71123 100644
--- a/sound/atmel/abdac.c
+++ b/sound/atmel/abdac.c
@@ -535,9 +535,9 @@ out_put_pclk:
535} 535}
536 536
537#ifdef CONFIG_PM 537#ifdef CONFIG_PM
538static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg) 538static int atmel_abdac_suspend(struct device *pdev)
539{ 539{
540 struct snd_card *card = platform_get_drvdata(pdev); 540 struct snd_card *card = dev_get_drvdata(pdev);
541 struct atmel_abdac *dac = card->private_data; 541 struct atmel_abdac *dac = card->private_data;
542 542
543 dw_dma_cyclic_stop(dac->dma.chan); 543 dw_dma_cyclic_stop(dac->dma.chan);
@@ -547,9 +547,9 @@ static int atmel_abdac_suspend(struct platform_device *pdev, pm_message_t msg)
547 return 0; 547 return 0;
548} 548}
549 549
550static int atmel_abdac_resume(struct platform_device *pdev) 550static int atmel_abdac_resume(struct device *pdev)
551{ 551{
552 struct snd_card *card = platform_get_drvdata(pdev); 552 struct snd_card *card = dev_get_drvdata(pdev);
553 struct atmel_abdac *dac = card->private_data; 553 struct atmel_abdac *dac = card->private_data;
554 554
555 clk_enable(dac->pclk); 555 clk_enable(dac->pclk);
@@ -559,9 +559,11 @@ static int atmel_abdac_resume(struct platform_device *pdev)
559 559
560 return 0; 560 return 0;
561} 561}
562
563static SIMPLE_DEV_PM_OPS(atmel_abdac_pm, atmel_abdac_suspend, atmel_abdac_resume);
564#define ATMEL_ABDAC_PM_OPS &atmel_abdac_pm
562#else 565#else
563#define atmel_abdac_suspend NULL 566#define ATMEL_ABDAC_PM_OPS NULL
564#define atmel_abdac_resume NULL
565#endif 567#endif
566 568
567static int __devexit atmel_abdac_remove(struct platform_device *pdev) 569static int __devexit atmel_abdac_remove(struct platform_device *pdev)
@@ -589,9 +591,9 @@ static struct platform_driver atmel_abdac_driver = {
589 .remove = __devexit_p(atmel_abdac_remove), 591 .remove = __devexit_p(atmel_abdac_remove),
590 .driver = { 592 .driver = {
591 .name = "atmel_abdac", 593 .name = "atmel_abdac",
594 .owner = THIS_MODULE,
595 .pm = ATMEL_ABDAC_PM_OPS,
592 }, 596 },
593 .suspend = atmel_abdac_suspend,
594 .resume = atmel_abdac_resume,
595}; 597};
596 598
597static int __init atmel_abdac_init(void) 599static int __init atmel_abdac_init(void)
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c
index f5ded640b39..bf47025bdf4 100644
--- a/sound/atmel/ac97c.c
+++ b/sound/atmel/ac97c.c
@@ -1135,9 +1135,9 @@ err_snd_card_new:
1135} 1135}
1136 1136
1137#ifdef CONFIG_PM 1137#ifdef CONFIG_PM
1138static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg) 1138static int atmel_ac97c_suspend(struct device *pdev)
1139{ 1139{
1140 struct snd_card *card = platform_get_drvdata(pdev); 1140 struct snd_card *card = dev_get_drvdata(pdev);
1141 struct atmel_ac97c *chip = card->private_data; 1141 struct atmel_ac97c *chip = card->private_data;
1142 1142
1143 if (cpu_is_at32ap7000()) { 1143 if (cpu_is_at32ap7000()) {
@@ -1151,9 +1151,9 @@ static int atmel_ac97c_suspend(struct platform_device *pdev, pm_message_t msg)
1151 return 0; 1151 return 0;
1152} 1152}
1153 1153
1154static int atmel_ac97c_resume(struct platform_device *pdev) 1154static int atmel_ac97c_resume(struct device *pdev)
1155{ 1155{
1156 struct snd_card *card = platform_get_drvdata(pdev); 1156 struct snd_card *card = dev_get_drvdata(pdev);
1157 struct atmel_ac97c *chip = card->private_data; 1157 struct atmel_ac97c *chip = card->private_data;
1158 1158
1159 clk_enable(chip->pclk); 1159 clk_enable(chip->pclk);
@@ -1165,9 +1165,11 @@ static int atmel_ac97c_resume(struct platform_device *pdev)
1165 } 1165 }
1166 return 0; 1166 return 0;
1167} 1167}
1168
1169static SIMPLE_DEV_PM_OPS(atmel_ac97c_pm, atmel_ac97c_suspend, atmel_ac97c_resume);
1170#define ATMEL_AC97C_PM_OPS &atmel_ac97c_pm
1168#else 1171#else
1169#define atmel_ac97c_suspend NULL 1172#define ATMEL_AC97C_PM_OPS NULL
1170#define atmel_ac97c_resume NULL
1171#endif 1173#endif
1172 1174
1173static int __devexit atmel_ac97c_remove(struct platform_device *pdev) 1175static int __devexit atmel_ac97c_remove(struct platform_device *pdev)
@@ -1210,9 +1212,9 @@ static struct platform_driver atmel_ac97c_driver = {
1210 .remove = __devexit_p(atmel_ac97c_remove), 1212 .remove = __devexit_p(atmel_ac97c_remove),
1211 .driver = { 1213 .driver = {
1212 .name = "atmel_ac97c", 1214 .name = "atmel_ac97c",
1215 .owner = THIS_MODULE,
1216 .pm = ATMEL_AC97C_PM_OPS,
1213 }, 1217 },
1214 .suspend = atmel_ac97c_suspend,
1215 .resume = atmel_ac97c_resume,
1216}; 1218};
1217 1219
1218static int __init atmel_ac97c_init(void) 1220static int __init atmel_ac97c_init(void)
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 8f312fa6c28..7ae67192339 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1250,10 +1250,10 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params,
1250int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, 1250int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime,
1251 unsigned int cond, 1251 unsigned int cond,
1252 snd_pcm_hw_param_t var, 1252 snd_pcm_hw_param_t var,
1253 struct snd_pcm_hw_constraint_list *l) 1253 const struct snd_pcm_hw_constraint_list *l)
1254{ 1254{
1255 return snd_pcm_hw_rule_add(runtime, cond, var, 1255 return snd_pcm_hw_rule_add(runtime, cond, var,
1256 snd_pcm_hw_rule_list, l, 1256 snd_pcm_hw_rule_list, (void *)l,
1257 var, -1); 1257 var, -1);
1258} 1258}
1259 1259
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c
index 9c9eff9afba..d4fc1bfbe45 100644
--- a/sound/core/pcm_misc.c
+++ b/sound/core/pcm_misc.c
@@ -488,3 +488,21 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate)
488 return SNDRV_PCM_RATE_KNOT; 488 return SNDRV_PCM_RATE_KNOT;
489} 489}
490EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); 490EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit);
491
492/**
493 * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate
494 * @rate_bit: the rate bit to convert
495 *
496 * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag
497 * or 0 for an unknown rate bit
498 */
499unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit)
500{
501 unsigned int i;
502
503 for (i = 0; i < snd_pcm_known_rates.count; i++)
504 if ((1u << i) == rate_bit)
505 return snd_pcm_known_rates.list[i];
506 return 0;
507}
508EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate);
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c
index 8b5c36f4d30..1128b35b2b0 100644
--- a/sound/drivers/aloop.c
+++ b/sound/drivers/aloop.c
@@ -1177,10 +1177,9 @@ static int __devexit loopback_remove(struct platform_device *devptr)
1177} 1177}
1178 1178
1179#ifdef CONFIG_PM 1179#ifdef CONFIG_PM
1180static int loopback_suspend(struct platform_device *pdev, 1180static int loopback_suspend(struct device *pdev)
1181 pm_message_t state)
1182{ 1181{
1183 struct snd_card *card = platform_get_drvdata(pdev); 1182 struct snd_card *card = dev_get_drvdata(pdev);
1184 struct loopback *loopback = card->private_data; 1183 struct loopback *loopback = card->private_data;
1185 1184
1186 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1185 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1190,13 +1189,18 @@ static int loopback_suspend(struct platform_device *pdev,
1190 return 0; 1189 return 0;
1191} 1190}
1192 1191
1193static int loopback_resume(struct platform_device *pdev) 1192static int loopback_resume(struct device *pdev)
1194{ 1193{
1195 struct snd_card *card = platform_get_drvdata(pdev); 1194 struct snd_card *card = dev_get_drvdata(pdev);
1196 1195
1197 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1196 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1198 return 0; 1197 return 0;
1199} 1198}
1199
1200static SIMPLE_DEV_PM_OPS(loopback_pm, loopback_suspend, loopback_resume);
1201#define LOOPBACK_PM_OPS &loopback_pm
1202#else
1203#define LOOPBACK_PM_OPS NULL
1200#endif 1204#endif
1201 1205
1202#define SND_LOOPBACK_DRIVER "snd_aloop" 1206#define SND_LOOPBACK_DRIVER "snd_aloop"
@@ -1204,12 +1208,10 @@ static int loopback_resume(struct platform_device *pdev)
1204static struct platform_driver loopback_driver = { 1208static struct platform_driver loopback_driver = {
1205 .probe = loopback_probe, 1209 .probe = loopback_probe,
1206 .remove = __devexit_p(loopback_remove), 1210 .remove = __devexit_p(loopback_remove),
1207#ifdef CONFIG_PM
1208 .suspend = loopback_suspend,
1209 .resume = loopback_resume,
1210#endif
1211 .driver = { 1211 .driver = {
1212 .name = SND_LOOPBACK_DRIVER 1212 .name = SND_LOOPBACK_DRIVER,
1213 .owner = THIS_MODULE,
1214 .pm = LOOPBACK_PM_OPS,
1213 }, 1215 },
1214}; 1216};
1215 1217
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index ad9434fd637..f7d3bfc6bca 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1065,9 +1065,9 @@ static int __devexit snd_dummy_remove(struct platform_device *devptr)
1065} 1065}
1066 1066
1067#ifdef CONFIG_PM 1067#ifdef CONFIG_PM
1068static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state) 1068static int snd_dummy_suspend(struct device *pdev)
1069{ 1069{
1070 struct snd_card *card = platform_get_drvdata(pdev); 1070 struct snd_card *card = dev_get_drvdata(pdev);
1071 struct snd_dummy *dummy = card->private_data; 1071 struct snd_dummy *dummy = card->private_data;
1072 1072
1073 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1073 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1075,13 +1075,18 @@ static int snd_dummy_suspend(struct platform_device *pdev, pm_message_t state)
1075 return 0; 1075 return 0;
1076} 1076}
1077 1077
1078static int snd_dummy_resume(struct platform_device *pdev) 1078static int snd_dummy_resume(struct device *pdev)
1079{ 1079{
1080 struct snd_card *card = platform_get_drvdata(pdev); 1080 struct snd_card *card = dev_get_drvdata(pdev);
1081 1081
1082 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1082 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1083 return 0; 1083 return 0;
1084} 1084}
1085
1086static SIMPLE_DEV_PM_OPS(snd_dummy_pm, snd_dummy_suspend, snd_dummy_resume);
1087#define SND_DUMMY_PM_OPS &snd_dummy_pm
1088#else
1089#define SND_DUMMY_PM_OPS NULL
1085#endif 1090#endif
1086 1091
1087#define SND_DUMMY_DRIVER "snd_dummy" 1092#define SND_DUMMY_DRIVER "snd_dummy"
@@ -1089,12 +1094,10 @@ static int snd_dummy_resume(struct platform_device *pdev)
1089static struct platform_driver snd_dummy_driver = { 1094static struct platform_driver snd_dummy_driver = {
1090 .probe = snd_dummy_probe, 1095 .probe = snd_dummy_probe,
1091 .remove = __devexit_p(snd_dummy_remove), 1096 .remove = __devexit_p(snd_dummy_remove),
1092#ifdef CONFIG_PM
1093 .suspend = snd_dummy_suspend,
1094 .resume = snd_dummy_resume,
1095#endif
1096 .driver = { 1097 .driver = {
1097 .name = SND_DUMMY_DRIVER 1098 .name = SND_DUMMY_DRIVER,
1099 .owner = THIS_MODULE,
1100 .pm = SND_DUMMY_PM_OPS,
1098 }, 1101 },
1099}; 1102};
1100 1103
diff --git a/sound/drivers/mpu401/mpu401.c b/sound/drivers/mpu401/mpu401.c
index 86f5fbc2da7..bc03a2046c9 100644
--- a/sound/drivers/mpu401/mpu401.c
+++ b/sound/drivers/mpu401/mpu401.c
@@ -139,7 +139,8 @@ static struct platform_driver snd_mpu401_driver = {
139 .probe = snd_mpu401_probe, 139 .probe = snd_mpu401_probe,
140 .remove = __devexit_p(snd_mpu401_remove), 140 .remove = __devexit_p(snd_mpu401_remove),
141 .driver = { 141 .driver = {
142 .name = SND_MPU401_DRIVER 142 .name = SND_MPU401_DRIVER,
143 .owner = THIS_MODULE,
143 }, 144 },
144}; 145};
145 146
diff --git a/sound/drivers/mtpav.c b/sound/drivers/mtpav.c
index 76930793fb6..cad73af3860 100644
--- a/sound/drivers/mtpav.c
+++ b/sound/drivers/mtpav.c
@@ -759,7 +759,8 @@ static struct platform_driver snd_mtpav_driver = {
759 .probe = snd_mtpav_probe, 759 .probe = snd_mtpav_probe,
760 .remove = __devexit_p(snd_mtpav_remove), 760 .remove = __devexit_p(snd_mtpav_remove),
761 .driver = { 761 .driver = {
762 .name = SND_MTPAV_DRIVER 762 .name = SND_MTPAV_DRIVER,
763 .owner = THIS_MODULE,
763 }, 764 },
764}; 765};
765 766
diff --git a/sound/drivers/mts64.c b/sound/drivers/mts64.c
index 621e60e2029..2d5514b0a29 100644
--- a/sound/drivers/mts64.c
+++ b/sound/drivers/mts64.c
@@ -1040,7 +1040,8 @@ static struct platform_driver snd_mts64_driver = {
1040 .probe = snd_mts64_probe, 1040 .probe = snd_mts64_probe,
1041 .remove = __devexit_p(snd_mts64_remove), 1041 .remove = __devexit_p(snd_mts64_remove),
1042 .driver = { 1042 .driver = {
1043 .name = PLATFORM_DRIVER 1043 .name = PLATFORM_DRIVER,
1044 .owner = THIS_MODULE,
1044 } 1045 }
1045}; 1046};
1046 1047
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c
index 99704e6a2e2..6ca59fc6dcb 100644
--- a/sound/drivers/pcsp/pcsp.c
+++ b/sound/drivers/pcsp/pcsp.c
@@ -200,15 +200,18 @@ static void pcsp_stop_beep(struct snd_pcsp *chip)
200} 200}
201 201
202#ifdef CONFIG_PM 202#ifdef CONFIG_PM
203static int pcsp_suspend(struct platform_device *dev, pm_message_t state) 203static int pcsp_suspend(struct device *dev)
204{ 204{
205 struct snd_pcsp *chip = platform_get_drvdata(dev); 205 struct snd_pcsp *chip = dev_get_drvdata(dev);
206 pcsp_stop_beep(chip); 206 pcsp_stop_beep(chip);
207 snd_pcm_suspend_all(chip->pcm); 207 snd_pcm_suspend_all(chip->pcm);
208 return 0; 208 return 0;
209} 209}
210
211static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL);
212#define PCSP_PM_OPS &pcsp_pm
210#else 213#else
211#define pcsp_suspend NULL 214#define PCSP_PM_OPS NULL
212#endif /* CONFIG_PM */ 215#endif /* CONFIG_PM */
213 216
214static void pcsp_shutdown(struct platform_device *dev) 217static void pcsp_shutdown(struct platform_device *dev)
@@ -221,10 +224,10 @@ static struct platform_driver pcsp_platform_driver = {
221 .driver = { 224 .driver = {
222 .name = "pcspkr", 225 .name = "pcspkr",
223 .owner = THIS_MODULE, 226 .owner = THIS_MODULE,
227 .pm = PCSP_PM_OPS,
224 }, 228 },
225 .probe = pcsp_probe, 229 .probe = pcsp_probe,
226 .remove = __devexit_p(pcsp_remove), 230 .remove = __devexit_p(pcsp_remove),
227 .suspend = pcsp_suspend,
228 .shutdown = pcsp_shutdown, 231 .shutdown = pcsp_shutdown,
229}; 232};
230 233
diff --git a/sound/drivers/portman2x4.c b/sound/drivers/portman2x4.c
index 3e32bd3d95d..8364855ed14 100644
--- a/sound/drivers/portman2x4.c
+++ b/sound/drivers/portman2x4.c
@@ -829,7 +829,8 @@ static struct platform_driver snd_portman_driver = {
829 .probe = snd_portman_probe, 829 .probe = snd_portman_probe,
830 .remove = __devexit_p(snd_portman_remove), 830 .remove = __devexit_p(snd_portman_remove),
831 .driver = { 831 .driver = {
832 .name = PLATFORM_DRIVER 832 .name = PLATFORM_DRIVER,
833 .owner = THIS_MODULE,
833 } 834 }
834}; 835};
835 836
diff --git a/sound/drivers/serial-u16550.c b/sound/drivers/serial-u16550.c
index b2d0e8e49be..86700671d1a 100644
--- a/sound/drivers/serial-u16550.c
+++ b/sound/drivers/serial-u16550.c
@@ -995,7 +995,8 @@ static struct platform_driver snd_serial_driver = {
995 .probe = snd_serial_probe, 995 .probe = snd_serial_probe,
996 .remove = __devexit_p( snd_serial_remove), 996 .remove = __devexit_p( snd_serial_remove),
997 .driver = { 997 .driver = {
998 .name = SND_SERIAL_DRIVER 998 .name = SND_SERIAL_DRIVER,
999 .owner = THIS_MODULE,
999 }, 1000 },
1000}; 1001};
1001 1002
diff --git a/sound/drivers/virmidi.c b/sound/drivers/virmidi.c
index 9d97478a18b..d7d514df905 100644
--- a/sound/drivers/virmidi.c
+++ b/sound/drivers/virmidi.c
@@ -142,7 +142,8 @@ static struct platform_driver snd_virmidi_driver = {
142 .probe = snd_virmidi_probe, 142 .probe = snd_virmidi_probe,
143 .remove = __devexit_p(snd_virmidi_remove), 143 .remove = __devexit_p(snd_virmidi_remove),
144 .driver = { 144 .driver = {
145 .name = SND_VIRMIDI_DRIVER 145 .name = SND_VIRMIDI_DRIVER,
146 .owner = THIS_MODULE,
146 }, 147 },
147}; 148};
148 149
diff --git a/sound/drivers/vx/vx_core.c b/sound/drivers/vx/vx_core.c
index b8e515999bc..de5055a3b0d 100644
--- a/sound/drivers/vx/vx_core.c
+++ b/sound/drivers/vx/vx_core.c
@@ -725,7 +725,7 @@ EXPORT_SYMBOL(snd_vx_dsp_load);
725/* 725/*
726 * suspend 726 * suspend
727 */ 727 */
728int snd_vx_suspend(struct vx_core *chip, pm_message_t state) 728int snd_vx_suspend(struct vx_core *chip)
729{ 729{
730 unsigned int i; 730 unsigned int i;
731 731
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c
index d7ccf28bd66..f8fbe22515c 100644
--- a/sound/isa/opti9xx/opti92x-ad1848.c
+++ b/sound/isa/opti9xx/opti92x-ad1848.c
@@ -135,10 +135,9 @@ struct snd_opti9xx {
135 unsigned long mc_base_size; 135 unsigned long mc_base_size;
136#ifdef OPTi93X 136#ifdef OPTi93X
137 unsigned long mc_indir_index; 137 unsigned long mc_indir_index;
138 unsigned long mc_indir_size;
139 struct resource *res_mc_indir; 138 struct resource *res_mc_indir;
140 struct snd_wss *codec;
141#endif /* OPTi93X */ 139#endif /* OPTi93X */
140 struct snd_wss *codec;
142 unsigned long pwd_reg; 141 unsigned long pwd_reg;
143 142
144 spinlock_t lock; 143 spinlock_t lock;
@@ -245,10 +244,8 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
245 case OPTi9XX_HW_82C931: 244 case OPTi9XX_HW_82C931:
246 case OPTi9XX_HW_82C933: 245 case OPTi9XX_HW_82C933:
247 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; 246 chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d;
248 if (!chip->mc_indir_index) { 247 if (!chip->mc_indir_index)
249 chip->mc_indir_index = 0xe0e; 248 chip->mc_indir_index = 0xe0e;
250 chip->mc_indir_size = 2;
251 }
252 chip->password = 0xe4; 249 chip->password = 0xe4;
253 chip->pwd_reg = 0; 250 chip->pwd_reg = 0;
254 break; 251 break;
@@ -351,7 +348,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
351 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) 348 (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
352 349
353 350
354static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, 351static int snd_opti9xx_configure(struct snd_opti9xx *chip,
355 long port, 352 long port,
356 int irq, int dma1, int dma2, 353 int irq, int dma1, int dma2,
357 long mpu_port, int mpu_irq) 354 long mpu_port, int mpu_irq)
@@ -403,7 +400,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
403 400
404#else /* OPTi93X */ 401#else /* OPTi93X */
405 case OPTi9XX_HW_82C931: 402 case OPTi9XX_HW_82C931:
406 case OPTi9XX_HW_82C933: 403 /* disable 3D sound (set GPIO1 as output, low) */
404 snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c);
405 case OPTi9XX_HW_82C933: /* FALL THROUGH */
407 /* 406 /*
408 * The BTC 1817DW has QS1000 wavetable which is connected 407 * The BTC 1817DW has QS1000 wavetable which is connected
409 * to the serial digital input of the OPTI931. 408 * to the serial digital input of the OPTI931.
@@ -696,8 +695,7 @@ static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip)
696 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) 695 if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1)))
697 return 0; 696 return 0;
698#else /* OPTi93X */ 697#else /* OPTi93X */
699 chip->res_mc_indir = request_region(chip->mc_indir_index, 698 chip->res_mc_indir = request_region(chip->mc_indir_index, 2,
700 chip->mc_indir_size,
701 "OPTi93x MC"); 699 "OPTi93x MC");
702 if (chip->res_mc_indir == NULL) 700 if (chip->res_mc_indir == NULL)
703 return -EBUSY; 701 return -EBUSY;
@@ -770,8 +768,9 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip,
770#ifdef OPTi93X 768#ifdef OPTi93X
771 port = pnp_port_start(pdev, 0) - 4; 769 port = pnp_port_start(pdev, 0) - 4;
772 fm_port = pnp_port_start(pdev, 1) + 8; 770 fm_port = pnp_port_start(pdev, 1) + 8;
773 chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; 771 /* adjust mc_indir_index - some cards report it at 0xe?d,
774 chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; 772 other at 0xe?c but it really is always at 0xe?e */
773 chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe;
775#else 774#else
776 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); 775 devmc = pnp_request_card_device(card, pid->devs[2].id, NULL);
777 if (devmc == NULL) 776 if (devmc == NULL)
@@ -871,9 +870,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
871 &codec); 870 &codec);
872 if (error < 0) 871 if (error < 0)
873 return error; 872 return error;
874#ifdef OPTi93X
875 chip->codec = codec; 873 chip->codec = codec;
876#endif
877 error = snd_wss_pcm(codec, 0, &pcm); 874 error = snd_wss_pcm(codec, 0, &pcm);
878 if (error < 0) 875 if (error < 0)
879 return error; 876 return error;
@@ -1054,11 +1051,55 @@ static int __devexit snd_opti9xx_isa_remove(struct device *devptr,
1054 return 0; 1051 return 0;
1055} 1052}
1056 1053
1054#ifdef CONFIG_PM
1055static int snd_opti9xx_suspend(struct snd_card *card)
1056{
1057 struct snd_opti9xx *chip = card->private_data;
1058
1059 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
1060 chip->codec->suspend(chip->codec);
1061 return 0;
1062}
1063
1064static int snd_opti9xx_resume(struct snd_card *card)
1065{
1066 struct snd_opti9xx *chip = card->private_data;
1067 int error, xdma2;
1068#if defined(CS4231) || defined(OPTi93X)
1069 xdma2 = dma2;
1070#else
1071 xdma2 = -1;
1072#endif
1073
1074 error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
1075 mpu_port, mpu_irq);
1076 if (error)
1077 return error;
1078 chip->codec->resume(chip->codec);
1079 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1080 return 0;
1081}
1082
1083static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n,
1084 pm_message_t state)
1085{
1086 return snd_opti9xx_suspend(dev_get_drvdata(dev));
1087}
1088
1089static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n)
1090{
1091 return snd_opti9xx_resume(dev_get_drvdata(dev));
1092}
1093#endif
1094
1057static struct isa_driver snd_opti9xx_driver = { 1095static struct isa_driver snd_opti9xx_driver = {
1058 .match = snd_opti9xx_isa_match, 1096 .match = snd_opti9xx_isa_match,
1059 .probe = snd_opti9xx_isa_probe, 1097 .probe = snd_opti9xx_isa_probe,
1060 .remove = __devexit_p(snd_opti9xx_isa_remove), 1098 .remove = __devexit_p(snd_opti9xx_isa_remove),
1061 /* FIXME: suspend/resume */ 1099#ifdef CONFIG_PM
1100 .suspend = snd_opti9xx_isa_suspend,
1101 .resume = snd_opti9xx_isa_resume,
1102#endif
1062 .driver = { 1103 .driver = {
1063 .name = DEV_NAME 1104 .name = DEV_NAME
1064 }, 1105 },
@@ -1124,12 +1165,29 @@ static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard)
1124 snd_opti9xx_pnp_is_probed = 0; 1165 snd_opti9xx_pnp_is_probed = 0;
1125} 1166}
1126 1167
1168#ifdef CONFIG_PM
1169static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard,
1170 pm_message_t state)
1171{
1172 return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard));
1173}
1174
1175static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard)
1176{
1177 return snd_opti9xx_resume(pnp_get_card_drvdata(pcard));
1178}
1179#endif
1180
1127static struct pnp_card_driver opti9xx_pnpc_driver = { 1181static struct pnp_card_driver opti9xx_pnpc_driver = {
1128 .flags = PNP_DRIVER_RES_DISABLE, 1182 .flags = PNP_DRIVER_RES_DISABLE,
1129 .name = "opti9xx", 1183 .name = "opti9xx",
1130 .id_table = snd_opti9xx_pnpids, 1184 .id_table = snd_opti9xx_pnpids,
1131 .probe = snd_opti9xx_pnp_probe, 1185 .probe = snd_opti9xx_pnp_probe,
1132 .remove = __devexit_p(snd_opti9xx_pnp_remove), 1186 .remove = __devexit_p(snd_opti9xx_pnp_remove),
1187#ifdef CONFIG_PM
1188 .suspend = snd_opti9xx_pnp_suspend,
1189 .resume = snd_opti9xx_pnp_resume,
1190#endif
1133}; 1191};
1134#endif 1192#endif
1135 1193
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c
index 49c8a0c2442..360b08b03e1 100644
--- a/sound/isa/wss/wss_lib.c
+++ b/sound/isa/wss/wss_lib.c
@@ -1456,7 +1456,6 @@ static struct snd_pcm_hardware snd_wss_playback =
1456{ 1456{
1457 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | 1457 .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
1458 SNDRV_PCM_INFO_MMAP_VALID | 1458 SNDRV_PCM_INFO_MMAP_VALID |
1459 SNDRV_PCM_INFO_RESUME |
1460 SNDRV_PCM_INFO_SYNC_START), 1459 SNDRV_PCM_INFO_SYNC_START),
1461 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | 1460 .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM |
1462 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), 1461 SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE),
@@ -1657,6 +1656,10 @@ static void snd_wss_resume(struct snd_wss *chip)
1657 break; 1656 break;
1658 } 1657 }
1659 } 1658 }
1659 /* Yamaha needs this to resume properly */
1660 if (chip->hardware == WSS_HW_OPL3SA2)
1661 snd_wss_out(chip, CS4231_PLAYBK_FORMAT,
1662 chip->image[CS4231_PLAYBK_FORMAT]);
1660 spin_unlock_irqrestore(&chip->reg_lock, flags); 1663 spin_unlock_irqrestore(&chip->reg_lock, flags);
1661#if 1 1664#if 1
1662 snd_wss_mce_down(chip); 1665 snd_wss_mce_down(chip);
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c
index 09d46484bc1..7d8803a00b7 100644
--- a/sound/oss/swarm_cs4297a.c
+++ b/sound/oss/swarm_cs4297a.c
@@ -69,7 +69,6 @@
69#include <linux/sound.h> 69#include <linux/sound.h>
70#include <linux/slab.h> 70#include <linux/slab.h>
71#include <linux/soundcard.h> 71#include <linux/soundcard.h>
72#include <linux/ac97_codec.h>
73#include <linux/pci.h> 72#include <linux/pci.h>
74#include <linux/bitops.h> 73#include <linux/bitops.h>
75#include <linux/interrupt.h> 74#include <linux/interrupt.h>
@@ -199,6 +198,22 @@ static const char invalid_magic[] =
199 } \ 198 } \
200}) 199})
201 200
201/* AC97 registers */
202#define AC97_MASTER_VOL_STEREO 0x0002 /* Line Out */
203#define AC97_PCBEEP_VOL 0x000a /* none */
204#define AC97_PHONE_VOL 0x000c /* TAD Input (mono) */
205#define AC97_MIC_VOL 0x000e /* MIC Input (mono) */
206#define AC97_LINEIN_VOL 0x0010 /* Line Input (stereo) */
207#define AC97_CD_VOL 0x0012 /* CD Input (stereo) */
208#define AC97_AUX_VOL 0x0016 /* Aux Input (stereo) */
209#define AC97_PCMOUT_VOL 0x0018 /* Wave Output (stereo) */
210#define AC97_RECORD_SELECT 0x001a /* */
211#define AC97_RECORD_GAIN 0x001c
212#define AC97_GENERAL_PURPOSE 0x0020
213#define AC97_3D_CONTROL 0x0022
214#define AC97_POWER_CONTROL 0x0026
215#define AC97_VENDOR_ID1 0x007c
216
202struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs }; 217struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs };
203 218
204typedef struct serdma_descr_s { 219typedef struct serdma_descr_s {
diff --git a/sound/oss/vwsnd.c b/sound/oss/vwsnd.c
index 643f1113b1d..7e814a5c367 100644
--- a/sound/oss/vwsnd.c
+++ b/sound/oss/vwsnd.c
@@ -438,7 +438,7 @@ static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val)
438 * 438 *
439 * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)). 439 * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)).
440 * As long as mask is constant, we trust the compiler will change the 440 * As long as mask is constant, we trust the compiler will change the
441 * multipy and divide into shifts. 441 * multiply and divide into shifts.
442 */ 442 */
443 443
444#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask)) 444#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask))
diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
index 9dfc27bf6cc..ee895f3c860 100644
--- a/sound/pci/ali5451/ali5451.c
+++ b/sound/pci/ali5451/ali5451.c
@@ -1884,9 +1884,10 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec)
1884} 1884}
1885 1885
1886#ifdef CONFIG_PM 1886#ifdef CONFIG_PM
1887static int ali_suspend(struct pci_dev *pci, pm_message_t state) 1887static int ali_suspend(struct device *dev)
1888{ 1888{
1889 struct snd_card *card = pci_get_drvdata(pci); 1889 struct pci_dev *pci = to_pci_dev(dev);
1890 struct snd_card *card = dev_get_drvdata(dev);
1890 struct snd_ali *chip = card->private_data; 1891 struct snd_ali *chip = card->private_data;
1891 struct snd_ali_image *im; 1892 struct snd_ali_image *im;
1892 int i, j; 1893 int i, j;
@@ -1929,13 +1930,14 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state)
1929 1930
1930 pci_disable_device(pci); 1931 pci_disable_device(pci);
1931 pci_save_state(pci); 1932 pci_save_state(pci);
1932 pci_set_power_state(pci, pci_choose_state(pci, state)); 1933 pci_set_power_state(pci, PCI_D3hot);
1933 return 0; 1934 return 0;
1934} 1935}
1935 1936
1936static int ali_resume(struct pci_dev *pci) 1937static int ali_resume(struct device *dev)
1937{ 1938{
1938 struct snd_card *card = pci_get_drvdata(pci); 1939 struct pci_dev *pci = to_pci_dev(dev);
1940 struct snd_card *card = dev_get_drvdata(dev);
1939 struct snd_ali *chip = card->private_data; 1941 struct snd_ali *chip = card->private_data;
1940 struct snd_ali_image *im; 1942 struct snd_ali_image *im;
1941 int i, j; 1943 int i, j;
@@ -1982,6 +1984,11 @@ static int ali_resume(struct pci_dev *pci)
1982 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1984 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1983 return 0; 1985 return 0;
1984} 1986}
1987
1988static SIMPLE_DEV_PM_OPS(ali_pm, ali_suspend, ali_resume);
1989#define ALI_PM_OPS &ali_pm
1990#else
1991#define ALI_PM_OPS NULL
1985#endif /* CONFIG_PM */ 1992#endif /* CONFIG_PM */
1986 1993
1987static int snd_ali_free(struct snd_ali * codec) 1994static int snd_ali_free(struct snd_ali * codec)
@@ -2299,10 +2306,9 @@ static struct pci_driver ali5451_driver = {
2299 .id_table = snd_ali_ids, 2306 .id_table = snd_ali_ids,
2300 .probe = snd_ali_probe, 2307 .probe = snd_ali_probe,
2301 .remove = __devexit_p(snd_ali_remove), 2308 .remove = __devexit_p(snd_ali_remove),
2302#ifdef CONFIG_PM 2309 .driver = {
2303 .suspend = ali_suspend, 2310 .pm = ALI_PM_OPS,
2304 .resume = ali_resume, 2311 },
2305#endif
2306}; 2312};
2307 2313
2308module_pci_driver(ali5451_driver); 2314module_pci_driver(ali5451_driver);
diff --git a/sound/pci/als300.c b/sound/pci/als300.c
index 59d65388faf..68c4469c6d1 100644
--- a/sound/pci/als300.c
+++ b/sound/pci/als300.c
@@ -766,9 +766,10 @@ static int __devinit snd_als300_create(struct snd_card *card,
766} 766}
767 767
768#ifdef CONFIG_PM 768#ifdef CONFIG_PM
769static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state) 769static int snd_als300_suspend(struct device *dev)
770{ 770{
771 struct snd_card *card = pci_get_drvdata(pci); 771 struct pci_dev *pci = to_pci_dev(dev);
772 struct snd_card *card = dev_get_drvdata(dev);
772 struct snd_als300 *chip = card->private_data; 773 struct snd_als300 *chip = card->private_data;
773 774
774 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 775 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -777,13 +778,14 @@ static int snd_als300_suspend(struct pci_dev *pci, pm_message_t state)
777 778
778 pci_disable_device(pci); 779 pci_disable_device(pci);
779 pci_save_state(pci); 780 pci_save_state(pci);
780 pci_set_power_state(pci, pci_choose_state(pci, state)); 781 pci_set_power_state(pci, PCI_D3hot);
781 return 0; 782 return 0;
782} 783}
783 784
784static int snd_als300_resume(struct pci_dev *pci) 785static int snd_als300_resume(struct device *dev)
785{ 786{
786 struct snd_card *card = pci_get_drvdata(pci); 787 struct pci_dev *pci = to_pci_dev(dev);
788 struct snd_card *card = dev_get_drvdata(dev);
787 struct snd_als300 *chip = card->private_data; 789 struct snd_als300 *chip = card->private_data;
788 790
789 pci_set_power_state(pci, PCI_D0); 791 pci_set_power_state(pci, PCI_D0);
@@ -802,6 +804,11 @@ static int snd_als300_resume(struct pci_dev *pci)
802 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 804 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
803 return 0; 805 return 0;
804} 806}
807
808static SIMPLE_DEV_PM_OPS(snd_als300_pm, snd_als300_suspend, snd_als300_resume);
809#define SND_ALS300_PM_OPS &snd_als300_pm
810#else
811#define SND_ALS300_PM_OPS NULL
805#endif 812#endif
806 813
807static int __devinit snd_als300_probe(struct pci_dev *pci, 814static int __devinit snd_als300_probe(struct pci_dev *pci,
@@ -857,10 +864,9 @@ static struct pci_driver als300_driver = {
857 .id_table = snd_als300_ids, 864 .id_table = snd_als300_ids,
858 .probe = snd_als300_probe, 865 .probe = snd_als300_probe,
859 .remove = __devexit_p(snd_als300_remove), 866 .remove = __devexit_p(snd_als300_remove),
860#ifdef CONFIG_PM 867 .driver = {
861 .suspend = snd_als300_suspend, 868 .pm = SND_ALS300_PM_OPS,
862 .resume = snd_als300_resume, 869 },
863#endif
864}; 870};
865 871
866module_pci_driver(als300_driver); 872module_pci_driver(als300_driver);
diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c
index 7d7f2598c74..0eeca49c575 100644
--- a/sound/pci/als4000.c
+++ b/sound/pci/als4000.c
@@ -988,9 +988,10 @@ static void __devexit snd_card_als4000_remove(struct pci_dev *pci)
988} 988}
989 989
990#ifdef CONFIG_PM 990#ifdef CONFIG_PM
991static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state) 991static int snd_als4000_suspend(struct device *dev)
992{ 992{
993 struct snd_card *card = pci_get_drvdata(pci); 993 struct pci_dev *pci = to_pci_dev(dev);
994 struct snd_card *card = dev_get_drvdata(dev);
994 struct snd_card_als4000 *acard = card->private_data; 995 struct snd_card_als4000 *acard = card->private_data;
995 struct snd_sb *chip = acard->chip; 996 struct snd_sb *chip = acard->chip;
996 997
@@ -1001,13 +1002,14 @@ static int snd_als4000_suspend(struct pci_dev *pci, pm_message_t state)
1001 1002
1002 pci_disable_device(pci); 1003 pci_disable_device(pci);
1003 pci_save_state(pci); 1004 pci_save_state(pci);
1004 pci_set_power_state(pci, pci_choose_state(pci, state)); 1005 pci_set_power_state(pci, PCI_D3hot);
1005 return 0; 1006 return 0;
1006} 1007}
1007 1008
1008static int snd_als4000_resume(struct pci_dev *pci) 1009static int snd_als4000_resume(struct device *dev)
1009{ 1010{
1010 struct snd_card *card = pci_get_drvdata(pci); 1011 struct pci_dev *pci = to_pci_dev(dev);
1012 struct snd_card *card = dev_get_drvdata(dev);
1011 struct snd_card_als4000 *acard = card->private_data; 1013 struct snd_card_als4000 *acard = card->private_data;
1012 struct snd_sb *chip = acard->chip; 1014 struct snd_sb *chip = acard->chip;
1013 1015
@@ -1033,18 +1035,21 @@ static int snd_als4000_resume(struct pci_dev *pci)
1033 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1035 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1034 return 0; 1036 return 0;
1035} 1037}
1036#endif /* CONFIG_PM */
1037 1038
1039static SIMPLE_DEV_PM_OPS(snd_als4000_pm, snd_als4000_suspend, snd_als4000_resume);
1040#define SND_ALS4000_PM_OPS &snd_als4000_pm
1041#else
1042#define SND_ALS4000_PM_OPS NULL
1043#endif /* CONFIG_PM */
1038 1044
1039static struct pci_driver als4000_driver = { 1045static struct pci_driver als4000_driver = {
1040 .name = KBUILD_MODNAME, 1046 .name = KBUILD_MODNAME,
1041 .id_table = snd_als4000_ids, 1047 .id_table = snd_als4000_ids,
1042 .probe = snd_card_als4000_probe, 1048 .probe = snd_card_als4000_probe,
1043 .remove = __devexit_p(snd_card_als4000_remove), 1049 .remove = __devexit_p(snd_card_als4000_remove),
1044#ifdef CONFIG_PM 1050 .driver = {
1045 .suspend = snd_als4000_suspend, 1051 .pm = SND_ALS4000_PM_OPS,
1046 .resume = snd_als4000_resume, 1052 },
1047#endif
1048}; 1053};
1049 1054
1050module_pci_driver(als4000_driver); 1055module_pci_driver(als4000_driver);
diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c
index 156a94f8a12..31020d2a868 100644
--- a/sound/pci/atiixp.c
+++ b/sound/pci/atiixp.c
@@ -1462,9 +1462,10 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp *chip, int clock,
1462/* 1462/*
1463 * power management 1463 * power management
1464 */ 1464 */
1465static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state) 1465static int snd_atiixp_suspend(struct device *dev)
1466{ 1466{
1467 struct snd_card *card = pci_get_drvdata(pci); 1467 struct pci_dev *pci = to_pci_dev(dev);
1468 struct snd_card *card = dev_get_drvdata(dev);
1468 struct atiixp *chip = card->private_data; 1469 struct atiixp *chip = card->private_data;
1469 int i; 1470 int i;
1470 1471
@@ -1484,13 +1485,14 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
1484 1485
1485 pci_disable_device(pci); 1486 pci_disable_device(pci);
1486 pci_save_state(pci); 1487 pci_save_state(pci);
1487 pci_set_power_state(pci, pci_choose_state(pci, state)); 1488 pci_set_power_state(pci, PCI_D3hot);
1488 return 0; 1489 return 0;
1489} 1490}
1490 1491
1491static int snd_atiixp_resume(struct pci_dev *pci) 1492static int snd_atiixp_resume(struct device *dev)
1492{ 1493{
1493 struct snd_card *card = pci_get_drvdata(pci); 1494 struct pci_dev *pci = to_pci_dev(dev);
1495 struct snd_card *card = dev_get_drvdata(dev);
1494 struct atiixp *chip = card->private_data; 1496 struct atiixp *chip = card->private_data;
1495 int i; 1497 int i;
1496 1498
@@ -1526,6 +1528,11 @@ static int snd_atiixp_resume(struct pci_dev *pci)
1526 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1528 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1527 return 0; 1529 return 0;
1528} 1530}
1531
1532static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
1533#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
1534#else
1535#define SND_ATIIXP_PM_OPS NULL
1529#endif /* CONFIG_PM */ 1536#endif /* CONFIG_PM */
1530 1537
1531 1538
@@ -1705,10 +1712,9 @@ static struct pci_driver atiixp_driver = {
1705 .id_table = snd_atiixp_ids, 1712 .id_table = snd_atiixp_ids,
1706 .probe = snd_atiixp_probe, 1713 .probe = snd_atiixp_probe,
1707 .remove = __devexit_p(snd_atiixp_remove), 1714 .remove = __devexit_p(snd_atiixp_remove),
1708#ifdef CONFIG_PM 1715 .driver = {
1709 .suspend = snd_atiixp_suspend, 1716 .pm = SND_ATIIXP_PM_OPS,
1710 .resume = snd_atiixp_resume, 1717 },
1711#endif
1712}; 1718};
1713 1719
1714module_pci_driver(atiixp_driver); 1720module_pci_driver(atiixp_driver);
diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c
index 30a4fd96ce7..79e204ec623 100644
--- a/sound/pci/atiixp_modem.c
+++ b/sound/pci/atiixp_modem.c
@@ -1117,9 +1117,10 @@ static int __devinit snd_atiixp_mixer_new(struct atiixp_modem *chip, int clock)
1117/* 1117/*
1118 * power management 1118 * power management
1119 */ 1119 */
1120static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state) 1120static int snd_atiixp_suspend(struct device *dev)
1121{ 1121{
1122 struct snd_card *card = pci_get_drvdata(pci); 1122 struct pci_dev *pci = to_pci_dev(dev);
1123 struct snd_card *card = dev_get_drvdata(dev);
1123 struct atiixp_modem *chip = card->private_data; 1124 struct atiixp_modem *chip = card->private_data;
1124 int i; 1125 int i;
1125 1126
@@ -1133,13 +1134,14 @@ static int snd_atiixp_suspend(struct pci_dev *pci, pm_message_t state)
1133 1134
1134 pci_disable_device(pci); 1135 pci_disable_device(pci);
1135 pci_save_state(pci); 1136 pci_save_state(pci);
1136 pci_set_power_state(pci, pci_choose_state(pci, state)); 1137 pci_set_power_state(pci, PCI_D3hot);
1137 return 0; 1138 return 0;
1138} 1139}
1139 1140
1140static int snd_atiixp_resume(struct pci_dev *pci) 1141static int snd_atiixp_resume(struct device *dev)
1141{ 1142{
1142 struct snd_card *card = pci_get_drvdata(pci); 1143 struct pci_dev *pci = to_pci_dev(dev);
1144 struct snd_card *card = dev_get_drvdata(dev);
1143 struct atiixp_modem *chip = card->private_data; 1145 struct atiixp_modem *chip = card->private_data;
1144 int i; 1146 int i;
1145 1147
@@ -1162,8 +1164,12 @@ static int snd_atiixp_resume(struct pci_dev *pci)
1162 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1164 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1163 return 0; 1165 return 0;
1164} 1166}
1165#endif /* CONFIG_PM */
1166 1167
1168static SIMPLE_DEV_PM_OPS(snd_atiixp_pm, snd_atiixp_suspend, snd_atiixp_resume);
1169#define SND_ATIIXP_PM_OPS &snd_atiixp_pm
1170#else
1171#define SND_ATIIXP_PM_OPS NULL
1172#endif /* CONFIG_PM */
1167 1173
1168#ifdef CONFIG_PROC_FS 1174#ifdef CONFIG_PROC_FS
1169/* 1175/*
@@ -1336,10 +1342,9 @@ static struct pci_driver atiixp_modem_driver = {
1336 .id_table = snd_atiixp_ids, 1342 .id_table = snd_atiixp_ids,
1337 .probe = snd_atiixp_probe, 1343 .probe = snd_atiixp_probe,
1338 .remove = __devexit_p(snd_atiixp_remove), 1344 .remove = __devexit_p(snd_atiixp_remove),
1339#ifdef CONFIG_PM 1345 .driver = {
1340 .suspend = snd_atiixp_suspend, 1346 .pm = SND_ATIIXP_PM_OPS,
1341 .resume = snd_atiixp_resume, 1347 },
1342#endif
1343}; 1348};
1344 1349
1345module_pci_driver(atiixp_modem_driver); 1350module_pci_driver(atiixp_modem_driver);
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c
index 557c782ae4f..fa13efbebda 100644
--- a/sound/pci/au88x0/au88x0_mixer.c
+++ b/sound/pci/au88x0/au88x0_mixer.c
@@ -10,6 +10,15 @@
10#include <sound/core.h> 10#include <sound/core.h>
11#include "au88x0.h" 11#include "au88x0.h"
12 12
13static int remove_ctl(struct snd_card *card, const char *name)
14{
15 struct snd_ctl_elem_id id;
16 memset(&id, 0, sizeof(id));
17 strcpy(id.name, name);
18 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
19 return snd_ctl_remove_id(card, &id);
20}
21
13static int __devinit snd_vortex_mixer(vortex_t * vortex) 22static int __devinit snd_vortex_mixer(vortex_t * vortex)
14{ 23{
15 struct snd_ac97_bus *pbus; 24 struct snd_ac97_bus *pbus;
@@ -28,5 +37,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex)
28 ac97.scaps = AC97_SCAP_NO_SPDIF; 37 ac97.scaps = AC97_SCAP_NO_SPDIF;
29 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); 38 err = snd_ac97_mixer(pbus, &ac97, &vortex->codec);
30 vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); 39 vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80));
40 remove_ctl(vortex->card, "Master Mono Playback Volume");
41 remove_ctl(vortex->card, "Master Mono Playback Switch");
31 return err; 42 return err;
32} 43}
diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c
index f0b4d7493af..4dddd871548 100644
--- a/sound/pci/azt3328.c
+++ b/sound/pci/azt3328.c
@@ -2794,9 +2794,10 @@ snd_azf3328_resume_ac97(const struct snd_azf3328 *chip)
2794} 2794}
2795 2795
2796static int 2796static int
2797snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state) 2797snd_azf3328_suspend(struct device *dev)
2798{ 2798{
2799 struct snd_card *card = pci_get_drvdata(pci); 2799 struct pci_dev *pci = to_pci_dev(dev);
2800 struct snd_card *card = dev_get_drvdata(dev);
2800 struct snd_azf3328 *chip = card->private_data; 2801 struct snd_azf3328 *chip = card->private_data;
2801 u16 *saved_regs_ctrl_u16; 2802 u16 *saved_regs_ctrl_u16;
2802 2803
@@ -2824,14 +2825,15 @@ snd_azf3328_suspend(struct pci_dev *pci, pm_message_t state)
2824 2825
2825 pci_disable_device(pci); 2826 pci_disable_device(pci);
2826 pci_save_state(pci); 2827 pci_save_state(pci);
2827 pci_set_power_state(pci, pci_choose_state(pci, state)); 2828 pci_set_power_state(pci, PCI_D3hot);
2828 return 0; 2829 return 0;
2829} 2830}
2830 2831
2831static int 2832static int
2832snd_azf3328_resume(struct pci_dev *pci) 2833snd_azf3328_resume(struct device *dev)
2833{ 2834{
2834 struct snd_card *card = pci_get_drvdata(pci); 2835 struct pci_dev *pci = to_pci_dev(dev);
2836 struct snd_card *card = dev_get_drvdata(dev);
2835 const struct snd_azf3328 *chip = card->private_data; 2837 const struct snd_azf3328 *chip = card->private_data;
2836 2838
2837 pci_set_power_state(pci, PCI_D0); 2839 pci_set_power_state(pci, PCI_D0);
@@ -2859,18 +2861,21 @@ snd_azf3328_resume(struct pci_dev *pci)
2859 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2861 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2860 return 0; 2862 return 0;
2861} 2863}
2862#endif /* CONFIG_PM */
2863 2864
2865static SIMPLE_DEV_PM_OPS(snd_azf3328_pm, snd_azf3328_suspend, snd_azf3328_resume);
2866#define SND_AZF3328_PM_OPS &snd_azf3328_pm
2867#else
2868#define SND_AZF3328_PM_OPS NULL
2869#endif /* CONFIG_PM */
2864 2870
2865static struct pci_driver azf3328_driver = { 2871static struct pci_driver azf3328_driver = {
2866 .name = KBUILD_MODNAME, 2872 .name = KBUILD_MODNAME,
2867 .id_table = snd_azf3328_ids, 2873 .id_table = snd_azf3328_ids,
2868 .probe = snd_azf3328_probe, 2874 .probe = snd_azf3328_probe,
2869 .remove = __devexit_p(snd_azf3328_remove), 2875 .remove = __devexit_p(snd_azf3328_remove),
2870#ifdef CONFIG_PM 2876 .driver = {
2871 .suspend = snd_azf3328_suspend, 2877 .pm = SND_AZF3328_PM_OPS,
2872 .resume = snd_azf3328_resume, 2878 },
2873#endif
2874}; 2879};
2875 2880
2876module_pci_driver(azf3328_driver); 2881module_pci_driver(azf3328_driver);
diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c
index e76d68a7081..83277b747b3 100644
--- a/sound/pci/ca0106/ca0106_main.c
+++ b/sound/pci/ca0106/ca0106_main.c
@@ -1872,9 +1872,10 @@ static void __devexit snd_ca0106_remove(struct pci_dev *pci)
1872} 1872}
1873 1873
1874#ifdef CONFIG_PM 1874#ifdef CONFIG_PM
1875static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state) 1875static int snd_ca0106_suspend(struct device *dev)
1876{ 1876{
1877 struct snd_card *card = pci_get_drvdata(pci); 1877 struct pci_dev *pci = to_pci_dev(dev);
1878 struct snd_card *card = dev_get_drvdata(dev);
1878 struct snd_ca0106 *chip = card->private_data; 1879 struct snd_ca0106 *chip = card->private_data;
1879 int i; 1880 int i;
1880 1881
@@ -1889,13 +1890,14 @@ static int snd_ca0106_suspend(struct pci_dev *pci, pm_message_t state)
1889 1890
1890 pci_disable_device(pci); 1891 pci_disable_device(pci);
1891 pci_save_state(pci); 1892 pci_save_state(pci);
1892 pci_set_power_state(pci, pci_choose_state(pci, state)); 1893 pci_set_power_state(pci, PCI_D3hot);
1893 return 0; 1894 return 0;
1894} 1895}
1895 1896
1896static int snd_ca0106_resume(struct pci_dev *pci) 1897static int snd_ca0106_resume(struct device *dev)
1897{ 1898{
1898 struct snd_card *card = pci_get_drvdata(pci); 1899 struct pci_dev *pci = to_pci_dev(dev);
1900 struct snd_card *card = dev_get_drvdata(dev);
1899 struct snd_ca0106 *chip = card->private_data; 1901 struct snd_ca0106 *chip = card->private_data;
1900 int i; 1902 int i;
1901 1903
@@ -1922,6 +1924,11 @@ static int snd_ca0106_resume(struct pci_dev *pci)
1922 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1924 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1923 return 0; 1925 return 0;
1924} 1926}
1927
1928static SIMPLE_DEV_PM_OPS(snd_ca0106_pm, snd_ca0106_suspend, snd_ca0106_resume);
1929#define SND_CA0106_PM_OPS &snd_ca0106_pm
1930#else
1931#define SND_CA0106_PM_OPS NULL
1925#endif 1932#endif
1926 1933
1927// PCI IDs 1934// PCI IDs
@@ -1937,10 +1944,9 @@ static struct pci_driver ca0106_driver = {
1937 .id_table = snd_ca0106_ids, 1944 .id_table = snd_ca0106_ids,
1938 .probe = snd_ca0106_probe, 1945 .probe = snd_ca0106_probe,
1939 .remove = __devexit_p(snd_ca0106_remove), 1946 .remove = __devexit_p(snd_ca0106_remove),
1940#ifdef CONFIG_PM 1947 .driver = {
1941 .suspend = snd_ca0106_suspend, 1948 .pm = SND_CA0106_PM_OPS,
1942 .resume = snd_ca0106_resume, 1949 },
1943#endif
1944}; 1950};
1945 1951
1946module_pci_driver(ca0106_driver); 1952module_pci_driver(ca0106_driver);
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index 3815bd4c677..b7d6f2b886e 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -3338,9 +3338,10 @@ static unsigned char saved_mixers[] = {
3338 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 3338 SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT,
3339}; 3339};
3340 3340
3341static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state) 3341static int snd_cmipci_suspend(struct device *dev)
3342{ 3342{
3343 struct snd_card *card = pci_get_drvdata(pci); 3343 struct pci_dev *pci = to_pci_dev(dev);
3344 struct snd_card *card = dev_get_drvdata(dev);
3344 struct cmipci *cm = card->private_data; 3345 struct cmipci *cm = card->private_data;
3345 int i; 3346 int i;
3346 3347
@@ -3361,13 +3362,14 @@ static int snd_cmipci_suspend(struct pci_dev *pci, pm_message_t state)
3361 3362
3362 pci_disable_device(pci); 3363 pci_disable_device(pci);
3363 pci_save_state(pci); 3364 pci_save_state(pci);
3364 pci_set_power_state(pci, pci_choose_state(pci, state)); 3365 pci_set_power_state(pci, PCI_D3hot);
3365 return 0; 3366 return 0;
3366} 3367}
3367 3368
3368static int snd_cmipci_resume(struct pci_dev *pci) 3369static int snd_cmipci_resume(struct device *dev)
3369{ 3370{
3370 struct snd_card *card = pci_get_drvdata(pci); 3371 struct pci_dev *pci = to_pci_dev(dev);
3372 struct snd_card *card = dev_get_drvdata(dev);
3371 struct cmipci *cm = card->private_data; 3373 struct cmipci *cm = card->private_data;
3372 int i; 3374 int i;
3373 3375
@@ -3396,6 +3398,11 @@ static int snd_cmipci_resume(struct pci_dev *pci)
3396 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 3398 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3397 return 0; 3399 return 0;
3398} 3400}
3401
3402static SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume);
3403#define SND_CMIPCI_PM_OPS &snd_cmipci_pm
3404#else
3405#define SND_CMIPCI_PM_OPS NULL
3399#endif /* CONFIG_PM */ 3406#endif /* CONFIG_PM */
3400 3407
3401static struct pci_driver cmipci_driver = { 3408static struct pci_driver cmipci_driver = {
@@ -3403,10 +3410,9 @@ static struct pci_driver cmipci_driver = {
3403 .id_table = snd_cmipci_ids, 3410 .id_table = snd_cmipci_ids,
3404 .probe = snd_cmipci_probe, 3411 .probe = snd_cmipci_probe,
3405 .remove = __devexit_p(snd_cmipci_remove), 3412 .remove = __devexit_p(snd_cmipci_remove),
3406#ifdef CONFIG_PM 3413 .driver = {
3407 .suspend = snd_cmipci_suspend, 3414 .pm = SND_CMIPCI_PM_OPS,
3408 .resume = snd_cmipci_resume, 3415 },
3409#endif
3410}; 3416};
3411 3417
3412module_pci_driver(cmipci_driver); 3418module_pci_driver(cmipci_driver);
diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c
index 33506ee569b..45a8317085f 100644
--- a/sound/pci/cs4281.c
+++ b/sound/pci/cs4281.c
@@ -1997,9 +1997,10 @@ static int saved_regs[SUSPEND_REGISTERS] = {
1997 1997
1998#define CLKCR1_CKRA 0x00010000L 1998#define CLKCR1_CKRA 0x00010000L
1999 1999
2000static int cs4281_suspend(struct pci_dev *pci, pm_message_t state) 2000static int cs4281_suspend(struct device *dev)
2001{ 2001{
2002 struct snd_card *card = pci_get_drvdata(pci); 2002 struct pci_dev *pci = to_pci_dev(dev);
2003 struct snd_card *card = dev_get_drvdata(dev);
2003 struct cs4281 *chip = card->private_data; 2004 struct cs4281 *chip = card->private_data;
2004 u32 ulCLK; 2005 u32 ulCLK;
2005 unsigned int i; 2006 unsigned int i;
@@ -2040,13 +2041,14 @@ static int cs4281_suspend(struct pci_dev *pci, pm_message_t state)
2040 2041
2041 pci_disable_device(pci); 2042 pci_disable_device(pci);
2042 pci_save_state(pci); 2043 pci_save_state(pci);
2043 pci_set_power_state(pci, pci_choose_state(pci, state)); 2044 pci_set_power_state(pci, PCI_D3hot);
2044 return 0; 2045 return 0;
2045} 2046}
2046 2047
2047static int cs4281_resume(struct pci_dev *pci) 2048static int cs4281_resume(struct device *dev)
2048{ 2049{
2049 struct snd_card *card = pci_get_drvdata(pci); 2050 struct pci_dev *pci = to_pci_dev(dev);
2051 struct snd_card *card = dev_get_drvdata(dev);
2050 struct cs4281 *chip = card->private_data; 2052 struct cs4281 *chip = card->private_data;
2051 unsigned int i; 2053 unsigned int i;
2052 u32 ulCLK; 2054 u32 ulCLK;
@@ -2082,6 +2084,11 @@ static int cs4281_resume(struct pci_dev *pci)
2082 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2084 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2083 return 0; 2085 return 0;
2084} 2086}
2087
2088static SIMPLE_DEV_PM_OPS(cs4281_pm, cs4281_suspend, cs4281_resume);
2089#define CS4281_PM_OPS &cs4281_pm
2090#else
2091#define CS4281_PM_OPS NULL
2085#endif /* CONFIG_PM */ 2092#endif /* CONFIG_PM */
2086 2093
2087static struct pci_driver cs4281_driver = { 2094static struct pci_driver cs4281_driver = {
@@ -2089,10 +2096,9 @@ static struct pci_driver cs4281_driver = {
2089 .id_table = snd_cs4281_ids, 2096 .id_table = snd_cs4281_ids,
2090 .probe = snd_cs4281_probe, 2097 .probe = snd_cs4281_probe,
2091 .remove = __devexit_p(snd_cs4281_remove), 2098 .remove = __devexit_p(snd_cs4281_remove),
2092#ifdef CONFIG_PM 2099 .driver = {
2093 .suspend = cs4281_suspend, 2100 .pm = CS4281_PM_OPS,
2094 .resume = cs4281_resume, 2101 },
2095#endif
2096}; 2102};
2097 2103
2098module_pci_driver(cs4281_driver); 2104module_pci_driver(cs4281_driver);
diff --git a/sound/pci/cs46xx/cs46xx.c b/sound/pci/cs46xx/cs46xx.c
index 6cc7404e0e8..1e007c736a8 100644
--- a/sound/pci/cs46xx/cs46xx.c
+++ b/sound/pci/cs46xx/cs46xx.c
@@ -30,7 +30,7 @@
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/module.h> 31#include <linux/module.h>
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/cs46xx.h> 33#include "cs46xx.h"
34#include <sound/initval.h> 34#include <sound/initval.h>
35 35
36MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); 36MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
@@ -167,8 +167,9 @@ static struct pci_driver cs46xx_driver = {
167 .probe = snd_card_cs46xx_probe, 167 .probe = snd_card_cs46xx_probe,
168 .remove = __devexit_p(snd_card_cs46xx_remove), 168 .remove = __devexit_p(snd_card_cs46xx_remove),
169#ifdef CONFIG_PM 169#ifdef CONFIG_PM
170 .suspend = snd_cs46xx_suspend, 170 .driver = {
171 .resume = snd_cs46xx_resume, 171 .pm = &snd_cs46xx_pm,
172 },
172#endif 173#endif
173}; 174};
174 175
diff --git a/sound/pci/cs46xx/cs46xx.h b/sound/pci/cs46xx/cs46xx.h
new file mode 100644
index 00000000000..29d8a8da1ba
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx.h
@@ -0,0 +1,1744 @@
1#ifndef __SOUND_CS46XX_H
2#define __SOUND_CS46XX_H
3
4/*
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>,
6 * Cirrus Logic, Inc.
7 * Definitions for Cirrus Logic CS46xx chips
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/pcm.h>
27#include <sound/pcm-indirect.h>
28#include <sound/rawmidi.h>
29#include <sound/ac97_codec.h>
30#include "cs46xx_dsp_spos.h"
31
32/*
33 * Direct registers
34 */
35
36/*
37 * The following define the offsets of the registers accessed via base address
38 * register zero on the CS46xx part.
39 */
40#define BA0_HISR 0x00000000
41#define BA0_HSR0 0x00000004
42#define BA0_HICR 0x00000008
43#define BA0_DMSR 0x00000100
44#define BA0_HSAR 0x00000110
45#define BA0_HDAR 0x00000114
46#define BA0_HDMR 0x00000118
47#define BA0_HDCR 0x0000011C
48#define BA0_PFMC 0x00000200
49#define BA0_PFCV1 0x00000204
50#define BA0_PFCV2 0x00000208
51#define BA0_PCICFG00 0x00000300
52#define BA0_PCICFG04 0x00000304
53#define BA0_PCICFG08 0x00000308
54#define BA0_PCICFG0C 0x0000030C
55#define BA0_PCICFG10 0x00000310
56#define BA0_PCICFG14 0x00000314
57#define BA0_PCICFG18 0x00000318
58#define BA0_PCICFG1C 0x0000031C
59#define BA0_PCICFG20 0x00000320
60#define BA0_PCICFG24 0x00000324
61#define BA0_PCICFG28 0x00000328
62#define BA0_PCICFG2C 0x0000032C
63#define BA0_PCICFG30 0x00000330
64#define BA0_PCICFG34 0x00000334
65#define BA0_PCICFG38 0x00000338
66#define BA0_PCICFG3C 0x0000033C
67#define BA0_CLKCR1 0x00000400
68#define BA0_CLKCR2 0x00000404
69#define BA0_PLLM 0x00000408
70#define BA0_PLLCC 0x0000040C
71#define BA0_FRR 0x00000410
72#define BA0_CFL1 0x00000414
73#define BA0_CFL2 0x00000418
74#define BA0_SERMC1 0x00000420
75#define BA0_SERMC2 0x00000424
76#define BA0_SERC1 0x00000428
77#define BA0_SERC2 0x0000042C
78#define BA0_SERC3 0x00000430
79#define BA0_SERC4 0x00000434
80#define BA0_SERC5 0x00000438
81#define BA0_SERBSP 0x0000043C
82#define BA0_SERBST 0x00000440
83#define BA0_SERBCM 0x00000444
84#define BA0_SERBAD 0x00000448
85#define BA0_SERBCF 0x0000044C
86#define BA0_SERBWP 0x00000450
87#define BA0_SERBRP 0x00000454
88#ifndef NO_CS4612
89#define BA0_ASER_FADDR 0x00000458
90#endif
91#define BA0_ACCTL 0x00000460
92#define BA0_ACSTS 0x00000464
93#define BA0_ACOSV 0x00000468
94#define BA0_ACCAD 0x0000046C
95#define BA0_ACCDA 0x00000470
96#define BA0_ACISV 0x00000474
97#define BA0_ACSAD 0x00000478
98#define BA0_ACSDA 0x0000047C
99#define BA0_JSPT 0x00000480
100#define BA0_JSCTL 0x00000484
101#define BA0_JSC1 0x00000488
102#define BA0_JSC2 0x0000048C
103#define BA0_MIDCR 0x00000490
104#define BA0_MIDSR 0x00000494
105#define BA0_MIDWP 0x00000498
106#define BA0_MIDRP 0x0000049C
107#define BA0_JSIO 0x000004A0
108#ifndef NO_CS4612
109#define BA0_ASER_MASTER 0x000004A4
110#endif
111#define BA0_CFGI 0x000004B0
112#define BA0_SSVID 0x000004B4
113#define BA0_GPIOR 0x000004B8
114#ifndef NO_CS4612
115#define BA0_EGPIODR 0x000004BC
116#define BA0_EGPIOPTR 0x000004C0
117#define BA0_EGPIOTR 0x000004C4
118#define BA0_EGPIOWR 0x000004C8
119#define BA0_EGPIOSR 0x000004CC
120#define BA0_SERC6 0x000004D0
121#define BA0_SERC7 0x000004D4
122#define BA0_SERACC 0x000004D8
123#define BA0_ACCTL2 0x000004E0
124#define BA0_ACSTS2 0x000004E4
125#define BA0_ACOSV2 0x000004E8
126#define BA0_ACCAD2 0x000004EC
127#define BA0_ACCDA2 0x000004F0
128#define BA0_ACISV2 0x000004F4
129#define BA0_ACSAD2 0x000004F8
130#define BA0_ACSDA2 0x000004FC
131#define BA0_IOTAC0 0x00000500
132#define BA0_IOTAC1 0x00000504
133#define BA0_IOTAC2 0x00000508
134#define BA0_IOTAC3 0x0000050C
135#define BA0_IOTAC4 0x00000510
136#define BA0_IOTAC5 0x00000514
137#define BA0_IOTAC6 0x00000518
138#define BA0_IOTAC7 0x0000051C
139#define BA0_IOTAC8 0x00000520
140#define BA0_IOTAC9 0x00000524
141#define BA0_IOTAC10 0x00000528
142#define BA0_IOTAC11 0x0000052C
143#define BA0_IOTFR0 0x00000540
144#define BA0_IOTFR1 0x00000544
145#define BA0_IOTFR2 0x00000548
146#define BA0_IOTFR3 0x0000054C
147#define BA0_IOTFR4 0x00000550
148#define BA0_IOTFR5 0x00000554
149#define BA0_IOTFR6 0x00000558
150#define BA0_IOTFR7 0x0000055C
151#define BA0_IOTFIFO 0x00000580
152#define BA0_IOTRRD 0x00000584
153#define BA0_IOTFP 0x00000588
154#define BA0_IOTCR 0x0000058C
155#define BA0_DPCID 0x00000590
156#define BA0_DPCIA 0x00000594
157#define BA0_DPCIC 0x00000598
158#define BA0_PCPCIR 0x00000600
159#define BA0_PCPCIG 0x00000604
160#define BA0_PCPCIEN 0x00000608
161#define BA0_EPCIPMC 0x00000610
162#endif
163
164/*
165 * The following define the offsets of the registers and memories accessed via
166 * base address register one on the CS46xx part.
167 */
168#define BA1_SP_DMEM0 0x00000000
169#define BA1_SP_DMEM1 0x00010000
170#define BA1_SP_PMEM 0x00020000
171#define BA1_SP_REG 0x00030000
172#define BA1_SPCR 0x00030000
173#define BA1_DREG 0x00030004
174#define BA1_DSRWP 0x00030008
175#define BA1_TWPR 0x0003000C
176#define BA1_SPWR 0x00030010
177#define BA1_SPIR 0x00030014
178#define BA1_FGR1 0x00030020
179#define BA1_SPCS 0x00030028
180#define BA1_SDSR 0x0003002C
181#define BA1_FRMT 0x00030030
182#define BA1_FRCC 0x00030034
183#define BA1_FRSC 0x00030038
184#define BA1_OMNI_MEM 0x000E0000
185
186
187/*
188 * The following defines are for the flags in the host interrupt status
189 * register.
190 */
191#define HISR_VC_MASK 0x0000FFFF
192#define HISR_VC0 0x00000001
193#define HISR_VC1 0x00000002
194#define HISR_VC2 0x00000004
195#define HISR_VC3 0x00000008
196#define HISR_VC4 0x00000010
197#define HISR_VC5 0x00000020
198#define HISR_VC6 0x00000040
199#define HISR_VC7 0x00000080
200#define HISR_VC8 0x00000100
201#define HISR_VC9 0x00000200
202#define HISR_VC10 0x00000400
203#define HISR_VC11 0x00000800
204#define HISR_VC12 0x00001000
205#define HISR_VC13 0x00002000
206#define HISR_VC14 0x00004000
207#define HISR_VC15 0x00008000
208#define HISR_INT0 0x00010000
209#define HISR_INT1 0x00020000
210#define HISR_DMAI 0x00040000
211#define HISR_FROVR 0x00080000
212#define HISR_MIDI 0x00100000
213#ifdef NO_CS4612
214#define HISR_RESERVED 0x0FE00000
215#else
216#define HISR_SBINT 0x00200000
217#define HISR_RESERVED 0x0FC00000
218#endif
219#define HISR_H0P 0x40000000
220#define HISR_INTENA 0x80000000
221
222/*
223 * The following defines are for the flags in the host signal register 0.
224 */
225#define HSR0_VC_MASK 0xFFFFFFFF
226#define HSR0_VC16 0x00000001
227#define HSR0_VC17 0x00000002
228#define HSR0_VC18 0x00000004
229#define HSR0_VC19 0x00000008
230#define HSR0_VC20 0x00000010
231#define HSR0_VC21 0x00000020
232#define HSR0_VC22 0x00000040
233#define HSR0_VC23 0x00000080
234#define HSR0_VC24 0x00000100
235#define HSR0_VC25 0x00000200
236#define HSR0_VC26 0x00000400
237#define HSR0_VC27 0x00000800
238#define HSR0_VC28 0x00001000
239#define HSR0_VC29 0x00002000
240#define HSR0_VC30 0x00004000
241#define HSR0_VC31 0x00008000
242#define HSR0_VC32 0x00010000
243#define HSR0_VC33 0x00020000
244#define HSR0_VC34 0x00040000
245#define HSR0_VC35 0x00080000
246#define HSR0_VC36 0x00100000
247#define HSR0_VC37 0x00200000
248#define HSR0_VC38 0x00400000
249#define HSR0_VC39 0x00800000
250#define HSR0_VC40 0x01000000
251#define HSR0_VC41 0x02000000
252#define HSR0_VC42 0x04000000
253#define HSR0_VC43 0x08000000
254#define HSR0_VC44 0x10000000
255#define HSR0_VC45 0x20000000
256#define HSR0_VC46 0x40000000
257#define HSR0_VC47 0x80000000
258
259/*
260 * The following defines are for the flags in the host interrupt control
261 * register.
262 */
263#define HICR_IEV 0x00000001
264#define HICR_CHGM 0x00000002
265
266/*
267 * The following defines are for the flags in the DMA status register.
268 */
269#define DMSR_HP 0x00000001
270#define DMSR_HR 0x00000002
271#define DMSR_SP 0x00000004
272#define DMSR_SR 0x00000008
273
274/*
275 * The following defines are for the flags in the host DMA source address
276 * register.
277 */
278#define HSAR_HOST_ADDR_MASK 0xFFFFFFFF
279#define HSAR_DSP_ADDR_MASK 0x0000FFFF
280#define HSAR_MEMID_MASK 0x000F0000
281#define HSAR_MEMID_SP_DMEM0 0x00000000
282#define HSAR_MEMID_SP_DMEM1 0x00010000
283#define HSAR_MEMID_SP_PMEM 0x00020000
284#define HSAR_MEMID_SP_DEBUG 0x00030000
285#define HSAR_MEMID_OMNI_MEM 0x000E0000
286#define HSAR_END 0x40000000
287#define HSAR_ERR 0x80000000
288
289/*
290 * The following defines are for the flags in the host DMA destination address
291 * register.
292 */
293#define HDAR_HOST_ADDR_MASK 0xFFFFFFFF
294#define HDAR_DSP_ADDR_MASK 0x0000FFFF
295#define HDAR_MEMID_MASK 0x000F0000
296#define HDAR_MEMID_SP_DMEM0 0x00000000
297#define HDAR_MEMID_SP_DMEM1 0x00010000
298#define HDAR_MEMID_SP_PMEM 0x00020000
299#define HDAR_MEMID_SP_DEBUG 0x00030000
300#define HDAR_MEMID_OMNI_MEM 0x000E0000
301#define HDAR_END 0x40000000
302#define HDAR_ERR 0x80000000
303
304/*
305 * The following defines are for the flags in the host DMA control register.
306 */
307#define HDMR_AC_MASK 0x0000F000
308#define HDMR_AC_8_16 0x00001000
309#define HDMR_AC_M_S 0x00002000
310#define HDMR_AC_B_L 0x00004000
311#define HDMR_AC_S_U 0x00008000
312
313/*
314 * The following defines are for the flags in the host DMA control register.
315 */
316#define HDCR_COUNT_MASK 0x000003FF
317#define HDCR_DONE 0x00004000
318#define HDCR_OPT 0x00008000
319#define HDCR_WBD 0x00400000
320#define HDCR_WBS 0x00800000
321#define HDCR_DMS_MASK 0x07000000
322#define HDCR_DMS_LINEAR 0x00000000
323#define HDCR_DMS_16_DWORDS 0x01000000
324#define HDCR_DMS_32_DWORDS 0x02000000
325#define HDCR_DMS_64_DWORDS 0x03000000
326#define HDCR_DMS_128_DWORDS 0x04000000
327#define HDCR_DMS_256_DWORDS 0x05000000
328#define HDCR_DMS_512_DWORDS 0x06000000
329#define HDCR_DMS_1024_DWORDS 0x07000000
330#define HDCR_DH 0x08000000
331#define HDCR_SMS_MASK 0x70000000
332#define HDCR_SMS_LINEAR 0x00000000
333#define HDCR_SMS_16_DWORDS 0x10000000
334#define HDCR_SMS_32_DWORDS 0x20000000
335#define HDCR_SMS_64_DWORDS 0x30000000
336#define HDCR_SMS_128_DWORDS 0x40000000
337#define HDCR_SMS_256_DWORDS 0x50000000
338#define HDCR_SMS_512_DWORDS 0x60000000
339#define HDCR_SMS_1024_DWORDS 0x70000000
340#define HDCR_SH 0x80000000
341#define HDCR_COUNT_SHIFT 0
342
343/*
344 * The following defines are for the flags in the performance monitor control
345 * register.
346 */
347#define PFMC_C1SS_MASK 0x0000001F
348#define PFMC_C1EV 0x00000020
349#define PFMC_C1RS 0x00008000
350#define PFMC_C2SS_MASK 0x001F0000
351#define PFMC_C2EV 0x00200000
352#define PFMC_C2RS 0x80000000
353#define PFMC_C1SS_SHIFT 0
354#define PFMC_C2SS_SHIFT 16
355#define PFMC_BUS_GRANT 0
356#define PFMC_GRANT_AFTER_REQ 1
357#define PFMC_TRANSACTION 2
358#define PFMC_DWORD_TRANSFER 3
359#define PFMC_SLAVE_READ 4
360#define PFMC_SLAVE_WRITE 5
361#define PFMC_PREEMPTION 6
362#define PFMC_DISCONNECT_RETRY 7
363#define PFMC_INTERRUPT 8
364#define PFMC_BUS_OWNERSHIP 9
365#define PFMC_TRANSACTION_LAG 10
366#define PFMC_PCI_CLOCK 11
367#define PFMC_SERIAL_CLOCK 12
368#define PFMC_SP_CLOCK 13
369
370/*
371 * The following defines are for the flags in the performance counter value 1
372 * register.
373 */
374#define PFCV1_PC1V_MASK 0xFFFFFFFF
375#define PFCV1_PC1V_SHIFT 0
376
377/*
378 * The following defines are for the flags in the performance counter value 2
379 * register.
380 */
381#define PFCV2_PC2V_MASK 0xFFFFFFFF
382#define PFCV2_PC2V_SHIFT 0
383
384/*
385 * The following defines are for the flags in the clock control register 1.
386 */
387#define CLKCR1_OSCS 0x00000001
388#define CLKCR1_OSCP 0x00000002
389#define CLKCR1_PLLSS_MASK 0x0000000C
390#define CLKCR1_PLLSS_SERIAL 0x00000000
391#define CLKCR1_PLLSS_CRYSTAL 0x00000004
392#define CLKCR1_PLLSS_PCI 0x00000008
393#define CLKCR1_PLLSS_RESERVED 0x0000000C
394#define CLKCR1_PLLP 0x00000010
395#define CLKCR1_SWCE 0x00000020
396#define CLKCR1_PLLOS 0x00000040
397
398/*
399 * The following defines are for the flags in the clock control register 2.
400 */
401#define CLKCR2_PDIVS_MASK 0x0000000F
402#define CLKCR2_PDIVS_1 0x00000001
403#define CLKCR2_PDIVS_2 0x00000002
404#define CLKCR2_PDIVS_4 0x00000004
405#define CLKCR2_PDIVS_7 0x00000007
406#define CLKCR2_PDIVS_8 0x00000008
407#define CLKCR2_PDIVS_16 0x00000000
408
409/*
410 * The following defines are for the flags in the PLL multiplier register.
411 */
412#define PLLM_MASK 0x000000FF
413#define PLLM_SHIFT 0
414
415/*
416 * The following defines are for the flags in the PLL capacitor coefficient
417 * register.
418 */
419#define PLLCC_CDR_MASK 0x00000007
420#ifndef NO_CS4610
421#define PLLCC_CDR_240_350_MHZ 0x00000000
422#define PLLCC_CDR_184_265_MHZ 0x00000001
423#define PLLCC_CDR_144_205_MHZ 0x00000002
424#define PLLCC_CDR_111_160_MHZ 0x00000003
425#define PLLCC_CDR_87_123_MHZ 0x00000004
426#define PLLCC_CDR_67_96_MHZ 0x00000005
427#define PLLCC_CDR_52_74_MHZ 0x00000006
428#define PLLCC_CDR_45_58_MHZ 0x00000007
429#endif
430#ifndef NO_CS4612
431#define PLLCC_CDR_271_398_MHZ 0x00000000
432#define PLLCC_CDR_227_330_MHZ 0x00000001
433#define PLLCC_CDR_167_239_MHZ 0x00000002
434#define PLLCC_CDR_150_215_MHZ 0x00000003
435#define PLLCC_CDR_107_154_MHZ 0x00000004
436#define PLLCC_CDR_98_140_MHZ 0x00000005
437#define PLLCC_CDR_73_104_MHZ 0x00000006
438#define PLLCC_CDR_63_90_MHZ 0x00000007
439#endif
440#define PLLCC_LPF_MASK 0x000000F8
441#ifndef NO_CS4610
442#define PLLCC_LPF_23850_60000_KHZ 0x00000000
443#define PLLCC_LPF_7960_26290_KHZ 0x00000008
444#define PLLCC_LPF_4160_10980_KHZ 0x00000018
445#define PLLCC_LPF_1740_4580_KHZ 0x00000038
446#define PLLCC_LPF_724_1910_KHZ 0x00000078
447#define PLLCC_LPF_317_798_KHZ 0x000000F8
448#endif
449#ifndef NO_CS4612
450#define PLLCC_LPF_25580_64530_KHZ 0x00000000
451#define PLLCC_LPF_14360_37270_KHZ 0x00000008
452#define PLLCC_LPF_6100_16020_KHZ 0x00000018
453#define PLLCC_LPF_2540_6690_KHZ 0x00000038
454#define PLLCC_LPF_1050_2780_KHZ 0x00000078
455#define PLLCC_LPF_450_1160_KHZ 0x000000F8
456#endif
457
458/*
459 * The following defines are for the flags in the feature reporting register.
460 */
461#define FRR_FAB_MASK 0x00000003
462#define FRR_MASK_MASK 0x0000001C
463#ifdef NO_CS4612
464#define FRR_CFOP_MASK 0x000000E0
465#else
466#define FRR_CFOP_MASK 0x00000FE0
467#endif
468#define FRR_CFOP_NOT_DVD 0x00000020
469#define FRR_CFOP_A3D 0x00000040
470#define FRR_CFOP_128_PIN 0x00000080
471#ifndef NO_CS4612
472#define FRR_CFOP_CS4280 0x00000800
473#endif
474#define FRR_FAB_SHIFT 0
475#define FRR_MASK_SHIFT 2
476#define FRR_CFOP_SHIFT 5
477
478/*
479 * The following defines are for the flags in the configuration load 1
480 * register.
481 */
482#define CFL1_CLOCK_SOURCE_MASK 0x00000003
483#define CFL1_CLOCK_SOURCE_CS423X 0x00000000
484#define CFL1_CLOCK_SOURCE_AC97 0x00000001
485#define CFL1_CLOCK_SOURCE_CRYSTAL 0x00000002
486#define CFL1_CLOCK_SOURCE_DUAL_AC97 0x00000003
487#define CFL1_VALID_DATA_MASK 0x000000FF
488
489/*
490 * The following defines are for the flags in the configuration load 2
491 * register.
492 */
493#define CFL2_VALID_DATA_MASK 0x000000FF
494
495/*
496 * The following defines are for the flags in the serial port master control
497 * register 1.
498 */
499#define SERMC1_MSPE 0x00000001
500#define SERMC1_PTC_MASK 0x0000000E
501#define SERMC1_PTC_CS423X 0x00000000
502#define SERMC1_PTC_AC97 0x00000002
503#define SERMC1_PTC_DAC 0x00000004
504#define SERMC1_PLB 0x00000010
505#define SERMC1_XLB 0x00000020
506
507/*
508 * The following defines are for the flags in the serial port master control
509 * register 2.
510 */
511#define SERMC2_LROE 0x00000001
512#define SERMC2_MCOE 0x00000002
513#define SERMC2_MCDIV 0x00000004
514
515/*
516 * The following defines are for the flags in the serial port 1 configuration
517 * register.
518 */
519#define SERC1_SO1EN 0x00000001
520#define SERC1_SO1F_MASK 0x0000000E
521#define SERC1_SO1F_CS423X 0x00000000
522#define SERC1_SO1F_AC97 0x00000002
523#define SERC1_SO1F_DAC 0x00000004
524#define SERC1_SO1F_SPDIF 0x00000006
525
526/*
527 * The following defines are for the flags in the serial port 2 configuration
528 * register.
529 */
530#define SERC2_SI1EN 0x00000001
531#define SERC2_SI1F_MASK 0x0000000E
532#define SERC2_SI1F_CS423X 0x00000000
533#define SERC2_SI1F_AC97 0x00000002
534#define SERC2_SI1F_ADC 0x00000004
535#define SERC2_SI1F_SPDIF 0x00000006
536
537/*
538 * The following defines are for the flags in the serial port 3 configuration
539 * register.
540 */
541#define SERC3_SO2EN 0x00000001
542#define SERC3_SO2F_MASK 0x00000006
543#define SERC3_SO2F_DAC 0x00000000
544#define SERC3_SO2F_SPDIF 0x00000002
545
546/*
547 * The following defines are for the flags in the serial port 4 configuration
548 * register.
549 */
550#define SERC4_SO3EN 0x00000001
551#define SERC4_SO3F_MASK 0x00000006
552#define SERC4_SO3F_DAC 0x00000000
553#define SERC4_SO3F_SPDIF 0x00000002
554
555/*
556 * The following defines are for the flags in the serial port 5 configuration
557 * register.
558 */
559#define SERC5_SI2EN 0x00000001
560#define SERC5_SI2F_MASK 0x00000006
561#define SERC5_SI2F_ADC 0x00000000
562#define SERC5_SI2F_SPDIF 0x00000002
563
564/*
565 * The following defines are for the flags in the serial port backdoor sample
566 * pointer register.
567 */
568#define SERBSP_FSP_MASK 0x0000000F
569#define SERBSP_FSP_SHIFT 0
570
571/*
572 * The following defines are for the flags in the serial port backdoor status
573 * register.
574 */
575#define SERBST_RRDY 0x00000001
576#define SERBST_WBSY 0x00000002
577
578/*
579 * The following defines are for the flags in the serial port backdoor command
580 * register.
581 */
582#define SERBCM_RDC 0x00000001
583#define SERBCM_WRC 0x00000002
584
585/*
586 * The following defines are for the flags in the serial port backdoor address
587 * register.
588 */
589#ifdef NO_CS4612
590#define SERBAD_FAD_MASK 0x000000FF
591#else
592#define SERBAD_FAD_MASK 0x000001FF
593#endif
594#define SERBAD_FAD_SHIFT 0
595
596/*
597 * The following defines are for the flags in the serial port backdoor
598 * configuration register.
599 */
600#define SERBCF_HBP 0x00000001
601
602/*
603 * The following defines are for the flags in the serial port backdoor write
604 * port register.
605 */
606#define SERBWP_FWD_MASK 0x000FFFFF
607#define SERBWP_FWD_SHIFT 0
608
609/*
610 * The following defines are for the flags in the serial port backdoor read
611 * port register.
612 */
613#define SERBRP_FRD_MASK 0x000FFFFF
614#define SERBRP_FRD_SHIFT 0
615
616/*
617 * The following defines are for the flags in the async FIFO address register.
618 */
619#ifndef NO_CS4612
620#define ASER_FADDR_A1_MASK 0x000001FF
621#define ASER_FADDR_EN1 0x00008000
622#define ASER_FADDR_A2_MASK 0x01FF0000
623#define ASER_FADDR_EN2 0x80000000
624#define ASER_FADDR_A1_SHIFT 0
625#define ASER_FADDR_A2_SHIFT 16
626#endif
627
628/*
629 * The following defines are for the flags in the AC97 control register.
630 */
631#define ACCTL_RSTN 0x00000001
632#define ACCTL_ESYN 0x00000002
633#define ACCTL_VFRM 0x00000004
634#define ACCTL_DCV 0x00000008
635#define ACCTL_CRW 0x00000010
636#define ACCTL_ASYN 0x00000020
637#ifndef NO_CS4612
638#define ACCTL_TC 0x00000040
639#endif
640
641/*
642 * The following defines are for the flags in the AC97 status register.
643 */
644#define ACSTS_CRDY 0x00000001
645#define ACSTS_VSTS 0x00000002
646#ifndef NO_CS4612
647#define ACSTS_WKUP 0x00000004
648#endif
649
650/*
651 * The following defines are for the flags in the AC97 output slot valid
652 * register.
653 */
654#define ACOSV_SLV3 0x00000001
655#define ACOSV_SLV4 0x00000002
656#define ACOSV_SLV5 0x00000004
657#define ACOSV_SLV6 0x00000008
658#define ACOSV_SLV7 0x00000010
659#define ACOSV_SLV8 0x00000020
660#define ACOSV_SLV9 0x00000040
661#define ACOSV_SLV10 0x00000080
662#define ACOSV_SLV11 0x00000100
663#define ACOSV_SLV12 0x00000200
664
665/*
666 * The following defines are for the flags in the AC97 command address
667 * register.
668 */
669#define ACCAD_CI_MASK 0x0000007F
670#define ACCAD_CI_SHIFT 0
671
672/*
673 * The following defines are for the flags in the AC97 command data register.
674 */
675#define ACCDA_CD_MASK 0x0000FFFF
676#define ACCDA_CD_SHIFT 0
677
678/*
679 * The following defines are for the flags in the AC97 input slot valid
680 * register.
681 */
682#define ACISV_ISV3 0x00000001
683#define ACISV_ISV4 0x00000002
684#define ACISV_ISV5 0x00000004
685#define ACISV_ISV6 0x00000008
686#define ACISV_ISV7 0x00000010
687#define ACISV_ISV8 0x00000020
688#define ACISV_ISV9 0x00000040
689#define ACISV_ISV10 0x00000080
690#define ACISV_ISV11 0x00000100
691#define ACISV_ISV12 0x00000200
692
693/*
694 * The following defines are for the flags in the AC97 status address
695 * register.
696 */
697#define ACSAD_SI_MASK 0x0000007F
698#define ACSAD_SI_SHIFT 0
699
700/*
701 * The following defines are for the flags in the AC97 status data register.
702 */
703#define ACSDA_SD_MASK 0x0000FFFF
704#define ACSDA_SD_SHIFT 0
705
706/*
707 * The following defines are for the flags in the joystick poll/trigger
708 * register.
709 */
710#define JSPT_CAX 0x00000001
711#define JSPT_CAY 0x00000002
712#define JSPT_CBX 0x00000004
713#define JSPT_CBY 0x00000008
714#define JSPT_BA1 0x00000010
715#define JSPT_BA2 0x00000020
716#define JSPT_BB1 0x00000040
717#define JSPT_BB2 0x00000080
718
719/*
720 * The following defines are for the flags in the joystick control register.
721 */
722#define JSCTL_SP_MASK 0x00000003
723#define JSCTL_SP_SLOW 0x00000000
724#define JSCTL_SP_MEDIUM_SLOW 0x00000001
725#define JSCTL_SP_MEDIUM_FAST 0x00000002
726#define JSCTL_SP_FAST 0x00000003
727#define JSCTL_ARE 0x00000004
728
729/*
730 * The following defines are for the flags in the joystick coordinate pair 1
731 * readback register.
732 */
733#define JSC1_Y1V_MASK 0x0000FFFF
734#define JSC1_X1V_MASK 0xFFFF0000
735#define JSC1_Y1V_SHIFT 0
736#define JSC1_X1V_SHIFT 16
737
738/*
739 * The following defines are for the flags in the joystick coordinate pair 2
740 * readback register.
741 */
742#define JSC2_Y2V_MASK 0x0000FFFF
743#define JSC2_X2V_MASK 0xFFFF0000
744#define JSC2_Y2V_SHIFT 0
745#define JSC2_X2V_SHIFT 16
746
747/*
748 * The following defines are for the flags in the MIDI control register.
749 */
750#define MIDCR_TXE 0x00000001 /* Enable transmitting. */
751#define MIDCR_RXE 0x00000002 /* Enable receiving. */
752#define MIDCR_RIE 0x00000004 /* Interrupt upon tx ready. */
753#define MIDCR_TIE 0x00000008 /* Interrupt upon rx ready. */
754#define MIDCR_MLB 0x00000010 /* Enable midi loopback. */
755#define MIDCR_MRST 0x00000020 /* Reset interface. */
756
757/*
758 * The following defines are for the flags in the MIDI status register.
759 */
760#define MIDSR_TBF 0x00000001 /* Tx FIFO is full. */
761#define MIDSR_RBE 0x00000002 /* Rx FIFO is empty. */
762
763/*
764 * The following defines are for the flags in the MIDI write port register.
765 */
766#define MIDWP_MWD_MASK 0x000000FF
767#define MIDWP_MWD_SHIFT 0
768
769/*
770 * The following defines are for the flags in the MIDI read port register.
771 */
772#define MIDRP_MRD_MASK 0x000000FF
773#define MIDRP_MRD_SHIFT 0
774
775/*
776 * The following defines are for the flags in the joystick GPIO register.
777 */
778#define JSIO_DAX 0x00000001
779#define JSIO_DAY 0x00000002
780#define JSIO_DBX 0x00000004
781#define JSIO_DBY 0x00000008
782#define JSIO_AXOE 0x00000010
783#define JSIO_AYOE 0x00000020
784#define JSIO_BXOE 0x00000040
785#define JSIO_BYOE 0x00000080
786
787/*
788 * The following defines are for the flags in the master async/sync serial
789 * port enable register.
790 */
791#ifndef NO_CS4612
792#define ASER_MASTER_ME 0x00000001
793#endif
794
795/*
796 * The following defines are for the flags in the configuration interface
797 * register.
798 */
799#define CFGI_CLK 0x00000001
800#define CFGI_DOUT 0x00000002
801#define CFGI_DIN_EEN 0x00000004
802#define CFGI_EELD 0x00000008
803
804/*
805 * The following defines are for the flags in the subsystem ID and vendor ID
806 * register.
807 */
808#define SSVID_VID_MASK 0x0000FFFF
809#define SSVID_SID_MASK 0xFFFF0000
810#define SSVID_VID_SHIFT 0
811#define SSVID_SID_SHIFT 16
812
813/*
814 * The following defines are for the flags in the GPIO pin interface register.
815 */
816#define GPIOR_VOLDN 0x00000001
817#define GPIOR_VOLUP 0x00000002
818#define GPIOR_SI2D 0x00000004
819#define GPIOR_SI2OE 0x00000008
820
821/*
822 * The following defines are for the flags in the extended GPIO pin direction
823 * register.
824 */
825#ifndef NO_CS4612
826#define EGPIODR_GPOE0 0x00000001
827#define EGPIODR_GPOE1 0x00000002
828#define EGPIODR_GPOE2 0x00000004
829#define EGPIODR_GPOE3 0x00000008
830#define EGPIODR_GPOE4 0x00000010
831#define EGPIODR_GPOE5 0x00000020
832#define EGPIODR_GPOE6 0x00000040
833#define EGPIODR_GPOE7 0x00000080
834#define EGPIODR_GPOE8 0x00000100
835#endif
836
837/*
838 * The following defines are for the flags in the extended GPIO pin polarity/
839 * type register.
840 */
841#ifndef NO_CS4612
842#define EGPIOPTR_GPPT0 0x00000001
843#define EGPIOPTR_GPPT1 0x00000002
844#define EGPIOPTR_GPPT2 0x00000004
845#define EGPIOPTR_GPPT3 0x00000008
846#define EGPIOPTR_GPPT4 0x00000010
847#define EGPIOPTR_GPPT5 0x00000020
848#define EGPIOPTR_GPPT6 0x00000040
849#define EGPIOPTR_GPPT7 0x00000080
850#define EGPIOPTR_GPPT8 0x00000100
851#endif
852
853/*
854 * The following defines are for the flags in the extended GPIO pin sticky
855 * register.
856 */
857#ifndef NO_CS4612
858#define EGPIOTR_GPS0 0x00000001
859#define EGPIOTR_GPS1 0x00000002
860#define EGPIOTR_GPS2 0x00000004
861#define EGPIOTR_GPS3 0x00000008
862#define EGPIOTR_GPS4 0x00000010
863#define EGPIOTR_GPS5 0x00000020
864#define EGPIOTR_GPS6 0x00000040
865#define EGPIOTR_GPS7 0x00000080
866#define EGPIOTR_GPS8 0x00000100
867#endif
868
869/*
870 * The following defines are for the flags in the extended GPIO ping wakeup
871 * register.
872 */
873#ifndef NO_CS4612
874#define EGPIOWR_GPW0 0x00000001
875#define EGPIOWR_GPW1 0x00000002
876#define EGPIOWR_GPW2 0x00000004
877#define EGPIOWR_GPW3 0x00000008
878#define EGPIOWR_GPW4 0x00000010
879#define EGPIOWR_GPW5 0x00000020
880#define EGPIOWR_GPW6 0x00000040
881#define EGPIOWR_GPW7 0x00000080
882#define EGPIOWR_GPW8 0x00000100
883#endif
884
885/*
886 * The following defines are for the flags in the extended GPIO pin status
887 * register.
888 */
889#ifndef NO_CS4612
890#define EGPIOSR_GPS0 0x00000001
891#define EGPIOSR_GPS1 0x00000002
892#define EGPIOSR_GPS2 0x00000004
893#define EGPIOSR_GPS3 0x00000008
894#define EGPIOSR_GPS4 0x00000010
895#define EGPIOSR_GPS5 0x00000020
896#define EGPIOSR_GPS6 0x00000040
897#define EGPIOSR_GPS7 0x00000080
898#define EGPIOSR_GPS8 0x00000100
899#endif
900
901/*
902 * The following defines are for the flags in the serial port 6 configuration
903 * register.
904 */
905#ifndef NO_CS4612
906#define SERC6_ASDO2EN 0x00000001
907#endif
908
909/*
910 * The following defines are for the flags in the serial port 7 configuration
911 * register.
912 */
913#ifndef NO_CS4612
914#define SERC7_ASDI2EN 0x00000001
915#define SERC7_POSILB 0x00000002
916#define SERC7_SIPOLB 0x00000004
917#define SERC7_SOSILB 0x00000008
918#define SERC7_SISOLB 0x00000010
919#endif
920
921/*
922 * The following defines are for the flags in the serial port AC link
923 * configuration register.
924 */
925#ifndef NO_CS4612
926#define SERACC_CHIP_TYPE_MASK 0x00000001
927#define SERACC_CHIP_TYPE_1_03 0x00000000
928#define SERACC_CHIP_TYPE_2_0 0x00000001
929#define SERACC_TWO_CODECS 0x00000002
930#define SERACC_MDM 0x00000004
931#define SERACC_HSP 0x00000008
932#define SERACC_ODT 0x00000010 /* only CS4630 */
933#endif
934
935/*
936 * The following defines are for the flags in the AC97 control register 2.
937 */
938#ifndef NO_CS4612
939#define ACCTL2_RSTN 0x00000001
940#define ACCTL2_ESYN 0x00000002
941#define ACCTL2_VFRM 0x00000004
942#define ACCTL2_DCV 0x00000008
943#define ACCTL2_CRW 0x00000010
944#define ACCTL2_ASYN 0x00000020
945#endif
946
947/*
948 * The following defines are for the flags in the AC97 status register 2.
949 */
950#ifndef NO_CS4612
951#define ACSTS2_CRDY 0x00000001
952#define ACSTS2_VSTS 0x00000002
953#endif
954
955/*
956 * The following defines are for the flags in the AC97 output slot valid
957 * register 2.
958 */
959#ifndef NO_CS4612
960#define ACOSV2_SLV3 0x00000001
961#define ACOSV2_SLV4 0x00000002
962#define ACOSV2_SLV5 0x00000004
963#define ACOSV2_SLV6 0x00000008
964#define ACOSV2_SLV7 0x00000010
965#define ACOSV2_SLV8 0x00000020
966#define ACOSV2_SLV9 0x00000040
967#define ACOSV2_SLV10 0x00000080
968#define ACOSV2_SLV11 0x00000100
969#define ACOSV2_SLV12 0x00000200
970#endif
971
972/*
973 * The following defines are for the flags in the AC97 command address
974 * register 2.
975 */
976#ifndef NO_CS4612
977#define ACCAD2_CI_MASK 0x0000007F
978#define ACCAD2_CI_SHIFT 0
979#endif
980
981/*
982 * The following defines are for the flags in the AC97 command data register
983 * 2.
984 */
985#ifndef NO_CS4612
986#define ACCDA2_CD_MASK 0x0000FFFF
987#define ACCDA2_CD_SHIFT 0
988#endif
989
990/*
991 * The following defines are for the flags in the AC97 input slot valid
992 * register 2.
993 */
994#ifndef NO_CS4612
995#define ACISV2_ISV3 0x00000001
996#define ACISV2_ISV4 0x00000002
997#define ACISV2_ISV5 0x00000004
998#define ACISV2_ISV6 0x00000008
999#define ACISV2_ISV7 0x00000010
1000#define ACISV2_ISV8 0x00000020
1001#define ACISV2_ISV9 0x00000040
1002#define ACISV2_ISV10 0x00000080
1003#define ACISV2_ISV11 0x00000100
1004#define ACISV2_ISV12 0x00000200
1005#endif
1006
1007/*
1008 * The following defines are for the flags in the AC97 status address
1009 * register 2.
1010 */
1011#ifndef NO_CS4612
1012#define ACSAD2_SI_MASK 0x0000007F
1013#define ACSAD2_SI_SHIFT 0
1014#endif
1015
1016/*
1017 * The following defines are for the flags in the AC97 status data register 2.
1018 */
1019#ifndef NO_CS4612
1020#define ACSDA2_SD_MASK 0x0000FFFF
1021#define ACSDA2_SD_SHIFT 0
1022#endif
1023
1024/*
1025 * The following defines are for the flags in the I/O trap address and control
1026 * registers (all 12).
1027 */
1028#ifndef NO_CS4612
1029#define IOTAC_SA_MASK 0x0000FFFF
1030#define IOTAC_MSK_MASK 0x000F0000
1031#define IOTAC_IODC_MASK 0x06000000
1032#define IOTAC_IODC_16_BIT 0x00000000
1033#define IOTAC_IODC_10_BIT 0x02000000
1034#define IOTAC_IODC_12_BIT 0x04000000
1035#define IOTAC_WSPI 0x08000000
1036#define IOTAC_RSPI 0x10000000
1037#define IOTAC_WSE 0x20000000
1038#define IOTAC_WE 0x40000000
1039#define IOTAC_RE 0x80000000
1040#define IOTAC_SA_SHIFT 0
1041#define IOTAC_MSK_SHIFT 16
1042#endif
1043
1044/*
1045 * The following defines are for the flags in the I/O trap fast read registers
1046 * (all 8).
1047 */
1048#ifndef NO_CS4612
1049#define IOTFR_D_MASK 0x0000FFFF
1050#define IOTFR_A_MASK 0x000F0000
1051#define IOTFR_R_MASK 0x0F000000
1052#define IOTFR_ALL 0x40000000
1053#define IOTFR_VL 0x80000000
1054#define IOTFR_D_SHIFT 0
1055#define IOTFR_A_SHIFT 16
1056#define IOTFR_R_SHIFT 24
1057#endif
1058
1059/*
1060 * The following defines are for the flags in the I/O trap FIFO register.
1061 */
1062#ifndef NO_CS4612
1063#define IOTFIFO_BA_MASK 0x00003FFF
1064#define IOTFIFO_S_MASK 0x00FF0000
1065#define IOTFIFO_OF 0x40000000
1066#define IOTFIFO_SPIOF 0x80000000
1067#define IOTFIFO_BA_SHIFT 0
1068#define IOTFIFO_S_SHIFT 16
1069#endif
1070
1071/*
1072 * The following defines are for the flags in the I/O trap retry read data
1073 * register.
1074 */
1075#ifndef NO_CS4612
1076#define IOTRRD_D_MASK 0x0000FFFF
1077#define IOTRRD_RDV 0x80000000
1078#define IOTRRD_D_SHIFT 0
1079#endif
1080
1081/*
1082 * The following defines are for the flags in the I/O trap FIFO pointer
1083 * register.
1084 */
1085#ifndef NO_CS4612
1086#define IOTFP_CA_MASK 0x00003FFF
1087#define IOTFP_PA_MASK 0x3FFF0000
1088#define IOTFP_CA_SHIFT 0
1089#define IOTFP_PA_SHIFT 16
1090#endif
1091
1092/*
1093 * The following defines are for the flags in the I/O trap control register.
1094 */
1095#ifndef NO_CS4612
1096#define IOTCR_ITD 0x00000001
1097#define IOTCR_HRV 0x00000002
1098#define IOTCR_SRV 0x00000004
1099#define IOTCR_DTI 0x00000008
1100#define IOTCR_DFI 0x00000010
1101#define IOTCR_DDP 0x00000020
1102#define IOTCR_JTE 0x00000040
1103#define IOTCR_PPE 0x00000080
1104#endif
1105
1106/*
1107 * The following defines are for the flags in the direct PCI data register.
1108 */
1109#ifndef NO_CS4612
1110#define DPCID_D_MASK 0xFFFFFFFF
1111#define DPCID_D_SHIFT 0
1112#endif
1113
1114/*
1115 * The following defines are for the flags in the direct PCI address register.
1116 */
1117#ifndef NO_CS4612
1118#define DPCIA_A_MASK 0xFFFFFFFF
1119#define DPCIA_A_SHIFT 0
1120#endif
1121
1122/*
1123 * The following defines are for the flags in the direct PCI command register.
1124 */
1125#ifndef NO_CS4612
1126#define DPCIC_C_MASK 0x0000000F
1127#define DPCIC_C_IOREAD 0x00000002
1128#define DPCIC_C_IOWRITE 0x00000003
1129#define DPCIC_BE_MASK 0x000000F0
1130#endif
1131
1132/*
1133 * The following defines are for the flags in the PC/PCI request register.
1134 */
1135#ifndef NO_CS4612
1136#define PCPCIR_RDC_MASK 0x00000007
1137#define PCPCIR_C_MASK 0x00007000
1138#define PCPCIR_REQ 0x00008000
1139#define PCPCIR_RDC_SHIFT 0
1140#define PCPCIR_C_SHIFT 12
1141#endif
1142
1143/*
1144 * The following defines are for the flags in the PC/PCI grant register.
1145 */
1146#ifndef NO_CS4612
1147#define PCPCIG_GDC_MASK 0x00000007
1148#define PCPCIG_VL 0x00008000
1149#define PCPCIG_GDC_SHIFT 0
1150#endif
1151
1152/*
1153 * The following defines are for the flags in the PC/PCI master enable
1154 * register.
1155 */
1156#ifndef NO_CS4612
1157#define PCPCIEN_EN 0x00000001
1158#endif
1159
1160/*
1161 * The following defines are for the flags in the extended PCI power
1162 * management control register.
1163 */
1164#ifndef NO_CS4612
1165#define EPCIPMC_GWU 0x00000001
1166#define EPCIPMC_FSPC 0x00000002
1167#endif
1168
1169/*
1170 * The following defines are for the flags in the SP control register.
1171 */
1172#define SPCR_RUN 0x00000001
1173#define SPCR_STPFR 0x00000002
1174#define SPCR_RUNFR 0x00000004
1175#define SPCR_TICK 0x00000008
1176#define SPCR_DRQEN 0x00000020
1177#define SPCR_RSTSP 0x00000040
1178#define SPCR_OREN 0x00000080
1179#ifndef NO_CS4612
1180#define SPCR_PCIINT 0x00000100
1181#define SPCR_OINTD 0x00000200
1182#define SPCR_CRE 0x00008000
1183#endif
1184
1185/*
1186 * The following defines are for the flags in the debug index register.
1187 */
1188#define DREG_REGID_MASK 0x0000007F
1189#define DREG_DEBUG 0x00000080
1190#define DREG_RGBK_MASK 0x00000700
1191#define DREG_TRAP 0x00000800
1192#if !defined(NO_CS4612)
1193#if !defined(NO_CS4615)
1194#define DREG_TRAPX 0x00001000
1195#endif
1196#endif
1197#define DREG_REGID_SHIFT 0
1198#define DREG_RGBK_SHIFT 8
1199#define DREG_RGBK_REGID_MASK 0x0000077F
1200#define DREG_REGID_R0 0x00000010
1201#define DREG_REGID_R1 0x00000011
1202#define DREG_REGID_R2 0x00000012
1203#define DREG_REGID_R3 0x00000013
1204#define DREG_REGID_R4 0x00000014
1205#define DREG_REGID_R5 0x00000015
1206#define DREG_REGID_R6 0x00000016
1207#define DREG_REGID_R7 0x00000017
1208#define DREG_REGID_R8 0x00000018
1209#define DREG_REGID_R9 0x00000019
1210#define DREG_REGID_RA 0x0000001A
1211#define DREG_REGID_RB 0x0000001B
1212#define DREG_REGID_RC 0x0000001C
1213#define DREG_REGID_RD 0x0000001D
1214#define DREG_REGID_RE 0x0000001E
1215#define DREG_REGID_RF 0x0000001F
1216#define DREG_REGID_RA_BUS_LOW 0x00000020
1217#define DREG_REGID_RA_BUS_HIGH 0x00000038
1218#define DREG_REGID_YBUS_LOW 0x00000050
1219#define DREG_REGID_YBUS_HIGH 0x00000058
1220#define DREG_REGID_TRAP_0 0x00000100
1221#define DREG_REGID_TRAP_1 0x00000101
1222#define DREG_REGID_TRAP_2 0x00000102
1223#define DREG_REGID_TRAP_3 0x00000103
1224#define DREG_REGID_TRAP_4 0x00000104
1225#define DREG_REGID_TRAP_5 0x00000105
1226#define DREG_REGID_TRAP_6 0x00000106
1227#define DREG_REGID_TRAP_7 0x00000107
1228#define DREG_REGID_INDIRECT_ADDRESS 0x0000010E
1229#define DREG_REGID_TOP_OF_STACK 0x0000010F
1230#if !defined(NO_CS4612)
1231#if !defined(NO_CS4615)
1232#define DREG_REGID_TRAP_8 0x00000110
1233#define DREG_REGID_TRAP_9 0x00000111
1234#define DREG_REGID_TRAP_10 0x00000112
1235#define DREG_REGID_TRAP_11 0x00000113
1236#define DREG_REGID_TRAP_12 0x00000114
1237#define DREG_REGID_TRAP_13 0x00000115
1238#define DREG_REGID_TRAP_14 0x00000116
1239#define DREG_REGID_TRAP_15 0x00000117
1240#define DREG_REGID_TRAP_16 0x00000118
1241#define DREG_REGID_TRAP_17 0x00000119
1242#define DREG_REGID_TRAP_18 0x0000011A
1243#define DREG_REGID_TRAP_19 0x0000011B
1244#define DREG_REGID_TRAP_20 0x0000011C
1245#define DREG_REGID_TRAP_21 0x0000011D
1246#define DREG_REGID_TRAP_22 0x0000011E
1247#define DREG_REGID_TRAP_23 0x0000011F
1248#endif
1249#endif
1250#define DREG_REGID_RSA0_LOW 0x00000200
1251#define DREG_REGID_RSA0_HIGH 0x00000201
1252#define DREG_REGID_RSA1_LOW 0x00000202
1253#define DREG_REGID_RSA1_HIGH 0x00000203
1254#define DREG_REGID_RSA2 0x00000204
1255#define DREG_REGID_RSA3 0x00000205
1256#define DREG_REGID_RSI0_LOW 0x00000206
1257#define DREG_REGID_RSI0_HIGH 0x00000207
1258#define DREG_REGID_RSI1 0x00000208
1259#define DREG_REGID_RSI2 0x00000209
1260#define DREG_REGID_SAGUSTATUS 0x0000020A
1261#define DREG_REGID_RSCONFIG01_LOW 0x0000020B
1262#define DREG_REGID_RSCONFIG01_HIGH 0x0000020C
1263#define DREG_REGID_RSCONFIG23_LOW 0x0000020D
1264#define DREG_REGID_RSCONFIG23_HIGH 0x0000020E
1265#define DREG_REGID_RSDMA01E 0x0000020F
1266#define DREG_REGID_RSDMA23E 0x00000210
1267#define DREG_REGID_RSD0_LOW 0x00000211
1268#define DREG_REGID_RSD0_HIGH 0x00000212
1269#define DREG_REGID_RSD1_LOW 0x00000213
1270#define DREG_REGID_RSD1_HIGH 0x00000214
1271#define DREG_REGID_RSD2_LOW 0x00000215
1272#define DREG_REGID_RSD2_HIGH 0x00000216
1273#define DREG_REGID_RSD3_LOW 0x00000217
1274#define DREG_REGID_RSD3_HIGH 0x00000218
1275#define DREG_REGID_SRAR_HIGH 0x0000021A
1276#define DREG_REGID_SRAR_LOW 0x0000021B
1277#define DREG_REGID_DMA_STATE 0x0000021C
1278#define DREG_REGID_CURRENT_DMA_STREAM 0x0000021D
1279#define DREG_REGID_NEXT_DMA_STREAM 0x0000021E
1280#define DREG_REGID_CPU_STATUS 0x00000300
1281#define DREG_REGID_MAC_MODE 0x00000301
1282#define DREG_REGID_STACK_AND_REPEAT 0x00000302
1283#define DREG_REGID_INDEX0 0x00000304
1284#define DREG_REGID_INDEX1 0x00000305
1285#define DREG_REGID_DMA_STATE_0_3 0x00000400
1286#define DREG_REGID_DMA_STATE_4_7 0x00000404
1287#define DREG_REGID_DMA_STATE_8_11 0x00000408
1288#define DREG_REGID_DMA_STATE_12_15 0x0000040C
1289#define DREG_REGID_DMA_STATE_16_19 0x00000410
1290#define DREG_REGID_DMA_STATE_20_23 0x00000414
1291#define DREG_REGID_DMA_STATE_24_27 0x00000418
1292#define DREG_REGID_DMA_STATE_28_31 0x0000041C
1293#define DREG_REGID_DMA_STATE_32_35 0x00000420
1294#define DREG_REGID_DMA_STATE_36_39 0x00000424
1295#define DREG_REGID_DMA_STATE_40_43 0x00000428
1296#define DREG_REGID_DMA_STATE_44_47 0x0000042C
1297#define DREG_REGID_DMA_STATE_48_51 0x00000430
1298#define DREG_REGID_DMA_STATE_52_55 0x00000434
1299#define DREG_REGID_DMA_STATE_56_59 0x00000438
1300#define DREG_REGID_DMA_STATE_60_63 0x0000043C
1301#define DREG_REGID_DMA_STATE_64_67 0x00000440
1302#define DREG_REGID_DMA_STATE_68_71 0x00000444
1303#define DREG_REGID_DMA_STATE_72_75 0x00000448
1304#define DREG_REGID_DMA_STATE_76_79 0x0000044C
1305#define DREG_REGID_DMA_STATE_80_83 0x00000450
1306#define DREG_REGID_DMA_STATE_84_87 0x00000454
1307#define DREG_REGID_DMA_STATE_88_91 0x00000458
1308#define DREG_REGID_DMA_STATE_92_95 0x0000045C
1309#define DREG_REGID_TRAP_SELECT 0x00000500
1310#define DREG_REGID_TRAP_WRITE_0 0x00000500
1311#define DREG_REGID_TRAP_WRITE_1 0x00000501
1312#define DREG_REGID_TRAP_WRITE_2 0x00000502
1313#define DREG_REGID_TRAP_WRITE_3 0x00000503
1314#define DREG_REGID_TRAP_WRITE_4 0x00000504
1315#define DREG_REGID_TRAP_WRITE_5 0x00000505
1316#define DREG_REGID_TRAP_WRITE_6 0x00000506
1317#define DREG_REGID_TRAP_WRITE_7 0x00000507
1318#if !defined(NO_CS4612)
1319#if !defined(NO_CS4615)
1320#define DREG_REGID_TRAP_WRITE_8 0x00000510
1321#define DREG_REGID_TRAP_WRITE_9 0x00000511
1322#define DREG_REGID_TRAP_WRITE_10 0x00000512
1323#define DREG_REGID_TRAP_WRITE_11 0x00000513
1324#define DREG_REGID_TRAP_WRITE_12 0x00000514
1325#define DREG_REGID_TRAP_WRITE_13 0x00000515
1326#define DREG_REGID_TRAP_WRITE_14 0x00000516
1327#define DREG_REGID_TRAP_WRITE_15 0x00000517
1328#define DREG_REGID_TRAP_WRITE_16 0x00000518
1329#define DREG_REGID_TRAP_WRITE_17 0x00000519
1330#define DREG_REGID_TRAP_WRITE_18 0x0000051A
1331#define DREG_REGID_TRAP_WRITE_19 0x0000051B
1332#define DREG_REGID_TRAP_WRITE_20 0x0000051C
1333#define DREG_REGID_TRAP_WRITE_21 0x0000051D
1334#define DREG_REGID_TRAP_WRITE_22 0x0000051E
1335#define DREG_REGID_TRAP_WRITE_23 0x0000051F
1336#endif
1337#endif
1338#define DREG_REGID_MAC0_ACC0_LOW 0x00000600
1339#define DREG_REGID_MAC0_ACC1_LOW 0x00000601
1340#define DREG_REGID_MAC0_ACC2_LOW 0x00000602
1341#define DREG_REGID_MAC0_ACC3_LOW 0x00000603
1342#define DREG_REGID_MAC1_ACC0_LOW 0x00000604
1343#define DREG_REGID_MAC1_ACC1_LOW 0x00000605
1344#define DREG_REGID_MAC1_ACC2_LOW 0x00000606
1345#define DREG_REGID_MAC1_ACC3_LOW 0x00000607
1346#define DREG_REGID_MAC0_ACC0_MID 0x00000608
1347#define DREG_REGID_MAC0_ACC1_MID 0x00000609
1348#define DREG_REGID_MAC0_ACC2_MID 0x0000060A
1349#define DREG_REGID_MAC0_ACC3_MID 0x0000060B
1350#define DREG_REGID_MAC1_ACC0_MID 0x0000060C
1351#define DREG_REGID_MAC1_ACC1_MID 0x0000060D
1352#define DREG_REGID_MAC1_ACC2_MID 0x0000060E
1353#define DREG_REGID_MAC1_ACC3_MID 0x0000060F
1354#define DREG_REGID_MAC0_ACC0_HIGH 0x00000610
1355#define DREG_REGID_MAC0_ACC1_HIGH 0x00000611
1356#define DREG_REGID_MAC0_ACC2_HIGH 0x00000612
1357#define DREG_REGID_MAC0_ACC3_HIGH 0x00000613
1358#define DREG_REGID_MAC1_ACC0_HIGH 0x00000614
1359#define DREG_REGID_MAC1_ACC1_HIGH 0x00000615
1360#define DREG_REGID_MAC1_ACC2_HIGH 0x00000616
1361#define DREG_REGID_MAC1_ACC3_HIGH 0x00000617
1362#define DREG_REGID_RSHOUT_LOW 0x00000620
1363#define DREG_REGID_RSHOUT_MID 0x00000628
1364#define DREG_REGID_RSHOUT_HIGH 0x00000630
1365
1366/*
1367 * The following defines are for the flags in the DMA stream requestor write
1368 */
1369#define DSRWP_DSR_MASK 0x0000000F
1370#define DSRWP_DSR_BG_RQ 0x00000001
1371#define DSRWP_DSR_PRIORITY_MASK 0x00000006
1372#define DSRWP_DSR_PRIORITY_0 0x00000000
1373#define DSRWP_DSR_PRIORITY_1 0x00000002
1374#define DSRWP_DSR_PRIORITY_2 0x00000004
1375#define DSRWP_DSR_PRIORITY_3 0x00000006
1376#define DSRWP_DSR_RQ_PENDING 0x00000008
1377
1378/*
1379 * The following defines are for the flags in the trap write port register.
1380 */
1381#define TWPR_TW_MASK 0x0000FFFF
1382#define TWPR_TW_SHIFT 0
1383
1384/*
1385 * The following defines are for the flags in the stack pointer write
1386 * register.
1387 */
1388#define SPWR_STKP_MASK 0x0000000F
1389#define SPWR_STKP_SHIFT 0
1390
1391/*
1392 * The following defines are for the flags in the SP interrupt register.
1393 */
1394#define SPIR_FRI 0x00000001
1395#define SPIR_DOI 0x00000002
1396#define SPIR_GPI2 0x00000004
1397#define SPIR_GPI3 0x00000008
1398#define SPIR_IP0 0x00000010
1399#define SPIR_IP1 0x00000020
1400#define SPIR_IP2 0x00000040
1401#define SPIR_IP3 0x00000080
1402
1403/*
1404 * The following defines are for the flags in the functional group 1 register.
1405 */
1406#define FGR1_F1S_MASK 0x0000FFFF
1407#define FGR1_F1S_SHIFT 0
1408
1409/*
1410 * The following defines are for the flags in the SP clock status register.
1411 */
1412#define SPCS_FRI 0x00000001
1413#define SPCS_DOI 0x00000002
1414#define SPCS_GPI2 0x00000004
1415#define SPCS_GPI3 0x00000008
1416#define SPCS_IP0 0x00000010
1417#define SPCS_IP1 0x00000020
1418#define SPCS_IP2 0x00000040
1419#define SPCS_IP3 0x00000080
1420#define SPCS_SPRUN 0x00000100
1421#define SPCS_SLEEP 0x00000200
1422#define SPCS_FG 0x00000400
1423#define SPCS_ORUN 0x00000800
1424#define SPCS_IRQ 0x00001000
1425#define SPCS_FGN_MASK 0x0000E000
1426#define SPCS_FGN_SHIFT 13
1427
1428/*
1429 * The following defines are for the flags in the SP DMA requestor status
1430 * register.
1431 */
1432#define SDSR_DCS_MASK 0x000000FF
1433#define SDSR_DCS_SHIFT 0
1434#define SDSR_DCS_NONE 0x00000007
1435
1436/*
1437 * The following defines are for the flags in the frame timer register.
1438 */
1439#define FRMT_FTV_MASK 0x0000FFFF
1440#define FRMT_FTV_SHIFT 0
1441
1442/*
1443 * The following defines are for the flags in the frame timer current count
1444 * register.
1445 */
1446#define FRCC_FCC_MASK 0x0000FFFF
1447#define FRCC_FCC_SHIFT 0
1448
1449/*
1450 * The following defines are for the flags in the frame timer save count
1451 * register.
1452 */
1453#define FRSC_FCS_MASK 0x0000FFFF
1454#define FRSC_FCS_SHIFT 0
1455
1456/*
1457 * The following define the various flags stored in the scatter/gather
1458 * descriptors.
1459 */
1460#define DMA_SG_NEXT_ENTRY_MASK 0x00000FF8
1461#define DMA_SG_SAMPLE_END_MASK 0x0FFF0000
1462#define DMA_SG_SAMPLE_END_FLAG 0x10000000
1463#define DMA_SG_LOOP_END_FLAG 0x20000000
1464#define DMA_SG_SIGNAL_END_FLAG 0x40000000
1465#define DMA_SG_SIGNAL_PAGE_FLAG 0x80000000
1466#define DMA_SG_NEXT_ENTRY_SHIFT 3
1467#define DMA_SG_SAMPLE_END_SHIFT 16
1468
1469/*
1470 * The following define the offsets of the fields within the on-chip generic
1471 * DMA requestor.
1472 */
1473#define DMA_RQ_CONTROL1 0x00000000
1474#define DMA_RQ_CONTROL2 0x00000004
1475#define DMA_RQ_SOURCE_ADDR 0x00000008
1476#define DMA_RQ_DESTINATION_ADDR 0x0000000C
1477#define DMA_RQ_NEXT_PAGE_ADDR 0x00000010
1478#define DMA_RQ_NEXT_PAGE_SGDESC 0x00000014
1479#define DMA_RQ_LOOP_START_ADDR 0x00000018
1480#define DMA_RQ_POST_LOOP_ADDR 0x0000001C
1481#define DMA_RQ_PAGE_MAP_ADDR 0x00000020
1482
1483/*
1484 * The following defines are for the flags in the first control word of the
1485 * on-chip generic DMA requestor.
1486 */
1487#define DMA_RQ_C1_COUNT_MASK 0x000003FF
1488#define DMA_RQ_C1_DESTINATION_SCATTER 0x00001000
1489#define DMA_RQ_C1_SOURCE_GATHER 0x00002000
1490#define DMA_RQ_C1_DONE_FLAG 0x00004000
1491#define DMA_RQ_C1_OPTIMIZE_STATE 0x00008000
1492#define DMA_RQ_C1_SAMPLE_END_STATE_MASK 0x00030000
1493#define DMA_RQ_C1_FULL_PAGE 0x00000000
1494#define DMA_RQ_C1_BEFORE_SAMPLE_END 0x00010000
1495#define DMA_RQ_C1_PAGE_MAP_ERROR 0x00020000
1496#define DMA_RQ_C1_AT_SAMPLE_END 0x00030000
1497#define DMA_RQ_C1_LOOP_END_STATE_MASK 0x000C0000
1498#define DMA_RQ_C1_NOT_LOOP_END 0x00000000
1499#define DMA_RQ_C1_BEFORE_LOOP_END 0x00040000
1500#define DMA_RQ_C1_2PAGE_LOOP_BEGIN 0x00080000
1501#define DMA_RQ_C1_LOOP_BEGIN 0x000C0000
1502#define DMA_RQ_C1_PAGE_MAP_MASK 0x00300000
1503#define DMA_RQ_C1_PM_NONE_PENDING 0x00000000
1504#define DMA_RQ_C1_PM_NEXT_PENDING 0x00100000
1505#define DMA_RQ_C1_PM_RESERVED 0x00200000
1506#define DMA_RQ_C1_PM_LOOP_NEXT_PENDING 0x00300000
1507#define DMA_RQ_C1_WRITEBACK_DEST_FLAG 0x00400000
1508#define DMA_RQ_C1_WRITEBACK_SRC_FLAG 0x00800000
1509#define DMA_RQ_C1_DEST_SIZE_MASK 0x07000000
1510#define DMA_RQ_C1_DEST_LINEAR 0x00000000
1511#define DMA_RQ_C1_DEST_MOD16 0x01000000
1512#define DMA_RQ_C1_DEST_MOD32 0x02000000
1513#define DMA_RQ_C1_DEST_MOD64 0x03000000
1514#define DMA_RQ_C1_DEST_MOD128 0x04000000
1515#define DMA_RQ_C1_DEST_MOD256 0x05000000
1516#define DMA_RQ_C1_DEST_MOD512 0x06000000
1517#define DMA_RQ_C1_DEST_MOD1024 0x07000000
1518#define DMA_RQ_C1_DEST_ON_HOST 0x08000000
1519#define DMA_RQ_C1_SOURCE_SIZE_MASK 0x70000000
1520#define DMA_RQ_C1_SOURCE_LINEAR 0x00000000
1521#define DMA_RQ_C1_SOURCE_MOD16 0x10000000
1522#define DMA_RQ_C1_SOURCE_MOD32 0x20000000
1523#define DMA_RQ_C1_SOURCE_MOD64 0x30000000
1524#define DMA_RQ_C1_SOURCE_MOD128 0x40000000
1525#define DMA_RQ_C1_SOURCE_MOD256 0x50000000
1526#define DMA_RQ_C1_SOURCE_MOD512 0x60000000
1527#define DMA_RQ_C1_SOURCE_MOD1024 0x70000000
1528#define DMA_RQ_C1_SOURCE_ON_HOST 0x80000000
1529#define DMA_RQ_C1_COUNT_SHIFT 0
1530
1531/*
1532 * The following defines are for the flags in the second control word of the
1533 * on-chip generic DMA requestor.
1534 */
1535#define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK 0x0000003F
1536#define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK 0x00000300
1537#define DMA_RQ_C2_NO_VIRTUAL_SIGNAL 0x00000000
1538#define DMA_RQ_C2_SIGNAL_EVERY_DMA 0x00000100
1539#define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG 0x00000200
1540#define DMA_RQ_C2_SIGNAL_DEST_PINGPONG 0x00000300
1541#define DMA_RQ_C2_AUDIO_CONVERT_MASK 0x0000F000
1542#define DMA_RQ_C2_AC_NONE 0x00000000
1543#define DMA_RQ_C2_AC_8_TO_16_BIT 0x00001000
1544#define DMA_RQ_C2_AC_MONO_TO_STEREO 0x00002000
1545#define DMA_RQ_C2_AC_ENDIAN_CONVERT 0x00004000
1546#define DMA_RQ_C2_AC_SIGNED_CONVERT 0x00008000
1547#define DMA_RQ_C2_LOOP_END_MASK 0x0FFF0000
1548#define DMA_RQ_C2_LOOP_MASK 0x30000000
1549#define DMA_RQ_C2_NO_LOOP 0x00000000
1550#define DMA_RQ_C2_ONE_PAGE_LOOP 0x10000000
1551#define DMA_RQ_C2_TWO_PAGE_LOOP 0x20000000
1552#define DMA_RQ_C2_MULTI_PAGE_LOOP 0x30000000
1553#define DMA_RQ_C2_SIGNAL_LOOP_BACK 0x40000000
1554#define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE 0x80000000
1555#define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT 0
1556#define DMA_RQ_C2_LOOP_END_SHIFT 16
1557
1558/*
1559 * The following defines are for the flags in the source and destination words
1560 * of the on-chip generic DMA requestor.
1561 */
1562#define DMA_RQ_SD_ADDRESS_MASK 0x0000FFFF
1563#define DMA_RQ_SD_MEMORY_ID_MASK 0x000F0000
1564#define DMA_RQ_SD_SP_PARAM_ADDR 0x00000000
1565#define DMA_RQ_SD_SP_SAMPLE_ADDR 0x00010000
1566#define DMA_RQ_SD_SP_PROGRAM_ADDR 0x00020000
1567#define DMA_RQ_SD_SP_DEBUG_ADDR 0x00030000
1568#define DMA_RQ_SD_OMNIMEM_ADDR 0x000E0000
1569#define DMA_RQ_SD_END_FLAG 0x40000000
1570#define DMA_RQ_SD_ERROR_FLAG 0x80000000
1571#define DMA_RQ_SD_ADDRESS_SHIFT 0
1572
1573/*
1574 * The following defines are for the flags in the page map address word of the
1575 * on-chip generic DMA requestor.
1576 */
1577#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK 0x00000FF8
1578#define DMA_RQ_PMA_PAGE_TABLE_MASK 0xFFFFF000
1579#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT 3
1580#define DMA_RQ_PMA_PAGE_TABLE_SHIFT 12
1581
1582#define BA1_VARIDEC_BUF_1 0x000
1583
1584#define BA1_PDTC 0x0c0 /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */
1585#define BA1_PFIE 0x0c4 /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */
1586#define BA1_PBA 0x0c8 /* BA1_PLAY_BUFFER_ADDRESS */
1587#define BA1_PVOL 0x0f8 /* BA1_PLAY_VOLUME_REG */
1588#define BA1_PSRC 0x288 /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */
1589#define BA1_PCTL 0x2a4 /* BA1_PLAY_CONTROL_REG */
1590#define BA1_PPI 0x2b4 /* BA1_PLAY_PHASE_INCREMENT_REG */
1591
1592#define BA1_CCTL 0x064 /* BA1_CAPTURE_CONTROL_REG */
1593#define BA1_CIE 0x104 /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */
1594#define BA1_CBA 0x10c /* BA1_CAPTURE_BUFFER_ADDRESS */
1595#define BA1_CSRC 0x2c8 /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */
1596#define BA1_CCI 0x2d8 /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */
1597#define BA1_CD 0x2e0 /* BA1_CAPTURE_DELAY_REG */
1598#define BA1_CPI 0x2f4 /* BA1_CAPTURE_PHASE_INCREMENT_REG */
1599#define BA1_CVOL 0x2f8 /* BA1_CAPTURE_VOLUME_REG */
1600
1601#define BA1_CFG1 0x134 /* BA1_CAPTURE_FRAME_GROUP_1_REG */
1602#define BA1_CFG2 0x138 /* BA1_CAPTURE_FRAME_GROUP_2_REG */
1603#define BA1_CCST 0x13c /* BA1_CAPTURE_CONSTANT_REG */
1604#define BA1_CSPB 0x340 /* BA1_CAPTURE_SPB_ADDRESS */
1605
1606/*
1607 *
1608 */
1609
1610#define CS46XX_MODE_OUTPUT (1<<0) /* MIDI UART - output */
1611#define CS46XX_MODE_INPUT (1<<1) /* MIDI UART - input */
1612
1613/*
1614 *
1615 */
1616
1617#define SAVE_REG_MAX 0x10
1618#define POWER_DOWN_ALL 0x7f0f
1619
1620/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
1621#define MAX_NR_AC97 4
1622#define CS46XX_PRIMARY_CODEC_INDEX 0
1623#define CS46XX_SECONDARY_CODEC_INDEX 1
1624#define CS46XX_SECONDARY_CODEC_OFFSET 0x80
1625#define CS46XX_DSP_CAPTURE_CHANNEL 1
1626
1627/* capture */
1628#define CS46XX_DSP_CAPTURE_CHANNEL 1
1629
1630/* mixer */
1631#define CS46XX_MIXER_SPDIF_INPUT_ELEMENT 1
1632#define CS46XX_MIXER_SPDIF_OUTPUT_ELEMENT 2
1633
1634
1635struct snd_cs46xx_pcm {
1636 struct snd_dma_buffer hw_buf;
1637
1638 unsigned int ctl;
1639 unsigned int shift; /* Shift count to trasform frames in bytes */
1640 struct snd_pcm_indirect pcm_rec;
1641 struct snd_pcm_substream *substream;
1642
1643 struct dsp_pcm_channel_descriptor * pcm_channel;
1644
1645 int pcm_channel_id; /* Fron Rear, Center Lfe ... */
1646};
1647
1648struct snd_cs46xx_region {
1649 char name[24];
1650 unsigned long base;
1651 void __iomem *remap_addr;
1652 unsigned long size;
1653 struct resource *resource;
1654};
1655
1656struct snd_cs46xx {
1657 int irq;
1658 unsigned long ba0_addr;
1659 unsigned long ba1_addr;
1660 union {
1661 struct {
1662 struct snd_cs46xx_region ba0;
1663 struct snd_cs46xx_region data0;
1664 struct snd_cs46xx_region data1;
1665 struct snd_cs46xx_region pmem;
1666 struct snd_cs46xx_region reg;
1667 } name;
1668 struct snd_cs46xx_region idx[5];
1669 } region;
1670
1671 unsigned int mode;
1672
1673 struct {
1674 struct snd_dma_buffer hw_buf;
1675
1676 unsigned int ctl;
1677 unsigned int shift; /* Shift count to trasform frames in bytes */
1678 struct snd_pcm_indirect pcm_rec;
1679 struct snd_pcm_substream *substream;
1680 } capt;
1681
1682
1683 int nr_ac97_codecs;
1684 struct snd_ac97_bus *ac97_bus;
1685 struct snd_ac97 *ac97[MAX_NR_AC97];
1686
1687 struct pci_dev *pci;
1688 struct snd_card *card;
1689 struct snd_pcm *pcm;
1690
1691 struct snd_rawmidi *rmidi;
1692 struct snd_rawmidi_substream *midi_input;
1693 struct snd_rawmidi_substream *midi_output;
1694
1695 spinlock_t reg_lock;
1696 unsigned int midcr;
1697 unsigned int uartm;
1698
1699 int amplifier;
1700 void (*amplifier_ctrl)(struct snd_cs46xx *, int);
1701 void (*active_ctrl)(struct snd_cs46xx *, int);
1702 void (*mixer_init)(struct snd_cs46xx *);
1703
1704 int acpi_port;
1705 struct snd_kcontrol *eapd_switch; /* for amplifier hack */
1706 int accept_valid; /* accept mmap valid (for OSS) */
1707 int in_suspend;
1708
1709 struct gameport *gameport;
1710
1711#ifdef CONFIG_SND_CS46XX_NEW_DSP
1712 struct mutex spos_mutex;
1713
1714 struct dsp_spos_instance * dsp_spos_instance;
1715
1716 struct snd_pcm *pcm_rear;
1717 struct snd_pcm *pcm_center_lfe;
1718 struct snd_pcm *pcm_iec958;
1719#else /* for compatibility */
1720 struct snd_cs46xx_pcm *playback_pcm;
1721 unsigned int play_ctl;
1722#endif
1723
1724#ifdef CONFIG_PM
1725 u32 *saved_regs;
1726#endif
1727};
1728
1729int snd_cs46xx_create(struct snd_card *card,
1730 struct pci_dev *pci,
1731 int external_amp, int thinkpad,
1732 struct snd_cs46xx **rcodec);
1733extern const struct dev_pm_ops snd_cs46xx_pm;
1734
1735int snd_cs46xx_pcm(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1736int snd_cs46xx_pcm_rear(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1737int snd_cs46xx_pcm_iec958(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1738int snd_cs46xx_pcm_center_lfe(struct snd_cs46xx *chip, int device, struct snd_pcm **rpcm);
1739int snd_cs46xx_mixer(struct snd_cs46xx *chip, int spdif_device);
1740int snd_cs46xx_midi(struct snd_cs46xx *chip, int device, struct snd_rawmidi **rmidi);
1741int snd_cs46xx_start_dsp(struct snd_cs46xx *chip);
1742int snd_cs46xx_gameport(struct snd_cs46xx *chip);
1743
1744#endif /* __SOUND_CS46XX_H */
diff --git a/sound/pci/cs46xx/cs46xx_dsp_scb_types.h b/sound/pci/cs46xx/cs46xx_dsp_scb_types.h
new file mode 100644
index 00000000000..080857ad0ca
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_dsp_scb_types.h
@@ -0,0 +1,1213 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 *
21 * NOTE: comments are copy/paste from cwcemb80.lst
22 * provided by Tom Woller at Cirrus (my only
23 * documentation about the SP OS running inside
24 * the DSP)
25 */
26
27#ifndef __CS46XX_DSP_SCB_TYPES_H__
28#define __CS46XX_DSP_SCB_TYPES_H__
29
30#include <asm/byteorder.h>
31
32#ifndef ___DSP_DUAL_16BIT_ALLOC
33#if defined(__LITTLE_ENDIAN)
34#define ___DSP_DUAL_16BIT_ALLOC(a,b) u16 a; u16 b;
35#elif defined(__BIG_ENDIAN)
36#define ___DSP_DUAL_16BIT_ALLOC(a,b) u16 b; u16 a;
37#else
38#error Not __LITTLE_ENDIAN and not __BIG_ENDIAN, then what ???
39#endif
40#endif
41
42/* This structs are used internally by the SP */
43
44struct dsp_basic_dma_req {
45 /* DMA Requestor Word 0 (DCW) fields:
46
47 31 [30-28]27 [26:24] 23 22 21 20 [19:18] [17:16] 15 14 13 12 11 10 9 8 7 6 [5:0]
48 _______________________________________________________________________________________
49 |S| SBT |D| DBT |wb|wb| | | LS | SS |Opt|Do|SSG|DSG| | | | | | | Dword |
50 |H|_____ |H|_________|S_|D |__|__|______|_______|___|ne|__ |__ |__|__|_|_|_|_|_Count -1|
51 */
52 u32 dcw; /* DMA Control Word */
53 u32 dmw; /* DMA Mode Word */
54 u32 saw; /* Source Address Word */
55 u32 daw; /* Destination Address Word */
56};
57
58struct dsp_scatter_gather_ext {
59 u32 npaw; /* Next-Page Address Word */
60
61 /* DMA Requestor Word 5 (NPCW) fields:
62
63 31-30 29 28 [27:16] [15:12] [11:3] [2:0]
64 _________________________________________________________________________________________
65 |SV |LE|SE| Sample-end byte offset | | Page-map entry offset for next | |
66 |page|__|__| ___________________________|_________|__page, if !sample-end___________|____|
67 */
68 u32 npcw; /* Next-Page Control Word */
69 u32 lbaw; /* Loop-Begin Address Word */
70 u32 nplbaw; /* Next-Page after Loop-Begin Address Word */
71 u32 sgaw; /* Scatter/Gather Address Word */
72};
73
74struct dsp_volume_control {
75 ___DSP_DUAL_16BIT_ALLOC(
76 rightTarg, /* Target volume for left & right channels */
77 leftTarg
78 )
79 ___DSP_DUAL_16BIT_ALLOC(
80 rightVol, /* Current left & right channel volumes */
81 leftVol
82 )
83};
84
85/* Generic stream control block (SCB) structure definition */
86struct dsp_generic_scb {
87 /* For streaming I/O, the DSP should never alter any words in the DMA
88 requestor or the scatter/gather extension. Only ad hoc DMA request
89 streams are free to alter the requestor (currently only occur in the
90 DOS-based MIDI controller and in debugger-inserted code).
91
92 If an SCB does not have any associated DMA requestor, these 9 ints
93 may be freed for use by other tasks, but the pointer to the SCB must
94 still be such that the insOrd:nextSCB appear at offset 9 from the
95 SCB pointer.
96
97 Basic (non scatter/gather) DMA requestor (4 ints)
98 */
99
100 /* Initialized by the host, only modified by DMA
101 R/O for the DSP task */
102 struct dsp_basic_dma_req basic_req; /* Optional */
103
104 /* Scatter/gather DMA requestor extension (5 ints)
105 Initialized by the host, only modified by DMA
106 DSP task never needs to even read these.
107 */
108 struct dsp_scatter_gather_ext sg_ext; /* Optional */
109
110 /* Sublist pointer & next stream control block (SCB) link.
111 Initialized & modified by the host R/O for the DSP task
112 */
113 ___DSP_DUAL_16BIT_ALLOC(
114 next_scb, /* REQUIRED */
115 sub_list_ptr /* REQUIRED */
116 )
117
118 /* Pointer to this tasks parameter block & stream function pointer
119 Initialized by the host R/O for the DSP task */
120 ___DSP_DUAL_16BIT_ALLOC(
121 entry_point, /* REQUIRED */
122 this_spb /* REQUIRED */
123 )
124
125 /* rsConfig register for stream buffer (rsDMA reg.
126 is loaded from basicReq.daw for incoming streams, or
127 basicReq.saw, for outgoing streams)
128
129 31 30 29 [28:24] [23:16] 15 14 13 12 11 10 9 8 7 6 5 4 [3:0]
130 ______________________________________________________________________________
131 |DMA |D|maxDMAsize| streamNum|dir|p| | | | | | |ds |shr 1|rev Cy | mod |
132 |prio |_|__________|__________|___|_|__|__|__|__|_|_|___|_____|_______|_______|
133 31 30 29 [28:24] [23:16] 15 14 13 12 11 10 9 8 7 6 5 4 [3:0]
134
135
136 Initialized by the host R/O for the DSP task
137 */
138 u32 strm_rs_config; /* REQUIRED */
139 //
140 /* On mixer input streams: indicates mixer input stream configuration
141 On Tees, this is copied from the stream being snooped
142
143 Stream sample pointer & MAC-unit mode for this stream
144
145 Initialized by the host Updated by the DSP task
146 */
147 u32 strm_buf_ptr; /* REQUIRED */
148
149 /* On mixer input streams: points to next mixer input and is updated by the
150 mixer subroutine in the "parent" DSP task
151 (least-significant 16 bits are preserved, unused)
152
153 On Tees, the pointer is copied from the stream being snooped on
154 initialization, and, subsequently, it is copied into the
155 stream being snooped.
156
157 On wavetable/3D voices: the strmBufPtr will use all 32 bits to allow for
158 fractional phase accumulation
159
160 Fractional increment per output sample in the input sample buffer
161
162 (Not used on mixer input streams & redefined on Tees)
163 On wavetable/3D voices: this 32-bit word specifies the integer.fractional
164 increment per output sample.
165 */
166 u32 strmPhiIncr;
167
168
169 /* Standard stereo volume control
170 Initialized by the host (host updates target volumes)
171
172 Current volumes update by the DSP task
173 On mixer input streams: required & updated by the mixer subroutine in the
174 "parent" DSP task
175
176 On Tees, both current & target volumes are copied up on initialization,
177 and, subsequently, the target volume is copied up while the current
178 volume is copied down.
179
180 These two 32-bit words are redefined for wavetable & 3-D voices.
181 */
182 struct dsp_volume_control vol_ctrl_t; /* Optional */
183};
184
185
186struct dsp_spos_control_block {
187 /* WARNING: Certain items in this structure are modified by the host
188 Any dword that can be modified by the host, must not be
189 modified by the SP as the host can only do atomic dword
190 writes, and to do otherwise, even a read modify write,
191 may lead to corrupted data on the SP.
192
193 This rule does not apply to one off boot time initialisation prior to starting the SP
194 */
195
196
197 ___DSP_DUAL_16BIT_ALLOC(
198 /* First element on the Hyper forground task tree */
199 hfg_tree_root_ptr, /* HOST */
200 /* First 3 dwords are written by the host and read-only on the DSP */
201 hfg_stack_base /* HOST */
202 )
203
204 ___DSP_DUAL_16BIT_ALLOC(
205 /* Point to this data structure to enable easy access */
206 spos_cb_ptr, /* SP */
207 prev_task_tree_ptr /* SP && HOST */
208 )
209
210 ___DSP_DUAL_16BIT_ALLOC(
211 /* Currently Unused */
212 xxinterval_timer_period,
213 /* Enable extension of SPOS data structure */
214 HFGSPB_ptr
215 )
216
217
218 ___DSP_DUAL_16BIT_ALLOC(
219 xxnum_HFG_ticks_thisInterval,
220 /* Modified by the DSP */
221 xxnum_tntervals
222 )
223
224
225 /* Set by DSP upon encountering a trap (breakpoint) or a spurious
226 interrupt. The host must clear this dword after reading it
227 upon receiving spInt1. */
228 ___DSP_DUAL_16BIT_ALLOC(
229 spurious_int_flag, /* (Host & SP) Nature of the spurious interrupt */
230 trap_flag /* (Host & SP) Nature of detected Trap */
231 )
232
233 ___DSP_DUAL_16BIT_ALLOC(
234 unused2,
235 invalid_IP_flag /* (Host & SP ) Indicate detection of invalid instruction pointer */
236 )
237
238 ___DSP_DUAL_16BIT_ALLOC(
239 /* pointer to forground task tree header for use in next task search */
240 fg_task_tree_hdr_ptr, /* HOST */
241 /* Data structure for controlling synchronous link update */
242 hfg_sync_update_ptr /* HOST */
243 )
244
245 ___DSP_DUAL_16BIT_ALLOC(
246 begin_foreground_FCNT, /* SP */
247 /* Place holder for holding sleep timing */
248 last_FCNT_before_sleep /* SP */
249 )
250
251 ___DSP_DUAL_16BIT_ALLOC(
252 unused7, /* SP */
253 next_task_treePtr /* SP */
254 )
255
256 u32 unused5;
257
258 ___DSP_DUAL_16BIT_ALLOC(
259 active_flags, /* SP */
260 /* State flags, used to assist control of execution of Hyper Forground */
261 HFG_flags /* SP */
262 )
263
264 ___DSP_DUAL_16BIT_ALLOC(
265 unused9,
266 unused8
267 )
268
269 /* Space for saving enough context so that we can set up enough
270 to save some more context.
271 */
272 u32 rFE_save_for_invalid_IP;
273 u32 r32_save_for_spurious_int;
274 u32 r32_save_for_trap;
275 u32 r32_save_for_HFG;
276};
277
278/* SPB for MIX_TO_OSTREAM algorithm family */
279struct dsp_mix2_ostream_spb
280{
281 /* 16b.16b integer.frac approximation to the
282 number of 3 sample triplets to output each
283 frame. (approximation must be floor, to
284 insure that the fractional error is always
285 positive)
286 */
287 u32 outTripletsPerFrame;
288
289 /* 16b.16b integer.frac accumulated number of
290 output triplets since the start of group
291 */
292 u32 accumOutTriplets;
293};
294
295/* SCB for Timing master algorithm */
296struct dsp_timing_master_scb {
297 /* First 12 dwords from generic_scb_t */
298 struct dsp_basic_dma_req basic_req; /* Optional */
299 struct dsp_scatter_gather_ext sg_ext; /* Optional */
300 ___DSP_DUAL_16BIT_ALLOC(
301 next_scb, /* REQUIRED */
302 sub_list_ptr /* REQUIRED */
303 )
304
305 ___DSP_DUAL_16BIT_ALLOC(
306 entry_point, /* REQUIRED */
307 this_spb /* REQUIRED */
308 )
309
310 ___DSP_DUAL_16BIT_ALLOC(
311 /* Initial values are 0000:xxxx */
312 reserved,
313 extra_sample_accum
314 )
315
316
317 /* Initial values are xxxx:0000
318 hi: Current CODEC output FIFO pointer
319 (0 to 0x0f)
320 lo: Flag indicating that the CODEC
321 FIFO is sync'd (host clears to
322 resynchronize the FIFO pointer
323 upon start/restart)
324 */
325 ___DSP_DUAL_16BIT_ALLOC(
326 codec_FIFO_syncd,
327 codec_FIFO_ptr
328 )
329
330 /* Init. 8000:0005 for 44.1k
331 8000:0001 for 48k
332 hi: Fractional sample accumulator 0.16b
333 lo: Number of frames remaining to be
334 processed in the current group of
335 frames
336 */
337 ___DSP_DUAL_16BIT_ALLOC(
338 frac_samp_accum_qm1,
339 TM_frms_left_in_group
340 )
341
342 /* Init. 0001:0005 for 44.1k
343 0000:0001 for 48k
344 hi: Fractional sample correction factor 0.16b
345 to be added every frameGroupLength frames
346 to correct for truncation error in
347 nsamp_per_frm_q15
348 lo: Number of frames in the group
349 */
350 ___DSP_DUAL_16BIT_ALLOC(
351 frac_samp_correction_qm1,
352 TM_frm_group_length
353 )
354
355 /* Init. 44.1k*65536/8k = 0x00058333 for 44.1k
356 48k*65536/8k = 0x00060000 for 48k
357 16b.16b integer.frac approximation to the
358 number of samples to output each frame.
359 (approximation must be floor, to insure */
360 u32 nsamp_per_frm_q15;
361};
362
363/* SCB for CODEC output algorithm */
364struct dsp_codec_output_scb {
365 /* First 13 dwords from generic_scb_t */
366 struct dsp_basic_dma_req basic_req; /* Optional */
367 struct dsp_scatter_gather_ext sg_ext; /* Optional */
368 ___DSP_DUAL_16BIT_ALLOC(
369 next_scb, /* REQUIRED */
370 sub_list_ptr /* REQUIRED */
371 )
372
373 ___DSP_DUAL_16BIT_ALLOC(
374 entry_point, /* REQUIRED */
375 this_spb /* REQUIRED */
376 )
377
378 u32 strm_rs_config; /* REQUIRED */
379
380 u32 strm_buf_ptr; /* REQUIRED */
381
382 /* NOTE: The CODEC output task reads samples from the first task on its
383 sublist at the stream buffer pointer (init. to lag DMA destination
384 address word). After the required number of samples is transferred,
385 the CODEC output task advances sub_list_ptr->strm_buf_ptr past the samples
386 consumed.
387 */
388
389 /* Init. 0000:0010 for SDout
390 0060:0010 for SDout2
391 0080:0010 for SDout3
392 hi: Base IO address of FIFO to which
393 the left-channel samples are to
394 be written.
395 lo: Displacement for the base IO
396 address for left-channel to obtain
397 the base IO address for the FIFO
398 to which the right-channel samples
399 are to be written.
400 */
401 ___DSP_DUAL_16BIT_ALLOC(
402 left_chan_base_IO_addr,
403 right_chan_IO_disp
404 )
405
406
407 /* Init: 0x0080:0004 for non-AC-97
408 Init: 0x0080:0000 for AC-97
409 hi: Exponential volume change rate
410 for input stream
411 lo: Positive shift count to shift the
412 16-bit input sample to obtain the
413 32-bit output word
414 */
415 ___DSP_DUAL_16BIT_ALLOC(
416 CO_scale_shift_count,
417 CO_exp_vol_change_rate
418 )
419
420 /* Pointer to SCB at end of input chain */
421 ___DSP_DUAL_16BIT_ALLOC(
422 reserved,
423 last_sub_ptr
424 )
425};
426
427/* SCB for CODEC input algorithm */
428struct dsp_codec_input_scb {
429 /* First 13 dwords from generic_scb_t */
430 struct dsp_basic_dma_req basic_req; /* Optional */
431 struct dsp_scatter_gather_ext sg_ext; /* Optional */
432 ___DSP_DUAL_16BIT_ALLOC(
433 next_scb, /* REQUIRED */
434 sub_list_ptr /* REQUIRED */
435 )
436
437 ___DSP_DUAL_16BIT_ALLOC(
438 entry_point, /* REQUIRED */
439 this_spb /* REQUIRED */
440 )
441
442 u32 strm_rs_config; /* REQUIRED */
443 u32 strm_buf_ptr; /* REQUIRED */
444
445 /* NOTE: The CODEC input task reads samples from the hardware FIFO
446 sublist at the DMA source address word (sub_list_ptr->basic_req.saw).
447 After the required number of samples is transferred, the CODEC
448 output task advances sub_list_ptr->basic_req.saw past the samples
449 consumed. SPuD must initialize the sub_list_ptr->basic_req.saw
450 to point half-way around from the initial sub_list_ptr->strm_nuf_ptr
451 to allow for lag/lead.
452 */
453
454 /* Init. 0000:0010 for SDout
455 0060:0010 for SDout2
456 0080:0010 for SDout3
457 hi: Base IO address of FIFO to which
458 the left-channel samples are to
459 be written.
460 lo: Displacement for the base IO
461 address for left-channel to obtain
462 the base IO address for the FIFO
463 to which the right-channel samples
464 are to be written.
465 */
466 ___DSP_DUAL_16BIT_ALLOC(
467 rightChanINdisp,
468 left_chan_base_IN_addr
469 )
470 /* Init. ?:fffc
471 lo: Negative shift count to shift the
472 32-bit input dword to obtain the
473 16-bit sample msb-aligned (count
474 is negative to shift left)
475 */
476 ___DSP_DUAL_16BIT_ALLOC(
477 scaleShiftCount,
478 reserver1
479 )
480
481 u32 reserved2;
482};
483
484
485struct dsp_pcm_serial_input_scb {
486 /* First 13 dwords from generic_scb_t */
487 struct dsp_basic_dma_req basic_req; /* Optional */
488 struct dsp_scatter_gather_ext sg_ext; /* Optional */
489 ___DSP_DUAL_16BIT_ALLOC(
490 next_scb, /* REQUIRED */
491 sub_list_ptr /* REQUIRED */
492 )
493
494 ___DSP_DUAL_16BIT_ALLOC(
495 entry_point, /* REQUIRED */
496 this_spb /* REQUIRED */
497 )
498
499 u32 strm_buf_ptr; /* REQUIRED */
500 u32 strm_rs_config; /* REQUIRED */
501
502 /* Init. Ptr to CODEC input SCB
503 hi: Pointer to the SCB containing the
504 input buffer to which CODEC input
505 samples are written
506 lo: Flag indicating the link to the CODEC
507 input task is to be initialized
508 */
509 ___DSP_DUAL_16BIT_ALLOC(
510 init_codec_input_link,
511 codec_input_buf_scb
512 )
513
514 /* Initialized by the host (host updates target volumes) */
515 struct dsp_volume_control psi_vol_ctrl;
516
517};
518
519struct dsp_src_task_scb {
520 ___DSP_DUAL_16BIT_ALLOC(
521 frames_left_in_gof,
522 gofs_left_in_sec
523 )
524
525 ___DSP_DUAL_16BIT_ALLOC(
526 const2_thirds,
527 num_extra_tnput_samples
528 )
529
530 ___DSP_DUAL_16BIT_ALLOC(
531 cor_per_gof,
532 correction_per_sec
533 )
534
535 ___DSP_DUAL_16BIT_ALLOC(
536 output_buf_producer_ptr,
537 junk_DMA_MID
538 )
539
540 ___DSP_DUAL_16BIT_ALLOC(
541 gof_length,
542 gofs_per_sec
543 )
544
545 u32 input_buf_strm_config;
546
547 ___DSP_DUAL_16BIT_ALLOC(
548 reserved_for_SRC_use,
549 input_buf_consumer_ptr
550 )
551
552 u32 accum_phi;
553
554 ___DSP_DUAL_16BIT_ALLOC(
555 exp_src_vol_change_rate,
556 input_buf_producer_ptr
557 )
558
559 ___DSP_DUAL_16BIT_ALLOC(
560 src_next_scb,
561 src_sub_list_ptr
562 )
563
564 ___DSP_DUAL_16BIT_ALLOC(
565 src_entry_point,
566 src_this_sbp
567 )
568
569 u32 src_strm_rs_config;
570 u32 src_strm_buf_ptr;
571
572 u32 phiIncr6int_26frac;
573
574 struct dsp_volume_control src_vol_ctrl;
575};
576
577struct dsp_decimate_by_pow2_scb {
578 /* decimationFactor = 2, 4, or 8 (larger factors waste too much memory
579 when compared to cascading decimators)
580 */
581 ___DSP_DUAL_16BIT_ALLOC(
582 dec2_coef_base_ptr,
583 dec2_coef_increment
584 )
585
586 /* coefIncrement = 128 / decimationFactor (for our ROM filter)
587 coefBasePtr = 0x8000 (for our ROM filter)
588 */
589 ___DSP_DUAL_16BIT_ALLOC(
590 dec2_in_samples_per_out_triplet,
591 dec2_extra_in_samples
592 )
593 /* extraInSamples: # of accumulated, unused input samples (init. to 0)
594 inSamplesPerOutTriplet = 3 * decimationFactor
595 */
596
597 ___DSP_DUAL_16BIT_ALLOC(
598 dec2_const2_thirds,
599 dec2_half_num_taps_mp5
600 )
601 /* halfNumTapsM5: (1/2 number of taps in decimation filter) minus 5
602 const2thirds: constant 2/3 in 16Q0 format (sign.15)
603 */
604
605 ___DSP_DUAL_16BIT_ALLOC(
606 dec2_output_buf_producer_ptr,
607 dec2_junkdma_mid
608 )
609
610 u32 dec2_reserved2;
611
612 u32 dec2_input_nuf_strm_config;
613 /* inputBufStrmConfig: rsConfig for the input buffer to the decimator
614 (buffer size = decimationFactor * 32 dwords)
615 */
616
617 ___DSP_DUAL_16BIT_ALLOC(
618 dec2_phi_incr,
619 dec2_input_buf_consumer_ptr
620 )
621 /* inputBufConsumerPtr: Input buffer read pointer (into SRC filter)
622 phiIncr = decimationFactor * 4
623 */
624
625 u32 dec2_reserved3;
626
627 ___DSP_DUAL_16BIT_ALLOC(
628 dec2_exp_vol_change_rate,
629 dec2_input_buf_producer_ptr
630 )
631 /* inputBufProducerPtr: Input buffer write pointer
632 expVolChangeRate: Exponential volume change rate for possible
633 future mixer on input streams
634 */
635
636 ___DSP_DUAL_16BIT_ALLOC(
637 dec2_next_scb,
638 dec2_sub_list_ptr
639 )
640
641 ___DSP_DUAL_16BIT_ALLOC(
642 dec2_entry_point,
643 dec2_this_spb
644 )
645
646 u32 dec2_strm_rs_config;
647 u32 dec2_strm_buf_ptr;
648
649 u32 dec2_reserved4;
650
651 struct dsp_volume_control dec2_vol_ctrl; /* Not used! */
652};
653
654struct dsp_vari_decimate_scb {
655 ___DSP_DUAL_16BIT_ALLOC(
656 vdec_frames_left_in_gof,
657 vdec_gofs_left_in_sec
658 )
659
660 ___DSP_DUAL_16BIT_ALLOC(
661 vdec_const2_thirds,
662 vdec_extra_in_samples
663 )
664 /* extraInSamples: # of accumulated, unused input samples (init. to 0)
665 const2thirds: constant 2/3 in 16Q0 format (sign.15) */
666
667 ___DSP_DUAL_16BIT_ALLOC(
668 vdec_cor_per_gof,
669 vdec_correction_per_sec
670 )
671
672 ___DSP_DUAL_16BIT_ALLOC(
673 vdec_output_buf_producer_ptr,
674 vdec_input_buf_consumer_ptr
675 )
676 /* inputBufConsumerPtr: Input buffer read pointer (into SRC filter) */
677 ___DSP_DUAL_16BIT_ALLOC(
678 vdec_gof_length,
679 vdec_gofs_per_sec
680 )
681
682 u32 vdec_input_buf_strm_config;
683 /* inputBufStrmConfig: rsConfig for the input buffer to the decimator
684 (buffer size = 64 dwords) */
685 u32 vdec_coef_increment;
686 /* coefIncrement = - 128.0 / decimationFactor (as a 32Q15 number) */
687
688 u32 vdec_accumphi;
689 /* accumPhi: accumulated fractional phase increment (6.26) */
690
691 ___DSP_DUAL_16BIT_ALLOC(
692 vdec_exp_vol_change_rate,
693 vdec_input_buf_producer_ptr
694 )
695 /* inputBufProducerPtr: Input buffer write pointer
696 expVolChangeRate: Exponential volume change rate for possible
697 future mixer on input streams */
698
699 ___DSP_DUAL_16BIT_ALLOC(
700 vdec_next_scb,
701 vdec_sub_list_ptr
702 )
703
704 ___DSP_DUAL_16BIT_ALLOC(
705 vdec_entry_point,
706 vdec_this_spb
707 )
708
709 u32 vdec_strm_rs_config;
710 u32 vdec_strm_buf_ptr;
711
712 u32 vdec_phi_incr_6int_26frac;
713
714 struct dsp_volume_control vdec_vol_ctrl;
715};
716
717
718/* SCB for MIX_TO_OSTREAM algorithm family */
719struct dsp_mix2_ostream_scb {
720 /* First 13 dwords from generic_scb_t */
721 struct dsp_basic_dma_req basic_req; /* Optional */
722 struct dsp_scatter_gather_ext sg_ext; /* Optional */
723 ___DSP_DUAL_16BIT_ALLOC(
724 next_scb, /* REQUIRED */
725 sub_list_ptr /* REQUIRED */
726 )
727
728 ___DSP_DUAL_16BIT_ALLOC(
729 entry_point, /* REQUIRED */
730 this_spb /* REQUIRED */
731 )
732
733 u32 strm_rs_config; /* REQUIRED */
734 u32 strm_buf_ptr; /* REQUIRED */
735
736
737 /* hi: Number of mixed-down input triplets
738 computed since start of group
739 lo: Number of frames remaining to be
740 processed in the current group of
741 frames
742 */
743 ___DSP_DUAL_16BIT_ALLOC(
744 frames_left_in_group,
745 accum_input_triplets
746 )
747
748 /* hi: Exponential volume change rate
749 for mixer on input streams
750 lo: Number of frames in the group
751 */
752 ___DSP_DUAL_16BIT_ALLOC(
753 frame_group_length,
754 exp_vol_change_rate
755 )
756
757 ___DSP_DUAL_16BIT_ALLOC(
758 const_FFFF,
759 const_zero
760 )
761};
762
763
764/* SCB for S16_MIX algorithm */
765struct dsp_mix_only_scb {
766 /* First 13 dwords from generic_scb_t */
767 struct dsp_basic_dma_req basic_req; /* Optional */
768 struct dsp_scatter_gather_ext sg_ext; /* Optional */
769 ___DSP_DUAL_16BIT_ALLOC(
770 next_scb, /* REQUIRED */
771 sub_list_ptr /* REQUIRED */
772 )
773
774 ___DSP_DUAL_16BIT_ALLOC(
775 entry_point, /* REQUIRED */
776 this_spb /* REQUIRED */
777 )
778
779 u32 strm_rs_config; /* REQUIRED */
780 u32 strm_buf_ptr; /* REQUIRED */
781
782 u32 reserved;
783 struct dsp_volume_control vol_ctrl;
784};
785
786/* SCB for the async. CODEC input algorithm */
787struct dsp_async_codec_input_scb {
788 u32 io_free2;
789
790 u32 io_current_total;
791 u32 io_previous_total;
792
793 u16 io_count;
794 u16 io_count_limit;
795
796 u16 o_fifo_base_addr;
797 u16 ost_mo_format;
798 /* 1 = stereo; 0 = mono
799 xxx for ASER 1 (not allowed); 118 for ASER2 */
800
801 u32 ostrm_rs_config;
802 u32 ostrm_buf_ptr;
803
804 ___DSP_DUAL_16BIT_ALLOC(
805 io_sclks_per_lr_clk,
806 io_io_enable
807 )
808
809 u32 io_free4;
810
811 ___DSP_DUAL_16BIT_ALLOC(
812 io_next_scb,
813 io_sub_list_ptr
814 )
815
816 ___DSP_DUAL_16BIT_ALLOC(
817 io_entry_point,
818 io_this_spb
819 )
820
821 u32 istrm_rs_config;
822 u32 istrm_buf_ptr;
823
824 /* Init. 0000:8042: for ASER1
825 0000:8044: for ASER2 */
826 ___DSP_DUAL_16BIT_ALLOC(
827 io_stat_reg_addr,
828 iofifo_pointer
829 )
830
831 /* Init 1 stero:100 ASER1
832 Init 0 mono:110 ASER2
833 */
834 ___DSP_DUAL_16BIT_ALLOC(
835 ififo_base_addr,
836 ist_mo_format
837 )
838
839 u32 i_free;
840};
841
842
843/* SCB for the SP/DIF CODEC input and output */
844struct dsp_spdifiscb {
845 ___DSP_DUAL_16BIT_ALLOC(
846 status_ptr,
847 status_start_ptr
848 )
849
850 u32 current_total;
851 u32 previous_total;
852
853 ___DSP_DUAL_16BIT_ALLOC(
854 count,
855 count_limit
856 )
857
858 u32 status_data;
859
860 ___DSP_DUAL_16BIT_ALLOC(
861 status,
862 free4
863 )
864
865 u32 free3;
866
867 ___DSP_DUAL_16BIT_ALLOC(
868 free2,
869 bit_count
870 )
871
872 u32 temp_status;
873
874 ___DSP_DUAL_16BIT_ALLOC(
875 next_SCB,
876 sub_list_ptr
877 )
878
879 ___DSP_DUAL_16BIT_ALLOC(
880 entry_point,
881 this_spb
882 )
883
884 u32 strm_rs_config;
885 u32 strm_buf_ptr;
886
887 ___DSP_DUAL_16BIT_ALLOC(
888 stat_reg_addr,
889 fifo_pointer
890 )
891
892 ___DSP_DUAL_16BIT_ALLOC(
893 fifo_base_addr,
894 st_mo_format
895 )
896
897 u32 free1;
898};
899
900
901/* SCB for the SP/DIF CODEC input and output */
902struct dsp_spdifoscb {
903
904 u32 free2;
905
906 u32 free3[4];
907
908 /* Need to be here for compatibility with AsynchFGTxCode */
909 u32 strm_rs_config;
910
911 u32 strm_buf_ptr;
912
913 ___DSP_DUAL_16BIT_ALLOC(
914 status,
915 free5
916 )
917
918 u32 free4;
919
920 ___DSP_DUAL_16BIT_ALLOC(
921 next_scb,
922 sub_list_ptr
923 )
924
925 ___DSP_DUAL_16BIT_ALLOC(
926 entry_point,
927 this_spb
928 )
929
930 u32 free6[2];
931
932 ___DSP_DUAL_16BIT_ALLOC(
933 stat_reg_addr,
934 fifo_pointer
935 )
936
937 ___DSP_DUAL_16BIT_ALLOC(
938 fifo_base_addr,
939 st_mo_format
940 )
941
942 u32 free1;
943};
944
945
946struct dsp_asynch_fg_rx_scb {
947 ___DSP_DUAL_16BIT_ALLOC(
948 bot_buf_mask,
949 buf_Mask
950 )
951
952 ___DSP_DUAL_16BIT_ALLOC(
953 max,
954 min
955 )
956
957 ___DSP_DUAL_16BIT_ALLOC(
958 old_producer_pointer,
959 hfg_scb_ptr
960 )
961
962 ___DSP_DUAL_16BIT_ALLOC(
963 delta,
964 adjust_count
965 )
966
967 u32 unused2[5];
968
969 ___DSP_DUAL_16BIT_ALLOC(
970 sibling_ptr,
971 child_ptr
972 )
973
974 ___DSP_DUAL_16BIT_ALLOC(
975 code_ptr,
976 this_ptr
977 )
978
979 u32 strm_rs_config;
980
981 u32 strm_buf_ptr;
982
983 u32 unused_phi_incr;
984
985 ___DSP_DUAL_16BIT_ALLOC(
986 right_targ,
987 left_targ
988 )
989
990 ___DSP_DUAL_16BIT_ALLOC(
991 right_vol,
992 left_vol
993 )
994};
995
996
997struct dsp_asynch_fg_tx_scb {
998 ___DSP_DUAL_16BIT_ALLOC(
999 not_buf_mask,
1000 buf_mask
1001 )
1002
1003 ___DSP_DUAL_16BIT_ALLOC(
1004 max,
1005 min
1006 )
1007
1008 ___DSP_DUAL_16BIT_ALLOC(
1009 unused1,
1010 hfg_scb_ptr
1011 )
1012
1013 ___DSP_DUAL_16BIT_ALLOC(
1014 delta,
1015 adjust_count
1016 )
1017
1018 u32 accum_phi;
1019
1020 ___DSP_DUAL_16BIT_ALLOC(
1021 unused2,
1022 const_one_third
1023 )
1024
1025 u32 unused3[3];
1026
1027 ___DSP_DUAL_16BIT_ALLOC(
1028 sibling_ptr,
1029 child_ptr
1030 )
1031
1032 ___DSP_DUAL_16BIT_ALLOC(
1033 codePtr,
1034 this_ptr
1035 )
1036
1037 u32 strm_rs_config;
1038
1039 u32 strm_buf_ptr;
1040
1041 u32 phi_incr;
1042
1043 ___DSP_DUAL_16BIT_ALLOC(
1044 unused_right_targ,
1045 unused_left_targ
1046 )
1047
1048 ___DSP_DUAL_16BIT_ALLOC(
1049 unused_right_vol,
1050 unused_left_vol
1051 )
1052};
1053
1054
1055struct dsp_output_snoop_scb {
1056 /* First 13 dwords from generic_scb_t */
1057 struct dsp_basic_dma_req basic_req; /* Optional */
1058 struct dsp_scatter_gather_ext sg_ext; /* Optional */
1059 ___DSP_DUAL_16BIT_ALLOC(
1060 next_scb, /* REQUIRED */
1061 sub_list_ptr /* REQUIRED */
1062 )
1063
1064 ___DSP_DUAL_16BIT_ALLOC(
1065 entry_point, /* REQUIRED */
1066 this_spb /* REQUIRED */
1067 )
1068
1069 u32 strm_rs_config; /* REQUIRED */
1070 u32 strm_buf_ptr; /* REQUIRED */
1071
1072 ___DSP_DUAL_16BIT_ALLOC(
1073 init_snoop_input_link,
1074 snoop_child_input_scb
1075 )
1076
1077 u32 snoop_input_buf_ptr;
1078
1079 ___DSP_DUAL_16BIT_ALLOC(
1080 reserved,
1081 input_scb
1082 )
1083};
1084
1085struct dsp_spio_write_scb {
1086 ___DSP_DUAL_16BIT_ALLOC(
1087 address1,
1088 address2
1089 )
1090
1091 u32 data1;
1092
1093 u32 data2;
1094
1095 ___DSP_DUAL_16BIT_ALLOC(
1096 address3,
1097 address4
1098 )
1099
1100 u32 data3;
1101
1102 u32 data4;
1103
1104 ___DSP_DUAL_16BIT_ALLOC(
1105 unused1,
1106 data_ptr
1107 )
1108
1109 u32 unused2[2];
1110
1111 ___DSP_DUAL_16BIT_ALLOC(
1112 sibling_ptr,
1113 child_ptr
1114 )
1115
1116 ___DSP_DUAL_16BIT_ALLOC(
1117 entry_point,
1118 this_ptr
1119 )
1120
1121 u32 unused3[5];
1122};
1123
1124struct dsp_magic_snoop_task {
1125 u32 i0;
1126 u32 i1;
1127
1128 u32 strm_buf_ptr1;
1129
1130 u16 i2;
1131 u16 snoop_scb;
1132
1133 u32 i3;
1134 u32 i4;
1135 u32 i5;
1136 u32 i6;
1137
1138 u32 i7;
1139
1140 ___DSP_DUAL_16BIT_ALLOC(
1141 next_scb,
1142 sub_list_ptr
1143 )
1144
1145 ___DSP_DUAL_16BIT_ALLOC(
1146 entry_point,
1147 this_ptr
1148 )
1149
1150 u32 strm_buf_config;
1151 u32 strm_buf_ptr2;
1152
1153 u32 i8;
1154
1155 struct dsp_volume_control vdec_vol_ctrl;
1156};
1157
1158
1159struct dsp_filter_scb {
1160 ___DSP_DUAL_16BIT_ALLOC(
1161 a0_right, /* 0x00 */
1162 a0_left
1163 )
1164 ___DSP_DUAL_16BIT_ALLOC(
1165 a1_right, /* 0x01 */
1166 a1_left
1167 )
1168 ___DSP_DUAL_16BIT_ALLOC(
1169 a2_right, /* 0x02 */
1170 a2_left
1171 )
1172 ___DSP_DUAL_16BIT_ALLOC(
1173 output_buf_ptr, /* 0x03 */
1174 init
1175 )
1176
1177 ___DSP_DUAL_16BIT_ALLOC(
1178 filter_unused3, /* 0x04 */
1179 filter_unused2
1180 )
1181
1182 u32 prev_sample_output1; /* 0x05 */
1183 u32 prev_sample_output2; /* 0x06 */
1184 u32 prev_sample_input1; /* 0x07 */
1185 u32 prev_sample_input2; /* 0x08 */
1186
1187 ___DSP_DUAL_16BIT_ALLOC(
1188 next_scb_ptr, /* 0x09 */
1189 sub_list_ptr
1190 )
1191
1192 ___DSP_DUAL_16BIT_ALLOC(
1193 entry_point, /* 0x0A */
1194 spb_ptr
1195 )
1196
1197 u32 strm_rs_config; /* 0x0B */
1198 u32 strm_buf_ptr; /* 0x0C */
1199
1200 ___DSP_DUAL_16BIT_ALLOC(
1201 b0_right, /* 0x0D */
1202 b0_left
1203 )
1204 ___DSP_DUAL_16BIT_ALLOC(
1205 b1_right, /* 0x0E */
1206 b1_left
1207 )
1208 ___DSP_DUAL_16BIT_ALLOC(
1209 b2_right, /* 0x0F */
1210 b2_left
1211 )
1212};
1213#endif /* __DSP_SCB_TYPES_H__ */
diff --git a/sound/pci/cs46xx/cs46xx_dsp_spos.h b/sound/pci/cs46xx/cs46xx_dsp_spos.h
new file mode 100644
index 00000000000..8008c59288a
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_dsp_spos.h
@@ -0,0 +1,234 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef __CS46XX_DSP_SPOS_H__
23#define __CS46XX_DSP_SPOS_H__
24
25#include "cs46xx_dsp_scb_types.h"
26#include "cs46xx_dsp_task_types.h"
27
28#define SYMBOL_CONSTANT 0x0
29#define SYMBOL_SAMPLE 0x1
30#define SYMBOL_PARAMETER 0x2
31#define SYMBOL_CODE 0x3
32
33#define SEGTYPE_SP_PROGRAM 0x00000001
34#define SEGTYPE_SP_PARAMETER 0x00000002
35#define SEGTYPE_SP_SAMPLE 0x00000003
36#define SEGTYPE_SP_COEFFICIENT 0x00000004
37
38#define DSP_SPOS_UU 0x0deadul /* unused */
39#define DSP_SPOS_DC 0x0badul /* don't care */
40#define DSP_SPOS_DC_DC 0x0bad0badul /* don't care */
41#define DSP_SPOS_UUUU 0xdeadc0edul /* unused */
42#define DSP_SPOS_UUHI 0xdeadul
43#define DSP_SPOS_UULO 0xc0edul
44#define DSP_SPOS_DCDC 0x0badf1d0ul /* don't care */
45#define DSP_SPOS_DCDCHI 0x0badul
46#define DSP_SPOS_DCDCLO 0xf1d0ul
47
48#define DSP_MAX_TASK_NAME 60
49#define DSP_MAX_SYMBOL_NAME 100
50#define DSP_MAX_SCB_NAME 60
51#define DSP_MAX_SCB_DESC 200
52#define DSP_MAX_TASK_DESC 50
53
54#define DSP_MAX_PCM_CHANNELS 32
55#define DSP_MAX_SRC_NR 14
56
57#define DSP_PCM_MAIN_CHANNEL 1
58#define DSP_PCM_REAR_CHANNEL 2
59#define DSP_PCM_CENTER_LFE_CHANNEL 3
60#define DSP_PCM_S71_CHANNEL 4 /* surround 7.1 */
61#define DSP_IEC958_CHANNEL 5
62
63#define DSP_SPDIF_STATUS_OUTPUT_ENABLED 1
64#define DSP_SPDIF_STATUS_PLAYBACK_OPEN 2
65#define DSP_SPDIF_STATUS_HW_ENABLED 4
66#define DSP_SPDIF_STATUS_INPUT_CTRL_ENABLED 8
67
68struct dsp_symbol_entry {
69 u32 address;
70 char symbol_name[DSP_MAX_SYMBOL_NAME];
71 int symbol_type;
72
73 /* initialized by driver */
74 struct dsp_module_desc * module;
75 int deleted;
76};
77
78struct dsp_symbol_desc {
79 int nsymbols;
80
81 struct dsp_symbol_entry *symbols;
82
83 /* initialized by driver */
84 int highest_frag_index;
85};
86
87struct dsp_segment_desc {
88 int segment_type;
89 u32 offset;
90 u32 size;
91 u32 * data;
92};
93
94struct dsp_module_desc {
95 char * module_name;
96 struct dsp_symbol_desc symbol_table;
97 int nsegments;
98 struct dsp_segment_desc * segments;
99
100 /* initialized by driver */
101 u32 overlay_begin_address;
102 u32 load_address;
103 int nfixups;
104};
105
106struct dsp_scb_descriptor {
107 char scb_name[DSP_MAX_SCB_NAME];
108 u32 address;
109 int index;
110 u32 *data;
111
112 struct dsp_scb_descriptor * sub_list_ptr;
113 struct dsp_scb_descriptor * next_scb_ptr;
114 struct dsp_scb_descriptor * parent_scb_ptr;
115
116 struct dsp_symbol_entry * task_entry;
117 struct dsp_symbol_entry * scb_symbol;
118
119 struct snd_info_entry *proc_info;
120 int ref_count;
121
122 u16 volume[2];
123 unsigned int deleted :1;
124 unsigned int updated :1;
125 unsigned int volume_set :1;
126};
127
128struct dsp_task_descriptor {
129 char task_name[DSP_MAX_TASK_NAME];
130 int size;
131 u32 address;
132 int index;
133 u32 *data;
134};
135
136struct dsp_pcm_channel_descriptor {
137 int active;
138 int src_slot;
139 int pcm_slot;
140 u32 sample_rate;
141 u32 unlinked;
142 struct dsp_scb_descriptor * pcm_reader_scb;
143 struct dsp_scb_descriptor * src_scb;
144 struct dsp_scb_descriptor * mixer_scb;
145
146 void * private_data;
147};
148
149struct dsp_spos_instance {
150 struct dsp_symbol_desc symbol_table; /* currently available loaded symbols in SP */
151
152 int nmodules;
153 struct dsp_module_desc * modules; /* modules loaded into SP */
154
155 struct dsp_segment_desc code;
156
157 /* Main PCM playback mixer */
158 struct dsp_scb_descriptor * master_mix_scb;
159 u16 dac_volume_right;
160 u16 dac_volume_left;
161
162 /* Rear/surround PCM playback mixer */
163 struct dsp_scb_descriptor * rear_mix_scb;
164
165 /* Center/LFE mixer */
166 struct dsp_scb_descriptor * center_lfe_mix_scb;
167
168 int npcm_channels;
169 int nsrc_scb;
170 struct dsp_pcm_channel_descriptor pcm_channels[DSP_MAX_PCM_CHANNELS];
171 int src_scb_slots[DSP_MAX_SRC_NR];
172
173 /* cache this symbols */
174 struct dsp_symbol_entry * null_algorithm; /* used by PCMreaderSCB's */
175 struct dsp_symbol_entry * s16_up; /* used by SRCtaskSCB's */
176
177 /* proc fs */
178 struct snd_card *snd_card;
179 struct snd_info_entry * proc_dsp_dir;
180 struct snd_info_entry * proc_sym_info_entry;
181 struct snd_info_entry * proc_modules_info_entry;
182 struct snd_info_entry * proc_parameter_dump_info_entry;
183 struct snd_info_entry * proc_sample_dump_info_entry;
184
185 /* SCB's descriptors */
186 int nscb;
187 int scb_highest_frag_index;
188 struct dsp_scb_descriptor scbs[DSP_MAX_SCB_DESC];
189 struct snd_info_entry * proc_scb_info_entry;
190 struct dsp_scb_descriptor * the_null_scb;
191
192 /* Task's descriptors */
193 int ntask;
194 struct dsp_task_descriptor tasks[DSP_MAX_TASK_DESC];
195 struct snd_info_entry * proc_task_info_entry;
196
197 /* SPDIF status */
198 int spdif_status_out;
199 int spdif_status_in;
200 u16 spdif_input_volume_right;
201 u16 spdif_input_volume_left;
202 /* spdif channel status,
203 left right and user validity bits */
204 unsigned int spdif_csuv_default;
205 unsigned int spdif_csuv_stream;
206
207 /* SPDIF input sample rate converter */
208 struct dsp_scb_descriptor * spdif_in_src;
209 /* SPDIF input asynch. receiver */
210 struct dsp_scb_descriptor * asynch_rx_scb;
211
212 /* Capture record mixer SCB */
213 struct dsp_scb_descriptor * record_mixer_scb;
214
215 /* CODEC input SCB */
216 struct dsp_scb_descriptor * codec_in_scb;
217
218 /* reference snooper */
219 struct dsp_scb_descriptor * ref_snoop_scb;
220
221 /* SPDIF output PCM reference */
222 struct dsp_scb_descriptor * spdif_pcm_input_scb;
223
224 /* asynch TX task */
225 struct dsp_scb_descriptor * asynch_tx_scb;
226
227 /* record sources */
228 struct dsp_scb_descriptor * pcm_input;
229 struct dsp_scb_descriptor * adc_input;
230
231 int spdif_in_sample_rate;
232};
233
234#endif /* __DSP_SPOS_H__ */
diff --git a/sound/pci/cs46xx/cs46xx_dsp_task_types.h b/sound/pci/cs46xx/cs46xx_dsp_task_types.h
new file mode 100644
index 00000000000..5cf920bfda2
--- /dev/null
+++ b/sound/pci/cs46xx/cs46xx_dsp_task_types.h
@@ -0,0 +1,252 @@
1/*
2 * The driver for the Cirrus Logic's Sound Fusion CS46XX based soundcards
3 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 *
21 * NOTE: comments are copy/paste from cwcemb80.lst
22 * provided by Tom Woller at Cirrus (my only
23 * documentation about the SP OS running inside
24 * the DSP)
25 */
26
27#ifndef __CS46XX_DSP_TASK_TYPES_H__
28#define __CS46XX_DSP_TASK_TYPES_H__
29
30#include "cs46xx_dsp_scb_types.h"
31
32/*********************************************************************************************
33Example hierarchy of stream control blocks in the SP
34
35hfgTree
36Ptr____Call (c)
37 \
38 -------+------ ------------- ------------- ------------- -----
39| SBlaster IF |______\| Foreground |___\| Middlegr'nd |___\| Background |___\| Nul |
40| |Goto /| tree header |g /| tree header |g /| tree header |g /| SCB |r
41 -------------- (g) ------------- ------------- ------------- -----
42 |c |c |c |c
43 | | | |
44 \/ ------------- ------------- -------------
45 | Foreground |_\ | Middlegr'nd |_\ | Background |_\
46 | tree |g/ | tree |g/ | tree |g/
47 ------------- ------------- -------------
48 |c |c |c
49 | | |
50 \/ \/ \/
51
52*********************************************************************************************/
53
54#define HFG_FIRST_EXECUTE_MODE 0x0001
55#define HFG_FIRST_EXECUTE_MODE_BIT 0
56#define HFG_CONTEXT_SWITCH_MODE 0x0002
57#define HFG_CONTEXT_SWITCH_MODE_BIT 1
58
59#define MAX_FG_STACK_SIZE 32 /* THESE NEED TO BE COMPUTED PROPERLY */
60#define MAX_MG_STACK_SIZE 16
61#define MAX_BG_STACK_SIZE 9
62#define MAX_HFG_STACK_SIZE 4
63
64#define SLEEP_ACTIVE_INCREMENT 0 /* Enable task tree thread to go to sleep
65 This should only ever be used on the Background thread */
66#define STANDARD_ACTIVE_INCREMENT 1 /* Task tree thread normal operation */
67#define SUSPEND_ACTIVE_INCREMENT 2 /* Cause execution to suspend in the task tree thread
68 This should only ever be used on the Background thread */
69
70#define HOSTFLAGS_DISABLE_BG_SLEEP 0 /* Host-controlled flag that determines whether we go to sleep
71 at the end of BG */
72
73/* Minimal context save area for Hyper Forground */
74struct dsp_hf_save_area {
75 u32 r10_save;
76 u32 r54_save;
77 u32 r98_save;
78
79 ___DSP_DUAL_16BIT_ALLOC(
80 status_save,
81 ind_save
82 )
83
84 ___DSP_DUAL_16BIT_ALLOC(
85 rci1_save,
86 rci0_save
87 )
88
89 u32 r32_save;
90 u32 r76_save;
91 u32 rsd2_save;
92
93 ___DSP_DUAL_16BIT_ALLOC(
94 rsi2_save, /* See TaskTreeParameterBlock for
95 remainder of registers */
96 rsa2Save
97 )
98 /* saved as part of HFG context */
99};
100
101
102/* Task link data structure */
103struct dsp_tree_link {
104 ___DSP_DUAL_16BIT_ALLOC(
105 /* Pointer to sibling task control block */
106 next_scb,
107 /* Pointer to child task control block */
108 sub_ptr
109 )
110
111 ___DSP_DUAL_16BIT_ALLOC(
112 /* Pointer to code entry point */
113 entry_point,
114 /* Pointer to local data */
115 this_spb
116 )
117};
118
119
120struct dsp_task_tree_data {
121 ___DSP_DUAL_16BIT_ALLOC(
122 /* Initial tock count; controls task tree execution rate */
123 tock_count_limit,
124 /* Tock down counter */
125 tock_count
126 )
127
128 /* Add to ActiveCount when TockCountLimit reached:
129 Subtract on task tree termination */
130 ___DSP_DUAL_16BIT_ALLOC(
131 active_tncrement,
132 /* Number of pending activations for task tree */
133 active_count
134 )
135
136 ___DSP_DUAL_16BIT_ALLOC(
137 /* BitNumber to enable modification of correct bit in ActiveTaskFlags */
138 active_bit,
139 /* Pointer to OS location for indicating current activity on task level */
140 active_task_flags_ptr
141 )
142
143 /* Data structure for controlling movement of memory blocks:-
144 currently unused */
145 ___DSP_DUAL_16BIT_ALLOC(
146 mem_upd_ptr,
147 /* Data structure for controlling synchronous link update */
148 link_upd_ptr
149 )
150
151 ___DSP_DUAL_16BIT_ALLOC(
152 /* Save area for remainder of full context. */
153 save_area,
154 /* Address of start of local stack for data storage */
155 data_stack_base_ptr
156 )
157
158};
159
160
161struct dsp_interval_timer_data
162{
163 /* These data items have the same relative locations to those */
164 ___DSP_DUAL_16BIT_ALLOC(
165 interval_timer_period,
166 itd_unused
167 )
168
169 /* used for this data in the SPOS control block for SPOS 1.0 */
170 ___DSP_DUAL_16BIT_ALLOC(
171 num_FG_ticks_this_interval,
172 num_intervals
173 )
174};
175
176
177/* This structure contains extra storage for the task tree
178 Currently, this additional data is related only to a full context save */
179struct dsp_task_tree_context_block {
180 /* Up to 10 values are saved onto the stack. 8 for the task tree, 1 for
181 The access to the context switch (call or interrupt), and 1 spare that
182 users should never use. This last may be required by the system */
183 ___DSP_DUAL_16BIT_ALLOC(
184 stack1,
185 stack0
186 )
187 ___DSP_DUAL_16BIT_ALLOC(
188 stack3,
189 stack2
190 )
191 ___DSP_DUAL_16BIT_ALLOC(
192 stack5,
193 stack4
194 )
195 ___DSP_DUAL_16BIT_ALLOC(
196 stack7,
197 stack6
198 )
199 ___DSP_DUAL_16BIT_ALLOC(
200 stack9,
201 stack8
202 )
203
204 u32 saverfe;
205
206 /* Value may be overwriten by stack save algorithm.
207 Retain the size of the stack data saved here if used */
208 ___DSP_DUAL_16BIT_ALLOC(
209 reserved1,
210 stack_size
211 )
212 u32 saverba; /* (HFG) */
213 u32 saverdc;
214 u32 savers_config_23; /* (HFG) */
215 u32 savers_DMA23; /* (HFG) */
216 u32 saversa0;
217 u32 saversi0;
218 u32 saversa1;
219 u32 saversi1;
220 u32 saversa3;
221 u32 saversd0;
222 u32 saversd1;
223 u32 saversd3;
224 u32 savers_config01;
225 u32 savers_DMA01;
226 u32 saveacc0hl;
227 u32 saveacc1hl;
228 u32 saveacc0xacc1x;
229 u32 saveacc2hl;
230 u32 saveacc3hl;
231 u32 saveacc2xacc3x;
232 u32 saveaux0hl;
233 u32 saveaux1hl;
234 u32 saveaux0xaux1x;
235 u32 saveaux2hl;
236 u32 saveaux3hl;
237 u32 saveaux2xaux3x;
238 u32 savershouthl;
239 u32 savershoutxmacmode;
240};
241
242
243struct dsp_task_tree_control_block {
244 struct dsp_hf_save_area context;
245 struct dsp_tree_link links;
246 struct dsp_task_tree_data data;
247 struct dsp_task_tree_context_block context_blk;
248 struct dsp_interval_timer_data int_timer;
249};
250
251
252#endif /* __DSP_TASK_TYPES_H__ */
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c
index 4fa53161b09..f75f5ffdfdf 100644
--- a/sound/pci/cs46xx/cs46xx_lib.c
+++ b/sound/pci/cs46xx/cs46xx_lib.c
@@ -61,7 +61,7 @@
61#include <sound/info.h> 61#include <sound/info.h>
62#include <sound/pcm.h> 62#include <sound/pcm.h>
63#include <sound/pcm_params.h> 63#include <sound/pcm_params.h>
64#include <sound/cs46xx.h> 64#include "cs46xx.h"
65 65
66#include <asm/io.h> 66#include <asm/io.h>
67 67
@@ -3599,9 +3599,10 @@ static unsigned int saved_regs[] = {
3599 BA1_CVOL, 3599 BA1_CVOL,
3600}; 3600};
3601 3601
3602int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state) 3602static int snd_cs46xx_suspend(struct device *dev)
3603{ 3603{
3604 struct snd_card *card = pci_get_drvdata(pci); 3604 struct pci_dev *pci = to_pci_dev(dev);
3605 struct snd_card *card = dev_get_drvdata(dev);
3605 struct snd_cs46xx *chip = card->private_data; 3606 struct snd_cs46xx *chip = card->private_data;
3606 int i, amp_saved; 3607 int i, amp_saved;
3607 3608
@@ -3628,13 +3629,14 @@ int snd_cs46xx_suspend(struct pci_dev *pci, pm_message_t state)
3628 3629
3629 pci_disable_device(pci); 3630 pci_disable_device(pci);
3630 pci_save_state(pci); 3631 pci_save_state(pci);
3631 pci_set_power_state(pci, pci_choose_state(pci, state)); 3632 pci_set_power_state(pci, PCI_D3hot);
3632 return 0; 3633 return 0;
3633} 3634}
3634 3635
3635int snd_cs46xx_resume(struct pci_dev *pci) 3636static int snd_cs46xx_resume(struct device *dev)
3636{ 3637{
3637 struct snd_card *card = pci_get_drvdata(pci); 3638 struct pci_dev *pci = to_pci_dev(dev);
3639 struct snd_card *card = dev_get_drvdata(dev);
3638 struct snd_cs46xx *chip = card->private_data; 3640 struct snd_cs46xx *chip = card->private_data;
3639 int amp_saved; 3641 int amp_saved;
3640#ifdef CONFIG_SND_CS46XX_NEW_DSP 3642#ifdef CONFIG_SND_CS46XX_NEW_DSP
@@ -3707,6 +3709,8 @@ int snd_cs46xx_resume(struct pci_dev *pci)
3707 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 3709 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
3708 return 0; 3710 return 0;
3709} 3711}
3712
3713SIMPLE_DEV_PM_OPS(snd_cs46xx_pm, snd_cs46xx_suspend, snd_cs46xx_resume);
3710#endif /* CONFIG_PM */ 3714#endif /* CONFIG_PM */
3711 3715
3712 3716
diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c
index e377287192a..56fec0bc0ef 100644
--- a/sound/pci/cs46xx/dsp_spos.c
+++ b/sound/pci/cs46xx/dsp_spos.c
@@ -32,7 +32,7 @@
32#include <sound/control.h> 32#include <sound/control.h>
33#include <sound/info.h> 33#include <sound/info.h>
34#include <sound/asoundef.h> 34#include <sound/asoundef.h>
35#include <sound/cs46xx.h> 35#include "cs46xx.h"
36 36
37#include "cs46xx_lib.h" 37#include "cs46xx_lib.h"
38#include "dsp_spos.h" 38#include "dsp_spos.h"
diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c
index 00b148a1023..c2c695b07f8 100644
--- a/sound/pci/cs46xx/dsp_spos_scb_lib.c
+++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c
@@ -31,7 +31,7 @@
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/control.h> 32#include <sound/control.h>
33#include <sound/info.h> 33#include <sound/info.h>
34#include <sound/cs46xx.h> 34#include "cs46xx.h"
35 35
36#include "cs46xx_lib.h" 36#include "cs46xx_lib.h"
37#include "dsp_spos.h" 37#include "dsp_spos.h"
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c
index 2c9697cf0a1..51f64ba5fac 100644
--- a/sound/pci/cs5535audio/cs5535audio.c
+++ b/sound/pci/cs5535audio/cs5535audio.c
@@ -400,8 +400,9 @@ static struct pci_driver cs5535audio_driver = {
400 .probe = snd_cs5535audio_probe, 400 .probe = snd_cs5535audio_probe,
401 .remove = __devexit_p(snd_cs5535audio_remove), 401 .remove = __devexit_p(snd_cs5535audio_remove),
402#ifdef CONFIG_PM 402#ifdef CONFIG_PM
403 .suspend = snd_cs5535audio_suspend, 403 .driver = {
404 .resume = snd_cs5535audio_resume, 404 .pm = &snd_cs5535audio_pm,
405 },
405#endif 406#endif
406}; 407};
407 408
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h
index 51966d782a3..bb3cc641130 100644
--- a/sound/pci/cs5535audio/cs5535audio.h
+++ b/sound/pci/cs5535audio/cs5535audio.h
@@ -94,10 +94,7 @@ struct cs5535audio {
94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS]; 94 struct cs5535audio_dma dmas[NUM_CS5535AUDIO_DMAS];
95}; 95};
96 96
97#ifdef CONFIG_PM 97extern const struct dev_pm_ops snd_cs5535audio_pm;
98int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state);
99int snd_cs5535audio_resume(struct pci_dev *pci);
100#endif
101 98
102#ifdef CONFIG_OLPC 99#ifdef CONFIG_OLPC
103void __devinit olpc_prequirks(struct snd_card *card, 100void __devinit olpc_prequirks(struct snd_card *card,
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c
index 185b0008832..6c34def5986 100644
--- a/sound/pci/cs5535audio/cs5535audio_pm.c
+++ b/sound/pci/cs5535audio/cs5535audio_pm.c
@@ -55,9 +55,10 @@ static void snd_cs5535audio_stop_hardware(struct cs5535audio *cs5535au)
55 55
56} 56}
57 57
58int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state) 58static int snd_cs5535audio_suspend(struct device *dev)
59{ 59{
60 struct snd_card *card = pci_get_drvdata(pci); 60 struct pci_dev *pci = to_pci_dev(dev);
61 struct snd_card *card = dev_get_drvdata(dev);
61 struct cs5535audio *cs5535au = card->private_data; 62 struct cs5535audio *cs5535au = card->private_data;
62 int i; 63 int i;
63 64
@@ -77,13 +78,14 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state)
77 return -EIO; 78 return -EIO;
78 } 79 }
79 pci_disable_device(pci); 80 pci_disable_device(pci);
80 pci_set_power_state(pci, pci_choose_state(pci, state)); 81 pci_set_power_state(pci, PCI_D3hot);
81 return 0; 82 return 0;
82} 83}
83 84
84int snd_cs5535audio_resume(struct pci_dev *pci) 85static int snd_cs5535audio_resume(struct device *dev)
85{ 86{
86 struct snd_card *card = pci_get_drvdata(pci); 87 struct pci_dev *pci = to_pci_dev(dev);
88 struct snd_card *card = dev_get_drvdata(dev);
87 struct cs5535audio *cs5535au = card->private_data; 89 struct cs5535audio *cs5535au = card->private_data;
88 u32 tmp; 90 u32 tmp;
89 int timeout; 91 int timeout;
@@ -129,3 +131,4 @@ int snd_cs5535audio_resume(struct pci_dev *pci)
129 return 0; 131 return 0;
130} 132}
131 133
134SIMPLE_DEV_PM_OPS(snd_cs5535audio_pm, snd_cs5535audio_suspend, snd_cs5535audio_resume);
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c
index d8a4423539c..8e40262d411 100644
--- a/sound/pci/ctxfi/ctatc.c
+++ b/sound/pci/ctxfi/ctatc.c
@@ -1537,7 +1537,7 @@ static void atc_connect_resources(struct ct_atc *atc)
1537} 1537}
1538 1538
1539#ifdef CONFIG_PM 1539#ifdef CONFIG_PM
1540static int atc_suspend(struct ct_atc *atc, pm_message_t state) 1540static int atc_suspend(struct ct_atc *atc)
1541{ 1541{
1542 int i; 1542 int i;
1543 struct hw *hw = atc->hw; 1543 struct hw *hw = atc->hw;
@@ -1553,7 +1553,7 @@ static int atc_suspend(struct ct_atc *atc, pm_message_t state)
1553 1553
1554 atc_release_resources(atc); 1554 atc_release_resources(atc);
1555 1555
1556 hw->suspend(hw, state); 1556 hw->suspend(hw);
1557 1557
1558 return 0; 1558 return 0;
1559} 1559}
diff --git a/sound/pci/ctxfi/ctatc.h b/sound/pci/ctxfi/ctatc.h
index 3a0def656af..653e813ad14 100644
--- a/sound/pci/ctxfi/ctatc.h
+++ b/sound/pci/ctxfi/ctatc.h
@@ -144,7 +144,7 @@ struct ct_atc {
144 struct ct_timer *timer; 144 struct ct_timer *timer;
145 145
146#ifdef CONFIG_PM 146#ifdef CONFIG_PM
147 int (*suspend)(struct ct_atc *atc, pm_message_t state); 147 int (*suspend)(struct ct_atc *atc);
148 int (*resume)(struct ct_atc *atc); 148 int (*resume)(struct ct_atc *atc);
149#define NUM_PCMS (NUM_CTALSADEVS - 1) 149#define NUM_PCMS (NUM_CTALSADEVS - 1)
150 struct snd_pcm *pcms[NUM_PCMS]; 150 struct snd_pcm *pcms[NUM_PCMS];
diff --git a/sound/pci/ctxfi/cthardware.h b/sound/pci/ctxfi/cthardware.h
index 908315bec3b..c56fe533b3f 100644
--- a/sound/pci/ctxfi/cthardware.h
+++ b/sound/pci/ctxfi/cthardware.h
@@ -73,7 +73,7 @@ struct hw {
73 int (*card_stop)(struct hw *hw); 73 int (*card_stop)(struct hw *hw);
74 int (*pll_init)(struct hw *hw, unsigned int rsr); 74 int (*pll_init)(struct hw *hw, unsigned int rsr);
75#ifdef CONFIG_PM 75#ifdef CONFIG_PM
76 int (*suspend)(struct hw *hw, pm_message_t state); 76 int (*suspend)(struct hw *hw);
77 int (*resume)(struct hw *hw, struct card_conf *info); 77 int (*resume)(struct hw *hw, struct card_conf *info);
78#endif 78#endif
79 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source); 79 int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
diff --git a/sound/pci/ctxfi/cthw20k1.c b/sound/pci/ctxfi/cthw20k1.c
index a7df19791f5..dc1969bc67d 100644
--- a/sound/pci/ctxfi/cthw20k1.c
+++ b/sound/pci/ctxfi/cthw20k1.c
@@ -2086,7 +2086,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2086} 2086}
2087 2087
2088#ifdef CONFIG_PM 2088#ifdef CONFIG_PM
2089static int hw_suspend(struct hw *hw, pm_message_t state) 2089static int hw_suspend(struct hw *hw)
2090{ 2090{
2091 struct pci_dev *pci = hw->pci; 2091 struct pci_dev *pci = hw->pci;
2092 2092
@@ -2099,7 +2099,7 @@ static int hw_suspend(struct hw *hw, pm_message_t state)
2099 2099
2100 pci_disable_device(pci); 2100 pci_disable_device(pci);
2101 pci_save_state(pci); 2101 pci_save_state(pci);
2102 pci_set_power_state(pci, pci_choose_state(pci, state)); 2102 pci_set_power_state(pci, PCI_D3hot);
2103 2103
2104 return 0; 2104 return 0;
2105} 2105}
diff --git a/sound/pci/ctxfi/cthw20k2.c b/sound/pci/ctxfi/cthw20k2.c
index d6c54b524bf..9d1231dc4ae 100644
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -2202,7 +2202,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
2202} 2202}
2203 2203
2204#ifdef CONFIG_PM 2204#ifdef CONFIG_PM
2205static int hw_suspend(struct hw *hw, pm_message_t state) 2205static int hw_suspend(struct hw *hw)
2206{ 2206{
2207 struct pci_dev *pci = hw->pci; 2207 struct pci_dev *pci = hw->pci;
2208 2208
@@ -2210,7 +2210,7 @@ static int hw_suspend(struct hw *hw, pm_message_t state)
2210 2210
2211 pci_disable_device(pci); 2211 pci_disable_device(pci);
2212 pci_save_state(pci); 2212 pci_save_state(pci);
2213 pci_set_power_state(pci, pci_choose_state(pci, state)); 2213 pci_set_power_state(pci, PCI_D3hot);
2214 2214
2215 return 0; 2215 return 0;
2216} 2216}
diff --git a/sound/pci/ctxfi/xfi.c b/sound/pci/ctxfi/xfi.c
index 75aa2c33841..e002183ef8b 100644
--- a/sound/pci/ctxfi/xfi.c
+++ b/sound/pci/ctxfi/xfi.c
@@ -126,21 +126,26 @@ static void __devexit ct_card_remove(struct pci_dev *pci)
126} 126}
127 127
128#ifdef CONFIG_PM 128#ifdef CONFIG_PM
129static int ct_card_suspend(struct pci_dev *pci, pm_message_t state) 129static int ct_card_suspend(struct device *dev)
130{ 130{
131 struct snd_card *card = pci_get_drvdata(pci); 131 struct snd_card *card = dev_get_drvdata(dev);
132 struct ct_atc *atc = card->private_data; 132 struct ct_atc *atc = card->private_data;
133 133
134 return atc->suspend(atc, state); 134 return atc->suspend(atc);
135} 135}
136 136
137static int ct_card_resume(struct pci_dev *pci) 137static int ct_card_resume(struct device *dev)
138{ 138{
139 struct snd_card *card = pci_get_drvdata(pci); 139 struct snd_card *card = dev_get_drvdata(dev);
140 struct ct_atc *atc = card->private_data; 140 struct ct_atc *atc = card->private_data;
141 141
142 return atc->resume(atc); 142 return atc->resume(atc);
143} 143}
144
145static SIMPLE_DEV_PM_OPS(ct_card_pm, ct_card_suspend, ct_card_resume);
146#define CT_CARD_PM_OPS &ct_card_pm
147#else
148#define CT_CARD_PM_OPS NULL
144#endif 149#endif
145 150
146static struct pci_driver ct_driver = { 151static struct pci_driver ct_driver = {
@@ -148,10 +153,9 @@ static struct pci_driver ct_driver = {
148 .id_table = ct_pci_dev_ids, 153 .id_table = ct_pci_dev_ids,
149 .probe = ct_card_probe, 154 .probe = ct_card_probe,
150 .remove = __devexit_p(ct_card_remove), 155 .remove = __devexit_p(ct_card_remove),
151#ifdef CONFIG_PM 156 .driver = {
152 .suspend = ct_card_suspend, 157 .pm = CT_CARD_PM_OPS,
153 .resume = ct_card_resume, 158 },
154#endif
155}; 159};
156 160
157module_pci_driver(ct_driver); 161module_pci_driver(ct_driver);
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
index 0f8eda1dafd..0ff754f180d 100644
--- a/sound/pci/echoaudio/echoaudio.c
+++ b/sound/pci/echoaudio/echoaudio.c
@@ -2205,9 +2205,10 @@ ctl_error:
2205 2205
2206#if defined(CONFIG_PM) 2206#if defined(CONFIG_PM)
2207 2207
2208static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state) 2208static int snd_echo_suspend(struct device *dev)
2209{ 2209{
2210 struct echoaudio *chip = pci_get_drvdata(pci); 2210 struct pci_dev *pci = to_pci_dev(dev);
2211 struct echoaudio *chip = dev_get_drvdata(dev);
2211 2212
2212 DE_INIT(("suspend start\n")); 2213 DE_INIT(("suspend start\n"));
2213 snd_pcm_suspend_all(chip->analog_pcm); 2214 snd_pcm_suspend_all(chip->analog_pcm);
@@ -2242,9 +2243,10 @@ static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
2242 2243
2243 2244
2244 2245
2245static int snd_echo_resume(struct pci_dev *pci) 2246static int snd_echo_resume(struct device *dev)
2246{ 2247{
2247 struct echoaudio *chip = pci_get_drvdata(pci); 2248 struct pci_dev *pci = to_pci_dev(dev);
2249 struct echoaudio *chip = dev_get_drvdata(dev);
2248 struct comm_page *commpage, *commpage_bak; 2250 struct comm_page *commpage, *commpage_bak;
2249 u32 pipe_alloc_mask; 2251 u32 pipe_alloc_mask;
2250 int err; 2252 int err;
@@ -2307,10 +2309,13 @@ static int snd_echo_resume(struct pci_dev *pci)
2307 return 0; 2309 return 0;
2308} 2310}
2309 2311
2312static SIMPLE_DEV_PM_OPS(snd_echo_pm, snd_echo_suspend, snd_echo_resume);
2313#define SND_ECHO_PM_OPS &snd_echo_pm
2314#else
2315#define SND_ECHO_PM_OPS NULL
2310#endif /* CONFIG_PM */ 2316#endif /* CONFIG_PM */
2311 2317
2312 2318
2313
2314static void __devexit snd_echo_remove(struct pci_dev *pci) 2319static void __devexit snd_echo_remove(struct pci_dev *pci)
2315{ 2320{
2316 struct echoaudio *chip; 2321 struct echoaudio *chip;
@@ -2333,10 +2338,9 @@ static struct pci_driver echo_driver = {
2333 .id_table = snd_echo_ids, 2338 .id_table = snd_echo_ids,
2334 .probe = snd_echo_probe, 2339 .probe = snd_echo_probe,
2335 .remove = __devexit_p(snd_echo_remove), 2340 .remove = __devexit_p(snd_echo_remove),
2336#ifdef CONFIG_PM 2341 .driver = {
2337 .suspend = snd_echo_suspend, 2342 .pm = SND_ECHO_PM_OPS,
2338 .resume = snd_echo_resume, 2343 },
2339#endif /* CONFIG_PM */
2340}; 2344};
2341 2345
2342module_pci_driver(echo_driver); 2346module_pci_driver(echo_driver);
diff --git a/sound/pci/emu10k1/emu10k1.c b/sound/pci/emu10k1/emu10k1.c
index 7fdbbe4d996..ddac4e6d660 100644
--- a/sound/pci/emu10k1/emu10k1.c
+++ b/sound/pci/emu10k1/emu10k1.c
@@ -207,9 +207,10 @@ static void __devexit snd_card_emu10k1_remove(struct pci_dev *pci)
207 207
208 208
209#ifdef CONFIG_PM 209#ifdef CONFIG_PM
210static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state) 210static int snd_emu10k1_suspend(struct device *dev)
211{ 211{
212 struct snd_card *card = pci_get_drvdata(pci); 212 struct pci_dev *pci = to_pci_dev(dev);
213 struct snd_card *card = dev_get_drvdata(dev);
213 struct snd_emu10k1 *emu = card->private_data; 214 struct snd_emu10k1 *emu = card->private_data;
214 215
215 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 216 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -231,13 +232,14 @@ static int snd_emu10k1_suspend(struct pci_dev *pci, pm_message_t state)
231 232
232 pci_disable_device(pci); 233 pci_disable_device(pci);
233 pci_save_state(pci); 234 pci_save_state(pci);
234 pci_set_power_state(pci, pci_choose_state(pci, state)); 235 pci_set_power_state(pci, PCI_D3hot);
235 return 0; 236 return 0;
236} 237}
237 238
238static int snd_emu10k1_resume(struct pci_dev *pci) 239static int snd_emu10k1_resume(struct device *dev)
239{ 240{
240 struct snd_card *card = pci_get_drvdata(pci); 241 struct pci_dev *pci = to_pci_dev(dev);
242 struct snd_card *card = dev_get_drvdata(dev);
241 struct snd_emu10k1 *emu = card->private_data; 243 struct snd_emu10k1 *emu = card->private_data;
242 244
243 pci_set_power_state(pci, PCI_D0); 245 pci_set_power_state(pci, PCI_D0);
@@ -261,17 +263,21 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
261 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 263 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
262 return 0; 264 return 0;
263} 265}
264#endif 266
267static SIMPLE_DEV_PM_OPS(snd_emu10k1_pm, snd_emu10k1_suspend, snd_emu10k1_resume);
268#define SND_EMU10K1_PM_OPS &snd_emu10k1_pm
269#else
270#define SND_EMU10K1_PM_OPS NULL
271#endif /* CONFIG_PM */
265 272
266static struct pci_driver emu10k1_driver = { 273static struct pci_driver emu10k1_driver = {
267 .name = KBUILD_MODNAME, 274 .name = KBUILD_MODNAME,
268 .id_table = snd_emu10k1_ids, 275 .id_table = snd_emu10k1_ids,
269 .probe = snd_card_emu10k1_probe, 276 .probe = snd_card_emu10k1_probe,
270 .remove = __devexit_p(snd_card_emu10k1_remove), 277 .remove = __devexit_p(snd_card_emu10k1_remove),
271#ifdef CONFIG_PM 278 .driver = {
272 .suspend = snd_emu10k1_suspend, 279 .pm = SND_EMU10K1_PM_OPS,
273 .resume = snd_emu10k1_resume, 280 },
274#endif
275}; 281};
276 282
277module_pci_driver(emu10k1_driver); 283module_pci_driver(emu10k1_driver);
diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c
index 3821c81d1c9..f7e6f73186e 100644
--- a/sound/pci/ens1370.c
+++ b/sound/pci/ens1370.c
@@ -2033,9 +2033,10 @@ static void snd_ensoniq_chip_init(struct ensoniq *ensoniq)
2033} 2033}
2034 2034
2035#ifdef CONFIG_PM 2035#ifdef CONFIG_PM
2036static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state) 2036static int snd_ensoniq_suspend(struct device *dev)
2037{ 2037{
2038 struct snd_card *card = pci_get_drvdata(pci); 2038 struct pci_dev *pci = to_pci_dev(dev);
2039 struct snd_card *card = dev_get_drvdata(dev);
2039 struct ensoniq *ensoniq = card->private_data; 2040 struct ensoniq *ensoniq = card->private_data;
2040 2041
2041 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2042 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -2058,13 +2059,14 @@ static int snd_ensoniq_suspend(struct pci_dev *pci, pm_message_t state)
2058 2059
2059 pci_disable_device(pci); 2060 pci_disable_device(pci);
2060 pci_save_state(pci); 2061 pci_save_state(pci);
2061 pci_set_power_state(pci, pci_choose_state(pci, state)); 2062 pci_set_power_state(pci, PCI_D3hot);
2062 return 0; 2063 return 0;
2063} 2064}
2064 2065
2065static int snd_ensoniq_resume(struct pci_dev *pci) 2066static int snd_ensoniq_resume(struct device *dev)
2066{ 2067{
2067 struct snd_card *card = pci_get_drvdata(pci); 2068 struct pci_dev *pci = to_pci_dev(dev);
2069 struct snd_card *card = dev_get_drvdata(dev);
2068 struct ensoniq *ensoniq = card->private_data; 2070 struct ensoniq *ensoniq = card->private_data;
2069 2071
2070 pci_set_power_state(pci, PCI_D0); 2072 pci_set_power_state(pci, PCI_D0);
@@ -2087,8 +2089,12 @@ static int snd_ensoniq_resume(struct pci_dev *pci)
2087 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2089 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2088 return 0; 2090 return 0;
2089} 2091}
2090#endif /* CONFIG_PM */
2091 2092
2093static SIMPLE_DEV_PM_OPS(snd_ensoniq_pm, snd_ensoniq_suspend, snd_ensoniq_resume);
2094#define SND_ENSONIQ_PM_OPS &snd_ensoniq_pm
2095#else
2096#define SND_ENSONIQ_PM_OPS NULL
2097#endif /* CONFIG_PM */
2092 2098
2093static int __devinit snd_ensoniq_create(struct snd_card *card, 2099static int __devinit snd_ensoniq_create(struct snd_card *card,
2094 struct pci_dev *pci, 2100 struct pci_dev *pci,
@@ -2493,10 +2499,9 @@ static struct pci_driver ens137x_driver = {
2493 .id_table = snd_audiopci_ids, 2499 .id_table = snd_audiopci_ids,
2494 .probe = snd_audiopci_probe, 2500 .probe = snd_audiopci_probe,
2495 .remove = __devexit_p(snd_audiopci_remove), 2501 .remove = __devexit_p(snd_audiopci_remove),
2496#ifdef CONFIG_PM 2502 .driver = {
2497 .suspend = snd_ensoniq_suspend, 2503 .pm = SND_ENSONIQ_PM_OPS,
2498 .resume = snd_ensoniq_resume, 2504 },
2499#endif
2500}; 2505};
2501 2506
2502module_pci_driver(ens137x_driver); 2507module_pci_driver(ens137x_driver);
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c
index 82c8d8c5c52..dbb81807bc1 100644
--- a/sound/pci/es1938.c
+++ b/sound/pci/es1938.c
@@ -1321,35 +1321,30 @@ static int snd_es1938_put_double(struct snd_kcontrol *kcontrol,
1321 return change; 1321 return change;
1322} 1322}
1323 1323
1324static unsigned int db_scale_master[] = { 1324static const DECLARE_TLV_DB_RANGE(db_scale_master,
1325 TLV_DB_RANGE_HEAD(2),
1326 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1), 1325 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1),
1327 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0), 1326 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0),
1328}; 1327);
1329 1328
1330static unsigned int db_scale_audio1[] = { 1329static const DECLARE_TLV_DB_RANGE(db_scale_audio1,
1331 TLV_DB_RANGE_HEAD(2),
1332 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1), 1330 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1),
1333 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0), 1331 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0),
1334}; 1332);
1335 1333
1336static unsigned int db_scale_audio2[] = { 1334static const DECLARE_TLV_DB_RANGE(db_scale_audio2,
1337 TLV_DB_RANGE_HEAD(2),
1338 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1), 1335 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1),
1339 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0), 1336 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0),
1340}; 1337);
1341 1338
1342static unsigned int db_scale_mic[] = { 1339static const DECLARE_TLV_DB_RANGE(db_scale_mic,
1343 TLV_DB_RANGE_HEAD(2),
1344 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1), 1340 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1),
1345 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0), 1341 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0),
1346}; 1342);
1347 1343
1348static unsigned int db_scale_line[] = { 1344static const DECLARE_TLV_DB_RANGE(db_scale_line,
1349 TLV_DB_RANGE_HEAD(2),
1350 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1), 1345 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1),
1351 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), 1346 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0),
1352}; 1347);
1353 1348
1354static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); 1349static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0);
1355 1350
@@ -1474,9 +1469,10 @@ static unsigned char saved_regs[SAVED_REG_SIZE+1] = {
1474}; 1469};
1475 1470
1476 1471
1477static int es1938_suspend(struct pci_dev *pci, pm_message_t state) 1472static int es1938_suspend(struct device *dev)
1478{ 1473{
1479 struct snd_card *card = pci_get_drvdata(pci); 1474 struct pci_dev *pci = to_pci_dev(dev);
1475 struct snd_card *card = dev_get_drvdata(dev);
1480 struct es1938 *chip = card->private_data; 1476 struct es1938 *chip = card->private_data;
1481 unsigned char *s, *d; 1477 unsigned char *s, *d;
1482 1478
@@ -1494,13 +1490,14 @@ static int es1938_suspend(struct pci_dev *pci, pm_message_t state)
1494 } 1490 }
1495 pci_disable_device(pci); 1491 pci_disable_device(pci);
1496 pci_save_state(pci); 1492 pci_save_state(pci);
1497 pci_set_power_state(pci, pci_choose_state(pci, state)); 1493 pci_set_power_state(pci, PCI_D3hot);
1498 return 0; 1494 return 0;
1499} 1495}
1500 1496
1501static int es1938_resume(struct pci_dev *pci) 1497static int es1938_resume(struct device *dev)
1502{ 1498{
1503 struct snd_card *card = pci_get_drvdata(pci); 1499 struct pci_dev *pci = to_pci_dev(dev);
1500 struct snd_card *card = dev_get_drvdata(dev);
1504 struct es1938 *chip = card->private_data; 1501 struct es1938 *chip = card->private_data;
1505 unsigned char *s, *d; 1502 unsigned char *s, *d;
1506 1503
@@ -1534,6 +1531,11 @@ static int es1938_resume(struct pci_dev *pci)
1534 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1531 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1535 return 0; 1532 return 0;
1536} 1533}
1534
1535static SIMPLE_DEV_PM_OPS(es1938_pm, es1938_suspend, es1938_resume);
1536#define ES1938_PM_OPS &es1938_pm
1537#else
1538#define ES1938_PM_OPS NULL
1537#endif /* CONFIG_PM */ 1539#endif /* CONFIG_PM */
1538 1540
1539#ifdef SUPPORT_JOYSTICK 1541#ifdef SUPPORT_JOYSTICK
@@ -1887,10 +1889,9 @@ static struct pci_driver es1938_driver = {
1887 .id_table = snd_es1938_ids, 1889 .id_table = snd_es1938_ids,
1888 .probe = snd_es1938_probe, 1890 .probe = snd_es1938_probe,
1889 .remove = __devexit_p(snd_es1938_remove), 1891 .remove = __devexit_p(snd_es1938_remove),
1890#ifdef CONFIG_PM 1892 .driver = {
1891 .suspend = es1938_suspend, 1893 .pm = ES1938_PM_OPS,
1892 .resume = es1938_resume, 1894 },
1893#endif
1894}; 1895};
1895 1896
1896module_pci_driver(es1938_driver); 1897module_pci_driver(es1938_driver);
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c
index 52b5c0bf90c..fb4c90b99c0 100644
--- a/sound/pci/es1968.c
+++ b/sound/pci/es1968.c
@@ -2381,9 +2381,10 @@ static void snd_es1968_start_irq(struct es1968 *chip)
2381/* 2381/*
2382 * PM support 2382 * PM support
2383 */ 2383 */
2384static int es1968_suspend(struct pci_dev *pci, pm_message_t state) 2384static int es1968_suspend(struct device *dev)
2385{ 2385{
2386 struct snd_card *card = pci_get_drvdata(pci); 2386 struct pci_dev *pci = to_pci_dev(dev);
2387 struct snd_card *card = dev_get_drvdata(dev);
2387 struct es1968 *chip = card->private_data; 2388 struct es1968 *chip = card->private_data;
2388 2389
2389 if (! chip->do_pm) 2390 if (! chip->do_pm)
@@ -2398,13 +2399,14 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
2398 2399
2399 pci_disable_device(pci); 2400 pci_disable_device(pci);
2400 pci_save_state(pci); 2401 pci_save_state(pci);
2401 pci_set_power_state(pci, pci_choose_state(pci, state)); 2402 pci_set_power_state(pci, PCI_D3hot);
2402 return 0; 2403 return 0;
2403} 2404}
2404 2405
2405static int es1968_resume(struct pci_dev *pci) 2406static int es1968_resume(struct device *dev)
2406{ 2407{
2407 struct snd_card *card = pci_get_drvdata(pci); 2408 struct pci_dev *pci = to_pci_dev(dev);
2409 struct snd_card *card = dev_get_drvdata(dev);
2408 struct es1968 *chip = card->private_data; 2410 struct es1968 *chip = card->private_data;
2409 struct esschan *es; 2411 struct esschan *es;
2410 2412
@@ -2454,6 +2456,11 @@ static int es1968_resume(struct pci_dev *pci)
2454 chip->in_suspend = 0; 2456 chip->in_suspend = 0;
2455 return 0; 2457 return 0;
2456} 2458}
2459
2460static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume);
2461#define ES1968_PM_OPS &es1968_pm
2462#else
2463#define ES1968_PM_OPS NULL
2457#endif /* CONFIG_PM */ 2464#endif /* CONFIG_PM */
2458 2465
2459#ifdef SUPPORT_JOYSTICK 2466#ifdef SUPPORT_JOYSTICK
@@ -2903,10 +2910,9 @@ static struct pci_driver es1968_driver = {
2903 .id_table = snd_es1968_ids, 2910 .id_table = snd_es1968_ids,
2904 .probe = snd_es1968_probe, 2911 .probe = snd_es1968_probe,
2905 .remove = __devexit_p(snd_es1968_remove), 2912 .remove = __devexit_p(snd_es1968_remove),
2906#ifdef CONFIG_PM 2913 .driver = {
2907 .suspend = es1968_suspend, 2914 .pm = ES1968_PM_OPS,
2908 .resume = es1968_resume, 2915 },
2909#endif
2910}; 2916};
2911 2917
2912module_pci_driver(es1968_driver); 2918module_pci_driver(es1968_driver);
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c
index b32e8024ea8..522c8706f24 100644
--- a/sound/pci/fm801.c
+++ b/sound/pci/fm801.c
@@ -1369,9 +1369,10 @@ static unsigned char saved_regs[] = {
1369 FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL, 1369 FM801_CODEC_CTRL, FM801_I2S_MODE, FM801_VOLUME, FM801_GEN_CTRL,
1370}; 1370};
1371 1371
1372static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state) 1372static int snd_fm801_suspend(struct device *dev)
1373{ 1373{
1374 struct snd_card *card = pci_get_drvdata(pci); 1374 struct pci_dev *pci = to_pci_dev(dev);
1375 struct snd_card *card = dev_get_drvdata(dev);
1375 struct fm801 *chip = card->private_data; 1376 struct fm801 *chip = card->private_data;
1376 int i; 1377 int i;
1377 1378
@@ -1385,13 +1386,14 @@ static int snd_fm801_suspend(struct pci_dev *pci, pm_message_t state)
1385 1386
1386 pci_disable_device(pci); 1387 pci_disable_device(pci);
1387 pci_save_state(pci); 1388 pci_save_state(pci);
1388 pci_set_power_state(pci, pci_choose_state(pci, state)); 1389 pci_set_power_state(pci, PCI_D3hot);
1389 return 0; 1390 return 0;
1390} 1391}
1391 1392
1392static int snd_fm801_resume(struct pci_dev *pci) 1393static int snd_fm801_resume(struct device *dev)
1393{ 1394{
1394 struct snd_card *card = pci_get_drvdata(pci); 1395 struct pci_dev *pci = to_pci_dev(dev);
1396 struct snd_card *card = dev_get_drvdata(dev);
1395 struct fm801 *chip = card->private_data; 1397 struct fm801 *chip = card->private_data;
1396 int i; 1398 int i;
1397 1399
@@ -1414,17 +1416,21 @@ static int snd_fm801_resume(struct pci_dev *pci)
1414 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1416 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1415 return 0; 1417 return 0;
1416} 1418}
1417#endif 1419
1420static SIMPLE_DEV_PM_OPS(snd_fm801_pm, snd_fm801_suspend, snd_fm801_resume);
1421#define SND_FM801_PM_OPS &snd_fm801_pm
1422#else
1423#define SND_FM801_PM_OPS NULL
1424#endif /* CONFIG_PM */
1418 1425
1419static struct pci_driver fm801_driver = { 1426static struct pci_driver fm801_driver = {
1420 .name = KBUILD_MODNAME, 1427 .name = KBUILD_MODNAME,
1421 .id_table = snd_fm801_ids, 1428 .id_table = snd_fm801_ids,
1422 .probe = snd_card_fm801_probe, 1429 .probe = snd_card_fm801_probe,
1423 .remove = __devexit_p(snd_card_fm801_remove), 1430 .remove = __devexit_p(snd_card_fm801_remove),
1424#ifdef CONFIG_PM 1431 .driver = {
1425 .suspend = snd_fm801_suspend, 1432 .pm = SND_FM801_PM_OPS,
1426 .resume = snd_fm801_resume, 1433 },
1427#endif
1428}; 1434};
1429 1435
1430module_pci_driver(fm801_driver); 1436module_pci_driver(fm801_driver);
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index d0307976418..194d625c1f8 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -53,15 +53,14 @@ config SND_HDA_INPUT_BEEP
53 driver. This interface is used to generate digital beeps. 53 driver. This interface is used to generate digital beeps.
54 54
55config SND_HDA_INPUT_BEEP_MODE 55config SND_HDA_INPUT_BEEP_MODE
56 int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)" 56 int "Digital beep registration mode (0=off, 1=on)"
57 depends on SND_HDA_INPUT_BEEP=y 57 depends on SND_HDA_INPUT_BEEP=y
58 default "1" 58 default "1"
59 range 0 2 59 range 0 1
60 help 60 help
61 Set 0 to disable the digital beep interface for HD-audio by default. 61 Set 0 to disable the digital beep interface for HD-audio by default.
62 Set 1 to always enable the digital beep interface for HD-audio by 62 Set 1 to always enable the digital beep interface for HD-audio by
63 default. Set 2 to control the beep device registration to input 63 default.
64 layer using a "Beep Switch" in mixer applications.
65 64
66config SND_HDA_INPUT_JACK 65config SND_HDA_INPUT_JACK
67 bool "Support jack plugging notification via input layer" 66 bool "Support jack plugging notification via input layer"
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
index f7520b9f909..647218d69f6 100644
--- a/sound/pci/hda/hda_auto_parser.c
+++ b/sound/pci/hda/hda_auto_parser.c
@@ -727,7 +727,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
727 models++; 727 models++;
728 } 728 }
729 } 729 }
730 if (id < 0) { 730 if (id < 0 && quirk) {
731 q = snd_pci_quirk_lookup(codec->bus->pci, quirk); 731 q = snd_pci_quirk_lookup(codec->bus->pci, quirk);
732 if (q) { 732 if (q) {
733 id = q->value; 733 id = q->value;
@@ -736,7 +736,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
736#endif 736#endif
737 } 737 }
738 } 738 }
739 if (id < 0) { 739 if (id < 0 && quirk) {
740 for (q = quirk; q->subvendor; q++) { 740 for (q = quirk; q->subvendor; q++) {
741 unsigned int vendorid = 741 unsigned int vendorid =
742 q->subdevice | (q->subvendor << 16); 742 q->subdevice | (q->subvendor << 16);
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index 60738e52b8f..0bc2315b181 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -162,50 +162,20 @@ static int snd_hda_do_attach(struct hda_beep *beep)
162 return 0; 162 return 0;
163} 163}
164 164
165static void snd_hda_do_register(struct work_struct *work)
166{
167 struct hda_beep *beep =
168 container_of(work, struct hda_beep, register_work);
169
170 mutex_lock(&beep->mutex);
171 if (beep->enabled && !beep->dev)
172 snd_hda_do_attach(beep);
173 mutex_unlock(&beep->mutex);
174}
175
176static void snd_hda_do_unregister(struct work_struct *work)
177{
178 struct hda_beep *beep =
179 container_of(work, struct hda_beep, unregister_work.work);
180
181 mutex_lock(&beep->mutex);
182 if (!beep->enabled && beep->dev)
183 snd_hda_do_detach(beep);
184 mutex_unlock(&beep->mutex);
185}
186
187int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) 165int snd_hda_enable_beep_device(struct hda_codec *codec, int enable)
188{ 166{
189 struct hda_beep *beep = codec->beep; 167 struct hda_beep *beep = codec->beep;
190 enable = !!enable; 168 if (!beep)
191 if (beep == NULL)
192 return 0; 169 return 0;
170 enable = !!enable;
193 if (beep->enabled != enable) { 171 if (beep->enabled != enable) {
194 beep->enabled = enable; 172 beep->enabled = enable;
195 if (!enable) { 173 if (!enable) {
174 cancel_work_sync(&beep->beep_work);
196 /* turn off beep */ 175 /* turn off beep */
197 snd_hda_codec_write(beep->codec, beep->nid, 0, 176 snd_hda_codec_write(beep->codec, beep->nid, 0,
198 AC_VERB_SET_BEEP_CONTROL, 0); 177 AC_VERB_SET_BEEP_CONTROL, 0);
199 } 178 }
200 if (beep->mode == HDA_BEEP_MODE_SWREG) {
201 if (enable) {
202 cancel_delayed_work(&beep->unregister_work);
203 schedule_work(&beep->register_work);
204 } else {
205 schedule_delayed_work(&beep->unregister_work,
206 HZ);
207 }
208 }
209 return 1; 179 return 1;
210 } 180 }
211 return 0; 181 return 0;
@@ -215,6 +185,7 @@ EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device);
215int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) 185int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
216{ 186{
217 struct hda_beep *beep; 187 struct hda_beep *beep;
188 int err;
218 189
219 if (!snd_hda_get_bool_hint(codec, "beep")) 190 if (!snd_hda_get_bool_hint(codec, "beep"))
220 return 0; /* disabled explicitly by hints */ 191 return 0; /* disabled explicitly by hints */
@@ -232,21 +203,16 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
232 203
233 beep->nid = nid; 204 beep->nid = nid;
234 beep->codec = codec; 205 beep->codec = codec;
235 beep->mode = codec->beep_mode;
236 codec->beep = beep; 206 codec->beep = beep;
237 207
238 INIT_WORK(&beep->register_work, &snd_hda_do_register);
239 INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister);
240 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); 208 INIT_WORK(&beep->beep_work, &snd_hda_generate_beep);
241 mutex_init(&beep->mutex); 209 mutex_init(&beep->mutex);
242 210
243 if (beep->mode == HDA_BEEP_MODE_ON) { 211 err = snd_hda_do_attach(beep);
244 int err = snd_hda_do_attach(beep); 212 if (err < 0) {
245 if (err < 0) { 213 kfree(beep);
246 kfree(beep); 214 codec->beep = NULL;
247 codec->beep = NULL; 215 return err;
248 return err;
249 }
250 } 216 }
251 217
252 return 0; 218 return 0;
@@ -257,8 +223,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
257{ 223{
258 struct hda_beep *beep = codec->beep; 224 struct hda_beep *beep = codec->beep;
259 if (beep) { 225 if (beep) {
260 cancel_work_sync(&beep->register_work);
261 cancel_delayed_work(&beep->unregister_work);
262 if (beep->dev) 226 if (beep->dev)
263 snd_hda_do_detach(beep); 227 snd_hda_do_detach(beep);
264 codec->beep = NULL; 228 codec->beep = NULL;
@@ -266,3 +230,31 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
266 } 230 }
267} 231}
268EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); 232EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device);
233
234/* get/put callbacks for beep mute mixer switches */
235int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
236 struct snd_ctl_elem_value *ucontrol)
237{
238 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
239 struct hda_beep *beep = codec->beep;
240 if (beep) {
241 ucontrol->value.integer.value[0] =
242 ucontrol->value.integer.value[1] =
243 beep->enabled;
244 return 0;
245 }
246 return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
247}
248EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep);
249
250int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
251 struct snd_ctl_elem_value *ucontrol)
252{
253 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
254 struct hda_beep *beep = codec->beep;
255 if (beep)
256 snd_hda_enable_beep_device(codec,
257 *ucontrol->value.integer.value);
258 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
259}
260EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h
index 55f0647458c..4dc6933bc65 100644
--- a/sound/pci/hda/hda_beep.h
+++ b/sound/pci/hda/hda_beep.h
@@ -26,21 +26,16 @@
26 26
27#define HDA_BEEP_MODE_OFF 0 27#define HDA_BEEP_MODE_OFF 0
28#define HDA_BEEP_MODE_ON 1 28#define HDA_BEEP_MODE_ON 1
29#define HDA_BEEP_MODE_SWREG 2
30 29
31/* beep information */ 30/* beep information */
32struct hda_beep { 31struct hda_beep {
33 struct input_dev *dev; 32 struct input_dev *dev;
34 struct hda_codec *codec; 33 struct hda_codec *codec;
35 unsigned int mode;
36 char phys[32]; 34 char phys[32];
37 int tone; 35 int tone;
38 hda_nid_t nid; 36 hda_nid_t nid;
39 unsigned int enabled:1; 37 unsigned int enabled:1;
40 unsigned int request_enable:1;
41 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ 38 unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */
42 struct work_struct register_work; /* registration work */
43 struct delayed_work unregister_work; /* unregistration work */
44 struct work_struct beep_work; /* scheduled task for beep event */ 39 struct work_struct beep_work; /* scheduled task for beep event */
45 struct mutex mutex; 40 struct mutex mutex;
46}; 41};
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 51cb2a2e4fc..88a9c20eb7a 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2676,25 +2676,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
2676} 2676}
2677EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); 2677EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
2678 2678
2679#ifdef CONFIG_SND_HDA_INPUT_BEEP
2680/**
2681 * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
2682 *
2683 * This function calls snd_hda_enable_beep_device(), which behaves differently
2684 * depending on beep_mode option.
2685 */
2686int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
2687 struct snd_ctl_elem_value *ucontrol)
2688{
2689 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2690 long *valp = ucontrol->value.integer.value;
2691
2692 snd_hda_enable_beep_device(codec, *valp);
2693 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2694}
2695EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
2696#endif /* CONFIG_SND_HDA_INPUT_BEEP */
2697
2698/* 2679/*
2699 * bound volume controls 2680 * bound volume controls
2700 * 2681 *
@@ -3509,22 +3490,52 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
3509EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); 3490EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all);
3510 3491
3511/* 3492/*
3493 * supported power states check
3494 */
3495static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg,
3496 unsigned int power_state)
3497{
3498 int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE);
3499
3500 if (sup < 0)
3501 return false;
3502 if (sup & power_state)
3503 return true;
3504 else
3505 return false;
3506}
3507
3508/*
3512 * set power state of the codec 3509 * set power state of the codec
3513 */ 3510 */
3514static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, 3511static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3515 unsigned int power_state) 3512 unsigned int power_state)
3516{ 3513{
3514 int count;
3515 unsigned int state;
3516
3517 if (codec->patch_ops.set_power_state) { 3517 if (codec->patch_ops.set_power_state) {
3518 codec->patch_ops.set_power_state(codec, fg, power_state); 3518 codec->patch_ops.set_power_state(codec, fg, power_state);
3519 return; 3519 return;
3520 } 3520 }
3521 3521
3522 /* this delay seems necessary to avoid click noise at power-down */ 3522 /* this delay seems necessary to avoid click noise at power-down */
3523 if (power_state == AC_PWRST_D3) 3523 if (power_state == AC_PWRST_D3) {
3524 msleep(100); 3524 /* transition time less than 10ms for power down */
3525 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, 3525 bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS);
3526 power_state); 3526 msleep(epss ? 10 : 100);
3527 snd_hda_codec_set_power_to_all(codec, fg, power_state, true); 3527 }
3528
3529 /* repeat power states setting at most 10 times*/
3530 for (count = 0; count < 10; count++) {
3531 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
3532 power_state);
3533 snd_hda_codec_set_power_to_all(codec, fg, power_state, true);
3534 state = snd_hda_codec_read(codec, fg, 0,
3535 AC_VERB_GET_POWER_STATE, 0);
3536 if (!(state & AC_PWRST_ERROR))
3537 break;
3538 }
3528} 3539}
3529 3540
3530#ifdef CONFIG_SND_HDA_HWDEP 3541#ifdef CONFIG_SND_HDA_HWDEP
@@ -3545,7 +3556,7 @@ static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
3545static void hda_call_codec_suspend(struct hda_codec *codec) 3556static void hda_call_codec_suspend(struct hda_codec *codec)
3546{ 3557{
3547 if (codec->patch_ops.suspend) 3558 if (codec->patch_ops.suspend)
3548 codec->patch_ops.suspend(codec, PMSG_SUSPEND); 3559 codec->patch_ops.suspend(codec);
3549 hda_cleanup_all_streams(codec); 3560 hda_cleanup_all_streams(codec);
3550 hda_set_power_state(codec, 3561 hda_set_power_state(codec,
3551 codec->afg ? codec->afg : codec->mfg, 3562 codec->afg ? codec->afg : codec->mfg,
@@ -4418,6 +4429,13 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down)
4418 cancel_delayed_work_sync(&codec->power_work); 4429 cancel_delayed_work_sync(&codec->power_work);
4419 4430
4420 spin_lock(&codec->power_lock); 4431 spin_lock(&codec->power_lock);
4432 /* If the power down delayed work was cancelled above before starting,
4433 * then there is no need to go through power up here.
4434 */
4435 if (codec->power_on) {
4436 spin_unlock(&codec->power_lock);
4437 return;
4438 }
4421 trace_hda_power_up(codec); 4439 trace_hda_power_up(codec);
4422 snd_hda_update_power_acct(codec); 4440 snd_hda_update_power_acct(codec);
4423 codec->power_on = 1; 4441 codec->power_on = 1;
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 2fdaadbb432..c422d330ca5 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -323,6 +323,9 @@ enum {
323#define AC_PWRST_D1 0x01 323#define AC_PWRST_D1 0x01
324#define AC_PWRST_D2 0x02 324#define AC_PWRST_D2 0x02
325#define AC_PWRST_D3 0x03 325#define AC_PWRST_D3 0x03
326#define AC_PWRST_ERROR (1<<8)
327#define AC_PWRST_CLK_STOP_OK (1<<9)
328#define AC_PWRST_SETTING_RESET (1<<10)
326 329
327/* Processing capabilies */ 330/* Processing capabilies */
328#define AC_PCAP_BENIGN (1<<0) 331#define AC_PCAP_BENIGN (1<<0)
@@ -703,7 +706,7 @@ struct hda_codec_ops {
703 void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg, 706 void (*set_power_state)(struct hda_codec *codec, hda_nid_t fg,
704 unsigned int power_state); 707 unsigned int power_state);
705#ifdef CONFIG_PM 708#ifdef CONFIG_PM
706 int (*suspend)(struct hda_codec *codec, pm_message_t state); 709 int (*suspend)(struct hda_codec *codec);
707 int (*resume)(struct hda_codec *codec); 710 int (*resume)(struct hda_codec *codec);
708#endif 711#endif
709#ifdef CONFIG_SND_HDA_POWER_SAVE 712#ifdef CONFIG_SND_HDA_POWER_SAVE
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 7757536b9d5..c8aced182fd 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -72,7 +72,7 @@ static int enable_msi = -1;
72static char *patch[SNDRV_CARDS]; 72static char *patch[SNDRV_CARDS];
73#endif 73#endif
74#ifdef CONFIG_SND_HDA_INPUT_BEEP 74#ifdef CONFIG_SND_HDA_INPUT_BEEP
75static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 75static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] =
76 CONFIG_SND_HDA_INPUT_BEEP_MODE}; 76 CONFIG_SND_HDA_INPUT_BEEP_MODE};
77#endif 77#endif
78 78
@@ -103,9 +103,9 @@ module_param_array(patch, charp, NULL, 0444);
103MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); 103MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface.");
104#endif 104#endif
105#ifdef CONFIG_SND_HDA_INPUT_BEEP 105#ifdef CONFIG_SND_HDA_INPUT_BEEP
106module_param_array(beep_mode, int, NULL, 0444); 106module_param_array(beep_mode, bool, NULL, 0444);
107MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " 107MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode "
108 "(0=off, 1=on, 2=mute switch on/off) (default=1)."); 108 "(0=off, 1=on) (default=1).");
109#endif 109#endif
110 110
111#ifdef CONFIG_SND_HDA_POWER_SAVE 111#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
151 "{Intel, CPT}," 151 "{Intel, CPT},"
152 "{Intel, PPT}," 152 "{Intel, PPT},"
153 "{Intel, LPT}," 153 "{Intel, LPT},"
154 "{Intel, HPT},"
154 "{Intel, PBG}," 155 "{Intel, PBG},"
155 "{Intel, SCH}," 156 "{Intel, SCH},"
156 "{ATI, SB450}," 157 "{ATI, SB450},"
@@ -535,6 +536,7 @@ enum {
535#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ 536#define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */
536#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ 537#define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */
537#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ 538#define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */
539#define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */
538 540
539/* quirks for ATI SB / AMD Hudson */ 541/* quirks for ATI SB / AMD Hudson */
540#define AZX_DCAPS_PRESET_ATI_SB \ 542#define AZX_DCAPS_PRESET_ATI_SB \
@@ -2403,9 +2405,10 @@ static void azx_power_notify(struct hda_bus *bus)
2403 * power management 2405 * power management
2404 */ 2406 */
2405 2407
2406static int azx_suspend(struct pci_dev *pci, pm_message_t state) 2408static int azx_suspend(struct device *dev)
2407{ 2409{
2408 struct snd_card *card = pci_get_drvdata(pci); 2410 struct pci_dev *pci = to_pci_dev(dev);
2411 struct snd_card *card = dev_get_drvdata(dev);
2409 struct azx *chip = card->private_data; 2412 struct azx *chip = card->private_data;
2410 struct azx_pcm *p; 2413 struct azx_pcm *p;
2411 2414
@@ -2424,13 +2427,14 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state)
2424 pci_disable_msi(chip->pci); 2427 pci_disable_msi(chip->pci);
2425 pci_disable_device(pci); 2428 pci_disable_device(pci);
2426 pci_save_state(pci); 2429 pci_save_state(pci);
2427 pci_set_power_state(pci, pci_choose_state(pci, state)); 2430 pci_set_power_state(pci, PCI_D3hot);
2428 return 0; 2431 return 0;
2429} 2432}
2430 2433
2431static int azx_resume(struct pci_dev *pci) 2434static int azx_resume(struct device *dev)
2432{ 2435{
2433 struct snd_card *card = pci_get_drvdata(pci); 2436 struct pci_dev *pci = to_pci_dev(dev);
2437 struct snd_card *card = dev_get_drvdata(dev);
2434 struct azx *chip = card->private_data; 2438 struct azx *chip = card->private_data;
2435 2439
2436 pci_set_power_state(pci, PCI_D0); 2440 pci_set_power_state(pci, PCI_D0);
@@ -2455,6 +2459,12 @@ static int azx_resume(struct pci_dev *pci)
2455 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2459 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2456 return 0; 2460 return 0;
2457} 2461}
2462static SIMPLE_DEV_PM_OPS(azx_pm, azx_suspend, azx_resume);
2463#define AZX_PM_OPS &azx_pm
2464#else
2465#define azx_suspend(dev)
2466#define azx_resume(dev)
2467#define AZX_PM_OPS NULL
2458#endif /* CONFIG_PM */ 2468#endif /* CONFIG_PM */
2459 2469
2460 2470
@@ -2521,13 +2531,13 @@ static void azx_vs_set_state(struct pci_dev *pci,
2521 disabled ? "Disabling" : "Enabling", 2531 disabled ? "Disabling" : "Enabling",
2522 pci_name(chip->pci)); 2532 pci_name(chip->pci));
2523 if (disabled) { 2533 if (disabled) {
2524 azx_suspend(pci, PMSG_FREEZE); 2534 azx_suspend(&pci->dev);
2525 chip->disabled = true; 2535 chip->disabled = true;
2526 snd_hda_lock_devices(chip->bus); 2536 snd_hda_lock_devices(chip->bus);
2527 } else { 2537 } else {
2528 snd_hda_unlock_devices(chip->bus); 2538 snd_hda_unlock_devices(chip->bus);
2529 chip->disabled = false; 2539 chip->disabled = false;
2530 azx_resume(pci); 2540 azx_resume(&pci->dev);
2531 } 2541 }
2532 } 2542 }
2533} 2543}
@@ -2731,6 +2741,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix)
2731 snd_printd(SFX "Using LPIB position fix\n"); 2741 snd_printd(SFX "Using LPIB position fix\n");
2732 return POS_FIX_LPIB; 2742 return POS_FIX_LPIB;
2733 } 2743 }
2744 if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) {
2745 snd_printd(SFX "Using COMBO position fix\n");
2746 return POS_FIX_COMBO;
2747 }
2734 return POS_FIX_AUTO; 2748 return POS_FIX_AUTO;
2735} 2749}
2736 2750
@@ -3243,7 +3257,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3243 /* CPT */ 3257 /* CPT */
3244 { PCI_DEVICE(0x8086, 0x1c20), 3258 { PCI_DEVICE(0x8086, 0x1c20),
3245 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3259 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3246 AZX_DCAPS_BUFSIZE }, 3260 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3247 /* PBG */ 3261 /* PBG */
3248 { PCI_DEVICE(0x8086, 0x1d20), 3262 { PCI_DEVICE(0x8086, 0x1d20),
3249 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3263 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
@@ -3251,11 +3265,15 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3251 /* Panther Point */ 3265 /* Panther Point */
3252 { PCI_DEVICE(0x8086, 0x1e20), 3266 { PCI_DEVICE(0x8086, 0x1e20),
3253 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3267 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3254 AZX_DCAPS_BUFSIZE}, 3268 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3255 /* Lynx Point */ 3269 /* Lynx Point */
3256 { PCI_DEVICE(0x8086, 0x8c20), 3270 { PCI_DEVICE(0x8086, 0x8c20),
3257 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | 3271 .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP |
3258 AZX_DCAPS_BUFSIZE}, 3272 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3273 /* Haswell */
3274 { PCI_DEVICE(0x8086, 0x0c0c),
3275 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
3276 AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO },
3259 /* SCH */ 3277 /* SCH */
3260 { PCI_DEVICE(0x8086, 0x811b), 3278 { PCI_DEVICE(0x8086, 0x811b),
3261 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | 3279 .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP |
@@ -3341,6 +3359,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
3341 /* VIA VT8251/VT8237A */ 3359 /* VIA VT8251/VT8237A */
3342 { PCI_DEVICE(0x1106, 0x3288), 3360 { PCI_DEVICE(0x1106, 0x3288),
3343 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, 3361 .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA },
3362 /* VIA GFX VT7122/VX900 */
3363 { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC },
3364 /* VIA GFX VT6122/VX11 */
3365 { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC },
3344 /* SIS966 */ 3366 /* SIS966 */
3345 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, 3367 { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS },
3346 /* ULI M5461 */ 3368 /* ULI M5461 */
@@ -3398,10 +3420,9 @@ static struct pci_driver azx_driver = {
3398 .id_table = azx_ids, 3420 .id_table = azx_ids,
3399 .probe = azx_probe, 3421 .probe = azx_probe,
3400 .remove = __devexit_p(azx_remove), 3422 .remove = __devexit_p(azx_remove),
3401#ifdef CONFIG_PM 3423 .driver = {
3402 .suspend = azx_suspend, 3424 .pm = AZX_PM_OPS,
3403 .resume = azx_resume, 3425 },
3404#endif
3405}; 3426};
3406 3427
3407module_pci_driver(azx_driver); 3428module_pci_driver(azx_driver);
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 2dd1c113a4c..aaccc0236bd 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
127static void jack_detect_update(struct hda_codec *codec, 127static void jack_detect_update(struct hda_codec *codec,
128 struct hda_jack_tbl *jack) 128 struct hda_jack_tbl *jack)
129{ 129{
130 if (jack->jack_dirty || !jack->jack_detect) { 130 if (!jack->jack_dirty)
131 return;
132
133 if (jack->phantom_jack)
134 jack->pin_sense = AC_PINSENSE_PRESENCE;
135 else
131 jack->pin_sense = read_pin_sense(codec, jack->nid); 136 jack->pin_sense = read_pin_sense(codec, jack->nid);
132 jack->jack_dirty = 0; 137
133 } 138 jack->jack_dirty = 0;
134} 139}
135 140
136/** 141/**
@@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack)
264 * This assigns a jack-detection kctl to the given pin. The kcontrol 269 * This assigns a jack-detection kctl to the given pin. The kcontrol
265 * will have the given name and index. 270 * will have the given name and index.
266 */ 271 */
267int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, 272static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
268 const char *name, int idx) 273 const char *name, int idx, bool phantom_jack)
269{ 274{
270 struct hda_jack_tbl *jack; 275 struct hda_jack_tbl *jack;
271 struct snd_kcontrol *kctl; 276 struct snd_kcontrol *kctl;
@@ -283,47 +288,81 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
283 if (err < 0) 288 if (err < 0)
284 return err; 289 return err;
285 jack->kctl = kctl; 290 jack->kctl = kctl;
291 jack->phantom_jack = !!phantom_jack;
292
286 state = snd_hda_jack_detect(codec, nid); 293 state = snd_hda_jack_detect(codec, nid);
287 snd_kctl_jack_report(codec->bus->card, kctl, state); 294 snd_kctl_jack_report(codec->bus->card, kctl, state);
288#ifdef CONFIG_SND_HDA_INPUT_JACK 295#ifdef CONFIG_SND_HDA_INPUT_JACK
289 jack->type = get_input_jack_type(codec, nid); 296 if (!phantom_jack) {
290 err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); 297 jack->type = get_input_jack_type(codec, nid);
291 if (err < 0) 298 err = snd_jack_new(codec->bus->card, name, jack->type,
292 return err; 299 &jack->jack);
293 jack->jack->private_data = jack; 300 if (err < 0)
294 jack->jack->private_free = hda_free_jack_priv; 301 return err;
295 snd_jack_report(jack->jack, state ? jack->type : 0); 302 jack->jack->private_data = jack;
303 jack->jack->private_free = hda_free_jack_priv;
304 snd_jack_report(jack->jack, state ? jack->type : 0);
305 }
296#endif 306#endif
297 return 0; 307 return 0;
298} 308}
309
310int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
311 const char *name, int idx)
312{
313 return __snd_hda_jack_add_kctl(codec, nid, name, idx, false);
314}
299EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); 315EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl);
300 316
317/* get the unique index number for the given kctl name */
318static int get_unique_index(struct hda_codec *codec, const char *name, int idx)
319{
320 struct hda_jack_tbl *jack;
321 int i, len = strlen(name);
322 again:
323 jack = codec->jacktbl.list;
324 for (i = 0; i < codec->jacktbl.used; i++, jack++) {
325 /* jack->kctl.id contains "XXX Jack" name string with index */
326 if (jack->kctl &&
327 !strncmp(name, jack->kctl->id.name, len) &&
328 !strcmp(" Jack", jack->kctl->id.name + len) &&
329 jack->kctl->id.index == idx) {
330 idx++;
331 goto again;
332 }
333 }
334 return idx;
335}
336
301static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, 337static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid,
302 const struct auto_pin_cfg *cfg, 338 const struct auto_pin_cfg *cfg)
303 char *lastname, int *lastidx)
304{ 339{
305 unsigned int def_conf, conn; 340 unsigned int def_conf, conn;
306 char name[44]; 341 char name[44];
307 int idx, err; 342 int idx, err;
343 bool phantom_jack;
308 344
309 if (!nid) 345 if (!nid)
310 return 0; 346 return 0;
311 if (!is_jack_detectable(codec, nid))
312 return 0;
313 def_conf = snd_hda_codec_get_pincfg(codec, nid); 347 def_conf = snd_hda_codec_get_pincfg(codec, nid);
314 conn = get_defcfg_connect(def_conf); 348 conn = get_defcfg_connect(def_conf);
315 if (conn != AC_JACK_PORT_COMPLEX) 349 if (conn == AC_JACK_PORT_NONE)
316 return 0; 350 return 0;
351 phantom_jack = (conn != AC_JACK_PORT_COMPLEX) ||
352 !is_jack_detectable(codec, nid);
317 353
318 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); 354 snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx);
319 if (!strcmp(name, lastname) && idx == *lastidx) 355 if (phantom_jack)
320 idx++; 356 /* Example final name: "Internal Mic Phantom Jack" */
321 strncpy(lastname, name, 44); 357 strncat(name, " Phantom", sizeof(name) - strlen(name) - 1);
322 *lastidx = idx; 358 idx = get_unique_index(codec, name, idx);
323 err = snd_hda_jack_add_kctl(codec, nid, name, idx); 359 err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack);
324 if (err < 0) 360 if (err < 0)
325 return err; 361 return err;
326 return snd_hda_jack_detect_enable(codec, nid, 0); 362
363 if (!phantom_jack)
364 return snd_hda_jack_detect_enable(codec, nid, 0);
365 return 0;
327} 366}
328 367
329/** 368/**
@@ -333,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec,
333 const struct auto_pin_cfg *cfg) 372 const struct auto_pin_cfg *cfg)
334{ 373{
335 const hda_nid_t *p; 374 const hda_nid_t *p;
336 int i, err, lastidx = 0; 375 int i, err;
337 char lastname[44] = "";
338 376
339 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { 377 for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) {
340 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 378 err = add_jack_kctl(codec, *p, cfg);
341 if (err < 0) 379 if (err < 0)
342 return err; 380 return err;
343 } 381 }
344 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { 382 for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) {
345 if (*p == *cfg->line_out_pins) /* might be duplicated */ 383 if (*p == *cfg->line_out_pins) /* might be duplicated */
346 break; 384 break;
347 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 385 err = add_jack_kctl(codec, *p, cfg);
348 if (err < 0) 386 if (err < 0)
349 return err; 387 return err;
350 } 388 }
351 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { 389 for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) {
352 if (*p == *cfg->line_out_pins) /* might be duplicated */ 390 if (*p == *cfg->line_out_pins) /* might be duplicated */
353 break; 391 break;
354 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 392 err = add_jack_kctl(codec, *p, cfg);
355 if (err < 0) 393 if (err < 0)
356 return err; 394 return err;
357 } 395 }
358 for (i = 0; i < cfg->num_inputs; i++) { 396 for (i = 0; i < cfg->num_inputs; i++) {
359 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); 397 err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg);
360 if (err < 0) 398 if (err < 0)
361 return err; 399 return err;
362 } 400 }
363 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { 401 for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) {
364 err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); 402 err = add_jack_kctl(codec, *p, cfg);
365 if (err < 0) 403 if (err < 0)
366 return err; 404 return err;
367 } 405 }
368 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); 406 err = add_jack_kctl(codec, cfg->dig_in_pin, cfg);
369 if (err < 0) 407 if (err < 0)
370 return err; 408 return err;
371 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); 409 err = add_jack_kctl(codec, cfg->mono_out_pin, cfg);
372 if (err < 0) 410 if (err < 0)
373 return err; 411 return err;
374 return 0; 412 return 0;
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index 8ae52465ec5..a9803da633c 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -23,6 +23,7 @@ struct hda_jack_tbl {
23 unsigned int pin_sense; /* cached pin-sense value */ 23 unsigned int pin_sense; /* cached pin-sense value */
24 unsigned int jack_detect:1; /* capable of jack-detection? */ 24 unsigned int jack_detect:1; /* capable of jack-detection? */
25 unsigned int jack_dirty:1; /* needs to update? */ 25 unsigned int jack_dirty:1; /* needs to update? */
26 unsigned int phantom_jack:1; /* a fixed, always present port? */
26 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ 27 struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */
27#ifdef CONFIG_SND_HDA_INPUT_JACK 28#ifdef CONFIG_SND_HDA_INPUT_JACK
28 int type; 29 int type;
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h
index 9a096a8e0fc..1b4c12941ba 100644
--- a/sound/pci/hda/hda_local.h
+++ b/sound/pci/hda/hda_local.h
@@ -89,7 +89,7 @@
89 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ 89 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
90 .subdevice = HDA_SUBDEV_AMP_FLAG, \ 90 .subdevice = HDA_SUBDEV_AMP_FLAG, \
91 .info = snd_hda_mixer_amp_switch_info, \ 91 .info = snd_hda_mixer_amp_switch_info, \
92 .get = snd_hda_mixer_amp_switch_get, \ 92 .get = snd_hda_mixer_amp_switch_get_beep, \
93 .put = snd_hda_mixer_amp_switch_put_beep, \ 93 .put = snd_hda_mixer_amp_switch_put_beep, \
94 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } 94 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
95#else 95#else
@@ -121,6 +121,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
121int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, 121int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
122 struct snd_ctl_elem_value *ucontrol); 122 struct snd_ctl_elem_value *ucontrol);
123#ifdef CONFIG_SND_HDA_INPUT_BEEP 123#ifdef CONFIG_SND_HDA_INPUT_BEEP
124int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol,
125 struct snd_ctl_elem_value *ucontrol);
124int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, 126int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
125 struct snd_ctl_elem_value *ucontrol); 127 struct snd_ctl_elem_value *ucontrol);
126#endif 128#endif
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index e59e2f059b6..7e46258fc70 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -426,10 +426,10 @@ static void print_digital_conv(struct snd_info_buffer *buffer,
426 426
427static const char *get_pwr_state(u32 state) 427static const char *get_pwr_state(u32 state)
428{ 428{
429 static const char * const buf[4] = { 429 static const char * const buf[] = {
430 "D0", "D1", "D2", "D3" 430 "D0", "D1", "D2", "D3", "D3cold"
431 }; 431 };
432 if (state < 4) 432 if (state < ARRAY_SIZE(buf))
433 return buf[state]; 433 return buf[state];
434 return "UNKNOWN"; 434 return "UNKNOWN";
435} 435}
@@ -451,14 +451,21 @@ static void print_power_state(struct snd_info_buffer *buffer,
451 int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); 451 int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE);
452 int pwr = snd_hda_codec_read(codec, nid, 0, 452 int pwr = snd_hda_codec_read(codec, nid, 0,
453 AC_VERB_GET_POWER_STATE, 0); 453 AC_VERB_GET_POWER_STATE, 0);
454 if (sup) 454 if (sup != -1)
455 snd_iprintf(buffer, " Power states: %s\n", 455 snd_iprintf(buffer, " Power states: %s\n",
456 bits_names(sup, names, ARRAY_SIZE(names))); 456 bits_names(sup, names, ARRAY_SIZE(names)));
457 457
458 snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", 458 snd_iprintf(buffer, " Power: setting=%s, actual=%s",
459 get_pwr_state(pwr & AC_PWRST_SETTING), 459 get_pwr_state(pwr & AC_PWRST_SETTING),
460 get_pwr_state((pwr & AC_PWRST_ACTUAL) >> 460 get_pwr_state((pwr & AC_PWRST_ACTUAL) >>
461 AC_PWRST_ACTUAL_SHIFT)); 461 AC_PWRST_ACTUAL_SHIFT));
462 if (pwr & AC_PWRST_ERROR)
463 snd_iprintf(buffer, ", Error");
464 if (pwr & AC_PWRST_CLK_STOP_OK)
465 snd_iprintf(buffer, ", Clock-stop-OK");
466 if (pwr & AC_PWRST_SETTING_RESET)
467 snd_iprintf(buffer, ", Setting-reset");
468 snd_iprintf(buffer, "\n");
462} 469}
463 470
464static void print_unsol_cap(struct snd_info_buffer *buffer, 471static void print_unsol_cap(struct snd_info_buffer *buffer,
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d8b2d6dee98..0208fa121e5 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -642,7 +642,7 @@ static void ad198x_free(struct hda_codec *codec)
642} 642}
643 643
644#ifdef CONFIG_PM 644#ifdef CONFIG_PM
645static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) 645static int ad198x_suspend(struct hda_codec *codec)
646{ 646{
647 ad198x_shutup(codec); 647 ad198x_shutup(codec);
648 return 0; 648 return 0;
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c
index 9647ed4d792..0c4c1a61b37 100644
--- a/sound/pci/hda/patch_cirrus.c
+++ b/sound/pci/hda/patch_cirrus.c
@@ -1892,7 +1892,7 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
1892 Manage PDREF, when transitioning to D3hot 1892 Manage PDREF, when transitioning to D3hot
1893 (DAC,ADC) -> D3, PDREF=1, AFG->D3 1893 (DAC,ADC) -> D3, PDREF=1, AFG->D3
1894*/ 1894*/
1895static int cs421x_suspend(struct hda_codec *codec, pm_message_t state) 1895static int cs421x_suspend(struct hda_codec *codec)
1896{ 1896{
1897 struct cs_spec *spec = codec->spec; 1897 struct cs_spec *spec = codec->spec;
1898 unsigned int coef; 1898 unsigned int coef;
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 2bf99fc1cbf..14361184ae1 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -554,7 +554,7 @@ static int conexant_build_controls(struct hda_codec *codec)
554} 554}
555 555
556#ifdef CONFIG_SND_HDA_POWER_SAVE 556#ifdef CONFIG_SND_HDA_POWER_SAVE
557static int conexant_suspend(struct hda_codec *codec, pm_message_t state) 557static int conexant_suspend(struct hda_codec *codec)
558{ 558{
559 snd_hda_shutup_pins(codec); 559 snd_hda_shutup_pins(codec);
560 return 0; 560 return 0;
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index ad319d4dc32..641408dc28c 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -85,7 +85,7 @@ struct hdmi_spec {
85 * Non-generic ATI/NVIDIA specific 85 * Non-generic ATI/NVIDIA specific
86 */ 86 */
87 struct hda_multi_out multiout; 87 struct hda_multi_out multiout;
88 const struct hda_pcm_stream *pcm_playback; 88 struct hda_pcm_stream pcm_playback;
89}; 89};
90 90
91 91
@@ -787,7 +787,7 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res)
787 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); 787 int cp_ready = !!(res & AC_UNSOL_RES_CP_READY);
788 788
789 printk(KERN_INFO 789 printk(KERN_INFO
790 "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", 790 "HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n",
791 codec->addr, 791 codec->addr,
792 tag, 792 tag,
793 subtag, 793 subtag,
@@ -876,7 +876,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
876 struct hdmi_spec_per_pin *per_pin; 876 struct hdmi_spec_per_pin *per_pin;
877 struct hdmi_eld *eld; 877 struct hdmi_eld *eld;
878 struct hdmi_spec_per_cvt *per_cvt = NULL; 878 struct hdmi_spec_per_cvt *per_cvt = NULL;
879 int pinctl;
880 879
881 /* Validate hinfo */ 880 /* Validate hinfo */
882 pin_idx = hinfo_to_pin_index(spec, hinfo); 881 pin_idx = hinfo_to_pin_index(spec, hinfo);
@@ -912,11 +911,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
912 snd_hda_codec_write(codec, per_pin->pin_nid, 0, 911 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
913 AC_VERB_SET_CONNECT_SEL, 912 AC_VERB_SET_CONNECT_SEL,
914 mux_idx); 913 mux_idx);
915 pinctl = snd_hda_codec_read(codec, per_pin->pin_nid, 0,
916 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
917 snd_hda_codec_write(codec, per_pin->pin_nid, 0,
918 AC_VERB_SET_PIN_WIDGET_CONTROL,
919 pinctl | PIN_OUT);
920 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid); 914 snd_hda_spdif_ctls_assign(codec, pin_idx, per_cvt->cvt_nid);
921 915
922 /* Initially set the converter's capabilities */ 916 /* Initially set the converter's capabilities */
@@ -1153,11 +1147,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1153 struct hdmi_spec *spec = codec->spec; 1147 struct hdmi_spec *spec = codec->spec;
1154 int pin_idx = hinfo_to_pin_index(spec, hinfo); 1148 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1155 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; 1149 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid;
1150 int pinctl;
1156 1151
1157 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); 1152 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1158 1153
1159 hdmi_setup_audio_infoframe(codec, pin_idx, substream); 1154 hdmi_setup_audio_infoframe(codec, pin_idx, substream);
1160 1155
1156 pinctl = snd_hda_codec_read(codec, pin_nid, 0,
1157 AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
1158 snd_hda_codec_write(codec, pin_nid, 0,
1159 AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl | PIN_OUT);
1160
1161 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); 1161 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1162} 1162}
1163 1163
@@ -1277,23 +1277,34 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1277 return 0; 1277 return 0;
1278} 1278}
1279 1279
1280static int generic_hdmi_init(struct hda_codec *codec) 1280static int generic_hdmi_init_per_pins(struct hda_codec *codec)
1281{ 1281{
1282 struct hdmi_spec *spec = codec->spec; 1282 struct hdmi_spec *spec = codec->spec;
1283 int pin_idx; 1283 int pin_idx;
1284 1284
1285 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1285 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1286 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1286 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1287 hda_nid_t pin_nid = per_pin->pin_nid;
1288 struct hdmi_eld *eld = &per_pin->sink_eld; 1287 struct hdmi_eld *eld = &per_pin->sink_eld;
1289 1288
1290 hdmi_init_pin(codec, pin_nid);
1291 snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
1292
1293 per_pin->codec = codec; 1289 per_pin->codec = codec;
1294 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); 1290 INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld);
1295 snd_hda_eld_proc_new(codec, eld, pin_idx); 1291 snd_hda_eld_proc_new(codec, eld, pin_idx);
1296 } 1292 }
1293 return 0;
1294}
1295
1296static int generic_hdmi_init(struct hda_codec *codec)
1297{
1298 struct hdmi_spec *spec = codec->spec;
1299 int pin_idx;
1300
1301 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1302 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx];
1303 hda_nid_t pin_nid = per_pin->pin_nid;
1304
1305 hdmi_init_pin(codec, pin_nid);
1306 snd_hda_jack_detect_enable(codec, pin_nid, pin_nid);
1307 }
1297 snd_hda_jack_report_sync(codec); 1308 snd_hda_jack_report_sync(codec);
1298 return 0; 1309 return 0;
1299} 1310}
@@ -1338,6 +1349,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1338 return -EINVAL; 1349 return -EINVAL;
1339 } 1350 }
1340 codec->patch_ops = generic_hdmi_patch_ops; 1351 codec->patch_ops = generic_hdmi_patch_ops;
1352 generic_hdmi_init_per_pins(codec);
1341 1353
1342 init_channel_allocations(); 1354 init_channel_allocations();
1343 1355
@@ -1352,45 +1364,65 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
1352{ 1364{
1353 struct hdmi_spec *spec = codec->spec; 1365 struct hdmi_spec *spec = codec->spec;
1354 struct hda_pcm *info = spec->pcm_rec; 1366 struct hda_pcm *info = spec->pcm_rec;
1355 int i; 1367 unsigned int chans;
1368 struct hda_pcm_stream *pstr;
1356 1369
1357 codec->num_pcms = spec->num_cvts; 1370 codec->num_pcms = 1;
1358 codec->pcm_info = info; 1371 codec->pcm_info = info;
1359 1372
1360 for (i = 0; i < codec->num_pcms; i++, info++) { 1373 chans = get_wcaps(codec, spec->cvts[0].cvt_nid);
1361 unsigned int chans; 1374 chans = get_wcaps_channels(chans);
1362 struct hda_pcm_stream *pstr;
1363
1364 chans = get_wcaps(codec, spec->cvts[i].cvt_nid);
1365 chans = get_wcaps_channels(chans);
1366 1375
1367 info->name = get_hdmi_pcm_name(i); 1376 info->name = get_hdmi_pcm_name(0);
1368 info->pcm_type = HDA_PCM_TYPE_HDMI; 1377 info->pcm_type = HDA_PCM_TYPE_HDMI;
1369 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1378 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1370 snd_BUG_ON(!spec->pcm_playback); 1379 *pstr = spec->pcm_playback;
1371 *pstr = *spec->pcm_playback; 1380 pstr->nid = spec->cvts[0].cvt_nid;
1372 pstr->nid = spec->cvts[i].cvt_nid; 1381 if (pstr->channels_max <= 2 && chans && chans <= 16)
1373 if (pstr->channels_max <= 2 && chans && chans <= 16) 1382 pstr->channels_max = chans;
1374 pstr->channels_max = chans;
1375 }
1376 1383
1377 return 0; 1384 return 0;
1378} 1385}
1379 1386
1387/* unsolicited event for jack sensing */
1388static void simple_hdmi_unsol_event(struct hda_codec *codec,
1389 unsigned int res)
1390{
1391 snd_hda_jack_set_dirty_all(codec);
1392 snd_hda_jack_report_sync(codec);
1393}
1394
1395/* generic_hdmi_build_jack can be used for simple_hdmi, too,
1396 * as long as spec->pins[] is set correctly
1397 */
1398#define simple_hdmi_build_jack generic_hdmi_build_jack
1399
1380static int simple_playback_build_controls(struct hda_codec *codec) 1400static int simple_playback_build_controls(struct hda_codec *codec)
1381{ 1401{
1382 struct hdmi_spec *spec = codec->spec; 1402 struct hdmi_spec *spec = codec->spec;
1383 int err; 1403 int err;
1384 int i;
1385 1404
1386 for (i = 0; i < codec->num_pcms; i++) { 1405 err = snd_hda_create_spdif_out_ctls(codec,
1387 err = snd_hda_create_spdif_out_ctls(codec, 1406 spec->cvts[0].cvt_nid,
1388 spec->cvts[i].cvt_nid, 1407 spec->cvts[0].cvt_nid);
1389 spec->cvts[i].cvt_nid); 1408 if (err < 0)
1390 if (err < 0) 1409 return err;
1391 return err; 1410 return simple_hdmi_build_jack(codec, 0);
1392 } 1411}
1393 1412
1413static int simple_playback_init(struct hda_codec *codec)
1414{
1415 struct hdmi_spec *spec = codec->spec;
1416 hda_nid_t pin = spec->pins[0].pin_nid;
1417
1418 snd_hda_codec_write(codec, pin, 0,
1419 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
1420 /* some codecs require to unmute the pin */
1421 if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)
1422 snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1423 AMP_OUT_UNMUTE);
1424 snd_hda_jack_detect_enable(codec, pin, pin);
1425 snd_hda_jack_report_sync(codec);
1394 return 0; 1426 return 0;
1395} 1427}
1396 1428
@@ -1418,7 +1450,15 @@ static const hda_nid_t nvhdmi_con_nids_7x[4] = {
1418 0x6, 0x8, 0xa, 0xc, 1450 0x6, 0x8, 0xa, 0xc,
1419}; 1451};
1420 1452
1421static const struct hda_verb nvhdmi_basic_init_7x[] = { 1453static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = {
1454 /* set audio protect on */
1455 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1456 /* enable digital output on pin widget */
1457 { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 },
1458 {} /* terminator */
1459};
1460
1461static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = {
1422 /* set audio protect on */ 1462 /* set audio protect on */
1423 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, 1463 { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1},
1424 /* enable digital output on pin widget */ 1464 /* enable digital output on pin widget */
@@ -1446,9 +1486,15 @@ static const struct hda_verb nvhdmi_basic_init_7x[] = {
1446 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) 1486 (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE)
1447#endif 1487#endif
1448 1488
1449static int nvhdmi_7x_init(struct hda_codec *codec) 1489static int nvhdmi_7x_init_2ch(struct hda_codec *codec)
1450{ 1490{
1451 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x); 1491 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch);
1492 return 0;
1493}
1494
1495static int nvhdmi_7x_init_8ch(struct hda_codec *codec)
1496{
1497 snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch);
1452 return 0; 1498 return 0;
1453} 1499}
1454 1500
@@ -1524,6 +1570,50 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1524 stream_tag, format, substream); 1570 stream_tag, format, substream);
1525} 1571}
1526 1572
1573static const struct hda_pcm_stream simple_pcm_playback = {
1574 .substreams = 1,
1575 .channels_min = 2,
1576 .channels_max = 2,
1577 .ops = {
1578 .open = simple_playback_pcm_open,
1579 .close = simple_playback_pcm_close,
1580 .prepare = simple_playback_pcm_prepare
1581 },
1582};
1583
1584static const struct hda_codec_ops simple_hdmi_patch_ops = {
1585 .build_controls = simple_playback_build_controls,
1586 .build_pcms = simple_playback_build_pcms,
1587 .init = simple_playback_init,
1588 .free = simple_playback_free,
1589 .unsol_event = simple_hdmi_unsol_event,
1590};
1591
1592static int patch_simple_hdmi(struct hda_codec *codec,
1593 hda_nid_t cvt_nid, hda_nid_t pin_nid)
1594{
1595 struct hdmi_spec *spec;
1596
1597 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1598 if (!spec)
1599 return -ENOMEM;
1600
1601 codec->spec = spec;
1602
1603 spec->multiout.num_dacs = 0; /* no analog */
1604 spec->multiout.max_channels = 2;
1605 spec->multiout.dig_out_nid = cvt_nid;
1606 spec->num_cvts = 1;
1607 spec->num_pins = 1;
1608 spec->cvts[0].cvt_nid = cvt_nid;
1609 spec->pins[0].pin_nid = pin_nid;
1610 spec->pcm_playback = simple_pcm_playback;
1611
1612 codec->patch_ops = simple_hdmi_patch_ops;
1613
1614 return 0;
1615}
1616
1527static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, 1617static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec,
1528 int channels) 1618 int channels)
1529{ 1619{
@@ -1696,54 +1786,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = {
1696 }, 1786 },
1697}; 1787};
1698 1788
1699static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = {
1700 .substreams = 1,
1701 .channels_min = 2,
1702 .channels_max = 2,
1703 .nid = nvhdmi_master_con_nid_7x,
1704 .rates = SUPPORTED_RATES,
1705 .maxbps = SUPPORTED_MAXBPS,
1706 .formats = SUPPORTED_FORMATS,
1707 .ops = {
1708 .open = simple_playback_pcm_open,
1709 .close = simple_playback_pcm_close,
1710 .prepare = simple_playback_pcm_prepare
1711 },
1712};
1713
1714static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = {
1715 .build_controls = simple_playback_build_controls,
1716 .build_pcms = simple_playback_build_pcms,
1717 .init = nvhdmi_7x_init,
1718 .free = simple_playback_free,
1719};
1720
1721static const struct hda_codec_ops nvhdmi_patch_ops_2ch = {
1722 .build_controls = simple_playback_build_controls,
1723 .build_pcms = simple_playback_build_pcms,
1724 .init = nvhdmi_7x_init,
1725 .free = simple_playback_free,
1726};
1727
1728static int patch_nvhdmi_2ch(struct hda_codec *codec) 1789static int patch_nvhdmi_2ch(struct hda_codec *codec)
1729{ 1790{
1730 struct hdmi_spec *spec; 1791 struct hdmi_spec *spec;
1792 int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x,
1793 nvhdmi_master_pin_nid_7x);
1794 if (err < 0)
1795 return err;
1731 1796
1732 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 1797 codec->patch_ops.init = nvhdmi_7x_init_2ch;
1733 if (spec == NULL) 1798 /* override the PCM rates, etc, as the codec doesn't give full list */
1734 return -ENOMEM; 1799 spec = codec->spec;
1735 1800 spec->pcm_playback.rates = SUPPORTED_RATES;
1736 codec->spec = spec; 1801 spec->pcm_playback.maxbps = SUPPORTED_MAXBPS;
1737 1802 spec->pcm_playback.formats = SUPPORTED_FORMATS;
1738 spec->multiout.num_dacs = 0; /* no analog */
1739 spec->multiout.max_channels = 2;
1740 spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x;
1741 spec->num_cvts = 1;
1742 spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x;
1743 spec->pcm_playback = &nvhdmi_pcm_playback_2ch;
1744
1745 codec->patch_ops = nvhdmi_patch_ops_2ch;
1746
1747 return 0; 1803 return 0;
1748} 1804}
1749 1805
@@ -1751,13 +1807,12 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec)
1751{ 1807{
1752 struct hdmi_spec *spec; 1808 struct hdmi_spec *spec;
1753 int err = patch_nvhdmi_2ch(codec); 1809 int err = patch_nvhdmi_2ch(codec);
1754
1755 if (err < 0) 1810 if (err < 0)
1756 return err; 1811 return err;
1757 spec = codec->spec; 1812 spec = codec->spec;
1758 spec->multiout.max_channels = 8; 1813 spec->multiout.max_channels = 8;
1759 spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; 1814 spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x;
1760 codec->patch_ops = nvhdmi_patch_ops_8ch_7x; 1815 codec->patch_ops.init = nvhdmi_7x_init_8ch;
1761 1816
1762 /* Initialize the audio infoframe channel mask and checksum to something 1817 /* Initialize the audio infoframe channel mask and checksum to something
1763 * valid */ 1818 * valid */
@@ -1801,69 +1856,26 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1801 return 0; 1856 return 0;
1802} 1857}
1803 1858
1804static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { 1859static int patch_atihdmi(struct hda_codec *codec)
1805 .substreams = 1,
1806 .channels_min = 2,
1807 .channels_max = 2,
1808 .nid = ATIHDMI_CVT_NID,
1809 .ops = {
1810 .open = simple_playback_pcm_open,
1811 .close = simple_playback_pcm_close,
1812 .prepare = atihdmi_playback_pcm_prepare
1813 },
1814};
1815
1816static const struct hda_verb atihdmi_basic_init[] = {
1817 /* enable digital output on pin widget */
1818 { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1819 {} /* terminator */
1820};
1821
1822static int atihdmi_init(struct hda_codec *codec)
1823{ 1860{
1824 struct hdmi_spec *spec = codec->spec; 1861 struct hdmi_spec *spec;
1825 1862 int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID);
1826 snd_hda_sequence_write(codec, atihdmi_basic_init); 1863 if (err < 0)
1827 /* SI codec requires to unmute the pin */ 1864 return err;
1828 if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP) 1865 spec = codec->spec;
1829 snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0, 1866 spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare;
1830 AC_VERB_SET_AMP_GAIN_MUTE,
1831 AMP_OUT_UNMUTE);
1832 return 0; 1867 return 0;
1833} 1868}
1834 1869
1835static const struct hda_codec_ops atihdmi_patch_ops = { 1870/* VIA HDMI Implementation */
1836 .build_controls = simple_playback_build_controls, 1871#define VIAHDMI_CVT_NID 0x02 /* audio converter1 */
1837 .build_pcms = simple_playback_build_pcms, 1872#define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */
1838 .init = atihdmi_init,
1839 .free = simple_playback_free,
1840};
1841 1873
1842 1874static int patch_via_hdmi(struct hda_codec *codec)
1843static int patch_atihdmi(struct hda_codec *codec)
1844{ 1875{
1845 struct hdmi_spec *spec; 1876 return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID);
1846
1847 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
1848 if (spec == NULL)
1849 return -ENOMEM;
1850
1851 codec->spec = spec;
1852
1853 spec->multiout.num_dacs = 0; /* no analog */
1854 spec->multiout.max_channels = 2;
1855 spec->multiout.dig_out_nid = ATIHDMI_CVT_NID;
1856 spec->num_cvts = 1;
1857 spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID;
1858 spec->pins[0].pin_nid = ATIHDMI_PIN_NID;
1859 spec->pcm_playback = &atihdmi_pcm_digital_playback;
1860
1861 codec->patch_ops = atihdmi_patch_ops;
1862
1863 return 0;
1864} 1877}
1865 1878
1866
1867/* 1879/*
1868 * patch entries 1880 * patch entries
1869 */ 1881 */
@@ -1902,8 +1914,13 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1902{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, 1914{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi },
1903{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, 1915{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi },
1904{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, 1916{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi },
1917{ .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi },
1905{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, 1918{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch },
1906{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, 1919{ .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch },
1920{ .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
1921{ .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi },
1922{ .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi },
1923{ .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi },
1907{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1924{ .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1908{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, 1925{ .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi },
1909{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, 1926{ .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi },
@@ -1911,6 +1928,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = {
1911{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, 1928{ .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi },
1912{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, 1929{ .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi },
1913{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, 1930{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi },
1931{ .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi },
1914{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, 1932{ .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi },
1915{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, 1933{ .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi },
1916{} /* terminator */ 1934{} /* terminator */
@@ -1948,8 +1966,13 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041");
1948MODULE_ALIAS("snd-hda-codec-id:10de0042"); 1966MODULE_ALIAS("snd-hda-codec-id:10de0042");
1949MODULE_ALIAS("snd-hda-codec-id:10de0043"); 1967MODULE_ALIAS("snd-hda-codec-id:10de0043");
1950MODULE_ALIAS("snd-hda-codec-id:10de0044"); 1968MODULE_ALIAS("snd-hda-codec-id:10de0044");
1969MODULE_ALIAS("snd-hda-codec-id:10de0051");
1951MODULE_ALIAS("snd-hda-codec-id:10de0067"); 1970MODULE_ALIAS("snd-hda-codec-id:10de0067");
1952MODULE_ALIAS("snd-hda-codec-id:10de8001"); 1971MODULE_ALIAS("snd-hda-codec-id:10de8001");
1972MODULE_ALIAS("snd-hda-codec-id:11069f80");
1973MODULE_ALIAS("snd-hda-codec-id:11069f81");
1974MODULE_ALIAS("snd-hda-codec-id:11069f84");
1975MODULE_ALIAS("snd-hda-codec-id:11069f85");
1953MODULE_ALIAS("snd-hda-codec-id:17e80047"); 1976MODULE_ALIAS("snd-hda-codec-id:17e80047");
1954MODULE_ALIAS("snd-hda-codec-id:80860054"); 1977MODULE_ALIAS("snd-hda-codec-id:80860054");
1955MODULE_ALIAS("snd-hda-codec-id:80862801"); 1978MODULE_ALIAS("snd-hda-codec-id:80862801");
@@ -1958,6 +1981,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803");
1958MODULE_ALIAS("snd-hda-codec-id:80862804"); 1981MODULE_ALIAS("snd-hda-codec-id:80862804");
1959MODULE_ALIAS("snd-hda-codec-id:80862805"); 1982MODULE_ALIAS("snd-hda-codec-id:80862805");
1960MODULE_ALIAS("snd-hda-codec-id:80862806"); 1983MODULE_ALIAS("snd-hda-codec-id:80862806");
1984MODULE_ALIAS("snd-hda-codec-id:80862807");
1961MODULE_ALIAS("snd-hda-codec-id:80862880"); 1985MODULE_ALIAS("snd-hda-codec-id:80862880");
1962MODULE_ALIAS("snd-hda-codec-id:808629fb"); 1986MODULE_ALIAS("snd-hda-codec-id:808629fb");
1963 1987
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index aa4c25e0f32..f141395dfee 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -170,10 +170,10 @@ struct alc_spec {
170 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; 170 hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS];
171 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; 171 unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS];
172 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ 172 int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */
173 hda_nid_t inv_dmic_pin;
173 174
174 /* hooks */ 175 /* hooks */
175 void (*init_hook)(struct hda_codec *codec); 176 void (*init_hook)(struct hda_codec *codec);
176 void (*unsol_event)(struct hda_codec *codec, unsigned int res);
177#ifdef CONFIG_SND_HDA_POWER_SAVE 177#ifdef CONFIG_SND_HDA_POWER_SAVE
178 void (*power_hook)(struct hda_codec *codec); 178 void (*power_hook)(struct hda_codec *codec);
179#endif 179#endif
@@ -201,6 +201,8 @@ struct alc_spec {
201 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ 201 unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */
202 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ 202 unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */
203 unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ 203 unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */
204 unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */
205 unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */
204 206
205 /* auto-mute control */ 207 /* auto-mute control */
206 int automute_mode; 208 int automute_mode;
@@ -298,6 +300,39 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx)
298} 300}
299 301
300static void call_update_outputs(struct hda_codec *codec); 302static void call_update_outputs(struct hda_codec *codec);
303static void alc_inv_dmic_sync(struct hda_codec *codec, bool force);
304
305/* for shared I/O, change the pin-control accordingly */
306static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic)
307{
308 struct alc_spec *spec = codec->spec;
309 unsigned int val;
310 hda_nid_t pin = spec->autocfg.inputs[1].pin;
311 /* NOTE: this assumes that there are only two inputs, the
312 * first is the real internal mic and the second is HP/mic jack.
313 */
314
315 val = snd_hda_get_default_vref(codec, pin);
316
317 /* This pin does not have vref caps - let's enable vref on pin 0x18
318 instead, as suggested by Realtek */
319 if (val == AC_PINCTL_VREF_HIZ) {
320 const hda_nid_t vref_pin = 0x18;
321 /* Sanity check pin 0x18 */
322 if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN &&
323 get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) {
324 unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin);
325 if (vref_val != AC_PINCTL_VREF_HIZ)
326 snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0));
327 }
328 }
329
330 val = set_as_mic ? val | PIN_IN : PIN_HP;
331 snd_hda_set_pin_ctl(codec, pin, val);
332
333 spec->automute_speaker = !set_as_mic;
334 call_update_outputs(codec);
335}
301 336
302/* select the given imux item; either unmute exclusively or select the route */ 337/* select the given imux item; either unmute exclusively or select the route */
303static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, 338static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
@@ -325,21 +360,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
325 return 0; 360 return 0;
326 spec->cur_mux[adc_idx] = idx; 361 spec->cur_mux[adc_idx] = idx;
327 362
328 /* for shared I/O, change the pin-control accordingly */ 363 if (spec->shared_mic_hp)
329 if (spec->shared_mic_hp) { 364 update_shared_mic_hp(codec, spec->cur_mux[adc_idx]);
330 unsigned int val;
331 hda_nid_t pin = spec->autocfg.inputs[1].pin;
332 /* NOTE: this assumes that there are only two inputs, the
333 * first is the real internal mic and the second is HP jack.
334 */
335 if (spec->cur_mux[adc_idx])
336 val = snd_hda_get_default_vref(codec, pin) | PIN_IN;
337 else
338 val = PIN_HP;
339 snd_hda_set_pin_ctl(codec, pin, val);
340 spec->automute_speaker = !spec->cur_mux[adc_idx];
341 call_update_outputs(codec);
342 }
343 365
344 if (spec->dyn_adc_switch) { 366 if (spec->dyn_adc_switch) {
345 alc_dyn_adc_pcm_resetup(codec, idx); 367 alc_dyn_adc_pcm_resetup(codec, idx);
@@ -368,6 +390,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx,
368 AC_VERB_SET_CONNECT_SEL, 390 AC_VERB_SET_CONNECT_SEL,
369 imux->items[idx].index); 391 imux->items[idx].index);
370 } 392 }
393 alc_inv_dmic_sync(codec, true);
371 return 1; 394 return 1;
372} 395}
373 396
@@ -664,7 +687,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid)
664} 687}
665 688
666/* unsolicited event for HP jack sensing */ 689/* unsolicited event for HP jack sensing */
667static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) 690static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
668{ 691{
669 int action; 692 int action;
670 693
@@ -1000,11 +1023,9 @@ static void alc_init_automute(struct hda_codec *codec)
1000 spec->automute_lo = spec->automute_lo_possible; 1023 spec->automute_lo = spec->automute_lo_possible;
1001 spec->automute_speaker = spec->automute_speaker_possible; 1024 spec->automute_speaker = spec->automute_speaker_possible;
1002 1025
1003 if (spec->automute_speaker_possible || spec->automute_lo_possible) { 1026 if (spec->automute_speaker_possible || spec->automute_lo_possible)
1004 /* create a control for automute mode */ 1027 /* create a control for automute mode */
1005 alc_add_automute_mode_enum(codec); 1028 alc_add_automute_mode_enum(codec);
1006 spec->unsol_event = alc_sku_unsol_event;
1007 }
1008} 1029}
1009 1030
1010/* return the position of NID in the list, or -1 if not found */ 1031/* return the position of NID in the list, or -1 if not found */
@@ -1167,7 +1188,6 @@ static void alc_init_auto_mic(struct hda_codec *codec)
1167 1188
1168 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", 1189 snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
1169 ext, fixed, dock); 1190 ext, fixed, dock);
1170 spec->unsol_event = alc_sku_unsol_event;
1171} 1191}
1172 1192
1173/* check the availabilities of auto-mute and auto-mic switches */ 1193/* check the availabilities of auto-mute and auto-mic switches */
@@ -1556,14 +1576,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol,
1556 1576
1557static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, 1577static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1558 struct snd_ctl_elem_value *ucontrol, 1578 struct snd_ctl_elem_value *ucontrol,
1559 getput_call_t func, bool check_adc_switch) 1579 getput_call_t func, bool is_put)
1560{ 1580{
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1581 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 struct alc_spec *spec = codec->spec; 1582 struct alc_spec *spec = codec->spec;
1563 int i, err = 0; 1583 int i, err = 0;
1564 1584
1565 mutex_lock(&codec->control_mutex); 1585 mutex_lock(&codec->control_mutex);
1566 if (check_adc_switch && spec->dyn_adc_switch) { 1586 if (is_put && spec->dyn_adc_switch) {
1567 for (i = 0; i < spec->num_adc_nids; i++) { 1587 for (i = 0; i < spec->num_adc_nids; i++) {
1568 kcontrol->private_value = 1588 kcontrol->private_value =
1569 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], 1589 HDA_COMPOSE_AMP_VAL(spec->adc_nids[i],
@@ -1584,6 +1604,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
1584 3, 0, HDA_INPUT); 1604 3, 0, HDA_INPUT);
1585 err = func(kcontrol, ucontrol); 1605 err = func(kcontrol, ucontrol);
1586 } 1606 }
1607 if (err >= 0 && is_put)
1608 alc_inv_dmic_sync(codec, false);
1587 error: 1609 error:
1588 mutex_unlock(&codec->control_mutex); 1610 mutex_unlock(&codec->control_mutex);
1589 return err; 1611 return err;
@@ -1676,6 +1698,116 @@ DEFINE_CAPMIX_NOSRC(2);
1676DEFINE_CAPMIX_NOSRC(3); 1698DEFINE_CAPMIX_NOSRC(3);
1677 1699
1678/* 1700/*
1701 * Inverted digital-mic handling
1702 *
1703 * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch"
1704 * gives the additional mute only to the right channel of the digital mic
1705 * capture stream. This is a workaround for avoiding the almost silence
1706 * by summing the stereo stream from some (known to be ForteMedia)
1707 * digital mic unit.
1708 *
1709 * The logic is to call alc_inv_dmic_sync() after each action (possibly)
1710 * modifying ADC amp. When the mute flag is set, it mutes the R-channel
1711 * without caching so that the cache can still keep the original value.
1712 * The cached value is then restored when the flag is set off or any other
1713 * than d-mic is used as the current input source.
1714 */
1715static void alc_inv_dmic_sync(struct hda_codec *codec, bool force)
1716{
1717 struct alc_spec *spec = codec->spec;
1718 int i;
1719
1720 if (!spec->inv_dmic_fixup)
1721 return;
1722 if (!spec->inv_dmic_muted && !force)
1723 return;
1724 for (i = 0; i < spec->num_adc_nids; i++) {
1725 int src = spec->dyn_adc_switch ? 0 : i;
1726 bool dmic_fixup = false;
1727 hda_nid_t nid;
1728 int parm, dir, v;
1729
1730 if (spec->inv_dmic_muted &&
1731 spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin)
1732 dmic_fixup = true;
1733 if (!dmic_fixup && !force)
1734 continue;
1735 if (spec->vol_in_capsrc) {
1736 nid = spec->capsrc_nids[i];
1737 parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT;
1738 dir = HDA_OUTPUT;
1739 } else {
1740 nid = spec->adc_nids[i];
1741 parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT;
1742 dir = HDA_INPUT;
1743 }
1744 /* we care only right channel */
1745 v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0);
1746 if (v & 0x80) /* if already muted, we don't need to touch */
1747 continue;
1748 if (dmic_fixup) /* add mute for d-mic */
1749 v |= 0x80;
1750 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE,
1751 parm | v);
1752 }
1753}
1754
1755static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol,
1756 struct snd_ctl_elem_value *ucontrol)
1757{
1758 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1759 struct alc_spec *spec = codec->spec;
1760
1761 ucontrol->value.integer.value[0] = !spec->inv_dmic_muted;
1762 return 0;
1763}
1764
1765static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol,
1766 struct snd_ctl_elem_value *ucontrol)
1767{
1768 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1769 struct alc_spec *spec = codec->spec;
1770 unsigned int val = !ucontrol->value.integer.value[0];
1771
1772 if (val == spec->inv_dmic_muted)
1773 return 0;
1774 spec->inv_dmic_muted = val;
1775 alc_inv_dmic_sync(codec, true);
1776 return 0;
1777}
1778
1779static const struct snd_kcontrol_new alc_inv_dmic_sw = {
1780 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1781 .info = snd_ctl_boolean_mono_info,
1782 .get = alc_inv_dmic_sw_get,
1783 .put = alc_inv_dmic_sw_put,
1784};
1785
1786static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid)
1787{
1788 struct alc_spec *spec = codec->spec;
1789 struct snd_kcontrol_new *knew = alc_kcontrol_new(spec);
1790 if (!knew)
1791 return -ENOMEM;
1792 *knew = alc_inv_dmic_sw;
1793 knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL);
1794 if (!knew->name)
1795 return -ENOMEM;
1796 spec->inv_dmic_fixup = 1;
1797 spec->inv_dmic_muted = 0;
1798 spec->inv_dmic_pin = nid;
1799 return 0;
1800}
1801
1802/* typically the digital mic is put at node 0x12 */
1803static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec,
1804 const struct alc_fixup *fix, int action)
1805{
1806 if (action == ALC_FIXUP_ACT_PROBE)
1807 alc_add_inv_dmic_mixer(codec, 0x12);
1808}
1809
1810/*
1679 * virtual master controls 1811 * virtual master controls
1680 */ 1812 */
1681 1813
@@ -1865,13 +1997,31 @@ static int __alc_build_controls(struct hda_codec *codec)
1865 return 0; 1997 return 0;
1866} 1998}
1867 1999
1868static int alc_build_controls(struct hda_codec *codec) 2000static int alc_build_jacks(struct hda_codec *codec)
1869{ 2001{
1870 struct alc_spec *spec = codec->spec; 2002 struct alc_spec *spec = codec->spec;
2003
2004 if (spec->shared_mic_hp) {
2005 int err;
2006 int nid = spec->autocfg.inputs[1].pin;
2007 err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0);
2008 if (err < 0)
2009 return err;
2010 err = snd_hda_jack_detect_enable(codec, nid, 0);
2011 if (err < 0)
2012 return err;
2013 }
2014
2015 return snd_hda_jack_add_kctls(codec, &spec->autocfg);
2016}
2017
2018static int alc_build_controls(struct hda_codec *codec)
2019{
1871 int err = __alc_build_controls(codec); 2020 int err = __alc_build_controls(codec);
1872 if (err < 0) 2021 if (err < 0)
1873 return err; 2022 return err;
1874 err = snd_hda_jack_add_kctls(codec, &spec->autocfg); 2023
2024 err = alc_build_jacks(codec);
1875 if (err < 0) 2025 if (err < 0)
1876 return err; 2026 return err;
1877 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); 2027 alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD);
@@ -1908,14 +2058,6 @@ static int alc_init(struct hda_codec *codec)
1908 return 0; 2058 return 0;
1909} 2059}
1910 2060
1911static void alc_unsol_event(struct hda_codec *codec, unsigned int res)
1912{
1913 struct alc_spec *spec = codec->spec;
1914
1915 if (spec->unsol_event)
1916 spec->unsol_event(codec, res);
1917}
1918
1919#ifdef CONFIG_SND_HDA_POWER_SAVE 2061#ifdef CONFIG_SND_HDA_POWER_SAVE
1920static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) 2062static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid)
1921{ 2063{
@@ -2300,7 +2442,7 @@ static void alc_power_eapd(struct hda_codec *codec)
2300 alc_auto_setup_eapd(codec, false); 2442 alc_auto_setup_eapd(codec, false);
2301} 2443}
2302 2444
2303static int alc_suspend(struct hda_codec *codec, pm_message_t state) 2445static int alc_suspend(struct hda_codec *codec)
2304{ 2446{
2305 struct alc_spec *spec = codec->spec; 2447 struct alc_spec *spec = codec->spec;
2306 alc_shutup(codec); 2448 alc_shutup(codec);
@@ -2317,6 +2459,7 @@ static int alc_resume(struct hda_codec *codec)
2317 codec->patch_ops.init(codec); 2459 codec->patch_ops.init(codec);
2318 snd_hda_codec_resume_amp(codec); 2460 snd_hda_codec_resume_amp(codec);
2319 snd_hda_codec_resume_cache(codec); 2461 snd_hda_codec_resume_cache(codec);
2462 alc_inv_dmic_sync(codec, true);
2320 hda_call_check_power_status(codec, 0x01); 2463 hda_call_check_power_status(codec, 0x01);
2321 return 0; 2464 return 0;
2322} 2465}
@@ -4116,14 +4259,12 @@ static void set_capture_mixer(struct hda_codec *codec)
4116 */ 4259 */
4117static void alc_auto_init_std(struct hda_codec *codec) 4260static void alc_auto_init_std(struct hda_codec *codec)
4118{ 4261{
4119 struct alc_spec *spec = codec->spec;
4120 alc_auto_init_multi_out(codec); 4262 alc_auto_init_multi_out(codec);
4121 alc_auto_init_extra_out(codec); 4263 alc_auto_init_extra_out(codec);
4122 alc_auto_init_analog_input(codec); 4264 alc_auto_init_analog_input(codec);
4123 alc_auto_init_input_src(codec); 4265 alc_auto_init_input_src(codec);
4124 alc_auto_init_digital(codec); 4266 alc_auto_init_digital(codec);
4125 if (spec->unsol_event) 4267 alc_inithook(codec);
4126 alc_inithook(codec);
4127} 4268}
4128 4269
4129/* 4270/*
@@ -4724,7 +4865,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec,
4724 spec->automute_speaker = 1; 4865 spec->automute_speaker = 1;
4725 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ 4866 spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */
4726 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); 4867 snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT);
4727 spec->unsol_event = alc_sku_unsol_event;
4728 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); 4868 snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs);
4729 } 4869 }
4730} 4870}
@@ -4909,6 +5049,7 @@ enum {
4909 ALC889_FIXUP_DAC_ROUTE, 5049 ALC889_FIXUP_DAC_ROUTE,
4910 ALC889_FIXUP_MBP_VREF, 5050 ALC889_FIXUP_MBP_VREF,
4911 ALC889_FIXUP_IMAC91_VREF, 5051 ALC889_FIXUP_IMAC91_VREF,
5052 ALC882_FIXUP_INV_DMIC,
4912}; 5053};
4913 5054
4914static void alc889_fixup_coef(struct hda_codec *codec, 5055static void alc889_fixup_coef(struct hda_codec *codec,
@@ -5212,6 +5353,10 @@ static const struct alc_fixup alc882_fixups[] = {
5212 .chained = true, 5353 .chained = true,
5213 .chain_id = ALC882_FIXUP_GPIO1, 5354 .chain_id = ALC882_FIXUP_GPIO1,
5214 }, 5355 },
5356 [ALC882_FIXUP_INV_DMIC] = {
5357 .type = ALC_FIXUP_FUNC,
5358 .v.func = alc_fixup_inv_dmic_0x12,
5359 },
5215}; 5360};
5216 5361
5217static const struct snd_pci_quirk alc882_fixup_tbl[] = { 5362static const struct snd_pci_quirk alc882_fixup_tbl[] = {
@@ -5286,6 +5431,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = {
5286 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, 5431 {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"},
5287 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, 5432 {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"},
5288 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, 5433 {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"},
5434 {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"},
5289 {} 5435 {}
5290}; 5436};
5291 5437
@@ -5373,6 +5519,7 @@ enum {
5373 ALC262_FIXUP_LENOVO_3000, 5519 ALC262_FIXUP_LENOVO_3000,
5374 ALC262_FIXUP_BENQ, 5520 ALC262_FIXUP_BENQ,
5375 ALC262_FIXUP_BENQ_T31, 5521 ALC262_FIXUP_BENQ_T31,
5522 ALC262_FIXUP_INV_DMIC,
5376}; 5523};
5377 5524
5378static const struct alc_fixup alc262_fixups[] = { 5525static const struct alc_fixup alc262_fixups[] = {
@@ -5424,6 +5571,10 @@ static const struct alc_fixup alc262_fixups[] = {
5424 {} 5571 {}
5425 } 5572 }
5426 }, 5573 },
5574 [ALC262_FIXUP_INV_DMIC] = {
5575 .type = ALC_FIXUP_FUNC,
5576 .v.func = alc_fixup_inv_dmic_0x12,
5577 },
5427}; 5578};
5428 5579
5429static const struct snd_pci_quirk alc262_fixup_tbl[] = { 5580static const struct snd_pci_quirk alc262_fixup_tbl[] = {
@@ -5438,6 +5589,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = {
5438 {} 5589 {}
5439}; 5590};
5440 5591
5592static const struct alc_model_fixup alc262_fixup_models[] = {
5593 {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"},
5594 {}
5595};
5441 5596
5442/* 5597/*
5443 */ 5598 */
@@ -5466,7 +5621,8 @@ static int patch_alc262(struct hda_codec *codec)
5466#endif 5621#endif
5467 alc_fix_pll_init(codec, 0x20, 0x0a, 10); 5622 alc_fix_pll_init(codec, 0x20, 0x0a, 10);
5468 5623
5469 alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); 5624 alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl,
5625 alc262_fixups);
5470 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); 5626 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5471 5627
5472 alc_auto_parse_customize_define(codec); 5628 alc_auto_parse_customize_define(codec);
@@ -5522,6 +5678,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = {
5522 { } 5678 { }
5523}; 5679};
5524 5680
5681enum {
5682 ALC268_FIXUP_INV_DMIC,
5683};
5684
5685static const struct alc_fixup alc268_fixups[] = {
5686 [ALC268_FIXUP_INV_DMIC] = {
5687 .type = ALC_FIXUP_FUNC,
5688 .v.func = alc_fixup_inv_dmic_0x12,
5689 },
5690};
5691
5692static const struct alc_model_fixup alc268_fixup_models[] = {
5693 {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"},
5694 {}
5695};
5696
5525/* 5697/*
5526 * BIOS auto configuration 5698 * BIOS auto configuration
5527 */ 5699 */
@@ -5553,6 +5725,9 @@ static int patch_alc268(struct hda_codec *codec)
5553 5725
5554 spec = codec->spec; 5726 spec = codec->spec;
5555 5727
5728 alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups);
5729 alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE);
5730
5556 /* automatic parse from the BIOS config */ 5731 /* automatic parse from the BIOS config */
5557 err = alc268_parse_auto_config(codec); 5732 err = alc268_parse_auto_config(codec);
5558 if (err < 0) 5733 if (err < 0)
@@ -5582,6 +5757,8 @@ static int patch_alc268(struct hda_codec *codec)
5582 codec->patch_ops = alc_patch_ops; 5757 codec->patch_ops = alc_patch_ops;
5583 spec->shutup = alc_eapd_shutup; 5758 spec->shutup = alc_eapd_shutup;
5584 5759
5760 alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE);
5761
5585 return 0; 5762 return 0;
5586 5763
5587 error: 5764 error:
@@ -5704,6 +5881,15 @@ static int alc269_resume(struct hda_codec *codec)
5704} 5881}
5705#endif /* CONFIG_PM */ 5882#endif /* CONFIG_PM */
5706 5883
5884static void alc269_fixup_pincfg_no_hp_to_lineout(struct hda_codec *codec,
5885 const struct alc_fixup *fix, int action)
5886{
5887 struct alc_spec *spec = codec->spec;
5888
5889 if (action == ALC_FIXUP_ACT_PRE_PROBE)
5890 spec->parse_flags = HDA_PINCFG_NO_HP_FIXUP;
5891}
5892
5707static void alc269_fixup_hweq(struct hda_codec *codec, 5893static void alc269_fixup_hweq(struct hda_codec *codec,
5708 const struct alc_fixup *fix, int action) 5894 const struct alc_fixup *fix, int action)
5709{ 5895{
@@ -5810,6 +5996,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec,
5810 } 5996 }
5811} 5997}
5812 5998
5999
5813enum { 6000enum {
5814 ALC269_FIXUP_SONY_VAIO, 6001 ALC269_FIXUP_SONY_VAIO,
5815 ALC275_FIXUP_SONY_VAIO_GPIO2, 6002 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -5828,6 +6015,9 @@ enum {
5828 ALC269VB_FIXUP_AMIC, 6015 ALC269VB_FIXUP_AMIC,
5829 ALC269VB_FIXUP_DMIC, 6016 ALC269VB_FIXUP_DMIC,
5830 ALC269_FIXUP_MIC2_MUTE_LED, 6017 ALC269_FIXUP_MIC2_MUTE_LED,
6018 ALC269_FIXUP_INV_DMIC,
6019 ALC269_FIXUP_LENOVO_DOCK,
6020 ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT,
5831}; 6021};
5832 6022
5833static const struct alc_fixup alc269_fixups[] = { 6023static const struct alc_fixup alc269_fixups[] = {
@@ -5952,12 +6142,33 @@ static const struct alc_fixup alc269_fixups[] = {
5952 .type = ALC_FIXUP_FUNC, 6142 .type = ALC_FIXUP_FUNC,
5953 .v.func = alc269_fixup_mic2_mute, 6143 .v.func = alc269_fixup_mic2_mute,
5954 }, 6144 },
6145 [ALC269_FIXUP_INV_DMIC] = {
6146 .type = ALC_FIXUP_FUNC,
6147 .v.func = alc_fixup_inv_dmic_0x12,
6148 },
6149 [ALC269_FIXUP_LENOVO_DOCK] = {
6150 .type = ALC_FIXUP_PINS,
6151 .v.pins = (const struct alc_pincfg[]) {
6152 { 0x19, 0x23a11040 }, /* dock mic */
6153 { 0x1b, 0x2121103f }, /* dock headphone */
6154 { }
6155 },
6156 .chained = true,
6157 .chain_id = ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT
6158 },
6159 [ALC269_FIXUP_PINCFG_NO_HP_TO_LINEOUT] = {
6160 .type = ALC_FIXUP_FUNC,
6161 .v.func = alc269_fixup_pincfg_no_hp_to_lineout,
6162 },
5955}; 6163};
5956 6164
5957static const struct snd_pci_quirk alc269_fixup_tbl[] = { 6165static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6166 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
6167 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
5958 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), 6168 SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED),
5959 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), 6169 SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC),
5960 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), 6170 SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW),
6171 SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC),
5961 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), 6172 SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC),
5962 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), 6173 SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC),
5963 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), 6174 SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC),
@@ -5975,6 +6186,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
5975 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), 6186 SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE),
5976 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), 6187 SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE),
5977 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), 6188 SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE),
6189 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
5978 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), 6190 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE),
5979 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), 6191 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K),
5980 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 6192 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
@@ -6033,6 +6245,10 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
6033static const struct alc_model_fixup alc269_fixup_models[] = { 6245static const struct alc_model_fixup alc269_fixup_models[] = {
6034 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, 6246 {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"},
6035 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, 6247 {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"},
6248 {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"},
6249 {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"},
6250 {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"},
6251 {.id = ALC269_FIXUP_LENOVO_DOCK, .name = "lenovo-dock"},
6036 {} 6252 {}
6037}; 6253};
6038 6254
@@ -6329,12 +6545,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = {
6329 {} 6545 {}
6330}; 6546};
6331 6547
6332static const struct hda_verb alc660vd_eapd_verbs[] = {
6333 {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2},
6334 {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2},
6335 { }
6336};
6337
6338/* 6548/*
6339 */ 6549 */
6340static int patch_alc861vd(struct hda_codec *codec) 6550static int patch_alc861vd(struct hda_codec *codec)
@@ -6356,11 +6566,6 @@ static int patch_alc861vd(struct hda_codec *codec)
6356 if (err < 0) 6566 if (err < 0)
6357 goto error; 6567 goto error;
6358 6568
6359 if (codec->vendor_id == 0x10ec0660) {
6360 /* always turn on EAPD */
6361 snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs);
6362 }
6363
6364 if (!spec->no_analog) { 6569 if (!spec->no_analog) {
6365 err = snd_hda_attach_beep_device(codec, 0x23); 6570 err = snd_hda_attach_beep_device(codec, 0x23);
6366 if (err < 0) 6571 if (err < 0)
@@ -6443,6 +6648,7 @@ enum {
6443 ALC662_FIXUP_ASUS_MODE8, 6648 ALC662_FIXUP_ASUS_MODE8,
6444 ALC662_FIXUP_NO_JACK_DETECT, 6649 ALC662_FIXUP_NO_JACK_DETECT,
6445 ALC662_FIXUP_ZOTAC_Z68, 6650 ALC662_FIXUP_ZOTAC_Z68,
6651 ALC662_FIXUP_INV_DMIC,
6446}; 6652};
6447 6653
6448static const struct alc_fixup alc662_fixups[] = { 6654static const struct alc_fixup alc662_fixups[] = {
@@ -6599,12 +6805,17 @@ static const struct alc_fixup alc662_fixups[] = {
6599 { } 6805 { }
6600 } 6806 }
6601 }, 6807 },
6808 [ALC662_FIXUP_INV_DMIC] = {
6809 .type = ALC_FIXUP_FUNC,
6810 .v.func = alc_fixup_inv_dmic_0x12,
6811 },
6602}; 6812};
6603 6813
6604static const struct snd_pci_quirk alc662_fixup_tbl[] = { 6814static const struct snd_pci_quirk alc662_fixup_tbl[] = {
6605 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), 6815 SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2),
6606 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), 6816 SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE),
6607 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), 6817 SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE),
6818 SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC),
6608 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), 6819 SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE),
6609 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), 6820 SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
6610 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), 6821 SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT),
@@ -6685,6 +6896,7 @@ static const struct alc_model_fixup alc662_fixup_models[] = {
6685 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, 6896 {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"},
6686 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, 6897 {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"},
6687 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, 6898 {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"},
6899 {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"},
6688 {} 6900 {}
6689}; 6901};
6690 6902
@@ -6831,6 +7043,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
6831 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, 7043 { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 },
6832 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, 7044 { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 },
6833 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, 7045 { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 },
7046 { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 },
6834 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", 7047 { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660",
6835 .patch = patch_alc861 }, 7048 .patch = patch_alc861 },
6836 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, 7049 { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd },
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 07675282015..a1596a3b171 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -4997,7 +4997,7 @@ static int stac92xx_resume(struct hda_codec *codec)
4997 return 0; 4997 return 0;
4998} 4998}
4999 4999
5000static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) 5000static int stac92xx_suspend(struct hda_codec *codec)
5001{ 5001{
5002 stac92xx_shutup(codec); 5002 stac92xx_shutup(codec);
5003 return 0; 5003 return 0;
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 82b368068e0..90645560ed3 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -1748,7 +1748,7 @@ static void via_unsol_event(struct hda_codec *codec,
1748} 1748}
1749 1749
1750#ifdef CONFIG_PM 1750#ifdef CONFIG_PM
1751static int via_suspend(struct hda_codec *codec, pm_message_t state) 1751static int via_suspend(struct hda_codec *codec)
1752{ 1752{
1753 struct via_spec *spec = codec->spec; 1753 struct via_spec *spec = codec->spec;
1754 vt1708_stop_hp_work(spec); 1754 vt1708_stop_hp_work(spec);
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c
index a01a00d1cf4..bed9f34f4ef 100644
--- a/sound/pci/ice1712/ice1724.c
+++ b/sound/pci/ice1712/ice1724.c
@@ -2793,9 +2793,10 @@ static void __devexit snd_vt1724_remove(struct pci_dev *pci)
2793} 2793}
2794 2794
2795#ifdef CONFIG_PM 2795#ifdef CONFIG_PM
2796static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state) 2796static int snd_vt1724_suspend(struct device *dev)
2797{ 2797{
2798 struct snd_card *card = pci_get_drvdata(pci); 2798 struct pci_dev *pci = to_pci_dev(dev);
2799 struct snd_card *card = dev_get_drvdata(dev);
2799 struct snd_ice1712 *ice = card->private_data; 2800 struct snd_ice1712 *ice = card->private_data;
2800 2801
2801 if (!ice->pm_suspend_enabled) 2802 if (!ice->pm_suspend_enabled)
@@ -2820,13 +2821,14 @@ static int snd_vt1724_suspend(struct pci_dev *pci, pm_message_t state)
2820 2821
2821 pci_disable_device(pci); 2822 pci_disable_device(pci);
2822 pci_save_state(pci); 2823 pci_save_state(pci);
2823 pci_set_power_state(pci, pci_choose_state(pci, state)); 2824 pci_set_power_state(pci, PCI_D3hot);
2824 return 0; 2825 return 0;
2825} 2826}
2826 2827
2827static int snd_vt1724_resume(struct pci_dev *pci) 2828static int snd_vt1724_resume(struct device *dev)
2828{ 2829{
2829 struct snd_card *card = pci_get_drvdata(pci); 2830 struct pci_dev *pci = to_pci_dev(dev);
2831 struct snd_card *card = dev_get_drvdata(dev);
2830 struct snd_ice1712 *ice = card->private_data; 2832 struct snd_ice1712 *ice = card->private_data;
2831 2833
2832 if (!ice->pm_suspend_enabled) 2834 if (!ice->pm_suspend_enabled)
@@ -2871,17 +2873,21 @@ static int snd_vt1724_resume(struct pci_dev *pci)
2871 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2873 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2872 return 0; 2874 return 0;
2873} 2875}
2874#endif 2876
2877static SIMPLE_DEV_PM_OPS(snd_vt1724_pm, snd_vt1724_suspend, snd_vt1724_resume);
2878#define SND_VT1724_PM_OPS &snd_vt1724_pm
2879#else
2880#define SND_VT1724_PM_OPS NULL
2881#endif /* CONFIG_PM */
2875 2882
2876static struct pci_driver vt1724_driver = { 2883static struct pci_driver vt1724_driver = {
2877 .name = KBUILD_MODNAME, 2884 .name = KBUILD_MODNAME,
2878 .id_table = snd_vt1724_ids, 2885 .id_table = snd_vt1724_ids,
2879 .probe = snd_vt1724_probe, 2886 .probe = snd_vt1724_probe,
2880 .remove = __devexit_p(snd_vt1724_remove), 2887 .remove = __devexit_p(snd_vt1724_remove),
2881#ifdef CONFIG_PM 2888 .driver = {
2882 .suspend = snd_vt1724_suspend, 2889 .pm = SND_VT1724_PM_OPS,
2883 .resume = snd_vt1724_resume, 2890 },
2884#endif
2885}; 2891};
2886 2892
2887module_pci_driver(vt1724_driver); 2893module_pci_driver(vt1724_driver);
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c
index f4e2dd4da8c..cd553f592e2 100644
--- a/sound/pci/intel8x0.c
+++ b/sound/pci/intel8x0.c
@@ -2624,9 +2624,10 @@ static int snd_intel8x0_free(struct intel8x0 *chip)
2624/* 2624/*
2625 * power management 2625 * power management
2626 */ 2626 */
2627static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state) 2627static int intel8x0_suspend(struct device *dev)
2628{ 2628{
2629 struct snd_card *card = pci_get_drvdata(pci); 2629 struct pci_dev *pci = to_pci_dev(dev);
2630 struct snd_card *card = dev_get_drvdata(dev);
2630 struct intel8x0 *chip = card->private_data; 2631 struct intel8x0 *chip = card->private_data;
2631 int i; 2632 int i;
2632 2633
@@ -2658,13 +2659,14 @@ static int intel8x0_suspend(struct pci_dev *pci, pm_message_t state)
2658 /* The call below may disable built-in speaker on some laptops 2659 /* The call below may disable built-in speaker on some laptops
2659 * after S2RAM. So, don't touch it. 2660 * after S2RAM. So, don't touch it.
2660 */ 2661 */
2661 /* pci_set_power_state(pci, pci_choose_state(pci, state)); */ 2662 /* pci_set_power_state(pci, PCI_D3hot); */
2662 return 0; 2663 return 0;
2663} 2664}
2664 2665
2665static int intel8x0_resume(struct pci_dev *pci) 2666static int intel8x0_resume(struct device *dev)
2666{ 2667{
2667 struct snd_card *card = pci_get_drvdata(pci); 2668 struct pci_dev *pci = to_pci_dev(dev);
2669 struct snd_card *card = dev_get_drvdata(dev);
2668 struct intel8x0 *chip = card->private_data; 2670 struct intel8x0 *chip = card->private_data;
2669 int i; 2671 int i;
2670 2672
@@ -2734,6 +2736,11 @@ static int intel8x0_resume(struct pci_dev *pci)
2734 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2736 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2735 return 0; 2737 return 0;
2736} 2738}
2739
2740static SIMPLE_DEV_PM_OPS(intel8x0_pm, intel8x0_suspend, intel8x0_resume);
2741#define INTEL8X0_PM_OPS &intel8x0_pm
2742#else
2743#define INTEL8X0_PM_OPS NULL
2737#endif /* CONFIG_PM */ 2744#endif /* CONFIG_PM */
2738 2745
2739#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */ 2746#define INTEL8X0_TESTBUF_SIZE 32768 /* enough large for one shot */
@@ -3343,10 +3350,9 @@ static struct pci_driver intel8x0_driver = {
3343 .id_table = snd_intel8x0_ids, 3350 .id_table = snd_intel8x0_ids,
3344 .probe = snd_intel8x0_probe, 3351 .probe = snd_intel8x0_probe,
3345 .remove = __devexit_p(snd_intel8x0_remove), 3352 .remove = __devexit_p(snd_intel8x0_remove),
3346#ifdef CONFIG_PM 3353 .driver = {
3347 .suspend = intel8x0_suspend, 3354 .pm = INTEL8X0_PM_OPS,
3348 .resume = intel8x0_resume, 3355 },
3349#endif
3350}; 3356};
3351 3357
3352module_pci_driver(intel8x0_driver); 3358module_pci_driver(intel8x0_driver);
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c
index fc27a6a69e7..da44bb3f8e7 100644
--- a/sound/pci/intel8x0m.c
+++ b/sound/pci/intel8x0m.c
@@ -1012,9 +1012,10 @@ static int snd_intel8x0m_free(struct intel8x0m *chip)
1012/* 1012/*
1013 * power management 1013 * power management
1014 */ 1014 */
1015static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state) 1015static int intel8x0m_suspend(struct device *dev)
1016{ 1016{
1017 struct snd_card *card = pci_get_drvdata(pci); 1017 struct pci_dev *pci = to_pci_dev(dev);
1018 struct snd_card *card = dev_get_drvdata(dev);
1018 struct intel8x0m *chip = card->private_data; 1019 struct intel8x0m *chip = card->private_data;
1019 int i; 1020 int i;
1020 1021
@@ -1028,13 +1029,14 @@ static int intel8x0m_suspend(struct pci_dev *pci, pm_message_t state)
1028 } 1029 }
1029 pci_disable_device(pci); 1030 pci_disable_device(pci);
1030 pci_save_state(pci); 1031 pci_save_state(pci);
1031 pci_set_power_state(pci, pci_choose_state(pci, state)); 1032 pci_set_power_state(pci, PCI_D3hot);
1032 return 0; 1033 return 0;
1033} 1034}
1034 1035
1035static int intel8x0m_resume(struct pci_dev *pci) 1036static int intel8x0m_resume(struct device *dev)
1036{ 1037{
1037 struct snd_card *card = pci_get_drvdata(pci); 1038 struct pci_dev *pci = to_pci_dev(dev);
1039 struct snd_card *card = dev_get_drvdata(dev);
1038 struct intel8x0m *chip = card->private_data; 1040 struct intel8x0m *chip = card->private_data;
1039 1041
1040 pci_set_power_state(pci, PCI_D0); 1042 pci_set_power_state(pci, PCI_D0);
@@ -1060,6 +1062,11 @@ static int intel8x0m_resume(struct pci_dev *pci)
1060 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1062 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1061 return 0; 1063 return 0;
1062} 1064}
1065
1066static SIMPLE_DEV_PM_OPS(intel8x0m_pm, intel8x0m_suspend, intel8x0m_resume);
1067#define INTEL8X0M_PM_OPS &intel8x0m_pm
1068#else
1069#define INTEL8X0M_PM_OPS NULL
1063#endif /* CONFIG_PM */ 1070#endif /* CONFIG_PM */
1064 1071
1065#ifdef CONFIG_PROC_FS 1072#ifdef CONFIG_PROC_FS
@@ -1329,10 +1336,9 @@ static struct pci_driver intel8x0m_driver = {
1329 .id_table = snd_intel8x0m_ids, 1336 .id_table = snd_intel8x0m_ids,
1330 .probe = snd_intel8x0m_probe, 1337 .probe = snd_intel8x0m_probe,
1331 .remove = __devexit_p(snd_intel8x0m_remove), 1338 .remove = __devexit_p(snd_intel8x0m_remove),
1332#ifdef CONFIG_PM 1339 .driver = {
1333 .suspend = intel8x0m_suspend, 1340 .pm = INTEL8X0M_PM_OPS,
1334 .resume = intel8x0m_resume, 1341 },
1335#endif
1336}; 1342};
1337 1343
1338module_pci_driver(intel8x0m_driver); 1344module_pci_driver(intel8x0m_driver);
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index deef2139958..c85d1ffcc95 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -361,74 +361,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)");
361#define DSP2HOST_REQ_I2SRATE 0x02 361#define DSP2HOST_REQ_I2SRATE 0x02
362#define DSP2HOST_REQ_TIMER 0x04 362#define DSP2HOST_REQ_TIMER 0x04
363 363
364/* AC97 registers */
365/* XXX fix this crap up */
366/*#define AC97_RESET 0x00*/
367
368#define AC97_VOL_MUTE_B 0x8000
369#define AC97_VOL_M 0x1F
370#define AC97_LEFT_VOL_S 8
371
372#define AC97_MASTER_VOL 0x02
373#define AC97_LINE_LEVEL_VOL 0x04
374#define AC97_MASTER_MONO_VOL 0x06
375#define AC97_PC_BEEP_VOL 0x0A
376#define AC97_PC_BEEP_VOL_M 0x0F
377#define AC97_SROUND_MASTER_VOL 0x38
378#define AC97_PC_BEEP_VOL_S 1
379
380/*#define AC97_PHONE_VOL 0x0C
381#define AC97_MIC_VOL 0x0E*/
382#define AC97_MIC_20DB_ENABLE 0x40
383
384/*#define AC97_LINEIN_VOL 0x10
385#define AC97_CD_VOL 0x12
386#define AC97_VIDEO_VOL 0x14
387#define AC97_AUX_VOL 0x16*/
388#define AC97_PCM_OUT_VOL 0x18
389/*#define AC97_RECORD_SELECT 0x1A*/
390#define AC97_RECORD_MIC 0x00
391#define AC97_RECORD_CD 0x01
392#define AC97_RECORD_VIDEO 0x02
393#define AC97_RECORD_AUX 0x03
394#define AC97_RECORD_MONO_MUX 0x02
395#define AC97_RECORD_DIGITAL 0x03
396#define AC97_RECORD_LINE 0x04
397#define AC97_RECORD_STEREO 0x05
398#define AC97_RECORD_MONO 0x06
399#define AC97_RECORD_PHONE 0x07
400
401/*#define AC97_RECORD_GAIN 0x1C*/
402#define AC97_RECORD_VOL_M 0x0F
403
404/*#define AC97_GENERAL_PURPOSE 0x20*/
405#define AC97_POWER_DOWN_CTRL 0x26
406#define AC97_ADC_READY 0x0001
407#define AC97_DAC_READY 0x0002
408#define AC97_ANALOG_READY 0x0004
409#define AC97_VREF_ON 0x0008
410#define AC97_PR0 0x0100
411#define AC97_PR1 0x0200
412#define AC97_PR2 0x0400
413#define AC97_PR3 0x0800
414#define AC97_PR4 0x1000
415
416#define AC97_RESERVED1 0x28
417
418#define AC97_VENDOR_TEST 0x5A
419
420#define AC97_CLOCK_DELAY 0x5C
421#define AC97_LINEOUT_MUX_SEL 0x0001
422#define AC97_MONO_MUX_SEL 0x0002
423#define AC97_CLOCK_DELAY_SEL 0x1F
424#define AC97_DAC_CDS_SHIFT 6
425#define AC97_ADC_CDS_SHIFT 11
426
427#define AC97_MULTI_CHANNEL_SEL 0x74
428
429/*#define AC97_VENDOR_ID1 0x7C
430#define AC97_VENDOR_ID2 0x7E*/
431
432/* 364/*
433 * ASSP control regs 365 * ASSP control regs
434 */ 366 */
@@ -2459,9 +2391,10 @@ static int snd_m3_free(struct snd_m3 *chip)
2459 * APM support 2391 * APM support
2460 */ 2392 */
2461#ifdef CONFIG_PM 2393#ifdef CONFIG_PM
2462static int m3_suspend(struct pci_dev *pci, pm_message_t state) 2394static int m3_suspend(struct device *dev)
2463{ 2395{
2464 struct snd_card *card = pci_get_drvdata(pci); 2396 struct pci_dev *pci = to_pci_dev(dev);
2397 struct snd_card *card = dev_get_drvdata(dev);
2465 struct snd_m3 *chip = card->private_data; 2398 struct snd_m3 *chip = card->private_data;
2466 int i, dsp_index; 2399 int i, dsp_index;
2467 2400
@@ -2489,13 +2422,14 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
2489 2422
2490 pci_disable_device(pci); 2423 pci_disable_device(pci);
2491 pci_save_state(pci); 2424 pci_save_state(pci);
2492 pci_set_power_state(pci, pci_choose_state(pci, state)); 2425 pci_set_power_state(pci, PCI_D3hot);
2493 return 0; 2426 return 0;
2494} 2427}
2495 2428
2496static int m3_resume(struct pci_dev *pci) 2429static int m3_resume(struct device *dev)
2497{ 2430{
2498 struct snd_card *card = pci_get_drvdata(pci); 2431 struct pci_dev *pci = to_pci_dev(dev);
2432 struct snd_card *card = dev_get_drvdata(dev);
2499 struct snd_m3 *chip = card->private_data; 2433 struct snd_m3 *chip = card->private_data;
2500 int i, dsp_index; 2434 int i, dsp_index;
2501 2435
@@ -2546,6 +2480,11 @@ static int m3_resume(struct pci_dev *pci)
2546 chip->in_suspend = 0; 2480 chip->in_suspend = 0;
2547 return 0; 2481 return 0;
2548} 2482}
2483
2484static SIMPLE_DEV_PM_OPS(m3_pm, m3_suspend, m3_resume);
2485#define M3_PM_OPS &m3_pm
2486#else
2487#define M3_PM_OPS NULL
2549#endif /* CONFIG_PM */ 2488#endif /* CONFIG_PM */
2550 2489
2551#ifdef CONFIG_SND_MAESTRO3_INPUT 2490#ifdef CONFIG_SND_MAESTRO3_INPUT
@@ -2842,10 +2781,9 @@ static struct pci_driver m3_driver = {
2842 .id_table = snd_m3_ids, 2781 .id_table = snd_m3_ids,
2843 .probe = snd_m3_probe, 2782 .probe = snd_m3_probe,
2844 .remove = __devexit_p(snd_m3_remove), 2783 .remove = __devexit_p(snd_m3_remove),
2845#ifdef CONFIG_PM 2784 .driver = {
2846 .suspend = m3_suspend, 2785 .pm = M3_PM_OPS,
2847 .resume = m3_resume, 2786 },
2848#endif
2849}; 2787};
2850 2788
2851module_pci_driver(m3_driver); 2789module_pci_driver(m3_driver);
diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c
index 8159b05ee94..465cff25b14 100644
--- a/sound/pci/nm256/nm256.c
+++ b/sound/pci/nm256/nm256.c
@@ -1382,9 +1382,10 @@ snd_nm256_peek_for_sig(struct nm256 *chip)
1382 * APM event handler, so the card is properly reinitialized after a power 1382 * APM event handler, so the card is properly reinitialized after a power
1383 * event. 1383 * event.
1384 */ 1384 */
1385static int nm256_suspend(struct pci_dev *pci, pm_message_t state) 1385static int nm256_suspend(struct device *dev)
1386{ 1386{
1387 struct snd_card *card = pci_get_drvdata(pci); 1387 struct pci_dev *pci = to_pci_dev(dev);
1388 struct snd_card *card = dev_get_drvdata(dev);
1388 struct nm256 *chip = card->private_data; 1389 struct nm256 *chip = card->private_data;
1389 1390
1390 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 1391 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
@@ -1393,13 +1394,14 @@ static int nm256_suspend(struct pci_dev *pci, pm_message_t state)
1393 chip->coeffs_current = 0; 1394 chip->coeffs_current = 0;
1394 pci_disable_device(pci); 1395 pci_disable_device(pci);
1395 pci_save_state(pci); 1396 pci_save_state(pci);
1396 pci_set_power_state(pci, pci_choose_state(pci, state)); 1397 pci_set_power_state(pci, PCI_D3hot);
1397 return 0; 1398 return 0;
1398} 1399}
1399 1400
1400static int nm256_resume(struct pci_dev *pci) 1401static int nm256_resume(struct device *dev)
1401{ 1402{
1402 struct snd_card *card = pci_get_drvdata(pci); 1403 struct pci_dev *pci = to_pci_dev(dev);
1404 struct snd_card *card = dev_get_drvdata(dev);
1403 struct nm256 *chip = card->private_data; 1405 struct nm256 *chip = card->private_data;
1404 int i; 1406 int i;
1405 1407
@@ -1434,6 +1436,11 @@ static int nm256_resume(struct pci_dev *pci)
1434 chip->in_resume = 0; 1436 chip->in_resume = 0;
1435 return 0; 1437 return 0;
1436} 1438}
1439
1440static SIMPLE_DEV_PM_OPS(nm256_pm, nm256_suspend, nm256_resume);
1441#define NM256_PM_OPS &nm256_pm
1442#else
1443#define NM256_PM_OPS NULL
1437#endif /* CONFIG_PM */ 1444#endif /* CONFIG_PM */
1438 1445
1439static int snd_nm256_free(struct nm256 *chip) 1446static int snd_nm256_free(struct nm256 *chip)
@@ -1747,10 +1754,9 @@ static struct pci_driver nm256_driver = {
1747 .id_table = snd_nm256_ids, 1754 .id_table = snd_nm256_ids,
1748 .probe = snd_nm256_probe, 1755 .probe = snd_nm256_probe,
1749 .remove = __devexit_p(snd_nm256_remove), 1756 .remove = __devexit_p(snd_nm256_remove),
1750#ifdef CONFIG_PM 1757 .driver = {
1751 .suspend = nm256_suspend, 1758 .pm = NM256_PM_OPS,
1752 .resume = nm256_resume, 1759 },
1753#endif
1754}; 1760};
1755 1761
1756module_pci_driver(nm256_driver); 1762module_pci_driver(nm256_driver);
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index 610275bfbae..37520a2b4dc 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -873,8 +873,9 @@ static struct pci_driver oxygen_driver = {
873 .probe = generic_oxygen_probe, 873 .probe = generic_oxygen_probe,
874 .remove = __devexit_p(oxygen_pci_remove), 874 .remove = __devexit_p(oxygen_pci_remove),
875#ifdef CONFIG_PM 875#ifdef CONFIG_PM
876 .suspend = oxygen_pci_suspend, 876 .driver = {
877 .resume = oxygen_pci_resume, 877 .pm = &oxygen_pci_pm,
878 },
878#endif 879#endif
879}; 880};
880 881
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index f53897a708b..7112a89fb8b 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -162,8 +162,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
162 ); 162 );
163void oxygen_pci_remove(struct pci_dev *pci); 163void oxygen_pci_remove(struct pci_dev *pci);
164#ifdef CONFIG_PM 164#ifdef CONFIG_PM
165int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); 165extern const struct dev_pm_ops oxygen_pci_pm;
166int oxygen_pci_resume(struct pci_dev *pci);
167#endif 166#endif
168void oxygen_pci_shutdown(struct pci_dev *pci); 167void oxygen_pci_shutdown(struct pci_dev *pci);
169 168
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 92e2d67f16a..ab8738e21ad 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -727,9 +727,10 @@ void oxygen_pci_remove(struct pci_dev *pci)
727EXPORT_SYMBOL(oxygen_pci_remove); 727EXPORT_SYMBOL(oxygen_pci_remove);
728 728
729#ifdef CONFIG_PM 729#ifdef CONFIG_PM
730int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) 730static int oxygen_pci_suspend(struct device *dev)
731{ 731{
732 struct snd_card *card = pci_get_drvdata(pci); 732 struct pci_dev *pci = to_pci_dev(dev);
733 struct snd_card *card = dev_get_drvdata(dev);
733 struct oxygen *chip = card->private_data; 734 struct oxygen *chip = card->private_data;
734 unsigned int i, saved_interrupt_mask; 735 unsigned int i, saved_interrupt_mask;
735 736
@@ -756,10 +757,9 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state)
756 757
757 pci_disable_device(pci); 758 pci_disable_device(pci);
758 pci_save_state(pci); 759 pci_save_state(pci);
759 pci_set_power_state(pci, pci_choose_state(pci, state)); 760 pci_set_power_state(pci, PCI_D3hot);
760 return 0; 761 return 0;
761} 762}
762EXPORT_SYMBOL(oxygen_pci_suspend);
763 763
764static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = { 764static const u32 registers_to_restore[OXYGEN_IO_SIZE / 32] = {
765 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff, 765 0xffffffff, 0x00ff077f, 0x00011d08, 0x007f00ff,
@@ -787,9 +787,10 @@ static void oxygen_restore_ac97(struct oxygen *chip, unsigned int codec)
787 chip->saved_ac97_registers[codec][i]); 787 chip->saved_ac97_registers[codec][i]);
788} 788}
789 789
790int oxygen_pci_resume(struct pci_dev *pci) 790static int oxygen_pci_resume(struct device *dev)
791{ 791{
792 struct snd_card *card = pci_get_drvdata(pci); 792 struct pci_dev *pci = to_pci_dev(dev);
793 struct snd_card *card = dev_get_drvdata(dev);
793 struct oxygen *chip = card->private_data; 794 struct oxygen *chip = card->private_data;
794 unsigned int i; 795 unsigned int i;
795 796
@@ -820,7 +821,9 @@ int oxygen_pci_resume(struct pci_dev *pci)
820 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 821 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
821 return 0; 822 return 0;
822} 823}
823EXPORT_SYMBOL(oxygen_pci_resume); 824
825SIMPLE_DEV_PM_OPS(oxygen_pci_pm, oxygen_pci_suspend, oxygen_pci_resume);
826EXPORT_SYMBOL(oxygen_pci_pm);
824#endif /* CONFIG_PM */ 827#endif /* CONFIG_PM */
825 828
826void oxygen_pci_shutdown(struct pci_dev *pci) 829void oxygen_pci_shutdown(struct pci_dev *pci)
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 19962c6d38c..d3b606b69f3 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -94,8 +94,9 @@ static struct pci_driver xonar_driver = {
94 .probe = xonar_probe, 94 .probe = xonar_probe,
95 .remove = __devexit_p(oxygen_pci_remove), 95 .remove = __devexit_p(oxygen_pci_remove),
96#ifdef CONFIG_PM 96#ifdef CONFIG_PM
97 .suspend = oxygen_pci_suspend, 97 .driver = {
98 .resume = oxygen_pci_resume, 98 .pm = &oxygen_pci_pm,
99 },
99#endif 100#endif
100 .shutdown = oxygen_pci_shutdown, 101 .shutdown = oxygen_pci_shutdown,
101}; 102};
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c
index 0435f45e951..e3ac1f768ff 100644
--- a/sound/pci/pcxhr/pcxhr.c
+++ b/sound/pci/pcxhr/pcxhr.c
@@ -1368,6 +1368,67 @@ static void pcxhr_proc_gpo_write(struct snd_info_entry *entry,
1368 } 1368 }
1369} 1369}
1370 1370
1371/* Access to the results of the CMD_GET_TIME_CODE RMH */
1372#define TIME_CODE_VALID_MASK 0x00800000
1373#define TIME_CODE_NEW_MASK 0x00400000
1374#define TIME_CODE_BACK_MASK 0x00200000
1375#define TIME_CODE_WAIT_MASK 0x00100000
1376
1377/* Values for the CMD_MANAGE_SIGNAL RMH */
1378#define MANAGE_SIGNAL_TIME_CODE 0x01
1379#define MANAGE_SIGNAL_MIDI 0x02
1380
1381/* linear time code read proc*/
1382static void pcxhr_proc_ltc(struct snd_info_entry *entry,
1383 struct snd_info_buffer *buffer)
1384{
1385 struct snd_pcxhr *chip = entry->private_data;
1386 struct pcxhr_mgr *mgr = chip->mgr;
1387 struct pcxhr_rmh rmh;
1388 unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm;
1389 int err;
1390 /* commands available when embedded DSP is running */
1391 if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) {
1392 snd_iprintf(buffer, "no firmware loaded\n");
1393 return;
1394 }
1395 if (!mgr->capture_ltc) {
1396 pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL);
1397 rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE;
1398 err = pcxhr_send_msg(mgr, &rmh);
1399 if (err) {
1400 snd_iprintf(buffer, "ltc not activated (%d)\n", err);
1401 return;
1402 }
1403 if (mgr->is_hr_stereo)
1404 hr222_manage_timecode(mgr, 1);
1405 else
1406 pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE,
1407 REG_CONT_VALSMPTE, NULL);
1408 mgr->capture_ltc = 1;
1409 }
1410 pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE);
1411 err = pcxhr_send_msg(mgr, &rmh);
1412 if (err) {
1413 snd_iprintf(buffer, "ltc read error (err=%d)\n", err);
1414 return ;
1415 }
1416 ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf);
1417 ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf);
1418 ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf);
1419 ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf);
1420
1421 snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n",
1422 ltcHrs, ltcMin, ltcSec, ltcFrm);
1423 snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff,
1424 rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff);
1425 /*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n",
1426 rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/
1427 if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) {
1428 snd_iprintf(buffer, "warning: linear timecode not valid\n");
1429 }
1430}
1431
1371static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) 1432static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
1372{ 1433{
1373 struct snd_info_entry *entry; 1434 struct snd_info_entry *entry;
@@ -1383,6 +1444,8 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip)
1383 entry->c.text.write = pcxhr_proc_gpo_write; 1444 entry->c.text.write = pcxhr_proc_gpo_write;
1384 entry->mode |= S_IWUSR; 1445 entry->mode |= S_IWUSR;
1385 } 1446 }
1447 if (!snd_card_proc_new(chip->card, "ltc", &entry))
1448 snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc);
1386} 1449}
1387/* end of proc interface */ 1450/* end of proc interface */
1388 1451
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h
index bda776c4988..a4c602c4517 100644
--- a/sound/pci/pcxhr/pcxhr.h
+++ b/sound/pci/pcxhr/pcxhr.h
@@ -103,6 +103,7 @@ struct pcxhr_mgr {
103 unsigned int board_has_mic:1; /* if 1 the board has microphone input */ 103 unsigned int board_has_mic:1; /* if 1 the board has microphone input */
104 unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ 104 unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */
105 unsigned int mono_capture:1; /* if 1 the board does mono capture */ 105 unsigned int mono_capture:1; /* if 1 the board does mono capture */
106 unsigned int capture_ltc:1; /* if 1 the board captures LTC input */
106 107
107 struct snd_dma_buffer hostport; 108 struct snd_dma_buffer hostport;
108 109
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c
index 304411c1fe4..b33db1e006e 100644
--- a/sound/pci/pcxhr/pcxhr_core.c
+++ b/sound/pci/pcxhr/pcxhr_core.c
@@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = {
504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, 504[CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED },
505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, 505[CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED },
506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, 506[CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED },
507[CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED },
508[CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED },
507}; 509};
508 510
509#ifdef CONFIG_SND_DEBUG_VERBOSE 511#ifdef CONFIG_SND_DEBUG_VERBOSE
@@ -533,6 +535,8 @@ static char* cmd_names[] = {
533[CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", 535[CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN",
534[CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", 536[CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT",
535[CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", 537[CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST",
538[CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE",
539[CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL",
536}; 540};
537#endif 541#endif
538 542
@@ -1133,13 +1137,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr,
1133 hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; 1137 hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24;
1134 hw_sample_count += (u_int64_t)rmh.stat[1]; 1138 hw_sample_count += (u_int64_t)rmh.stat[1];
1135 1139
1136 snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", 1140 snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n",
1137 stream->pipe->is_capture ? 'C' : 'P', 1141 stream->pipe->is_capture ? 'C' : 'P',
1138 stream->substream->number, 1142 stream->substream->number,
1139 (long unsigned int)hw_sample_count, 1143 hw_sample_count,
1140 (long unsigned int)(stream->timer_abs_periods + 1144 stream->timer_abs_periods + stream->timer_period_frag +
1141 stream->timer_period_frag + 1145 mgr->granularity);
1142 mgr->granularity));
1143 return hw_sample_count; 1146 return hw_sample_count;
1144} 1147}
1145 1148
@@ -1243,10 +1246,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id)
1243 1246
1244 if ((dsp_time_diff < 0) && 1247 if ((dsp_time_diff < 0) &&
1245 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { 1248 (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) {
1246 snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " 1249 /* handle dsp counter wraparound without resync */
1247 "resynchronize all streams\n", 1250 int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1;
1251 snd_printdd("WARNING DSP timestamp old(%d) new(%d)",
1248 mgr->dsp_time_last, dsp_time_new); 1252 mgr->dsp_time_last, dsp_time_new);
1249 mgr->dsp_time_err++; 1253 if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) {
1254 snd_printdd("-> timestamp wraparound OK: "
1255 "diff=%d\n", tmp_diff);
1256 dsp_time_diff = tmp_diff;
1257 } else {
1258 snd_printdd("-> resynchronize all streams\n");
1259 mgr->dsp_time_err++;
1260 }
1250 } 1261 }
1251#ifdef CONFIG_SND_DEBUG_VERBOSE 1262#ifdef CONFIG_SND_DEBUG_VERBOSE
1252 if (dsp_time_diff == 0) 1263 if (dsp_time_diff == 0)
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h
index be0173796cd..a81ab6b811e 100644
--- a/sound/pci/pcxhr/pcxhr_core.h
+++ b/sound/pci/pcxhr/pcxhr_core.h
@@ -79,6 +79,8 @@ enum {
79 CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */ 79 CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */
80 CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */ 80 CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */
81 CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */ 81 CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */
82 CMD_GET_TIME_CODE, /* cmd_len = 1 stat_len = 5 */
83 CMD_MANAGE_SIGNAL, /* cmd_len = 1 stat_len = 0 */
82 CMD_LAST_INDEX 84 CMD_LAST_INDEX
83}; 85};
84 86
@@ -116,7 +118,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh);
116#define IO_NUM_REG_OUT_ANA_LEVEL 20 118#define IO_NUM_REG_OUT_ANA_LEVEL 20
117#define IO_NUM_REG_IN_ANA_LEVEL 21 119#define IO_NUM_REG_IN_ANA_LEVEL 21
118 120
119 121#define REG_CONT_VALSMPTE 0x000800
120#define REG_CONT_UNMUTE_INPUTS 0x020000 122#define REG_CONT_UNMUTE_INPUTS 0x020000
121 123
122/* parameters used with register IO_NUM_REG_STATUS */ 124/* parameters used with register IO_NUM_REG_STATUS */
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c
index 1cb82c0a9cb..84fe57626eb 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.c
+++ b/sound/pci/pcxhr/pcxhr_mix22.c
@@ -53,6 +53,7 @@
53#define PCXHR_DSP_RESET_DSP 0x01 53#define PCXHR_DSP_RESET_DSP 0x01
54#define PCXHR_DSP_RESET_MUTE 0x02 54#define PCXHR_DSP_RESET_MUTE 0x02
55#define PCXHR_DSP_RESET_CODEC 0x08 55#define PCXHR_DSP_RESET_CODEC 0x08
56#define PCXHR_DSP_RESET_SMPTE 0x10
56#define PCXHR_DSP_RESET_GPO_OFFSET 5 57#define PCXHR_DSP_RESET_GPO_OFFSET 5
57#define PCXHR_DSP_RESET_GPO_MASK 0x60 58#define PCXHR_DSP_RESET_GPO_MASK 0x60
58 59
@@ -527,6 +528,16 @@ int hr222_write_gpo(struct pcxhr_mgr *mgr, int value)
527 return 0; 528 return 0;
528} 529}
529 530
531int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable)
532{
533 if (enable)
534 mgr->dsp_reset |= PCXHR_DSP_RESET_SMPTE;
535 else
536 mgr->dsp_reset &= ~PCXHR_DSP_RESET_SMPTE;
537
538 PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset);
539 return 0;
540}
530 541
531int hr222_update_analog_audio_level(struct snd_pcxhr *chip, 542int hr222_update_analog_audio_level(struct snd_pcxhr *chip,
532 int is_capture, int channel) 543 int is_capture, int channel)
diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h
index 5a37a0007e8..5971b9933f4 100644
--- a/sound/pci/pcxhr/pcxhr_mix22.h
+++ b/sound/pci/pcxhr/pcxhr_mix22.h
@@ -34,6 +34,7 @@ int hr222_get_external_clock(struct pcxhr_mgr *mgr,
34 34
35int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value); 35int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value);
36int hr222_write_gpo(struct pcxhr_mgr *mgr, int value); 36int hr222_write_gpo(struct pcxhr_mgr *mgr, int value);
37int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable);
37 38
38#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */ 39#define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */
39#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */ 40#define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */
diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c
index cbeb3f77350..760ee467cd9 100644
--- a/sound/pci/riptide/riptide.c
+++ b/sound/pci/riptide/riptide.c
@@ -1151,9 +1151,10 @@ static void riptide_handleirq(unsigned long dev_id)
1151} 1151}
1152 1152
1153#ifdef CONFIG_PM 1153#ifdef CONFIG_PM
1154static int riptide_suspend(struct pci_dev *pci, pm_message_t state) 1154static int riptide_suspend(struct device *dev)
1155{ 1155{
1156 struct snd_card *card = pci_get_drvdata(pci); 1156 struct pci_dev *pci = to_pci_dev(dev);
1157 struct snd_card *card = dev_get_drvdata(dev);
1157 struct snd_riptide *chip = card->private_data; 1158 struct snd_riptide *chip = card->private_data;
1158 1159
1159 chip->in_suspend = 1; 1160 chip->in_suspend = 1;
@@ -1162,13 +1163,14 @@ static int riptide_suspend(struct pci_dev *pci, pm_message_t state)
1162 snd_ac97_suspend(chip->ac97); 1163 snd_ac97_suspend(chip->ac97);
1163 pci_disable_device(pci); 1164 pci_disable_device(pci);
1164 pci_save_state(pci); 1165 pci_save_state(pci);
1165 pci_set_power_state(pci, pci_choose_state(pci, state)); 1166 pci_set_power_state(pci, PCI_D3hot);
1166 return 0; 1167 return 0;
1167} 1168}
1168 1169
1169static int riptide_resume(struct pci_dev *pci) 1170static int riptide_resume(struct device *dev)
1170{ 1171{
1171 struct snd_card *card = pci_get_drvdata(pci); 1172 struct pci_dev *pci = to_pci_dev(dev);
1173 struct snd_card *card = dev_get_drvdata(dev);
1172 struct snd_riptide *chip = card->private_data; 1174 struct snd_riptide *chip = card->private_data;
1173 1175
1174 pci_set_power_state(pci, PCI_D0); 1176 pci_set_power_state(pci, PCI_D0);
@@ -1186,7 +1188,12 @@ static int riptide_resume(struct pci_dev *pci)
1186 chip->in_suspend = 0; 1188 chip->in_suspend = 0;
1187 return 0; 1189 return 0;
1188} 1190}
1189#endif 1191
1192static SIMPLE_DEV_PM_OPS(riptide_pm, riptide_suspend, riptide_resume);
1193#define RIPTIDE_PM_OPS &riptide_pm
1194#else
1195#define RIPTIDE_PM_OPS NULL
1196#endif /* CONFIG_PM */
1190 1197
1191static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip) 1198static int try_to_load_firmware(struct cmdif *cif, struct snd_riptide *chip)
1192{ 1199{
@@ -2180,10 +2187,9 @@ static struct pci_driver driver = {
2180 .id_table = snd_riptide_ids, 2187 .id_table = snd_riptide_ids,
2181 .probe = snd_card_riptide_probe, 2188 .probe = snd_card_riptide_probe,
2182 .remove = __devexit_p(snd_card_riptide_remove), 2189 .remove = __devexit_p(snd_card_riptide_remove),
2183#ifdef CONFIG_PM 2190 .driver = {
2184 .suspend = riptide_suspend, 2191 .pm = RIPTIDE_PM_OPS,
2185 .resume = riptide_resume, 2192 },
2186#endif
2187}; 2193};
2188 2194
2189#ifdef SUPPORT_JOYSTICK 2195#ifdef SUPPORT_JOYSTICK
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c
index 1552642765d..512434efcc3 100644
--- a/sound/pci/sis7019.c
+++ b/sound/pci/sis7019.c
@@ -1209,9 +1209,10 @@ static int sis_chip_init(struct sis7019 *sis)
1209} 1209}
1210 1210
1211#ifdef CONFIG_PM 1211#ifdef CONFIG_PM
1212static int sis_suspend(struct pci_dev *pci, pm_message_t state) 1212static int sis_suspend(struct device *dev)
1213{ 1213{
1214 struct snd_card *card = pci_get_drvdata(pci); 1214 struct pci_dev *pci = to_pci_dev(dev);
1215 struct snd_card *card = dev_get_drvdata(dev);
1215 struct sis7019 *sis = card->private_data; 1216 struct sis7019 *sis = card->private_data;
1216 void __iomem *ioaddr = sis->ioaddr; 1217 void __iomem *ioaddr = sis->ioaddr;
1217 int i; 1218 int i;
@@ -1241,13 +1242,14 @@ static int sis_suspend(struct pci_dev *pci, pm_message_t state)
1241 1242
1242 pci_disable_device(pci); 1243 pci_disable_device(pci);
1243 pci_save_state(pci); 1244 pci_save_state(pci);
1244 pci_set_power_state(pci, pci_choose_state(pci, state)); 1245 pci_set_power_state(pci, PCI_D3hot);
1245 return 0; 1246 return 0;
1246} 1247}
1247 1248
1248static int sis_resume(struct pci_dev *pci) 1249static int sis_resume(struct device *dev)
1249{ 1250{
1250 struct snd_card *card = pci_get_drvdata(pci); 1251 struct pci_dev *pci = to_pci_dev(dev);
1252 struct snd_card *card = dev_get_drvdata(dev);
1251 struct sis7019 *sis = card->private_data; 1253 struct sis7019 *sis = card->private_data;
1252 void __iomem *ioaddr = sis->ioaddr; 1254 void __iomem *ioaddr = sis->ioaddr;
1253 int i; 1255 int i;
@@ -1298,6 +1300,11 @@ error:
1298 snd_card_disconnect(card); 1300 snd_card_disconnect(card);
1299 return -EIO; 1301 return -EIO;
1300} 1302}
1303
1304static SIMPLE_DEV_PM_OPS(sis_pm, sis_suspend, sis_resume);
1305#define SIS_PM_OPS &sis_pm
1306#else
1307#define SIS_PM_OPS NULL
1301#endif /* CONFIG_PM */ 1308#endif /* CONFIG_PM */
1302 1309
1303static int sis_alloc_suspend(struct sis7019 *sis) 1310static int sis_alloc_suspend(struct sis7019 *sis)
@@ -1481,11 +1488,9 @@ static struct pci_driver sis7019_driver = {
1481 .id_table = snd_sis7019_ids, 1488 .id_table = snd_sis7019_ids,
1482 .probe = snd_sis7019_probe, 1489 .probe = snd_sis7019_probe,
1483 .remove = __devexit_p(snd_sis7019_remove), 1490 .remove = __devexit_p(snd_sis7019_remove),
1484 1491 .driver = {
1485#ifdef CONFIG_PM 1492 .pm = SIS_PM_OPS,
1486 .suspend = sis_suspend, 1493 },
1487 .resume = sis_resume,
1488#endif
1489}; 1494};
1490 1495
1491module_pci_driver(sis7019_driver); 1496module_pci_driver(sis7019_driver);
diff --git a/sound/pci/trident/trident.c b/sound/pci/trident/trident.c
index 611983ec732..d36e6ca147e 100644
--- a/sound/pci/trident/trident.c
+++ b/sound/pci/trident/trident.c
@@ -26,7 +26,7 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <sound/core.h> 28#include <sound/core.h>
29#include <sound/trident.h> 29#include "trident.h"
30#include <sound/initval.h> 30#include <sound/initval.h>
31 31
32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>"); 32MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, <audio@tridentmicro.com>");
@@ -178,8 +178,9 @@ static struct pci_driver trident_driver = {
178 .probe = snd_trident_probe, 178 .probe = snd_trident_probe,
179 .remove = __devexit_p(snd_trident_remove), 179 .remove = __devexit_p(snd_trident_remove),
180#ifdef CONFIG_PM 180#ifdef CONFIG_PM
181 .suspend = snd_trident_suspend, 181 .driver = {
182 .resume = snd_trident_resume, 182 .pm = &snd_trident_pm,
183 },
183#endif 184#endif
184}; 185};
185 186
diff --git a/sound/pci/trident/trident.h b/sound/pci/trident/trident.h
new file mode 100644
index 00000000000..5f110eb56e4
--- /dev/null
+++ b/sound/pci/trident/trident.h
@@ -0,0 +1,444 @@
1#ifndef __SOUND_TRIDENT_H
2#define __SOUND_TRIDENT_H
3
4/*
5 * audio@tridentmicro.com
6 * Fri Feb 19 15:55:28 MST 1999
7 * Definitions for Trident 4DWave DX/NX chips
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 */
25
26#include <sound/pcm.h>
27#include <sound/mpu401.h>
28#include <sound/ac97_codec.h>
29#include <sound/util_mem.h>
30
31#define TRIDENT_DEVICE_ID_DX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_DX)
32#define TRIDENT_DEVICE_ID_NX ((PCI_VENDOR_ID_TRIDENT<<16)|PCI_DEVICE_ID_TRIDENT_4DWAVE_NX)
33#define TRIDENT_DEVICE_ID_SI7018 ((PCI_VENDOR_ID_SI<<16)|PCI_DEVICE_ID_SI_7018)
34
35#define SNDRV_TRIDENT_VOICE_TYPE_PCM 0
36#define SNDRV_TRIDENT_VOICE_TYPE_SYNTH 1
37#define SNDRV_TRIDENT_VOICE_TYPE_MIDI 2
38
39#define SNDRV_TRIDENT_VFLG_RUNNING (1<<0)
40
41/* TLB code constants */
42#define SNDRV_TRIDENT_PAGE_SIZE 4096
43#define SNDRV_TRIDENT_PAGE_SHIFT 12
44#define SNDRV_TRIDENT_PAGE_MASK ((1<<SNDRV_TRIDENT_PAGE_SHIFT)-1)
45#define SNDRV_TRIDENT_MAX_PAGES 4096
46
47/*
48 * Direct registers
49 */
50
51#define TRID_REG(trident, x) ((trident)->port + (x))
52
53#define ID_4DWAVE_DX 0x2000
54#define ID_4DWAVE_NX 0x2001
55
56/* Bank definitions */
57
58#define T4D_BANK_A 0
59#define T4D_BANK_B 1
60#define T4D_NUM_BANKS 2
61
62/* Register definitions */
63
64/* Global registers */
65
66enum global_control_bits {
67 CHANNEL_IDX = 0x0000003f,
68 OVERRUN_IE = 0x00000400, /* interrupt enable: capture overrun */
69 UNDERRUN_IE = 0x00000800, /* interrupt enable: playback underrun */
70 ENDLP_IE = 0x00001000, /* interrupt enable: end of buffer */
71 MIDLP_IE = 0x00002000, /* interrupt enable: middle buffer */
72 ETOG_IE = 0x00004000, /* interrupt enable: envelope toggling */
73 EDROP_IE = 0x00008000, /* interrupt enable: envelope drop */
74 BANK_B_EN = 0x00010000, /* SiS: enable bank B (64 channels) */
75 PCMIN_B_MIX = 0x00020000, /* SiS: PCM IN B mixing enable */
76 I2S_OUT_ASSIGN = 0x00040000, /* SiS: I2S Out contains surround PCM */
77 SPDIF_OUT_ASSIGN= 0x00080000, /* SiS: 0=S/PDIF L/R | 1=PCM Out FIFO */
78 MAIN_OUT_ASSIGN = 0x00100000, /* SiS: 0=PCM Out FIFO | 1=MMC Out buffer */
79};
80
81enum miscint_bits {
82 PB_UNDERRUN_IRQ = 0x00000001, REC_OVERRUN_IRQ = 0x00000002,
83 SB_IRQ = 0x00000004, MPU401_IRQ = 0x00000008,
84 OPL3_IRQ = 0x00000010, ADDRESS_IRQ = 0x00000020,
85 ENVELOPE_IRQ = 0x00000040, PB_UNDERRUN = 0x00000100,
86 REC_OVERRUN = 0x00000200, MIXER_UNDERFLOW = 0x00000400,
87 MIXER_OVERFLOW = 0x00000800, NX_SB_IRQ_DISABLE = 0x00001000,
88 ST_TARGET_REACHED = 0x00008000,
89 PB_24K_MODE = 0x00010000, ST_IRQ_EN = 0x00800000,
90 ACGPIO_IRQ = 0x01000000
91};
92
93/* T2 legacy dma control registers. */
94#define LEGACY_DMAR0 0x00 // ADR0
95#define LEGACY_DMAR4 0x04 // CNT0
96#define LEGACY_DMAR6 0x06 // CNT0 - High bits
97#define LEGACY_DMAR11 0x0b // MOD
98#define LEGACY_DMAR15 0x0f // MMR
99
100#define T4D_START_A 0x80
101#define T4D_STOP_A 0x84
102#define T4D_DLY_A 0x88
103#define T4D_SIGN_CSO_A 0x8c
104#define T4D_CSPF_A 0x90
105#define T4D_CSPF_B 0xbc
106#define T4D_CEBC_A 0x94
107#define T4D_AINT_A 0x98
108#define T4D_AINTEN_A 0x9c
109#define T4D_LFO_GC_CIR 0xa0
110#define T4D_MUSICVOL_WAVEVOL 0xa8
111#define T4D_SBDELTA_DELTA_R 0xac
112#define T4D_MISCINT 0xb0
113#define T4D_START_B 0xb4
114#define T4D_STOP_B 0xb8
115#define T4D_SBBL_SBCL 0xc0
116#define T4D_SBCTRL_SBE2R_SBDD 0xc4
117#define T4D_STIMER 0xc8
118#define T4D_AINT_B 0xd8
119#define T4D_AINTEN_B 0xdc
120#define T4D_RCI 0x70
121
122/* MPU-401 UART */
123#define T4D_MPU401_BASE 0x20
124#define T4D_MPUR0 0x20
125#define T4D_MPUR1 0x21
126#define T4D_MPUR2 0x22
127#define T4D_MPUR3 0x23
128
129/* S/PDIF Registers */
130#define NX_SPCTRL_SPCSO 0x24
131#define NX_SPLBA 0x28
132#define NX_SPESO 0x2c
133#define NX_SPCSTATUS 0x64
134
135/* Joystick */
136#define GAMEPORT_GCR 0x30
137#define GAMEPORT_MODE_ADC 0x80
138#define GAMEPORT_LEGACY 0x31
139#define GAMEPORT_AXES 0x34
140
141/* NX Specific Registers */
142#define NX_TLBC 0x6c
143
144/* Channel Registers */
145
146#define CH_START 0xe0
147
148#define CH_DX_CSO_ALPHA_FMS 0xe0
149#define CH_DX_ESO_DELTA 0xe8
150#define CH_DX_FMC_RVOL_CVOL 0xec
151
152#define CH_NX_DELTA_CSO 0xe0
153#define CH_NX_DELTA_ESO 0xe8
154#define CH_NX_ALPHA_FMS_FMC_RVOL_CVOL 0xec
155
156#define CH_LBA 0xe4
157#define CH_GVSEL_PAN_VOL_CTRL_EC 0xf0
158#define CH_EBUF1 0xf4
159#define CH_EBUF2 0xf8
160
161/* AC-97 Registers */
162
163#define DX_ACR0_AC97_W 0x40
164#define DX_ACR1_AC97_R 0x44
165#define DX_ACR2_AC97_COM_STAT 0x48
166
167#define NX_ACR0_AC97_COM_STAT 0x40
168#define NX_ACR1_AC97_W 0x44
169#define NX_ACR2_AC97_R_PRIMARY 0x48
170#define NX_ACR3_AC97_R_SECONDARY 0x4c
171
172#define SI_AC97_WRITE 0x40
173#define SI_AC97_READ 0x44
174#define SI_SERIAL_INTF_CTRL 0x48
175#define SI_AC97_GPIO 0x4c
176#define SI_ASR0 0x50
177#define SI_SPDIF_CS 0x70
178#define SI_GPIO 0x7c
179
180enum trident_nx_ac97_bits {
181 /* ACR1-3 */
182 NX_AC97_BUSY_WRITE = 0x0800,
183 NX_AC97_BUSY_READ = 0x0800,
184 NX_AC97_BUSY_DATA = 0x0400,
185 NX_AC97_WRITE_SECONDARY = 0x0100,
186 /* ACR0 */
187 NX_AC97_SECONDARY_READY = 0x0040,
188 NX_AC97_SECONDARY_RECORD = 0x0020,
189 NX_AC97_SURROUND_OUTPUT = 0x0010,
190 NX_AC97_PRIMARY_READY = 0x0008,
191 NX_AC97_PRIMARY_RECORD = 0x0004,
192 NX_AC97_PCM_OUTPUT = 0x0002,
193 NX_AC97_WARM_RESET = 0x0001
194};
195
196enum trident_dx_ac97_bits {
197 DX_AC97_BUSY_WRITE = 0x8000,
198 DX_AC97_BUSY_READ = 0x8000,
199 DX_AC97_READY = 0x0010,
200 DX_AC97_RECORD = 0x0008,
201 DX_AC97_PLAYBACK = 0x0002
202};
203
204enum sis7018_ac97_bits {
205 SI_AC97_BUSY_WRITE = 0x00008000,
206 SI_AC97_AUDIO_BUSY = 0x00004000,
207 SI_AC97_MODEM_BUSY = 0x00002000,
208 SI_AC97_BUSY_READ = 0x00008000,
209 SI_AC97_SECONDARY = 0x00000080,
210};
211
212enum serial_intf_ctrl_bits {
213 WARM_RESET = 0x00000001,
214 COLD_RESET = 0x00000002,
215 I2S_CLOCK = 0x00000004,
216 PCM_SEC_AC97 = 0x00000008,
217 AC97_DBL_RATE = 0x00000010,
218 SPDIF_EN = 0x00000020,
219 I2S_OUTPUT_EN = 0x00000040,
220 I2S_INPUT_EN = 0x00000080,
221 PCMIN = 0x00000100,
222 LINE1IN = 0x00000200,
223 MICIN = 0x00000400,
224 LINE2IN = 0x00000800,
225 HEAD_SET_IN = 0x00001000,
226 GPIOIN = 0x00002000,
227 /* 7018 spec says id = 01 but the demo board routed to 10
228 SECONDARY_ID= 0x00004000, */
229 SECONDARY_ID = 0x00004000,
230 PCMOUT = 0x00010000,
231 SURROUT = 0x00020000,
232 CENTEROUT = 0x00040000,
233 LFEOUT = 0x00080000,
234 LINE1OUT = 0x00100000,
235 LINE2OUT = 0x00200000,
236 GPIOOUT = 0x00400000,
237 SI_AC97_PRIMARY_READY = 0x01000000,
238 SI_AC97_SECONDARY_READY = 0x02000000,
239 SI_AC97_POWERDOWN = 0x04000000,
240};
241
242/* PCM defaults */
243
244#define T4D_DEFAULT_PCM_VOL 10 /* 0 - 255 */
245#define T4D_DEFAULT_PCM_PAN 0 /* 0 - 127 */
246#define T4D_DEFAULT_PCM_RVOL 127 /* 0 - 127 */
247#define T4D_DEFAULT_PCM_CVOL 127 /* 0 - 127 */
248
249struct snd_trident;
250struct snd_trident_voice;
251struct snd_trident_pcm_mixer;
252
253struct snd_trident_port {
254 struct snd_midi_channel_set * chset;
255 struct snd_trident * trident;
256 int mode; /* operation mode */
257 int client; /* sequencer client number */
258 int port; /* sequencer port number */
259 unsigned int midi_has_voices: 1;
260};
261
262struct snd_trident_memblk_arg {
263 short first_page, last_page;
264};
265
266struct snd_trident_tlb {
267 unsigned int * entries; /* 16k-aligned TLB table */
268 dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */
269 unsigned long * shadow_entries; /* shadow entries with virtual addresses */
270 struct snd_dma_buffer buffer;
271 struct snd_util_memhdr * memhdr; /* page allocation list */
272 struct snd_dma_buffer silent_page;
273};
274
275struct snd_trident_voice {
276 unsigned int number;
277 unsigned int use: 1,
278 pcm: 1,
279 synth:1,
280 midi: 1;
281 unsigned int flags;
282 unsigned char client;
283 unsigned char port;
284 unsigned char index;
285
286 struct snd_trident_sample_ops *sample_ops;
287
288 /* channel parameters */
289 unsigned int CSO; /* 24 bits (16 on DX) */
290 unsigned int ESO; /* 24 bits (16 on DX) */
291 unsigned int LBA; /* 30 bits */
292 unsigned short EC; /* 12 bits */
293 unsigned short Alpha; /* 12 bits */
294 unsigned short Delta; /* 16 bits */
295 unsigned short Attribute; /* 16 bits - SiS 7018 */
296 unsigned short Vol; /* 12 bits (6.6) */
297 unsigned char Pan; /* 7 bits (1.4.2) */
298 unsigned char GVSel; /* 1 bit */
299 unsigned char RVol; /* 7 bits (5.2) */
300 unsigned char CVol; /* 7 bits (5.2) */
301 unsigned char FMC; /* 2 bits */
302 unsigned char CTRL; /* 4 bits */
303 unsigned char FMS; /* 4 bits */
304 unsigned char LFO; /* 8 bits */
305
306 unsigned int negCSO; /* nonzero - use negative CSO */
307
308 struct snd_util_memblk *memblk; /* memory block if TLB enabled */
309
310 /* PCM data */
311
312 struct snd_trident *trident;
313 struct snd_pcm_substream *substream;
314 struct snd_trident_voice *extra; /* extra PCM voice (acts as interrupt generator) */
315 unsigned int running: 1,
316 capture: 1,
317 spdif: 1,
318 foldback: 1,
319 isync: 1,
320 isync2: 1,
321 isync3: 1;
322 int foldback_chan; /* foldback subdevice number */
323 unsigned int stimer; /* global sample timer (to detect spurious interrupts) */
324 unsigned int spurious_threshold; /* spurious threshold */
325 unsigned int isync_mark;
326 unsigned int isync_max;
327 unsigned int isync_ESO;
328
329 /* --- */
330
331 void *private_data;
332 void (*private_free)(struct snd_trident_voice *voice);
333};
334
335struct snd_4dwave {
336 int seq_client;
337
338 struct snd_trident_port seq_ports[4];
339 struct snd_trident_voice voices[64];
340
341 int ChanSynthCount; /* number of allocated synth channels */
342 int max_size; /* maximum synth memory size in bytes */
343 int current_size; /* current allocated synth mem in bytes */
344};
345
346struct snd_trident_pcm_mixer {
347 struct snd_trident_voice *voice; /* active voice */
348 unsigned short vol; /* front volume */
349 unsigned char pan; /* pan control */
350 unsigned char rvol; /* rear volume */
351 unsigned char cvol; /* center volume */
352 unsigned char pad;
353};
354
355struct snd_trident {
356 int irq;
357
358 unsigned int device; /* device ID */
359
360 unsigned char bDMAStart;
361
362 unsigned long port;
363 unsigned long midi_port;
364
365 unsigned int spurious_irq_count;
366 unsigned int spurious_irq_max_delta;
367
368 struct snd_trident_tlb tlb; /* TLB entries for NX cards */
369
370 unsigned char spdif_ctrl;
371 unsigned char spdif_pcm_ctrl;
372 unsigned int spdif_bits;
373 unsigned int spdif_pcm_bits;
374 struct snd_kcontrol *spdif_pcm_ctl; /* S/PDIF settings */
375 unsigned int ac97_ctrl;
376
377 unsigned int ChanMap[2]; /* allocation map for hardware channels */
378
379 int ChanPCM; /* max number of PCM channels */
380 int ChanPCMcnt; /* actual number of PCM channels */
381
382 unsigned int ac97_detect: 1; /* 1 = AC97 in detection phase */
383 unsigned int in_suspend: 1; /* 1 during suspend/resume */
384
385 struct snd_4dwave synth; /* synth specific variables */
386
387 spinlock_t event_lock;
388 spinlock_t voice_alloc;
389
390 struct snd_dma_device dma_dev;
391
392 struct pci_dev *pci;
393 struct snd_card *card;
394 struct snd_pcm *pcm; /* ADC/DAC PCM */
395 struct snd_pcm *foldback; /* Foldback PCM */
396 struct snd_pcm *spdif; /* SPDIF PCM */
397 struct snd_rawmidi *rmidi;
398
399 struct snd_ac97_bus *ac97_bus;
400 struct snd_ac97 *ac97;
401 struct snd_ac97 *ac97_sec;
402
403 unsigned int musicvol_wavevol;
404 struct snd_trident_pcm_mixer pcm_mixer[32];
405 struct snd_kcontrol *ctl_vol; /* front volume */
406 struct snd_kcontrol *ctl_pan; /* pan */
407 struct snd_kcontrol *ctl_rvol; /* rear volume */
408 struct snd_kcontrol *ctl_cvol; /* center volume */
409
410 spinlock_t reg_lock;
411
412 struct gameport *gameport;
413};
414
415int snd_trident_create(struct snd_card *card,
416 struct pci_dev *pci,
417 int pcm_streams,
418 int pcm_spdif_device,
419 int max_wavetable_size,
420 struct snd_trident ** rtrident);
421int snd_trident_create_gameport(struct snd_trident *trident);
422
423int snd_trident_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
424int snd_trident_foldback_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
425int snd_trident_spdif_pcm(struct snd_trident * trident, int device, struct snd_pcm **rpcm);
426int snd_trident_attach_synthesizer(struct snd_trident * trident);
427struct snd_trident_voice *snd_trident_alloc_voice(struct snd_trident * trident, int type,
428 int client, int port);
429void snd_trident_free_voice(struct snd_trident * trident, struct snd_trident_voice *voice);
430void snd_trident_start_voice(struct snd_trident * trident, unsigned int voice);
431void snd_trident_stop_voice(struct snd_trident * trident, unsigned int voice);
432void snd_trident_write_voice_regs(struct snd_trident * trident, struct snd_trident_voice *voice);
433extern const struct dev_pm_ops snd_trident_pm;
434
435/* TLB memory allocation */
436struct snd_util_memblk *snd_trident_alloc_pages(struct snd_trident *trident,
437 struct snd_pcm_substream *substream);
438int snd_trident_free_pages(struct snd_trident *trident, struct snd_util_memblk *blk);
439struct snd_util_memblk *snd_trident_synth_alloc(struct snd_trident *trident, unsigned int size);
440int snd_trident_synth_free(struct snd_trident *trident, struct snd_util_memblk *blk);
441int snd_trident_synth_copy_from_user(struct snd_trident *trident, struct snd_util_memblk *blk,
442 int offset, const char __user *data, int size);
443
444#endif /* __SOUND_TRIDENT_H */
diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c
index 61d3c0e8d4c..94011dcae73 100644
--- a/sound/pci/trident/trident_main.c
+++ b/sound/pci/trident/trident_main.c
@@ -41,7 +41,7 @@
41#include <sound/info.h> 41#include <sound/info.h>
42#include <sound/control.h> 42#include <sound/control.h>
43#include <sound/tlv.h> 43#include <sound/tlv.h>
44#include <sound/trident.h> 44#include "trident.h"
45#include <sound/asoundef.h> 45#include <sound/asoundef.h>
46 46
47#include <asm/io.h> 47#include <asm/io.h>
@@ -3920,9 +3920,10 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor
3920} 3920}
3921 3921
3922#ifdef CONFIG_PM 3922#ifdef CONFIG_PM
3923int snd_trident_suspend(struct pci_dev *pci, pm_message_t state) 3923static int snd_trident_suspend(struct device *dev)
3924{ 3924{
3925 struct snd_card *card = pci_get_drvdata(pci); 3925 struct pci_dev *pci = to_pci_dev(dev);
3926 struct snd_card *card = dev_get_drvdata(dev);
3926 struct snd_trident *trident = card->private_data; 3927 struct snd_trident *trident = card->private_data;
3927 3928
3928 trident->in_suspend = 1; 3929 trident->in_suspend = 1;
@@ -3936,13 +3937,14 @@ int snd_trident_suspend(struct pci_dev *pci, pm_message_t state)
3936 3937
3937 pci_disable_device(pci); 3938 pci_disable_device(pci);
3938 pci_save_state(pci); 3939 pci_save_state(pci);
3939 pci_set_power_state(pci, pci_choose_state(pci, state)); 3940 pci_set_power_state(pci, PCI_D3hot);
3940 return 0; 3941 return 0;
3941} 3942}
3942 3943
3943int snd_trident_resume(struct pci_dev *pci) 3944static int snd_trident_resume(struct device *dev)
3944{ 3945{
3945 struct snd_card *card = pci_get_drvdata(pci); 3946 struct pci_dev *pci = to_pci_dev(dev);
3947 struct snd_card *card = dev_get_drvdata(dev);
3946 struct snd_trident *trident = card->private_data; 3948 struct snd_trident *trident = card->private_data;
3947 3949
3948 pci_set_power_state(pci, PCI_D0); 3950 pci_set_power_state(pci, PCI_D0);
@@ -3979,4 +3981,6 @@ int snd_trident_resume(struct pci_dev *pci)
3979 trident->in_suspend = 0; 3981 trident->in_suspend = 0;
3980 return 0; 3982 return 0;
3981} 3983}
3984
3985SIMPLE_DEV_PM_OPS(snd_trident_pm, snd_trident_suspend, snd_trident_resume);
3982#endif /* CONFIG_PM */ 3986#endif /* CONFIG_PM */
diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c
index f9779e23fe5..3102a579660 100644
--- a/sound/pci/trident/trident_memory.c
+++ b/sound/pci/trident/trident_memory.c
@@ -29,7 +29,7 @@
29#include <linux/mutex.h> 29#include <linux/mutex.h>
30 30
31#include <sound/core.h> 31#include <sound/core.h>
32#include <sound/trident.h> 32#include "trident.h"
33 33
34/* page arguments of these two macros are Trident page (4096 bytes), not like 34/* page arguments of these two macros are Trident page (4096 bytes), not like
35 * aligned pages in others 35 * aligned pages in others
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c
index b5afab48943..0eb7245dd36 100644
--- a/sound/pci/via82xx.c
+++ b/sound/pci/via82xx.c
@@ -2242,9 +2242,10 @@ static int snd_via82xx_chip_init(struct via82xx *chip)
2242/* 2242/*
2243 * power management 2243 * power management
2244 */ 2244 */
2245static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state) 2245static int snd_via82xx_suspend(struct device *dev)
2246{ 2246{
2247 struct snd_card *card = pci_get_drvdata(pci); 2247 struct pci_dev *pci = to_pci_dev(dev);
2248 struct snd_card *card = dev_get_drvdata(dev);
2248 struct via82xx *chip = card->private_data; 2249 struct via82xx *chip = card->private_data;
2249 int i; 2250 int i;
2250 2251
@@ -2265,13 +2266,14 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
2265 2266
2266 pci_disable_device(pci); 2267 pci_disable_device(pci);
2267 pci_save_state(pci); 2268 pci_save_state(pci);
2268 pci_set_power_state(pci, pci_choose_state(pci, state)); 2269 pci_set_power_state(pci, PCI_D3hot);
2269 return 0; 2270 return 0;
2270} 2271}
2271 2272
2272static int snd_via82xx_resume(struct pci_dev *pci) 2273static int snd_via82xx_resume(struct device *dev)
2273{ 2274{
2274 struct snd_card *card = pci_get_drvdata(pci); 2275 struct pci_dev *pci = to_pci_dev(dev);
2276 struct snd_card *card = dev_get_drvdata(dev);
2275 struct via82xx *chip = card->private_data; 2277 struct via82xx *chip = card->private_data;
2276 int i; 2278 int i;
2277 2279
@@ -2306,6 +2308,11 @@ static int snd_via82xx_resume(struct pci_dev *pci)
2306 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2308 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2307 return 0; 2309 return 0;
2308} 2310}
2311
2312static SIMPLE_DEV_PM_OPS(snd_via82xx_pm, snd_via82xx_suspend, snd_via82xx_resume);
2313#define SND_VIA82XX_PM_OPS &snd_via82xx_pm
2314#else
2315#define SND_VIA82XX_PM_OPS NULL
2309#endif /* CONFIG_PM */ 2316#endif /* CONFIG_PM */
2310 2317
2311static int snd_via82xx_free(struct via82xx *chip) 2318static int snd_via82xx_free(struct via82xx *chip)
@@ -2624,10 +2631,9 @@ static struct pci_driver via82xx_driver = {
2624 .id_table = snd_via82xx_ids, 2631 .id_table = snd_via82xx_ids,
2625 .probe = snd_via82xx_probe, 2632 .probe = snd_via82xx_probe,
2626 .remove = __devexit_p(snd_via82xx_remove), 2633 .remove = __devexit_p(snd_via82xx_remove),
2627#ifdef CONFIG_PM 2634 .driver = {
2628 .suspend = snd_via82xx_suspend, 2635 .pm = SND_VIA82XX_PM_OPS,
2629 .resume = snd_via82xx_resume, 2636 },
2630#endif
2631}; 2637};
2632 2638
2633module_pci_driver(via82xx_driver); 2639module_pci_driver(via82xx_driver);
diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c
index 59fd47ed0a3..e886bc16999 100644
--- a/sound/pci/via82xx_modem.c
+++ b/sound/pci/via82xx_modem.c
@@ -1023,9 +1023,10 @@ static int snd_via82xx_chip_init(struct via82xx_modem *chip)
1023/* 1023/*
1024 * power management 1024 * power management
1025 */ 1025 */
1026static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state) 1026static int snd_via82xx_suspend(struct device *dev)
1027{ 1027{
1028 struct snd_card *card = pci_get_drvdata(pci); 1028 struct pci_dev *pci = to_pci_dev(dev);
1029 struct snd_card *card = dev_get_drvdata(dev);
1029 struct via82xx_modem *chip = card->private_data; 1030 struct via82xx_modem *chip = card->private_data;
1030 int i; 1031 int i;
1031 1032
@@ -1039,13 +1040,14 @@ static int snd_via82xx_suspend(struct pci_dev *pci, pm_message_t state)
1039 1040
1040 pci_disable_device(pci); 1041 pci_disable_device(pci);
1041 pci_save_state(pci); 1042 pci_save_state(pci);
1042 pci_set_power_state(pci, pci_choose_state(pci, state)); 1043 pci_set_power_state(pci, PCI_D3hot);
1043 return 0; 1044 return 0;
1044} 1045}
1045 1046
1046static int snd_via82xx_resume(struct pci_dev *pci) 1047static int snd_via82xx_resume(struct device *dev)
1047{ 1048{
1048 struct snd_card *card = pci_get_drvdata(pci); 1049 struct pci_dev *pci = to_pci_dev(dev);
1050 struct snd_card *card = dev_get_drvdata(dev);
1049 struct via82xx_modem *chip = card->private_data; 1051 struct via82xx_modem *chip = card->private_data;
1050 int i; 1052 int i;
1051 1053
@@ -1069,6 +1071,11 @@ static int snd_via82xx_resume(struct pci_dev *pci)
1069 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 1071 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
1070 return 0; 1072 return 0;
1071} 1073}
1074
1075static SIMPLE_DEV_PM_OPS(snd_via82xx_pm, snd_via82xx_suspend, snd_via82xx_resume);
1076#define SND_VIA82XX_PM_OPS &snd_via82xx_pm
1077#else
1078#define SND_VIA82XX_PM_OPS NULL
1072#endif /* CONFIG_PM */ 1079#endif /* CONFIG_PM */
1073 1080
1074static int snd_via82xx_free(struct via82xx_modem *chip) 1081static int snd_via82xx_free(struct via82xx_modem *chip)
@@ -1228,10 +1235,9 @@ static struct pci_driver via82xx_modem_driver = {
1228 .id_table = snd_via82xx_modem_ids, 1235 .id_table = snd_via82xx_modem_ids,
1229 .probe = snd_via82xx_probe, 1236 .probe = snd_via82xx_probe,
1230 .remove = __devexit_p(snd_via82xx_remove), 1237 .remove = __devexit_p(snd_via82xx_remove),
1231#ifdef CONFIG_PM 1238 .driver = {
1232 .suspend = snd_via82xx_suspend, 1239 .pm = SND_VIA82XX_PM_OPS,
1233 .resume = snd_via82xx_resume, 1240 },
1234#endif
1235}; 1241};
1236 1242
1237module_pci_driver(via82xx_modem_driver); 1243module_pci_driver(via82xx_modem_driver);
diff --git a/sound/pci/vx222/vx222.c b/sound/pci/vx222/vx222.c
index 1ea1f656a5d..b89e7a86e9d 100644
--- a/sound/pci/vx222/vx222.c
+++ b/sound/pci/vx222/vx222.c
@@ -258,22 +258,24 @@ static void __devexit snd_vx222_remove(struct pci_dev *pci)
258} 258}
259 259
260#ifdef CONFIG_PM 260#ifdef CONFIG_PM
261static int snd_vx222_suspend(struct pci_dev *pci, pm_message_t state) 261static int snd_vx222_suspend(struct device *dev)
262{ 262{
263 struct snd_card *card = pci_get_drvdata(pci); 263 struct pci_dev *pci = to_pci_dev(dev);
264 struct snd_card *card = dev_get_drvdata(dev);
264 struct snd_vx222 *vx = card->private_data; 265 struct snd_vx222 *vx = card->private_data;
265 int err; 266 int err;
266 267
267 err = snd_vx_suspend(&vx->core, state); 268 err = snd_vx_suspend(&vx->core);
268 pci_disable_device(pci); 269 pci_disable_device(pci);
269 pci_save_state(pci); 270 pci_save_state(pci);
270 pci_set_power_state(pci, pci_choose_state(pci, state)); 271 pci_set_power_state(pci, PCI_D3hot);
271 return err; 272 return err;
272} 273}
273 274
274static int snd_vx222_resume(struct pci_dev *pci) 275static int snd_vx222_resume(struct device *dev)
275{ 276{
276 struct snd_card *card = pci_get_drvdata(pci); 277 struct pci_dev *pci = to_pci_dev(dev);
278 struct snd_card *card = dev_get_drvdata(dev);
277 struct snd_vx222 *vx = card->private_data; 279 struct snd_vx222 *vx = card->private_data;
278 280
279 pci_set_power_state(pci, PCI_D0); 281 pci_set_power_state(pci, PCI_D0);
@@ -287,6 +289,11 @@ static int snd_vx222_resume(struct pci_dev *pci)
287 pci_set_master(pci); 289 pci_set_master(pci);
288 return snd_vx_resume(&vx->core); 290 return snd_vx_resume(&vx->core);
289} 291}
292
293static SIMPLE_DEV_PM_OPS(snd_vx222_pm, snd_vx222_suspend, snd_vx222_resume);
294#define SND_VX222_PM_OPS &snd_vx222_pm
295#else
296#define SND_VX222_PM_OPS NULL
290#endif 297#endif
291 298
292static struct pci_driver vx222_driver = { 299static struct pci_driver vx222_driver = {
@@ -294,10 +301,9 @@ static struct pci_driver vx222_driver = {
294 .id_table = snd_vx222_ids, 301 .id_table = snd_vx222_ids,
295 .probe = snd_vx222_probe, 302 .probe = snd_vx222_probe,
296 .remove = __devexit_p(snd_vx222_remove), 303 .remove = __devexit_p(snd_vx222_remove),
297#ifdef CONFIG_PM 304 .driver = {
298 .suspend = snd_vx222_suspend, 305 .pm = SND_VX222_PM_OPS,
299 .resume = snd_vx222_resume, 306 },
300#endif
301}; 307};
302 308
303module_pci_driver(vx222_driver); 309module_pci_driver(vx222_driver);
diff --git a/sound/pci/ymfpci/ymfpci.c b/sound/pci/ymfpci/ymfpci.c
index 9a1d01d653a..4810356b97b 100644
--- a/sound/pci/ymfpci/ymfpci.c
+++ b/sound/pci/ymfpci/ymfpci.c
@@ -24,7 +24,7 @@
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <sound/core.h> 26#include <sound/core.h>
27#include <sound/ymfpci.h> 27#include "ymfpci.h"
28#include <sound/mpu401.h> 28#include <sound/mpu401.h>
29#include <sound/opl3.h> 29#include <sound/opl3.h>
30#include <sound/initval.h> 30#include <sound/initval.h>
@@ -356,8 +356,9 @@ static struct pci_driver ymfpci_driver = {
356 .probe = snd_card_ymfpci_probe, 356 .probe = snd_card_ymfpci_probe,
357 .remove = __devexit_p(snd_card_ymfpci_remove), 357 .remove = __devexit_p(snd_card_ymfpci_remove),
358#ifdef CONFIG_PM 358#ifdef CONFIG_PM
359 .suspend = snd_ymfpci_suspend, 359 .driver = {
360 .resume = snd_ymfpci_resume, 360 .pm = &snd_ymfpci_pm,
361 },
361#endif 362#endif
362}; 363};
363 364
diff --git a/sound/pci/ymfpci/ymfpci.h b/sound/pci/ymfpci/ymfpci.h
new file mode 100644
index 00000000000..bddc4052286
--- /dev/null
+++ b/sound/pci/ymfpci/ymfpci.h
@@ -0,0 +1,389 @@
1#ifndef __SOUND_YMFPCI_H
2#define __SOUND_YMFPCI_H
3
4/*
5 * Copyright (c) by Jaroslav Kysela <perex@perex.cz>
6 * Definitions for Yahama YMF724/740/744/754 chips
7 *
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 *
23 */
24
25#include <sound/pcm.h>
26#include <sound/rawmidi.h>
27#include <sound/ac97_codec.h>
28#include <sound/timer.h>
29#include <linux/gameport.h>
30
31/*
32 * Direct registers
33 */
34
35#define YMFREG(chip, reg) (chip->port + YDSXGR_##reg)
36
37#define YDSXGR_INTFLAG 0x0004
38#define YDSXGR_ACTIVITY 0x0006
39#define YDSXGR_GLOBALCTRL 0x0008
40#define YDSXGR_ZVCTRL 0x000A
41#define YDSXGR_TIMERCTRL 0x0010
42#define YDSXGR_TIMERCOUNT 0x0012
43#define YDSXGR_SPDIFOUTCTRL 0x0018
44#define YDSXGR_SPDIFOUTSTATUS 0x001C
45#define YDSXGR_EEPROMCTRL 0x0020
46#define YDSXGR_SPDIFINCTRL 0x0034
47#define YDSXGR_SPDIFINSTATUS 0x0038
48#define YDSXGR_DSPPROGRAMDL 0x0048
49#define YDSXGR_DLCNTRL 0x004C
50#define YDSXGR_GPIOININTFLAG 0x0050
51#define YDSXGR_GPIOININTENABLE 0x0052
52#define YDSXGR_GPIOINSTATUS 0x0054
53#define YDSXGR_GPIOOUTCTRL 0x0056
54#define YDSXGR_GPIOFUNCENABLE 0x0058
55#define YDSXGR_GPIOTYPECONFIG 0x005A
56#define YDSXGR_AC97CMDDATA 0x0060
57#define YDSXGR_AC97CMDADR 0x0062
58#define YDSXGR_PRISTATUSDATA 0x0064
59#define YDSXGR_PRISTATUSADR 0x0066
60#define YDSXGR_SECSTATUSDATA 0x0068
61#define YDSXGR_SECSTATUSADR 0x006A
62#define YDSXGR_SECCONFIG 0x0070
63#define YDSXGR_LEGACYOUTVOL 0x0080
64#define YDSXGR_LEGACYOUTVOLL 0x0080
65#define YDSXGR_LEGACYOUTVOLR 0x0082
66#define YDSXGR_NATIVEDACOUTVOL 0x0084
67#define YDSXGR_NATIVEDACOUTVOLL 0x0084
68#define YDSXGR_NATIVEDACOUTVOLR 0x0086
69#define YDSXGR_ZVOUTVOL 0x0088
70#define YDSXGR_ZVOUTVOLL 0x0088
71#define YDSXGR_ZVOUTVOLR 0x008A
72#define YDSXGR_SECADCOUTVOL 0x008C
73#define YDSXGR_SECADCOUTVOLL 0x008C
74#define YDSXGR_SECADCOUTVOLR 0x008E
75#define YDSXGR_PRIADCOUTVOL 0x0090
76#define YDSXGR_PRIADCOUTVOLL 0x0090
77#define YDSXGR_PRIADCOUTVOLR 0x0092
78#define YDSXGR_LEGACYLOOPVOL 0x0094
79#define YDSXGR_LEGACYLOOPVOLL 0x0094
80#define YDSXGR_LEGACYLOOPVOLR 0x0096
81#define YDSXGR_NATIVEDACLOOPVOL 0x0098
82#define YDSXGR_NATIVEDACLOOPVOLL 0x0098
83#define YDSXGR_NATIVEDACLOOPVOLR 0x009A
84#define YDSXGR_ZVLOOPVOL 0x009C
85#define YDSXGR_ZVLOOPVOLL 0x009E
86#define YDSXGR_ZVLOOPVOLR 0x009E
87#define YDSXGR_SECADCLOOPVOL 0x00A0
88#define YDSXGR_SECADCLOOPVOLL 0x00A0
89#define YDSXGR_SECADCLOOPVOLR 0x00A2
90#define YDSXGR_PRIADCLOOPVOL 0x00A4
91#define YDSXGR_PRIADCLOOPVOLL 0x00A4
92#define YDSXGR_PRIADCLOOPVOLR 0x00A6
93#define YDSXGR_NATIVEADCINVOL 0x00A8
94#define YDSXGR_NATIVEADCINVOLL 0x00A8
95#define YDSXGR_NATIVEADCINVOLR 0x00AA
96#define YDSXGR_NATIVEDACINVOL 0x00AC
97#define YDSXGR_NATIVEDACINVOLL 0x00AC
98#define YDSXGR_NATIVEDACINVOLR 0x00AE
99#define YDSXGR_BUF441OUTVOL 0x00B0
100#define YDSXGR_BUF441OUTVOLL 0x00B0
101#define YDSXGR_BUF441OUTVOLR 0x00B2
102#define YDSXGR_BUF441LOOPVOL 0x00B4
103#define YDSXGR_BUF441LOOPVOLL 0x00B4
104#define YDSXGR_BUF441LOOPVOLR 0x00B6
105#define YDSXGR_SPDIFOUTVOL 0x00B8
106#define YDSXGR_SPDIFOUTVOLL 0x00B8
107#define YDSXGR_SPDIFOUTVOLR 0x00BA
108#define YDSXGR_SPDIFLOOPVOL 0x00BC
109#define YDSXGR_SPDIFLOOPVOLL 0x00BC
110#define YDSXGR_SPDIFLOOPVOLR 0x00BE
111#define YDSXGR_ADCSLOTSR 0x00C0
112#define YDSXGR_RECSLOTSR 0x00C4
113#define YDSXGR_ADCFORMAT 0x00C8
114#define YDSXGR_RECFORMAT 0x00CC
115#define YDSXGR_P44SLOTSR 0x00D0
116#define YDSXGR_STATUS 0x0100
117#define YDSXGR_CTRLSELECT 0x0104
118#define YDSXGR_MODE 0x0108
119#define YDSXGR_SAMPLECOUNT 0x010C
120#define YDSXGR_NUMOFSAMPLES 0x0110
121#define YDSXGR_CONFIG 0x0114
122#define YDSXGR_PLAYCTRLSIZE 0x0140
123#define YDSXGR_RECCTRLSIZE 0x0144
124#define YDSXGR_EFFCTRLSIZE 0x0148
125#define YDSXGR_WORKSIZE 0x014C
126#define YDSXGR_MAPOFREC 0x0150
127#define YDSXGR_MAPOFEFFECT 0x0154
128#define YDSXGR_PLAYCTRLBASE 0x0158
129#define YDSXGR_RECCTRLBASE 0x015C
130#define YDSXGR_EFFCTRLBASE 0x0160
131#define YDSXGR_WORKBASE 0x0164
132#define YDSXGR_DSPINSTRAM 0x1000
133#define YDSXGR_CTRLINSTRAM 0x4000
134
135#define YDSXG_AC97READCMD 0x8000
136#define YDSXG_AC97WRITECMD 0x0000
137
138#define PCIR_DSXG_LEGACY 0x40
139#define PCIR_DSXG_ELEGACY 0x42
140#define PCIR_DSXG_CTRL 0x48
141#define PCIR_DSXG_PWRCTRL1 0x4a
142#define PCIR_DSXG_PWRCTRL2 0x4e
143#define PCIR_DSXG_FMBASE 0x60
144#define PCIR_DSXG_SBBASE 0x62
145#define PCIR_DSXG_MPU401BASE 0x64
146#define PCIR_DSXG_JOYBASE 0x66
147
148#define YDSXG_DSPLENGTH 0x0080
149#define YDSXG_CTRLLENGTH 0x3000
150
151#define YDSXG_DEFAULT_WORK_SIZE 0x0400
152
153#define YDSXG_PLAYBACK_VOICES 64
154#define YDSXG_CAPTURE_VOICES 2
155#define YDSXG_EFFECT_VOICES 5
156
157#define YMFPCI_LEGACY_SBEN (1 << 0) /* soundblaster enable */
158#define YMFPCI_LEGACY_FMEN (1 << 1) /* OPL3 enable */
159#define YMFPCI_LEGACY_JPEN (1 << 2) /* joystick enable */
160#define YMFPCI_LEGACY_MEN (1 << 3) /* MPU401 enable */
161#define YMFPCI_LEGACY_MIEN (1 << 4) /* MPU RX irq enable */
162#define YMFPCI_LEGACY_IOBITS (1 << 5) /* i/o bits range, 0 = 16bit, 1 =10bit */
163#define YMFPCI_LEGACY_SDMA (3 << 6) /* SB DMA select */
164#define YMFPCI_LEGACY_SBIRQ (7 << 8) /* SB IRQ select */
165#define YMFPCI_LEGACY_MPUIRQ (7 << 11) /* MPU IRQ select */
166#define YMFPCI_LEGACY_SIEN (1 << 14) /* serialized IRQ */
167#define YMFPCI_LEGACY_LAD (1 << 15) /* legacy audio disable */
168
169#define YMFPCI_LEGACY2_FMIO (3 << 0) /* OPL3 i/o address (724/740) */
170#define YMFPCI_LEGACY2_SBIO (3 << 2) /* SB i/o address (724/740) */
171#define YMFPCI_LEGACY2_MPUIO (3 << 4) /* MPU401 i/o address (724/740) */
172#define YMFPCI_LEGACY2_JSIO (3 << 6) /* joystick i/o address (724/740) */
173#define YMFPCI_LEGACY2_MAIM (1 << 8) /* MPU401 ack intr mask */
174#define YMFPCI_LEGACY2_SMOD (3 << 11) /* SB DMA mode */
175#define YMFPCI_LEGACY2_SBVER (3 << 13) /* SB version select */
176#define YMFPCI_LEGACY2_IMOD (1 << 15) /* legacy IRQ mode */
177/* SIEN:IMOD 0:0 = legacy irq, 0:1 = INTA, 1:0 = serialized IRQ */
178
179#if defined(CONFIG_GAMEPORT) || (defined(MODULE) && defined(CONFIG_GAMEPORT_MODULE))
180#define SUPPORT_JOYSTICK
181#endif
182
183/*
184 *
185 */
186
187struct snd_ymfpci_playback_bank {
188 u32 format;
189 u32 loop_default;
190 u32 base; /* 32-bit address */
191 u32 loop_start; /* 32-bit offset */
192 u32 loop_end; /* 32-bit offset */
193 u32 loop_frac; /* 8-bit fraction - loop_start */
194 u32 delta_end; /* pitch delta end */
195 u32 lpfK_end;
196 u32 eg_gain_end;
197 u32 left_gain_end;
198 u32 right_gain_end;
199 u32 eff1_gain_end;
200 u32 eff2_gain_end;
201 u32 eff3_gain_end;
202 u32 lpfQ;
203 u32 status;
204 u32 num_of_frames;
205 u32 loop_count;
206 u32 start;
207 u32 start_frac;
208 u32 delta;
209 u32 lpfK;
210 u32 eg_gain;
211 u32 left_gain;
212 u32 right_gain;
213 u32 eff1_gain;
214 u32 eff2_gain;
215 u32 eff3_gain;
216 u32 lpfD1;
217 u32 lpfD2;
218 };
219
220struct snd_ymfpci_capture_bank {
221 u32 base; /* 32-bit address */
222 u32 loop_end; /* 32-bit offset */
223 u32 start; /* 32-bit offset */
224 u32 num_of_loops; /* counter */
225};
226
227struct snd_ymfpci_effect_bank {
228 u32 base; /* 32-bit address */
229 u32 loop_end; /* 32-bit offset */
230 u32 start; /* 32-bit offset */
231 u32 temp;
232};
233
234struct snd_ymfpci_pcm;
235struct snd_ymfpci;
236
237enum snd_ymfpci_voice_type {
238 YMFPCI_PCM,
239 YMFPCI_SYNTH,
240 YMFPCI_MIDI
241};
242
243struct snd_ymfpci_voice {
244 struct snd_ymfpci *chip;
245 int number;
246 unsigned int use: 1,
247 pcm: 1,
248 synth: 1,
249 midi: 1;
250 struct snd_ymfpci_playback_bank *bank;
251 dma_addr_t bank_addr;
252 void (*interrupt)(struct snd_ymfpci *chip, struct snd_ymfpci_voice *voice);
253 struct snd_ymfpci_pcm *ypcm;
254};
255
256enum snd_ymfpci_pcm_type {
257 PLAYBACK_VOICE,
258 CAPTURE_REC,
259 CAPTURE_AC97,
260 EFFECT_DRY_LEFT,
261 EFFECT_DRY_RIGHT,
262 EFFECT_EFF1,
263 EFFECT_EFF2,
264 EFFECT_EFF3
265};
266
267struct snd_ymfpci_pcm {
268 struct snd_ymfpci *chip;
269 enum snd_ymfpci_pcm_type type;
270 struct snd_pcm_substream *substream;
271 struct snd_ymfpci_voice *voices[2]; /* playback only */
272 unsigned int running: 1,
273 use_441_slot: 1,
274 output_front: 1,
275 output_rear: 1,
276 swap_rear: 1;
277 unsigned int update_pcm_vol;
278 u32 period_size; /* cached from runtime->period_size */
279 u32 buffer_size; /* cached from runtime->buffer_size */
280 u32 period_pos;
281 u32 last_pos;
282 u32 capture_bank_number;
283 u32 shift;
284};
285
286struct snd_ymfpci {
287 int irq;
288
289 unsigned int device_id; /* PCI device ID */
290 unsigned char rev; /* PCI revision */
291 unsigned long reg_area_phys;
292 void __iomem *reg_area_virt;
293 struct resource *res_reg_area;
294 struct resource *fm_res;
295 struct resource *mpu_res;
296
297 unsigned short old_legacy_ctrl;
298#ifdef SUPPORT_JOYSTICK
299 struct gameport *gameport;
300#endif
301
302 struct snd_dma_buffer work_ptr;
303
304 unsigned int bank_size_playback;
305 unsigned int bank_size_capture;
306 unsigned int bank_size_effect;
307 unsigned int work_size;
308
309 void *bank_base_playback;
310 void *bank_base_capture;
311 void *bank_base_effect;
312 void *work_base;
313 dma_addr_t bank_base_playback_addr;
314 dma_addr_t bank_base_capture_addr;
315 dma_addr_t bank_base_effect_addr;
316 dma_addr_t work_base_addr;
317 struct snd_dma_buffer ac3_tmp_base;
318
319 u32 *ctrl_playback;
320 struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2];
321 struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2];
322 struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2];
323
324 int start_count;
325
326 u32 active_bank;
327 struct snd_ymfpci_voice voices[64];
328 int src441_used;
329
330 struct snd_ac97_bus *ac97_bus;
331 struct snd_ac97 *ac97;
332 struct snd_rawmidi *rawmidi;
333 struct snd_timer *timer;
334 unsigned int timer_ticks;
335
336 struct pci_dev *pci;
337 struct snd_card *card;
338 struct snd_pcm *pcm;
339 struct snd_pcm *pcm2;
340 struct snd_pcm *pcm_spdif;
341 struct snd_pcm *pcm_4ch;
342 struct snd_pcm_substream *capture_substream[YDSXG_CAPTURE_VOICES];
343 struct snd_pcm_substream *effect_substream[YDSXG_EFFECT_VOICES];
344 struct snd_kcontrol *ctl_vol_recsrc;
345 struct snd_kcontrol *ctl_vol_adcrec;
346 struct snd_kcontrol *ctl_vol_spdifrec;
347 unsigned short spdif_bits, spdif_pcm_bits;
348 struct snd_kcontrol *spdif_pcm_ctl;
349 int mode_dup4ch;
350 int rear_opened;
351 int spdif_opened;
352 struct snd_ymfpci_pcm_mixer {
353 u16 left;
354 u16 right;
355 struct snd_kcontrol *ctl;
356 } pcm_mixer[32];
357
358 spinlock_t reg_lock;
359 spinlock_t voice_lock;
360 wait_queue_head_t interrupt_sleep;
361 atomic_t interrupt_sleep_count;
362 struct snd_info_entry *proc_entry;
363 const struct firmware *dsp_microcode;
364 const struct firmware *controller_microcode;
365
366#ifdef CONFIG_PM
367 u32 *saved_regs;
368 u32 saved_ydsxgr_mode;
369 u16 saved_dsxg_legacy;
370 u16 saved_dsxg_elegacy;
371#endif
372};
373
374int snd_ymfpci_create(struct snd_card *card,
375 struct pci_dev *pci,
376 unsigned short old_legacy_ctrl,
377 struct snd_ymfpci ** rcodec);
378void snd_ymfpci_free_gameport(struct snd_ymfpci *chip);
379
380extern const struct dev_pm_ops snd_ymfpci_pm;
381
382int snd_ymfpci_pcm(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
383int snd_ymfpci_pcm2(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
384int snd_ymfpci_pcm_spdif(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
385int snd_ymfpci_pcm_4ch(struct snd_ymfpci *chip, int device, struct snd_pcm **rpcm);
386int snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch);
387int snd_ymfpci_timer(struct snd_ymfpci *chip, int device);
388
389#endif /* __SOUND_YMFPCI_H */
diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c
index a8159b81e9c..62b23635b75 100644
--- a/sound/pci/ymfpci/ymfpci_main.c
+++ b/sound/pci/ymfpci/ymfpci_main.c
@@ -33,7 +33,7 @@
33#include <sound/control.h> 33#include <sound/control.h>
34#include <sound/info.h> 34#include <sound/info.h>
35#include <sound/tlv.h> 35#include <sound/tlv.h>
36#include <sound/ymfpci.h> 36#include "ymfpci.h"
37#include <sound/asoundef.h> 37#include <sound/asoundef.h>
38#include <sound/mpu401.h> 38#include <sound/mpu401.h>
39 39
@@ -2302,9 +2302,10 @@ static int saved_regs_index[] = {
2302}; 2302};
2303#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index) 2303#define YDSXGR_NUM_SAVED_REGS ARRAY_SIZE(saved_regs_index)
2304 2304
2305int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state) 2305static int snd_ymfpci_suspend(struct device *dev)
2306{ 2306{
2307 struct snd_card *card = pci_get_drvdata(pci); 2307 struct pci_dev *pci = to_pci_dev(dev);
2308 struct snd_card *card = dev_get_drvdata(dev);
2308 struct snd_ymfpci *chip = card->private_data; 2309 struct snd_ymfpci *chip = card->private_data;
2309 unsigned int i; 2310 unsigned int i;
2310 2311
@@ -2326,13 +2327,14 @@ int snd_ymfpci_suspend(struct pci_dev *pci, pm_message_t state)
2326 snd_ymfpci_disable_dsp(chip); 2327 snd_ymfpci_disable_dsp(chip);
2327 pci_disable_device(pci); 2328 pci_disable_device(pci);
2328 pci_save_state(pci); 2329 pci_save_state(pci);
2329 pci_set_power_state(pci, pci_choose_state(pci, state)); 2330 pci_set_power_state(pci, PCI_D3hot);
2330 return 0; 2331 return 0;
2331} 2332}
2332 2333
2333int snd_ymfpci_resume(struct pci_dev *pci) 2334static int snd_ymfpci_resume(struct device *dev)
2334{ 2335{
2335 struct snd_card *card = pci_get_drvdata(pci); 2336 struct pci_dev *pci = to_pci_dev(dev);
2337 struct snd_card *card = dev_get_drvdata(dev);
2336 struct snd_ymfpci *chip = card->private_data; 2338 struct snd_ymfpci *chip = card->private_data;
2337 unsigned int i; 2339 unsigned int i;
2338 2340
@@ -2370,6 +2372,8 @@ int snd_ymfpci_resume(struct pci_dev *pci)
2370 snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2372 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2371 return 0; 2373 return 0;
2372} 2374}
2375
2376SIMPLE_DEV_PM_OPS(snd_ymfpci_pm, snd_ymfpci_suspend, snd_ymfpci_resume);
2373#endif /* CONFIG_PM */ 2377#endif /* CONFIG_PM */
2374 2378
2375int __devinit snd_ymfpci_create(struct snd_card *card, 2379int __devinit snd_ymfpci_create(struct snd_card *card,
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c
index 830839a874b..f9b5229b272 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c
@@ -251,7 +251,7 @@ static int pdacf_suspend(struct pcmcia_device *link)
251 snd_printdd(KERN_DEBUG "SUSPEND\n"); 251 snd_printdd(KERN_DEBUG "SUSPEND\n");
252 if (chip) { 252 if (chip) {
253 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n"); 253 snd_printdd(KERN_DEBUG "snd_pdacf_suspend calling\n");
254 snd_pdacf_suspend(chip, PMSG_SUSPEND); 254 snd_pdacf_suspend(chip);
255 } 255 }
256 256
257 return 0; 257 return 0;
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.h b/sound/pcmcia/pdaudiocf/pdaudiocf.h
index 6ce9ad70029..ea41e57d717 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf.h
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf.h
@@ -131,7 +131,7 @@ struct snd_pdacf *snd_pdacf_create(struct snd_card *card);
131int snd_pdacf_ak4117_create(struct snd_pdacf *pdacf); 131int snd_pdacf_ak4117_create(struct snd_pdacf *pdacf);
132void snd_pdacf_powerdown(struct snd_pdacf *chip); 132void snd_pdacf_powerdown(struct snd_pdacf *chip);
133#ifdef CONFIG_PM 133#ifdef CONFIG_PM
134int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state); 134int snd_pdacf_suspend(struct snd_pdacf *chip);
135int snd_pdacf_resume(struct snd_pdacf *chip); 135int snd_pdacf_resume(struct snd_pdacf *chip);
136#endif 136#endif
137int snd_pdacf_pcm_new(struct snd_pdacf *chip); 137int snd_pdacf_pcm_new(struct snd_pdacf *chip);
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
index 9dce0bde5c0..ea0adfb984a 100644
--- a/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
+++ b/sound/pcmcia/pdaudiocf/pdaudiocf_core.c
@@ -262,7 +262,7 @@ void snd_pdacf_powerdown(struct snd_pdacf *chip)
262 262
263#ifdef CONFIG_PM 263#ifdef CONFIG_PM
264 264
265int snd_pdacf_suspend(struct snd_pdacf *chip, pm_message_t state) 265int snd_pdacf_suspend(struct snd_pdacf *chip)
266{ 266{
267 u16 val; 267 u16 val;
268 268
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c
index 512f0b47237..8f9350475c7 100644
--- a/sound/pcmcia/vx/vxpocket.c
+++ b/sound/pcmcia/vx/vxpocket.c
@@ -260,7 +260,7 @@ static int vxp_suspend(struct pcmcia_device *link)
260 snd_printdd(KERN_DEBUG "SUSPEND\n"); 260 snd_printdd(KERN_DEBUG "SUSPEND\n");
261 if (chip) { 261 if (chip) {
262 snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n"); 262 snd_printdd(KERN_DEBUG "snd_vx_suspend calling\n");
263 snd_vx_suspend(chip, PMSG_SUSPEND); 263 snd_vx_suspend(chip);
264 } 264 }
265 265
266 return 0; 266 return 0;
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c
index 5a4e263b5b0..f5ceb6f282d 100644
--- a/sound/ppc/powermac.c
+++ b/sound/ppc/powermac.c
@@ -144,19 +144,24 @@ static int __devexit snd_pmac_remove(struct platform_device *devptr)
144} 144}
145 145
146#ifdef CONFIG_PM 146#ifdef CONFIG_PM
147static int snd_pmac_driver_suspend(struct platform_device *devptr, pm_message_t state) 147static int snd_pmac_driver_suspend(struct device *dev)
148{ 148{
149 struct snd_card *card = platform_get_drvdata(devptr); 149 struct snd_card *card = dev_get_drvdata(dev);
150 snd_pmac_suspend(card->private_data); 150 snd_pmac_suspend(card->private_data);
151 return 0; 151 return 0;
152} 152}
153 153
154static int snd_pmac_driver_resume(struct platform_device *devptr) 154static int snd_pmac_driver_resume(struct device *dev)
155{ 155{
156 struct snd_card *card = platform_get_drvdata(devptr); 156 struct snd_card *card = dev_get_drvdata(dev);
157 snd_pmac_resume(card->private_data); 157 snd_pmac_resume(card->private_data);
158 return 0; 158 return 0;
159} 159}
160
161static SIMPLE_DEV_PM_OPS(snd_pmac_pm, snd_pmac_driver_suspend, snd_pmac_driver_resume);
162#define SND_PMAC_PM_OPS &snd_pmac_pm
163#else
164#define SND_PMAC_PM_OPS NULL
160#endif 165#endif
161 166
162#define SND_PMAC_DRIVER "snd_powermac" 167#define SND_PMAC_DRIVER "snd_powermac"
@@ -164,12 +169,10 @@ static int snd_pmac_driver_resume(struct platform_device *devptr)
164static struct platform_driver snd_pmac_driver = { 169static struct platform_driver snd_pmac_driver = {
165 .probe = snd_pmac_probe, 170 .probe = snd_pmac_probe,
166 .remove = __devexit_p(snd_pmac_remove), 171 .remove = __devexit_p(snd_pmac_remove),
167#ifdef CONFIG_PM
168 .suspend = snd_pmac_driver_suspend,
169 .resume = snd_pmac_driver_resume,
170#endif
171 .driver = { 172 .driver = {
172 .name = SND_PMAC_DRIVER 173 .name = SND_PMAC_DRIVER,
174 .owner = THIS_MODULE,
175 .pm = SND_PMAC_PM_OPS,
173 }, 176 },
174}; 177};
175 178
diff --git a/sound/sh/aica.c b/sound/sh/aica.c
index 391a38ca58b..d48b523207e 100644
--- a/sound/sh/aica.c
+++ b/sound/sh/aica.c
@@ -654,7 +654,9 @@ static struct platform_driver snd_aica_driver = {
654 .probe = snd_aica_probe, 654 .probe = snd_aica_probe,
655 .remove = __devexit_p(snd_aica_remove), 655 .remove = __devexit_p(snd_aica_remove),
656 .driver = { 656 .driver = {
657 .name = SND_AICA_DRIVER}, 657 .name = SND_AICA_DRIVER,
658 .owner = THIS_MODULE,
659 },
658}; 660};
659 661
660static int __init aica_init(void) 662static int __init aica_init(void)
diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c
index f8b01c77b29..0a3394751ed 100644
--- a/sound/sh/sh_dac_audio.c
+++ b/sound/sh/sh_dac_audio.c
@@ -438,6 +438,7 @@ static struct platform_driver sh_dac_driver = {
438 .remove = snd_sh_dac_remove, 438 .remove = snd_sh_dac_remove,
439 .driver = { 439 .driver = {
440 .name = "dac_audio", 440 .name = "dac_audio",
441 .owner = THIS_MODULE,
441 }, 442 },
442}; 443};
443 444
diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig
index 40b2ad1bb1c..c5de0a84566 100644
--- a/sound/soc/Kconfig
+++ b/sound/soc/Kconfig
@@ -33,6 +33,7 @@ source "sound/soc/atmel/Kconfig"
33source "sound/soc/au1x/Kconfig" 33source "sound/soc/au1x/Kconfig"
34source "sound/soc/blackfin/Kconfig" 34source "sound/soc/blackfin/Kconfig"
35source "sound/soc/davinci/Kconfig" 35source "sound/soc/davinci/Kconfig"
36source "sound/soc/dwc/Kconfig"
36source "sound/soc/ep93xx/Kconfig" 37source "sound/soc/ep93xx/Kconfig"
37source "sound/soc/fsl/Kconfig" 38source "sound/soc/fsl/Kconfig"
38source "sound/soc/jz4740/Kconfig" 39source "sound/soc/jz4740/Kconfig"
diff --git a/sound/soc/Makefile b/sound/soc/Makefile
index 70990f4017f..00a555a743b 100644
--- a/sound/soc/Makefile
+++ b/sound/soc/Makefile
@@ -11,6 +11,7 @@ obj-$(CONFIG_SND_SOC) += atmel/
11obj-$(CONFIG_SND_SOC) += au1x/ 11obj-$(CONFIG_SND_SOC) += au1x/
12obj-$(CONFIG_SND_SOC) += blackfin/ 12obj-$(CONFIG_SND_SOC) += blackfin/
13obj-$(CONFIG_SND_SOC) += davinci/ 13obj-$(CONFIG_SND_SOC) += davinci/
14obj-$(CONFIG_SND_SOC) += dwc/
14obj-$(CONFIG_SND_SOC) += ep93xx/ 15obj-$(CONFIG_SND_SOC) += ep93xx/
15obj-$(CONFIG_SND_SOC) += fsl/ 16obj-$(CONFIG_SND_SOC) += fsl/
16obj-$(CONFIG_SND_SOC) += jz4740/ 17obj-$(CONFIG_SND_SOC) += jz4740/
diff --git a/sound/soc/blackfin/Kconfig b/sound/soc/blackfin/Kconfig
index 9f6bc55fc39..16b88f5c26e 100644
--- a/sound/soc/blackfin/Kconfig
+++ b/sound/soc/blackfin/Kconfig
@@ -1,7 +1,8 @@
1config SND_BF5XX_I2S 1config SND_BF5XX_I2S
2 tristate "SoC I2S Audio for the ADI BF5xx chip" 2 tristate "SoC I2S Audio for the ADI Blackfin chip"
3 depends on BLACKFIN 3 depends on BLACKFIN
4 select SND_BF5XX_SOC_SPORT 4 select SND_BF5XX_SOC_SPORT if !BF60x
5 select SND_BF6XX_SOC_SPORT if BF60x
5 help 6 help
6 Say Y or M if you want to add support for codecs attached to 7 Say Y or M if you want to add support for codecs attached to
7 the Blackfin SPORT (synchronous serial ports) interface in I2S 8 the Blackfin SPORT (synchronous serial ports) interface in I2S
@@ -9,12 +10,14 @@ config SND_BF5XX_I2S
9 You will also need to select the audio interfaces to support below. 10 You will also need to select the audio interfaces to support below.
10 11
11config SND_BF5XX_SOC_SSM2602 12config SND_BF5XX_SOC_SSM2602
12 tristate "SoC SSM2602 Audio support for BF52x ezkit" 13 tristate "SoC SSM2602 Audio Codec Add-On Card support"
13 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C) 14 depends on SND_BF5XX_I2S && (SPI_MASTER || I2C)
14 select SND_BF5XX_SOC_I2S 15 select SND_BF5XX_SOC_I2S if !BF60x
16 select SND_BF6XX_SOC_I2S if BF60x
15 select SND_SOC_SSM2602 17 select SND_SOC_SSM2602
16 help 18 help
17 Say Y if you want to add support for SoC audio on BF527-EZKIT. 19 Say Y if you want to add support for the Analog Devices
20 SSM2602 Audio Codec Add-On Card.
18 21
19config SND_SOC_BFIN_EVAL_ADAU1701 22config SND_SOC_BFIN_EVAL_ADAU1701
20 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards" 23 tristate "Support for the EVAL-ADAU1701MINIZ board on Blackfin eval boards"
@@ -162,9 +165,15 @@ config SND_BF5XX_SOC_AD1980
162config SND_BF5XX_SOC_SPORT 165config SND_BF5XX_SOC_SPORT
163 tristate 166 tristate
164 167
168config SND_BF6XX_SOC_SPORT
169 tristate
170
165config SND_BF5XX_SOC_I2S 171config SND_BF5XX_SOC_I2S
166 tristate 172 tristate
167 173
174config SND_BF6XX_SOC_I2S
175 tristate
176
168config SND_BF5XX_SOC_TDM 177config SND_BF5XX_SOC_TDM
169 tristate 178 tristate
170 179
@@ -173,7 +182,7 @@ config SND_BF5XX_SOC_AC97
173 182
174config SND_BF5XX_SPORT_NUM 183config SND_BF5XX_SPORT_NUM
175 int "Set a SPORT for Sound chip" 184 int "Set a SPORT for Sound chip"
176 depends on (SND_BF5XX_I2S || SND_BF5XX_AC97 || SND_BF5XX_TDM) 185 depends on (SND_BF5XX_SOC_SPORT || SND_BF6XX_SOC_SPORT)
177 range 0 3 if BF54x 186 range 0 3 if BF54x
178 range 0 1 if !BF54x 187 range 0 1 if !BF54x
179 default 0 188 default 0
diff --git a/sound/soc/blackfin/Makefile b/sound/soc/blackfin/Makefile
index 1bf86ccaa8d..6fea1f4cbee 100644
--- a/sound/soc/blackfin/Makefile
+++ b/sound/soc/blackfin/Makefile
@@ -3,16 +3,20 @@ snd-bf5xx-ac97-objs := bf5xx-ac97-pcm.o
3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o 3snd-bf5xx-i2s-objs := bf5xx-i2s-pcm.o
4snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o 4snd-bf5xx-tdm-objs := bf5xx-tdm-pcm.o
5snd-soc-bf5xx-sport-objs := bf5xx-sport.o 5snd-soc-bf5xx-sport-objs := bf5xx-sport.o
6snd-soc-bf6xx-sport-objs := bf6xx-sport.o
6snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o 7snd-soc-bf5xx-ac97-objs := bf5xx-ac97.o
7snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o 8snd-soc-bf5xx-i2s-objs := bf5xx-i2s.o
9snd-soc-bf6xx-i2s-objs := bf6xx-i2s.o
8snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o 10snd-soc-bf5xx-tdm-objs := bf5xx-tdm.o
9 11
10obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o 12obj-$(CONFIG_SND_BF5XX_AC97) += snd-bf5xx-ac97.o
11obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o 13obj-$(CONFIG_SND_BF5XX_I2S) += snd-bf5xx-i2s.o
12obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o 14obj-$(CONFIG_SND_BF5XX_TDM) += snd-bf5xx-tdm.o
13obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o 15obj-$(CONFIG_SND_BF5XX_SOC_SPORT) += snd-soc-bf5xx-sport.o
16obj-$(CONFIG_SND_BF6XX_SOC_SPORT) += snd-soc-bf6xx-sport.o
14obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o 17obj-$(CONFIG_SND_BF5XX_SOC_AC97) += snd-soc-bf5xx-ac97.o
15obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o 18obj-$(CONFIG_SND_BF5XX_SOC_I2S) += snd-soc-bf5xx-i2s.o
19obj-$(CONFIG_SND_BF6XX_SOC_I2S) += snd-soc-bf6xx-i2s.o
16obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o 20obj-$(CONFIG_SND_BF5XX_SOC_TDM) += snd-soc-bf5xx-tdm.o
17 21
18# Blackfin Machine Support 22# Blackfin Machine Support
diff --git a/sound/soc/blackfin/bf6xx-i2s.c b/sound/soc/blackfin/bf6xx-i2s.c
new file mode 100644
index 00000000000..c3c2466d3a4
--- /dev/null
+++ b/sound/soc/blackfin/bf6xx-i2s.c
@@ -0,0 +1,234 @@
1/*
2 * bf6xx-i2s.c - Analog Devices BF6XX i2s interface driver
3 *
4 * Copyright (c) 2012 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/device.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/platform_device.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dai.h>
28
29#include "bf6xx-sport.h"
30
31struct sport_params param;
32
33static int bfin_i2s_set_dai_fmt(struct snd_soc_dai *cpu_dai,
34 unsigned int fmt)
35{
36 struct sport_device *sport = snd_soc_dai_get_drvdata(cpu_dai);
37 struct device *dev = &sport->pdev->dev;
38 int ret = 0;
39
40 param.spctl &= ~(SPORT_CTL_OPMODE | SPORT_CTL_CKRE | SPORT_CTL_FSR
41 | SPORT_CTL_LFS | SPORT_CTL_LAFS);
42 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
43 case SND_SOC_DAIFMT_I2S:
44 param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_CKRE
45 | SPORT_CTL_LFS;
46 break;
47 case SND_SOC_DAIFMT_DSP_A:
48 param.spctl |= SPORT_CTL_FSR;
49 break;
50 case SND_SOC_DAIFMT_LEFT_J:
51 param.spctl |= SPORT_CTL_OPMODE | SPORT_CTL_LFS
52 | SPORT_CTL_LAFS;
53 break;
54 default:
55 dev_err(dev, "%s: Unknown DAI format type\n", __func__);
56 ret = -EINVAL;
57 break;
58 }
59
60 param.spctl &= ~(SPORT_CTL_ICLK | SPORT_CTL_IFS);
61 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
62 case SND_SOC_DAIFMT_CBM_CFM:
63 break;
64 case SND_SOC_DAIFMT_CBS_CFS:
65 case SND_SOC_DAIFMT_CBM_CFS:
66 case SND_SOC_DAIFMT_CBS_CFM:
67 ret = -EINVAL;
68 break;
69 default:
70 dev_err(dev, "%s: Unknown DAI master type\n", __func__);
71 ret = -EINVAL;
72 break;
73 }
74
75 return ret;
76}
77
78static int bfin_i2s_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params,
80 struct snd_soc_dai *dai)
81{
82 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
83 struct device *dev = &sport->pdev->dev;
84 int ret = 0;
85
86 param.spctl &= ~SPORT_CTL_SLEN;
87 switch (params_format(params)) {
88 case SNDRV_PCM_FORMAT_S8:
89 param.spctl |= 0x70;
90 sport->wdsize = 1;
91 case SNDRV_PCM_FORMAT_S16_LE:
92 param.spctl |= 0xf0;
93 sport->wdsize = 2;
94 break;
95 case SNDRV_PCM_FORMAT_S24_LE:
96 param.spctl |= 0x170;
97 sport->wdsize = 3;
98 break;
99 case SNDRV_PCM_FORMAT_S32_LE:
100 param.spctl |= 0x1f0;
101 sport->wdsize = 4;
102 break;
103 }
104
105 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
106 ret = sport_set_tx_params(sport, &param);
107 if (ret) {
108 dev_err(dev, "SPORT tx is busy!\n");
109 return ret;
110 }
111 } else {
112 ret = sport_set_rx_params(sport, &param);
113 if (ret) {
114 dev_err(dev, "SPORT rx is busy!\n");
115 return ret;
116 }
117 }
118 return 0;
119}
120
121#ifdef CONFIG_PM
122static int bfin_i2s_suspend(struct snd_soc_dai *dai)
123{
124 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
125
126 if (dai->capture_active)
127 sport_rx_stop(sport);
128 if (dai->playback_active)
129 sport_tx_stop(sport);
130 return 0;
131}
132
133static int bfin_i2s_resume(struct snd_soc_dai *dai)
134{
135 struct sport_device *sport = snd_soc_dai_get_drvdata(dai);
136 struct device *dev = &sport->pdev->dev;
137 int ret;
138
139 ret = sport_set_tx_params(sport, &param);
140 if (ret) {
141 dev_err(dev, "SPORT tx is busy!\n");
142 return ret;
143 }
144 ret = sport_set_rx_params(sport, &param);
145 if (ret) {
146 dev_err(dev, "SPORT rx is busy!\n");
147 return ret;
148 }
149
150 return 0;
151}
152
153#else
154#define bfin_i2s_suspend NULL
155#define bfin_i2s_resume NULL
156#endif
157
158#define BFIN_I2S_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
159 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | \
160 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 | \
161 SNDRV_PCM_RATE_96000)
162
163#define BFIN_I2S_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
164 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
165
166static struct snd_soc_dai_ops bfin_i2s_dai_ops = {
167 .hw_params = bfin_i2s_hw_params,
168 .set_fmt = bfin_i2s_set_dai_fmt,
169};
170
171static struct snd_soc_dai_driver bfin_i2s_dai = {
172 .suspend = bfin_i2s_suspend,
173 .resume = bfin_i2s_resume,
174 .playback = {
175 .channels_min = 1,
176 .channels_max = 2,
177 .rates = BFIN_I2S_RATES,
178 .formats = BFIN_I2S_FORMATS,
179 },
180 .capture = {
181 .channels_min = 1,
182 .channels_max = 2,
183 .rates = BFIN_I2S_RATES,
184 .formats = BFIN_I2S_FORMATS,
185 },
186 .ops = &bfin_i2s_dai_ops,
187};
188
189static int __devinit bfin_i2s_probe(struct platform_device *pdev)
190{
191 struct sport_device *sport;
192 struct device *dev = &pdev->dev;
193 int ret;
194
195 sport = sport_create(pdev);
196 if (!sport)
197 return -ENODEV;
198
199 /* register with the ASoC layers */
200 ret = snd_soc_register_dai(dev, &bfin_i2s_dai);
201 if (ret) {
202 dev_err(dev, "Failed to register DAI: %d\n", ret);
203 sport_delete(sport);
204 return ret;
205 }
206 platform_set_drvdata(pdev, sport);
207
208 return 0;
209}
210
211static int __devexit bfin_i2s_remove(struct platform_device *pdev)
212{
213 struct sport_device *sport = platform_get_drvdata(pdev);
214
215 snd_soc_unregister_dai(&pdev->dev);
216 sport_delete(sport);
217
218 return 0;
219}
220
221static struct platform_driver bfin_i2s_driver = {
222 .probe = bfin_i2s_probe,
223 .remove = __devexit_p(bfin_i2s_remove),
224 .driver = {
225 .name = "bfin-i2s",
226 .owner = THIS_MODULE,
227 },
228};
229
230module_platform_driver(bfin_i2s_driver);
231
232MODULE_DESCRIPTION("Analog Devices BF6XX i2s interface driver");
233MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
234MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c
new file mode 100644
index 00000000000..318c5ba5360
--- /dev/null
+++ b/sound/soc/blackfin/bf6xx-sport.c
@@ -0,0 +1,422 @@
1/*
2 * bf6xx_sport.c Analog Devices BF6XX SPORT driver
3 *
4 * Copyright (c) 2012 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/device.h>
21#include <linux/dma-mapping.h>
22#include <linux/interrupt.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/slab.h>
26
27#include <asm/blackfin.h>
28#include <asm/dma.h>
29#include <asm/portmux.h>
30
31#include "bf6xx-sport.h"
32
33int sport_set_tx_params(struct sport_device *sport,
34 struct sport_params *params)
35{
36 if (sport->tx_regs->spctl & SPORT_CTL_SPENPRI)
37 return -EBUSY;
38 sport->tx_regs->spctl = params->spctl | SPORT_CTL_SPTRAN;
39 sport->tx_regs->div = params->div;
40 SSYNC();
41 return 0;
42}
43EXPORT_SYMBOL(sport_set_tx_params);
44
45int sport_set_rx_params(struct sport_device *sport,
46 struct sport_params *params)
47{
48 if (sport->rx_regs->spctl & SPORT_CTL_SPENPRI)
49 return -EBUSY;
50 sport->rx_regs->spctl = params->spctl & ~SPORT_CTL_SPTRAN;
51 sport->rx_regs->div = params->div;
52 SSYNC();
53 return 0;
54}
55EXPORT_SYMBOL(sport_set_rx_params);
56
57static int compute_wdsize(size_t wdsize)
58{
59 switch (wdsize) {
60 case 1:
61 return WDSIZE_8 | PSIZE_8;
62 case 2:
63 return WDSIZE_16 | PSIZE_16;
64 default:
65 return WDSIZE_32 | PSIZE_32;
66 }
67}
68
69void sport_tx_start(struct sport_device *sport)
70{
71 set_dma_next_desc_addr(sport->tx_dma_chan, sport->tx_desc);
72 set_dma_config(sport->tx_dma_chan, DMAFLOW_LIST | DI_EN
73 | compute_wdsize(sport->wdsize) | NDSIZE_6);
74 enable_dma(sport->tx_dma_chan);
75 sport->tx_regs->spctl |= SPORT_CTL_SPENPRI;
76 SSYNC();
77}
78EXPORT_SYMBOL(sport_tx_start);
79
80void sport_rx_start(struct sport_device *sport)
81{
82 set_dma_next_desc_addr(sport->rx_dma_chan, sport->rx_desc);
83 set_dma_config(sport->rx_dma_chan, DMAFLOW_LIST | DI_EN | WNR
84 | compute_wdsize(sport->wdsize) | NDSIZE_6);
85 enable_dma(sport->rx_dma_chan);
86 sport->rx_regs->spctl |= SPORT_CTL_SPENPRI;
87 SSYNC();
88}
89EXPORT_SYMBOL(sport_rx_start);
90
91void sport_tx_stop(struct sport_device *sport)
92{
93 sport->tx_regs->spctl &= ~SPORT_CTL_SPENPRI;
94 SSYNC();
95 disable_dma(sport->tx_dma_chan);
96}
97EXPORT_SYMBOL(sport_tx_stop);
98
99void sport_rx_stop(struct sport_device *sport)
100{
101 sport->rx_regs->spctl &= ~SPORT_CTL_SPENPRI;
102 SSYNC();
103 disable_dma(sport->rx_dma_chan);
104}
105EXPORT_SYMBOL(sport_rx_stop);
106
107void sport_set_tx_callback(struct sport_device *sport,
108 void (*tx_callback)(void *), void *tx_data)
109{
110 sport->tx_callback = tx_callback;
111 sport->tx_data = tx_data;
112}
113EXPORT_SYMBOL(sport_set_tx_callback);
114
115void sport_set_rx_callback(struct sport_device *sport,
116 void (*rx_callback)(void *), void *rx_data)
117{
118 sport->rx_callback = rx_callback;
119 sport->rx_data = rx_data;
120}
121EXPORT_SYMBOL(sport_set_rx_callback);
122
123static void setup_desc(struct dmasg *desc, void *buf, int fragcount,
124 size_t fragsize, unsigned int cfg,
125 unsigned int count, size_t wdsize)
126{
127
128 int i;
129
130 for (i = 0; i < fragcount; ++i) {
131 desc[i].next_desc_addr = &(desc[i + 1]);
132 desc[i].start_addr = (unsigned long)buf + i*fragsize;
133 desc[i].cfg = cfg;
134 desc[i].x_count = count;
135 desc[i].x_modify = wdsize;
136 desc[i].y_count = 0;
137 desc[i].y_modify = 0;
138 }
139
140 /* make circular */
141 desc[fragcount-1].next_desc_addr = desc;
142}
143
144int sport_config_tx_dma(struct sport_device *sport, void *buf,
145 int fragcount, size_t fragsize)
146{
147 unsigned int count;
148 unsigned int cfg;
149 dma_addr_t addr;
150
151 count = fragsize/sport->wdsize;
152
153 if (sport->tx_desc)
154 dma_free_coherent(NULL, sport->tx_desc_size,
155 sport->tx_desc, 0);
156
157 sport->tx_desc = dma_alloc_coherent(NULL,
158 fragcount * sizeof(struct dmasg), &addr, 0);
159 sport->tx_desc_size = fragcount * sizeof(struct dmasg);
160 if (!sport->tx_desc)
161 return -ENOMEM;
162
163 sport->tx_buf = buf;
164 sport->tx_fragsize = fragsize;
165 sport->tx_frags = fragcount;
166 cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize) | NDSIZE_6;
167
168 setup_desc(sport->tx_desc, buf, fragcount, fragsize,
169 cfg|DMAEN, count, sport->wdsize);
170
171 return 0;
172}
173EXPORT_SYMBOL(sport_config_tx_dma);
174
175int sport_config_rx_dma(struct sport_device *sport, void *buf,
176 int fragcount, size_t fragsize)
177{
178 unsigned int count;
179 unsigned int cfg;
180 dma_addr_t addr;
181
182 count = fragsize/sport->wdsize;
183
184 if (sport->rx_desc)
185 dma_free_coherent(NULL, sport->rx_desc_size,
186 sport->rx_desc, 0);
187
188 sport->rx_desc = dma_alloc_coherent(NULL,
189 fragcount * sizeof(struct dmasg), &addr, 0);
190 sport->rx_desc_size = fragcount * sizeof(struct dmasg);
191 if (!sport->rx_desc)
192 return -ENOMEM;
193
194 sport->rx_buf = buf;
195 sport->rx_fragsize = fragsize;
196 sport->rx_frags = fragcount;
197 cfg = DMAFLOW_LIST | DI_EN | compute_wdsize(sport->wdsize)
198 | WNR | NDSIZE_6;
199
200 setup_desc(sport->rx_desc, buf, fragcount, fragsize,
201 cfg|DMAEN, count, sport->wdsize);
202
203 return 0;
204}
205EXPORT_SYMBOL(sport_config_rx_dma);
206
207unsigned long sport_curr_offset_tx(struct sport_device *sport)
208{
209 unsigned long curr = get_dma_curr_addr(sport->tx_dma_chan);
210
211 return (unsigned char *)curr - sport->tx_buf;
212}
213EXPORT_SYMBOL(sport_curr_offset_tx);
214
215unsigned long sport_curr_offset_rx(struct sport_device *sport)
216{
217 unsigned long curr = get_dma_curr_addr(sport->rx_dma_chan);
218
219 return (unsigned char *)curr - sport->rx_buf;
220}
221EXPORT_SYMBOL(sport_curr_offset_rx);
222
223static irqreturn_t sport_tx_irq(int irq, void *dev_id)
224{
225 struct sport_device *sport = dev_id;
226 static unsigned long status;
227
228 status = get_dma_curr_irqstat(sport->tx_dma_chan);
229 if (status & (DMA_DONE|DMA_ERR)) {
230 clear_dma_irqstat(sport->tx_dma_chan);
231 SSYNC();
232 }
233 if (sport->tx_callback)
234 sport->tx_callback(sport->tx_data);
235 return IRQ_HANDLED;
236}
237
238static irqreturn_t sport_rx_irq(int irq, void *dev_id)
239{
240 struct sport_device *sport = dev_id;
241 unsigned long status;
242
243 status = get_dma_curr_irqstat(sport->rx_dma_chan);
244 if (status & (DMA_DONE|DMA_ERR)) {
245 clear_dma_irqstat(sport->rx_dma_chan);
246 SSYNC();
247 }
248 if (sport->rx_callback)
249 sport->rx_callback(sport->rx_data);
250 return IRQ_HANDLED;
251}
252
253static irqreturn_t sport_err_irq(int irq, void *dev_id)
254{
255 struct sport_device *sport = dev_id;
256 struct device *dev = &sport->pdev->dev;
257
258 if (sport->tx_regs->spctl & SPORT_CTL_DERRPRI)
259 dev_err(dev, "sport error: TUVF\n");
260 if (sport->rx_regs->spctl & SPORT_CTL_DERRPRI)
261 dev_err(dev, "sport error: ROVF\n");
262
263 return IRQ_HANDLED;
264}
265
266static int sport_get_resource(struct sport_device *sport)
267{
268 struct platform_device *pdev = sport->pdev;
269 struct device *dev = &pdev->dev;
270 struct bfin_snd_platform_data *pdata = dev->platform_data;
271 struct resource *res;
272
273 if (!pdata) {
274 dev_err(dev, "No platform data\n");
275 return -ENODEV;
276 }
277 sport->pin_req = pdata->pin_req;
278
279 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
280 if (!res) {
281 dev_err(dev, "No tx MEM resource\n");
282 return -ENODEV;
283 }
284 sport->tx_regs = (struct sport_register *)res->start;
285
286 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
287 if (!res) {
288 dev_err(dev, "No rx MEM resource\n");
289 return -ENODEV;
290 }
291 sport->rx_regs = (struct sport_register *)res->start;
292
293 res = platform_get_resource(pdev, IORESOURCE_DMA, 0);
294 if (!res) {
295 dev_err(dev, "No tx DMA resource\n");
296 return -ENODEV;
297 }
298 sport->tx_dma_chan = res->start;
299
300 res = platform_get_resource(pdev, IORESOURCE_DMA, 1);
301 if (!res) {
302 dev_err(dev, "No rx DMA resource\n");
303 return -ENODEV;
304 }
305 sport->rx_dma_chan = res->start;
306
307 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
308 if (!res) {
309 dev_err(dev, "No tx error irq resource\n");
310 return -ENODEV;
311 }
312 sport->tx_err_irq = res->start;
313
314 res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
315 if (!res) {
316 dev_err(dev, "No rx error irq resource\n");
317 return -ENODEV;
318 }
319 sport->rx_err_irq = res->start;
320
321 return 0;
322}
323
324static int sport_request_resource(struct sport_device *sport)
325{
326 struct device *dev = &sport->pdev->dev;
327 int ret;
328
329 ret = peripheral_request_list(sport->pin_req, "soc-audio");
330 if (ret) {
331 dev_err(dev, "Unable to request sport pin\n");
332 return ret;
333 }
334
335 ret = request_dma(sport->tx_dma_chan, "SPORT TX Data");
336 if (ret) {
337 dev_err(dev, "Unable to allocate DMA channel for sport tx\n");
338 goto err_tx_dma;
339 }
340 set_dma_callback(sport->tx_dma_chan, sport_tx_irq, sport);
341
342 ret = request_dma(sport->rx_dma_chan, "SPORT RX Data");
343 if (ret) {
344 dev_err(dev, "Unable to allocate DMA channel for sport rx\n");
345 goto err_rx_dma;
346 }
347 set_dma_callback(sport->rx_dma_chan, sport_rx_irq, sport);
348
349 ret = request_irq(sport->tx_err_irq, sport_err_irq,
350 0, "SPORT TX ERROR", sport);
351 if (ret) {
352 dev_err(dev, "Unable to allocate tx error IRQ for sport\n");
353 goto err_tx_irq;
354 }
355
356 ret = request_irq(sport->rx_err_irq, sport_err_irq,
357 0, "SPORT RX ERROR", sport);
358 if (ret) {
359 dev_err(dev, "Unable to allocate rx error IRQ for sport\n");
360 goto err_rx_irq;
361 }
362
363 return 0;
364err_rx_irq:
365 free_irq(sport->tx_err_irq, sport);
366err_tx_irq:
367 free_dma(sport->rx_dma_chan);
368err_rx_dma:
369 free_dma(sport->tx_dma_chan);
370err_tx_dma:
371 peripheral_free_list(sport->pin_req);
372 return ret;
373}
374
375static void sport_free_resource(struct sport_device *sport)
376{
377 free_irq(sport->rx_err_irq, sport);
378 free_irq(sport->tx_err_irq, sport);
379 free_dma(sport->rx_dma_chan);
380 free_dma(sport->tx_dma_chan);
381 peripheral_free_list(sport->pin_req);
382}
383
384struct sport_device *sport_create(struct platform_device *pdev)
385{
386 struct device *dev = &pdev->dev;
387 struct sport_device *sport;
388 int ret;
389
390 sport = kzalloc(sizeof(*sport), GFP_KERNEL);
391 if (!sport) {
392 dev_err(dev, "Unable to allocate memory for sport device\n");
393 return NULL;
394 }
395 sport->pdev = pdev;
396
397 ret = sport_get_resource(sport);
398 if (ret) {
399 kfree(sport);
400 return NULL;
401 }
402
403 ret = sport_request_resource(sport);
404 if (ret) {
405 kfree(sport);
406 return NULL;
407 }
408
409 dev_dbg(dev, "SPORT create success\n");
410 return sport;
411}
412EXPORT_SYMBOL(sport_create);
413
414void sport_delete(struct sport_device *sport)
415{
416 sport_free_resource(sport);
417}
418EXPORT_SYMBOL(sport_delete);
419
420MODULE_DESCRIPTION("Analog Devices BF6XX SPORT driver");
421MODULE_AUTHOR("Scott Jiang <Scott.Jiang.Linux@gmail.com>");
422MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/blackfin/bf6xx-sport.h b/sound/soc/blackfin/bf6xx-sport.h
new file mode 100644
index 00000000000..307d193cfce
--- /dev/null
+++ b/sound/soc/blackfin/bf6xx-sport.h
@@ -0,0 +1,82 @@
1/*
2 * bf6xx_sport - Analog Devices BF6XX SPORT driver
3 *
4 * Copyright (c) 2012 Analog Devices Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU 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., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#ifndef _BF6XX_SPORT_H_
21#define _BF6XX_SPORT_H_
22
23#include <linux/platform_device.h>
24#include <asm/bfin_sport3.h>
25
26struct sport_device {
27 struct platform_device *pdev;
28 const unsigned short *pin_req;
29 struct sport_register *tx_regs;
30 struct sport_register *rx_regs;
31 int tx_dma_chan;
32 int rx_dma_chan;
33 int tx_err_irq;
34 int rx_err_irq;
35
36 void (*tx_callback)(void *data);
37 void *tx_data;
38 void (*rx_callback)(void *data);
39 void *rx_data;
40
41 struct dmasg *tx_desc;
42 struct dmasg *rx_desc;
43 unsigned int tx_desc_size;
44 unsigned int rx_desc_size;
45 unsigned char *tx_buf;
46 unsigned char *rx_buf;
47 unsigned int tx_fragsize;
48 unsigned int rx_fragsize;
49 unsigned int tx_frags;
50 unsigned int rx_frags;
51 unsigned int wdsize;
52};
53
54struct sport_params {
55 u32 spctl;
56 u32 div;
57};
58
59struct sport_device *sport_create(struct platform_device *pdev);
60void sport_delete(struct sport_device *sport);
61int sport_set_tx_params(struct sport_device *sport,
62 struct sport_params *params);
63int sport_set_rx_params(struct sport_device *sport,
64 struct sport_params *params);
65void sport_tx_start(struct sport_device *sport);
66void sport_rx_start(struct sport_device *sport);
67void sport_tx_stop(struct sport_device *sport);
68void sport_rx_stop(struct sport_device *sport);
69void sport_set_tx_callback(struct sport_device *sport,
70 void (*tx_callback)(void *), void *tx_data);
71void sport_set_rx_callback(struct sport_device *sport,
72 void (*rx_callback)(void *), void *rx_data);
73int sport_config_tx_dma(struct sport_device *sport, void *buf,
74 int fragcount, size_t fragsize);
75int sport_config_rx_dma(struct sport_device *sport, void *buf,
76 int fragcount, size_t fragsize);
77unsigned long sport_curr_offset_tx(struct sport_device *sport);
78unsigned long sport_curr_offset_rx(struct sport_device *sport);
79
80
81
82#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 1e1613a438d..9f8e8594aeb 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -12,6 +12,7 @@ config SND_SOC_ALL_CODECS
12 tristate "Build all ASoC CODEC drivers" 12 tristate "Build all ASoC CODEC drivers"
13 select SND_SOC_88PM860X if MFD_88PM860X 13 select SND_SOC_88PM860X if MFD_88PM860X
14 select SND_SOC_L3 14 select SND_SOC_L3
15 select SND_SOC_AB8500_CODEC if ABX500_CORE
15 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS 16 select SND_SOC_AC97_CODEC if SND_SOC_AC97_BUS
16 select SND_SOC_AD1836 if SPI_MASTER 17 select SND_SOC_AD1836 if SPI_MASTER
17 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI 18 select SND_SOC_AD193X if SND_SOC_I2C_AND_SPI
@@ -35,7 +36,9 @@ config SND_SOC_ALL_CODECS
35 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI 36 select SND_SOC_CS4271 if SND_SOC_I2C_AND_SPI
36 select SND_SOC_CX20442 37 select SND_SOC_CX20442
37 select SND_SOC_DA7210 if I2C 38 select SND_SOC_DA7210 if I2C
39 select SND_SOC_DA732X if I2C
38 select SND_SOC_DFBMCS320 40 select SND_SOC_DFBMCS320
41 select SND_SOC_ISABELLE if I2C
39 select SND_SOC_JZ4740_CODEC 42 select SND_SOC_JZ4740_CODEC
40 select SND_SOC_LM4857 if I2C 43 select SND_SOC_LM4857 if I2C
41 select SND_SOC_LM49453 if I2C 44 select SND_SOC_LM49453 if I2C
@@ -54,6 +57,7 @@ config SND_SOC_ALL_CODECS
54 select SND_SOC_SPDIF 57 select SND_SOC_SPDIF
55 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI 58 select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
56 select SND_SOC_STA32X if I2C 59 select SND_SOC_STA32X if I2C
60 select SND_SOC_STA529 if I2C
57 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS 61 select SND_SOC_STAC9766 if SND_SOC_AC97_BUS
58 select SND_SOC_TLV320AIC23 if I2C 62 select SND_SOC_TLV320AIC23 if I2C
59 select SND_SOC_TLV320AIC26 if SPI_MASTER 63 select SND_SOC_TLV320AIC26 if SPI_MASTER
@@ -70,6 +74,8 @@ config SND_SOC_ALL_CODECS
70 select SND_SOC_WM2000 if I2C 74 select SND_SOC_WM2000 if I2C
71 select SND_SOC_WM2200 if I2C 75 select SND_SOC_WM2200 if I2C
72 select SND_SOC_WM5100 if I2C 76 select SND_SOC_WM5100 if I2C
77 select SND_SOC_WM5102 if MFD_WM5102
78 select SND_SOC_WM5110 if MFD_WM5110
73 select SND_SOC_WM8350 if MFD_WM8350 79 select SND_SOC_WM8350 if MFD_WM8350
74 select SND_SOC_WM8400 if MFD_WM8400 80 select SND_SOC_WM8400 if MFD_WM8400
75 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI 81 select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -126,11 +132,21 @@ config SND_SOC_ALL_CODECS
126config SND_SOC_88PM860X 132config SND_SOC_88PM860X
127 tristate 133 tristate
128 134
135config SND_SOC_ARIZONA
136 tristate
137 default y if SND_SOC_WM5102=y
138 default y if SND_SOC_WM5110=y
139 default m if SND_SOC_WM5102=m
140 default m if SND_SOC_WM5110=m
141
129config SND_SOC_WM_HUBS 142config SND_SOC_WM_HUBS
130 tristate 143 tristate
131 default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y 144 default y if SND_SOC_WM8993=y || SND_SOC_WM8994=y
132 default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m 145 default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
133 146
147config SND_SOC_AB8500_CODEC
148 tristate
149
134config SND_SOC_AC97_CODEC 150config SND_SOC_AC97_CODEC
135 tristate 151 tristate
136 select SND_AC97_CODEC 152 select SND_AC97_CODEC
@@ -219,12 +235,18 @@ config SND_SOC_L3
219config SND_SOC_DA7210 235config SND_SOC_DA7210
220 tristate 236 tristate
221 237
238config SND_SOC_DA732X
239 tristate
240
222config SND_SOC_DFBMCS320 241config SND_SOC_DFBMCS320
223 tristate 242 tristate
224 243
225config SND_SOC_DMIC 244config SND_SOC_DMIC
226 tristate 245 tristate
227 246
247config SND_SOC_ISABELLE
248 tristate
249
228config SND_SOC_LM49453 250config SND_SOC_LM49453
229 tristate 251 tristate
230 252
@@ -266,6 +288,9 @@ config SND_SOC_SSM2602
266config SND_SOC_STA32X 288config SND_SOC_STA32X
267 tristate 289 tristate
268 290
291config SND_SOC_STA529
292 tristate
293
269config SND_SOC_STAC9766 294config SND_SOC_STAC9766
270 tristate 295 tristate
271 296
@@ -313,6 +338,12 @@ config SND_SOC_WM2200
313config SND_SOC_WM5100 338config SND_SOC_WM5100
314 tristate 339 tristate
315 340
341config SND_SOC_WM5102
342 tristate
343
344config SND_SOC_WM5110
345 tristate
346
316config SND_SOC_WM8350 347config SND_SOC_WM8350
317 tristate 348 tristate
318 349
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index fc27fec3948..34148bb59c6 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -1,4 +1,5 @@
1snd-soc-88pm860x-objs := 88pm860x-codec.o 1snd-soc-88pm860x-objs := 88pm860x-codec.o
2snd-soc-ab8500-codec-objs := ab8500-codec.o
2snd-soc-ac97-objs := ac97.o 3snd-soc-ac97-objs := ac97.o
3snd-soc-ad1836-objs := ad1836.o 4snd-soc-ad1836-objs := ad1836.o
4snd-soc-ad193x-objs := ad193x.o 5snd-soc-ad193x-objs := ad193x.o
@@ -13,6 +14,7 @@ snd-soc-ak4535-objs := ak4535.o
13snd-soc-ak4641-objs := ak4641.o 14snd-soc-ak4641-objs := ak4641.o
14snd-soc-ak4642-objs := ak4642.o 15snd-soc-ak4642-objs := ak4642.o
15snd-soc-ak4671-objs := ak4671.o 16snd-soc-ak4671-objs := ak4671.o
17snd-soc-arizona-objs := arizona.o
16snd-soc-cq93vc-objs := cq93vc.o 18snd-soc-cq93vc-objs := cq93vc.o
17snd-soc-cs42l51-objs := cs42l51.o 19snd-soc-cs42l51-objs := cs42l51.o
18snd-soc-cs42l52-objs := cs42l52.o 20snd-soc-cs42l52-objs := cs42l52.o
@@ -21,8 +23,10 @@ snd-soc-cs4270-objs := cs4270.o
21snd-soc-cs4271-objs := cs4271.o 23snd-soc-cs4271-objs := cs4271.o
22snd-soc-cx20442-objs := cx20442.o 24snd-soc-cx20442-objs := cx20442.o
23snd-soc-da7210-objs := da7210.o 25snd-soc-da7210-objs := da7210.o
26snd-soc-da732x-objs := da732x.o
24snd-soc-dfbmcs320-objs := dfbmcs320.o 27snd-soc-dfbmcs320-objs := dfbmcs320.o
25snd-soc-dmic-objs := dmic.o 28snd-soc-dmic-objs := dmic.o
29snd-soc-isabelle-objs := isabelle.o
26snd-soc-jz4740-codec-objs := jz4740.o 30snd-soc-jz4740-codec-objs := jz4740.o
27snd-soc-l3-objs := l3.o 31snd-soc-l3-objs := l3.o
28snd-soc-lm4857-objs := lm4857.o 32snd-soc-lm4857-objs := lm4857.o
@@ -41,9 +45,11 @@ snd-soc-alc5623-objs := alc5623.o
41snd-soc-alc5632-objs := alc5632.o 45snd-soc-alc5632-objs := alc5632.o
42snd-soc-sigmadsp-objs := sigmadsp.o 46snd-soc-sigmadsp-objs := sigmadsp.o
43snd-soc-sn95031-objs := sn95031.o 47snd-soc-sn95031-objs := sn95031.o
44snd-soc-spdif-objs := spdif_transciever.o 48snd-soc-spdif-tx-objs := spdif_transciever.o
49snd-soc-spdif-rx-objs := spdif_receiver.o
45snd-soc-ssm2602-objs := ssm2602.o 50snd-soc-ssm2602-objs := ssm2602.o
46snd-soc-sta32x-objs := sta32x.o 51snd-soc-sta32x-objs := sta32x.o
52snd-soc-sta529-objs := sta529.o
47snd-soc-stac9766-objs := stac9766.o 53snd-soc-stac9766-objs := stac9766.o
48snd-soc-tlv320aic23-objs := tlv320aic23.o 54snd-soc-tlv320aic23-objs := tlv320aic23.o
49snd-soc-tlv320aic26-objs := tlv320aic26.o 55snd-soc-tlv320aic26-objs := tlv320aic26.o
@@ -59,6 +65,8 @@ snd-soc-wm1250-ev1-objs := wm1250-ev1.o
59snd-soc-wm2000-objs := wm2000.o 65snd-soc-wm2000-objs := wm2000.o
60snd-soc-wm2200-objs := wm2200.o 66snd-soc-wm2200-objs := wm2200.o
61snd-soc-wm5100-objs := wm5100.o wm5100-tables.o 67snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
68snd-soc-wm5102-objs := wm5102.o
69snd-soc-wm5110-objs := wm5110.o
62snd-soc-wm8350-objs := wm8350.o 70snd-soc-wm8350-objs := wm8350.o
63snd-soc-wm8400-objs := wm8400.o 71snd-soc-wm8400-objs := wm8400.o
64snd-soc-wm8510-objs := wm8510.o 72snd-soc-wm8510-objs := wm8510.o
@@ -108,6 +116,7 @@ snd-soc-max9877-objs := max9877.o
108snd-soc-tpa6130a2-objs := tpa6130a2.o 116snd-soc-tpa6130a2-objs := tpa6130a2.o
109 117
110obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o 118obj-$(CONFIG_SND_SOC_88PM860X) += snd-soc-88pm860x.o
119obj-$(CONFIG_SND_SOC_AB8500_CODEC) += snd-soc-ab8500-codec.o
111obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o 120obj-$(CONFIG_SND_SOC_AC97_CODEC) += snd-soc-ac97.o
112obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o 121obj-$(CONFIG_SND_SOC_AD1836) += snd-soc-ad1836.o
113obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o 122obj-$(CONFIG_SND_SOC_AD193X) += snd-soc-ad193x.o
@@ -124,6 +133,7 @@ obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
124obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o 133obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
125obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o 134obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
126obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o 135obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
136obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
127obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o 137obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
128obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o 138obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
129obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o 139obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
@@ -132,8 +142,10 @@ obj-$(CONFIG_SND_SOC_CS4270) += snd-soc-cs4270.o
132obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o 142obj-$(CONFIG_SND_SOC_CS4271) += snd-soc-cs4271.o
133obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o 143obj-$(CONFIG_SND_SOC_CX20442) += snd-soc-cx20442.o
134obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o 144obj-$(CONFIG_SND_SOC_DA7210) += snd-soc-da7210.o
145obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
135obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o 146obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
136obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o 147obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
148obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
137obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o 149obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
138obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o 150obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
139obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o 151obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
@@ -150,9 +162,10 @@ obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
150obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 162obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
151obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o 163obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
152obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o 164obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
153obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o 165obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
154obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o 166obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
155obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o 167obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
168obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
156obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o 169obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o
157obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o 170obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
158obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o 171obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
@@ -168,6 +181,8 @@ obj-$(CONFIG_SND_SOC_WM1250_EV1) += snd-soc-wm1250-ev1.o
168obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o 181obj-$(CONFIG_SND_SOC_WM2000) += snd-soc-wm2000.o
169obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o 182obj-$(CONFIG_SND_SOC_WM2200) += snd-soc-wm2200.o
170obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o 183obj-$(CONFIG_SND_SOC_WM5100) += snd-soc-wm5100.o
184obj-$(CONFIG_SND_SOC_WM5102) += snd-soc-wm5102.o
185obj-$(CONFIG_SND_SOC_WM5110) += snd-soc-wm5110.o
171obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o 186obj-$(CONFIG_SND_SOC_WM8350) += snd-soc-wm8350.o
172obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o 187obj-$(CONFIG_SND_SOC_WM8400) += snd-soc-wm8400.o
173obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o 188obj-$(CONFIG_SND_SOC_WM8510) += snd-soc-wm8510.o
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
new file mode 100644
index 00000000000..3c795921c5f
--- /dev/null
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -0,0 +1,2522 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>,
6 * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
7 * for ST-Ericsson.
8 *
9 * Based on the early work done by:
10 * Mikko J. Lehto <mikko.lehto@symbio.com>,
11 * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
12 * Jarmo K. Kuronen <jarmo.kuronen@symbio.com>,
13 * for ST-Ericsson.
14 *
15 * License terms:
16 *
17 * This program is free software; you can redistribute it and/or modify it
18 * under the terms of the GNU General Public License version 2 as published
19 * by the Free Software Foundation.
20 */
21
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/device.h>
25#include <linux/slab.h>
26#include <linux/moduleparam.h>
27#include <linux/init.h>
28#include <linux/delay.h>
29#include <linux/pm.h>
30#include <linux/platform_device.h>
31#include <linux/mutex.h>
32#include <linux/mfd/abx500/ab8500.h>
33#include <linux/mfd/abx500.h>
34#include <linux/mfd/abx500/ab8500-sysctrl.h>
35#include <linux/mfd/abx500/ab8500-codec.h>
36#include <linux/regulator/consumer.h>
37
38#include <sound/core.h>
39#include <sound/pcm.h>
40#include <sound/pcm_params.h>
41#include <sound/initval.h>
42#include <sound/soc.h>
43#include <sound/soc-dapm.h>
44#include <sound/tlv.h>
45
46#include "ab8500-codec.h"
47
48/* Macrocell value definitions */
49#define CLK_32K_OUT2_DISABLE 0x01
50#define INACTIVE_RESET_AUDIO 0x02
51#define ENABLE_AUDIO_CLK_TO_AUDIO_BLK 0x10
52#define ENABLE_VINTCORE12_SUPPLY 0x04
53#define GPIO27_DIR_OUTPUT 0x04
54#define GPIO29_DIR_OUTPUT 0x10
55#define GPIO31_DIR_OUTPUT 0x40
56
57/* Macrocell register definitions */
58#define AB8500_CTRL3_REG 0x0200
59#define AB8500_GPIO_DIR4_REG 0x1013
60
61/* Nr of FIR/IIR-coeff banks in ANC-block */
62#define AB8500_NR_OF_ANC_COEFF_BANKS 2
63
64/* Minimum duration to keep ANC IIR Init bit high or
65low before proceeding with the configuration sequence */
66#define AB8500_ANC_SM_DELAY 2000
67
68#define AB8500_FILTER_CONTROL(xname, xcount, xmin, xmax) \
69{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
70 .info = filter_control_info, \
71 .get = filter_control_get, .put = filter_control_put, \
72 .private_value = (unsigned long)&(struct filter_control) \
73 {.count = xcount, .min = xmin, .max = xmax} }
74
75struct filter_control {
76 long min, max;
77 unsigned int count;
78 long value[128];
79};
80
81/* Sidetone states */
82static const char * const enum_sid_state[] = {
83 "Unconfigured",
84 "Apply FIR",
85 "FIR is configured",
86};
87enum sid_state {
88 SID_UNCONFIGURED = 0,
89 SID_APPLY_FIR = 1,
90 SID_FIR_CONFIGURED = 2,
91};
92
93static const char * const enum_anc_state[] = {
94 "Unconfigured",
95 "Apply FIR and IIR",
96 "FIR and IIR are configured",
97 "Apply FIR",
98 "FIR is configured",
99 "Apply IIR",
100 "IIR is configured"
101};
102enum anc_state {
103 ANC_UNCONFIGURED = 0,
104 ANC_APPLY_FIR_IIR = 1,
105 ANC_FIR_IIR_CONFIGURED = 2,
106 ANC_APPLY_FIR = 3,
107 ANC_FIR_CONFIGURED = 4,
108 ANC_APPLY_IIR = 5,
109 ANC_IIR_CONFIGURED = 6
110};
111
112/* Analog microphones */
113enum amic_idx {
114 AMIC_IDX_1A,
115 AMIC_IDX_1B,
116 AMIC_IDX_2
117};
118
119struct ab8500_codec_drvdata_dbg {
120 struct regulator *vaud;
121 struct regulator *vamic1;
122 struct regulator *vamic2;
123 struct regulator *vdmic;
124};
125
126/* Private data for AB8500 device-driver */
127struct ab8500_codec_drvdata {
128 /* Sidetone */
129 long *sid_fir_values;
130 enum sid_state sid_status;
131
132 /* ANC */
133 struct mutex anc_lock;
134 long *anc_fir_values;
135 long *anc_iir_values;
136 enum anc_state anc_status;
137};
138
139static inline const char *amic_micbias_str(enum amic_micbias micbias)
140{
141 switch (micbias) {
142 case AMIC_MICBIAS_VAMIC1:
143 return "VAMIC1";
144 case AMIC_MICBIAS_VAMIC2:
145 return "VAMIC2";
146 default:
147 return "Unknown";
148 }
149}
150
151static inline const char *amic_type_str(enum amic_type type)
152{
153 switch (type) {
154 case AMIC_TYPE_DIFFERENTIAL:
155 return "DIFFERENTIAL";
156 case AMIC_TYPE_SINGLE_ENDED:
157 return "SINGLE ENDED";
158 default:
159 return "Unknown";
160 }
161}
162
163/*
164 * Read'n'write functions
165 */
166
167/* Read a register from the audio-bank of AB8500 */
168static unsigned int ab8500_codec_read_reg(struct snd_soc_codec *codec,
169 unsigned int reg)
170{
171 int status;
172 unsigned int value = 0;
173
174 u8 value8;
175 status = abx500_get_register_interruptible(codec->dev, AB8500_AUDIO,
176 reg, &value8);
177 if (status < 0) {
178 dev_err(codec->dev,
179 "%s: ERROR: Register (0x%02x:0x%02x) read failed (%d).\n",
180 __func__, (u8)AB8500_AUDIO, (u8)reg, status);
181 } else {
182 dev_dbg(codec->dev,
183 "%s: Read 0x%02x from register 0x%02x:0x%02x\n",
184 __func__, value8, (u8)AB8500_AUDIO, (u8)reg);
185 value = (unsigned int)value8;
186 }
187
188 return value;
189}
190
191/* Write to a register in the audio-bank of AB8500 */
192static int ab8500_codec_write_reg(struct snd_soc_codec *codec,
193 unsigned int reg, unsigned int value)
194{
195 int status;
196
197 status = abx500_set_register_interruptible(codec->dev, AB8500_AUDIO,
198 reg, value);
199 if (status < 0)
200 dev_err(codec->dev,
201 "%s: ERROR: Register (%02x:%02x) write failed (%d).\n",
202 __func__, (u8)AB8500_AUDIO, (u8)reg, status);
203 else
204 dev_dbg(codec->dev,
205 "%s: Wrote 0x%02x into register %02x:%02x\n",
206 __func__, (u8)value, (u8)AB8500_AUDIO, (u8)reg);
207
208 return status;
209}
210
211/*
212 * Controls - DAPM
213 */
214
215/* Earpiece */
216
217/* Earpiece source selector */
218static const char * const enum_ear_lineout_source[] = {"Headset Left",
219 "Speaker Left"};
220static SOC_ENUM_SINGLE_DECL(dapm_enum_ear_lineout_source, AB8500_DMICFILTCONF,
221 AB8500_DMICFILTCONF_DA3TOEAR, enum_ear_lineout_source);
222static const struct snd_kcontrol_new dapm_ear_lineout_source =
223 SOC_DAPM_ENUM("Earpiece or LineOut Mono Source",
224 dapm_enum_ear_lineout_source);
225
226/* LineOut */
227
228/* LineOut source selector */
229static const char * const enum_lineout_source[] = {"Mono Path", "Stereo Path"};
230static SOC_ENUM_DOUBLE_DECL(dapm_enum_lineout_source, AB8500_ANACONF5,
231 AB8500_ANACONF5_HSLDACTOLOL,
232 AB8500_ANACONF5_HSRDACTOLOR, enum_lineout_source);
233static const struct snd_kcontrol_new dapm_lineout_source[] = {
234 SOC_DAPM_ENUM("LineOut Source", dapm_enum_lineout_source),
235};
236
237/* Handsfree */
238
239/* Speaker Left - ANC selector */
240static const char * const enum_HFx_sel[] = {"Audio Path", "ANC"};
241static SOC_ENUM_SINGLE_DECL(dapm_enum_HFl_sel, AB8500_DIGMULTCONF2,
242 AB8500_DIGMULTCONF2_HFLSEL, enum_HFx_sel);
243static const struct snd_kcontrol_new dapm_HFl_select[] = {
244 SOC_DAPM_ENUM("Speaker Left Source", dapm_enum_HFl_sel),
245};
246
247/* Speaker Right - ANC selector */
248static SOC_ENUM_SINGLE_DECL(dapm_enum_HFr_sel, AB8500_DIGMULTCONF2,
249 AB8500_DIGMULTCONF2_HFRSEL, enum_HFx_sel);
250static const struct snd_kcontrol_new dapm_HFr_select[] = {
251 SOC_DAPM_ENUM("Speaker Right Source", dapm_enum_HFr_sel),
252};
253
254/* Mic 1 */
255
256/* Mic 1 - Mic 1a or 1b selector */
257static const char * const enum_mic1ab_sel[] = {"Mic 1b", "Mic 1a"};
258static SOC_ENUM_SINGLE_DECL(dapm_enum_mic1ab_sel, AB8500_ANACONF3,
259 AB8500_ANACONF3_MIC1SEL, enum_mic1ab_sel);
260static const struct snd_kcontrol_new dapm_mic1ab_mux[] = {
261 SOC_DAPM_ENUM("Mic 1a or 1b Select", dapm_enum_mic1ab_sel),
262};
263
264/* Mic 1 - AD3 - Mic 1 or DMic 3 selector */
265static const char * const enum_ad3_sel[] = {"Mic 1", "DMic 3"};
266static SOC_ENUM_SINGLE_DECL(dapm_enum_ad3_sel, AB8500_DIGMULTCONF1,
267 AB8500_DIGMULTCONF1_AD3SEL, enum_ad3_sel);
268static const struct snd_kcontrol_new dapm_ad3_select[] = {
269 SOC_DAPM_ENUM("AD3 Source Select", dapm_enum_ad3_sel),
270};
271
272/* Mic 1 - AD6 - Mic 1 or DMic 6 selector */
273static const char * const enum_ad6_sel[] = {"Mic 1", "DMic 6"};
274static SOC_ENUM_SINGLE_DECL(dapm_enum_ad6_sel, AB8500_DIGMULTCONF1,
275 AB8500_DIGMULTCONF1_AD6SEL, enum_ad6_sel);
276static const struct snd_kcontrol_new dapm_ad6_select[] = {
277 SOC_DAPM_ENUM("AD6 Source Select", dapm_enum_ad6_sel),
278};
279
280/* Mic 2 */
281
282/* Mic 2 - AD5 - Mic 2 or DMic 5 selector */
283static const char * const enum_ad5_sel[] = {"Mic 2", "DMic 5"};
284static SOC_ENUM_SINGLE_DECL(dapm_enum_ad5_sel, AB8500_DIGMULTCONF1,
285 AB8500_DIGMULTCONF1_AD5SEL, enum_ad5_sel);
286static const struct snd_kcontrol_new dapm_ad5_select[] = {
287 SOC_DAPM_ENUM("AD5 Source Select", dapm_enum_ad5_sel),
288};
289
290/* LineIn */
291
292/* LineIn left - AD1 - LineIn Left or DMic 1 selector */
293static const char * const enum_ad1_sel[] = {"LineIn Left", "DMic 1"};
294static SOC_ENUM_SINGLE_DECL(dapm_enum_ad1_sel, AB8500_DIGMULTCONF1,
295 AB8500_DIGMULTCONF1_AD1SEL, enum_ad1_sel);
296static const struct snd_kcontrol_new dapm_ad1_select[] = {
297 SOC_DAPM_ENUM("AD1 Source Select", dapm_enum_ad1_sel),
298};
299
300/* LineIn right - Mic 2 or LineIn Right selector */
301static const char * const enum_mic2lr_sel[] = {"Mic 2", "LineIn Right"};
302static SOC_ENUM_SINGLE_DECL(dapm_enum_mic2lr_sel, AB8500_ANACONF3,
303 AB8500_ANACONF3_LINRSEL, enum_mic2lr_sel);
304static const struct snd_kcontrol_new dapm_mic2lr_select[] = {
305 SOC_DAPM_ENUM("Mic 2 or LINR Select", dapm_enum_mic2lr_sel),
306};
307
308/* LineIn right - AD2 - LineIn Right or DMic2 selector */
309static const char * const enum_ad2_sel[] = {"LineIn Right", "DMic 2"};
310static SOC_ENUM_SINGLE_DECL(dapm_enum_ad2_sel, AB8500_DIGMULTCONF1,
311 AB8500_DIGMULTCONF1_AD2SEL, enum_ad2_sel);
312static const struct snd_kcontrol_new dapm_ad2_select[] = {
313 SOC_DAPM_ENUM("AD2 Source Select", dapm_enum_ad2_sel),
314};
315
316
317/* ANC */
318
319static const char * const enum_anc_in_sel[] = {"Mic 1 / DMic 6",
320 "Mic 2 / DMic 5"};
321static SOC_ENUM_SINGLE_DECL(dapm_enum_anc_in_sel, AB8500_DMICFILTCONF,
322 AB8500_DMICFILTCONF_ANCINSEL, enum_anc_in_sel);
323static const struct snd_kcontrol_new dapm_anc_in_select[] = {
324 SOC_DAPM_ENUM("ANC Source", dapm_enum_anc_in_sel),
325};
326
327/* ANC - Enable/Disable */
328static const struct snd_kcontrol_new dapm_anc_enable[] = {
329 SOC_DAPM_SINGLE("Switch", AB8500_ANCCONF1,
330 AB8500_ANCCONF1_ENANC, 0, 0),
331};
332
333/* ANC to Earpiece - Mute */
334static const struct snd_kcontrol_new dapm_anc_ear_mute[] = {
335 SOC_DAPM_SINGLE("Switch", AB8500_DIGMULTCONF1,
336 AB8500_DIGMULTCONF1_ANCSEL, 1, 0),
337};
338
339
340
341/* Sidetone left */
342
343/* Sidetone left - Input selector */
344static const char * const enum_stfir1_in_sel[] = {
345 "LineIn Left", "LineIn Right", "Mic 1", "Headset Left"
346};
347static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir1_in_sel, AB8500_DIGMULTCONF2,
348 AB8500_DIGMULTCONF2_FIRSID1SEL, enum_stfir1_in_sel);
349static const struct snd_kcontrol_new dapm_stfir1_in_select[] = {
350 SOC_DAPM_ENUM("Sidetone Left Source", dapm_enum_stfir1_in_sel),
351};
352
353/* Sidetone right path */
354
355/* Sidetone right - Input selector */
356static const char * const enum_stfir2_in_sel[] = {
357 "LineIn Right", "Mic 1", "DMic 4", "Headset Right"
358};
359static SOC_ENUM_SINGLE_DECL(dapm_enum_stfir2_in_sel, AB8500_DIGMULTCONF2,
360 AB8500_DIGMULTCONF2_FIRSID2SEL, enum_stfir2_in_sel);
361static const struct snd_kcontrol_new dapm_stfir2_in_select[] = {
362 SOC_DAPM_ENUM("Sidetone Right Source", dapm_enum_stfir2_in_sel),
363};
364
365/* Vibra */
366
367static const char * const enum_pwm2vibx[] = {"Audio Path", "PWM Generator"};
368
369static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib1, AB8500_PWMGENCONF1,
370 AB8500_PWMGENCONF1_PWMTOVIB1, enum_pwm2vibx);
371
372static const struct snd_kcontrol_new dapm_pwm2vib1[] = {
373 SOC_DAPM_ENUM("Vibra 1 Controller", dapm_enum_pwm2vib1),
374};
375
376static SOC_ENUM_SINGLE_DECL(dapm_enum_pwm2vib2, AB8500_PWMGENCONF1,
377 AB8500_PWMGENCONF1_PWMTOVIB2, enum_pwm2vibx);
378
379static const struct snd_kcontrol_new dapm_pwm2vib2[] = {
380 SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2),
381};
382
383/*
384 * DAPM-widgets
385 */
386
387static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
388
389 /* Clocks */
390 SND_SOC_DAPM_CLOCK_SUPPLY("audioclk"),
391
392 /* Regulators */
393 SND_SOC_DAPM_REGULATOR_SUPPLY("V-AUD", 0),
394 SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC1", 0),
395 SND_SOC_DAPM_REGULATOR_SUPPLY("V-AMIC2", 0),
396 SND_SOC_DAPM_REGULATOR_SUPPLY("V-DMIC", 0),
397
398 /* Power */
399 SND_SOC_DAPM_SUPPLY("Audio Power",
400 AB8500_POWERUP, AB8500_POWERUP_POWERUP, 0,
401 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
402 SND_SOC_DAPM_SUPPLY("Audio Analog Power",
403 AB8500_POWERUP, AB8500_POWERUP_ENANA, 0,
404 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
405
406 /* Main supply node */
407 SND_SOC_DAPM_SUPPLY("Main Supply", SND_SOC_NOPM, 0, 0,
408 NULL, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
409
410 /* DA/AD */
411
412 SND_SOC_DAPM_INPUT("ADC Input"),
413 SND_SOC_DAPM_ADC("ADC", "ab8500_0c", SND_SOC_NOPM, 0, 0),
414
415 SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
416 SND_SOC_DAPM_OUTPUT("DAC Output"),
417
418 SND_SOC_DAPM_AIF_IN("DA_IN1", NULL, 0, SND_SOC_NOPM, 0, 0),
419 SND_SOC_DAPM_AIF_IN("DA_IN2", NULL, 0, SND_SOC_NOPM, 0, 0),
420 SND_SOC_DAPM_AIF_IN("DA_IN3", NULL, 0, SND_SOC_NOPM, 0, 0),
421 SND_SOC_DAPM_AIF_IN("DA_IN4", NULL, 0, SND_SOC_NOPM, 0, 0),
422 SND_SOC_DAPM_AIF_IN("DA_IN5", NULL, 0, SND_SOC_NOPM, 0, 0),
423 SND_SOC_DAPM_AIF_IN("DA_IN6", NULL, 0, SND_SOC_NOPM, 0, 0),
424 SND_SOC_DAPM_AIF_OUT("AD_OUT1", NULL, 0, SND_SOC_NOPM, 0, 0),
425 SND_SOC_DAPM_AIF_OUT("AD_OUT2", NULL, 0, SND_SOC_NOPM, 0, 0),
426 SND_SOC_DAPM_AIF_OUT("AD_OUT3", NULL, 0, SND_SOC_NOPM, 0, 0),
427 SND_SOC_DAPM_AIF_OUT("AD_OUT4", NULL, 0, SND_SOC_NOPM, 0, 0),
428 SND_SOC_DAPM_AIF_OUT("AD_OUT57", NULL, 0, SND_SOC_NOPM, 0, 0),
429 SND_SOC_DAPM_AIF_OUT("AD_OUT68", NULL, 0, SND_SOC_NOPM, 0, 0),
430
431 /* Headset path */
432
433 SND_SOC_DAPM_SUPPLY("Charge Pump", AB8500_ANACONF5,
434 AB8500_ANACONF5_ENCPHS, 0, NULL, 0),
435
436 SND_SOC_DAPM_DAC("DA1 Enable", "ab8500_0p",
437 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA1, 0),
438 SND_SOC_DAPM_DAC("DA2 Enable", "ab8500_0p",
439 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA2, 0),
440
441 SND_SOC_DAPM_PGA("HSL Digital Volume", SND_SOC_NOPM, 0, 0,
442 NULL, 0),
443 SND_SOC_DAPM_PGA("HSR Digital Volume", SND_SOC_NOPM, 0, 0,
444 NULL, 0),
445
446 SND_SOC_DAPM_DAC("HSL DAC", "ab8500_0p",
447 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSL, 0),
448 SND_SOC_DAPM_DAC("HSR DAC", "ab8500_0p",
449 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHSR, 0),
450 SND_SOC_DAPM_MIXER("HSL DAC Mute", AB8500_MUTECONF,
451 AB8500_MUTECONF_MUTDACHSL, 1,
452 NULL, 0),
453 SND_SOC_DAPM_MIXER("HSR DAC Mute", AB8500_MUTECONF,
454 AB8500_MUTECONF_MUTDACHSR, 1,
455 NULL, 0),
456 SND_SOC_DAPM_DAC("HSL DAC Driver", "ab8500_0p",
457 AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSL, 0),
458 SND_SOC_DAPM_DAC("HSR DAC Driver", "ab8500_0p",
459 AB8500_ANACONF3, AB8500_ANACONF3_ENDRVHSR, 0),
460
461 SND_SOC_DAPM_MIXER("HSL Mute",
462 AB8500_MUTECONF, AB8500_MUTECONF_MUTHSL, 1,
463 NULL, 0),
464 SND_SOC_DAPM_MIXER("HSR Mute",
465 AB8500_MUTECONF, AB8500_MUTECONF_MUTHSR, 1,
466 NULL, 0),
467 SND_SOC_DAPM_MIXER("HSL Enable",
468 AB8500_ANACONF4, AB8500_ANACONF4_ENHSL, 0,
469 NULL, 0),
470 SND_SOC_DAPM_MIXER("HSR Enable",
471 AB8500_ANACONF4, AB8500_ANACONF4_ENHSR, 0,
472 NULL, 0),
473 SND_SOC_DAPM_PGA("HSL Volume",
474 SND_SOC_NOPM, 0, 0,
475 NULL, 0),
476 SND_SOC_DAPM_PGA("HSR Volume",
477 SND_SOC_NOPM, 0, 0,
478 NULL, 0),
479
480 SND_SOC_DAPM_OUTPUT("Headset Left"),
481 SND_SOC_DAPM_OUTPUT("Headset Right"),
482
483 /* LineOut path */
484
485 SND_SOC_DAPM_MUX("LineOut Source",
486 SND_SOC_NOPM, 0, 0, dapm_lineout_source),
487
488 SND_SOC_DAPM_MIXER("LOL Disable HFL",
489 AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 1,
490 NULL, 0),
491 SND_SOC_DAPM_MIXER("LOR Disable HFR",
492 AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 1,
493 NULL, 0),
494
495 SND_SOC_DAPM_MIXER("LOL Enable",
496 AB8500_ANACONF5, AB8500_ANACONF5_ENLOL, 0,
497 NULL, 0),
498 SND_SOC_DAPM_MIXER("LOR Enable",
499 AB8500_ANACONF5, AB8500_ANACONF5_ENLOR, 0,
500 NULL, 0),
501
502 SND_SOC_DAPM_OUTPUT("LineOut Left"),
503 SND_SOC_DAPM_OUTPUT("LineOut Right"),
504
505 /* Earpiece path */
506
507 SND_SOC_DAPM_MUX("Earpiece or LineOut Mono Source",
508 SND_SOC_NOPM, 0, 0, &dapm_ear_lineout_source),
509 SND_SOC_DAPM_MIXER("EAR DAC",
510 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACEAR, 0,
511 NULL, 0),
512 SND_SOC_DAPM_MIXER("EAR Mute",
513 AB8500_MUTECONF, AB8500_MUTECONF_MUTEAR, 1,
514 NULL, 0),
515 SND_SOC_DAPM_MIXER("EAR Enable",
516 AB8500_ANACONF4, AB8500_ANACONF4_ENEAR, 0,
517 NULL, 0),
518
519 SND_SOC_DAPM_OUTPUT("Earpiece"),
520
521 /* Handsfree path */
522
523 SND_SOC_DAPM_MIXER("DA3 Channel Volume",
524 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA3, 0,
525 NULL, 0),
526 SND_SOC_DAPM_MIXER("DA4 Channel Volume",
527 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA4, 0,
528 NULL, 0),
529 SND_SOC_DAPM_MUX("Speaker Left Source",
530 SND_SOC_NOPM, 0, 0, dapm_HFl_select),
531 SND_SOC_DAPM_MUX("Speaker Right Source",
532 SND_SOC_NOPM, 0, 0, dapm_HFr_select),
533 SND_SOC_DAPM_MIXER("HFL DAC", AB8500_DAPATHCONF,
534 AB8500_DAPATHCONF_ENDACHFL, 0,
535 NULL, 0),
536 SND_SOC_DAPM_MIXER("HFR DAC",
537 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACHFR, 0,
538 NULL, 0),
539 SND_SOC_DAPM_MIXER("DA4 or ANC path to HfR",
540 AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFREN, 0,
541 NULL, 0),
542 SND_SOC_DAPM_MIXER("DA3 or ANC path to HfL",
543 AB8500_DIGMULTCONF2, AB8500_DIGMULTCONF2_DATOHFLEN, 0,
544 NULL, 0),
545 SND_SOC_DAPM_MIXER("HFL Enable",
546 AB8500_ANACONF4, AB8500_ANACONF4_ENHFL, 0,
547 NULL, 0),
548 SND_SOC_DAPM_MIXER("HFR Enable",
549 AB8500_ANACONF4, AB8500_ANACONF4_ENHFR, 0,
550 NULL, 0),
551
552 SND_SOC_DAPM_OUTPUT("Speaker Left"),
553 SND_SOC_DAPM_OUTPUT("Speaker Right"),
554
555 /* Vibrator path */
556
557 SND_SOC_DAPM_INPUT("PWMGEN1"),
558 SND_SOC_DAPM_INPUT("PWMGEN2"),
559
560 SND_SOC_DAPM_MIXER("DA5 Channel Volume",
561 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA5, 0,
562 NULL, 0),
563 SND_SOC_DAPM_MIXER("DA6 Channel Volume",
564 AB8500_DAPATHENA, AB8500_DAPATHENA_ENDA6, 0,
565 NULL, 0),
566 SND_SOC_DAPM_MIXER("VIB1 DAC",
567 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB1, 0,
568 NULL, 0),
569 SND_SOC_DAPM_MIXER("VIB2 DAC",
570 AB8500_DAPATHCONF, AB8500_DAPATHCONF_ENDACVIB2, 0,
571 NULL, 0),
572 SND_SOC_DAPM_MUX("Vibra 1 Controller",
573 SND_SOC_NOPM, 0, 0, dapm_pwm2vib1),
574 SND_SOC_DAPM_MUX("Vibra 2 Controller",
575 SND_SOC_NOPM, 0, 0, dapm_pwm2vib2),
576 SND_SOC_DAPM_MIXER("VIB1 Enable",
577 AB8500_ANACONF4, AB8500_ANACONF4_ENVIB1, 0,
578 NULL, 0),
579 SND_SOC_DAPM_MIXER("VIB2 Enable",
580 AB8500_ANACONF4, AB8500_ANACONF4_ENVIB2, 0,
581 NULL, 0),
582
583 SND_SOC_DAPM_OUTPUT("Vibra 1"),
584 SND_SOC_DAPM_OUTPUT("Vibra 2"),
585
586 /* Mic 1 */
587
588 SND_SOC_DAPM_INPUT("Mic 1"),
589
590 SND_SOC_DAPM_MUX("Mic 1a or 1b Select",
591 SND_SOC_NOPM, 0, 0, dapm_mic1ab_mux),
592 SND_SOC_DAPM_MIXER("MIC1 Mute",
593 AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC1, 1,
594 NULL, 0),
595 SND_SOC_DAPM_MIXER("MIC1A V-AMICx Enable",
596 AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0,
597 NULL, 0),
598 SND_SOC_DAPM_MIXER("MIC1B V-AMICx Enable",
599 AB8500_ANACONF2, AB8500_ANACONF2_ENMIC1, 0,
600 NULL, 0),
601 SND_SOC_DAPM_MIXER("MIC1 ADC",
602 AB8500_ANACONF3, AB8500_ANACONF3_ENADCMIC, 0,
603 NULL, 0),
604 SND_SOC_DAPM_MUX("AD3 Source Select",
605 SND_SOC_NOPM, 0, 0, dapm_ad3_select),
606 SND_SOC_DAPM_MIXER("AD3 Channel Volume",
607 SND_SOC_NOPM, 0, 0,
608 NULL, 0),
609 SND_SOC_DAPM_MIXER("AD3 Enable",
610 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, 0,
611 NULL, 0),
612
613 /* Mic 2 */
614
615 SND_SOC_DAPM_INPUT("Mic 2"),
616
617 SND_SOC_DAPM_MIXER("MIC2 Mute",
618 AB8500_ANACONF2, AB8500_ANACONF2_MUTMIC2, 1,
619 NULL, 0),
620 SND_SOC_DAPM_MIXER("MIC2 V-AMICx Enable", AB8500_ANACONF2,
621 AB8500_ANACONF2_ENMIC2, 0,
622 NULL, 0),
623
624 /* LineIn */
625
626 SND_SOC_DAPM_INPUT("LineIn Left"),
627 SND_SOC_DAPM_INPUT("LineIn Right"),
628
629 SND_SOC_DAPM_MIXER("LINL Mute",
630 AB8500_ANACONF2, AB8500_ANACONF2_MUTLINL, 1,
631 NULL, 0),
632 SND_SOC_DAPM_MIXER("LINR Mute",
633 AB8500_ANACONF2, AB8500_ANACONF2_MUTLINR, 1,
634 NULL, 0),
635 SND_SOC_DAPM_MIXER("LINL Enable", AB8500_ANACONF2,
636 AB8500_ANACONF2_ENLINL, 0,
637 NULL, 0),
638 SND_SOC_DAPM_MIXER("LINR Enable", AB8500_ANACONF2,
639 AB8500_ANACONF2_ENLINR, 0,
640 NULL, 0),
641
642 /* LineIn Bypass path */
643 SND_SOC_DAPM_MIXER("LINL to HSL Volume",
644 SND_SOC_NOPM, 0, 0,
645 NULL, 0),
646 SND_SOC_DAPM_MIXER("LINR to HSR Volume",
647 SND_SOC_NOPM, 0, 0,
648 NULL, 0),
649
650 /* LineIn, Mic 2 */
651 SND_SOC_DAPM_MUX("Mic 2 or LINR Select",
652 SND_SOC_NOPM, 0, 0, dapm_mic2lr_select),
653 SND_SOC_DAPM_MIXER("LINL ADC", AB8500_ANACONF3,
654 AB8500_ANACONF3_ENADCLINL, 0,
655 NULL, 0),
656 SND_SOC_DAPM_MIXER("LINR ADC", AB8500_ANACONF3,
657 AB8500_ANACONF3_ENADCLINR, 0,
658 NULL, 0),
659 SND_SOC_DAPM_MUX("AD1 Source Select",
660 SND_SOC_NOPM, 0, 0, dapm_ad1_select),
661 SND_SOC_DAPM_MUX("AD2 Source Select",
662 SND_SOC_NOPM, 0, 0, dapm_ad2_select),
663 SND_SOC_DAPM_MIXER("AD1 Channel Volume",
664 SND_SOC_NOPM, 0, 0,
665 NULL, 0),
666 SND_SOC_DAPM_MIXER("AD2 Channel Volume",
667 SND_SOC_NOPM, 0, 0,
668 NULL, 0),
669
670 SND_SOC_DAPM_MIXER("AD12 Enable",
671 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD12, 0,
672 NULL, 0),
673
674 /* HD Capture path */
675
676 SND_SOC_DAPM_MUX("AD5 Source Select",
677 SND_SOC_NOPM, 0, 0, dapm_ad5_select),
678 SND_SOC_DAPM_MUX("AD6 Source Select",
679 SND_SOC_NOPM, 0, 0, dapm_ad6_select),
680 SND_SOC_DAPM_MIXER("AD5 Channel Volume",
681 SND_SOC_NOPM, 0, 0,
682 NULL, 0),
683 SND_SOC_DAPM_MIXER("AD6 Channel Volume",
684 SND_SOC_NOPM, 0, 0,
685 NULL, 0),
686 SND_SOC_DAPM_MIXER("AD57 Enable",
687 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0,
688 NULL, 0),
689 SND_SOC_DAPM_MIXER("AD68 Enable",
690 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0,
691 NULL, 0),
692
693 /* Digital Microphone path */
694
695 SND_SOC_DAPM_INPUT("DMic 1"),
696 SND_SOC_DAPM_INPUT("DMic 2"),
697 SND_SOC_DAPM_INPUT("DMic 3"),
698 SND_SOC_DAPM_INPUT("DMic 4"),
699 SND_SOC_DAPM_INPUT("DMic 5"),
700 SND_SOC_DAPM_INPUT("DMic 6"),
701
702 SND_SOC_DAPM_MIXER("DMIC1",
703 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC1, 0,
704 NULL, 0),
705 SND_SOC_DAPM_MIXER("DMIC2",
706 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC2, 0,
707 NULL, 0),
708 SND_SOC_DAPM_MIXER("DMIC3",
709 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC3, 0,
710 NULL, 0),
711 SND_SOC_DAPM_MIXER("DMIC4",
712 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC4, 0,
713 NULL, 0),
714 SND_SOC_DAPM_MIXER("DMIC5",
715 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC5, 0,
716 NULL, 0),
717 SND_SOC_DAPM_MIXER("DMIC6",
718 AB8500_DIGMICCONF, AB8500_DIGMICCONF_ENDMIC6, 0,
719 NULL, 0),
720 SND_SOC_DAPM_MIXER("AD4 Channel Volume",
721 SND_SOC_NOPM, 0, 0,
722 NULL, 0),
723 SND_SOC_DAPM_MIXER("AD4 Enable",
724 AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34,
725 0, NULL, 0),
726
727 /* Acoustical Noise Cancellation path */
728
729 SND_SOC_DAPM_INPUT("ANC Configure Input"),
730 SND_SOC_DAPM_OUTPUT("ANC Configure Output"),
731
732 SND_SOC_DAPM_MUX("ANC Source",
733 SND_SOC_NOPM, 0, 0,
734 dapm_anc_in_select),
735 SND_SOC_DAPM_SWITCH("ANC",
736 SND_SOC_NOPM, 0, 0,
737 dapm_anc_enable),
738 SND_SOC_DAPM_SWITCH("ANC to Earpiece",
739 SND_SOC_NOPM, 0, 0,
740 dapm_anc_ear_mute),
741
742 /* Sidetone Filter path */
743
744 SND_SOC_DAPM_MUX("Sidetone Left Source",
745 SND_SOC_NOPM, 0, 0,
746 dapm_stfir1_in_select),
747 SND_SOC_DAPM_MUX("Sidetone Right Source",
748 SND_SOC_NOPM, 0, 0,
749 dapm_stfir2_in_select),
750 SND_SOC_DAPM_MIXER("STFIR1 Control",
751 SND_SOC_NOPM, 0, 0,
752 NULL, 0),
753 SND_SOC_DAPM_MIXER("STFIR2 Control",
754 SND_SOC_NOPM, 0, 0,
755 NULL, 0),
756 SND_SOC_DAPM_MIXER("STFIR1 Volume",
757 SND_SOC_NOPM, 0, 0,
758 NULL, 0),
759 SND_SOC_DAPM_MIXER("STFIR2 Volume",
760 SND_SOC_NOPM, 0, 0,
761 NULL, 0),
762};
763
764/*
765 * DAPM-routes
766 */
767static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
768 /* Power AB8500 audio-block when AD/DA is active */
769 {"Main Supply", NULL, "V-AUD"},
770 {"Main Supply", NULL, "audioclk"},
771 {"Main Supply", NULL, "Audio Power"},
772 {"Main Supply", NULL, "Audio Analog Power"},
773
774 {"DAC", NULL, "ab8500_0p"},
775 {"DAC", NULL, "Main Supply"},
776 {"ADC", NULL, "ab8500_0c"},
777 {"ADC", NULL, "Main Supply"},
778
779 /* ANC Configure */
780 {"ANC Configure Input", NULL, "Main Supply"},
781 {"ANC Configure Output", NULL, "ANC Configure Input"},
782
783 /* AD/DA */
784 {"ADC", NULL, "ADC Input"},
785 {"DAC Output", NULL, "DAC"},
786
787 /* Powerup charge pump if DA1/2 is in use */
788
789 {"DA_IN1", NULL, "ab8500_0p"},
790 {"DA_IN1", NULL, "Charge Pump"},
791 {"DA_IN2", NULL, "ab8500_0p"},
792 {"DA_IN2", NULL, "Charge Pump"},
793
794 /* Headset path */
795
796 {"DA1 Enable", NULL, "DA_IN1"},
797 {"DA2 Enable", NULL, "DA_IN2"},
798
799 {"HSL Digital Volume", NULL, "DA1 Enable"},
800 {"HSR Digital Volume", NULL, "DA2 Enable"},
801
802 {"HSL DAC", NULL, "HSL Digital Volume"},
803 {"HSR DAC", NULL, "HSR Digital Volume"},
804
805 {"HSL DAC Mute", NULL, "HSL DAC"},
806 {"HSR DAC Mute", NULL, "HSR DAC"},
807
808 {"HSL DAC Driver", NULL, "HSL DAC Mute"},
809 {"HSR DAC Driver", NULL, "HSR DAC Mute"},
810
811 {"HSL Mute", NULL, "HSL DAC Driver"},
812 {"HSR Mute", NULL, "HSR DAC Driver"},
813
814 {"HSL Enable", NULL, "HSL Mute"},
815 {"HSR Enable", NULL, "HSR Mute"},
816
817 {"HSL Volume", NULL, "HSL Enable"},
818 {"HSR Volume", NULL, "HSR Enable"},
819
820 {"Headset Left", NULL, "HSL Volume"},
821 {"Headset Right", NULL, "HSR Volume"},
822
823 /* HF or LineOut path */
824
825 {"DA_IN3", NULL, "ab8500_0p"},
826 {"DA3 Channel Volume", NULL, "DA_IN3"},
827 {"DA_IN4", NULL, "ab8500_0p"},
828 {"DA4 Channel Volume", NULL, "DA_IN4"},
829
830 {"Speaker Left Source", "Audio Path", "DA3 Channel Volume"},
831 {"Speaker Right Source", "Audio Path", "DA4 Channel Volume"},
832
833 {"DA3 or ANC path to HfL", NULL, "Speaker Left Source"},
834 {"DA4 or ANC path to HfR", NULL, "Speaker Right Source"},
835
836 /* HF path */
837
838 {"HFL DAC", NULL, "DA3 or ANC path to HfL"},
839 {"HFR DAC", NULL, "DA4 or ANC path to HfR"},
840
841 {"HFL Enable", NULL, "HFL DAC"},
842 {"HFR Enable", NULL, "HFR DAC"},
843
844 {"Speaker Left", NULL, "HFL Enable"},
845 {"Speaker Right", NULL, "HFR Enable"},
846
847 /* Earpiece path */
848
849 {"Earpiece or LineOut Mono Source", "Headset Left",
850 "HSL Digital Volume"},
851 {"Earpiece or LineOut Mono Source", "Speaker Left",
852 "DA3 or ANC path to HfL"},
853
854 {"EAR DAC", NULL, "Earpiece or LineOut Mono Source"},
855
856 {"EAR Mute", NULL, "EAR DAC"},
857
858 {"EAR Enable", NULL, "EAR Mute"},
859
860 {"Earpiece", NULL, "EAR Enable"},
861
862 /* LineOut path stereo */
863
864 {"LineOut Source", "Stereo Path", "HSL DAC Driver"},
865 {"LineOut Source", "Stereo Path", "HSR DAC Driver"},
866
867 /* LineOut path mono */
868
869 {"LineOut Source", "Mono Path", "EAR DAC"},
870
871 /* LineOut path */
872
873 {"LOL Disable HFL", NULL, "LineOut Source"},
874 {"LOR Disable HFR", NULL, "LineOut Source"},
875
876 {"LOL Enable", NULL, "LOL Disable HFL"},
877 {"LOR Enable", NULL, "LOR Disable HFR"},
878
879 {"LineOut Left", NULL, "LOL Enable"},
880 {"LineOut Right", NULL, "LOR Enable"},
881
882 /* Vibrator path */
883
884 {"DA_IN5", NULL, "ab8500_0p"},
885 {"DA5 Channel Volume", NULL, "DA_IN5"},
886 {"DA_IN6", NULL, "ab8500_0p"},
887 {"DA6 Channel Volume", NULL, "DA_IN6"},
888
889 {"VIB1 DAC", NULL, "DA5 Channel Volume"},
890 {"VIB2 DAC", NULL, "DA6 Channel Volume"},
891
892 {"Vibra 1 Controller", "Audio Path", "VIB1 DAC"},
893 {"Vibra 2 Controller", "Audio Path", "VIB2 DAC"},
894 {"Vibra 1 Controller", "PWM Generator", "PWMGEN1"},
895 {"Vibra 2 Controller", "PWM Generator", "PWMGEN2"},
896
897 {"VIB1 Enable", NULL, "Vibra 1 Controller"},
898 {"VIB2 Enable", NULL, "Vibra 2 Controller"},
899
900 {"Vibra 1", NULL, "VIB1 Enable"},
901 {"Vibra 2", NULL, "VIB2 Enable"},
902
903
904 /* Mic 2 */
905
906 {"MIC2 V-AMICx Enable", NULL, "Mic 2"},
907
908 /* LineIn */
909 {"LINL Mute", NULL, "LineIn Left"},
910 {"LINR Mute", NULL, "LineIn Right"},
911
912 {"LINL Enable", NULL, "LINL Mute"},
913 {"LINR Enable", NULL, "LINR Mute"},
914
915 /* LineIn, Mic 2 */
916 {"Mic 2 or LINR Select", "LineIn Right", "LINR Enable"},
917 {"Mic 2 or LINR Select", "Mic 2", "MIC2 V-AMICx Enable"},
918
919 {"LINL ADC", NULL, "LINL Enable"},
920 {"LINR ADC", NULL, "Mic 2 or LINR Select"},
921
922 {"AD1 Source Select", "LineIn Left", "LINL ADC"},
923 {"AD2 Source Select", "LineIn Right", "LINR ADC"},
924
925 {"AD1 Channel Volume", NULL, "AD1 Source Select"},
926 {"AD2 Channel Volume", NULL, "AD2 Source Select"},
927
928 {"AD12 Enable", NULL, "AD1 Channel Volume"},
929 {"AD12 Enable", NULL, "AD2 Channel Volume"},
930
931 {"AD_OUT1", NULL, "ab8500_0c"},
932 {"AD_OUT1", NULL, "AD12 Enable"},
933 {"AD_OUT2", NULL, "ab8500_0c"},
934 {"AD_OUT2", NULL, "AD12 Enable"},
935
936 /* Mic 1 */
937
938 {"MIC1 Mute", NULL, "Mic 1"},
939
940 {"MIC1A V-AMICx Enable", NULL, "MIC1 Mute"},
941 {"MIC1B V-AMICx Enable", NULL, "MIC1 Mute"},
942
943 {"Mic 1a or 1b Select", "Mic 1a", "MIC1A V-AMICx Enable"},
944 {"Mic 1a or 1b Select", "Mic 1b", "MIC1B V-AMICx Enable"},
945
946 {"MIC1 ADC", NULL, "Mic 1a or 1b Select"},
947
948 {"AD3 Source Select", "Mic 1", "MIC1 ADC"},
949
950 {"AD3 Channel Volume", NULL, "AD3 Source Select"},
951
952 {"AD3 Enable", NULL, "AD3 Channel Volume"},
953
954 {"AD_OUT3", NULL, "ab8500_0c"},
955 {"AD_OUT3", NULL, "AD3 Enable"},
956
957 /* HD Capture path */
958
959 {"AD5 Source Select", "Mic 2", "LINR ADC"},
960 {"AD6 Source Select", "Mic 1", "MIC1 ADC"},
961
962 {"AD5 Channel Volume", NULL, "AD5 Source Select"},
963 {"AD6 Channel Volume", NULL, "AD6 Source Select"},
964
965 {"AD57 Enable", NULL, "AD5 Channel Volume"},
966 {"AD68 Enable", NULL, "AD6 Channel Volume"},
967
968 {"AD_OUT57", NULL, "ab8500_0c"},
969 {"AD_OUT57", NULL, "AD57 Enable"},
970 {"AD_OUT68", NULL, "ab8500_0c"},
971 {"AD_OUT68", NULL, "AD68 Enable"},
972
973 /* Digital Microphone path */
974
975 {"DMic 1", NULL, "V-DMIC"},
976 {"DMic 2", NULL, "V-DMIC"},
977 {"DMic 3", NULL, "V-DMIC"},
978 {"DMic 4", NULL, "V-DMIC"},
979 {"DMic 5", NULL, "V-DMIC"},
980 {"DMic 6", NULL, "V-DMIC"},
981
982 {"AD1 Source Select", NULL, "DMic 1"},
983 {"AD2 Source Select", NULL, "DMic 2"},
984 {"AD3 Source Select", NULL, "DMic 3"},
985 {"AD5 Source Select", NULL, "DMic 5"},
986 {"AD6 Source Select", NULL, "DMic 6"},
987
988 {"AD4 Channel Volume", NULL, "DMic 4"},
989 {"AD4 Enable", NULL, "AD4 Channel Volume"},
990
991 {"AD_OUT4", NULL, "ab8500_0c"},
992 {"AD_OUT4", NULL, "AD4 Enable"},
993
994 /* LineIn Bypass path */
995
996 {"LINL to HSL Volume", NULL, "LINL Enable"},
997 {"LINR to HSR Volume", NULL, "LINR Enable"},
998
999 {"HSL DAC Driver", NULL, "LINL to HSL Volume"},
1000 {"HSR DAC Driver", NULL, "LINR to HSR Volume"},
1001
1002 /* ANC path (Acoustic Noise Cancellation) */
1003
1004 {"ANC Source", "Mic 2 / DMic 5", "AD5 Channel Volume"},
1005 {"ANC Source", "Mic 1 / DMic 6", "AD6 Channel Volume"},
1006
1007 {"ANC", "Switch", "ANC Source"},
1008
1009 {"Speaker Left Source", "ANC", "ANC"},
1010 {"Speaker Right Source", "ANC", "ANC"},
1011 {"ANC to Earpiece", "Switch", "ANC"},
1012
1013 {"HSL Digital Volume", NULL, "ANC to Earpiece"},
1014
1015 /* Sidetone Filter path */
1016
1017 {"Sidetone Left Source", "LineIn Left", "AD12 Enable"},
1018 {"Sidetone Left Source", "LineIn Right", "AD12 Enable"},
1019 {"Sidetone Left Source", "Mic 1", "AD3 Enable"},
1020 {"Sidetone Left Source", "Headset Left", "DA_IN1"},
1021 {"Sidetone Right Source", "LineIn Right", "AD12 Enable"},
1022 {"Sidetone Right Source", "Mic 1", "AD3 Enable"},
1023 {"Sidetone Right Source", "DMic 4", "AD4 Enable"},
1024 {"Sidetone Right Source", "Headset Right", "DA_IN2"},
1025
1026 {"STFIR1 Control", NULL, "Sidetone Left Source"},
1027 {"STFIR2 Control", NULL, "Sidetone Right Source"},
1028
1029 {"STFIR1 Volume", NULL, "STFIR1 Control"},
1030 {"STFIR2 Volume", NULL, "STFIR2 Control"},
1031
1032 {"DA1 Enable", NULL, "STFIR1 Volume"},
1033 {"DA2 Enable", NULL, "STFIR2 Volume"},
1034};
1035
1036static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1a_vamicx[] = {
1037 {"MIC1A V-AMICx Enable", NULL, "V-AMIC1"},
1038 {"MIC1A V-AMICx Enable", NULL, "V-AMIC2"},
1039};
1040
1041static const struct snd_soc_dapm_route ab8500_dapm_routes_mic1b_vamicx[] = {
1042 {"MIC1B V-AMICx Enable", NULL, "V-AMIC1"},
1043 {"MIC1B V-AMICx Enable", NULL, "V-AMIC2"},
1044};
1045
1046static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
1047 {"MIC2 V-AMICx Enable", NULL, "V-AMIC1"},
1048 {"MIC2 V-AMICx Enable", NULL, "V-AMIC2"},
1049};
1050
1051/* ANC FIR-coefficients configuration sequence */
1052static void anc_fir(struct snd_soc_codec *codec,
1053 unsigned int bnk, unsigned int par, unsigned int val)
1054{
1055 if (par == 0 && bnk == 0)
1056 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1057 BIT(AB8500_ANCCONF1_ANCFIRUPDATE),
1058 BIT(AB8500_ANCCONF1_ANCFIRUPDATE));
1059
1060 snd_soc_write(codec, AB8500_ANCCONF5, val >> 8 & 0xff);
1061 snd_soc_write(codec, AB8500_ANCCONF6, val & 0xff);
1062
1063 if (par == AB8500_ANC_FIR_COEFFS - 1 && bnk == 1)
1064 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1065 BIT(AB8500_ANCCONF1_ANCFIRUPDATE), 0);
1066}
1067
1068/* ANC IIR-coefficients configuration sequence */
1069static void anc_iir(struct snd_soc_codec *codec, unsigned int bnk,
1070 unsigned int par, unsigned int val)
1071{
1072 if (par == 0) {
1073 if (bnk == 0) {
1074 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1075 BIT(AB8500_ANCCONF1_ANCIIRINIT),
1076 BIT(AB8500_ANCCONF1_ANCIIRINIT));
1077 usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
1078 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1079 BIT(AB8500_ANCCONF1_ANCIIRINIT), 0);
1080 usleep_range(AB8500_ANC_SM_DELAY, AB8500_ANC_SM_DELAY);
1081 } else {
1082 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1083 BIT(AB8500_ANCCONF1_ANCIIRUPDATE),
1084 BIT(AB8500_ANCCONF1_ANCIIRUPDATE));
1085 }
1086 } else if (par > 3) {
1087 snd_soc_write(codec, AB8500_ANCCONF7, 0);
1088 snd_soc_write(codec, AB8500_ANCCONF8, val >> 16 & 0xff);
1089 }
1090
1091 snd_soc_write(codec, AB8500_ANCCONF7, val >> 8 & 0xff);
1092 snd_soc_write(codec, AB8500_ANCCONF8, val & 0xff);
1093
1094 if (par == AB8500_ANC_IIR_COEFFS - 1 && bnk == 1)
1095 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1096 BIT(AB8500_ANCCONF1_ANCIIRUPDATE), 0);
1097}
1098
1099/* ANC IIR-/FIR-coefficients configuration sequence */
1100static void anc_configure(struct snd_soc_codec *codec,
1101 bool apply_fir, bool apply_iir)
1102{
1103 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1104 unsigned int bnk, par, val;
1105
1106 dev_dbg(codec->dev, "%s: Enter.\n", __func__);
1107
1108 if (apply_fir)
1109 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1110 BIT(AB8500_ANCCONF1_ENANC), 0);
1111
1112 snd_soc_update_bits(codec, AB8500_ANCCONF1,
1113 BIT(AB8500_ANCCONF1_ENANC), BIT(AB8500_ANCCONF1_ENANC));
1114
1115 if (apply_fir)
1116 for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
1117 for (par = 0; par < AB8500_ANC_FIR_COEFFS; par++) {
1118 val = snd_soc_read(codec,
1119 drvdata->anc_fir_values[par]);
1120 anc_fir(codec, bnk, par, val);
1121 }
1122
1123 if (apply_iir)
1124 for (bnk = 0; bnk < AB8500_NR_OF_ANC_COEFF_BANKS; bnk++)
1125 for (par = 0; par < AB8500_ANC_IIR_COEFFS; par++) {
1126 val = snd_soc_read(codec,
1127 drvdata->anc_iir_values[par]);
1128 anc_iir(codec, bnk, par, val);
1129 }
1130
1131 dev_dbg(codec->dev, "%s: Exit.\n", __func__);
1132}
1133
1134/*
1135 * Control-events
1136 */
1137
1138static int sid_status_control_get(struct snd_kcontrol *kcontrol,
1139 struct snd_ctl_elem_value *ucontrol)
1140{
1141 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1142 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1143
1144 mutex_lock(&codec->mutex);
1145 ucontrol->value.integer.value[0] = drvdata->sid_status;
1146 mutex_unlock(&codec->mutex);
1147
1148 return 0;
1149}
1150
1151/* Write sidetone FIR-coefficients configuration sequence */
1152static int sid_status_control_put(struct snd_kcontrol *kcontrol,
1153 struct snd_ctl_elem_value *ucontrol)
1154{
1155 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1156 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1157 unsigned int param, sidconf, val;
1158 int status = 1;
1159
1160 dev_dbg(codec->dev, "%s: Enter\n", __func__);
1161
1162 if (ucontrol->value.integer.value[0] != SID_APPLY_FIR) {
1163 dev_err(codec->dev,
1164 "%s: ERROR: This control supports '%s' only!\n",
1165 __func__, enum_sid_state[SID_APPLY_FIR]);
1166 return -EIO;
1167 }
1168
1169 mutex_lock(&codec->mutex);
1170
1171 sidconf = snd_soc_read(codec, AB8500_SIDFIRCONF);
1172 if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
1173 if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) {
1174 dev_err(codec->dev, "%s: Sidetone busy while off!\n",
1175 __func__);
1176 status = -EPERM;
1177 } else {
1178 status = -EBUSY;
1179 }
1180 goto out;
1181 }
1182
1183 snd_soc_write(codec, AB8500_SIDFIRADR, 0);
1184
1185 for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
1186 val = snd_soc_read(codec, drvdata->sid_fir_values[param]);
1187 snd_soc_write(codec, AB8500_SIDFIRCOEF1, val >> 8 & 0xff);
1188 snd_soc_write(codec, AB8500_SIDFIRCOEF2, val & 0xff);
1189 }
1190
1191 snd_soc_update_bits(codec, AB8500_SIDFIRADR,
1192 BIT(AB8500_SIDFIRADR_FIRSIDSET),
1193 BIT(AB8500_SIDFIRADR_FIRSIDSET));
1194 snd_soc_update_bits(codec, AB8500_SIDFIRADR,
1195 BIT(AB8500_SIDFIRADR_FIRSIDSET), 0);
1196
1197 drvdata->sid_status = SID_FIR_CONFIGURED;
1198
1199out:
1200 mutex_unlock(&codec->mutex);
1201
1202 dev_dbg(codec->dev, "%s: Exit\n", __func__);
1203
1204 return status;
1205}
1206
1207static int anc_status_control_get(struct snd_kcontrol *kcontrol,
1208 struct snd_ctl_elem_value *ucontrol)
1209{
1210 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1211 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1212
1213 mutex_lock(&codec->mutex);
1214 ucontrol->value.integer.value[0] = drvdata->anc_status;
1215 mutex_unlock(&codec->mutex);
1216
1217 return 0;
1218}
1219
1220static int anc_status_control_put(struct snd_kcontrol *kcontrol,
1221 struct snd_ctl_elem_value *ucontrol)
1222{
1223 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1224 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(codec->dev);
1225 struct device *dev = codec->dev;
1226 bool apply_fir, apply_iir;
1227 int req, status;
1228
1229 dev_dbg(dev, "%s: Enter.\n", __func__);
1230
1231 mutex_lock(&drvdata->anc_lock);
1232
1233 req = ucontrol->value.integer.value[0];
1234 if (req != ANC_APPLY_FIR_IIR && req != ANC_APPLY_FIR &&
1235 req != ANC_APPLY_IIR) {
1236 dev_err(dev, "%s: ERROR: Unsupported status to set '%s'!\n",
1237 __func__, enum_anc_state[req]);
1238 status = -EINVAL;
1239 goto cleanup;
1240 }
1241 apply_fir = req == ANC_APPLY_FIR || req == ANC_APPLY_FIR_IIR;
1242 apply_iir = req == ANC_APPLY_IIR || req == ANC_APPLY_FIR_IIR;
1243
1244 status = snd_soc_dapm_force_enable_pin(&codec->dapm,
1245 "ANC Configure Input");
1246 if (status < 0) {
1247 dev_err(dev,
1248 "%s: ERROR: Failed to enable power (status = %d)!\n",
1249 __func__, status);
1250 goto cleanup;
1251 }
1252 snd_soc_dapm_sync(&codec->dapm);
1253
1254 mutex_lock(&codec->mutex);
1255 anc_configure(codec, apply_fir, apply_iir);
1256 mutex_unlock(&codec->mutex);
1257
1258 if (apply_fir) {
1259 if (drvdata->anc_status == ANC_IIR_CONFIGURED)
1260 drvdata->anc_status = ANC_FIR_IIR_CONFIGURED;
1261 else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED)
1262 drvdata->anc_status = ANC_FIR_CONFIGURED;
1263 }
1264 if (apply_iir) {
1265 if (drvdata->anc_status == ANC_FIR_CONFIGURED)
1266 drvdata->anc_status = ANC_FIR_IIR_CONFIGURED;
1267 else if (drvdata->anc_status != ANC_FIR_IIR_CONFIGURED)
1268 drvdata->anc_status = ANC_IIR_CONFIGURED;
1269 }
1270
1271 status = snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input");
1272 snd_soc_dapm_sync(&codec->dapm);
1273
1274cleanup:
1275 mutex_unlock(&drvdata->anc_lock);
1276
1277 if (status < 0)
1278 dev_err(dev, "%s: Unable to configure ANC! (status = %d)\n",
1279 __func__, status);
1280
1281 dev_dbg(dev, "%s: Exit.\n", __func__);
1282
1283 return (status < 0) ? status : 1;
1284}
1285
1286static int filter_control_info(struct snd_kcontrol *kcontrol,
1287 struct snd_ctl_elem_info *uinfo)
1288{
1289 struct filter_control *fc =
1290 (struct filter_control *)kcontrol->private_value;
1291
1292 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1293 uinfo->count = fc->count;
1294 uinfo->value.integer.min = fc->min;
1295 uinfo->value.integer.max = fc->max;
1296
1297 return 0;
1298}
1299
1300static int filter_control_get(struct snd_kcontrol *kcontrol,
1301 struct snd_ctl_elem_value *ucontrol)
1302{
1303 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1304 struct filter_control *fc =
1305 (struct filter_control *)kcontrol->private_value;
1306 unsigned int i;
1307
1308 mutex_lock(&codec->mutex);
1309 for (i = 0; i < fc->count; i++)
1310 ucontrol->value.integer.value[i] = fc->value[i];
1311 mutex_unlock(&codec->mutex);
1312
1313 return 0;
1314}
1315
1316static int filter_control_put(struct snd_kcontrol *kcontrol,
1317 struct snd_ctl_elem_value *ucontrol)
1318{
1319 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
1320 struct filter_control *fc =
1321 (struct filter_control *)kcontrol->private_value;
1322 unsigned int i;
1323
1324 mutex_lock(&codec->mutex);
1325 for (i = 0; i < fc->count; i++)
1326 fc->value[i] = ucontrol->value.integer.value[i];
1327 mutex_unlock(&codec->mutex);
1328
1329 return 0;
1330}
1331
1332/*
1333 * Controls - Non-DAPM ASoC
1334 */
1335
1336static DECLARE_TLV_DB_SCALE(adx_dig_gain_tlv, -3200, 100, 1);
1337/* -32dB = Mute */
1338
1339static DECLARE_TLV_DB_SCALE(dax_dig_gain_tlv, -6300, 100, 1);
1340/* -63dB = Mute */
1341
1342static DECLARE_TLV_DB_SCALE(hs_ear_dig_gain_tlv, -100, 100, 1);
1343/* -1dB = Mute */
1344
1345static const unsigned int hs_gain_tlv[] = {
1346 TLV_DB_RANGE_HEAD(2),
1347 0, 3, TLV_DB_SCALE_ITEM(-3200, 400, 0),
1348 4, 15, TLV_DB_SCALE_ITEM(-1800, 200, 0),
1349};
1350
1351static DECLARE_TLV_DB_SCALE(mic_gain_tlv, 0, 100, 0);
1352
1353static DECLARE_TLV_DB_SCALE(lin_gain_tlv, -1000, 200, 0);
1354
1355static DECLARE_TLV_DB_SCALE(lin2hs_gain_tlv, -3800, 200, 1);
1356/* -38dB = Mute */
1357
1358static const char * const enum_hsfadspeed[] = {"2ms", "0.5ms", "10.6ms",
1359 "5ms"};
1360static SOC_ENUM_SINGLE_DECL(soc_enum_hsfadspeed,
1361 AB8500_DIGMICCONF, AB8500_DIGMICCONF_HSFADSPEED, enum_hsfadspeed);
1362
1363static const char * const enum_envdetthre[] = {
1364 "250mV", "300mV", "350mV", "400mV",
1365 "450mV", "500mV", "550mV", "600mV",
1366 "650mV", "700mV", "750mV", "800mV",
1367 "850mV", "900mV", "950mV", "1.00V" };
1368static SOC_ENUM_SINGLE_DECL(soc_enum_envdeththre,
1369 AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETHTHRE, enum_envdetthre);
1370static SOC_ENUM_SINGLE_DECL(soc_enum_envdetlthre,
1371 AB8500_ENVCPCONF, AB8500_ENVCPCONF_ENVDETLTHRE, enum_envdetthre);
1372static const char * const enum_envdettime[] = {
1373 "26.6us", "53.2us", "106us", "213us",
1374 "426us", "851us", "1.70ms", "3.40ms",
1375 "6.81ms", "13.6ms", "27.2ms", "54.5ms",
1376 "109ms", "218ms", "436ms", "872ms" };
1377static SOC_ENUM_SINGLE_DECL(soc_enum_envdettime,
1378 AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETTIME, enum_envdettime);
1379
1380static const char * const enum_sinc31[] = {"Sinc 3", "Sinc 1"};
1381static SOC_ENUM_SINGLE_DECL(soc_enum_hsesinc, AB8500_HSLEARDIGGAIN,
1382 AB8500_HSLEARDIGGAIN_HSSINC1, enum_sinc31);
1383
1384static const char * const enum_fadespeed[] = {"1ms", "4ms", "8ms", "16ms"};
1385static SOC_ENUM_SINGLE_DECL(soc_enum_fadespeed, AB8500_HSRDIGGAIN,
1386 AB8500_HSRDIGGAIN_FADESPEED, enum_fadespeed);
1387
1388/* Earpiece */
1389
1390static const char * const enum_lowpow[] = {"Normal", "Low Power"};
1391static SOC_ENUM_SINGLE_DECL(soc_enum_eardaclowpow, AB8500_ANACONF1,
1392 AB8500_ANACONF1_EARDACLOWPOW, enum_lowpow);
1393static SOC_ENUM_SINGLE_DECL(soc_enum_eardrvlowpow, AB8500_ANACONF1,
1394 AB8500_ANACONF1_EARDRVLOWPOW, enum_lowpow);
1395
1396static const char * const enum_av_mode[] = {"Audio", "Voice"};
1397static SOC_ENUM_DOUBLE_DECL(soc_enum_ad12voice, AB8500_ADFILTCONF,
1398 AB8500_ADFILTCONF_AD1VOICE, AB8500_ADFILTCONF_AD2VOICE, enum_av_mode);
1399static SOC_ENUM_DOUBLE_DECL(soc_enum_ad34voice, AB8500_ADFILTCONF,
1400 AB8500_ADFILTCONF_AD3VOICE, AB8500_ADFILTCONF_AD4VOICE, enum_av_mode);
1401
1402/* DA */
1403
1404static SOC_ENUM_SINGLE_DECL(soc_enum_da12voice,
1405 AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DA12VOICE,
1406 enum_av_mode);
1407static SOC_ENUM_SINGLE_DECL(soc_enum_da34voice,
1408 AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DA34VOICE,
1409 enum_av_mode);
1410static SOC_ENUM_SINGLE_DECL(soc_enum_da56voice,
1411 AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DA56VOICE,
1412 enum_av_mode);
1413
1414static const char * const enum_da2hslr[] = {"Sidetone", "Audio Path"};
1415static SOC_ENUM_DOUBLE_DECL(soc_enum_da2hslr, AB8500_DIGMULTCONF1,
1416 AB8500_DIGMULTCONF1_DATOHSLEN,
1417 AB8500_DIGMULTCONF1_DATOHSREN, enum_da2hslr);
1418
1419static const char * const enum_sinc53[] = {"Sinc 5", "Sinc 3"};
1420static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic12sinc, AB8500_DMICFILTCONF,
1421 AB8500_DMICFILTCONF_DMIC1SINC3,
1422 AB8500_DMICFILTCONF_DMIC2SINC3, enum_sinc53);
1423static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic34sinc, AB8500_DMICFILTCONF,
1424 AB8500_DMICFILTCONF_DMIC3SINC3,
1425 AB8500_DMICFILTCONF_DMIC4SINC3, enum_sinc53);
1426static SOC_ENUM_DOUBLE_DECL(soc_enum_dmic56sinc, AB8500_DMICFILTCONF,
1427 AB8500_DMICFILTCONF_DMIC5SINC3,
1428 AB8500_DMICFILTCONF_DMIC6SINC3, enum_sinc53);
1429
1430/* Digital interface - DA from slot mapping */
1431static const char * const enum_da_from_slot_map[] = {"SLOT0",
1432 "SLOT1",
1433 "SLOT2",
1434 "SLOT3",
1435 "SLOT4",
1436 "SLOT5",
1437 "SLOT6",
1438 "SLOT7",
1439 "SLOT8",
1440 "SLOT9",
1441 "SLOT10",
1442 "SLOT11",
1443 "SLOT12",
1444 "SLOT13",
1445 "SLOT14",
1446 "SLOT15",
1447 "SLOT16",
1448 "SLOT17",
1449 "SLOT18",
1450 "SLOT19",
1451 "SLOT20",
1452 "SLOT21",
1453 "SLOT22",
1454 "SLOT23",
1455 "SLOT24",
1456 "SLOT25",
1457 "SLOT26",
1458 "SLOT27",
1459 "SLOT28",
1460 "SLOT29",
1461 "SLOT30",
1462 "SLOT31"};
1463static SOC_ENUM_SINGLE_DECL(soc_enum_da1slotmap,
1464 AB8500_DASLOTCONF1, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1465 enum_da_from_slot_map);
1466static SOC_ENUM_SINGLE_DECL(soc_enum_da2slotmap,
1467 AB8500_DASLOTCONF2, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1468 enum_da_from_slot_map);
1469static SOC_ENUM_SINGLE_DECL(soc_enum_da3slotmap,
1470 AB8500_DASLOTCONF3, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1471 enum_da_from_slot_map);
1472static SOC_ENUM_SINGLE_DECL(soc_enum_da4slotmap,
1473 AB8500_DASLOTCONF4, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1474 enum_da_from_slot_map);
1475static SOC_ENUM_SINGLE_DECL(soc_enum_da5slotmap,
1476 AB8500_DASLOTCONF5, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1477 enum_da_from_slot_map);
1478static SOC_ENUM_SINGLE_DECL(soc_enum_da6slotmap,
1479 AB8500_DASLOTCONF6, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1480 enum_da_from_slot_map);
1481static SOC_ENUM_SINGLE_DECL(soc_enum_da7slotmap,
1482 AB8500_DASLOTCONF7, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1483 enum_da_from_slot_map);
1484static SOC_ENUM_SINGLE_DECL(soc_enum_da8slotmap,
1485 AB8500_DASLOTCONF8, AB8500_DASLOTCONFX_SLTODAX_SHIFT,
1486 enum_da_from_slot_map);
1487
1488/* Digital interface - AD to slot mapping */
1489static const char * const enum_ad_to_slot_map[] = {"AD_OUT1",
1490 "AD_OUT2",
1491 "AD_OUT3",
1492 "AD_OUT4",
1493 "AD_OUT5",
1494 "AD_OUT6",
1495 "AD_OUT7",
1496 "AD_OUT8",
1497 "zeroes",
1498 "tristate"};
1499static SOC_ENUM_SINGLE_DECL(soc_enum_adslot0map,
1500 AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_EVEN_SHIFT,
1501 enum_ad_to_slot_map);
1502static SOC_ENUM_SINGLE_DECL(soc_enum_adslot1map,
1503 AB8500_ADSLOTSEL1, AB8500_ADSLOTSELX_ODD_SHIFT,
1504 enum_ad_to_slot_map);
1505static SOC_ENUM_SINGLE_DECL(soc_enum_adslot2map,
1506 AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_EVEN_SHIFT,
1507 enum_ad_to_slot_map);
1508static SOC_ENUM_SINGLE_DECL(soc_enum_adslot3map,
1509 AB8500_ADSLOTSEL2, AB8500_ADSLOTSELX_ODD_SHIFT,
1510 enum_ad_to_slot_map);
1511static SOC_ENUM_SINGLE_DECL(soc_enum_adslot4map,
1512 AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_EVEN_SHIFT,
1513 enum_ad_to_slot_map);
1514static SOC_ENUM_SINGLE_DECL(soc_enum_adslot5map,
1515 AB8500_ADSLOTSEL3, AB8500_ADSLOTSELX_ODD_SHIFT,
1516 enum_ad_to_slot_map);
1517static SOC_ENUM_SINGLE_DECL(soc_enum_adslot6map,
1518 AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_EVEN_SHIFT,
1519 enum_ad_to_slot_map);
1520static SOC_ENUM_SINGLE_DECL(soc_enum_adslot7map,
1521 AB8500_ADSLOTSEL4, AB8500_ADSLOTSELX_ODD_SHIFT,
1522 enum_ad_to_slot_map);
1523static SOC_ENUM_SINGLE_DECL(soc_enum_adslot8map,
1524 AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_EVEN_SHIFT,
1525 enum_ad_to_slot_map);
1526static SOC_ENUM_SINGLE_DECL(soc_enum_adslot9map,
1527 AB8500_ADSLOTSEL5, AB8500_ADSLOTSELX_ODD_SHIFT,
1528 enum_ad_to_slot_map);
1529static SOC_ENUM_SINGLE_DECL(soc_enum_adslot10map,
1530 AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_EVEN_SHIFT,
1531 enum_ad_to_slot_map);
1532static SOC_ENUM_SINGLE_DECL(soc_enum_adslot11map,
1533 AB8500_ADSLOTSEL6, AB8500_ADSLOTSELX_ODD_SHIFT,
1534 enum_ad_to_slot_map);
1535static SOC_ENUM_SINGLE_DECL(soc_enum_adslot12map,
1536 AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_EVEN_SHIFT,
1537 enum_ad_to_slot_map);
1538static SOC_ENUM_SINGLE_DECL(soc_enum_adslot13map,
1539 AB8500_ADSLOTSEL7, AB8500_ADSLOTSELX_ODD_SHIFT,
1540 enum_ad_to_slot_map);
1541static SOC_ENUM_SINGLE_DECL(soc_enum_adslot14map,
1542 AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_EVEN_SHIFT,
1543 enum_ad_to_slot_map);
1544static SOC_ENUM_SINGLE_DECL(soc_enum_adslot15map,
1545 AB8500_ADSLOTSEL8, AB8500_ADSLOTSELX_ODD_SHIFT,
1546 enum_ad_to_slot_map);
1547static SOC_ENUM_SINGLE_DECL(soc_enum_adslot16map,
1548 AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_EVEN_SHIFT,
1549 enum_ad_to_slot_map);
1550static SOC_ENUM_SINGLE_DECL(soc_enum_adslot17map,
1551 AB8500_ADSLOTSEL9, AB8500_ADSLOTSELX_ODD_SHIFT,
1552 enum_ad_to_slot_map);
1553static SOC_ENUM_SINGLE_DECL(soc_enum_adslot18map,
1554 AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_EVEN_SHIFT,
1555 enum_ad_to_slot_map);
1556static SOC_ENUM_SINGLE_DECL(soc_enum_adslot19map,
1557 AB8500_ADSLOTSEL10, AB8500_ADSLOTSELX_ODD_SHIFT,
1558 enum_ad_to_slot_map);
1559static SOC_ENUM_SINGLE_DECL(soc_enum_adslot20map,
1560 AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_EVEN_SHIFT,
1561 enum_ad_to_slot_map);
1562static SOC_ENUM_SINGLE_DECL(soc_enum_adslot21map,
1563 AB8500_ADSLOTSEL11, AB8500_ADSLOTSELX_ODD_SHIFT,
1564 enum_ad_to_slot_map);
1565static SOC_ENUM_SINGLE_DECL(soc_enum_adslot22map,
1566 AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_EVEN_SHIFT,
1567 enum_ad_to_slot_map);
1568static SOC_ENUM_SINGLE_DECL(soc_enum_adslot23map,
1569 AB8500_ADSLOTSEL12, AB8500_ADSLOTSELX_ODD_SHIFT,
1570 enum_ad_to_slot_map);
1571static SOC_ENUM_SINGLE_DECL(soc_enum_adslot24map,
1572 AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_EVEN_SHIFT,
1573 enum_ad_to_slot_map);
1574static SOC_ENUM_SINGLE_DECL(soc_enum_adslot25map,
1575 AB8500_ADSLOTSEL13, AB8500_ADSLOTSELX_ODD_SHIFT,
1576 enum_ad_to_slot_map);
1577static SOC_ENUM_SINGLE_DECL(soc_enum_adslot26map,
1578 AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_EVEN_SHIFT,
1579 enum_ad_to_slot_map);
1580static SOC_ENUM_SINGLE_DECL(soc_enum_adslot27map,
1581 AB8500_ADSLOTSEL14, AB8500_ADSLOTSELX_ODD_SHIFT,
1582 enum_ad_to_slot_map);
1583static SOC_ENUM_SINGLE_DECL(soc_enum_adslot28map,
1584 AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_EVEN_SHIFT,
1585 enum_ad_to_slot_map);
1586static SOC_ENUM_SINGLE_DECL(soc_enum_adslot29map,
1587 AB8500_ADSLOTSEL15, AB8500_ADSLOTSELX_ODD_SHIFT,
1588 enum_ad_to_slot_map);
1589static SOC_ENUM_SINGLE_DECL(soc_enum_adslot30map,
1590 AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_EVEN_SHIFT,
1591 enum_ad_to_slot_map);
1592static SOC_ENUM_SINGLE_DECL(soc_enum_adslot31map,
1593 AB8500_ADSLOTSEL16, AB8500_ADSLOTSELX_ODD_SHIFT,
1594 enum_ad_to_slot_map);
1595
1596/* Digital interface - Burst mode */
1597static const char * const enum_mask[] = {"Unmasked", "Masked"};
1598static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomask,
1599 AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOMASK,
1600 enum_mask);
1601static const char * const enum_bitclk0[] = {"19_2_MHz", "38_4_MHz"};
1602static SOC_ENUM_SINGLE_DECL(soc_enum_bfifo19m2,
1603 AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFO19M2,
1604 enum_bitclk0);
1605static const char * const enum_slavemaster[] = {"Slave", "Master"};
1606static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast,
1607 AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT,
1608 enum_slavemaster);
1609
1610/* Sidetone */
1611static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state);
1612
1613/* ANC */
1614static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_ancstate, enum_anc_state);
1615
1616static struct snd_kcontrol_new ab8500_ctrls[] = {
1617 /* Charge pump */
1618 SOC_ENUM("Charge Pump High Threshold For Low Voltage",
1619 soc_enum_envdeththre),
1620 SOC_ENUM("Charge Pump Low Threshold For Low Voltage",
1621 soc_enum_envdetlthre),
1622 SOC_SINGLE("Charge Pump Envelope Detection Switch",
1623 AB8500_SIGENVCONF, AB8500_SIGENVCONF_ENVDETCPEN,
1624 1, 0),
1625 SOC_ENUM("Charge Pump Envelope Detection Decay Time",
1626 soc_enum_envdettime),
1627
1628 /* Headset */
1629 SOC_ENUM("Headset Mode", soc_enum_da12voice),
1630 SOC_SINGLE("Headset High Pass Switch",
1631 AB8500_ANACONF1, AB8500_ANACONF1_HSHPEN,
1632 1, 0),
1633 SOC_SINGLE("Headset Low Power Switch",
1634 AB8500_ANACONF1, AB8500_ANACONF1_HSLOWPOW,
1635 1, 0),
1636 SOC_SINGLE("Headset DAC Low Power Switch",
1637 AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW1,
1638 1, 0),
1639 SOC_SINGLE("Headset DAC Drv Low Power Switch",
1640 AB8500_ANACONF1, AB8500_ANACONF1_DACLOWPOW0,
1641 1, 0),
1642 SOC_ENUM("Headset Fade Speed", soc_enum_hsfadspeed),
1643 SOC_ENUM("Headset Source", soc_enum_da2hslr),
1644 SOC_ENUM("Headset Filter", soc_enum_hsesinc),
1645 SOC_DOUBLE_R_TLV("Headset Master Volume",
1646 AB8500_DADIGGAIN1, AB8500_DADIGGAIN2,
1647 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv),
1648 SOC_DOUBLE_R_TLV("Headset Digital Volume",
1649 AB8500_HSLEARDIGGAIN, AB8500_HSRDIGGAIN,
1650 0, AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX, 1, hs_ear_dig_gain_tlv),
1651 SOC_DOUBLE_TLV("Headset Volume",
1652 AB8500_ANAGAIN3,
1653 AB8500_ANAGAIN3_HSLGAIN, AB8500_ANAGAIN3_HSRGAIN,
1654 AB8500_ANAGAIN3_HSXGAIN_MAX, 1, hs_gain_tlv),
1655
1656 /* Earpiece */
1657 SOC_ENUM("Earpiece DAC Mode",
1658 soc_enum_eardaclowpow),
1659 SOC_ENUM("Earpiece DAC Drv Mode",
1660 soc_enum_eardrvlowpow),
1661
1662 /* HandsFree */
1663 SOC_ENUM("HF Mode", soc_enum_da34voice),
1664 SOC_SINGLE("HF and Headset Swap Switch",
1665 AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_SWAPDA12_34,
1666 1, 0),
1667 SOC_DOUBLE("HF Low EMI Mode Switch",
1668 AB8500_CLASSDCONF1,
1669 AB8500_CLASSDCONF1_HFLSWAPEN, AB8500_CLASSDCONF1_HFRSWAPEN,
1670 1, 0),
1671 SOC_DOUBLE("HF FIR Bypass Switch",
1672 AB8500_CLASSDCONF2,
1673 AB8500_CLASSDCONF2_FIRBYP0, AB8500_CLASSDCONF2_FIRBYP1,
1674 1, 0),
1675 SOC_DOUBLE("HF High Volume Switch",
1676 AB8500_CLASSDCONF2,
1677 AB8500_CLASSDCONF2_HIGHVOLEN0, AB8500_CLASSDCONF2_HIGHVOLEN1,
1678 1, 0),
1679 SOC_SINGLE("HF L and R Bridge Switch",
1680 AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLHF,
1681 1, 0),
1682 SOC_DOUBLE_R_TLV("HF Master Volume",
1683 AB8500_DADIGGAIN3, AB8500_DADIGGAIN4,
1684 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv),
1685
1686 /* Vibra */
1687 SOC_DOUBLE("Vibra High Volume Switch",
1688 AB8500_CLASSDCONF2,
1689 AB8500_CLASSDCONF2_HIGHVOLEN2, AB8500_CLASSDCONF2_HIGHVOLEN3,
1690 1, 0),
1691 SOC_DOUBLE("Vibra Low EMI Mode Switch",
1692 AB8500_CLASSDCONF1,
1693 AB8500_CLASSDCONF1_VIB1SWAPEN, AB8500_CLASSDCONF1_VIB2SWAPEN,
1694 1, 0),
1695 SOC_DOUBLE("Vibra FIR Bypass Switch",
1696 AB8500_CLASSDCONF2,
1697 AB8500_CLASSDCONF2_FIRBYP2, AB8500_CLASSDCONF2_FIRBYP3,
1698 1, 0),
1699 SOC_ENUM("Vibra Mode", soc_enum_da56voice),
1700 SOC_DOUBLE_R("Vibra PWM Duty Cycle N",
1701 AB8500_PWMGENCONF3, AB8500_PWMGENCONF5,
1702 AB8500_PWMGENCONFX_PWMVIBXDUTCYC,
1703 AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0),
1704 SOC_DOUBLE_R("Vibra PWM Duty Cycle P",
1705 AB8500_PWMGENCONF2, AB8500_PWMGENCONF4,
1706 AB8500_PWMGENCONFX_PWMVIBXDUTCYC,
1707 AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX, 0),
1708 SOC_SINGLE("Vibra 1 and 2 Bridge Switch",
1709 AB8500_CLASSDCONF1, AB8500_CLASSDCONF1_PARLVIB,
1710 1, 0),
1711 SOC_DOUBLE_R_TLV("Vibra Master Volume",
1712 AB8500_DADIGGAIN5, AB8500_DADIGGAIN6,
1713 0, AB8500_DADIGGAINX_DAXGAIN_MAX, 1, dax_dig_gain_tlv),
1714
1715 /* HandsFree, Vibra */
1716 SOC_SINGLE("ClassD High Pass Volume",
1717 AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHHPGAIN,
1718 AB8500_CLASSDCONF3_DITHHPGAIN_MAX, 0),
1719 SOC_SINGLE("ClassD White Volume",
1720 AB8500_CLASSDCONF3, AB8500_CLASSDCONF3_DITHWGAIN,
1721 AB8500_CLASSDCONF3_DITHWGAIN_MAX, 0),
1722
1723 /* Mic 1, Mic 2, LineIn */
1724 SOC_DOUBLE_R_TLV("Mic Master Volume",
1725 AB8500_ADDIGGAIN3, AB8500_ADDIGGAIN4,
1726 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv),
1727
1728 /* Mic 1 */
1729 SOC_SINGLE_TLV("Mic 1",
1730 AB8500_ANAGAIN1,
1731 AB8500_ANAGAINX_MICXGAIN,
1732 AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv),
1733 SOC_SINGLE("Mic 1 Low Power Switch",
1734 AB8500_ANAGAIN1, AB8500_ANAGAINX_LOWPOWMICX,
1735 1, 0),
1736
1737 /* Mic 2 */
1738 SOC_DOUBLE("Mic High Pass Switch",
1739 AB8500_ADFILTCONF,
1740 AB8500_ADFILTCONF_AD3NH, AB8500_ADFILTCONF_AD4NH,
1741 1, 1),
1742 SOC_ENUM("Mic Mode", soc_enum_ad34voice),
1743 SOC_ENUM("Mic Filter", soc_enum_dmic34sinc),
1744 SOC_SINGLE_TLV("Mic 2",
1745 AB8500_ANAGAIN2,
1746 AB8500_ANAGAINX_MICXGAIN,
1747 AB8500_ANAGAINX_MICXGAIN_MAX, 0, mic_gain_tlv),
1748 SOC_SINGLE("Mic 2 Low Power Switch",
1749 AB8500_ANAGAIN2, AB8500_ANAGAINX_LOWPOWMICX,
1750 1, 0),
1751
1752 /* LineIn */
1753 SOC_DOUBLE("LineIn High Pass Switch",
1754 AB8500_ADFILTCONF,
1755 AB8500_ADFILTCONF_AD1NH, AB8500_ADFILTCONF_AD2NH,
1756 1, 1),
1757 SOC_ENUM("LineIn Filter", soc_enum_dmic12sinc),
1758 SOC_ENUM("LineIn Mode", soc_enum_ad12voice),
1759 SOC_DOUBLE_R_TLV("LineIn Master Volume",
1760 AB8500_ADDIGGAIN1, AB8500_ADDIGGAIN2,
1761 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv),
1762 SOC_DOUBLE_TLV("LineIn",
1763 AB8500_ANAGAIN4,
1764 AB8500_ANAGAIN4_LINLGAIN, AB8500_ANAGAIN4_LINRGAIN,
1765 AB8500_ANAGAIN4_LINXGAIN_MAX, 0, lin_gain_tlv),
1766 SOC_DOUBLE_R_TLV("LineIn to Headset Volume",
1767 AB8500_DIGLINHSLGAIN, AB8500_DIGLINHSRGAIN,
1768 AB8500_DIGLINHSXGAIN_LINTOHSXGAIN,
1769 AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX,
1770 1, lin2hs_gain_tlv),
1771
1772 /* DMic */
1773 SOC_ENUM("DMic Filter", soc_enum_dmic56sinc),
1774 SOC_DOUBLE_R_TLV("DMic Master Volume",
1775 AB8500_ADDIGGAIN5, AB8500_ADDIGGAIN6,
1776 0, AB8500_ADDIGGAINX_ADXGAIN_MAX, 1, adx_dig_gain_tlv),
1777
1778 /* Digital gains */
1779 SOC_ENUM("Digital Gain Fade Speed", soc_enum_fadespeed),
1780
1781 /* Analog loopback */
1782 SOC_DOUBLE_R_TLV("Analog Loopback Volume",
1783 AB8500_ADDIGLOOPGAIN1, AB8500_ADDIGLOOPGAIN2,
1784 0, AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX, 1, dax_dig_gain_tlv),
1785
1786 /* Digital interface - DA from slot mapping */
1787 SOC_ENUM("Digital Interface DA 1 From Slot Map", soc_enum_da1slotmap),
1788 SOC_ENUM("Digital Interface DA 2 From Slot Map", soc_enum_da2slotmap),
1789 SOC_ENUM("Digital Interface DA 3 From Slot Map", soc_enum_da3slotmap),
1790 SOC_ENUM("Digital Interface DA 4 From Slot Map", soc_enum_da4slotmap),
1791 SOC_ENUM("Digital Interface DA 5 From Slot Map", soc_enum_da5slotmap),
1792 SOC_ENUM("Digital Interface DA 6 From Slot Map", soc_enum_da6slotmap),
1793 SOC_ENUM("Digital Interface DA 7 From Slot Map", soc_enum_da7slotmap),
1794 SOC_ENUM("Digital Interface DA 8 From Slot Map", soc_enum_da8slotmap),
1795
1796 /* Digital interface - AD to slot mapping */
1797 SOC_ENUM("Digital Interface AD To Slot 0 Map", soc_enum_adslot0map),
1798 SOC_ENUM("Digital Interface AD To Slot 1 Map", soc_enum_adslot1map),
1799 SOC_ENUM("Digital Interface AD To Slot 2 Map", soc_enum_adslot2map),
1800 SOC_ENUM("Digital Interface AD To Slot 3 Map", soc_enum_adslot3map),
1801 SOC_ENUM("Digital Interface AD To Slot 4 Map", soc_enum_adslot4map),
1802 SOC_ENUM("Digital Interface AD To Slot 5 Map", soc_enum_adslot5map),
1803 SOC_ENUM("Digital Interface AD To Slot 6 Map", soc_enum_adslot6map),
1804 SOC_ENUM("Digital Interface AD To Slot 7 Map", soc_enum_adslot7map),
1805 SOC_ENUM("Digital Interface AD To Slot 8 Map", soc_enum_adslot8map),
1806 SOC_ENUM("Digital Interface AD To Slot 9 Map", soc_enum_adslot9map),
1807 SOC_ENUM("Digital Interface AD To Slot 10 Map", soc_enum_adslot10map),
1808 SOC_ENUM("Digital Interface AD To Slot 11 Map", soc_enum_adslot11map),
1809 SOC_ENUM("Digital Interface AD To Slot 12 Map", soc_enum_adslot12map),
1810 SOC_ENUM("Digital Interface AD To Slot 13 Map", soc_enum_adslot13map),
1811 SOC_ENUM("Digital Interface AD To Slot 14 Map", soc_enum_adslot14map),
1812 SOC_ENUM("Digital Interface AD To Slot 15 Map", soc_enum_adslot15map),
1813 SOC_ENUM("Digital Interface AD To Slot 16 Map", soc_enum_adslot16map),
1814 SOC_ENUM("Digital Interface AD To Slot 17 Map", soc_enum_adslot17map),
1815 SOC_ENUM("Digital Interface AD To Slot 18 Map", soc_enum_adslot18map),
1816 SOC_ENUM("Digital Interface AD To Slot 19 Map", soc_enum_adslot19map),
1817 SOC_ENUM("Digital Interface AD To Slot 20 Map", soc_enum_adslot20map),
1818 SOC_ENUM("Digital Interface AD To Slot 21 Map", soc_enum_adslot21map),
1819 SOC_ENUM("Digital Interface AD To Slot 22 Map", soc_enum_adslot22map),
1820 SOC_ENUM("Digital Interface AD To Slot 23 Map", soc_enum_adslot23map),
1821 SOC_ENUM("Digital Interface AD To Slot 24 Map", soc_enum_adslot24map),
1822 SOC_ENUM("Digital Interface AD To Slot 25 Map", soc_enum_adslot25map),
1823 SOC_ENUM("Digital Interface AD To Slot 26 Map", soc_enum_adslot26map),
1824 SOC_ENUM("Digital Interface AD To Slot 27 Map", soc_enum_adslot27map),
1825 SOC_ENUM("Digital Interface AD To Slot 28 Map", soc_enum_adslot28map),
1826 SOC_ENUM("Digital Interface AD To Slot 29 Map", soc_enum_adslot29map),
1827 SOC_ENUM("Digital Interface AD To Slot 30 Map", soc_enum_adslot30map),
1828 SOC_ENUM("Digital Interface AD To Slot 31 Map", soc_enum_adslot31map),
1829
1830 /* Digital interface - Loopback */
1831 SOC_SINGLE("Digital Interface AD 1 Loopback Switch",
1832 AB8500_DASLOTCONF1, AB8500_DASLOTCONF1_DAI7TOADO1,
1833 1, 0),
1834 SOC_SINGLE("Digital Interface AD 2 Loopback Switch",
1835 AB8500_DASLOTCONF2, AB8500_DASLOTCONF2_DAI8TOADO2,
1836 1, 0),
1837 SOC_SINGLE("Digital Interface AD 3 Loopback Switch",
1838 AB8500_DASLOTCONF3, AB8500_DASLOTCONF3_DAI7TOADO3,
1839 1, 0),
1840 SOC_SINGLE("Digital Interface AD 4 Loopback Switch",
1841 AB8500_DASLOTCONF4, AB8500_DASLOTCONF4_DAI8TOADO4,
1842 1, 0),
1843 SOC_SINGLE("Digital Interface AD 5 Loopback Switch",
1844 AB8500_DASLOTCONF5, AB8500_DASLOTCONF5_DAI7TOADO5,
1845 1, 0),
1846 SOC_SINGLE("Digital Interface AD 6 Loopback Switch",
1847 AB8500_DASLOTCONF6, AB8500_DASLOTCONF6_DAI8TOADO6,
1848 1, 0),
1849 SOC_SINGLE("Digital Interface AD 7 Loopback Switch",
1850 AB8500_DASLOTCONF7, AB8500_DASLOTCONF7_DAI8TOADO7,
1851 1, 0),
1852 SOC_SINGLE("Digital Interface AD 8 Loopback Switch",
1853 AB8500_DASLOTCONF8, AB8500_DASLOTCONF8_DAI7TOADO8,
1854 1, 0),
1855
1856 /* Digital interface - Burst FIFO */
1857 SOC_SINGLE("Digital Interface 0 FIFO Enable Switch",
1858 AB8500_DIGIFCONF3, AB8500_DIGIFCONF3_IF0BFIFOEN,
1859 1, 0),
1860 SOC_ENUM("Burst FIFO Mask", soc_enum_bfifomask),
1861 SOC_ENUM("Burst FIFO Bit-clock Frequency", soc_enum_bfifo19m2),
1862 SOC_SINGLE("Burst FIFO Threshold",
1863 AB8500_FIFOCONF1, AB8500_FIFOCONF1_BFIFOINT_SHIFT,
1864 AB8500_FIFOCONF1_BFIFOINT_MAX, 0),
1865 SOC_SINGLE("Burst FIFO Length",
1866 AB8500_FIFOCONF2, AB8500_FIFOCONF2_BFIFOTX_SHIFT,
1867 AB8500_FIFOCONF2_BFIFOTX_MAX, 0),
1868 SOC_SINGLE("Burst FIFO EOS Extra Slots",
1869 AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOEXSL_SHIFT,
1870 AB8500_FIFOCONF3_BFIFOEXSL_MAX, 0),
1871 SOC_SINGLE("Burst FIFO FS Extra Bit-clocks",
1872 AB8500_FIFOCONF3, AB8500_FIFOCONF3_PREBITCLK0_SHIFT,
1873 AB8500_FIFOCONF3_PREBITCLK0_MAX, 0),
1874 SOC_ENUM("Burst FIFO Interface Mode", soc_enum_bfifomast),
1875
1876 SOC_SINGLE("Burst FIFO Interface Switch",
1877 AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFORUN_SHIFT,
1878 1, 0),
1879 SOC_SINGLE("Burst FIFO Switch Frame Number",
1880 AB8500_FIFOCONF4, AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT,
1881 AB8500_FIFOCONF4_BFIFOFRAMSW_MAX, 0),
1882 SOC_SINGLE("Burst FIFO Wake Up Delay",
1883 AB8500_FIFOCONF5, AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT,
1884 AB8500_FIFOCONF5_BFIFOWAKEUP_MAX, 0),
1885 SOC_SINGLE("Burst FIFO Samples In FIFO",
1886 AB8500_FIFOCONF6, AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT,
1887 AB8500_FIFOCONF6_BFIFOSAMPLE_MAX, 0),
1888
1889 /* ANC */
1890 SOC_ENUM_EXT("ANC Status", soc_enum_ancstate,
1891 anc_status_control_get, anc_status_control_put),
1892 SOC_SINGLE_XR_SX("ANC Warp Delay Shift",
1893 AB8500_ANCCONF2, 1, AB8500_ANCCONF2_SHIFT,
1894 AB8500_ANCCONF2_MIN, AB8500_ANCCONF2_MAX, 0),
1895 SOC_SINGLE_XR_SX("ANC FIR Output Shift",
1896 AB8500_ANCCONF3, 1, AB8500_ANCCONF3_SHIFT,
1897 AB8500_ANCCONF3_MIN, AB8500_ANCCONF3_MAX, 0),
1898 SOC_SINGLE_XR_SX("ANC IIR Output Shift",
1899 AB8500_ANCCONF4, 1, AB8500_ANCCONF4_SHIFT,
1900 AB8500_ANCCONF4_MIN, AB8500_ANCCONF4_MAX, 0),
1901 SOC_SINGLE_XR_SX("ANC Warp Delay",
1902 AB8500_ANCCONF9, 2, AB8500_ANC_WARP_DELAY_SHIFT,
1903 AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0),
1904
1905 /* Sidetone */
1906 SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate,
1907 sid_status_control_get, sid_status_control_put),
1908 SOC_SINGLE_STROBE("Sidetone Reset",
1909 AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0),
1910};
1911
1912static struct snd_kcontrol_new ab8500_filter_controls[] = {
1913 AB8500_FILTER_CONTROL("ANC FIR Coefficients", AB8500_ANC_FIR_COEFFS,
1914 AB8500_ANC_FIR_COEFF_MIN, AB8500_ANC_FIR_COEFF_MAX),
1915 AB8500_FILTER_CONTROL("ANC IIR Coefficients", AB8500_ANC_IIR_COEFFS,
1916 AB8500_ANC_IIR_COEFF_MIN, AB8500_ANC_IIR_COEFF_MAX),
1917 AB8500_FILTER_CONTROL("Sidetone FIR Coefficients",
1918 AB8500_SID_FIR_COEFFS, AB8500_SID_FIR_COEFF_MIN,
1919 AB8500_SID_FIR_COEFF_MAX)
1920};
1921enum ab8500_filter {
1922 AB8500_FILTER_ANC_FIR = 0,
1923 AB8500_FILTER_ANC_IIR = 1,
1924 AB8500_FILTER_SID_FIR = 2,
1925};
1926
1927/*
1928 * Extended interface for codec-driver
1929 */
1930
1931static int ab8500_audio_init_audioblock(struct snd_soc_codec *codec)
1932{
1933 int status;
1934
1935 dev_dbg(codec->dev, "%s: Enter.\n", __func__);
1936
1937 /* Reset audio-registers and disable 32kHz-clock output 2 */
1938 status = ab8500_sysctrl_write(AB8500_STW4500CTRL3,
1939 AB8500_STW4500CTRL3_CLK32KOUT2DIS |
1940 AB8500_STW4500CTRL3_RESETAUDN,
1941 AB8500_STW4500CTRL3_RESETAUDN);
1942 if (status < 0)
1943 return status;
1944
1945 return 0;
1946}
1947
1948static int ab8500_audio_setup_mics(struct snd_soc_codec *codec,
1949 struct amic_settings *amics)
1950{
1951 u8 value8;
1952 unsigned int value;
1953 int status;
1954 const struct snd_soc_dapm_route *route;
1955
1956 dev_dbg(codec->dev, "%s: Enter.\n", __func__);
1957
1958 /* Set DMic-clocks to outputs */
1959 status = abx500_get_register_interruptible(codec->dev, (u8)AB8500_MISC,
1960 (u8)AB8500_GPIO_DIR4_REG,
1961 &value8);
1962 if (status < 0)
1963 return status;
1964 value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
1965 GPIO31_DIR_OUTPUT;
1966 status = abx500_set_register_interruptible(codec->dev,
1967 (u8)AB8500_MISC,
1968 (u8)AB8500_GPIO_DIR4_REG,
1969 value);
1970 if (status < 0)
1971 return status;
1972
1973 /* Attach regulators to AMic DAPM-paths */
1974 dev_dbg(codec->dev, "%s: Mic 1a regulator: %s\n", __func__,
1975 amic_micbias_str(amics->mic1a_micbias));
1976 route = &ab8500_dapm_routes_mic1a_vamicx[amics->mic1a_micbias];
1977 status = snd_soc_dapm_add_routes(&codec->dapm, route, 1);
1978 dev_dbg(codec->dev, "%s: Mic 1b regulator: %s\n", __func__,
1979 amic_micbias_str(amics->mic1b_micbias));
1980 route = &ab8500_dapm_routes_mic1b_vamicx[amics->mic1b_micbias];
1981 status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1);
1982 dev_dbg(codec->dev, "%s: Mic 2 regulator: %s\n", __func__,
1983 amic_micbias_str(amics->mic2_micbias));
1984 route = &ab8500_dapm_routes_mic2_vamicx[amics->mic2_micbias];
1985 status |= snd_soc_dapm_add_routes(&codec->dapm, route, 1);
1986 if (status < 0) {
1987 dev_err(codec->dev,
1988 "%s: Failed to add AMic-regulator DAPM-routes (%d).\n",
1989 __func__, status);
1990 return status;
1991 }
1992
1993 /* Set AMic-configuration */
1994 dev_dbg(codec->dev, "%s: Mic 1 mic-type: %s\n", __func__,
1995 amic_type_str(amics->mic1_type));
1996 snd_soc_update_bits(codec, AB8500_ANAGAIN1, AB8500_ANAGAINX_ENSEMICX,
1997 amics->mic1_type == AMIC_TYPE_DIFFERENTIAL ?
1998 0 : AB8500_ANAGAINX_ENSEMICX);
1999 dev_dbg(codec->dev, "%s: Mic 2 mic-type: %s\n", __func__,
2000 amic_type_str(amics->mic2_type));
2001 snd_soc_update_bits(codec, AB8500_ANAGAIN2, AB8500_ANAGAINX_ENSEMICX,
2002 amics->mic2_type == AMIC_TYPE_DIFFERENTIAL ?
2003 0 : AB8500_ANAGAINX_ENSEMICX);
2004
2005 return 0;
2006}
2007EXPORT_SYMBOL_GPL(ab8500_audio_setup_mics);
2008
2009static int ab8500_audio_set_ear_cmv(struct snd_soc_codec *codec,
2010 enum ear_cm_voltage ear_cmv)
2011{
2012 char *cmv_str;
2013
2014 switch (ear_cmv) {
2015 case EAR_CMV_0_95V:
2016 cmv_str = "0.95V";
2017 break;
2018 case EAR_CMV_1_10V:
2019 cmv_str = "1.10V";
2020 break;
2021 case EAR_CMV_1_27V:
2022 cmv_str = "1.27V";
2023 break;
2024 case EAR_CMV_1_58V:
2025 cmv_str = "1.58V";
2026 break;
2027 default:
2028 dev_err(codec->dev,
2029 "%s: Unknown earpiece CM-voltage (%d)!\n",
2030 __func__, (int)ear_cmv);
2031 return -EINVAL;
2032 }
2033 dev_dbg(codec->dev, "%s: Earpiece CM-voltage: %s\n", __func__,
2034 cmv_str);
2035 snd_soc_update_bits(codec, AB8500_ANACONF1, AB8500_ANACONF1_EARSELCM,
2036 ear_cmv);
2037
2038 return 0;
2039}
2040EXPORT_SYMBOL_GPL(ab8500_audio_set_ear_cmv);
2041
2042static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
2043 unsigned int delay)
2044{
2045 unsigned int mask, val;
2046 struct snd_soc_codec *codec = dai->codec;
2047
2048 mask = BIT(AB8500_DIGIFCONF2_IF0DEL);
2049 val = 0;
2050
2051 switch (delay) {
2052 case 0:
2053 break;
2054 case 1:
2055 val |= BIT(AB8500_DIGIFCONF2_IF0DEL);
2056 break;
2057 default:
2058 dev_err(dai->codec->dev,
2059 "%s: ERROR: Unsupported bit-delay (0x%x)!\n",
2060 __func__, delay);
2061 return -EINVAL;
2062 }
2063
2064 dev_dbg(dai->codec->dev, "%s: IF0 Bit-delay: %d bits.\n",
2065 __func__, delay);
2066 snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
2067
2068 return 0;
2069}
2070
2071/* Gates clocking according format mask */
2072static int ab8500_codec_set_dai_clock_gate(struct snd_soc_codec *codec,
2073 unsigned int fmt)
2074{
2075 unsigned int mask;
2076 unsigned int val;
2077
2078 mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) |
2079 BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
2080
2081 val = BIT(AB8500_DIGIFCONF1_ENMASTGEN);
2082
2083 switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
2084 case SND_SOC_DAIFMT_CONT: /* continuous clock */
2085 dev_dbg(codec->dev, "%s: IF0 Clock is continuous.\n",
2086 __func__);
2087 val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
2088 break;
2089 case SND_SOC_DAIFMT_GATED: /* clock is gated */
2090 dev_dbg(codec->dev, "%s: IF0 Clock is gated.\n",
2091 __func__);
2092 break;
2093 default:
2094 dev_err(codec->dev,
2095 "%s: ERROR: Unsupported clock mask (0x%x)!\n",
2096 __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK);
2097 return -EINVAL;
2098 }
2099
2100 snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
2101
2102 return 0;
2103}
2104
2105static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2106{
2107 unsigned int mask;
2108 unsigned int val;
2109 struct snd_soc_codec *codec = dai->codec;
2110 int status;
2111
2112 dev_dbg(codec->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
2113
2114 mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) |
2115 BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) |
2116 BIT(AB8500_DIGIFCONF3_IF0BFIFOEN) |
2117 BIT(AB8500_DIGIFCONF3_IF0MASTER);
2118 val = 0;
2119
2120 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
2121 case SND_SOC_DAIFMT_CBM_CFM: /* codec clk & FRM master */
2122 dev_dbg(dai->codec->dev,
2123 "%s: IF0 Master-mode: AB8500 master.\n", __func__);
2124 val |= BIT(AB8500_DIGIFCONF3_IF0MASTER);
2125 break;
2126 case SND_SOC_DAIFMT_CBS_CFS: /* codec clk & FRM slave */
2127 dev_dbg(dai->codec->dev,
2128 "%s: IF0 Master-mode: AB8500 slave.\n", __func__);
2129 break;
2130 case SND_SOC_DAIFMT_CBS_CFM: /* codec clk slave & FRM master */
2131 case SND_SOC_DAIFMT_CBM_CFS: /* codec clk master & frame slave */
2132 dev_err(dai->codec->dev,
2133 "%s: ERROR: The device is either a master or a slave.\n",
2134 __func__);
2135 default:
2136 dev_err(dai->codec->dev,
2137 "%s: ERROR: Unsupporter master mask 0x%x\n",
2138 __func__, fmt & SND_SOC_DAIFMT_MASTER_MASK);
2139 return -EINVAL;
2140 break;
2141 }
2142
2143 snd_soc_update_bits(codec, AB8500_DIGIFCONF3, mask, val);
2144
2145 /* Set clock gating */
2146 status = ab8500_codec_set_dai_clock_gate(codec, fmt);
2147 if (status) {
2148 dev_err(dai->codec->dev,
2149 "%s: ERRROR: Failed to set clock gate (%d).\n",
2150 __func__, status);
2151 return status;
2152 }
2153
2154 /* Setting data transfer format */
2155
2156 mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) |
2157 BIT(AB8500_DIGIFCONF2_IF0FORMAT1) |
2158 BIT(AB8500_DIGIFCONF2_FSYNC0P) |
2159 BIT(AB8500_DIGIFCONF2_BITCLK0P);
2160 val = 0;
2161
2162 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2163 case SND_SOC_DAIFMT_I2S: /* I2S mode */
2164 dev_dbg(dai->codec->dev, "%s: IF0 Protocol: I2S\n", __func__);
2165 val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1);
2166 ab8500_audio_set_bit_delay(dai, 0);
2167 break;
2168
2169 case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
2170 dev_dbg(dai->codec->dev,
2171 "%s: IF0 Protocol: DSP A (TDM)\n", __func__);
2172 val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
2173 ab8500_audio_set_bit_delay(dai, 1);
2174 break;
2175
2176 case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
2177 dev_dbg(dai->codec->dev,
2178 "%s: IF0 Protocol: DSP B (TDM)\n", __func__);
2179 val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
2180 ab8500_audio_set_bit_delay(dai, 0);
2181 break;
2182
2183 default:
2184 dev_err(dai->codec->dev,
2185 "%s: ERROR: Unsupported format (0x%x)!\n",
2186 __func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
2187 return -EINVAL;
2188 }
2189
2190 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2191 case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
2192 dev_dbg(dai->codec->dev,
2193 "%s: IF0: Normal bit clock, normal frame\n",
2194 __func__);
2195 break;
2196 case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */
2197 dev_dbg(dai->codec->dev,
2198 "%s: IF0: Normal bit clock, inverted frame\n",
2199 __func__);
2200 val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
2201 break;
2202 case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */
2203 dev_dbg(dai->codec->dev,
2204 "%s: IF0: Inverted bit clock, normal frame\n",
2205 __func__);
2206 val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
2207 break;
2208 case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */
2209 dev_dbg(dai->codec->dev,
2210 "%s: IF0: Inverted bit clock, inverted frame\n",
2211 __func__);
2212 val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
2213 val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
2214 break;
2215 default:
2216 dev_err(dai->codec->dev,
2217 "%s: ERROR: Unsupported INV mask 0x%x\n",
2218 __func__, fmt & SND_SOC_DAIFMT_INV_MASK);
2219 return -EINVAL;
2220 }
2221
2222 snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
2223
2224 return 0;
2225}
2226
2227static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
2228 unsigned int tx_mask, unsigned int rx_mask,
2229 int slots, int slot_width)
2230{
2231 struct snd_soc_codec *codec = dai->codec;
2232 unsigned int val, mask, slots_active;
2233
2234 mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
2235 BIT(AB8500_DIGIFCONF2_IF0WL1);
2236 val = 0;
2237
2238 switch (slot_width) {
2239 case 16:
2240 break;
2241 case 20:
2242 val |= BIT(AB8500_DIGIFCONF2_IF0WL0);
2243 break;
2244 case 24:
2245 val |= BIT(AB8500_DIGIFCONF2_IF0WL1);
2246 break;
2247 case 32:
2248 val |= BIT(AB8500_DIGIFCONF2_IF0WL1) |
2249 BIT(AB8500_DIGIFCONF2_IF0WL0);
2250 break;
2251 default:
2252 dev_err(dai->codec->dev, "%s: Unsupported slot-width 0x%x\n",
2253 __func__, slot_width);
2254 return -EINVAL;
2255 }
2256
2257 dev_dbg(dai->codec->dev, "%s: IF0 slot-width: %d bits.\n",
2258 __func__, slot_width);
2259 snd_soc_update_bits(codec, AB8500_DIGIFCONF2, mask, val);
2260
2261 /* Setup TDM clocking according to slot count */
2262 dev_dbg(dai->codec->dev, "%s: Slots, total: %d\n", __func__, slots);
2263 mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
2264 BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
2265 switch (slots) {
2266 case 2:
2267 val = AB8500_MASK_NONE;
2268 break;
2269 case 4:
2270 val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0);
2271 break;
2272 case 8:
2273 val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
2274 break;
2275 case 16:
2276 val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
2277 BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
2278 break;
2279 default:
2280 dev_err(dai->codec->dev,
2281 "%s: ERROR: Unsupported number of slots (%d)!\n",
2282 __func__, slots);
2283 return -EINVAL;
2284 }
2285 snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val);
2286
2287 /* Setup TDM DA according to active tx slots */
2288 mask = AB8500_DASLOTCONFX_SLTODAX_MASK;
2289 slots_active = hweight32(tx_mask);
2290 dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__,
2291 slots_active);
2292 switch (slots_active) {
2293 case 0:
2294 break;
2295 case 1:
2296 /* Slot 9 -> DA_IN1 & DA_IN3 */
2297 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11);
2298 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11);
2299 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11);
2300 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11);
2301 break;
2302 case 2:
2303 /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */
2304 snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9);
2305 snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9);
2306 snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11);
2307 snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11);
2308
2309 break;
2310 case 8:
2311 dev_dbg(dai->codec->dev,
2312 "%s: In 8-channel mode DA-from-slot mapping is set manually.",
2313 __func__);
2314 break;
2315 default:
2316 dev_err(dai->codec->dev,
2317 "%s: Unsupported number of active TX-slots (%d)!\n",
2318 __func__, slots_active);
2319 return -EINVAL;
2320 }
2321
2322 /* Setup TDM AD according to active RX-slots */
2323 slots_active = hweight32(rx_mask);
2324 dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__,
2325 slots_active);
2326 switch (slots_active) {
2327 case 0:
2328 break;
2329 case 1:
2330 /* AD_OUT3 -> slot 0 & 1 */
2331 snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL,
2332 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
2333 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD);
2334 break;
2335 case 2:
2336 /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */
2337 snd_soc_update_bits(codec,
2338 AB8500_ADSLOTSEL1,
2339 AB8500_MASK_ALL,
2340 AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN |
2341 AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD);
2342 break;
2343 case 8:
2344 dev_dbg(dai->codec->dev,
2345 "%s: In 8-channel mode AD-to-slot mapping is set manually.",
2346 __func__);
2347 break;
2348 default:
2349 dev_err(dai->codec->dev,
2350 "%s: Unsupported number of active RX-slots (%d)!\n",
2351 __func__, slots_active);
2352 return -EINVAL;
2353 }
2354
2355 return 0;
2356}
2357
2358struct snd_soc_dai_driver ab8500_codec_dai[] = {
2359 {
2360 .name = "ab8500-codec-dai.0",
2361 .id = 0,
2362 .playback = {
2363 .stream_name = "ab8500_0p",
2364 .channels_min = 1,
2365 .channels_max = 8,
2366 .rates = AB8500_SUPPORTED_RATE,
2367 .formats = AB8500_SUPPORTED_FMT,
2368 },
2369 .ops = (struct snd_soc_dai_ops[]) {
2370 {
2371 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2372 .set_fmt = ab8500_codec_set_dai_fmt,
2373 }
2374 },
2375 .symmetric_rates = 1
2376 },
2377 {
2378 .name = "ab8500-codec-dai.1",
2379 .id = 1,
2380 .capture = {
2381 .stream_name = "ab8500_0c",
2382 .channels_min = 1,
2383 .channels_max = 8,
2384 .rates = AB8500_SUPPORTED_RATE,
2385 .formats = AB8500_SUPPORTED_FMT,
2386 },
2387 .ops = (struct snd_soc_dai_ops[]) {
2388 {
2389 .set_tdm_slot = ab8500_codec_set_dai_tdm_slot,
2390 .set_fmt = ab8500_codec_set_dai_fmt,
2391 }
2392 },
2393 .symmetric_rates = 1
2394 }
2395};
2396
2397static int ab8500_codec_probe(struct snd_soc_codec *codec)
2398{
2399 struct device *dev = codec->dev;
2400 struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
2401 struct ab8500_platform_data *pdata;
2402 struct filter_control *fc;
2403 int status;
2404
2405 dev_dbg(dev, "%s: Enter.\n", __func__);
2406
2407 /* Setup AB8500 according to board-settings */
2408 pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent);
2409 status = ab8500_audio_setup_mics(codec, &pdata->codec->amics);
2410 if (status < 0) {
2411 pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
2412 return status;
2413 }
2414 status = ab8500_audio_set_ear_cmv(codec, pdata->codec->ear_cmv);
2415 if (status < 0) {
2416 pr_err("%s: Failed to set earpiece CM-voltage (%d)!\n",
2417 __func__, status);
2418 return status;
2419 }
2420
2421 status = ab8500_audio_init_audioblock(codec);
2422 if (status < 0) {
2423 dev_err(dev, "%s: failed to init audio-block (%d)!\n",
2424 __func__, status);
2425 return status;
2426 }
2427
2428 /* Override HW-defaults */
2429 ab8500_codec_write_reg(codec,
2430 AB8500_ANACONF5,
2431 BIT(AB8500_ANACONF5_HSAUTOEN));
2432 ab8500_codec_write_reg(codec,
2433 AB8500_SHORTCIRCONF,
2434 BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
2435
2436 /* Add filter controls */
2437 status = snd_soc_add_codec_controls(codec, ab8500_filter_controls,
2438 ARRAY_SIZE(ab8500_filter_controls));
2439 if (status < 0) {
2440 dev_err(dev,
2441 "%s: failed to add ab8500 filter controls (%d).\n",
2442 __func__, status);
2443 return status;
2444 }
2445 fc = (struct filter_control *)
2446 &ab8500_filter_controls[AB8500_FILTER_ANC_FIR].private_value;
2447 drvdata->anc_fir_values = (long *)fc->value;
2448 fc = (struct filter_control *)
2449 &ab8500_filter_controls[AB8500_FILTER_ANC_IIR].private_value;
2450 drvdata->anc_iir_values = (long *)fc->value;
2451 fc = (struct filter_control *)
2452 &ab8500_filter_controls[AB8500_FILTER_SID_FIR].private_value;
2453 drvdata->sid_fir_values = (long *)fc->value;
2454
2455 (void)snd_soc_dapm_disable_pin(&codec->dapm, "ANC Configure Input");
2456
2457 mutex_init(&drvdata->anc_lock);
2458
2459 return status;
2460}
2461
2462static struct snd_soc_codec_driver ab8500_codec_driver = {
2463 .probe = ab8500_codec_probe,
2464 .read = ab8500_codec_read_reg,
2465 .write = ab8500_codec_write_reg,
2466 .reg_word_size = sizeof(u8),
2467 .controls = ab8500_ctrls,
2468 .num_controls = ARRAY_SIZE(ab8500_ctrls),
2469 .dapm_widgets = ab8500_dapm_widgets,
2470 .num_dapm_widgets = ARRAY_SIZE(ab8500_dapm_widgets),
2471 .dapm_routes = ab8500_dapm_routes,
2472 .num_dapm_routes = ARRAY_SIZE(ab8500_dapm_routes),
2473};
2474
2475static int __devinit ab8500_codec_driver_probe(struct platform_device *pdev)
2476{
2477 int status;
2478 struct ab8500_codec_drvdata *drvdata;
2479
2480 dev_dbg(&pdev->dev, "%s: Enter.\n", __func__);
2481
2482 /* Create driver private-data struct */
2483 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct ab8500_codec_drvdata),
2484 GFP_KERNEL);
2485 drvdata->sid_status = SID_UNCONFIGURED;
2486 drvdata->anc_status = ANC_UNCONFIGURED;
2487 dev_set_drvdata(&pdev->dev, drvdata);
2488
2489 dev_dbg(&pdev->dev, "%s: Register codec.\n", __func__);
2490 status = snd_soc_register_codec(&pdev->dev, &ab8500_codec_driver,
2491 ab8500_codec_dai,
2492 ARRAY_SIZE(ab8500_codec_dai));
2493 if (status < 0)
2494 dev_err(&pdev->dev,
2495 "%s: Error: Failed to register codec (%d).\n",
2496 __func__, status);
2497
2498 return status;
2499}
2500
2501static int __devexit ab8500_codec_driver_remove(struct platform_device *pdev)
2502{
2503 dev_info(&pdev->dev, "%s Enter.\n", __func__);
2504
2505 snd_soc_unregister_codec(&pdev->dev);
2506
2507 return 0;
2508}
2509
2510static struct platform_driver ab8500_codec_platform_driver = {
2511 .driver = {
2512 .name = "ab8500-codec",
2513 .owner = THIS_MODULE,
2514 },
2515 .probe = ab8500_codec_driver_probe,
2516 .remove = __devexit_p(ab8500_codec_driver_remove),
2517 .suspend = NULL,
2518 .resume = NULL,
2519};
2520module_platform_driver(ab8500_codec_platform_driver);
2521
2522MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h
new file mode 100644
index 00000000000..114f69a0c62
--- /dev/null
+++ b/sound/soc/codecs/ab8500-codec.h
@@ -0,0 +1,590 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>,
6 * Roger Nilsson <roger.xr.nilsson@stericsson.com>,
7 * for ST-Ericsson.
8 *
9 * Based on the early work done by:
10 * Mikko J. Lehto <mikko.lehto@symbio.com>,
11 * Mikko Sarmanne <mikko.sarmanne@symbio.com>,
12 * for ST-Ericsson.
13 *
14 * License terms:
15 *
16 * This program is free software; you can redistribute it and/or modify it
17 * under the terms of the GNU General Public License version 2 as published
18 * by the Free Software Foundation.
19 */
20
21#ifndef AB8500_CODEC_REGISTERS_H
22#define AB8500_CODEC_REGISTERS_H
23
24#define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000)
25#define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE)
26
27/* AB8500 audio bank (0x0d) register definitions */
28
29#define AB8500_POWERUP 0x00
30#define AB8500_AUDSWRESET 0x01
31#define AB8500_ADPATHENA 0x02
32#define AB8500_DAPATHENA 0x03
33#define AB8500_ANACONF1 0x04
34#define AB8500_ANACONF2 0x05
35#define AB8500_DIGMICCONF 0x06
36#define AB8500_ANACONF3 0x07
37#define AB8500_ANACONF4 0x08
38#define AB8500_DAPATHCONF 0x09
39#define AB8500_MUTECONF 0x0A
40#define AB8500_SHORTCIRCONF 0x0B
41#define AB8500_ANACONF5 0x0C
42#define AB8500_ENVCPCONF 0x0D
43#define AB8500_SIGENVCONF 0x0E
44#define AB8500_PWMGENCONF1 0x0F
45#define AB8500_PWMGENCONF2 0x10
46#define AB8500_PWMGENCONF3 0x11
47#define AB8500_PWMGENCONF4 0x12
48#define AB8500_PWMGENCONF5 0x13
49#define AB8500_ANAGAIN1 0x14
50#define AB8500_ANAGAIN2 0x15
51#define AB8500_ANAGAIN3 0x16
52#define AB8500_ANAGAIN4 0x17
53#define AB8500_DIGLINHSLGAIN 0x18
54#define AB8500_DIGLINHSRGAIN 0x19
55#define AB8500_ADFILTCONF 0x1A
56#define AB8500_DIGIFCONF1 0x1B
57#define AB8500_DIGIFCONF2 0x1C
58#define AB8500_DIGIFCONF3 0x1D
59#define AB8500_DIGIFCONF4 0x1E
60#define AB8500_ADSLOTSEL1 0x1F
61#define AB8500_ADSLOTSEL2 0x20
62#define AB8500_ADSLOTSEL3 0x21
63#define AB8500_ADSLOTSEL4 0x22
64#define AB8500_ADSLOTSEL5 0x23
65#define AB8500_ADSLOTSEL6 0x24
66#define AB8500_ADSLOTSEL7 0x25
67#define AB8500_ADSLOTSEL8 0x26
68#define AB8500_ADSLOTSEL9 0x27
69#define AB8500_ADSLOTSEL10 0x28
70#define AB8500_ADSLOTSEL11 0x29
71#define AB8500_ADSLOTSEL12 0x2A
72#define AB8500_ADSLOTSEL13 0x2B
73#define AB8500_ADSLOTSEL14 0x2C
74#define AB8500_ADSLOTSEL15 0x2D
75#define AB8500_ADSLOTSEL16 0x2E
76#define AB8500_ADSLOTHIZCTRL1 0x2F
77#define AB8500_ADSLOTHIZCTRL2 0x30
78#define AB8500_ADSLOTHIZCTRL3 0x31
79#define AB8500_ADSLOTHIZCTRL4 0x32
80#define AB8500_DASLOTCONF1 0x33
81#define AB8500_DASLOTCONF2 0x34
82#define AB8500_DASLOTCONF3 0x35
83#define AB8500_DASLOTCONF4 0x36
84#define AB8500_DASLOTCONF5 0x37
85#define AB8500_DASLOTCONF6 0x38
86#define AB8500_DASLOTCONF7 0x39
87#define AB8500_DASLOTCONF8 0x3A
88#define AB8500_CLASSDCONF1 0x3B
89#define AB8500_CLASSDCONF2 0x3C
90#define AB8500_CLASSDCONF3 0x3D
91#define AB8500_DMICFILTCONF 0x3E
92#define AB8500_DIGMULTCONF1 0x3F
93#define AB8500_DIGMULTCONF2 0x40
94#define AB8500_ADDIGGAIN1 0x41
95#define AB8500_ADDIGGAIN2 0x42
96#define AB8500_ADDIGGAIN3 0x43
97#define AB8500_ADDIGGAIN4 0x44
98#define AB8500_ADDIGGAIN5 0x45
99#define AB8500_ADDIGGAIN6 0x46
100#define AB8500_DADIGGAIN1 0x47
101#define AB8500_DADIGGAIN2 0x48
102#define AB8500_DADIGGAIN3 0x49
103#define AB8500_DADIGGAIN4 0x4A
104#define AB8500_DADIGGAIN5 0x4B
105#define AB8500_DADIGGAIN6 0x4C
106#define AB8500_ADDIGLOOPGAIN1 0x4D
107#define AB8500_ADDIGLOOPGAIN2 0x4E
108#define AB8500_HSLEARDIGGAIN 0x4F
109#define AB8500_HSRDIGGAIN 0x50
110#define AB8500_SIDFIRGAIN1 0x51
111#define AB8500_SIDFIRGAIN2 0x52
112#define AB8500_ANCCONF1 0x53
113#define AB8500_ANCCONF2 0x54
114#define AB8500_ANCCONF3 0x55
115#define AB8500_ANCCONF4 0x56
116#define AB8500_ANCCONF5 0x57
117#define AB8500_ANCCONF6 0x58
118#define AB8500_ANCCONF7 0x59
119#define AB8500_ANCCONF8 0x5A
120#define AB8500_ANCCONF9 0x5B
121#define AB8500_ANCCONF10 0x5C
122#define AB8500_ANCCONF11 0x5D
123#define AB8500_ANCCONF12 0x5E
124#define AB8500_ANCCONF13 0x5F
125#define AB8500_ANCCONF14 0x60
126#define AB8500_SIDFIRADR 0x61
127#define AB8500_SIDFIRCOEF1 0x62
128#define AB8500_SIDFIRCOEF2 0x63
129#define AB8500_SIDFIRCONF 0x64
130#define AB8500_AUDINTMASK1 0x65
131#define AB8500_AUDINTSOURCE1 0x66
132#define AB8500_AUDINTMASK2 0x67
133#define AB8500_AUDINTSOURCE2 0x68
134#define AB8500_FIFOCONF1 0x69
135#define AB8500_FIFOCONF2 0x6A
136#define AB8500_FIFOCONF3 0x6B
137#define AB8500_FIFOCONF4 0x6C
138#define AB8500_FIFOCONF5 0x6D
139#define AB8500_FIFOCONF6 0x6E
140#define AB8500_AUDREV 0x6F
141
142#define AB8500_FIRST_REG AB8500_POWERUP
143#define AB8500_LAST_REG AB8500_AUDREV
144#define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1)
145
146#define AB8500_MASK_ALL 0xFF
147#define AB8500_MASK_NONE 0x00
148
149/* AB8500_POWERUP */
150#define AB8500_POWERUP_POWERUP 7
151#define AB8500_POWERUP_ENANA 3
152
153/* AB8500_AUDSWRESET */
154#define AB8500_AUDSWRESET_SWRESET 7
155
156/* AB8500_ADPATHENA */
157#define AB8500_ADPATHENA_ENAD12 7
158#define AB8500_ADPATHENA_ENAD34 5
159#define AB8500_ADPATHENA_ENAD5768 3
160
161/* AB8500_DAPATHENA */
162#define AB8500_DAPATHENA_ENDA1 7
163#define AB8500_DAPATHENA_ENDA2 6
164#define AB8500_DAPATHENA_ENDA3 5
165#define AB8500_DAPATHENA_ENDA4 4
166#define AB8500_DAPATHENA_ENDA5 3
167#define AB8500_DAPATHENA_ENDA6 2
168
169/* AB8500_ANACONF1 */
170#define AB8500_ANACONF1_HSLOWPOW 7
171#define AB8500_ANACONF1_DACLOWPOW1 6
172#define AB8500_ANACONF1_DACLOWPOW0 5
173#define AB8500_ANACONF1_EARDACLOWPOW 4
174#define AB8500_ANACONF1_EARSELCM 2
175#define AB8500_ANACONF1_HSHPEN 1
176#define AB8500_ANACONF1_EARDRVLOWPOW 0
177
178/* AB8500_ANACONF2 */
179#define AB8500_ANACONF2_ENMIC1 7
180#define AB8500_ANACONF2_ENMIC2 6
181#define AB8500_ANACONF2_ENLINL 5
182#define AB8500_ANACONF2_ENLINR 4
183#define AB8500_ANACONF2_MUTMIC1 3
184#define AB8500_ANACONF2_MUTMIC2 2
185#define AB8500_ANACONF2_MUTLINL 1
186#define AB8500_ANACONF2_MUTLINR 0
187
188/* AB8500_DIGMICCONF */
189#define AB8500_DIGMICCONF_ENDMIC1 7
190#define AB8500_DIGMICCONF_ENDMIC2 6
191#define AB8500_DIGMICCONF_ENDMIC3 5
192#define AB8500_DIGMICCONF_ENDMIC4 4
193#define AB8500_DIGMICCONF_ENDMIC5 3
194#define AB8500_DIGMICCONF_ENDMIC6 2
195#define AB8500_DIGMICCONF_HSFADSPEED 0
196
197/* AB8500_ANACONF3 */
198#define AB8500_ANACONF3_MIC1SEL 7
199#define AB8500_ANACONF3_LINRSEL 6
200#define AB8500_ANACONF3_ENDRVHSL 5
201#define AB8500_ANACONF3_ENDRVHSR 4
202#define AB8500_ANACONF3_ENADCMIC 2
203#define AB8500_ANACONF3_ENADCLINL 1
204#define AB8500_ANACONF3_ENADCLINR 0
205
206/* AB8500_ANACONF4 */
207#define AB8500_ANACONF4_DISPDVSS 7
208#define AB8500_ANACONF4_ENEAR 6
209#define AB8500_ANACONF4_ENHSL 5
210#define AB8500_ANACONF4_ENHSR 4
211#define AB8500_ANACONF4_ENHFL 3
212#define AB8500_ANACONF4_ENHFR 2
213#define AB8500_ANACONF4_ENVIB1 1
214#define AB8500_ANACONF4_ENVIB2 0
215
216/* AB8500_DAPATHCONF */
217#define AB8500_DAPATHCONF_ENDACEAR 6
218#define AB8500_DAPATHCONF_ENDACHSL 5
219#define AB8500_DAPATHCONF_ENDACHSR 4
220#define AB8500_DAPATHCONF_ENDACHFL 3
221#define AB8500_DAPATHCONF_ENDACHFR 2
222#define AB8500_DAPATHCONF_ENDACVIB1 1
223#define AB8500_DAPATHCONF_ENDACVIB2 0
224
225/* AB8500_MUTECONF */
226#define AB8500_MUTECONF_MUTEAR 6
227#define AB8500_MUTECONF_MUTHSL 5
228#define AB8500_MUTECONF_MUTHSR 4
229#define AB8500_MUTECONF_MUTDACEAR 2
230#define AB8500_MUTECONF_MUTDACHSL 1
231#define AB8500_MUTECONF_MUTDACHSR 0
232
233/* AB8500_SHORTCIRCONF */
234#define AB8500_SHORTCIRCONF_ENSHORTPWD 7
235#define AB8500_SHORTCIRCONF_EARSHORTDIS 6
236#define AB8500_SHORTCIRCONF_HSSHORTDIS 5
237#define AB8500_SHORTCIRCONF_HSPULLDEN 4
238#define AB8500_SHORTCIRCONF_HSOSCEN 2
239#define AB8500_SHORTCIRCONF_HSFADDIS 1
240#define AB8500_SHORTCIRCONF_HSZCDDIS 0
241/* Zero cross should be disabled */
242
243/* AB8500_ANACONF5 */
244#define AB8500_ANACONF5_ENCPHS 7
245#define AB8500_ANACONF5_HSLDACTOLOL 5
246#define AB8500_ANACONF5_HSRDACTOLOR 4
247#define AB8500_ANACONF5_ENLOL 3
248#define AB8500_ANACONF5_ENLOR 2
249#define AB8500_ANACONF5_HSAUTOEN 0
250
251/* AB8500_ENVCPCONF */
252#define AB8500_ENVCPCONF_ENVDETHTHRE 4
253#define AB8500_ENVCPCONF_ENVDETLTHRE 0
254#define AB8500_ENVCPCONF_ENVDETHTHRE_MAX 0x0F
255#define AB8500_ENVCPCONF_ENVDETLTHRE_MAX 0x0F
256
257/* AB8500_SIGENVCONF */
258#define AB8500_SIGENVCONF_CPLVEN 5
259#define AB8500_SIGENVCONF_ENVDETCPEN 4
260#define AB8500_SIGENVCONF_ENVDETTIME 0
261#define AB8500_SIGENVCONF_ENVDETTIME_MAX 0x0F
262
263/* AB8500_PWMGENCONF1 */
264#define AB8500_PWMGENCONF1_PWMTOVIB1 7
265#define AB8500_PWMGENCONF1_PWMTOVIB2 6
266#define AB8500_PWMGENCONF1_PWM1CTRL 5
267#define AB8500_PWMGENCONF1_PWM2CTRL 4
268#define AB8500_PWMGENCONF1_PWM1NCTRL 3
269#define AB8500_PWMGENCONF1_PWM1PCTRL 2
270#define AB8500_PWMGENCONF1_PWM2NCTRL 1
271#define AB8500_PWMGENCONF1_PWM2PCTRL 0
272
273/* AB8500_PWMGENCONF2 */
274/* AB8500_PWMGENCONF3 */
275/* AB8500_PWMGENCONF4 */
276/* AB8500_PWMGENCONF5 */
277#define AB8500_PWMGENCONFX_PWMVIBXPOL 7
278#define AB8500_PWMGENCONFX_PWMVIBXDUTCYC 0
279#define AB8500_PWMGENCONFX_PWMVIBXDUTCYC_MAX 0x64
280
281/* AB8500_ANAGAIN1 */
282/* AB8500_ANAGAIN2 */
283#define AB8500_ANAGAINX_ENSEMICX 7
284#define AB8500_ANAGAINX_LOWPOWMICX 6
285#define AB8500_ANAGAINX_MICXGAIN 0
286#define AB8500_ANAGAINX_MICXGAIN_MAX 0x1F
287
288/* AB8500_ANAGAIN3 */
289#define AB8500_ANAGAIN3_HSLGAIN 4
290#define AB8500_ANAGAIN3_HSRGAIN 0
291#define AB8500_ANAGAIN3_HSXGAIN_MAX 0x0F
292
293/* AB8500_ANAGAIN4 */
294#define AB8500_ANAGAIN4_LINLGAIN 4
295#define AB8500_ANAGAIN4_LINRGAIN 0
296#define AB8500_ANAGAIN4_LINXGAIN_MAX 0x0F
297
298/* AB8500_DIGLINHSLGAIN */
299/* AB8500_DIGLINHSRGAIN */
300#define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN 0
301#define AB8500_DIGLINHSXGAIN_LINTOHSXGAIN_MAX 0x13
302
303/* AB8500_ADFILTCONF */
304#define AB8500_ADFILTCONF_AD1NH 7
305#define AB8500_ADFILTCONF_AD2NH 6
306#define AB8500_ADFILTCONF_AD3NH 5
307#define AB8500_ADFILTCONF_AD4NH 4
308#define AB8500_ADFILTCONF_AD1VOICE 3
309#define AB8500_ADFILTCONF_AD2VOICE 2
310#define AB8500_ADFILTCONF_AD3VOICE 1
311#define AB8500_ADFILTCONF_AD4VOICE 0
312
313/* AB8500_DIGIFCONF1 */
314#define AB8500_DIGIFCONF1_ENMASTGEN 7
315#define AB8500_DIGIFCONF1_IF1BITCLKOS1 6
316#define AB8500_DIGIFCONF1_IF1BITCLKOS0 5
317#define AB8500_DIGIFCONF1_ENFSBITCLK1 4
318#define AB8500_DIGIFCONF1_IF0BITCLKOS1 2
319#define AB8500_DIGIFCONF1_IF0BITCLKOS0 1
320#define AB8500_DIGIFCONF1_ENFSBITCLK0 0
321
322/* AB8500_DIGIFCONF2 */
323#define AB8500_DIGIFCONF2_FSYNC0P 6
324#define AB8500_DIGIFCONF2_BITCLK0P 5
325#define AB8500_DIGIFCONF2_IF0DEL 4
326#define AB8500_DIGIFCONF2_IF0FORMAT1 3
327#define AB8500_DIGIFCONF2_IF0FORMAT0 2
328#define AB8500_DIGIFCONF2_IF0WL1 1
329#define AB8500_DIGIFCONF2_IF0WL0 0
330
331/* AB8500_DIGIFCONF3 */
332#define AB8500_DIGIFCONF3_IF0DATOIF1AD 7
333#define AB8500_DIGIFCONF3_IF0CLKTOIF1CLK 6
334#define AB8500_DIGIFCONF3_IF1MASTER 5
335#define AB8500_DIGIFCONF3_IF1DATOIF0AD 3
336#define AB8500_DIGIFCONF3_IF1CLKTOIF0CLK 2
337#define AB8500_DIGIFCONF3_IF0MASTER 1
338#define AB8500_DIGIFCONF3_IF0BFIFOEN 0
339
340/* AB8500_DIGIFCONF4 */
341#define AB8500_DIGIFCONF4_FSYNC1P 6
342#define AB8500_DIGIFCONF4_BITCLK1P 5
343#define AB8500_DIGIFCONF4_IF1DEL 4
344#define AB8500_DIGIFCONF4_IF1FORMAT1 3
345#define AB8500_DIGIFCONF4_IF1FORMAT0 2
346#define AB8500_DIGIFCONF4_IF1WL1 1
347#define AB8500_DIGIFCONF4_IF1WL0 0
348
349/* AB8500_ADSLOTSELX */
350#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00
351#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x01
352#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x02
353#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x03
354#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x04
355#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x05
356#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x06
357#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x07
358#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x08
359#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0x0F
360#define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00
361#define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x10
362#define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x20
363#define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x30
364#define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x40
365#define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x50
366#define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x60
367#define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x70
368#define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x80
369#define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0xF0
370#define AB8500_ADSLOTSELX_EVEN_SHIFT 0
371#define AB8500_ADSLOTSELX_ODD_SHIFT 4
372
373/* AB8500_ADSLOTHIZCTRL1 */
374/* AB8500_ADSLOTHIZCTRL2 */
375/* AB8500_ADSLOTHIZCTRL3 */
376/* AB8500_ADSLOTHIZCTRL4 */
377/* AB8500_DASLOTCONF1 */
378#define AB8500_DASLOTCONF1_DA12VOICE 7
379#define AB8500_DASLOTCONF1_SWAPDA12_34 6
380#define AB8500_DASLOTCONF1_DAI7TOADO1 5
381
382/* AB8500_DASLOTCONF2 */
383#define AB8500_DASLOTCONF2_DAI8TOADO2 5
384
385/* AB8500_DASLOTCONF3 */
386#define AB8500_DASLOTCONF3_DA34VOICE 7
387#define AB8500_DASLOTCONF3_DAI7TOADO3 5
388
389/* AB8500_DASLOTCONF4 */
390#define AB8500_DASLOTCONF4_DAI8TOADO4 5
391
392/* AB8500_DASLOTCONF5 */
393#define AB8500_DASLOTCONF5_DA56VOICE 7
394#define AB8500_DASLOTCONF5_DAI7TOADO5 5
395
396/* AB8500_DASLOTCONF6 */
397#define AB8500_DASLOTCONF6_DAI8TOADO6 5
398
399/* AB8500_DASLOTCONF7 */
400#define AB8500_DASLOTCONF7_DAI8TOADO7 5
401
402/* AB8500_DASLOTCONF8 */
403#define AB8500_DASLOTCONF8_DAI7TOADO8 5
404
405#define AB8500_DASLOTCONFX_SLTODAX_SHIFT 0
406#define AB8500_DASLOTCONFX_SLTODAX_MASK 0x1F
407
408/* AB8500_CLASSDCONF1 */
409#define AB8500_CLASSDCONF1_PARLHF 7
410#define AB8500_CLASSDCONF1_PARLVIB 6
411#define AB8500_CLASSDCONF1_VIB1SWAPEN 3
412#define AB8500_CLASSDCONF1_VIB2SWAPEN 2
413#define AB8500_CLASSDCONF1_HFLSWAPEN 1
414#define AB8500_CLASSDCONF1_HFRSWAPEN 0
415
416/* AB8500_CLASSDCONF2 */
417#define AB8500_CLASSDCONF2_FIRBYP3 7
418#define AB8500_CLASSDCONF2_FIRBYP2 6
419#define AB8500_CLASSDCONF2_FIRBYP1 5
420#define AB8500_CLASSDCONF2_FIRBYP0 4
421#define AB8500_CLASSDCONF2_HIGHVOLEN3 3
422#define AB8500_CLASSDCONF2_HIGHVOLEN2 2
423#define AB8500_CLASSDCONF2_HIGHVOLEN1 1
424#define AB8500_CLASSDCONF2_HIGHVOLEN0 0
425
426/* AB8500_CLASSDCONF3 */
427#define AB8500_CLASSDCONF3_DITHHPGAIN 4
428#define AB8500_CLASSDCONF3_DITHHPGAIN_MAX 0x0A
429#define AB8500_CLASSDCONF3_DITHWGAIN 0
430#define AB8500_CLASSDCONF3_DITHWGAIN_MAX 0x0A
431
432/* AB8500_DMICFILTCONF */
433#define AB8500_DMICFILTCONF_ANCINSEL 7
434#define AB8500_DMICFILTCONF_DA3TOEAR 6
435#define AB8500_DMICFILTCONF_DMIC1SINC3 5
436#define AB8500_DMICFILTCONF_DMIC2SINC3 4
437#define AB8500_DMICFILTCONF_DMIC3SINC3 3
438#define AB8500_DMICFILTCONF_DMIC4SINC3 2
439#define AB8500_DMICFILTCONF_DMIC5SINC3 1
440#define AB8500_DMICFILTCONF_DMIC6SINC3 0
441
442/* AB8500_DIGMULTCONF1 */
443#define AB8500_DIGMULTCONF1_DATOHSLEN 7
444#define AB8500_DIGMULTCONF1_DATOHSREN 6
445#define AB8500_DIGMULTCONF1_AD1SEL 5
446#define AB8500_DIGMULTCONF1_AD2SEL 4
447#define AB8500_DIGMULTCONF1_AD3SEL 3
448#define AB8500_DIGMULTCONF1_AD5SEL 2
449#define AB8500_DIGMULTCONF1_AD6SEL 1
450#define AB8500_DIGMULTCONF1_ANCSEL 0
451
452/* AB8500_DIGMULTCONF2 */
453#define AB8500_DIGMULTCONF2_DATOHFREN 7
454#define AB8500_DIGMULTCONF2_DATOHFLEN 6
455#define AB8500_DIGMULTCONF2_HFRSEL 5
456#define AB8500_DIGMULTCONF2_HFLSEL 4
457#define AB8500_DIGMULTCONF2_FIRSID1SEL 2
458#define AB8500_DIGMULTCONF2_FIRSID2SEL 0
459
460/* AB8500_ADDIGGAIN1 */
461/* AB8500_ADDIGGAIN2 */
462/* AB8500_ADDIGGAIN3 */
463/* AB8500_ADDIGGAIN4 */
464/* AB8500_ADDIGGAIN5 */
465/* AB8500_ADDIGGAIN6 */
466#define AB8500_ADDIGGAINX_FADEDISADX 6
467#define AB8500_ADDIGGAINX_ADXGAIN_MAX 0x3F
468
469/* AB8500_DADIGGAIN1 */
470/* AB8500_DADIGGAIN2 */
471/* AB8500_DADIGGAIN3 */
472/* AB8500_DADIGGAIN4 */
473/* AB8500_DADIGGAIN5 */
474/* AB8500_DADIGGAIN6 */
475#define AB8500_DADIGGAINX_FADEDISDAX 6
476#define AB8500_DADIGGAINX_DAXGAIN_MAX 0x3F
477
478/* AB8500_ADDIGLOOPGAIN1 */
479/* AB8500_ADDIGLOOPGAIN2 */
480#define AB8500_ADDIGLOOPGAINX_FADEDISADXL 6
481#define AB8500_ADDIGLOOPGAINX_ADXLBGAIN_MAX 0x3F
482
483/* AB8500_HSLEARDIGGAIN */
484#define AB8500_HSLEARDIGGAIN_HSSINC1 7
485#define AB8500_HSLEARDIGGAIN_FADEDISHSL 4
486#define AB8500_HSLEARDIGGAIN_HSLDGAIN_MAX 0x09
487
488/* AB8500_HSRDIGGAIN */
489#define AB8500_HSRDIGGAIN_FADESPEED 6
490#define AB8500_HSRDIGGAIN_FADEDISHSR 4
491#define AB8500_HSRDIGGAIN_HSRDGAIN_MAX 0x09
492
493/* AB8500_SIDFIRGAIN1 */
494/* AB8500_SIDFIRGAIN2 */
495#define AB8500_SIDFIRGAINX_FIRSIDXGAIN_MAX 0x1F
496
497/* AB8500_ANCCONF1 */
498#define AB8500_ANCCONF1_ANCIIRUPDATE 3
499#define AB8500_ANCCONF1_ENANC 2
500#define AB8500_ANCCONF1_ANCIIRINIT 1
501#define AB8500_ANCCONF1_ANCFIRUPDATE 0
502
503/* AB8500_ANCCONF2 */
504#define AB8500_ANCCONF2_SHIFT 5
505#define AB8500_ANCCONF2_MIN -0x10
506#define AB8500_ANCCONF2_MAX 0xF
507
508/* AB8500_ANCCONF3 */
509#define AB8500_ANCCONF3_SHIFT 5
510#define AB8500_ANCCONF3_MIN -0x10
511#define AB8500_ANCCONF3_MAX 0xF
512
513/* AB8500_ANCCONF4 */
514#define AB8500_ANCCONF4_SHIFT 5
515#define AB8500_ANCCONF4_MIN -0x10
516#define AB8500_ANCCONF4_MAX 0xF
517
518/* AB8500_ANC_FIR_COEFFS */
519#define AB8500_ANC_FIR_COEFF_MIN -0x8000
520#define AB8500_ANC_FIR_COEFF_MAX 0x7FFF
521#define AB8500_ANC_FIR_COEFFS 15
522
523/* AB8500_ANC_IIR_COEFFS */
524#define AB8500_ANC_IIR_COEFF_MIN -0x800000
525#define AB8500_ANC_IIR_COEFF_MAX 0x7FFFFF
526#define AB8500_ANC_IIR_COEFFS 24
527/* AB8500_ANC_WARP_DELAY */
528#define AB8500_ANC_WARP_DELAY_SHIFT 16
529#define AB8500_ANC_WARP_DELAY_MIN 0x0000
530#define AB8500_ANC_WARP_DELAY_MAX 0xFFFF
531
532/* AB8500_ANCCONF11 */
533/* AB8500_ANCCONF12 */
534/* AB8500_ANCCONF13 */
535/* AB8500_ANCCONF14 */
536
537/* AB8500_SIDFIRADR */
538#define AB8500_SIDFIRADR_FIRSIDSET 7
539#define AB8500_SIDFIRADR_ADDRESS_SHIFT 0
540#define AB8500_SIDFIRADR_ADDRESS_MAX 0x7F
541
542/* AB8500_SIDFIRCOEF1 */
543/* AB8500_SIDFIRCOEF2 */
544#define AB8500_SID_FIR_COEFF_MIN 0
545#define AB8500_SID_FIR_COEFF_MAX 0xFFFF
546#define AB8500_SID_FIR_COEFFS 128
547
548/* AB8500_SIDFIRCONF */
549#define AB8500_SIDFIRCONF_ENFIRSIDS 2
550#define AB8500_SIDFIRCONF_FIRSIDSTOIF1 1
551#define AB8500_SIDFIRCONF_FIRSIDBUSY 0
552
553/* AB8500_AUDINTMASK1 */
554/* AB8500_AUDINTSOURCE1 */
555/* AB8500_AUDINTMASK2 */
556/* AB8500_AUDINTSOURCE2 */
557
558/* AB8500_FIFOCONF1 */
559#define AB8500_FIFOCONF1_BFIFOMASK 0x80
560#define AB8500_FIFOCONF1_BFIFO19M2 0x40
561#define AB8500_FIFOCONF1_BFIFOINT_SHIFT 0
562#define AB8500_FIFOCONF1_BFIFOINT_MAX 0x3F
563
564/* AB8500_FIFOCONF2 */
565#define AB8500_FIFOCONF2_BFIFOTX_SHIFT 0
566#define AB8500_FIFOCONF2_BFIFOTX_MAX 0xFF
567
568/* AB8500_FIFOCONF3 */
569#define AB8500_FIFOCONF3_BFIFOEXSL_SHIFT 5
570#define AB8500_FIFOCONF3_BFIFOEXSL_MAX 0x5
571#define AB8500_FIFOCONF3_PREBITCLK0_SHIFT 2
572#define AB8500_FIFOCONF3_PREBITCLK0_MAX 0x7
573#define AB8500_FIFOCONF3_BFIFOMAST_SHIFT 1
574#define AB8500_FIFOCONF3_BFIFORUN_SHIFT 0
575
576/* AB8500_FIFOCONF4 */
577#define AB8500_FIFOCONF4_BFIFOFRAMSW_SHIFT 0
578#define AB8500_FIFOCONF4_BFIFOFRAMSW_MAX 0xFF
579
580/* AB8500_FIFOCONF5 */
581#define AB8500_FIFOCONF5_BFIFOWAKEUP_SHIFT 0
582#define AB8500_FIFOCONF5_BFIFOWAKEUP_MAX 0xFF
583
584/* AB8500_FIFOCONF6 */
585#define AB8500_FIFOCONF6_BFIFOSAMPLE_SHIFT 0
586#define AB8500_FIFOCONF6_BFIFOSAMPLE_MAX 0xFF
587
588/* AB8500_AUDREV */
589
590#endif
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c
index 2023c749f23..ea06b834a7d 100644
--- a/sound/soc/codecs/ac97.c
+++ b/sound/soc/codecs/ac97.c
@@ -91,11 +91,6 @@ static int ac97_soc_probe(struct snd_soc_codec *codec)
91 return 0; 91 return 0;
92} 92}
93 93
94static int ac97_soc_remove(struct snd_soc_codec *codec)
95{
96 return 0;
97}
98
99#ifdef CONFIG_PM 94#ifdef CONFIG_PM
100static int ac97_soc_suspend(struct snd_soc_codec *codec) 95static int ac97_soc_suspend(struct snd_soc_codec *codec)
101{ 96{
@@ -119,7 +114,6 @@ static struct snd_soc_codec_driver soc_codec_dev_ac97 = {
119 .write = ac97_write, 114 .write = ac97_write,
120 .read = ac97_read, 115 .read = ac97_read,
121 .probe = ac97_soc_probe, 116 .probe = ac97_soc_probe,
122 .remove = ac97_soc_remove,
123 .suspend = ac97_soc_suspend, 117 .suspend = ac97_soc_suspend,
124 .resume = ac97_soc_resume, 118 .resume = ac97_soc_resume,
125}; 119};
diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
new file mode 100644
index 00000000000..5c9cacaf2d5
--- /dev/null
+++ b/sound/soc/codecs/arizona.c
@@ -0,0 +1,937 @@
1/*
2 * arizona.c - Wolfson Arizona class device shared support
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/gcd.h>
14#include <linux/module.h>
15#include <linux/pm_runtime.h>
16#include <sound/pcm.h>
17#include <sound/pcm_params.h>
18#include <sound/tlv.h>
19
20#include <linux/mfd/arizona/core.h>
21#include <linux/mfd/arizona/registers.h>
22
23#include "arizona.h"
24
25#define ARIZONA_AIF_BCLK_CTRL 0x00
26#define ARIZONA_AIF_TX_PIN_CTRL 0x01
27#define ARIZONA_AIF_RX_PIN_CTRL 0x02
28#define ARIZONA_AIF_RATE_CTRL 0x03
29#define ARIZONA_AIF_FORMAT 0x04
30#define ARIZONA_AIF_TX_BCLK_RATE 0x05
31#define ARIZONA_AIF_RX_BCLK_RATE 0x06
32#define ARIZONA_AIF_FRAME_CTRL_1 0x07
33#define ARIZONA_AIF_FRAME_CTRL_2 0x08
34#define ARIZONA_AIF_FRAME_CTRL_3 0x09
35#define ARIZONA_AIF_FRAME_CTRL_4 0x0A
36#define ARIZONA_AIF_FRAME_CTRL_5 0x0B
37#define ARIZONA_AIF_FRAME_CTRL_6 0x0C
38#define ARIZONA_AIF_FRAME_CTRL_7 0x0D
39#define ARIZONA_AIF_FRAME_CTRL_8 0x0E
40#define ARIZONA_AIF_FRAME_CTRL_9 0x0F
41#define ARIZONA_AIF_FRAME_CTRL_10 0x10
42#define ARIZONA_AIF_FRAME_CTRL_11 0x11
43#define ARIZONA_AIF_FRAME_CTRL_12 0x12
44#define ARIZONA_AIF_FRAME_CTRL_13 0x13
45#define ARIZONA_AIF_FRAME_CTRL_14 0x14
46#define ARIZONA_AIF_FRAME_CTRL_15 0x15
47#define ARIZONA_AIF_FRAME_CTRL_16 0x16
48#define ARIZONA_AIF_FRAME_CTRL_17 0x17
49#define ARIZONA_AIF_FRAME_CTRL_18 0x18
50#define ARIZONA_AIF_TX_ENABLES 0x19
51#define ARIZONA_AIF_RX_ENABLES 0x1A
52#define ARIZONA_AIF_FORCE_WRITE 0x1B
53
54#define arizona_fll_err(_fll, fmt, ...) \
55 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
56#define arizona_fll_warn(_fll, fmt, ...) \
57 dev_warn(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
58#define arizona_fll_dbg(_fll, fmt, ...) \
59 dev_err(_fll->arizona->dev, "FLL%d: " fmt, _fll->id, ##__VA_ARGS__)
60
61#define arizona_aif_err(_dai, fmt, ...) \
62 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
63#define arizona_aif_warn(_dai, fmt, ...) \
64 dev_warn(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
65#define arizona_aif_dbg(_dai, fmt, ...) \
66 dev_err(_dai->dev, "AIF%d: " fmt, _dai->id, ##__VA_ARGS__)
67
68const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS] = {
69 "None",
70 "Tone Generator 1",
71 "Tone Generator 2",
72 "Haptics",
73 "AEC",
74 "Mic Mute Mixer",
75 "Noise Generator",
76 "IN1L",
77 "IN1R",
78 "IN2L",
79 "IN2R",
80 "IN3L",
81 "IN3R",
82 "IN4L",
83 "IN4R",
84 "AIF1RX1",
85 "AIF1RX2",
86 "AIF1RX3",
87 "AIF1RX4",
88 "AIF1RX5",
89 "AIF1RX6",
90 "AIF1RX7",
91 "AIF1RX8",
92 "AIF2RX1",
93 "AIF2RX2",
94 "AIF3RX1",
95 "AIF3RX2",
96 "SLIMRX1",
97 "SLIMRX2",
98 "SLIMRX3",
99 "SLIMRX4",
100 "SLIMRX5",
101 "SLIMRX6",
102 "SLIMRX7",
103 "SLIMRX8",
104 "EQ1",
105 "EQ2",
106 "EQ3",
107 "EQ4",
108 "DRC1L",
109 "DRC1R",
110 "DRC2L",
111 "DRC2R",
112 "LHPF1",
113 "LHPF2",
114 "LHPF3",
115 "LHPF4",
116 "DSP1.1",
117 "DSP1.2",
118 "DSP1.3",
119 "DSP1.4",
120 "DSP1.5",
121 "DSP1.6",
122 "ASRC1L",
123 "ASRC1R",
124 "ASRC2L",
125 "ASRC2R",
126};
127EXPORT_SYMBOL_GPL(arizona_mixer_texts);
128
129int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS] = {
130 0x00, /* None */
131 0x04, /* Tone */
132 0x05,
133 0x06, /* Haptics */
134 0x08, /* AEC */
135 0x0c, /* Noise mixer */
136 0x0d, /* Comfort noise */
137 0x10, /* IN1L */
138 0x11,
139 0x12,
140 0x13,
141 0x14,
142 0x15,
143 0x16,
144 0x17,
145 0x20, /* AIF1RX1 */
146 0x21,
147 0x22,
148 0x23,
149 0x24,
150 0x25,
151 0x26,
152 0x27,
153 0x28, /* AIF2RX1 */
154 0x29,
155 0x30, /* AIF3RX1 */
156 0x31,
157 0x38, /* SLIMRX1 */
158 0x39,
159 0x3a,
160 0x3b,
161 0x3c,
162 0x3d,
163 0x3e,
164 0x3f,
165 0x50, /* EQ1 */
166 0x51,
167 0x52,
168 0x53,
169 0x58, /* DRC1L */
170 0x59,
171 0x5a,
172 0x5b,
173 0x60, /* LHPF1 */
174 0x61,
175 0x62,
176 0x63,
177 0x68, /* DSP1.1 */
178 0x69,
179 0x6a,
180 0x6b,
181 0x6c,
182 0x6d,
183 0x90, /* ASRC1L */
184 0x91,
185 0x92,
186 0x93,
187};
188EXPORT_SYMBOL_GPL(arizona_mixer_values);
189
190const DECLARE_TLV_DB_SCALE(arizona_mixer_tlv, -3200, 100, 0);
191EXPORT_SYMBOL_GPL(arizona_mixer_tlv);
192
193static const char *arizona_lhpf_mode_text[] = {
194 "Low-pass", "High-pass"
195};
196
197const struct soc_enum arizona_lhpf1_mode =
198 SOC_ENUM_SINGLE(ARIZONA_HPLPF1_1, ARIZONA_LHPF1_MODE_SHIFT, 2,
199 arizona_lhpf_mode_text);
200EXPORT_SYMBOL_GPL(arizona_lhpf1_mode);
201
202const struct soc_enum arizona_lhpf2_mode =
203 SOC_ENUM_SINGLE(ARIZONA_HPLPF2_1, ARIZONA_LHPF2_MODE_SHIFT, 2,
204 arizona_lhpf_mode_text);
205EXPORT_SYMBOL_GPL(arizona_lhpf2_mode);
206
207const struct soc_enum arizona_lhpf3_mode =
208 SOC_ENUM_SINGLE(ARIZONA_HPLPF3_1, ARIZONA_LHPF3_MODE_SHIFT, 2,
209 arizona_lhpf_mode_text);
210EXPORT_SYMBOL_GPL(arizona_lhpf3_mode);
211
212const struct soc_enum arizona_lhpf4_mode =
213 SOC_ENUM_SINGLE(ARIZONA_HPLPF4_1, ARIZONA_LHPF4_MODE_SHIFT, 2,
214 arizona_lhpf_mode_text);
215EXPORT_SYMBOL_GPL(arizona_lhpf4_mode);
216
217int arizona_in_ev(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol,
218 int event)
219{
220 return 0;
221}
222EXPORT_SYMBOL_GPL(arizona_in_ev);
223
224int arizona_out_ev(struct snd_soc_dapm_widget *w,
225 struct snd_kcontrol *kcontrol,
226 int event)
227{
228 return 0;
229}
230EXPORT_SYMBOL_GPL(arizona_out_ev);
231
232int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
233 int source, unsigned int freq, int dir)
234{
235 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
236 struct arizona *arizona = priv->arizona;
237 char *name;
238 unsigned int reg;
239 unsigned int mask = ARIZONA_SYSCLK_FREQ_MASK | ARIZONA_SYSCLK_SRC_MASK;
240 unsigned int val = source << ARIZONA_SYSCLK_SRC_SHIFT;
241 unsigned int *clk;
242
243 switch (clk_id) {
244 case ARIZONA_CLK_SYSCLK:
245 name = "SYSCLK";
246 reg = ARIZONA_SYSTEM_CLOCK_1;
247 clk = &priv->sysclk;
248 mask |= ARIZONA_SYSCLK_FRAC;
249 break;
250 case ARIZONA_CLK_ASYNCCLK:
251 name = "ASYNCCLK";
252 reg = ARIZONA_ASYNC_CLOCK_1;
253 clk = &priv->asyncclk;
254 break;
255 default:
256 return -EINVAL;
257 }
258
259 switch (freq) {
260 case 5644800:
261 case 6144000:
262 break;
263 case 11289600:
264 case 12288000:
265 val |= 1 << ARIZONA_SYSCLK_FREQ_SHIFT;
266 break;
267 case 22579200:
268 case 24576000:
269 val |= 2 << ARIZONA_SYSCLK_FREQ_SHIFT;
270 break;
271 case 45158400:
272 case 49152000:
273 val |= 3 << ARIZONA_SYSCLK_FREQ_SHIFT;
274 break;
275 default:
276 return -EINVAL;
277 }
278
279 *clk = freq;
280
281 if (freq % 6144000)
282 val |= ARIZONA_SYSCLK_FRAC;
283
284 dev_dbg(arizona->dev, "%s set to %uHz", name, freq);
285
286 return regmap_update_bits(arizona->regmap, reg, mask, val);
287}
288EXPORT_SYMBOL_GPL(arizona_set_sysclk);
289
290static int arizona_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
291{
292 struct snd_soc_codec *codec = dai->codec;
293 int lrclk, bclk, mode, base;
294
295 base = dai->driver->base;
296
297 lrclk = 0;
298 bclk = 0;
299
300 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
301 case SND_SOC_DAIFMT_DSP_A:
302 mode = 0;
303 break;
304 case SND_SOC_DAIFMT_DSP_B:
305 mode = 1;
306 break;
307 case SND_SOC_DAIFMT_I2S:
308 mode = 2;
309 break;
310 case SND_SOC_DAIFMT_LEFT_J:
311 mode = 3;
312 break;
313 default:
314 arizona_aif_err(dai, "Unsupported DAI format %d\n",
315 fmt & SND_SOC_DAIFMT_FORMAT_MASK);
316 return -EINVAL;
317 }
318
319 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
320 case SND_SOC_DAIFMT_CBS_CFS:
321 break;
322 case SND_SOC_DAIFMT_CBS_CFM:
323 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
324 break;
325 case SND_SOC_DAIFMT_CBM_CFS:
326 bclk |= ARIZONA_AIF1_BCLK_MSTR;
327 break;
328 case SND_SOC_DAIFMT_CBM_CFM:
329 bclk |= ARIZONA_AIF1_BCLK_MSTR;
330 lrclk |= ARIZONA_AIF1TX_LRCLK_MSTR;
331 break;
332 default:
333 arizona_aif_err(dai, "Unsupported master mode %d\n",
334 fmt & SND_SOC_DAIFMT_MASTER_MASK);
335 return -EINVAL;
336 }
337
338 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
339 case SND_SOC_DAIFMT_NB_NF:
340 break;
341 case SND_SOC_DAIFMT_IB_IF:
342 bclk |= ARIZONA_AIF1_BCLK_INV;
343 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
344 break;
345 case SND_SOC_DAIFMT_IB_NF:
346 bclk |= ARIZONA_AIF1_BCLK_INV;
347 break;
348 case SND_SOC_DAIFMT_NB_IF:
349 lrclk |= ARIZONA_AIF1TX_LRCLK_INV;
350 break;
351 default:
352 return -EINVAL;
353 }
354
355 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
356 ARIZONA_AIF1_BCLK_INV | ARIZONA_AIF1_BCLK_MSTR,
357 bclk);
358 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_PIN_CTRL,
359 ARIZONA_AIF1TX_LRCLK_INV |
360 ARIZONA_AIF1TX_LRCLK_MSTR, lrclk);
361 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_PIN_CTRL,
362 ARIZONA_AIF1RX_LRCLK_INV |
363 ARIZONA_AIF1RX_LRCLK_MSTR, lrclk);
364 snd_soc_update_bits(codec, base + ARIZONA_AIF_FORMAT,
365 ARIZONA_AIF1_FMT_MASK, mode);
366
367 return 0;
368}
369
370static const int arizona_48k_bclk_rates[] = {
371 -1,
372 48000,
373 64000,
374 96000,
375 128000,
376 192000,
377 256000,
378 384000,
379 512000,
380 768000,
381 1024000,
382 1536000,
383 2048000,
384 3072000,
385 4096000,
386 6144000,
387 8192000,
388 12288000,
389 24576000,
390};
391
392static const unsigned int arizona_48k_rates[] = {
393 12000,
394 24000,
395 48000,
396 96000,
397 192000,
398 384000,
399 768000,
400 4000,
401 8000,
402 16000,
403 32000,
404 64000,
405 128000,
406 256000,
407 512000,
408};
409
410static const struct snd_pcm_hw_constraint_list arizona_48k_constraint = {
411 .count = ARRAY_SIZE(arizona_48k_rates),
412 .list = arizona_48k_rates,
413};
414
415static const int arizona_44k1_bclk_rates[] = {
416 -1,
417 44100,
418 58800,
419 88200,
420 117600,
421 177640,
422 235200,
423 352800,
424 470400,
425 705600,
426 940800,
427 1411200,
428 1881600,
429 2882400,
430 3763200,
431 5644800,
432 7526400,
433 11289600,
434 22579200,
435};
436
437static const unsigned int arizona_44k1_rates[] = {
438 11025,
439 22050,
440 44100,
441 88200,
442 176400,
443 352800,
444 705600,
445};
446
447static const struct snd_pcm_hw_constraint_list arizona_44k1_constraint = {
448 .count = ARRAY_SIZE(arizona_44k1_rates),
449 .list = arizona_44k1_rates,
450};
451
452static int arizona_sr_vals[] = {
453 0,
454 12000,
455 24000,
456 48000,
457 96000,
458 192000,
459 384000,
460 768000,
461 0,
462 11025,
463 22050,
464 44100,
465 88200,
466 176400,
467 352800,
468 705600,
469 4000,
470 8000,
471 16000,
472 32000,
473 64000,
474 128000,
475 256000,
476 512000,
477};
478
479static int arizona_startup(struct snd_pcm_substream *substream,
480 struct snd_soc_dai *dai)
481{
482 struct snd_soc_codec *codec = dai->codec;
483 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
484 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
485 const struct snd_pcm_hw_constraint_list *constraint;
486 unsigned int base_rate;
487
488 switch (dai_priv->clk) {
489 case ARIZONA_CLK_SYSCLK:
490 base_rate = priv->sysclk;
491 break;
492 case ARIZONA_CLK_ASYNCCLK:
493 base_rate = priv->asyncclk;
494 break;
495 default:
496 return 0;
497 }
498
499 if (base_rate % 8000)
500 constraint = &arizona_44k1_constraint;
501 else
502 constraint = &arizona_48k_constraint;
503
504 return snd_pcm_hw_constraint_list(substream->runtime, 0,
505 SNDRV_PCM_HW_PARAM_RATE,
506 constraint);
507}
508
509static int arizona_hw_params(struct snd_pcm_substream *substream,
510 struct snd_pcm_hw_params *params,
511 struct snd_soc_dai *dai)
512{
513 struct snd_soc_codec *codec = dai->codec;
514 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
515 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
516 int base = dai->driver->base;
517 const int *rates;
518 int i;
519 int bclk, lrclk, wl, frame, sr_val;
520
521 if (params_rate(params) % 8000)
522 rates = &arizona_44k1_bclk_rates[0];
523 else
524 rates = &arizona_48k_bclk_rates[0];
525
526 for (i = 0; i < ARRAY_SIZE(arizona_44k1_bclk_rates); i++) {
527 if (rates[i] >= snd_soc_params_to_bclk(params) &&
528 rates[i] % params_rate(params) == 0) {
529 bclk = i;
530 break;
531 }
532 }
533 if (i == ARRAY_SIZE(arizona_44k1_bclk_rates)) {
534 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
535 params_rate(params));
536 return -EINVAL;
537 }
538
539 for (i = 0; i < ARRAY_SIZE(arizona_sr_vals); i++)
540 if (arizona_sr_vals[i] == params_rate(params))
541 break;
542 if (i == ARRAY_SIZE(arizona_sr_vals)) {
543 arizona_aif_err(dai, "Unsupported sample rate %dHz\n",
544 params_rate(params));
545 return -EINVAL;
546 }
547 sr_val = i;
548
549 lrclk = snd_soc_params_to_bclk(params) / params_rate(params);
550
551 arizona_aif_dbg(dai, "BCLK %dHz LRCLK %dHz\n",
552 rates[bclk], rates[bclk] / lrclk);
553
554 wl = snd_pcm_format_width(params_format(params));
555 frame = wl << ARIZONA_AIF1TX_WL_SHIFT | wl;
556
557 /*
558 * We will need to be more flexible than this in future,
559 * currently we use a single sample rate for SYSCLK.
560 */
561 switch (dai_priv->clk) {
562 case ARIZONA_CLK_SYSCLK:
563 snd_soc_update_bits(codec, ARIZONA_SAMPLE_RATE_1,
564 ARIZONA_SAMPLE_RATE_1_MASK, sr_val);
565 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
566 ARIZONA_AIF1_RATE_MASK, 0);
567 break;
568 case ARIZONA_CLK_ASYNCCLK:
569 snd_soc_update_bits(codec, ARIZONA_ASYNC_SAMPLE_RATE_1,
570 ARIZONA_ASYNC_SAMPLE_RATE_MASK, sr_val);
571 snd_soc_update_bits(codec, base + ARIZONA_AIF_RATE_CTRL,
572 ARIZONA_AIF1_RATE_MASK, 8);
573 break;
574 default:
575 arizona_aif_err(dai, "Invalid clock %d\n", dai_priv->clk);
576 return -EINVAL;
577 }
578
579 snd_soc_update_bits(codec, base + ARIZONA_AIF_BCLK_CTRL,
580 ARIZONA_AIF1_BCLK_FREQ_MASK, bclk);
581 snd_soc_update_bits(codec, base + ARIZONA_AIF_TX_BCLK_RATE,
582 ARIZONA_AIF1TX_BCPF_MASK, lrclk);
583 snd_soc_update_bits(codec, base + ARIZONA_AIF_RX_BCLK_RATE,
584 ARIZONA_AIF1RX_BCPF_MASK, lrclk);
585 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_1,
586 ARIZONA_AIF1TX_WL_MASK |
587 ARIZONA_AIF1TX_SLOT_LEN_MASK, frame);
588 snd_soc_update_bits(codec, base + ARIZONA_AIF_FRAME_CTRL_2,
589 ARIZONA_AIF1RX_WL_MASK |
590 ARIZONA_AIF1RX_SLOT_LEN_MASK, frame);
591
592 return 0;
593}
594
595static const char *arizona_dai_clk_str(int clk_id)
596{
597 switch (clk_id) {
598 case ARIZONA_CLK_SYSCLK:
599 return "SYSCLK";
600 case ARIZONA_CLK_ASYNCCLK:
601 return "ASYNCCLK";
602 default:
603 return "Unknown clock";
604 }
605}
606
607static int arizona_dai_set_sysclk(struct snd_soc_dai *dai,
608 int clk_id, unsigned int freq, int dir)
609{
610 struct snd_soc_codec *codec = dai->codec;
611 struct arizona_priv *priv = snd_soc_codec_get_drvdata(codec);
612 struct arizona_dai_priv *dai_priv = &priv->dai[dai->id - 1];
613 struct snd_soc_dapm_route routes[2];
614
615 switch (clk_id) {
616 case ARIZONA_CLK_SYSCLK:
617 case ARIZONA_CLK_ASYNCCLK:
618 break;
619 default:
620 return -EINVAL;
621 }
622
623 if (clk_id == dai_priv->clk)
624 return 0;
625
626 if (dai->active) {
627 dev_err(codec->dev, "Can't change clock on active DAI %d\n",
628 dai->id);
629 return -EBUSY;
630 }
631
632 memset(&routes, 0, sizeof(routes));
633 routes[0].sink = dai->driver->capture.stream_name;
634 routes[1].sink = dai->driver->playback.stream_name;
635
636 routes[0].source = arizona_dai_clk_str(dai_priv->clk);
637 routes[1].source = arizona_dai_clk_str(dai_priv->clk);
638 snd_soc_dapm_del_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
639
640 routes[0].source = arizona_dai_clk_str(clk_id);
641 routes[1].source = arizona_dai_clk_str(clk_id);
642 snd_soc_dapm_add_routes(&codec->dapm, routes, ARRAY_SIZE(routes));
643
644 return snd_soc_dapm_sync(&codec->dapm);
645}
646
647const struct snd_soc_dai_ops arizona_dai_ops = {
648 .startup = arizona_startup,
649 .set_fmt = arizona_set_fmt,
650 .hw_params = arizona_hw_params,
651 .set_sysclk = arizona_dai_set_sysclk,
652};
653EXPORT_SYMBOL_GPL(arizona_dai_ops);
654
655int arizona_init_dai(struct arizona_priv *priv, int id)
656{
657 struct arizona_dai_priv *dai_priv = &priv->dai[id];
658
659 dai_priv->clk = ARIZONA_CLK_SYSCLK;
660
661 return 0;
662}
663EXPORT_SYMBOL_GPL(arizona_init_dai);
664
665static irqreturn_t arizona_fll_lock(int irq, void *data)
666{
667 struct arizona_fll *fll = data;
668
669 arizona_fll_dbg(fll, "Locked\n");
670
671 complete(&fll->lock);
672
673 return IRQ_HANDLED;
674}
675
676static irqreturn_t arizona_fll_clock_ok(int irq, void *data)
677{
678 struct arizona_fll *fll = data;
679
680 arizona_fll_dbg(fll, "clock OK\n");
681
682 complete(&fll->ok);
683
684 return IRQ_HANDLED;
685}
686
687static struct {
688 unsigned int min;
689 unsigned int max;
690 u16 fratio;
691 int ratio;
692} fll_fratios[] = {
693 { 0, 64000, 4, 16 },
694 { 64000, 128000, 3, 8 },
695 { 128000, 256000, 2, 4 },
696 { 256000, 1000000, 1, 2 },
697 { 1000000, 13500000, 0, 1 },
698};
699
700struct arizona_fll_cfg {
701 int n;
702 int theta;
703 int lambda;
704 int refdiv;
705 int outdiv;
706 int fratio;
707};
708
709static int arizona_calc_fll(struct arizona_fll *fll,
710 struct arizona_fll_cfg *cfg,
711 unsigned int Fref,
712 unsigned int Fout)
713{
714 unsigned int target, div, gcd_fll;
715 int i, ratio;
716
717 arizona_fll_dbg(fll, "Fref=%u Fout=%u\n", Fref, Fout);
718
719 /* Fref must be <=13.5MHz */
720 div = 1;
721 cfg->refdiv = 0;
722 while ((Fref / div) > 13500000) {
723 div *= 2;
724 cfg->refdiv++;
725
726 if (div > 8) {
727 arizona_fll_err(fll,
728 "Can't scale %dMHz in to <=13.5MHz\n",
729 Fref);
730 return -EINVAL;
731 }
732 }
733
734 /* Apply the division for our remaining calculations */
735 Fref /= div;
736
737 /* Fvco should be over the targt; don't check the upper bound */
738 div = 1;
739 while (Fout * div < 90000000 * fll->vco_mult) {
740 div++;
741 if (div > 7) {
742 arizona_fll_err(fll, "No FLL_OUTDIV for Fout=%uHz\n",
743 Fout);
744 return -EINVAL;
745 }
746 }
747 target = Fout * div / fll->vco_mult;
748 cfg->outdiv = div;
749
750 arizona_fll_dbg(fll, "Fvco=%dHz\n", target);
751
752 /* Find an appropraite FLL_FRATIO and factor it out of the target */
753 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
754 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
755 cfg->fratio = fll_fratios[i].fratio;
756 ratio = fll_fratios[i].ratio;
757 break;
758 }
759 }
760 if (i == ARRAY_SIZE(fll_fratios)) {
761 arizona_fll_err(fll, "Unable to find FRATIO for Fref=%uHz\n",
762 Fref);
763 return -EINVAL;
764 }
765
766 cfg->n = target / (ratio * Fref);
767
768 if (target % Fref) {
769 gcd_fll = gcd(target, ratio * Fref);
770 arizona_fll_dbg(fll, "GCD=%u\n", gcd_fll);
771
772 cfg->theta = (target - (cfg->n * ratio * Fref))
773 / gcd_fll;
774 cfg->lambda = (ratio * Fref) / gcd_fll;
775 } else {
776 cfg->theta = 0;
777 cfg->lambda = 0;
778 }
779
780 arizona_fll_dbg(fll, "N=%x THETA=%x LAMBDA=%x\n",
781 cfg->n, cfg->theta, cfg->lambda);
782 arizona_fll_dbg(fll, "FRATIO=%x(%d) OUTDIV=%x REFCLK_DIV=%x\n",
783 cfg->fratio, cfg->fratio, cfg->outdiv, cfg->refdiv);
784
785 return 0;
786
787}
788
789static void arizona_apply_fll(struct arizona *arizona, unsigned int base,
790 struct arizona_fll_cfg *cfg, int source)
791{
792 regmap_update_bits(arizona->regmap, base + 3,
793 ARIZONA_FLL1_THETA_MASK, cfg->theta);
794 regmap_update_bits(arizona->regmap, base + 4,
795 ARIZONA_FLL1_LAMBDA_MASK, cfg->lambda);
796 regmap_update_bits(arizona->regmap, base + 5,
797 ARIZONA_FLL1_FRATIO_MASK,
798 cfg->fratio << ARIZONA_FLL1_FRATIO_SHIFT);
799 regmap_update_bits(arizona->regmap, base + 6,
800 ARIZONA_FLL1_CLK_REF_DIV_MASK |
801 ARIZONA_FLL1_CLK_REF_SRC_MASK,
802 cfg->refdiv << ARIZONA_FLL1_CLK_REF_DIV_SHIFT |
803 source << ARIZONA_FLL1_CLK_REF_SRC_SHIFT);
804
805 regmap_update_bits(arizona->regmap, base + 2,
806 ARIZONA_FLL1_CTRL_UPD | ARIZONA_FLL1_N_MASK,
807 ARIZONA_FLL1_CTRL_UPD | cfg->n);
808}
809
810int arizona_set_fll(struct arizona_fll *fll, int source,
811 unsigned int Fref, unsigned int Fout)
812{
813 struct arizona *arizona = fll->arizona;
814 struct arizona_fll_cfg cfg, sync;
815 unsigned int reg, val;
816 int syncsrc;
817 bool ena;
818 int ret;
819
820 ret = regmap_read(arizona->regmap, fll->base + 1, &reg);
821 if (ret != 0) {
822 arizona_fll_err(fll, "Failed to read current state: %d\n",
823 ret);
824 return ret;
825 }
826 ena = reg & ARIZONA_FLL1_ENA;
827
828 if (Fout) {
829 /* Do we have a 32kHz reference? */
830 regmap_read(arizona->regmap, ARIZONA_CLOCK_32K_1, &val);
831 switch (val & ARIZONA_CLK_32K_SRC_MASK) {
832 case ARIZONA_CLK_SRC_MCLK1:
833 case ARIZONA_CLK_SRC_MCLK2:
834 syncsrc = val & ARIZONA_CLK_32K_SRC_MASK;
835 break;
836 default:
837 syncsrc = -1;
838 }
839
840 if (source == syncsrc)
841 syncsrc = -1;
842
843 if (syncsrc >= 0) {
844 ret = arizona_calc_fll(fll, &sync, Fref, Fout);
845 if (ret != 0)
846 return ret;
847
848 ret = arizona_calc_fll(fll, &cfg, 32768, Fout);
849 if (ret != 0)
850 return ret;
851 } else {
852 ret = arizona_calc_fll(fll, &cfg, Fref, Fout);
853 if (ret != 0)
854 return ret;
855 }
856 } else {
857 regmap_update_bits(arizona->regmap, fll->base + 1,
858 ARIZONA_FLL1_ENA, 0);
859 regmap_update_bits(arizona->regmap, fll->base + 0x11,
860 ARIZONA_FLL1_SYNC_ENA, 0);
861
862 if (ena)
863 pm_runtime_put_autosuspend(arizona->dev);
864
865 return 0;
866 }
867
868 regmap_update_bits(arizona->regmap, fll->base + 5,
869 ARIZONA_FLL1_OUTDIV_MASK,
870 cfg.outdiv << ARIZONA_FLL1_OUTDIV_SHIFT);
871
872 if (syncsrc >= 0) {
873 arizona_apply_fll(arizona, fll->base, &cfg, syncsrc);
874 arizona_apply_fll(arizona, fll->base + 0x10, &sync, source);
875 } else {
876 arizona_apply_fll(arizona, fll->base, &cfg, source);
877 }
878
879 if (!ena)
880 pm_runtime_get(arizona->dev);
881
882 /* Clear any pending completions */
883 try_wait_for_completion(&fll->ok);
884
885 regmap_update_bits(arizona->regmap, fll->base + 1,
886 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
887 if (syncsrc >= 0)
888 regmap_update_bits(arizona->regmap, fll->base + 0x11,
889 ARIZONA_FLL1_SYNC_ENA,
890 ARIZONA_FLL1_SYNC_ENA);
891
892 ret = wait_for_completion_timeout(&fll->ok,
893 msecs_to_jiffies(25));
894 if (ret == 0)
895 arizona_fll_warn(fll, "Timed out waiting for lock\n");
896
897 return 0;
898}
899EXPORT_SYMBOL_GPL(arizona_set_fll);
900
901int arizona_init_fll(struct arizona *arizona, int id, int base, int lock_irq,
902 int ok_irq, struct arizona_fll *fll)
903{
904 int ret;
905
906 init_completion(&fll->lock);
907 init_completion(&fll->ok);
908
909 fll->id = id;
910 fll->base = base;
911 fll->arizona = arizona;
912
913 snprintf(fll->lock_name, sizeof(fll->lock_name), "FLL%d lock", id);
914 snprintf(fll->clock_ok_name, sizeof(fll->clock_ok_name),
915 "FLL%d clock OK", id);
916
917 ret = arizona_request_irq(arizona, lock_irq, fll->lock_name,
918 arizona_fll_lock, fll);
919 if (ret != 0) {
920 dev_err(arizona->dev, "Failed to get FLL%d lock IRQ: %d\n",
921 id, ret);
922 }
923
924 ret = arizona_request_irq(arizona, ok_irq, fll->clock_ok_name,
925 arizona_fll_clock_ok, fll);
926 if (ret != 0) {
927 dev_err(arizona->dev, "Failed to get FLL%d clock OK IRQ: %d\n",
928 id, ret);
929 }
930
931 return 0;
932}
933EXPORT_SYMBOL_GPL(arizona_init_fll);
934
935MODULE_DESCRIPTION("ASoC Wolfson Arizona class device support");
936MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
937MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/arizona.h b/sound/soc/codecs/arizona.h
new file mode 100644
index 00000000000..59caca8865e
--- /dev/null
+++ b/sound/soc/codecs/arizona.h
@@ -0,0 +1,159 @@
1/*
2 * arizona.h - Wolfson Arizona class device shared support
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _ASOC_ARIZONA_H
14#define _ASOC_ARIZONA_H
15
16#include <linux/completion.h>
17
18#include <sound/soc.h>
19
20#define ARIZONA_CLK_SYSCLK 1
21#define ARIZONA_CLK_ASYNCCLK 2
22
23#define ARIZONA_CLK_SRC_MCLK1 0x0
24#define ARIZONA_CLK_SRC_MCLK2 0x1
25#define ARIZONA_CLK_SRC_FLL1 0x4
26#define ARIZONA_CLK_SRC_FLL2 0x5
27#define ARIZONA_CLK_SRC_AIF1BCLK 0x8
28#define ARIZONA_CLK_SRC_AIF2BCLK 0x9
29#define ARIZONA_CLK_SRC_AIF3BCLK 0xa
30
31#define ARIZONA_FLL_SRC_MCLK1 0
32#define ARIZONA_FLL_SRC_MCLK2 1
33#define ARIZONA_FLL_SRC_SLIMCLK 2
34#define ARIZONA_FLL_SRC_FLL1 3
35#define ARIZONA_FLL_SRC_FLL2 4
36#define ARIZONA_FLL_SRC_AIF1BCLK 5
37#define ARIZONA_FLL_SRC_AIF2BCLK 6
38#define ARIZONA_FLL_SRC_AIF3BCLK 7
39#define ARIZONA_FLL_SRC_AIF1LRCLK 8
40#define ARIZONA_FLL_SRC_AIF2LRCLK 9
41#define ARIZONA_FLL_SRC_AIF3LRCLK 10
42
43#define ARIZONA_MIXER_VOL_MASK 0x00FE
44#define ARIZONA_MIXER_VOL_SHIFT 1
45#define ARIZONA_MIXER_VOL_WIDTH 7
46
47#define ARIZONA_MAX_DAI 3
48
49struct arizona;
50
51struct arizona_dai_priv {
52 int clk;
53};
54
55struct arizona_priv {
56 struct arizona *arizona;
57 int sysclk;
58 int asyncclk;
59 struct arizona_dai_priv dai[ARIZONA_MAX_DAI];
60};
61
62#define ARIZONA_NUM_MIXER_INPUTS 57
63
64extern const unsigned int arizona_mixer_tlv[];
65extern const char *arizona_mixer_texts[ARIZONA_NUM_MIXER_INPUTS];
66extern int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
67
68#define ARIZONA_MIXER_CONTROLS(name, base) \
69 SOC_SINGLE_RANGE_TLV(name " Input 1 Volume", base + 1, \
70 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
71 arizona_mixer_tlv), \
72 SOC_SINGLE_RANGE_TLV(name " Input 2 Volume", base + 3, \
73 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
74 arizona_mixer_tlv), \
75 SOC_SINGLE_RANGE_TLV(name " Input 3 Volume", base + 5, \
76 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
77 arizona_mixer_tlv), \
78 SOC_SINGLE_RANGE_TLV(name " Input 4 Volume", base + 7, \
79 ARIZONA_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \
80 arizona_mixer_tlv)
81
82#define ARIZONA_MUX_ENUM_DECL(name, reg) \
83 SOC_VALUE_ENUM_SINGLE_DECL(name, reg, 0, 0xff, \
84 arizona_mixer_texts, arizona_mixer_values)
85
86#define ARIZONA_MUX_CTL_DECL(name) \
87 const struct snd_kcontrol_new name##_mux = \
88 SOC_DAPM_VALUE_ENUM("Route", name##_enum)
89
90#define ARIZONA_MIXER_ENUMS(name, base_reg) \
91 static ARIZONA_MUX_ENUM_DECL(name##_in1_enum, base_reg); \
92 static ARIZONA_MUX_ENUM_DECL(name##_in2_enum, base_reg + 2); \
93 static ARIZONA_MUX_ENUM_DECL(name##_in3_enum, base_reg + 4); \
94 static ARIZONA_MUX_ENUM_DECL(name##_in4_enum, base_reg + 6); \
95 static ARIZONA_MUX_CTL_DECL(name##_in1); \
96 static ARIZONA_MUX_CTL_DECL(name##_in2); \
97 static ARIZONA_MUX_CTL_DECL(name##_in3); \
98 static ARIZONA_MUX_CTL_DECL(name##_in4)
99
100#define ARIZONA_MUX(name, ctrl) \
101 SND_SOC_DAPM_VALUE_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)
102
103#define ARIZONA_MIXER_WIDGETS(name, name_str) \
104 ARIZONA_MUX(name_str " Input 1", &name##_in1_mux), \
105 ARIZONA_MUX(name_str " Input 2", &name##_in2_mux), \
106 ARIZONA_MUX(name_str " Input 3", &name##_in3_mux), \
107 ARIZONA_MUX(name_str " Input 4", &name##_in4_mux), \
108 SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)
109
110#define ARIZONA_MIXER_ROUTES(widget, name) \
111 { widget, NULL, name " Mixer" }, \
112 { name " Mixer", NULL, name " Input 1" }, \
113 { name " Mixer", NULL, name " Input 2" }, \
114 { name " Mixer", NULL, name " Input 3" }, \
115 { name " Mixer", NULL, name " Input 4" }, \
116 ARIZONA_MIXER_INPUT_ROUTES(name " Input 1"), \
117 ARIZONA_MIXER_INPUT_ROUTES(name " Input 2"), \
118 ARIZONA_MIXER_INPUT_ROUTES(name " Input 3"), \
119 ARIZONA_MIXER_INPUT_ROUTES(name " Input 4")
120
121extern const struct soc_enum arizona_lhpf1_mode;
122extern const struct soc_enum arizona_lhpf2_mode;
123extern const struct soc_enum arizona_lhpf3_mode;
124extern const struct soc_enum arizona_lhpf4_mode;
125
126extern int arizona_in_ev(struct snd_soc_dapm_widget *w,
127 struct snd_kcontrol *kcontrol,
128 int event);
129extern int arizona_out_ev(struct snd_soc_dapm_widget *w,
130 struct snd_kcontrol *kcontrol,
131 int event);
132
133extern int arizona_set_sysclk(struct snd_soc_codec *codec, int clk_id,
134 int source, unsigned int freq, int dir);
135
136extern const struct snd_soc_dai_ops arizona_dai_ops;
137
138#define ARIZONA_FLL_NAME_LEN 20
139
140struct arizona_fll {
141 struct arizona *arizona;
142 int id;
143 unsigned int base;
144 unsigned int vco_mult;
145 struct completion lock;
146 struct completion ok;
147
148 char lock_name[ARIZONA_FLL_NAME_LEN];
149 char clock_ok_name[ARIZONA_FLL_NAME_LEN];
150};
151
152extern int arizona_init_fll(struct arizona *arizona, int id, int base,
153 int lock_irq, int ok_irq, struct arizona_fll *fll);
154extern int arizona_set_fll(struct arizona_fll *fll, int source,
155 unsigned int Fref, unsigned int Fout);
156
157extern int arizona_init_dai(struct arizona_priv *priv, int dai);
158
159#endif
diff --git a/sound/soc/codecs/cs42l52.c b/sound/soc/codecs/cs42l52.c
index a7109413aef..628daf6a1d9 100644
--- a/sound/soc/codecs/cs42l52.c
+++ b/sound/soc/codecs/cs42l52.c
@@ -14,7 +14,6 @@
14 14
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/moduleparam.h> 16#include <linux/moduleparam.h>
17#include <linux/version.h>
18#include <linux/kernel.h> 17#include <linux/kernel.h>
19#include <linux/init.h> 18#include <linux/init.h>
20#include <linux/delay.h> 19#include <linux/delay.h>
@@ -1217,11 +1216,11 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1217 return -ENOMEM; 1216 return -ENOMEM;
1218 cs42l52->dev = &i2c_client->dev; 1217 cs42l52->dev = &i2c_client->dev;
1219 1218
1220 cs42l52->regmap = regmap_init_i2c(i2c_client, &cs42l52_regmap); 1219 cs42l52->regmap = devm_regmap_init_i2c(i2c_client, &cs42l52_regmap);
1221 if (IS_ERR(cs42l52->regmap)) { 1220 if (IS_ERR(cs42l52->regmap)) {
1222 ret = PTR_ERR(cs42l52->regmap); 1221 ret = PTR_ERR(cs42l52->regmap);
1223 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 1222 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1224 goto err; 1223 return ret;
1225 } 1224 }
1226 1225
1227 i2c_set_clientdata(i2c_client, cs42l52); 1226 i2c_set_clientdata(i2c_client, cs42l52);
@@ -1243,7 +1242,7 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1243 dev_err(&i2c_client->dev, 1242 dev_err(&i2c_client->dev,
1244 "CS42L52 Device ID (%X). Expected %X\n", 1243 "CS42L52 Device ID (%X). Expected %X\n",
1245 devid, CS42L52_CHIP_ID); 1244 devid, CS42L52_CHIP_ID);
1246 goto err_regmap; 1245 return ret;
1247 } 1246 }
1248 1247
1249 regcache_cache_only(cs42l52->regmap, true); 1248 regcache_cache_only(cs42l52->regmap, true);
@@ -1251,23 +1250,13 @@ static int cs42l52_i2c_probe(struct i2c_client *i2c_client,
1251 ret = snd_soc_register_codec(&i2c_client->dev, 1250 ret = snd_soc_register_codec(&i2c_client->dev,
1252 &soc_codec_dev_cs42l52, &cs42l52_dai, 1); 1251 &soc_codec_dev_cs42l52, &cs42l52_dai, 1);
1253 if (ret < 0) 1252 if (ret < 0)
1254 goto err_regmap; 1253 return ret;
1255 return 0; 1254 return 0;
1256
1257err_regmap:
1258 regmap_exit(cs42l52->regmap);
1259
1260err:
1261 return ret;
1262} 1255}
1263 1256
1264static int cs42l52_i2c_remove(struct i2c_client *client) 1257static int cs42l52_i2c_remove(struct i2c_client *client)
1265{ 1258{
1266 struct cs42l52_private *cs42l52 = i2c_get_clientdata(client);
1267
1268 snd_soc_unregister_codec(&client->dev); 1259 snd_soc_unregister_codec(&client->dev);
1269 regmap_exit(cs42l52->regmap);
1270
1271 return 0; 1260 return 0;
1272} 1261}
1273 1262
diff --git a/sound/soc/codecs/cs42l73.c b/sound/soc/codecs/cs42l73.c
index e0d45fdaa75..2c08c4cb465 100644
--- a/sound/soc/codecs/cs42l73.c
+++ b/sound/soc/codecs/cs42l73.c
@@ -1362,11 +1362,11 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
1362 1362
1363 i2c_set_clientdata(i2c_client, cs42l73); 1363 i2c_set_clientdata(i2c_client, cs42l73);
1364 1364
1365 cs42l73->regmap = regmap_init_i2c(i2c_client, &cs42l73_regmap); 1365 cs42l73->regmap = devm_regmap_init_i2c(i2c_client, &cs42l73_regmap);
1366 if (IS_ERR(cs42l73->regmap)) { 1366 if (IS_ERR(cs42l73->regmap)) {
1367 ret = PTR_ERR(cs42l73->regmap); 1367 ret = PTR_ERR(cs42l73->regmap);
1368 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret); 1368 dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);
1369 goto err; 1369 return ret;
1370 } 1370 }
1371 /* initialize codec */ 1371 /* initialize codec */
1372 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg); 1372 ret = regmap_read(cs42l73->regmap, CS42L73_DEVID_AB, &reg);
@@ -1384,13 +1384,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
1384 dev_err(&i2c_client->dev, 1384 dev_err(&i2c_client->dev,
1385 "CS42L73 Device ID (%X). Expected %X\n", 1385 "CS42L73 Device ID (%X). Expected %X\n",
1386 devid, CS42L73_DEVID); 1386 devid, CS42L73_DEVID);
1387 goto err_regmap; 1387 return ret;
1388 } 1388 }
1389 1389
1390 ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg); 1390 ret = regmap_read(cs42l73->regmap, CS42L73_REVID, &reg);
1391 if (ret < 0) { 1391 if (ret < 0) {
1392 dev_err(&i2c_client->dev, "Get Revision ID failed\n"); 1392 dev_err(&i2c_client->dev, "Get Revision ID failed\n");
1393 goto err_regmap; 1393 return ret;;
1394 } 1394 }
1395 1395
1396 dev_info(&i2c_client->dev, 1396 dev_info(&i2c_client->dev,
@@ -1402,23 +1402,13 @@ static __devinit int cs42l73_i2c_probe(struct i2c_client *i2c_client,
1402 &soc_codec_dev_cs42l73, cs42l73_dai, 1402 &soc_codec_dev_cs42l73, cs42l73_dai,
1403 ARRAY_SIZE(cs42l73_dai)); 1403 ARRAY_SIZE(cs42l73_dai));
1404 if (ret < 0) 1404 if (ret < 0)
1405 goto err_regmap; 1405 return ret;
1406 return 0; 1406 return 0;
1407
1408err_regmap:
1409 regmap_exit(cs42l73->regmap);
1410
1411err:
1412 return ret;
1413} 1407}
1414 1408
1415static __devexit int cs42l73_i2c_remove(struct i2c_client *client) 1409static __devexit int cs42l73_i2c_remove(struct i2c_client *client)
1416{ 1410{
1417 struct cs42l73_private *cs42l73 = i2c_get_clientdata(client);
1418
1419 snd_soc_unregister_codec(&client->dev); 1411 snd_soc_unregister_codec(&client->dev);
1420 regmap_exit(cs42l73->regmap);
1421
1422 return 0; 1412 return 0;
1423} 1413}
1424 1414
diff --git a/sound/soc/codecs/da732x.c b/sound/soc/codecs/da732x.c
new file mode 100644
index 00000000000..01be2a320e2
--- /dev/null
+++ b/sound/soc/codecs/da732x.c
@@ -0,0 +1,1627 @@
1/*
2 * da732x.c --- Dialog DA732X ALSA SoC Audio Driver
3 *
4 * Copyright (C) 2012 Dialog Semiconductor GmbH
5 *
6 * Author: Michal Hajduk <Michal.Hajduk@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/i2c.h>
19#include <linux/regmap.h>
20#include <linux/platform_device.h>
21#include <linux/slab.h>
22#include <linux/sysfs.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/soc-dapm.h>
28#include <sound/initval.h>
29#include <sound/tlv.h>
30#include <asm/div64.h>
31
32#include "da732x.h"
33#include "da732x_reg.h"
34
35
36struct da732x_priv {
37 struct regmap *regmap;
38 struct snd_soc_codec *codec;
39
40 unsigned int sysclk;
41 bool pll_en;
42};
43
44/*
45 * da732x register cache - default settings
46 */
47static struct reg_default da732x_reg_cache[] = {
48 { DA732X_REG_REF1 , 0x02 },
49 { DA732X_REG_BIAS_EN , 0x80 },
50 { DA732X_REG_BIAS1 , 0x00 },
51 { DA732X_REG_BIAS2 , 0x00 },
52 { DA732X_REG_BIAS3 , 0x00 },
53 { DA732X_REG_BIAS4 , 0x00 },
54 { DA732X_REG_MICBIAS2 , 0x00 },
55 { DA732X_REG_MICBIAS1 , 0x00 },
56 { DA732X_REG_MICDET , 0x00 },
57 { DA732X_REG_MIC1_PRE , 0x01 },
58 { DA732X_REG_MIC1 , 0x40 },
59 { DA732X_REG_MIC2_PRE , 0x01 },
60 { DA732X_REG_MIC2 , 0x40 },
61 { DA732X_REG_AUX1L , 0x75 },
62 { DA732X_REG_AUX1R , 0x75 },
63 { DA732X_REG_MIC3_PRE , 0x01 },
64 { DA732X_REG_MIC3 , 0x40 },
65 { DA732X_REG_INP_PINBIAS , 0x00 },
66 { DA732X_REG_INP_ZC_EN , 0x00 },
67 { DA732X_REG_INP_MUX , 0x50 },
68 { DA732X_REG_HP_DET , 0x00 },
69 { DA732X_REG_HPL_DAC_OFFSET , 0x00 },
70 { DA732X_REG_HPL_DAC_OFF_CNTL , 0x00 },
71 { DA732X_REG_HPL_OUT_OFFSET , 0x00 },
72 { DA732X_REG_HPL , 0x40 },
73 { DA732X_REG_HPL_VOL , 0x0F },
74 { DA732X_REG_HPR_DAC_OFFSET , 0x00 },
75 { DA732X_REG_HPR_DAC_OFF_CNTL , 0x00 },
76 { DA732X_REG_HPR_OUT_OFFSET , 0x00 },
77 { DA732X_REG_HPR , 0x40 },
78 { DA732X_REG_HPR_VOL , 0x0F },
79 { DA732X_REG_LIN2 , 0x4F },
80 { DA732X_REG_LIN3 , 0x4F },
81 { DA732X_REG_LIN4 , 0x4F },
82 { DA732X_REG_OUT_ZC_EN , 0x00 },
83 { DA732X_REG_HP_LIN1_GNDSEL , 0x00 },
84 { DA732X_REG_CP_HP1 , 0x0C },
85 { DA732X_REG_CP_HP2 , 0x03 },
86 { DA732X_REG_CP_CTRL1 , 0x00 },
87 { DA732X_REG_CP_CTRL2 , 0x99 },
88 { DA732X_REG_CP_CTRL3 , 0x25 },
89 { DA732X_REG_CP_LEVEL_MASK , 0x3F },
90 { DA732X_REG_CP_DET , 0x00 },
91 { DA732X_REG_CP_STATUS , 0x00 },
92 { DA732X_REG_CP_THRESH1 , 0x00 },
93 { DA732X_REG_CP_THRESH2 , 0x00 },
94 { DA732X_REG_CP_THRESH3 , 0x00 },
95 { DA732X_REG_CP_THRESH4 , 0x00 },
96 { DA732X_REG_CP_THRESH5 , 0x00 },
97 { DA732X_REG_CP_THRESH6 , 0x00 },
98 { DA732X_REG_CP_THRESH7 , 0x00 },
99 { DA732X_REG_CP_THRESH8 , 0x00 },
100 { DA732X_REG_PLL_DIV_LO , 0x00 },
101 { DA732X_REG_PLL_DIV_MID , 0x00 },
102 { DA732X_REG_PLL_DIV_HI , 0x00 },
103 { DA732X_REG_PLL_CTRL , 0x02 },
104 { DA732X_REG_CLK_CTRL , 0xaa },
105 { DA732X_REG_CLK_DSP , 0x07 },
106 { DA732X_REG_CLK_EN1 , 0x00 },
107 { DA732X_REG_CLK_EN2 , 0x00 },
108 { DA732X_REG_CLK_EN3 , 0x00 },
109 { DA732X_REG_CLK_EN4 , 0x00 },
110 { DA732X_REG_CLK_EN5 , 0x00 },
111 { DA732X_REG_AIF_MCLK , 0x00 },
112 { DA732X_REG_AIFA1 , 0x02 },
113 { DA732X_REG_AIFA2 , 0x00 },
114 { DA732X_REG_AIFA3 , 0x08 },
115 { DA732X_REG_AIFB1 , 0x02 },
116 { DA732X_REG_AIFB2 , 0x00 },
117 { DA732X_REG_AIFB3 , 0x08 },
118 { DA732X_REG_PC_CTRL , 0xC0 },
119 { DA732X_REG_DATA_ROUTE , 0x00 },
120 { DA732X_REG_DSP_CTRL , 0x00 },
121 { DA732X_REG_CIF_CTRL2 , 0x00 },
122 { DA732X_REG_HANDSHAKE , 0x00 },
123 { DA732X_REG_SPARE1_OUT , 0x00 },
124 { DA732X_REG_SPARE2_OUT , 0x00 },
125 { DA732X_REG_SPARE1_IN , 0x00 },
126 { DA732X_REG_ADC1_PD , 0x00 },
127 { DA732X_REG_ADC1_HPF , 0x00 },
128 { DA732X_REG_ADC1_SEL , 0x00 },
129 { DA732X_REG_ADC1_EQ12 , 0x00 },
130 { DA732X_REG_ADC1_EQ34 , 0x00 },
131 { DA732X_REG_ADC1_EQ5 , 0x00 },
132 { DA732X_REG_ADC2_PD , 0x00 },
133 { DA732X_REG_ADC2_HPF , 0x00 },
134 { DA732X_REG_ADC2_SEL , 0x00 },
135 { DA732X_REG_ADC2_EQ12 , 0x00 },
136 { DA732X_REG_ADC2_EQ34 , 0x00 },
137 { DA732X_REG_ADC2_EQ5 , 0x00 },
138 { DA732X_REG_DAC1_HPF , 0x00 },
139 { DA732X_REG_DAC1_L_VOL , 0x00 },
140 { DA732X_REG_DAC1_R_VOL , 0x00 },
141 { DA732X_REG_DAC1_SEL , 0x00 },
142 { DA732X_REG_DAC1_SOFTMUTE , 0x00 },
143 { DA732X_REG_DAC1_EQ12 , 0x00 },
144 { DA732X_REG_DAC1_EQ34 , 0x00 },
145 { DA732X_REG_DAC1_EQ5 , 0x00 },
146 { DA732X_REG_DAC2_HPF , 0x00 },
147 { DA732X_REG_DAC2_L_VOL , 0x00 },
148 { DA732X_REG_DAC2_R_VOL , 0x00 },
149 { DA732X_REG_DAC2_SEL , 0x00 },
150 { DA732X_REG_DAC2_SOFTMUTE , 0x00 },
151 { DA732X_REG_DAC2_EQ12 , 0x00 },
152 { DA732X_REG_DAC2_EQ34 , 0x00 },
153 { DA732X_REG_DAC2_EQ5 , 0x00 },
154 { DA732X_REG_DAC3_HPF , 0x00 },
155 { DA732X_REG_DAC3_VOL , 0x00 },
156 { DA732X_REG_DAC3_SEL , 0x00 },
157 { DA732X_REG_DAC3_SOFTMUTE , 0x00 },
158 { DA732X_REG_DAC3_EQ12 , 0x00 },
159 { DA732X_REG_DAC3_EQ34 , 0x00 },
160 { DA732X_REG_DAC3_EQ5 , 0x00 },
161 { DA732X_REG_BIQ_BYP , 0x00 },
162 { DA732X_REG_DMA_CMD , 0x00 },
163 { DA732X_REG_DMA_ADDR0 , 0x00 },
164 { DA732X_REG_DMA_ADDR1 , 0x00 },
165 { DA732X_REG_DMA_DATA0 , 0x00 },
166 { DA732X_REG_DMA_DATA1 , 0x00 },
167 { DA732X_REG_DMA_DATA2 , 0x00 },
168 { DA732X_REG_DMA_DATA3 , 0x00 },
169 { DA732X_REG_UNLOCK , 0x00 },
170};
171
172static inline int da732x_get_input_div(struct snd_soc_codec *codec, int sysclk)
173{
174 int val;
175 int ret;
176
177 if (sysclk < DA732X_MCLK_10MHZ) {
178 val = DA732X_MCLK_RET_0_10MHZ;
179 ret = DA732X_MCLK_VAL_0_10MHZ;
180 } else if ((sysclk >= DA732X_MCLK_10MHZ) &&
181 (sysclk < DA732X_MCLK_20MHZ)) {
182 val = DA732X_MCLK_RET_10_20MHZ;
183 ret = DA732X_MCLK_VAL_10_20MHZ;
184 } else if ((sysclk >= DA732X_MCLK_20MHZ) &&
185 (sysclk < DA732X_MCLK_40MHZ)) {
186 val = DA732X_MCLK_RET_20_40MHZ;
187 ret = DA732X_MCLK_VAL_20_40MHZ;
188 } else if ((sysclk >= DA732X_MCLK_40MHZ) &&
189 (sysclk <= DA732X_MCLK_54MHZ)) {
190 val = DA732X_MCLK_RET_40_54MHZ;
191 ret = DA732X_MCLK_VAL_40_54MHZ;
192 } else {
193 return -EINVAL;
194 }
195
196 snd_soc_write(codec, DA732X_REG_PLL_CTRL, val);
197
198 return ret;
199}
200
201static void da732x_set_charge_pump(struct snd_soc_codec *codec, int state)
202{
203 switch (state) {
204 case DA732X_ENABLE_CP:
205 snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_EN);
206 snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_EN |
207 DA732X_HP_CP_REG | DA732X_HP_CP_PULSESKIP);
208 snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA732X_CP_EN |
209 DA732X_CP_CTRL_CPVDD1);
210 snd_soc_write(codec, DA732X_REG_CP_CTRL2,
211 DA732X_CP_MANAGE_MAGNITUDE | DA732X_CP_BOOST);
212 snd_soc_write(codec, DA732X_REG_CP_CTRL3, DA732X_CP_1MHZ);
213 break;
214 case DA732X_DISABLE_CP:
215 snd_soc_write(codec, DA732X_REG_CLK_EN2, DA732X_CP_CLK_DIS);
216 snd_soc_write(codec, DA732X_REG_CP_HP2, DA732X_HP_CP_DIS);
217 snd_soc_write(codec, DA732X_REG_CP_CTRL1, DA723X_CP_DIS);
218 break;
219 default:
220 pr_err(KERN_ERR "Wrong charge pump state\n");
221 break;
222 }
223}
224
225static const DECLARE_TLV_DB_SCALE(mic_boost_tlv, DA732X_MIC_PRE_VOL_DB_MIN,
226 DA732X_MIC_PRE_VOL_DB_INC, 0);
227
228static const DECLARE_TLV_DB_SCALE(mic_pga_tlv, DA732X_MIC_VOL_DB_MIN,
229 DA732X_MIC_VOL_DB_INC, 0);
230
231static const DECLARE_TLV_DB_SCALE(aux_pga_tlv, DA732X_AUX_VOL_DB_MIN,
232 DA732X_AUX_VOL_DB_INC, 0);
233
234static const DECLARE_TLV_DB_SCALE(hp_pga_tlv, DA732X_HP_VOL_DB_MIN,
235 DA732X_AUX_VOL_DB_INC, 0);
236
237static const DECLARE_TLV_DB_SCALE(lin2_pga_tlv, DA732X_LIN2_VOL_DB_MIN,
238 DA732X_LIN2_VOL_DB_INC, 0);
239
240static const DECLARE_TLV_DB_SCALE(lin3_pga_tlv, DA732X_LIN3_VOL_DB_MIN,
241 DA732X_LIN3_VOL_DB_INC, 0);
242
243static const DECLARE_TLV_DB_SCALE(lin4_pga_tlv, DA732X_LIN4_VOL_DB_MIN,
244 DA732X_LIN4_VOL_DB_INC, 0);
245
246static const DECLARE_TLV_DB_SCALE(adc_pga_tlv, DA732X_ADC_VOL_DB_MIN,
247 DA732X_ADC_VOL_DB_INC, 0);
248
249static const DECLARE_TLV_DB_SCALE(dac_pga_tlv, DA732X_DAC_VOL_DB_MIN,
250 DA732X_DAC_VOL_DB_INC, 0);
251
252static const DECLARE_TLV_DB_SCALE(eq_band_pga_tlv, DA732X_EQ_BAND_VOL_DB_MIN,
253 DA732X_EQ_BAND_VOL_DB_INC, 0);
254
255static const DECLARE_TLV_DB_SCALE(eq_overall_tlv, DA732X_EQ_OVERALL_VOL_DB_MIN,
256 DA732X_EQ_OVERALL_VOL_DB_INC, 0);
257
258/* High Pass Filter */
259static const char *da732x_hpf_mode[] = {
260 "Disable", "Music", "Voice",
261};
262
263static const char *da732x_hpf_music[] = {
264 "1.8Hz", "3.75Hz", "7.5Hz", "15Hz",
265};
266
267static const char *da732x_hpf_voice[] = {
268 "2.5Hz", "25Hz", "50Hz", "100Hz",
269 "150Hz", "200Hz", "300Hz", "400Hz"
270};
271
272static const struct soc_enum da732x_dac1_hpf_mode_enum[] = {
273 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MODE_SHIFT,
274 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
275};
276
277static const struct soc_enum da732x_dac2_hpf_mode_enum[] = {
278 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MODE_SHIFT,
279 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
280};
281
282static const struct soc_enum da732x_dac3_hpf_mode_enum[] = {
283 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MODE_SHIFT,
284 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
285};
286
287static const struct soc_enum da732x_adc1_hpf_mode_enum[] = {
288 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MODE_SHIFT,
289 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
290};
291
292static const struct soc_enum da732x_adc2_hpf_mode_enum[] = {
293 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MODE_SHIFT,
294 DA732X_HPF_MODE_MAX, da732x_hpf_mode)
295};
296
297static const struct soc_enum da732x_dac1_hp_filter_enum[] = {
298 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_MUSIC_SHIFT,
299 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
300};
301
302static const struct soc_enum da732x_dac2_hp_filter_enum[] = {
303 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_MUSIC_SHIFT,
304 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
305};
306
307static const struct soc_enum da732x_dac3_hp_filter_enum[] = {
308 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_MUSIC_SHIFT,
309 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
310};
311
312static const struct soc_enum da732x_adc1_hp_filter_enum[] = {
313 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_MUSIC_SHIFT,
314 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
315};
316
317static const struct soc_enum da732x_adc2_hp_filter_enum[] = {
318 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_MUSIC_SHIFT,
319 DA732X_HPF_MUSIC_MAX, da732x_hpf_music)
320};
321
322static const struct soc_enum da732x_dac1_voice_filter_enum[] = {
323 SOC_ENUM_SINGLE(DA732X_REG_DAC1_HPF, DA732X_HPF_VOICE_SHIFT,
324 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
325};
326
327static const struct soc_enum da732x_dac2_voice_filter_enum[] = {
328 SOC_ENUM_SINGLE(DA732X_REG_DAC2_HPF, DA732X_HPF_VOICE_SHIFT,
329 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
330};
331
332static const struct soc_enum da732x_dac3_voice_filter_enum[] = {
333 SOC_ENUM_SINGLE(DA732X_REG_DAC3_HPF, DA732X_HPF_VOICE_SHIFT,
334 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
335};
336
337static const struct soc_enum da732x_adc1_voice_filter_enum[] = {
338 SOC_ENUM_SINGLE(DA732X_REG_ADC1_HPF, DA732X_HPF_VOICE_SHIFT,
339 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
340};
341
342static const struct soc_enum da732x_adc2_voice_filter_enum[] = {
343 SOC_ENUM_SINGLE(DA732X_REG_ADC2_HPF, DA732X_HPF_VOICE_SHIFT,
344 DA732X_HPF_VOICE_MAX, da732x_hpf_voice)
345};
346
347
348static int da732x_hpf_set(struct snd_kcontrol *kcontrol,
349 struct snd_ctl_elem_value *ucontrol)
350{
351 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
352 struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
353 unsigned int reg = enum_ctrl->reg;
354 unsigned int sel = ucontrol->value.integer.value[0];
355 unsigned int bits;
356
357 switch (sel) {
358 case DA732X_HPF_DISABLED:
359 bits = DA732X_HPF_DIS;
360 break;
361 case DA732X_HPF_VOICE:
362 bits = DA732X_HPF_VOICE_EN;
363 break;
364 case DA732X_HPF_MUSIC:
365 bits = DA732X_HPF_MUSIC_EN;
366 break;
367 default:
368 return -EINVAL;
369 }
370
371 snd_soc_update_bits(codec, reg, DA732X_HPF_MASK, bits);
372
373 return 0;
374}
375
376static int da732x_hpf_get(struct snd_kcontrol *kcontrol,
377 struct snd_ctl_elem_value *ucontrol)
378{
379 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
380 struct soc_enum *enum_ctrl = (struct soc_enum *)kcontrol->private_value;
381 unsigned int reg = enum_ctrl->reg;
382 int val;
383
384 val = snd_soc_read(codec, reg) & DA732X_HPF_MASK;
385
386 switch (val) {
387 case DA732X_HPF_VOICE_EN:
388 ucontrol->value.integer.value[0] = DA732X_HPF_VOICE;
389 break;
390 case DA732X_HPF_MUSIC_EN:
391 ucontrol->value.integer.value[0] = DA732X_HPF_MUSIC;
392 break;
393 default:
394 ucontrol->value.integer.value[0] = DA732X_HPF_DISABLED;
395 break;
396 }
397
398 return 0;
399}
400
401static const struct snd_kcontrol_new da732x_snd_controls[] = {
402 /* Input PGAs */
403 SOC_SINGLE_RANGE_TLV("MIC1 Boost Volume", DA732X_REG_MIC1_PRE,
404 DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
405 DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
406 SOC_SINGLE_RANGE_TLV("MIC2 Boost Volume", DA732X_REG_MIC2_PRE,
407 DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
408 DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
409 SOC_SINGLE_RANGE_TLV("MIC3 Boost Volume", DA732X_REG_MIC3_PRE,
410 DA732X_MICBOOST_SHIFT, DA732X_MICBOOST_MIN,
411 DA732X_MICBOOST_MAX, 0, mic_boost_tlv),
412
413 /* MICs */
414 SOC_SINGLE("MIC1 Switch", DA732X_REG_MIC1, DA732X_MIC_MUTE_SHIFT,
415 DA732X_SWITCH_MAX, DA732X_INVERT),
416 SOC_SINGLE_RANGE_TLV("MIC1 Volume", DA732X_REG_MIC1,
417 DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
418 DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
419 SOC_SINGLE("MIC2 Switch", DA732X_REG_MIC2, DA732X_MIC_MUTE_SHIFT,
420 DA732X_SWITCH_MAX, DA732X_INVERT),
421 SOC_SINGLE_RANGE_TLV("MIC2 Volume", DA732X_REG_MIC2,
422 DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
423 DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
424 SOC_SINGLE("MIC3 Switch", DA732X_REG_MIC3, DA732X_MIC_MUTE_SHIFT,
425 DA732X_SWITCH_MAX, DA732X_INVERT),
426 SOC_SINGLE_RANGE_TLV("MIC3 Volume", DA732X_REG_MIC3,
427 DA732X_MIC_VOL_SHIFT, DA732X_MIC_VOL_VAL_MIN,
428 DA732X_MIC_VOL_VAL_MAX, 0, mic_pga_tlv),
429
430 /* AUXs */
431 SOC_SINGLE("AUX1L Switch", DA732X_REG_AUX1L, DA732X_AUX_MUTE_SHIFT,
432 DA732X_SWITCH_MAX, DA732X_INVERT),
433 SOC_SINGLE_TLV("AUX1L Volume", DA732X_REG_AUX1L,
434 DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX,
435 DA732X_NO_INVERT, aux_pga_tlv),
436 SOC_SINGLE("AUX1R Switch", DA732X_REG_AUX1R, DA732X_AUX_MUTE_SHIFT,
437 DA732X_SWITCH_MAX, DA732X_INVERT),
438 SOC_SINGLE_TLV("AUX1R Volume", DA732X_REG_AUX1R,
439 DA732X_AUX_VOL_SHIFT, DA732X_AUX_VOL_VAL_MAX,
440 DA732X_NO_INVERT, aux_pga_tlv),
441
442 /* ADCs */
443 SOC_DOUBLE_TLV("ADC1 Volume", DA732X_REG_ADC1_SEL,
444 DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT,
445 DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv),
446
447 SOC_DOUBLE_TLV("ADC2 Volume", DA732X_REG_ADC2_SEL,
448 DA732X_ADCL_VOL_SHIFT, DA732X_ADCR_VOL_SHIFT,
449 DA732X_ADC_VOL_VAL_MAX, DA732X_INVERT, adc_pga_tlv),
450
451 /* DACs */
452 SOC_DOUBLE("Digital Playback DAC12 Switch", DA732X_REG_DAC1_SEL,
453 DA732X_DACL_MUTE_SHIFT, DA732X_DACR_MUTE_SHIFT,
454 DA732X_SWITCH_MAX, DA732X_INVERT),
455 SOC_DOUBLE_R_TLV("Digital Playback DAC12 Volume", DA732X_REG_DAC1_L_VOL,
456 DA732X_REG_DAC1_R_VOL, DA732X_DAC_VOL_SHIFT,
457 DA732X_DAC_VOL_VAL_MAX, DA732X_INVERT, dac_pga_tlv),
458 SOC_SINGLE("Digital Playback DAC3 Switch", DA732X_REG_DAC2_SEL,
459 DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
460 SOC_SINGLE_TLV("Digital Playback DAC3 Volume", DA732X_REG_DAC2_L_VOL,
461 DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
462 DA732X_INVERT, dac_pga_tlv),
463 SOC_SINGLE("Digital Playback DAC4 Switch", DA732X_REG_DAC2_SEL,
464 DA732X_DACR_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
465 SOC_SINGLE_TLV("Digital Playback DAC4 Volume", DA732X_REG_DAC2_R_VOL,
466 DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
467 DA732X_INVERT, dac_pga_tlv),
468 SOC_SINGLE("Digital Playback DAC5 Switch", DA732X_REG_DAC3_SEL,
469 DA732X_DACL_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
470 SOC_SINGLE_TLV("Digital Playback DAC5 Volume", DA732X_REG_DAC3_VOL,
471 DA732X_DAC_VOL_SHIFT, DA732X_DAC_VOL_VAL_MAX,
472 DA732X_INVERT, dac_pga_tlv),
473
474 /* High Pass Filters */
475 SOC_ENUM_EXT("DAC1 High Pass Filter Mode",
476 da732x_dac1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
477 SOC_ENUM("DAC1 High Pass Filter", da732x_dac1_hp_filter_enum),
478 SOC_ENUM("DAC1 Voice Filter", da732x_dac1_voice_filter_enum),
479
480 SOC_ENUM_EXT("DAC2 High Pass Filter Mode",
481 da732x_dac2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
482 SOC_ENUM("DAC2 High Pass Filter", da732x_dac2_hp_filter_enum),
483 SOC_ENUM("DAC2 Voice Filter", da732x_dac2_voice_filter_enum),
484
485 SOC_ENUM_EXT("DAC3 High Pass Filter Mode",
486 da732x_dac3_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
487 SOC_ENUM("DAC3 High Pass Filter", da732x_dac3_hp_filter_enum),
488 SOC_ENUM("DAC3 Filter Mode", da732x_dac3_voice_filter_enum),
489
490 SOC_ENUM_EXT("ADC1 High Pass Filter Mode",
491 da732x_adc1_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
492 SOC_ENUM("ADC1 High Pass Filter", da732x_adc1_hp_filter_enum),
493 SOC_ENUM("ADC1 Voice Filter", da732x_adc1_voice_filter_enum),
494
495 SOC_ENUM_EXT("ADC2 High Pass Filter Mode",
496 da732x_adc2_hpf_mode_enum, da732x_hpf_get, da732x_hpf_set),
497 SOC_ENUM("ADC2 High Pass Filter", da732x_adc2_hp_filter_enum),
498 SOC_ENUM("ADC2 Voice Filter", da732x_adc2_voice_filter_enum),
499
500 /* Equalizers */
501 SOC_SINGLE("ADC1 EQ Switch", DA732X_REG_ADC1_EQ5,
502 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
503 SOC_SINGLE_TLV("ADC1 EQ Band 1 Volume", DA732X_REG_ADC1_EQ12,
504 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
505 DA732X_INVERT, eq_band_pga_tlv),
506 SOC_SINGLE_TLV("ADC1 EQ Band 2 Volume", DA732X_REG_ADC1_EQ12,
507 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
508 DA732X_INVERT, eq_band_pga_tlv),
509 SOC_SINGLE_TLV("ADC1 EQ Band 3 Volume", DA732X_REG_ADC1_EQ34,
510 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
511 DA732X_INVERT, eq_band_pga_tlv),
512 SOC_SINGLE_TLV("ADC1 EQ Band 4 Volume", DA732X_REG_ADC1_EQ34,
513 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
514 DA732X_INVERT, eq_band_pga_tlv),
515 SOC_SINGLE_TLV("ADC1 EQ Band 5 Volume", DA732X_REG_ADC1_EQ5,
516 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
517 DA732X_INVERT, eq_band_pga_tlv),
518 SOC_SINGLE_TLV("ADC1 EQ Overall Volume", DA732X_REG_ADC1_EQ5,
519 DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX,
520 DA732X_INVERT, eq_overall_tlv),
521
522 SOC_SINGLE("ADC2 EQ Switch", DA732X_REG_ADC2_EQ5,
523 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
524 SOC_SINGLE_TLV("ADC2 EQ Band 1 Volume", DA732X_REG_ADC2_EQ12,
525 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
526 DA732X_INVERT, eq_band_pga_tlv),
527 SOC_SINGLE_TLV("ADC2 EQ Band 2 Volume", DA732X_REG_ADC2_EQ12,
528 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
529 DA732X_INVERT, eq_band_pga_tlv),
530 SOC_SINGLE_TLV("ADC2 EQ Band 3 Volume", DA732X_REG_ADC2_EQ34,
531 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
532 DA732X_INVERT, eq_band_pga_tlv),
533 SOC_SINGLE_TLV("ACD2 EQ Band 4 Volume", DA732X_REG_ADC2_EQ34,
534 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
535 DA732X_INVERT, eq_band_pga_tlv),
536 SOC_SINGLE_TLV("ACD2 EQ Band 5 Volume", DA732X_REG_ADC2_EQ5,
537 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
538 DA732X_INVERT, eq_band_pga_tlv),
539 SOC_SINGLE_TLV("ADC2 EQ Overall Volume", DA732X_REG_ADC1_EQ5,
540 DA732X_EQ_OVERALL_SHIFT, DA732X_EQ_OVERALL_VOL_VAL_MAX,
541 DA732X_INVERT, eq_overall_tlv),
542
543 SOC_SINGLE("DAC1 EQ Switch", DA732X_REG_DAC1_EQ5,
544 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
545 SOC_SINGLE_TLV("DAC1 EQ Band 1 Volume", DA732X_REG_DAC1_EQ12,
546 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
547 DA732X_INVERT, eq_band_pga_tlv),
548 SOC_SINGLE_TLV("DAC1 EQ Band 2 Volume", DA732X_REG_DAC1_EQ12,
549 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
550 DA732X_INVERT, eq_band_pga_tlv),
551 SOC_SINGLE_TLV("DAC1 EQ Band 3 Volume", DA732X_REG_DAC1_EQ34,
552 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
553 DA732X_INVERT, eq_band_pga_tlv),
554 SOC_SINGLE_TLV("DAC1 EQ Band 4 Volume", DA732X_REG_DAC1_EQ34,
555 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
556 DA732X_INVERT, eq_band_pga_tlv),
557 SOC_SINGLE_TLV("DAC1 EQ Band 5 Volume", DA732X_REG_DAC1_EQ5,
558 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
559 DA732X_INVERT, eq_band_pga_tlv),
560
561 SOC_SINGLE("DAC2 EQ Switch", DA732X_REG_DAC2_EQ5,
562 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
563 SOC_SINGLE_TLV("DAC2 EQ Band 1 Volume", DA732X_REG_DAC2_EQ12,
564 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
565 DA732X_INVERT, eq_band_pga_tlv),
566 SOC_SINGLE_TLV("DAC2 EQ Band 2 Volume", DA732X_REG_DAC2_EQ12,
567 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
568 DA732X_INVERT, eq_band_pga_tlv),
569 SOC_SINGLE_TLV("DAC2 EQ Band 3 Volume", DA732X_REG_DAC2_EQ34,
570 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
571 DA732X_INVERT, eq_band_pga_tlv),
572 SOC_SINGLE_TLV("DAC2 EQ Band 4 Volume", DA732X_REG_DAC2_EQ34,
573 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
574 DA732X_INVERT, eq_band_pga_tlv),
575 SOC_SINGLE_TLV("DAC2 EQ Band 5 Volume", DA732X_REG_DAC2_EQ5,
576 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
577 DA732X_INVERT, eq_band_pga_tlv),
578
579 SOC_SINGLE("DAC3 EQ Switch", DA732X_REG_DAC3_EQ5,
580 DA732X_EQ_EN_SHIFT, DA732X_EQ_EN_MAX, DA732X_NO_INVERT),
581 SOC_SINGLE_TLV("DAC3 EQ Band 1 Volume", DA732X_REG_DAC3_EQ12,
582 DA732X_EQ_BAND1_SHIFT, DA732X_EQ_VOL_VAL_MAX,
583 DA732X_INVERT, eq_band_pga_tlv),
584 SOC_SINGLE_TLV("DAC3 EQ Band 2 Volume", DA732X_REG_DAC3_EQ12,
585 DA732X_EQ_BAND2_SHIFT, DA732X_EQ_VOL_VAL_MAX,
586 DA732X_INVERT, eq_band_pga_tlv),
587 SOC_SINGLE_TLV("DAC3 EQ Band 3 Volume", DA732X_REG_DAC3_EQ34,
588 DA732X_EQ_BAND3_SHIFT, DA732X_EQ_VOL_VAL_MAX,
589 DA732X_INVERT, eq_band_pga_tlv),
590 SOC_SINGLE_TLV("DAC3 EQ Band 4 Volume", DA732X_REG_DAC3_EQ34,
591 DA732X_EQ_BAND4_SHIFT, DA732X_EQ_VOL_VAL_MAX,
592 DA732X_INVERT, eq_band_pga_tlv),
593 SOC_SINGLE_TLV("DAC3 EQ Band 5 Volume", DA732X_REG_DAC3_EQ5,
594 DA732X_EQ_BAND5_SHIFT, DA732X_EQ_VOL_VAL_MAX,
595 DA732X_INVERT, eq_band_pga_tlv),
596
597 /* Lineout 2 Reciever*/
598 SOC_SINGLE("Lineout 2 Switch", DA732X_REG_LIN2, DA732X_LOUT_MUTE_SHIFT,
599 DA732X_SWITCH_MAX, DA732X_INVERT),
600 SOC_SINGLE_TLV("Lineout 2 Volume", DA732X_REG_LIN2,
601 DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
602 DA732X_NO_INVERT, lin2_pga_tlv),
603
604 /* Lineout 3 SPEAKER*/
605 SOC_SINGLE("Lineout 3 Switch", DA732X_REG_LIN3, DA732X_LOUT_MUTE_SHIFT,
606 DA732X_SWITCH_MAX, DA732X_INVERT),
607 SOC_SINGLE_TLV("Lineout 3 Volume", DA732X_REG_LIN3,
608 DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
609 DA732X_NO_INVERT, lin3_pga_tlv),
610
611 /* Lineout 4 */
612 SOC_SINGLE("Lineout 4 Switch", DA732X_REG_LIN4, DA732X_LOUT_MUTE_SHIFT,
613 DA732X_SWITCH_MAX, DA732X_INVERT),
614 SOC_SINGLE_TLV("Lineout 4 Volume", DA732X_REG_LIN4,
615 DA732X_LOUT_VOL_SHIFT, DA732X_LOUT_VOL_VAL_MAX,
616 DA732X_NO_INVERT, lin4_pga_tlv),
617
618 /* Headphones */
619 SOC_DOUBLE_R("Headphone Switch", DA732X_REG_HPR, DA732X_REG_HPL,
620 DA732X_HP_MUTE_SHIFT, DA732X_SWITCH_MAX, DA732X_INVERT),
621 SOC_DOUBLE_R_TLV("Headphone Volume", DA732X_REG_HPL_VOL,
622 DA732X_REG_HPR_VOL, DA732X_HP_VOL_SHIFT,
623 DA732X_HP_VOL_VAL_MAX, DA732X_NO_INVERT, hp_pga_tlv),
624};
625
626static int da732x_adc_event(struct snd_soc_dapm_widget *w,
627 struct snd_kcontrol *kcontrol, int event)
628{
629 struct snd_soc_codec *codec = w->codec;
630
631 switch (event) {
632 case SND_SOC_DAPM_POST_PMU:
633 switch (w->reg) {
634 case DA732X_REG_ADC1_PD:
635 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
636 DA732X_ADCA_BB_CLK_EN,
637 DA732X_ADCA_BB_CLK_EN);
638 break;
639 case DA732X_REG_ADC2_PD:
640 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
641 DA732X_ADCC_BB_CLK_EN,
642 DA732X_ADCC_BB_CLK_EN);
643 break;
644 default:
645 return -EINVAL;
646 }
647
648 snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
649 DA732X_ADC_SET_ACT);
650 snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
651 DA732X_ADC_ON);
652 break;
653 case SND_SOC_DAPM_POST_PMD:
654 snd_soc_update_bits(codec, w->reg, DA732X_ADC_PD_MASK,
655 DA732X_ADC_OFF);
656 snd_soc_update_bits(codec, w->reg, DA732X_ADC_RST_MASK,
657 DA732X_ADC_SET_RST);
658
659 switch (w->reg) {
660 case DA732X_REG_ADC1_PD:
661 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
662 DA732X_ADCA_BB_CLK_EN, 0);
663 break;
664 case DA732X_REG_ADC2_PD:
665 snd_soc_update_bits(codec, DA732X_REG_CLK_EN3,
666 DA732X_ADCC_BB_CLK_EN, 0);
667 break;
668 default:
669 return -EINVAL;
670 }
671
672 break;
673 default:
674 return -EINVAL;
675 }
676
677 return 0;
678}
679
680static int da732x_out_pga_event(struct snd_soc_dapm_widget *w,
681 struct snd_kcontrol *kcontrol, int event)
682{
683 struct snd_soc_codec *codec = w->codec;
684
685 switch (event) {
686 case SND_SOC_DAPM_POST_PMU:
687 snd_soc_update_bits(codec, w->reg,
688 (1 << w->shift) | DA732X_OUT_HIZ_EN,
689 (1 << w->shift) | DA732X_OUT_HIZ_EN);
690 break;
691 case SND_SOC_DAPM_POST_PMD:
692 snd_soc_update_bits(codec, w->reg,
693 (1 << w->shift) | DA732X_OUT_HIZ_EN,
694 (1 << w->shift) | DA732X_OUT_HIZ_DIS);
695 break;
696 default:
697 return -EINVAL;
698 }
699
700 return 0;
701}
702
703static const char *adcl_text[] = {
704 "AUX1L", "MIC1"
705};
706
707static const char *adcr_text[] = {
708 "AUX1R", "MIC2", "MIC3"
709};
710
711static const char *enable_text[] = {
712 "Disabled",
713 "Enabled"
714};
715
716/* ADC1LMUX */
717static const struct soc_enum adc1l_enum =
718 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1L_MUX_SEL_SHIFT,
719 DA732X_ADCL_MUX_MAX, adcl_text);
720static const struct snd_kcontrol_new adc1l_mux =
721 SOC_DAPM_ENUM("ADC Route", adc1l_enum);
722
723/* ADC1RMUX */
724static const struct soc_enum adc1r_enum =
725 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC1R_MUX_SEL_SHIFT,
726 DA732X_ADCR_MUX_MAX, adcr_text);
727static const struct snd_kcontrol_new adc1r_mux =
728 SOC_DAPM_ENUM("ADC Route", adc1r_enum);
729
730/* ADC2LMUX */
731static const struct soc_enum adc2l_enum =
732 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2L_MUX_SEL_SHIFT,
733 DA732X_ADCL_MUX_MAX, adcl_text);
734static const struct snd_kcontrol_new adc2l_mux =
735 SOC_DAPM_ENUM("ADC Route", adc2l_enum);
736
737/* ADC2RMUX */
738static const struct soc_enum adc2r_enum =
739 SOC_ENUM_SINGLE(DA732X_REG_INP_MUX, DA732X_ADC2R_MUX_SEL_SHIFT,
740 DA732X_ADCR_MUX_MAX, adcr_text);
741
742static const struct snd_kcontrol_new adc2r_mux =
743 SOC_DAPM_ENUM("ADC Route", adc2r_enum);
744
745static const struct soc_enum da732x_hp_left_output =
746 SOC_ENUM_SINGLE(DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN_SHIFT,
747 DA732X_DAC_EN_MAX, enable_text);
748
749static const struct snd_kcontrol_new hpl_mux =
750 SOC_DAPM_ENUM("HPL Switch", da732x_hp_left_output);
751
752static const struct soc_enum da732x_hp_right_output =
753 SOC_ENUM_SINGLE(DA732X_REG_HPR, DA732X_HP_OUT_DAC_EN_SHIFT,
754 DA732X_DAC_EN_MAX, enable_text);
755
756static const struct snd_kcontrol_new hpr_mux =
757 SOC_DAPM_ENUM("HPR Switch", da732x_hp_right_output);
758
759static const struct soc_enum da732x_speaker_output =
760 SOC_ENUM_SINGLE(DA732X_REG_LIN3, DA732X_LOUT_DAC_EN_SHIFT,
761 DA732X_DAC_EN_MAX, enable_text);
762
763static const struct snd_kcontrol_new spk_mux =
764 SOC_DAPM_ENUM("SPK Switch", da732x_speaker_output);
765
766static const struct soc_enum da732x_lout4_output =
767 SOC_ENUM_SINGLE(DA732X_REG_LIN4, DA732X_LOUT_DAC_EN_SHIFT,
768 DA732X_DAC_EN_MAX, enable_text);
769
770static const struct snd_kcontrol_new lout4_mux =
771 SOC_DAPM_ENUM("LOUT4 Switch", da732x_lout4_output);
772
773static const struct soc_enum da732x_lout2_output =
774 SOC_ENUM_SINGLE(DA732X_REG_LIN2, DA732X_LOUT_DAC_EN_SHIFT,
775 DA732X_DAC_EN_MAX, enable_text);
776
777static const struct snd_kcontrol_new lout2_mux =
778 SOC_DAPM_ENUM("LOUT2 Switch", da732x_lout2_output);
779
780static const struct snd_soc_dapm_widget da732x_dapm_widgets[] = {
781 /* Supplies */
782 SND_SOC_DAPM_SUPPLY("ADC1 Supply", DA732X_REG_ADC1_PD, 0,
783 DA732X_NO_INVERT, da732x_adc_event,
784 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
785 SND_SOC_DAPM_SUPPLY("ADC2 Supply", DA732X_REG_ADC2_PD, 0,
786 DA732X_NO_INVERT, da732x_adc_event,
787 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
788 SND_SOC_DAPM_SUPPLY("DAC1 CLK", DA732X_REG_CLK_EN4,
789 DA732X_DACA_BB_CLK_SHIFT, DA732X_NO_INVERT,
790 NULL, 0),
791 SND_SOC_DAPM_SUPPLY("DAC2 CLK", DA732X_REG_CLK_EN4,
792 DA732X_DACC_BB_CLK_SHIFT, DA732X_NO_INVERT,
793 NULL, 0),
794 SND_SOC_DAPM_SUPPLY("DAC3 CLK", DA732X_REG_CLK_EN5,
795 DA732X_DACE_BB_CLK_SHIFT, DA732X_NO_INVERT,
796 NULL, 0),
797
798 /* Micbias */
799 SND_SOC_DAPM_SUPPLY("MICBIAS1", DA732X_REG_MICBIAS1,
800 DA732X_MICBIAS_EN_SHIFT,
801 DA732X_NO_INVERT, NULL, 0),
802 SND_SOC_DAPM_SUPPLY("MICBIAS2", DA732X_REG_MICBIAS2,
803 DA732X_MICBIAS_EN_SHIFT,
804 DA732X_NO_INVERT, NULL, 0),
805
806 /* Inputs */
807 SND_SOC_DAPM_INPUT("MIC1"),
808 SND_SOC_DAPM_INPUT("MIC2"),
809 SND_SOC_DAPM_INPUT("MIC3"),
810 SND_SOC_DAPM_INPUT("AUX1L"),
811 SND_SOC_DAPM_INPUT("AUX1R"),
812
813 /* Outputs */
814 SND_SOC_DAPM_OUTPUT("HPL"),
815 SND_SOC_DAPM_OUTPUT("HPR"),
816 SND_SOC_DAPM_OUTPUT("LOUTL"),
817 SND_SOC_DAPM_OUTPUT("LOUTR"),
818 SND_SOC_DAPM_OUTPUT("ClassD"),
819
820 /* ADCs */
821 SND_SOC_DAPM_ADC("ADC1L", NULL, DA732X_REG_ADC1_SEL,
822 DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT),
823 SND_SOC_DAPM_ADC("ADC1R", NULL, DA732X_REG_ADC1_SEL,
824 DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT),
825 SND_SOC_DAPM_ADC("ADC2L", NULL, DA732X_REG_ADC2_SEL,
826 DA732X_ADCL_EN_SHIFT, DA732X_NO_INVERT),
827 SND_SOC_DAPM_ADC("ADC2R", NULL, DA732X_REG_ADC2_SEL,
828 DA732X_ADCR_EN_SHIFT, DA732X_NO_INVERT),
829
830 /* DACs */
831 SND_SOC_DAPM_DAC("DAC1L", NULL, DA732X_REG_DAC1_SEL,
832 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
833 SND_SOC_DAPM_DAC("DAC1R", NULL, DA732X_REG_DAC1_SEL,
834 DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT),
835 SND_SOC_DAPM_DAC("DAC2L", NULL, DA732X_REG_DAC2_SEL,
836 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
837 SND_SOC_DAPM_DAC("DAC2R", NULL, DA732X_REG_DAC2_SEL,
838 DA732X_DACR_EN_SHIFT, DA732X_NO_INVERT),
839 SND_SOC_DAPM_DAC("DAC3", NULL, DA732X_REG_DAC3_SEL,
840 DA732X_DACL_EN_SHIFT, DA732X_NO_INVERT),
841
842 /* Input Pgas */
843 SND_SOC_DAPM_PGA("MIC1 PGA", DA732X_REG_MIC1, DA732X_MIC_EN_SHIFT,
844 0, NULL, 0),
845 SND_SOC_DAPM_PGA("MIC2 PGA", DA732X_REG_MIC2, DA732X_MIC_EN_SHIFT,
846 0, NULL, 0),
847 SND_SOC_DAPM_PGA("MIC3 PGA", DA732X_REG_MIC3, DA732X_MIC_EN_SHIFT,
848 0, NULL, 0),
849 SND_SOC_DAPM_PGA("AUX1L PGA", DA732X_REG_AUX1L, DA732X_AUX_EN_SHIFT,
850 0, NULL, 0),
851 SND_SOC_DAPM_PGA("AUX1R PGA", DA732X_REG_AUX1R, DA732X_AUX_EN_SHIFT,
852 0, NULL, 0),
853
854 SND_SOC_DAPM_PGA_E("HP Left", DA732X_REG_HPL, DA732X_HP_OUT_EN_SHIFT,
855 0, NULL, 0, da732x_out_pga_event,
856 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
857 SND_SOC_DAPM_PGA_E("HP Right", DA732X_REG_HPR, DA732X_HP_OUT_EN_SHIFT,
858 0, NULL, 0, da732x_out_pga_event,
859 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
860 SND_SOC_DAPM_PGA_E("LIN2", DA732X_REG_LIN2, DA732X_LIN_OUT_EN_SHIFT,
861 0, NULL, 0, da732x_out_pga_event,
862 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
863 SND_SOC_DAPM_PGA_E("LIN3", DA732X_REG_LIN3, DA732X_LIN_OUT_EN_SHIFT,
864 0, NULL, 0, da732x_out_pga_event,
865 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
866 SND_SOC_DAPM_PGA_E("LIN4", DA732X_REG_LIN4, DA732X_LIN_OUT_EN_SHIFT,
867 0, NULL, 0, da732x_out_pga_event,
868 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
869
870 /* MUXs */
871 SND_SOC_DAPM_MUX("ADC1 Left MUX", SND_SOC_NOPM, 0, 0, &adc1l_mux),
872 SND_SOC_DAPM_MUX("ADC1 Right MUX", SND_SOC_NOPM, 0, 0, &adc1r_mux),
873 SND_SOC_DAPM_MUX("ADC2 Left MUX", SND_SOC_NOPM, 0, 0, &adc2l_mux),
874 SND_SOC_DAPM_MUX("ADC2 Right MUX", SND_SOC_NOPM, 0, 0, &adc2r_mux),
875
876 SND_SOC_DAPM_MUX("HP Left MUX", SND_SOC_NOPM, 0, 0, &hpl_mux),
877 SND_SOC_DAPM_MUX("HP Right MUX", SND_SOC_NOPM, 0, 0, &hpr_mux),
878 SND_SOC_DAPM_MUX("Speaker MUX", SND_SOC_NOPM, 0, 0, &spk_mux),
879 SND_SOC_DAPM_MUX("LOUT2 MUX", SND_SOC_NOPM, 0, 0, &lout2_mux),
880 SND_SOC_DAPM_MUX("LOUT4 MUX", SND_SOC_NOPM, 0, 0, &lout4_mux),
881
882 /* AIF interfaces */
883 SND_SOC_DAPM_AIF_OUT("AIFA Output", "AIFA Capture", 0, DA732X_REG_AIFA3,
884 DA732X_AIF_EN_SHIFT, 0),
885 SND_SOC_DAPM_AIF_IN("AIFA Input", "AIFA Playback", 0, DA732X_REG_AIFA3,
886 DA732X_AIF_EN_SHIFT, 0),
887
888 SND_SOC_DAPM_AIF_OUT("AIFB Output", "AIFB Capture", 0, DA732X_REG_AIFB3,
889 DA732X_AIF_EN_SHIFT, 0),
890 SND_SOC_DAPM_AIF_IN("AIFB Input", "AIFB Playback", 0, DA732X_REG_AIFB3,
891 DA732X_AIF_EN_SHIFT, 0),
892};
893
894static const struct snd_soc_dapm_route da732x_dapm_routes[] = {
895 /* Inputs */
896 {"AUX1L PGA", "NULL", "AUX1L"},
897 {"AUX1R PGA", "NULL", "AUX1R"},
898 {"MIC1 PGA", NULL, "MIC1"},
899 {"MIC2 PGA", "NULL", "MIC2"},
900 {"MIC3 PGA", "NULL", "MIC3"},
901
902 /* Capture Path */
903 {"ADC1 Left MUX", "MIC1", "MIC1 PGA"},
904 {"ADC1 Left MUX", "AUX1L", "AUX1L PGA"},
905
906 {"ADC1 Right MUX", "AUX1R", "AUX1R PGA"},
907 {"ADC1 Right MUX", "MIC2", "MIC2 PGA"},
908 {"ADC1 Right MUX", "MIC3", "MIC3 PGA"},
909
910 {"ADC2 Left MUX", "AUX1L", "AUX1L PGA"},
911 {"ADC2 Left MUX", "MIC1", "MIC1 PGA"},
912
913 {"ADC2 Right MUX", "AUX1R", "AUX1R PGA"},
914 {"ADC2 Right MUX", "MIC2", "MIC2 PGA"},
915 {"ADC2 Right MUX", "MIC3", "MIC3 PGA"},
916
917 {"ADC1L", NULL, "ADC1 Supply"},
918 {"ADC1R", NULL, "ADC1 Supply"},
919 {"ADC2L", NULL, "ADC2 Supply"},
920 {"ADC2R", NULL, "ADC2 Supply"},
921
922 {"ADC1L", NULL, "ADC1 Left MUX"},
923 {"ADC1R", NULL, "ADC1 Right MUX"},
924 {"ADC2L", NULL, "ADC2 Left MUX"},
925 {"ADC2R", NULL, "ADC2 Right MUX"},
926
927 {"AIFA Output", NULL, "ADC1L"},
928 {"AIFA Output", NULL, "ADC1R"},
929 {"AIFB Output", NULL, "ADC2L"},
930 {"AIFB Output", NULL, "ADC2R"},
931
932 {"HP Left MUX", "Enabled", "AIFA Input"},
933 {"HP Right MUX", "Enabled", "AIFA Input"},
934 {"Speaker MUX", "Enabled", "AIFB Input"},
935 {"LOUT2 MUX", "Enabled", "AIFB Input"},
936 {"LOUT4 MUX", "Enabled", "AIFB Input"},
937
938 {"DAC1L", NULL, "DAC1 CLK"},
939 {"DAC1R", NULL, "DAC1 CLK"},
940 {"DAC2L", NULL, "DAC2 CLK"},
941 {"DAC2R", NULL, "DAC2 CLK"},
942 {"DAC3", NULL, "DAC3 CLK"},
943
944 {"DAC1L", NULL, "HP Left MUX"},
945 {"DAC1R", NULL, "HP Right MUX"},
946 {"DAC2L", NULL, "Speaker MUX"},
947 {"DAC2R", NULL, "LOUT4 MUX"},
948 {"DAC3", NULL, "LOUT2 MUX"},
949
950 /* Output Pgas */
951 {"HP Left", NULL, "DAC1L"},
952 {"HP Right", NULL, "DAC1R"},
953 {"LIN3", NULL, "DAC2L"},
954 {"LIN4", NULL, "DAC2R"},
955 {"LIN2", NULL, "DAC3"},
956
957 /* Outputs */
958 {"ClassD", NULL, "LIN3"},
959 {"LOUTL", NULL, "LIN2"},
960 {"LOUTR", NULL, "LIN4"},
961 {"HPL", NULL, "HP Left"},
962 {"HPR", NULL, "HP Right"},
963};
964
965static int da732x_hw_params(struct snd_pcm_substream *substream,
966 struct snd_pcm_hw_params *params,
967 struct snd_soc_dai *dai)
968{
969 struct snd_soc_codec *codec = dai->codec;
970 u32 aif = 0;
971 u32 reg_aif;
972 u32 fs;
973
974 reg_aif = dai->driver->base;
975
976 switch (params_format(params)) {
977 case SNDRV_PCM_FORMAT_S16_LE:
978 aif |= DA732X_AIF_WORD_16;
979 break;
980 case SNDRV_PCM_FORMAT_S20_3LE:
981 aif |= DA732X_AIF_WORD_20;
982 break;
983 case SNDRV_PCM_FORMAT_S24_LE:
984 aif |= DA732X_AIF_WORD_24;
985 break;
986 case SNDRV_PCM_FORMAT_S32_LE:
987 aif |= DA732X_AIF_WORD_32;
988 break;
989 default:
990 return -EINVAL;
991 }
992
993 switch (params_rate(params)) {
994 case 8000:
995 fs = DA732X_SR_8KHZ;
996 break;
997 case 11025:
998 fs = DA732X_SR_11_025KHZ;
999 break;
1000 case 12000:
1001 fs = DA732X_SR_12KHZ;
1002 break;
1003 case 16000:
1004 fs = DA732X_SR_16KHZ;
1005 break;
1006 case 22050:
1007 fs = DA732X_SR_22_05KHZ;
1008 break;
1009 case 24000:
1010 fs = DA732X_SR_24KHZ;
1011 break;
1012 case 32000:
1013 fs = DA732X_SR_32KHZ;
1014 break;
1015 case 44100:
1016 fs = DA732X_SR_44_1KHZ;
1017 break;
1018 case 48000:
1019 fs = DA732X_SR_48KHZ;
1020 break;
1021 case 88100:
1022 fs = DA732X_SR_88_1KHZ;
1023 break;
1024 case 96000:
1025 fs = DA732X_SR_96KHZ;
1026 break;
1027 default:
1028 return -EINVAL;
1029 }
1030
1031 snd_soc_update_bits(codec, reg_aif, DA732X_AIF_WORD_MASK, aif);
1032 snd_soc_update_bits(codec, DA732X_REG_CLK_CTRL, DA732X_SR1_MASK, fs);
1033
1034 return 0;
1035}
1036
1037static int da732x_set_dai_fmt(struct snd_soc_dai *dai, u32 fmt)
1038{
1039 struct snd_soc_codec *codec = dai->codec;
1040 u32 aif_mclk, pc_count;
1041 u32 reg_aif1, aif1;
1042 u32 reg_aif3, aif3;
1043
1044 switch (dai->id) {
1045 case DA732X_DAI_ID1:
1046 reg_aif1 = DA732X_REG_AIFA1;
1047 reg_aif3 = DA732X_REG_AIFA3;
1048 pc_count = DA732X_PC_PULSE_AIFA | DA732X_PC_RESYNC_NOT_AUT |
1049 DA732X_PC_SAME;
1050 break;
1051 case DA732X_DAI_ID2:
1052 reg_aif1 = DA732X_REG_AIFB1;
1053 reg_aif3 = DA732X_REG_AIFB3;
1054 pc_count = DA732X_PC_PULSE_AIFB | DA732X_PC_RESYNC_NOT_AUT |
1055 DA732X_PC_SAME;
1056 break;
1057 default:
1058 return -EINVAL;
1059 }
1060
1061 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1062 case SND_SOC_DAIFMT_CBS_CFS:
1063 aif1 = DA732X_AIF_SLAVE;
1064 aif_mclk = DA732X_AIFM_FRAME_64 | DA732X_AIFM_SRC_SEL_AIFA;
1065 break;
1066 case SND_SOC_DAIFMT_CBM_CFM:
1067 aif1 = DA732X_AIF_CLK_FROM_SRC;
1068 aif_mclk = DA732X_CLK_GENERATION_AIF_A;
1069 break;
1070 default:
1071 return -EINVAL;
1072 }
1073
1074 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1075 case SND_SOC_DAIFMT_I2S:
1076 aif3 = DA732X_AIF_I2S_MODE;
1077 break;
1078 case SND_SOC_DAIFMT_RIGHT_J:
1079 aif3 = DA732X_AIF_RIGHT_J_MODE;
1080 break;
1081 case SND_SOC_DAIFMT_LEFT_J:
1082 aif3 = DA732X_AIF_LEFT_J_MODE;
1083 break;
1084 case SND_SOC_DAIFMT_DSP_B:
1085 aif3 = DA732X_AIF_DSP_MODE;
1086 break;
1087 default:
1088 return -EINVAL;
1089 }
1090
1091 /* Clock inversion */
1092 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
1093 case SND_SOC_DAIFMT_DSP_B:
1094 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1095 case SND_SOC_DAIFMT_NB_NF:
1096 break;
1097 case SND_SOC_DAIFMT_IB_NF:
1098 aif3 |= DA732X_AIF_BCLK_INV;
1099 break;
1100 default:
1101 return -EINVAL;
1102 }
1103 break;
1104 case SND_SOC_DAIFMT_I2S:
1105 case SND_SOC_DAIFMT_RIGHT_J:
1106 case SND_SOC_DAIFMT_LEFT_J:
1107 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
1108 case SND_SOC_DAIFMT_NB_NF:
1109 break;
1110 case SND_SOC_DAIFMT_IB_IF:
1111 aif3 |= DA732X_AIF_BCLK_INV | DA732X_AIF_WCLK_INV;
1112 break;
1113 case SND_SOC_DAIFMT_IB_NF:
1114 aif3 |= DA732X_AIF_BCLK_INV;
1115 break;
1116 case SND_SOC_DAIFMT_NB_IF:
1117 aif3 |= DA732X_AIF_WCLK_INV;
1118 break;
1119 default:
1120 return -EINVAL;
1121 }
1122 break;
1123 default:
1124 return -EINVAL;
1125 }
1126
1127 snd_soc_write(codec, DA732X_REG_AIF_MCLK, aif_mclk);
1128 snd_soc_update_bits(codec, reg_aif1, DA732X_AIF1_CLK_MASK, aif1);
1129 snd_soc_update_bits(codec, reg_aif3, DA732X_AIF_BCLK_INV |
1130 DA732X_AIF_WCLK_INV | DA732X_AIF_MODE_MASK, aif3);
1131 snd_soc_write(codec, DA732X_REG_PC_CTRL, pc_count);
1132
1133 return 0;
1134}
1135
1136
1137
1138static int da732x_set_dai_pll(struct snd_soc_codec *codec, int pll_id,
1139 int source, unsigned int freq_in,
1140 unsigned int freq_out)
1141{
1142 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1143 int fref, indiv;
1144 u8 div_lo, div_mid, div_hi;
1145 u64 frac_div;
1146
1147 /* Disable PLL */
1148 if (freq_out == 0) {
1149 snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
1150 DA732X_PLL_EN, 0);
1151 da732x->pll_en = false;
1152 return 0;
1153 }
1154
1155 if (da732x->pll_en)
1156 return -EBUSY;
1157
1158 if (source == DA732X_SRCCLK_MCLK) {
1159 /* Validate Sysclk rate */
1160 switch (da732x->sysclk) {
1161 case 11290000:
1162 case 12288000:
1163 case 22580000:
1164 case 24576000:
1165 case 45160000:
1166 case 49152000:
1167 snd_soc_write(codec, DA732X_REG_PLL_CTRL,
1168 DA732X_PLL_BYPASS);
1169 return 0;
1170 default:
1171 dev_err(codec->dev,
1172 "Cannot use PLL Bypass, invalid SYSCLK rate\n");
1173 return -EINVAL;
1174 }
1175 }
1176
1177 indiv = da732x_get_input_div(codec, da732x->sysclk);
1178 if (indiv < 0)
1179 return indiv;
1180
1181 fref = (da732x->sysclk / indiv);
1182 div_hi = freq_out / fref;
1183 frac_div = (u64)(freq_out % fref) * 8192ULL;
1184 do_div(frac_div, fref);
1185 div_mid = (frac_div >> DA732X_1BYTE_SHIFT) & DA732X_U8_MASK;
1186 div_lo = (frac_div) & DA732X_U8_MASK;
1187
1188 snd_soc_write(codec, DA732X_REG_PLL_DIV_LO, div_lo);
1189 snd_soc_write(codec, DA732X_REG_PLL_DIV_MID, div_mid);
1190 snd_soc_write(codec, DA732X_REG_PLL_DIV_HI, div_hi);
1191
1192 snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL, DA732X_PLL_EN,
1193 DA732X_PLL_EN);
1194
1195 da732x->pll_en = true;
1196
1197 return 0;
1198}
1199
1200static int da732x_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
1201 unsigned int freq, int dir)
1202{
1203 struct snd_soc_codec *codec = dai->codec;
1204 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1205
1206 da732x->sysclk = freq;
1207
1208 return 0;
1209}
1210
1211#define DA732X_RATES SNDRV_PCM_RATE_8000_96000
1212
1213#define DA732X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
1214 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
1215
1216static struct snd_soc_dai_ops da732x_dai1_ops = {
1217 .hw_params = da732x_hw_params,
1218 .set_fmt = da732x_set_dai_fmt,
1219 .set_sysclk = da732x_set_dai_sysclk,
1220};
1221
1222static struct snd_soc_dai_ops da732x_dai2_ops = {
1223 .hw_params = da732x_hw_params,
1224 .set_fmt = da732x_set_dai_fmt,
1225 .set_sysclk = da732x_set_dai_sysclk,
1226};
1227
1228static struct snd_soc_dai_driver da732x_dai[] = {
1229 {
1230 .name = "DA732X_AIFA",
1231 .id = DA732X_DAI_ID1,
1232 .base = DA732X_REG_AIFA1,
1233 .playback = {
1234 .stream_name = "AIFA Playback",
1235 .channels_min = 1,
1236 .channels_max = 2,
1237 .rates = DA732X_RATES,
1238 .formats = DA732X_FORMATS,
1239 },
1240 .capture = {
1241 .stream_name = "AIFA Capture",
1242 .channels_min = 1,
1243 .channels_max = 2,
1244 .rates = DA732X_RATES,
1245 .formats = DA732X_FORMATS,
1246 },
1247 .ops = &da732x_dai1_ops,
1248 },
1249 {
1250 .name = "DA732X_AIFB",
1251 .id = DA732X_DAI_ID2,
1252 .base = DA732X_REG_AIFB1,
1253 .playback = {
1254 .stream_name = "AIFB Playback",
1255 .channels_min = 1,
1256 .channels_max = 2,
1257 .rates = DA732X_RATES,
1258 .formats = DA732X_FORMATS,
1259 },
1260 .capture = {
1261 .stream_name = "AIFB Capture",
1262 .channels_min = 1,
1263 .channels_max = 2,
1264 .rates = DA732X_RATES,
1265 .formats = DA732X_FORMATS,
1266 },
1267 .ops = &da732x_dai2_ops,
1268 },
1269};
1270
1271static const struct regmap_config da732x_regmap = {
1272 .reg_bits = 8,
1273 .val_bits = 8,
1274
1275 .max_register = DA732X_MAX_REG,
1276 .reg_defaults = da732x_reg_cache,
1277 .num_reg_defaults = ARRAY_SIZE(da732x_reg_cache),
1278 .cache_type = REGCACHE_RBTREE,
1279};
1280
1281
1282static void da732x_dac_offset_adjust(struct snd_soc_codec *codec)
1283{
1284 u8 offset[DA732X_HP_DACS];
1285 u8 sign[DA732X_HP_DACS];
1286 u8 step = DA732X_DAC_OFFSET_STEP;
1287
1288 /* Initialize DAC offset calibration circuits and registers */
1289 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1290 DA732X_HP_DAC_OFFSET_TRIM_VAL);
1291 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1292 DA732X_HP_DAC_OFFSET_TRIM_VAL);
1293 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
1294 DA732X_HP_DAC_OFF_CALIBRATION |
1295 DA732X_HP_DAC_OFF_SCALE_STEPS);
1296 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
1297 DA732X_HP_DAC_OFF_CALIBRATION |
1298 DA732X_HP_DAC_OFF_SCALE_STEPS);
1299
1300 /* Wait for voltage stabilization */
1301 msleep(DA732X_WAIT_FOR_STABILIZATION);
1302
1303 /* Check DAC offset sign */
1304 sign[DA732X_HPL_DAC] = (codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1305 DA732X_HP_DAC_OFF_CNTL_COMPO);
1306 sign[DA732X_HPR_DAC] = (codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1307 DA732X_HP_DAC_OFF_CNTL_COMPO);
1308
1309 /* Binary search DAC offset values (both channels at once) */
1310 offset[DA732X_HPL_DAC] = sign[DA732X_HPL_DAC] << DA732X_HP_DAC_COMPO_SHIFT;
1311 offset[DA732X_HPR_DAC] = sign[DA732X_HPR_DAC] << DA732X_HP_DAC_COMPO_SHIFT;
1312
1313 do {
1314 offset[DA732X_HPL_DAC] |= step;
1315 offset[DA732X_HPR_DAC] |= step;
1316 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1317 ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
1318 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1319 ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
1320
1321 msleep(DA732X_WAIT_FOR_STABILIZATION);
1322
1323 if ((codec->hw_read(codec, DA732X_REG_HPL_DAC_OFF_CNTL) &
1324 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPL_DAC])
1325 offset[DA732X_HPL_DAC] &= ~step;
1326 if ((codec->hw_read(codec, DA732X_REG_HPR_DAC_OFF_CNTL) &
1327 DA732X_HP_DAC_OFF_CNTL_COMPO) ^ sign[DA732X_HPR_DAC])
1328 offset[DA732X_HPR_DAC] &= ~step;
1329
1330 step >>= 1;
1331 } while (step);
1332
1333 /* Write final DAC offsets to registers */
1334 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFFSET,
1335 ~offset[DA732X_HPL_DAC] & DA732X_HP_DAC_OFF_MASK);
1336 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFFSET,
1337 ~offset[DA732X_HPR_DAC] & DA732X_HP_DAC_OFF_MASK);
1338
1339 /* End DAC calibration mode */
1340 snd_soc_write(codec, DA732X_REG_HPL_DAC_OFF_CNTL,
1341 DA732X_HP_DAC_OFF_SCALE_STEPS);
1342 snd_soc_write(codec, DA732X_REG_HPR_DAC_OFF_CNTL,
1343 DA732X_HP_DAC_OFF_SCALE_STEPS);
1344}
1345
1346static void da732x_output_offset_adjust(struct snd_soc_codec *codec)
1347{
1348 u8 offset[DA732X_HP_AMPS];
1349 u8 sign[DA732X_HP_AMPS];
1350 u8 step = DA732X_OUTPUT_OFFSET_STEP;
1351
1352 offset[DA732X_HPL_AMP] = DA732X_HP_OUT_TRIM_VAL;
1353 offset[DA732X_HPR_AMP] = DA732X_HP_OUT_TRIM_VAL;
1354
1355 /* Initialize output offset calibration circuits and registers */
1356 snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
1357 snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, DA732X_HP_OUT_TRIM_VAL);
1358 snd_soc_write(codec, DA732X_REG_HPL,
1359 DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
1360 snd_soc_write(codec, DA732X_REG_HPR,
1361 DA732X_HP_OUT_COMP | DA732X_HP_OUT_EN);
1362
1363 /* Wait for voltage stabilization */
1364 msleep(DA732X_WAIT_FOR_STABILIZATION);
1365
1366 /* Check output offset sign */
1367 sign[DA732X_HPL_AMP] = codec->hw_read(codec, DA732X_REG_HPL) &
1368 DA732X_HP_OUT_COMPO;
1369 sign[DA732X_HPR_AMP] = codec->hw_read(codec, DA732X_REG_HPR) &
1370 DA732X_HP_OUT_COMPO;
1371
1372 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_COMP |
1373 (sign[DA732X_HPL_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
1374 DA732X_HP_OUT_EN);
1375 snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_COMP |
1376 (sign[DA732X_HPR_AMP] >> DA732X_HP_OUT_COMPO_SHIFT) |
1377 DA732X_HP_OUT_EN);
1378
1379 /* Binary search output offset values (both channels at once) */
1380 do {
1381 offset[DA732X_HPL_AMP] |= step;
1382 offset[DA732X_HPR_AMP] |= step;
1383 snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET,
1384 offset[DA732X_HPL_AMP]);
1385 snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET,
1386 offset[DA732X_HPR_AMP]);
1387
1388 msleep(DA732X_WAIT_FOR_STABILIZATION);
1389
1390 if ((codec->hw_read(codec, DA732X_REG_HPL) &
1391 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPL_AMP])
1392 offset[DA732X_HPL_AMP] &= ~step;
1393 if ((codec->hw_read(codec, DA732X_REG_HPR) &
1394 DA732X_HP_OUT_COMPO) ^ sign[DA732X_HPR_AMP])
1395 offset[DA732X_HPR_AMP] &= ~step;
1396
1397 step >>= 1;
1398 } while (step);
1399
1400 /* Write final DAC offsets to registers */
1401 snd_soc_write(codec, DA732X_REG_HPL_OUT_OFFSET, offset[DA732X_HPL_AMP]);
1402 snd_soc_write(codec, DA732X_REG_HPR_OUT_OFFSET, offset[DA732X_HPR_AMP]);
1403}
1404
1405static void da732x_hp_dc_offset_cancellation(struct snd_soc_codec *codec)
1406{
1407 /* Make sure that we have Soft Mute enabled */
1408 snd_soc_write(codec, DA732X_REG_DAC1_SOFTMUTE, DA732X_SOFTMUTE_EN |
1409 DA732X_GAIN_RAMPED | DA732X_16_SAMPLES);
1410 snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACL_EN |
1411 DA732X_DACR_EN | DA732X_DACL_SDM | DA732X_DACR_SDM |
1412 DA732X_DACL_MUTE | DA732X_DACR_MUTE);
1413 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_OUT_DAC_EN |
1414 DA732X_HP_OUT_MUTE | DA732X_HP_OUT_EN);
1415 snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_OUT_EN |
1416 DA732X_HP_OUT_MUTE | DA732X_HP_OUT_DAC_EN);
1417
1418 da732x_dac_offset_adjust(codec);
1419 da732x_output_offset_adjust(codec);
1420
1421 snd_soc_write(codec, DA732X_REG_DAC1_SEL, DA732X_DACS_DIS);
1422 snd_soc_write(codec, DA732X_REG_HPL, DA732X_HP_DIS);
1423 snd_soc_write(codec, DA732X_REG_HPR, DA732X_HP_DIS);
1424}
1425
1426static int da732x_set_bias_level(struct snd_soc_codec *codec,
1427 enum snd_soc_bias_level level)
1428{
1429 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1430
1431 switch (level) {
1432 case SND_SOC_BIAS_ON:
1433 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1434 DA732X_BIAS_BOOST_MASK,
1435 DA732X_BIAS_BOOST_100PC);
1436 break;
1437 case SND_SOC_BIAS_PREPARE:
1438 break;
1439 case SND_SOC_BIAS_STANDBY:
1440 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1441 /* Init Codec */
1442 snd_soc_write(codec, DA732X_REG_REF1,
1443 DA732X_VMID_FASTCHG);
1444 snd_soc_write(codec, DA732X_REG_BIAS_EN,
1445 DA732X_BIAS_EN);
1446
1447 mdelay(DA732X_STARTUP_DELAY);
1448
1449 /* Disable Fast Charge and enable DAC ref voltage */
1450 snd_soc_write(codec, DA732X_REG_REF1,
1451 DA732X_REFBUFX2_EN);
1452
1453 /* Enable bypass DSP routing */
1454 snd_soc_write(codec, DA732X_REG_DATA_ROUTE,
1455 DA732X_BYPASS_DSP);
1456
1457 /* Enable Digital subsystem */
1458 snd_soc_write(codec, DA732X_REG_DSP_CTRL,
1459 DA732X_DIGITAL_EN);
1460
1461 snd_soc_write(codec, DA732X_REG_SPARE1_OUT,
1462 DA732X_HP_DRIVER_EN |
1463 DA732X_HP_GATE_LOW |
1464 DA732X_HP_LOOP_GAIN_CTRL);
1465 snd_soc_write(codec, DA732X_REG_HP_LIN1_GNDSEL,
1466 DA732X_HP_OUT_GNDSEL);
1467
1468 da732x_set_charge_pump(codec, DA732X_ENABLE_CP);
1469
1470 snd_soc_write(codec, DA732X_REG_CLK_EN1,
1471 DA732X_SYS3_CLK_EN | DA732X_PC_CLK_EN);
1472
1473 /* Enable Zero Crossing */
1474 snd_soc_write(codec, DA732X_REG_INP_ZC_EN,
1475 DA732X_MIC1_PRE_ZC_EN |
1476 DA732X_MIC1_ZC_EN |
1477 DA732X_MIC2_PRE_ZC_EN |
1478 DA732X_MIC2_ZC_EN |
1479 DA732X_AUXL_ZC_EN |
1480 DA732X_AUXR_ZC_EN |
1481 DA732X_MIC3_PRE_ZC_EN |
1482 DA732X_MIC3_ZC_EN);
1483 snd_soc_write(codec, DA732X_REG_OUT_ZC_EN,
1484 DA732X_HPL_ZC_EN | DA732X_HPR_ZC_EN |
1485 DA732X_LIN2_ZC_EN | DA732X_LIN3_ZC_EN |
1486 DA732X_LIN4_ZC_EN);
1487
1488 da732x_hp_dc_offset_cancellation(codec);
1489
1490 regcache_cache_only(codec->control_data, false);
1491 regcache_sync(codec->control_data);
1492 } else {
1493 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN,
1494 DA732X_BIAS_BOOST_MASK,
1495 DA732X_BIAS_BOOST_50PC);
1496 snd_soc_update_bits(codec, DA732X_REG_PLL_CTRL,
1497 DA732X_PLL_EN, 0);
1498 da732x->pll_en = false;
1499 }
1500 break;
1501 case SND_SOC_BIAS_OFF:
1502 regcache_cache_only(codec->control_data, true);
1503 da732x_set_charge_pump(codec, DA732X_DISABLE_CP);
1504 snd_soc_update_bits(codec, DA732X_REG_BIAS_EN, DA732X_BIAS_EN,
1505 DA732X_BIAS_DIS);
1506 da732x->pll_en = false;
1507 break;
1508 }
1509
1510 codec->dapm.bias_level = level;
1511
1512 return 0;
1513}
1514
1515static int da732x_probe(struct snd_soc_codec *codec)
1516{
1517 struct da732x_priv *da732x = snd_soc_codec_get_drvdata(codec);
1518 struct snd_soc_dapm_context *dapm = &codec->dapm;
1519 int ret = 0;
1520
1521 da732x->codec = codec;
1522
1523 dapm->idle_bias_off = false;
1524
1525 codec->control_data = da732x->regmap;
1526
1527 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1528 if (ret != 0) {
1529 dev_err(codec->dev, "Failed to register codec.\n");
1530 goto err;
1531 }
1532
1533 da732x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1534err:
1535 return ret;
1536}
1537
1538static int da732x_remove(struct snd_soc_codec *codec)
1539{
1540
1541 da732x_set_bias_level(codec, SND_SOC_BIAS_OFF);
1542
1543 return 0;
1544}
1545
1546static struct snd_soc_codec_driver soc_codec_dev_da732x = {
1547 .probe = da732x_probe,
1548 .remove = da732x_remove,
1549 .set_bias_level = da732x_set_bias_level,
1550 .controls = da732x_snd_controls,
1551 .num_controls = ARRAY_SIZE(da732x_snd_controls),
1552 .dapm_widgets = da732x_dapm_widgets,
1553 .num_dapm_widgets = ARRAY_SIZE(da732x_dapm_widgets),
1554 .dapm_routes = da732x_dapm_routes,
1555 .num_dapm_routes = ARRAY_SIZE(da732x_dapm_routes),
1556 .set_pll = da732x_set_dai_pll,
1557 .reg_cache_size = ARRAY_SIZE(da732x_reg_cache),
1558};
1559
1560static __devinit int da732x_i2c_probe(struct i2c_client *i2c,
1561 const struct i2c_device_id *id)
1562{
1563 struct da732x_priv *da732x;
1564 unsigned int reg;
1565 int ret;
1566
1567 da732x = devm_kzalloc(&i2c->dev, sizeof(struct da732x_priv),
1568 GFP_KERNEL);
1569 if (!da732x)
1570 return -ENOMEM;
1571
1572 i2c_set_clientdata(i2c, da732x);
1573
1574 da732x->regmap = devm_regmap_init_i2c(i2c, &da732x_regmap);
1575 if (IS_ERR(da732x->regmap)) {
1576 ret = PTR_ERR(da732x->regmap);
1577 dev_err(&i2c->dev, "Failed to initialize regmap\n");
1578 goto err;
1579 }
1580
1581 ret = regmap_read(da732x->regmap, DA732X_REG_ID, &reg);
1582 if (ret < 0) {
1583 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
1584 goto err;
1585 }
1586
1587 dev_info(&i2c->dev, "Revision: %d.%d\n",
1588 (reg & DA732X_ID_MAJOR_MASK), (reg & DA732X_ID_MINOR_MASK));
1589
1590 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_da732x,
1591 da732x_dai, ARRAY_SIZE(da732x_dai));
1592 if (ret != 0)
1593 dev_err(&i2c->dev, "Failed to register codec.\n");
1594
1595err:
1596 return ret;
1597}
1598
1599static __devexit int da732x_i2c_remove(struct i2c_client *client)
1600{
1601 snd_soc_unregister_codec(&client->dev);
1602
1603 return 0;
1604}
1605
1606static const struct i2c_device_id da732x_i2c_id[] = {
1607 { "da7320", 0},
1608 { }
1609};
1610MODULE_DEVICE_TABLE(i2c, da732x_i2c_id);
1611
1612static struct i2c_driver da732x_i2c_driver = {
1613 .driver = {
1614 .name = "da7320",
1615 .owner = THIS_MODULE,
1616 },
1617 .probe = da732x_i2c_probe,
1618 .remove = __devexit_p(da732x_i2c_remove),
1619 .id_table = da732x_i2c_id,
1620};
1621
1622module_i2c_driver(da732x_i2c_driver);
1623
1624
1625MODULE_DESCRIPTION("ASoC DA732X driver");
1626MODULE_AUTHOR("Michal Hajduk <michal.hajduk@diasemi.com>");
1627MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/da732x.h b/sound/soc/codecs/da732x.h
new file mode 100644
index 00000000000..c8ce5475de2
--- /dev/null
+++ b/sound/soc/codecs/da732x.h
@@ -0,0 +1,133 @@
1/*
2 * da732x.h -- Dialog DA732X ALSA SoC Audio Driver Header File
3 *
4 * Copyright (C) 2012 Dialog Semiconductor GmbH
5 *
6 * Author: Michal Hajduk <Michal.Hajduk@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __DA732X_H_
14#define __DA732X_H
15
16#include <sound/soc.h>
17
18/* General */
19#define DA732X_U8_MASK 0xFF
20#define DA732X_4BYTES 4
21#define DA732X_3BYTES 3
22#define DA732X_2BYTES 2
23#define DA732X_1BYTE 1
24#define DA732X_1BYTE_SHIFT 8
25#define DA732X_2BYTES_SHIFT 16
26#define DA732X_3BYTES_SHIFT 24
27#define DA732X_4BYTES_SHIFT 32
28
29#define DA732X_DACS_DIS 0x0
30#define DA732X_HP_DIS 0x0
31#define DA732X_CLEAR_REG 0x0
32
33/* Calibration */
34#define DA732X_DAC_OFFSET_STEP 0x20
35#define DA732X_OUTPUT_OFFSET_STEP 0x80
36#define DA732X_HP_OUT_TRIM_VAL 0x0
37#define DA732X_WAIT_FOR_STABILIZATION 1
38#define DA732X_HPL_DAC 0
39#define DA732X_HPR_DAC 1
40#define DA732X_HP_DACS 2
41#define DA732X_HPL_AMP 0
42#define DA732X_HPR_AMP 1
43#define DA732X_HP_AMPS 2
44
45/* Clock settings */
46#define DA732X_STARTUP_DELAY 100
47#define DA732X_PLL_OUT_196608 196608000
48#define DA732X_PLL_OUT_180634 180633600
49#define DA732X_PLL_OUT_SRM 188620800
50#define DA732X_MCLK_10MHZ 10000000
51#define DA732X_MCLK_20MHZ 20000000
52#define DA732X_MCLK_40MHZ 40000000
53#define DA732X_MCLK_54MHZ 54000000
54#define DA732X_MCLK_RET_0_10MHZ 0
55#define DA732X_MCLK_VAL_0_10MHZ 1
56#define DA732X_MCLK_RET_10_20MHZ 1
57#define DA732X_MCLK_VAL_10_20MHZ 2
58#define DA732X_MCLK_RET_20_40MHZ 2
59#define DA732X_MCLK_VAL_20_40MHZ 4
60#define DA732X_MCLK_RET_40_54MHZ 3
61#define DA732X_MCLK_VAL_40_54MHZ 8
62#define DA732X_DAI_ID1 0
63#define DA732X_DAI_ID2 1
64#define DA732X_SRCCLK_PLL 0
65#define DA732X_SRCCLK_MCLK 1
66
67#define DA732X_LIN_LP_VOL 0x4F
68#define DA732X_LP_VOL 0x40
69
70/* Kcontrols */
71#define DA732X_DAC_EN_MAX 2
72#define DA732X_ADCL_MUX_MAX 2
73#define DA732X_ADCR_MUX_MAX 3
74#define DA732X_HPF_MODE_MAX 3
75#define DA732X_HPF_MODE_SHIFT 4
76#define DA732X_HPF_MUSIC_SHIFT 0
77#define DA732X_HPF_MUSIC_MAX 4
78#define DA732X_HPF_VOICE_SHIFT 4
79#define DA732X_HPF_VOICE_MAX 8
80#define DA732X_EQ_EN_MAX 1
81#define DA732X_HPF_VOICE 1
82#define DA732X_HPF_MUSIC 2
83#define DA732X_HPF_DISABLED 0
84#define DA732X_NO_INVERT 0
85#define DA732X_INVERT 1
86#define DA732X_SWITCH_MAX 1
87#define DA732X_ENABLE_CP 1
88#define DA732X_DISABLE_CP 0
89#define DA732X_DISABLE_ALL_CLKS 0
90#define DA732X_RESET_ADCS 0
91
92/* dB values */
93#define DA732X_MIC_VOL_DB_MIN 0
94#define DA732X_MIC_VOL_DB_INC 50
95#define DA732X_MIC_PRE_VOL_DB_MIN 0
96#define DA732X_MIC_PRE_VOL_DB_INC 600
97#define DA732X_AUX_VOL_DB_MIN -6000
98#define DA732X_AUX_VOL_DB_INC 150
99#define DA732X_HP_VOL_DB_MIN -2250
100#define DA732X_HP_VOL_DB_INC 150
101#define DA732X_LIN2_VOL_DB_MIN -1650
102#define DA732X_LIN2_VOL_DB_INC 150
103#define DA732X_LIN3_VOL_DB_MIN -1650
104#define DA732X_LIN3_VOL_DB_INC 150
105#define DA732X_LIN4_VOL_DB_MIN -2250
106#define DA732X_LIN4_VOL_DB_INC 150
107#define DA732X_EQ_BAND_VOL_DB_MIN -1050
108#define DA732X_EQ_BAND_VOL_DB_INC 150
109#define DA732X_DAC_VOL_DB_MIN -7725
110#define DA732X_DAC_VOL_DB_INC 75
111#define DA732X_ADC_VOL_DB_MIN 0
112#define DA732X_ADC_VOL_DB_INC -1
113#define DA732X_EQ_OVERALL_VOL_DB_MIN -1800
114#define DA732X_EQ_OVERALL_VOL_DB_INC 600
115
116#define DA732X_SOC_ENUM_DOUBLE_R(xreg, xrreg, xmax, xtext) \
117 {.reg = xreg, .reg2 = xrreg, .max = xmax, .texts = xtext}
118
119enum da732x_sysctl {
120 DA732X_SR_8KHZ = 0x1,
121 DA732X_SR_11_025KHZ = 0x2,
122 DA732X_SR_12KHZ = 0x3,
123 DA732X_SR_16KHZ = 0x5,
124 DA732X_SR_22_05KHZ = 0x6,
125 DA732X_SR_24KHZ = 0x7,
126 DA732X_SR_32KHZ = 0x9,
127 DA732X_SR_44_1KHZ = 0xA,
128 DA732X_SR_48KHZ = 0xB,
129 DA732X_SR_88_1KHZ = 0xE,
130 DA732X_SR_96KHZ = 0xF,
131};
132
133#endif /* __DA732X_H_ */
diff --git a/sound/soc/codecs/da732x_reg.h b/sound/soc/codecs/da732x_reg.h
new file mode 100644
index 00000000000..bdd03ca4b2d
--- /dev/null
+++ b/sound/soc/codecs/da732x_reg.h
@@ -0,0 +1,654 @@
1/*
2 * da732x_reg.h --- Dialog DA732X ALSA SoC Audio Registers Header File
3 *
4 * Copyright (C) 2012 Dialog Semiconductor GmbH
5 *
6 * Author: Michal Hajduk <Michal.Hajduk@diasemi.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef __DA732X_REG_H_
14#define __DA732X_REG_H_
15
16/* DA732X registers */
17#define DA732X_REG_STATUS_EXT 0x00
18#define DA732X_REG_STATUS 0x01
19#define DA732X_REG_REF1 0x02
20#define DA732X_REG_BIAS_EN 0x03
21#define DA732X_REG_BIAS1 0x04
22#define DA732X_REG_BIAS2 0x05
23#define DA732X_REG_BIAS3 0x06
24#define DA732X_REG_BIAS4 0x07
25#define DA732X_REG_MICBIAS2 0x0F
26#define DA732X_REG_MICBIAS1 0x10
27#define DA732X_REG_MICDET 0x11
28#define DA732X_REG_MIC1_PRE 0x12
29#define DA732X_REG_MIC1 0x13
30#define DA732X_REG_MIC2_PRE 0x14
31#define DA732X_REG_MIC2 0x15
32#define DA732X_REG_AUX1L 0x16
33#define DA732X_REG_AUX1R 0x17
34#define DA732X_REG_MIC3_PRE 0x18
35#define DA732X_REG_MIC3 0x19
36#define DA732X_REG_INP_PINBIAS 0x1A
37#define DA732X_REG_INP_ZC_EN 0x1B
38#define DA732X_REG_INP_MUX 0x1D
39#define DA732X_REG_HP_DET 0x20
40#define DA732X_REG_HPL_DAC_OFFSET 0x21
41#define DA732X_REG_HPL_DAC_OFF_CNTL 0x22
42#define DA732X_REG_HPL_OUT_OFFSET 0x23
43#define DA732X_REG_HPL 0x24
44#define DA732X_REG_HPL_VOL 0x25
45#define DA732X_REG_HPR_DAC_OFFSET 0x26
46#define DA732X_REG_HPR_DAC_OFF_CNTL 0x27
47#define DA732X_REG_HPR_OUT_OFFSET 0x28
48#define DA732X_REG_HPR 0x29
49#define DA732X_REG_HPR_VOL 0x2A
50#define DA732X_REG_LIN2 0x2B
51#define DA732X_REG_LIN3 0x2C
52#define DA732X_REG_LIN4 0x2D
53#define DA732X_REG_OUT_ZC_EN 0x2E
54#define DA732X_REG_HP_LIN1_GNDSEL 0x37
55#define DA732X_REG_CP_HP1 0x3A
56#define DA732X_REG_CP_HP2 0x3B
57#define DA732X_REG_CP_CTRL1 0x40
58#define DA732X_REG_CP_CTRL2 0x41
59#define DA732X_REG_CP_CTRL3 0x42
60#define DA732X_REG_CP_LEVEL_MASK 0x43
61#define DA732X_REG_CP_DET 0x44
62#define DA732X_REG_CP_STATUS 0x45
63#define DA732X_REG_CP_THRESH1 0x46
64#define DA732X_REG_CP_THRESH2 0x47
65#define DA732X_REG_CP_THRESH3 0x48
66#define DA732X_REG_CP_THRESH4 0x49
67#define DA732X_REG_CP_THRESH5 0x4A
68#define DA732X_REG_CP_THRESH6 0x4B
69#define DA732X_REG_CP_THRESH7 0x4C
70#define DA732X_REG_CP_THRESH8 0x4D
71#define DA732X_REG_PLL_DIV_LO 0x50
72#define DA732X_REG_PLL_DIV_MID 0x51
73#define DA732X_REG_PLL_DIV_HI 0x52
74#define DA732X_REG_PLL_CTRL 0x53
75#define DA732X_REG_CLK_CTRL 0x54
76#define DA732X_REG_CLK_DSP 0x5A
77#define DA732X_REG_CLK_EN1 0x5B
78#define DA732X_REG_CLK_EN2 0x5C
79#define DA732X_REG_CLK_EN3 0x5D
80#define DA732X_REG_CLK_EN4 0x5E
81#define DA732X_REG_CLK_EN5 0x5F
82#define DA732X_REG_AIF_MCLK 0x60
83#define DA732X_REG_AIFA1 0x61
84#define DA732X_REG_AIFA2 0x62
85#define DA732X_REG_AIFA3 0x63
86#define DA732X_REG_AIFB1 0x64
87#define DA732X_REG_AIFB2 0x65
88#define DA732X_REG_AIFB3 0x66
89#define DA732X_REG_PC_CTRL 0x6A
90#define DA732X_REG_DATA_ROUTE 0x70
91#define DA732X_REG_DSP_CTRL 0x71
92#define DA732X_REG_CIF_CTRL2 0x74
93#define DA732X_REG_HANDSHAKE 0x75
94#define DA732X_REG_MBOX0 0x76
95#define DA732X_REG_MBOX1 0x77
96#define DA732X_REG_MBOX2 0x78
97#define DA732X_REG_MBOX_STATUS 0x79
98#define DA732X_REG_SPARE1_OUT 0x7D
99#define DA732X_REG_SPARE2_OUT 0x7E
100#define DA732X_REG_SPARE1_IN 0x7F
101#define DA732X_REG_ID 0x81
102#define DA732X_REG_ADC1_PD 0x90
103#define DA732X_REG_ADC1_HPF 0x93
104#define DA732X_REG_ADC1_SEL 0x94
105#define DA732X_REG_ADC1_EQ12 0x95
106#define DA732X_REG_ADC1_EQ34 0x96
107#define DA732X_REG_ADC1_EQ5 0x97
108#define DA732X_REG_ADC2_PD 0x98
109#define DA732X_REG_ADC2_HPF 0x9B
110#define DA732X_REG_ADC2_SEL 0x9C
111#define DA732X_REG_ADC2_EQ12 0x9D
112#define DA732X_REG_ADC2_EQ34 0x9E
113#define DA732X_REG_ADC2_EQ5 0x9F
114#define DA732X_REG_DAC1_HPF 0xA0
115#define DA732X_REG_DAC1_L_VOL 0xA1
116#define DA732X_REG_DAC1_R_VOL 0xA2
117#define DA732X_REG_DAC1_SEL 0xA3
118#define DA732X_REG_DAC1_SOFTMUTE 0xA4
119#define DA732X_REG_DAC1_EQ12 0xA5
120#define DA732X_REG_DAC1_EQ34 0xA6
121#define DA732X_REG_DAC1_EQ5 0xA7
122#define DA732X_REG_DAC2_HPF 0xB0
123#define DA732X_REG_DAC2_L_VOL 0xB1
124#define DA732X_REG_DAC2_R_VOL 0xB2
125#define DA732X_REG_DAC2_SEL 0xB3
126#define DA732X_REG_DAC2_SOFTMUTE 0xB4
127#define DA732X_REG_DAC2_EQ12 0xB5
128#define DA732X_REG_DAC2_EQ34 0xB6
129#define DA732X_REG_DAC2_EQ5 0xB7
130#define DA732X_REG_DAC3_HPF 0xC0
131#define DA732X_REG_DAC3_VOL 0xC1
132#define DA732X_REG_DAC3_SEL 0xC3
133#define DA732X_REG_DAC3_SOFTMUTE 0xC4
134#define DA732X_REG_DAC3_EQ12 0xC5
135#define DA732X_REG_DAC3_EQ34 0xC6
136#define DA732X_REG_DAC3_EQ5 0xC7
137#define DA732X_REG_BIQ_BYP 0xD2
138#define DA732X_REG_DMA_CMD 0xD3
139#define DA732X_REG_DMA_ADDR0 0xD4
140#define DA732X_REG_DMA_ADDR1 0xD5
141#define DA732X_REG_DMA_DATA0 0xD6
142#define DA732X_REG_DMA_DATA1 0xD7
143#define DA732X_REG_DMA_DATA2 0xD8
144#define DA732X_REG_DMA_DATA3 0xD9
145#define DA732X_REG_DMA_STATUS 0xDA
146#define DA732X_REG_BROWNOUT 0xDF
147#define DA732X_REG_UNLOCK 0xE0
148
149#define DA732X_MAX_REG DA732X_REG_UNLOCK
150/*
151 * Bits
152 */
153
154/* DA732X_REG_STATUS_EXT (addr=0x00) */
155#define DA732X_STATUS_EXT_DSP (1 << 4)
156#define DA732X_STATUS_EXT_CLEAR (0 << 0)
157
158/* DA732X_REG_STATUS (addr=0x01) */
159#define DA732X_STATUS_PLL_LOCK (1 << 0)
160#define DA732X_STATUS_PLL_MCLK_DET (1 << 1)
161#define DA732X_STATUS_HPDET_OUT (1 << 2)
162#define DA732X_STATUS_INP_MIXDET_1 (1 << 3)
163#define DA732X_STATUS_INP_MIXDET_2 (1 << 4)
164#define DA732X_STATUS_BO_STATUS (1 << 5)
165
166/* DA732X_REG_REF1 (addr=0x02) */
167#define DA732X_VMID_FASTCHG (1 << 1)
168#define DA732X_VMID_FASTDISCHG (1 << 2)
169#define DA732X_REFBUFX2_EN (1 << 6)
170#define DA732X_REFBUFX2_DIS (0 << 6)
171
172/* DA732X_REG_BIAS_EN (addr=0x03) */
173#define DA732X_BIAS_BOOST_MASK (3 << 0)
174#define DA732X_BIAS_BOOST_100PC (0 << 0)
175#define DA732X_BIAS_BOOST_133PC (1 << 0)
176#define DA732X_BIAS_BOOST_88PC (2 << 0)
177#define DA732X_BIAS_BOOST_50PC (3 << 0)
178#define DA732X_BIAS_EN (1 << 7)
179#define DA732X_BIAS_DIS (0 << 7)
180
181/* DA732X_REG_BIAS1 (addr=0x04) */
182#define DA732X_BIAS1_HP_DAC_BIAS_MASK (3 << 0)
183#define DA732X_BIAS1_HP_DAC_BIAS_100PC (0 << 0)
184#define DA732X_BIAS1_HP_DAC_BIAS_150PC (1 << 0)
185#define DA732X_BIAS1_HP_DAC_BIAS_50PC (2 << 0)
186#define DA732X_BIAS1_HP_DAC_BIAS_75PC (3 << 0)
187#define DA732X_BIAS1_HP_OUT_BIAS_MASK (7 << 4)
188#define DA732X_BIAS1_HP_OUT_BIAS_100PC (0 << 4)
189#define DA732X_BIAS1_HP_OUT_BIAS_125PC (1 << 4)
190#define DA732X_BIAS1_HP_OUT_BIAS_150PC (2 << 4)
191#define DA732X_BIAS1_HP_OUT_BIAS_175PC (3 << 4)
192#define DA732X_BIAS1_HP_OUT_BIAS_200PC (4 << 4)
193#define DA732X_BIAS1_HP_OUT_BIAS_250PC (5 << 4)
194#define DA732X_BIAS1_HP_OUT_BIAS_300PC (6 << 4)
195#define DA732X_BIAS1_HP_OUT_BIAS_350PC (7 << 4)
196
197/* DA732X_REG_BIAS2 (addr=0x05) */
198#define DA732X_BIAS2_LINE2_DAC_BIAS_MASK (3 << 0)
199#define DA732X_BIAS2_LINE2_DAC_BIAS_100PC (0 << 0)
200#define DA732X_BIAS2_LINE2_DAC_BIAS_150PC (1 << 0)
201#define DA732X_BIAS2_LINE2_DAC_BIAS_50PC (2 << 0)
202#define DA732X_BIAS2_LINE2_DAC_BIAS_75PC (3 << 0)
203#define DA732X_BIAS2_LINE2_OUT_BIAS_MASK (7 << 4)
204#define DA732X_BIAS2_LINE2_OUT_BIAS_100PC (0 << 4)
205#define DA732X_BIAS2_LINE2_OUT_BIAS_125PC (1 << 4)
206#define DA732X_BIAS2_LINE2_OUT_BIAS_150PC (2 << 4)
207#define DA732X_BIAS2_LINE2_OUT_BIAS_175PC (3 << 4)
208#define DA732X_BIAS2_LINE2_OUT_BIAS_200PC (4 << 4)
209#define DA732X_BIAS2_LINE2_OUT_BIAS_250PC (5 << 4)
210#define DA732X_BIAS2_LINE2_OUT_BIAS_300PC (6 << 4)
211#define DA732X_BIAS2_LINE2_OUT_BIAS_350PC (7 << 4)
212
213/* DA732X_REG_BIAS3 (addr=0x06) */
214#define DA732X_BIAS3_LINE3_DAC_BIAS_MASK (3 << 0)
215#define DA732X_BIAS3_LINE3_DAC_BIAS_100PC (0 << 0)
216#define DA732X_BIAS3_LINE3_DAC_BIAS_150PC (1 << 0)
217#define DA732X_BIAS3_LINE3_DAC_BIAS_50PC (2 << 0)
218#define DA732X_BIAS3_LINE3_DAC_BIAS_75PC (3 << 0)
219#define DA732X_BIAS3_LINE3_OUT_BIAS_MASK (7 << 4)
220#define DA732X_BIAS3_LINE3_OUT_BIAS_100PC (0 << 4)
221#define DA732X_BIAS3_LINE3_OUT_BIAS_125PC (1 << 4)
222#define DA732X_BIAS3_LINE3_OUT_BIAS_150PC (2 << 4)
223#define DA732X_BIAS3_LINE3_OUT_BIAS_175PC (3 << 4)
224#define DA732X_BIAS3_LINE3_OUT_BIAS_200PC (4 << 4)
225#define DA732X_BIAS3_LINE3_OUT_BIAS_250PC (5 << 4)
226#define DA732X_BIAS3_LINE3_OUT_BIAS_300PC (6 << 4)
227#define DA732X_BIAS3_LINE3_OUT_BIAS_350PC (7 << 4)
228
229/* DA732X_REG_BIAS4 (addr=0x07) */
230#define DA732X_BIAS4_LINE4_DAC_BIAS_MASK (3 << 0)
231#define DA732X_BIAS4_LINE4_DAC_BIAS_100PC (0 << 0)
232#define DA732X_BIAS4_LINE4_DAC_BIAS_150PC (1 << 0)
233#define DA732X_BIAS4_LINE4_DAC_BIAS_50PC (2 << 0)
234#define DA732X_BIAS4_LINE4_DAC_BIAS_75PC (3 << 0)
235#define DA732X_BIAS4_LINE4_OUT_BIAS_MASK (7 << 4)
236#define DA732X_BIAS4_LINE4_OUT_BIAS_100PC (0 << 4)
237#define DA732X_BIAS4_LINE4_OUT_BIAS_125PC (1 << 4)
238#define DA732X_BIAS4_LINE4_OUT_BIAS_150PC (2 << 4)
239#define DA732X_BIAS4_LINE4_OUT_BIAS_175PC (3 << 4)
240#define DA732X_BIAS4_LINE4_OUT_BIAS_200PC (4 << 4)
241#define DA732X_BIAS4_LINE4_OUT_BIAS_250PC (5 << 4)
242#define DA732X_BIAS4_LINE4_OUT_BIAS_300PC (6 << 4)
243#define DA732X_BIAS4_LINE4_OUT_BIAS_350PC (7 << 4)
244
245/* DA732X_REG_SIF_VDD_SEL (addr=0x08) */
246#define DA732X_SIF_VDD_SEL_AIFA_VDD2 (1 << 0)
247#define DA732X_SIF_VDD_SEL_AIFB_VDD2 (1 << 1)
248#define DA732X_SIF_VDD_SEL_CIFA_VDD2 (1 << 4)
249
250/* DA732X_REG_MICBIAS2/1 (addr=0x0F/0x10) */
251#define DA732X_MICBIAS_VOLTAGE_MASK (0x0F << 0)
252#define DA732X_MICBIAS_VOLTAGE_2V (0x00 << 0)
253#define DA732X_MICBIAS_VOLTAGE_2V05 (0x01 << 0)
254#define DA732X_MICBIAS_VOLTAGE_2V1 (0x02 << 0)
255#define DA732X_MICBIAS_VOLTAGE_2V15 (0x03 << 0)
256#define DA732X_MICBIAS_VOLTAGE_2V2 (0x04 << 0)
257#define DA732X_MICBIAS_VOLTAGE_2V25 (0x05 << 0)
258#define DA732X_MICBIAS_VOLTAGE_2V3 (0x06 << 0)
259#define DA732X_MICBIAS_VOLTAGE_2V35 (0x07 << 0)
260#define DA732X_MICBIAS_VOLTAGE_2V4 (0x08 << 0)
261#define DA732X_MICBIAS_VOLTAGE_2V45 (0x09 << 0)
262#define DA732X_MICBIAS_VOLTAGE_2V5 (0x0A << 0)
263#define DA732X_MICBIAS_EN (1 << 7)
264#define DA732X_MICBIAS_EN_SHIFT 7
265#define DA732X_MICBIAS_VOLTAGE_SHIFT 0
266#define DA732X_MICBIAS_VOLTAGE_MAX 0x0B
267
268/* DA732X_REG_MICDET (addr=0x11) */
269#define DA732X_MICDET_INP_MICRES (1 << 0)
270#define DA732X_MICDET_INP_MICHOOK (1 << 1)
271#define DA732X_MICDET_INP_DEBOUNCE_PRD_8MS (0 << 0)
272#define DA732X_MICDET_INP_DEBOUNCE_PRD_16MS (1 << 0)
273#define DA732X_MICDET_INP_DEBOUNCE_PRD_32MS (2 << 0)
274#define DA732X_MICDET_INP_DEBOUNCE_PRD_64MS (3 << 0)
275#define DA732X_MICDET_INP_MICDET_EN (1 << 7)
276
277/* DA732X_REG_MIC1/2/3_PRE (addr=0x11/0x14/0x18) */
278#define DA732X_MICBOOST_MASK 0x7
279#define DA732X_MICBOOST_SHIFT 0
280#define DA732X_MICBOOST_MIN 0x1
281#define DA732X_MICBOOST_MAX DA732X_MICBOOST_MASK
282
283/* DA732X_REG_MIC1/2/3 (addr=0x13/0x15/0x19) */
284#define DA732X_MIC_VOL_SHIFT 0
285#define DA732X_MIC_VOL_VAL_MASK 0x1F
286#define DA732X_MIC_MUTE_SHIFT 6
287#define DA732X_MIC_EN_SHIFT 7
288#define DA732X_MIC_VOL_VAL_MIN 0x7
289#define DA732X_MIC_VOL_VAL_MAX DA732X_MIC_VOL_VAL_MASK
290
291/* DA732X_REG_AUX1L/R (addr=0x16/0x17) */
292#define DA732X_AUX_VOL_SHIFT 0
293#define DA732X_AUX_VOL_MASK 0x7
294#define DA732X_AUX_MUTE_SHIFT 6
295#define DA732X_AUX_EN_SHIFT 7
296#define DA732X_AUX_VOL_VAL_MAX DA732X_AUX_VOL_MASK
297
298/* DA732X_REG_INP_PINBIAS (addr=0x1A) */
299#define DA732X_INP_MICL_PINBIAS_EN (1 << 0)
300#define DA732X_INP_MICR_PINBIAS_EN (1 << 1)
301#define DA732X_INP_AUX1L_PINBIAS_EN (1 << 2)
302#define DA732X_INP_AUX1R_PINBIAS_EN (1 << 3)
303#define DA732X_INP_AUX2_PINBIAS_EN (1 << 4)
304
305/* DA732X_REG_INP_ZC_EN (addr=0x1B) */
306#define DA732X_MIC1_PRE_ZC_EN (1 << 0)
307#define DA732X_MIC1_ZC_EN (1 << 1)
308#define DA732X_MIC2_PRE_ZC_EN (1 << 2)
309#define DA732X_MIC2_ZC_EN (1 << 3)
310#define DA732X_AUXL_ZC_EN (1 << 4)
311#define DA732X_AUXR_ZC_EN (1 << 5)
312#define DA732X_MIC3_PRE_ZC_EN (1 << 6)
313#define DA732X_MIC3_ZC_EN (1 << 7)
314
315/* DA732X_REG_INP_MUX (addr=0x1D) */
316#define DA732X_INP_ADC1L_MUX_SEL_AUX1L (0 << 0)
317#define DA732X_INP_ADC1L_MUX_SEL_MIC1 (1 << 0)
318#define DA732X_INP_ADC1R_MUX_SEL_MASK (3 << 2)
319#define DA732X_INP_ADC1R_MUX_SEL_AUX1R (0 << 2)
320#define DA732X_INP_ADC1R_MUX_SEL_MIC2 (1 << 2)
321#define DA732X_INP_ADC1R_MUX_SEL_MIC3 (2 << 2)
322#define DA732X_INP_ADC2L_MUX_SEL_AUX1L (0 << 4)
323#define DA732X_INP_ADC2L_MUX_SEL_MICL (1 << 4)
324#define DA732X_INP_ADC2R_MUX_SEL_MASK (3 << 6)
325#define DA732X_INP_ADC2R_MUX_SEL_AUX1R (0 << 6)
326#define DA732X_INP_ADC2R_MUX_SEL_MICR (1 << 6)
327#define DA732X_INP_ADC2R_MUX_SEL_AUX2 (2 << 6)
328#define DA732X_ADC1L_MUX_SEL_SHIFT 0
329#define DA732X_ADC1R_MUX_SEL_SHIFT 2
330#define DA732X_ADC2L_MUX_SEL_SHIFT 4
331#define DA732X_ADC2R_MUX_SEL_SHIFT 6
332
333/* DA732X_REG_HP_DET (addr=0x20) */
334#define DA732X_HP_DET_AZ (1 << 0)
335#define DA732X_HP_DET_SEL1 (1 << 1)
336#define DA732X_HP_DET_IS_MASK (3 << 2)
337#define DA732X_HP_DET_IS_0_5UA (0 << 2)
338#define DA732X_HP_DET_IS_1UA (1 << 2)
339#define DA732X_HP_DET_IS_2UA (2 << 2)
340#define DA732X_HP_DET_IS_4UA (3 << 2)
341#define DA732X_HP_DET_RS_MASK (3 << 4)
342#define DA732X_HP_DET_RS_INFINITE (0 << 4)
343#define DA732X_HP_DET_RS_100KOHM (1 << 4)
344#define DA732X_HP_DET_RS_10KOHM (2 << 4)
345#define DA732X_HP_DET_RS_1KOHM (3 << 4)
346#define DA732X_HP_DET_EN (1 << 7)
347
348/* DA732X_REG_HPL_DAC_OFFSET (addr=0x21/0x26) */
349#define DA732X_HP_DAC_OFFSET_TRIM_MASK (0x3F << 0)
350#define DA732X_HP_DAC_OFFSET_DAC_SIGN (1 << 6)
351
352/* DA732X_REG_HPL_DAC_OFF_CNTL (addr=0x22/0x27) */
353#define DA732X_HP_DAC_OFF_CNTL_CONT_MASK (7 << 0)
354#define DA732X_HP_DAC_OFF_CNTL_COMPO (1 << 3)
355#define DA732X_HP_DAC_OFF_CALIBRATION (1 << 0)
356#define DA732X_HP_DAC_OFF_SCALE_STEPS (1 << 1)
357#define DA732X_HP_DAC_OFF_MASK 0x7F
358#define DA732X_HP_DAC_COMPO_SHIFT 3
359
360/* DA732X_REG_HPL_OUT_OFFSET (addr=0x23/0x28) */
361#define DA732X_HP_OUT_OFFSET_MASK (0xFF << 0)
362#define DA732X_HP_DAC_OFFSET_TRIM_VAL 0x7F
363
364/* DA732X_REG_HPL/R (addr=0x24/0x29) */
365#define DA732X_HP_OUT_SIGN (1 << 0)
366#define DA732X_HP_OUT_COMP (1 << 1)
367#define DA732X_HP_OUT_RESERVED (1 << 2)
368#define DA732X_HP_OUT_COMPO (1 << 3)
369#define DA732X_HP_OUT_DAC_EN (1 << 4)
370#define DA732X_HP_OUT_HIZ_EN (1 << 5)
371#define DA732X_HP_OUT_HIZ_DIS (0 << 5)
372#define DA732X_HP_OUT_MUTE (1 << 6)
373#define DA732X_HP_OUT_EN (1 << 7)
374#define DA732X_HP_OUT_COMPO_SHIFT 3
375#define DA732X_HP_OUT_DAC_EN_SHIFT 4
376#define DA732X_HP_HIZ_SHIFT 5
377#define DA732X_HP_MUTE_SHIFT 6
378#define DA732X_HP_OUT_EN_SHIFT 7
379
380#define DA732X_OUT_HIZ_EN (1 << 5)
381#define DA732X_OUT_HIZ_DIS (0 << 5)
382
383/* DA732X_REG_HPL/R_VOL (addr=0x25/0x2A) */
384#define DA732X_HP_VOL_VAL_MASK 0xF
385#define DA732X_HP_VOL_SHIFT 0
386#define DA732X_HP_VOL_VAL_MAX DA732X_HP_VOL_VAL_MASK
387
388/* DA732X_REG_LIN2/3/4 (addr=0x2B/0x2C/0x2D) */
389#define DA732X_LOUT_VOL_SHIFT 0
390#define DA732X_LOUT_VOL_MASK 0x0F
391#define DA732X_LOUT_DAC_OFF (0 << 4)
392#define DA732X_LOUT_DAC_EN (1 << 4)
393#define DA732X_LOUT_HIZ_N_DIS (0 << 5)
394#define DA732X_LOUT_HIZ_N_EN (1 << 5)
395#define DA732X_LOUT_UNMUTED (0 << 6)
396#define DA732X_LOUT_MUTED (1 << 6)
397#define DA732X_LOUT_EN (0 << 7)
398#define DA732X_LOUT_DIS (1 << 7)
399#define DA732X_LOUT_DAC_EN_SHIFT 4
400#define DA732X_LOUT_MUTE_SHIFT 6
401#define DA732X_LIN_OUT_EN_SHIFT 7
402#define DA732X_LOUT_VOL_VAL_MAX DA732X_LOUT_VOL_MASK
403
404/* DA732X_REG_OUT_ZC_EN (addr=0x2E) */
405#define DA732X_HPL_ZC_EN_SHIFT 0
406#define DA732X_HPR_ZC_EN_SHIFT 1
407#define DA732X_HPL_ZC_EN (1 << 0)
408#define DA732X_HPL_ZC_DIS (0 << 0)
409#define DA732X_HPR_ZC_EN (1 << 1)
410#define DA732X_HPR_ZC_DIS (0 << 1)
411#define DA732X_LIN2_ZC_EN (1 << 2)
412#define DA732X_LIN2_ZC_DIS (0 << 2)
413#define DA732X_LIN3_ZC_EN (1 << 3)
414#define DA732X_LIN3_ZC_DIS (0 << 3)
415#define DA732X_LIN4_ZC_EN (1 << 4)
416#define DA732X_LIN4_ZC_DIS (0 << 4)
417
418/* DA732X_REG_HP_LIN1_GNDSEL (addr=0x37) */
419#define DA732X_HP_OUT_GNDSEL (1 << 0)
420
421/* DA732X_REG_CP_HP2 (addr=0x3a) */
422#define DA732X_HP_CP_PULSESKIP (1 << 0)
423#define DA732X_HP_CP_REG (1 << 1)
424#define DA732X_HP_CP_EN (1 << 3)
425#define DA732X_HP_CP_DIS (0 << 3)
426
427/* DA732X_REG_CP_CTRL1 (addr=0x40) */
428#define DA732X_CP_MODE_MASK (7 << 1)
429#define DA732X_CP_CTRL_STANDBY (0 << 1)
430#define DA732X_CP_CTRL_CPVDD6 (2 << 1)
431#define DA732X_CP_CTRL_CPVDD5 (3 << 1)
432#define DA732X_CP_CTRL_CPVDD4 (4 << 1)
433#define DA732X_CP_CTRL_CPVDD3 (5 << 1)
434#define DA732X_CP_CTRL_CPVDD2 (6 << 1)
435#define DA732X_CP_CTRL_CPVDD1 (7 << 1)
436#define DA723X_CP_DIS (0 << 7)
437#define DA732X_CP_EN (1 << 7)
438
439/* DA732X_REG_CP_CTRL2 (addr=0x41) */
440#define DA732X_CP_BOOST (1 << 0)
441#define DA732X_CP_MANAGE_MAGNITUDE (2 << 2)
442
443/* DA732X_REG_CP_CTRL3 (addr=0x42) */
444#define DA732X_CP_1MHZ (0 << 0)
445#define DA732X_CP_500KHZ (1 << 0)
446#define DA732X_CP_250KHZ (2 << 0)
447#define DA732X_CP_125KHZ (3 << 0)
448#define DA732X_CP_63KHZ (4 << 0)
449#define DA732X_CP_0KHZ (5 << 0)
450
451/* DA732X_REG_PLL_CTRL (addr=0x53) */
452#define DA732X_PLL_INDIV_MASK (3 << 0)
453#define DA732X_PLL_SRM_EN (1 << 2)
454#define DA732X_PLL_EN (1 << 7)
455#define DA732X_PLL_BYPASS (0 << 0)
456
457/* DA732X_REG_CLK_CTRL (addr=0x54) */
458#define DA732X_SR1_MASK (0xF)
459#define DA732X_SR2_MASK (0xF0)
460
461/* DA732X_REG_CLK_DSP (addr=0x5A) */
462#define DA732X_DSP_FREQ_MASK (7 << 0)
463#define DA732X_DSP_FREQ_12MHZ (0 << 0)
464#define DA732X_DSP_FREQ_24MHZ (1 << 0)
465#define DA732X_DSP_FREQ_36MHZ (2 << 0)
466#define DA732X_DSP_FREQ_48MHZ (3 << 0)
467#define DA732X_DSP_FREQ_60MHZ (4 << 0)
468#define DA732X_DSP_FREQ_72MHZ (5 << 0)
469#define DA732X_DSP_FREQ_84MHZ (6 << 0)
470#define DA732X_DSP_FREQ_96MHZ (7 << 0)
471
472/* DA732X_REG_CLK_EN1 (addr=0x5B) */
473#define DA732X_DSP_CLK_EN (1 << 0)
474#define DA732X_SYS3_CLK_EN (1 << 1)
475#define DA732X_DSP12_CLK_EN (1 << 2)
476#define DA732X_PC_CLK_EN (1 << 3)
477#define DA732X_MCLK_SQR_EN (1 << 7)
478
479/* DA732X_REG_CLK_EN2 (addr=0x5C) */
480#define DA732X_UART_CLK_EN (1 << 1)
481#define DA732X_CP_CLK_EN (1 << 2)
482#define DA732X_CP_CLK_DIS (0 << 2)
483
484/* DA732X_REG_CLK_EN3 (addr=0x5D) */
485#define DA732X_ADCA_BB_CLK_EN (1 << 0)
486#define DA732X_ADCC_BB_CLK_EN (1 << 4)
487
488/* DA732X_REG_CLK_EN4 (addr=0x5E) */
489#define DA732X_DACA_BB_CLK_EN (1 << 0)
490#define DA732X_DACC_BB_CLK_EN (1 << 4)
491#define DA732X_DACA_BB_CLK_SHIFT 0
492#define DA732X_DACC_BB_CLK_SHIFT 4
493
494/* DA732X_REG_CLK_EN5 (addr=0x5F) */
495#define DA732X_DACE_BB_CLK_EN (1 << 0)
496#define DA732X_DACE_BB_CLK_SHIFT 0
497
498/* DA732X_REG_AIF_MCLK (addr=0x60) */
499#define DA732X_AIFM_FRAME_64 (1 << 2)
500#define DA732X_AIFM_SRC_SEL_AIFA (1 << 6)
501#define DA732X_CLK_GENERATION_AIF_A (1 << 4)
502#define DA732X_NO_CLK_GENERATION 0x0
503
504/* DA732X_REG_AIFA1 (addr=0x61) */
505#define DA732X_AIF_WORD_MASK (0x3 << 0)
506#define DA732X_AIF_WORD_16 (0 << 0)
507#define DA732X_AIF_WORD_20 (1 << 0)
508#define DA732X_AIF_WORD_24 (2 << 0)
509#define DA732X_AIF_WORD_32 (3 << 0)
510#define DA732X_AIF_TDM_MONO_SHIFT (1 << 6)
511#define DA732X_AIF1_CLK_MASK (1 << 7)
512#define DA732X_AIF_SLAVE (0 << 7)
513#define DA732X_AIF_CLK_FROM_SRC (1 << 7)
514
515/* DA732X_REG_AIFA3 (addr=0x63) */
516#define DA732X_AIF_MODE_SHIFT 0
517#define DA732X_AIF_MODE_MASK 0x3
518#define DA732X_AIF_I2S_MODE (0 << 0)
519#define DA732X_AIF_LEFT_J_MODE (1 << 0)
520#define DA732X_AIF_RIGHT_J_MODE (2 << 0)
521#define DA732X_AIF_DSP_MODE (3 << 0)
522#define DA732X_AIF_WCLK_INV (1 << 4)
523#define DA732X_AIF_BCLK_INV (1 << 5)
524#define DA732X_AIF_EN (1 << 7)
525#define DA732X_AIF_EN_SHIFT 7
526
527/* DA732X_REG_PC_CTRL (addr=0x6a) */
528#define DA732X_PC_PULSE_AIFA (0 << 0)
529#define DA732X_PC_PULSE_AIFB (1 << 0)
530#define DA732X_PC_RESYNC_AUT (1 << 6)
531#define DA732X_PC_RESYNC_NOT_AUT (0 << 6)
532#define DA732X_PC_SAME (1 << 7)
533
534/* DA732X_REG_DATA_ROUTE (addr=0x70) */
535#define DA732X_ADC1_TO_AIFA (0 << 0)
536#define DA732X_DSP_TO_AIFA (1 << 0)
537#define DA732X_ADC2_TO_AIFB (0 << 1)
538#define DA732X_DSP_TO_AIFB (1 << 1)
539#define DA732X_AIFA_TO_DAC1L (0 << 2)
540#define DA732X_DSP_TO_DAC1L (1 << 2)
541#define DA732X_AIFA_TO_DAC1R (0 << 3)
542#define DA732X_DSP_TO_DAC1R (1 << 3)
543#define DA732X_AIFB_TO_DAC2L (0 << 4)
544#define DA732X_DSP_TO_DAC2L (1 << 4)
545#define DA732X_AIFB_TO_DAC2R (0 << 5)
546#define DA732X_DSP_TO_DAC2R (1 << 5)
547#define DA732X_AIFB_TO_DAC3 (0 << 6)
548#define DA732X_DSP_TO_DAC3 (1 << 6)
549#define DA732X_BYPASS_DSP (0 << 0)
550#define DA732X_ALL_TO_DSP (0x7F << 0)
551
552/* DA732X_REG_DSP_CTRL (addr=0x71) */
553#define DA732X_DIGITAL_EN (1 << 0)
554#define DA732X_DIGITAL_RESET (0 << 0)
555#define DA732X_DSP_CORE_EN (1 << 1)
556#define DA732X_DSP_CORE_RESET (0 << 1)
557
558/* DA732X_REG_SPARE1_OUT (addr=0x7D)*/
559#define DA732X_HP_DRIVER_EN (1 << 0)
560#define DA732X_HP_GATE_LOW (1 << 2)
561#define DA732X_HP_LOOP_GAIN_CTRL (1 << 3)
562
563/* DA732X_REG_ID (addr=0x81)*/
564#define DA732X_ID_MINOR_MASK (0xF << 0)
565#define DA732X_ID_MAJOR_MASK (0xF << 4)
566
567/* DA732X_REG_ADC1/2_PD (addr=0x90/0x98) */
568#define DA732X_ADC_RST_MASK (0x3 << 0)
569#define DA732X_ADC_PD_MASK (0x3 << 2)
570#define DA732X_ADC_SET_ACT (0x3 << 0)
571#define DA732X_ADC_SET_RST (0x0 << 0)
572#define DA732X_ADC_ON (0x3 << 2)
573#define DA732X_ADC_OFF (0x0 << 2)
574
575/* DA732X_REG_ADC1/2_SEL (addr=0x94/0x9C) */
576#define DA732X_ADC_VOL_VAL_MASK 0x7
577#define DA732X_ADCL_VOL_SHIFT 0
578#define DA732X_ADCR_VOL_SHIFT 4
579#define DA732X_ADCL_EN_SHIFT 2
580#define DA732X_ADCR_EN_SHIFT 3
581#define DA732X_ADCL_EN (1 << 2)
582#define DA732X_ADCR_EN (1 << 3)
583#define DA732X_ADC_VOL_VAL_MAX DA732X_ADC_VOL_VAL_MASK
584
585/*
586 * DA732X_REG_ADC1/2_HPF (addr=0x93/0x9b)
587 * DA732x_REG_DAC1/2/3_HPG (addr=0xA5/0xB5/0xC5)
588 */
589#define DA732X_HPF_MUSIC_EN (1 << 3)
590#define DA732X_HPF_VOICE_EN ((1 << 3) | (1 << 7))
591#define DA732X_HPF_MASK ((1 << 3) | (1 << 7))
592#define DA732X_HPF_DIS ((0 << 3) | (0 << 7))
593
594/* DA732X_REG_DAC1/2/3_VOL */
595#define DA732X_DAC_VOL_VAL_MASK 0x7F
596#define DA732X_DAC_VOL_SHIFT 0
597#define DA732X_DAC_VOL_VAL_MAX DA732X_DAC_VOL_VAL_MASK
598
599/* DA732X_REG_DAC1/2/3_SEL (addr=0xA3/0xB3/0xC3) */
600#define DA732X_DACL_EN_SHIFT 3
601#define DA732X_DACR_EN_SHIFT 7
602#define DA732X_DACL_MUTE_SHIFT 2
603#define DA732X_DACR_MUTE_SHIFT 6
604#define DA732X_DACL_EN (1 << 3)
605#define DA732X_DACR_EN (1 << 7)
606#define DA732X_DACL_SDM (1 << 0)
607#define DA732X_DACR_SDM (1 << 4)
608#define DA732X_DACL_MUTE (1 << 2)
609#define DA732X_DACR_MUTE (1 << 6)
610
611/* DA732X_REG_DAC_SOFTMUTE (addr=0xA4/0xB4/0xC4) */
612#define DA732X_SOFTMUTE_EN (1 << 7)
613#define DA732X_GAIN_RAMPED (1 << 6)
614#define DA732X_16_SAMPLES (4 << 0)
615#define DA732X_SOFTMUTE_MASK (1 << 7)
616#define DA732X_SOFTMUTE_SHIFT 7
617
618/*
619 * DA732x_REG_ADC1/2_EQ12 (addr=0x95/0x9D)
620 * DA732x_REG_ADC1/2_EQ34 (addr=0x96/0x9E)
621 * DA732x_REG_ADC1/2_EQ5 (addr=0x97/0x9F)
622 * DA732x_REG_DAC1/2/3_EQ12 (addr=0xA5/0xB5/0xC5)
623 * DA732x_REG_DAC1/2/3_EQ34 (addr=0xA6/0xB6/0xC6)
624 * DA732x_REG_DAC1/2/3_EQ5 (addr=0xA7/0xB7/0xB7)
625 */
626#define DA732X_EQ_VOL_VAL_MASK 0xF
627#define DA732X_EQ_BAND1_SHIFT 0
628#define DA732X_EQ_BAND2_SHIFT 4
629#define DA732X_EQ_BAND3_SHIFT 0
630#define DA732X_EQ_BAND4_SHIFT 4
631#define DA732X_EQ_BAND5_SHIFT 0
632#define DA732X_EQ_OVERALL_SHIFT 4
633#define DA732X_EQ_OVERALL_VOL_VAL_MASK 0x3
634#define DA732X_EQ_DIS (0 << 7)
635#define DA732X_EQ_EN (1 << 7)
636#define DA732X_EQ_EN_SHIFT 7
637#define DA732X_EQ_VOL_VAL_MAX DA732X_EQ_VOL_VAL_MASK
638#define DA732X_EQ_OVERALL_VOL_VAL_MAX DA732X_EQ_OVERALL_VOL_VAL_MASK
639
640/* DA732X_REG_DMA_CMD (addr=0xD3) */
641#define DA732X_SEL_DSP_DMA_MASK (3 << 0)
642#define DA732X_SEL_DSP_DMA_DIS (0 << 0)
643#define DA732X_SEL_DSP_DMA_PMEM (1 << 0)
644#define DA732X_SEL_DSP_DMA_XMEM (2 << 0)
645#define DA732X_SEL_DSP_DMA_YMEM (3 << 0)
646#define DA732X_DSP_RW_MASK (1 << 4)
647#define DA732X_DSP_DMA_WRITE (0 << 4)
648#define DA732X_DSP_DMA_READ (1 << 4)
649
650/* DA732X_REG_DMA_STATUS (addr=0xDA) */
651#define DA732X_DSP_DMA_FREE (0 << 0)
652#define DA732X_DSP_DMA_BUSY (1 << 0)
653
654#endif /* __DA732X_REG_H_ */
diff --git a/sound/soc/codecs/isabelle.c b/sound/soc/codecs/isabelle.c
new file mode 100644
index 00000000000..5d8f39e3297
--- /dev/null
+++ b/sound/soc/codecs/isabelle.c
@@ -0,0 +1,1176 @@
1/*
2 * isabelle.c - Low power high fidelity audio codec driver
3 *
4 * Copyright (c) 2012 Texas Instruments, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 *
11 * Initially based on sound/soc/codecs/twl6040.c
12 *
13 */
14#include <linux/module.h>
15#include <linux/moduleparam.h>
16#include <linux/version.h>
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/delay.h>
20#include <linux/pm.h>
21#include <linux/regmap.h>
22#include <linux/i2c.h>
23#include <linux/slab.h>
24#include <sound/core.h>
25#include <sound/pcm.h>
26#include <sound/pcm_params.h>
27#include <sound/soc.h>
28#include <sound/soc-dapm.h>
29#include <sound/tlv.h>
30#include <sound/jack.h>
31#include <sound/initval.h>
32#include <asm/div64.h>
33#include "isabelle.h"
34
35
36/* Register default values for ISABELLE driver. */
37static struct reg_default isabelle_reg_defs[] = {
38 { 0, 0x00 },
39 { 1, 0x00 },
40 { 2, 0x00 },
41 { 3, 0x00 },
42 { 4, 0x00 },
43 { 5, 0x00 },
44 { 6, 0x00 },
45 { 7, 0x00 },
46 { 8, 0x00 },
47 { 9, 0x00 },
48 { 10, 0x00 },
49 { 11, 0x00 },
50 { 12, 0x00 },
51 { 13, 0x00 },
52 { 14, 0x00 },
53 { 15, 0x00 },
54 { 16, 0x00 },
55 { 17, 0x00 },
56 { 18, 0x00 },
57 { 19, 0x00 },
58 { 20, 0x00 },
59 { 21, 0x02 },
60 { 22, 0x02 },
61 { 23, 0x02 },
62 { 24, 0x02 },
63 { 25, 0x0F },
64 { 26, 0x8F },
65 { 27, 0x0F },
66 { 28, 0x8F },
67 { 29, 0x00 },
68 { 30, 0x00 },
69 { 31, 0x00 },
70 { 32, 0x00 },
71 { 33, 0x00 },
72 { 34, 0x00 },
73 { 35, 0x00 },
74 { 36, 0x00 },
75 { 37, 0x00 },
76 { 38, 0x00 },
77 { 39, 0x00 },
78 { 40, 0x00 },
79 { 41, 0x00 },
80 { 42, 0x00 },
81 { 43, 0x00 },
82 { 44, 0x00 },
83 { 45, 0x00 },
84 { 46, 0x00 },
85 { 47, 0x00 },
86 { 48, 0x00 },
87 { 49, 0x00 },
88 { 50, 0x00 },
89 { 51, 0x00 },
90 { 52, 0x00 },
91 { 53, 0x00 },
92 { 54, 0x00 },
93 { 55, 0x00 },
94 { 56, 0x00 },
95 { 57, 0x00 },
96 { 58, 0x00 },
97 { 59, 0x00 },
98 { 60, 0x00 },
99 { 61, 0x00 },
100 { 62, 0x00 },
101 { 63, 0x00 },
102 { 64, 0x00 },
103 { 65, 0x00 },
104 { 66, 0x00 },
105 { 67, 0x00 },
106 { 68, 0x00 },
107 { 69, 0x90 },
108 { 70, 0x90 },
109 { 71, 0x90 },
110 { 72, 0x00 },
111 { 73, 0x00 },
112 { 74, 0x00 },
113 { 75, 0x00 },
114 { 76, 0x00 },
115 { 77, 0x00 },
116 { 78, 0x00 },
117 { 79, 0x00 },
118 { 80, 0x00 },
119 { 81, 0x00 },
120 { 82, 0x00 },
121 { 83, 0x00 },
122 { 84, 0x00 },
123 { 85, 0x07 },
124 { 86, 0x00 },
125 { 87, 0x00 },
126 { 88, 0x00 },
127 { 89, 0x07 },
128 { 90, 0x80 },
129 { 91, 0x07 },
130 { 92, 0x07 },
131 { 93, 0x00 },
132 { 94, 0x00 },
133 { 95, 0x00 },
134 { 96, 0x00 },
135 { 97, 0x00 },
136 { 98, 0x00 },
137 { 99, 0x00 },
138};
139
140static const char *isabelle_rx1_texts[] = {"VRX1", "ARX1"};
141static const char *isabelle_rx2_texts[] = {"VRX2", "ARX2"};
142
143static const struct soc_enum isabelle_rx1_enum[] = {
144 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 3, 1, isabelle_rx1_texts),
145 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 5, 1, isabelle_rx1_texts),
146};
147
148static const struct soc_enum isabelle_rx2_enum[] = {
149 SOC_ENUM_SINGLE(ISABELLE_VOICE_HPF_CFG_REG, 2, 1, isabelle_rx2_texts),
150 SOC_ENUM_SINGLE(ISABELLE_AUDIO_HPF_CFG_REG, 4, 1, isabelle_rx2_texts),
151};
152
153/* Headset DAC playback switches */
154static const struct snd_kcontrol_new rx1_mux_controls =
155 SOC_DAPM_ENUM("Route", isabelle_rx1_enum);
156
157static const struct snd_kcontrol_new rx2_mux_controls =
158 SOC_DAPM_ENUM("Route", isabelle_rx2_enum);
159
160/* TX input selection */
161static const char *isabelle_atx_texts[] = {"AMIC1", "DMIC"};
162static const char *isabelle_vtx_texts[] = {"AMIC2", "DMIC"};
163
164static const struct soc_enum isabelle_atx_enum[] = {
165 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 7, 1, isabelle_atx_texts),
166 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_atx_texts),
167};
168
169static const struct soc_enum isabelle_vtx_enum[] = {
170 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 6, 1, isabelle_vtx_texts),
171 SOC_ENUM_SINGLE(ISABELLE_DMIC_CFG_REG, 0, 1, isabelle_vtx_texts),
172};
173
174static const struct snd_kcontrol_new atx_mux_controls =
175 SOC_DAPM_ENUM("Route", isabelle_atx_enum);
176
177static const struct snd_kcontrol_new vtx_mux_controls =
178 SOC_DAPM_ENUM("Route", isabelle_vtx_enum);
179
180/* Left analog microphone selection */
181static const char *isabelle_amic1_texts[] = {
182 "Main Mic", "Headset Mic", "Aux/FM Left"};
183
184/* Left analog microphone selection */
185static const char *isabelle_amic2_texts[] = {"Sub Mic", "Aux/FM Right"};
186
187static const struct soc_enum isabelle_amic1_enum[] = {
188 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 5,
189 ARRAY_SIZE(isabelle_amic1_texts),
190 isabelle_amic1_texts),
191};
192
193static const struct soc_enum isabelle_amic2_enum[] = {
194 SOC_ENUM_SINGLE(ISABELLE_AMIC_CFG_REG, 4,
195 ARRAY_SIZE(isabelle_amic2_texts),
196 isabelle_amic2_texts),
197};
198
199static const struct snd_kcontrol_new amic1_control =
200 SOC_DAPM_ENUM("Route", isabelle_amic1_enum);
201
202static const struct snd_kcontrol_new amic2_control =
203 SOC_DAPM_ENUM("Route", isabelle_amic2_enum);
204
205static const char *isabelle_st_audio_texts[] = {"ATX1", "ATX2"};
206
207static const char *isabelle_st_voice_texts[] = {"VTX1", "VTX2"};
208
209static const struct soc_enum isabelle_st_audio_enum[] = {
210 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA1_CFG_REG, 7, 1,
211 isabelle_st_audio_texts),
212 SOC_ENUM_SINGLE(ISABELLE_ATX_STPGA2_CFG_REG, 7, 1,
213 isabelle_st_audio_texts),
214};
215
216static const struct soc_enum isabelle_st_voice_enum[] = {
217 SOC_ENUM_SINGLE(ISABELLE_VTX_STPGA1_CFG_REG, 7, 1,
218 isabelle_st_voice_texts),
219 SOC_ENUM_SINGLE(ISABELLE_VTX2_STPGA2_CFG_REG, 7, 1,
220 isabelle_st_voice_texts),
221};
222
223static const struct snd_kcontrol_new st_audio_control =
224 SOC_DAPM_ENUM("Route", isabelle_st_audio_enum);
225
226static const struct snd_kcontrol_new st_voice_control =
227 SOC_DAPM_ENUM("Route", isabelle_st_voice_enum);
228
229/* Mixer controls */
230static const struct snd_kcontrol_new isabelle_hs_left_mixer_controls[] = {
231SOC_DAPM_SINGLE("DAC1L Playback Switch", ISABELLE_HSDRV_CFG1_REG, 7, 1, 0),
232SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 6, 1, 0),
233};
234
235static const struct snd_kcontrol_new isabelle_hs_right_mixer_controls[] = {
236SOC_DAPM_SINGLE("DAC1R Playback Switch", ISABELLE_HSDRV_CFG1_REG, 5, 1, 0),
237SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HSDRV_CFG1_REG, 4, 1, 0),
238};
239
240static const struct snd_kcontrol_new isabelle_hf_left_mixer_controls[] = {
241SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_HFLPGA_CFG_REG, 7, 1, 0),
242SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_HFLPGA_CFG_REG, 6, 1, 0),
243};
244
245static const struct snd_kcontrol_new isabelle_hf_right_mixer_controls[] = {
246SOC_DAPM_SINGLE("DAC2R Playback Switch", ISABELLE_HFRPGA_CFG_REG, 7, 1, 0),
247SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_HFRPGA_CFG_REG, 6, 1, 0),
248};
249
250static const struct snd_kcontrol_new isabelle_ep_mixer_controls[] = {
251SOC_DAPM_SINGLE("DAC2L Playback Switch", ISABELLE_EARDRV_CFG1_REG, 7, 1, 0),
252SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_EARDRV_CFG1_REG, 6, 1, 0),
253};
254
255static const struct snd_kcontrol_new isabelle_aux_left_mixer_controls[] = {
256SOC_DAPM_SINGLE("DAC3L Playback Switch", ISABELLE_LINEAMP_CFG_REG, 7, 1, 0),
257SOC_DAPM_SINGLE("APGA1 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 6, 1, 0),
258};
259
260static const struct snd_kcontrol_new isabelle_aux_right_mixer_controls[] = {
261SOC_DAPM_SINGLE("DAC3R Playback Switch", ISABELLE_LINEAMP_CFG_REG, 5, 1, 0),
262SOC_DAPM_SINGLE("APGA2 Playback Switch", ISABELLE_LINEAMP_CFG_REG, 4, 1, 0),
263};
264
265static const struct snd_kcontrol_new isabelle_dpga1_left_mixer_controls[] = {
266SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 7, 1, 0),
267SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 6, 1, 0),
268SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 5, 1, 0),
269};
270
271static const struct snd_kcontrol_new isabelle_dpga1_right_mixer_controls[] = {
272SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 3, 1, 0),
273SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 2, 1, 0),
274SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA1LR_IN_SEL_REG, 1, 1, 0),
275};
276
277static const struct snd_kcontrol_new isabelle_dpga2_left_mixer_controls[] = {
278SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 7, 1, 0),
279SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 6, 1, 0),
280SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 5, 1, 0),
281SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 4, 1, 0),
282SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 3, 1, 0),
283SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2L_IN_SEL_REG, 2, 1, 0),
284};
285
286static const struct snd_kcontrol_new isabelle_dpga2_right_mixer_controls[] = {
287SOC_DAPM_SINGLE("USNC Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 7, 1, 0),
288SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 3, 1, 0),
289SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 2, 1, 0),
290SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA2R_IN_SEL_REG, 1, 1, 0),
291};
292
293static const struct snd_kcontrol_new isabelle_dpga3_left_mixer_controls[] = {
294SOC_DAPM_SINGLE("RX1 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 7, 1, 0),
295SOC_DAPM_SINGLE("RX3 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 6, 1, 0),
296SOC_DAPM_SINGLE("RX5 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 5, 1, 0),
297};
298
299static const struct snd_kcontrol_new isabelle_dpga3_right_mixer_controls[] = {
300SOC_DAPM_SINGLE("RX2 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 3, 1, 0),
301SOC_DAPM_SINGLE("RX4 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 2, 1, 0),
302SOC_DAPM_SINGLE("RX6 Playback Switch", ISABELLE_DPGA3LR_IN_SEL_REG, 1, 1, 0),
303};
304
305static const struct snd_kcontrol_new isabelle_rx1_mixer_controls[] = {
306SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 7, 1, 0),
307SOC_DAPM_SINGLE("DL1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 6, 1, 0),
308};
309
310static const struct snd_kcontrol_new isabelle_rx2_mixer_controls[] = {
311SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 5, 1, 0),
312SOC_DAPM_SINGLE("DL2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 4, 1, 0),
313};
314
315static const struct snd_kcontrol_new isabelle_rx3_mixer_controls[] = {
316SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 3, 1, 0),
317SOC_DAPM_SINGLE("DL3 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 2, 1, 0),
318};
319
320static const struct snd_kcontrol_new isabelle_rx4_mixer_controls[] = {
321SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 1, 1, 0),
322SOC_DAPM_SINGLE("DL4 Playback Switch", ISABELLE_RX_INPUT_CFG_REG, 0, 1, 0),
323};
324
325static const struct snd_kcontrol_new isabelle_rx5_mixer_controls[] = {
326SOC_DAPM_SINGLE("ST1 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 7, 1, 0),
327SOC_DAPM_SINGLE("DL5 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 6, 1, 0),
328};
329
330static const struct snd_kcontrol_new isabelle_rx6_mixer_controls[] = {
331SOC_DAPM_SINGLE("ST2 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 5, 1, 0),
332SOC_DAPM_SINGLE("DL6 Playback Switch", ISABELLE_RX_INPUT_CFG2_REG, 4, 1, 0),
333};
334
335static const struct snd_kcontrol_new ep_path_enable_control =
336 SOC_DAPM_SINGLE("Switch", ISABELLE_EARDRV_CFG2_REG, 0, 1, 0);
337
338/* TLV Declarations */
339static const DECLARE_TLV_DB_SCALE(mic_amp_tlv, 0, 100, 0);
340static const DECLARE_TLV_DB_SCALE(afm_amp_tlv, -3300, 300, 0);
341static const DECLARE_TLV_DB_SCALE(dac_tlv, -1200, 200, 0);
342static const DECLARE_TLV_DB_SCALE(hf_tlv, -5000, 200, 0);
343
344/* from -63 to 0 dB in 1 dB steps */
345static const DECLARE_TLV_DB_SCALE(dpga_tlv, -6300, 100, 1);
346
347/* from -63 to 9 dB in 1 dB steps */
348static const DECLARE_TLV_DB_SCALE(rx_tlv, -6300, 100, 1);
349
350static const DECLARE_TLV_DB_SCALE(st_tlv, -2700, 300, 1);
351static const DECLARE_TLV_DB_SCALE(tx_tlv, -600, 100, 0);
352
353static const struct snd_kcontrol_new isabelle_snd_controls[] = {
354 SOC_DOUBLE_TLV("Headset Playback Volume", ISABELLE_HSDRV_GAIN_REG,
355 4, 0, 0xF, 0, dac_tlv),
356 SOC_DOUBLE_R_TLV("Handsfree Playback Volume",
357 ISABELLE_HFLPGA_CFG_REG, ISABELLE_HFRPGA_CFG_REG,
358 0, 0x1F, 0, hf_tlv),
359 SOC_DOUBLE_TLV("Aux Playback Volume", ISABELLE_LINEAMP_GAIN_REG,
360 4, 0, 0xF, 0, dac_tlv),
361 SOC_SINGLE_TLV("Earpiece Playback Volume", ISABELLE_EARDRV_CFG1_REG,
362 0, 0xF, 0, dac_tlv),
363
364 SOC_DOUBLE_TLV("Aux FM Volume", ISABELLE_APGA_GAIN_REG, 4, 0, 0xF, 0,
365 afm_amp_tlv),
366 SOC_SINGLE_TLV("Mic1 Capture Volume", ISABELLE_MIC1_GAIN_REG, 3, 0x1F,
367 0, mic_amp_tlv),
368 SOC_SINGLE_TLV("Mic2 Capture Volume", ISABELLE_MIC2_GAIN_REG, 3, 0x1F,
369 0, mic_amp_tlv),
370
371 SOC_DOUBLE_R_TLV("DPGA1 Volume", ISABELLE_DPGA1L_GAIN_REG,
372 ISABELLE_DPGA1R_GAIN_REG, 0, 0x3F, 0, dpga_tlv),
373 SOC_DOUBLE_R_TLV("DPGA2 Volume", ISABELLE_DPGA2L_GAIN_REG,
374 ISABELLE_DPGA2R_GAIN_REG, 0, 0x3F, 0, dpga_tlv),
375 SOC_DOUBLE_R_TLV("DPGA3 Volume", ISABELLE_DPGA3L_GAIN_REG,
376 ISABELLE_DPGA3R_GAIN_REG, 0, 0x3F, 0, dpga_tlv),
377
378 SOC_SINGLE_TLV("Sidetone Audio TX1 Volume",
379 ISABELLE_ATX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv),
380 SOC_SINGLE_TLV("Sidetone Audio TX2 Volume",
381 ISABELLE_ATX_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv),
382 SOC_SINGLE_TLV("Sidetone Voice TX1 Volume",
383 ISABELLE_VTX_STPGA1_CFG_REG, 0, 0xF, 0, st_tlv),
384 SOC_SINGLE_TLV("Sidetone Voice TX2 Volume",
385 ISABELLE_VTX2_STPGA2_CFG_REG, 0, 0xF, 0, st_tlv),
386
387 SOC_SINGLE_TLV("Audio TX1 Volume", ISABELLE_ATX1_DPGA_REG, 4, 0xF, 0,
388 tx_tlv),
389 SOC_SINGLE_TLV("Audio TX2 Volume", ISABELLE_ATX2_DPGA_REG, 4, 0xF, 0,
390 tx_tlv),
391 SOC_SINGLE_TLV("Voice TX1 Volume", ISABELLE_VTX1_DPGA_REG, 4, 0xF, 0,
392 tx_tlv),
393 SOC_SINGLE_TLV("Voice TX2 Volume", ISABELLE_VTX2_DPGA_REG, 4, 0xF, 0,
394 tx_tlv),
395
396 SOC_SINGLE_TLV("RX1 DPGA Volume", ISABELLE_RX1_DPGA_REG, 0, 0x3F, 0,
397 rx_tlv),
398 SOC_SINGLE_TLV("RX2 DPGA Volume", ISABELLE_RX2_DPGA_REG, 0, 0x3F, 0,
399 rx_tlv),
400 SOC_SINGLE_TLV("RX3 DPGA Volume", ISABELLE_RX3_DPGA_REG, 0, 0x3F, 0,
401 rx_tlv),
402 SOC_SINGLE_TLV("RX4 DPGA Volume", ISABELLE_RX4_DPGA_REG, 0, 0x3F, 0,
403 rx_tlv),
404 SOC_SINGLE_TLV("RX5 DPGA Volume", ISABELLE_RX5_DPGA_REG, 0, 0x3F, 0,
405 rx_tlv),
406 SOC_SINGLE_TLV("RX6 DPGA Volume", ISABELLE_RX6_DPGA_REG, 0, 0x3F, 0,
407 rx_tlv),
408
409 SOC_SINGLE("Headset Noise Gate", ISABELLE_HS_NG_CFG1_REG, 7, 1, 0),
410 SOC_SINGLE("Handsfree Noise Gate", ISABELLE_HF_NG_CFG1_REG, 7, 1, 0),
411
412 SOC_SINGLE("ATX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
413 7, 1, 0),
414 SOC_SINGLE("ATX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
415 6, 1, 0),
416 SOC_SINGLE("ARX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
417 5, 1, 0),
418 SOC_SINGLE("ARX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
419 4, 1, 0),
420 SOC_SINGLE("ARX3 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
421 3, 1, 0),
422 SOC_SINGLE("ARX4 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
423 2, 1, 0),
424 SOC_SINGLE("ARX5 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
425 1, 1, 0),
426 SOC_SINGLE("ARX6 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
427 0, 1, 0),
428 SOC_SINGLE("VRX1 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
429 3, 1, 0),
430 SOC_SINGLE("VRX2 Filter Bypass Switch", ISABELLE_AUDIO_HPF_CFG_REG,
431 2, 1, 0),
432
433 SOC_SINGLE("ATX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
434 7, 1, 0),
435 SOC_SINGLE("ATX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
436 6, 1, 0),
437 SOC_SINGLE("VTX1 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
438 5, 1, 0),
439 SOC_SINGLE("VTX2 Filter Enable Switch", ISABELLE_ALU_TX_EN_REG,
440 4, 1, 0),
441 SOC_SINGLE("RX1 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
442 5, 1, 0),
443 SOC_SINGLE("RX2 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
444 4, 1, 0),
445 SOC_SINGLE("RX3 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
446 3, 1, 0),
447 SOC_SINGLE("RX4 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
448 2, 1, 0),
449 SOC_SINGLE("RX5 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
450 1, 1, 0),
451 SOC_SINGLE("RX6 Filter Enable Switch", ISABELLE_ALU_RX_EN_REG,
452 0, 1, 0),
453
454 SOC_SINGLE("ULATX12 Capture Switch", ISABELLE_ULATX12_INTF_CFG_REG,
455 7, 1, 0),
456
457 SOC_SINGLE("DL12 Playback Switch", ISABELLE_DL12_INTF_CFG_REG,
458 7, 1, 0),
459 SOC_SINGLE("DL34 Playback Switch", ISABELLE_DL34_INTF_CFG_REG,
460 7, 1, 0),
461 SOC_SINGLE("DL56 Playback Switch", ISABELLE_DL56_INTF_CFG_REG,
462 7, 1, 0),
463
464 /* DMIC Switch */
465 SOC_SINGLE("DMIC Switch", ISABELLE_DMIC_CFG_REG, 0, 1, 0),
466};
467
468static const struct snd_soc_dapm_widget isabelle_dapm_widgets[] = {
469 /* Inputs */
470 SND_SOC_DAPM_INPUT("MAINMIC"),
471 SND_SOC_DAPM_INPUT("HSMIC"),
472 SND_SOC_DAPM_INPUT("SUBMIC"),
473 SND_SOC_DAPM_INPUT("LINEIN1"),
474 SND_SOC_DAPM_INPUT("LINEIN2"),
475 SND_SOC_DAPM_INPUT("DMICDAT"),
476
477 /* Outputs */
478 SND_SOC_DAPM_OUTPUT("HSOL"),
479 SND_SOC_DAPM_OUTPUT("HSOR"),
480 SND_SOC_DAPM_OUTPUT("HFL"),
481 SND_SOC_DAPM_OUTPUT("HFR"),
482 SND_SOC_DAPM_OUTPUT("EP"),
483 SND_SOC_DAPM_OUTPUT("LINEOUT1"),
484 SND_SOC_DAPM_OUTPUT("LINEOUT2"),
485
486 SND_SOC_DAPM_PGA("DL1", SND_SOC_NOPM, 0, 0, NULL, 0),
487 SND_SOC_DAPM_PGA("DL2", SND_SOC_NOPM, 0, 0, NULL, 0),
488 SND_SOC_DAPM_PGA("DL3", SND_SOC_NOPM, 0, 0, NULL, 0),
489 SND_SOC_DAPM_PGA("DL4", SND_SOC_NOPM, 0, 0, NULL, 0),
490 SND_SOC_DAPM_PGA("DL5", SND_SOC_NOPM, 0, 0, NULL, 0),
491 SND_SOC_DAPM_PGA("DL6", SND_SOC_NOPM, 0, 0, NULL, 0),
492
493 /* Analog input muxes for the capture amplifiers */
494 SND_SOC_DAPM_MUX("Analog Left Capture Route",
495 SND_SOC_NOPM, 0, 0, &amic1_control),
496 SND_SOC_DAPM_MUX("Analog Right Capture Route",
497 SND_SOC_NOPM, 0, 0, &amic2_control),
498
499 SND_SOC_DAPM_MUX("Sidetone Audio Playback", SND_SOC_NOPM, 0, 0,
500 &st_audio_control),
501 SND_SOC_DAPM_MUX("Sidetone Voice Playback", SND_SOC_NOPM, 0, 0,
502 &st_voice_control),
503
504 /* AIF */
505 SND_SOC_DAPM_AIF_IN("INTF1_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 7, 0),
506 SND_SOC_DAPM_AIF_IN("INTF2_SDI", NULL, 0, ISABELLE_INTF_EN_REG, 6, 0),
507
508 SND_SOC_DAPM_AIF_OUT("INTF1_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 5, 0),
509 SND_SOC_DAPM_AIF_OUT("INTF2_SDO", NULL, 0, ISABELLE_INTF_EN_REG, 4, 0),
510
511 SND_SOC_DAPM_OUT_DRV("ULATX1", SND_SOC_NOPM, 0, 0, NULL, 0),
512 SND_SOC_DAPM_OUT_DRV("ULATX2", SND_SOC_NOPM, 0, 0, NULL, 0),
513 SND_SOC_DAPM_OUT_DRV("ULVTX1", SND_SOC_NOPM, 0, 0, NULL, 0),
514 SND_SOC_DAPM_OUT_DRV("ULVTX2", SND_SOC_NOPM, 0, 0, NULL, 0),
515
516 /* Analog Capture PGAs */
517 SND_SOC_DAPM_PGA("MicAmp1", ISABELLE_AMIC_CFG_REG, 5, 0, NULL, 0),
518 SND_SOC_DAPM_PGA("MicAmp2", ISABELLE_AMIC_CFG_REG, 4, 0, NULL, 0),
519
520 /* Auxiliary FM PGAs */
521 SND_SOC_DAPM_PGA("APGA1", ISABELLE_APGA_CFG_REG, 7, 0, NULL, 0),
522 SND_SOC_DAPM_PGA("APGA2", ISABELLE_APGA_CFG_REG, 6, 0, NULL, 0),
523
524 /* ADCs */
525 SND_SOC_DAPM_ADC("ADC1", "Left Front Capture",
526 ISABELLE_AMIC_CFG_REG, 7, 0),
527 SND_SOC_DAPM_ADC("ADC2", "Right Front Capture",
528 ISABELLE_AMIC_CFG_REG, 6, 0),
529
530 /* Microphone Bias */
531 SND_SOC_DAPM_SUPPLY("Headset Mic Bias", ISABELLE_ABIAS_CFG_REG,
532 3, 0, NULL, 0),
533 SND_SOC_DAPM_SUPPLY("Main Mic Bias", ISABELLE_ABIAS_CFG_REG,
534 2, 0, NULL, 0),
535 SND_SOC_DAPM_SUPPLY("Digital Mic1 Bias",
536 ISABELLE_DBIAS_CFG_REG, 3, 0, NULL, 0),
537 SND_SOC_DAPM_SUPPLY("Digital Mic2 Bias",
538 ISABELLE_DBIAS_CFG_REG, 2, 0, NULL, 0),
539
540 /* Mixers */
541 SND_SOC_DAPM_MIXER("Headset Left Mixer", SND_SOC_NOPM, 0, 0,
542 isabelle_hs_left_mixer_controls,
543 ARRAY_SIZE(isabelle_hs_left_mixer_controls)),
544 SND_SOC_DAPM_MIXER("Headset Right Mixer", SND_SOC_NOPM, 0, 0,
545 isabelle_hs_right_mixer_controls,
546 ARRAY_SIZE(isabelle_hs_right_mixer_controls)),
547 SND_SOC_DAPM_MIXER("Handsfree Left Mixer", SND_SOC_NOPM, 0, 0,
548 isabelle_hf_left_mixer_controls,
549 ARRAY_SIZE(isabelle_hf_left_mixer_controls)),
550 SND_SOC_DAPM_MIXER("Handsfree Right Mixer", SND_SOC_NOPM, 0, 0,
551 isabelle_hf_right_mixer_controls,
552 ARRAY_SIZE(isabelle_hf_right_mixer_controls)),
553 SND_SOC_DAPM_MIXER("LINEOUT1 Mixer", SND_SOC_NOPM, 0, 0,
554 isabelle_aux_left_mixer_controls,
555 ARRAY_SIZE(isabelle_aux_left_mixer_controls)),
556 SND_SOC_DAPM_MIXER("LINEOUT2 Mixer", SND_SOC_NOPM, 0, 0,
557 isabelle_aux_right_mixer_controls,
558 ARRAY_SIZE(isabelle_aux_right_mixer_controls)),
559 SND_SOC_DAPM_MIXER("Earphone Mixer", SND_SOC_NOPM, 0, 0,
560 isabelle_ep_mixer_controls,
561 ARRAY_SIZE(isabelle_ep_mixer_controls)),
562
563 SND_SOC_DAPM_MIXER("DPGA1L Mixer", SND_SOC_NOPM, 0, 0,
564 isabelle_dpga1_left_mixer_controls,
565 ARRAY_SIZE(isabelle_dpga1_left_mixer_controls)),
566 SND_SOC_DAPM_MIXER("DPGA1R Mixer", SND_SOC_NOPM, 0, 0,
567 isabelle_dpga1_right_mixer_controls,
568 ARRAY_SIZE(isabelle_dpga1_right_mixer_controls)),
569 SND_SOC_DAPM_MIXER("DPGA2L Mixer", SND_SOC_NOPM, 0, 0,
570 isabelle_dpga2_left_mixer_controls,
571 ARRAY_SIZE(isabelle_dpga2_left_mixer_controls)),
572 SND_SOC_DAPM_MIXER("DPGA2R Mixer", SND_SOC_NOPM, 0, 0,
573 isabelle_dpga2_right_mixer_controls,
574 ARRAY_SIZE(isabelle_dpga2_right_mixer_controls)),
575 SND_SOC_DAPM_MIXER("DPGA3L Mixer", SND_SOC_NOPM, 0, 0,
576 isabelle_dpga3_left_mixer_controls,
577 ARRAY_SIZE(isabelle_dpga3_left_mixer_controls)),
578 SND_SOC_DAPM_MIXER("DPGA3R Mixer", SND_SOC_NOPM, 0, 0,
579 isabelle_dpga3_right_mixer_controls,
580 ARRAY_SIZE(isabelle_dpga3_right_mixer_controls)),
581
582 SND_SOC_DAPM_MIXER("RX1 Mixer", SND_SOC_NOPM, 0, 0,
583 isabelle_rx1_mixer_controls,
584 ARRAY_SIZE(isabelle_rx1_mixer_controls)),
585 SND_SOC_DAPM_MIXER("RX2 Mixer", SND_SOC_NOPM, 0, 0,
586 isabelle_rx2_mixer_controls,
587 ARRAY_SIZE(isabelle_rx2_mixer_controls)),
588 SND_SOC_DAPM_MIXER("RX3 Mixer", SND_SOC_NOPM, 0, 0,
589 isabelle_rx3_mixer_controls,
590 ARRAY_SIZE(isabelle_rx3_mixer_controls)),
591 SND_SOC_DAPM_MIXER("RX4 Mixer", SND_SOC_NOPM, 0, 0,
592 isabelle_rx4_mixer_controls,
593 ARRAY_SIZE(isabelle_rx4_mixer_controls)),
594 SND_SOC_DAPM_MIXER("RX5 Mixer", SND_SOC_NOPM, 0, 0,
595 isabelle_rx5_mixer_controls,
596 ARRAY_SIZE(isabelle_rx5_mixer_controls)),
597 SND_SOC_DAPM_MIXER("RX6 Mixer", SND_SOC_NOPM, 0, 0,
598 isabelle_rx6_mixer_controls,
599 ARRAY_SIZE(isabelle_rx6_mixer_controls)),
600
601 /* DACs */
602 SND_SOC_DAPM_DAC("DAC1L", "Headset Playback", ISABELLE_DAC_CFG_REG,
603 5, 0),
604 SND_SOC_DAPM_DAC("DAC1R", "Headset Playback", ISABELLE_DAC_CFG_REG,
605 4, 0),
606 SND_SOC_DAPM_DAC("DAC2L", "Handsfree Playback", ISABELLE_DAC_CFG_REG,
607 3, 0),
608 SND_SOC_DAPM_DAC("DAC2R", "Handsfree Playback", ISABELLE_DAC_CFG_REG,
609 2, 0),
610 SND_SOC_DAPM_DAC("DAC3L", "Lineout Playback", ISABELLE_DAC_CFG_REG,
611 1, 0),
612 SND_SOC_DAPM_DAC("DAC3R", "Lineout Playback", ISABELLE_DAC_CFG_REG,
613 0, 0),
614
615 /* Analog Playback PGAs */
616 SND_SOC_DAPM_PGA("Sidetone Audio PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
617 SND_SOC_DAPM_PGA("Sidetone Voice PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
618 SND_SOC_DAPM_PGA("HF Left PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
619 SND_SOC_DAPM_PGA("HF Right PGA", SND_SOC_NOPM, 0, 0, NULL, 0),
620 SND_SOC_DAPM_PGA("DPGA1L", SND_SOC_NOPM, 0, 0, NULL, 0),
621 SND_SOC_DAPM_PGA("DPGA1R", SND_SOC_NOPM, 0, 0, NULL, 0),
622 SND_SOC_DAPM_PGA("DPGA2L", SND_SOC_NOPM, 0, 0, NULL, 0),
623 SND_SOC_DAPM_PGA("DPGA2R", SND_SOC_NOPM, 0, 0, NULL, 0),
624 SND_SOC_DAPM_PGA("DPGA3L", SND_SOC_NOPM, 0, 0, NULL, 0),
625 SND_SOC_DAPM_PGA("DPGA3R", SND_SOC_NOPM, 0, 0, NULL, 0),
626
627 /* Analog Playback Mux */
628 SND_SOC_DAPM_MUX("RX1 Playback", ISABELLE_ALU_RX_EN_REG, 5, 0,
629 &rx1_mux_controls),
630 SND_SOC_DAPM_MUX("RX2 Playback", ISABELLE_ALU_RX_EN_REG, 4, 0,
631 &rx2_mux_controls),
632
633 /* TX Select */
634 SND_SOC_DAPM_MUX("ATX Select", ISABELLE_TX_INPUT_CFG_REG,
635 7, 0, &atx_mux_controls),
636 SND_SOC_DAPM_MUX("VTX Select", ISABELLE_TX_INPUT_CFG_REG,
637 6, 0, &vtx_mux_controls),
638
639 SND_SOC_DAPM_SWITCH("Earphone Playback", SND_SOC_NOPM, 0, 0,
640 &ep_path_enable_control),
641
642 /* Output Drivers */
643 SND_SOC_DAPM_OUT_DRV("HS Left Driver", ISABELLE_HSDRV_CFG2_REG,
644 1, 0, NULL, 0),
645 SND_SOC_DAPM_OUT_DRV("HS Right Driver", ISABELLE_HSDRV_CFG2_REG,
646 0, 0, NULL, 0),
647 SND_SOC_DAPM_OUT_DRV("LINEOUT1 Left Driver", ISABELLE_LINEAMP_CFG_REG,
648 1, 0, NULL, 0),
649 SND_SOC_DAPM_OUT_DRV("LINEOUT2 Right Driver", ISABELLE_LINEAMP_CFG_REG,
650 0, 0, NULL, 0),
651 SND_SOC_DAPM_OUT_DRV("Earphone Driver", ISABELLE_EARDRV_CFG2_REG,
652 1, 0, NULL, 0),
653
654 SND_SOC_DAPM_OUT_DRV("HF Left Driver", ISABELLE_HFDRV_CFG_REG,
655 1, 0, NULL, 0),
656 SND_SOC_DAPM_OUT_DRV("HF Right Driver", ISABELLE_HFDRV_CFG_REG,
657 0, 0, NULL, 0),
658};
659
660static const struct snd_soc_dapm_route isabelle_intercon[] = {
661 /* Interface mapping */
662 { "DL1", "DL12 Playback Switch", "INTF1_SDI" },
663 { "DL2", "DL12 Playback Switch", "INTF1_SDI" },
664 { "DL3", "DL34 Playback Switch", "INTF1_SDI" },
665 { "DL4", "DL34 Playback Switch", "INTF1_SDI" },
666 { "DL5", "DL56 Playback Switch", "INTF1_SDI" },
667 { "DL6", "DL56 Playback Switch", "INTF1_SDI" },
668
669 { "DL1", "DL12 Playback Switch", "INTF2_SDI" },
670 { "DL2", "DL12 Playback Switch", "INTF2_SDI" },
671 { "DL3", "DL34 Playback Switch", "INTF2_SDI" },
672 { "DL4", "DL34 Playback Switch", "INTF2_SDI" },
673 { "DL5", "DL56 Playback Switch", "INTF2_SDI" },
674 { "DL6", "DL56 Playback Switch", "INTF2_SDI" },
675
676 /* Input side mapping */
677 { "Sidetone Audio PGA", NULL, "Sidetone Audio Playback" },
678 { "Sidetone Voice PGA", NULL, "Sidetone Voice Playback" },
679
680 { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Audio PGA" },
681
682 { "RX1 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" },
683 { "RX1 Mixer", "DL1 Playback Switch", "DL1" },
684
685 { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Audio PGA" },
686
687 { "RX2 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" },
688 { "RX2 Mixer", "DL2 Playback Switch", "DL2" },
689
690 { "RX3 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" },
691 { "RX3 Mixer", "DL3 Playback Switch", "DL3" },
692
693 { "RX4 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" },
694 { "RX4 Mixer", "DL4 Playback Switch", "DL4" },
695
696 { "RX5 Mixer", "ST1 Playback Switch", "Sidetone Voice PGA" },
697 { "RX5 Mixer", "DL5 Playback Switch", "DL5" },
698
699 { "RX6 Mixer", "ST2 Playback Switch", "Sidetone Voice PGA" },
700 { "RX6 Mixer", "DL6 Playback Switch", "DL6" },
701
702 /* Capture path */
703 { "Analog Left Capture Route", "Headset Mic", "HSMIC" },
704 { "Analog Left Capture Route", "Main Mic", "MAINMIC" },
705 { "Analog Left Capture Route", "Aux/FM Left", "LINEIN1" },
706
707 { "Analog Right Capture Route", "Sub Mic", "SUBMIC" },
708 { "Analog Right Capture Route", "Aux/FM Right", "LINEIN2" },
709
710 { "MicAmp1", NULL, "Analog Left Capture Route" },
711 { "MicAmp2", NULL, "Analog Right Capture Route" },
712
713 { "ADC1", NULL, "MicAmp1" },
714 { "ADC2", NULL, "MicAmp2" },
715
716 { "ATX Select", "AMIC1", "ADC1" },
717 { "ATX Select", "DMIC", "DMICDAT" },
718 { "ATX Select", "AMIC2", "ADC2" },
719
720 { "VTX Select", "AMIC1", "ADC1" },
721 { "VTX Select", "DMIC", "DMICDAT" },
722 { "VTX Select", "AMIC2", "ADC2" },
723
724 { "ULATX1", "ATX1 Filter Enable Switch", "ATX Select" },
725 { "ULATX1", "ATX1 Filter Bypass Switch", "ATX Select" },
726 { "ULATX2", "ATX2 Filter Enable Switch", "ATX Select" },
727 { "ULATX2", "ATX2 Filter Bypass Switch", "ATX Select" },
728
729 { "ULVTX1", "VTX1 Filter Enable Switch", "VTX Select" },
730 { "ULVTX1", "VTX1 Filter Bypass Switch", "VTX Select" },
731 { "ULVTX2", "VTX2 Filter Enable Switch", "VTX Select" },
732 { "ULVTX2", "VTX2 Filter Bypass Switch", "VTX Select" },
733
734 { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX1" },
735 { "INTF1_SDO", "ULATX12 Capture Switch", "ULATX2" },
736 { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX1" },
737 { "INTF2_SDO", "ULATX12 Capture Switch", "ULATX2" },
738
739 { "INTF1_SDO", NULL, "ULVTX1" },
740 { "INTF1_SDO", NULL, "ULVTX2" },
741 { "INTF2_SDO", NULL, "ULVTX1" },
742 { "INTF2_SDO", NULL, "ULVTX2" },
743
744 /* AFM Path */
745 { "APGA1", NULL, "LINEIN1" },
746 { "APGA2", NULL, "LINEIN2" },
747
748 { "RX1 Playback", "VRX1 Filter Bypass Switch", "RX1 Mixer" },
749 { "RX1 Playback", "ARX1 Filter Bypass Switch", "RX1 Mixer" },
750 { "RX1 Playback", "RX1 Filter Enable Switch", "RX1 Mixer" },
751
752 { "RX2 Playback", "VRX2 Filter Bypass Switch", "RX2 Mixer" },
753 { "RX2 Playback", "ARX2 Filter Bypass Switch", "RX2 Mixer" },
754 { "RX2 Playback", "RX2 Filter Enable Switch", "RX2 Mixer" },
755
756 { "RX3 Playback", "ARX3 Filter Bypass Switch", "RX3 Mixer" },
757 { "RX3 Playback", "RX3 Filter Enable Switch", "RX3 Mixer" },
758
759 { "RX4 Playback", "ARX4 Filter Bypass Switch", "RX4 Mixer" },
760 { "RX4 Playback", "RX4 Filter Enable Switch", "RX4 Mixer" },
761
762 { "RX5 Playback", "ARX5 Filter Bypass Switch", "RX5 Mixer" },
763 { "RX5 Playback", "RX5 Filter Enable Switch", "RX5 Mixer" },
764
765 { "RX6 Playback", "ARX6 Filter Bypass Switch", "RX6 Mixer" },
766 { "RX6 Playback", "RX6 Filter Enable Switch", "RX6 Mixer" },
767
768 { "DPGA1L Mixer", "RX1 Playback Switch", "RX1 Playback" },
769 { "DPGA1L Mixer", "RX3 Playback Switch", "RX3 Playback" },
770 { "DPGA1L Mixer", "RX5 Playback Switch", "RX5 Playback" },
771
772 { "DPGA1R Mixer", "RX2 Playback Switch", "RX2 Playback" },
773 { "DPGA1R Mixer", "RX4 Playback Switch", "RX4 Playback" },
774 { "DPGA1R Mixer", "RX6 Playback Switch", "RX6 Playback" },
775
776 { "DPGA1L", NULL, "DPGA1L Mixer" },
777 { "DPGA1R", NULL, "DPGA1R Mixer" },
778
779 { "DAC1L", NULL, "DPGA1L" },
780 { "DAC1R", NULL, "DPGA1R" },
781
782 { "DPGA2L Mixer", "RX1 Playback Switch", "RX1 Playback" },
783 { "DPGA2L Mixer", "RX2 Playback Switch", "RX2 Playback" },
784 { "DPGA2L Mixer", "RX3 Playback Switch", "RX3 Playback" },
785 { "DPGA2L Mixer", "RX4 Playback Switch", "RX4 Playback" },
786 { "DPGA2L Mixer", "RX5 Playback Switch", "RX5 Playback" },
787 { "DPGA2L Mixer", "RX6 Playback Switch", "RX6 Playback" },
788
789 { "DPGA2R Mixer", "RX2 Playback Switch", "RX2 Playback" },
790 { "DPGA2R Mixer", "RX4 Playback Switch", "RX4 Playback" },
791 { "DPGA2R Mixer", "RX6 Playback Switch", "RX6 Playback" },
792
793 { "DPGA2L", NULL, "DPGA2L Mixer" },
794 { "DPGA2R", NULL, "DPGA2R Mixer" },
795
796 { "DAC2L", NULL, "DPGA2L" },
797 { "DAC2R", NULL, "DPGA2R" },
798
799 { "DPGA3L Mixer", "RX1 Playback Switch", "RX1 Playback" },
800 { "DPGA3L Mixer", "RX3 Playback Switch", "RX3 Playback" },
801 { "DPGA3L Mixer", "RX5 Playback Switch", "RX5 Playback" },
802
803 { "DPGA3R Mixer", "RX2 Playback Switch", "RX2 Playback" },
804 { "DPGA3R Mixer", "RX4 Playback Switch", "RX4 Playback" },
805 { "DPGA3R Mixer", "RX6 Playback Switch", "RX6 Playback" },
806
807 { "DPGA3L", NULL, "DPGA3L Mixer" },
808 { "DPGA3R", NULL, "DPGA3R Mixer" },
809
810 { "DAC3L", NULL, "DPGA3L" },
811 { "DAC3R", NULL, "DPGA3R" },
812
813 { "Headset Left Mixer", "DAC1L Playback Switch", "DAC1L" },
814 { "Headset Left Mixer", "APGA1 Playback Switch", "APGA1" },
815
816 { "Headset Right Mixer", "DAC1R Playback Switch", "DAC1R" },
817 { "Headset Right Mixer", "APGA2 Playback Switch", "APGA2" },
818
819 { "HS Left Driver", NULL, "Headset Left Mixer" },
820 { "HS Right Driver", NULL, "Headset Right Mixer" },
821
822 { "HSOL", NULL, "HS Left Driver" },
823 { "HSOR", NULL, "HS Right Driver" },
824
825 /* Earphone playback path */
826 { "Earphone Mixer", "DAC2L Playback Switch", "DAC2L" },
827 { "Earphone Mixer", "APGA1 Playback Switch", "APGA1" },
828
829 { "Earphone Playback", "Switch", "Earphone Mixer" },
830 { "Earphone Driver", NULL, "Earphone Playback" },
831 { "EP", NULL, "Earphone Driver" },
832
833 { "Handsfree Left Mixer", "DAC2L Playback Switch", "DAC2L" },
834 { "Handsfree Left Mixer", "APGA1 Playback Switch", "APGA1" },
835
836 { "Handsfree Right Mixer", "DAC2R Playback Switch", "DAC2R" },
837 { "Handsfree Right Mixer", "APGA2 Playback Switch", "APGA2" },
838
839 { "HF Left PGA", NULL, "Handsfree Left Mixer" },
840 { "HF Right PGA", NULL, "Handsfree Right Mixer" },
841
842 { "HF Left Driver", NULL, "HF Left PGA" },
843 { "HF Right Driver", NULL, "HF Right PGA" },
844
845 { "HFL", NULL, "HF Left Driver" },
846 { "HFR", NULL, "HF Right Driver" },
847
848 { "LINEOUT1 Mixer", "DAC3L Playback Switch", "DAC3L" },
849 { "LINEOUT1 Mixer", "APGA1 Playback Switch", "APGA1" },
850
851 { "LINEOUT2 Mixer", "DAC3R Playback Switch", "DAC3R" },
852 { "LINEOUT2 Mixer", "APGA2 Playback Switch", "APGA2" },
853
854 { "LINEOUT1 Driver", NULL, "LINEOUT1 Mixer" },
855 { "LINEOUT2 Driver", NULL, "LINEOUT2 Mixer" },
856
857 { "LINEOUT1", NULL, "LINEOUT1 Driver" },
858 { "LINEOUT2", NULL, "LINEOUT2 Driver" },
859};
860
861static int isabelle_hs_mute(struct snd_soc_dai *dai, int mute)
862{
863 snd_soc_update_bits(dai->codec, ISABELLE_DAC1_SOFTRAMP_REG,
864 BIT(4), (mute ? BIT(4) : 0));
865
866 return 0;
867}
868
869static int isabelle_hf_mute(struct snd_soc_dai *dai, int mute)
870{
871 snd_soc_update_bits(dai->codec, ISABELLE_DAC2_SOFTRAMP_REG,
872 BIT(4), (mute ? BIT(4) : 0));
873
874 return 0;
875}
876
877static int isabelle_line_mute(struct snd_soc_dai *dai, int mute)
878{
879 snd_soc_update_bits(dai->codec, ISABELLE_DAC3_SOFTRAMP_REG,
880 BIT(4), (mute ? BIT(4) : 0));
881
882 return 0;
883}
884
885static int isabelle_set_bias_level(struct snd_soc_codec *codec,
886 enum snd_soc_bias_level level)
887{
888 switch (level) {
889 case SND_SOC_BIAS_ON:
890 break;
891 case SND_SOC_BIAS_PREPARE:
892 break;
893
894 case SND_SOC_BIAS_STANDBY:
895 snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
896 ISABELLE_CHIP_EN, BIT(0));
897 break;
898
899 case SND_SOC_BIAS_OFF:
900 snd_soc_update_bits(codec, ISABELLE_PWR_EN_REG,
901 ISABELLE_CHIP_EN, 0);
902 break;
903 }
904
905 codec->dapm.bias_level = level;
906
907 return 0;
908}
909
910static int isabelle_hw_params(struct snd_pcm_substream *substream,
911 struct snd_pcm_hw_params *params,
912 struct snd_soc_dai *dai)
913{
914 struct snd_soc_pcm_runtime *rtd = substream->private_data;
915 struct snd_soc_codec *codec = rtd->codec;
916 u16 aif = 0;
917 unsigned int fs_val = 0;
918
919 switch (params_rate(params)) {
920 case 8000:
921 fs_val = ISABELLE_FS_RATE_8;
922 break;
923 case 11025:
924 fs_val = ISABELLE_FS_RATE_11;
925 break;
926 case 12000:
927 fs_val = ISABELLE_FS_RATE_12;
928 break;
929 case 16000:
930 fs_val = ISABELLE_FS_RATE_16;
931 break;
932 case 22050:
933 fs_val = ISABELLE_FS_RATE_22;
934 break;
935 case 24000:
936 fs_val = ISABELLE_FS_RATE_24;
937 break;
938 case 32000:
939 fs_val = ISABELLE_FS_RATE_32;
940 break;
941 case 44100:
942 fs_val = ISABELLE_FS_RATE_44;
943 break;
944 case 48000:
945 fs_val = ISABELLE_FS_RATE_48;
946 break;
947 default:
948 return -EINVAL;
949 }
950
951 snd_soc_update_bits(codec, ISABELLE_FS_RATE_CFG_REG,
952 ISABELLE_FS_RATE_MASK, fs_val);
953
954 /* bit size */
955 switch (params_format(params)) {
956 case SNDRV_PCM_FORMAT_S20_3LE:
957 aif |= ISABELLE_AIF_LENGTH_20;
958 break;
959 case SNDRV_PCM_FORMAT_S32_LE:
960 aif |= ISABELLE_AIF_LENGTH_32;
961 break;
962 default:
963 return -EINVAL;
964 }
965
966 snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
967 ISABELLE_AIF_LENGTH_MASK, aif);
968
969 return 0;
970}
971
972static int isabelle_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
973{
974 struct snd_soc_codec *codec = codec_dai->codec;
975 unsigned int aif_val = 0;
976
977 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
978 case SND_SOC_DAIFMT_CBS_CFS:
979 aif_val &= ~ISABELLE_AIF_MS;
980 break;
981 case SND_SOC_DAIFMT_CBM_CFM:
982 aif_val |= ISABELLE_AIF_MS;
983 break;
984 default:
985 return -EINVAL;
986 }
987
988 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
989 case SND_SOC_DAIFMT_I2S:
990 aif_val |= ISABELLE_I2S_MODE;
991 break;
992 case SND_SOC_DAIFMT_LEFT_J:
993 aif_val |= ISABELLE_LEFT_J_MODE;
994 break;
995 case SND_SOC_DAIFMT_PDM:
996 aif_val |= ISABELLE_PDM_MODE;
997 break;
998 default:
999 return -EINVAL;
1000 }
1001
1002 snd_soc_update_bits(codec, ISABELLE_INTF_CFG_REG,
1003 (ISABELLE_AIF_MS | ISABELLE_AIF_FMT_MASK), aif_val);
1004
1005 return 0;
1006}
1007
1008/* Rates supported by Isabelle driver */
1009#define ISABELLE_RATES SNDRV_PCM_RATE_8000_48000
1010
1011/* Formates supported by Isabelle driver. */
1012#define ISABELLE_FORMATS (SNDRV_PCM_FMTBIT_S20_3LE |\
1013 SNDRV_PCM_FMTBIT_S32_LE)
1014
1015static struct snd_soc_dai_ops isabelle_hs_dai_ops = {
1016 .hw_params = isabelle_hw_params,
1017 .set_fmt = isabelle_set_dai_fmt,
1018 .digital_mute = isabelle_hs_mute,
1019};
1020
1021static struct snd_soc_dai_ops isabelle_hf_dai_ops = {
1022 .hw_params = isabelle_hw_params,
1023 .set_fmt = isabelle_set_dai_fmt,
1024 .digital_mute = isabelle_hf_mute,
1025};
1026
1027static struct snd_soc_dai_ops isabelle_line_dai_ops = {
1028 .hw_params = isabelle_hw_params,
1029 .set_fmt = isabelle_set_dai_fmt,
1030 .digital_mute = isabelle_line_mute,
1031};
1032
1033static struct snd_soc_dai_ops isabelle_ul_dai_ops = {
1034 .hw_params = isabelle_hw_params,
1035 .set_fmt = isabelle_set_dai_fmt,
1036};
1037
1038/* ISABELLE dai structure */
1039static struct snd_soc_dai_driver isabelle_dai[] = {
1040 {
1041 .name = "isabelle-dl1",
1042 .playback = {
1043 .stream_name = "Headset Playback",
1044 .channels_min = 1,
1045 .channels_max = 2,
1046 .rates = ISABELLE_RATES,
1047 .formats = ISABELLE_FORMATS,
1048 },
1049 .ops = &isabelle_hs_dai_ops,
1050 },
1051 {
1052 .name = "isabelle-dl2",
1053 .playback = {
1054 .stream_name = "Handsfree Playback",
1055 .channels_min = 1,
1056 .channels_max = 2,
1057 .rates = ISABELLE_RATES,
1058 .formats = ISABELLE_FORMATS,
1059 },
1060 .ops = &isabelle_hf_dai_ops,
1061 },
1062 {
1063 .name = "isabelle-lineout",
1064 .playback = {
1065 .stream_name = "Lineout Playback",
1066 .channels_min = 1,
1067 .channels_max = 2,
1068 .rates = ISABELLE_RATES,
1069 .formats = ISABELLE_FORMATS,
1070 },
1071 .ops = &isabelle_line_dai_ops,
1072 },
1073 {
1074 .name = "isabelle-ul",
1075 .capture = {
1076 .stream_name = "Capture",
1077 .channels_min = 1,
1078 .channels_max = 2,
1079 .rates = ISABELLE_RATES,
1080 .formats = ISABELLE_FORMATS,
1081 },
1082 .ops = &isabelle_ul_dai_ops,
1083 },
1084};
1085
1086static int isabelle_probe(struct snd_soc_codec *codec)
1087{
1088 int ret = 0;
1089
1090 codec->control_data = dev_get_regmap(codec->dev, NULL);
1091
1092 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
1093 if (ret < 0) {
1094 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
1095 return ret;
1096 }
1097
1098 return 0;
1099}
1100
1101static struct snd_soc_codec_driver soc_codec_dev_isabelle = {
1102 .probe = isabelle_probe,
1103 .set_bias_level = isabelle_set_bias_level,
1104 .controls = isabelle_snd_controls,
1105 .num_controls = ARRAY_SIZE(isabelle_snd_controls),
1106 .dapm_widgets = isabelle_dapm_widgets,
1107 .num_dapm_widgets = ARRAY_SIZE(isabelle_dapm_widgets),
1108 .dapm_routes = isabelle_intercon,
1109 .num_dapm_routes = ARRAY_SIZE(isabelle_intercon),
1110 .idle_bias_off = true,
1111};
1112
1113static const struct regmap_config isabelle_regmap_config = {
1114 .reg_bits = 8,
1115 .val_bits = 8,
1116
1117 .max_register = ISABELLE_MAX_REGISTER,
1118 .reg_defaults = isabelle_reg_defs,
1119 .num_reg_defaults = ARRAY_SIZE(isabelle_reg_defs),
1120 .cache_type = REGCACHE_RBTREE,
1121};
1122
1123static int __devinit isabelle_i2c_probe(struct i2c_client *i2c,
1124 const struct i2c_device_id *id)
1125{
1126 struct regmap *isabelle_regmap;
1127 int ret = 0;
1128
1129 isabelle_regmap = devm_regmap_init_i2c(i2c, &isabelle_regmap_config);
1130 if (IS_ERR(isabelle_regmap)) {
1131 ret = PTR_ERR(isabelle_regmap);
1132 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
1133 ret);
1134 return ret;
1135 }
1136 i2c_set_clientdata(i2c, isabelle_regmap);
1137
1138 ret = snd_soc_register_codec(&i2c->dev,
1139 &soc_codec_dev_isabelle, isabelle_dai,
1140 ARRAY_SIZE(isabelle_dai));
1141 if (ret < 0) {
1142 dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
1143 return ret;
1144 }
1145
1146 return ret;
1147}
1148
1149static int __devexit isabelle_i2c_remove(struct i2c_client *client)
1150{
1151 snd_soc_unregister_codec(&client->dev);
1152 return 0;
1153}
1154
1155static const struct i2c_device_id isabelle_i2c_id[] = {
1156 { "isabelle", 0 },
1157 { }
1158};
1159MODULE_DEVICE_TABLE(i2c, isabelle_i2c_id);
1160
1161static struct i2c_driver isabelle_i2c_driver = {
1162 .driver = {
1163 .name = "isabelle",
1164 .owner = THIS_MODULE,
1165 },
1166 .probe = isabelle_i2c_probe,
1167 .remove = __devexit_p(isabelle_i2c_remove),
1168 .id_table = isabelle_i2c_id,
1169};
1170
1171module_i2c_driver(isabelle_i2c_driver);
1172
1173MODULE_DESCRIPTION("ASoC ISABELLE driver");
1174MODULE_AUTHOR("Vishwas A Deshpande <vishwas.a.deshpande@ti.com>");
1175MODULE_AUTHOR("M R Swami Reddy <MR.Swami.Reddy@ti.com>");
1176MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/isabelle.h b/sound/soc/codecs/isabelle.h
new file mode 100644
index 00000000000..96d839a8c95
--- /dev/null
+++ b/sound/soc/codecs/isabelle.h
@@ -0,0 +1,143 @@
1/*
2 * isabelle.h - Low power high fidelity audio codec driver header file
3 *
4 * Copyright (c) 2012 Texas Instruments, Inc
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 */
11
12#ifndef _ISABELLE_H
13#define _ISABELLE_H
14
15#include <linux/bitops.h>
16
17/* ISABELLE REGISTERS */
18
19#define ISABELLE_PWR_CFG_REG 0x01
20#define ISABELLE_PWR_EN_REG 0x02
21#define ISABELLE_PS_EN1_REG 0x03
22#define ISABELLE_INT1_STATUS_REG 0x04
23#define ISABELLE_INT1_MASK_REG 0x05
24#define ISABELLE_INT2_STATUS_REG 0x06
25#define ISABELLE_INT2_MASK_REG 0x07
26#define ISABELLE_HKCTL1_REG 0x08
27#define ISABELLE_HKCTL2_REG 0x09
28#define ISABELLE_HKCTL3_REG 0x0A
29#define ISABELLE_ACCDET_STATUS_REG 0x0B
30#define ISABELLE_BUTTON_ID_REG 0x0C
31#define ISABELLE_PLL_CFG_REG 0x10
32#define ISABELLE_PLL_EN_REG 0x11
33#define ISABELLE_FS_RATE_CFG_REG 0x12
34#define ISABELLE_INTF_CFG_REG 0x13
35#define ISABELLE_INTF_EN_REG 0x14
36#define ISABELLE_ULATX12_INTF_CFG_REG 0x15
37#define ISABELLE_DL12_INTF_CFG_REG 0x16
38#define ISABELLE_DL34_INTF_CFG_REG 0x17
39#define ISABELLE_DL56_INTF_CFG_REG 0x18
40#define ISABELLE_ATX_STPGA1_CFG_REG 0x19
41#define ISABELLE_ATX_STPGA2_CFG_REG 0x1A
42#define ISABELLE_VTX_STPGA1_CFG_REG 0x1B
43#define ISABELLE_VTX2_STPGA2_CFG_REG 0x1C
44#define ISABELLE_ATX1_DPGA_REG 0x1D
45#define ISABELLE_ATX2_DPGA_REG 0x1E
46#define ISABELLE_VTX1_DPGA_REG 0x1F
47#define ISABELLE_VTX2_DPGA_REG 0x20
48#define ISABELLE_TX_INPUT_CFG_REG 0x21
49#define ISABELLE_RX_INPUT_CFG_REG 0x22
50#define ISABELLE_RX_INPUT_CFG2_REG 0x23
51#define ISABELLE_VOICE_HPF_CFG_REG 0x24
52#define ISABELLE_AUDIO_HPF_CFG_REG 0x25
53#define ISABELLE_RX1_DPGA_REG 0x26
54#define ISABELLE_RX2_DPGA_REG 0x27
55#define ISABELLE_RX3_DPGA_REG 0x28
56#define ISABELLE_RX4_DPGA_REG 0x29
57#define ISABELLE_RX5_DPGA_REG 0x2A
58#define ISABELLE_RX6_DPGA_REG 0x2B
59#define ISABELLE_ALU_TX_EN_REG 0x2C
60#define ISABELLE_ALU_RX_EN_REG 0x2D
61#define ISABELLE_IIR_RESYNC_REG 0x2E
62#define ISABELLE_ABIAS_CFG_REG 0x30
63#define ISABELLE_DBIAS_CFG_REG 0x31
64#define ISABELLE_MIC1_GAIN_REG 0x32
65#define ISABELLE_MIC2_GAIN_REG 0x33
66#define ISABELLE_AMIC_CFG_REG 0x34
67#define ISABELLE_DMIC_CFG_REG 0x35
68#define ISABELLE_APGA_GAIN_REG 0x36
69#define ISABELLE_APGA_CFG_REG 0x37
70#define ISABELLE_TX_GAIN_DLY_REG 0x38
71#define ISABELLE_RX_GAIN_DLY_REG 0x39
72#define ISABELLE_RX_PWR_CTRL_REG 0x3A
73#define ISABELLE_DPGA1LR_IN_SEL_REG 0x3B
74#define ISABELLE_DPGA1L_GAIN_REG 0x3C
75#define ISABELLE_DPGA1R_GAIN_REG 0x3D
76#define ISABELLE_DPGA2L_IN_SEL_REG 0x3E
77#define ISABELLE_DPGA2R_IN_SEL_REG 0x3F
78#define ISABELLE_DPGA2L_GAIN_REG 0x40
79#define ISABELLE_DPGA2R_GAIN_REG 0x41
80#define ISABELLE_DPGA3LR_IN_SEL_REG 0x42
81#define ISABELLE_DPGA3L_GAIN_REG 0x43
82#define ISABELLE_DPGA3R_GAIN_REG 0x44
83#define ISABELLE_DAC1_SOFTRAMP_REG 0x45
84#define ISABELLE_DAC2_SOFTRAMP_REG 0x46
85#define ISABELLE_DAC3_SOFTRAMP_REG 0x47
86#define ISABELLE_DAC_CFG_REG 0x48
87#define ISABELLE_EARDRV_CFG1_REG 0x49
88#define ISABELLE_EARDRV_CFG2_REG 0x4A
89#define ISABELLE_HSDRV_GAIN_REG 0x4B
90#define ISABELLE_HSDRV_CFG1_REG 0x4C
91#define ISABELLE_HSDRV_CFG2_REG 0x4D
92#define ISABELLE_HS_NG_CFG1_REG 0x4E
93#define ISABELLE_HS_NG_CFG2_REG 0x4F
94#define ISABELLE_LINEAMP_GAIN_REG 0x50
95#define ISABELLE_LINEAMP_CFG_REG 0x51
96#define ISABELLE_HFL_VOL_CTRL_REG 0x52
97#define ISABELLE_HFL_SFTVOL_CTRL_REG 0x53
98#define ISABELLE_HFL_LIM_CTRL_1_REG 0x54
99#define ISABELLE_HFL_LIM_CTRL_2_REG 0x55
100#define ISABELLE_HFR_VOL_CTRL_REG 0x56
101#define ISABELLE_HFR_SFTVOL_CTRL_REG 0x57
102#define ISABELLE_HFR_LIM_CTRL_1_REG 0x58
103#define ISABELLE_HFR_LIM_CTRL_2_REG 0x59
104#define ISABELLE_HF_MODE_REG 0x5A
105#define ISABELLE_HFLPGA_CFG_REG 0x5B
106#define ISABELLE_HFRPGA_CFG_REG 0x5C
107#define ISABELLE_HFDRV_CFG_REG 0x5D
108#define ISABELLE_PDMOUT_CFG1_REG 0x5E
109#define ISABELLE_PDMOUT_CFG2_REG 0x5F
110#define ISABELLE_PDMOUT_L_WM_REG 0x60
111#define ISABELLE_PDMOUT_R_WM_REG 0x61
112#define ISABELLE_HF_NG_CFG1_REG 0x62
113#define ISABELLE_HF_NG_CFG2_REG 0x63
114
115/* ISABELLE_PWR_EN_REG (0x02h) */
116#define ISABELLE_CHIP_EN BIT(0)
117
118/* ISABELLE DAI FORMATS */
119#define ISABELLE_AIF_FMT_MASK 0x70
120#define ISABELLE_I2S_MODE 0x0
121#define ISABELLE_LEFT_J_MODE 0x1
122#define ISABELLE_PDM_MODE 0x2
123
124#define ISABELLE_AIF_LENGTH_MASK 0x30
125#define ISABELLE_AIF_LENGTH_20 0x00
126#define ISABELLE_AIF_LENGTH_32 0x10
127
128#define ISABELLE_AIF_MS 0x80
129
130#define ISABELLE_FS_RATE_MASK 0xF
131#define ISABELLE_FS_RATE_8 0x0
132#define ISABELLE_FS_RATE_11 0x1
133#define ISABELLE_FS_RATE_12 0x2
134#define ISABELLE_FS_RATE_16 0x4
135#define ISABELLE_FS_RATE_22 0x5
136#define ISABELLE_FS_RATE_24 0x6
137#define ISABELLE_FS_RATE_32 0x8
138#define ISABELLE_FS_RATE_44 0x9
139#define ISABELLE_FS_RATE_48 0xA
140
141#define ISABELLE_MAX_REGISTER 0xFF
142
143#endif
diff --git a/sound/soc/codecs/lm49453.c b/sound/soc/codecs/lm49453.c
index 802b9f176b1..99b0a9dcff3 100644
--- a/sound/soc/codecs/lm49453.c
+++ b/sound/soc/codecs/lm49453.c
@@ -12,7 +12,6 @@
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/moduleparam.h> 14#include <linux/moduleparam.h>
15#include <linux/version.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/delay.h> 17#include <linux/delay.h>
@@ -1358,7 +1357,7 @@ static struct snd_soc_dai_ops lm49453_lineout_dai_ops = {
1358}; 1357};
1359 1358
1360/* LM49453 dai structure. */ 1359/* LM49453 dai structure. */
1361static const struct snd_soc_dai_driver lm49453_dai[] = { 1360static struct snd_soc_dai_driver lm49453_dai[] = {
1362 { 1361 {
1363 .name = "LM49453 Headset", 1362 .name = "LM49453 Headset",
1364 .playback = { 1363 .playback = {
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 35179e2c23c..7cd508e16a5 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2216,7 +2216,7 @@ static irqreturn_t max98095_report_jack(int irq, void *data)
2216 return IRQ_HANDLED; 2216 return IRQ_HANDLED;
2217} 2217}
2218 2218
2219int max98095_jack_detect_enable(struct snd_soc_codec *codec) 2219static int max98095_jack_detect_enable(struct snd_soc_codec *codec)
2220{ 2220{
2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec); 2221 struct max98095_priv *max98095 = snd_soc_codec_get_drvdata(codec);
2222 int ret = 0; 2222 int ret = 0;
@@ -2245,7 +2245,7 @@ int max98095_jack_detect_enable(struct snd_soc_codec *codec)
2245 return ret; 2245 return ret;
2246} 2246}
2247 2247
2248int max98095_jack_detect_disable(struct snd_soc_codec *codec) 2248static int max98095_jack_detect_disable(struct snd_soc_codec *codec)
2249{ 2249{
2250 int ret = 0; 2250 int ret = 0;
2251 2251
@@ -2286,6 +2286,7 @@ int max98095_jack_detect(struct snd_soc_codec *codec,
2286 max98095_report_jack(client->irq, codec); 2286 max98095_report_jack(client->irq, codec);
2287 return 0; 2287 return 0;
2288} 2288}
2289EXPORT_SYMBOL_GPL(max98095_jack_detect);
2289 2290
2290#ifdef CONFIG_PM 2291#ifdef CONFIG_PM
2291static int max98095_suspend(struct snd_soc_codec *codec) 2292static int max98095_suspend(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/ml26124.c b/sound/soc/codecs/ml26124.c
index 22cb5bf5927..96aa5fa0516 100644
--- a/sound/soc/codecs/ml26124.c
+++ b/sound/soc/codecs/ml26124.c
@@ -638,7 +638,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
638 638
639 i2c_set_clientdata(i2c, priv); 639 i2c_set_clientdata(i2c, priv);
640 640
641 priv->regmap = regmap_init_i2c(i2c, &ml26124_i2c_regmap); 641 priv->regmap = devm_regmap_init_i2c(i2c, &ml26124_i2c_regmap);
642 if (IS_ERR(priv->regmap)) { 642 if (IS_ERR(priv->regmap)) {
643 ret = PTR_ERR(priv->regmap); 643 ret = PTR_ERR(priv->regmap);
644 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret); 644 dev_err(&i2c->dev, "regmap_init_i2c() failed: %d\n", ret);
@@ -651,10 +651,7 @@ static __devinit int ml26124_i2c_probe(struct i2c_client *i2c,
651 651
652static __devexit int ml26124_i2c_remove(struct i2c_client *client) 652static __devexit int ml26124_i2c_remove(struct i2c_client *client)
653{ 653{
654 struct ml26124_priv *priv = i2c_get_clientdata(client);
655
656 snd_soc_unregister_codec(&client->dev); 654 snd_soc_unregister_codec(&client->dev);
657 regmap_exit(priv->regmap);
658 return 0; 655 return 0;
659} 656}
660 657
diff --git a/sound/soc/codecs/spdif_receiver.c b/sound/soc/codecs/spdif_receiver.c
new file mode 100644
index 00000000000..dd8d856053f
--- /dev/null
+++ b/sound/soc/codecs/spdif_receiver.c
@@ -0,0 +1,67 @@
1/*
2 * ALSA SoC SPDIF DIR (Digital Interface Reciever) driver
3 *
4 * Based on ALSA SoC SPDIF DIT driver
5 *
6 * This driver is used by controllers which can operate in DIR (SPDI/F) where
7 * no codec is needed. This file provides stub codec that can be used
8 * in these configurations. SPEAr SPDIF IN Audio controller uses this driver.
9 *
10 * Author: Vipin Kumar, <vipin.kumar@st.com>
11 * Copyright: (C) 2012 ST Microelectronics
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 */
17
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/slab.h>
21#include <sound/soc.h>
22#include <sound/pcm.h>
23#include <sound/initval.h>
24
25#define STUB_RATES SNDRV_PCM_RATE_8000_192000
26#define STUB_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
27 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
28
29static struct snd_soc_codec_driver soc_codec_spdif_dir;
30
31static struct snd_soc_dai_driver dir_stub_dai = {
32 .name = "dir-hifi",
33 .capture = {
34 .stream_name = "Capture",
35 .channels_min = 1,
36 .channels_max = 384,
37 .rates = STUB_RATES,
38 .formats = STUB_FORMATS,
39 },
40};
41
42static int spdif_dir_probe(struct platform_device *pdev)
43{
44 return snd_soc_register_codec(&pdev->dev, &soc_codec_spdif_dir,
45 &dir_stub_dai, 1);
46}
47
48static int spdif_dir_remove(struct platform_device *pdev)
49{
50 snd_soc_unregister_codec(&pdev->dev);
51 return 0;
52}
53
54static struct platform_driver spdif_dir_driver = {
55 .probe = spdif_dir_probe,
56 .remove = spdif_dir_remove,
57 .driver = {
58 .name = "spdif-dir",
59 .owner = THIS_MODULE,
60 },
61};
62
63module_platform_driver(spdif_dir_driver);
64
65MODULE_DESCRIPTION("ASoC SPDIF DIR driver");
66MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>");
67MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/sta529.c b/sound/soc/codecs/sta529.c
new file mode 100644
index 00000000000..0c225cd569d
--- /dev/null
+++ b/sound/soc/codecs/sta529.c
@@ -0,0 +1,442 @@
1/*
2 * ASoC codec driver for spear platform
3 *
4 * sound/soc/codecs/sta529.c -- spear ALSA Soc codec driver
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/clk.h>
15#include <linux/init.h>
16#include <linux/i2c.h>
17#include <linux/io.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/pm.h>
21#include <linux/regmap.h>
22#include <linux/slab.h>
23
24#include <sound/core.h>
25#include <sound/initval.h>
26#include <sound/pcm.h>
27#include <sound/pcm_params.h>
28#include <sound/soc.h>
29#include <sound/soc-dapm.h>
30#include <sound/tlv.h>
31
32/* STA529 Register offsets */
33#define STA529_FFXCFG0 0x00
34#define STA529_FFXCFG1 0x01
35#define STA529_MVOL 0x02
36#define STA529_LVOL 0x03
37#define STA529_RVOL 0x04
38#define STA529_TTF0 0x05
39#define STA529_TTF1 0x06
40#define STA529_TTP0 0x07
41#define STA529_TTP1 0x08
42#define STA529_S2PCFG0 0x0A
43#define STA529_S2PCFG1 0x0B
44#define STA529_P2SCFG0 0x0C
45#define STA529_P2SCFG1 0x0D
46#define STA529_PLLCFG0 0x14
47#define STA529_PLLCFG1 0x15
48#define STA529_PLLCFG2 0x16
49#define STA529_PLLCFG3 0x17
50#define STA529_PLLPFE 0x18
51#define STA529_PLLST 0x19
52#define STA529_ADCCFG 0x1E /*mic_select*/
53#define STA529_CKOCFG 0x1F
54#define STA529_MISC 0x20
55#define STA529_PADST0 0x21
56#define STA529_PADST1 0x22
57#define STA529_FFXST 0x23
58#define STA529_PWMIN1 0x2D
59#define STA529_PWMIN2 0x2E
60#define STA529_POWST 0x32
61
62#define STA529_MAX_REGISTER 0x32
63
64#define STA529_RATES (SNDRV_PCM_RATE_8000 | \
65 SNDRV_PCM_RATE_11025 | \
66 SNDRV_PCM_RATE_16000 | \
67 SNDRV_PCM_RATE_22050 | \
68 SNDRV_PCM_RATE_32000 | \
69 SNDRV_PCM_RATE_44100 | \
70 SNDRV_PCM_RATE_48000)
71
72#define STA529_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
73 SNDRV_PCM_FMTBIT_S24_LE | \
74 SNDRV_PCM_FMTBIT_S32_LE)
75#define S2PC_VALUE 0x98
76#define CLOCK_OUT 0x60
77#define LEFT_J_DATA_FORMAT 0x10
78#define I2S_DATA_FORMAT 0x12
79#define RIGHT_J_DATA_FORMAT 0x14
80#define CODEC_MUTE_VAL 0x80
81
82#define POWER_CNTLMSAK 0x40
83#define POWER_STDBY 0x40
84#define FFX_MASK 0x80
85#define FFX_OFF 0x80
86#define POWER_UP 0x00
87#define FFX_CLK_ENB 0x01
88#define FFX_CLK_DIS 0x00
89#define FFX_CLK_MSK 0x01
90#define PLAY_FREQ_RANGE_MSK 0x70
91#define CAP_FREQ_RANGE_MSK 0x0C
92#define PDATA_LEN_MSK 0xC0
93#define BCLK_TO_FS_MSK 0x30
94#define AUDIO_MUTE_MSK 0x80
95
96static const struct reg_default sta529_reg_defaults[] = {
97 { 0, 0x35 }, /* R0 - FFX Configuration reg 0 */
98 { 1, 0xc8 }, /* R1 - FFX Configuration reg 1 */
99 { 2, 0x50 }, /* R2 - Master Volume */
100 { 3, 0x00 }, /* R3 - Left Volume */
101 { 4, 0x00 }, /* R4 - Right Volume */
102 { 10, 0xb2 }, /* R10 - S2P Config Reg 0 */
103 { 11, 0x41 }, /* R11 - S2P Config Reg 1 */
104 { 12, 0x92 }, /* R12 - P2S Config Reg 0 */
105 { 13, 0x41 }, /* R13 - P2S Config Reg 1 */
106 { 30, 0xd2 }, /* R30 - ADC Config Reg */
107 { 31, 0x40 }, /* R31 - clock Out Reg */
108 { 32, 0x21 }, /* R32 - Misc Register */
109};
110
111struct sta529 {
112 struct regmap *regmap;
113};
114
115static bool sta529_readable(struct device *dev, unsigned int reg)
116{
117 switch (reg) {
118
119 case STA529_FFXCFG0:
120 case STA529_FFXCFG1:
121 case STA529_MVOL:
122 case STA529_LVOL:
123 case STA529_RVOL:
124 case STA529_S2PCFG0:
125 case STA529_S2PCFG1:
126 case STA529_P2SCFG0:
127 case STA529_P2SCFG1:
128 case STA529_ADCCFG:
129 case STA529_CKOCFG:
130 case STA529_MISC:
131 return true;
132 default:
133 return false;
134 }
135}
136
137
138static const char *pwm_mode_text[] = { "Binary", "Headphone", "Ternary",
139 "Phase-shift"};
140
141static const DECLARE_TLV_DB_SCALE(out_gain_tlv, -9150, 50, 0);
142static const DECLARE_TLV_DB_SCALE(master_vol_tlv, -12750, 50, 0);
143static const SOC_ENUM_SINGLE_DECL(pwm_src, STA529_FFXCFG1, 4, pwm_mode_text);
144
145static const struct snd_kcontrol_new sta529_snd_controls[] = {
146 SOC_DOUBLE_R_TLV("Digital Playback Volume", STA529_LVOL, STA529_RVOL, 0,
147 127, 0, out_gain_tlv),
148 SOC_SINGLE_TLV("Master Playback Volume", STA529_MVOL, 0, 127, 1,
149 master_vol_tlv),
150 SOC_ENUM("PWM Select", pwm_src),
151};
152
153static int sta529_set_bias_level(struct snd_soc_codec *codec, enum
154 snd_soc_bias_level level)
155{
156 struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
157
158 switch (level) {
159 case SND_SOC_BIAS_ON:
160 case SND_SOC_BIAS_PREPARE:
161 snd_soc_update_bits(codec, STA529_FFXCFG0, POWER_CNTLMSAK,
162 POWER_UP);
163 snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
164 FFX_CLK_ENB);
165 break;
166 case SND_SOC_BIAS_STANDBY:
167 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
168 regcache_sync(sta529->regmap);
169 snd_soc_update_bits(codec, STA529_FFXCFG0,
170 POWER_CNTLMSAK, POWER_STDBY);
171 /* Making FFX output to zero */
172 snd_soc_update_bits(codec, STA529_FFXCFG0, FFX_MASK,
173 FFX_OFF);
174 snd_soc_update_bits(codec, STA529_MISC, FFX_CLK_MSK,
175 FFX_CLK_DIS);
176 break;
177 case SND_SOC_BIAS_OFF:
178 break;
179 }
180
181 /*
182 * store the label for powers down audio subsystem for suspend.This is
183 * used by soc core layer
184 */
185 codec->dapm.bias_level = level;
186
187 return 0;
188
189}
190
191static int sta529_hw_params(struct snd_pcm_substream *substream,
192 struct snd_pcm_hw_params *params,
193 struct snd_soc_dai *dai)
194{
195 struct snd_soc_pcm_runtime *rtd = substream->private_data;
196 struct snd_soc_codec *codec = rtd->codec;
197 int pdata, play_freq_val, record_freq_val;
198 int bclk_to_fs_ratio;
199
200 switch (params_format(params)) {
201 case SNDRV_PCM_FORMAT_S16_LE:
202 pdata = 1;
203 bclk_to_fs_ratio = 0;
204 break;
205 case SNDRV_PCM_FORMAT_S24_LE:
206 pdata = 2;
207 bclk_to_fs_ratio = 1;
208 break;
209 case SNDRV_PCM_FORMAT_S32_LE:
210 pdata = 3;
211 bclk_to_fs_ratio = 2;
212 break;
213 default:
214 dev_err(codec->dev, "Unsupported format\n");
215 return -EINVAL;
216 }
217
218 switch (params_rate(params)) {
219 case 8000:
220 case 11025:
221 play_freq_val = 0;
222 record_freq_val = 2;
223 break;
224 case 16000:
225 case 22050:
226 play_freq_val = 1;
227 record_freq_val = 0;
228 break;
229
230 case 32000:
231 case 44100:
232 case 48000:
233 play_freq_val = 2;
234 record_freq_val = 0;
235 break;
236 default:
237 dev_err(codec->dev, "Unsupported rate\n");
238 return -EINVAL;
239 }
240
241 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
242 snd_soc_update_bits(codec, STA529_S2PCFG1, PDATA_LEN_MSK,
243 pdata << 6);
244 snd_soc_update_bits(codec, STA529_S2PCFG1, BCLK_TO_FS_MSK,
245 bclk_to_fs_ratio << 4);
246 snd_soc_update_bits(codec, STA529_MISC, PLAY_FREQ_RANGE_MSK,
247 play_freq_val << 4);
248 } else {
249 snd_soc_update_bits(codec, STA529_P2SCFG1, PDATA_LEN_MSK,
250 pdata << 6);
251 snd_soc_update_bits(codec, STA529_P2SCFG1, BCLK_TO_FS_MSK,
252 bclk_to_fs_ratio << 4);
253 snd_soc_update_bits(codec, STA529_MISC, CAP_FREQ_RANGE_MSK,
254 record_freq_val << 2);
255 }
256
257 return 0;
258}
259
260static int sta529_mute(struct snd_soc_dai *dai, int mute)
261{
262 u8 val = 0;
263
264 if (mute)
265 val |= CODEC_MUTE_VAL;
266
267 snd_soc_update_bits(dai->codec, STA529_FFXCFG0, AUDIO_MUTE_MSK, val);
268
269 return 0;
270}
271
272static int sta529_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt)
273{
274 struct snd_soc_codec *codec = codec_dai->codec;
275 u8 mode = 0;
276
277 /* interface format */
278 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
279 case SND_SOC_DAIFMT_LEFT_J:
280 mode = LEFT_J_DATA_FORMAT;
281 break;
282 case SND_SOC_DAIFMT_I2S:
283 mode = I2S_DATA_FORMAT;
284 break;
285 case SND_SOC_DAIFMT_RIGHT_J:
286 mode = RIGHT_J_DATA_FORMAT;
287 break;
288 default:
289 return -EINVAL;
290 }
291
292 snd_soc_update_bits(codec, STA529_S2PCFG0, 0x0D, mode);
293
294 return 0;
295}
296
297static const struct snd_soc_dai_ops sta529_dai_ops = {
298 .hw_params = sta529_hw_params,
299 .set_fmt = sta529_set_dai_fmt,
300 .digital_mute = sta529_mute,
301};
302
303static struct snd_soc_dai_driver sta529_dai = {
304 .name = "sta529-audio",
305 .playback = {
306 .stream_name = "Playback",
307 .channels_min = 2,
308 .channels_max = 2,
309 .rates = STA529_RATES,
310 .formats = STA529_FORMAT,
311 },
312 .capture = {
313 .stream_name = "Capture",
314 .channels_min = 2,
315 .channels_max = 2,
316 .rates = STA529_RATES,
317 .formats = STA529_FORMAT,
318 },
319 .ops = &sta529_dai_ops,
320};
321
322static int sta529_probe(struct snd_soc_codec *codec)
323{
324 struct sta529 *sta529 = snd_soc_codec_get_drvdata(codec);
325 int ret;
326
327 codec->control_data = sta529->regmap;
328 ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_REGMAP);
329
330 if (ret < 0) {
331 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
332 return ret;
333 }
334 sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
335
336 return 0;
337}
338
339/* power down chip */
340static int sta529_remove(struct snd_soc_codec *codec)
341{
342 sta529_set_bias_level(codec, SND_SOC_BIAS_OFF);
343
344 return 0;
345}
346
347static int sta529_suspend(struct snd_soc_codec *codec)
348{
349 sta529_set_bias_level(codec, SND_SOC_BIAS_OFF);
350
351 return 0;
352}
353
354static int sta529_resume(struct snd_soc_codec *codec)
355{
356 sta529_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
357
358 return 0;
359}
360
361struct snd_soc_codec_driver sta529_codec_driver = {
362 .probe = sta529_probe,
363 .remove = sta529_remove,
364 .set_bias_level = sta529_set_bias_level,
365 .suspend = sta529_suspend,
366 .resume = sta529_resume,
367 .controls = sta529_snd_controls,
368 .num_controls = ARRAY_SIZE(sta529_snd_controls),
369};
370
371static const struct regmap_config sta529_regmap = {
372 .reg_bits = 8,
373 .val_bits = 8,
374
375 .max_register = STA529_MAX_REGISTER,
376 .readable_reg = sta529_readable,
377
378 .cache_type = REGCACHE_RBTREE,
379 .reg_defaults = sta529_reg_defaults,
380 .num_reg_defaults = ARRAY_SIZE(sta529_reg_defaults),
381};
382
383static __devinit int sta529_i2c_probe(struct i2c_client *i2c,
384 const struct i2c_device_id *id)
385{
386 struct sta529 *sta529;
387 int ret;
388
389 if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
390 return -EINVAL;
391
392 sta529 = devm_kzalloc(&i2c->dev, sizeof(struct sta529), GFP_KERNEL);
393 if (sta529 == NULL) {
394 dev_err(&i2c->dev, "Can not allocate memory\n");
395 return -ENOMEM;
396 }
397
398 sta529->regmap = devm_regmap_init_i2c(i2c, &sta529_regmap);
399 if (IS_ERR(sta529->regmap)) {
400 ret = PTR_ERR(sta529->regmap);
401 dev_err(&i2c->dev, "Failed to allocate regmap: %d\n", ret);
402 return ret;
403 }
404
405 i2c_set_clientdata(i2c, sta529);
406
407 ret = snd_soc_register_codec(&i2c->dev,
408 &sta529_codec_driver, &sta529_dai, 1);
409 if (ret != 0)
410 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
411
412 return ret;
413}
414
415static int __devexit sta529_i2c_remove(struct i2c_client *client)
416{
417 snd_soc_unregister_codec(&client->dev);
418
419 return 0;
420}
421
422static const struct i2c_device_id sta529_i2c_id[] = {
423 { "sta529", 0 },
424 { }
425};
426MODULE_DEVICE_TABLE(i2c, sta529_i2c_id);
427
428static struct i2c_driver sta529_i2c_driver = {
429 .driver = {
430 .name = "sta529",
431 .owner = THIS_MODULE,
432 },
433 .probe = sta529_i2c_probe,
434 .remove = __devexit_p(sta529_i2c_remove),
435 .id_table = sta529_i2c_id,
436};
437
438module_i2c_driver(sta529_i2c_driver);
439
440MODULE_DESCRIPTION("ASoC STA529 codec driver");
441MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
442MODULE_LICENSE("GPL");
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index e9b62b5ea63..dc78f5a4bcb 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -118,7 +118,9 @@ static const u8 aic3x_reg[AIC3X_CACHEREGNUM] = {
118 0x00, 0x00, 0x00, 0x00, /* 88 */ 118 0x00, 0x00, 0x00, 0x00, /* 88 */
119 0x00, 0x00, 0x00, 0x00, /* 92 */ 119 0x00, 0x00, 0x00, 0x00, /* 92 */
120 0x00, 0x00, 0x00, 0x00, /* 96 */ 120 0x00, 0x00, 0x00, 0x00, /* 96 */
121 0x00, 0x00, 0x02, /* 100 */ 121 0x00, 0x00, 0x02, 0x00, /* 100 */
122 0x00, 0x00, 0x00, 0x00, /* 104 */
123 0x00, 0x00, /* 108 */
122}; 124};
123 125
124#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \ 126#define SOC_DAPM_SINGLE_AIC3X(xname, reg, shift, mask, invert) \
@@ -229,6 +231,25 @@ static const struct soc_enum aic3x_enum[] = {
229 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf), 231 SOC_ENUM_DOUBLE(AIC3X_CODEC_DFILT_CTRL, 6, 4, 4, aic3x_adc_hpf),
230}; 232};
231 233
234static const char *aic3x_agc_level[] =
235 { "-5.5dB", "-8dB", "-10dB", "-12dB", "-14dB", "-17dB", "-20dB", "-24dB" };
236static const struct soc_enum aic3x_agc_level_enum[] = {
237 SOC_ENUM_SINGLE(LAGC_CTRL_A, 4, 8, aic3x_agc_level),
238 SOC_ENUM_SINGLE(RAGC_CTRL_A, 4, 8, aic3x_agc_level),
239};
240
241static const char *aic3x_agc_attack[] = { "8ms", "11ms", "16ms", "20ms" };
242static const struct soc_enum aic3x_agc_attack_enum[] = {
243 SOC_ENUM_SINGLE(LAGC_CTRL_A, 2, 4, aic3x_agc_attack),
244 SOC_ENUM_SINGLE(RAGC_CTRL_A, 2, 4, aic3x_agc_attack),
245};
246
247static const char *aic3x_agc_decay[] = { "100ms", "200ms", "400ms", "500ms" };
248static const struct soc_enum aic3x_agc_decay_enum[] = {
249 SOC_ENUM_SINGLE(LAGC_CTRL_A, 0, 4, aic3x_agc_decay),
250 SOC_ENUM_SINGLE(RAGC_CTRL_A, 0, 4, aic3x_agc_decay),
251};
252
232/* 253/*
233 * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps 254 * DAC digital volumes. From -63.5 to 0 dB in 0.5 dB steps
234 */ 255 */
@@ -353,6 +374,15 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
353 * adjust PGA to max value when ADC is on and will never go back. 374 * adjust PGA to max value when ADC is on and will never go back.
354 */ 375 */
355 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0), 376 SOC_DOUBLE_R("AGC Switch", LAGC_CTRL_A, RAGC_CTRL_A, 7, 0x01, 0),
377 SOC_ENUM("Left AGC Target level", aic3x_agc_level_enum[0]),
378 SOC_ENUM("Right AGC Target level", aic3x_agc_level_enum[1]),
379 SOC_ENUM("Left AGC Attack time", aic3x_agc_attack_enum[0]),
380 SOC_ENUM("Right AGC Attack time", aic3x_agc_attack_enum[1]),
381 SOC_ENUM("Left AGC Decay time", aic3x_agc_decay_enum[0]),
382 SOC_ENUM("Right AGC Decay time", aic3x_agc_decay_enum[1]),
383
384 /* De-emphasis */
385 SOC_DOUBLE("De-emphasis Switch", AIC3X_CODEC_DFILT_CTRL, 2, 0, 0x01, 0),
356 386
357 /* Input */ 387 /* Input */
358 SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL, 388 SOC_DOUBLE_R_TLV("PGA Capture Volume", LADC_VOL, RADC_VOL,
@@ -368,7 +398,7 @@ static const struct snd_kcontrol_new aic3x_snd_controls[] = {
368static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0); 398static DECLARE_TLV_DB_SCALE(classd_amp_tlv, 0, 600, 0);
369 399
370static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl = 400static const struct snd_kcontrol_new aic3x_classd_amp_gain_ctrl =
371 SOC_DOUBLE_TLV("Class-D Amplifier Gain", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv); 401 SOC_DOUBLE_TLV("Class-D Playback Volume", CLASSD_CTRL, 6, 4, 3, 0, classd_amp_tlv);
372 402
373/* Left DAC Mux */ 403/* Left DAC Mux */
374static const struct snd_kcontrol_new aic3x_left_dac_mux_controls = 404static const struct snd_kcontrol_new aic3x_left_dac_mux_controls =
@@ -970,6 +1000,12 @@ static int aic3x_set_dai_sysclk(struct snd_soc_dai *codec_dai,
970 struct snd_soc_codec *codec = codec_dai->codec; 1000 struct snd_soc_codec *codec = codec_dai->codec;
971 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); 1001 struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec);
972 1002
1003 /* set clock on MCLK or GPIO2 or BCLK */
1004 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, PLLCLK_IN_MASK,
1005 clk_id << PLLCLK_IN_SHIFT);
1006 snd_soc_update_bits(codec, AIC3X_CLKGEN_CTRL_REG, CLKDIV_IN_MASK,
1007 clk_id << CLKDIV_IN_SHIFT);
1008
973 aic3x->sysclk = freq; 1009 aic3x->sysclk = freq;
974 return 0; 1010 return 0;
975} 1011}
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h
index 08c7f6685ff..6db3c41b016 100644
--- a/sound/soc/codecs/tlv320aic3x.h
+++ b/sound/soc/codecs/tlv320aic3x.h
@@ -13,7 +13,7 @@
13#define _AIC3X_H 13#define _AIC3X_H
14 14
15/* AIC3X register space */ 15/* AIC3X register space */
16#define AIC3X_CACHEREGNUM 103 16#define AIC3X_CACHEREGNUM 110
17 17
18/* Page select register */ 18/* Page select register */
19#define AIC3X_PAGE_SELECT 0 19#define AIC3X_PAGE_SELECT 0
@@ -74,6 +74,8 @@
74#define HPLCOM_CFG 37 74#define HPLCOM_CFG 37
75/* Right High Power Output control registers */ 75/* Right High Power Output control registers */
76#define HPRCOM_CFG 38 76#define HPRCOM_CFG 38
77/* High Power Output Stage Control Register */
78#define HPOUT_SC 40
77/* DAC Output Switching control registers */ 79/* DAC Output Switching control registers */
78#define DAC_LINE_MUX 41 80#define DAC_LINE_MUX 41
79/* High Power Output Driver Pop Reduction registers */ 81/* High Power Output Driver Pop Reduction registers */
@@ -148,6 +150,17 @@
148#define AIC3X_GPIOB_REG 101 150#define AIC3X_GPIOB_REG 101
149/* Clock generation control register */ 151/* Clock generation control register */
150#define AIC3X_CLKGEN_CTRL_REG 102 152#define AIC3X_CLKGEN_CTRL_REG 102
153/* New AGC registers */
154#define LAGCN_ATTACK 103
155#define LAGCN_DECAY 104
156#define RAGCN_ATTACK 105
157#define RAGCN_DECAY 106
158/* New Programmable ADC Digital Path and I2C Bus Condition Register */
159#define NEW_ADC_DIGITALPATH 107
160/* Passive Analog Signal Bypass Selection During Powerdown Register */
161#define PASSIVE_BYPASS 108
162/* DAC Quiescent Current Adjustment Register */
163#define DAC_ICC_ADJ 109
151 164
152/* Page select register bits */ 165/* Page select register bits */
153#define PAGE0_SELECT 0 166#define PAGE0_SELECT 0
@@ -163,6 +176,10 @@
163#define DUAL_RATE_MODE ((1 << 5) | (1 << 6)) 176#define DUAL_RATE_MODE ((1 << 5) | (1 << 6))
164#define LDAC2LCH (0x1 << 3) 177#define LDAC2LCH (0x1 << 3)
165#define RDAC2RCH (0x1 << 1) 178#define RDAC2RCH (0x1 << 1)
179#define LDAC2RCH (0x2 << 3)
180#define RDAC2LCH (0x2 << 1)
181#define LDAC2MONOMIX (0x3 << 3)
182#define RDAC2MONOMIX (0x3 << 1)
166 183
167/* PLL registers bitfields */ 184/* PLL registers bitfields */
168#define PLLP_SHIFT 0 185#define PLLP_SHIFT 0
@@ -179,6 +196,14 @@
179#define PLL_CLKIN_SHIFT 4 196#define PLL_CLKIN_SHIFT 4
180#define MCLK_SOURCE 0x0 197#define MCLK_SOURCE 0x0
181#define PLL_CLKDIV_SHIFT 0 198#define PLL_CLKDIV_SHIFT 0
199#define PLLCLK_IN_MASK 0x30
200#define PLLCLK_IN_SHIFT 4
201#define CLKDIV_IN_MASK 0xc0
202#define CLKDIV_IN_SHIFT 6
203/* clock in source */
204#define CLKIN_MCLK 0
205#define CLKIN_GPIO2 1
206#define CLKIN_BCLK 2
182 207
183/* Software reset register bits */ 208/* Software reset register bits */
184#define SOFT_RESET 0x80 209#define SOFT_RESET 0x80
diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c
index a36e9fcdf18..0ff1e70b777 100644
--- a/sound/soc/codecs/twl6040.c
+++ b/sound/soc/codecs/twl6040.c
@@ -553,7 +553,7 @@ static const struct snd_kcontrol_new vibrar_mux_controls =
553 553
554/* Headset power mode */ 554/* Headset power mode */
555static const char *twl6040_power_mode_texts[] = { 555static const char *twl6040_power_mode_texts[] = {
556 "Low-Power", "High-Perfomance", 556 "Low-Power", "High-Performance",
557}; 557};
558 558
559static const struct soc_enum twl6040_power_mode_enum = 559static const struct soc_enum twl6040_power_mode_enum =
diff --git a/sound/soc/codecs/wm1250-ev1.c b/sound/soc/codecs/wm1250-ev1.c
index e0b51e9f8b1..951d7b49476 100644
--- a/sound/soc/codecs/wm1250-ev1.c
+++ b/sound/soc/codecs/wm1250-ev1.c
@@ -121,20 +121,23 @@ static const struct snd_soc_dai_ops wm1250_ev1_ops = {
121 .hw_params = wm1250_ev1_hw_params, 121 .hw_params = wm1250_ev1_hw_params,
122}; 122};
123 123
124#define WM1250_EV1_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\
125 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_64000)
126
124static struct snd_soc_dai_driver wm1250_ev1_dai = { 127static struct snd_soc_dai_driver wm1250_ev1_dai = {
125 .name = "wm1250-ev1", 128 .name = "wm1250-ev1",
126 .playback = { 129 .playback = {
127 .stream_name = "Playback", 130 .stream_name = "Playback",
128 .channels_min = 1, 131 .channels_min = 1,
129 .channels_max = 2, 132 .channels_max = 2,
130 .rates = SNDRV_PCM_RATE_8000, 133 .rates = WM1250_EV1_RATES,
131 .formats = SNDRV_PCM_FMTBIT_S16_LE, 134 .formats = SNDRV_PCM_FMTBIT_S16_LE,
132 }, 135 },
133 .capture = { 136 .capture = {
134 .stream_name = "Capture", 137 .stream_name = "Capture",
135 .channels_min = 1, 138 .channels_min = 1,
136 .channels_max = 2, 139 .channels_max = 2,
137 .rates = SNDRV_PCM_RATE_8000, 140 .rates = WM1250_EV1_RATES,
138 .formats = SNDRV_PCM_FMTBIT_S16_LE, 141 .formats = SNDRV_PCM_FMTBIT_S16_LE,
139 }, 142 },
140 .ops = &wm1250_ev1_ops, 143 .ops = &wm1250_ev1_ops,
diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c
index 0418fa11e6b..3fd5b29dc93 100644
--- a/sound/soc/codecs/wm2000.c
+++ b/sound/soc/codecs/wm2000.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm2000.c -- WM2000 ALSA Soc Audio driver 2 * wm2000.c -- WM2000 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008-2010 Wolfson Microelectronics PLC. 4 * Copyright 2008-2011 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -674,9 +674,39 @@ static int wm2000_resume(struct snd_soc_codec *codec)
674#define wm2000_resume NULL 674#define wm2000_resume NULL
675#endif 675#endif
676 676
677static bool wm2000_readable_reg(struct device *dev, unsigned int reg)
678{
679 switch (reg) {
680 case WM2000_REG_SYS_START:
681 case WM2000_REG_SPEECH_CLARITY:
682 case WM2000_REG_SYS_WATCHDOG:
683 case WM2000_REG_ANA_VMID_PD_TIME:
684 case WM2000_REG_ANA_VMID_PU_TIME:
685 case WM2000_REG_CAT_FLTR_INDX:
686 case WM2000_REG_CAT_GAIN_0:
687 case WM2000_REG_SYS_STATUS:
688 case WM2000_REG_SYS_MODE_CNTRL:
689 case WM2000_REG_SYS_START0:
690 case WM2000_REG_SYS_START1:
691 case WM2000_REG_ID1:
692 case WM2000_REG_ID2:
693 case WM2000_REG_REVISON:
694 case WM2000_REG_SYS_CTL1:
695 case WM2000_REG_SYS_CTL2:
696 case WM2000_REG_ANC_STAT:
697 case WM2000_REG_IF_CTL:
698 return true;
699 default:
700 return false;
701 }
702}
703
677static const struct regmap_config wm2000_regmap = { 704static const struct regmap_config wm2000_regmap = {
678 .reg_bits = 8, 705 .reg_bits = 8,
679 .val_bits = 8, 706 .val_bits = 8,
707
708 .max_register = WM2000_REG_IF_CTL,
709 .readable_reg = wm2000_readable_reg,
680}; 710};
681 711
682static int wm2000_probe(struct snd_soc_codec *codec) 712static int wm2000_probe(struct snd_soc_codec *codec)
diff --git a/sound/soc/codecs/wm5100-tables.c b/sound/soc/codecs/wm5100-tables.c
index e167207a19c..e239f4bf246 100644
--- a/sound/soc/codecs/wm5100-tables.c
+++ b/sound/soc/codecs/wm5100-tables.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data 2 * wm5100-tables.c -- WM5100 ALSA SoC Audio driver data
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics plc 4 * Copyright 2011-2 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm5100.c b/sound/soc/codecs/wm5100.c
index cb6d5372103..f4817292ef4 100644
--- a/sound/soc/codecs/wm5100.c
+++ b/sound/soc/codecs/wm5100.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm5100.c -- WM5100 ALSA SoC Audio driver 2 * wm5100.c -- WM5100 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics plc 4 * Copyright 2011-2 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -2378,13 +2378,6 @@ static int wm5100_remove(struct snd_soc_codec *codec)
2378 return 0; 2378 return 0;
2379} 2379}
2380 2380
2381static int wm5100_soc_volatile(struct snd_soc_codec *codec,
2382 unsigned int reg)
2383{
2384 return true;
2385}
2386
2387
2388static struct snd_soc_codec_driver soc_codec_dev_wm5100 = { 2381static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2389 .probe = wm5100_probe, 2382 .probe = wm5100_probe,
2390 .remove = wm5100_remove, 2383 .remove = wm5100_remove,
@@ -2392,8 +2385,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm5100 = {
2392 .set_sysclk = wm5100_set_sysclk, 2385 .set_sysclk = wm5100_set_sysclk,
2393 .set_pll = wm5100_set_fll, 2386 .set_pll = wm5100_set_fll,
2394 .idle_bias_off = 1, 2387 .idle_bias_off = 1,
2395 .reg_cache_size = WM5100_MAX_REGISTER,
2396 .volatile_register = wm5100_soc_volatile,
2397 2388
2398 .seq_notifier = wm5100_seq_notifier, 2389 .seq_notifier = wm5100_seq_notifier,
2399 .controls = wm5100_snd_controls, 2390 .controls = wm5100_snd_controls,
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
new file mode 100644
index 00000000000..6537f16d383
--- /dev/null
+++ b/sound/soc/codecs/wm5102.c
@@ -0,0 +1,903 @@
1/*
2 * wm5102.c -- WM5102 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm5102.h"
34
35struct wm5102_priv {
36 struct arizona_priv core;
37 struct arizona_fll fll[2];
38};
39
40static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
41static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44
45static const struct snd_kcontrol_new wm5102_snd_controls[] = {
46SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
47 ARIZONA_IN1_OSR_SHIFT, 1, 0),
48SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
49 ARIZONA_IN2_OSR_SHIFT, 1, 0),
50SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
51 ARIZONA_IN3_OSR_SHIFT, 1, 0),
52
53SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL,
54 ARIZONA_IN1R_CONTROL,
55 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
56SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL,
57 ARIZONA_IN2R_CONTROL,
58 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
59SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL,
60 ARIZONA_IN3R_CONTROL,
61 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
62
63SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L,
64 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1),
65SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L,
66 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1),
67SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L,
68 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1),
69
70SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
71 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_DIG_VOL_SHIFT,
72 0xbf, 0, digital_tlv),
73SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
74 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_DIG_VOL_SHIFT,
75 0xbf, 0, digital_tlv),
76SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
77 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT,
78 0xbf, 0, digital_tlv),
79
80ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
81ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
82ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
83ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
84
85SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
86 24, 0, eq_tlv),
87SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
88 24, 0, eq_tlv),
89SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
90 24, 0, eq_tlv),
91SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
92 24, 0, eq_tlv),
93SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
94 24, 0, eq_tlv),
95
96SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
97 24, 0, eq_tlv),
98SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
99 24, 0, eq_tlv),
100SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
101 24, 0, eq_tlv),
102SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
103 24, 0, eq_tlv),
104SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
105 24, 0, eq_tlv),
106
107SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
108 24, 0, eq_tlv),
109SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
110 24, 0, eq_tlv),
111SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
112 24, 0, eq_tlv),
113SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
114 24, 0, eq_tlv),
115SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
116 24, 0, eq_tlv),
117
118SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
119 24, 0, eq_tlv),
120SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
121 24, 0, eq_tlv),
122SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
123 24, 0, eq_tlv),
124SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
125 24, 0, eq_tlv),
126SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
127 24, 0, eq_tlv),
128
129ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
130ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
131ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE),
132ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE),
133
134SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
135 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
136SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5,
137 ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA),
138
139ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
140ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
141ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
142ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
143
144SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
145SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
146SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
147SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
148
149ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
150ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
151
152SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
153 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
154
155ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
156ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
157ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
158ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
159ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
160ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
161ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
162ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
163ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
164
165SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
166 ARIZONA_OUT1_OSR_SHIFT, 1, 0),
167SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
168 ARIZONA_OUT2_OSR_SHIFT, 1, 0),
169SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
170 ARIZONA_OUT3_OSR_SHIFT, 1, 0),
171SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
172 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
173SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
174 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
175
176SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
177 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
178SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
179 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
180SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
181 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
182SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
183 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
184SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
185 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
186
187SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
188 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
189 0xbf, 0, digital_tlv),
190SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
191 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
192 0xbf, 0, digital_tlv),
193SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
194 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
195SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
196 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
197 0xbf, 0, digital_tlv),
198SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
199 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
200 0xbf, 0, digital_tlv),
201
202SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
203 ARIZONA_OUTPUT_PATH_CONFIG_1R,
204 ARIZONA_OUT1L_PGA_VOL_SHIFT,
205 0x34, 0x40, 0, ana_tlv),
206SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
207 ARIZONA_OUTPUT_PATH_CONFIG_2R,
208 ARIZONA_OUT2L_PGA_VOL_SHIFT,
209 0x34, 0x40, 0, ana_tlv),
210SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
211 ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
212
213SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
214 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
215
216ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
217ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
218ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
219ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
220ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
221ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
222ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
223ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
224
225ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
226ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
227
228ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
229ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
230};
231
232ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
233ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
234ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
235ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
236
237ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
238ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
239ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE);
240ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE);
241
242ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
243ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
244ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
245ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
246
247ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE);
248ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE);
249
250ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
251ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
252
253ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
254ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
255ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
256ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
257ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
258ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
259ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
260ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
261ARIZONA_MIXER_ENUMS(SPKDAT1R, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
262
263ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
264ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
265ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
266ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
267ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
268ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
269ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
270ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
271
272ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
273ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
274
275ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
276ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
277
278ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
279ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
280ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
281ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
282
283static const struct snd_soc_dapm_widget wm5102_dapm_widgets[] = {
284SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
285 0, NULL, 0),
286SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
287 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
288
289SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
290SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
291SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
292SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
293SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
294SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
295
296SND_SOC_DAPM_SIGGEN("TONE"),
297SND_SOC_DAPM_SIGGEN("NOISE"),
298
299SND_SOC_DAPM_INPUT("IN1L"),
300SND_SOC_DAPM_INPUT("IN1R"),
301SND_SOC_DAPM_INPUT("IN2L"),
302SND_SOC_DAPM_INPUT("IN2R"),
303SND_SOC_DAPM_INPUT("IN3L"),
304SND_SOC_DAPM_INPUT("IN3R"),
305
306SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
307 0, NULL, 0, arizona_in_ev,
308 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
309SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
310 0, NULL, 0, arizona_in_ev,
311 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
312SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
313 0, NULL, 0, arizona_in_ev,
314 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
315SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
316 0, NULL, 0, arizona_in_ev,
317 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
318SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
319 0, NULL, 0, arizona_in_ev,
320 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
321SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
322 0, NULL, 0, arizona_in_ev,
323 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
324
325SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
326 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
327SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
328 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
329SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
330 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
331
332SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
333 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
334
335SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
336 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
337SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
338 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
339
340SND_SOC_DAPM_PGA("Mic Mute Mixer", ARIZONA_MIC_NOISE_MIX_CONTROL_1,
341 ARIZONA_MICMUTE_MIX_ENA_SHIFT, 0, NULL, 0),
342
343SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
344SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
345SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
346SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
347
348SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
349 NULL, 0),
350SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
351 NULL, 0),
352SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0,
353 NULL, 0),
354SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0,
355 NULL, 0),
356
357SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
358 NULL, 0),
359SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
360 NULL, 0),
361SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
362 NULL, 0),
363SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
364 NULL, 0),
365
366SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
367 0, NULL, 0),
368SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
369 0, NULL, 0),
370
371SND_SOC_DAPM_PGA("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
372 NULL, 0),
373SND_SOC_DAPM_PGA("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
374 NULL, 0),
375SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
376 NULL, 0),
377SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
378 NULL, 0),
379
380SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
381 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
382SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
383 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
384SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
385 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
386SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
387 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
388SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
389 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
390SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
391 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
392SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
393 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
394SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
395 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
396
397SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
398 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
399SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
400 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
401SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
402 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
403SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
404 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
405SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
406 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
407SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
408 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
409SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
410 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
411SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
412 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
413
414SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
415 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
416SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
417 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
418
419SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
420 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
421SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
422 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
423
424SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
425 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
426SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
427 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
428
429SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
430 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
431SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
432 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
433
434SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
435 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
436 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
437SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1,
438 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
439 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
440SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
441 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
442 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
443SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
444 ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
445 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
446SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
447 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
448 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
449SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
450 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
451 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
452SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
453 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
454 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
455SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
456 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
457 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
458SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
459 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
460 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
461
462ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
463ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
464ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"),
465ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
466
467ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
468ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
469ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"),
470ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"),
471
472ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
473ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
474ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
475ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
476
477ARIZONA_MIXER_WIDGETS(Mic, "Mic"),
478ARIZONA_MIXER_WIDGETS(Noise, "Noise"),
479
480ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
481ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
482
483ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
484ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
485ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
486ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
487ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
488ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
489ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
490ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
491ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
492
493ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
494ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
495ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
496ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
497ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
498ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
499ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
500ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
501
502ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
503ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
504
505ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
506ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
507
508ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
509ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
510ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
511ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
512
513SND_SOC_DAPM_OUTPUT("HPOUT1L"),
514SND_SOC_DAPM_OUTPUT("HPOUT1R"),
515SND_SOC_DAPM_OUTPUT("HPOUT2L"),
516SND_SOC_DAPM_OUTPUT("HPOUT2R"),
517SND_SOC_DAPM_OUTPUT("EPOUTN"),
518SND_SOC_DAPM_OUTPUT("EPOUTP"),
519SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
520SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
521SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
522SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
523SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
524SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
525};
526
527#define ARIZONA_MIXER_INPUT_ROUTES(name) \
528 { name, "Noise Generator", "Noise Generator" }, \
529 { name, "Tone Generator 1", "Tone Generator 1" }, \
530 { name, "Tone Generator 2", "Tone Generator 2" }, \
531 { name, "IN1L", "IN1L PGA" }, \
532 { name, "IN1R", "IN1R PGA" }, \
533 { name, "IN2L", "IN2L PGA" }, \
534 { name, "IN2R", "IN2R PGA" }, \
535 { name, "IN3L", "IN3L PGA" }, \
536 { name, "IN3R", "IN3R PGA" }, \
537 { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \
538 { name, "AIF1RX1", "AIF1RX1" }, \
539 { name, "AIF1RX2", "AIF1RX2" }, \
540 { name, "AIF1RX3", "AIF1RX3" }, \
541 { name, "AIF1RX4", "AIF1RX4" }, \
542 { name, "AIF1RX5", "AIF1RX5" }, \
543 { name, "AIF1RX6", "AIF1RX6" }, \
544 { name, "AIF1RX7", "AIF1RX7" }, \
545 { name, "AIF1RX8", "AIF1RX8" }, \
546 { name, "AIF2RX1", "AIF2RX1" }, \
547 { name, "AIF2RX2", "AIF2RX2" }, \
548 { name, "AIF3RX1", "AIF3RX1" }, \
549 { name, "AIF3RX2", "AIF3RX2" }, \
550 { name, "EQ1", "EQ1" }, \
551 { name, "EQ2", "EQ2" }, \
552 { name, "EQ3", "EQ3" }, \
553 { name, "EQ4", "EQ4" }, \
554 { name, "DRC1L", "DRC1L" }, \
555 { name, "DRC1R", "DRC1R" }, \
556 { name, "DRC2L", "DRC2L" }, \
557 { name, "DRC2R", "DRC2R" }, \
558 { name, "LHPF1", "LHPF1" }, \
559 { name, "LHPF2", "LHPF2" }, \
560 { name, "LHPF3", "LHPF3" }, \
561 { name, "LHPF4", "LHPF4" }, \
562 { name, "ASRC1L", "ASRC1L" }, \
563 { name, "ASRC1R", "ASRC1R" }, \
564 { name, "ASRC2L", "ASRC2L" }, \
565 { name, "ASRC2R", "ASRC2R" }
566
567static const struct snd_soc_dapm_route wm5102_dapm_routes[] = {
568 { "AIF2 Capture", NULL, "DBVDD2" },
569 { "AIF2 Playback", NULL, "DBVDD2" },
570
571 { "AIF3 Capture", NULL, "DBVDD3" },
572 { "AIF3 Playback", NULL, "DBVDD3" },
573
574 { "OUT1L", NULL, "CPVDD" },
575 { "OUT1R", NULL, "CPVDD" },
576 { "OUT2L", NULL, "CPVDD" },
577 { "OUT2R", NULL, "CPVDD" },
578 { "OUT3L", NULL, "CPVDD" },
579
580 { "OUT4L", NULL, "SPKVDDL" },
581 { "OUT4R", NULL, "SPKVDDR" },
582
583 { "OUT1L", NULL, "SYSCLK" },
584 { "OUT1R", NULL, "SYSCLK" },
585 { "OUT2L", NULL, "SYSCLK" },
586 { "OUT2R", NULL, "SYSCLK" },
587 { "OUT3L", NULL, "SYSCLK" },
588 { "OUT4L", NULL, "SYSCLK" },
589 { "OUT4R", NULL, "SYSCLK" },
590 { "OUT5L", NULL, "SYSCLK" },
591 { "OUT5R", NULL, "SYSCLK" },
592
593 { "MICBIAS1", NULL, "MICVDD" },
594 { "MICBIAS2", NULL, "MICVDD" },
595 { "MICBIAS3", NULL, "MICVDD" },
596
597 { "Noise Generator", NULL, "NOISE" },
598 { "Tone Generator 1", NULL, "TONE" },
599 { "Tone Generator 2", NULL, "TONE" },
600
601 { "Mic Mute Mixer", NULL, "Noise Mixer" },
602 { "Mic Mute Mixer", NULL, "Mic Mixer" },
603
604 { "AIF1 Capture", NULL, "AIF1TX1" },
605 { "AIF1 Capture", NULL, "AIF1TX2" },
606 { "AIF1 Capture", NULL, "AIF1TX3" },
607 { "AIF1 Capture", NULL, "AIF1TX4" },
608 { "AIF1 Capture", NULL, "AIF1TX5" },
609 { "AIF1 Capture", NULL, "AIF1TX6" },
610 { "AIF1 Capture", NULL, "AIF1TX7" },
611 { "AIF1 Capture", NULL, "AIF1TX8" },
612
613 { "AIF1RX1", NULL, "AIF1 Playback" },
614 { "AIF1RX2", NULL, "AIF1 Playback" },
615 { "AIF1RX3", NULL, "AIF1 Playback" },
616 { "AIF1RX4", NULL, "AIF1 Playback" },
617 { "AIF1RX5", NULL, "AIF1 Playback" },
618 { "AIF1RX6", NULL, "AIF1 Playback" },
619 { "AIF1RX7", NULL, "AIF1 Playback" },
620 { "AIF1RX8", NULL, "AIF1 Playback" },
621
622 { "AIF2 Capture", NULL, "AIF2TX1" },
623 { "AIF2 Capture", NULL, "AIF2TX2" },
624
625 { "AIF2RX1", NULL, "AIF2 Playback" },
626 { "AIF2RX2", NULL, "AIF2 Playback" },
627
628 { "AIF3 Capture", NULL, "AIF3TX1" },
629 { "AIF3 Capture", NULL, "AIF3TX2" },
630
631 { "AIF3RX1", NULL, "AIF3 Playback" },
632 { "AIF3RX2", NULL, "AIF3 Playback" },
633
634 { "AIF1 Playback", NULL, "SYSCLK" },
635 { "AIF2 Playback", NULL, "SYSCLK" },
636 { "AIF3 Playback", NULL, "SYSCLK" },
637
638 { "AIF1 Capture", NULL, "SYSCLK" },
639 { "AIF2 Capture", NULL, "SYSCLK" },
640 { "AIF3 Capture", NULL, "SYSCLK" },
641
642 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
643 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
644 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
645 ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
646 ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
647
648 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
649 ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
650 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
651 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
652
653 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
654 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
655
656 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
657 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
658 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
659 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
660 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
661 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
662 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
663 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
664
665 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
666 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
667
668 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
669 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
670
671 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
672 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
673 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
674 ARIZONA_MIXER_ROUTES("EQ4", "EQ4"),
675
676 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
677 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
678 ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"),
679 ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"),
680
681 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
682 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
683 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
684 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
685
686 ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
687 ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
688 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
689 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
690
691 { "HPOUT1L", NULL, "OUT1L" },
692 { "HPOUT1R", NULL, "OUT1R" },
693
694 { "HPOUT2L", NULL, "OUT2L" },
695 { "HPOUT2R", NULL, "OUT2R" },
696
697 { "EPOUTN", NULL, "OUT3L" },
698 { "EPOUTP", NULL, "OUT3L" },
699
700 { "SPKOUTLN", NULL, "OUT4L" },
701 { "SPKOUTLP", NULL, "OUT4L" },
702
703 { "SPKOUTRN", NULL, "OUT4R" },
704 { "SPKOUTRP", NULL, "OUT4R" },
705
706 { "SPKDAT1L", NULL, "OUT5L" },
707 { "SPKDAT1R", NULL, "OUT5R" },
708};
709
710static int wm5102_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
711 unsigned int Fref, unsigned int Fout)
712{
713 struct wm5102_priv *wm5102 = snd_soc_codec_get_drvdata(codec);
714
715 switch (fll_id) {
716 case WM5102_FLL1:
717 return arizona_set_fll(&wm5102->fll[0], source, Fref, Fout);
718 case WM5102_FLL2:
719 return arizona_set_fll(&wm5102->fll[1], source, Fref, Fout);
720 default:
721 return -EINVAL;
722 }
723}
724
725#define WM5102_RATES SNDRV_PCM_RATE_8000_192000
726
727#define WM5102_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
728 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
729
730static struct snd_soc_dai_driver wm5102_dai[] = {
731 {
732 .name = "wm5102-aif1",
733 .id = 1,
734 .base = ARIZONA_AIF1_BCLK_CTRL,
735 .playback = {
736 .stream_name = "AIF1 Playback",
737 .channels_min = 1,
738 .channels_max = 8,
739 .rates = WM5102_RATES,
740 .formats = WM5102_FORMATS,
741 },
742 .capture = {
743 .stream_name = "AIF1 Capture",
744 .channels_min = 1,
745 .channels_max = 8,
746 .rates = WM5102_RATES,
747 .formats = WM5102_FORMATS,
748 },
749 .ops = &arizona_dai_ops,
750 .symmetric_rates = 1,
751 },
752 {
753 .name = "wm5102-aif2",
754 .id = 2,
755 .base = ARIZONA_AIF2_BCLK_CTRL,
756 .playback = {
757 .stream_name = "AIF2 Playback",
758 .channels_min = 1,
759 .channels_max = 2,
760 .rates = WM5102_RATES,
761 .formats = WM5102_FORMATS,
762 },
763 .capture = {
764 .stream_name = "AIF2 Capture",
765 .channels_min = 1,
766 .channels_max = 2,
767 .rates = WM5102_RATES,
768 .formats = WM5102_FORMATS,
769 },
770 .ops = &arizona_dai_ops,
771 .symmetric_rates = 1,
772 },
773 {
774 .name = "wm5102-aif3",
775 .id = 3,
776 .base = ARIZONA_AIF3_BCLK_CTRL,
777 .playback = {
778 .stream_name = "AIF3 Playback",
779 .channels_min = 1,
780 .channels_max = 2,
781 .rates = WM5102_RATES,
782 .formats = WM5102_FORMATS,
783 },
784 .capture = {
785 .stream_name = "AIF3 Capture",
786 .channels_min = 1,
787 .channels_max = 2,
788 .rates = WM5102_RATES,
789 .formats = WM5102_FORMATS,
790 },
791 .ops = &arizona_dai_ops,
792 .symmetric_rates = 1,
793 },
794};
795
796static int wm5102_codec_probe(struct snd_soc_codec *codec)
797{
798 struct wm5102_priv *priv = snd_soc_codec_get_drvdata(codec);
799
800 codec->control_data = priv->core.arizona->regmap;
801 return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
802}
803
804#define WM5102_DIG_VU 0x0200
805
806static unsigned int wm5102_digital_vu[] = {
807 ARIZONA_ADC_DIGITAL_VOLUME_1L,
808 ARIZONA_ADC_DIGITAL_VOLUME_1R,
809 ARIZONA_ADC_DIGITAL_VOLUME_2L,
810 ARIZONA_ADC_DIGITAL_VOLUME_2R,
811 ARIZONA_ADC_DIGITAL_VOLUME_3L,
812 ARIZONA_ADC_DIGITAL_VOLUME_3R,
813
814 ARIZONA_DAC_DIGITAL_VOLUME_1L,
815 ARIZONA_DAC_DIGITAL_VOLUME_1R,
816 ARIZONA_DAC_DIGITAL_VOLUME_2L,
817 ARIZONA_DAC_DIGITAL_VOLUME_2R,
818 ARIZONA_DAC_DIGITAL_VOLUME_3L,
819 ARIZONA_DAC_DIGITAL_VOLUME_3R,
820 ARIZONA_DAC_DIGITAL_VOLUME_4L,
821 ARIZONA_DAC_DIGITAL_VOLUME_4R,
822 ARIZONA_DAC_DIGITAL_VOLUME_5L,
823 ARIZONA_DAC_DIGITAL_VOLUME_5R,
824};
825
826static struct snd_soc_codec_driver soc_codec_dev_wm5102 = {
827 .probe = wm5102_codec_probe,
828
829 .idle_bias_off = true,
830
831 .set_sysclk = arizona_set_sysclk,
832 .set_pll = wm5102_set_fll,
833
834 .controls = wm5102_snd_controls,
835 .num_controls = ARRAY_SIZE(wm5102_snd_controls),
836 .dapm_widgets = wm5102_dapm_widgets,
837 .num_dapm_widgets = ARRAY_SIZE(wm5102_dapm_widgets),
838 .dapm_routes = wm5102_dapm_routes,
839 .num_dapm_routes = ARRAY_SIZE(wm5102_dapm_routes),
840};
841
842static int __devinit wm5102_probe(struct platform_device *pdev)
843{
844 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
845 struct wm5102_priv *wm5102;
846 int i;
847
848 wm5102 = devm_kzalloc(&pdev->dev, sizeof(struct wm5102_priv),
849 GFP_KERNEL);
850 if (wm5102 == NULL)
851 return -ENOMEM;
852 platform_set_drvdata(pdev, wm5102);
853
854 wm5102->core.arizona = arizona;
855
856 for (i = 0; i < ARRAY_SIZE(wm5102->fll); i++)
857 wm5102->fll[i].vco_mult = 1;
858
859 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
860 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
861 &wm5102->fll[0]);
862 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
863 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
864 &wm5102->fll[1]);
865
866 for (i = 0; i < ARRAY_SIZE(wm5102_dai); i++)
867 arizona_init_dai(&wm5102->core, i);
868
869 /* Latch volume update bits */
870 for (i = 0; i < ARRAY_SIZE(wm5102_digital_vu); i++)
871 regmap_update_bits(arizona->regmap, wm5102_digital_vu[i],
872 WM5102_DIG_VU, WM5102_DIG_VU);
873
874 pm_runtime_enable(&pdev->dev);
875 pm_runtime_idle(&pdev->dev);
876
877 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5102,
878 wm5102_dai, ARRAY_SIZE(wm5102_dai));
879}
880
881static int __devexit wm5102_remove(struct platform_device *pdev)
882{
883 snd_soc_unregister_codec(&pdev->dev);
884 pm_runtime_disable(&pdev->dev);
885
886 return 0;
887}
888
889static struct platform_driver wm5102_codec_driver = {
890 .driver = {
891 .name = "wm5102-codec",
892 .owner = THIS_MODULE,
893 },
894 .probe = wm5102_probe,
895 .remove = __devexit_p(wm5102_remove),
896};
897
898module_platform_driver(wm5102_codec_driver);
899
900MODULE_DESCRIPTION("ASoC WM5102 driver");
901MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
902MODULE_LICENSE("GPL");
903MODULE_ALIAS("platform:wm5102-codec");
diff --git a/sound/soc/codecs/wm5102.h b/sound/soc/codecs/wm5102.h
new file mode 100644
index 00000000000..d30477f3070
--- /dev/null
+++ b/sound/soc/codecs/wm5102.h
@@ -0,0 +1,21 @@
1/*
2 * wm5102.h -- WM5102 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM5102_H
14#define _WM5102_H
15
16#include "arizona.h"
17
18#define WM5102_FLL1 1
19#define WM5102_FLL2 2
20
21#endif
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
new file mode 100644
index 00000000000..8033f706518
--- /dev/null
+++ b/sound/soc/codecs/wm5110.c
@@ -0,0 +1,950 @@
1/*
2 * wm5110.c -- WM5110 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/module.h>
14#include <linux/moduleparam.h>
15#include <linux/init.h>
16#include <linux/delay.h>
17#include <linux/pm.h>
18#include <linux/pm_runtime.h>
19#include <linux/regmap.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25#include <sound/jack.h>
26#include <sound/initval.h>
27#include <sound/tlv.h>
28
29#include <linux/mfd/arizona/core.h>
30#include <linux/mfd/arizona/registers.h>
31
32#include "arizona.h"
33#include "wm5110.h"
34
35struct wm5110_priv {
36 struct arizona_priv core;
37 struct arizona_fll fll[2];
38};
39
40static DECLARE_TLV_DB_SCALE(ana_tlv, 0, 100, 0);
41static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
42static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
43static DECLARE_TLV_DB_SCALE(noise_tlv, 0, 600, 0);
44
45static const struct snd_kcontrol_new wm5110_snd_controls[] = {
46SOC_SINGLE("IN1 High Performance Switch", ARIZONA_IN1L_CONTROL,
47 ARIZONA_IN1_OSR_SHIFT, 1, 0),
48SOC_SINGLE("IN2 High Performance Switch", ARIZONA_IN2L_CONTROL,
49 ARIZONA_IN2_OSR_SHIFT, 1, 0),
50SOC_SINGLE("IN3 High Performance Switch", ARIZONA_IN3L_CONTROL,
51 ARIZONA_IN3_OSR_SHIFT, 1, 0),
52SOC_SINGLE("IN4 High Performance Switch", ARIZONA_IN4L_CONTROL,
53 ARIZONA_IN4_OSR_SHIFT, 1, 0),
54
55SOC_DOUBLE_R_RANGE_TLV("IN1 Volume", ARIZONA_IN1L_CONTROL,
56 ARIZONA_IN1R_CONTROL,
57 ARIZONA_IN1L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
58SOC_DOUBLE_R_RANGE_TLV("IN2 Volume", ARIZONA_IN2L_CONTROL,
59 ARIZONA_IN2R_CONTROL,
60 ARIZONA_IN2L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
61SOC_DOUBLE_R_RANGE_TLV("IN3 Volume", ARIZONA_IN3L_CONTROL,
62 ARIZONA_IN3R_CONTROL,
63 ARIZONA_IN3L_PGA_VOL_SHIFT, 0x40, 0x5f, 0, ana_tlv),
64
65SOC_DOUBLE_R("IN1 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_1L,
66 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_MUTE_SHIFT, 1, 1),
67SOC_DOUBLE_R("IN2 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_2L,
68 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_MUTE_SHIFT, 1, 1),
69SOC_DOUBLE_R("IN3 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_3L,
70 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_MUTE_SHIFT, 1, 1),
71SOC_DOUBLE_R("IN4 Digital Switch", ARIZONA_ADC_DIGITAL_VOLUME_4L,
72 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_MUTE_SHIFT, 1, 1),
73
74SOC_DOUBLE_R_TLV("IN1 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_1L,
75 ARIZONA_ADC_DIGITAL_VOLUME_1R, ARIZONA_IN1L_DIG_VOL_SHIFT,
76 0xbf, 0, digital_tlv),
77SOC_DOUBLE_R_TLV("IN2 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_2L,
78 ARIZONA_ADC_DIGITAL_VOLUME_2R, ARIZONA_IN2L_DIG_VOL_SHIFT,
79 0xbf, 0, digital_tlv),
80SOC_DOUBLE_R_TLV("IN3 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_3L,
81 ARIZONA_ADC_DIGITAL_VOLUME_3R, ARIZONA_IN3L_DIG_VOL_SHIFT,
82 0xbf, 0, digital_tlv),
83SOC_DOUBLE_R_TLV("IN4 Digital Volume", ARIZONA_ADC_DIGITAL_VOLUME_4L,
84 ARIZONA_ADC_DIGITAL_VOLUME_4R, ARIZONA_IN4L_DIG_VOL_SHIFT,
85 0xbf, 0, digital_tlv),
86
87ARIZONA_MIXER_CONTROLS("EQ1", ARIZONA_EQ1MIX_INPUT_1_SOURCE),
88ARIZONA_MIXER_CONTROLS("EQ2", ARIZONA_EQ2MIX_INPUT_1_SOURCE),
89ARIZONA_MIXER_CONTROLS("EQ3", ARIZONA_EQ3MIX_INPUT_1_SOURCE),
90ARIZONA_MIXER_CONTROLS("EQ4", ARIZONA_EQ4MIX_INPUT_1_SOURCE),
91
92SOC_SINGLE_TLV("EQ1 B1 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B1_GAIN_SHIFT,
93 24, 0, eq_tlv),
94SOC_SINGLE_TLV("EQ1 B2 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B2_GAIN_SHIFT,
95 24, 0, eq_tlv),
96SOC_SINGLE_TLV("EQ1 B3 Volume", ARIZONA_EQ1_1, ARIZONA_EQ1_B3_GAIN_SHIFT,
97 24, 0, eq_tlv),
98SOC_SINGLE_TLV("EQ1 B4 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B4_GAIN_SHIFT,
99 24, 0, eq_tlv),
100SOC_SINGLE_TLV("EQ1 B5 Volume", ARIZONA_EQ1_2, ARIZONA_EQ1_B5_GAIN_SHIFT,
101 24, 0, eq_tlv),
102
103SOC_SINGLE_TLV("EQ2 B1 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B1_GAIN_SHIFT,
104 24, 0, eq_tlv),
105SOC_SINGLE_TLV("EQ2 B2 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B2_GAIN_SHIFT,
106 24, 0, eq_tlv),
107SOC_SINGLE_TLV("EQ2 B3 Volume", ARIZONA_EQ2_1, ARIZONA_EQ2_B3_GAIN_SHIFT,
108 24, 0, eq_tlv),
109SOC_SINGLE_TLV("EQ2 B4 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B4_GAIN_SHIFT,
110 24, 0, eq_tlv),
111SOC_SINGLE_TLV("EQ2 B5 Volume", ARIZONA_EQ2_2, ARIZONA_EQ2_B5_GAIN_SHIFT,
112 24, 0, eq_tlv),
113
114SOC_SINGLE_TLV("EQ3 B1 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B1_GAIN_SHIFT,
115 24, 0, eq_tlv),
116SOC_SINGLE_TLV("EQ3 B2 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B2_GAIN_SHIFT,
117 24, 0, eq_tlv),
118SOC_SINGLE_TLV("EQ3 B3 Volume", ARIZONA_EQ3_1, ARIZONA_EQ3_B3_GAIN_SHIFT,
119 24, 0, eq_tlv),
120SOC_SINGLE_TLV("EQ3 B4 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B4_GAIN_SHIFT,
121 24, 0, eq_tlv),
122SOC_SINGLE_TLV("EQ3 B5 Volume", ARIZONA_EQ3_2, ARIZONA_EQ3_B5_GAIN_SHIFT,
123 24, 0, eq_tlv),
124
125SOC_SINGLE_TLV("EQ4 B1 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B1_GAIN_SHIFT,
126 24, 0, eq_tlv),
127SOC_SINGLE_TLV("EQ4 B2 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B2_GAIN_SHIFT,
128 24, 0, eq_tlv),
129SOC_SINGLE_TLV("EQ4 B3 Volume", ARIZONA_EQ4_1, ARIZONA_EQ4_B3_GAIN_SHIFT,
130 24, 0, eq_tlv),
131SOC_SINGLE_TLV("EQ4 B4 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B4_GAIN_SHIFT,
132 24, 0, eq_tlv),
133SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT,
134 24, 0, eq_tlv),
135
136ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE),
137ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE),
138ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE),
139ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE),
140
141SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5,
142 ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA),
143SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5,
144 ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA),
145
146ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE),
147ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE),
148ARIZONA_MIXER_CONTROLS("LHPF3", ARIZONA_HPLP3MIX_INPUT_1_SOURCE),
149ARIZONA_MIXER_CONTROLS("LHPF4", ARIZONA_HPLP4MIX_INPUT_1_SOURCE),
150
151SOC_ENUM("LHPF1 Mode", arizona_lhpf1_mode),
152SOC_ENUM("LHPF2 Mode", arizona_lhpf2_mode),
153SOC_ENUM("LHPF3 Mode", arizona_lhpf3_mode),
154SOC_ENUM("LHPF4 Mode", arizona_lhpf4_mode),
155
156ARIZONA_MIXER_CONTROLS("Mic", ARIZONA_MICMIX_INPUT_1_SOURCE),
157ARIZONA_MIXER_CONTROLS("Noise", ARIZONA_NOISEMIX_INPUT_1_SOURCE),
158
159SOC_SINGLE_TLV("Noise Generator Volume", ARIZONA_COMFORT_NOISE_GENERATOR,
160 ARIZONA_NOISE_GEN_GAIN_SHIFT, 0x16, 0, noise_tlv),
161
162ARIZONA_MIXER_CONTROLS("HPOUT1L", ARIZONA_OUT1LMIX_INPUT_1_SOURCE),
163ARIZONA_MIXER_CONTROLS("HPOUT1R", ARIZONA_OUT1RMIX_INPUT_1_SOURCE),
164ARIZONA_MIXER_CONTROLS("HPOUT2L", ARIZONA_OUT2LMIX_INPUT_1_SOURCE),
165ARIZONA_MIXER_CONTROLS("HPOUT2R", ARIZONA_OUT2RMIX_INPUT_1_SOURCE),
166ARIZONA_MIXER_CONTROLS("EPOUT", ARIZONA_OUT3LMIX_INPUT_1_SOURCE),
167ARIZONA_MIXER_CONTROLS("SPKOUTL", ARIZONA_OUT4LMIX_INPUT_1_SOURCE),
168ARIZONA_MIXER_CONTROLS("SPKOUTR", ARIZONA_OUT4RMIX_INPUT_1_SOURCE),
169ARIZONA_MIXER_CONTROLS("SPKDAT1L", ARIZONA_OUT5LMIX_INPUT_1_SOURCE),
170ARIZONA_MIXER_CONTROLS("SPKDAT1R", ARIZONA_OUT5RMIX_INPUT_1_SOURCE),
171ARIZONA_MIXER_CONTROLS("SPKDAT2L", ARIZONA_OUT6LMIX_INPUT_1_SOURCE),
172ARIZONA_MIXER_CONTROLS("SPKDAT2R", ARIZONA_OUT6RMIX_INPUT_1_SOURCE),
173
174SOC_SINGLE("HPOUT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_1L,
175 ARIZONA_OUT1_OSR_SHIFT, 1, 0),
176SOC_SINGLE("OUT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_2L,
177 ARIZONA_OUT2_OSR_SHIFT, 1, 0),
178SOC_SINGLE("EPOUT High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_3L,
179 ARIZONA_OUT3_OSR_SHIFT, 1, 0),
180SOC_SINGLE("Speaker High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_4L,
181 ARIZONA_OUT4_OSR_SHIFT, 1, 0),
182SOC_SINGLE("SPKDAT1 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_5L,
183 ARIZONA_OUT5_OSR_SHIFT, 1, 0),
184SOC_SINGLE("SPKDAT2 High Performance Switch", ARIZONA_OUTPUT_PATH_CONFIG_6L,
185 ARIZONA_OUT6_OSR_SHIFT, 1, 0),
186
187SOC_DOUBLE_R("HPOUT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_1L,
188 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_MUTE_SHIFT, 1, 1),
189SOC_DOUBLE_R("OUT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_2L,
190 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_MUTE_SHIFT, 1, 1),
191SOC_SINGLE("EPOUT Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_3L,
192 ARIZONA_OUT3L_MUTE_SHIFT, 1, 1),
193SOC_DOUBLE_R("Speaker Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_4L,
194 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_MUTE_SHIFT, 1, 1),
195SOC_DOUBLE_R("SPKDAT1 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_5L,
196 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_MUTE_SHIFT, 1, 1),
197SOC_DOUBLE_R("SPKDAT2 Digital Switch", ARIZONA_DAC_DIGITAL_VOLUME_6L,
198 ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_MUTE_SHIFT, 1, 1),
199
200SOC_DOUBLE_R_TLV("HPOUT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_1L,
201 ARIZONA_DAC_DIGITAL_VOLUME_1R, ARIZONA_OUT1L_VOL_SHIFT,
202 0xbf, 0, digital_tlv),
203SOC_DOUBLE_R_TLV("OUT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_2L,
204 ARIZONA_DAC_DIGITAL_VOLUME_2R, ARIZONA_OUT2L_VOL_SHIFT,
205 0xbf, 0, digital_tlv),
206SOC_SINGLE_TLV("EPOUT Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_3L,
207 ARIZONA_OUT3L_VOL_SHIFT, 0xbf, 0, digital_tlv),
208SOC_DOUBLE_R_TLV("Speaker Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_4L,
209 ARIZONA_DAC_DIGITAL_VOLUME_4R, ARIZONA_OUT4L_VOL_SHIFT,
210 0xbf, 0, digital_tlv),
211SOC_DOUBLE_R_TLV("SPKDAT1 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_5L,
212 ARIZONA_DAC_DIGITAL_VOLUME_5R, ARIZONA_OUT5L_VOL_SHIFT,
213 0xbf, 0, digital_tlv),
214SOC_DOUBLE_R_TLV("SPKDAT2 Digital Volume", ARIZONA_DAC_DIGITAL_VOLUME_6L,
215 ARIZONA_DAC_DIGITAL_VOLUME_6R, ARIZONA_OUT6L_VOL_SHIFT,
216 0xbf, 0, digital_tlv),
217
218SOC_DOUBLE_R_RANGE_TLV("HPOUT1 Volume", ARIZONA_OUTPUT_PATH_CONFIG_1L,
219 ARIZONA_OUTPUT_PATH_CONFIG_1R,
220 ARIZONA_OUT1L_PGA_VOL_SHIFT,
221 0x34, 0x40, 0, ana_tlv),
222SOC_DOUBLE_R_RANGE_TLV("OUT2 Volume", ARIZONA_OUTPUT_PATH_CONFIG_2L,
223 ARIZONA_OUTPUT_PATH_CONFIG_2R,
224 ARIZONA_OUT2L_PGA_VOL_SHIFT,
225 0x34, 0x40, 0, ana_tlv),
226SOC_SINGLE_RANGE_TLV("EPOUT Volume", ARIZONA_OUTPUT_PATH_CONFIG_3L,
227 ARIZONA_OUT3L_PGA_VOL_SHIFT, 0x34, 0x40, 0, ana_tlv),
228
229SOC_DOUBLE("SPKDAT1 Switch", ARIZONA_PDM_SPK1_CTRL_1, ARIZONA_SPK1L_MUTE_SHIFT,
230 ARIZONA_SPK1R_MUTE_SHIFT, 1, 1),
231SOC_DOUBLE("SPKDAT2 Switch", ARIZONA_PDM_SPK2_CTRL_1, ARIZONA_SPK2L_MUTE_SHIFT,
232 ARIZONA_SPK2R_MUTE_SHIFT, 1, 1),
233
234ARIZONA_MIXER_CONTROLS("AIF1TX1", ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE),
235ARIZONA_MIXER_CONTROLS("AIF1TX2", ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE),
236ARIZONA_MIXER_CONTROLS("AIF1TX3", ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE),
237ARIZONA_MIXER_CONTROLS("AIF1TX4", ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE),
238ARIZONA_MIXER_CONTROLS("AIF1TX5", ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE),
239ARIZONA_MIXER_CONTROLS("AIF1TX6", ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE),
240ARIZONA_MIXER_CONTROLS("AIF1TX7", ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE),
241ARIZONA_MIXER_CONTROLS("AIF1TX8", ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE),
242
243ARIZONA_MIXER_CONTROLS("AIF2TX1", ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE),
244ARIZONA_MIXER_CONTROLS("AIF2TX2", ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE),
245
246ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
247ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
248};
249
250ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
251ARIZONA_MIXER_ENUMS(EQ2, ARIZONA_EQ2MIX_INPUT_1_SOURCE);
252ARIZONA_MIXER_ENUMS(EQ3, ARIZONA_EQ3MIX_INPUT_1_SOURCE);
253ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE);
254
255ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE);
256ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE);
257ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE);
258ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE);
259
260ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE);
261ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE);
262ARIZONA_MIXER_ENUMS(LHPF3, ARIZONA_HPLP3MIX_INPUT_1_SOURCE);
263ARIZONA_MIXER_ENUMS(LHPF4, ARIZONA_HPLP4MIX_INPUT_1_SOURCE);
264
265ARIZONA_MIXER_ENUMS(Mic, ARIZONA_MICMIX_INPUT_1_SOURCE);
266ARIZONA_MIXER_ENUMS(Noise, ARIZONA_NOISEMIX_INPUT_1_SOURCE);
267
268ARIZONA_MIXER_ENUMS(PWM1, ARIZONA_PWM1MIX_INPUT_1_SOURCE);
269ARIZONA_MIXER_ENUMS(PWM2, ARIZONA_PWM2MIX_INPUT_1_SOURCE);
270
271ARIZONA_MIXER_ENUMS(OUT1L, ARIZONA_OUT1LMIX_INPUT_1_SOURCE);
272ARIZONA_MIXER_ENUMS(OUT1R, ARIZONA_OUT1RMIX_INPUT_1_SOURCE);
273ARIZONA_MIXER_ENUMS(OUT2L, ARIZONA_OUT2LMIX_INPUT_1_SOURCE);
274ARIZONA_MIXER_ENUMS(OUT2R, ARIZONA_OUT2RMIX_INPUT_1_SOURCE);
275ARIZONA_MIXER_ENUMS(OUT3, ARIZONA_OUT3LMIX_INPUT_1_SOURCE);
276ARIZONA_MIXER_ENUMS(SPKOUTL, ARIZONA_OUT4LMIX_INPUT_1_SOURCE);
277ARIZONA_MIXER_ENUMS(SPKOUTR, ARIZONA_OUT4RMIX_INPUT_1_SOURCE);
278ARIZONA_MIXER_ENUMS(SPKDAT1L, ARIZONA_OUT5LMIX_INPUT_1_SOURCE);
279ARIZONA_MIXER_ENUMS(SPKDAT1R, ARIZONA_OUT5RMIX_INPUT_1_SOURCE);
280ARIZONA_MIXER_ENUMS(SPKDAT2L, ARIZONA_OUT6LMIX_INPUT_1_SOURCE);
281ARIZONA_MIXER_ENUMS(SPKDAT2R, ARIZONA_OUT6RMIX_INPUT_1_SOURCE);
282
283ARIZONA_MIXER_ENUMS(AIF1TX1, ARIZONA_AIF1TX1MIX_INPUT_1_SOURCE);
284ARIZONA_MIXER_ENUMS(AIF1TX2, ARIZONA_AIF1TX2MIX_INPUT_1_SOURCE);
285ARIZONA_MIXER_ENUMS(AIF1TX3, ARIZONA_AIF1TX3MIX_INPUT_1_SOURCE);
286ARIZONA_MIXER_ENUMS(AIF1TX4, ARIZONA_AIF1TX4MIX_INPUT_1_SOURCE);
287ARIZONA_MIXER_ENUMS(AIF1TX5, ARIZONA_AIF1TX5MIX_INPUT_1_SOURCE);
288ARIZONA_MIXER_ENUMS(AIF1TX6, ARIZONA_AIF1TX6MIX_INPUT_1_SOURCE);
289ARIZONA_MIXER_ENUMS(AIF1TX7, ARIZONA_AIF1TX7MIX_INPUT_1_SOURCE);
290ARIZONA_MIXER_ENUMS(AIF1TX8, ARIZONA_AIF1TX8MIX_INPUT_1_SOURCE);
291
292ARIZONA_MIXER_ENUMS(AIF2TX1, ARIZONA_AIF2TX1MIX_INPUT_1_SOURCE);
293ARIZONA_MIXER_ENUMS(AIF2TX2, ARIZONA_AIF2TX2MIX_INPUT_1_SOURCE);
294
295ARIZONA_MIXER_ENUMS(AIF3TX1, ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE);
296ARIZONA_MIXER_ENUMS(AIF3TX2, ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE);
297
298ARIZONA_MIXER_ENUMS(ASRC1L, ARIZONA_ASRC1LMIX_INPUT_1_SOURCE);
299ARIZONA_MIXER_ENUMS(ASRC1R, ARIZONA_ASRC1RMIX_INPUT_1_SOURCE);
300ARIZONA_MIXER_ENUMS(ASRC2L, ARIZONA_ASRC2LMIX_INPUT_1_SOURCE);
301ARIZONA_MIXER_ENUMS(ASRC2R, ARIZONA_ASRC2RMIX_INPUT_1_SOURCE);
302
303static const struct snd_soc_dapm_widget wm5110_dapm_widgets[] = {
304SND_SOC_DAPM_SUPPLY("SYSCLK", ARIZONA_SYSTEM_CLOCK_1, ARIZONA_SYSCLK_ENA_SHIFT,
305 0, NULL, 0),
306SND_SOC_DAPM_SUPPLY("ASYNCCLK", ARIZONA_ASYNC_CLOCK_1,
307 ARIZONA_ASYNC_CLK_ENA_SHIFT, 0, NULL, 0),
308
309SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD2", 0),
310SND_SOC_DAPM_REGULATOR_SUPPLY("DBVDD3", 0),
311SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20),
312SND_SOC_DAPM_REGULATOR_SUPPLY("MICVDD", 0),
313SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDL", 0),
314SND_SOC_DAPM_REGULATOR_SUPPLY("SPKVDDR", 0),
315
316SND_SOC_DAPM_SIGGEN("TONE"),
317SND_SOC_DAPM_SIGGEN("NOISE"),
318
319SND_SOC_DAPM_INPUT("IN1L"),
320SND_SOC_DAPM_INPUT("IN1R"),
321SND_SOC_DAPM_INPUT("IN2L"),
322SND_SOC_DAPM_INPUT("IN2R"),
323SND_SOC_DAPM_INPUT("IN3L"),
324SND_SOC_DAPM_INPUT("IN3R"),
325SND_SOC_DAPM_INPUT("IN4L"),
326SND_SOC_DAPM_INPUT("IN4R"),
327
328SND_SOC_DAPM_PGA_E("IN1L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1L_ENA_SHIFT,
329 0, NULL, 0, arizona_in_ev,
330 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
331SND_SOC_DAPM_PGA_E("IN1R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN1R_ENA_SHIFT,
332 0, NULL, 0, arizona_in_ev,
333 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
334SND_SOC_DAPM_PGA_E("IN2L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2L_ENA_SHIFT,
335 0, NULL, 0, arizona_in_ev,
336 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
337SND_SOC_DAPM_PGA_E("IN2R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN2R_ENA_SHIFT,
338 0, NULL, 0, arizona_in_ev,
339 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
340SND_SOC_DAPM_PGA_E("IN3L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3L_ENA_SHIFT,
341 0, NULL, 0, arizona_in_ev,
342 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
343SND_SOC_DAPM_PGA_E("IN3R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN3R_ENA_SHIFT,
344 0, NULL, 0, arizona_in_ev,
345 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
346SND_SOC_DAPM_PGA_E("IN4L PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4L_ENA_SHIFT,
347 0, NULL, 0, arizona_in_ev,
348 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
349SND_SOC_DAPM_PGA_E("IN4R PGA", ARIZONA_INPUT_ENABLES, ARIZONA_IN4R_ENA_SHIFT,
350 0, NULL, 0, arizona_in_ev,
351 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
352
353SND_SOC_DAPM_SUPPLY("MICBIAS1", ARIZONA_MIC_BIAS_CTRL_1,
354 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
355SND_SOC_DAPM_SUPPLY("MICBIAS2", ARIZONA_MIC_BIAS_CTRL_2,
356 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
357SND_SOC_DAPM_SUPPLY("MICBIAS3", ARIZONA_MIC_BIAS_CTRL_3,
358 ARIZONA_MICB1_ENA_SHIFT, 0, NULL, 0),
359
360SND_SOC_DAPM_PGA("Noise Generator", ARIZONA_COMFORT_NOISE_GENERATOR,
361 ARIZONA_NOISE_GEN_ENA_SHIFT, 0, NULL, 0),
362
363SND_SOC_DAPM_PGA("Tone Generator 1", ARIZONA_TONE_GENERATOR_1,
364 ARIZONA_TONE1_ENA_SHIFT, 0, NULL, 0),
365SND_SOC_DAPM_PGA("Tone Generator 2", ARIZONA_TONE_GENERATOR_1,
366 ARIZONA_TONE2_ENA_SHIFT, 0, NULL, 0),
367
368SND_SOC_DAPM_PGA("Mic Mute Mixer", ARIZONA_MIC_NOISE_MIX_CONTROL_1,
369 ARIZONA_MICMUTE_MIX_ENA_SHIFT, 0, NULL, 0),
370
371SND_SOC_DAPM_PGA("EQ1", ARIZONA_EQ1_1, ARIZONA_EQ1_ENA_SHIFT, 0, NULL, 0),
372SND_SOC_DAPM_PGA("EQ2", ARIZONA_EQ2_1, ARIZONA_EQ2_ENA_SHIFT, 0, NULL, 0),
373SND_SOC_DAPM_PGA("EQ3", ARIZONA_EQ3_1, ARIZONA_EQ3_ENA_SHIFT, 0, NULL, 0),
374SND_SOC_DAPM_PGA("EQ4", ARIZONA_EQ4_1, ARIZONA_EQ4_ENA_SHIFT, 0, NULL, 0),
375
376SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0,
377 NULL, 0),
378SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0,
379 NULL, 0),
380SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0,
381 NULL, 0),
382SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0,
383 NULL, 0),
384
385SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0,
386 NULL, 0),
387SND_SOC_DAPM_PGA("LHPF2", ARIZONA_HPLPF2_1, ARIZONA_LHPF2_ENA_SHIFT, 0,
388 NULL, 0),
389SND_SOC_DAPM_PGA("LHPF3", ARIZONA_HPLPF3_1, ARIZONA_LHPF3_ENA_SHIFT, 0,
390 NULL, 0),
391SND_SOC_DAPM_PGA("LHPF4", ARIZONA_HPLPF4_1, ARIZONA_LHPF4_ENA_SHIFT, 0,
392 NULL, 0),
393
394SND_SOC_DAPM_PGA("PWM1 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM1_ENA_SHIFT,
395 0, NULL, 0),
396SND_SOC_DAPM_PGA("PWM2 Driver", ARIZONA_PWM_DRIVE_1, ARIZONA_PWM2_ENA_SHIFT,
397 0, NULL, 0),
398
399SND_SOC_DAPM_PGA("ASRC1L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1L_ENA_SHIFT, 0,
400 NULL, 0),
401SND_SOC_DAPM_PGA("ASRC1R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC1R_ENA_SHIFT, 0,
402 NULL, 0),
403SND_SOC_DAPM_PGA("ASRC2L", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2L_ENA_SHIFT, 0,
404 NULL, 0),
405SND_SOC_DAPM_PGA("ASRC2R", ARIZONA_ASRC_ENABLE, ARIZONA_ASRC2R_ENA_SHIFT, 0,
406 NULL, 0),
407
408SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 0,
409 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX1_ENA_SHIFT, 0),
410SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 0,
411 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX2_ENA_SHIFT, 0),
412SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 0,
413 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX3_ENA_SHIFT, 0),
414SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 0,
415 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX4_ENA_SHIFT, 0),
416SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 0,
417 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX5_ENA_SHIFT, 0),
418SND_SOC_DAPM_AIF_OUT("AIF1TX6", NULL, 0,
419 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX6_ENA_SHIFT, 0),
420SND_SOC_DAPM_AIF_OUT("AIF1TX7", NULL, 0,
421 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX7_ENA_SHIFT, 0),
422SND_SOC_DAPM_AIF_OUT("AIF1TX8", NULL, 0,
423 ARIZONA_AIF1_TX_ENABLES, ARIZONA_AIF1TX8_ENA_SHIFT, 0),
424
425SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 0,
426 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX1_ENA_SHIFT, 0),
427SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 0,
428 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX2_ENA_SHIFT, 0),
429SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 0,
430 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX3_ENA_SHIFT, 0),
431SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 0,
432 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX4_ENA_SHIFT, 0),
433SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 0,
434 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX5_ENA_SHIFT, 0),
435SND_SOC_DAPM_AIF_IN("AIF1RX6", NULL, 0,
436 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX6_ENA_SHIFT, 0),
437SND_SOC_DAPM_AIF_IN("AIF1RX7", NULL, 0,
438 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX7_ENA_SHIFT, 0),
439SND_SOC_DAPM_AIF_IN("AIF1RX8", NULL, 0,
440 ARIZONA_AIF1_RX_ENABLES, ARIZONA_AIF1RX8_ENA_SHIFT, 0),
441
442SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0,
443 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX1_ENA_SHIFT, 0),
444SND_SOC_DAPM_AIF_OUT("AIF2TX2", NULL, 0,
445 ARIZONA_AIF2_TX_ENABLES, ARIZONA_AIF2TX2_ENA_SHIFT, 0),
446
447SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0,
448 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX1_ENA_SHIFT, 0),
449SND_SOC_DAPM_AIF_IN("AIF2RX2", NULL, 0,
450 ARIZONA_AIF2_RX_ENABLES, ARIZONA_AIF2RX2_ENA_SHIFT, 0),
451
452SND_SOC_DAPM_AIF_OUT("AIF3TX1", NULL, 0,
453 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX1_ENA_SHIFT, 0),
454SND_SOC_DAPM_AIF_OUT("AIF3TX2", NULL, 0,
455 ARIZONA_AIF3_TX_ENABLES, ARIZONA_AIF3TX2_ENA_SHIFT, 0),
456
457SND_SOC_DAPM_AIF_IN("AIF3RX1", NULL, 0,
458 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX1_ENA_SHIFT, 0),
459SND_SOC_DAPM_AIF_IN("AIF3RX2", NULL, 0,
460 ARIZONA_AIF3_RX_ENABLES, ARIZONA_AIF3RX2_ENA_SHIFT, 0),
461
462SND_SOC_DAPM_PGA_E("OUT1L", ARIZONA_OUTPUT_ENABLES_1,
463 ARIZONA_OUT1L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
464 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
465SND_SOC_DAPM_PGA_E("OUT1R", ARIZONA_OUTPUT_ENABLES_1,
466 ARIZONA_OUT1R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
467 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
468SND_SOC_DAPM_PGA_E("OUT2L", ARIZONA_OUTPUT_ENABLES_1,
469 ARIZONA_OUT2L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
470 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
471SND_SOC_DAPM_PGA_E("OUT2R", ARIZONA_OUTPUT_ENABLES_1,
472 ARIZONA_OUT2R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
473 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
474SND_SOC_DAPM_PGA_E("OUT3L", ARIZONA_OUTPUT_ENABLES_1,
475 ARIZONA_OUT3L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
476 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
477SND_SOC_DAPM_PGA_E("OUT4L", ARIZONA_OUTPUT_ENABLES_1,
478 ARIZONA_OUT4L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
479 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
480SND_SOC_DAPM_PGA_E("OUT4R", ARIZONA_OUTPUT_ENABLES_1,
481 ARIZONA_OUT4R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
482 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
483SND_SOC_DAPM_PGA_E("OUT5L", ARIZONA_OUTPUT_ENABLES_1,
484 ARIZONA_OUT5L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
485 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
486SND_SOC_DAPM_PGA_E("OUT5R", ARIZONA_OUTPUT_ENABLES_1,
487 ARIZONA_OUT5R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
488 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
489SND_SOC_DAPM_PGA_E("OUT6L", ARIZONA_OUTPUT_ENABLES_1,
490 ARIZONA_OUT6L_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
491 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
492SND_SOC_DAPM_PGA_E("OUT6R", ARIZONA_OUTPUT_ENABLES_1,
493 ARIZONA_OUT6R_ENA_SHIFT, 0, NULL, 0, arizona_out_ev,
494 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
495
496ARIZONA_MIXER_WIDGETS(EQ1, "EQ1"),
497ARIZONA_MIXER_WIDGETS(EQ2, "EQ2"),
498ARIZONA_MIXER_WIDGETS(EQ3, "EQ3"),
499ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"),
500
501ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"),
502ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"),
503ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"),
504ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"),
505
506ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"),
507ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"),
508ARIZONA_MIXER_WIDGETS(LHPF3, "LHPF3"),
509ARIZONA_MIXER_WIDGETS(LHPF4, "LHPF4"),
510
511ARIZONA_MIXER_WIDGETS(Mic, "Mic"),
512ARIZONA_MIXER_WIDGETS(Noise, "Noise"),
513
514ARIZONA_MIXER_WIDGETS(PWM1, "PWM1"),
515ARIZONA_MIXER_WIDGETS(PWM2, "PWM2"),
516
517ARIZONA_MIXER_WIDGETS(OUT1L, "HPOUT1L"),
518ARIZONA_MIXER_WIDGETS(OUT1R, "HPOUT1R"),
519ARIZONA_MIXER_WIDGETS(OUT2L, "HPOUT2L"),
520ARIZONA_MIXER_WIDGETS(OUT2R, "HPOUT2R"),
521ARIZONA_MIXER_WIDGETS(OUT3, "EPOUT"),
522ARIZONA_MIXER_WIDGETS(SPKOUTL, "SPKOUTL"),
523ARIZONA_MIXER_WIDGETS(SPKOUTR, "SPKOUTR"),
524ARIZONA_MIXER_WIDGETS(SPKDAT1L, "SPKDAT1L"),
525ARIZONA_MIXER_WIDGETS(SPKDAT1R, "SPKDAT1R"),
526ARIZONA_MIXER_WIDGETS(SPKDAT2L, "SPKDAT2L"),
527ARIZONA_MIXER_WIDGETS(SPKDAT2R, "SPKDAT2R"),
528
529ARIZONA_MIXER_WIDGETS(AIF1TX1, "AIF1TX1"),
530ARIZONA_MIXER_WIDGETS(AIF1TX2, "AIF1TX2"),
531ARIZONA_MIXER_WIDGETS(AIF1TX3, "AIF1TX3"),
532ARIZONA_MIXER_WIDGETS(AIF1TX4, "AIF1TX4"),
533ARIZONA_MIXER_WIDGETS(AIF1TX5, "AIF1TX5"),
534ARIZONA_MIXER_WIDGETS(AIF1TX6, "AIF1TX6"),
535ARIZONA_MIXER_WIDGETS(AIF1TX7, "AIF1TX7"),
536ARIZONA_MIXER_WIDGETS(AIF1TX8, "AIF1TX8"),
537
538ARIZONA_MIXER_WIDGETS(AIF2TX1, "AIF2TX1"),
539ARIZONA_MIXER_WIDGETS(AIF2TX2, "AIF2TX2"),
540
541ARIZONA_MIXER_WIDGETS(AIF3TX1, "AIF3TX1"),
542ARIZONA_MIXER_WIDGETS(AIF3TX2, "AIF3TX2"),
543
544ARIZONA_MIXER_WIDGETS(ASRC1L, "ASRC1L"),
545ARIZONA_MIXER_WIDGETS(ASRC1R, "ASRC1R"),
546ARIZONA_MIXER_WIDGETS(ASRC2L, "ASRC2L"),
547ARIZONA_MIXER_WIDGETS(ASRC2R, "ASRC2R"),
548
549SND_SOC_DAPM_OUTPUT("HPOUT1L"),
550SND_SOC_DAPM_OUTPUT("HPOUT1R"),
551SND_SOC_DAPM_OUTPUT("HPOUT2L"),
552SND_SOC_DAPM_OUTPUT("HPOUT2R"),
553SND_SOC_DAPM_OUTPUT("EPOUTN"),
554SND_SOC_DAPM_OUTPUT("EPOUTP"),
555SND_SOC_DAPM_OUTPUT("SPKOUTLN"),
556SND_SOC_DAPM_OUTPUT("SPKOUTLP"),
557SND_SOC_DAPM_OUTPUT("SPKOUTRN"),
558SND_SOC_DAPM_OUTPUT("SPKOUTRP"),
559SND_SOC_DAPM_OUTPUT("SPKDAT1L"),
560SND_SOC_DAPM_OUTPUT("SPKDAT1R"),
561SND_SOC_DAPM_OUTPUT("SPKDAT2L"),
562SND_SOC_DAPM_OUTPUT("SPKDAT2R"),
563};
564
565#define ARIZONA_MIXER_INPUT_ROUTES(name) \
566 { name, "Noise Generator", "Noise Generator" }, \
567 { name, "Tone Generator 1", "Tone Generator 1" }, \
568 { name, "Tone Generator 2", "Tone Generator 2" }, \
569 { name, "IN1L", "IN1L PGA" }, \
570 { name, "IN1R", "IN1R PGA" }, \
571 { name, "IN2L", "IN2L PGA" }, \
572 { name, "IN2R", "IN2R PGA" }, \
573 { name, "IN3L", "IN3L PGA" }, \
574 { name, "IN3R", "IN3R PGA" }, \
575 { name, "IN4L", "IN4L PGA" }, \
576 { name, "IN4R", "IN4R PGA" }, \
577 { name, "Mic Mute Mixer", "Mic Mute Mixer" }, \
578 { name, "AIF1RX1", "AIF1RX1" }, \
579 { name, "AIF1RX2", "AIF1RX2" }, \
580 { name, "AIF1RX3", "AIF1RX3" }, \
581 { name, "AIF1RX4", "AIF1RX4" }, \
582 { name, "AIF1RX5", "AIF1RX5" }, \
583 { name, "AIF1RX6", "AIF1RX6" }, \
584 { name, "AIF1RX7", "AIF1RX7" }, \
585 { name, "AIF1RX8", "AIF1RX8" }, \
586 { name, "AIF2RX1", "AIF2RX1" }, \
587 { name, "AIF2RX2", "AIF2RX2" }, \
588 { name, "AIF3RX1", "AIF3RX1" }, \
589 { name, "AIF3RX2", "AIF3RX2" }, \
590 { name, "EQ1", "EQ1" }, \
591 { name, "EQ2", "EQ2" }, \
592 { name, "EQ3", "EQ3" }, \
593 { name, "EQ4", "EQ4" }, \
594 { name, "DRC1L", "DRC1L" }, \
595 { name, "DRC1R", "DRC1R" }, \
596 { name, "DRC2L", "DRC2L" }, \
597 { name, "DRC2R", "DRC2R" }, \
598 { name, "LHPF1", "LHPF1" }, \
599 { name, "LHPF2", "LHPF2" }, \
600 { name, "LHPF3", "LHPF3" }, \
601 { name, "LHPF4", "LHPF4" }, \
602 { name, "ASRC1L", "ASRC1L" }, \
603 { name, "ASRC1R", "ASRC1R" }, \
604 { name, "ASRC2L", "ASRC2L" }, \
605 { name, "ASRC2R", "ASRC2R" }
606
607static const struct snd_soc_dapm_route wm5110_dapm_routes[] = {
608 { "AIF2 Capture", NULL, "DBVDD2" },
609 { "AIF2 Playback", NULL, "DBVDD2" },
610
611 { "AIF3 Capture", NULL, "DBVDD3" },
612 { "AIF3 Playback", NULL, "DBVDD3" },
613
614 { "OUT1L", NULL, "CPVDD" },
615 { "OUT1R", NULL, "CPVDD" },
616 { "OUT2L", NULL, "CPVDD" },
617 { "OUT2R", NULL, "CPVDD" },
618 { "OUT3L", NULL, "CPVDD" },
619
620 { "OUT4L", NULL, "SPKVDDL" },
621 { "OUT4R", NULL, "SPKVDDR" },
622
623 { "OUT1L", NULL, "SYSCLK" },
624 { "OUT1R", NULL, "SYSCLK" },
625 { "OUT2L", NULL, "SYSCLK" },
626 { "OUT2R", NULL, "SYSCLK" },
627 { "OUT3L", NULL, "SYSCLK" },
628 { "OUT4L", NULL, "SYSCLK" },
629 { "OUT4R", NULL, "SYSCLK" },
630 { "OUT5L", NULL, "SYSCLK" },
631 { "OUT5R", NULL, "SYSCLK" },
632 { "OUT6L", NULL, "SYSCLK" },
633 { "OUT6R", NULL, "SYSCLK" },
634
635 { "MICBIAS1", NULL, "MICVDD" },
636 { "MICBIAS2", NULL, "MICVDD" },
637 { "MICBIAS3", NULL, "MICVDD" },
638
639 { "Noise Generator", NULL, "NOISE" },
640 { "Tone Generator 1", NULL, "TONE" },
641 { "Tone Generator 2", NULL, "TONE" },
642
643 { "Mic Mute Mixer", NULL, "Noise Mixer" },
644 { "Mic Mute Mixer", NULL, "Mic Mixer" },
645
646 { "AIF1 Capture", NULL, "AIF1TX1" },
647 { "AIF1 Capture", NULL, "AIF1TX2" },
648 { "AIF1 Capture", NULL, "AIF1TX3" },
649 { "AIF1 Capture", NULL, "AIF1TX4" },
650 { "AIF1 Capture", NULL, "AIF1TX5" },
651 { "AIF1 Capture", NULL, "AIF1TX6" },
652 { "AIF1 Capture", NULL, "AIF1TX7" },
653 { "AIF1 Capture", NULL, "AIF1TX8" },
654
655 { "AIF1RX1", NULL, "AIF1 Playback" },
656 { "AIF1RX2", NULL, "AIF1 Playback" },
657 { "AIF1RX3", NULL, "AIF1 Playback" },
658 { "AIF1RX4", NULL, "AIF1 Playback" },
659 { "AIF1RX5", NULL, "AIF1 Playback" },
660 { "AIF1RX6", NULL, "AIF1 Playback" },
661 { "AIF1RX7", NULL, "AIF1 Playback" },
662 { "AIF1RX8", NULL, "AIF1 Playback" },
663
664 { "AIF2 Capture", NULL, "AIF2TX1" },
665 { "AIF2 Capture", NULL, "AIF2TX2" },
666
667 { "AIF2RX1", NULL, "AIF2 Playback" },
668 { "AIF2RX2", NULL, "AIF2 Playback" },
669
670 { "AIF3 Capture", NULL, "AIF3TX1" },
671 { "AIF3 Capture", NULL, "AIF3TX2" },
672
673 { "AIF3RX1", NULL, "AIF3 Playback" },
674 { "AIF3RX2", NULL, "AIF3 Playback" },
675
676 { "AIF1 Playback", NULL, "SYSCLK" },
677 { "AIF2 Playback", NULL, "SYSCLK" },
678 { "AIF3 Playback", NULL, "SYSCLK" },
679
680 { "AIF1 Capture", NULL, "SYSCLK" },
681 { "AIF2 Capture", NULL, "SYSCLK" },
682 { "AIF3 Capture", NULL, "SYSCLK" },
683
684 ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"),
685 ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"),
686 ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"),
687 ARIZONA_MIXER_ROUTES("OUT2R", "HPOUT2R"),
688 ARIZONA_MIXER_ROUTES("OUT3L", "EPOUT"),
689
690 ARIZONA_MIXER_ROUTES("OUT4L", "SPKOUTL"),
691 ARIZONA_MIXER_ROUTES("OUT4R", "SPKOUTR"),
692 ARIZONA_MIXER_ROUTES("OUT5L", "SPKDAT1L"),
693 ARIZONA_MIXER_ROUTES("OUT5R", "SPKDAT1R"),
694 ARIZONA_MIXER_ROUTES("OUT6L", "SPKDAT2L"),
695 ARIZONA_MIXER_ROUTES("OUT6R", "SPKDAT2R"),
696
697 ARIZONA_MIXER_ROUTES("PWM1 Driver", "PWM1"),
698 ARIZONA_MIXER_ROUTES("PWM2 Driver", "PWM2"),
699
700 ARIZONA_MIXER_ROUTES("AIF1TX1", "AIF1TX1"),
701 ARIZONA_MIXER_ROUTES("AIF1TX2", "AIF1TX2"),
702 ARIZONA_MIXER_ROUTES("AIF1TX3", "AIF1TX3"),
703 ARIZONA_MIXER_ROUTES("AIF1TX4", "AIF1TX4"),
704 ARIZONA_MIXER_ROUTES("AIF1TX5", "AIF1TX5"),
705 ARIZONA_MIXER_ROUTES("AIF1TX6", "AIF1TX6"),
706 ARIZONA_MIXER_ROUTES("AIF1TX7", "AIF1TX7"),
707 ARIZONA_MIXER_ROUTES("AIF1TX8", "AIF1TX8"),
708
709 ARIZONA_MIXER_ROUTES("AIF2TX1", "AIF2TX1"),
710 ARIZONA_MIXER_ROUTES("AIF2TX2", "AIF2TX2"),
711
712 ARIZONA_MIXER_ROUTES("AIF3TX1", "AIF3TX1"),
713 ARIZONA_MIXER_ROUTES("AIF3TX2", "AIF3TX2"),
714
715 ARIZONA_MIXER_ROUTES("EQ1", "EQ1"),
716 ARIZONA_MIXER_ROUTES("EQ2", "EQ2"),
717 ARIZONA_MIXER_ROUTES("EQ3", "EQ3"),
718 ARIZONA_MIXER_ROUTES("EQ4", "EQ4"),
719
720 ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"),
721 ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"),
722 ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"),
723 ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"),
724
725 ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"),
726 ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"),
727 ARIZONA_MIXER_ROUTES("LHPF3", "LHPF3"),
728 ARIZONA_MIXER_ROUTES("LHPF4", "LHPF4"),
729
730 ARIZONA_MIXER_ROUTES("ASRC1L", "ASRC1L"),
731 ARIZONA_MIXER_ROUTES("ASRC1R", "ASRC1R"),
732 ARIZONA_MIXER_ROUTES("ASRC2L", "ASRC2L"),
733 ARIZONA_MIXER_ROUTES("ASRC2R", "ASRC2R"),
734
735 { "HPOUT1L", NULL, "OUT1L" },
736 { "HPOUT1R", NULL, "OUT1R" },
737
738 { "HPOUT2L", NULL, "OUT2L" },
739 { "HPOUT2R", NULL, "OUT2R" },
740
741 { "EPOUTN", NULL, "OUT3L" },
742 { "EPOUTP", NULL, "OUT3L" },
743
744 { "SPKOUTLN", NULL, "OUT4L" },
745 { "SPKOUTLP", NULL, "OUT4L" },
746
747 { "SPKOUTRN", NULL, "OUT4R" },
748 { "SPKOUTRP", NULL, "OUT4R" },
749
750 { "SPKDAT1L", NULL, "OUT5L" },
751 { "SPKDAT1R", NULL, "OUT5R" },
752
753 { "SPKDAT2L", NULL, "OUT6L" },
754 { "SPKDAT2R", NULL, "OUT6R" },
755};
756
757static int wm5110_set_fll(struct snd_soc_codec *codec, int fll_id, int source,
758 unsigned int Fref, unsigned int Fout)
759{
760 struct wm5110_priv *wm5110 = snd_soc_codec_get_drvdata(codec);
761
762 switch (fll_id) {
763 case WM5110_FLL1:
764 return arizona_set_fll(&wm5110->fll[0], source, Fref, Fout);
765 case WM5110_FLL2:
766 return arizona_set_fll(&wm5110->fll[1], source, Fref, Fout);
767 default:
768 return -EINVAL;
769 }
770}
771
772#define WM5110_RATES SNDRV_PCM_RATE_8000_192000
773
774#define WM5110_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
775 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
776
777static struct snd_soc_dai_driver wm5110_dai[] = {
778 {
779 .name = "wm5110-aif1",
780 .id = 1,
781 .base = ARIZONA_AIF1_BCLK_CTRL,
782 .playback = {
783 .stream_name = "AIF1 Playback",
784 .channels_min = 1,
785 .channels_max = 8,
786 .rates = WM5110_RATES,
787 .formats = WM5110_FORMATS,
788 },
789 .capture = {
790 .stream_name = "AIF1 Capture",
791 .channels_min = 1,
792 .channels_max = 8,
793 .rates = WM5110_RATES,
794 .formats = WM5110_FORMATS,
795 },
796 .ops = &arizona_dai_ops,
797 .symmetric_rates = 1,
798 },
799 {
800 .name = "wm5110-aif2",
801 .id = 2,
802 .base = ARIZONA_AIF2_BCLK_CTRL,
803 .playback = {
804 .stream_name = "AIF2 Playback",
805 .channels_min = 1,
806 .channels_max = 2,
807 .rates = WM5110_RATES,
808 .formats = WM5110_FORMATS,
809 },
810 .capture = {
811 .stream_name = "AIF2 Capture",
812 .channels_min = 1,
813 .channels_max = 2,
814 .rates = WM5110_RATES,
815 .formats = WM5110_FORMATS,
816 },
817 .ops = &arizona_dai_ops,
818 .symmetric_rates = 1,
819 },
820 {
821 .name = "wm5110-aif3",
822 .id = 3,
823 .base = ARIZONA_AIF3_BCLK_CTRL,
824 .playback = {
825 .stream_name = "AIF3 Playback",
826 .channels_min = 1,
827 .channels_max = 2,
828 .rates = WM5110_RATES,
829 .formats = WM5110_FORMATS,
830 },
831 .capture = {
832 .stream_name = "AIF3 Capture",
833 .channels_min = 1,
834 .channels_max = 2,
835 .rates = WM5110_RATES,
836 .formats = WM5110_FORMATS,
837 },
838 .ops = &arizona_dai_ops,
839 .symmetric_rates = 1,
840 },
841};
842
843static int wm5110_codec_probe(struct snd_soc_codec *codec)
844{
845 struct wm5110_priv *priv = snd_soc_codec_get_drvdata(codec);
846
847 codec->control_data = priv->core.arizona->regmap;
848 return snd_soc_codec_set_cache_io(codec, 32, 16, SND_SOC_REGMAP);
849}
850
851#define WM5110_DIG_VU 0x0200
852
853static unsigned int wm5110_digital_vu[] = {
854 ARIZONA_ADC_DIGITAL_VOLUME_1L,
855 ARIZONA_ADC_DIGITAL_VOLUME_1R,
856 ARIZONA_ADC_DIGITAL_VOLUME_2L,
857 ARIZONA_ADC_DIGITAL_VOLUME_2R,
858 ARIZONA_ADC_DIGITAL_VOLUME_3L,
859 ARIZONA_ADC_DIGITAL_VOLUME_3R,
860
861 ARIZONA_DAC_DIGITAL_VOLUME_1L,
862 ARIZONA_DAC_DIGITAL_VOLUME_1R,
863 ARIZONA_DAC_DIGITAL_VOLUME_2L,
864 ARIZONA_DAC_DIGITAL_VOLUME_2R,
865 ARIZONA_DAC_DIGITAL_VOLUME_3L,
866 ARIZONA_DAC_DIGITAL_VOLUME_3R,
867 ARIZONA_DAC_DIGITAL_VOLUME_4L,
868 ARIZONA_DAC_DIGITAL_VOLUME_4R,
869 ARIZONA_DAC_DIGITAL_VOLUME_5L,
870 ARIZONA_DAC_DIGITAL_VOLUME_5R,
871};
872
873static struct snd_soc_codec_driver soc_codec_dev_wm5110 = {
874 .probe = wm5110_codec_probe,
875
876 .idle_bias_off = true,
877
878 .set_sysclk = arizona_set_sysclk,
879 .set_pll = wm5110_set_fll,
880
881 .controls = wm5110_snd_controls,
882 .num_controls = ARRAY_SIZE(wm5110_snd_controls),
883 .dapm_widgets = wm5110_dapm_widgets,
884 .num_dapm_widgets = ARRAY_SIZE(wm5110_dapm_widgets),
885 .dapm_routes = wm5110_dapm_routes,
886 .num_dapm_routes = ARRAY_SIZE(wm5110_dapm_routes),
887};
888
889static int __devinit wm5110_probe(struct platform_device *pdev)
890{
891 struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
892 struct wm5110_priv *wm5110;
893 int i;
894
895 wm5110 = devm_kzalloc(&pdev->dev, sizeof(struct wm5110_priv),
896 GFP_KERNEL);
897 if (wm5110 == NULL)
898 return -ENOMEM;
899 platform_set_drvdata(pdev, wm5110);
900
901 wm5110->core.arizona = arizona;
902
903 for (i = 0; i < ARRAY_SIZE(wm5110->fll); i++)
904 wm5110->fll[i].vco_mult = 3;
905
906 arizona_init_fll(arizona, 1, ARIZONA_FLL1_CONTROL_1 - 1,
907 ARIZONA_IRQ_FLL1_LOCK, ARIZONA_IRQ_FLL1_CLOCK_OK,
908 &wm5110->fll[0]);
909 arizona_init_fll(arizona, 2, ARIZONA_FLL2_CONTROL_1 - 1,
910 ARIZONA_IRQ_FLL2_LOCK, ARIZONA_IRQ_FLL2_CLOCK_OK,
911 &wm5110->fll[1]);
912
913 for (i = 0; i < ARRAY_SIZE(wm5110_dai); i++)
914 arizona_init_dai(&wm5110->core, i);
915
916 /* Latch volume update bits */
917 for (i = 0; i < ARRAY_SIZE(wm5110_digital_vu); i++)
918 regmap_update_bits(arizona->regmap, wm5110_digital_vu[i],
919 WM5110_DIG_VU, WM5110_DIG_VU);
920
921 pm_runtime_enable(&pdev->dev);
922 pm_runtime_idle(&pdev->dev);
923
924 return snd_soc_register_codec(&pdev->dev, &soc_codec_dev_wm5110,
925 wm5110_dai, ARRAY_SIZE(wm5110_dai));
926}
927
928static int __devexit wm5110_remove(struct platform_device *pdev)
929{
930 snd_soc_unregister_codec(&pdev->dev);
931 pm_runtime_disable(&pdev->dev);
932
933 return 0;
934}
935
936static struct platform_driver wm5110_codec_driver = {
937 .driver = {
938 .name = "wm5110-codec",
939 .owner = THIS_MODULE,
940 },
941 .probe = wm5110_probe,
942 .remove = __devexit_p(wm5110_remove),
943};
944
945module_platform_driver(wm5110_codec_driver);
946
947MODULE_DESCRIPTION("ASoC WM5110 driver");
948MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
949MODULE_LICENSE("GPL");
950MODULE_ALIAS("platform:wm5110-codec");
diff --git a/sound/soc/codecs/wm5110.h b/sound/soc/codecs/wm5110.h
new file mode 100644
index 00000000000..75e9351ccab
--- /dev/null
+++ b/sound/soc/codecs/wm5110.h
@@ -0,0 +1,21 @@
1/*
2 * wm5110.h -- WM5110 ALSA SoC Audio driver
3 *
4 * Copyright 2012 Wolfson Microelectronics plc
5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#ifndef _WM5110_H
14#define _WM5110_H
15
16#include "arizona.h"
17
18#define WM5110_FLL1 1
19#define WM5110_FLL2 2
20
21#endif
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c
index 555ee146ae0..d26c8ae4e6d 100644
--- a/sound/soc/codecs/wm8350.c
+++ b/sound/soc/codecs/wm8350.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8350.c -- WM8350 ALSA SoC audio driver 2 * wm8350.c -- WM8350 ALSA SoC audio driver
3 * 3 *
4 * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC. 4 * Copyright (C) 2007-12 Wolfson Microelectronics PLC.
5 * 5 *
6 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 6 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
7 * 7 *
@@ -71,20 +71,6 @@ struct wm8350_data {
71 int fll_freq_in; 71 int fll_freq_in;
72}; 72};
73 73
74static unsigned int wm8350_codec_read(struct snd_soc_codec *codec,
75 unsigned int reg)
76{
77 struct wm8350 *wm8350 = codec->control_data;
78 return wm8350_reg_read(wm8350, reg);
79}
80
81static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg,
82 unsigned int value)
83{
84 struct wm8350 *wm8350 = codec->control_data;
85 return wm8350_reg_write(wm8350, reg, value);
86}
87
88/* 74/*
89 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown. 75 * Ramp OUT1 PGA volume to minimise pops at stream startup and shutdown.
90 */ 76 */
@@ -1519,7 +1505,9 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec)
1519 if (ret != 0) 1505 if (ret != 0)
1520 return ret; 1506 return ret;
1521 1507
1522 codec->control_data = wm8350; 1508 codec->control_data = wm8350->regmap;
1509
1510 snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
1523 1511
1524 /* Put the codec into reset if it wasn't already */ 1512 /* Put the codec into reset if it wasn't already */
1525 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); 1513 wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);
@@ -1629,8 +1617,6 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8350 = {
1629 .remove = wm8350_codec_remove, 1617 .remove = wm8350_codec_remove,
1630 .suspend = wm8350_suspend, 1618 .suspend = wm8350_suspend,
1631 .resume = wm8350_resume, 1619 .resume = wm8350_resume,
1632 .read = wm8350_codec_read,
1633 .write = wm8350_codec_write,
1634 .set_bias_level = wm8350_set_bias_level, 1620 .set_bias_level = wm8350_set_bias_level,
1635 1621
1636 .controls = wm8350_snd_controls, 1622 .controls = wm8350_snd_controls,
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c
index 5dc31ebcd0e..5d277a915f8 100644
--- a/sound/soc/codecs/wm8400.c
+++ b/sound/soc/codecs/wm8400.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8400.c -- WM8400 ALSA Soc Audio driver 2 * wm8400.c -- WM8400 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008, 2009 Wolfson Microelectronics PLC. 4 * Copyright 2008-11 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 211285164d7..7c68226376e 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8580.c -- WM8580 ALSA Soc Audio driver 2 * wm8580.c -- WM8580 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2008, 2009 Wolfson Microelectronics PLC. 4 * Copyright 2008-11 Wolfson Microelectronics PLC.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the 7 * under the terms of the GNU General Public License as published by the
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c
index 9d1b9b0271f..bb1d26919b1 100644
--- a/sound/soc/codecs/wm8731.c
+++ b/sound/soc/codecs/wm8731.c
@@ -2,6 +2,7 @@
2 * wm8731.c -- WM8731 ALSA SoC Audio driver 2 * wm8731.c -- WM8731 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2005 Openedhand Ltd. 4 * Copyright 2005 Openedhand Ltd.
5 * Copyright 2006-12 Wolfson Microelectronics, plc
5 * 6 *
6 * Author: Richard Purdie <richard@openedhand.com> 7 * Author: Richard Purdie <richard@openedhand.com>
7 * 8 *
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c
index 6e849cb0424..35f3d23200e 100644
--- a/sound/soc/codecs/wm8741.c
+++ b/sound/soc/codecs/wm8741.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8741.c -- WM8741 ALSA SoC Audio driver 2 * wm8741.c -- WM8741 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010-1 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com> 6 * Author: Ian Lartey <ian@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c
index a26482cd765..13bff87ddcf 100644
--- a/sound/soc/codecs/wm8753.c
+++ b/sound/soc/codecs/wm8753.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8753.c -- WM8753 ALSA Soc Audio driver 2 * wm8753.c -- WM8753 ALSA Soc Audio driver
3 * 3 *
4 * Copyright 2003 Wolfson Microelectronics PLC. 4 * Copyright 2003-11 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c
index a19db5a0a17..879c356a904 100644
--- a/sound/soc/codecs/wm8776.c
+++ b/sound/soc/codecs/wm8776.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8776.c -- WM8776 ALSA SoC Audio driver 2 * wm8776.c -- WM8776 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c
index 6bd1b767b13..c088020172a 100644
--- a/sound/soc/codecs/wm8804.c
+++ b/sound/soc/codecs/wm8804.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8804.c -- WM8804 S/PDIF transceiver driver 2 * wm8804.c -- WM8804 S/PDIF transceiver driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010-11 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com> 6 * Author: Dimitris Papastamos <dp@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c
index 86b8a292659..73f1c8d7baf 100644
--- a/sound/soc/codecs/wm8903.c
+++ b/sound/soc/codecs/wm8903.c
@@ -1,8 +1,8 @@
1/* 1/*
2 * wm8903.c -- WM8903 ALSA SoC Audio driver 2 * wm8903.c -- WM8903 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2008 Wolfson Microelectronics 4 * Copyright 2008-12 Wolfson Microelectronics
5 * Copyright 2011 NVIDIA, Inc. 5 * Copyright 2011-2012 NVIDIA, Inc.
6 * 6 *
7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
8 * 8 *
@@ -116,6 +116,7 @@ static const struct reg_default wm8903_reg_defaults[] = {
116 116
117struct wm8903_priv { 117struct wm8903_priv {
118 struct wm8903_platform_data *pdata; 118 struct wm8903_platform_data *pdata;
119 struct device *dev;
119 struct snd_soc_codec *codec; 120 struct snd_soc_codec *codec;
120 struct regmap *regmap; 121 struct regmap *regmap;
121 122
@@ -1635,17 +1636,27 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect);
1635 1636
1636static irqreturn_t wm8903_irq(int irq, void *data) 1637static irqreturn_t wm8903_irq(int irq, void *data)
1637{ 1638{
1638 struct snd_soc_codec *codec = data; 1639 struct wm8903_priv *wm8903 = data;
1639 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1640 int mic_report, ret;
1640 int mic_report; 1641 unsigned int int_val, mask, int_pol;
1641 int int_pol;
1642 int int_val = 0;
1643 int mask = ~snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1_MASK);
1644 1642
1645 int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; 1643 ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1_MASK,
1644 &mask);
1645 if (ret != 0) {
1646 dev_err(wm8903->dev, "Failed to read IRQ mask: %d\n", ret);
1647 return IRQ_NONE;
1648 }
1649
1650 ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_STATUS_1, &int_val);
1651 if (ret != 0) {
1652 dev_err(wm8903->dev, "Failed to read IRQ status: %d\n", ret);
1653 return IRQ_NONE;
1654 }
1655
1656 int_val &= ~mask;
1646 1657
1647 if (int_val & WM8903_WSEQ_BUSY_EINT) { 1658 if (int_val & WM8903_WSEQ_BUSY_EINT) {
1648 dev_warn(codec->dev, "Write sequencer done\n"); 1659 dev_warn(wm8903->dev, "Write sequencer done\n");
1649 } 1660 }
1650 1661
1651 /* 1662 /*
@@ -1656,22 +1667,28 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1656 * the polarity register. 1667 * the polarity register.
1657 */ 1668 */
1658 mic_report = wm8903->mic_last_report; 1669 mic_report = wm8903->mic_last_report;
1659 int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); 1670 ret = regmap_read(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1,
1671 &int_pol);
1672 if (ret != 0) {
1673 dev_err(wm8903->dev, "Failed to read interrupt polarity: %d\n",
1674 ret);
1675 return IRQ_HANDLED;
1676 }
1660 1677
1661#ifndef CONFIG_SND_SOC_WM8903_MODULE 1678#ifndef CONFIG_SND_SOC_WM8903_MODULE
1662 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) 1679 if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT))
1663 trace_snd_soc_jack_irq(dev_name(codec->dev)); 1680 trace_snd_soc_jack_irq(dev_name(wm8903->dev));
1664#endif 1681#endif
1665 1682
1666 if (int_val & WM8903_MICSHRT_EINT) { 1683 if (int_val & WM8903_MICSHRT_EINT) {
1667 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); 1684 dev_dbg(wm8903->dev, "Microphone short (pol=%x)\n", int_pol);
1668 1685
1669 mic_report ^= wm8903->mic_short; 1686 mic_report ^= wm8903->mic_short;
1670 int_pol ^= WM8903_MICSHRT_INV; 1687 int_pol ^= WM8903_MICSHRT_INV;
1671 } 1688 }
1672 1689
1673 if (int_val & WM8903_MICDET_EINT) { 1690 if (int_val & WM8903_MICDET_EINT) {
1674 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); 1691 dev_dbg(wm8903->dev, "Microphone detect (pol=%x)\n", int_pol);
1675 1692
1676 mic_report ^= wm8903->mic_det; 1693 mic_report ^= wm8903->mic_det;
1677 int_pol ^= WM8903_MICDET_INV; 1694 int_pol ^= WM8903_MICDET_INV;
@@ -1679,8 +1696,8 @@ static irqreturn_t wm8903_irq(int irq, void *data)
1679 msleep(wm8903->mic_delay); 1696 msleep(wm8903->mic_delay);
1680 } 1697 }
1681 1698
1682 snd_soc_update_bits(codec, WM8903_INTERRUPT_POLARITY_1, 1699 regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_POLARITY_1,
1683 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol); 1700 WM8903_MICSHRT_INV | WM8903_MICDET_INV, int_pol);
1684 1701
1685 snd_soc_jack_report(wm8903->mic_jack, mic_report, 1702 snd_soc_jack_report(wm8903->mic_jack, mic_report,
1686 wm8903->mic_short | wm8903->mic_det); 1703 wm8903->mic_short | wm8903->mic_det);
@@ -1774,7 +1791,6 @@ static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset)
1774static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) 1791static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1775{ 1792{
1776 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1793 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1777 struct snd_soc_codec *codec = wm8903->codec;
1778 unsigned int mask, val; 1794 unsigned int mask, val;
1779 int ret; 1795 int ret;
1780 1796
@@ -1782,8 +1798,8 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1782 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | 1798 val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) |
1783 WM8903_GP1_DIR; 1799 WM8903_GP1_DIR;
1784 1800
1785 ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, 1801 ret = regmap_update_bits(wm8903->regmap,
1786 mask, val); 1802 WM8903_GPIO_CONTROL_1 + offset, mask, val);
1787 if (ret < 0) 1803 if (ret < 0)
1788 return ret; 1804 return ret;
1789 1805
@@ -1793,10 +1809,9 @@ static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset)
1793static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) 1809static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset)
1794{ 1810{
1795 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1811 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1796 struct snd_soc_codec *codec = wm8903->codec; 1812 unsigned int reg;
1797 int reg;
1798 1813
1799 reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset); 1814 regmap_read(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset, &reg);
1800 1815
1801 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; 1816 return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT;
1802} 1817}
@@ -1805,7 +1820,6 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1805 unsigned offset, int value) 1820 unsigned offset, int value)
1806{ 1821{
1807 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1822 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1808 struct snd_soc_codec *codec = wm8903->codec;
1809 unsigned int mask, val; 1823 unsigned int mask, val;
1810 int ret; 1824 int ret;
1811 1825
@@ -1813,8 +1827,8 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1813 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | 1827 val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) |
1814 (value << WM8903_GP2_LVL_SHIFT); 1828 (value << WM8903_GP2_LVL_SHIFT);
1815 1829
1816 ret = snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, 1830 ret = regmap_update_bits(wm8903->regmap,
1817 mask, val); 1831 WM8903_GPIO_CONTROL_1 + offset, mask, val);
1818 if (ret < 0) 1832 if (ret < 0)
1819 return ret; 1833 return ret;
1820 1834
@@ -1824,11 +1838,10 @@ static int wm8903_gpio_direction_out(struct gpio_chip *chip,
1824static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) 1838static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
1825{ 1839{
1826 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); 1840 struct wm8903_priv *wm8903 = gpio_to_wm8903(chip);
1827 struct snd_soc_codec *codec = wm8903->codec;
1828 1841
1829 snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, 1842 regmap_update_bits(wm8903->regmap, WM8903_GPIO_CONTROL_1 + offset,
1830 WM8903_GP1_LVL_MASK, 1843 WM8903_GP1_LVL_MASK,
1831 !!value << WM8903_GP1_LVL_SHIFT); 1844 !!value << WM8903_GP1_LVL_SHIFT);
1832} 1845}
1833 1846
1834static struct gpio_chip wm8903_template_chip = { 1847static struct gpio_chip wm8903_template_chip = {
@@ -1842,15 +1855,14 @@ static struct gpio_chip wm8903_template_chip = {
1842 .can_sleep = 1, 1855 .can_sleep = 1,
1843}; 1856};
1844 1857
1845static void wm8903_init_gpio(struct snd_soc_codec *codec) 1858static void wm8903_init_gpio(struct wm8903_priv *wm8903)
1846{ 1859{
1847 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1848 struct wm8903_platform_data *pdata = wm8903->pdata; 1860 struct wm8903_platform_data *pdata = wm8903->pdata;
1849 int ret; 1861 int ret;
1850 1862
1851 wm8903->gpio_chip = wm8903_template_chip; 1863 wm8903->gpio_chip = wm8903_template_chip;
1852 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; 1864 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO;
1853 wm8903->gpio_chip.dev = codec->dev; 1865 wm8903->gpio_chip.dev = wm8903->dev;
1854 1866
1855 if (pdata->gpio_base) 1867 if (pdata->gpio_base)
1856 wm8903->gpio_chip.base = pdata->gpio_base; 1868 wm8903->gpio_chip.base = pdata->gpio_base;
@@ -1859,24 +1871,23 @@ static void wm8903_init_gpio(struct snd_soc_codec *codec)
1859 1871
1860 ret = gpiochip_add(&wm8903->gpio_chip); 1872 ret = gpiochip_add(&wm8903->gpio_chip);
1861 if (ret != 0) 1873 if (ret != 0)
1862 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); 1874 dev_err(wm8903->dev, "Failed to add GPIOs: %d\n", ret);
1863} 1875}
1864 1876
1865static void wm8903_free_gpio(struct snd_soc_codec *codec) 1877static void wm8903_free_gpio(struct wm8903_priv *wm8903)
1866{ 1878{
1867 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1868 int ret; 1879 int ret;
1869 1880
1870 ret = gpiochip_remove(&wm8903->gpio_chip); 1881 ret = gpiochip_remove(&wm8903->gpio_chip);
1871 if (ret != 0) 1882 if (ret != 0)
1872 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); 1883 dev_err(wm8903->dev, "Failed to remove GPIOs: %d\n", ret);
1873} 1884}
1874#else 1885#else
1875static void wm8903_init_gpio(struct snd_soc_codec *codec) 1886static void wm8903_init_gpio(struct wm8903_priv *wm8903)
1876{ 1887{
1877} 1888}
1878 1889
1879static void wm8903_free_gpio(struct snd_soc_codec *codec) 1890static void wm8903_free_gpio(struct wm8903_priv *wm8903)
1880{ 1891{
1881} 1892}
1882#endif 1893#endif
@@ -1884,11 +1895,7 @@ static void wm8903_free_gpio(struct snd_soc_codec *codec)
1884static int wm8903_probe(struct snd_soc_codec *codec) 1895static int wm8903_probe(struct snd_soc_codec *codec)
1885{ 1896{
1886 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); 1897 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
1887 struct wm8903_platform_data *pdata = wm8903->pdata; 1898 int ret;
1888 int ret, i;
1889 int trigger, irq_pol;
1890 u16 val;
1891 bool mic_gpio = false;
1892 1899
1893 wm8903->codec = codec; 1900 wm8903->codec = codec;
1894 codec->control_data = wm8903->regmap; 1901 codec->control_data = wm8903->regmap;
@@ -1899,121 +1906,16 @@ static int wm8903_probe(struct snd_soc_codec *codec)
1899 return ret; 1906 return ret;
1900 } 1907 }
1901 1908
1902 /* Set up GPIOs, detect if any are MIC detect outputs */
1903 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
1904 if ((!pdata->gpio_cfg[i]) ||
1905 (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO))
1906 continue;
1907
1908 snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
1909 pdata->gpio_cfg[i] & 0x7fff);
1910
1911 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
1912 >> WM8903_GP1_FN_SHIFT;
1913
1914 switch (val) {
1915 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
1916 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
1917 mic_gpio = true;
1918 break;
1919 default:
1920 break;
1921 }
1922 }
1923
1924 /* Set up microphone detection */
1925 snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
1926 pdata->micdet_cfg);
1927
1928 /* Microphone detection needs the WSEQ clock */
1929 if (pdata->micdet_cfg)
1930 snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
1931 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
1932
1933 /* If microphone detection is enabled by pdata but
1934 * detected via IRQ then interrupts can be lost before
1935 * the machine driver has set up microphone detection
1936 * IRQs as the IRQs are clear on read. The detection
1937 * will be enabled when the machine driver configures.
1938 */
1939 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
1940
1941 wm8903->mic_delay = pdata->micdet_delay;
1942
1943 if (wm8903->irq) {
1944 if (pdata->irq_active_low) {
1945 trigger = IRQF_TRIGGER_LOW;
1946 irq_pol = WM8903_IRQ_POL;
1947 } else {
1948 trigger = IRQF_TRIGGER_HIGH;
1949 irq_pol = 0;
1950 }
1951
1952 snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL,
1953 WM8903_IRQ_POL, irq_pol);
1954
1955 ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq,
1956 trigger | IRQF_ONESHOT,
1957 "wm8903", codec);
1958 if (ret != 0) {
1959 dev_err(codec->dev, "Failed to request IRQ: %d\n",
1960 ret);
1961 return ret;
1962 }
1963
1964 /* Enable write sequencer interrupts */
1965 snd_soc_update_bits(codec, WM8903_INTERRUPT_STATUS_1_MASK,
1966 WM8903_IM_WSEQ_BUSY_EINT, 0);
1967 }
1968
1969 /* power on device */ 1909 /* power on device */
1970 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1910 wm8903_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1971 1911
1972 /* Latch volume update bits */
1973 val = snd_soc_read(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT);
1974 val |= WM8903_ADCVU;
1975 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_LEFT, val);
1976 snd_soc_write(codec, WM8903_ADC_DIGITAL_VOLUME_RIGHT, val);
1977
1978 val = snd_soc_read(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT);
1979 val |= WM8903_DACVU;
1980 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_LEFT, val);
1981 snd_soc_write(codec, WM8903_DAC_DIGITAL_VOLUME_RIGHT, val);
1982
1983 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT1_LEFT);
1984 val |= WM8903_HPOUTVU;
1985 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_LEFT, val);
1986 snd_soc_write(codec, WM8903_ANALOGUE_OUT1_RIGHT, val);
1987
1988 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT2_LEFT);
1989 val |= WM8903_LINEOUTVU;
1990 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_LEFT, val);
1991 snd_soc_write(codec, WM8903_ANALOGUE_OUT2_RIGHT, val);
1992
1993 val = snd_soc_read(codec, WM8903_ANALOGUE_OUT3_LEFT);
1994 val |= WM8903_SPKVU;
1995 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_LEFT, val);
1996 snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val);
1997
1998 /* Enable DAC soft mute by default */
1999 snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1,
2000 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
2001 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
2002
2003 wm8903_init_gpio(codec);
2004
2005 return ret; 1912 return ret;
2006} 1913}
2007 1914
2008/* power down chip */ 1915/* power down chip */
2009static int wm8903_remove(struct snd_soc_codec *codec) 1916static int wm8903_remove(struct snd_soc_codec *codec)
2010{ 1917{
2011 struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec);
2012
2013 wm8903_free_gpio(codec);
2014 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); 1918 wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF);
2015 if (wm8903->irq)
2016 free_irq(wm8903->irq, codec);
2017 1919
2018 return 0; 1920 return 0;
2019} 1921}
@@ -2123,15 +2025,18 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2123{ 2025{
2124 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); 2026 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev);
2125 struct wm8903_priv *wm8903; 2027 struct wm8903_priv *wm8903;
2126 unsigned int val; 2028 int trigger;
2127 int ret; 2029 bool mic_gpio = false;
2030 unsigned int val, irq_pol;
2031 int ret, i;
2128 2032
2129 wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), 2033 wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv),
2130 GFP_KERNEL); 2034 GFP_KERNEL);
2131 if (wm8903 == NULL) 2035 if (wm8903 == NULL)
2132 return -ENOMEM; 2036 return -ENOMEM;
2037 wm8903->dev = &i2c->dev;
2133 2038
2134 wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); 2039 wm8903->regmap = devm_regmap_init_i2c(i2c, &wm8903_regmap);
2135 if (IS_ERR(wm8903->regmap)) { 2040 if (IS_ERR(wm8903->regmap)) {
2136 ret = PTR_ERR(wm8903->regmap); 2041 ret = PTR_ERR(wm8903->regmap);
2137 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2042 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2140,7 +2045,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2140 } 2045 }
2141 2046
2142 i2c_set_clientdata(i2c, wm8903); 2047 i2c_set_clientdata(i2c, wm8903);
2143 wm8903->irq = i2c->irq;
2144 2048
2145 /* If no platform data was supplied, create storage for defaults */ 2049 /* If no platform data was supplied, create storage for defaults */
2146 if (pdata) { 2050 if (pdata) {
@@ -2167,6 +2071,8 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2167 } 2071 }
2168 } 2072 }
2169 2073
2074 pdata = wm8903->pdata;
2075
2170 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); 2076 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val);
2171 if (ret != 0) { 2077 if (ret != 0) {
2172 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); 2078 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret);
@@ -2189,6 +2095,107 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2189 /* Reset the device */ 2095 /* Reset the device */
2190 regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); 2096 regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903);
2191 2097
2098 wm8903_init_gpio(wm8903);
2099
2100 /* Set up GPIO pin state, detect if any are MIC detect outputs */
2101 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
2102 if ((!pdata->gpio_cfg[i]) ||
2103 (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO))
2104 continue;
2105
2106 regmap_write(wm8903->regmap, WM8903_GPIO_CONTROL_1 + i,
2107 pdata->gpio_cfg[i] & 0x7fff);
2108
2109 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK)
2110 >> WM8903_GP1_FN_SHIFT;
2111
2112 switch (val) {
2113 case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT:
2114 case WM8903_GPn_FN_MICBIAS_SHORT_DETECT:
2115 mic_gpio = true;
2116 break;
2117 default:
2118 break;
2119 }
2120 }
2121
2122 /* Set up microphone detection */
2123 regmap_write(wm8903->regmap, WM8903_MIC_BIAS_CONTROL_0,
2124 pdata->micdet_cfg);
2125
2126 /* Microphone detection needs the WSEQ clock */
2127 if (pdata->micdet_cfg)
2128 regmap_update_bits(wm8903->regmap, WM8903_WRITE_SEQUENCER_0,
2129 WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);
2130
2131 /* If microphone detection is enabled by pdata but
2132 * detected via IRQ then interrupts can be lost before
2133 * the machine driver has set up microphone detection
2134 * IRQs as the IRQs are clear on read. The detection
2135 * will be enabled when the machine driver configures.
2136 */
2137 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA));
2138
2139 wm8903->mic_delay = pdata->micdet_delay;
2140
2141 if (i2c->irq) {
2142 if (pdata->irq_active_low) {
2143 trigger = IRQF_TRIGGER_LOW;
2144 irq_pol = WM8903_IRQ_POL;
2145 } else {
2146 trigger = IRQF_TRIGGER_HIGH;
2147 irq_pol = 0;
2148 }
2149
2150 regmap_update_bits(wm8903->regmap, WM8903_INTERRUPT_CONTROL,
2151 WM8903_IRQ_POL, irq_pol);
2152
2153 ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq,
2154 trigger | IRQF_ONESHOT,
2155 "wm8903", wm8903);
2156 if (ret != 0) {
2157 dev_err(wm8903->dev, "Failed to request IRQ: %d\n",
2158 ret);
2159 return ret;
2160 }
2161
2162 /* Enable write sequencer interrupts */
2163 regmap_update_bits(wm8903->regmap,
2164 WM8903_INTERRUPT_STATUS_1_MASK,
2165 WM8903_IM_WSEQ_BUSY_EINT, 0);
2166 }
2167
2168 /* Latch volume update bits */
2169 regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_LEFT,
2170 WM8903_ADCVU, WM8903_ADCVU);
2171 regmap_update_bits(wm8903->regmap, WM8903_ADC_DIGITAL_VOLUME_RIGHT,
2172 WM8903_ADCVU, WM8903_ADCVU);
2173
2174 regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_LEFT,
2175 WM8903_DACVU, WM8903_DACVU);
2176 regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_VOLUME_RIGHT,
2177 WM8903_DACVU, WM8903_DACVU);
2178
2179 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_LEFT,
2180 WM8903_HPOUTVU, WM8903_HPOUTVU);
2181 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT1_RIGHT,
2182 WM8903_HPOUTVU, WM8903_HPOUTVU);
2183
2184 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_LEFT,
2185 WM8903_LINEOUTVU, WM8903_LINEOUTVU);
2186 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT2_RIGHT,
2187 WM8903_LINEOUTVU, WM8903_LINEOUTVU);
2188
2189 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_LEFT,
2190 WM8903_SPKVU, WM8903_SPKVU);
2191 regmap_update_bits(wm8903->regmap, WM8903_ANALOGUE_OUT3_RIGHT,
2192 WM8903_SPKVU, WM8903_SPKVU);
2193
2194 /* Enable DAC soft mute by default */
2195 regmap_update_bits(wm8903->regmap, WM8903_DAC_DIGITAL_1,
2196 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE,
2197 WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE);
2198
2192 ret = snd_soc_register_codec(&i2c->dev, 2199 ret = snd_soc_register_codec(&i2c->dev,
2193 &soc_codec_dev_wm8903, &wm8903_dai, 1); 2200 &soc_codec_dev_wm8903, &wm8903_dai, 1);
2194 if (ret != 0) 2201 if (ret != 0)
@@ -2196,7 +2203,6 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
2196 2203
2197 return 0; 2204 return 0;
2198err: 2205err:
2199 regmap_exit(wm8903->regmap);
2200 return ret; 2206 return ret;
2201} 2207}
2202 2208
@@ -2204,7 +2210,9 @@ static __devexit int wm8903_i2c_remove(struct i2c_client *client)
2204{ 2210{
2205 struct wm8903_priv *wm8903 = i2c_get_clientdata(client); 2211 struct wm8903_priv *wm8903 = i2c_get_clientdata(client);
2206 2212
2207 regmap_exit(wm8903->regmap); 2213 if (client->irq)
2214 free_irq(client->irq, wm8903);
2215 wm8903_free_gpio(wm8903);
2208 snd_soc_unregister_codec(&client->dev); 2216 snd_soc_unregister_codec(&client->dev);
2209 2217
2210 return 0; 2218 return 0;
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 812acd83fb4..0013afe48e6 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8904.c -- WM8904 ALSA SoC Audio driver 2 * wm8904.c -- WM8904 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -314,11 +314,6 @@ static bool wm8904_readable_register(struct device *dev, unsigned int reg)
314 } 314 }
315} 315}
316 316
317static int wm8904_reset(struct snd_soc_codec *codec)
318{
319 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0);
320}
321
322static int wm8904_configure_clocking(struct snd_soc_codec *codec) 317static int wm8904_configure_clocking(struct snd_soc_codec *codec)
323{ 318{
324 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 319 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
@@ -1945,25 +1940,6 @@ static struct snd_soc_dai_driver wm8904_dai = {
1945 .symmetric_rates = 1, 1940 .symmetric_rates = 1,
1946}; 1941};
1947 1942
1948#ifdef CONFIG_PM
1949static int wm8904_suspend(struct snd_soc_codec *codec)
1950{
1951 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
1952
1953 return 0;
1954}
1955
1956static int wm8904_resume(struct snd_soc_codec *codec)
1957{
1958 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1959
1960 return 0;
1961}
1962#else
1963#define wm8904_suspend NULL
1964#define wm8904_resume NULL
1965#endif
1966
1967static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec) 1943static void wm8904_handle_retune_mobile_pdata(struct snd_soc_codec *codec)
1968{ 1944{
1969 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 1945 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
@@ -2078,8 +2054,7 @@ static void wm8904_handle_pdata(struct snd_soc_codec *codec)
2078static int wm8904_probe(struct snd_soc_codec *codec) 2054static int wm8904_probe(struct snd_soc_codec *codec)
2079{ 2055{
2080 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 2056 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2081 struct wm8904_pdata *pdata = wm8904->pdata; 2057 int ret;
2082 int ret, i;
2083 2058
2084 codec->control_data = wm8904->regmap; 2059 codec->control_data = wm8904->regmap;
2085 2060
@@ -2101,127 +2076,17 @@ static int wm8904_probe(struct snd_soc_codec *codec)
2101 return ret; 2076 return ret;
2102 } 2077 }
2103 2078
2104 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2105 wm8904->supplies[i].supply = wm8904_supply_names[i];
2106
2107 ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8904->supplies),
2108 wm8904->supplies);
2109 if (ret != 0) {
2110 dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
2111 return ret;
2112 }
2113
2114 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2115 wm8904->supplies);
2116 if (ret != 0) {
2117 dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
2118 goto err_get;
2119 }
2120
2121 ret = snd_soc_read(codec, WM8904_SW_RESET_AND_ID);
2122 if (ret < 0) {
2123 dev_err(codec->dev, "Failed to read ID register\n");
2124 goto err_enable;
2125 }
2126 if (ret != 0x8904) {
2127 dev_err(codec->dev, "Device is not a WM8904, ID is %x\n", ret);
2128 ret = -EINVAL;
2129 goto err_enable;
2130 }
2131
2132 ret = snd_soc_read(codec, WM8904_REVISION);
2133 if (ret < 0) {
2134 dev_err(codec->dev, "Failed to read device revision: %d\n",
2135 ret);
2136 goto err_enable;
2137 }
2138 dev_info(codec->dev, "revision %c\n", ret + 'A');
2139
2140 ret = wm8904_reset(codec);
2141 if (ret < 0) {
2142 dev_err(codec->dev, "Failed to issue reset\n");
2143 goto err_enable;
2144 }
2145
2146 regcache_cache_only(wm8904->regmap, true);
2147 /* Change some default settings - latch VU and enable ZC */
2148 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2149 WM8904_ADC_VU, WM8904_ADC_VU);
2150 snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2151 WM8904_ADC_VU, WM8904_ADC_VU);
2152 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2153 WM8904_DAC_VU, WM8904_DAC_VU);
2154 snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2155 WM8904_DAC_VU, WM8904_DAC_VU);
2156 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT,
2157 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2158 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2159 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT,
2160 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2161 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2162 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT,
2163 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2164 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2165 snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT,
2166 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2167 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2168 snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0,
2169 WM8904_SR_MODE, 0);
2170
2171 /* Apply configuration from the platform data. */
2172 if (wm8904->pdata) {
2173 for (i = 0; i < WM8904_GPIO_REGS; i++) {
2174 if (!pdata->gpio_cfg[i])
2175 continue;
2176
2177 regmap_update_bits(wm8904->regmap,
2178 WM8904_GPIO_CONTROL_1 + i,
2179 0xffff,
2180 pdata->gpio_cfg[i]);
2181 }
2182
2183 /* Zero is the default value for these anyway */
2184 for (i = 0; i < WM8904_MIC_REGS; i++)
2185 regmap_update_bits(wm8904->regmap,
2186 WM8904_MIC_BIAS_CONTROL_0 + i,
2187 0xffff,
2188 pdata->mic_cfg[i]);
2189 }
2190
2191 /* Set Class W by default - this will be managed by the Class
2192 * G widget at runtime where bypass paths are available.
2193 */
2194 snd_soc_update_bits(codec, WM8904_CLASS_W_0,
2195 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2196
2197 /* Use normal bias source */
2198 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0,
2199 WM8904_POBCTRL, 0);
2200
2201 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
2202
2203 /* Bias level configuration will have done an extra enable */
2204 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2205
2206 wm8904_handle_pdata(codec); 2079 wm8904_handle_pdata(codec);
2207 2080
2208 wm8904_add_widgets(codec); 2081 wm8904_add_widgets(codec);
2209 2082
2210 return 0; 2083 return 0;
2211
2212err_enable:
2213 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2214err_get:
2215 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2216 return ret;
2217} 2084}
2218 2085
2219static int wm8904_remove(struct snd_soc_codec *codec) 2086static int wm8904_remove(struct snd_soc_codec *codec)
2220{ 2087{
2221 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); 2088 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
2222 2089
2223 wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
2224 regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2225 kfree(wm8904->retune_mobile_texts); 2090 kfree(wm8904->retune_mobile_texts);
2226 kfree(wm8904->drc_texts); 2091 kfree(wm8904->drc_texts);
2227 2092
@@ -2231,8 +2096,6 @@ static int wm8904_remove(struct snd_soc_codec *codec)
2231static struct snd_soc_codec_driver soc_codec_dev_wm8904 = { 2096static struct snd_soc_codec_driver soc_codec_dev_wm8904 = {
2232 .probe = wm8904_probe, 2097 .probe = wm8904_probe,
2233 .remove = wm8904_remove, 2098 .remove = wm8904_remove,
2234 .suspend = wm8904_suspend,
2235 .resume = wm8904_resume,
2236 .set_bias_level = wm8904_set_bias_level, 2099 .set_bias_level = wm8904_set_bias_level,
2237 .idle_bias_off = true, 2100 .idle_bias_off = true,
2238}; 2101};
@@ -2254,14 +2117,15 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2254 const struct i2c_device_id *id) 2117 const struct i2c_device_id *id)
2255{ 2118{
2256 struct wm8904_priv *wm8904; 2119 struct wm8904_priv *wm8904;
2257 int ret; 2120 unsigned int val;
2121 int ret, i;
2258 2122
2259 wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv), 2123 wm8904 = devm_kzalloc(&i2c->dev, sizeof(struct wm8904_priv),
2260 GFP_KERNEL); 2124 GFP_KERNEL);
2261 if (wm8904 == NULL) 2125 if (wm8904 == NULL)
2262 return -ENOMEM; 2126 return -ENOMEM;
2263 2127
2264 wm8904->regmap = regmap_init_i2c(i2c, &wm8904_regmap); 2128 wm8904->regmap = devm_regmap_init_i2c(i2c, &wm8904_regmap);
2265 if (IS_ERR(wm8904->regmap)) { 2129 if (IS_ERR(wm8904->regmap)) {
2266 ret = PTR_ERR(wm8904->regmap); 2130 ret = PTR_ERR(wm8904->regmap);
2267 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", 2131 dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
@@ -2273,23 +2137,121 @@ static __devinit int wm8904_i2c_probe(struct i2c_client *i2c,
2273 i2c_set_clientdata(i2c, wm8904); 2137 i2c_set_clientdata(i2c, wm8904);
2274 wm8904->pdata = i2c->dev.platform_data; 2138 wm8904->pdata = i2c->dev.platform_data;
2275 2139
2140 for (i = 0; i < ARRAY_SIZE(wm8904->supplies); i++)
2141 wm8904->supplies[i].supply = wm8904_supply_names[i];
2142
2143 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8904->supplies),
2144 wm8904->supplies);
2145 if (ret != 0) {
2146 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
2147 return ret;
2148 }
2149
2150 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies),
2151 wm8904->supplies);
2152 if (ret != 0) {
2153 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
2154 return ret;
2155 }
2156
2157 ret = regmap_read(wm8904->regmap, WM8904_SW_RESET_AND_ID, &val);
2158 if (ret < 0) {
2159 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
2160 goto err_enable;
2161 }
2162 if (val != 0x8904) {
2163 dev_err(&i2c->dev, "Device is not a WM8904, ID is %x\n", val);
2164 ret = -EINVAL;
2165 goto err_enable;
2166 }
2167
2168 ret = regmap_read(wm8904->regmap, WM8904_REVISION, &val);
2169 if (ret < 0) {
2170 dev_err(&i2c->dev, "Failed to read device revision: %d\n",
2171 ret);
2172 goto err_enable;
2173 }
2174 dev_info(&i2c->dev, "revision %c\n", val + 'A');
2175
2176 ret = regmap_write(wm8904->regmap, WM8904_SW_RESET_AND_ID, 0);
2177 if (ret < 0) {
2178 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
2179 goto err_enable;
2180 }
2181
2182 /* Change some default settings - latch VU and enable ZC */
2183 regmap_update_bits(wm8904->regmap, WM8904_ADC_DIGITAL_VOLUME_LEFT,
2184 WM8904_ADC_VU, WM8904_ADC_VU);
2185 regmap_update_bits(wm8904->regmap, WM8904_ADC_DIGITAL_VOLUME_RIGHT,
2186 WM8904_ADC_VU, WM8904_ADC_VU);
2187 regmap_update_bits(wm8904->regmap, WM8904_DAC_DIGITAL_VOLUME_LEFT,
2188 WM8904_DAC_VU, WM8904_DAC_VU);
2189 regmap_update_bits(wm8904->regmap, WM8904_DAC_DIGITAL_VOLUME_RIGHT,
2190 WM8904_DAC_VU, WM8904_DAC_VU);
2191 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT1_LEFT,
2192 WM8904_HPOUT_VU | WM8904_HPOUTLZC,
2193 WM8904_HPOUT_VU | WM8904_HPOUTLZC);
2194 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT1_RIGHT,
2195 WM8904_HPOUT_VU | WM8904_HPOUTRZC,
2196 WM8904_HPOUT_VU | WM8904_HPOUTRZC);
2197 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT2_LEFT,
2198 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC,
2199 WM8904_LINEOUT_VU | WM8904_LINEOUTLZC);
2200 regmap_update_bits(wm8904->regmap, WM8904_ANALOGUE_OUT2_RIGHT,
2201 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC,
2202 WM8904_LINEOUT_VU | WM8904_LINEOUTRZC);
2203 regmap_update_bits(wm8904->regmap, WM8904_CLOCK_RATES_0,
2204 WM8904_SR_MODE, 0);
2205
2206 /* Apply configuration from the platform data. */
2207 if (wm8904->pdata) {
2208 for (i = 0; i < WM8904_GPIO_REGS; i++) {
2209 if (!wm8904->pdata->gpio_cfg[i])
2210 continue;
2211
2212 regmap_update_bits(wm8904->regmap,
2213 WM8904_GPIO_CONTROL_1 + i,
2214 0xffff,
2215 wm8904->pdata->gpio_cfg[i]);
2216 }
2217
2218 /* Zero is the default value for these anyway */
2219 for (i = 0; i < WM8904_MIC_REGS; i++)
2220 regmap_update_bits(wm8904->regmap,
2221 WM8904_MIC_BIAS_CONTROL_0 + i,
2222 0xffff,
2223 wm8904->pdata->mic_cfg[i]);
2224 }
2225
2226 /* Set Class W by default - this will be managed by the Class
2227 * G widget at runtime where bypass paths are available.
2228 */
2229 regmap_update_bits(wm8904->regmap, WM8904_CLASS_W_0,
2230 WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR);
2231
2232 /* Use normal bias source */
2233 regmap_update_bits(wm8904->regmap, WM8904_BIAS_CONTROL_0,
2234 WM8904_POBCTRL, 0);
2235
2236 /* Can leave the device powered off until we need it */
2237 regcache_cache_only(wm8904->regmap, true);
2238 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2239
2276 ret = snd_soc_register_codec(&i2c->dev, 2240 ret = snd_soc_register_codec(&i2c->dev,
2277 &soc_codec_dev_wm8904, &wm8904_dai, 1); 2241 &soc_codec_dev_wm8904, &wm8904_dai, 1);
2278 if (ret != 0) 2242 if (ret != 0)
2279 goto err; 2243 return ret;
2280 2244
2281 return 0; 2245 return 0;
2282 2246
2283err: 2247err_enable:
2284 regmap_exit(wm8904->regmap); 2248 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
2285 return ret; 2249 return ret;
2286} 2250}
2287 2251
2288static __devexit int wm8904_i2c_remove(struct i2c_client *client) 2252static __devexit int wm8904_i2c_remove(struct i2c_client *client)
2289{ 2253{
2290 struct wm8904_priv *wm8904 = i2c_get_clientdata(client);
2291 snd_soc_unregister_codec(&client->dev); 2254 snd_soc_unregister_codec(&client->dev);
2292 regmap_exit(wm8904->regmap);
2293 return 0; 2255 return 0;
2294} 2256}
2295 2257
@@ -2311,23 +2273,7 @@ static struct i2c_driver wm8904_i2c_driver = {
2311 .id_table = wm8904_i2c_id, 2273 .id_table = wm8904_i2c_id,
2312}; 2274};
2313 2275
2314static int __init wm8904_modinit(void) 2276module_i2c_driver(wm8904_i2c_driver);
2315{
2316 int ret = 0;
2317 ret = i2c_add_driver(&wm8904_i2c_driver);
2318 if (ret != 0) {
2319 printk(KERN_ERR "Failed to register wm8904 I2C driver: %d\n",
2320 ret);
2321 }
2322 return ret;
2323}
2324module_init(wm8904_modinit);
2325
2326static void __exit wm8904_exit(void)
2327{
2328 i2c_del_driver(&wm8904_i2c_driver);
2329}
2330module_exit(wm8904_exit);
2331 2277
2332MODULE_DESCRIPTION("ASoC WM8904 driver"); 2278MODULE_DESCRIPTION("ASoC WM8904 driver");
2333MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 2279MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c
index 8bc659d8dd2..96518ac8e24 100644
--- a/sound/soc/codecs/wm8960.c
+++ b/sound/soc/codecs/wm8960.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * wm8960.c -- WM8960 ALSA SoC Audio driver 2 * wm8960.c -- WM8960 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2007-11 Wolfson Microelectronics, plc
5 *
4 * Author: Liam Girdwood 6 * Author: Liam Girdwood
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c
index 05ea7c27409..01edbcc754d 100644
--- a/sound/soc/codecs/wm8961.c
+++ b/sound/soc/codecs/wm8961.c
@@ -1,6 +1,8 @@
1/* 1/*
2 * wm8961.c -- WM8961 ALSA SoC Audio driver 2 * wm8961.c -- WM8961 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009-10 Wolfson Microelectronics, plc
5 *
4 * Author: Mark Brown 6 * Author: Mark Brown
5 * 7 *
6 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 0cfce9999c8..eaf65863ec2 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8962.c -- WM8962 ALSA SoC Audio driver 2 * wm8962.c -- WM8962 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2010 Wolfson Microelectronics plc 4 * Copyright 2010-2 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -2580,6 +2580,9 @@ static int wm8962_hw_params(struct snd_pcm_substream *substream,
2580 WM8962_SAMPLE_RATE_INT_MODE | 2580 WM8962_SAMPLE_RATE_INT_MODE |
2581 WM8962_SAMPLE_RATE_MASK, adctl3); 2581 WM8962_SAMPLE_RATE_MASK, adctl3);
2582 2582
2583 dev_dbg(codec->dev, "hw_params set BCLK %dHz LRCLK %dHz\n",
2584 wm8962->bclk, wm8962->lrclk);
2585
2583 if (codec->dapm.bias_level == SND_SOC_BIAS_ON) 2586 if (codec->dapm.bias_level == SND_SOC_BIAS_ON)
2584 wm8962_configure_bclk(codec); 2587 wm8962_configure_bclk(codec);
2585 2588
@@ -3722,6 +3725,9 @@ static int wm8962_runtime_resume(struct device *dev)
3722 } 3725 }
3723 3726
3724 regcache_cache_only(wm8962->regmap, false); 3727 regcache_cache_only(wm8962->regmap, false);
3728
3729 wm8962_reset(wm8962);
3730
3725 regcache_sync(wm8962->regmap); 3731 regcache_sync(wm8962->regmap);
3726 3732
3727 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, 3733 regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP,
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c
index 36acfccab99..9fd80d68897 100644
--- a/sound/soc/codecs/wm8993.c
+++ b/sound/soc/codecs/wm8993.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8993.c -- WM8993 ALSA SoC audio driver 2 * wm8993.c -- WM8993 ALSA SoC audio driver
3 * 3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c
index 1436b6ce74d..bb62f4b3d56 100644
--- a/sound/soc/codecs/wm8994.c
+++ b/sound/soc/codecs/wm8994.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8994.c -- WM8994 ALSA SoC Audio driver 2 * wm8994.c -- WM8994 ALSA SoC Audio driver
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
@@ -2967,23 +2967,8 @@ static struct snd_soc_dai_driver wm8994_dai[] = {
2967static int wm8994_codec_suspend(struct snd_soc_codec *codec) 2967static int wm8994_codec_suspend(struct snd_soc_codec *codec)
2968{ 2968{
2969 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); 2969 struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
2970 struct wm8994 *control = wm8994->wm8994;
2971 int i, ret; 2970 int i, ret;
2972 2971
2973 switch (control->type) {
2974 case WM8994:
2975 snd_soc_update_bits(codec, WM8994_MICBIAS, WM8994_MICD_ENA, 0);
2976 break;
2977 case WM1811:
2978 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
2979 WM1811_JACKDET_MODE_MASK, 0);
2980 /* Fall through */
2981 case WM8958:
2982 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
2983 WM8958_MICD_ENA, 0);
2984 break;
2985 }
2986
2987 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) { 2972 for (i = 0; i < ARRAY_SIZE(wm8994->fll); i++) {
2988 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i], 2973 memcpy(&wm8994->fll_suspend[i], &wm8994->fll[i],
2989 sizeof(struct wm8994_fll_config)); 2974 sizeof(struct wm8994_fll_config));
@@ -3033,28 +3018,6 @@ static int wm8994_codec_resume(struct snd_soc_codec *codec)
3033 i + 1, ret); 3018 i + 1, ret);
3034 } 3019 }
3035 3020
3036 switch (control->type) {
3037 case WM8994:
3038 if (wm8994->micdet[0].jack || wm8994->micdet[1].jack)
3039 snd_soc_update_bits(codec, WM8994_MICBIAS,
3040 WM8994_MICD_ENA, WM8994_MICD_ENA);
3041 break;
3042 case WM1811:
3043 if (wm8994->jackdet && wm8994->jack_cb) {
3044 /* Restart from idle */
3045 snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
3046 WM1811_JACKDET_MODE_MASK,
3047 WM1811_JACKDET_MODE_JACK);
3048 break;
3049 }
3050 break;
3051 case WM8958:
3052 if (wm8994->jack_cb)
3053 snd_soc_update_bits(codec, WM8958_MIC_DETECT_1,
3054 WM8958_MICD_ENA, WM8958_MICD_ENA);
3055 break;
3056 }
3057
3058 return 0; 3021 return 0;
3059} 3022}
3060#else 3023#else
@@ -3729,9 +3692,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3729 3692
3730 if (wm8994->pdata && wm8994->pdata->micdet_irq) 3693 if (wm8994->pdata && wm8994->pdata->micdet_irq)
3731 wm8994->micdet_irq = wm8994->pdata->micdet_irq; 3694 wm8994->micdet_irq = wm8994->pdata->micdet_irq;
3732 else if (wm8994->pdata && wm8994->pdata->irq_base)
3733 wm8994->micdet_irq = wm8994->pdata->irq_base +
3734 WM8994_IRQ_MIC1_DET;
3735 3695
3736 pm_runtime_enable(codec->dev); 3696 pm_runtime_enable(codec->dev);
3737 pm_runtime_idle(codec->dev); 3697 pm_runtime_idle(codec->dev);
@@ -3870,6 +3830,10 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec)
3870 dev_warn(codec->dev, 3830 dev_warn(codec->dev,
3871 "Failed to request Mic detect IRQ: %d\n", 3831 "Failed to request Mic detect IRQ: %d\n",
3872 ret); 3832 ret);
3833 } else {
3834 wm8994_request_irq(wm8994->wm8994, WM8994_IRQ_MIC1_DET,
3835 wm8958_mic_irq, "Mic detect",
3836 wm8994);
3873 } 3837 }
3874 } 3838 }
3875 3839
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index dc9b42b7fc4..00f183dfa45 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8996.c - WM8996 audio codec interface 2 * wm8996.c - WM8996 audio codec interface
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics PLC. 4 * Copyright 2011-2 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -296,184 +296,6 @@ static struct reg_default wm8996_reg[] = {
296 { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, 296 { WM8996_RIGHT_PDM_SPEAKER, 0x1 },
297 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, 297 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },
298 { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, 298 { WM8996_PDM_SPEAKER_VOLUME, 0x66 },
299 { WM8996_WRITE_SEQUENCER_0, 0x1 },
300 { WM8996_WRITE_SEQUENCER_1, 0x1 },
301 { WM8996_WRITE_SEQUENCER_3, 0x6 },
302 { WM8996_WRITE_SEQUENCER_4, 0x40 },
303 { WM8996_WRITE_SEQUENCER_5, 0x1 },
304 { WM8996_WRITE_SEQUENCER_6, 0xf },
305 { WM8996_WRITE_SEQUENCER_7, 0x6 },
306 { WM8996_WRITE_SEQUENCER_8, 0x1 },
307 { WM8996_WRITE_SEQUENCER_9, 0x3 },
308 { WM8996_WRITE_SEQUENCER_10, 0x104 },
309 { WM8996_WRITE_SEQUENCER_12, 0x60 },
310 { WM8996_WRITE_SEQUENCER_13, 0x11 },
311 { WM8996_WRITE_SEQUENCER_14, 0x401 },
312 { WM8996_WRITE_SEQUENCER_16, 0x50 },
313 { WM8996_WRITE_SEQUENCER_17, 0x3 },
314 { WM8996_WRITE_SEQUENCER_18, 0x100 },
315 { WM8996_WRITE_SEQUENCER_20, 0x51 },
316 { WM8996_WRITE_SEQUENCER_21, 0x3 },
317 { WM8996_WRITE_SEQUENCER_22, 0x104 },
318 { WM8996_WRITE_SEQUENCER_23, 0xa },
319 { WM8996_WRITE_SEQUENCER_24, 0x60 },
320 { WM8996_WRITE_SEQUENCER_25, 0x3b },
321 { WM8996_WRITE_SEQUENCER_26, 0x502 },
322 { WM8996_WRITE_SEQUENCER_27, 0x100 },
323 { WM8996_WRITE_SEQUENCER_28, 0x2fff },
324 { WM8996_WRITE_SEQUENCER_32, 0x2fff },
325 { WM8996_WRITE_SEQUENCER_36, 0x2fff },
326 { WM8996_WRITE_SEQUENCER_40, 0x2fff },
327 { WM8996_WRITE_SEQUENCER_44, 0x2fff },
328 { WM8996_WRITE_SEQUENCER_48, 0x2fff },
329 { WM8996_WRITE_SEQUENCER_52, 0x2fff },
330 { WM8996_WRITE_SEQUENCER_56, 0x2fff },
331 { WM8996_WRITE_SEQUENCER_60, 0x2fff },
332 { WM8996_WRITE_SEQUENCER_64, 0x1 },
333 { WM8996_WRITE_SEQUENCER_65, 0x1 },
334 { WM8996_WRITE_SEQUENCER_67, 0x6 },
335 { WM8996_WRITE_SEQUENCER_68, 0x40 },
336 { WM8996_WRITE_SEQUENCER_69, 0x1 },
337 { WM8996_WRITE_SEQUENCER_70, 0xf },
338 { WM8996_WRITE_SEQUENCER_71, 0x6 },
339 { WM8996_WRITE_SEQUENCER_72, 0x1 },
340 { WM8996_WRITE_SEQUENCER_73, 0x3 },
341 { WM8996_WRITE_SEQUENCER_74, 0x104 },
342 { WM8996_WRITE_SEQUENCER_76, 0x60 },
343 { WM8996_WRITE_SEQUENCER_77, 0x11 },
344 { WM8996_WRITE_SEQUENCER_78, 0x401 },
345 { WM8996_WRITE_SEQUENCER_80, 0x50 },
346 { WM8996_WRITE_SEQUENCER_81, 0x3 },
347 { WM8996_WRITE_SEQUENCER_82, 0x100 },
348 { WM8996_WRITE_SEQUENCER_84, 0x60 },
349 { WM8996_WRITE_SEQUENCER_85, 0x3b },
350 { WM8996_WRITE_SEQUENCER_86, 0x502 },
351 { WM8996_WRITE_SEQUENCER_87, 0x100 },
352 { WM8996_WRITE_SEQUENCER_88, 0x2fff },
353 { WM8996_WRITE_SEQUENCER_92, 0x2fff },
354 { WM8996_WRITE_SEQUENCER_96, 0x2fff },
355 { WM8996_WRITE_SEQUENCER_100, 0x2fff },
356 { WM8996_WRITE_SEQUENCER_104, 0x2fff },
357 { WM8996_WRITE_SEQUENCER_108, 0x2fff },
358 { WM8996_WRITE_SEQUENCER_112, 0x2fff },
359 { WM8996_WRITE_SEQUENCER_116, 0x2fff },
360 { WM8996_WRITE_SEQUENCER_120, 0x2fff },
361 { WM8996_WRITE_SEQUENCER_124, 0x2fff },
362 { WM8996_WRITE_SEQUENCER_128, 0x1 },
363 { WM8996_WRITE_SEQUENCER_129, 0x1 },
364 { WM8996_WRITE_SEQUENCER_131, 0x6 },
365 { WM8996_WRITE_SEQUENCER_132, 0x40 },
366 { WM8996_WRITE_SEQUENCER_133, 0x1 },
367 { WM8996_WRITE_SEQUENCER_134, 0xf },
368 { WM8996_WRITE_SEQUENCER_135, 0x6 },
369 { WM8996_WRITE_SEQUENCER_136, 0x1 },
370 { WM8996_WRITE_SEQUENCER_137, 0x3 },
371 { WM8996_WRITE_SEQUENCER_138, 0x106 },
372 { WM8996_WRITE_SEQUENCER_140, 0x61 },
373 { WM8996_WRITE_SEQUENCER_141, 0x11 },
374 { WM8996_WRITE_SEQUENCER_142, 0x401 },
375 { WM8996_WRITE_SEQUENCER_144, 0x50 },
376 { WM8996_WRITE_SEQUENCER_145, 0x3 },
377 { WM8996_WRITE_SEQUENCER_146, 0x102 },
378 { WM8996_WRITE_SEQUENCER_148, 0x51 },
379 { WM8996_WRITE_SEQUENCER_149, 0x3 },
380 { WM8996_WRITE_SEQUENCER_150, 0x106 },
381 { WM8996_WRITE_SEQUENCER_151, 0xa },
382 { WM8996_WRITE_SEQUENCER_152, 0x61 },
383 { WM8996_WRITE_SEQUENCER_153, 0x3b },
384 { WM8996_WRITE_SEQUENCER_154, 0x502 },
385 { WM8996_WRITE_SEQUENCER_155, 0x100 },
386 { WM8996_WRITE_SEQUENCER_156, 0x2fff },
387 { WM8996_WRITE_SEQUENCER_160, 0x2fff },
388 { WM8996_WRITE_SEQUENCER_164, 0x2fff },
389 { WM8996_WRITE_SEQUENCER_168, 0x2fff },
390 { WM8996_WRITE_SEQUENCER_172, 0x2fff },
391 { WM8996_WRITE_SEQUENCER_176, 0x2fff },
392 { WM8996_WRITE_SEQUENCER_180, 0x2fff },
393 { WM8996_WRITE_SEQUENCER_184, 0x2fff },
394 { WM8996_WRITE_SEQUENCER_188, 0x2fff },
395 { WM8996_WRITE_SEQUENCER_192, 0x1 },
396 { WM8996_WRITE_SEQUENCER_193, 0x1 },
397 { WM8996_WRITE_SEQUENCER_195, 0x6 },
398 { WM8996_WRITE_SEQUENCER_196, 0x40 },
399 { WM8996_WRITE_SEQUENCER_197, 0x1 },
400 { WM8996_WRITE_SEQUENCER_198, 0xf },
401 { WM8996_WRITE_SEQUENCER_199, 0x6 },
402 { WM8996_WRITE_SEQUENCER_200, 0x1 },
403 { WM8996_WRITE_SEQUENCER_201, 0x3 },
404 { WM8996_WRITE_SEQUENCER_202, 0x106 },
405 { WM8996_WRITE_SEQUENCER_204, 0x61 },
406 { WM8996_WRITE_SEQUENCER_205, 0x11 },
407 { WM8996_WRITE_SEQUENCER_206, 0x401 },
408 { WM8996_WRITE_SEQUENCER_208, 0x50 },
409 { WM8996_WRITE_SEQUENCER_209, 0x3 },
410 { WM8996_WRITE_SEQUENCER_210, 0x102 },
411 { WM8996_WRITE_SEQUENCER_212, 0x61 },
412 { WM8996_WRITE_SEQUENCER_213, 0x3b },
413 { WM8996_WRITE_SEQUENCER_214, 0x502 },
414 { WM8996_WRITE_SEQUENCER_215, 0x100 },
415 { WM8996_WRITE_SEQUENCER_216, 0x2fff },
416 { WM8996_WRITE_SEQUENCER_220, 0x2fff },
417 { WM8996_WRITE_SEQUENCER_224, 0x2fff },
418 { WM8996_WRITE_SEQUENCER_228, 0x2fff },
419 { WM8996_WRITE_SEQUENCER_232, 0x2fff },
420 { WM8996_WRITE_SEQUENCER_236, 0x2fff },
421 { WM8996_WRITE_SEQUENCER_240, 0x2fff },
422 { WM8996_WRITE_SEQUENCER_244, 0x2fff },
423 { WM8996_WRITE_SEQUENCER_248, 0x2fff },
424 { WM8996_WRITE_SEQUENCER_252, 0x2fff },
425 { WM8996_WRITE_SEQUENCER_256, 0x60 },
426 { WM8996_WRITE_SEQUENCER_258, 0x601 },
427 { WM8996_WRITE_SEQUENCER_260, 0x50 },
428 { WM8996_WRITE_SEQUENCER_262, 0x100 },
429 { WM8996_WRITE_SEQUENCER_264, 0x1 },
430 { WM8996_WRITE_SEQUENCER_266, 0x104 },
431 { WM8996_WRITE_SEQUENCER_267, 0x100 },
432 { WM8996_WRITE_SEQUENCER_268, 0x2fff },
433 { WM8996_WRITE_SEQUENCER_272, 0x2fff },
434 { WM8996_WRITE_SEQUENCER_276, 0x2fff },
435 { WM8996_WRITE_SEQUENCER_280, 0x2fff },
436 { WM8996_WRITE_SEQUENCER_284, 0x2fff },
437 { WM8996_WRITE_SEQUENCER_288, 0x2fff },
438 { WM8996_WRITE_SEQUENCER_292, 0x2fff },
439 { WM8996_WRITE_SEQUENCER_296, 0x2fff },
440 { WM8996_WRITE_SEQUENCER_300, 0x2fff },
441 { WM8996_WRITE_SEQUENCER_304, 0x2fff },
442 { WM8996_WRITE_SEQUENCER_308, 0x2fff },
443 { WM8996_WRITE_SEQUENCER_312, 0x2fff },
444 { WM8996_WRITE_SEQUENCER_316, 0x2fff },
445 { WM8996_WRITE_SEQUENCER_320, 0x61 },
446 { WM8996_WRITE_SEQUENCER_322, 0x601 },
447 { WM8996_WRITE_SEQUENCER_324, 0x50 },
448 { WM8996_WRITE_SEQUENCER_326, 0x102 },
449 { WM8996_WRITE_SEQUENCER_328, 0x1 },
450 { WM8996_WRITE_SEQUENCER_330, 0x106 },
451 { WM8996_WRITE_SEQUENCER_331, 0x100 },
452 { WM8996_WRITE_SEQUENCER_332, 0x2fff },
453 { WM8996_WRITE_SEQUENCER_336, 0x2fff },
454 { WM8996_WRITE_SEQUENCER_340, 0x2fff },
455 { WM8996_WRITE_SEQUENCER_344, 0x2fff },
456 { WM8996_WRITE_SEQUENCER_348, 0x2fff },
457 { WM8996_WRITE_SEQUENCER_352, 0x2fff },
458 { WM8996_WRITE_SEQUENCER_356, 0x2fff },
459 { WM8996_WRITE_SEQUENCER_360, 0x2fff },
460 { WM8996_WRITE_SEQUENCER_364, 0x2fff },
461 { WM8996_WRITE_SEQUENCER_368, 0x2fff },
462 { WM8996_WRITE_SEQUENCER_372, 0x2fff },
463 { WM8996_WRITE_SEQUENCER_376, 0x2fff },
464 { WM8996_WRITE_SEQUENCER_380, 0x2fff },
465 { WM8996_WRITE_SEQUENCER_384, 0x60 },
466 { WM8996_WRITE_SEQUENCER_386, 0x601 },
467 { WM8996_WRITE_SEQUENCER_388, 0x61 },
468 { WM8996_WRITE_SEQUENCER_390, 0x601 },
469 { WM8996_WRITE_SEQUENCER_392, 0x50 },
470 { WM8996_WRITE_SEQUENCER_394, 0x300 },
471 { WM8996_WRITE_SEQUENCER_396, 0x1 },
472 { WM8996_WRITE_SEQUENCER_398, 0x304 },
473 { WM8996_WRITE_SEQUENCER_400, 0x40 },
474 { WM8996_WRITE_SEQUENCER_402, 0xf },
475 { WM8996_WRITE_SEQUENCER_404, 0x1 },
476 { WM8996_WRITE_SEQUENCER_407, 0x100 },
477}; 299};
478 300
479static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); 301static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
@@ -1706,18 +1528,6 @@ static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
1706 } 1528 }
1707} 1529}
1708 1530
1709static int wm8996_reset(struct wm8996_priv *wm8996)
1710{
1711 if (wm8996->pdata.ldo_ena > 0) {
1712 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1713 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
1714 return 0;
1715 } else {
1716 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
1717 0x8915);
1718 }
1719}
1720
1721static const int bclk_divs[] = { 1531static const int bclk_divs[] = {
1722 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 1532 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1723}; 1533};
@@ -1809,8 +1619,10 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1809 1619
1810 case SND_SOC_BIAS_OFF: 1620 case SND_SOC_BIAS_OFF:
1811 regcache_cache_only(codec->control_data, true); 1621 regcache_cache_only(codec->control_data, true);
1812 if (wm8996->pdata.ldo_ena >= 0) 1622 if (wm8996->pdata.ldo_ena >= 0) {
1813 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 1623 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1624 regcache_cache_only(codec->control_data, true);
1625 }
1814 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), 1626 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
1815 wm8996->supplies); 1627 wm8996->supplies);
1816 break; 1628 break;
@@ -2807,7 +2619,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2807 int ret; 2619 int ret;
2808 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2620 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2809 struct i2c_client *i2c = to_i2c_client(codec->dev); 2621 struct i2c_client *i2c = to_i2c_client(codec->dev);
2810 int i, irq_flags; 2622 int irq_flags;
2811 2623
2812 wm8996->codec = codec; 2624 wm8996->codec = codec;
2813 2625
@@ -2822,177 +2634,12 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2822 goto err; 2634 goto err;
2823 } 2635 }
2824 2636
2825 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2826 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2827 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2828
2829 /* This should really be moved into the regulator core */
2830 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
2831 ret = regulator_register_notifier(wm8996->supplies[i].consumer,
2832 &wm8996->disable_nb[i]);
2833 if (ret != 0) {
2834 dev_err(codec->dev,
2835 "Failed to register regulator notifier: %d\n",
2836 ret);
2837 }
2838 }
2839
2840 /* Apply platform data settings */
2841 snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
2842 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
2843 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
2844 wm8996->pdata.inr_mode);
2845
2846 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
2847 if (!wm8996->pdata.gpio_default[i])
2848 continue;
2849
2850 snd_soc_write(codec, WM8996_GPIO_1 + i,
2851 wm8996->pdata.gpio_default[i] & 0xffff);
2852 }
2853
2854 if (wm8996->pdata.spkmute_seq)
2855 snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
2856 WM8996_SPK_MUTE_ENDIAN |
2857 WM8996_SPK_MUTE_SEQ1_MASK,
2858 wm8996->pdata.spkmute_seq);
2859
2860 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
2861 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
2862 WM8996_MICD_SRC, wm8996->pdata.micdet_def);
2863
2864 /* Latch volume update bits */
2865 snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME,
2866 WM8996_IN1_VU, WM8996_IN1_VU);
2867 snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME,
2868 WM8996_IN1_VU, WM8996_IN1_VU);
2869
2870 snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME,
2871 WM8996_DAC1_VU, WM8996_DAC1_VU);
2872 snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME,
2873 WM8996_DAC1_VU, WM8996_DAC1_VU);
2874 snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME,
2875 WM8996_DAC2_VU, WM8996_DAC2_VU);
2876 snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME,
2877 WM8996_DAC2_VU, WM8996_DAC2_VU);
2878
2879 snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME,
2880 WM8996_DAC1_VU, WM8996_DAC1_VU);
2881 snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME,
2882 WM8996_DAC1_VU, WM8996_DAC1_VU);
2883 snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME,
2884 WM8996_DAC2_VU, WM8996_DAC2_VU);
2885 snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME,
2886 WM8996_DAC2_VU, WM8996_DAC2_VU);
2887
2888 snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME,
2889 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2890 snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME,
2891 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2892 snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME,
2893 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2894 snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME,
2895 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2896
2897 snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME,
2898 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2899 snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME,
2900 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2901 snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME,
2902 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2903 snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME,
2904 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2905
2906 /* No support currently for the underclocked TDM modes and
2907 * pick a default TDM layout with each channel pair working with
2908 * slots 0 and 1. */
2909 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
2910 WM8996_AIF1RX_CHAN0_SLOTS_MASK |
2911 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2912 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2913 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
2914 WM8996_AIF1RX_CHAN1_SLOTS_MASK |
2915 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
2916 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2917 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
2918 WM8996_AIF1RX_CHAN2_SLOTS_MASK |
2919 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
2920 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2921 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
2922 WM8996_AIF1RX_CHAN3_SLOTS_MASK |
2923 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2924 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2925 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
2926 WM8996_AIF1RX_CHAN4_SLOTS_MASK |
2927 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2928 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2929 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
2930 WM8996_AIF1RX_CHAN5_SLOTS_MASK |
2931 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2932 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2933
2934 snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
2935 WM8996_AIF2RX_CHAN0_SLOTS_MASK |
2936 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
2937 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2938 snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
2939 WM8996_AIF2RX_CHAN1_SLOTS_MASK |
2940 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
2941 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2942
2943 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
2944 WM8996_AIF1TX_CHAN0_SLOTS_MASK |
2945 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2946 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2947 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2948 WM8996_AIF1TX_CHAN1_SLOTS_MASK |
2949 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2950 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2951 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
2952 WM8996_AIF1TX_CHAN2_SLOTS_MASK |
2953 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2954 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2955 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
2956 WM8996_AIF1TX_CHAN3_SLOTS_MASK |
2957 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2958 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2959 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
2960 WM8996_AIF1TX_CHAN4_SLOTS_MASK |
2961 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2962 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2963 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
2964 WM8996_AIF1TX_CHAN5_SLOTS_MASK |
2965 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2966 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2967
2968 snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
2969 WM8996_AIF2TX_CHAN0_SLOTS_MASK |
2970 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
2971 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2972 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2973 WM8996_AIF2TX_CHAN1_SLOTS_MASK |
2974 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
2975 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2976
2977 if (wm8996->pdata.num_retune_mobile_cfgs) 2637 if (wm8996->pdata.num_retune_mobile_cfgs)
2978 wm8996_retune_mobile_pdata(codec); 2638 wm8996_retune_mobile_pdata(codec);
2979 else 2639 else
2980 snd_soc_add_codec_controls(codec, wm8996_eq_controls, 2640 snd_soc_add_codec_controls(codec, wm8996_eq_controls,
2981 ARRAY_SIZE(wm8996_eq_controls)); 2641 ARRAY_SIZE(wm8996_eq_controls));
2982 2642
2983 /* If the TX LRCLK pins are not in LRCLK mode configure the
2984 * AIFs to source their clocks from the RX LRCLKs.
2985 */
2986 if ((snd_soc_read(codec, WM8996_GPIO_1)))
2987 snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2,
2988 WM8996_AIF1TX_LRCLK_MODE,
2989 WM8996_AIF1TX_LRCLK_MODE);
2990
2991 if ((snd_soc_read(codec, WM8996_GPIO_2)))
2992 snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2,
2993 WM8996_AIF2TX_LRCLK_MODE,
2994 WM8996_AIF2TX_LRCLK_MODE);
2995
2996 if (i2c->irq) { 2643 if (i2c->irq) {
2997 if (wm8996->pdata.irq_flags) 2644 if (wm8996->pdata.irq_flags)
2998 irq_flags = wm8996->pdata.irq_flags; 2645 irq_flags = wm8996->pdata.irq_flags;
@@ -3036,9 +2683,7 @@ err:
3036 2683
3037static int wm8996_remove(struct snd_soc_codec *codec) 2684static int wm8996_remove(struct snd_soc_codec *codec)
3038{ 2685{
3039 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
3040 struct i2c_client *i2c = to_i2c_client(codec->dev); 2686 struct i2c_client *i2c = to_i2c_client(codec->dev);
3041 int i;
3042 2687
3043 snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL, 2688 snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
3044 WM8996_IM_IRQ, WM8996_IM_IRQ); 2689 WM8996_IM_IRQ, WM8996_IM_IRQ);
@@ -3046,10 +2691,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
3046 if (i2c->irq) 2691 if (i2c->irq)
3047 free_irq(i2c->irq, codec); 2692 free_irq(i2c->irq, codec);
3048 2693
3049 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3050 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3051 &wm8996->disable_nb[i]);
3052
3053 return 0; 2694 return 0;
3054} 2695}
3055 2696
@@ -3163,6 +2804,21 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3163 goto err_gpio; 2804 goto err_gpio;
3164 } 2805 }
3165 2806
2807 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2808 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2809 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2810
2811 /* This should really be moved into the regulator core */
2812 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
2813 ret = regulator_register_notifier(wm8996->supplies[i].consumer,
2814 &wm8996->disable_nb[i]);
2815 if (ret != 0) {
2816 dev_err(&i2c->dev,
2817 "Failed to register regulator notifier: %d\n",
2818 ret);
2819 }
2820 }
2821
3166 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), 2822 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
3167 wm8996->supplies); 2823 wm8996->supplies);
3168 if (ret != 0) { 2824 if (ret != 0) {
@@ -3175,7 +2831,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3175 msleep(5); 2831 msleep(5);
3176 } 2832 }
3177 2833
3178 wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); 2834 wm8996->regmap = devm_regmap_init_i2c(i2c, &wm8996_regmap);
3179 if (IS_ERR(wm8996->regmap)) { 2835 if (IS_ERR(wm8996->regmap)) {
3180 ret = PTR_ERR(wm8996->regmap); 2836 ret = PTR_ERR(wm8996->regmap);
3181 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 2837 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
@@ -3203,15 +2859,199 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3203 dev_info(&i2c->dev, "revision %c\n", 2859 dev_info(&i2c->dev, "revision %c\n",
3204 (reg & WM8996_CHIP_REV_MASK) + 'A'); 2860 (reg & WM8996_CHIP_REV_MASK) + 'A');
3205 2861
3206 ret = wm8996_reset(wm8996); 2862 if (wm8996->pdata.ldo_ena > 0) {
3207 if (ret < 0) { 2863 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3208 dev_err(&i2c->dev, "Failed to issue reset\n"); 2864 regcache_cache_only(wm8996->regmap, true);
3209 goto err_regmap; 2865 } else {
2866 ret = regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
2867 0x8915);
2868 if (ret != 0) {
2869 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
2870 goto err_regmap;
2871 }
3210 } 2872 }
3211 2873
3212 regcache_cache_only(wm8996->regmap, true);
3213 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2874 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3214 2875
2876 /* Apply platform data settings */
2877 regmap_update_bits(wm8996->regmap, WM8996_LINE_INPUT_CONTROL,
2878 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
2879 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
2880 wm8996->pdata.inr_mode);
2881
2882 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
2883 if (!wm8996->pdata.gpio_default[i])
2884 continue;
2885
2886 regmap_write(wm8996->regmap, WM8996_GPIO_1 + i,
2887 wm8996->pdata.gpio_default[i] & 0xffff);
2888 }
2889
2890 if (wm8996->pdata.spkmute_seq)
2891 regmap_update_bits(wm8996->regmap,
2892 WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
2893 WM8996_SPK_MUTE_ENDIAN |
2894 WM8996_SPK_MUTE_SEQ1_MASK,
2895 wm8996->pdata.spkmute_seq);
2896
2897 regmap_update_bits(wm8996->regmap, WM8996_ACCESSORY_DETECT_MODE_2,
2898 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
2899 WM8996_MICD_SRC, wm8996->pdata.micdet_def);
2900
2901 /* Latch volume update bits */
2902 regmap_update_bits(wm8996->regmap, WM8996_LEFT_LINE_INPUT_VOLUME,
2903 WM8996_IN1_VU, WM8996_IN1_VU);
2904 regmap_update_bits(wm8996->regmap, WM8996_RIGHT_LINE_INPUT_VOLUME,
2905 WM8996_IN1_VU, WM8996_IN1_VU);
2906
2907 regmap_update_bits(wm8996->regmap, WM8996_DAC1_LEFT_VOLUME,
2908 WM8996_DAC1_VU, WM8996_DAC1_VU);
2909 regmap_update_bits(wm8996->regmap, WM8996_DAC1_RIGHT_VOLUME,
2910 WM8996_DAC1_VU, WM8996_DAC1_VU);
2911 regmap_update_bits(wm8996->regmap, WM8996_DAC2_LEFT_VOLUME,
2912 WM8996_DAC2_VU, WM8996_DAC2_VU);
2913 regmap_update_bits(wm8996->regmap, WM8996_DAC2_RIGHT_VOLUME,
2914 WM8996_DAC2_VU, WM8996_DAC2_VU);
2915
2916 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_LEFT_VOLUME,
2917 WM8996_DAC1_VU, WM8996_DAC1_VU);
2918 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_RIGHT_VOLUME,
2919 WM8996_DAC1_VU, WM8996_DAC1_VU);
2920 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_LEFT_VOLUME,
2921 WM8996_DAC2_VU, WM8996_DAC2_VU);
2922 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_RIGHT_VOLUME,
2923 WM8996_DAC2_VU, WM8996_DAC2_VU);
2924
2925 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_LEFT_VOLUME,
2926 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2927 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_RIGHT_VOLUME,
2928 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2929 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_LEFT_VOLUME,
2930 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2931 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_RIGHT_VOLUME,
2932 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2933
2934 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_LEFT_VOLUME,
2935 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2936 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_RIGHT_VOLUME,
2937 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2938 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_LEFT_VOLUME,
2939 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2940 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_RIGHT_VOLUME,
2941 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2942
2943 /* No support currently for the underclocked TDM modes and
2944 * pick a default TDM layout with each channel pair working with
2945 * slots 0 and 1. */
2946 regmap_update_bits(wm8996->regmap,
2947 WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
2948 WM8996_AIF1RX_CHAN0_SLOTS_MASK |
2949 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2950 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2951 regmap_update_bits(wm8996->regmap,
2952 WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
2953 WM8996_AIF1RX_CHAN1_SLOTS_MASK |
2954 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
2955 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2956 regmap_update_bits(wm8996->regmap,
2957 WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
2958 WM8996_AIF1RX_CHAN2_SLOTS_MASK |
2959 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
2960 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2961 regmap_update_bits(wm8996->regmap,
2962 WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
2963 WM8996_AIF1RX_CHAN3_SLOTS_MASK |
2964 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2965 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2966 regmap_update_bits(wm8996->regmap,
2967 WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
2968 WM8996_AIF1RX_CHAN4_SLOTS_MASK |
2969 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2970 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2971 regmap_update_bits(wm8996->regmap,
2972 WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
2973 WM8996_AIF1RX_CHAN5_SLOTS_MASK |
2974 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2975 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2976
2977 regmap_update_bits(wm8996->regmap,
2978 WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
2979 WM8996_AIF2RX_CHAN0_SLOTS_MASK |
2980 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
2981 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2982 regmap_update_bits(wm8996->regmap,
2983 WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
2984 WM8996_AIF2RX_CHAN1_SLOTS_MASK |
2985 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
2986 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2987
2988 regmap_update_bits(wm8996->regmap,
2989 WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
2990 WM8996_AIF1TX_CHAN0_SLOTS_MASK |
2991 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2992 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2993 regmap_update_bits(wm8996->regmap,
2994 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2995 WM8996_AIF1TX_CHAN1_SLOTS_MASK |
2996 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2997 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2998 regmap_update_bits(wm8996->regmap,
2999 WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
3000 WM8996_AIF1TX_CHAN2_SLOTS_MASK |
3001 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3002 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
3003 regmap_update_bits(wm8996->regmap,
3004 WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
3005 WM8996_AIF1TX_CHAN3_SLOTS_MASK |
3006 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3007 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
3008 regmap_update_bits(wm8996->regmap,
3009 WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
3010 WM8996_AIF1TX_CHAN4_SLOTS_MASK |
3011 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3012 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
3013 regmap_update_bits(wm8996->regmap,
3014 WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
3015 WM8996_AIF1TX_CHAN5_SLOTS_MASK |
3016 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3017 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
3018
3019 regmap_update_bits(wm8996->regmap,
3020 WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
3021 WM8996_AIF2TX_CHAN0_SLOTS_MASK |
3022 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
3023 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
3024 regmap_update_bits(wm8996->regmap,
3025 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
3026 WM8996_AIF2TX_CHAN1_SLOTS_MASK |
3027 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
3028 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
3029
3030 /* If the TX LRCLK pins are not in LRCLK mode configure the
3031 * AIFs to source their clocks from the RX LRCLKs.
3032 */
3033 ret = regmap_read(wm8996->regmap, WM8996_GPIO_1, &reg);
3034 if (ret != 0) {
3035 dev_err(&i2c->dev, "Failed to read GPIO1: %d\n", ret);
3036 goto err_regmap;
3037 }
3038
3039 if (reg & WM8996_GP1_FN_MASK)
3040 regmap_update_bits(wm8996->regmap, WM8996_AIF1_TX_LRCLK_2,
3041 WM8996_AIF1TX_LRCLK_MODE,
3042 WM8996_AIF1TX_LRCLK_MODE);
3043
3044 ret = regmap_read(wm8996->regmap, WM8996_GPIO_2, &reg);
3045 if (ret != 0) {
3046 dev_err(&i2c->dev, "Failed to read GPIO2: %d\n", ret);
3047 goto err_regmap;
3048 }
3049
3050 if (reg & WM8996_GP2_FN_MASK)
3051 regmap_update_bits(wm8996->regmap, WM8996_AIF2_TX_LRCLK_2,
3052 WM8996_AIF2TX_LRCLK_MODE,
3053 WM8996_AIF2TX_LRCLK_MODE);
3054
3215 wm8996_init_gpio(wm8996); 3055 wm8996_init_gpio(wm8996);
3216 3056
3217 ret = snd_soc_register_codec(&i2c->dev, 3057 ret = snd_soc_register_codec(&i2c->dev,
@@ -3225,7 +3065,6 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3225err_gpiolib: 3065err_gpiolib:
3226 wm8996_free_gpio(wm8996); 3066 wm8996_free_gpio(wm8996);
3227err_regmap: 3067err_regmap:
3228 regmap_exit(wm8996->regmap);
3229err_enable: 3068err_enable:
3230 if (wm8996->pdata.ldo_ena > 0) 3069 if (wm8996->pdata.ldo_ena > 0)
3231 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3070 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3241,14 +3080,18 @@ err:
3241static __devexit int wm8996_i2c_remove(struct i2c_client *client) 3080static __devexit int wm8996_i2c_remove(struct i2c_client *client)
3242{ 3081{
3243 struct wm8996_priv *wm8996 = i2c_get_clientdata(client); 3082 struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
3083 int i;
3244 3084
3245 snd_soc_unregister_codec(&client->dev); 3085 snd_soc_unregister_codec(&client->dev);
3246 wm8996_free_gpio(wm8996); 3086 wm8996_free_gpio(wm8996);
3247 regmap_exit(wm8996->regmap);
3248 if (wm8996->pdata.ldo_ena > 0) { 3087 if (wm8996->pdata.ldo_ena > 0) {
3249 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3088 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3250 gpio_free(wm8996->pdata.ldo_ena); 3089 gpio_free(wm8996->pdata.ldo_ena);
3251 } 3090 }
3091 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3092 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3093 &wm8996->disable_nb[i]);
3094
3252 return 0; 3095 return 0;
3253} 3096}
3254 3097
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index 9328270df16..2de74e1ea22 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Mark Brown 4 * Author: Mark Brown
5 * 5 *
6 * Copyright 2009 Wolfson Microelectronics plc 6 * Copyright 2009-12 Wolfson Microelectronics plc
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c
index 4b263b6edf1..2c2346fdd63 100644
--- a/sound/soc/codecs/wm9090.c
+++ b/sound/soc/codecs/wm9090.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * ALSA SoC WM9090 driver 2 * ALSA SoC WM9090 driver
3 * 3 *
4 * Copyright 2009, 2010 Wolfson Microelectronics 4 * Copyright 2009-12 Wolfson Microelectronics
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
index a1541414d90..099e6ec3212 100644
--- a/sound/soc/codecs/wm9712.c
+++ b/sound/soc/codecs/wm9712.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm9712.c -- ALSA Soc WM9712 codec support 2 * wm9712.c -- ALSA Soc WM9712 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006-12 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
index 2d22cc70d53..3eb19fb71d1 100644
--- a/sound/soc/codecs/wm9713.c
+++ b/sound/soc/codecs/wm9713.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm9713.c -- ALSA Soc WM9713 codec support 2 * wm9713.c -- ALSA Soc WM9713 codec support
3 * 3 *
4 * Copyright 2006 Wolfson Microelectronics PLC. 4 * Copyright 2006-10 Wolfson Microelectronics PLC.
5 * Author: Liam Girdwood <lrg@slimlogic.co.uk> 5 * Author: Liam Girdwood <lrg@slimlogic.co.uk>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c
index dfe957a47f2..61baa48823c 100644
--- a/sound/soc/codecs/wm_hubs.c
+++ b/sound/soc/codecs/wm_hubs.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm_hubs.c -- WM8993/4 common code 2 * wm_hubs.c -- WM8993/4 common code
3 * 3 *
4 * Copyright 2009 Wolfson Microelectronics plc 4 * Copyright 2009-12 Wolfson Microelectronics plc
5 * 5 *
6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
7 * 7 *
diff --git a/sound/soc/dwc/Kconfig b/sound/soc/dwc/Kconfig
new file mode 100644
index 00000000000..e334900cf0b
--- /dev/null
+++ b/sound/soc/dwc/Kconfig
@@ -0,0 +1,9 @@
1config SND_DESIGNWARE_I2S
2 tristate "Synopsys I2S Device Driver"
3 depends on CLKDEV_LOOKUP
4 help
5 Say Y or M if you want to add support for I2S driver for
6 Synopsys desigwnware I2S device. The device supports upto
7 maximum of 8 channels each for play and record.
8
9
diff --git a/sound/soc/dwc/Makefile b/sound/soc/dwc/Makefile
new file mode 100644
index 00000000000..319371f690f
--- /dev/null
+++ b/sound/soc/dwc/Makefile
@@ -0,0 +1,3 @@
1# SYNOPSYS Platform Support
2obj-$(CONFIG_SND_DESIGNWARE_I2S) += designware_i2s.o
3
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
new file mode 100644
index 00000000000..1aa51300c56
--- /dev/null
+++ b/sound/soc/dwc/designware_i2s.c
@@ -0,0 +1,455 @@
1/*
2 * ALSA SoC Synopsys I2S Audio Layer
3 *
4 * sound/soc/spear/designware_i2s.c
5 *
6 * Copyright (C) 2010 ST Microelectronics
7 * Rajeev Kumar <rajeev-dlh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/clk.h>
15#include <linux/device.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/interrupt.h>
19#include <linux/module.h>
20#include <linux/slab.h>
21#include <sound/designware_i2s.h>
22#include <sound/pcm.h>
23#include <sound/pcm_params.h>
24#include <sound/soc.h>
25
26/* common register for all channel */
27#define IER 0x000
28#define IRER 0x004
29#define ITER 0x008
30#define CER 0x00C
31#define CCR 0x010
32#define RXFFR 0x014
33#define TXFFR 0x018
34
35/* I2STxRxRegisters for all channels */
36#define LRBR_LTHR(x) (0x40 * x + 0x020)
37#define RRBR_RTHR(x) (0x40 * x + 0x024)
38#define RER(x) (0x40 * x + 0x028)
39#define TER(x) (0x40 * x + 0x02C)
40#define RCR(x) (0x40 * x + 0x030)
41#define TCR(x) (0x40 * x + 0x034)
42#define ISR(x) (0x40 * x + 0x038)
43#define IMR(x) (0x40 * x + 0x03C)
44#define ROR(x) (0x40 * x + 0x040)
45#define TOR(x) (0x40 * x + 0x044)
46#define RFCR(x) (0x40 * x + 0x048)
47#define TFCR(x) (0x40 * x + 0x04C)
48#define RFF(x) (0x40 * x + 0x050)
49#define TFF(x) (0x40 * x + 0x054)
50
51/* I2SCOMPRegisters */
52#define I2S_COMP_PARAM_2 0x01F0
53#define I2S_COMP_PARAM_1 0x01F4
54#define I2S_COMP_VERSION 0x01F8
55#define I2S_COMP_TYPE 0x01FC
56
57#define MAX_CHANNEL_NUM 8
58#define MIN_CHANNEL_NUM 2
59
60struct dw_i2s_dev {
61 void __iomem *i2s_base;
62 struct clk *clk;
63 int active;
64 unsigned int capability;
65 struct device *dev;
66
67 /* data related to DMA transfers b/w i2s and DMAC */
68 struct i2s_dma_data play_dma_data;
69 struct i2s_dma_data capture_dma_data;
70 struct i2s_clk_config_data config;
71 int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
72};
73
74static inline void i2s_write_reg(void __iomem *io_base, int reg, u32 val)
75{
76 writel(val, io_base + reg);
77}
78
79static inline u32 i2s_read_reg(void __iomem *io_base, int reg)
80{
81 return readl(io_base + reg);
82}
83
84static inline void i2s_disable_channels(struct dw_i2s_dev *dev, u32 stream)
85{
86 u32 i = 0;
87
88 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
89 for (i = 0; i < 4; i++)
90 i2s_write_reg(dev->i2s_base, TER(i), 0);
91 } else {
92 for (i = 0; i < 4; i++)
93 i2s_write_reg(dev->i2s_base, RER(i), 0);
94 }
95}
96
97static inline void i2s_clear_irqs(struct dw_i2s_dev *dev, u32 stream)
98{
99 u32 i = 0;
100
101 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
102 for (i = 0; i < 4; i++)
103 i2s_write_reg(dev->i2s_base, TOR(i), 0);
104 } else {
105 for (i = 0; i < 4; i++)
106 i2s_write_reg(dev->i2s_base, ROR(i), 0);
107 }
108}
109
110static void i2s_start(struct dw_i2s_dev *dev,
111 struct snd_pcm_substream *substream)
112{
113
114 i2s_write_reg(dev->i2s_base, IER, 1);
115
116 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
117 i2s_write_reg(dev->i2s_base, ITER, 1);
118 else
119 i2s_write_reg(dev->i2s_base, IRER, 1);
120
121 i2s_write_reg(dev->i2s_base, CER, 1);
122}
123
124static void i2s_stop(struct dw_i2s_dev *dev,
125 struct snd_pcm_substream *substream)
126{
127 u32 i = 0, irq;
128
129 i2s_clear_irqs(dev, substream->stream);
130 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
131 i2s_write_reg(dev->i2s_base, ITER, 0);
132
133 for (i = 0; i < 4; i++) {
134 irq = i2s_read_reg(dev->i2s_base, IMR(i));
135 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x30);
136 }
137 } else {
138 i2s_write_reg(dev->i2s_base, IRER, 0);
139
140 for (i = 0; i < 4; i++) {
141 irq = i2s_read_reg(dev->i2s_base, IMR(i));
142 i2s_write_reg(dev->i2s_base, IMR(i), irq | 0x03);
143 }
144 }
145
146 if (!dev->active) {
147 i2s_write_reg(dev->i2s_base, CER, 0);
148 i2s_write_reg(dev->i2s_base, IER, 0);
149 }
150}
151
152static int dw_i2s_startup(struct snd_pcm_substream *substream,
153 struct snd_soc_dai *cpu_dai)
154{
155 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(cpu_dai);
156 struct i2s_dma_data *dma_data = NULL;
157
158 if (!(dev->capability & DWC_I2S_RECORD) &&
159 (substream->stream == SNDRV_PCM_STREAM_CAPTURE))
160 return -EINVAL;
161
162 if (!(dev->capability & DWC_I2S_PLAY) &&
163 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
164 return -EINVAL;
165
166 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
167 dma_data = &dev->play_dma_data;
168 else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
169 dma_data = &dev->capture_dma_data;
170
171 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)dma_data);
172
173 return 0;
174}
175
176static int dw_i2s_hw_params(struct snd_pcm_substream *substream,
177 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
178{
179 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
180 struct i2s_clk_config_data *config = &dev->config;
181 u32 ccr, xfer_resolution, ch_reg, irq;
182 int ret;
183
184 switch (params_format(params)) {
185 case SNDRV_PCM_FORMAT_S16_LE:
186 config->data_width = 16;
187 ccr = 0x00;
188 xfer_resolution = 0x02;
189 break;
190
191 case SNDRV_PCM_FORMAT_S24_LE:
192 config->data_width = 24;
193 ccr = 0x08;
194 xfer_resolution = 0x04;
195 break;
196
197 case SNDRV_PCM_FORMAT_S32_LE:
198 config->data_width = 32;
199 ccr = 0x10;
200 xfer_resolution = 0x05;
201 break;
202
203 default:
204 dev_err(dev->dev, "designware-i2s: unsuppted PCM fmt");
205 return -EINVAL;
206 }
207
208 config->chan_nr = params_channels(params);
209
210 switch (config->chan_nr) {
211 case EIGHT_CHANNEL_SUPPORT:
212 ch_reg = 3;
213 case SIX_CHANNEL_SUPPORT:
214 ch_reg = 2;
215 case FOUR_CHANNEL_SUPPORT:
216 ch_reg = 1;
217 case TWO_CHANNEL_SUPPORT:
218 ch_reg = 0;
219 break;
220 default:
221 dev_err(dev->dev, "channel not supported\n");
222 }
223
224 i2s_disable_channels(dev, substream->stream);
225
226 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
227 i2s_write_reg(dev->i2s_base, TCR(ch_reg), xfer_resolution);
228 i2s_write_reg(dev->i2s_base, TFCR(ch_reg), 0x02);
229 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
230 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x30);
231 i2s_write_reg(dev->i2s_base, TER(ch_reg), 1);
232 } else {
233 i2s_write_reg(dev->i2s_base, RCR(ch_reg), xfer_resolution);
234 i2s_write_reg(dev->i2s_base, RFCR(ch_reg), 0x07);
235 irq = i2s_read_reg(dev->i2s_base, IMR(ch_reg));
236 i2s_write_reg(dev->i2s_base, IMR(ch_reg), irq & ~0x03);
237 i2s_write_reg(dev->i2s_base, RER(ch_reg), 1);
238 }
239
240 i2s_write_reg(dev->i2s_base, CCR, ccr);
241
242 config->sample_rate = params_rate(params);
243
244 if (!dev->i2s_clk_cfg)
245 return -EINVAL;
246
247 ret = dev->i2s_clk_cfg(config);
248 if (ret < 0) {
249 dev_err(dev->dev, "runtime audio clk config fail\n");
250 return ret;
251 }
252
253 return 0;
254}
255
256static void dw_i2s_shutdown(struct snd_pcm_substream *substream,
257 struct snd_soc_dai *dai)
258{
259 snd_soc_dai_set_dma_data(dai, substream, NULL);
260}
261
262static int dw_i2s_trigger(struct snd_pcm_substream *substream,
263 int cmd, struct snd_soc_dai *dai)
264{
265 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
266 int ret = 0;
267
268 switch (cmd) {
269 case SNDRV_PCM_TRIGGER_START:
270 case SNDRV_PCM_TRIGGER_RESUME:
271 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
272 dev->active++;
273 i2s_start(dev, substream);
274 break;
275
276 case SNDRV_PCM_TRIGGER_STOP:
277 case SNDRV_PCM_TRIGGER_SUSPEND:
278 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
279 dev->active--;
280 i2s_stop(dev, substream);
281 break;
282 default:
283 ret = -EINVAL;
284 break;
285 }
286 return ret;
287}
288
289static struct snd_soc_dai_ops dw_i2s_dai_ops = {
290 .startup = dw_i2s_startup,
291 .shutdown = dw_i2s_shutdown,
292 .hw_params = dw_i2s_hw_params,
293 .trigger = dw_i2s_trigger,
294};
295
296#ifdef CONFIG_PM
297
298static int dw_i2s_suspend(struct snd_soc_dai *dai)
299{
300 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
301
302 clk_disable(dev->clk);
303 return 0;
304}
305
306static int dw_i2s_resume(struct snd_soc_dai *dai)
307{
308 struct dw_i2s_dev *dev = snd_soc_dai_get_drvdata(dai);
309
310 clk_enable(dev->clk);
311 return 0;
312}
313
314#else
315#define dw_i2s_suspend NULL
316#define dw_i2s_resume NULL
317#endif
318
319static int dw_i2s_probe(struct platform_device *pdev)
320{
321 const struct i2s_platform_data *pdata = pdev->dev.platform_data;
322 struct dw_i2s_dev *dev;
323 struct resource *res;
324 int ret;
325 unsigned int cap;
326 struct snd_soc_dai_driver *dw_i2s_dai;
327
328 if (!pdata) {
329 dev_err(&pdev->dev, "Invalid platform data\n");
330 return -EINVAL;
331 }
332
333 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
334 if (!res) {
335 dev_err(&pdev->dev, "no i2s resource defined\n");
336 return -ENODEV;
337 }
338
339 if (!devm_request_mem_region(&pdev->dev, res->start,
340 resource_size(res), pdev->name)) {
341 dev_err(&pdev->dev, "i2s region already claimed\n");
342 return -EBUSY;
343 }
344
345 dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
346 if (!dev) {
347 dev_warn(&pdev->dev, "kzalloc fail\n");
348 return -ENOMEM;
349 }
350
351 dev->i2s_base = devm_ioremap(&pdev->dev, res->start,
352 resource_size(res));
353 if (!dev->i2s_base) {
354 dev_err(&pdev->dev, "ioremap fail for i2s_region\n");
355 return -ENOMEM;
356 }
357
358 cap = pdata->cap;
359 dev->capability = cap;
360 dev->i2s_clk_cfg = pdata->i2s_clk_cfg;
361
362 /* Set DMA slaves info */
363
364 dev->play_dma_data.data = pdata->play_dma_data;
365 dev->capture_dma_data.data = pdata->capture_dma_data;
366 dev->play_dma_data.addr = res->start + I2S_TXDMA;
367 dev->capture_dma_data.addr = res->start + I2S_RXDMA;
368 dev->play_dma_data.max_burst = 16;
369 dev->capture_dma_data.max_burst = 16;
370 dev->play_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
371 dev->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
372 dev->play_dma_data.filter = pdata->filter;
373 dev->capture_dma_data.filter = pdata->filter;
374
375 dev->clk = clk_get(&pdev->dev, NULL);
376 if (IS_ERR(dev->clk))
377 return PTR_ERR(dev->clk);
378
379 ret = clk_enable(dev->clk);
380 if (ret < 0)
381 goto err_clk_put;
382
383 dw_i2s_dai = devm_kzalloc(&pdev->dev, sizeof(*dw_i2s_dai), GFP_KERNEL);
384 if (!dw_i2s_dai) {
385 dev_err(&pdev->dev, "mem allocation failed for dai driver\n");
386 ret = -ENOMEM;
387 goto err_clk_disable;
388 }
389
390 if (cap & DWC_I2S_PLAY) {
391 dev_dbg(&pdev->dev, " SPEAr: play supported\n");
392 dw_i2s_dai->playback.channels_min = MIN_CHANNEL_NUM;
393 dw_i2s_dai->playback.channels_max = pdata->channel;
394 dw_i2s_dai->playback.formats = pdata->snd_fmts;
395 dw_i2s_dai->playback.rates = pdata->snd_rates;
396 }
397
398 if (cap & DWC_I2S_RECORD) {
399 dev_dbg(&pdev->dev, "SPEAr: record supported\n");
400 dw_i2s_dai->capture.channels_min = MIN_CHANNEL_NUM;
401 dw_i2s_dai->capture.channels_max = pdata->channel;
402 dw_i2s_dai->capture.formats = pdata->snd_fmts;
403 dw_i2s_dai->capture.rates = pdata->snd_rates;
404 }
405
406 dw_i2s_dai->ops = &dw_i2s_dai_ops;
407 dw_i2s_dai->suspend = dw_i2s_suspend;
408 dw_i2s_dai->resume = dw_i2s_resume;
409
410 dev->dev = &pdev->dev;
411 dev_set_drvdata(&pdev->dev, dev);
412 ret = snd_soc_register_dai(&pdev->dev, dw_i2s_dai);
413 if (ret != 0) {
414 dev_err(&pdev->dev, "not able to register dai\n");
415 goto err_set_drvdata;
416 }
417
418 return 0;
419
420err_set_drvdata:
421 dev_set_drvdata(&pdev->dev, NULL);
422err_clk_disable:
423 clk_disable(dev->clk);
424err_clk_put:
425 clk_put(dev->clk);
426 return ret;
427}
428
429static int dw_i2s_remove(struct platform_device *pdev)
430{
431 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
432
433 snd_soc_unregister_dai(&pdev->dev);
434 dev_set_drvdata(&pdev->dev, NULL);
435
436 clk_put(dev->clk);
437
438 return 0;
439}
440
441static struct platform_driver dw_i2s_driver = {
442 .probe = dw_i2s_probe,
443 .remove = dw_i2s_remove,
444 .driver = {
445 .name = "designware-i2s",
446 .owner = THIS_MODULE,
447 },
448};
449
450module_platform_driver(dw_i2s_driver);
451
452MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
453MODULE_DESCRIPTION("DESIGNWARE I2S SoC Interface");
454MODULE_LICENSE("GPL");
455MODULE_ALIAS("platform:designware_i2s");
diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c
index 162dbb74f4c..4eea98b42bc 100644
--- a/sound/soc/ep93xx/ep93xx-pcm.c
+++ b/sound/soc/ep93xx/ep93xx-pcm.c
@@ -136,7 +136,7 @@ static struct snd_pcm_ops ep93xx_pcm_ops = {
136 .hw_params = ep93xx_pcm_hw_params, 136 .hw_params = ep93xx_pcm_hw_params,
137 .hw_free = ep93xx_pcm_hw_free, 137 .hw_free = ep93xx_pcm_hw_free,
138 .trigger = snd_dmaengine_pcm_trigger, 138 .trigger = snd_dmaengine_pcm_trigger,
139 .pointer = snd_dmaengine_pcm_pointer, 139 .pointer = snd_dmaengine_pcm_pointer_no_residue,
140 .mmap = ep93xx_pcm_mmap, 140 .mmap = ep93xx_pcm_mmap,
141}; 141};
142 142
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index 080327414c6..e7c800ebbd7 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -156,7 +156,7 @@ static void __init audmux_debugfs_init(void)
156 return; 156 return;
157 } 157 }
158 158
159 for (i = 0; i < MX31_AUDMUX_PORT6_SSI_PINS_6 + 1; i++) { 159 for (i = 0; i < MX31_AUDMUX_PORT7_SSI_PINS_7 + 1; i++) {
160 snprintf(buf, sizeof(buf), "ssi%d", i); 160 snprintf(buf, sizeof(buf), "ssi%d", i);
161 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root, 161 if (!debugfs_create_file(buf, 0444, audmux_debugfs_root,
162 (void *)i, &audmux_debugfs_fops)) 162 (void *)i, &audmux_debugfs_fops))
diff --git a/sound/soc/fsl/imx-audmux.h b/sound/soc/fsl/imx-audmux.h
index 04ebbab8d7b..b8ff44b9daf 100644
--- a/sound/soc/fsl/imx-audmux.h
+++ b/sound/soc/fsl/imx-audmux.h
@@ -14,6 +14,7 @@
14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3 14#define MX31_AUDMUX_PORT4_SSI_PINS_4 3
15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4 15#define MX31_AUDMUX_PORT5_SSI_PINS_5 4
16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5 16#define MX31_AUDMUX_PORT6_SSI_PINS_6 5
17#define MX31_AUDMUX_PORT7_SSI_PINS_7 6
17 18
18#define MX51_AUDMUX_PORT1_SSI0 0 19#define MX51_AUDMUX_PORT1_SSI0 0
19#define MX51_AUDMUX_PORT2_SSI1 1 20#define MX51_AUDMUX_PORT2_SSI1 1
diff --git a/sound/soc/fsl/imx-mc13783.c b/sound/soc/fsl/imx-mc13783.c
index f59c3494366..549b31fdc9d 100644
--- a/sound/soc/fsl/imx-mc13783.c
+++ b/sound/soc/fsl/imx-mc13783.c
@@ -111,22 +111,39 @@ static int __devinit imx_mc13783_probe(struct platform_device *pdev)
111 return ret; 111 return ret;
112 } 112 }
113 113
114 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT4_SSI_PINS_4, 114 if (machine_is_mx31_3ds()) {
115 IMX_AUDMUX_V2_PTCR_SYN, 115 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT4_SSI_PINS_4,
116 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) | 116 IMX_AUDMUX_V2_PTCR_SYN,
117 IMX_AUDMUX_V2_PDCR_MODE(1) | 117 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT1_SSI0) |
118 IMX_AUDMUX_V2_PDCR_INMMASK(0xfc)); 118 IMX_AUDMUX_V2_PDCR_MODE(1) |
119 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0, 119 IMX_AUDMUX_V2_PDCR_INMMASK(0xfc));
120 IMX_AUDMUX_V2_PTCR_SYN | 120 imx_audmux_v2_configure_port(MX31_AUDMUX_PORT1_SSI0,
121 IMX_AUDMUX_V2_PTCR_TFSDIR | 121 IMX_AUDMUX_V2_PTCR_SYN |
122 IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | 122 IMX_AUDMUX_V2_PTCR_TFSDIR |
123 IMX_AUDMUX_V2_PTCR_TCLKDIR | 123 IMX_AUDMUX_V2_PTCR_TFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
124 IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | 124 IMX_AUDMUX_V2_PTCR_TCLKDIR |
125 IMX_AUDMUX_V2_PTCR_RFSDIR | 125 IMX_AUDMUX_V2_PTCR_TCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
126 IMX_AUDMUX_V2_PTCR_RFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) | 126 IMX_AUDMUX_V2_PTCR_RFSDIR |
127 IMX_AUDMUX_V2_PTCR_RCLKDIR | 127 IMX_AUDMUX_V2_PTCR_RFSEL(MX31_AUDMUX_PORT4_SSI_PINS_4) |
128 IMX_AUDMUX_V2_PTCR_RCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4), 128 IMX_AUDMUX_V2_PTCR_RCLKDIR |
129 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT4_SSI_PINS_4)); 129 IMX_AUDMUX_V2_PTCR_RCSEL(MX31_AUDMUX_PORT4_SSI_PINS_4),
130 IMX_AUDMUX_V2_PDCR_RXDSEL(MX31_AUDMUX_PORT4_SSI_PINS_4));
131 } else if (machine_is_mx27_3ds()) {
132 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR1_SSI0,
133 IMX_AUDMUX_V1_PCR_SYN |
134 IMX_AUDMUX_V1_PCR_TFSDIR |
135 IMX_AUDMUX_V1_PCR_TCLKDIR |
136 IMX_AUDMUX_V1_PCR_RFSDIR |
137 IMX_AUDMUX_V1_PCR_RCLKDIR |
138 IMX_AUDMUX_V1_PCR_TFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
139 IMX_AUDMUX_V1_PCR_RFCSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4) |
140 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR3_SSI_PINS_4)
141 );
142 imx_audmux_v1_configure_port(MX27_AUDMUX_HPCR3_SSI_PINS_4,
143 IMX_AUDMUX_V1_PCR_SYN |
144 IMX_AUDMUX_V1_PCR_RXDSEL(MX27_AUDMUX_HPCR1_SSI0)
145 );
146 }
130 147
131 return ret; 148 return ret;
132} 149}
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index f3c0a5ef35c..48f9d886f02 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -141,7 +141,7 @@ static struct snd_pcm_ops imx_pcm_ops = {
141 .ioctl = snd_pcm_lib_ioctl, 141 .ioctl = snd_pcm_lib_ioctl,
142 .hw_params = snd_imx_pcm_hw_params, 142 .hw_params = snd_imx_pcm_hw_params,
143 .trigger = snd_dmaengine_pcm_trigger, 143 .trigger = snd_dmaengine_pcm_trigger,
144 .pointer = snd_dmaengine_pcm_pointer, 144 .pointer = snd_dmaengine_pcm_pointer_no_residue,
145 .mmap = snd_imx_pcm_mmap, 145 .mmap = snd_imx_pcm_mmap,
146}; 146};
147 147
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index 456b7d723d6..ee27ba3933b 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -29,6 +29,7 @@
29 29
30#include <asm/fiq.h> 30#include <asm/fiq.h>
31 31
32#include <mach/irqs.h>
32#include <mach/ssi.h> 33#include <mach/ssi.h>
33 34
34#include "imx-ssi.h" 35#include "imx-ssi.h"
diff --git a/sound/soc/fsl/imx-sgtl5000.c b/sound/soc/fsl/imx-sgtl5000.c
index 3a729caeb8c..fb21b17f17f 100644
--- a/sound/soc/fsl/imx-sgtl5000.c
+++ b/sound/soc/fsl/imx-sgtl5000.c
@@ -95,8 +95,7 @@ static int __devinit imx_sgtl5000_probe(struct platform_device *pdev)
95 return ret; 95 return ret;
96 } 96 }
97 imx_audmux_v2_configure_port(ext_port, 97 imx_audmux_v2_configure_port(ext_port,
98 IMX_AUDMUX_V2_PTCR_SYN | 98 IMX_AUDMUX_V2_PTCR_SYN,
99 IMX_AUDMUX_V2_PTCR_TCSEL(int_port),
100 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port)); 99 IMX_AUDMUX_V2_PDCR_RXDSEL(int_port));
101 if (ret) { 100 if (ret) {
102 dev_err(&pdev->dev, "audmux external port setup failed\n"); 101 dev_err(&pdev->dev, "audmux external port setup failed\n");
diff --git a/sound/soc/mxs/mxs-pcm.c b/sound/soc/mxs/mxs-pcm.c
index 373dec90579..f82d766cbf9 100644
--- a/sound/soc/mxs/mxs-pcm.c
+++ b/sound/soc/mxs/mxs-pcm.c
@@ -141,7 +141,7 @@ static struct snd_pcm_ops mxs_pcm_ops = {
141 .ioctl = snd_pcm_lib_ioctl, 141 .ioctl = snd_pcm_lib_ioctl,
142 .hw_params = snd_mxs_pcm_hw_params, 142 .hw_params = snd_mxs_pcm_hw_params,
143 .trigger = snd_dmaengine_pcm_trigger, 143 .trigger = snd_dmaengine_pcm_trigger,
144 .pointer = snd_dmaengine_pcm_pointer, 144 .pointer = snd_dmaengine_pcm_pointer_no_residue,
145 .mmap = snd_mxs_pcm_mmap, 145 .mmap = snd_mxs_pcm_mmap,
146}; 146};
147 147
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index 3e6e8764b2e..215113b05f7 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -133,7 +133,7 @@ static int __devinit mxs_sgtl5000_probe_dt(struct platform_device *pdev)
133 mxs_sgtl5000_dai[i].codec_name = NULL; 133 mxs_sgtl5000_dai[i].codec_name = NULL;
134 mxs_sgtl5000_dai[i].codec_of_node = codec_np; 134 mxs_sgtl5000_dai[i].codec_of_node = codec_np;
135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL; 135 mxs_sgtl5000_dai[i].cpu_dai_name = NULL;
136 mxs_sgtl5000_dai[i].cpu_dai_of_node = saif_np[i]; 136 mxs_sgtl5000_dai[i].cpu_of_node = saif_np[i];
137 mxs_sgtl5000_dai[i].platform_name = NULL; 137 mxs_sgtl5000_dai[i].platform_name = NULL;
138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i]; 138 mxs_sgtl5000_dai[i].platform_of_node = saif_np[i];
139 } 139 }
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c
index 59d47ab5b15..2c66e2498a4 100644
--- a/sound/soc/omap/omap-mcpdm.c
+++ b/sound/soc/omap/omap-mcpdm.c
@@ -527,6 +527,7 @@ static struct platform_driver asoc_mcpdm_driver = {
527 527
528module_platform_driver(asoc_mcpdm_driver); 528module_platform_driver(asoc_mcpdm_driver);
529 529
530MODULE_ALIAS("platform:omap-mcpdm");
530MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>"); 531MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
531MODULE_DESCRIPTION("OMAP PDM SoC Interface"); 532MODULE_DESCRIPTION("OMAP PDM SoC Interface");
532MODULE_LICENSE("GPL"); 533MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig
index a0f7d3cfa47..4d2e46fae77 100644
--- a/sound/soc/pxa/Kconfig
+++ b/sound/soc/pxa/Kconfig
@@ -8,6 +8,15 @@ config SND_PXA2XX_SOC
8 the PXA2xx AC97, I2S or SSP interface. You will also need 8 the PXA2xx AC97, I2S or SSP interface. You will also need
9 to select the audio interfaces to support below. 9 to select the audio interfaces to support below.
10 10
11config SND_MMP_SOC
12 bool "Soc Audio for Marvell MMP chips"
13 depends on ARCH_MMP
14 select SND_SOC_DMAENGINE_PCM
15 select SND_ARM
16 help
17 Say Y if you want to add support for codecs attached to
18 the MMP SSPA interface.
19
11config SND_PXA2XX_AC97 20config SND_PXA2XX_AC97
12 tristate 21 tristate
13 select SND_AC97_CODEC 22 select SND_AC97_CODEC
@@ -26,6 +35,9 @@ config SND_PXA_SOC_SSP
26 tristate 35 tristate
27 select PXA_SSP 36 select PXA_SSP
28 37
38config SND_MMP_SOC_SSPA
39 tristate
40
29config SND_PXA2XX_SOC_CORGI 41config SND_PXA2XX_SOC_CORGI
30 tristate "SoC Audio support for Sharp Zaurus SL-C7x0" 42 tristate "SoC Audio support for Sharp Zaurus SL-C7x0"
31 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx 43 depends on SND_PXA2XX_SOC && PXA_SHARP_C7xx
@@ -138,6 +150,26 @@ config SND_SOC_TAVOREVB3
138 Say Y if you want to add support for SoC audio on the 150 Say Y if you want to add support for SoC audio on the
139 Marvell Saarb reference platform. 151 Marvell Saarb reference platform.
140 152
153config SND_PXA910_SOC
154 tristate "SoC Audio for Marvell PXA910 chip"
155 depends on ARCH_MMP && SND
156 select SND_PCM
157 help
158 Say Y if you want to add support for SoC audio on the
159 Marvell PXA910 reference platform.
160
161config SND_SOC_TTC_DKB
162 bool "SoC Audio support for TTC DKB"
163 depends on SND_PXA910_SOC && MACH_TTC_DKB
164 select PXA_SSP
165 select SND_PXA_SOC_SSP
166 select SND_MMP_SOC
167 select MFD_88PM860X
168 select SND_SOC_88PM860X
169 help
170 Say Y if you want to add support for SoC audio on TTC DKB
171
172
141config SND_SOC_ZYLONITE 173config SND_SOC_ZYLONITE
142 tristate "SoC Audio support for Marvell Zylonite" 174 tristate "SoC Audio support for Marvell Zylonite"
143 depends on SND_PXA2XX_SOC && MACH_ZYLONITE 175 depends on SND_PXA2XX_SOC && MACH_ZYLONITE
@@ -194,3 +226,13 @@ config SND_PXA2XX_SOC_IMOTE2
194 help 226 help
195 Say Y if you want to add support for SoC audio on the 227 Say Y if you want to add support for SoC audio on the
196 IMote 2. 228 IMote 2.
229
230config SND_MMP_SOC_BROWNSTONE
231 tristate "SoC Audio support for Marvell Brownstone"
232 depends on SND_MMP_SOC && MACH_BROWNSTONE
233 select SND_MMP_SOC_SSPA
234 select MFD_WM8994
235 select SND_SOC_WM8994
236 help
237 Say Y if you want to add support for SoC audio on the
238 Marvell Brownstone reference platform.
diff --git a/sound/soc/pxa/Makefile b/sound/soc/pxa/Makefile
index af357623be9..d8a265d2d5d 100644
--- a/sound/soc/pxa/Makefile
+++ b/sound/soc/pxa/Makefile
@@ -3,11 +3,15 @@ snd-soc-pxa2xx-objs := pxa2xx-pcm.o
3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o 3snd-soc-pxa2xx-ac97-objs := pxa2xx-ac97.o
4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o 4snd-soc-pxa2xx-i2s-objs := pxa2xx-i2s.o
5snd-soc-pxa-ssp-objs := pxa-ssp.o 5snd-soc-pxa-ssp-objs := pxa-ssp.o
6snd-soc-mmp-objs := mmp-pcm.o
7snd-soc-mmp-sspa-objs := mmp-sspa.o
6 8
7obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o 9obj-$(CONFIG_SND_PXA2XX_SOC) += snd-soc-pxa2xx.o
8obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o 10obj-$(CONFIG_SND_PXA2XX_SOC_AC97) += snd-soc-pxa2xx-ac97.o
9obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o 11obj-$(CONFIG_SND_PXA2XX_SOC_I2S) += snd-soc-pxa2xx-i2s.o
10obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o 12obj-$(CONFIG_SND_PXA_SOC_SSP) += snd-soc-pxa-ssp.o
13obj-$(CONFIG_SND_MMP_SOC) += snd-soc-mmp.o
14obj-$(CONFIG_SND_MMP_SOC_SSPA) += snd-soc-mmp-sspa.o
11 15
12# PXA Machine Support 16# PXA Machine Support
13snd-soc-corgi-objs := corgi.o 17snd-soc-corgi-objs := corgi.o
@@ -28,6 +32,8 @@ snd-soc-mioa701-objs := mioa701_wm9713.o
28snd-soc-z2-objs := z2.o 32snd-soc-z2-objs := z2.o
29snd-soc-imote2-objs := imote2.o 33snd-soc-imote2-objs := imote2.o
30snd-soc-raumfeld-objs := raumfeld.o 34snd-soc-raumfeld-objs := raumfeld.o
35snd-soc-brownstone-objs := brownstone.o
36snd-soc-ttc-dkb-objs := ttc-dkb.o
31 37
32obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o 38obj-$(CONFIG_SND_PXA2XX_SOC_CORGI) += snd-soc-corgi.o
33obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o 39obj-$(CONFIG_SND_PXA2XX_SOC_POODLE) += snd-soc-poodle.o
@@ -47,3 +53,5 @@ obj-$(CONFIG_SND_SOC_TAVOREVB3) += snd-soc-tavorevb3.o
47obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o 53obj-$(CONFIG_SND_SOC_ZYLONITE) += snd-soc-zylonite.o
48obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o 54obj-$(CONFIG_SND_PXA2XX_SOC_IMOTE2) += snd-soc-imote2.o
49obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o 55obj-$(CONFIG_SND_SOC_RAUMFELD) += snd-soc-raumfeld.o
56obj-$(CONFIG_SND_MMP_SOC_BROWNSTONE) += snd-soc-brownstone.o
57obj-$(CONFIG_SND_SOC_TTC_DKB) += snd-soc-ttc-dkb.o
diff --git a/sound/soc/pxa/brownstone.c b/sound/soc/pxa/brownstone.c
new file mode 100644
index 00000000000..5e666e03d33
--- /dev/null
+++ b/sound/soc/pxa/brownstone.c
@@ -0,0 +1,174 @@
1/*
2 * linux/sound/soc/pxa/brownstone.c
3 *
4 * Copyright (C) 2011 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14#include <sound/core.h>
15#include <sound/pcm.h>
16#include <sound/soc.h>
17#include <sound/jack.h>
18
19#include "../codecs/wm8994.h"
20#include "mmp-sspa.h"
21
22static const struct snd_kcontrol_new brownstone_dapm_control[] = {
23 SOC_DAPM_PIN_SWITCH("Ext Spk"),
24};
25
26static const struct snd_soc_dapm_widget brownstone_dapm_widgets[] = {
27 SND_SOC_DAPM_SPK("Ext Spk", NULL),
28 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
29 SND_SOC_DAPM_MIC("Headset Mic", NULL),
30 SND_SOC_DAPM_MIC("Main Mic", NULL),
31};
32
33static const struct snd_soc_dapm_route brownstone_audio_map[] = {
34 {"Ext Spk", NULL, "SPKOUTLP"},
35 {"Ext Spk", NULL, "SPKOUTLN"},
36 {"Ext Spk", NULL, "SPKOUTRP"},
37 {"Ext Spk", NULL, "SPKOUTRN"},
38
39 {"Headset Stereophone", NULL, "HPOUT1L"},
40 {"Headset Stereophone", NULL, "HPOUT1R"},
41
42 {"IN1RN", NULL, "Headset Mic"},
43
44 {"DMIC1DAT", NULL, "MICBIAS1"},
45 {"MICBIAS1", NULL, "Main Mic"},
46};
47
48static int brownstone_wm8994_init(struct snd_soc_pcm_runtime *rtd)
49{
50 struct snd_soc_codec *codec = rtd->codec;
51 struct snd_soc_dapm_context *dapm = &codec->dapm;
52
53 snd_soc_dapm_enable_pin(dapm, "Ext Spk");
54 snd_soc_dapm_enable_pin(dapm, "Headset Stereophone");
55 snd_soc_dapm_enable_pin(dapm, "Headset Mic");
56 snd_soc_dapm_enable_pin(dapm, "Main Mic");
57
58 /* set endpoints to not connected */
59 snd_soc_dapm_nc_pin(dapm, "HPOUT2P");
60 snd_soc_dapm_nc_pin(dapm, "HPOUT2N");
61 snd_soc_dapm_nc_pin(dapm, "LINEOUT1N");
62 snd_soc_dapm_nc_pin(dapm, "LINEOUT1P");
63 snd_soc_dapm_nc_pin(dapm, "LINEOUT2N");
64 snd_soc_dapm_nc_pin(dapm, "LINEOUT2P");
65 snd_soc_dapm_nc_pin(dapm, "IN1LN");
66 snd_soc_dapm_nc_pin(dapm, "IN1LP");
67 snd_soc_dapm_nc_pin(dapm, "IN1RP");
68 snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN");
69 snd_soc_dapm_nc_pin(dapm, "IN2RN");
70 snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP");
71 snd_soc_dapm_nc_pin(dapm, "IN2LN");
72
73 snd_soc_dapm_sync(dapm);
74
75 return 0;
76}
77
78static int brownstone_wm8994_hw_params(struct snd_pcm_substream *substream,
79 struct snd_pcm_hw_params *params)
80{
81 struct snd_soc_pcm_runtime *rtd = substream->private_data;
82 struct snd_soc_dai *codec_dai = rtd->codec_dai;
83 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
84 int freq_out, sspa_mclk, sysclk;
85 int sspa_div;
86
87 if (params_rate(params) > 11025) {
88 freq_out = params_rate(params) * 512;
89 sysclk = params_rate(params) * 256;
90 sspa_mclk = params_rate(params) * 64;
91 } else {
92 freq_out = params_rate(params) * 1024;
93 sysclk = params_rate(params) * 512;
94 sspa_mclk = params_rate(params) * 64;
95 }
96 sspa_div = freq_out;
97 do_div(sspa_div, sspa_mclk);
98
99 snd_soc_dai_set_sysclk(cpu_dai, MMP_SSPA_CLK_AUDIO, freq_out, 0);
100 snd_soc_dai_set_pll(cpu_dai, MMP_SYSCLK, 0, freq_out, sysclk);
101 snd_soc_dai_set_pll(cpu_dai, MMP_SSPA_CLK, 0, freq_out, sspa_mclk);
102
103 /* set wm8994 sysclk */
104 snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_MCLK1, sysclk, 0);
105
106 return 0;
107}
108
109/* machine stream operations */
110static struct snd_soc_ops brownstone_ops = {
111 .hw_params = brownstone_wm8994_hw_params,
112};
113
114static struct snd_soc_dai_link brownstone_wm8994_dai[] = {
115{
116 .name = "WM8994",
117 .stream_name = "WM8994 HiFi",
118 .cpu_dai_name = "mmp-sspa-dai.0",
119 .codec_dai_name = "wm8994-aif1",
120 .platform_name = "mmp-pcm-audio",
121 .codec_name = "wm8994-codec",
122 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
123 SND_SOC_DAIFMT_CBS_CFS,
124 .ops = &brownstone_ops,
125 .init = brownstone_wm8994_init,
126},
127};
128
129/* audio machine driver */
130static struct snd_soc_card brownstone = {
131 .name = "brownstone",
132 .dai_link = brownstone_wm8994_dai,
133 .num_links = ARRAY_SIZE(brownstone_wm8994_dai),
134
135 .controls = brownstone_dapm_control,
136 .num_controls = ARRAY_SIZE(brownstone_dapm_control),
137 .dapm_widgets = brownstone_dapm_widgets,
138 .num_dapm_widgets = ARRAY_SIZE(brownstone_dapm_widgets),
139 .dapm_routes = brownstone_audio_map,
140 .num_dapm_routes = ARRAY_SIZE(brownstone_audio_map),
141};
142
143static int __devinit brownstone_probe(struct platform_device *pdev)
144{
145 int ret;
146
147 brownstone.dev = &pdev->dev;
148 ret = snd_soc_register_card(&brownstone);
149 if (ret)
150 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
151 ret);
152 return ret;
153}
154
155static int __devexit brownstone_remove(struct platform_device *pdev)
156{
157 snd_soc_unregister_card(&brownstone);
158 return 0;
159}
160
161static struct platform_driver mmp_driver = {
162 .driver = {
163 .name = "brownstone-audio",
164 .owner = THIS_MODULE,
165 },
166 .probe = brownstone_probe,
167 .remove = __devexit_p(brownstone_remove),
168};
169
170module_platform_driver(mmp_driver);
171
172MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
173MODULE_DESCRIPTION("ALSA SoC Brownstone");
174MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c
index 9c585af59b5..8687c1c65d2 100644
--- a/sound/soc/pxa/mioa701_wm9713.c
+++ b/sound/soc/pxa/mioa701_wm9713.c
@@ -186,36 +186,27 @@ static struct snd_soc_card mioa701 = {
186 .num_links = ARRAY_SIZE(mioa701_dai), 186 .num_links = ARRAY_SIZE(mioa701_dai),
187}; 187};
188 188
189static struct platform_device *mioa701_snd_device; 189static int __devinit mioa701_wm9713_probe(struct platform_device *pdev)
190
191static int mioa701_wm9713_probe(struct platform_device *pdev)
192{ 190{
193 int ret; 191 int rc;
194 192
195 if (!machine_is_mioa701()) 193 if (!machine_is_mioa701())
196 return -ENODEV; 194 return -ENODEV;
197 195
198 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will" 196 mioa701.dev = &pdev->dev;
199 "lead to overheating and possible destruction of your device." 197 rc = snd_soc_register_card(&mioa701);
200 "Do not use without a good knowledge of mio's board design!\n"); 198 if (!rc)
201 199 dev_warn(&pdev->dev, "Be warned that incorrect mixers/muxes setup will"
202 mioa701_snd_device = platform_device_alloc("soc-audio", -1); 200 "lead to overheating and possible destruction of your device."
203 if (!mioa701_snd_device) 201 " Do not use without a good knowledge of mio's board design!\n");
204 return -ENOMEM; 202 return rc;
205
206 platform_set_drvdata(mioa701_snd_device, &mioa701);
207
208 ret = platform_device_add(mioa701_snd_device);
209 if (!ret)
210 return 0;
211
212 platform_device_put(mioa701_snd_device);
213 return ret;
214} 203}
215 204
216static int __devexit mioa701_wm9713_remove(struct platform_device *pdev) 205static int __devexit mioa701_wm9713_remove(struct platform_device *pdev)
217{ 206{
218 platform_device_unregister(mioa701_snd_device); 207 struct snd_soc_card *card = platform_get_drvdata(pdev);
208
209 snd_soc_unregister_card(card);
219 return 0; 210 return 0;
220} 211}
221 212
diff --git a/sound/soc/pxa/mmp-pcm.c b/sound/soc/pxa/mmp-pcm.c
new file mode 100644
index 00000000000..73ac5463c9e
--- /dev/null
+++ b/sound/soc/pxa/mmp-pcm.c
@@ -0,0 +1,297 @@
1/*
2 * linux/sound/soc/pxa/mmp-pcm.c
3 *
4 * Copyright (C) 2011 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/platform_device.h>
15#include <linux/slab.h>
16#include <linux/dma-mapping.h>
17#include <linux/dmaengine.h>
18#include <linux/platform_data/mmp_audio.h>
19#include <sound/pxa2xx-lib.h>
20#include <sound/core.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <mach/sram.h>
25#include <sound/dmaengine_pcm.h>
26
27struct mmp_dma_data {
28 int ssp_id;
29 struct resource *dma_res;
30};
31
32#define MMP_PCM_INFO (SNDRV_PCM_INFO_MMAP | \
33 SNDRV_PCM_INFO_MMAP_VALID | \
34 SNDRV_PCM_INFO_INTERLEAVED | \
35 SNDRV_PCM_INFO_PAUSE | \
36 SNDRV_PCM_INFO_RESUME)
37
38#define MMP_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
39 SNDRV_PCM_FMTBIT_S24_LE | \
40 SNDRV_PCM_FMTBIT_S32_LE)
41
42static struct snd_pcm_hardware mmp_pcm_hardware[] = {
43 {
44 .info = MMP_PCM_INFO,
45 .formats = MMP_PCM_FORMATS,
46 .period_bytes_min = 1024,
47 .period_bytes_max = 2048,
48 .periods_min = 2,
49 .periods_max = 32,
50 .buffer_bytes_max = 4096,
51 .fifo_size = 32,
52 },
53 {
54 .info = MMP_PCM_INFO,
55 .formats = MMP_PCM_FORMATS,
56 .period_bytes_min = 1024,
57 .period_bytes_max = 2048,
58 .periods_min = 2,
59 .periods_max = 32,
60 .buffer_bytes_max = 4096,
61 .fifo_size = 32,
62 },
63};
64
65static int mmp_pcm_hw_params(struct snd_pcm_substream *substream,
66 struct snd_pcm_hw_params *params)
67{
68 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
69 struct snd_soc_pcm_runtime *rtd = substream->private_data;
70 struct pxa2xx_pcm_dma_params *dma_params;
71 struct dma_slave_config slave_config;
72 int ret;
73
74 dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
75 if (!dma_params)
76 return 0;
77
78 ret = snd_hwparams_to_dma_slave_config(substream, params, &slave_config);
79 if (ret)
80 return ret;
81
82 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
83 slave_config.dst_addr = dma_params->dev_addr;
84 slave_config.dst_maxburst = 4;
85 } else {
86 slave_config.src_addr = dma_params->dev_addr;
87 slave_config.src_maxburst = 4;
88 }
89
90 ret = dmaengine_slave_config(chan, &slave_config);
91 if (ret)
92 return ret;
93
94 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
95
96 return 0;
97}
98
99static bool filter(struct dma_chan *chan, void *param)
100{
101 struct mmp_dma_data *dma_data = param;
102 bool found = false;
103 char *devname;
104
105 devname = kasprintf(GFP_KERNEL, "%s.%d", dma_data->dma_res->name,
106 dma_data->ssp_id);
107 if ((strcmp(dev_name(chan->device->dev), devname) == 0) &&
108 (chan->chan_id == dma_data->dma_res->start)) {
109 found = true;
110 }
111
112 kfree(devname);
113 return found;
114}
115
116static int mmp_pcm_open(struct snd_pcm_substream *substream)
117{
118 struct snd_soc_pcm_runtime *rtd = substream->private_data;
119 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
120 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
121 struct mmp_dma_data *dma_data;
122 struct resource *r;
123 int ret;
124
125 r = platform_get_resource(pdev, IORESOURCE_DMA, substream->stream);
126 if (!r)
127 return -EBUSY;
128
129 snd_soc_set_runtime_hwparams(substream,
130 &mmp_pcm_hardware[substream->stream]);
131 dma_data = devm_kzalloc(&pdev->dev,
132 sizeof(struct mmp_dma_data), GFP_KERNEL);
133 if (dma_data == NULL)
134 return -ENOMEM;
135
136 dma_data->dma_res = r;
137 dma_data->ssp_id = cpu_dai->id;
138
139 ret = snd_dmaengine_pcm_open(substream, filter, dma_data);
140 if (ret) {
141 devm_kfree(&pdev->dev, dma_data);
142 return ret;
143 }
144
145 snd_dmaengine_pcm_set_data(substream, dma_data);
146 return 0;
147}
148
149static int mmp_pcm_close(struct snd_pcm_substream *substream)
150{
151 struct mmp_dma_data *dma_data = snd_dmaengine_pcm_get_data(substream);
152 struct snd_soc_pcm_runtime *rtd = substream->private_data;
153 struct platform_device *pdev = to_platform_device(rtd->platform->dev);
154
155 snd_dmaengine_pcm_close(substream);
156 devm_kfree(&pdev->dev, dma_data);
157 return 0;
158}
159
160static int mmp_pcm_mmap(struct snd_pcm_substream *substream,
161 struct vm_area_struct *vma)
162{
163 struct snd_pcm_runtime *runtime = substream->runtime;
164 unsigned long off = vma->vm_pgoff;
165
166 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
167 return remap_pfn_range(vma, vma->vm_start,
168 __phys_to_pfn(runtime->dma_addr) + off,
169 vma->vm_end - vma->vm_start, vma->vm_page_prot);
170}
171
172struct snd_pcm_ops mmp_pcm_ops = {
173 .open = mmp_pcm_open,
174 .close = mmp_pcm_close,
175 .ioctl = snd_pcm_lib_ioctl,
176 .hw_params = mmp_pcm_hw_params,
177 .trigger = snd_dmaengine_pcm_trigger,
178 .pointer = snd_dmaengine_pcm_pointer,
179 .mmap = mmp_pcm_mmap,
180};
181
182static void mmp_pcm_free_dma_buffers(struct snd_pcm *pcm)
183{
184 struct snd_pcm_substream *substream;
185 struct snd_dma_buffer *buf;
186 int stream;
187 struct gen_pool *gpool;
188
189 gpool = sram_get_gpool("asram");
190 if (!gpool)
191 return;
192
193 for (stream = 0; stream < 2; stream++) {
194 size_t size = mmp_pcm_hardware[stream].buffer_bytes_max;
195
196 substream = pcm->streams[stream].substream;
197 if (!substream)
198 continue;
199
200 buf = &substream->dma_buffer;
201 if (!buf->area)
202 continue;
203 gen_pool_free(gpool, (unsigned long)buf->area, size);
204 buf->area = NULL;
205 }
206
207 return;
208}
209
210static int mmp_pcm_preallocate_dma_buffer(struct snd_pcm_substream *substream,
211 int stream)
212{
213 struct snd_dma_buffer *buf = &substream->dma_buffer;
214 size_t size = mmp_pcm_hardware[stream].buffer_bytes_max;
215 struct gen_pool *gpool;
216
217 buf->dev.type = SNDRV_DMA_TYPE_DEV;
218 buf->dev.dev = substream->pcm->card->dev;
219 buf->private_data = NULL;
220
221 gpool = sram_get_gpool("asram");
222 if (!gpool)
223 return -ENOMEM;
224
225 buf->area = (unsigned char *)gen_pool_alloc(gpool, size);
226 if (!buf->area)
227 return -ENOMEM;
228 buf->addr = gen_pool_virt_to_phys(gpool, (unsigned long)buf->area);
229 buf->bytes = size;
230 return 0;
231}
232
233int mmp_pcm_new(struct snd_soc_pcm_runtime *rtd)
234{
235 struct snd_pcm_substream *substream;
236 struct snd_pcm *pcm = rtd->pcm;
237 int ret = 0, stream;
238
239 for (stream = 0; stream < 2; stream++) {
240 substream = pcm->streams[stream].substream;
241
242 ret = mmp_pcm_preallocate_dma_buffer(substream, stream);
243 if (ret)
244 goto err;
245 }
246
247 return 0;
248
249err:
250 mmp_pcm_free_dma_buffers(pcm);
251 return ret;
252}
253
254struct snd_soc_platform_driver mmp_soc_platform = {
255 .ops = &mmp_pcm_ops,
256 .pcm_new = mmp_pcm_new,
257 .pcm_free = mmp_pcm_free_dma_buffers,
258};
259
260static __devinit int mmp_pcm_probe(struct platform_device *pdev)
261{
262 struct mmp_audio_platdata *pdata = pdev->dev.platform_data;
263
264 if (pdata) {
265 mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].buffer_bytes_max =
266 pdata->buffer_max_playback;
267 mmp_pcm_hardware[SNDRV_PCM_STREAM_PLAYBACK].period_bytes_max =
268 pdata->period_max_playback;
269 mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].buffer_bytes_max =
270 pdata->buffer_max_capture;
271 mmp_pcm_hardware[SNDRV_PCM_STREAM_CAPTURE].period_bytes_max =
272 pdata->period_max_capture;
273 }
274 return snd_soc_register_platform(&pdev->dev, &mmp_soc_platform);
275}
276
277static int __devexit mmp_pcm_remove(struct platform_device *pdev)
278{
279 snd_soc_unregister_platform(&pdev->dev);
280 return 0;
281}
282
283static struct platform_driver mmp_pcm_driver = {
284 .driver = {
285 .name = "mmp-pcm-audio",
286 .owner = THIS_MODULE,
287 },
288
289 .probe = mmp_pcm_probe,
290 .remove = __devexit_p(mmp_pcm_remove),
291};
292
293module_platform_driver(mmp_pcm_driver);
294
295MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
296MODULE_DESCRIPTION("MMP Soc Audio DMA module");
297MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mmp-sspa.c b/sound/soc/pxa/mmp-sspa.c
new file mode 100644
index 00000000000..4d6cb8a30fc
--- /dev/null
+++ b/sound/soc/pxa/mmp-sspa.c
@@ -0,0 +1,480 @@
1/*
2 * linux/sound/soc/pxa/mmp-sspa.c
3 * Base on pxa2xx-ssp.c
4 *
5 * Copyright (C) 2011 Marvell International Ltd.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/delay.h>
26#include <linux/clk.h>
27#include <linux/slab.h>
28#include <linux/pxa2xx_ssp.h>
29#include <linux/io.h>
30#include <sound/core.h>
31#include <sound/pcm.h>
32#include <sound/initval.h>
33#include <sound/pcm_params.h>
34#include <sound/soc.h>
35#include <sound/pxa2xx-lib.h>
36#include "mmp-sspa.h"
37
38/*
39 * SSPA audio private data
40 */
41struct sspa_priv {
42 struct ssp_device *sspa;
43 struct pxa2xx_pcm_dma_params *dma_params;
44 struct clk *audio_clk;
45 struct clk *sysclk;
46 int dai_fmt;
47 int running_cnt;
48};
49
50static void mmp_sspa_write_reg(struct ssp_device *sspa, u32 reg, u32 val)
51{
52 __raw_writel(val, sspa->mmio_base + reg);
53}
54
55static u32 mmp_sspa_read_reg(struct ssp_device *sspa, u32 reg)
56{
57 return __raw_readl(sspa->mmio_base + reg);
58}
59
60static void mmp_sspa_tx_enable(struct ssp_device *sspa)
61{
62 unsigned int sspa_sp;
63
64 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP);
65 sspa_sp |= SSPA_SP_S_EN;
66 sspa_sp |= SSPA_SP_WEN;
67 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
68}
69
70static void mmp_sspa_tx_disable(struct ssp_device *sspa)
71{
72 unsigned int sspa_sp;
73
74 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_TXSP);
75 sspa_sp &= ~SSPA_SP_S_EN;
76 sspa_sp |= SSPA_SP_WEN;
77 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
78}
79
80static void mmp_sspa_rx_enable(struct ssp_device *sspa)
81{
82 unsigned int sspa_sp;
83
84 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP);
85 sspa_sp |= SSPA_SP_S_EN;
86 sspa_sp |= SSPA_SP_WEN;
87 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
88}
89
90static void mmp_sspa_rx_disable(struct ssp_device *sspa)
91{
92 unsigned int sspa_sp;
93
94 sspa_sp = mmp_sspa_read_reg(sspa, SSPA_RXSP);
95 sspa_sp &= ~SSPA_SP_S_EN;
96 sspa_sp |= SSPA_SP_WEN;
97 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
98}
99
100static int mmp_sspa_startup(struct snd_pcm_substream *substream,
101 struct snd_soc_dai *dai)
102{
103 struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai);
104
105 clk_enable(priv->sysclk);
106 clk_enable(priv->sspa->clk);
107
108 return 0;
109}
110
111static void mmp_sspa_shutdown(struct snd_pcm_substream *substream,
112 struct snd_soc_dai *dai)
113{
114 struct sspa_priv *priv = snd_soc_dai_get_drvdata(dai);
115
116 clk_disable(priv->sspa->clk);
117 clk_disable(priv->sysclk);
118
119 return;
120}
121
122/*
123 * Set the SSP ports SYSCLK.
124 */
125static int mmp_sspa_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
126 int clk_id, unsigned int freq, int dir)
127{
128 struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
129 int ret = 0;
130
131 switch (clk_id) {
132 case MMP_SSPA_CLK_AUDIO:
133 ret = clk_set_rate(priv->audio_clk, freq);
134 if (ret)
135 return ret;
136 break;
137 case MMP_SSPA_CLK_PLL:
138 case MMP_SSPA_CLK_VCXO:
139 /* not support yet */
140 return -EINVAL;
141 default:
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148static int mmp_sspa_set_dai_pll(struct snd_soc_dai *cpu_dai, int pll_id,
149 int source, unsigned int freq_in,
150 unsigned int freq_out)
151{
152 struct sspa_priv *priv = snd_soc_dai_get_drvdata(cpu_dai);
153 int ret = 0;
154
155 switch (pll_id) {
156 case MMP_SYSCLK:
157 ret = clk_set_rate(priv->sysclk, freq_out);
158 if (ret)
159 return ret;
160 break;
161 case MMP_SSPA_CLK:
162 ret = clk_set_rate(priv->sspa->clk, freq_out);
163 if (ret)
164 return ret;
165 break;
166 default:
167 return -ENODEV;
168 }
169
170 return 0;
171}
172
173/*
174 * Set up the sspa dai format. The sspa port must be inactive
175 * before calling this function as the physical
176 * interface format is changed.
177 */
178static int mmp_sspa_set_dai_fmt(struct snd_soc_dai *cpu_dai,
179 unsigned int fmt)
180{
181 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(cpu_dai);
182 struct ssp_device *sspa = sspa_priv->sspa;
183 u32 sspa_sp, sspa_ctrl;
184
185 /* check if we need to change anything at all */
186 if (sspa_priv->dai_fmt == fmt)
187 return 0;
188
189 /* we can only change the settings if the port is not in use */
190 if ((mmp_sspa_read_reg(sspa, SSPA_TXSP) & SSPA_SP_S_EN) ||
191 (mmp_sspa_read_reg(sspa, SSPA_RXSP) & SSPA_SP_S_EN)) {
192 dev_err(&sspa->pdev->dev,
193 "can't change hardware dai format: stream is in use\n");
194 return -EINVAL;
195 }
196
197 /* reset port settings */
198 sspa_sp = SSPA_SP_WEN | SSPA_SP_S_RST | SSPA_SP_FFLUSH;
199 sspa_ctrl = 0;
200
201 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
202 case SND_SOC_DAIFMT_CBS_CFS:
203 sspa_sp |= SSPA_SP_MSL;
204 break;
205 case SND_SOC_DAIFMT_CBM_CFM:
206 break;
207 default:
208 return -EINVAL;
209 }
210
211 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
212 case SND_SOC_DAIFMT_NB_NF:
213 sspa_sp |= SSPA_SP_FSP;
214 break;
215 default:
216 return -EINVAL;
217 }
218
219 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
220 case SND_SOC_DAIFMT_I2S:
221 sspa_sp |= SSPA_TXSP_FPER(63);
222 sspa_sp |= SSPA_SP_FWID(31);
223 sspa_ctrl |= SSPA_CTL_XDATDLY(1);
224 break;
225 default:
226 return -EINVAL;
227 }
228
229 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
230 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
231
232 sspa_sp &= ~(SSPA_SP_S_RST | SSPA_SP_FFLUSH);
233 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
234 mmp_sspa_write_reg(sspa, SSPA_RXSP, sspa_sp);
235
236 /*
237 * FIXME: hw issue, for the tx serial port,
238 * can not config the master/slave mode;
239 * so must clean this bit.
240 * The master/slave mode has been set in the
241 * rx port.
242 */
243 sspa_sp &= ~SSPA_SP_MSL;
244 mmp_sspa_write_reg(sspa, SSPA_TXSP, sspa_sp);
245
246 mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
247 mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
248
249 /* Since we are configuring the timings for the format by hand
250 * we have to defer some things until hw_params() where we
251 * know parameters like the sample size.
252 */
253 sspa_priv->dai_fmt = fmt;
254 return 0;
255}
256
257/*
258 * Set the SSPA audio DMA parameters and sample size.
259 * Can be called multiple times by oss emulation.
260 */
261static int mmp_sspa_hw_params(struct snd_pcm_substream *substream,
262 struct snd_pcm_hw_params *params,
263 struct snd_soc_dai *dai)
264{
265 struct snd_soc_pcm_runtime *rtd = substream->private_data;
266 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
267 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
268 struct ssp_device *sspa = sspa_priv->sspa;
269 struct pxa2xx_pcm_dma_params *dma_params;
270 u32 sspa_ctrl;
271
272 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
273 sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_TXCTL);
274 else
275 sspa_ctrl = mmp_sspa_read_reg(sspa, SSPA_RXCTL);
276
277 sspa_ctrl &= ~SSPA_CTL_XFRLEN1_MASK;
278 sspa_ctrl |= SSPA_CTL_XFRLEN1(params_channels(params) - 1);
279 sspa_ctrl &= ~SSPA_CTL_XWDLEN1_MASK;
280 sspa_ctrl |= SSPA_CTL_XWDLEN1(SSPA_CTL_32_BITS);
281 sspa_ctrl &= ~SSPA_CTL_XSSZ1_MASK;
282
283 switch (params_format(params)) {
284 case SNDRV_PCM_FORMAT_S8:
285 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_8_BITS);
286 break;
287 case SNDRV_PCM_FORMAT_S16_LE:
288 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_16_BITS);
289 break;
290 case SNDRV_PCM_FORMAT_S20_3LE:
291 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_20_BITS);
292 break;
293 case SNDRV_PCM_FORMAT_S24_3LE:
294 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_24_BITS);
295 break;
296 case SNDRV_PCM_FORMAT_S32_LE:
297 sspa_ctrl |= SSPA_CTL_XSSZ1(SSPA_CTL_32_BITS);
298 break;
299 default:
300 return -EINVAL;
301 }
302
303 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
304 mmp_sspa_write_reg(sspa, SSPA_TXCTL, sspa_ctrl);
305 mmp_sspa_write_reg(sspa, SSPA_TXFIFO_LL, 0x1);
306 } else {
307 mmp_sspa_write_reg(sspa, SSPA_RXCTL, sspa_ctrl);
308 mmp_sspa_write_reg(sspa, SSPA_RXFIFO_UL, 0x0);
309 }
310
311 dma_params = &sspa_priv->dma_params[substream->stream];
312 dma_params->dev_addr = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
313 (sspa->phys_base + SSPA_TXD) :
314 (sspa->phys_base + SSPA_RXD);
315 snd_soc_dai_set_dma_data(cpu_dai, substream, dma_params);
316 return 0;
317}
318
319static int mmp_sspa_trigger(struct snd_pcm_substream *substream, int cmd,
320 struct snd_soc_dai *dai)
321{
322 struct sspa_priv *sspa_priv = snd_soc_dai_get_drvdata(dai);
323 struct ssp_device *sspa = sspa_priv->sspa;
324 int ret = 0;
325
326 switch (cmd) {
327 case SNDRV_PCM_TRIGGER_START:
328 case SNDRV_PCM_TRIGGER_RESUME:
329 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
330 /*
331 * whatever playback or capture, must enable rx.
332 * this is a hw issue, so need check if rx has been
333 * enabled or not; if has been enabled by another
334 * stream, do not enable again.
335 */
336 if (!sspa_priv->running_cnt)
337 mmp_sspa_rx_enable(sspa);
338
339 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
340 mmp_sspa_tx_enable(sspa);
341
342 sspa_priv->running_cnt++;
343 break;
344
345 case SNDRV_PCM_TRIGGER_STOP:
346 case SNDRV_PCM_TRIGGER_SUSPEND:
347 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
348 sspa_priv->running_cnt--;
349
350 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
351 mmp_sspa_tx_disable(sspa);
352
353 /* have no capture stream, disable rx port */
354 if (!sspa_priv->running_cnt)
355 mmp_sspa_rx_disable(sspa);
356 break;
357
358 default:
359 ret = -EINVAL;
360 }
361
362 return ret;
363}
364
365static int mmp_sspa_probe(struct snd_soc_dai *dai)
366{
367 struct sspa_priv *priv = dev_get_drvdata(dai->dev);
368
369 snd_soc_dai_set_drvdata(dai, priv);
370 return 0;
371
372}
373
374#define MMP_SSPA_RATES SNDRV_PCM_RATE_8000_192000
375#define MMP_SSPA_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
376 SNDRV_PCM_FMTBIT_S16_LE | \
377 SNDRV_PCM_FMTBIT_S24_LE | \
378 SNDRV_PCM_FMTBIT_S24_LE | \
379 SNDRV_PCM_FMTBIT_S32_LE)
380
381static struct snd_soc_dai_ops mmp_sspa_dai_ops = {
382 .startup = mmp_sspa_startup,
383 .shutdown = mmp_sspa_shutdown,
384 .trigger = mmp_sspa_trigger,
385 .hw_params = mmp_sspa_hw_params,
386 .set_sysclk = mmp_sspa_set_dai_sysclk,
387 .set_pll = mmp_sspa_set_dai_pll,
388 .set_fmt = mmp_sspa_set_dai_fmt,
389};
390
391struct snd_soc_dai_driver mmp_sspa_dai = {
392 .probe = mmp_sspa_probe,
393 .playback = {
394 .channels_min = 1,
395 .channels_max = 128,
396 .rates = MMP_SSPA_RATES,
397 .formats = MMP_SSPA_FORMATS,
398 },
399 .capture = {
400 .channels_min = 1,
401 .channels_max = 2,
402 .rates = MMP_SSPA_RATES,
403 .formats = MMP_SSPA_FORMATS,
404 },
405 .ops = &mmp_sspa_dai_ops,
406};
407
408static __devinit int asoc_mmp_sspa_probe(struct platform_device *pdev)
409{
410 struct sspa_priv *priv;
411 struct resource *res;
412
413 priv = devm_kzalloc(&pdev->dev,
414 sizeof(struct sspa_priv), GFP_KERNEL);
415 if (!priv)
416 return -ENOMEM;
417
418 priv->sspa = devm_kzalloc(&pdev->dev,
419 sizeof(struct ssp_device), GFP_KERNEL);
420 if (priv->sspa == NULL)
421 return -ENOMEM;
422
423 priv->dma_params = devm_kzalloc(&pdev->dev,
424 2 * sizeof(struct pxa2xx_pcm_dma_params), GFP_KERNEL);
425 if (priv->dma_params == NULL)
426 return -ENOMEM;
427
428 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
429 if (res == NULL)
430 return -ENOMEM;
431
432 priv->sspa->mmio_base = devm_request_and_ioremap(&pdev->dev, res);
433 if (priv->sspa->mmio_base == NULL)
434 return -ENODEV;
435
436 priv->sspa->clk = devm_clk_get(&pdev->dev, NULL);
437 if (IS_ERR(priv->sspa->clk))
438 return PTR_ERR(priv->sspa->clk);
439
440 priv->audio_clk = clk_get(NULL, "mmp-audio");
441 if (IS_ERR(priv->audio_clk))
442 return PTR_ERR(priv->audio_clk);
443
444 priv->sysclk = clk_get(NULL, "mmp-sysclk");
445 if (IS_ERR(priv->sysclk)) {
446 clk_put(priv->audio_clk);
447 return PTR_ERR(priv->sysclk);
448 }
449 clk_enable(priv->audio_clk);
450 priv->dai_fmt = (unsigned int) -1;
451 platform_set_drvdata(pdev, priv);
452
453 return snd_soc_register_dai(&pdev->dev, &mmp_sspa_dai);
454}
455
456static int __devexit asoc_mmp_sspa_remove(struct platform_device *pdev)
457{
458 struct sspa_priv *priv = platform_get_drvdata(pdev);
459
460 clk_disable(priv->audio_clk);
461 clk_put(priv->audio_clk);
462 clk_put(priv->sysclk);
463 snd_soc_unregister_dai(&pdev->dev);
464 return 0;
465}
466
467static struct platform_driver asoc_mmp_sspa_driver = {
468 .driver = {
469 .name = "mmp-sspa-dai",
470 .owner = THIS_MODULE,
471 },
472 .probe = asoc_mmp_sspa_probe,
473 .remove = __devexit_p(asoc_mmp_sspa_remove),
474};
475
476module_platform_driver(asoc_mmp_sspa_driver);
477
478MODULE_AUTHOR("Leo Yan <leoy@marvell.com>");
479MODULE_DESCRIPTION("MMP SSPA SoC Interface");
480MODULE_LICENSE("GPL");
diff --git a/sound/soc/pxa/mmp-sspa.h b/sound/soc/pxa/mmp-sspa.h
new file mode 100644
index 00000000000..ea365cb9e78
--- /dev/null
+++ b/sound/soc/pxa/mmp-sspa.h
@@ -0,0 +1,92 @@
1/*
2 * linux/sound/soc/pxa/mmp-sspa.h
3 *
4 * Copyright (C) 2011 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21#ifndef _MMP_SSPA_H
22#define _MMP_SSPA_H
23
24/*
25 * SSPA Registers
26 */
27#define SSPA_RXD (0x00)
28#define SSPA_RXID (0x04)
29#define SSPA_RXCTL (0x08)
30#define SSPA_RXSP (0x0c)
31#define SSPA_RXFIFO_UL (0x10)
32#define SSPA_RXINT_MASK (0x14)
33#define SSPA_RXC (0x18)
34#define SSPA_RXFIFO_NOFS (0x1c)
35#define SSPA_RXFIFO_SIZE (0x20)
36
37#define SSPA_TXD (0x80)
38#define SSPA_TXID (0x84)
39#define SSPA_TXCTL (0x88)
40#define SSPA_TXSP (0x8c)
41#define SSPA_TXFIFO_LL (0x90)
42#define SSPA_TXINT_MASK (0x94)
43#define SSPA_TXC (0x98)
44#define SSPA_TXFIFO_NOFS (0x9c)
45#define SSPA_TXFIFO_SIZE (0xa0)
46
47/* SSPA Control Register */
48#define SSPA_CTL_XPH (1 << 31) /* Read Phase */
49#define SSPA_CTL_XFIG (1 << 15) /* Transmit Zeros when FIFO Empty */
50#define SSPA_CTL_JST (1 << 3) /* Audio Sample Justification */
51#define SSPA_CTL_XFRLEN2_MASK (7 << 24)
52#define SSPA_CTL_XFRLEN2(x) ((x) << 24) /* Transmit Frame Length in Phase 2 */
53#define SSPA_CTL_XWDLEN2_MASK (7 << 21)
54#define SSPA_CTL_XWDLEN2(x) ((x) << 21) /* Transmit Word Length in Phase 2 */
55#define SSPA_CTL_XDATDLY(x) ((x) << 19) /* Tansmit Data Delay */
56#define SSPA_CTL_XSSZ2_MASK (7 << 16)
57#define SSPA_CTL_XSSZ2(x) ((x) << 16) /* Transmit Sample Audio Size */
58#define SSPA_CTL_XFRLEN1_MASK (7 << 8)
59#define SSPA_CTL_XFRLEN1(x) ((x) << 8) /* Transmit Frame Length in Phase 1 */
60#define SSPA_CTL_XWDLEN1_MASK (7 << 5)
61#define SSPA_CTL_XWDLEN1(x) ((x) << 5) /* Transmit Word Length in Phase 1 */
62#define SSPA_CTL_XSSZ1_MASK (7 << 0)
63#define SSPA_CTL_XSSZ1(x) ((x) << 0) /* XSSZ1 */
64
65#define SSPA_CTL_8_BITS (0x0) /* Sample Size */
66#define SSPA_CTL_12_BITS (0x1)
67#define SSPA_CTL_16_BITS (0x2)
68#define SSPA_CTL_20_BITS (0x3)
69#define SSPA_CTL_24_BITS (0x4)
70#define SSPA_CTL_32_BITS (0x5)
71
72/* SSPA Serial Port Register */
73#define SSPA_SP_WEN (1 << 31) /* Write Configuration Enable */
74#define SSPA_SP_MSL (1 << 18) /* Master Slave Configuration */
75#define SSPA_SP_CLKP (1 << 17) /* CLKP Polarity Clock Edge Select */
76#define SSPA_SP_FSP (1 << 16) /* FSP Polarity Clock Edge Select */
77#define SSPA_SP_FFLUSH (1 << 2) /* FIFO Flush */
78#define SSPA_SP_S_RST (1 << 1) /* Active High Reset Signal */
79#define SSPA_SP_S_EN (1 << 0) /* Serial Clock Domain Enable */
80#define SSPA_SP_FWID(x) ((x) << 20) /* Frame-Sync Width */
81#define SSPA_TXSP_FPER(x) ((x) << 4) /* Frame-Sync Active */
82
83/* sspa clock sources */
84#define MMP_SSPA_CLK_PLL 0
85#define MMP_SSPA_CLK_VCXO 1
86#define MMP_SSPA_CLK_AUDIO 3
87
88/* sspa pll id */
89#define MMP_SYSCLK 0
90#define MMP_SSPA_CLK 1
91
92#endif /* _MMP_SSPA_H */
diff --git a/sound/soc/pxa/ttc-dkb.c b/sound/soc/pxa/ttc-dkb.c
new file mode 100644
index 00000000000..935491a8a77
--- /dev/null
+++ b/sound/soc/pxa/ttc-dkb.c
@@ -0,0 +1,173 @@
1/*
2 * linux/sound/soc/pxa/ttc_dkb.c
3 *
4 * Copyright (C) 2012 Marvell International Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <sound/core.h>
24#include <sound/pcm.h>
25#include <sound/soc.h>
26#include <sound/jack.h>
27#include <asm/mach-types.h>
28#include <sound/pcm_params.h>
29#include "../codecs/88pm860x-codec.h"
30
31static struct snd_soc_jack hs_jack, mic_jack;
32
33static struct snd_soc_jack_pin hs_jack_pins[] = {
34 { .pin = "Headset Stereophone", .mask = SND_JACK_HEADPHONE, },
35};
36
37static struct snd_soc_jack_pin mic_jack_pins[] = {
38 { .pin = "Headset Mic 2", .mask = SND_JACK_MICROPHONE, },
39};
40
41/* ttc machine dapm widgets */
42static const struct snd_soc_dapm_widget ttc_dapm_widgets[] = {
43 SND_SOC_DAPM_HP("Headset Stereophone", NULL),
44 SND_SOC_DAPM_LINE("Lineout Out 1", NULL),
45 SND_SOC_DAPM_LINE("Lineout Out 2", NULL),
46 SND_SOC_DAPM_SPK("Ext Speaker", NULL),
47 SND_SOC_DAPM_MIC("Ext Mic 1", NULL),
48 SND_SOC_DAPM_MIC("Headset Mic 2", NULL),
49 SND_SOC_DAPM_MIC("Ext Mic 3", NULL),
50};
51
52/* ttc machine audio map */
53static const struct snd_soc_dapm_route ttc_audio_map[] = {
54 {"Headset Stereophone", NULL, "HS1"},
55 {"Headset Stereophone", NULL, "HS2"},
56
57 {"Ext Speaker", NULL, "LSP"},
58 {"Ext Speaker", NULL, "LSN"},
59
60 {"Lineout Out 1", NULL, "LINEOUT1"},
61 {"Lineout Out 2", NULL, "LINEOUT2"},
62
63 {"MIC1P", NULL, "Mic1 Bias"},
64 {"MIC1N", NULL, "Mic1 Bias"},
65 {"Mic1 Bias", NULL, "Ext Mic 1"},
66
67 {"MIC2P", NULL, "Mic1 Bias"},
68 {"MIC2N", NULL, "Mic1 Bias"},
69 {"Mic1 Bias", NULL, "Headset Mic 2"},
70
71 {"MIC3P", NULL, "Mic3 Bias"},
72 {"MIC3N", NULL, "Mic3 Bias"},
73 {"Mic3 Bias", NULL, "Ext Mic 3"},
74};
75
76static int ttc_pm860x_init(struct snd_soc_pcm_runtime *rtd)
77{
78 struct snd_soc_codec *codec = rtd->codec;
79 struct snd_soc_dapm_context *dapm = &codec->dapm;
80
81 /* connected pins */
82 snd_soc_dapm_enable_pin(dapm, "Ext Speaker");
83 snd_soc_dapm_enable_pin(dapm, "Ext Mic 1");
84 snd_soc_dapm_enable_pin(dapm, "Ext Mic 3");
85 snd_soc_dapm_disable_pin(dapm, "Headset Mic 2");
86 snd_soc_dapm_disable_pin(dapm, "Headset Stereophone");
87
88 /* Headset jack detection */
89 snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE
90 | SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2,
91 &hs_jack);
92 snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins),
93 hs_jack_pins);
94 snd_soc_jack_new(codec, "Microphone Jack", SND_JACK_MICROPHONE,
95 &mic_jack);
96 snd_soc_jack_add_pins(&mic_jack, ARRAY_SIZE(mic_jack_pins),
97 mic_jack_pins);
98
99 /* headphone, microphone detection & headset short detection */
100 pm860x_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADPHONE,
101 SND_JACK_BTN_0, SND_JACK_BTN_1, SND_JACK_BTN_2);
102 pm860x_mic_jack_detect(codec, &hs_jack, SND_JACK_MICROPHONE);
103
104 return 0;
105}
106
107/* ttc/td-dkb digital audio interface glue - connects codec <--> CPU */
108static struct snd_soc_dai_link ttc_pm860x_hifi_dai[] = {
109{
110 .name = "88pm860x i2s",
111 .stream_name = "audio playback",
112 .codec_name = "88pm860x-codec",
113 .platform_name = "mmp-pcm-audio",
114 .cpu_dai_name = "pxa-ssp-dai.1",
115 .codec_dai_name = "88pm860x-i2s",
116 .dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
117 SND_SOC_DAIFMT_CBM_CFM,
118 .init = ttc_pm860x_init,
119},
120};
121
122/* ttc/td audio machine driver */
123static struct snd_soc_card ttc_dkb_card = {
124 .name = "ttc-dkb-hifi",
125 .dai_link = ttc_pm860x_hifi_dai,
126 .num_links = ARRAY_SIZE(ttc_pm860x_hifi_dai),
127
128 .dapm_widgets = ttc_dapm_widgets,
129 .num_dapm_widgets = ARRAY_SIZE(ttc_dapm_widgets),
130 .dapm_routes = ttc_audio_map,
131 .num_dapm_routes = ARRAY_SIZE(ttc_audio_map),
132};
133
134static int __devinit ttc_dkb_probe(struct platform_device *pdev)
135{
136 struct snd_soc_card *card = &ttc_dkb_card;
137 int ret;
138
139 card->dev = &pdev->dev;
140
141 ret = snd_soc_register_card(card);
142 if (ret)
143 dev_err(&pdev->dev, "snd_soc_register_card() failed: %d\n",
144 ret);
145
146 return ret;
147}
148
149static int __devexit ttc_dkb_remove(struct platform_device *pdev)
150{
151 struct snd_soc_card *card = platform_get_drvdata(pdev);
152
153 snd_soc_unregister_card(card);
154
155 return 0;
156}
157
158static struct platform_driver ttc_dkb_driver = {
159 .driver = {
160 .name = "ttc-dkb-audio",
161 .owner = THIS_MODULE,
162 },
163 .probe = ttc_dkb_probe,
164 .remove = __devexit_p(ttc_dkb_remove),
165};
166
167module_platform_driver(ttc_dkb_driver);
168
169/* Module information */
170MODULE_AUTHOR("Qiao Zhou, <zhouqiao@marvell.com>");
171MODULE_DESCRIPTION("ALSA SoC TTC DKB");
172MODULE_LICENSE("GPL");
173MODULE_ALIAS("platform:ttc-dkb-audio");
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index ddc6cde14e2..f3ebc38c10f 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -74,7 +74,7 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
74 struct runtime_data *prtd = substream->runtime->private_data; 74 struct runtime_data *prtd = substream->runtime->private_data;
75 dma_addr_t pos = prtd->dma_pos; 75 dma_addr_t pos = prtd->dma_pos;
76 unsigned int limit; 76 unsigned int limit;
77 struct samsung_dma_prep_info dma_info; 77 struct samsung_dma_prep dma_info;
78 78
79 pr_debug("Entered %s\n", __func__); 79 pr_debug("Entered %s\n", __func__);
80 80
@@ -146,7 +146,8 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
146 unsigned long totbytes = params_buffer_bytes(params); 146 unsigned long totbytes = params_buffer_bytes(params);
147 struct s3c_dma_params *dma = 147 struct s3c_dma_params *dma =
148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); 148 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
149 struct samsung_dma_info dma_info; 149 struct samsung_dma_req req;
150 struct samsung_dma_config config;
150 151
151 pr_debug("Entered %s\n", __func__); 152 pr_debug("Entered %s\n", __func__);
152 153
@@ -166,16 +167,17 @@ static int dma_hw_params(struct snd_pcm_substream *substream,
166 167
167 prtd->params->ops = samsung_dma_get_ops(); 168 prtd->params->ops = samsung_dma_get_ops();
168 169
169 dma_info.cap = (samsung_dma_has_circular() ? 170 req.cap = (samsung_dma_has_circular() ?
170 DMA_CYCLIC : DMA_SLAVE); 171 DMA_CYCLIC : DMA_SLAVE);
171 dma_info.client = prtd->params->client; 172 req.client = prtd->params->client;
172 dma_info.direction = 173 config.direction =
173 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK 174 (substream->stream == SNDRV_PCM_STREAM_PLAYBACK
174 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM); 175 ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
175 dma_info.width = prtd->params->dma_size; 176 config.width = prtd->params->dma_size;
176 dma_info.fifo = prtd->params->dma_addr; 177 config.fifo = prtd->params->dma_addr;
177 prtd->params->ch = prtd->params->ops->request( 178 prtd->params->ch = prtd->params->ops->request(
178 prtd->params->channel, &dma_info); 179 prtd->params->channel, &req);
180 prtd->params->ops->config(prtd->params->ch, &config);
179 } 181 }
180 182
181 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); 183 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
diff --git a/sound/soc/samsung/littlemill.c b/sound/soc/samsung/littlemill.c
index c82c646b8a0..ee52c8a0077 100644
--- a/sound/soc/samsung/littlemill.c
+++ b/sound/soc/samsung/littlemill.c
@@ -211,6 +211,11 @@ static int bbclk_ev(struct snd_soc_dapm_widget *w,
211 return 0; 211 return 0;
212} 212}
213 213
214static const struct snd_kcontrol_new controls[] = {
215 SOC_DAPM_PIN_SWITCH("WM1250 Input"),
216 SOC_DAPM_PIN_SWITCH("WM1250 Output"),
217};
218
214static struct snd_soc_dapm_widget widgets[] = { 219static struct snd_soc_dapm_widget widgets[] = {
215 SND_SOC_DAPM_HP("Headphone", NULL), 220 SND_SOC_DAPM_HP("Headphone", NULL),
216 221
@@ -282,6 +287,8 @@ static struct snd_soc_card littlemill = {
282 .set_bias_level = littlemill_set_bias_level, 287 .set_bias_level = littlemill_set_bias_level,
283 .set_bias_level_post = littlemill_set_bias_level_post, 288 .set_bias_level_post = littlemill_set_bias_level_post,
284 289
290 .controls = controls,
291 .num_controls = ARRAY_SIZE(controls),
285 .dapm_widgets = widgets, 292 .dapm_widgets = widgets,
286 .num_dapm_widgets = ARRAY_SIZE(widgets), 293 .num_dapm_widgets = ARRAY_SIZE(widgets),
287 .dapm_routes = audio_paths, 294 .dapm_routes = audio_paths,
diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c
index 79fbeea99d4..ac7701b3c5d 100644
--- a/sound/soc/samsung/s3c2412-i2s.c
+++ b/sound/soc/samsung/s3c2412-i2s.c
@@ -25,7 +25,6 @@
25#include <sound/soc.h> 25#include <sound/soc.h>
26#include <sound/pcm_params.h> 26#include <sound/pcm_params.h>
27 27
28#include <mach/regs-gpio.h>
29#include <mach/dma.h> 28#include <mach/dma.h>
30 29
31#include "dma.h" 30#include "dma.h"
@@ -83,12 +82,9 @@ static int s3c2412_i2s_probe(struct snd_soc_dai *dai)
83 82
84 s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; 83 s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk;
85 84
86 /* Configure the I2S pins in correct mode */ 85 /* Configure the I2S pins (GPE0...GPE4) in correct mode */
87 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); 86 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
88 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); 87 S3C_GPIO_PULL_NONE);
89 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
90 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
91 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
92 88
93 return 0; 89 return 0;
94} 90}
diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c
index c4aa4d412fb..0aae3a3883d 100644
--- a/sound/soc/samsung/s3c24xx-i2s.c
+++ b/sound/soc/samsung/s3c24xx-i2s.c
@@ -23,7 +23,6 @@
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <sound/pcm_params.h> 24#include <sound/pcm_params.h>
25 25
26#include <mach/regs-gpio.h>
27#include <mach/dma.h> 26#include <mach/dma.h>
28#include <plat/regs-iis.h> 27#include <plat/regs-iis.h>
29 28
@@ -391,12 +390,9 @@ static int s3c24xx_i2s_probe(struct snd_soc_dai *dai)
391 } 390 }
392 clk_enable(s3c24xx_i2s.iis_clk); 391 clk_enable(s3c24xx_i2s.iis_clk);
393 392
394 /* Configure the I2S pins in correct mode */ 393 /* Configure the I2S pins (GPE0...GPE4) in correct mode */
395 s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); 394 s3c_gpio_cfgall_range(S3C2410_GPE(0), 5, S3C_GPIO_SFN(2),
396 s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); 395 S3C_GPIO_PULL_NONE);
397 s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK);
398 s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI);
399 s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO);
400 396
401 writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); 397 writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON);
402 398
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c
index 8eb309f23d1..48dd4dd9ee0 100644
--- a/sound/soc/samsung/smdk_wm8994.c
+++ b/sound/soc/samsung/smdk_wm8994.c
@@ -149,31 +149,41 @@ static struct snd_soc_card smdk = {
149 .num_links = ARRAY_SIZE(smdk_dai), 149 .num_links = ARRAY_SIZE(smdk_dai),
150}; 150};
151 151
152static struct platform_device *smdk_snd_device;
153 152
154static int __init smdk_audio_init(void) 153static int __devinit smdk_audio_probe(struct platform_device *pdev)
155{ 154{
156 int ret; 155 int ret;
156 struct snd_soc_card *card = &smdk;
157 157
158 smdk_snd_device = platform_device_alloc("soc-audio", -1); 158 card->dev = &pdev->dev;
159 if (!smdk_snd_device) 159 ret = snd_soc_register_card(card);
160 return -ENOMEM;
161 160
162 platform_set_drvdata(smdk_snd_device, &smdk);
163
164 ret = platform_device_add(smdk_snd_device);
165 if (ret) 161 if (ret)
166 platform_device_put(smdk_snd_device); 162 dev_err(&pdev->dev, "snd_soc_register_card() failed:%d\n", ret);
167 163
168 return ret; 164 return ret;
169} 165}
170module_init(smdk_audio_init);
171 166
172static void __exit smdk_audio_exit(void) 167static int __devexit smdk_audio_remove(struct platform_device *pdev)
173{ 168{
174 platform_device_unregister(smdk_snd_device); 169 struct snd_soc_card *card = platform_get_drvdata(pdev);
170
171 snd_soc_unregister_card(card);
172
173 return 0;
175} 174}
176module_exit(smdk_audio_exit); 175
176static struct platform_driver smdk_audio_driver = {
177 .driver = {
178 .name = "smdk-audio",
179 .owner = THIS_MODULE,
180 },
181 .probe = smdk_audio_probe,
182 .remove = __devexit_p(smdk_audio_remove),
183};
184
185module_platform_driver(smdk_audio_driver);
177 186
178MODULE_DESCRIPTION("ALSA SoC SMDK WM8994"); 187MODULE_DESCRIPTION("ALSA SoC SMDK WM8994");
179MODULE_LICENSE("GPL"); 188MODULE_LICENSE("GPL");
189MODULE_ALIAS("platform:smdk-audio");
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 2ef98536f1d..0540408a9fa 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -247,7 +247,7 @@ struct fsi_priv {
247struct fsi_stream_handler { 247struct 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
574static int fsi_stream_probe(struct fsi_priv *fsi) 574static 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
1187static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io) 1176static 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
@@ -1631,8 +1631,8 @@ static void fsi_handler_init(struct fsi_priv *fsi)
1631 fsi->capture.priv = fsi; 1631 fsi->capture.priv = fsi;
1632 1632
1633 if (fsi->info->tx_id) { 1633 if (fsi->info->tx_id) {
1634 fsi->playback.slave.slave_id = fsi->info->tx_id; 1634 fsi->playback.slave.shdma_slave.slave_id = fsi->info->tx_id;
1635 fsi->playback.handler = &fsi_dma_push_handler; 1635 fsi->playback.handler = &fsi_dma_push_handler;
1636 } 1636 }
1637} 1637}
1638 1638
@@ -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;
diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c
index 5cfcc655e95..488f9becb44 100644
--- a/sound/soc/sh/siu_pcm.c
+++ b/sound/soc/sh/siu_pcm.c
@@ -330,12 +330,9 @@ static bool filter(struct dma_chan *chan, void *slave)
330{ 330{
331 struct sh_dmae_slave *param = slave; 331 struct sh_dmae_slave *param = slave;
332 332
333 pr_debug("%s: slave ID %d\n", __func__, param->slave_id); 333 pr_debug("%s: slave ID %d\n", __func__, param->shdma_slave.slave_id);
334 334
335 if (unlikely(param->dma_dev != chan->device->dev)) 335 chan->private = &param->shdma_slave;
336 return false;
337
338 chan->private = param;
339 return true; 336 return true;
340} 337}
341 338
@@ -360,16 +357,15 @@ static int siu_pcm_open(struct snd_pcm_substream *ss)
360 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { 357 if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) {
361 siu_stream = &port_info->playback; 358 siu_stream = &port_info->playback;
362 param = &siu_stream->param; 359 param = &siu_stream->param;
363 param->slave_id = port ? pdata->dma_slave_tx_b : 360 param->shdma_slave.slave_id = port ? pdata->dma_slave_tx_b :
364 pdata->dma_slave_tx_a; 361 pdata->dma_slave_tx_a;
365 } else { 362 } else {
366 siu_stream = &port_info->capture; 363 siu_stream = &port_info->capture;
367 param = &siu_stream->param; 364 param = &siu_stream->param;
368 param->slave_id = port ? pdata->dma_slave_rx_b : 365 param->shdma_slave.slave_id = port ? pdata->dma_slave_rx_b :
369 pdata->dma_slave_rx_a; 366 pdata->dma_slave_rx_a;
370 } 367 }
371 368
372 param->dma_dev = pdata->dma_dev;
373 /* Get DMA channel */ 369 /* Get DMA channel */
374 siu_stream->chan = dma_request_channel(mask, filter, param); 370 siu_stream->chan = dma_request_channel(mask, filter, param);
375 if (!siu_stream->chan) { 371 if (!siu_stream->chan) {
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b37ee8077ed..f219b2f7ee6 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -812,13 +812,15 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
812 812
813 /* Find CPU DAI from registered DAIs*/ 813 /* Find CPU DAI from registered DAIs*/
814 list_for_each_entry(cpu_dai, &dai_list, list) { 814 list_for_each_entry(cpu_dai, &dai_list, list) {
815 if (dai_link->cpu_dai_of_node) { 815 if (dai_link->cpu_of_node &&
816 if (cpu_dai->dev->of_node != dai_link->cpu_dai_of_node) 816 (cpu_dai->dev->of_node != dai_link->cpu_of_node))
817 continue; 817 continue;
818 } else { 818 if (dai_link->cpu_name &&
819 if (strcmp(cpu_dai->name, dai_link->cpu_dai_name)) 819 strcmp(dev_name(cpu_dai->dev), dai_link->cpu_name))
820 continue; 820 continue;
821 } 821 if (dai_link->cpu_dai_name &&
822 strcmp(cpu_dai->name, dai_link->cpu_dai_name))
823 continue;
822 824
823 rtd->cpu_dai = cpu_dai; 825 rtd->cpu_dai = cpu_dai;
824 } 826 }
@@ -896,6 +898,28 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num)
896 return 0; 898 return 0;
897} 899}
898 900
901static int soc_remove_platform(struct snd_soc_platform *platform)
902{
903 int ret;
904
905 if (platform->driver->remove) {
906 ret = platform->driver->remove(platform);
907 if (ret < 0)
908 pr_err("asoc: failed to remove %s: %d\n",
909 platform->name, ret);
910 }
911
912 /* Make sure all DAPM widgets are freed */
913 snd_soc_dapm_free(&platform->dapm);
914
915 soc_cleanup_platform_debugfs(platform);
916 platform->probed = 0;
917 list_del(&platform->card_list);
918 module_put(platform->dev->driver->owner);
919
920 return 0;
921}
922
899static void soc_remove_codec(struct snd_soc_codec *codec) 923static void soc_remove_codec(struct snd_soc_codec *codec)
900{ 924{
901 int err; 925 int err;
@@ -917,11 +941,9 @@ static void soc_remove_codec(struct snd_soc_codec *codec)
917 module_put(codec->dev->driver->owner); 941 module_put(codec->dev->driver->owner);
918} 942}
919 943
920static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order) 944static void soc_remove_link_dais(struct snd_soc_card *card, int num, int order)
921{ 945{
922 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 946 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
923 struct snd_soc_codec *codec = rtd->codec;
924 struct snd_soc_platform *platform = rtd->platform;
925 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; 947 struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai;
926 int err; 948 int err;
927 949
@@ -946,30 +968,6 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
946 list_del(&codec_dai->card_list); 968 list_del(&codec_dai->card_list);
947 } 969 }
948 970
949 /* remove the platform */
950 if (platform && platform->probed &&
951 platform->driver->remove_order == order) {
952 if (platform->driver->remove) {
953 err = platform->driver->remove(platform);
954 if (err < 0)
955 pr_err("asoc: failed to remove %s: %d\n",
956 platform->name, err);
957 }
958
959 /* Make sure all DAPM widgets are freed */
960 snd_soc_dapm_free(&platform->dapm);
961
962 soc_cleanup_platform_debugfs(platform);
963 platform->probed = 0;
964 list_del(&platform->card_list);
965 module_put(platform->dev->driver->owner);
966 }
967
968 /* remove the CODEC */
969 if (codec && codec->probed &&
970 codec->driver->remove_order == order)
971 soc_remove_codec(codec);
972
973 /* remove the cpu_dai */ 971 /* remove the cpu_dai */
974 if (cpu_dai && cpu_dai->probed && 972 if (cpu_dai && cpu_dai->probed &&
975 cpu_dai->driver->remove_order == order) { 973 cpu_dai->driver->remove_order == order) {
@@ -981,7 +979,43 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num, int order)
981 } 979 }
982 cpu_dai->probed = 0; 980 cpu_dai->probed = 0;
983 list_del(&cpu_dai->card_list); 981 list_del(&cpu_dai->card_list);
984 module_put(cpu_dai->dev->driver->owner); 982
983 if (!cpu_dai->codec) {
984 snd_soc_dapm_free(&cpu_dai->dapm);
985 module_put(cpu_dai->dev->driver->owner);
986 }
987 }
988}
989
990static void soc_remove_link_components(struct snd_soc_card *card, int num,
991 int order)
992{
993 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
994 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
995 struct snd_soc_dai *codec_dai = rtd->codec_dai;
996 struct snd_soc_platform *platform = rtd->platform;
997 struct snd_soc_codec *codec;
998
999 /* remove the platform */
1000 if (platform && platform->probed &&
1001 platform->driver->remove_order == order) {
1002 soc_remove_platform(platform);
1003 }
1004
1005 /* remove the CODEC-side CODEC */
1006 if (codec_dai) {
1007 codec = codec_dai->codec;
1008 if (codec && codec->probed &&
1009 codec->driver->remove_order == order)
1010 soc_remove_codec(codec);
1011 }
1012
1013 /* remove any CPU-side CODEC */
1014 if (cpu_dai) {
1015 codec = cpu_dai->codec;
1016 if (codec && codec->probed &&
1017 codec->driver->remove_order == order)
1018 soc_remove_codec(codec);
985 } 1019 }
986} 1020}
987 1021
@@ -992,8 +1026,15 @@ static void soc_remove_dai_links(struct snd_soc_card *card)
992 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1026 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
993 order++) { 1027 order++) {
994 for (dai = 0; dai < card->num_rtd; dai++) 1028 for (dai = 0; dai < card->num_rtd; dai++)
995 soc_remove_dai_link(card, dai, order); 1029 soc_remove_link_dais(card, dai, order);
996 } 1030 }
1031
1032 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1033 order++) {
1034 for (dai = 0; dai < card->num_rtd; dai++)
1035 soc_remove_link_components(card, dai, order);
1036 }
1037
997 card->num_rtd = 0; 1038 card->num_rtd = 0;
998} 1039}
999 1040
@@ -1054,6 +1095,10 @@ static int soc_probe_codec(struct snd_soc_card *card,
1054 } 1095 }
1055 } 1096 }
1056 1097
1098 /* If the driver didn't set I/O up try regmap */
1099 if (!codec->control_data)
1100 snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP);
1101
1057 if (driver->controls) 1102 if (driver->controls)
1058 snd_soc_add_codec_controls(codec, driver->controls, 1103 snd_soc_add_codec_controls(codec, driver->controls,
1059 driver->num_controls); 1104 driver->num_controls);
@@ -1230,7 +1275,44 @@ out:
1230 return 0; 1275 return 0;
1231} 1276}
1232 1277
1233static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order) 1278static int soc_probe_link_components(struct snd_soc_card *card, int num,
1279 int order)
1280{
1281 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
1282 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
1283 struct snd_soc_dai *codec_dai = rtd->codec_dai;
1284 struct snd_soc_platform *platform = rtd->platform;
1285 int ret;
1286
1287 /* probe the CPU-side component, if it is a CODEC */
1288 if (cpu_dai->codec &&
1289 !cpu_dai->codec->probed &&
1290 cpu_dai->codec->driver->probe_order == order) {
1291 ret = soc_probe_codec(card, cpu_dai->codec);
1292 if (ret < 0)
1293 return ret;
1294 }
1295
1296 /* probe the CODEC-side component */
1297 if (!codec_dai->codec->probed &&
1298 codec_dai->codec->driver->probe_order == order) {
1299 ret = soc_probe_codec(card, codec_dai->codec);
1300 if (ret < 0)
1301 return ret;
1302 }
1303
1304 /* probe the platform */
1305 if (!platform->probed &&
1306 platform->driver->probe_order == order) {
1307 ret = soc_probe_platform(card, platform);
1308 if (ret < 0)
1309 return ret;
1310 }
1311
1312 return 0;
1313}
1314
1315static int soc_probe_link_dais(struct snd_soc_card *card, int num, int order)
1234{ 1316{
1235 struct snd_soc_dai_link *dai_link = &card->dai_link[num]; 1317 struct snd_soc_dai_link *dai_link = &card->dai_link[num];
1236 struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; 1318 struct snd_soc_pcm_runtime *rtd = &card->rtd[num];
@@ -1255,11 +1337,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1255 /* probe the cpu_dai */ 1337 /* probe the cpu_dai */
1256 if (!cpu_dai->probed && 1338 if (!cpu_dai->probed &&
1257 cpu_dai->driver->probe_order == order) { 1339 cpu_dai->driver->probe_order == order) {
1258 cpu_dai->dapm.card = card; 1340 if (!cpu_dai->codec) {
1259 if (!try_module_get(cpu_dai->dev->driver->owner)) 1341 cpu_dai->dapm.card = card;
1260 return -ENODEV; 1342 if (!try_module_get(cpu_dai->dev->driver->owner))
1343 return -ENODEV;
1261 1344
1262 snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai); 1345 list_add(&cpu_dai->dapm.list, &card->dapm_list);
1346 snd_soc_dapm_new_dai_widgets(&cpu_dai->dapm, cpu_dai);
1347 }
1263 1348
1264 if (cpu_dai->driver->probe) { 1349 if (cpu_dai->driver->probe) {
1265 ret = cpu_dai->driver->probe(cpu_dai); 1350 ret = cpu_dai->driver->probe(cpu_dai);
@@ -1275,22 +1360,6 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num, int order)
1275 list_add(&cpu_dai->card_list, &card->dai_dev_list); 1360 list_add(&cpu_dai->card_list, &card->dai_dev_list);
1276 } 1361 }
1277 1362
1278 /* probe the CODEC */
1279 if (!codec->probed &&
1280 codec->driver->probe_order == order) {
1281 ret = soc_probe_codec(card, codec);
1282 if (ret < 0)
1283 return ret;
1284 }
1285
1286 /* probe the platform */
1287 if (!platform->probed &&
1288 platform->driver->probe_order == order) {
1289 ret = soc_probe_platform(card, platform);
1290 if (ret < 0)
1291 return ret;
1292 }
1293
1294 /* probe the CODEC DAI */ 1363 /* probe the CODEC DAI */
1295 if (!codec_dai->probed && codec_dai->driver->probe_order == order) { 1364 if (!codec_dai->probed && codec_dai->driver->probe_order == order) {
1296 if (codec_dai->driver->probe) { 1365 if (codec_dai->driver->probe) {
@@ -1565,14 +1634,27 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1565 goto card_probe_error; 1634 goto card_probe_error;
1566 } 1635 }
1567 1636
1568 /* early DAI link probe */ 1637 /* probe all components used by DAI links on this card */
1569 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST; 1638 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1570 order++) { 1639 order++) {
1571 for (i = 0; i < card->num_links; i++) { 1640 for (i = 0; i < card->num_links; i++) {
1572 ret = soc_probe_dai_link(card, i, order); 1641 ret = soc_probe_link_components(card, i, order);
1573 if (ret < 0) { 1642 if (ret < 0) {
1574 pr_err("asoc: failed to instantiate card %s: %d\n", 1643 pr_err("asoc: failed to instantiate card %s: %d\n",
1575 card->name, ret); 1644 card->name, ret);
1645 goto probe_dai_err;
1646 }
1647 }
1648 }
1649
1650 /* probe all DAI links on this card */
1651 for (order = SND_SOC_COMP_ORDER_FIRST; order <= SND_SOC_COMP_ORDER_LAST;
1652 order++) {
1653 for (i = 0; i < card->num_links; i++) {
1654 ret = soc_probe_link_dais(card, i, order);
1655 if (ret < 0) {
1656 pr_err("asoc: failed to instantiate card %s: %d\n",
1657 card->name, ret);
1576 goto probe_dai_err; 1658 goto probe_dai_err;
1577 } 1659 }
1578 } 1660 }
@@ -2790,6 +2872,104 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
2790EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8); 2872EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);
2791 2873
2792/** 2874/**
2875 * snd_soc_info_volsw_range - single mixer info callback with range.
2876 * @kcontrol: mixer control
2877 * @uinfo: control element information
2878 *
2879 * Callback to provide information, within a range, about a single
2880 * mixer control.
2881 *
2882 * returns 0 for success.
2883 */
2884int snd_soc_info_volsw_range(struct snd_kcontrol *kcontrol,
2885 struct snd_ctl_elem_info *uinfo)
2886{
2887 struct soc_mixer_control *mc =
2888 (struct soc_mixer_control *)kcontrol->private_value;
2889 int platform_max;
2890 int min = mc->min;
2891
2892 if (!mc->platform_max)
2893 mc->platform_max = mc->max;
2894 platform_max = mc->platform_max;
2895
2896 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
2897 uinfo->count = 1;
2898 uinfo->value.integer.min = 0;
2899 uinfo->value.integer.max = platform_max - min;
2900
2901 return 0;
2902}
2903EXPORT_SYMBOL_GPL(snd_soc_info_volsw_range);
2904
2905/**
2906 * snd_soc_put_volsw_range - single mixer put value callback with range.
2907 * @kcontrol: mixer control
2908 * @ucontrol: control element information
2909 *
2910 * Callback to set the value, within a range, for a single mixer control.
2911 *
2912 * Returns 0 for success.
2913 */
2914int snd_soc_put_volsw_range(struct snd_kcontrol *kcontrol,
2915 struct snd_ctl_elem_value *ucontrol)
2916{
2917 struct soc_mixer_control *mc =
2918 (struct soc_mixer_control *)kcontrol->private_value;
2919 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2920 unsigned int reg = mc->reg;
2921 unsigned int shift = mc->shift;
2922 int min = mc->min;
2923 int max = mc->max;
2924 unsigned int mask = (1 << fls(max)) - 1;
2925 unsigned int invert = mc->invert;
2926 unsigned int val, val_mask;
2927
2928 val = ((ucontrol->value.integer.value[0] + min) & mask);
2929 if (invert)
2930 val = max - val;
2931 val_mask = mask << shift;
2932 val = val << shift;
2933
2934 return snd_soc_update_bits_locked(codec, reg, val_mask, val);
2935}
2936EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range);
2937
2938/**
2939 * snd_soc_get_volsw_range - single mixer get callback with range
2940 * @kcontrol: mixer control
2941 * @ucontrol: control element information
2942 *
2943 * Callback to get the value, within a range, of a single mixer control.
2944 *
2945 * Returns 0 for success.
2946 */
2947int snd_soc_get_volsw_range(struct snd_kcontrol *kcontrol,
2948 struct snd_ctl_elem_value *ucontrol)
2949{
2950 struct soc_mixer_control *mc =
2951 (struct soc_mixer_control *)kcontrol->private_value;
2952 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
2953 unsigned int reg = mc->reg;
2954 unsigned int shift = mc->shift;
2955 int min = mc->min;
2956 int max = mc->max;
2957 unsigned int mask = (1 << fls(max)) - 1;
2958 unsigned int invert = mc->invert;
2959
2960 ucontrol->value.integer.value[0] =
2961 (snd_soc_read(codec, reg) >> shift) & mask;
2962 if (invert)
2963 ucontrol->value.integer.value[0] =
2964 max - ucontrol->value.integer.value[0];
2965 ucontrol->value.integer.value[0] =
2966 ucontrol->value.integer.value[0] - min;
2967
2968 return 0;
2969}
2970EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range);
2971
2972/**
2793 * snd_soc_limit_volume - Set new limit to an existing volume control. 2973 * snd_soc_limit_volume - Set new limit to an existing volume control.
2794 * 2974 *
2795 * @codec: where to look for the control 2975 * @codec: where to look for the control
@@ -3346,6 +3526,12 @@ int snd_soc_register_card(struct snd_soc_card *card)
3346 link->name); 3526 link->name);
3347 return -EINVAL; 3527 return -EINVAL;
3348 } 3528 }
3529 /* Codec DAI name must be specified */
3530 if (!link->codec_dai_name) {
3531 dev_err(card->dev, "codec_dai_name not set for %s\n",
3532 link->name);
3533 return -EINVAL;
3534 }
3349 3535
3350 /* 3536 /*
3351 * Platform may be specified by either name or OF node, but 3537 * Platform may be specified by either name or OF node, but
@@ -3358,12 +3544,24 @@ int snd_soc_register_card(struct snd_soc_card *card)
3358 } 3544 }
3359 3545
3360 /* 3546 /*
3361 * CPU DAI must be specified by 1 of name or OF node, 3547 * CPU device may be specified by either name or OF node, but
3362 * not both or neither. 3548 * can be left unspecified, and will be matched based on DAI
3549 * name alone..
3550 */
3551 if (link->cpu_name && link->cpu_of_node) {
3552 dev_err(card->dev,
3553 "Neither/both cpu name/of_node are set for %s\n",
3554 link->name);
3555 return -EINVAL;
3556 }
3557 /*
3558 * At least one of CPU DAI name or CPU device name/node must be
3559 * specified
3363 */ 3560 */
3364 if (!!link->cpu_dai_name == !!link->cpu_dai_of_node) { 3561 if (!link->cpu_dai_name &&
3562 !(link->cpu_name || link->cpu_of_node)) {
3365 dev_err(card->dev, 3563 dev_err(card->dev,
3366 "Neither/both cpu_dai name/of_node are set for %s\n", 3564 "Neither cpu_dai_name nor cpu_name/of_node are set for %s\n",
3367 link->name); 3565 link->name);
3368 return -EINVAL; 3566 return -EINVAL;
3369 } 3567 }
@@ -3938,6 +4136,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
3938 dev_err(card->dev, 4136 dev_err(card->dev,
3939 "Property '%s' index %d could not be read: %d\n", 4137 "Property '%s' index %d could not be read: %d\n",
3940 propname, 2 * i, ret); 4138 propname, 2 * i, ret);
4139 kfree(routes);
3941 return -EINVAL; 4140 return -EINVAL;
3942 } 4141 }
3943 ret = of_property_read_string_index(np, propname, 4142 ret = of_property_read_string_index(np, propname,
@@ -3946,6 +4145,7 @@ int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
3946 dev_err(card->dev, 4145 dev_err(card->dev,
3947 "Property '%s' index %d could not be read: %d\n", 4146 "Property '%s' index %d could not be read: %d\n",
3948 propname, (2 * i) + 1, ret); 4147 propname, (2 * i) + 1, ret);
4148 kfree(routes);
3949 return -EINVAL; 4149 return -EINVAL;
3950 } 4150 }
3951 } 4151 }
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index 89eae93445c..4d181df95dc 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -35,6 +35,7 @@
35#include <linux/debugfs.h> 35#include <linux/debugfs.h>
36#include <linux/pm_runtime.h> 36#include <linux/pm_runtime.h>
37#include <linux/regulator/consumer.h> 37#include <linux/regulator/consumer.h>
38#include <linux/clk.h>
38#include <linux/slab.h> 39#include <linux/slab.h>
39#include <sound/core.h> 40#include <sound/core.h>
40#include <sound/pcm.h> 41#include <sound/pcm.h>
@@ -51,6 +52,7 @@ static int dapm_up_seq[] = {
51 [snd_soc_dapm_pre] = 0, 52 [snd_soc_dapm_pre] = 0,
52 [snd_soc_dapm_supply] = 1, 53 [snd_soc_dapm_supply] = 1,
53 [snd_soc_dapm_regulator_supply] = 1, 54 [snd_soc_dapm_regulator_supply] = 1,
55 [snd_soc_dapm_clock_supply] = 1,
54 [snd_soc_dapm_micbias] = 2, 56 [snd_soc_dapm_micbias] = 2,
55 [snd_soc_dapm_dai_link] = 2, 57 [snd_soc_dapm_dai_link] = 2,
56 [snd_soc_dapm_dai] = 3, 58 [snd_soc_dapm_dai] = 3,
@@ -92,6 +94,7 @@ static int dapm_down_seq[] = {
92 [snd_soc_dapm_aif_out] = 10, 94 [snd_soc_dapm_aif_out] = 10,
93 [snd_soc_dapm_dai] = 10, 95 [snd_soc_dapm_dai] = 10,
94 [snd_soc_dapm_dai_link] = 11, 96 [snd_soc_dapm_dai_link] = 11,
97 [snd_soc_dapm_clock_supply] = 12,
95 [snd_soc_dapm_regulator_supply] = 12, 98 [snd_soc_dapm_regulator_supply] = 12,
96 [snd_soc_dapm_supply] = 12, 99 [snd_soc_dapm_supply] = 12,
97 [snd_soc_dapm_post] = 13, 100 [snd_soc_dapm_post] = 13,
@@ -288,9 +291,9 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_dapm_context *dapm,
288 if (dapm->codec->driver->set_bias_level) 291 if (dapm->codec->driver->set_bias_level)
289 ret = dapm->codec->driver->set_bias_level(dapm->codec, 292 ret = dapm->codec->driver->set_bias_level(dapm->codec,
290 level); 293 level);
291 else 294 } else
292 dapm->bias_level = level; 295 dapm->bias_level = level;
293 } 296
294 if (ret != 0) 297 if (ret != 0)
295 goto out; 298 goto out;
296 299
@@ -321,11 +324,10 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
321 324
322 val = soc_widget_read(w, reg); 325 val = soc_widget_read(w, reg);
323 val = (val >> shift) & mask; 326 val = (val >> shift) & mask;
327 if (invert)
328 val = max - val;
324 329
325 if ((invert && !val) || (!invert && val)) 330 p->connect = !!val;
326 p->connect = 1;
327 else
328 p->connect = 0;
329 } 331 }
330 break; 332 break;
331 case snd_soc_dapm_mux: { 333 case snd_soc_dapm_mux: {
@@ -391,6 +393,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
391 case snd_soc_dapm_vmid: 393 case snd_soc_dapm_vmid:
392 case snd_soc_dapm_supply: 394 case snd_soc_dapm_supply:
393 case snd_soc_dapm_regulator_supply: 395 case snd_soc_dapm_regulator_supply:
396 case snd_soc_dapm_clock_supply:
394 case snd_soc_dapm_aif_in: 397 case snd_soc_dapm_aif_in:
395 case snd_soc_dapm_aif_out: 398 case snd_soc_dapm_aif_out:
396 case snd_soc_dapm_dai: 399 case snd_soc_dapm_dai:
@@ -764,6 +767,7 @@ static int is_connected_output_ep(struct snd_soc_dapm_widget *widget,
764 switch (widget->id) { 767 switch (widget->id) {
765 case snd_soc_dapm_supply: 768 case snd_soc_dapm_supply:
766 case snd_soc_dapm_regulator_supply: 769 case snd_soc_dapm_regulator_supply:
770 case snd_soc_dapm_clock_supply:
767 return 0; 771 return 0;
768 default: 772 default:
769 break; 773 break;
@@ -850,6 +854,7 @@ static int is_connected_input_ep(struct snd_soc_dapm_widget *widget,
850 switch (widget->id) { 854 switch (widget->id) {
851 case snd_soc_dapm_supply: 855 case snd_soc_dapm_supply:
852 case snd_soc_dapm_regulator_supply: 856 case snd_soc_dapm_regulator_supply:
857 case snd_soc_dapm_clock_supply:
853 return 0; 858 return 0;
854 default: 859 default:
855 break; 860 break;
@@ -996,6 +1001,27 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w,
996} 1001}
997EXPORT_SYMBOL_GPL(dapm_regulator_event); 1002EXPORT_SYMBOL_GPL(dapm_regulator_event);
998 1003
1004/*
1005 * Handler for clock supply widget.
1006 */
1007int dapm_clock_event(struct snd_soc_dapm_widget *w,
1008 struct snd_kcontrol *kcontrol, int event)
1009{
1010 if (!w->clk)
1011 return -EIO;
1012
1013#ifdef CONFIG_HAVE_CLK
1014 if (SND_SOC_DAPM_EVENT_ON(event)) {
1015 return clk_enable(w->clk);
1016 } else {
1017 clk_disable(w->clk);
1018 return 0;
1019 }
1020#endif
1021 return 0;
1022}
1023EXPORT_SYMBOL_GPL(dapm_clock_event);
1024
999static int dapm_widget_power_check(struct snd_soc_dapm_widget *w) 1025static int dapm_widget_power_check(struct snd_soc_dapm_widget *w)
1000{ 1026{
1001 if (w->power_checked) 1027 if (w->power_checked)
@@ -1487,6 +1513,7 @@ static void dapm_widget_set_power(struct snd_soc_dapm_widget *w, bool power,
1487 switch (w->id) { 1513 switch (w->id) {
1488 case snd_soc_dapm_supply: 1514 case snd_soc_dapm_supply:
1489 case snd_soc_dapm_regulator_supply: 1515 case snd_soc_dapm_regulator_supply:
1516 case snd_soc_dapm_clock_supply:
1490 /* Supplies can't affect their outputs, only their inputs */ 1517 /* Supplies can't affect their outputs, only their inputs */
1491 break; 1518 break;
1492 default: 1519 default:
@@ -1570,7 +1597,15 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1570 } 1597 }
1571 1598
1572 list_for_each_entry(w, &card->widgets, list) { 1599 list_for_each_entry(w, &card->widgets, list) {
1573 list_del_init(&w->dirty); 1600 switch (w->id) {
1601 case snd_soc_dapm_pre:
1602 case snd_soc_dapm_post:
1603 /* These widgets always need to be powered */
1604 break;
1605 default:
1606 list_del_init(&w->dirty);
1607 break;
1608 }
1574 1609
1575 if (w->power) { 1610 if (w->power) {
1576 d = w->dapm; 1611 d = w->dapm;
@@ -1587,6 +1622,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event)
1587 break; 1622 break;
1588 case snd_soc_dapm_supply: 1623 case snd_soc_dapm_supply:
1589 case snd_soc_dapm_regulator_supply: 1624 case snd_soc_dapm_regulator_supply:
1625 case snd_soc_dapm_clock_supply:
1590 case snd_soc_dapm_micbias: 1626 case snd_soc_dapm_micbias:
1591 if (d->target_bias_level < SND_SOC_BIAS_STANDBY) 1627 if (d->target_bias_level < SND_SOC_BIAS_STANDBY)
1592 d->target_bias_level = SND_SOC_BIAS_STANDBY; 1628 d->target_bias_level = SND_SOC_BIAS_STANDBY;
@@ -1941,6 +1977,7 @@ static ssize_t dapm_widget_show(struct device *dev,
1941 case snd_soc_dapm_mixer_named_ctl: 1977 case snd_soc_dapm_mixer_named_ctl:
1942 case snd_soc_dapm_supply: 1978 case snd_soc_dapm_supply:
1943 case snd_soc_dapm_regulator_supply: 1979 case snd_soc_dapm_regulator_supply:
1980 case snd_soc_dapm_clock_supply:
1944 if (w->name) 1981 if (w->name)
1945 count += sprintf(buf + count, "%s: %s\n", 1982 count += sprintf(buf + count, "%s: %s\n",
1946 w->name, w->power ? "On":"Off"); 1983 w->name, w->power ? "On":"Off");
@@ -2187,6 +2224,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2187 case snd_soc_dapm_post: 2224 case snd_soc_dapm_post:
2188 case snd_soc_dapm_supply: 2225 case snd_soc_dapm_supply:
2189 case snd_soc_dapm_regulator_supply: 2226 case snd_soc_dapm_regulator_supply:
2227 case snd_soc_dapm_clock_supply:
2190 case snd_soc_dapm_aif_in: 2228 case snd_soc_dapm_aif_in:
2191 case snd_soc_dapm_aif_out: 2229 case snd_soc_dapm_aif_out:
2192 case snd_soc_dapm_dai: 2230 case snd_soc_dapm_dai:
@@ -2221,6 +2259,10 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm,
2221 path->connect = 0; 2259 path->connect = 0;
2222 return 0; 2260 return 0;
2223 } 2261 }
2262
2263 dapm_mark_dirty(wsource, "Route added");
2264 dapm_mark_dirty(wsink, "Route added");
2265
2224 return 0; 2266 return 0;
2225 2267
2226err: 2268err:
@@ -2230,6 +2272,59 @@ err:
2230 return ret; 2272 return ret;
2231} 2273}
2232 2274
2275static int snd_soc_dapm_del_route(struct snd_soc_dapm_context *dapm,
2276 const struct snd_soc_dapm_route *route)
2277{
2278 struct snd_soc_dapm_path *path, *p;
2279 const char *sink;
2280 const char *source;
2281 char prefixed_sink[80];
2282 char prefixed_source[80];
2283
2284 if (route->control) {
2285 dev_err(dapm->dev,
2286 "Removal of routes with controls not supported\n");
2287 return -EINVAL;
2288 }
2289
2290 if (dapm->codec && dapm->codec->name_prefix) {
2291 snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s",
2292 dapm->codec->name_prefix, route->sink);
2293 sink = prefixed_sink;
2294 snprintf(prefixed_source, sizeof(prefixed_source), "%s %s",
2295 dapm->codec->name_prefix, route->source);
2296 source = prefixed_source;
2297 } else {
2298 sink = route->sink;
2299 source = route->source;
2300 }
2301
2302 path = NULL;
2303 list_for_each_entry(p, &dapm->card->paths, list) {
2304 if (strcmp(p->source->name, source) != 0)
2305 continue;
2306 if (strcmp(p->sink->name, sink) != 0)
2307 continue;
2308 path = p;
2309 break;
2310 }
2311
2312 if (path) {
2313 dapm_mark_dirty(path->source, "Route removed");
2314 dapm_mark_dirty(path->sink, "Route removed");
2315
2316 list_del(&path->list);
2317 list_del(&path->list_sink);
2318 list_del(&path->list_source);
2319 kfree(path);
2320 } else {
2321 dev_warn(dapm->dev, "Route %s->%s does not exist\n",
2322 source, sink);
2323 }
2324
2325 return 0;
2326}
2327
2233/** 2328/**
2234 * snd_soc_dapm_add_routes - Add routes between DAPM widgets 2329 * snd_soc_dapm_add_routes - Add routes between DAPM widgets
2235 * @dapm: DAPM context 2330 * @dapm: DAPM context
@@ -2246,15 +2341,15 @@ err:
2246int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 2341int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2247 const struct snd_soc_dapm_route *route, int num) 2342 const struct snd_soc_dapm_route *route, int num)
2248{ 2343{
2249 int i, ret = 0; 2344 int i, r, ret = 0;
2250 2345
2251 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT); 2346 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2252 for (i = 0; i < num; i++) { 2347 for (i = 0; i < num; i++) {
2253 ret = snd_soc_dapm_add_route(dapm, route); 2348 r = snd_soc_dapm_add_route(dapm, route);
2254 if (ret < 0) { 2349 if (r < 0) {
2255 dev_err(dapm->dev, "Failed to add route %s->%s\n", 2350 dev_err(dapm->dev, "Failed to add route %s->%s\n",
2256 route->source, route->sink); 2351 route->source, route->sink);
2257 break; 2352 ret = r;
2258 } 2353 }
2259 route++; 2354 route++;
2260 } 2355 }
@@ -2264,6 +2359,30 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm,
2264} 2359}
2265EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); 2360EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes);
2266 2361
2362/**
2363 * snd_soc_dapm_del_routes - Remove routes between DAPM widgets
2364 * @dapm: DAPM context
2365 * @route: audio routes
2366 * @num: number of routes
2367 *
2368 * Removes routes from the DAPM context.
2369 */
2370int snd_soc_dapm_del_routes(struct snd_soc_dapm_context *dapm,
2371 const struct snd_soc_dapm_route *route, int num)
2372{
2373 int i, ret = 0;
2374
2375 mutex_lock_nested(&dapm->card->dapm_mutex, SND_SOC_DAPM_CLASS_INIT);
2376 for (i = 0; i < num; i++) {
2377 snd_soc_dapm_del_route(dapm, route);
2378 route++;
2379 }
2380 mutex_unlock(&dapm->card->dapm_mutex);
2381
2382 return ret;
2383}
2384EXPORT_SYMBOL_GPL(snd_soc_dapm_del_routes);
2385
2267static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm, 2386static int snd_soc_dapm_weak_route(struct snd_soc_dapm_context *dapm,
2268 const struct snd_soc_dapm_route *route) 2387 const struct snd_soc_dapm_route *route)
2269{ 2388{
@@ -2434,23 +2553,20 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
2434 (struct soc_mixer_control *)kcontrol->private_value; 2553 (struct soc_mixer_control *)kcontrol->private_value;
2435 unsigned int reg = mc->reg; 2554 unsigned int reg = mc->reg;
2436 unsigned int shift = mc->shift; 2555 unsigned int shift = mc->shift;
2437 unsigned int rshift = mc->rshift;
2438 int max = mc->max; 2556 int max = mc->max;
2439 unsigned int invert = mc->invert;
2440 unsigned int mask = (1 << fls(max)) - 1; 2557 unsigned int mask = (1 << fls(max)) - 1;
2558 unsigned int invert = mc->invert;
2559
2560 if (snd_soc_volsw_is_stereo(mc))
2561 dev_warn(widget->dapm->dev,
2562 "Control '%s' is stereo, which is not supported\n",
2563 kcontrol->id.name);
2441 2564
2442 ucontrol->value.integer.value[0] = 2565 ucontrol->value.integer.value[0] =
2443 (snd_soc_read(widget->codec, reg) >> shift) & mask; 2566 (snd_soc_read(widget->codec, reg) >> shift) & mask;
2444 if (shift != rshift) 2567 if (invert)
2445 ucontrol->value.integer.value[1] =
2446 (snd_soc_read(widget->codec, reg) >> rshift) & mask;
2447 if (invert) {
2448 ucontrol->value.integer.value[0] = 2568 ucontrol->value.integer.value[0] =
2449 max - ucontrol->value.integer.value[0]; 2569 max - ucontrol->value.integer.value[0];
2450 if (shift != rshift)
2451 ucontrol->value.integer.value[1] =
2452 max - ucontrol->value.integer.value[1];
2453 }
2454 2570
2455 return 0; 2571 return 0;
2456} 2572}
@@ -2484,20 +2600,19 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol,
2484 struct snd_soc_dapm_update update; 2600 struct snd_soc_dapm_update update;
2485 int wi; 2601 int wi;
2486 2602
2603 if (snd_soc_volsw_is_stereo(mc))
2604 dev_warn(widget->dapm->dev,
2605 "Control '%s' is stereo, which is not supported\n",
2606 kcontrol->id.name);
2607
2487 val = (ucontrol->value.integer.value[0] & mask); 2608 val = (ucontrol->value.integer.value[0] & mask);
2609 connect = !!val;
2488 2610
2489 if (invert) 2611 if (invert)
2490 val = max - val; 2612 val = max - val;
2491 mask = mask << shift; 2613 mask = mask << shift;
2492 val = val << shift; 2614 val = val << shift;
2493 2615
2494 if (val)
2495 /* new connection */
2496 connect = invert ? 0 : 1;
2497 else
2498 /* old connection must be powered down */
2499 connect = invert ? 1 : 0;
2500
2501 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME); 2616 mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
2502 2617
2503 change = snd_soc_test_bits(widget->codec, reg, mask, val); 2618 change = snd_soc_test_bits(widget->codec, reg, mask, val);
@@ -2873,6 +2988,19 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2873 return NULL; 2988 return NULL;
2874 } 2989 }
2875 break; 2990 break;
2991 case snd_soc_dapm_clock_supply:
2992#ifdef CONFIG_CLKDEV_LOOKUP
2993 w->clk = devm_clk_get(dapm->dev, w->name);
2994 if (IS_ERR(w->clk)) {
2995 ret = PTR_ERR(w->clk);
2996 dev_err(dapm->dev, "Failed to request %s: %d\n",
2997 w->name, ret);
2998 return NULL;
2999 }
3000#else
3001 return NULL;
3002#endif
3003 break;
2876 default: 3004 default:
2877 break; 3005 break;
2878 } 3006 }
@@ -2924,6 +3052,7 @@ snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm,
2924 break; 3052 break;
2925 case snd_soc_dapm_supply: 3053 case snd_soc_dapm_supply:
2926 case snd_soc_dapm_regulator_supply: 3054 case snd_soc_dapm_regulator_supply:
3055 case snd_soc_dapm_clock_supply:
2927 w->power_check = dapm_supply_check_power; 3056 w->power_check = dapm_supply_check_power;
2928 break; 3057 break;
2929 case snd_soc_dapm_dai: 3058 case snd_soc_dapm_dai:
@@ -3538,10 +3667,13 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_free);
3538 3667
3539static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) 3668static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
3540{ 3669{
3670 struct snd_soc_card *card = dapm->card;
3541 struct snd_soc_dapm_widget *w; 3671 struct snd_soc_dapm_widget *w;
3542 LIST_HEAD(down_list); 3672 LIST_HEAD(down_list);
3543 int powerdown = 0; 3673 int powerdown = 0;
3544 3674
3675 mutex_lock(&card->dapm_mutex);
3676
3545 list_for_each_entry(w, &dapm->card->widgets, list) { 3677 list_for_each_entry(w, &dapm->card->widgets, list) {
3546 if (w->dapm != dapm) 3678 if (w->dapm != dapm)
3547 continue; 3679 continue;
@@ -3564,6 +3696,8 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm)
3564 snd_soc_dapm_set_bias_level(dapm, 3696 snd_soc_dapm_set_bias_level(dapm,
3565 SND_SOC_BIAS_STANDBY); 3697 SND_SOC_BIAS_STANDBY);
3566 } 3698 }
3699
3700 mutex_unlock(&card->dapm_mutex);
3567} 3701}
3568 3702
3569/* 3703/*
diff --git a/sound/soc/soc-dmaengine-pcm.c b/sound/soc/soc-dmaengine-pcm.c
index 475695234b3..5df529eda25 100644
--- a/sound/soc/soc-dmaengine-pcm.c
+++ b/sound/soc/soc-dmaengine-pcm.c
@@ -30,6 +30,7 @@
30 30
31struct dmaengine_pcm_runtime_data { 31struct dmaengine_pcm_runtime_data {
32 struct dma_chan *dma_chan; 32 struct dma_chan *dma_chan;
33 dma_cookie_t cookie;
33 34
34 unsigned int pos; 35 unsigned int pos;
35 36
@@ -153,7 +154,7 @@ static int dmaengine_pcm_prepare_and_submit(struct snd_pcm_substream *substream)
153 154
154 desc->callback = dmaengine_pcm_dma_complete; 155 desc->callback = dmaengine_pcm_dma_complete;
155 desc->callback_param = substream; 156 desc->callback_param = substream;
156 dmaengine_submit(desc); 157 prtd->cookie = dmaengine_submit(desc);
157 158
158 return 0; 159 return 0;
159} 160}
@@ -200,6 +201,20 @@ int snd_dmaengine_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
200EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger); 201EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
201 202
202/** 203/**
204 * snd_dmaengine_pcm_pointer_no_residue - dmaengine based PCM pointer implementation
205 * @substream: PCM substream
206 *
207 * This function is deprecated and should not be used by new drivers, as its
208 * results may be unreliable.
209 */
210snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream)
211{
212 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
213 return bytes_to_frames(substream->runtime, prtd->pos);
214}
215EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue);
216
217/**
203 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation 218 * snd_dmaengine_pcm_pointer - dmaengine based PCM pointer implementation
204 * @substream: PCM substream 219 * @substream: PCM substream
205 * 220 *
@@ -209,7 +224,19 @@ EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_trigger);
209snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream) 224snd_pcm_uframes_t snd_dmaengine_pcm_pointer(struct snd_pcm_substream *substream)
210{ 225{
211 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream); 226 struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
212 return bytes_to_frames(substream->runtime, prtd->pos); 227 struct dma_tx_state state;
228 enum dma_status status;
229 unsigned int buf_size;
230 unsigned int pos = 0;
231
232 status = dmaengine_tx_status(prtd->dma_chan, prtd->cookie, &state);
233 if (status == DMA_IN_PROGRESS || status == DMA_PAUSED) {
234 buf_size = snd_pcm_lib_buffer_bytes(substream);
235 if (state.residue > 0 && state.residue <= buf_size)
236 pos = buf_size - state.residue;
237 }
238
239 return bytes_to_frames(substream->runtime, pos);
213} 240}
214EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer); 241EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer);
215 242
@@ -243,7 +270,7 @@ static int dmaengine_pcm_request_channel(struct dmaengine_pcm_runtime_data *prtd
243 * Note that this function will use private_data field of the substream's 270 * Note that this function will use private_data field of the substream's
244 * runtime. So it is not availabe to your pcm driver implementation. If you need 271 * runtime. So it is not availabe to your pcm driver implementation. If you need
245 * to keep additional data attached to a substream use 272 * to keep additional data attached to a substream use
246 * snd_dmaeinge_pcm_{set,get}_data. 273 * snd_dmaengine_pcm_{set,get}_data.
247 */ 274 */
248int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream, 275int snd_dmaengine_pcm_open(struct snd_pcm_substream *substream,
249 dma_filter_fn filter_fn, void *filter_data) 276 dma_filter_fn filter_fn, void *filter_data)
diff --git a/sound/soc/soc-io.c b/sound/soc/soc-io.c
index 4d8dc6a27d4..29183ef2b93 100644
--- a/sound/soc/soc-io.c
+++ b/sound/soc/soc-io.c
@@ -142,11 +142,16 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec,
142 case SND_SOC_REGMAP: 142 case SND_SOC_REGMAP:
143 /* Device has made its own regmap arrangements */ 143 /* Device has made its own regmap arrangements */
144 codec->using_regmap = true; 144 codec->using_regmap = true;
145 145 if (!codec->control_data)
146 ret = regmap_get_val_bytes(codec->control_data); 146 codec->control_data = dev_get_regmap(codec->dev, NULL);
147 /* Errors are legitimate for non-integer byte multiples */ 147
148 if (ret > 0) 148 if (codec->control_data) {
149 codec->val_bytes = ret; 149 ret = regmap_get_val_bytes(codec->control_data);
150 /* Errors are legitimate for non-integer byte
151 * multiples */
152 if (ret > 0)
153 codec->val_bytes = ret;
154 }
150 break; 155 break;
151 156
152 default: 157 default:
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index 48fd15b312c..ef22d0bd9e9 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -1955,10 +1955,8 @@ static int dpcm_fe_dai_open(struct snd_pcm_substream *fe_substream)
1955 fe->dpcm[stream].runtime = fe_substream->runtime; 1955 fe->dpcm[stream].runtime = fe_substream->runtime;
1956 1956
1957 if (dpcm_path_get(fe, stream, &list) <= 0) { 1957 if (dpcm_path_get(fe, stream, &list) <= 0) {
1958 dev_warn(fe->dev, "asoc: %s no valid %s route\n", 1958 dev_dbg(fe->dev, "asoc: %s no valid %s route\n",
1959 fe->dai_link->name, stream ? "capture" : "playback"); 1959 fe->dai_link->name, stream ? "capture" : "playback");
1960 mutex_unlock(&fe->card->mutex);
1961 return -EINVAL;
1962 } 1960 }
1963 1961
1964 /* calculate valid and active FE <-> BE dpcms */ 1962 /* calculate valid and active FE <-> BE dpcms */
@@ -2003,7 +2001,6 @@ static int dpcm_fe_dai_close(struct snd_pcm_substream *fe_substream)
2003/* create a new pcm */ 2001/* create a new pcm */
2004int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num) 2002int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2005{ 2003{
2006 struct snd_soc_codec *codec = rtd->codec;
2007 struct snd_soc_platform *platform = rtd->platform; 2004 struct snd_soc_platform *platform = rtd->platform;
2008 struct snd_soc_dai *codec_dai = rtd->codec_dai; 2005 struct snd_soc_dai *codec_dai = rtd->codec_dai;
2009 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 2006 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
@@ -2042,7 +2039,8 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2042 capture, &pcm); 2039 capture, &pcm);
2043 } 2040 }
2044 if (ret < 0) { 2041 if (ret < 0) {
2045 printk(KERN_ERR "asoc: can't create pcm for codec %s\n", codec->name); 2042 dev_err(rtd->card->dev, "can't create pcm for %s\n",
2043 rtd->dai_link->name);
2046 return ret; 2044 return ret;
2047 } 2045 }
2048 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name); 2046 dev_dbg(rtd->card->dev, "registered pcm #%d %s\n",num, new_name);
@@ -2099,14 +2097,14 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2099 if (platform->driver->pcm_new) { 2097 if (platform->driver->pcm_new) {
2100 ret = platform->driver->pcm_new(rtd); 2098 ret = platform->driver->pcm_new(rtd);
2101 if (ret < 0) { 2099 if (ret < 0) {
2102 pr_err("asoc: platform pcm constructor failed\n"); 2100 dev_err(platform->dev, "pcm constructor failed\n");
2103 return ret; 2101 return ret;
2104 } 2102 }
2105 } 2103 }
2106 2104
2107 pcm->private_free = platform->driver->pcm_free; 2105 pcm->private_free = platform->driver->pcm_free;
2108out: 2106out:
2109 printk(KERN_INFO "asoc: %s <-> %s mapping ok\n", codec_dai->name, 2107 dev_info(rtd->card->dev, " %s <-> %s mapping ok\n", codec_dai->name,
2110 cpu_dai->name); 2108 cpu_dai->name);
2111 return ret; 2109 return ret;
2112} 2110}
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c
new file mode 100644
index 00000000000..c7c4b20395b
--- /dev/null
+++ b/sound/soc/spear/spdif_in.c
@@ -0,0 +1,297 @@
1/*
2 * ALSA SoC SPDIF In Audio Layer for spear processors
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Vipin Kumar <vipin.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/ioport.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <sound/pcm.h>
22#include <sound/pcm_params.h>
23#include <sound/soc.h>
24#include <sound/spear_dma.h>
25#include <sound/spear_spdif.h>
26#include "spdif_in_regs.h"
27
28struct spdif_in_params {
29 u32 format;
30};
31
32struct spdif_in_dev {
33 struct clk *clk;
34 struct spear_dma_data dma_params;
35 struct spdif_in_params saved_params;
36 void *io_base;
37 struct device *dev;
38 void (*reset_perip)(void);
39 int irq;
40};
41
42static void spdif_in_configure(struct spdif_in_dev *host)
43{
44 u32 ctrl = SPDIF_IN_PRTYEN | SPDIF_IN_STATEN | SPDIF_IN_USREN |
45 SPDIF_IN_VALEN | SPDIF_IN_BLKEN;
46 ctrl |= SPDIF_MODE_16BIT | SPDIF_FIFO_THRES_16;
47
48 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
49 writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK);
50}
51
52static int spdif_in_startup(struct snd_pcm_substream *substream,
53 struct snd_soc_dai *cpu_dai)
54{
55 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
56
57 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
58 return -EINVAL;
59
60 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
61 return 0;
62}
63
64static void spdif_in_shutdown(struct snd_pcm_substream *substream,
65 struct snd_soc_dai *dai)
66{
67 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
68
69 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
70 return;
71
72 writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
73 snd_soc_dai_set_dma_data(dai, substream, NULL);
74}
75
76static void spdif_in_format(struct spdif_in_dev *host, u32 format)
77{
78 u32 ctrl = readl(host->io_base + SPDIF_IN_CTRL);
79
80 switch (format) {
81 case SNDRV_PCM_FORMAT_S16_LE:
82 ctrl |= SPDIF_XTRACT_16BIT;
83 break;
84
85 case SNDRV_PCM_FORMAT_IEC958_SUBFRAME_LE:
86 ctrl &= ~SPDIF_XTRACT_16BIT;
87 break;
88 }
89
90 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
91}
92
93static int spdif_in_hw_params(struct snd_pcm_substream *substream,
94 struct snd_pcm_hw_params *params,
95 struct snd_soc_dai *dai)
96{
97 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
98 u32 format;
99
100 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
101 return -EINVAL;
102
103 format = params_format(params);
104 host->saved_params.format = format;
105
106 return 0;
107}
108
109static int spdif_in_trigger(struct snd_pcm_substream *substream, int cmd,
110 struct snd_soc_dai *dai)
111{
112 struct spdif_in_dev *host = snd_soc_dai_get_drvdata(dai);
113 u32 ctrl;
114 int ret = 0;
115
116 if (substream->stream != SNDRV_PCM_STREAM_CAPTURE)
117 return -EINVAL;
118
119 switch (cmd) {
120 case SNDRV_PCM_TRIGGER_START:
121 case SNDRV_PCM_TRIGGER_RESUME:
122 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
123 clk_enable(host->clk);
124 spdif_in_configure(host);
125 spdif_in_format(host, host->saved_params.format);
126
127 ctrl = readl(host->io_base + SPDIF_IN_CTRL);
128 ctrl |= SPDIF_IN_SAMPLE | SPDIF_IN_ENB;
129 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
130 writel(0xF, host->io_base + SPDIF_IN_IRQ_MASK);
131 break;
132
133 case SNDRV_PCM_TRIGGER_STOP:
134 case SNDRV_PCM_TRIGGER_SUSPEND:
135 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
136 ctrl = readl(host->io_base + SPDIF_IN_CTRL);
137 ctrl &= ~(SPDIF_IN_SAMPLE | SPDIF_IN_ENB);
138 writel(ctrl, host->io_base + SPDIF_IN_CTRL);
139 writel(0x0, host->io_base + SPDIF_IN_IRQ_MASK);
140
141 if (host->reset_perip)
142 host->reset_perip();
143 clk_disable(host->clk);
144 break;
145
146 default:
147 ret = -EINVAL;
148 break;
149 }
150 return ret;
151}
152
153static struct snd_soc_dai_ops spdif_in_dai_ops = {
154 .startup = spdif_in_startup,
155 .shutdown = spdif_in_shutdown,
156 .trigger = spdif_in_trigger,
157 .hw_params = spdif_in_hw_params,
158};
159
160struct snd_soc_dai_driver spdif_in_dai = {
161 .capture = {
162 .channels_min = 2,
163 .channels_max = 2,
164 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
165 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
166 SNDRV_PCM_RATE_192000),
167 .formats = SNDRV_PCM_FMTBIT_S16_LE | \
168 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
169 },
170 .ops = &spdif_in_dai_ops,
171};
172
173static irqreturn_t spdif_in_irq(int irq, void *arg)
174{
175 struct spdif_in_dev *host = (struct spdif_in_dev *)arg;
176
177 u32 irq_status = readl(host->io_base + SPDIF_IN_IRQ);
178
179 if (!irq_status)
180 return IRQ_NONE;
181
182 if (irq_status & SPDIF_IRQ_FIFOWRITE)
183 dev_err(host->dev, "spdif in: fifo write error");
184 if (irq_status & SPDIF_IRQ_EMPTYFIFOREAD)
185 dev_err(host->dev, "spdif in: empty fifo read error");
186 if (irq_status & SPDIF_IRQ_FIFOFULL)
187 dev_err(host->dev, "spdif in: fifo full error");
188 if (irq_status & SPDIF_IRQ_OUTOFRANGE)
189 dev_err(host->dev, "spdif in: out of range error");
190
191 writel(0, host->io_base + SPDIF_IN_IRQ);
192
193 return IRQ_HANDLED;
194}
195
196static int spdif_in_probe(struct platform_device *pdev)
197{
198 struct spdif_in_dev *host;
199 struct spear_spdif_platform_data *pdata;
200 struct resource *res, *res_fifo;
201 int ret;
202
203 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
204 if (!res)
205 return -EINVAL;
206
207 res_fifo = platform_get_resource(pdev, IORESOURCE_IO, 0);
208 if (!res_fifo)
209 return -EINVAL;
210
211 if (!devm_request_mem_region(&pdev->dev, res->start,
212 resource_size(res), pdev->name)) {
213 dev_warn(&pdev->dev, "Failed to get memory resourse\n");
214 return -ENOENT;
215 }
216
217 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
218 if (!host) {
219 dev_warn(&pdev->dev, "kzalloc fail\n");
220 return -ENOMEM;
221 }
222
223 host->io_base = devm_ioremap(&pdev->dev, res->start,
224 resource_size(res));
225 if (!host->io_base) {
226 dev_warn(&pdev->dev, "ioremap failed\n");
227 return -ENOMEM;
228 }
229
230 host->irq = platform_get_irq(pdev, 0);
231 if (host->irq < 0)
232 return -EINVAL;
233
234 host->clk = clk_get(&pdev->dev, NULL);
235 if (IS_ERR(host->clk))
236 return PTR_ERR(host->clk);
237
238 pdata = dev_get_platdata(&pdev->dev);
239
240 if (!pdata)
241 return -EINVAL;
242
243 host->dma_params.data = pdata->dma_params;
244 host->dma_params.addr = res_fifo->start;
245 host->dma_params.max_burst = 16;
246 host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
247 host->dma_params.filter = pdata->filter;
248 host->reset_perip = pdata->reset_perip;
249
250 host->dev = &pdev->dev;
251 dev_set_drvdata(&pdev->dev, host);
252
253 ret = devm_request_irq(&pdev->dev, host->irq, spdif_in_irq, 0,
254 "spdif-in", host);
255 if (ret) {
256 clk_put(host->clk);
257 dev_warn(&pdev->dev, "request_irq failed\n");
258 return ret;
259 }
260
261 ret = snd_soc_register_dai(&pdev->dev, &spdif_in_dai);
262 if (ret != 0) {
263 clk_put(host->clk);
264 return ret;
265 }
266
267 return 0;
268}
269
270static int spdif_in_remove(struct platform_device *pdev)
271{
272 struct spdif_in_dev *host = dev_get_drvdata(&pdev->dev);
273
274 snd_soc_unregister_dai(&pdev->dev);
275 dev_set_drvdata(&pdev->dev, NULL);
276
277 clk_put(host->clk);
278
279 return 0;
280}
281
282
283static struct platform_driver spdif_in_driver = {
284 .probe = spdif_in_probe,
285 .remove = spdif_in_remove,
286 .driver = {
287 .name = "spdif-in",
288 .owner = THIS_MODULE,
289 },
290};
291
292module_platform_driver(spdif_in_driver);
293
294MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>");
295MODULE_DESCRIPTION("SPEAr SPDIF IN SoC Interface");
296MODULE_LICENSE("GPL");
297MODULE_ALIAS("platform:spdif_in");
diff --git a/sound/soc/spear/spdif_in_regs.h b/sound/soc/spear/spdif_in_regs.h
new file mode 100644
index 00000000000..37af7bc66b7
--- /dev/null
+++ b/sound/soc/spear/spdif_in_regs.h
@@ -0,0 +1,60 @@
1/*
2 * SPEAr SPDIF IN controller header file
3 *
4 * Copyright (ST) 2011 Vipin Kumar (vipin.kumar@st.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef SPDIF_IN_REGS_H
22#define SPDIF_IN_REGS_H
23
24#define SPDIF_IN_CTRL 0x00
25 #define SPDIF_IN_PRTYEN (1 << 20)
26 #define SPDIF_IN_STATEN (1 << 19)
27 #define SPDIF_IN_USREN (1 << 18)
28 #define SPDIF_IN_VALEN (1 << 17)
29 #define SPDIF_IN_BLKEN (1 << 16)
30
31 #define SPDIF_MODE_24BIT (8 << 12)
32 #define SPDIF_MODE_23BIT (7 << 12)
33 #define SPDIF_MODE_22BIT (6 << 12)
34 #define SPDIF_MODE_21BIT (5 << 12)
35 #define SPDIF_MODE_20BIT (4 << 12)
36 #define SPDIF_MODE_19BIT (3 << 12)
37 #define SPDIF_MODE_18BIT (2 << 12)
38 #define SPDIF_MODE_17BIT (1 << 12)
39 #define SPDIF_MODE_16BIT (0 << 12)
40 #define SPDIF_MODE_MASK (0x0F << 12)
41
42 #define SPDIF_IN_VALID (1 << 11)
43 #define SPDIF_IN_SAMPLE (1 << 10)
44 #define SPDIF_DATA_SWAP (1 << 9)
45 #define SPDIF_IN_ENB (1 << 8)
46 #define SPDIF_DATA_REVERT (1 << 7)
47 #define SPDIF_XTRACT_16BIT (1 << 6)
48 #define SPDIF_FIFO_THRES_16 (16 << 0)
49
50#define SPDIF_IN_IRQ_MASK 0x04
51#define SPDIF_IN_IRQ 0x08
52 #define SPDIF_IRQ_FIFOWRITE (1 << 0)
53 #define SPDIF_IRQ_EMPTYFIFOREAD (1 << 1)
54 #define SPDIF_IRQ_FIFOFULL (1 << 2)
55 #define SPDIF_IRQ_OUTOFRANGE (1 << 3)
56
57#define SPDIF_IN_STA 0x0C
58 #define SPDIF_IN_LOCK (0x1 << 0)
59
60#endif /* SPDIF_IN_REGS_H */
diff --git a/sound/soc/spear/spdif_out.c b/sound/soc/spear/spdif_out.c
new file mode 100644
index 00000000000..5eac4cda2fd
--- /dev/null
+++ b/sound/soc/spear/spdif_out.c
@@ -0,0 +1,389 @@
1/*
2 * ALSA SoC SPDIF Out Audio Layer for spear processors
3 *
4 * Copyright (C) 2012 ST Microelectronics
5 * Vipin Kumar <vipin.kumar@st.com>
6 *
7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any
9 * warranty of any kind, whether express or implied.
10 */
11
12#include <linux/clk.h>
13#include <linux/delay.h>
14#include <linux/device.h>
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/io.h>
18#include <linux/ioport.h>
19#include <linux/module.h>
20#include <linux/platform_device.h>
21#include <sound/soc.h>
22#include <sound/spear_dma.h>
23#include <sound/spear_spdif.h>
24#include "spdif_out_regs.h"
25
26struct spdif_out_params {
27 u32 rate;
28 u32 core_freq;
29 u32 mute;
30};
31
32struct spdif_out_dev {
33 struct clk *clk;
34 struct spear_dma_data dma_params;
35 struct spdif_out_params saved_params;
36 u32 running;
37 void __iomem *io_base;
38};
39
40static void spdif_out_configure(struct spdif_out_dev *host)
41{
42 writel(SPDIF_OUT_RESET, host->io_base + SPDIF_OUT_SOFT_RST);
43 mdelay(1);
44 writel(readl(host->io_base + SPDIF_OUT_SOFT_RST) & ~SPDIF_OUT_RESET,
45 host->io_base + SPDIF_OUT_SOFT_RST);
46
47 writel(SPDIF_OUT_FDMA_TRIG_16 | SPDIF_OUT_MEMFMT_16_16 |
48 SPDIF_OUT_VALID_HW | SPDIF_OUT_USER_HW |
49 SPDIF_OUT_CHNLSTA_HW | SPDIF_OUT_PARITY_HW,
50 host->io_base + SPDIF_OUT_CFG);
51
52 writel(0x7F, host->io_base + SPDIF_OUT_INT_STA_CLR);
53 writel(0x7F, host->io_base + SPDIF_OUT_INT_EN_CLR);
54}
55
56static int spdif_out_startup(struct snd_pcm_substream *substream,
57 struct snd_soc_dai *cpu_dai)
58{
59 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
60 int ret;
61
62 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
63 return -EINVAL;
64
65 snd_soc_dai_set_dma_data(cpu_dai, substream, (void *)&host->dma_params);
66
67 ret = clk_enable(host->clk);
68 if (ret)
69 return ret;
70
71 host->running = true;
72 spdif_out_configure(host);
73
74 return 0;
75}
76
77static void spdif_out_shutdown(struct snd_pcm_substream *substream,
78 struct snd_soc_dai *dai)
79{
80 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
81
82 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
83 return;
84
85 clk_disable(host->clk);
86 host->running = false;
87 snd_soc_dai_set_dma_data(dai, substream, NULL);
88}
89
90static void spdif_out_clock(struct spdif_out_dev *host, u32 core_freq,
91 u32 rate)
92{
93 u32 divider, ctrl;
94
95 clk_set_rate(host->clk, core_freq);
96 divider = DIV_ROUND_CLOSEST(clk_get_rate(host->clk), (rate * 128));
97
98 ctrl = readl(host->io_base + SPDIF_OUT_CTRL);
99 ctrl &= ~SPDIF_DIVIDER_MASK;
100 ctrl |= (divider << SPDIF_DIVIDER_SHIFT) & SPDIF_DIVIDER_MASK;
101 writel(ctrl, host->io_base + SPDIF_OUT_CTRL);
102}
103
104static int spdif_out_hw_params(struct snd_pcm_substream *substream,
105 struct snd_pcm_hw_params *params,
106 struct snd_soc_dai *dai)
107{
108 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
109 u32 rate, core_freq;
110
111 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
112 return -EINVAL;
113
114 rate = params_rate(params);
115
116 switch (rate) {
117 case 8000:
118 case 16000:
119 case 32000:
120 case 64000:
121 /*
122 * The clock is multiplied by 10 to bring it to feasible range
123 * of frequencies for sscg
124 */
125 core_freq = 64000 * 128 * 10; /* 81.92 MHz */
126 break;
127 case 5512:
128 case 11025:
129 case 22050:
130 case 44100:
131 case 88200:
132 case 176400:
133 core_freq = 176400 * 128; /* 22.5792 MHz */
134 break;
135 case 48000:
136 case 96000:
137 case 192000:
138 default:
139 core_freq = 192000 * 128; /* 24.576 MHz */
140 break;
141 }
142
143 spdif_out_clock(host, core_freq, rate);
144 host->saved_params.core_freq = core_freq;
145 host->saved_params.rate = rate;
146
147 return 0;
148}
149
150static int spdif_out_trigger(struct snd_pcm_substream *substream, int cmd,
151 struct snd_soc_dai *dai)
152{
153 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
154 u32 ctrl;
155 int ret = 0;
156
157 if (substream->stream != SNDRV_PCM_STREAM_PLAYBACK)
158 return -EINVAL;
159
160 switch (cmd) {
161 case SNDRV_PCM_TRIGGER_START:
162 case SNDRV_PCM_TRIGGER_RESUME:
163 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
164 ctrl = readl(host->io_base + SPDIF_OUT_CTRL);
165 ctrl &= ~SPDIF_OPMODE_MASK;
166 if (!host->saved_params.mute)
167 ctrl |= SPDIF_OPMODE_AUD_DATA |
168 SPDIF_STATE_NORMAL;
169 else
170 ctrl |= SPDIF_OPMODE_MUTE_PCM;
171 writel(ctrl, host->io_base + SPDIF_OUT_CTRL);
172 break;
173
174 case SNDRV_PCM_TRIGGER_STOP:
175 case SNDRV_PCM_TRIGGER_SUSPEND:
176 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
177 ctrl = readl(host->io_base + SPDIF_OUT_CTRL);
178 ctrl &= ~SPDIF_OPMODE_MASK;
179 ctrl |= SPDIF_OPMODE_OFF;
180 writel(ctrl, host->io_base + SPDIF_OUT_CTRL);
181 break;
182
183 default:
184 ret = -EINVAL;
185 break;
186 }
187 return ret;
188}
189
190static int spdif_digital_mute(struct snd_soc_dai *dai, int mute)
191{
192 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(dai);
193 u32 val;
194
195 host->saved_params.mute = mute;
196 val = readl(host->io_base + SPDIF_OUT_CTRL);
197 val &= ~SPDIF_OPMODE_MASK;
198
199 if (mute)
200 val |= SPDIF_OPMODE_MUTE_PCM;
201 else {
202 if (host->running)
203 val |= SPDIF_OPMODE_AUD_DATA | SPDIF_STATE_NORMAL;
204 else
205 val |= SPDIF_OPMODE_OFF;
206 }
207
208 writel(val, host->io_base + SPDIF_OUT_CTRL);
209 return 0;
210}
211
212static int spdif_mute_get(struct snd_kcontrol *kcontrol,
213 struct snd_ctl_elem_value *ucontrol)
214{
215 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
216 struct snd_soc_card *card = codec->card;
217 struct snd_soc_pcm_runtime *rtd = card->rtd;
218 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
219 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
220
221 ucontrol->value.integer.value[0] = host->saved_params.mute;
222 return 0;
223}
224
225static int spdif_mute_put(struct snd_kcontrol *kcontrol,
226 struct snd_ctl_elem_value *ucontrol)
227{
228 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
229 struct snd_soc_card *card = codec->card;
230 struct snd_soc_pcm_runtime *rtd = card->rtd;
231 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
232 struct spdif_out_dev *host = snd_soc_dai_get_drvdata(cpu_dai);
233
234 if (host->saved_params.mute == ucontrol->value.integer.value[0])
235 return 0;
236
237 spdif_digital_mute(cpu_dai, ucontrol->value.integer.value[0]);
238
239 return 1;
240}
241static const struct snd_kcontrol_new spdif_out_controls[] = {
242 SOC_SINGLE_BOOL_EXT("IEC958 Playback Switch", 0,
243 spdif_mute_get, spdif_mute_put),
244};
245
246int spdif_soc_dai_probe(struct snd_soc_dai *dai)
247{
248 return snd_soc_add_dai_controls(dai, spdif_out_controls,
249 ARRAY_SIZE(spdif_out_controls));
250}
251
252static const struct snd_soc_dai_ops spdif_out_dai_ops = {
253 .digital_mute = spdif_digital_mute,
254 .startup = spdif_out_startup,
255 .shutdown = spdif_out_shutdown,
256 .trigger = spdif_out_trigger,
257 .hw_params = spdif_out_hw_params,
258};
259
260static struct snd_soc_dai_driver spdif_out_dai = {
261 .playback = {
262 .channels_min = 2,
263 .channels_max = 2,
264 .rates = (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \
265 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | \
266 SNDRV_PCM_RATE_192000),
267 .formats = SNDRV_PCM_FMTBIT_S16_LE,
268 },
269 .probe = spdif_soc_dai_probe,
270 .ops = &spdif_out_dai_ops,
271};
272
273static int spdif_out_probe(struct platform_device *pdev)
274{
275 struct spdif_out_dev *host;
276 struct spear_spdif_platform_data *pdata;
277 struct resource *res;
278 int ret;
279
280 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
281 if (!res)
282 return -EINVAL;
283
284 if (!devm_request_mem_region(&pdev->dev, res->start,
285 resource_size(res), pdev->name)) {
286 dev_warn(&pdev->dev, "Failed to get memory resourse\n");
287 return -ENOENT;
288 }
289
290 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
291 if (!host) {
292 dev_warn(&pdev->dev, "kzalloc fail\n");
293 return -ENOMEM;
294 }
295
296 host->io_base = devm_ioremap(&pdev->dev, res->start,
297 resource_size(res));
298 if (!host->io_base) {
299 dev_warn(&pdev->dev, "ioremap failed\n");
300 return -ENOMEM;
301 }
302
303 host->clk = clk_get(&pdev->dev, NULL);
304 if (IS_ERR(host->clk))
305 return PTR_ERR(host->clk);
306
307 pdata = dev_get_platdata(&pdev->dev);
308
309 host->dma_params.data = pdata->dma_params;
310 host->dma_params.addr = res->start + SPDIF_OUT_FIFO_DATA;
311 host->dma_params.max_burst = 16;
312 host->dma_params.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
313 host->dma_params.filter = pdata->filter;
314
315 dev_set_drvdata(&pdev->dev, host);
316
317 ret = snd_soc_register_dai(&pdev->dev, &spdif_out_dai);
318 if (ret != 0) {
319 clk_put(host->clk);
320 return ret;
321 }
322
323 return 0;
324}
325
326static int spdif_out_remove(struct platform_device *pdev)
327{
328 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
329
330 snd_soc_unregister_dai(&pdev->dev);
331 dev_set_drvdata(&pdev->dev, NULL);
332
333 clk_put(host->clk);
334
335 return 0;
336}
337
338#ifdef CONFIG_PM
339static int spdif_out_suspend(struct device *dev)
340{
341 struct platform_device *pdev = to_platform_device(dev);
342 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
343
344 if (host->running)
345 clk_disable(host->clk);
346
347 return 0;
348}
349
350static int spdif_out_resume(struct device *dev)
351{
352 struct platform_device *pdev = to_platform_device(dev);
353 struct spdif_out_dev *host = dev_get_drvdata(&pdev->dev);
354
355 if (host->running) {
356 clk_enable(host->clk);
357 spdif_out_configure(host);
358 spdif_out_clock(host, host->saved_params.core_freq,
359 host->saved_params.rate);
360 }
361 return 0;
362}
363
364static SIMPLE_DEV_PM_OPS(spdif_out_dev_pm_ops, spdif_out_suspend, \
365 spdif_out_resume);
366
367#define SPDIF_OUT_DEV_PM_OPS (&spdif_out_dev_pm_ops)
368
369#else
370#define SPDIF_OUT_DEV_PM_OPS NULL
371
372#endif
373
374static struct platform_driver spdif_out_driver = {
375 .probe = spdif_out_probe,
376 .remove = spdif_out_remove,
377 .driver = {
378 .name = "spdif-out",
379 .owner = THIS_MODULE,
380 .pm = SPDIF_OUT_DEV_PM_OPS,
381 },
382};
383
384module_platform_driver(spdif_out_driver);
385
386MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>");
387MODULE_DESCRIPTION("SPEAr SPDIF OUT SoC Interface");
388MODULE_LICENSE("GPL");
389MODULE_ALIAS("platform:spdif_out");
diff --git a/sound/soc/spear/spdif_out_regs.h b/sound/soc/spear/spdif_out_regs.h
new file mode 100644
index 00000000000..a5e53324b45
--- /dev/null
+++ b/sound/soc/spear/spdif_out_regs.h
@@ -0,0 +1,79 @@
1/*
2 * SPEAr SPDIF OUT controller header file
3 *
4 * Copyright (ST) 2011 Vipin Kumar (vipin.kumar@st.com)
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef SPDIF_OUT_REGS_H
22#define SPDIF_OUT_REGS_H
23
24#define SPDIF_OUT_SOFT_RST 0x00
25 #define SPDIF_OUT_RESET (1 << 0)
26#define SPDIF_OUT_FIFO_DATA 0x04
27#define SPDIF_OUT_INT_STA 0x08
28#define SPDIF_OUT_INT_STA_CLR 0x0C
29 #define SPDIF_INT_UNDERFLOW (1 << 0)
30 #define SPDIF_INT_EODATA (1 << 1)
31 #define SPDIF_INT_EOBLOCK (1 << 2)
32 #define SPDIF_INT_EOLATENCY (1 << 3)
33 #define SPDIF_INT_EOPD_DATA (1 << 4)
34 #define SPDIF_INT_MEMFULLREAD (1 << 5)
35 #define SPDIF_INT_EOPD_PAUSE (1 << 6)
36
37#define SPDIF_OUT_INT_EN 0x10
38#define SPDIF_OUT_INT_EN_SET 0x14
39#define SPDIF_OUT_INT_EN_CLR 0x18
40#define SPDIF_OUT_CTRL 0x1C
41 #define SPDIF_OPMODE_MASK (7 << 0)
42 #define SPDIF_OPMODE_OFF (0 << 0)
43 #define SPDIF_OPMODE_MUTE_PCM (1 << 0)
44 #define SPDIF_OPMODE_MUTE_PAUSE (2 << 0)
45 #define SPDIF_OPMODE_AUD_DATA (3 << 0)
46 #define SPDIF_OPMODE_ENCODE (4 << 0)
47 #define SPDIF_STATE_NORMAL (1 << 3)
48 #define SPDIF_DIVIDER_MASK (0xff << 5)
49 #define SPDIF_DIVIDER_SHIFT (5)
50 #define SPDIF_SAMPLEREAD_MASK (0x1ffff << 15)
51 #define SPDIF_SAMPLEREAD_SHIFT (15)
52#define SPDIF_OUT_STA 0x20
53#define SPDIF_OUT_PA_PB 0x24
54#define SPDIF_OUT_PC_PD 0x28
55#define SPDIF_OUT_CL1 0x2C
56#define SPDIF_OUT_CR1 0x30
57#define SPDIF_OUT_CL2_CR2_UV 0x34
58#define SPDIF_OUT_PAUSE_LAT 0x38
59#define SPDIF_OUT_FRMLEN_BRST 0x3C
60#define SPDIF_OUT_CFG 0x40
61 #define SPDIF_OUT_MEMFMT_16_0 (0 << 5)
62 #define SPDIF_OUT_MEMFMT_16_16 (1 << 5)
63 #define SPDIF_OUT_VALID_DMA (0 << 3)
64 #define SPDIF_OUT_VALID_HW (1 << 3)
65 #define SPDIF_OUT_USER_DMA (0 << 2)
66 #define SPDIF_OUT_USER_HW (1 << 2)
67 #define SPDIF_OUT_CHNLSTA_DMA (0 << 1)
68 #define SPDIF_OUT_CHNLSTA_HW (1 << 1)
69 #define SPDIF_OUT_PARITY_HW (0 << 0)
70 #define SPDIF_OUT_PARITY_DMA (1 << 0)
71 #define SPDIF_OUT_FDMA_TRIG_2 (2 << 8)
72 #define SPDIF_OUT_FDMA_TRIG_6 (6 << 8)
73 #define SPDIF_OUT_FDMA_TRIG_8 (8 << 8)
74 #define SPDIF_OUT_FDMA_TRIG_10 (10 << 8)
75 #define SPDIF_OUT_FDMA_TRIG_12 (12 << 8)
76 #define SPDIF_OUT_FDMA_TRIG_16 (16 << 8)
77 #define SPDIF_OUT_FDMA_TRIG_18 (18 << 8)
78
79#endif /* SPDIF_OUT_REGS_H */
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c
new file mode 100644
index 00000000000..97c2cac8e92
--- /dev/null
+++ b/sound/soc/spear/spear_pcm.c
@@ -0,0 +1,214 @@
1/*
2 * ALSA PCM interface for ST SPEAr Processors
3 *
4 * sound/soc/spear/spear_pcm.c
5 *
6 * Copyright (C) 2012 ST Microelectronics
7 * Rajeev Kumar<rajeev-dlh.kumar@st.com>
8 *
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
12 */
13
14#include <linux/module.h>
15#include <linux/dmaengine.h>
16#include <linux/dma-mapping.h>
17#include <linux/init.h>
18#include <linux/platform_device.h>
19#include <linux/scatterlist.h>
20#include <linux/slab.h>
21#include <sound/core.h>
22#include <sound/dmaengine_pcm.h>
23#include <sound/pcm.h>
24#include <sound/pcm_params.h>
25#include <sound/soc.h>
26#include <sound/spear_dma.h>
27
28struct snd_pcm_hardware spear_pcm_hardware = {
29 .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
30 SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID |
31 SNDRV_PCM_INFO_PAUSE | SNDRV_PCM_INFO_RESUME),
32 .buffer_bytes_max = 16 * 1024, /* max buffer size */
33 .period_bytes_min = 2 * 1024, /* 1 msec data minimum period size */
34 .period_bytes_max = 2 * 1024, /* maximum period size */
35 .periods_min = 1, /* min # periods */
36 .periods_max = 8, /* max # of periods */
37 .fifo_size = 0, /* fifo size in bytes */
38};
39
40static int spear_pcm_hw_params(struct snd_pcm_substream *substream,
41 struct snd_pcm_hw_params *params)
42{
43 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
44
45 return 0;
46}
47
48static int spear_pcm_hw_free(struct snd_pcm_substream *substream)
49{
50 snd_pcm_set_runtime_buffer(substream, NULL);
51
52 return 0;
53}
54
55static int spear_pcm_open(struct snd_pcm_substream *substream)
56{
57 struct snd_soc_pcm_runtime *rtd = substream->private_data;
58
59 struct spear_dma_data *dma_data = (struct spear_dma_data *)
60 snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
61 int ret;
62
63 ret = snd_soc_set_runtime_hwparams(substream, &spear_pcm_hardware);
64 if (ret)
65 return ret;
66
67 ret = snd_dmaengine_pcm_open(substream, dma_data->filter, dma_data);
68 if (ret)
69 return ret;
70
71 snd_dmaengine_pcm_set_data(substream, dma_data);
72
73 return 0;
74}
75
76static int spear_pcm_close(struct snd_pcm_substream *substream)
77{
78
79 snd_dmaengine_pcm_close(substream);
80
81 return 0;
82}
83
84static int spear_pcm_mmap(struct snd_pcm_substream *substream,
85 struct vm_area_struct *vma)
86{
87 struct snd_pcm_runtime *runtime = substream->runtime;
88
89 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
90 runtime->dma_area, runtime->dma_addr,
91 runtime->dma_bytes);
92}
93
94static struct snd_pcm_ops spear_pcm_ops = {
95 .open = spear_pcm_open,
96 .close = spear_pcm_close,
97 .ioctl = snd_pcm_lib_ioctl,
98 .hw_params = spear_pcm_hw_params,
99 .hw_free = spear_pcm_hw_free,
100 .trigger = snd_dmaengine_pcm_trigger,
101 .pointer = snd_dmaengine_pcm_pointer,
102 .mmap = spear_pcm_mmap,
103};
104
105static int
106spear_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream,
107 size_t size)
108{
109 struct snd_pcm_substream *substream = pcm->streams[stream].substream;
110 struct snd_dma_buffer *buf = &substream->dma_buffer;
111
112 buf->dev.type = SNDRV_DMA_TYPE_DEV;
113 buf->dev.dev = pcm->card->dev;
114 buf->private_data = NULL;
115
116 buf->area = dma_alloc_writecombine(pcm->card->dev, size,
117 &buf->addr, GFP_KERNEL);
118 if (!buf->area)
119 return -ENOMEM;
120
121 dev_info(buf->dev.dev,
122 " preallocate_dma_buffer: area=%p, addr=%p, size=%d\n",
123 (void *)buf->area, (void *)buf->addr, size);
124
125 buf->bytes = size;
126 return 0;
127}
128
129static void spear_pcm_free(struct snd_pcm *pcm)
130{
131 struct snd_pcm_substream *substream;
132 struct snd_dma_buffer *buf;
133 int stream;
134
135 for (stream = 0; stream < 2; stream++) {
136 substream = pcm->streams[stream].substream;
137 if (!substream)
138 continue;
139
140 buf = &substream->dma_buffer;
141 if (!buf && !buf->area)
142 continue;
143
144 dma_free_writecombine(pcm->card->dev, buf->bytes,
145 buf->area, buf->addr);
146 buf->area = NULL;
147 }
148}
149
150static u64 spear_pcm_dmamask = DMA_BIT_MASK(32);
151
152static int spear_pcm_new(struct snd_card *card,
153 struct snd_soc_dai *dai, struct snd_pcm *pcm)
154{
155 int ret;
156
157 if (!card->dev->dma_mask)
158 card->dev->dma_mask = &spear_pcm_dmamask;
159 if (!card->dev->coherent_dma_mask)
160 card->dev->coherent_dma_mask = DMA_BIT_MASK(32);
161
162 if (dai->driver->playback.channels_min) {
163 ret = spear_pcm_preallocate_dma_buffer(pcm,
164 SNDRV_PCM_STREAM_PLAYBACK,
165 spear_pcm_hardware.buffer_bytes_max);
166 if (ret)
167 return ret;
168 }
169
170 if (dai->driver->capture.channels_min) {
171 ret = spear_pcm_preallocate_dma_buffer(pcm,
172 SNDRV_PCM_STREAM_CAPTURE,
173 spear_pcm_hardware.buffer_bytes_max);
174 if (ret)
175 return ret;
176 }
177
178 return 0;
179}
180
181struct snd_soc_platform_driver spear_soc_platform = {
182 .ops = &spear_pcm_ops,
183 .pcm_new = spear_pcm_new,
184 .pcm_free = spear_pcm_free,
185};
186
187static int __devinit spear_soc_platform_probe(struct platform_device *pdev)
188{
189 return snd_soc_register_platform(&pdev->dev, &spear_soc_platform);
190}
191
192static int __devexit spear_soc_platform_remove(struct platform_device *pdev)
193{
194 snd_soc_unregister_platform(&pdev->dev);
195
196 return 0;
197}
198
199static struct platform_driver spear_pcm_driver = {
200 .driver = {
201 .name = "spear-pcm-audio",
202 .owner = THIS_MODULE,
203 },
204
205 .probe = spear_soc_platform_probe,
206 .remove = __devexit_p(spear_soc_platform_remove),
207};
208
209module_platform_driver(spear_pcm_driver);
210
211MODULE_AUTHOR("Rajeev Kumar <rajeev-dlh.kumar@st.com>");
212MODULE_DESCRIPTION("SPEAr PCM DMA module");
213MODULE_LICENSE("GPL");
214MODULE_ALIAS("platform:spear-pcm-audio");
diff --git a/sound/soc/tegra/Kconfig b/sound/soc/tegra/Kconfig
index c1c8e955f4d..02bcd308c18 100644
--- a/sound/soc/tegra/Kconfig
+++ b/sound/soc/tegra/Kconfig
@@ -1,7 +1,8 @@
1config SND_SOC_TEGRA 1config SND_SOC_TEGRA
2 tristate "SoC Audio for the Tegra System-on-Chip" 2 tristate "SoC Audio for the Tegra System-on-Chip"
3 depends on ARCH_TEGRA && TEGRA_SYSTEM_DMA 3 depends on ARCH_TEGRA && (TEGRA_SYSTEM_DMA || TEGRA20_APB_DMA)
4 select REGMAP_MMIO 4 select REGMAP_MMIO
5 select SND_SOC_DMAENGINE_PCM if TEGRA20_APB_DMA
5 help 6 help
6 Say Y or M here if you want support for SoC audio on Tegra. 7 Say Y or M here if you want support for SoC audio on Tegra.
7 8
@@ -58,17 +59,9 @@ config SND_SOC_TEGRA_WM8753
58 Say Y or M here if you want to add support for SoC audio on Tegra 59 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 boards using the WM8753 codec, such as Whistler.
60 61
61config MACH_HAS_SND_SOC_TEGRA_WM8903
62 bool
63 help
64 Machines that use the SND_SOC_TEGRA_WM8903 driver should select
65 this config option, in order to allow the user to enable
66 SND_SOC_TEGRA_WM8903.
67
68config SND_SOC_TEGRA_WM8903 62config SND_SOC_TEGRA_WM8903
69 tristate "SoC Audio support for Tegra boards using a WM8903 codec" 63 tristate "SoC Audio support for Tegra boards using a WM8903 codec"
70 depends on SND_SOC_TEGRA && I2C 64 depends on SND_SOC_TEGRA && I2C
71 depends on MACH_HAS_SND_SOC_TEGRA_WM8903
72 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 65 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
73 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC 66 select SND_SOC_TEGRA30_I2S if ARCH_TEGRA_3x_SOC
74 select SND_SOC_WM8903 67 select SND_SOC_WM8903
@@ -79,7 +72,7 @@ config SND_SOC_TEGRA_WM8903
79 72
80config SND_SOC_TEGRA_TRIMSLICE 73config SND_SOC_TEGRA_TRIMSLICE
81 tristate "SoC Audio support for TrimSlice board" 74 tristate "SoC Audio support for TrimSlice board"
82 depends on SND_SOC_TEGRA && MACH_TRIMSLICE && I2C 75 depends on SND_SOC_TEGRA && I2C
83 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC 76 select SND_SOC_TEGRA20_I2S if ARCH_TEGRA_2x_SOC
84 select SND_SOC_TLV320AIC23 77 select SND_SOC_TLV320AIC23
85 help 78 help
diff --git a/sound/soc/tegra/tegra20_i2s.c b/sound/soc/tegra/tegra20_i2s.c
index 0c7af63d444..0832e8afd73 100644
--- a/sound/soc/tegra/tegra20_i2s.c
+++ b/sound/soc/tegra/tegra20_i2s.c
@@ -46,23 +46,11 @@
46 46
47#define DRV_NAME "tegra20-i2s" 47#define DRV_NAME "tegra20-i2s"
48 48
49static inline void tegra20_i2s_write(struct tegra20_i2s *i2s, u32 reg, u32 val)
50{
51 regmap_write(i2s->regmap, reg, val);
52}
53
54static inline u32 tegra20_i2s_read(struct tegra20_i2s *i2s, u32 reg)
55{
56 u32 val;
57 regmap_read(i2s->regmap, reg, &val);
58 return val;
59}
60
61static int tegra20_i2s_runtime_suspend(struct device *dev) 49static int tegra20_i2s_runtime_suspend(struct device *dev)
62{ 50{
63 struct tegra20_i2s *i2s = dev_get_drvdata(dev); 51 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
64 52
65 clk_disable(i2s->clk_i2s); 53 clk_disable_unprepare(i2s->clk_i2s);
66 54
67 return 0; 55 return 0;
68} 56}
@@ -72,7 +60,7 @@ static int tegra20_i2s_runtime_resume(struct device *dev)
72 struct tegra20_i2s *i2s = dev_get_drvdata(dev); 60 struct tegra20_i2s *i2s = dev_get_drvdata(dev);
73 int ret; 61 int ret;
74 62
75 ret = clk_enable(i2s->clk_i2s); 63 ret = clk_prepare_enable(i2s->clk_i2s);
76 if (ret) { 64 if (ret) {
77 dev_err(dev, "clk_enable failed: %d\n", ret); 65 dev_err(dev, "clk_enable failed: %d\n", ret);
78 return ret; 66 return ret;
@@ -85,6 +73,7 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
85 unsigned int fmt) 73 unsigned int fmt)
86{ 74{
87 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 75 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
76 unsigned int mask, val;
88 77
89 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 78 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
90 case SND_SOC_DAIFMT_NB_NF: 79 case SND_SOC_DAIFMT_NB_NF:
@@ -93,10 +82,10 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
93 return -EINVAL; 82 return -EINVAL;
94 } 83 }
95 84
96 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_MASTER_ENABLE; 85 mask = TEGRA20_I2S_CTRL_MASTER_ENABLE;
97 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 86 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
98 case SND_SOC_DAIFMT_CBS_CFS: 87 case SND_SOC_DAIFMT_CBS_CFS:
99 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_MASTER_ENABLE; 88 val = TEGRA20_I2S_CTRL_MASTER_ENABLE;
100 break; 89 break;
101 case SND_SOC_DAIFMT_CBM_CFM: 90 case SND_SOC_DAIFMT_CBM_CFM:
102 break; 91 break;
@@ -104,33 +93,35 @@ static int tegra20_i2s_set_fmt(struct snd_soc_dai *dai,
104 return -EINVAL; 93 return -EINVAL;
105 } 94 }
106 95
107 i2s->reg_ctrl &= ~(TEGRA20_I2S_CTRL_BIT_FORMAT_MASK | 96 mask |= TEGRA20_I2S_CTRL_BIT_FORMAT_MASK |
108 TEGRA20_I2S_CTRL_LRCK_MASK); 97 TEGRA20_I2S_CTRL_LRCK_MASK;
109 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 98 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
110 case SND_SOC_DAIFMT_DSP_A: 99 case SND_SOC_DAIFMT_DSP_A:
111 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; 100 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
112 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 101 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
113 break; 102 break;
114 case SND_SOC_DAIFMT_DSP_B: 103 case SND_SOC_DAIFMT_DSP_B:
115 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP; 104 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_DSP;
116 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_R_LOW; 105 val |= TEGRA20_I2S_CTRL_LRCK_R_LOW;
117 break; 106 break;
118 case SND_SOC_DAIFMT_I2S: 107 case SND_SOC_DAIFMT_I2S:
119 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S; 108 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_I2S;
120 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 109 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
121 break; 110 break;
122 case SND_SOC_DAIFMT_RIGHT_J: 111 case SND_SOC_DAIFMT_RIGHT_J:
123 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM; 112 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_RJM;
124 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 113 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
125 break; 114 break;
126 case SND_SOC_DAIFMT_LEFT_J: 115 case SND_SOC_DAIFMT_LEFT_J:
127 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM; 116 val |= TEGRA20_I2S_CTRL_BIT_FORMAT_LJM;
128 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_LRCK_L_LOW; 117 val |= TEGRA20_I2S_CTRL_LRCK_L_LOW;
129 break; 118 break;
130 default: 119 default:
131 return -EINVAL; 120 return -EINVAL;
132 } 121 }
133 122
123 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
124
134 return 0; 125 return 0;
135} 126}
136 127
@@ -138,29 +129,34 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
138 struct snd_pcm_hw_params *params, 129 struct snd_pcm_hw_params *params,
139 struct snd_soc_dai *dai) 130 struct snd_soc_dai *dai)
140{ 131{
141 struct device *dev = substream->pcm->card->dev; 132 struct device *dev = dai->dev;
142 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai); 133 struct tegra20_i2s *i2s = snd_soc_dai_get_drvdata(dai);
143 u32 reg; 134 unsigned int mask, val;
144 int ret, sample_size, srate, i2sclock, bitcnt; 135 int ret, sample_size, srate, i2sclock, bitcnt;
145 136
146 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_BIT_SIZE_MASK; 137 mask = TEGRA20_I2S_CTRL_BIT_SIZE_MASK;
147 switch (params_format(params)) { 138 switch (params_format(params)) {
148 case SNDRV_PCM_FORMAT_S16_LE: 139 case SNDRV_PCM_FORMAT_S16_LE:
149 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_16; 140 val = TEGRA20_I2S_CTRL_BIT_SIZE_16;
150 sample_size = 16; 141 sample_size = 16;
151 break; 142 break;
152 case SNDRV_PCM_FORMAT_S24_LE: 143 case SNDRV_PCM_FORMAT_S24_LE:
153 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_24; 144 val = TEGRA20_I2S_CTRL_BIT_SIZE_24;
154 sample_size = 24; 145 sample_size = 24;
155 break; 146 break;
156 case SNDRV_PCM_FORMAT_S32_LE: 147 case SNDRV_PCM_FORMAT_S32_LE:
157 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_BIT_SIZE_32; 148 val = TEGRA20_I2S_CTRL_BIT_SIZE_32;
158 sample_size = 32; 149 sample_size = 32;
159 break; 150 break;
160 default: 151 default:
161 return -EINVAL; 152 return -EINVAL;
162 } 153 }
163 154
155 mask |= TEGRA20_I2S_CTRL_FIFO_FORMAT_MASK;
156 val |= TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
157
158 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL, mask, val);
159
164 srate = params_rate(params); 160 srate = params_rate(params);
165 161
166 /* Final "* 2" required by Tegra hardware */ 162 /* Final "* 2" required by Tegra hardware */
@@ -175,42 +171,44 @@ static int tegra20_i2s_hw_params(struct snd_pcm_substream *substream,
175 bitcnt = (i2sclock / (2 * srate)) - 1; 171 bitcnt = (i2sclock / (2 * srate)) - 1;
176 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US) 172 if (bitcnt < 0 || bitcnt > TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_MASK_US)
177 return -EINVAL; 173 return -EINVAL;
178 reg = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT; 174 val = bitcnt << TEGRA20_I2S_TIMING_CHANNEL_BIT_COUNT_SHIFT;
179 175
180 if (i2sclock % (2 * srate)) 176 if (i2sclock % (2 * srate))
181 reg |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE; 177 val |= TEGRA20_I2S_TIMING_NON_SYM_ENABLE;
182 178
183 tegra20_i2s_write(i2s, TEGRA20_I2S_TIMING, reg); 179 regmap_write(i2s->regmap, TEGRA20_I2S_TIMING, val);
184 180
185 tegra20_i2s_write(i2s, TEGRA20_I2S_FIFO_SCR, 181 regmap_write(i2s->regmap, TEGRA20_I2S_FIFO_SCR,
186 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | 182 TEGRA20_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS |
187 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); 183 TEGRA20_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS);
188 184
189 return 0; 185 return 0;
190} 186}
191 187
192static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s) 188static void tegra20_i2s_start_playback(struct tegra20_i2s *i2s)
193{ 189{
194 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO1_ENABLE; 190 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
195 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 191 TEGRA20_I2S_CTRL_FIFO1_ENABLE,
192 TEGRA20_I2S_CTRL_FIFO1_ENABLE);
196} 193}
197 194
198static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s) 195static void tegra20_i2s_stop_playback(struct tegra20_i2s *i2s)
199{ 196{
200 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO1_ENABLE; 197 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
201 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 198 TEGRA20_I2S_CTRL_FIFO1_ENABLE, 0);
202} 199}
203 200
204static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s) 201static void tegra20_i2s_start_capture(struct tegra20_i2s *i2s)
205{ 202{
206 i2s->reg_ctrl |= TEGRA20_I2S_CTRL_FIFO2_ENABLE; 203 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
207 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 204 TEGRA20_I2S_CTRL_FIFO2_ENABLE,
205 TEGRA20_I2S_CTRL_FIFO2_ENABLE);
208} 206}
209 207
210static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s) 208static void tegra20_i2s_stop_capture(struct tegra20_i2s *i2s)
211{ 209{
212 i2s->reg_ctrl &= ~TEGRA20_I2S_CTRL_FIFO2_ENABLE; 210 regmap_update_bits(i2s->regmap, TEGRA20_I2S_CTRL,
213 tegra20_i2s_write(i2s, TEGRA20_I2S_CTRL, i2s->reg_ctrl); 211 TEGRA20_I2S_CTRL_FIFO2_ENABLE, 0);
214} 212}
215 213
216static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 214static int tegra20_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -261,12 +259,14 @@ static const struct snd_soc_dai_ops tegra20_i2s_dai_ops = {
261static const struct snd_soc_dai_driver tegra20_i2s_dai_template = { 259static const struct snd_soc_dai_driver tegra20_i2s_dai_template = {
262 .probe = tegra20_i2s_probe, 260 .probe = tegra20_i2s_probe,
263 .playback = { 261 .playback = {
262 .stream_name = "Playback",
264 .channels_min = 2, 263 .channels_min = 2,
265 .channels_max = 2, 264 .channels_max = 2,
266 .rates = SNDRV_PCM_RATE_8000_96000, 265 .rates = SNDRV_PCM_RATE_8000_96000,
267 .formats = SNDRV_PCM_FMTBIT_S16_LE, 266 .formats = SNDRV_PCM_FMTBIT_S16_LE,
268 }, 267 },
269 .capture = { 268 .capture = {
269 .stream_name = "Capture",
270 .channels_min = 2, 270 .channels_min = 2,
271 .channels_max = 2, 271 .channels_max = 2,
272 .rates = SNDRV_PCM_RATE_8000_96000, 272 .rates = SNDRV_PCM_RATE_8000_96000,
@@ -412,8 +412,6 @@ static __devinit int tegra20_i2s_platform_probe(struct platform_device *pdev)
412 i2s->playback_dma_data.width = 32; 412 i2s->playback_dma_data.width = 32;
413 i2s->playback_dma_data.req_sel = dma_ch; 413 i2s->playback_dma_data.req_sel = dma_ch;
414 414
415 i2s->reg_ctrl = TEGRA20_I2S_CTRL_FIFO_FORMAT_PACKED;
416
417 pm_runtime_enable(&pdev->dev); 415 pm_runtime_enable(&pdev->dev);
418 if (!pm_runtime_enabled(&pdev->dev)) { 416 if (!pm_runtime_enabled(&pdev->dev)) {
419 ret = tegra20_i2s_runtime_resume(&pdev->dev); 417 ret = tegra20_i2s_runtime_resume(&pdev->dev);
diff --git a/sound/soc/tegra/tegra20_i2s.h b/sound/soc/tegra/tegra20_i2s.h
index a57efc6a597..c27069d24d7 100644
--- a/sound/soc/tegra/tegra20_i2s.h
+++ b/sound/soc/tegra/tegra20_i2s.h
@@ -158,7 +158,6 @@ struct tegra20_i2s {
158 struct tegra_pcm_dma_params capture_dma_data; 158 struct tegra_pcm_dma_params capture_dma_data;
159 struct tegra_pcm_dma_params playback_dma_data; 159 struct tegra_pcm_dma_params playback_dma_data;
160 struct regmap *regmap; 160 struct regmap *regmap;
161 u32 reg_ctrl;
162}; 161};
163 162
164#endif 163#endif
diff --git a/sound/soc/tegra/tegra20_spdif.c b/sound/soc/tegra/tegra20_spdif.c
index f9b57418bd0..3ebc8670ba0 100644
--- a/sound/soc/tegra/tegra20_spdif.c
+++ b/sound/soc/tegra/tegra20_spdif.c
@@ -37,24 +37,11 @@
37 37
38#define DRV_NAME "tegra20-spdif" 38#define DRV_NAME "tegra20-spdif"
39 39
40static inline void tegra20_spdif_write(struct tegra20_spdif *spdif, u32 reg,
41 u32 val)
42{
43 regmap_write(spdif->regmap, reg, val);
44}
45
46static inline u32 tegra20_spdif_read(struct tegra20_spdif *spdif, u32 reg)
47{
48 u32 val;
49 regmap_read(spdif->regmap, reg, &val);
50 return val;
51}
52
53static int tegra20_spdif_runtime_suspend(struct device *dev) 40static int tegra20_spdif_runtime_suspend(struct device *dev)
54{ 41{
55 struct tegra20_spdif *spdif = dev_get_drvdata(dev); 42 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
56 43
57 clk_disable(spdif->clk_spdif_out); 44 clk_disable_unprepare(spdif->clk_spdif_out);
58 45
59 return 0; 46 return 0;
60} 47}
@@ -64,7 +51,7 @@ static int tegra20_spdif_runtime_resume(struct device *dev)
64 struct tegra20_spdif *spdif = dev_get_drvdata(dev); 51 struct tegra20_spdif *spdif = dev_get_drvdata(dev);
65 int ret; 52 int ret;
66 53
67 ret = clk_enable(spdif->clk_spdif_out); 54 ret = clk_prepare_enable(spdif->clk_spdif_out);
68 if (ret) { 55 if (ret) {
69 dev_err(dev, "clk_enable failed: %d\n", ret); 56 dev_err(dev, "clk_enable failed: %d\n", ret);
70 return ret; 57 return ret;
@@ -77,21 +64,24 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
77 struct snd_pcm_hw_params *params, 64 struct snd_pcm_hw_params *params,
78 struct snd_soc_dai *dai) 65 struct snd_soc_dai *dai)
79{ 66{
80 struct device *dev = substream->pcm->card->dev; 67 struct device *dev = dai->dev;
81 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai); 68 struct tegra20_spdif *spdif = snd_soc_dai_get_drvdata(dai);
69 unsigned int mask, val;
82 int ret, spdifclock; 70 int ret, spdifclock;
83 71
84 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_PACK; 72 mask = TEGRA20_SPDIF_CTRL_PACK |
85 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_BIT_MODE_MASK; 73 TEGRA20_SPDIF_CTRL_BIT_MODE_MASK;
86 switch (params_format(params)) { 74 switch (params_format(params)) {
87 case SNDRV_PCM_FORMAT_S16_LE: 75 case SNDRV_PCM_FORMAT_S16_LE:
88 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_PACK; 76 val = TEGRA20_SPDIF_CTRL_PACK |
89 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT; 77 TEGRA20_SPDIF_CTRL_BIT_MODE_16BIT;
90 break; 78 break;
91 default: 79 default:
92 return -EINVAL; 80 return -EINVAL;
93 } 81 }
94 82
83 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL, mask, val);
84
95 switch (params_rate(params)) { 85 switch (params_rate(params)) {
96 case 32000: 86 case 32000:
97 spdifclock = 4096000; 87 spdifclock = 4096000;
@@ -129,14 +119,15 @@ static int tegra20_spdif_hw_params(struct snd_pcm_substream *substream,
129 119
130static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif) 120static void tegra20_spdif_start_playback(struct tegra20_spdif *spdif)
131{ 121{
132 spdif->reg_ctrl |= TEGRA20_SPDIF_CTRL_TX_EN; 122 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
133 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); 123 TEGRA20_SPDIF_CTRL_TX_EN,
124 TEGRA20_SPDIF_CTRL_TX_EN);
134} 125}
135 126
136static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif) 127static void tegra20_spdif_stop_playback(struct tegra20_spdif *spdif)
137{ 128{
138 spdif->reg_ctrl &= ~TEGRA20_SPDIF_CTRL_TX_EN; 129 regmap_update_bits(spdif->regmap, TEGRA20_SPDIF_CTRL,
139 tegra20_spdif_write(spdif, TEGRA20_SPDIF_CTRL, spdif->reg_ctrl); 130 TEGRA20_SPDIF_CTRL_TX_EN, 0);
140} 131}
141 132
142static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd, 133static int tegra20_spdif_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -181,6 +172,7 @@ static struct snd_soc_dai_driver tegra20_spdif_dai = {
181 .name = DRV_NAME, 172 .name = DRV_NAME,
182 .probe = tegra20_spdif_probe, 173 .probe = tegra20_spdif_probe,
183 .playback = { 174 .playback = {
175 .stream_name = "Playback",
184 .channels_min = 2, 176 .channels_min = 2,
185 .channels_max = 2, 177 .channels_max = 2,
186 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | 178 .rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |
diff --git a/sound/soc/tegra/tegra20_spdif.h b/sound/soc/tegra/tegra20_spdif.h
index ed756527efe..b48d699fd58 100644
--- a/sound/soc/tegra/tegra20_spdif.h
+++ b/sound/soc/tegra/tegra20_spdif.h
@@ -465,7 +465,6 @@ struct tegra20_spdif {
465 struct tegra_pcm_dma_params capture_dma_data; 465 struct tegra_pcm_dma_params capture_dma_data;
466 struct tegra_pcm_dma_params playback_dma_data; 466 struct tegra_pcm_dma_params playback_dma_data;
467 struct regmap *regmap; 467 struct regmap *regmap;
468 u32 reg_ctrl;
469}; 468};
470 469
471#endif 470#endif
diff --git a/sound/soc/tegra/tegra30_ahub.c b/sound/soc/tegra/tegra30_ahub.c
index f43edb364a1..bf5610122c7 100644
--- a/sound/soc/tegra/tegra30_ahub.c
+++ b/sound/soc/tegra/tegra30_ahub.c
@@ -56,8 +56,8 @@ static int tegra30_ahub_runtime_suspend(struct device *dev)
56 regcache_cache_only(ahub->regmap_apbif, true); 56 regcache_cache_only(ahub->regmap_apbif, true);
57 regcache_cache_only(ahub->regmap_ahub, true); 57 regcache_cache_only(ahub->regmap_ahub, true);
58 58
59 clk_disable(ahub->clk_apbif); 59 clk_disable_unprepare(ahub->clk_apbif);
60 clk_disable(ahub->clk_d_audio); 60 clk_disable_unprepare(ahub->clk_d_audio);
61 61
62 return 0; 62 return 0;
63} 63}
@@ -77,12 +77,12 @@ static int tegra30_ahub_runtime_resume(struct device *dev)
77{ 77{
78 int ret; 78 int ret;
79 79
80 ret = clk_enable(ahub->clk_d_audio); 80 ret = clk_prepare_enable(ahub->clk_d_audio);
81 if (ret) { 81 if (ret) {
82 dev_err(dev, "clk_enable d_audio failed: %d\n", ret); 82 dev_err(dev, "clk_enable d_audio failed: %d\n", ret);
83 return ret; 83 return ret;
84 } 84 }
85 ret = clk_enable(ahub->clk_apbif); 85 ret = clk_prepare_enable(ahub->clk_apbif);
86 if (ret) { 86 if (ret) {
87 dev_err(dev, "clk_enable apbif failed: %d\n", ret); 87 dev_err(dev, "clk_enable apbif failed: %d\n", ret);
88 clk_disable(ahub->clk_d_audio); 88 clk_disable(ahub->clk_d_audio);
diff --git a/sound/soc/tegra/tegra30_i2s.c b/sound/soc/tegra/tegra30_i2s.c
index 8596032985d..44184228d1f 100644
--- a/sound/soc/tegra/tegra30_i2s.c
+++ b/sound/soc/tegra/tegra30_i2s.c
@@ -44,25 +44,13 @@
44 44
45#define DRV_NAME "tegra30-i2s" 45#define DRV_NAME "tegra30-i2s"
46 46
47static inline void tegra30_i2s_write(struct tegra30_i2s *i2s, u32 reg, u32 val)
48{
49 regmap_write(i2s->regmap, reg, val);
50}
51
52static inline u32 tegra30_i2s_read(struct tegra30_i2s *i2s, u32 reg)
53{
54 u32 val;
55 regmap_read(i2s->regmap, reg, &val);
56 return val;
57}
58
59static int tegra30_i2s_runtime_suspend(struct device *dev) 47static int tegra30_i2s_runtime_suspend(struct device *dev)
60{ 48{
61 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 49 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
62 50
63 regcache_cache_only(i2s->regmap, true); 51 regcache_cache_only(i2s->regmap, true);
64 52
65 clk_disable(i2s->clk_i2s); 53 clk_disable_unprepare(i2s->clk_i2s);
66 54
67 return 0; 55 return 0;
68} 56}
@@ -72,7 +60,7 @@ static int tegra30_i2s_runtime_resume(struct device *dev)
72 struct tegra30_i2s *i2s = dev_get_drvdata(dev); 60 struct tegra30_i2s *i2s = dev_get_drvdata(dev);
73 int ret; 61 int ret;
74 62
75 ret = clk_enable(i2s->clk_i2s); 63 ret = clk_prepare_enable(i2s->clk_i2s);
76 if (ret) { 64 if (ret) {
77 dev_err(dev, "clk_enable failed: %d\n", ret); 65 dev_err(dev, "clk_enable failed: %d\n", ret);
78 return ret; 66 return ret;
@@ -128,6 +116,7 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
128 unsigned int fmt) 116 unsigned int fmt)
129{ 117{
130 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 118 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
119 unsigned int mask, val;
131 120
132 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 121 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
133 case SND_SOC_DAIFMT_NB_NF: 122 case SND_SOC_DAIFMT_NB_NF:
@@ -136,10 +125,10 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
136 return -EINVAL; 125 return -EINVAL;
137 } 126 }
138 127
139 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_MASTER_ENABLE; 128 mask = TEGRA30_I2S_CTRL_MASTER_ENABLE;
140 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 129 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
141 case SND_SOC_DAIFMT_CBS_CFS: 130 case SND_SOC_DAIFMT_CBS_CFS:
142 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_MASTER_ENABLE; 131 val = TEGRA30_I2S_CTRL_MASTER_ENABLE;
143 break; 132 break;
144 case SND_SOC_DAIFMT_CBM_CFM: 133 case SND_SOC_DAIFMT_CBM_CFM:
145 break; 134 break;
@@ -147,33 +136,37 @@ static int tegra30_i2s_set_fmt(struct snd_soc_dai *dai,
147 return -EINVAL; 136 return -EINVAL;
148 } 137 }
149 138
150 i2s->reg_ctrl &= ~(TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK | 139 mask |= TEGRA30_I2S_CTRL_FRAME_FORMAT_MASK |
151 TEGRA30_I2S_CTRL_LRCK_MASK); 140 TEGRA30_I2S_CTRL_LRCK_MASK;
152 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 141 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
153 case SND_SOC_DAIFMT_DSP_A: 142 case SND_SOC_DAIFMT_DSP_A:
154 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 143 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
155 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 144 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
156 break; 145 break;
157 case SND_SOC_DAIFMT_DSP_B: 146 case SND_SOC_DAIFMT_DSP_B:
158 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC; 147 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_FSYNC;
159 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_R_LOW; 148 val |= TEGRA30_I2S_CTRL_LRCK_R_LOW;
160 break; 149 break;
161 case SND_SOC_DAIFMT_I2S: 150 case SND_SOC_DAIFMT_I2S:
162 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 151 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
163 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 152 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
164 break; 153 break;
165 case SND_SOC_DAIFMT_RIGHT_J: 154 case SND_SOC_DAIFMT_RIGHT_J:
166 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 155 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
167 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 156 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
168 break; 157 break;
169 case SND_SOC_DAIFMT_LEFT_J: 158 case SND_SOC_DAIFMT_LEFT_J:
170 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK; 159 val |= TEGRA30_I2S_CTRL_FRAME_FORMAT_LRCK;
171 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_LRCK_L_LOW; 160 val |= TEGRA30_I2S_CTRL_LRCK_L_LOW;
172 break; 161 break;
173 default: 162 default:
174 return -EINVAL; 163 return -EINVAL;
175 } 164 }
176 165
166 pm_runtime_get_sync(dai->dev);
167 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
168 pm_runtime_put(dai->dev);
169
177 return 0; 170 return 0;
178} 171}
179 172
@@ -181,24 +174,26 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
181 struct snd_pcm_hw_params *params, 174 struct snd_pcm_hw_params *params,
182 struct snd_soc_dai *dai) 175 struct snd_soc_dai *dai)
183{ 176{
184 struct device *dev = substream->pcm->card->dev; 177 struct device *dev = dai->dev;
185 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai); 178 struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
186 u32 val; 179 unsigned int mask, val, reg;
187 int ret, sample_size, srate, i2sclock, bitcnt; 180 int ret, sample_size, srate, i2sclock, bitcnt;
188 181
189 if (params_channels(params) != 2) 182 if (params_channels(params) != 2)
190 return -EINVAL; 183 return -EINVAL;
191 184
192 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_BIT_SIZE_MASK; 185 mask = TEGRA30_I2S_CTRL_BIT_SIZE_MASK;
193 switch (params_format(params)) { 186 switch (params_format(params)) {
194 case SNDRV_PCM_FORMAT_S16_LE: 187 case SNDRV_PCM_FORMAT_S16_LE:
195 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_BIT_SIZE_16; 188 val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
196 sample_size = 16; 189 sample_size = 16;
197 break; 190 break;
198 default: 191 default:
199 return -EINVAL; 192 return -EINVAL;
200 } 193 }
201 194
195 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL, mask, val);
196
202 srate = params_rate(params); 197 srate = params_rate(params);
203 198
204 /* Final "* 2" required by Tegra hardware */ 199 /* Final "* 2" required by Tegra hardware */
@@ -219,7 +214,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
219 if (i2sclock % (2 * srate)) 214 if (i2sclock % (2 * srate))
220 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE; 215 val |= TEGRA30_I2S_TIMING_NON_SYM_ENABLE;
221 216
222 tegra30_i2s_write(i2s, TEGRA30_I2S_TIMING, val); 217 regmap_write(i2s->regmap, TEGRA30_I2S_TIMING, val);
223 218
224 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) | 219 val = (0 << TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT) |
225 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) | 220 (1 << TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT) |
@@ -229,15 +224,17 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
229 224
230 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 225 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
231 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX; 226 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_RX;
232 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_RX_CTRL, val); 227 reg = TEGRA30_I2S_CIF_RX_CTRL;
233 } else { 228 } else {
234 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX; 229 val |= TEGRA30_AUDIOCIF_CTRL_DIRECTION_TX;
235 tegra30_i2s_write(i2s, TEGRA30_I2S_CIF_TX_CTRL, val); 230 reg = TEGRA30_I2S_CIF_RX_CTRL;
236 } 231 }
237 232
233 regmap_write(i2s->regmap, reg, val);
234
238 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) | 235 val = (1 << TEGRA30_I2S_OFFSET_RX_DATA_OFFSET_SHIFT) |
239 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT); 236 (1 << TEGRA30_I2S_OFFSET_TX_DATA_OFFSET_SHIFT);
240 tegra30_i2s_write(i2s, TEGRA30_I2S_OFFSET, val); 237 regmap_write(i2s->regmap, TEGRA30_I2S_OFFSET, val);
241 238
242 return 0; 239 return 0;
243} 240}
@@ -245,29 +242,31 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
245static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s) 242static void tegra30_i2s_start_playback(struct tegra30_i2s *i2s)
246{ 243{
247 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif); 244 tegra30_ahub_enable_tx_fifo(i2s->playback_fifo_cif);
248 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_TX; 245 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
249 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 246 TEGRA30_I2S_CTRL_XFER_EN_TX,
247 TEGRA30_I2S_CTRL_XFER_EN_TX);
250} 248}
251 249
252static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s) 250static void tegra30_i2s_stop_playback(struct tegra30_i2s *i2s)
253{ 251{
254 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif); 252 tegra30_ahub_disable_tx_fifo(i2s->playback_fifo_cif);
255 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_TX; 253 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
256 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 254 TEGRA30_I2S_CTRL_XFER_EN_TX, 0);
257} 255}
258 256
259static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s) 257static void tegra30_i2s_start_capture(struct tegra30_i2s *i2s)
260{ 258{
261 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif); 259 tegra30_ahub_enable_rx_fifo(i2s->capture_fifo_cif);
262 i2s->reg_ctrl |= TEGRA30_I2S_CTRL_XFER_EN_RX; 260 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
263 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 261 TEGRA30_I2S_CTRL_XFER_EN_RX,
262 TEGRA30_I2S_CTRL_XFER_EN_RX);
264} 263}
265 264
266static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s) 265static void tegra30_i2s_stop_capture(struct tegra30_i2s *i2s)
267{ 266{
268 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif); 267 tegra30_ahub_disable_rx_fifo(i2s->capture_fifo_cif);
269 i2s->reg_ctrl &= ~TEGRA30_I2S_CTRL_XFER_EN_RX; 268 regmap_update_bits(i2s->regmap, TEGRA30_I2S_CTRL,
270 tegra30_i2s_write(i2s, TEGRA30_I2S_CTRL, i2s->reg_ctrl); 269 TEGRA30_I2S_CTRL_XFER_EN_RX, 0);
271} 270}
272 271
273static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd, 272static int tegra30_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
@@ -320,12 +319,14 @@ static struct snd_soc_dai_ops tegra30_i2s_dai_ops = {
320static const struct snd_soc_dai_driver tegra30_i2s_dai_template = { 319static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
321 .probe = tegra30_i2s_probe, 320 .probe = tegra30_i2s_probe,
322 .playback = { 321 .playback = {
322 .stream_name = "Playback",
323 .channels_min = 2, 323 .channels_min = 2,
324 .channels_max = 2, 324 .channels_max = 2,
325 .rates = SNDRV_PCM_RATE_8000_96000, 325 .rates = SNDRV_PCM_RATE_8000_96000,
326 .formats = SNDRV_PCM_FMTBIT_S16_LE, 326 .formats = SNDRV_PCM_FMTBIT_S16_LE,
327 }, 327 },
328 .capture = { 328 .capture = {
329 .stream_name = "Capture",
329 .channels_min = 2, 330 .channels_min = 2,
330 .channels_max = 2, 331 .channels_max = 2,
331 .rates = SNDRV_PCM_RATE_8000_96000, 332 .rates = SNDRV_PCM_RATE_8000_96000,
diff --git a/sound/soc/tegra/tegra30_i2s.h b/sound/soc/tegra/tegra30_i2s.h
index 91adf29c7a8..34dc47b9581 100644
--- a/sound/soc/tegra/tegra30_i2s.h
+++ b/sound/soc/tegra/tegra30_i2s.h
@@ -236,7 +236,6 @@ struct tegra30_i2s {
236 enum tegra30_ahub_txcif playback_fifo_cif; 236 enum tegra30_ahub_txcif playback_fifo_cif;
237 struct tegra_pcm_dma_params playback_dma_data; 237 struct tegra_pcm_dma_params playback_dma_data;
238 struct regmap *regmap; 238 struct regmap *regmap;
239 u32 reg_ctrl;
240}; 239};
241 240
242#endif 241#endif
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c
index 32de7006daf..d684df294c0 100644
--- a/sound/soc/tegra/tegra_alc5632.c
+++ b/sound/soc/tegra/tegra_alc5632.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver 2* tegra_alc5632.c -- Toshiba AC100(PAZ00) machine ASoC driver
3 * 3 *
4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net> 4 * Copyright (C) 2011 The AC100 Kernel Team <ac100@lists.lauchpad.net>
5 * Copyright (C) 2012 - NVIDIA, Inc. 5 * Copyright (C) 2012 - NVIDIA, Inc.
@@ -33,11 +33,8 @@
33 33
34#define DRV_NAME "tegra-alc5632" 34#define DRV_NAME "tegra-alc5632"
35 35
36#define GPIO_HP_DET BIT(0)
37
38struct tegra_alc5632 { 36struct tegra_alc5632 {
39 struct tegra_asoc_utils_data util_data; 37 struct tegra_asoc_utils_data util_data;
40 int gpio_requested;
41 int gpio_hp_det; 38 int gpio_hp_det;
42}; 39};
43 40
@@ -46,7 +43,7 @@ static int tegra_alc5632_asoc_hw_params(struct snd_pcm_substream *substream,
46{ 43{
47 struct snd_soc_pcm_runtime *rtd = substream->private_data; 44 struct snd_soc_pcm_runtime *rtd = substream->private_data;
48 struct snd_soc_dai *codec_dai = rtd->codec_dai; 45 struct snd_soc_dai *codec_dai = rtd->codec_dai;
49 struct snd_soc_codec *codec = rtd->codec; 46 struct snd_soc_codec *codec = codec_dai->codec;
50 struct snd_soc_card *card = codec->card; 47 struct snd_soc_card *card = codec->card;
51 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card); 48 struct tegra_alc5632 *alc5632 = snd_soc_card_get_drvdata(card);
52 int srate, mclk; 49 int srate, mclk;
@@ -108,9 +105,9 @@ static const struct snd_kcontrol_new tegra_alc5632_controls[] = {
108 105
109static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd) 106static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
110{ 107{
111 struct snd_soc_codec *codec = rtd->codec; 108 struct snd_soc_dai *codec_dai = rtd->codec_dai;
109 struct snd_soc_codec *codec = codec_dai->codec;
112 struct snd_soc_dapm_context *dapm = &codec->dapm; 110 struct snd_soc_dapm_context *dapm = &codec->dapm;
113 struct device_node *np = codec->card->dev->of_node;
114 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card); 111 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(codec->card);
115 112
116 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET, 113 snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET,
@@ -119,14 +116,11 @@ static int tegra_alc5632_asoc_init(struct snd_soc_pcm_runtime *rtd)
119 ARRAY_SIZE(tegra_alc5632_hs_jack_pins), 116 ARRAY_SIZE(tegra_alc5632_hs_jack_pins),
120 tegra_alc5632_hs_jack_pins); 117 tegra_alc5632_hs_jack_pins);
121 118
122 machine->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
123
124 if (gpio_is_valid(machine->gpio_hp_det)) { 119 if (gpio_is_valid(machine->gpio_hp_det)) {
125 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det; 120 tegra_alc5632_hp_jack_gpio.gpio = machine->gpio_hp_det;
126 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack, 121 snd_soc_jack_add_gpios(&tegra_alc5632_hs_jack,
127 1, 122 1,
128 &tegra_alc5632_hp_jack_gpio); 123 &tegra_alc5632_hp_jack_gpio);
129 machine->gpio_requested |= GPIO_HP_DET;
130 } 124 }
131 125
132 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1"); 126 snd_soc_dapm_force_enable_pin(dapm, "MICBIAS1");
@@ -159,6 +153,7 @@ static struct snd_soc_card snd_soc_tegra_alc5632 = {
159 153
160static __devinit int tegra_alc5632_probe(struct platform_device *pdev) 154static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
161{ 155{
156 struct device_node *np = pdev->dev.of_node;
162 struct snd_soc_card *card = &snd_soc_tegra_alc5632; 157 struct snd_soc_card *card = &snd_soc_tegra_alc5632;
163 struct tegra_alc5632 *alc5632; 158 struct tegra_alc5632 *alc5632;
164 int ret; 159 int ret;
@@ -181,6 +176,10 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
181 goto err; 176 goto err;
182 } 177 }
183 178
179 alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0);
180 if (alc5632->gpio_hp_det == -ENODEV)
181 return -EPROBE_DEFER;
182
184 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 183 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
185 if (ret) 184 if (ret)
186 goto err; 185 goto err;
@@ -199,16 +198,16 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev)
199 goto err; 198 goto err;
200 } 199 }
201 200
202 tegra_alc5632_dai.cpu_dai_of_node = of_parse_phandle( 201 tegra_alc5632_dai.cpu_of_node = of_parse_phandle(
203 pdev->dev.of_node, "nvidia,i2s-controller", 0); 202 pdev->dev.of_node, "nvidia,i2s-controller", 0);
204 if (!tegra_alc5632_dai.cpu_dai_of_node) { 203 if (!tegra_alc5632_dai.cpu_of_node) {
205 dev_err(&pdev->dev, 204 dev_err(&pdev->dev,
206 "Property 'nvidia,i2s-controller' missing or invalid\n"); 205 "Property 'nvidia,i2s-controller' missing or invalid\n");
207 ret = -EINVAL; 206 ret = -EINVAL;
208 goto err; 207 goto err;
209 } 208 }
210 209
211 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_dai_of_node; 210 tegra_alc5632_dai.platform_of_node = tegra_alc5632_dai.cpu_of_node;
212 211
213 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev); 212 ret = tegra_asoc_utils_init(&alc5632->util_data, &pdev->dev);
214 if (ret) 213 if (ret)
@@ -234,11 +233,8 @@ static int __devexit tegra_alc5632_remove(struct platform_device *pdev)
234 struct snd_soc_card *card = platform_get_drvdata(pdev); 233 struct snd_soc_card *card = platform_get_drvdata(pdev);
235 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card); 234 struct tegra_alc5632 *machine = snd_soc_card_get_drvdata(card);
236 235
237 if (machine->gpio_requested & GPIO_HP_DET) 236 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 1,
238 snd_soc_jack_free_gpios(&tegra_alc5632_hs_jack, 237 &tegra_alc5632_hp_jack_gpio);
239 1,
240 &tegra_alc5632_hp_jack_gpio);
241 machine->gpio_requested = 0;
242 238
243 snd_soc_unregister_card(card); 239 snd_soc_unregister_card(card);
244 240
diff --git a/sound/soc/tegra/tegra_asoc_utils.c b/sound/soc/tegra/tegra_asoc_utils.c
index 9515ce58ea0..6872c77a119 100644
--- a/sound/soc/tegra/tegra_asoc_utils.c
+++ b/sound/soc/tegra/tegra_asoc_utils.c
@@ -69,9 +69,9 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
69 data->set_baseclock = 0; 69 data->set_baseclock = 0;
70 data->set_mclk = 0; 70 data->set_mclk = 0;
71 71
72 clk_disable(data->clk_cdev1); 72 clk_disable_unprepare(data->clk_cdev1);
73 clk_disable(data->clk_pll_a_out0); 73 clk_disable_unprepare(data->clk_pll_a_out0);
74 clk_disable(data->clk_pll_a); 74 clk_disable_unprepare(data->clk_pll_a);
75 75
76 err = clk_set_rate(data->clk_pll_a, new_baseclock); 76 err = clk_set_rate(data->clk_pll_a, new_baseclock);
77 if (err) { 77 if (err) {
@@ -87,19 +87,19 @@ int tegra_asoc_utils_set_rate(struct tegra_asoc_utils_data *data, int srate,
87 87
88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */ 88 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
89 89
90 err = clk_enable(data->clk_pll_a); 90 err = clk_prepare_enable(data->clk_pll_a);
91 if (err) { 91 if (err) {
92 dev_err(data->dev, "Can't enable pll_a: %d\n", err); 92 dev_err(data->dev, "Can't enable pll_a: %d\n", err);
93 return err; 93 return err;
94 } 94 }
95 95
96 err = clk_enable(data->clk_pll_a_out0); 96 err = clk_prepare_enable(data->clk_pll_a_out0);
97 if (err) { 97 if (err) {
98 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err); 98 dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
99 return err; 99 return err;
100 } 100 }
101 101
102 err = clk_enable(data->clk_cdev1); 102 err = clk_prepare_enable(data->clk_cdev1);
103 if (err) { 103 if (err) {
104 dev_err(data->dev, "Can't enable cdev1: %d\n", err); 104 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
105 return err; 105 return err;
diff --git a/sound/soc/tegra/tegra_pcm.c b/sound/soc/tegra/tegra_pcm.c
index 127348dc09b..5658bcec193 100644
--- a/sound/soc/tegra/tegra_pcm.c
+++ b/sound/soc/tegra/tegra_pcm.c
@@ -36,6 +36,7 @@
36#include <sound/pcm.h> 36#include <sound/pcm.h>
37#include <sound/pcm_params.h> 37#include <sound/pcm_params.h>
38#include <sound/soc.h> 38#include <sound/soc.h>
39#include <sound/dmaengine_pcm.h>
39 40
40#include "tegra_pcm.h" 41#include "tegra_pcm.h"
41 42
@@ -56,6 +57,7 @@ static const struct snd_pcm_hardware tegra_pcm_hardware = {
56 .fifo_size = 4, 57 .fifo_size = 4,
57}; 58};
58 59
60#if defined(CONFIG_TEGRA_SYSTEM_DMA)
59static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd) 61static void tegra_pcm_queue_dma(struct tegra_runtime_data *prtd)
60{ 62{
61 struct snd_pcm_substream *substream = prtd->substream; 63 struct snd_pcm_substream *substream = prtd->substream;
@@ -285,6 +287,119 @@ static struct snd_pcm_ops tegra_pcm_ops = {
285 .pointer = tegra_pcm_pointer, 287 .pointer = tegra_pcm_pointer,
286 .mmap = tegra_pcm_mmap, 288 .mmap = tegra_pcm_mmap,
287}; 289};
290#else
291static int tegra_pcm_open(struct snd_pcm_substream *substream)
292{
293 struct snd_soc_pcm_runtime *rtd = substream->private_data;
294 struct device *dev = rtd->platform->dev;
295 int ret;
296
297 /* Set HW params now that initialization is complete */
298 snd_soc_set_runtime_hwparams(substream, &tegra_pcm_hardware);
299
300 ret = snd_dmaengine_pcm_open(substream, NULL, NULL);
301 if (ret) {
302 dev_err(dev, "dmaengine pcm open failed with err %d\n", ret);
303 return ret;
304 }
305
306 return 0;
307}
308
309static int tegra_pcm_close(struct snd_pcm_substream *substream)
310{
311 snd_dmaengine_pcm_close(substream);
312 return 0;
313}
314
315static int tegra_pcm_hw_params(struct snd_pcm_substream *substream,
316 struct snd_pcm_hw_params *params)
317{
318 struct snd_soc_pcm_runtime *rtd = substream->private_data;
319 struct device *dev = rtd->platform->dev;
320 struct dma_chan *chan = snd_dmaengine_pcm_get_chan(substream);
321 struct tegra_pcm_dma_params *dmap;
322 struct dma_slave_config slave_config;
323 int ret;
324
325 dmap = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
326
327 ret = snd_hwparams_to_dma_slave_config(substream, params,
328 &slave_config);
329 if (ret) {
330 dev_err(dev, "hw params config failed with err %d\n", ret);
331 return ret;
332 }
333
334 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
335 slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
336 slave_config.dst_addr = dmap->addr;
337 slave_config.src_maxburst = 0;
338 } else {
339 slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
340 slave_config.src_addr = dmap->addr;
341 slave_config.dst_maxburst = 0;
342 }
343 slave_config.slave_id = dmap->req_sel;
344
345 ret = dmaengine_slave_config(chan, &slave_config);
346 if (ret < 0) {
347 dev_err(dev, "dma slave config failed with err %d\n", ret);
348 return ret;
349 }
350
351 snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
352 return 0;
353}
354
355static int tegra_pcm_hw_free(struct snd_pcm_substream *substream)
356{
357 snd_pcm_set_runtime_buffer(substream, NULL);
358 return 0;
359}
360
361static int tegra_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
362{
363 switch (cmd) {
364 case SNDRV_PCM_TRIGGER_START:
365 case SNDRV_PCM_TRIGGER_RESUME:
366 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
367 return snd_dmaengine_pcm_trigger(substream,
368 SNDRV_PCM_TRIGGER_START);
369
370 case SNDRV_PCM_TRIGGER_STOP:
371 case SNDRV_PCM_TRIGGER_SUSPEND:
372 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
373 return snd_dmaengine_pcm_trigger(substream,
374 SNDRV_PCM_TRIGGER_STOP);
375 default:
376 return -EINVAL;
377 }
378 return 0;
379}
380
381static int tegra_pcm_mmap(struct snd_pcm_substream *substream,
382 struct vm_area_struct *vma)
383{
384 struct snd_pcm_runtime *runtime = substream->runtime;
385
386 return dma_mmap_writecombine(substream->pcm->card->dev, vma,
387 runtime->dma_area,
388 runtime->dma_addr,
389 runtime->dma_bytes);
390}
391
392static struct snd_pcm_ops tegra_pcm_ops = {
393 .open = tegra_pcm_open,
394 .close = tegra_pcm_close,
395 .ioctl = snd_pcm_lib_ioctl,
396 .hw_params = tegra_pcm_hw_params,
397 .hw_free = tegra_pcm_hw_free,
398 .trigger = tegra_pcm_trigger,
399 .pointer = snd_dmaengine_pcm_pointer,
400 .mmap = tegra_pcm_mmap,
401};
402#endif
288 403
289static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) 404static int tegra_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, int stream)
290{ 405{
diff --git a/sound/soc/tegra/tegra_pcm.h b/sound/soc/tegra/tegra_pcm.h
index 985d418a35e..a3a450352dc 100644
--- a/sound/soc/tegra/tegra_pcm.h
+++ b/sound/soc/tegra/tegra_pcm.h
@@ -40,6 +40,7 @@ struct tegra_pcm_dma_params {
40 unsigned long req_sel; 40 unsigned long req_sel;
41}; 41};
42 42
43#if defined(CONFIG_TEGRA_SYSTEM_DMA)
43struct tegra_runtime_data { 44struct tegra_runtime_data {
44 struct snd_pcm_substream *substream; 45 struct snd_pcm_substream *substream;
45 spinlock_t lock; 46 spinlock_t lock;
@@ -51,6 +52,7 @@ struct tegra_runtime_data {
51 struct tegra_dma_req dma_req[2]; 52 struct tegra_dma_req dma_req[2];
52 struct tegra_dma_channel *dma_chan; 53 struct tegra_dma_channel *dma_chan;
53}; 54};
55#endif
54 56
55int tegra_pcm_platform_register(struct device *dev); 57int tegra_pcm_platform_register(struct device *dev);
56void tegra_pcm_platform_unregister(struct device *dev); 58void tegra_pcm_platform_unregister(struct device *dev);
diff --git a/sound/soc/tegra/tegra_wm8753.c b/sound/soc/tegra/tegra_wm8753.c
index 4e77026807a..ea9166d5c4e 100644
--- a/sound/soc/tegra/tegra_wm8753.c
+++ b/sound/soc/tegra/tegra_wm8753.c
@@ -57,7 +57,7 @@ static int tegra_wm8753_hw_params(struct snd_pcm_substream *substream,
57{ 57{
58 struct snd_soc_pcm_runtime *rtd = substream->private_data; 58 struct snd_soc_pcm_runtime *rtd = substream->private_data;
59 struct snd_soc_dai *codec_dai = rtd->codec_dai; 59 struct snd_soc_dai *codec_dai = rtd->codec_dai;
60 struct snd_soc_codec *codec = rtd->codec; 60 struct snd_soc_codec *codec = codec_dai->codec;
61 struct snd_soc_card *card = codec->card; 61 struct snd_soc_card *card = codec->card;
62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card); 62 struct tegra_wm8753 *machine = snd_soc_card_get_drvdata(card);
63 int srate, mclk; 63 int srate, mclk;
@@ -157,9 +157,9 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
157 goto err; 157 goto err;
158 } 158 }
159 159
160 tegra_wm8753_dai.cpu_dai_of_node = of_parse_phandle( 160 tegra_wm8753_dai.cpu_of_node = of_parse_phandle(
161 pdev->dev.of_node, "nvidia,i2s-controller", 0); 161 pdev->dev.of_node, "nvidia,i2s-controller", 0);
162 if (!tegra_wm8753_dai.cpu_dai_of_node) { 162 if (!tegra_wm8753_dai.cpu_of_node) {
163 dev_err(&pdev->dev, 163 dev_err(&pdev->dev,
164 "Property 'nvidia,i2s-controller' missing or invalid\n"); 164 "Property 'nvidia,i2s-controller' missing or invalid\n");
165 ret = -EINVAL; 165 ret = -EINVAL;
@@ -167,7 +167,7 @@ static __devinit int tegra_wm8753_driver_probe(struct platform_device *pdev)
167 } 167 }
168 168
169 tegra_wm8753_dai.platform_of_node = 169 tegra_wm8753_dai.platform_of_node =
170 tegra_wm8753_dai.cpu_dai_of_node; 170 tegra_wm8753_dai.cpu_of_node;
171 171
172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev); 172 ret = tegra_asoc_utils_init(&machine->util_data, &pdev->dev);
173 if (ret) 173 if (ret)
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c
index 3b6da91188a..0c5bb33d258 100644
--- a/sound/soc/tegra/tegra_wm8903.c
+++ b/sound/soc/tegra/tegra_wm8903.c
@@ -28,8 +28,6 @@
28 * 28 *
29 */ 29 */
30 30
31#include <asm/mach-types.h>
32
33#include <linux/module.h> 31#include <linux/module.h>
34#include <linux/platform_device.h> 32#include <linux/platform_device.h>
35#include <linux/slab.h> 33#include <linux/slab.h>
@@ -50,16 +48,9 @@
50 48
51#define DRV_NAME "tegra-snd-wm8903" 49#define DRV_NAME "tegra-snd-wm8903"
52 50
53#define GPIO_SPKR_EN BIT(0)
54#define GPIO_HP_MUTE BIT(1)
55#define GPIO_INT_MIC_EN BIT(2)
56#define GPIO_EXT_MIC_EN BIT(3)
57#define GPIO_HP_DET BIT(4)
58
59struct tegra_wm8903 { 51struct tegra_wm8903 {
60 struct tegra_wm8903_platform_data pdata; 52 struct tegra_wm8903_platform_data pdata;
61 struct tegra_asoc_utils_data util_data; 53 struct tegra_asoc_utils_data util_data;
62 int gpio_requested;
63}; 54};
64 55
65static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream, 56static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
@@ -67,8 +58,7 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
67{ 58{
68 struct snd_soc_pcm_runtime *rtd = substream->private_data; 59 struct snd_soc_pcm_runtime *rtd = substream->private_data;
69 struct snd_soc_dai *codec_dai = rtd->codec_dai; 60 struct snd_soc_dai *codec_dai = rtd->codec_dai;
70 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 61 struct snd_soc_codec *codec = codec_dai->codec;
71 struct snd_soc_codec *codec = rtd->codec;
72 struct snd_soc_card *card = codec->card; 62 struct snd_soc_card *card = codec->card;
73 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 63 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
74 int srate, mclk; 64 int srate, mclk;
@@ -95,24 +85,6 @@ static int tegra_wm8903_hw_params(struct snd_pcm_substream *substream,
95 return err; 85 return err;
96 } 86 }
97 87
98 err = snd_soc_dai_set_fmt(codec_dai,
99 SND_SOC_DAIFMT_I2S |
100 SND_SOC_DAIFMT_NB_NF |
101 SND_SOC_DAIFMT_CBS_CFS);
102 if (err < 0) {
103 dev_err(card->dev, "codec_dai fmt not set\n");
104 return err;
105 }
106
107 err = snd_soc_dai_set_fmt(cpu_dai,
108 SND_SOC_DAIFMT_I2S |
109 SND_SOC_DAIFMT_NB_NF |
110 SND_SOC_DAIFMT_CBS_CFS);
111 if (err < 0) {
112 dev_err(card->dev, "cpu_dai fmt not set\n");
113 return err;
114 }
115
116 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 88 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
117 SND_SOC_CLOCK_IN); 89 SND_SOC_CLOCK_IN);
118 if (err < 0) { 90 if (err < 0) {
@@ -160,7 +132,7 @@ static int tegra_wm8903_event_int_spk(struct snd_soc_dapm_widget *w,
160 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 132 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
161 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 133 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
162 134
163 if (!(machine->gpio_requested & GPIO_SPKR_EN)) 135 if (!gpio_is_valid(pdata->gpio_spkr_en))
164 return 0; 136 return 0;
165 137
166 gpio_set_value_cansleep(pdata->gpio_spkr_en, 138 gpio_set_value_cansleep(pdata->gpio_spkr_en,
@@ -177,7 +149,7 @@ static int tegra_wm8903_event_hp(struct snd_soc_dapm_widget *w,
177 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 149 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
178 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 150 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
179 151
180 if (!(machine->gpio_requested & GPIO_HP_MUTE)) 152 if (!gpio_is_valid(pdata->gpio_hp_mute))
181 return 0; 153 return 0;
182 154
183 gpio_set_value_cansleep(pdata->gpio_hp_mute, 155 gpio_set_value_cansleep(pdata->gpio_hp_mute,
@@ -203,122 +175,18 @@ static const struct snd_soc_dapm_route harmony_audio_map[] = {
203 {"IN1L", NULL, "Mic Jack"}, 175 {"IN1L", NULL, "Mic Jack"},
204}; 176};
205 177
206static const struct snd_soc_dapm_route seaboard_audio_map[] = {
207 {"Headphone Jack", NULL, "HPOUTR"},
208 {"Headphone Jack", NULL, "HPOUTL"},
209 {"Int Spk", NULL, "ROP"},
210 {"Int Spk", NULL, "RON"},
211 {"Int Spk", NULL, "LOP"},
212 {"Int Spk", NULL, "LON"},
213 {"Mic Jack", NULL, "MICBIAS"},
214 {"IN1R", NULL, "Mic Jack"},
215};
216
217static const struct snd_soc_dapm_route kaen_audio_map[] = {
218 {"Headphone Jack", NULL, "HPOUTR"},
219 {"Headphone Jack", NULL, "HPOUTL"},
220 {"Int Spk", NULL, "ROP"},
221 {"Int Spk", NULL, "RON"},
222 {"Int Spk", NULL, "LOP"},
223 {"Int Spk", NULL, "LON"},
224 {"Mic Jack", NULL, "MICBIAS"},
225 {"IN2R", NULL, "Mic Jack"},
226};
227
228static const struct snd_soc_dapm_route aebl_audio_map[] = {
229 {"Headphone Jack", NULL, "HPOUTR"},
230 {"Headphone Jack", NULL, "HPOUTL"},
231 {"Int Spk", NULL, "LINEOUTR"},
232 {"Int Spk", NULL, "LINEOUTL"},
233 {"Mic Jack", NULL, "MICBIAS"},
234 {"IN1R", NULL, "Mic Jack"},
235};
236
237static const struct snd_kcontrol_new tegra_wm8903_controls[] = { 178static const struct snd_kcontrol_new tegra_wm8903_controls[] = {
238 SOC_DAPM_PIN_SWITCH("Int Spk"), 179 SOC_DAPM_PIN_SWITCH("Int Spk"),
239}; 180};
240 181
241static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd) 182static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
242{ 183{
243 struct snd_soc_codec *codec = rtd->codec; 184 struct snd_soc_dai *codec_dai = rtd->codec_dai;
185 struct snd_soc_codec *codec = codec_dai->codec;
244 struct snd_soc_dapm_context *dapm = &codec->dapm; 186 struct snd_soc_dapm_context *dapm = &codec->dapm;
245 struct snd_soc_card *card = codec->card; 187 struct snd_soc_card *card = codec->card;
246 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 188 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
247 struct tegra_wm8903_platform_data *pdata = &machine->pdata; 189 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
248 struct device_node *np = card->dev->of_node;
249 int ret;
250
251 if (card->dev->platform_data) {
252 memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
253 } else if (np) {
254 /*
255 * This part must be in init() rather than probe() in order to
256 * guarantee that the WM8903 has been probed, and hence its
257 * GPIO controller registered, which is a pre-condition for
258 * of_get_named_gpio() to be able to map the phandles in the
259 * properties to the controller node. Given this, all
260 * pdata handling is in init() for consistency.
261 */
262 pdata->gpio_spkr_en = of_get_named_gpio(np,
263 "nvidia,spkr-en-gpios", 0);
264 pdata->gpio_hp_mute = of_get_named_gpio(np,
265 "nvidia,hp-mute-gpios", 0);
266 pdata->gpio_hp_det = of_get_named_gpio(np,
267 "nvidia,hp-det-gpios", 0);
268 pdata->gpio_int_mic_en = of_get_named_gpio(np,
269 "nvidia,int-mic-en-gpios", 0);
270 pdata->gpio_ext_mic_en = of_get_named_gpio(np,
271 "nvidia,ext-mic-en-gpios", 0);
272 } else {
273 dev_err(card->dev, "No platform data supplied\n");
274 return -EINVAL;
275 }
276
277 if (gpio_is_valid(pdata->gpio_spkr_en)) {
278 ret = gpio_request(pdata->gpio_spkr_en, "spkr_en");
279 if (ret) {
280 dev_err(card->dev, "cannot get spkr_en gpio\n");
281 return ret;
282 }
283 machine->gpio_requested |= GPIO_SPKR_EN;
284
285 gpio_direction_output(pdata->gpio_spkr_en, 0);
286 }
287
288 if (gpio_is_valid(pdata->gpio_hp_mute)) {
289 ret = gpio_request(pdata->gpio_hp_mute, "hp_mute");
290 if (ret) {
291 dev_err(card->dev, "cannot get hp_mute gpio\n");
292 return ret;
293 }
294 machine->gpio_requested |= GPIO_HP_MUTE;
295
296 gpio_direction_output(pdata->gpio_hp_mute, 1);
297 }
298
299 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
300 ret = gpio_request(pdata->gpio_int_mic_en, "int_mic_en");
301 if (ret) {
302 dev_err(card->dev, "cannot get int_mic_en gpio\n");
303 return ret;
304 }
305 machine->gpio_requested |= GPIO_INT_MIC_EN;
306
307 /* Disable int mic; enable signal is active-high */
308 gpio_direction_output(pdata->gpio_int_mic_en, 0);
309 }
310
311 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
312 ret = gpio_request(pdata->gpio_ext_mic_en, "ext_mic_en");
313 if (ret) {
314 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
315 return ret;
316 }
317 machine->gpio_requested |= GPIO_EXT_MIC_EN;
318
319 /* Enable ext mic; enable signal is active-low */
320 gpio_direction_output(pdata->gpio_ext_mic_en, 0);
321 }
322 190
323 if (gpio_is_valid(pdata->gpio_hp_det)) { 191 if (gpio_is_valid(pdata->gpio_hp_det)) {
324 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det; 192 tegra_wm8903_hp_jack_gpio.gpio = pdata->gpio_hp_det;
@@ -330,7 +198,6 @@ static int tegra_wm8903_init(struct snd_soc_pcm_runtime *rtd)
330 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack, 198 snd_soc_jack_add_gpios(&tegra_wm8903_hp_jack,
331 1, 199 1,
332 &tegra_wm8903_hp_jack_gpio); 200 &tegra_wm8903_hp_jack_gpio);
333 machine->gpio_requested |= GPIO_HP_DET;
334 } 201 }
335 202
336 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE, 203 snd_soc_jack_new(codec, "Mic Jack", SND_JACK_MICROPHONE,
@@ -366,6 +233,9 @@ static struct snd_soc_dai_link tegra_wm8903_dai = {
366 .codec_dai_name = "wm8903-hifi", 233 .codec_dai_name = "wm8903-hifi",
367 .init = tegra_wm8903_init, 234 .init = tegra_wm8903_init,
368 .ops = &tegra_wm8903_ops, 235 .ops = &tegra_wm8903_ops,
236 .dai_fmt = SND_SOC_DAIFMT_I2S |
237 SND_SOC_DAIFMT_NB_NF |
238 SND_SOC_DAIFMT_CBS_CFS,
369}; 239};
370 240
371static struct snd_soc_card snd_soc_tegra_wm8903 = { 241static struct snd_soc_card snd_soc_tegra_wm8903 = {
@@ -385,8 +255,10 @@ static struct snd_soc_card snd_soc_tegra_wm8903 = {
385 255
386static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) 256static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
387{ 257{
258 struct device_node *np = pdev->dev.of_node;
388 struct snd_soc_card *card = &snd_soc_tegra_wm8903; 259 struct snd_soc_card *card = &snd_soc_tegra_wm8903;
389 struct tegra_wm8903 *machine; 260 struct tegra_wm8903 *machine;
261 struct tegra_wm8903_platform_data *pdata;
390 int ret; 262 int ret;
391 263
392 if (!pdev->dev.platform_data && !pdev->dev.of_node) { 264 if (!pdev->dev.platform_data && !pdev->dev.of_node) {
@@ -401,12 +273,42 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
401 ret = -ENOMEM; 273 ret = -ENOMEM;
402 goto err; 274 goto err;
403 } 275 }
276 pdata = &machine->pdata;
404 277
405 card->dev = &pdev->dev; 278 card->dev = &pdev->dev;
406 platform_set_drvdata(pdev, card); 279 platform_set_drvdata(pdev, card);
407 snd_soc_card_set_drvdata(card, machine); 280 snd_soc_card_set_drvdata(card, machine);
408 281
409 if (pdev->dev.of_node) { 282 if (pdev->dev.platform_data) {
283 memcpy(pdata, card->dev->platform_data, sizeof(*pdata));
284 } else if (np) {
285 pdata->gpio_spkr_en = of_get_named_gpio(np,
286 "nvidia,spkr-en-gpios", 0);
287 if (pdata->gpio_spkr_en == -ENODEV)
288 return -EPROBE_DEFER;
289
290 pdata->gpio_hp_mute = of_get_named_gpio(np,
291 "nvidia,hp-mute-gpios", 0);
292 if (pdata->gpio_hp_mute == -ENODEV)
293 return -EPROBE_DEFER;
294
295 pdata->gpio_hp_det = of_get_named_gpio(np,
296 "nvidia,hp-det-gpios", 0);
297 if (pdata->gpio_hp_det == -ENODEV)
298 return -EPROBE_DEFER;
299
300 pdata->gpio_int_mic_en = of_get_named_gpio(np,
301 "nvidia,int-mic-en-gpios", 0);
302 if (pdata->gpio_int_mic_en == -ENODEV)
303 return -EPROBE_DEFER;
304
305 pdata->gpio_ext_mic_en = of_get_named_gpio(np,
306 "nvidia,ext-mic-en-gpios", 0);
307 if (pdata->gpio_ext_mic_en == -ENODEV)
308 return -EPROBE_DEFER;
309 }
310
311 if (np) {
410 ret = snd_soc_of_parse_card_name(card, "nvidia,model"); 312 ret = snd_soc_of_parse_card_name(card, "nvidia,model");
411 if (ret) 313 if (ret)
412 goto err; 314 goto err;
@@ -417,8 +319,8 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
417 goto err; 319 goto err;
418 320
419 tegra_wm8903_dai.codec_name = NULL; 321 tegra_wm8903_dai.codec_name = NULL;
420 tegra_wm8903_dai.codec_of_node = of_parse_phandle( 322 tegra_wm8903_dai.codec_of_node = of_parse_phandle(np,
421 pdev->dev.of_node, "nvidia,audio-codec", 0); 323 "nvidia,audio-codec", 0);
422 if (!tegra_wm8903_dai.codec_of_node) { 324 if (!tegra_wm8903_dai.codec_of_node) {
423 dev_err(&pdev->dev, 325 dev_err(&pdev->dev,
424 "Property 'nvidia,audio-codec' missing or invalid\n"); 326 "Property 'nvidia,audio-codec' missing or invalid\n");
@@ -427,9 +329,9 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
427 } 329 }
428 330
429 tegra_wm8903_dai.cpu_dai_name = NULL; 331 tegra_wm8903_dai.cpu_dai_name = NULL;
430 tegra_wm8903_dai.cpu_dai_of_node = of_parse_phandle( 332 tegra_wm8903_dai.cpu_of_node = of_parse_phandle(np,
431 pdev->dev.of_node, "nvidia,i2s-controller", 0); 333 "nvidia,i2s-controller", 0);
432 if (!tegra_wm8903_dai.cpu_dai_of_node) { 334 if (!tegra_wm8903_dai.cpu_of_node) {
433 dev_err(&pdev->dev, 335 dev_err(&pdev->dev,
434 "Property 'nvidia,i2s-controller' missing or invalid\n"); 336 "Property 'nvidia,i2s-controller' missing or invalid\n");
435 ret = -EINVAL; 337 ret = -EINVAL;
@@ -438,20 +340,47 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev)
438 340
439 tegra_wm8903_dai.platform_name = NULL; 341 tegra_wm8903_dai.platform_name = NULL;
440 tegra_wm8903_dai.platform_of_node = 342 tegra_wm8903_dai.platform_of_node =
441 tegra_wm8903_dai.cpu_dai_of_node; 343 tegra_wm8903_dai.cpu_of_node;
442 } else { 344 } else {
443 if (machine_is_harmony()) { 345 card->dapm_routes = harmony_audio_map;
444 card->dapm_routes = harmony_audio_map; 346 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map);
445 card->num_dapm_routes = ARRAY_SIZE(harmony_audio_map); 347 }
446 } else if (machine_is_seaboard()) { 348
447 card->dapm_routes = seaboard_audio_map; 349 if (gpio_is_valid(pdata->gpio_spkr_en)) {
448 card->num_dapm_routes = ARRAY_SIZE(seaboard_audio_map); 350 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_spkr_en,
449 } else if (machine_is_kaen()) { 351 GPIOF_OUT_INIT_LOW, "spkr_en");
450 card->dapm_routes = kaen_audio_map; 352 if (ret) {
451 card->num_dapm_routes = ARRAY_SIZE(kaen_audio_map); 353 dev_err(card->dev, "cannot get spkr_en gpio\n");
452 } else { 354 return ret;
453 card->dapm_routes = aebl_audio_map; 355 }
454 card->num_dapm_routes = ARRAY_SIZE(aebl_audio_map); 356 }
357
358 if (gpio_is_valid(pdata->gpio_hp_mute)) {
359 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_hp_mute,
360 GPIOF_OUT_INIT_HIGH, "hp_mute");
361 if (ret) {
362 dev_err(card->dev, "cannot get hp_mute gpio\n");
363 return ret;
364 }
365 }
366
367 if (gpio_is_valid(pdata->gpio_int_mic_en)) {
368 /* Disable int mic; enable signal is active-high */
369 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_int_mic_en,
370 GPIOF_OUT_INIT_LOW, "int_mic_en");
371 if (ret) {
372 dev_err(card->dev, "cannot get int_mic_en gpio\n");
373 return ret;
374 }
375 }
376
377 if (gpio_is_valid(pdata->gpio_ext_mic_en)) {
378 /* Enable ext mic; enable signal is active-low */
379 ret = devm_gpio_request_one(&pdev->dev, pdata->gpio_ext_mic_en,
380 GPIOF_OUT_INIT_LOW, "ext_mic_en");
381 if (ret) {
382 dev_err(card->dev, "cannot get ext_mic_en gpio\n");
383 return ret;
455 } 384 }
456 } 385 }
457 386
@@ -478,21 +407,9 @@ static int __devexit tegra_wm8903_driver_remove(struct platform_device *pdev)
478{ 407{
479 struct snd_soc_card *card = platform_get_drvdata(pdev); 408 struct snd_soc_card *card = platform_get_drvdata(pdev);
480 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card); 409 struct tegra_wm8903 *machine = snd_soc_card_get_drvdata(card);
481 struct tegra_wm8903_platform_data *pdata = &machine->pdata;
482 410
483 if (machine->gpio_requested & GPIO_HP_DET) 411 snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 1,
484 snd_soc_jack_free_gpios(&tegra_wm8903_hp_jack, 412 &tegra_wm8903_hp_jack_gpio);
485 1,
486 &tegra_wm8903_hp_jack_gpio);
487 if (machine->gpio_requested & GPIO_EXT_MIC_EN)
488 gpio_free(pdata->gpio_ext_mic_en);
489 if (machine->gpio_requested & GPIO_INT_MIC_EN)
490 gpio_free(pdata->gpio_int_mic_en);
491 if (machine->gpio_requested & GPIO_HP_MUTE)
492 gpio_free(pdata->gpio_hp_mute);
493 if (machine->gpio_requested & GPIO_SPKR_EN)
494 gpio_free(pdata->gpio_spkr_en);
495 machine->gpio_requested = 0;
496 413
497 snd_soc_unregister_card(card); 414 snd_soc_unregister_card(card);
498 415
diff --git a/sound/soc/tegra/trimslice.c b/sound/soc/tegra/trimslice.c
index 4a8d5b672c9..e69a4f7000d 100644
--- a/sound/soc/tegra/trimslice.c
+++ b/sound/soc/tegra/trimslice.c
@@ -52,8 +52,7 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
52{ 52{
53 struct snd_soc_pcm_runtime *rtd = substream->private_data; 53 struct snd_soc_pcm_runtime *rtd = substream->private_data;
54 struct snd_soc_dai *codec_dai = rtd->codec_dai; 54 struct snd_soc_dai *codec_dai = rtd->codec_dai;
55 struct snd_soc_dai *cpu_dai = rtd->cpu_dai; 55 struct snd_soc_codec *codec = codec_dai->codec;
56 struct snd_soc_codec *codec = rtd->codec;
57 struct snd_soc_card *card = codec->card; 56 struct snd_soc_card *card = codec->card;
58 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card); 57 struct tegra_trimslice *trimslice = snd_soc_card_get_drvdata(card);
59 int srate, mclk; 58 int srate, mclk;
@@ -68,24 +67,6 @@ static int trimslice_asoc_hw_params(struct snd_pcm_substream *substream,
68 return err; 67 return err;
69 } 68 }
70 69
71 err = snd_soc_dai_set_fmt(codec_dai,
72 SND_SOC_DAIFMT_I2S |
73 SND_SOC_DAIFMT_NB_NF |
74 SND_SOC_DAIFMT_CBS_CFS);
75 if (err < 0) {
76 dev_err(card->dev, "codec_dai fmt not set\n");
77 return err;
78 }
79
80 err = snd_soc_dai_set_fmt(cpu_dai,
81 SND_SOC_DAIFMT_I2S |
82 SND_SOC_DAIFMT_NB_NF |
83 SND_SOC_DAIFMT_CBS_CFS);
84 if (err < 0) {
85 dev_err(card->dev, "cpu_dai fmt not set\n");
86 return err;
87 }
88
89 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, 70 err = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
90 SND_SOC_CLOCK_IN); 71 SND_SOC_CLOCK_IN);
91 if (err < 0) { 72 if (err < 0) {
@@ -121,6 +102,9 @@ static struct snd_soc_dai_link trimslice_tlv320aic23_dai = {
121 .cpu_dai_name = "tegra20-i2s.0", 102 .cpu_dai_name = "tegra20-i2s.0",
122 .codec_dai_name = "tlv320aic23-hifi", 103 .codec_dai_name = "tlv320aic23-hifi",
123 .ops = &trimslice_asoc_ops, 104 .ops = &trimslice_asoc_ops,
105 .dai_fmt = SND_SOC_DAIFMT_I2S |
106 SND_SOC_DAIFMT_NB_NF |
107 SND_SOC_DAIFMT_CBS_CFS,
124}; 108};
125 109
126static struct snd_soc_card snd_soc_trimslice = { 110static struct snd_soc_card snd_soc_trimslice = {
@@ -162,9 +146,9 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
162 } 146 }
163 147
164 trimslice_tlv320aic23_dai.cpu_dai_name = NULL; 148 trimslice_tlv320aic23_dai.cpu_dai_name = NULL;
165 trimslice_tlv320aic23_dai.cpu_dai_of_node = of_parse_phandle( 149 trimslice_tlv320aic23_dai.cpu_of_node = of_parse_phandle(
166 pdev->dev.of_node, "nvidia,i2s-controller", 0); 150 pdev->dev.of_node, "nvidia,i2s-controller", 0);
167 if (!trimslice_tlv320aic23_dai.cpu_dai_of_node) { 151 if (!trimslice_tlv320aic23_dai.cpu_of_node) {
168 dev_err(&pdev->dev, 152 dev_err(&pdev->dev,
169 "Property 'nvidia,i2s-controller' missing or invalid\n"); 153 "Property 'nvidia,i2s-controller' missing or invalid\n");
170 ret = -EINVAL; 154 ret = -EINVAL;
@@ -173,7 +157,7 @@ static __devinit int tegra_snd_trimslice_probe(struct platform_device *pdev)
173 157
174 trimslice_tlv320aic23_dai.platform_name = NULL; 158 trimslice_tlv320aic23_dai.platform_name = NULL;
175 trimslice_tlv320aic23_dai.platform_of_node = 159 trimslice_tlv320aic23_dai.platform_of_node =
176 trimslice_tlv320aic23_dai.cpu_dai_of_node; 160 trimslice_tlv320aic23_dai.cpu_of_node;
177 } 161 }
178 162
179 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev); 163 ret = tegra_asoc_utils_init(&trimslice->util_data, &pdev->dev);
diff --git a/sound/soc/ux500/Kconfig b/sound/soc/ux500/Kconfig
index 44cf43404cd..069330d82be 100644
--- a/sound/soc/ux500/Kconfig
+++ b/sound/soc/ux500/Kconfig
@@ -12,3 +12,21 @@ menuconfig SND_SOC_UX500
12config SND_SOC_UX500_PLAT_MSP_I2S 12config SND_SOC_UX500_PLAT_MSP_I2S
13 tristate 13 tristate
14 depends on SND_SOC_UX500 14 depends on SND_SOC_UX500
15
16config SND_SOC_UX500_PLAT_DMA
17 tristate "Platform - DB8500 (DMA)"
18 depends on SND_SOC_UX500
19 select SND_SOC_DMAENGINE_PCM
20 help
21 Say Y if you want to enable the Ux500 platform-driver.
22
23+config SND_SOC_UX500_MACH_MOP500
24+ tristate "Machine - MOP500 (Ux500 + AB8500)"
25 depends on AB8500_CORE && AB8500_GPADC && SND_SOC_UX500
26 select SND_SOC_AB8500_CODEC
27 select SND_SOC_UX500_PLAT_MSP_I2S
28 select SND_SOC_UX500_PLAT_DMA
29 help
30 Select this to enable the MOP500 machine-driver.
31 This will enable platform-drivers for: Ux500
32 This will enable codec-drivers for: AB8500
diff --git a/sound/soc/ux500/Makefile b/sound/soc/ux500/Makefile
index 19974c5a2ea..cce0c11a4d8 100644
--- a/sound/soc/ux500/Makefile
+++ b/sound/soc/ux500/Makefile
@@ -2,3 +2,9 @@
2 2
3snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o 3snd-soc-ux500-plat-msp-i2s-objs := ux500_msp_dai.o ux500_msp_i2s.o
4obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o 4obj-$(CONFIG_SND_SOC_UX500_PLAT_MSP_I2S) += snd-soc-ux500-plat-msp-i2s.o
5
6snd-soc-ux500-plat-dma-objs := ux500_pcm.o
7obj-$(CONFIG_SND_SOC_UX500_PLAT_DMA) += snd-soc-ux500-plat-dma.o
8
9snd-soc-ux500-mach-mop500-objs := mop500.o mop500_ab8500.o
10obj-$(CONFIG_SND_SOC_UX500_MACH_MOP500) += snd-soc-ux500-mach-mop500.o
diff --git a/sound/soc/ux500/mop500.c b/sound/soc/ux500/mop500.c
new file mode 100644
index 00000000000..31c4d26d035
--- /dev/null
+++ b/sound/soc/ux500/mop500.c
@@ -0,0 +1,113 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja (ola.o.lilja@stericsson.com)
5 * for ST-Ericsson.
6 *
7 * License terms:
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#include <asm/mach-types.h>
15
16#include <linux/module.h>
17#include <linux/io.h>
18#include <linux/spi/spi.h>
19
20#include <sound/soc.h>
21#include <sound/initval.h>
22
23#include "ux500_pcm.h"
24#include "ux500_msp_dai.h"
25
26#include <mop500_ab8500.h>
27
28/* Define the whole MOP500 soundcard, linking platform to the codec-drivers */
29struct snd_soc_dai_link mop500_dai_links[] = {
30 {
31 .name = "ab8500_0",
32 .stream_name = "ab8500_0",
33 .cpu_dai_name = "ux500-msp-i2s.1",
34 .codec_dai_name = "ab8500-codec-dai.0",
35 .platform_name = "ux500-pcm.0",
36 .codec_name = "ab8500-codec.0",
37 .init = mop500_ab8500_machine_init,
38 .ops = mop500_ab8500_ops,
39 },
40 {
41 .name = "ab8500_1",
42 .stream_name = "ab8500_1",
43 .cpu_dai_name = "ux500-msp-i2s.3",
44 .codec_dai_name = "ab8500-codec-dai.1",
45 .platform_name = "ux500-pcm.0",
46 .codec_name = "ab8500-codec.0",
47 .init = NULL,
48 .ops = mop500_ab8500_ops,
49 },
50};
51
52static struct snd_soc_card mop500_card = {
53 .name = "MOP500-card",
54 .probe = NULL,
55 .dai_link = mop500_dai_links,
56 .num_links = ARRAY_SIZE(mop500_dai_links),
57};
58
59static int __devinit mop500_probe(struct platform_device *pdev)
60{
61 int ret;
62
63 pr_debug("%s: Enter.\n", __func__);
64
65 dev_dbg(&pdev->dev, "%s: Enter.\n", __func__);
66
67 mop500_card.dev = &pdev->dev;
68
69 dev_dbg(&pdev->dev, "%s: Card %s: Set platform drvdata.\n",
70 __func__, mop500_card.name);
71 platform_set_drvdata(pdev, &mop500_card);
72
73 snd_soc_card_set_drvdata(&mop500_card, NULL);
74
75 dev_dbg(&pdev->dev, "%s: Card %s: num_links = %d\n",
76 __func__, mop500_card.name, mop500_card.num_links);
77 dev_dbg(&pdev->dev, "%s: Card %s: DAI-link 0: name = %s\n",
78 __func__, mop500_card.name, mop500_card.dai_link[0].name);
79 dev_dbg(&pdev->dev, "%s: Card %s: DAI-link 0: stream_name = %s\n",
80 __func__, mop500_card.name,
81 mop500_card.dai_link[0].stream_name);
82
83 ret = snd_soc_register_card(&mop500_card);
84 if (ret)
85 dev_err(&pdev->dev,
86 "Error: snd_soc_register_card failed (%d)!\n",
87 ret);
88
89 return ret;
90}
91
92static int __devexit mop500_remove(struct platform_device *pdev)
93{
94 struct snd_soc_card *mop500_card = platform_get_drvdata(pdev);
95
96 pr_debug("%s: Enter.\n", __func__);
97
98 snd_soc_unregister_card(mop500_card);
99 mop500_ab8500_remove(mop500_card);
100
101 return 0;
102}
103
104static struct platform_driver snd_soc_mop500_driver = {
105 .driver = {
106 .owner = THIS_MODULE,
107 .name = "snd-soc-mop500",
108 },
109 .probe = mop500_probe,
110 .remove = __devexit_p(mop500_remove),
111};
112
113module_platform_driver(snd_soc_mop500_driver);
diff --git a/sound/soc/ux500/mop500_ab8500.c b/sound/soc/ux500/mop500_ab8500.c
new file mode 100644
index 00000000000..78cce236693
--- /dev/null
+++ b/sound/soc/ux500/mop500_ab8500.c
@@ -0,0 +1,431 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Kristoffer Karlsson <kristoffer.karlsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <linux/module.h>
16#include <linux/device.h>
17#include <linux/io.h>
18#include <linux/clk.h>
19
20#include <mach/hardware.h>
21
22#include <sound/soc.h>
23#include <sound/soc-dapm.h>
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26
27#include "ux500_pcm.h"
28#include "ux500_msp_dai.h"
29#include "../codecs/ab8500-codec.h"
30
31#define TX_SLOT_MONO 0x0008
32#define TX_SLOT_STEREO 0x000a
33#define RX_SLOT_MONO 0x0001
34#define RX_SLOT_STEREO 0x0003
35#define TX_SLOT_8CH 0x00FF
36#define RX_SLOT_8CH 0x00FF
37
38#define DEF_TX_SLOTS TX_SLOT_STEREO
39#define DEF_RX_SLOTS RX_SLOT_MONO
40
41#define DRIVERMODE_NORMAL 0
42#define DRIVERMODE_CODEC_ONLY 1
43
44/* Slot configuration */
45static unsigned int tx_slots = DEF_TX_SLOTS;
46static unsigned int rx_slots = DEF_RX_SLOTS;
47
48/* Clocks */
49static const char * const enum_mclk[] = {
50 "SYSCLK",
51 "ULPCLK"
52};
53enum mclk {
54 MCLK_SYSCLK,
55 MCLK_ULPCLK,
56};
57
58static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_mclk, enum_mclk);
59
60/* Private data for machine-part MOP500<->AB8500 */
61struct mop500_ab8500_drvdata {
62 /* Clocks */
63 enum mclk mclk_sel;
64 struct clk *clk_ptr_intclk;
65 struct clk *clk_ptr_sysclk;
66 struct clk *clk_ptr_ulpclk;
67};
68
69static inline const char *get_mclk_str(enum mclk mclk_sel)
70{
71 switch (mclk_sel) {
72 case MCLK_SYSCLK:
73 return "SYSCLK";
74 case MCLK_ULPCLK:
75 return "ULPCLK";
76 default:
77 return "Unknown";
78 }
79}
80
81static int mop500_ab8500_set_mclk(struct device *dev,
82 struct mop500_ab8500_drvdata *drvdata)
83{
84 int status;
85 struct clk *clk_ptr;
86
87 if (IS_ERR(drvdata->clk_ptr_intclk)) {
88 dev_err(dev,
89 "%s: ERROR: intclk not initialized!\n", __func__);
90 return -EIO;
91 }
92
93 switch (drvdata->mclk_sel) {
94 case MCLK_SYSCLK:
95 clk_ptr = drvdata->clk_ptr_sysclk;
96 break;
97 case MCLK_ULPCLK:
98 clk_ptr = drvdata->clk_ptr_ulpclk;
99 break;
100 default:
101 return -EINVAL;
102 }
103
104 if (IS_ERR(clk_ptr)) {
105 dev_err(dev, "%s: ERROR: %s not initialized!\n", __func__,
106 get_mclk_str(drvdata->mclk_sel));
107 return -EIO;
108 }
109
110 status = clk_set_parent(drvdata->clk_ptr_intclk, clk_ptr);
111 if (status)
112 dev_err(dev,
113 "%s: ERROR: Setting intclk parent to %s failed (ret = %d)!",
114 __func__, get_mclk_str(drvdata->mclk_sel), status);
115 else
116 dev_dbg(dev,
117 "%s: intclk parent changed to %s.\n",
118 __func__, get_mclk_str(drvdata->mclk_sel));
119
120 return status;
121}
122
123/*
124 * Control-events
125 */
126
127static int mclk_input_control_get(struct snd_kcontrol *kcontrol,
128 struct snd_ctl_elem_value *ucontrol)
129{
130 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
131 struct mop500_ab8500_drvdata *drvdata =
132 snd_soc_card_get_drvdata(codec->card);
133
134 ucontrol->value.enumerated.item[0] = drvdata->mclk_sel;
135
136 return 0;
137}
138
139static int mclk_input_control_put(struct snd_kcontrol *kcontrol,
140 struct snd_ctl_elem_value *ucontrol)
141{
142 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
143 struct mop500_ab8500_drvdata *drvdata =
144 snd_soc_card_get_drvdata(codec->card);
145 unsigned int val = ucontrol->value.enumerated.item[0];
146
147 if (val > (unsigned int)MCLK_ULPCLK)
148 return -EINVAL;
149 if (drvdata->mclk_sel == val)
150 return 0;
151
152 drvdata->mclk_sel = val;
153
154 return 1;
155}
156
157/*
158 * Controls
159 */
160
161static struct snd_kcontrol_new mop500_ab8500_ctrls[] = {
162 SOC_ENUM_EXT("Master Clock Select",
163 soc_enum_mclk,
164 mclk_input_control_get, mclk_input_control_put),
165 /* Digital interface - Clocks */
166 SOC_SINGLE("Digital Interface Master Generator Switch",
167 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENMASTGEN,
168 1, 0),
169 SOC_SINGLE("Digital Interface 0 Bit-clock Switch",
170 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK0,
171 1, 0),
172 SOC_SINGLE("Digital Interface 1 Bit-clock Switch",
173 AB8500_DIGIFCONF1, AB8500_DIGIFCONF1_ENFSBITCLK1,
174 1, 0),
175 SOC_DAPM_PIN_SWITCH("Headset Left"),
176 SOC_DAPM_PIN_SWITCH("Headset Right"),
177 SOC_DAPM_PIN_SWITCH("Earpiece"),
178 SOC_DAPM_PIN_SWITCH("Speaker Left"),
179 SOC_DAPM_PIN_SWITCH("Speaker Right"),
180 SOC_DAPM_PIN_SWITCH("LineOut Left"),
181 SOC_DAPM_PIN_SWITCH("LineOut Right"),
182 SOC_DAPM_PIN_SWITCH("Vibra 1"),
183 SOC_DAPM_PIN_SWITCH("Vibra 2"),
184 SOC_DAPM_PIN_SWITCH("Mic 1"),
185 SOC_DAPM_PIN_SWITCH("Mic 2"),
186 SOC_DAPM_PIN_SWITCH("LineIn Left"),
187 SOC_DAPM_PIN_SWITCH("LineIn Right"),
188 SOC_DAPM_PIN_SWITCH("DMic 1"),
189 SOC_DAPM_PIN_SWITCH("DMic 2"),
190 SOC_DAPM_PIN_SWITCH("DMic 3"),
191 SOC_DAPM_PIN_SWITCH("DMic 4"),
192 SOC_DAPM_PIN_SWITCH("DMic 5"),
193 SOC_DAPM_PIN_SWITCH("DMic 6"),
194};
195
196/* ASoC */
197
198int mop500_ab8500_startup(struct snd_pcm_substream *substream)
199{
200 struct snd_soc_pcm_runtime *rtd = substream->private_data;
201
202 /* Set audio-clock source */
203 return mop500_ab8500_set_mclk(rtd->card->dev,
204 snd_soc_card_get_drvdata(rtd->card));
205}
206
207void mop500_ab8500_shutdown(struct snd_pcm_substream *substream)
208{
209 struct snd_soc_pcm_runtime *rtd = substream->private_data;
210 struct device *dev = rtd->card->dev;
211
212 dev_dbg(dev, "%s: Enter\n", __func__);
213
214 /* Reset slots configuration to default(s) */
215 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
216 tx_slots = DEF_TX_SLOTS;
217 else
218 rx_slots = DEF_RX_SLOTS;
219}
220
221int mop500_ab8500_hw_params(struct snd_pcm_substream *substream,
222 struct snd_pcm_hw_params *params)
223{
224 struct snd_soc_pcm_runtime *rtd = substream->private_data;
225 struct snd_soc_dai *codec_dai = rtd->codec_dai;
226 struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
227 struct device *dev = rtd->card->dev;
228 unsigned int fmt;
229 int channels, ret = 0, driver_mode, slots;
230 unsigned int sw_codec, sw_cpu;
231 bool is_playback;
232
233 dev_dbg(dev, "%s: Enter\n", __func__);
234
235 dev_dbg(dev, "%s: substream->pcm->name = %s\n"
236 "substream->pcm->id = %s.\n"
237 "substream->name = %s.\n"
238 "substream->number = %d.\n",
239 __func__,
240 substream->pcm->name,
241 substream->pcm->id,
242 substream->name,
243 substream->number);
244
245 channels = params_channels(params);
246
247 switch (params_format(params)) {
248 case SNDRV_PCM_FORMAT_S32_LE:
249 sw_cpu = 32;
250 break;
251
252 case SNDRV_PCM_FORMAT_S16_LE:
253 sw_cpu = 16;
254 break;
255
256 default:
257 return -EINVAL;
258 }
259
260 /* Setup codec depending on driver-mode */
261 if (channels == 8)
262 driver_mode = DRIVERMODE_CODEC_ONLY;
263 else
264 driver_mode = DRIVERMODE_NORMAL;
265 dev_dbg(dev, "%s: Driver-mode: %s.\n", __func__,
266 (driver_mode == DRIVERMODE_NORMAL) ? "NORMAL" : "CODEC_ONLY");
267
268 /* Setup format */
269
270 if (driver_mode == DRIVERMODE_NORMAL) {
271 fmt = SND_SOC_DAIFMT_DSP_A |
272 SND_SOC_DAIFMT_CBM_CFM |
273 SND_SOC_DAIFMT_NB_NF |
274 SND_SOC_DAIFMT_CONT;
275 } else {
276 fmt = SND_SOC_DAIFMT_DSP_A |
277 SND_SOC_DAIFMT_CBM_CFM |
278 SND_SOC_DAIFMT_NB_NF |
279 SND_SOC_DAIFMT_GATED;
280 }
281
282 ret = snd_soc_dai_set_fmt(codec_dai, fmt);
283 if (ret < 0) {
284 dev_err(dev,
285 "%s: ERROR: snd_soc_dai_set_fmt failed for codec_dai (ret = %d)!\n",
286 __func__, ret);
287 return ret;
288 }
289
290 ret = snd_soc_dai_set_fmt(cpu_dai, fmt);
291 if (ret < 0) {
292 dev_err(dev,
293 "%s: ERROR: snd_soc_dai_set_fmt failed for cpu_dai (ret = %d)!\n",
294 __func__, ret);
295 return ret;
296 }
297
298 /* Setup TDM-slots */
299
300 is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
301 switch (channels) {
302 case 1:
303 slots = 16;
304 tx_slots = (is_playback) ? TX_SLOT_MONO : 0;
305 rx_slots = (is_playback) ? 0 : RX_SLOT_MONO;
306 break;
307 case 2:
308 slots = 16;
309 tx_slots = (is_playback) ? TX_SLOT_STEREO : 0;
310 rx_slots = (is_playback) ? 0 : RX_SLOT_STEREO;
311 break;
312 case 8:
313 slots = 16;
314 tx_slots = (is_playback) ? TX_SLOT_8CH : 0;
315 rx_slots = (is_playback) ? 0 : RX_SLOT_8CH;
316 break;
317 default:
318 return -EINVAL;
319 }
320
321 if (driver_mode == DRIVERMODE_NORMAL)
322 sw_codec = sw_cpu;
323 else
324 sw_codec = 20;
325
326 dev_dbg(dev, "%s: CPU-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
327 tx_slots, rx_slots);
328 ret = snd_soc_dai_set_tdm_slot(cpu_dai, tx_slots, rx_slots, slots,
329 sw_cpu);
330 if (ret)
331 return ret;
332
333 dev_dbg(dev, "%s: CODEC-DAI TDM: TX=0x%04X RX=0x%04x\n", __func__,
334 tx_slots, rx_slots);
335 ret = snd_soc_dai_set_tdm_slot(codec_dai, tx_slots, rx_slots, slots,
336 sw_codec);
337 if (ret)
338 return ret;
339
340 return 0;
341}
342
343struct snd_soc_ops mop500_ab8500_ops[] = {
344 {
345 .hw_params = mop500_ab8500_hw_params,
346 .startup = mop500_ab8500_startup,
347 .shutdown = mop500_ab8500_shutdown,
348 }
349};
350
351int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *rtd)
352{
353 struct snd_soc_codec *codec = rtd->codec;
354 struct device *dev = rtd->card->dev;
355 struct mop500_ab8500_drvdata *drvdata;
356 int ret;
357
358 dev_dbg(dev, "%s Enter.\n", __func__);
359
360 /* Create driver private-data struct */
361 drvdata = devm_kzalloc(dev, sizeof(struct mop500_ab8500_drvdata),
362 GFP_KERNEL);
363 snd_soc_card_set_drvdata(rtd->card, drvdata);
364
365 /* Setup clocks */
366
367 drvdata->clk_ptr_sysclk = clk_get(dev, "sysclk");
368 if (IS_ERR(drvdata->clk_ptr_sysclk))
369 dev_warn(dev, "%s: WARNING: clk_get failed for 'sysclk'!\n",
370 __func__);
371 drvdata->clk_ptr_ulpclk = clk_get(dev, "ulpclk");
372 if (IS_ERR(drvdata->clk_ptr_ulpclk))
373 dev_warn(dev, "%s: WARNING: clk_get failed for 'ulpclk'!\n",
374 __func__);
375 drvdata->clk_ptr_intclk = clk_get(dev, "intclk");
376 if (IS_ERR(drvdata->clk_ptr_intclk))
377 dev_warn(dev, "%s: WARNING: clk_get failed for 'intclk'!\n",
378 __func__);
379
380 /* Set intclk default parent to ulpclk */
381 drvdata->mclk_sel = MCLK_ULPCLK;
382 ret = mop500_ab8500_set_mclk(dev, drvdata);
383 if (ret < 0)
384 dev_warn(dev, "%s: WARNING: mop500_ab8500_set_mclk!\n",
385 __func__);
386
387 drvdata->mclk_sel = MCLK_ULPCLK;
388
389 /* Add controls */
390 ret = snd_soc_add_codec_controls(codec, mop500_ab8500_ctrls,
391 ARRAY_SIZE(mop500_ab8500_ctrls));
392 if (ret < 0) {
393 pr_err("%s: Failed to add machine-controls (%d)!\n",
394 __func__, ret);
395 return ret;
396 }
397
398 ret = snd_soc_dapm_disable_pin(&codec->dapm, "Earpiece");
399 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Left");
400 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Speaker Right");
401 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Left");
402 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineOut Right");
403 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 1");
404 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Vibra 2");
405 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 1");
406 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "Mic 2");
407 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Left");
408 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "LineIn Right");
409 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 1");
410 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 2");
411 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 3");
412 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 4");
413 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 5");
414 ret |= snd_soc_dapm_disable_pin(&codec->dapm, "DMic 6");
415
416 return ret;
417}
418
419void mop500_ab8500_remove(struct snd_soc_card *card)
420{
421 struct mop500_ab8500_drvdata *drvdata = snd_soc_card_get_drvdata(card);
422
423 if (drvdata->clk_ptr_sysclk != NULL)
424 clk_put(drvdata->clk_ptr_sysclk);
425 if (drvdata->clk_ptr_ulpclk != NULL)
426 clk_put(drvdata->clk_ptr_ulpclk);
427 if (drvdata->clk_ptr_intclk != NULL)
428 clk_put(drvdata->clk_ptr_intclk);
429
430 snd_soc_card_set_drvdata(card, drvdata);
431}
diff --git a/sound/soc/ux500/mop500_ab8500.h b/sound/soc/ux500/mop500_ab8500.h
new file mode 100644
index 00000000000..cca5b33964b
--- /dev/null
+++ b/sound/soc/ux500/mop500_ab8500.h
@@ -0,0 +1,22 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>
5 * for ST-Ericsson.
6 *
7 * License terms:
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as published
11 * by the Free Software Foundation.
12 */
13
14#ifndef MOP500_AB8500_H
15#define MOP500_AB8500_H
16
17extern struct snd_soc_ops mop500_ab8500_ops[];
18
19int mop500_ab8500_machine_init(struct snd_soc_pcm_runtime *runtime);
20void mop500_ab8500_remove(struct snd_soc_card *card);
21
22#endif
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 93c6c40e724..62ac0285bfa 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -840,4 +840,4 @@ static struct platform_driver msp_i2s_driver = {
840}; 840};
841module_platform_driver(msp_i2s_driver); 841module_platform_driver(msp_i2s_driver);
842 842
843MODULE_LICENSE("GPLv2"); 843MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 496dec10c96..ee14d2dac2f 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -739,4 +739,4 @@ void ux500_msp_i2s_cleanup_msp(struct platform_device *pdev,
739 devm_kfree(&pdev->dev, msp); 739 devm_kfree(&pdev->dev, msp);
740} 740}
741 741
742MODULE_LICENSE("GPLv2"); 742MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_pcm.c b/sound/soc/ux500/ux500_pcm.c
new file mode 100644
index 00000000000..1a04e248453
--- /dev/null
+++ b/sound/soc/ux500/ux500_pcm.c
@@ -0,0 +1,318 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14
15#include <asm/page.h>
16
17#include <linux/module.h>
18#include <linux/dma-mapping.h>
19#include <linux/dmaengine.h>
20#include <linux/slab.h>
21
22#include <plat/ste_dma40.h>
23
24#include <sound/pcm.h>
25#include <sound/pcm_params.h>
26#include <sound/soc.h>
27#include <sound/dmaengine_pcm.h>
28
29#include "ux500_msp_i2s.h"
30#include "ux500_pcm.h"
31
32static struct snd_pcm_hardware ux500_pcm_hw_playback = {
33 .info = SNDRV_PCM_INFO_INTERLEAVED |
34 SNDRV_PCM_INFO_MMAP |
35 SNDRV_PCM_INFO_RESUME |
36 SNDRV_PCM_INFO_PAUSE,
37 .formats = SNDRV_PCM_FMTBIT_S16_LE |
38 SNDRV_PCM_FMTBIT_U16_LE |
39 SNDRV_PCM_FMTBIT_S16_BE |
40 SNDRV_PCM_FMTBIT_U16_BE,
41 .rates = SNDRV_PCM_RATE_KNOT,
42 .rate_min = UX500_PLATFORM_MIN_RATE_PLAYBACK,
43 .rate_max = UX500_PLATFORM_MAX_RATE_PLAYBACK,
44 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
45 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
46 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
47 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
48 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
49 .periods_min = UX500_PLATFORM_PERIODS_MIN,
50 .periods_max = UX500_PLATFORM_PERIODS_MAX,
51};
52
53static struct snd_pcm_hardware ux500_pcm_hw_capture = {
54 .info = SNDRV_PCM_INFO_INTERLEAVED |
55 SNDRV_PCM_INFO_MMAP |
56 SNDRV_PCM_INFO_RESUME |
57 SNDRV_PCM_INFO_PAUSE,
58 .formats = SNDRV_PCM_FMTBIT_S16_LE |
59 SNDRV_PCM_FMTBIT_U16_LE |
60 SNDRV_PCM_FMTBIT_S16_BE |
61 SNDRV_PCM_FMTBIT_U16_BE,
62 .rates = SNDRV_PCM_RATE_KNOT,
63 .rate_min = UX500_PLATFORM_MIN_RATE_CAPTURE,
64 .rate_max = UX500_PLATFORM_MAX_RATE_CAPTURE,
65 .channels_min = UX500_PLATFORM_MIN_CHANNELS,
66 .channels_max = UX500_PLATFORM_MAX_CHANNELS,
67 .buffer_bytes_max = UX500_PLATFORM_BUFFER_BYTES_MAX,
68 .period_bytes_min = UX500_PLATFORM_PERIODS_BYTES_MIN,
69 .period_bytes_max = UX500_PLATFORM_PERIODS_BYTES_MAX,
70 .periods_min = UX500_PLATFORM_PERIODS_MIN,
71 .periods_max = UX500_PLATFORM_PERIODS_MAX,
72};
73
74static void ux500_pcm_dma_hw_free(struct device *dev,
75 struct snd_pcm_substream *substream)
76{
77 struct snd_pcm_runtime *runtime = substream->runtime;
78 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
79
80 if (runtime->dma_area == NULL)
81 return;
82
83 if (buf != &substream->dma_buffer) {
84 dma_free_coherent(buf->dev.dev, buf->bytes, buf->area,
85 buf->addr);
86 kfree(runtime->dma_buffer_p);
87 }
88
89 snd_pcm_set_runtime_buffer(substream, NULL);
90}
91
92static int ux500_pcm_open(struct snd_pcm_substream *substream)
93{
94 int stream_id = substream->pstr->stream;
95 struct snd_pcm_runtime *runtime = substream->runtime;
96 struct snd_soc_pcm_runtime *rtd = substream->private_data;
97 struct snd_soc_dai *dai = rtd->cpu_dai;
98 struct device *dev = dai->dev;
99 int ret;
100 struct ux500_msp_dma_params *dma_params;
101 u16 per_data_width, mem_data_width;
102 struct stedma40_chan_cfg *dma_cfg;
103
104 dev_dbg(dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
105 snd_pcm_stream_str(substream));
106
107 dev_dbg(dev, "%s: Set runtime hwparams.\n", __func__);
108 if (stream_id == SNDRV_PCM_STREAM_PLAYBACK)
109 snd_soc_set_runtime_hwparams(substream,
110 &ux500_pcm_hw_playback);
111 else
112 snd_soc_set_runtime_hwparams(substream,
113 &ux500_pcm_hw_capture);
114
115 /* ensure that buffer size is a multiple of period size */
116 ret = snd_pcm_hw_constraint_integer(runtime,
117 SNDRV_PCM_HW_PARAM_PERIODS);
118 if (ret < 0) {
119 dev_err(dev, "%s: Error: snd_pcm_hw_constraints failed (%d)\n",
120 __func__, ret);
121 return ret;
122 }
123
124 dev_dbg(dev, "%s: Set hw-struct for %s.\n", __func__,
125 snd_pcm_stream_str(substream));
126 runtime->hw = (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ?
127 ux500_pcm_hw_playback : ux500_pcm_hw_capture;
128
129 mem_data_width = STEDMA40_HALFWORD_WIDTH;
130
131 dma_params = snd_soc_dai_get_dma_data(dai, substream);
132 switch (dma_params->data_size) {
133 case 32:
134 per_data_width = STEDMA40_WORD_WIDTH;
135 break;
136 case 16:
137 per_data_width = STEDMA40_HALFWORD_WIDTH;
138 break;
139 case 8:
140 per_data_width = STEDMA40_BYTE_WIDTH;
141 break;
142 default:
143 per_data_width = STEDMA40_WORD_WIDTH;
144 dev_warn(rtd->platform->dev,
145 "%s: Unknown data-size (%d)! Assuming 32 bits.\n",
146 __func__, dma_params->data_size);
147 }
148
149 dma_cfg = dma_params->dma_cfg;
150
151 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
152 dma_cfg->src_info.data_width = mem_data_width;
153 dma_cfg->dst_info.data_width = per_data_width;
154 } else {
155 dma_cfg->src_info.data_width = per_data_width;
156 dma_cfg->dst_info.data_width = mem_data_width;
157 }
158
159
160 ret = snd_dmaengine_pcm_open(substream, stedma40_filter, dma_cfg);
161 if (ret) {
162 dev_dbg(dai->dev,
163 "%s: ERROR: snd_dmaengine_pcm_open failed (%d)!\n",
164 __func__, ret);
165 return ret;
166 }
167
168 snd_dmaengine_pcm_set_data(substream, dma_cfg);
169
170 return 0;
171}
172
173static int ux500_pcm_close(struct snd_pcm_substream *substream)
174{
175 struct snd_soc_pcm_runtime *rtd = substream->private_data;
176 struct snd_soc_dai *dai = rtd->cpu_dai;
177
178 dev_dbg(dai->dev, "%s: Enter\n", __func__);
179
180 snd_dmaengine_pcm_close(substream);
181
182 return 0;
183}
184
185static int ux500_pcm_hw_params(struct snd_pcm_substream *substream,
186 struct snd_pcm_hw_params *hw_params)
187{
188 struct snd_pcm_runtime *runtime = substream->runtime;
189 struct snd_dma_buffer *buf = runtime->dma_buffer_p;
190 struct snd_soc_pcm_runtime *rtd = substream->private_data;
191 int ret = 0;
192 int size;
193
194 dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
195
196 size = params_buffer_bytes(hw_params);
197
198 if (buf) {
199 if (buf->bytes >= size)
200 goto out;
201 ux500_pcm_dma_hw_free(NULL, substream);
202 }
203
204 if (substream->dma_buffer.area != NULL &&
205 substream->dma_buffer.bytes >= size) {
206 buf = &substream->dma_buffer;
207 } else {
208 buf = kmalloc(sizeof(struct snd_dma_buffer), GFP_KERNEL);
209 if (!buf)
210 goto nomem;
211
212 buf->dev.type = SNDRV_DMA_TYPE_DEV;
213 buf->dev.dev = NULL;
214 buf->area = dma_alloc_coherent(NULL, size, &buf->addr,
215 GFP_KERNEL);
216 buf->bytes = size;
217 buf->private_data = NULL;
218
219 if (!buf->area)
220 goto free;
221 }
222 snd_pcm_set_runtime_buffer(substream, buf);
223 ret = 1;
224 out:
225 runtime->dma_bytes = size;
226 return ret;
227
228 free:
229 kfree(buf);
230 nomem:
231 return -ENOMEM;
232}
233
234static int ux500_pcm_hw_free(struct snd_pcm_substream *substream)
235{
236 struct snd_soc_pcm_runtime *rtd = substream->private_data;
237
238 dev_dbg(rtd->platform->dev, "%s: Enter\n", __func__);
239
240 ux500_pcm_dma_hw_free(NULL, substream);
241
242 return 0;
243}
244
245static int ux500_pcm_mmap(struct snd_pcm_substream *substream,
246 struct vm_area_struct *vma)
247{
248 struct snd_pcm_runtime *runtime = substream->runtime;
249 struct snd_soc_pcm_runtime *rtd = substream->private_data;
250
251 dev_dbg(rtd->platform->dev, "%s: Enter.\n", __func__);
252
253 return dma_mmap_coherent(NULL, vma, runtime->dma_area,
254 runtime->dma_addr, runtime->dma_bytes);
255}
256
257static struct snd_pcm_ops ux500_pcm_ops = {
258 .open = ux500_pcm_open,
259 .close = ux500_pcm_close,
260 .ioctl = snd_pcm_lib_ioctl,
261 .hw_params = ux500_pcm_hw_params,
262 .hw_free = ux500_pcm_hw_free,
263 .trigger = snd_dmaengine_pcm_trigger,
264 .pointer = snd_dmaengine_pcm_pointer_no_residue,
265 .mmap = ux500_pcm_mmap
266};
267
268int ux500_pcm_new(struct snd_soc_pcm_runtime *rtd)
269{
270 struct snd_pcm *pcm = rtd->pcm;
271
272 dev_dbg(rtd->platform->dev, "%s: Enter (id = '%s').\n", __func__,
273 pcm->id);
274
275 pcm->info_flags = 0;
276
277 return 0;
278}
279
280static struct snd_soc_platform_driver ux500_pcm_soc_drv = {
281 .ops = &ux500_pcm_ops,
282 .pcm_new = ux500_pcm_new,
283};
284
285static int __devexit ux500_pcm_drv_probe(struct platform_device *pdev)
286{
287 int ret;
288
289 ret = snd_soc_register_platform(&pdev->dev, &ux500_pcm_soc_drv);
290 if (ret < 0) {
291 dev_err(&pdev->dev,
292 "%s: ERROR: Failed to register platform '%s' (%d)!\n",
293 __func__, pdev->name, ret);
294 return ret;
295 }
296
297 return 0;
298}
299
300static int __devinit ux500_pcm_drv_remove(struct platform_device *pdev)
301{
302 snd_soc_unregister_platform(&pdev->dev);
303
304 return 0;
305}
306
307static struct platform_driver ux500_pcm_driver = {
308 .driver = {
309 .name = "ux500-pcm",
310 .owner = THIS_MODULE,
311 },
312
313 .probe = ux500_pcm_drv_probe,
314 .remove = __devexit_p(ux500_pcm_drv_remove),
315};
316module_platform_driver(ux500_pcm_driver);
317
318MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/ux500/ux500_pcm.h b/sound/soc/ux500/ux500_pcm.h
new file mode 100644
index 00000000000..77ed44d371e
--- /dev/null
+++ b/sound/soc/ux500/ux500_pcm.h
@@ -0,0 +1,35 @@
1/*
2 * Copyright (C) ST-Ericsson SA 2012
3 *
4 * Author: Ola Lilja <ola.o.lilja@stericsson.com>,
5 * Roger Nilsson <roger.xr.nilsson@stericsson.com>
6 * for ST-Ericsson.
7 *
8 * License terms:
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as published
12 * by the Free Software Foundation.
13 */
14#ifndef UX500_PCM_H
15#define UX500_PCM_H
16
17#include <asm/page.h>
18
19#include <linux/workqueue.h>
20
21#define UX500_PLATFORM_MIN_RATE_PLAYBACK 8000
22#define UX500_PLATFORM_MAX_RATE_PLAYBACK 48000
23#define UX500_PLATFORM_MIN_RATE_CAPTURE 8000
24#define UX500_PLATFORM_MAX_RATE_CAPTURE 48000
25
26#define UX500_PLATFORM_MIN_CHANNELS 1
27#define UX500_PLATFORM_MAX_CHANNELS 8
28
29#define UX500_PLATFORM_PERIODS_BYTES_MIN 128
30#define UX500_PLATFORM_PERIODS_BYTES_MAX (64 * PAGE_SIZE)
31#define UX500_PLATFORM_PERIODS_MIN 2
32#define UX500_PLATFORM_PERIODS_MAX 48
33#define UX500_PLATFORM_BUFFER_BYTES_MAX (2048 * PAGE_SIZE)
34
35#endif
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index 64aed432ae2..7da0d0aa72c 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -485,7 +485,7 @@ static int __devinit snd_probe(struct usb_interface *intf,
485 const struct usb_device_id *id) 485 const struct usb_device_id *id)
486{ 486{
487 int ret; 487 int ret;
488 struct snd_card *card; 488 struct snd_card *card = NULL;
489 struct usb_device *device = interface_to_usbdev(intf); 489 struct usb_device *device = interface_to_usbdev(intf);
490 490
491 ret = create_card(device, intf, &card); 491 ret = create_card(device, intf, &card);
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
index 41f4b691192..690000db0ec 100644
--- a/sound/usb/mixer_quirks.c
+++ b/sound/usb/mixer_quirks.c
@@ -42,6 +42,13 @@
42 42
43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; 43extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl;
44 44
45struct std_mono_table {
46 unsigned int unitid, control, cmask;
47 int val_type;
48 const char *name;
49 snd_kcontrol_tlv_rw_t *tlv_callback;
50};
51
45/* private_free callback */ 52/* private_free callback */
46static void usb_mixer_elem_free(struct snd_kcontrol *kctl) 53static void usb_mixer_elem_free(struct snd_kcontrol *kctl)
47{ 54{
@@ -114,6 +121,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer,
114} 121}
115 122
116/* 123/*
124 * Create a set of standard UAC controls from a table
125 */
126static int snd_create_std_mono_table(struct usb_mixer_interface *mixer,
127 struct std_mono_table *t)
128{
129 int err;
130
131 while (t->name != NULL) {
132 err = snd_create_std_mono_ctl(mixer, t->unitid, t->control,
133 t->cmask, t->val_type, t->name, t->tlv_callback);
134 if (err < 0)
135 return err;
136 t++;
137 }
138
139 return 0;
140}
141
142/*
117 * Sound Blaster remote control configuration 143 * Sound Blaster remote control configuration
118 * 144 *
119 * format of remote control data: 145 * format of remote control data:
@@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer)
916 return 0; 942 return 0;
917} 943}
918 944
919
920/*
921 * Create mixer for Electrix Ebox-44
922 *
923 * The mixer units from this device are corrupt, and even where they
924 * are valid they presents mono controls as L and R channels of
925 * stereo. So we create a good mixer in code.
926 */
927
928static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer)
929{
930 int err;
931
932 err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN,
933 "Headphone Playback Switch", NULL);
934 if (err < 0)
935 return err;
936 err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16,
937 "Headphone A Mix Playback Volume", NULL);
938 if (err < 0)
939 return err;
940 err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16,
941 "Headphone B Mix Playback Volume", NULL);
942 if (err < 0)
943 return err;
944
945 err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN,
946 "Output Playback Switch", NULL);
947 if (err < 0)
948 return err;
949 err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16,
950 "Output A Playback Volume", NULL);
951 if (err < 0)
952 return err;
953 err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16,
954 "Output B Playback Volume", NULL);
955 if (err < 0)
956 return err;
957
958 err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN,
959 "Input Capture Switch", NULL);
960 if (err < 0)
961 return err;
962 err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16,
963 "Input A Capture Volume", NULL);
964 if (err < 0)
965 return err;
966 err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16,
967 "Input B Capture Volume", NULL);
968 if (err < 0)
969 return err;
970
971 return 0;
972}
973
974void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, 945void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
975 unsigned char samplerate_id) 946 unsigned char samplerate_id)
976{ 947{
@@ -990,6 +961,81 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip,
990 } 961 }
991} 962}
992 963
964/*
965 * The mixer units for Ebox-44 are corrupt, and even where they
966 * are valid they presents mono controls as L and R channels of
967 * stereo. So we provide a good mixer here.
968 */
969struct std_mono_table ebox44_table[] = {
970 {
971 .unitid = 4,
972 .control = 1,
973 .cmask = 0x0,
974 .val_type = USB_MIXER_INV_BOOLEAN,
975 .name = "Headphone Playback Switch"
976 },
977 {
978 .unitid = 4,
979 .control = 2,
980 .cmask = 0x1,
981 .val_type = USB_MIXER_S16,
982 .name = "Headphone A Mix Playback Volume"
983 },
984 {
985 .unitid = 4,
986 .control = 2,
987 .cmask = 0x2,
988 .val_type = USB_MIXER_S16,
989 .name = "Headphone B Mix Playback Volume"
990 },
991
992 {
993 .unitid = 7,
994 .control = 1,
995 .cmask = 0x0,
996 .val_type = USB_MIXER_INV_BOOLEAN,
997 .name = "Output Playback Switch"
998 },
999 {
1000 .unitid = 7,
1001 .control = 2,
1002 .cmask = 0x1,
1003 .val_type = USB_MIXER_S16,
1004 .name = "Output A Playback Volume"
1005 },
1006 {
1007 .unitid = 7,
1008 .control = 2,
1009 .cmask = 0x2,
1010 .val_type = USB_MIXER_S16,
1011 .name = "Output B Playback Volume"
1012 },
1013
1014 {
1015 .unitid = 10,
1016 .control = 1,
1017 .cmask = 0x0,
1018 .val_type = USB_MIXER_INV_BOOLEAN,
1019 .name = "Input Capture Switch"
1020 },
1021 {
1022 .unitid = 10,
1023 .control = 2,
1024 .cmask = 0x1,
1025 .val_type = USB_MIXER_S16,
1026 .name = "Input A Capture Volume"
1027 },
1028 {
1029 .unitid = 10,
1030 .control = 2,
1031 .cmask = 0x2,
1032 .val_type = USB_MIXER_S16,
1033 .name = "Input B Capture Volume"
1034 },
1035
1036 {}
1037};
1038
993int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) 1039int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
994{ 1040{
995 int err = 0; 1041 int err = 0;
@@ -1035,7 +1081,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer)
1035 break; 1081 break;
1036 1082
1037 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ 1083 case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */
1038 err = snd_ebox44_create_mixer(mixer); 1084 /* detection is disabled in mixer_maps.c */
1085 err = snd_create_std_mono_table(mixer, ebox44_table);
1039 break; 1086 break;
1040 } 1087 }
1041 1088