diff options
| -rw-r--r-- | sound/soc/codecs/rt5677-spi.c | 233 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5677-spi.h | 8 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5677.c | 142 | ||||
| -rw-r--r-- | sound/soc/codecs/rt5677.h | 5 | ||||
| -rw-r--r-- | sound/soc/codecs/sirf-audio-codec.c | 4 | ||||
| -rw-r--r-- | sound/soc/generic/simple-card.c | 9 | ||||
| -rw-r--r-- | sound/soc/sh/dma-sh7760.c | 9 | ||||
| -rw-r--r-- | sound/soc/sh/ssi.c | 12 | ||||
| -rw-r--r-- | sound/soc/spear/spdif_in.c | 20 | ||||
| -rw-r--r-- | sound/soc/spear/spear_pcm.c | 2 |
10 files changed, 252 insertions, 192 deletions
diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c index ef6348cb9157..3505aafbade4 100644 --- a/sound/soc/codecs/rt5677-spi.c +++ b/sound/soc/codecs/rt5677-spi.c | |||
| @@ -31,84 +31,197 @@ | |||
| 31 | 31 | ||
| 32 | #include "rt5677-spi.h" | 32 | #include "rt5677-spi.h" |
| 33 | 33 | ||
| 34 | #define RT5677_SPI_BURST_LEN 240 | ||
| 35 | #define RT5677_SPI_HEADER 5 | ||
| 36 | #define RT5677_SPI_FREQ 6000000 | ||
| 37 | |||
| 38 | /* The AddressPhase and DataPhase of SPI commands are MSB first on the wire. | ||
| 39 | * DataPhase word size of 16-bit commands is 2 bytes. | ||
| 40 | * DataPhase word size of 32-bit commands is 4 bytes. | ||
| 41 | * DataPhase word size of burst commands is 8 bytes. | ||
| 42 | * The DSP CPU is little-endian. | ||
| 43 | */ | ||
| 44 | #define RT5677_SPI_WRITE_BURST 0x5 | ||
| 45 | #define RT5677_SPI_READ_BURST 0x4 | ||
| 46 | #define RT5677_SPI_WRITE_32 0x3 | ||
| 47 | #define RT5677_SPI_READ_32 0x2 | ||
| 48 | #define RT5677_SPI_WRITE_16 0x1 | ||
| 49 | #define RT5677_SPI_READ_16 0x0 | ||
| 50 | |||
| 34 | static struct spi_device *g_spi; | 51 | static struct spi_device *g_spi; |
| 52 | static DEFINE_MUTEX(spi_mutex); | ||
| 35 | 53 | ||
| 36 | /** | 54 | /* Select a suitable transfer command for the next transfer to ensure |
| 37 | * rt5677_spi_write - Write data to SPI. | 55 | * the transfer address is always naturally aligned while minimizing |
| 38 | * @txbuf: Data Buffer for writing. | 56 | * the total number of transfers required. |
| 39 | * @len: Data length. | 57 | * |
| 58 | * 3 transfer commands are available: | ||
| 59 | * RT5677_SPI_READ/WRITE_16: Transfer 2 bytes | ||
| 60 | * RT5677_SPI_READ/WRITE_32: Transfer 4 bytes | ||
| 61 | * RT5677_SPI_READ/WRITE_BURST: Transfer any multiples of 8 bytes | ||
| 62 | * | ||
| 63 | * For example, reading 260 bytes at 0x60030002 uses the following commands: | ||
| 64 | * 0x60030002 RT5677_SPI_READ_16 2 bytes | ||
| 65 | * 0x60030004 RT5677_SPI_READ_32 4 bytes | ||
| 66 | * 0x60030008 RT5677_SPI_READ_BURST 240 bytes | ||
| 67 | * 0x600300F8 RT5677_SPI_READ_BURST 8 bytes | ||
| 68 | * 0x60030100 RT5677_SPI_READ_32 4 bytes | ||
| 69 | * 0x60030104 RT5677_SPI_READ_16 2 bytes | ||
| 40 | * | 70 | * |
| 71 | * Input: | ||
| 72 | * @read: true for read commands; false for write commands | ||
| 73 | * @align: alignment of the next transfer address | ||
| 74 | * @remain: number of bytes remaining to transfer | ||
| 41 | * | 75 | * |
| 42 | * Returns true for success. | 76 | * Output: |
| 77 | * @len: number of bytes to transfer with the selected command | ||
| 78 | * Returns the selected command | ||
| 43 | */ | 79 | */ |
| 44 | int rt5677_spi_write(u8 *txbuf, size_t len) | 80 | static u8 rt5677_spi_select_cmd(bool read, u32 align, u32 remain, u32 *len) |
| 45 | { | 81 | { |
| 46 | int status; | 82 | u8 cmd; |
| 47 | 83 | ||
| 48 | status = spi_write(g_spi, txbuf, len); | 84 | if (align == 2 || align == 6 || remain == 2) { |
| 49 | 85 | cmd = RT5677_SPI_READ_16; | |
| 50 | if (status) | 86 | *len = 2; |
| 51 | dev_err(&g_spi->dev, "rt5677_spi_write error %d\n", status); | 87 | } else if (align == 4 || remain <= 6) { |
| 52 | 88 | cmd = RT5677_SPI_READ_32; | |
| 53 | return status; | 89 | *len = 4; |
| 90 | } else { | ||
| 91 | cmd = RT5677_SPI_READ_BURST; | ||
| 92 | *len = min_t(u32, remain & ~7, RT5677_SPI_BURST_LEN); | ||
| 93 | } | ||
| 94 | return read ? cmd : cmd + 1; | ||
| 54 | } | 95 | } |
| 55 | EXPORT_SYMBOL_GPL(rt5677_spi_write); | ||
| 56 | 96 | ||
| 57 | /** | 97 | /* Copy dstlen bytes from src to dst, while reversing byte order for each word. |
| 58 | * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address. | 98 | * If srclen < dstlen, zeros are padded. |
| 59 | * @addr: Start address. | ||
| 60 | * @txbuf: Data Buffer for writng. | ||
| 61 | * @len: Data length, it must be a multiple of 8. | ||
| 62 | * | ||
| 63 | * | ||
| 64 | * Returns true for success. | ||
| 65 | */ | 99 | */ |
| 66 | int rt5677_spi_burst_write(u32 addr, const struct firmware *fw) | 100 | static void rt5677_spi_reverse(u8 *dst, u32 dstlen, const u8 *src, u32 srclen) |
| 67 | { | 101 | { |
| 68 | u8 spi_cmd = RT5677_SPI_CMD_BURST_WRITE; | 102 | u32 w, i, si; |
| 69 | u8 *write_buf; | 103 | u32 word_size = min_t(u32, dstlen, 8); |
| 70 | unsigned int i, end, offset = 0; | 104 | |
| 71 | 105 | for (w = 0; w < dstlen; w += word_size) { | |
| 72 | write_buf = kmalloc(RT5677_SPI_BUF_LEN + 6, GFP_KERNEL); | 106 | for (i = 0; i < word_size; i++) { |
| 73 | 107 | si = w + word_size - i - 1; | |
| 74 | if (write_buf == NULL) | 108 | dst[w + i] = si < srclen ? src[si] : 0; |
| 75 | return -ENOMEM; | ||
| 76 | |||
| 77 | while (offset < fw->size) { | ||
| 78 | if (offset + RT5677_SPI_BUF_LEN <= fw->size) | ||
| 79 | end = RT5677_SPI_BUF_LEN; | ||
| 80 | else | ||
| 81 | end = fw->size % RT5677_SPI_BUF_LEN; | ||
| 82 | |||
| 83 | write_buf[0] = spi_cmd; | ||
| 84 | write_buf[1] = ((addr + offset) & 0xff000000) >> 24; | ||
| 85 | write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16; | ||
| 86 | write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8; | ||
| 87 | write_buf[4] = ((addr + offset) & 0x000000ff) >> 0; | ||
| 88 | |||
| 89 | for (i = 0; i < end; i += 8) { | ||
| 90 | write_buf[i + 12] = fw->data[offset + i + 0]; | ||
| 91 | write_buf[i + 11] = fw->data[offset + i + 1]; | ||
| 92 | write_buf[i + 10] = fw->data[offset + i + 2]; | ||
| 93 | write_buf[i + 9] = fw->data[offset + i + 3]; | ||
| 94 | write_buf[i + 8] = fw->data[offset + i + 4]; | ||
| 95 | write_buf[i + 7] = fw->data[offset + i + 5]; | ||
| 96 | write_buf[i + 6] = fw->data[offset + i + 6]; | ||
| 97 | write_buf[i + 5] = fw->data[offset + i + 7]; | ||
| 98 | } | 109 | } |
| 110 | } | ||
| 111 | } | ||
| 99 | 112 | ||
| 100 | write_buf[end + 5] = spi_cmd; | 113 | /* Read DSP address space using SPI. addr and len have to be 2-byte aligned. */ |
| 114 | int rt5677_spi_read(u32 addr, void *rxbuf, size_t len) | ||
| 115 | { | ||
| 116 | u32 offset; | ||
| 117 | int status = 0; | ||
| 118 | struct spi_transfer t[2]; | ||
| 119 | struct spi_message m; | ||
| 120 | /* +4 bytes is for the DummyPhase following the AddressPhase */ | ||
| 121 | u8 header[RT5677_SPI_HEADER + 4]; | ||
| 122 | u8 body[RT5677_SPI_BURST_LEN]; | ||
| 123 | u8 spi_cmd; | ||
| 124 | u8 *cb = rxbuf; | ||
| 125 | |||
| 126 | if (!g_spi) | ||
| 127 | return -ENODEV; | ||
| 128 | |||
| 129 | if ((addr & 1) || (len & 1)) { | ||
| 130 | dev_err(&g_spi->dev, "Bad read align 0x%x(%zu)\n", addr, len); | ||
| 131 | return -EACCES; | ||
| 132 | } | ||
| 101 | 133 | ||
| 102 | rt5677_spi_write(write_buf, end + 6); | 134 | memset(t, 0, sizeof(t)); |
| 135 | t[0].tx_buf = header; | ||
| 136 | t[0].len = sizeof(header); | ||
| 137 | t[0].speed_hz = RT5677_SPI_FREQ; | ||
| 138 | t[1].rx_buf = body; | ||
| 139 | t[1].speed_hz = RT5677_SPI_FREQ; | ||
| 140 | spi_message_init_with_transfers(&m, t, ARRAY_SIZE(t)); | ||
| 141 | |||
| 142 | for (offset = 0; offset < len; offset += t[1].len) { | ||
| 143 | spi_cmd = rt5677_spi_select_cmd(true, (addr + offset) & 7, | ||
| 144 | len - offset, &t[1].len); | ||
| 145 | |||
| 146 | /* Construct SPI message header */ | ||
| 147 | header[0] = spi_cmd; | ||
| 148 | header[1] = ((addr + offset) & 0xff000000) >> 24; | ||
| 149 | header[2] = ((addr + offset) & 0x00ff0000) >> 16; | ||
| 150 | header[3] = ((addr + offset) & 0x0000ff00) >> 8; | ||
| 151 | header[4] = ((addr + offset) & 0x000000ff) >> 0; | ||
| 152 | |||
| 153 | mutex_lock(&spi_mutex); | ||
| 154 | status |= spi_sync(g_spi, &m); | ||
| 155 | mutex_unlock(&spi_mutex); | ||
| 156 | |||
| 157 | /* Copy data back to caller buffer */ | ||
| 158 | rt5677_spi_reverse(cb + offset, t[1].len, body, t[1].len); | ||
| 159 | } | ||
| 160 | return status; | ||
| 161 | } | ||
| 162 | EXPORT_SYMBOL_GPL(rt5677_spi_read); | ||
| 103 | 163 | ||
| 104 | offset += RT5677_SPI_BUF_LEN; | 164 | /* Write DSP address space using SPI. addr has to be 2-byte aligned. |
| 165 | * If len is not 2-byte aligned, an extra byte of zero is written at the end | ||
| 166 | * as padding. | ||
| 167 | */ | ||
| 168 | int rt5677_spi_write(u32 addr, const void *txbuf, size_t len) | ||
| 169 | { | ||
| 170 | u32 offset, len_with_pad = len; | ||
| 171 | int status = 0; | ||
| 172 | struct spi_transfer t; | ||
| 173 | struct spi_message m; | ||
| 174 | /* +1 byte is for the DummyPhase following the DataPhase */ | ||
| 175 | u8 buf[RT5677_SPI_HEADER + RT5677_SPI_BURST_LEN + 1]; | ||
| 176 | u8 *body = buf + RT5677_SPI_HEADER; | ||
| 177 | u8 spi_cmd; | ||
| 178 | const u8 *cb = txbuf; | ||
| 179 | |||
| 180 | if (!g_spi) | ||
| 181 | return -ENODEV; | ||
| 182 | |||
| 183 | if (addr & 1) { | ||
| 184 | dev_err(&g_spi->dev, "Bad write align 0x%x(%zu)\n", addr, len); | ||
| 185 | return -EACCES; | ||
| 105 | } | 186 | } |
| 106 | 187 | ||
| 107 | kfree(write_buf); | 188 | if (len & 1) |
| 189 | len_with_pad = len + 1; | ||
| 190 | |||
| 191 | memset(&t, 0, sizeof(t)); | ||
| 192 | t.tx_buf = buf; | ||
| 193 | t.speed_hz = RT5677_SPI_FREQ; | ||
| 194 | spi_message_init_with_transfers(&m, &t, 1); | ||
| 195 | |||
| 196 | for (offset = 0; offset < len_with_pad;) { | ||
| 197 | spi_cmd = rt5677_spi_select_cmd(false, (addr + offset) & 7, | ||
| 198 | len_with_pad - offset, &t.len); | ||
| 199 | |||
| 200 | /* Construct SPI message header */ | ||
| 201 | buf[0] = spi_cmd; | ||
| 202 | buf[1] = ((addr + offset) & 0xff000000) >> 24; | ||
| 203 | buf[2] = ((addr + offset) & 0x00ff0000) >> 16; | ||
| 204 | buf[3] = ((addr + offset) & 0x0000ff00) >> 8; | ||
| 205 | buf[4] = ((addr + offset) & 0x000000ff) >> 0; | ||
| 206 | |||
| 207 | /* Fetch data from caller buffer */ | ||
| 208 | rt5677_spi_reverse(body, t.len, cb + offset, len - offset); | ||
| 209 | offset += t.len; | ||
| 210 | t.len += RT5677_SPI_HEADER + 1; | ||
| 211 | |||
| 212 | mutex_lock(&spi_mutex); | ||
| 213 | status |= spi_sync(g_spi, &m); | ||
| 214 | mutex_unlock(&spi_mutex); | ||
| 215 | } | ||
| 216 | return status; | ||
| 217 | } | ||
| 218 | EXPORT_SYMBOL_GPL(rt5677_spi_write); | ||
| 108 | 219 | ||
| 109 | return 0; | 220 | int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw) |
| 221 | { | ||
| 222 | return rt5677_spi_write(addr, fw->data, fw->size); | ||
| 110 | } | 223 | } |
| 111 | EXPORT_SYMBOL_GPL(rt5677_spi_burst_write); | 224 | EXPORT_SYMBOL_GPL(rt5677_spi_write_firmware); |
| 112 | 225 | ||
| 113 | static int rt5677_spi_probe(struct spi_device *spi) | 226 | static int rt5677_spi_probe(struct spi_device *spi) |
| 114 | { | 227 | { |
diff --git a/sound/soc/codecs/rt5677-spi.h b/sound/soc/codecs/rt5677-spi.h index ec41b2b3b2ca..662db16cfb6a 100644 --- a/sound/soc/codecs/rt5677-spi.h +++ b/sound/soc/codecs/rt5677-spi.h | |||
| @@ -12,10 +12,8 @@ | |||
| 12 | #ifndef __RT5677_SPI_H__ | 12 | #ifndef __RT5677_SPI_H__ |
| 13 | #define __RT5677_SPI_H__ | 13 | #define __RT5677_SPI_H__ |
| 14 | 14 | ||
| 15 | #define RT5677_SPI_BUF_LEN 240 | 15 | int rt5677_spi_read(u32 addr, void *rxbuf, size_t len); |
| 16 | #define RT5677_SPI_CMD_BURST_WRITE 0x05 | 16 | int rt5677_spi_write(u32 addr, const void *txbuf, size_t len); |
| 17 | 17 | int rt5677_spi_write_firmware(u32 addr, const struct firmware *fw); | |
| 18 | int rt5677_spi_write(u8 *txbuf, size_t len); | ||
| 19 | int rt5677_spi_burst_write(u32 addr, const struct firmware *fw); | ||
| 20 | 18 | ||
| 21 | #endif /* __RT5677_SPI_H__ */ | 19 | #endif /* __RT5677_SPI_H__ */ |
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c index d9999336a7a2..b7de51b09c35 100644 --- a/sound/soc/codecs/rt5677.c +++ b/sound/soc/codecs/rt5677.c | |||
| @@ -15,13 +15,12 @@ | |||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
| 17 | #include <linux/pm.h> | 17 | #include <linux/pm.h> |
| 18 | #include <linux/of_gpio.h> | ||
| 19 | #include <linux/regmap.h> | 18 | #include <linux/regmap.h> |
| 20 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
| 21 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| 22 | #include <linux/spi/spi.h> | 21 | #include <linux/spi/spi.h> |
| 23 | #include <linux/firmware.h> | 22 | #include <linux/firmware.h> |
| 24 | #include <linux/gpio.h> | 23 | #include <linux/property.h> |
| 25 | #include <sound/core.h> | 24 | #include <sound/core.h> |
| 26 | #include <sound/pcm.h> | 25 | #include <sound/pcm.h> |
| 27 | #include <sound/pcm_params.h> | 26 | #include <sound/pcm_params.h> |
| @@ -746,14 +745,14 @@ static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on) | |||
| 746 | ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1, | 745 | ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1, |
| 747 | codec->dev); | 746 | codec->dev); |
| 748 | if (ret == 0) { | 747 | if (ret == 0) { |
| 749 | rt5677_spi_burst_write(0x50000000, rt5677->fw1); | 748 | rt5677_spi_write_firmware(0x50000000, rt5677->fw1); |
| 750 | release_firmware(rt5677->fw1); | 749 | release_firmware(rt5677->fw1); |
| 751 | } | 750 | } |
| 752 | 751 | ||
| 753 | ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2, | 752 | ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2, |
| 754 | codec->dev); | 753 | codec->dev); |
| 755 | if (ret == 0) { | 754 | if (ret == 0) { |
| 756 | rt5677_spi_burst_write(0x60000000, rt5677->fw2); | 755 | rt5677_spi_write_firmware(0x60000000, rt5677->fw2); |
| 757 | release_firmware(rt5677->fw2); | 756 | release_firmware(rt5677->fw2); |
| 758 | } | 757 | } |
| 759 | 758 | ||
| @@ -4767,10 +4766,8 @@ static int rt5677_remove(struct snd_soc_codec *codec) | |||
| 4767 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 4766 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
| 4768 | 4767 | ||
| 4769 | regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); | 4768 | regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec); |
| 4770 | if (gpio_is_valid(rt5677->pow_ldo2)) | 4769 | gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); |
| 4771 | gpio_set_value_cansleep(rt5677->pow_ldo2, 0); | 4770 | gpiod_set_value_cansleep(rt5677->reset_pin, 0); |
| 4772 | if (gpio_is_valid(rt5677->reset_pin)) | ||
| 4773 | gpio_set_value_cansleep(rt5677->reset_pin, 0); | ||
| 4774 | 4771 | ||
| 4775 | return 0; | 4772 | return 0; |
| 4776 | } | 4773 | } |
| @@ -4784,10 +4781,8 @@ static int rt5677_suspend(struct snd_soc_codec *codec) | |||
| 4784 | regcache_cache_only(rt5677->regmap, true); | 4781 | regcache_cache_only(rt5677->regmap, true); |
| 4785 | regcache_mark_dirty(rt5677->regmap); | 4782 | regcache_mark_dirty(rt5677->regmap); |
| 4786 | 4783 | ||
| 4787 | if (gpio_is_valid(rt5677->pow_ldo2)) | 4784 | gpiod_set_value_cansleep(rt5677->pow_ldo2, 0); |
| 4788 | gpio_set_value_cansleep(rt5677->pow_ldo2, 0); | 4785 | gpiod_set_value_cansleep(rt5677->reset_pin, 0); |
| 4789 | if (gpio_is_valid(rt5677->reset_pin)) | ||
| 4790 | gpio_set_value_cansleep(rt5677->reset_pin, 0); | ||
| 4791 | } | 4786 | } |
| 4792 | 4787 | ||
| 4793 | return 0; | 4788 | return 0; |
| @@ -4798,12 +4793,9 @@ static int rt5677_resume(struct snd_soc_codec *codec) | |||
| 4798 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); | 4793 | struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); |
| 4799 | 4794 | ||
| 4800 | if (!rt5677->dsp_vad_en) { | 4795 | if (!rt5677->dsp_vad_en) { |
| 4801 | if (gpio_is_valid(rt5677->pow_ldo2)) | 4796 | gpiod_set_value_cansleep(rt5677->pow_ldo2, 1); |
| 4802 | gpio_set_value_cansleep(rt5677->pow_ldo2, 1); | 4797 | gpiod_set_value_cansleep(rt5677->reset_pin, 1); |
| 4803 | if (gpio_is_valid(rt5677->reset_pin)) | 4798 | if (rt5677->pow_ldo2 || rt5677->reset_pin) |
| 4804 | gpio_set_value_cansleep(rt5677->reset_pin, 1); | ||
| 4805 | if (gpio_is_valid(rt5677->pow_ldo2) || | ||
| 4806 | gpio_is_valid(rt5677->reset_pin)) | ||
| 4807 | msleep(10); | 4799 | msleep(10); |
| 4808 | 4800 | ||
| 4809 | regcache_cache_only(rt5677->regmap, false); | 4801 | regcache_cache_only(rt5677->regmap, false); |
| @@ -5027,45 +5019,29 @@ static const struct i2c_device_id rt5677_i2c_id[] = { | |||
| 5027 | }; | 5019 | }; |
| 5028 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); | 5020 | MODULE_DEVICE_TABLE(i2c, rt5677_i2c_id); |
| 5029 | 5021 | ||
| 5030 | static int rt5677_parse_dt(struct rt5677_priv *rt5677, struct device_node *np) | 5022 | static void rt5677_read_device_properties(struct rt5677_priv *rt5677, |
| 5023 | struct device *dev) | ||
| 5031 | { | 5024 | { |
| 5032 | rt5677->pdata.in1_diff = of_property_read_bool(np, | 5025 | rt5677->pdata.in1_diff = device_property_read_bool(dev, |
| 5033 | "realtek,in1-differential"); | 5026 | "realtek,in1-differential"); |
| 5034 | rt5677->pdata.in2_diff = of_property_read_bool(np, | 5027 | rt5677->pdata.in2_diff = device_property_read_bool(dev, |
| 5035 | "realtek,in2-differential"); | 5028 | "realtek,in2-differential"); |
| 5036 | rt5677->pdata.lout1_diff = of_property_read_bool(np, | 5029 | rt5677->pdata.lout1_diff = device_property_read_bool(dev, |
| 5037 | "realtek,lout1-differential"); | 5030 | "realtek,lout1-differential"); |
| 5038 | rt5677->pdata.lout2_diff = of_property_read_bool(np, | 5031 | rt5677->pdata.lout2_diff = device_property_read_bool(dev, |
| 5039 | "realtek,lout2-differential"); | 5032 | "realtek,lout2-differential"); |
| 5040 | rt5677->pdata.lout3_diff = of_property_read_bool(np, | 5033 | rt5677->pdata.lout3_diff = device_property_read_bool(dev, |
| 5041 | "realtek,lout3-differential"); | 5034 | "realtek,lout3-differential"); |
| 5042 | 5035 | ||
| 5043 | rt5677->pow_ldo2 = of_get_named_gpio(np, | 5036 | device_property_read_u8_array(dev, "realtek,gpio-config", |
| 5044 | "realtek,pow-ldo2-gpio", 0); | 5037 | rt5677->pdata.gpio_config, RT5677_GPIO_NUM); |
| 5045 | rt5677->reset_pin = of_get_named_gpio(np, | 5038 | |
| 5046 | "realtek,reset-gpio", 0); | 5039 | device_property_read_u32(dev, "realtek,jd1-gpio", |
| 5047 | 5040 | &rt5677->pdata.jd1_gpio); | |
| 5048 | /* | 5041 | device_property_read_u32(dev, "realtek,jd2-gpio", |
| 5049 | * POW_LDO2 is optional (it may be statically tied on the board). | 5042 | &rt5677->pdata.jd2_gpio); |
| 5050 | * -ENOENT means that the property doesn't exist, i.e. there is no | 5043 | device_property_read_u32(dev, "realtek,jd3-gpio", |
| 5051 | * GPIO, so is not an error. Any other error code means the property | 5044 | &rt5677->pdata.jd3_gpio); |
| 5052 | * exists, but could not be parsed. | ||
| 5053 | */ | ||
| 5054 | if (!gpio_is_valid(rt5677->pow_ldo2) && | ||
| 5055 | (rt5677->pow_ldo2 != -ENOENT)) | ||
| 5056 | return rt5677->pow_ldo2; | ||
| 5057 | if (!gpio_is_valid(rt5677->reset_pin) && | ||
| 5058 | (rt5677->reset_pin != -ENOENT)) | ||
| 5059 | return rt5677->reset_pin; | ||
| 5060 | |||
| 5061 | of_property_read_u8_array(np, "realtek,gpio-config", | ||
| 5062 | rt5677->pdata.gpio_config, RT5677_GPIO_NUM); | ||
| 5063 | |||
| 5064 | of_property_read_u32(np, "realtek,jd1-gpio", &rt5677->pdata.jd1_gpio); | ||
| 5065 | of_property_read_u32(np, "realtek,jd2-gpio", &rt5677->pdata.jd2_gpio); | ||
| 5066 | of_property_read_u32(np, "realtek,jd3-gpio", &rt5677->pdata.jd3_gpio); | ||
| 5067 | |||
| 5068 | return 0; | ||
| 5069 | } | 5045 | } |
| 5070 | 5046 | ||
| 5071 | static struct regmap_irq rt5677_irqs[] = { | 5047 | static struct regmap_irq rt5677_irqs[] = { |
| @@ -5148,43 +5124,29 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
| 5148 | 5124 | ||
| 5149 | if (pdata) | 5125 | if (pdata) |
| 5150 | rt5677->pdata = *pdata; | 5126 | rt5677->pdata = *pdata; |
| 5127 | else | ||
| 5128 | rt5677_read_device_properties(rt5677, &i2c->dev); | ||
| 5151 | 5129 | ||
| 5152 | if (i2c->dev.of_node) { | 5130 | /* pow-ldo2 and reset are optional. The codec pins may be statically |
| 5153 | ret = rt5677_parse_dt(rt5677, i2c->dev.of_node); | 5131 | * connected on the board without gpios. If the gpio device property |
| 5154 | if (ret) { | 5132 | * isn't specified, devm_gpiod_get_optional returns NULL. |
| 5155 | dev_err(&i2c->dev, "Failed to parse device tree: %d\n", | 5133 | */ |
| 5156 | ret); | 5134 | rt5677->pow_ldo2 = devm_gpiod_get_optional(&i2c->dev, |
| 5157 | return ret; | 5135 | "realtek,pow-ldo2", GPIOD_OUT_HIGH); |
| 5158 | } | 5136 | if (IS_ERR(rt5677->pow_ldo2)) { |
| 5159 | } else { | 5137 | ret = PTR_ERR(rt5677->pow_ldo2); |
| 5160 | rt5677->pow_ldo2 = -EINVAL; | 5138 | dev_err(&i2c->dev, "Failed to request POW_LDO2: %d\n", ret); |
| 5161 | rt5677->reset_pin = -EINVAL; | 5139 | return ret; |
| 5162 | } | ||
| 5163 | |||
| 5164 | if (gpio_is_valid(rt5677->pow_ldo2)) { | ||
| 5165 | ret = devm_gpio_request_one(&i2c->dev, rt5677->pow_ldo2, | ||
| 5166 | GPIOF_OUT_INIT_HIGH, | ||
| 5167 | "RT5677 POW_LDO2"); | ||
| 5168 | if (ret < 0) { | ||
| 5169 | dev_err(&i2c->dev, "Failed to request POW_LDO2 %d: %d\n", | ||
| 5170 | rt5677->pow_ldo2, ret); | ||
| 5171 | return ret; | ||
| 5172 | } | ||
| 5173 | } | 5140 | } |
| 5174 | 5141 | rt5677->reset_pin = devm_gpiod_get_optional(&i2c->dev, | |
| 5175 | if (gpio_is_valid(rt5677->reset_pin)) { | 5142 | "realtek,reset", GPIOD_OUT_HIGH); |
| 5176 | ret = devm_gpio_request_one(&i2c->dev, rt5677->reset_pin, | 5143 | if (IS_ERR(rt5677->reset_pin)) { |
| 5177 | GPIOF_OUT_INIT_HIGH, | 5144 | ret = PTR_ERR(rt5677->reset_pin); |
| 5178 | "RT5677 RESET"); | 5145 | dev_err(&i2c->dev, "Failed to request RESET: %d\n", ret); |
| 5179 | if (ret < 0) { | 5146 | return ret; |
| 5180 | dev_err(&i2c->dev, "Failed to request RESET %d: %d\n", | ||
| 5181 | rt5677->reset_pin, ret); | ||
| 5182 | return ret; | ||
| 5183 | } | ||
| 5184 | } | 5147 | } |
| 5185 | 5148 | ||
| 5186 | if (gpio_is_valid(rt5677->pow_ldo2) || | 5149 | if (rt5677->pow_ldo2 || rt5677->reset_pin) { |
| 5187 | gpio_is_valid(rt5677->reset_pin)) { | ||
| 5188 | /* Wait a while until I2C bus becomes available. The datasheet | 5150 | /* Wait a while until I2C bus becomes available. The datasheet |
| 5189 | * does not specify the exact we should wait but startup | 5151 | * does not specify the exact we should wait but startup |
| 5190 | * sequence mentiones at least a few milliseconds. | 5152 | * sequence mentiones at least a few milliseconds. |
| @@ -5212,7 +5174,7 @@ static int rt5677_i2c_probe(struct i2c_client *i2c, | |||
| 5212 | regmap_read(rt5677->regmap, RT5677_VENDOR_ID2, &val); | 5174 | regmap_read(rt5677->regmap, RT5677_VENDOR_ID2, &val); |
| 5213 | if (val != RT5677_DEVICE_ID) { | 5175 | if (val != RT5677_DEVICE_ID) { |
| 5214 | dev_err(&i2c->dev, | 5176 | dev_err(&i2c->dev, |
| 5215 | "Device with ID register %x is not rt5677\n", val); | 5177 | "Device with ID register %#x is not rt5677\n", val); |
| 5216 | return -ENODEV; | 5178 | return -ENODEV; |
| 5217 | } | 5179 | } |
| 5218 | 5180 | ||
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h index 7eca38a23255..d46855a42c40 100644 --- a/sound/soc/codecs/rt5677.h +++ b/sound/soc/codecs/rt5677.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | #include <sound/rt5677.h> | 15 | #include <sound/rt5677.h> |
| 16 | #include <linux/gpio/driver.h> | 16 | #include <linux/gpio/driver.h> |
| 17 | #include <linux/gpio/consumer.h> | ||
| 17 | 18 | ||
| 18 | /* Info */ | 19 | /* Info */ |
| 19 | #define RT5677_RESET 0x00 | 20 | #define RT5677_RESET 0x00 |
| @@ -1775,8 +1776,8 @@ struct rt5677_priv { | |||
| 1775 | int pll_src; | 1776 | int pll_src; |
| 1776 | int pll_in; | 1777 | int pll_in; |
| 1777 | int pll_out; | 1778 | int pll_out; |
| 1778 | int pow_ldo2; /* POW_LDO2 pin */ | 1779 | struct gpio_desc *pow_ldo2; /* POW_LDO2 pin */ |
| 1779 | int reset_pin; /* RESET pin */ | 1780 | struct gpio_desc *reset_pin; /* RESET pin */ |
| 1780 | enum rt5677_type type; | 1781 | enum rt5677_type type; |
| 1781 | #ifdef CONFIG_GPIOLIB | 1782 | #ifdef CONFIG_GPIOLIB |
| 1782 | struct gpio_chip gpio_chip; | 1783 | struct gpio_chip gpio_chip; |
diff --git a/sound/soc/codecs/sirf-audio-codec.c b/sound/soc/codecs/sirf-audio-codec.c index 29cb44256044..6bfd25c289d1 100644 --- a/sound/soc/codecs/sirf-audio-codec.c +++ b/sound/soc/codecs/sirf-audio-codec.c | |||
| @@ -370,11 +370,11 @@ static int sirf_audio_codec_trigger(struct snd_pcm_substream *substream, | |||
| 370 | return 0; | 370 | return 0; |
| 371 | } | 371 | } |
| 372 | 372 | ||
| 373 | struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { | 373 | static const struct snd_soc_dai_ops sirf_audio_codec_dai_ops = { |
| 374 | .trigger = sirf_audio_codec_trigger, | 374 | .trigger = sirf_audio_codec_trigger, |
| 375 | }; | 375 | }; |
| 376 | 376 | ||
| 377 | struct snd_soc_dai_driver sirf_audio_codec_dai = { | 377 | static struct snd_soc_dai_driver sirf_audio_codec_dai = { |
| 378 | .name = "sirf-audio-codec", | 378 | .name = "sirf-audio-codec", |
| 379 | .playback = { | 379 | .playback = { |
| 380 | .stream_name = "Playback", | 380 | .stream_name = "Playback", |
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c index d5554939146e..3ff76d419436 100644 --- a/sound/soc/generic/simple-card.c +++ b/sound/soc/generic/simple-card.c | |||
| @@ -76,6 +76,7 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | |||
| 76 | { | 76 | { |
| 77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 77 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
| 78 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | 78 | struct snd_soc_dai *codec_dai = rtd->codec_dai; |
| 79 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
| 79 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); | 80 | struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card); |
| 80 | struct simple_dai_props *dai_props = | 81 | struct simple_dai_props *dai_props = |
| 81 | &priv->dai_props[rtd - rtd->card->rtd]; | 82 | &priv->dai_props[rtd - rtd->card->rtd]; |
| @@ -91,8 +92,16 @@ static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream, | |||
| 91 | mclk = params_rate(params) * mclk_fs; | 92 | mclk = params_rate(params) * mclk_fs; |
| 92 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, | 93 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk, |
| 93 | SND_SOC_CLOCK_IN); | 94 | SND_SOC_CLOCK_IN); |
| 95 | if (ret && ret != -ENOTSUPP) | ||
| 96 | goto err; | ||
| 97 | |||
| 98 | ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk, | ||
| 99 | SND_SOC_CLOCK_OUT); | ||
| 100 | if (ret && ret != -ENOTSUPP) | ||
| 101 | goto err; | ||
| 94 | } | 102 | } |
| 95 | 103 | ||
| 104 | err: | ||
| 96 | return ret; | 105 | return ret; |
| 97 | } | 106 | } |
| 98 | 107 | ||
diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c index fd11404a3bc7..8fad4441c87d 100644 --- a/sound/soc/sh/dma-sh7760.c +++ b/sound/soc/sh/dma-sh7760.c | |||
| @@ -327,13 +327,7 @@ static struct snd_soc_platform_driver sh7760_soc_platform = { | |||
| 327 | 327 | ||
| 328 | static int sh7760_soc_platform_probe(struct platform_device *pdev) | 328 | static int sh7760_soc_platform_probe(struct platform_device *pdev) |
| 329 | { | 329 | { |
| 330 | return snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform); | 330 | return devm_snd_soc_register_platform(&pdev->dev, &sh7760_soc_platform); |
| 331 | } | ||
| 332 | |||
| 333 | static int sh7760_soc_platform_remove(struct platform_device *pdev) | ||
| 334 | { | ||
| 335 | snd_soc_unregister_platform(&pdev->dev); | ||
| 336 | return 0; | ||
| 337 | } | 331 | } |
| 338 | 332 | ||
| 339 | static struct platform_driver sh7760_pcm_driver = { | 333 | static struct platform_driver sh7760_pcm_driver = { |
| @@ -342,7 +336,6 @@ static struct platform_driver sh7760_pcm_driver = { | |||
| 342 | }, | 336 | }, |
| 343 | 337 | ||
| 344 | .probe = sh7760_soc_platform_probe, | 338 | .probe = sh7760_soc_platform_probe, |
| 345 | .remove = sh7760_soc_platform_remove, | ||
| 346 | }; | 339 | }; |
| 347 | 340 | ||
| 348 | module_platform_driver(sh7760_pcm_driver); | 341 | module_platform_driver(sh7760_pcm_driver); |
diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c index ab13146e4f82..89ed1b107ac5 100644 --- a/sound/soc/sh/ssi.c +++ b/sound/soc/sh/ssi.c | |||
| @@ -385,14 +385,9 @@ static const struct snd_soc_component_driver sh4_ssi_component = { | |||
| 385 | 385 | ||
| 386 | static int sh4_soc_dai_probe(struct platform_device *pdev) | 386 | static int sh4_soc_dai_probe(struct platform_device *pdev) |
| 387 | { | 387 | { |
| 388 | return snd_soc_register_component(&pdev->dev, &sh4_ssi_component, | 388 | return devm_snd_soc_register_component(&pdev->dev, &sh4_ssi_component, |
| 389 | sh4_ssi_dai, ARRAY_SIZE(sh4_ssi_dai)); | 389 | sh4_ssi_dai, |
| 390 | } | 390 | ARRAY_SIZE(sh4_ssi_dai)); |
| 391 | |||
| 392 | static int sh4_soc_dai_remove(struct platform_device *pdev) | ||
| 393 | { | ||
| 394 | snd_soc_unregister_component(&pdev->dev); | ||
| 395 | return 0; | ||
| 396 | } | 391 | } |
| 397 | 392 | ||
| 398 | static struct platform_driver sh4_ssi_driver = { | 393 | static struct platform_driver sh4_ssi_driver = { |
| @@ -401,7 +396,6 @@ static struct platform_driver sh4_ssi_driver = { | |||
| 401 | }, | 396 | }, |
| 402 | 397 | ||
| 403 | .probe = sh4_soc_dai_probe, | 398 | .probe = sh4_soc_dai_probe, |
| 404 | .remove = sh4_soc_dai_remove, | ||
| 405 | }; | 399 | }; |
| 406 | 400 | ||
| 407 | module_platform_driver(sh4_ssi_driver); | 401 | module_platform_driver(sh4_ssi_driver); |
diff --git a/sound/soc/spear/spdif_in.c b/sound/soc/spear/spdif_in.c index a4028601da01..977a078eb92f 100644 --- a/sound/soc/spear/spdif_in.c +++ b/sound/soc/spear/spdif_in.c | |||
| @@ -203,35 +203,25 @@ static int spdif_in_probe(struct platform_device *pdev) | |||
| 203 | struct spdif_in_dev *host; | 203 | struct spdif_in_dev *host; |
| 204 | struct spear_spdif_platform_data *pdata; | 204 | struct spear_spdif_platform_data *pdata; |
| 205 | struct resource *res, *res_fifo; | 205 | struct resource *res, *res_fifo; |
| 206 | void __iomem *io_base; | ||
| 206 | int ret; | 207 | int ret; |
| 207 | 208 | ||
| 208 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 209 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 209 | if (!res) | 210 | io_base = devm_ioremap_resource(&pdev->dev, res); |
| 210 | return -EINVAL; | 211 | if (IS_ERR(io_base)) |
| 212 | return PTR_ERR(io_base); | ||
| 211 | 213 | ||
| 212 | res_fifo = platform_get_resource(pdev, IORESOURCE_IO, 0); | 214 | res_fifo = platform_get_resource(pdev, IORESOURCE_IO, 0); |
| 213 | if (!res_fifo) | 215 | if (!res_fifo) |
| 214 | return -EINVAL; | 216 | return -EINVAL; |
| 215 | 217 | ||
| 216 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
| 217 | resource_size(res), pdev->name)) { | ||
| 218 | dev_warn(&pdev->dev, "Failed to get memory resourse\n"); | ||
| 219 | return -ENOENT; | ||
| 220 | } | ||
| 221 | |||
| 222 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); | 218 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); |
| 223 | if (!host) { | 219 | if (!host) { |
| 224 | dev_warn(&pdev->dev, "kzalloc fail\n"); | 220 | dev_warn(&pdev->dev, "kzalloc fail\n"); |
| 225 | return -ENOMEM; | 221 | return -ENOMEM; |
| 226 | } | 222 | } |
| 227 | 223 | ||
| 228 | host->io_base = devm_ioremap(&pdev->dev, res->start, | 224 | host->io_base = io_base; |
| 229 | resource_size(res)); | ||
| 230 | if (!host->io_base) { | ||
| 231 | dev_warn(&pdev->dev, "ioremap failed\n"); | ||
| 232 | return -ENOMEM; | ||
| 233 | } | ||
| 234 | |||
| 235 | host->irq = platform_get_irq(pdev, 0); | 225 | host->irq = platform_get_irq(pdev, 0); |
| 236 | if (host->irq < 0) | 226 | if (host->irq < 0) |
| 237 | return -EINVAL; | 227 | return -EINVAL; |
diff --git a/sound/soc/spear/spear_pcm.c b/sound/soc/spear/spear_pcm.c index a7dc3c56f44d..e8476da157cd 100644 --- a/sound/soc/spear/spear_pcm.c +++ b/sound/soc/spear/spear_pcm.c | |||
| @@ -44,7 +44,7 @@ int devm_spear_pcm_platform_register(struct device *dev, | |||
| 44 | *config = spear_dmaengine_pcm_config; | 44 | *config = spear_dmaengine_pcm_config; |
| 45 | config->compat_filter_fn = filter; | 45 | config->compat_filter_fn = filter; |
| 46 | 46 | ||
| 47 | return snd_dmaengine_pcm_register(dev, config, | 47 | return devm_snd_dmaengine_pcm_register(dev, config, |
| 48 | SND_DMAENGINE_PCM_FLAG_NO_DT | | 48 | SND_DMAENGINE_PCM_FLAG_NO_DT | |
| 49 | SND_DMAENGINE_PCM_FLAG_COMPAT); | 49 | SND_DMAENGINE_PCM_FLAG_COMPAT); |
| 50 | } | 50 | } |
