diff options
| -rw-r--r-- | drivers/firmware/sigma.c | 81 | ||||
| -rw-r--r-- | include/linux/sigma.h | 13 | ||||
| -rw-r--r-- | sound/soc/atmel/Kconfig | 21 | ||||
| -rw-r--r-- | sound/soc/atmel/Makefile | 4 | ||||
| -rw-r--r-- | sound/soc/atmel/playpaq_wm8510.c | 473 | ||||
| -rw-r--r-- | sound/soc/codecs/ad1836.h | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/cs4270.c | 10 | ||||
| -rw-r--r-- | sound/soc/codecs/cs42l51.c | 2 | ||||
| -rw-r--r-- | sound/soc/codecs/max9877.c | 10 | ||||
| -rw-r--r-- | sound/soc/codecs/wm8994.c | 7 | ||||
| -rw-r--r-- | sound/soc/fsl/mpc8610_hpcd.c | 24 | ||||
| -rw-r--r-- | sound/soc/samsung/smdk_wm8994.c | 1 | ||||
| -rw-r--r-- | sound/soc/samsung/speyside.c | 2 | ||||
| -rw-r--r-- | sound/soc/soc-core.c | 6 |
14 files changed, 102 insertions, 554 deletions
diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c index f10fc521951b..1eedb6f7fdab 100644 --- a/drivers/firmware/sigma.c +++ b/drivers/firmware/sigma.c | |||
| @@ -14,13 +14,34 @@ | |||
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/sigma.h> | 15 | #include <linux/sigma.h> |
| 16 | 16 | ||
| 17 | /* Return: 0==OK, <0==error, =1 ==no more actions */ | 17 | static size_t sigma_action_size(struct sigma_action *sa) |
| 18 | { | ||
| 19 | size_t payload = 0; | ||
| 20 | |||
| 21 | switch (sa->instr) { | ||
| 22 | case SIGMA_ACTION_WRITEXBYTES: | ||
| 23 | case SIGMA_ACTION_WRITESINGLE: | ||
| 24 | case SIGMA_ACTION_WRITESAFELOAD: | ||
| 25 | payload = sigma_action_len(sa); | ||
| 26 | break; | ||
| 27 | default: | ||
| 28 | break; | ||
| 29 | } | ||
| 30 | |||
| 31 | payload = ALIGN(payload, 2); | ||
| 32 | |||
| 33 | return payload + sizeof(struct sigma_action); | ||
| 34 | } | ||
| 35 | |||
| 36 | /* | ||
| 37 | * Returns a negative error value in case of an error, 0 if processing of | ||
| 38 | * the firmware should be stopped after this action, 1 otherwise. | ||
| 39 | */ | ||
| 18 | static int | 40 | static int |
| 19 | process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) | 41 | process_sigma_action(struct i2c_client *client, struct sigma_action *sa) |
| 20 | { | 42 | { |
| 21 | struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos); | ||
| 22 | size_t len = sigma_action_len(sa); | 43 | size_t len = sigma_action_len(sa); |
| 23 | int ret = 0; | 44 | int ret; |
| 24 | 45 | ||
| 25 | pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, | 46 | pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, |
| 26 | sa->instr, sa->addr, len); | 47 | sa->instr, sa->addr, len); |
| @@ -29,44 +50,50 @@ process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) | |||
| 29 | case SIGMA_ACTION_WRITEXBYTES: | 50 | case SIGMA_ACTION_WRITEXBYTES: |
| 30 | case SIGMA_ACTION_WRITESINGLE: | 51 | case SIGMA_ACTION_WRITESINGLE: |
| 31 | case SIGMA_ACTION_WRITESAFELOAD: | 52 | case SIGMA_ACTION_WRITESAFELOAD: |
| 32 | if (ssfw->fw->size < ssfw->pos + len) | ||
| 33 | return -EINVAL; | ||
| 34 | ret = i2c_master_send(client, (void *)&sa->addr, len); | 53 | ret = i2c_master_send(client, (void *)&sa->addr, len); |
| 35 | if (ret < 0) | 54 | if (ret < 0) |
| 36 | return -EINVAL; | 55 | return -EINVAL; |
| 37 | break; | 56 | break; |
| 38 | |||
| 39 | case SIGMA_ACTION_DELAY: | 57 | case SIGMA_ACTION_DELAY: |
| 40 | ret = 0; | ||
| 41 | udelay(len); | 58 | udelay(len); |
| 42 | len = 0; | 59 | len = 0; |
| 43 | break; | 60 | break; |
| 44 | |||
| 45 | case SIGMA_ACTION_END: | 61 | case SIGMA_ACTION_END: |
| 46 | return 1; | 62 | return 0; |
| 47 | |||
| 48 | default: | 63 | default: |
| 49 | return -EINVAL; | 64 | return -EINVAL; |
| 50 | } | 65 | } |
| 51 | 66 | ||
| 52 | /* when arrive here ret=0 or sent data */ | 67 | return 1; |
| 53 | ssfw->pos += sigma_action_size(sa, len); | ||
| 54 | return ssfw->pos == ssfw->fw->size; | ||
| 55 | } | 68 | } |
| 56 | 69 | ||
| 57 | static int | 70 | static int |
| 58 | process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) | 71 | process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) |
| 59 | { | 72 | { |
| 60 | pr_debug("%s: processing %p\n", __func__, ssfw); | 73 | struct sigma_action *sa; |
| 74 | size_t size; | ||
| 75 | int ret; | ||
| 76 | |||
| 77 | while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { | ||
| 78 | sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); | ||
| 79 | |||
| 80 | size = sigma_action_size(sa); | ||
| 81 | ssfw->pos += size; | ||
| 82 | if (ssfw->pos > ssfw->fw->size || size == 0) | ||
| 83 | break; | ||
| 84 | |||
| 85 | ret = process_sigma_action(client, sa); | ||
| 61 | 86 | ||
| 62 | while (1) { | ||
| 63 | int ret = process_sigma_action(client, ssfw); | ||
| 64 | pr_debug("%s: action returned %i\n", __func__, ret); | 87 | pr_debug("%s: action returned %i\n", __func__, ret); |
| 65 | if (ret == 1) | 88 | |
| 66 | return 0; | 89 | if (ret <= 0) |
| 67 | else if (ret) | ||
| 68 | return ret; | 90 | return ret; |
| 69 | } | 91 | } |
| 92 | |||
| 93 | if (ssfw->pos != ssfw->fw->size) | ||
| 94 | return -EINVAL; | ||
| 95 | |||
| 96 | return 0; | ||
| 70 | } | 97 | } |
| 71 | 98 | ||
| 72 | int process_sigma_firmware(struct i2c_client *client, const char *name) | 99 | int process_sigma_firmware(struct i2c_client *client, const char *name) |
| @@ -89,16 +116,24 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) | |||
| 89 | 116 | ||
| 90 | /* then verify the header */ | 117 | /* then verify the header */ |
| 91 | ret = -EINVAL; | 118 | ret = -EINVAL; |
| 92 | if (fw->size < sizeof(*ssfw_head)) | 119 | |
| 120 | /* | ||
| 121 | * Reject too small or unreasonable large files. The upper limit has been | ||
| 122 | * chosen a bit arbitrarily, but it should be enough for all practical | ||
| 123 | * purposes and having the limit makes it easier to avoid integer | ||
| 124 | * overflows later in the loading process. | ||
| 125 | */ | ||
| 126 | if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) | ||
| 93 | goto done; | 127 | goto done; |
| 94 | 128 | ||
| 95 | ssfw_head = (void *)fw->data; | 129 | ssfw_head = (void *)fw->data; |
| 96 | if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) | 130 | if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) |
| 97 | goto done; | 131 | goto done; |
| 98 | 132 | ||
| 99 | crc = crc32(0, fw->data, fw->size); | 133 | crc = crc32(0, fw->data + sizeof(*ssfw_head), |
| 134 | fw->size - sizeof(*ssfw_head)); | ||
| 100 | pr_debug("%s: crc=%x\n", __func__, crc); | 135 | pr_debug("%s: crc=%x\n", __func__, crc); |
| 101 | if (crc != ssfw_head->crc) | 136 | if (crc != le32_to_cpu(ssfw_head->crc)) |
| 102 | goto done; | 137 | goto done; |
| 103 | 138 | ||
| 104 | ssfw.pos = sizeof(*ssfw_head); | 139 | ssfw.pos = sizeof(*ssfw_head); |
diff --git a/include/linux/sigma.h b/include/linux/sigma.h index e2accb3164d8..d0de882c0d96 100644 --- a/include/linux/sigma.h +++ b/include/linux/sigma.h | |||
| @@ -24,7 +24,7 @@ struct sigma_firmware { | |||
| 24 | struct sigma_firmware_header { | 24 | struct sigma_firmware_header { |
| 25 | unsigned char magic[7]; | 25 | unsigned char magic[7]; |
| 26 | u8 version; | 26 | u8 version; |
| 27 | u32 crc; | 27 | __le32 crc; |
| 28 | }; | 28 | }; |
| 29 | 29 | ||
| 30 | enum { | 30 | enum { |
| @@ -40,19 +40,14 @@ enum { | |||
| 40 | struct sigma_action { | 40 | struct sigma_action { |
| 41 | u8 instr; | 41 | u8 instr; |
| 42 | u8 len_hi; | 42 | u8 len_hi; |
| 43 | u16 len; | 43 | __le16 len; |
| 44 | u16 addr; | 44 | __be16 addr; |
| 45 | unsigned char payload[]; | 45 | unsigned char payload[]; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
| 48 | static inline u32 sigma_action_len(struct sigma_action *sa) | 48 | static inline u32 sigma_action_len(struct sigma_action *sa) |
| 49 | { | 49 | { |
| 50 | return (sa->len_hi << 16) | sa->len; | 50 | return (sa->len_hi << 16) | le16_to_cpu(sa->len); |
| 51 | } | ||
| 52 | |||
| 53 | static inline size_t sigma_action_size(struct sigma_action *sa, u32 payload_len) | ||
| 54 | { | ||
| 55 | return sizeof(*sa) + payload_len + (payload_len % 2); | ||
| 56 | } | 51 | } |
| 57 | 52 | ||
| 58 | extern int process_sigma_firmware(struct i2c_client *client, const char *name); | 53 | extern int process_sigma_firmware(struct i2c_client *client, const char *name); |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index bee3c94f58b0..d1fcc816ce97 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | config SND_ATMEL_SOC | 1 | config SND_ATMEL_SOC |
| 2 | tristate "SoC Audio for the Atmel System-on-Chip" | 2 | tristate "SoC Audio for the Atmel System-on-Chip" |
| 3 | depends on ARCH_AT91 || AVR32 | 3 | depends on ARCH_AT91 |
| 4 | help | 4 | help |
| 5 | Say Y or M if you want to add support for codecs attached to | 5 | Say Y or M if you want to add support for codecs attached to |
| 6 | the ATMEL SSC interface. You will also need | 6 | the ATMEL SSC interface. You will also need |
| @@ -24,25 +24,6 @@ config SND_AT91_SOC_SAM9G20_WM8731 | |||
| 24 | Say Y if you want to add support for SoC audio on WM8731-based | 24 | Say Y if you want to add support for SoC audio on WM8731-based |
| 25 | AT91sam9g20 evaluation board. | 25 | AT91sam9g20 evaluation board. |
| 26 | 26 | ||
| 27 | config SND_AT32_SOC_PLAYPAQ | ||
| 28 | tristate "SoC Audio support for PlayPaq with WM8510" | ||
| 29 | depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS | ||
| 30 | select SND_ATMEL_SOC_SSC | ||
| 31 | select SND_SOC_WM8510 | ||
| 32 | help | ||
| 33 | Say Y or M here if you want to add support for SoC audio | ||
| 34 | on the LRS PlayPaq. | ||
| 35 | |||
| 36 | config SND_AT32_SOC_PLAYPAQ_SLAVE | ||
| 37 | bool "Run CODEC on PlayPaq in slave mode" | ||
| 38 | depends on SND_AT32_SOC_PLAYPAQ | ||
| 39 | default n | ||
| 40 | help | ||
| 41 | Say Y if you want to run with the AT32 SSC generating the BCLK | ||
| 42 | and FRAME signals on the PlayPaq. Unless you want to play | ||
| 43 | with the AT32 as the SSC master, you probably want to say N here, | ||
| 44 | as this will give you better sound quality. | ||
| 45 | |||
| 46 | config SND_AT91_SOC_AFEB9260 | 27 | config SND_AT91_SOC_AFEB9260 |
| 47 | tristate "SoC Audio support for AFEB9260 board" | 28 | tristate "SoC Audio support for AFEB9260 board" |
| 48 | depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC | 29 | depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC |
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index e7ea56bd5f82..a5c0bf19da78 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile | |||
| @@ -8,9 +8,5 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o | |||
| 8 | # AT91 Machine Support | 8 | # AT91 Machine Support |
| 9 | snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o | 9 | snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o |
| 10 | 10 | ||
| 11 | # AT32 Machine Support | ||
| 12 | snd-soc-playpaq-objs := playpaq_wm8510.o | ||
| 13 | |||
| 14 | obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o | 11 | obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o |
| 15 | obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o | ||
| 16 | obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o | 12 | obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o |
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c deleted file mode 100644 index 73ae99ad4578..000000000000 --- a/sound/soc/atmel/playpaq_wm8510.c +++ /dev/null | |||
| @@ -1,473 +0,0 @@ | |||
| 1 | /* sound/soc/at32/playpaq_wm8510.c | ||
| 2 | * ASoC machine driver for PlayPaq using WM8510 codec | ||
| 3 | * | ||
| 4 | * Copyright (C) 2008 Long Range Systems | ||
| 5 | * Geoffrey Wossum <gwossum@acm.org> | ||
| 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 version 2 as | ||
| 9 | * published by the Free Software Foundation. | ||
| 10 | * | ||
| 11 | * This code is largely inspired by sound/soc/at91/eti_b1_wm8731.c | ||
| 12 | * | ||
| 13 | * NOTE: If you don't have the AT32 enhanced portmux configured (which | ||
| 14 | * isn't currently in the mainline or Atmel patched kernel), you will | ||
| 15 | * need to set the MCLK pin (PA30) to peripheral A in your board initialization | ||
| 16 | * code. Something like: | ||
| 17 | * at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); | ||
| 18 | * | ||
| 19 | */ | ||
| 20 | |||
| 21 | /* #define DEBUG */ | ||
| 22 | |||
| 23 | #include <linux/module.h> | ||
| 24 | #include <linux/moduleparam.h> | ||
| 25 | #include <linux/kernel.h> | ||
| 26 | #include <linux/errno.h> | ||
| 27 | #include <linux/clk.h> | ||
| 28 | #include <linux/timer.h> | ||
| 29 | #include <linux/interrupt.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | |||
| 32 | #include <sound/core.h> | ||
| 33 | #include <sound/pcm.h> | ||
| 34 | #include <sound/pcm_params.h> | ||
| 35 | #include <sound/soc.h> | ||
| 36 | |||
| 37 | #include <mach/at32ap700x.h> | ||
| 38 | #include <mach/portmux.h> | ||
| 39 | |||
| 40 | #include "../codecs/wm8510.h" | ||
| 41 | #include "atmel-pcm.h" | ||
| 42 | #include "atmel_ssc_dai.h" | ||
| 43 | |||
| 44 | |||
| 45 | /*-------------------------------------------------------------------------*\ | ||
| 46 | * constants | ||
| 47 | \*-------------------------------------------------------------------------*/ | ||
| 48 | #define MCLK_PIN GPIO_PIN_PA(30) | ||
| 49 | #define MCLK_PERIPH GPIO_PERIPH_A | ||
| 50 | |||
| 51 | |||
| 52 | /*-------------------------------------------------------------------------*\ | ||
| 53 | * data types | ||
| 54 | \*-------------------------------------------------------------------------*/ | ||
| 55 | /* SSC clocking data */ | ||
| 56 | struct ssc_clock_data { | ||
| 57 | /* CMR div */ | ||
| 58 | unsigned int cmr_div; | ||
| 59 | |||
| 60 | /* Frame period (as needed by xCMR.PERIOD) */ | ||
| 61 | unsigned int period; | ||
| 62 | |||
| 63 | /* The SSC clock rate these settings where calculated for */ | ||
| 64 | unsigned long ssc_rate; | ||
| 65 | }; | ||
| 66 | |||
| 67 | |||
| 68 | /*-------------------------------------------------------------------------*\ | ||
| 69 | * module data | ||
| 70 | \*-------------------------------------------------------------------------*/ | ||
| 71 | static struct clk *_gclk0; | ||
| 72 | static struct clk *_pll0; | ||
| 73 | |||
| 74 | #define CODEC_CLK (_gclk0) | ||
| 75 | |||
| 76 | |||
| 77 | /*-------------------------------------------------------------------------*\ | ||
| 78 | * Sound SOC operations | ||
| 79 | \*-------------------------------------------------------------------------*/ | ||
| 80 | #if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
| 81 | static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock( | ||
| 82 | struct snd_pcm_hw_params *params, | ||
| 83 | struct snd_soc_dai *cpu_dai) | ||
| 84 | { | ||
| 85 | struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 86 | struct ssc_device *ssc = ssc_p->ssc; | ||
| 87 | struct ssc_clock_data cd; | ||
| 88 | unsigned int rate, width_bits, channels; | ||
| 89 | unsigned int bitrate, ssc_div; | ||
| 90 | unsigned actual_rate; | ||
| 91 | |||
| 92 | |||
| 93 | /* | ||
| 94 | * Figure out required bitrate | ||
| 95 | */ | ||
| 96 | rate = params_rate(params); | ||
| 97 | channels = params_channels(params); | ||
| 98 | width_bits = snd_pcm_format_physical_width(params_format(params)); | ||
| 99 | bitrate = rate * width_bits * channels; | ||
| 100 | |||
| 101 | |||
| 102 | /* | ||
| 103 | * Figure out required SSC divider and period for required bitrate | ||
| 104 | */ | ||
| 105 | cd.ssc_rate = clk_get_rate(ssc->clk); | ||
| 106 | ssc_div = cd.ssc_rate / bitrate; | ||
| 107 | cd.cmr_div = ssc_div / 2; | ||
| 108 | if (ssc_div & 1) { | ||
| 109 | /* round cmr_div up */ | ||
| 110 | cd.cmr_div++; | ||
| 111 | } | ||
| 112 | cd.period = width_bits - 1; | ||
| 113 | |||
| 114 | |||
| 115 | /* | ||
| 116 | * Find actual rate, compare to requested rate | ||
| 117 | */ | ||
| 118 | actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1)); | ||
| 119 | pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n", | ||
| 120 | rate, actual_rate); | ||
| 121 | |||
| 122 | |||
| 123 | return cd; | ||
| 124 | } | ||
| 125 | #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ | ||
| 126 | |||
| 127 | |||
| 128 | |||
| 129 | static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, | ||
| 130 | struct snd_pcm_hw_params *params) | ||
| 131 | { | ||
| 132 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
| 133 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
| 134 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 135 | struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 136 | struct ssc_device *ssc = ssc_p->ssc; | ||
| 137 | unsigned int pll_out = 0, bclk = 0, mclk_div = 0; | ||
| 138 | int ret; | ||
| 139 | |||
| 140 | |||
| 141 | /* Due to difficulties with getting the correct clocks from the AT32's | ||
| 142 | * PLL0, we're going to let the CODEC be in charge of all the clocks | ||
| 143 | */ | ||
| 144 | #if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
| 145 | const unsigned int fmt = (SND_SOC_DAIFMT_I2S | | ||
| 146 | SND_SOC_DAIFMT_NB_NF | | ||
| 147 | SND_SOC_DAIFMT_CBM_CFM); | ||
| 148 | #else | ||
| 149 | struct ssc_clock_data cd; | ||
| 150 | const unsigned int fmt = (SND_SOC_DAIFMT_I2S | | ||
| 151 | SND_SOC_DAIFMT_NB_NF | | ||
| 152 | SND_SOC_DAIFMT_CBS_CFS); | ||
| 153 | #endif | ||
| 154 | |||
| 155 | if (ssc == NULL) { | ||
| 156 | pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n"); | ||
| 157 | return -EINVAL; | ||
| 158 | } | ||
| 159 | |||
| 160 | |||
| 161 | /* | ||
| 162 | * Figure out PLL and BCLK dividers for WM8510 | ||
| 163 | */ | ||
| 164 | switch (params_rate(params)) { | ||
| 165 | case 48000: | ||
| 166 | pll_out = 24576000; | ||
| 167 | mclk_div = WM8510_MCLKDIV_2; | ||
| 168 | bclk = WM8510_BCLKDIV_8; | ||
| 169 | break; | ||
| 170 | |||
| 171 | case 44100: | ||
| 172 | pll_out = 22579200; | ||
| 173 | mclk_div = WM8510_MCLKDIV_2; | ||
| 174 | bclk = WM8510_BCLKDIV_8; | ||
| 175 | break; | ||
| 176 | |||
| 177 | case 22050: | ||
| 178 | pll_out = 22579200; | ||
| 179 | mclk_div = WM8510_MCLKDIV_4; | ||
| 180 | bclk = WM8510_BCLKDIV_8; | ||
| 181 | break; | ||
| 182 | |||
| 183 | case 16000: | ||
| 184 | pll_out = 24576000; | ||
| 185 | mclk_div = WM8510_MCLKDIV_6; | ||
| 186 | bclk = WM8510_BCLKDIV_8; | ||
| 187 | break; | ||
| 188 | |||
| 189 | case 11025: | ||
| 190 | pll_out = 22579200; | ||
| 191 | mclk_div = WM8510_MCLKDIV_8; | ||
| 192 | bclk = WM8510_BCLKDIV_8; | ||
| 193 | break; | ||
| 194 | |||
| 195 | case 8000: | ||
| 196 | pll_out = 24576000; | ||
| 197 | mclk_div = WM8510_MCLKDIV_12; | ||
| 198 | bclk = WM8510_BCLKDIV_8; | ||
| 199 | break; | ||
| 200 | |||
| 201 | default: | ||
| 202 | pr_warning("playpaq_wm8510: Unsupported sample rate %d\n", | ||
| 203 | params_rate(params)); | ||
| 204 | return -EINVAL; | ||
| 205 | } | ||
| 206 | |||
| 207 | |||
| 208 | /* | ||
| 209 | * set CPU and CODEC DAI configuration | ||
| 210 | */ | ||
| 211 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
| 212 | if (ret < 0) { | ||
| 213 | pr_warning("playpaq_wm8510: " | ||
| 214 | "Failed to set CODEC DAI format (%d)\n", | ||
| 215 | ret); | ||
| 216 | return ret; | ||
| 217 | } | ||
| 218 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
| 219 | if (ret < 0) { | ||
| 220 | pr_warning("playpaq_wm8510: " | ||
| 221 | "Failed to set CPU DAI format (%d)\n", | ||
| 222 | ret); | ||
| 223 | return ret; | ||
| 224 | } | ||
| 225 | |||
| 226 | |||
| 227 | /* | ||
| 228 | * Set CPU clock configuration | ||
| 229 | */ | ||
| 230 | #if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
| 231 | cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai); | ||
| 232 | pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n", | ||
| 233 | cd.cmr_div, cd.period); | ||
| 234 | ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div); | ||
| 235 | if (ret < 0) { | ||
| 236 | pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n", | ||
| 237 | ret); | ||
| 238 | return ret; | ||
| 239 | } | ||
| 240 | ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD, | ||
| 241 | cd.period); | ||
| 242 | if (ret < 0) { | ||
| 243 | pr_warning("playpaq_wm8510: " | ||
| 244 | "Failed to set CPU transmit period (%d)\n", | ||
| 245 | ret); | ||
| 246 | return ret; | ||
| 247 | } | ||
| 248 | #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ | ||
| 249 | |||
| 250 | |||
| 251 | /* | ||
| 252 | * Set CODEC clock configuration | ||
| 253 | */ | ||
| 254 | pr_debug("playpaq_wm8510: " | ||
| 255 | "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n", | ||
| 256 | clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div); | ||
| 257 | |||
| 258 | |||
| 259 | #if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
| 260 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk); | ||
| 261 | if (ret < 0) { | ||
| 262 | pr_warning | ||
| 263 | ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n", | ||
| 264 | ret); | ||
| 265 | return ret; | ||
| 266 | } | ||
| 267 | #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ | ||
| 268 | |||
| 269 | |||
| 270 | ret = snd_soc_dai_set_pll(codec_dai, 0, 0, | ||
| 271 | clk_get_rate(CODEC_CLK), pll_out); | ||
| 272 | if (ret < 0) { | ||
| 273 | pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", | ||
| 274 | ret); | ||
| 275 | return ret; | ||
| 276 | } | ||
| 277 | |||
| 278 | |||
| 279 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div); | ||
| 280 | if (ret < 0) { | ||
| 281 | pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n", | ||
| 282 | ret); | ||
| 283 | return ret; | ||
| 284 | } | ||
| 285 | |||
| 286 | |||
| 287 | return 0; | ||
| 288 | } | ||
| 289 | |||
| 290 | |||
| 291 | |||
| 292 | static struct snd_soc_ops playpaq_wm8510_ops = { | ||
| 293 | .hw_params = playpaq_wm8510_hw_params, | ||
| 294 | }; | ||
| 295 | |||
| 296 | |||
| 297 | |||
| 298 | static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = { | ||
| 299 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
| 300 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
| 301 | }; | ||
| 302 | |||
| 303 | |||
| 304 | |||
| 305 | static const struct snd_soc_dapm_route intercon[] = { | ||
| 306 | /* speaker connected to SPKOUT */ | ||
| 307 | {"Ext Spk", NULL, "SPKOUTP"}, | ||
| 308 | {"Ext Spk", NULL, "SPKOUTN"}, | ||
| 309 | |||
| 310 | {"Mic Bias", NULL, "Int Mic"}, | ||
| 311 | {"MICN", NULL, "Mic Bias"}, | ||
| 312 | {"MICP", NULL, "Mic Bias"}, | ||
| 313 | }; | ||
| 314 | |||
| 315 | |||
| 316 | |||
| 317 | static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) | ||
| 318 | { | ||
| 319 | struct snd_soc_codec *codec = rtd->codec; | ||
| 320 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
| 321 | int i; | ||
| 322 | |||
| 323 | /* | ||
| 324 | * Add DAPM widgets | ||
| 325 | */ | ||
| 326 | for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) | ||
| 327 | snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]); | ||
| 328 | |||
| 329 | |||
| 330 | |||
| 331 | /* | ||
| 332 | * Setup audio path interconnects | ||
| 333 | */ | ||
| 334 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | ||
| 335 | |||
| 336 | |||
| 337 | |||
| 338 | /* always connected pins */ | ||
| 339 | snd_soc_dapm_enable_pin(dapm, "Int Mic"); | ||
| 340 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | ||
| 341 | |||
| 342 | |||
| 343 | |||
| 344 | /* Make CSB show PLL rate */ | ||
| 345 | snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV, | ||
| 346 | WM8510_OPCLKDIV_1 | 4); | ||
| 347 | |||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | |||
| 352 | |||
| 353 | static struct snd_soc_dai_link playpaq_wm8510_dai = { | ||
| 354 | .name = "WM8510", | ||
| 355 | .stream_name = "WM8510 PCM", | ||
| 356 | .cpu_dai_name= "atmel-ssc-dai.0", | ||
| 357 | .platform_name = "atmel-pcm-audio", | ||
| 358 | .codec_name = "wm8510-codec.0-0x1a", | ||
| 359 | .codec_dai_name = "wm8510-hifi", | ||
| 360 | .init = playpaq_wm8510_init, | ||
| 361 | .ops = &playpaq_wm8510_ops, | ||
| 362 | }; | ||
| 363 | |||
| 364 | |||
| 365 | |||
| 366 | static struct snd_soc_card snd_soc_playpaq = { | ||
| 367 | .name = "LRS_PlayPaq_WM8510", | ||
| 368 | .dai_link = &playpaq_wm8510_dai, | ||
| 369 | .num_links = 1, | ||
| 370 | }; | ||
| 371 | |||
| 372 | static struct platform_device *playpaq_snd_device; | ||
| 373 | |||
| 374 | |||
| 375 | static int __init playpaq_asoc_init(void) | ||
| 376 | { | ||
| 377 | int ret = 0; | ||
| 378 | |||
| 379 | /* | ||
| 380 | * Configure MCLK for WM8510 | ||
| 381 | */ | ||
| 382 | _gclk0 = clk_get(NULL, "gclk0"); | ||
| 383 | if (IS_ERR(_gclk0)) { | ||
| 384 | _gclk0 = NULL; | ||
| 385 | ret = PTR_ERR(_gclk0); | ||
| 386 | goto err_gclk0; | ||
| 387 | } | ||
| 388 | _pll0 = clk_get(NULL, "pll0"); | ||
| 389 | if (IS_ERR(_pll0)) { | ||
| 390 | _pll0 = NULL; | ||
| 391 | ret = PTR_ERR(_pll0); | ||
| 392 | goto err_pll0; | ||
| 393 | } | ||
| 394 | ret = clk_set_parent(_gclk0, _pll0); | ||
| 395 | if (ret) { | ||
| 396 | pr_warning("snd-soc-playpaq: " | ||
| 397 | "Failed to set PLL0 as parent for DAC clock\n"); | ||
| 398 | goto err_set_clk; | ||
| 399 | } | ||
| 400 | clk_set_rate(CODEC_CLK, 12000000); | ||
| 401 | clk_enable(CODEC_CLK); | ||
| 402 | |||
| 403 | #if defined CONFIG_AT32_ENHANCED_PORTMUX | ||
| 404 | at32_select_periph(MCLK_PIN, MCLK_PERIPH, 0); | ||
| 405 | #endif | ||
| 406 | |||
| 407 | |||
| 408 | /* | ||
| 409 | * Create and register platform device | ||
| 410 | */ | ||
| 411 | playpaq_snd_device = platform_device_alloc("soc-audio", 0); | ||
| 412 | if (playpaq_snd_device == NULL) { | ||
| 413 | ret = -ENOMEM; | ||
| 414 | goto err_device_alloc; | ||
| 415 | } | ||
| 416 | |||
| 417 | platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq); | ||
| 418 | |||
| 419 | ret = platform_device_add(playpaq_snd_device); | ||
| 420 | if (ret) { | ||
| 421 | pr_warning("playpaq_wm8510: platform_device_add failed (%d)\n", | ||
| 422 | ret); | ||
| 423 | goto err_device_add; | ||
| 424 | } | ||
| 425 | |||
| 426 | return 0; | ||
| 427 | |||
| 428 | |||
| 429 | err_device_add: | ||
| 430 | if (playpaq_snd_device != NULL) { | ||
| 431 | platform_device_put(playpaq_snd_device); | ||
| 432 | playpaq_snd_device = NULL; | ||
| 433 | } | ||
| 434 | err_device_alloc: | ||
| 435 | err_set_clk: | ||
| 436 | if (_pll0 != NULL) { | ||
| 437 | clk_put(_pll0); | ||
| 438 | _pll0 = NULL; | ||
| 439 | } | ||
| 440 | err_pll0: | ||
| 441 | if (_gclk0 != NULL) { | ||
| 442 | clk_put(_gclk0); | ||
| 443 | _gclk0 = NULL; | ||
| 444 | } | ||
| 445 | return ret; | ||
| 446 | } | ||
| 447 | |||
| 448 | |||
| 449 | static void __exit playpaq_asoc_exit(void) | ||
| 450 | { | ||
| 451 | if (_gclk0 != NULL) { | ||
| 452 | clk_put(_gclk0); | ||
| 453 | _gclk0 = NULL; | ||
| 454 | } | ||
| 455 | if (_pll0 != NULL) { | ||
| 456 | clk_put(_pll0); | ||
| 457 | _pll0 = NULL; | ||
| 458 | } | ||
| 459 | |||
| 460 | #if defined CONFIG_AT32_ENHANCED_PORTMUX | ||
| 461 | at32_free_pin(MCLK_PIN); | ||
| 462 | #endif | ||
| 463 | |||
| 464 | platform_device_unregister(playpaq_snd_device); | ||
| 465 | playpaq_snd_device = NULL; | ||
| 466 | } | ||
| 467 | |||
| 468 | module_init(playpaq_asoc_init); | ||
| 469 | module_exit(playpaq_asoc_exit); | ||
| 470 | |||
| 471 | MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>"); | ||
| 472 | MODULE_DESCRIPTION("ASoC machine driver for LRS PlayPaq"); | ||
| 473 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h index 444747f0db26..dd7be0dbbc58 100644 --- a/sound/soc/codecs/ad1836.h +++ b/sound/soc/codecs/ad1836.h | |||
| @@ -34,7 +34,7 @@ | |||
| 34 | 34 | ||
| 35 | #define AD1836_ADC_CTRL2 13 | 35 | #define AD1836_ADC_CTRL2 13 |
| 36 | #define AD1836_ADC_WORD_LEN_MASK 0x30 | 36 | #define AD1836_ADC_WORD_LEN_MASK 0x30 |
| 37 | #define AD1836_ADC_WORD_OFFSET 5 | 37 | #define AD1836_ADC_WORD_OFFSET 4 |
| 38 | #define AD1836_ADC_SERFMT_MASK (7 << 6) | 38 | #define AD1836_ADC_SERFMT_MASK (7 << 6) |
| 39 | #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) | 39 | #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) |
| 40 | #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) | 40 | #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index f1f237ecec2a..73f46eb459f1 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
| @@ -601,7 +601,6 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) | |||
| 601 | static int cs4270_soc_resume(struct snd_soc_codec *codec) | 601 | static int cs4270_soc_resume(struct snd_soc_codec *codec) |
| 602 | { | 602 | { |
| 603 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 603 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
| 604 | struct i2c_client *i2c_client = to_i2c_client(codec->dev); | ||
| 605 | int reg; | 604 | int reg; |
| 606 | 605 | ||
| 607 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | 606 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), |
| @@ -612,14 +611,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec) | |||
| 612 | ndelay(500); | 611 | ndelay(500); |
| 613 | 612 | ||
| 614 | /* first restore the entire register cache ... */ | 613 | /* first restore the entire register cache ... */ |
| 615 | for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { | 614 | snd_soc_cache_sync(codec); |
| 616 | u8 val = snd_soc_read(codec, reg); | ||
| 617 | |||
| 618 | if (i2c_smbus_write_byte_data(i2c_client, reg, val)) { | ||
| 619 | dev_err(codec->dev, "i2c write failed\n"); | ||
| 620 | return -EIO; | ||
| 621 | } | ||
| 622 | } | ||
| 623 | 615 | ||
| 624 | /* ... then disable the power-down bits */ | 616 | /* ... then disable the power-down bits */ |
| 625 | reg = snd_soc_read(codec, CS4270_PWRCTL); | 617 | reg = snd_soc_read(codec, CS4270_PWRCTL); |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 8c3c8205d19e..1ee66361f61b 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
| @@ -555,7 +555,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
| 555 | 555 | ||
| 556 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 556 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
| 557 | .probe = cs42l51_probe, | 557 | .probe = cs42l51_probe, |
| 558 | .reg_cache_size = CS42L51_NUMREGS, | 558 | .reg_cache_size = CS42L51_NUMREGS + 1, |
| 559 | .reg_word_size = sizeof(u8), | 559 | .reg_word_size = sizeof(u8), |
| 560 | }; | 560 | }; |
| 561 | 561 | ||
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 9e7e964a5fa3..dcf6f2a1600a 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c | |||
| @@ -106,13 +106,13 @@ static int max9877_set_2reg(struct snd_kcontrol *kcontrol, | |||
| 106 | unsigned int mask = mc->max; | 106 | unsigned int mask = mc->max; |
| 107 | unsigned int val = (ucontrol->value.integer.value[0] & mask); | 107 | unsigned int val = (ucontrol->value.integer.value[0] & mask); |
| 108 | unsigned int val2 = (ucontrol->value.integer.value[1] & mask); | 108 | unsigned int val2 = (ucontrol->value.integer.value[1] & mask); |
| 109 | unsigned int change = 1; | 109 | unsigned int change = 0; |
| 110 | 110 | ||
| 111 | if (((max9877_regs[reg] >> shift) & mask) == val) | 111 | if (((max9877_regs[reg] >> shift) & mask) != val) |
| 112 | change = 0; | 112 | change = 1; |
| 113 | 113 | ||
| 114 | if (((max9877_regs[reg2] >> shift) & mask) == val2) | 114 | if (((max9877_regs[reg2] >> shift) & mask) != val2) |
| 115 | change = 0; | 115 | change = 1; |
| 116 | 116 | ||
| 117 | if (change) { | 117 | if (change) { |
| 118 | max9877_regs[reg] &= ~(mask << shift); | 118 | max9877_regs[reg] &= ~(mask << shift); |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9c982e47eb99..6c2988549003 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
| @@ -2357,6 +2357,11 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
| 2357 | bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; | 2357 | bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; |
| 2358 | 2358 | ||
| 2359 | lrclk = bclk_rate / params_rate(params); | 2359 | lrclk = bclk_rate / params_rate(params); |
| 2360 | if (!lrclk) { | ||
| 2361 | dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n", | ||
| 2362 | bclk_rate); | ||
| 2363 | return -EINVAL; | ||
| 2364 | } | ||
| 2360 | dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", | 2365 | dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", |
| 2361 | lrclk, bclk_rate / lrclk); | 2366 | lrclk, bclk_rate / lrclk); |
| 2362 | 2367 | ||
| @@ -3178,6 +3183,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
| 3178 | switch (wm8994->revision) { | 3183 | switch (wm8994->revision) { |
| 3179 | case 0: | 3184 | case 0: |
| 3180 | case 1: | 3185 | case 1: |
| 3186 | case 2: | ||
| 3187 | case 3: | ||
| 3181 | wm8994->hubs.dcs_codes_l = -9; | 3188 | wm8994->hubs.dcs_codes_l = -9; |
| 3182 | wm8994->hubs.dcs_codes_r = -5; | 3189 | wm8994->hubs.dcs_codes_r = -5; |
| 3183 | break; | 3190 | break; |
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 31af405bda84..ae49f1c78c6d 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c | |||
| @@ -392,7 +392,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | if (strcasecmp(sprop, "i2s-slave") == 0) { | 394 | if (strcasecmp(sprop, "i2s-slave") == 0) { |
| 395 | machine_data->dai_format = SND_SOC_DAIFMT_I2S; | 395 | machine_data->dai_format = |
| 396 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; | ||
| 396 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 397 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
| 397 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 398 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
| 398 | 399 | ||
| @@ -409,31 +410,38 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
| 409 | } | 410 | } |
| 410 | machine_data->clk_frequency = be32_to_cpup(iprop); | 411 | machine_data->clk_frequency = be32_to_cpup(iprop); |
| 411 | } else if (strcasecmp(sprop, "i2s-master") == 0) { | 412 | } else if (strcasecmp(sprop, "i2s-master") == 0) { |
| 412 | machine_data->dai_format = SND_SOC_DAIFMT_I2S; | 413 | machine_data->dai_format = |
| 414 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; | ||
| 413 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 415 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
| 414 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 416 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
| 415 | } else if (strcasecmp(sprop, "lj-slave") == 0) { | 417 | } else if (strcasecmp(sprop, "lj-slave") == 0) { |
| 416 | machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; | 418 | machine_data->dai_format = |
| 419 | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM; | ||
| 417 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 420 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
| 418 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 421 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
| 419 | } else if (strcasecmp(sprop, "lj-master") == 0) { | 422 | } else if (strcasecmp(sprop, "lj-master") == 0) { |
| 420 | machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; | 423 | machine_data->dai_format = |
| 424 | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS; | ||
| 421 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 425 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
| 422 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 426 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
| 423 | } else if (strcasecmp(sprop, "rj-slave") == 0) { | 427 | } else if (strcasecmp(sprop, "rj-slave") == 0) { |
| 424 | machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; | 428 | machine_data->dai_format = |
| 429 | SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM; | ||
| 425 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 430 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
| 426 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 431 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
| 427 | } else if (strcasecmp(sprop, "rj-master") == 0) { | 432 | } else if (strcasecmp(sprop, "rj-master") == 0) { |
| 428 | machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; | 433 | machine_data->dai_format = |
| 434 | SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS; | ||
| 429 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 435 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
| 430 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 436 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
| 431 | } else if (strcasecmp(sprop, "ac97-slave") == 0) { | 437 | } else if (strcasecmp(sprop, "ac97-slave") == 0) { |
| 432 | machine_data->dai_format = SND_SOC_DAIFMT_AC97; | 438 | machine_data->dai_format = |
| 439 | SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM; | ||
| 433 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 440 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
| 434 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 441 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
| 435 | } else if (strcasecmp(sprop, "ac97-master") == 0) { | 442 | } else if (strcasecmp(sprop, "ac97-master") == 0) { |
| 436 | machine_data->dai_format = SND_SOC_DAIFMT_AC97; | 443 | machine_data->dai_format = |
| 444 | SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS; | ||
| 437 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 445 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
| 438 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 446 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
| 439 | } else { | 447 | } else { |
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index f75e43997d5b..ad9ac42522e2 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | #include "../codecs/wm8994.h" | 10 | #include "../codecs/wm8994.h" |
| 11 | #include <sound/pcm_params.h> | 11 | #include <sound/pcm_params.h> |
| 12 | #include <linux/module.h> | ||
| 12 | 13 | ||
| 13 | /* | 14 | /* |
| 14 | * Default CFG switch settings to use this driver: | 15 | * Default CFG switch settings to use this driver: |
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 85bf541a771d..4b8e35410eb1 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c | |||
| @@ -191,7 +191,7 @@ static int speyside_late_probe(struct snd_soc_card *card) | |||
| 191 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); | 191 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); |
| 192 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); | 192 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); |
| 193 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); | 193 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); |
| 194 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); | 194 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker"); |
| 195 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); | 195 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); |
| 196 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); | 196 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); |
| 197 | 197 | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a5d3685a5d38..a25fa63ce9a2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
| @@ -709,6 +709,12 @@ int snd_soc_resume(struct device *dev) | |||
| 709 | struct snd_soc_card *card = dev_get_drvdata(dev); | 709 | struct snd_soc_card *card = dev_get_drvdata(dev); |
| 710 | int i, ac97_control = 0; | 710 | int i, ac97_control = 0; |
| 711 | 711 | ||
| 712 | /* If the initialization of this soc device failed, there is no codec | ||
| 713 | * associated with it. Just bail out in this case. | ||
| 714 | */ | ||
| 715 | if (list_empty(&card->codec_dev_list)) | ||
| 716 | return 0; | ||
| 717 | |||
| 712 | /* AC97 devices might have other drivers hanging off them so | 718 | /* AC97 devices might have other drivers hanging off them so |
| 713 | * need to resume immediately. Other drivers don't have that | 719 | * need to resume immediately. Other drivers don't have that |
| 714 | * problem and may take a substantial amount of time to resume | 720 | * problem and may take a substantial amount of time to resume |
