aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOder Chiou <oder_chiou@realtek.com>2014-10-06 04:30:51 -0400
committerMark Brown <broonie@kernel.org>2014-10-20 07:22:20 -0400
commitaf48f1d08a5474184da9aaf8b77f4a2848b1875e (patch)
tree59de8e574da74fe9ee49b8f426209a4ee5d91a6b
parent40eb90a18e93fbd4fd0e6892b31241356c3c8e43 (diff)
ASoC: rt5677: Support DSP function for VAD application
The ALC5677 has a programmable DSP, and there is a SPI that is dadicated for DSP firmware loading. Therefore, the patch includes a SPI driver for writing the DSP firmware. The VAD(Voice Activaty Detection) has be implemented and use the DSP to recognize the key phase. Signed-off-by: Oder Chiou <oder_chiou@realtek.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/Makefile2
-rw-r--r--sound/soc/codecs/rt5677-spi.c128
-rw-r--r--sound/soc/codecs/rt5677-spi.h21
-rw-r--r--sound/soc/codecs/rt5677.c288
-rw-r--r--sound/soc/codecs/rt5677.h6
5 files changed, 440 insertions, 5 deletions
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 5dce451661e4..4435f9f18ce8 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -79,7 +79,7 @@ snd-soc-rt5640-objs := rt5640.o
79snd-soc-rt5645-objs := rt5645.o 79snd-soc-rt5645-objs := rt5645.o
80snd-soc-rt5651-objs := rt5651.o 80snd-soc-rt5651-objs := rt5651.o
81snd-soc-rt5670-objs := rt5670.o 81snd-soc-rt5670-objs := rt5670.o
82snd-soc-rt5677-objs := rt5677.o 82snd-soc-rt5677-objs := rt5677.o rt5677-spi.o
83snd-soc-sgtl5000-objs := sgtl5000.o 83snd-soc-sgtl5000-objs := sgtl5000.o
84snd-soc-alc5623-objs := alc5623.o 84snd-soc-alc5623-objs := alc5623.o
85snd-soc-alc5632-objs := alc5632.o 85snd-soc-alc5632-objs := alc5632.o
diff --git a/sound/soc/codecs/rt5677-spi.c b/sound/soc/codecs/rt5677-spi.c
new file mode 100644
index 000000000000..11c38f3a9b72
--- /dev/null
+++ b/sound/soc/codecs/rt5677-spi.c
@@ -0,0 +1,128 @@
1/*
2 * rt5677-spi.c -- RT5677 ALSA SoC audio codec driver
3 *
4 * Copyright 2013 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
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
12#include <linux/module.h>
13#include <linux/input.h>
14#include <linux/spi/spi.h>
15#include <linux/device.h>
16#include <linux/init.h>
17#include <linux/delay.h>
18#include <linux/interrupt.h>
19#include <linux/irq.h>
20#include <linux/slab.h>
21#include <linux/gpio.h>
22#include <linux/sched.h>
23#include <linux/kthread.h>
24#include <linux/uaccess.h>
25#include <linux/miscdevice.h>
26#include <linux/regulator/consumer.h>
27#include <linux/pm_qos.h>
28#include <linux/sysfs.h>
29#include <linux/clk.h>
30#include <linux/firmware.h>
31
32#include "rt5677-spi.h"
33
34static struct spi_device *g_spi;
35
36/**
37 * rt5677_spi_write - Write data to SPI.
38 * @txbuf: Data Buffer for writing.
39 * @len: Data length.
40 *
41 *
42 * Returns true for success.
43 */
44int rt5677_spi_write(u8 *txbuf, size_t len)
45{
46 int status;
47
48 status = spi_write(g_spi, txbuf, len);
49
50 if (status)
51 dev_err(&g_spi->dev, "rt5677_spi_write error %d\n", status);
52
53 return status;
54}
55
56/**
57 * rt5677_spi_burst_write - Write data to SPI by rt5677 dsp memory address.
58 * @addr: Start address.
59 * @txbuf: Data Buffer for writng.
60 * @len: Data length, it must be a multiple of 8.
61 *
62 *
63 * Returns true for success.
64 */
65int rt5677_spi_burst_write(u32 addr, const struct firmware *fw)
66{
67 u8 spi_cmd = RT5677_SPI_CMD_BURST_WRITE;
68 u8 *write_buf;
69 unsigned int i, end, offset = 0;
70
71 write_buf = kmalloc(RT5677_SPI_BUF_LEN + 6, GFP_KERNEL);
72
73 if (write_buf == NULL)
74 return -ENOMEM;
75
76 while (offset < fw->size) {
77 if (offset + RT5677_SPI_BUF_LEN <= fw->size)
78 end = RT5677_SPI_BUF_LEN;
79 else
80 end = fw->size % RT5677_SPI_BUF_LEN;
81
82 write_buf[0] = spi_cmd;
83 write_buf[1] = ((addr + offset) & 0xff000000) >> 24;
84 write_buf[2] = ((addr + offset) & 0x00ff0000) >> 16;
85 write_buf[3] = ((addr + offset) & 0x0000ff00) >> 8;
86 write_buf[4] = ((addr + offset) & 0x000000ff) >> 0;
87
88 for (i = 0; i < end; i += 8) {
89 write_buf[i + 12] = fw->data[offset + i + 0];
90 write_buf[i + 11] = fw->data[offset + i + 1];
91 write_buf[i + 10] = fw->data[offset + i + 2];
92 write_buf[i + 9] = fw->data[offset + i + 3];
93 write_buf[i + 8] = fw->data[offset + i + 4];
94 write_buf[i + 7] = fw->data[offset + i + 5];
95 write_buf[i + 6] = fw->data[offset + i + 6];
96 write_buf[i + 5] = fw->data[offset + i + 7];
97 }
98
99 write_buf[end + 5] = spi_cmd;
100
101 rt5677_spi_write(write_buf, end + 6);
102
103 offset += RT5677_SPI_BUF_LEN;
104 }
105
106 kfree(write_buf);
107
108 return 0;
109}
110
111static int rt5677_spi_probe(struct spi_device *spi)
112{
113 g_spi = spi;
114 return 0;
115}
116
117static struct spi_driver rt5677_spi_driver = {
118 .driver = {
119 .name = "rt5677",
120 .owner = THIS_MODULE,
121 },
122 .probe = rt5677_spi_probe,
123};
124module_spi_driver(rt5677_spi_driver);
125
126MODULE_DESCRIPTION("ASoC RT5677 SPI driver");
127MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>");
128MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/codecs/rt5677-spi.h b/sound/soc/codecs/rt5677-spi.h
new file mode 100644
index 000000000000..7528bfd0b596
--- /dev/null
+++ b/sound/soc/codecs/rt5677-spi.h
@@ -0,0 +1,21 @@
1/*
2 * rt5677-spi.h -- RT5677 ALSA SoC audio codec driver
3 *
4 * Copyright 2013 Realtek Semiconductor Corp.
5 * Author: Oder Chiou <oder_chiou@realtek.com>
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
12#ifndef __RT5671_SPI_H__
13#define __RT5671_SPI_H__
14
15#define RT5677_SPI_BUF_LEN 240
16#define RT5677_SPI_CMD_BURST_WRITE 0x05
17
18int rt5677_spi_write(u8 *txbuf, size_t len);
19int rt5677_spi_burst_write(u32 addr, const struct firmware *fw);
20
21#endif /* __RT5677_SPI_H__ */
diff --git a/sound/soc/codecs/rt5677.c b/sound/soc/codecs/rt5677.c
index a454df39b7a5..e6e54fa648aa 100644
--- a/sound/soc/codecs/rt5677.c
+++ b/sound/soc/codecs/rt5677.c
@@ -20,6 +20,7 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/platform_device.h> 21#include <linux/platform_device.h>
22#include <linux/spi/spi.h> 22#include <linux/spi/spi.h>
23#include <linux/firmware.h>
23#include <linux/gpio.h> 24#include <linux/gpio.h>
24#include <sound/core.h> 25#include <sound/core.h>
25#include <sound/pcm.h> 26#include <sound/pcm.h>
@@ -31,6 +32,7 @@
31 32
32#include "rl6231.h" 33#include "rl6231.h"
33#include "rt5677.h" 34#include "rt5677.h"
35#include "rt5677-spi.h"
34 36
35#define RT5677_DEVICE_ID 0x6327 37#define RT5677_DEVICE_ID 0x6327
36 38
@@ -537,6 +539,243 @@ static bool rt5677_readable_register(struct device *dev, unsigned int reg)
537 } 539 }
538} 540}
539 541
542/**
543 * rt5677_dsp_mode_i2c_write_addr - Write value to address on DSP mode.
544 * @codec: SoC audio codec device.
545 * @addr: Address index.
546 * @value: Address data.
547 *
548 *
549 * Returns 0 for success or negative error code.
550 */
551static int rt5677_dsp_mode_i2c_write_addr(struct snd_soc_codec *codec,
552 unsigned int addr, unsigned int value, unsigned int opcode)
553{
554 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
555 int ret;
556
557 mutex_lock(&rt5677->dsp_cmd_lock);
558
559 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_MSB, addr >> 16);
560 if (ret < 0) {
561 dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret);
562 goto err;
563 }
564
565 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_LSB,
566 addr & 0xffff);
567 if (ret < 0) {
568 dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret);
569 goto err;
570 }
571
572 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_DATA_MSB,
573 value >> 16);
574 if (ret < 0) {
575 dev_err(codec->dev, "Failed to set data msb value: %d\n", ret);
576 goto err;
577 }
578
579 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_DATA_LSB,
580 value & 0xffff);
581 if (ret < 0) {
582 dev_err(codec->dev, "Failed to set data lsb value: %d\n", ret);
583 goto err;
584 }
585
586 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_OP_CODE, opcode);
587 if (ret < 0) {
588 dev_err(codec->dev, "Failed to set op code value: %d\n", ret);
589 goto err;
590 }
591
592err:
593 mutex_unlock(&rt5677->dsp_cmd_lock);
594
595 return ret;
596}
597
598/**
599 * rt5677_dsp_mode_i2c_read_addr - Read value from address on DSP mode.
600 * @codec: SoC audio codec device.
601 * @addr: Address index.
602 * @value: Address data.
603 *
604 * Returns 0 for success or negative error code.
605 */
606static int rt5677_dsp_mode_i2c_read_addr(
607 struct snd_soc_codec *codec, unsigned int addr, unsigned int *value)
608{
609 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
610 int ret;
611 unsigned int msb, lsb;
612
613 mutex_lock(&rt5677->dsp_cmd_lock);
614
615 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_MSB, addr >> 16);
616 if (ret < 0) {
617 dev_err(codec->dev, "Failed to set addr msb value: %d\n", ret);
618 goto err;
619 }
620
621 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_ADDR_LSB,
622 addr & 0xffff);
623 if (ret < 0) {
624 dev_err(codec->dev, "Failed to set addr lsb value: %d\n", ret);
625 goto err;
626 }
627
628 ret = regmap_write(rt5677->regmap, RT5677_DSP_I2C_OP_CODE , 0x0002);
629 if (ret < 0) {
630 dev_err(codec->dev, "Failed to set op code value: %d\n", ret);
631 goto err;
632 }
633
634 regmap_read(rt5677->regmap, RT5677_DSP_I2C_DATA_MSB, &msb);
635 regmap_read(rt5677->regmap, RT5677_DSP_I2C_DATA_LSB, &lsb);
636 *value = (msb << 16) | lsb;
637
638err:
639 mutex_unlock(&rt5677->dsp_cmd_lock);
640
641 return ret;
642}
643
644/**
645 * rt5677_dsp_mode_i2c_write - Write register on DSP mode.
646 * @codec: SoC audio codec device.
647 * @reg: Register index.
648 * @value: Register data.
649 *
650 *
651 * Returns 0 for success or negative error code.
652 */
653static int rt5677_dsp_mode_i2c_write(struct snd_soc_codec *codec,
654 unsigned int reg, unsigned int value)
655{
656 return rt5677_dsp_mode_i2c_write_addr(codec, 0x18020000 + reg * 2,
657 value, 0x0001);
658}
659
660/**
661 * rt5677_dsp_mode_i2c_read - Read register on DSP mode.
662 * @codec: SoC audio codec device.
663 * @reg: Register index.
664 *
665 *
666 * Returns Register value.
667 */
668static unsigned int rt5677_dsp_mode_i2c_read(
669 struct snd_soc_codec *codec, unsigned int reg)
670{
671 unsigned int value = 0;
672
673 rt5677_dsp_mode_i2c_read_addr(codec, 0x18020000 + reg * 2, &value);
674
675 return value;
676}
677
678/**
679 * rt5677_dsp_mode_i2c_update_bits - update register on DSP mode.
680 * @codec: audio codec
681 * @reg: register index.
682 * @mask: register mask
683 * @value: new value
684 *
685 *
686 * Returns 1 for change, 0 for no change, or negative error code.
687 */
688static int rt5677_dsp_mode_i2c_update_bits(struct snd_soc_codec *codec,
689 unsigned int reg, unsigned int mask, unsigned int value)
690{
691 unsigned int old, new;
692 int change, ret;
693
694 ret = rt5677_dsp_mode_i2c_read(codec, reg);
695 if (ret < 0) {
696 dev_err(codec->dev, "Failed to read reg: %d\n", ret);
697 goto err;
698 }
699
700 old = ret;
701 new = (old & ~mask) | (value & mask);
702 change = old != new;
703 if (change) {
704 ret = rt5677_dsp_mode_i2c_write(codec, reg, new);
705 if (ret < 0) {
706 dev_err(codec->dev,
707 "Failed to write reg: %d\n", ret);
708 goto err;
709 }
710 }
711 return change;
712
713err:
714 return ret;
715}
716
717static int rt5677_set_dsp_vad(struct snd_soc_codec *codec, bool on)
718{
719 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
720 static bool activity;
721 int ret;
722
723 if (on && !activity) {
724 activity = true;
725
726 regcache_cache_only(rt5677->regmap, false);
727 regcache_cache_bypass(rt5677->regmap, true);
728
729 regmap_update_bits(rt5677->regmap, RT5677_DIG_MISC, 0x1, 0x1);
730 regmap_update_bits(rt5677->regmap,
731 RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0f00);
732 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
733 RT5677_LDO1_SEL_MASK, 0x0);
734 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG2,
735 RT5677_PWR_LDO1, RT5677_PWR_LDO1);
736 regmap_write(rt5677->regmap, RT5677_GLB_CLK2, 0x0080);
737 regmap_write(rt5677->regmap, RT5677_PWR_DSP2, 0x07ff);
738 regmap_write(rt5677->regmap, RT5677_PWR_DSP1, 0x07ff);
739
740 ret = request_firmware(&rt5677->fw1, RT5677_FIRMWARE1,
741 codec->dev);
742 if (ret == 0) {
743 rt5677_spi_burst_write(0x50000000, rt5677->fw1);
744 release_firmware(rt5677->fw1);
745 }
746
747 ret = request_firmware(&rt5677->fw2, RT5677_FIRMWARE2,
748 codec->dev);
749 if (ret == 0) {
750 rt5677_spi_burst_write(0x60000000, rt5677->fw2);
751 release_firmware(rt5677->fw2);
752 }
753
754 rt5677_dsp_mode_i2c_update_bits(codec, RT5677_PWR_DSP1, 0x1,
755 0x0);
756
757 regcache_cache_bypass(rt5677->regmap, false);
758 regcache_cache_only(rt5677->regmap, true);
759 } else if (!on && activity) {
760 activity = false;
761
762 regcache_cache_only(rt5677->regmap, false);
763 regcache_cache_bypass(rt5677->regmap, true);
764
765 rt5677_dsp_mode_i2c_update_bits(codec, RT5677_PWR_DSP1, 0x1,
766 0x1);
767 rt5677_dsp_mode_i2c_write(codec, RT5677_PWR_DSP1, 0x0001);
768
769 regmap_write(rt5677->regmap, RT5677_RESET, 0x10ec);
770
771 regcache_cache_bypass(rt5677->regmap, false);
772 regcache_mark_dirty(rt5677->regmap);
773 regcache_sync(rt5677->regmap);
774 }
775
776 return 0;
777}
778
540static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0); 779static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
541static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0); 780static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -65625, 375, 0);
542static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); 781static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
@@ -556,6 +795,31 @@ static unsigned int bst_tlv[] = {
556 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0), 795 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
557}; 796};
558 797
798static int rt5677_dsp_vad_get(struct snd_kcontrol *kcontrol,
799 struct snd_ctl_elem_value *ucontrol)
800{
801 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
802 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
803
804 ucontrol->value.integer.value[0] = rt5677->dsp_vad_en;
805
806 return 0;
807}
808
809static int rt5677_dsp_vad_put(struct snd_kcontrol *kcontrol,
810 struct snd_ctl_elem_value *ucontrol)
811{
812 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
813 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
814
815 rt5677->dsp_vad_en = !!ucontrol->value.integer.value[0];
816
817 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF)
818 rt5677_set_dsp_vad(codec, rt5677->dsp_vad_en);
819
820 return 0;
821}
822
559static const struct snd_kcontrol_new rt5677_snd_controls[] = { 823static const struct snd_kcontrol_new rt5677_snd_controls[] = {
560 /* OUTPUT Control */ 824 /* OUTPUT Control */
561 SOC_SINGLE("OUT1 Playback Switch", RT5677_LOUT1, 825 SOC_SINGLE("OUT1 Playback Switch", RT5677_LOUT1,
@@ -627,6 +891,9 @@ static const struct snd_kcontrol_new rt5677_snd_controls[] = {
627 SOC_DOUBLE_TLV("Mono ADC Boost Volume", RT5677_ADC_BST_CTRL2, 891 SOC_DOUBLE_TLV("Mono ADC Boost Volume", RT5677_ADC_BST_CTRL2,
628 RT5677_MONO_ADC_L_BST_SFT, RT5677_MONO_ADC_R_BST_SFT, 3, 0, 892 RT5677_MONO_ADC_L_BST_SFT, RT5677_MONO_ADC_R_BST_SFT, 3, 0,
629 adc_bst_tlv), 893 adc_bst_tlv),
894
895 SOC_SINGLE_EXT("DSP VAD Switch", SND_SOC_NOPM, 0, 1, 0,
896 rt5677_dsp_vad_get, rt5677_dsp_vad_put),
630}; 897};
631 898
632/** 899/**
@@ -3181,6 +3448,8 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
3181 3448
3182 case SND_SOC_BIAS_PREPARE: 3449 case SND_SOC_BIAS_PREPARE:
3183 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { 3450 if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) {
3451 rt5677_set_dsp_vad(codec, false);
3452
3184 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1, 3453 regmap_update_bits(rt5677->regmap, RT5677_PWR_ANLG1,
3185 RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK, 3454 RT5677_LDO1_SEL_MASK | RT5677_LDO2_SEL_MASK,
3186 0x0055); 3455 0x0055);
@@ -3214,6 +3483,9 @@ static int rt5677_set_bias_level(struct snd_soc_codec *codec,
3214 regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000); 3483 regmap_write(rt5677->regmap, RT5677_PWR_ANLG2, 0x0000);
3215 regmap_update_bits(rt5677->regmap, 3484 regmap_update_bits(rt5677->regmap,
3216 RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000); 3485 RT5677_PR_BASE + RT5677_BIAS_CUR4, 0x0f00, 0x0000);
3486
3487 if (rt5677->dsp_vad_en)
3488 rt5677_set_dsp_vad(codec, true);
3217 break; 3489 break;
3218 3490
3219 default: 3491 default:
@@ -3407,6 +3679,8 @@ static int rt5677_probe(struct snd_soc_codec *codec)
3407 for (i = 0; i < RT5677_GPIO_NUM; i++) 3679 for (i = 0; i < RT5677_GPIO_NUM; i++)
3408 rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]); 3680 rt5677_gpio_config(rt5677, i, rt5677->pdata.gpio_config[i]);
3409 3681
3682 mutex_init(&rt5677->dsp_cmd_lock);
3683
3410 return 0; 3684 return 0;
3411} 3685}
3412 3686
@@ -3426,8 +3700,11 @@ static int rt5677_suspend(struct snd_soc_codec *codec)
3426{ 3700{
3427 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec); 3701 struct rt5677_priv *rt5677 = snd_soc_codec_get_drvdata(codec);
3428 3702
3429 regcache_cache_only(rt5677->regmap, true); 3703 if (!rt5677->dsp_vad_en) {
3430 regcache_mark_dirty(rt5677->regmap); 3704 regcache_cache_only(rt5677->regmap, true);
3705 regcache_mark_dirty(rt5677->regmap);
3706 }
3707
3431 if (gpio_is_valid(rt5677->pow_ldo2)) 3708 if (gpio_is_valid(rt5677->pow_ldo2))
3432 gpio_set_value_cansleep(rt5677->pow_ldo2, 0); 3709 gpio_set_value_cansleep(rt5677->pow_ldo2, 0);
3433 3710
@@ -3442,8 +3719,11 @@ static int rt5677_resume(struct snd_soc_codec *codec)
3442 gpio_set_value_cansleep(rt5677->pow_ldo2, 1); 3719 gpio_set_value_cansleep(rt5677->pow_ldo2, 1);
3443 msleep(10); 3720 msleep(10);
3444 } 3721 }
3445 regcache_cache_only(rt5677->regmap, false); 3722
3446 regcache_sync(rt5677->regmap); 3723 if (!rt5677->dsp_vad_en) {
3724 regcache_cache_only(rt5677->regmap, false);
3725 regcache_sync(rt5677->regmap);
3726 }
3447 3727
3448 return 0; 3728 return 0;
3449} 3729}
diff --git a/sound/soc/codecs/rt5677.h b/sound/soc/codecs/rt5677.h
index 99fd023e3290..20efa4a4c82c 100644
--- a/sound/soc/codecs/rt5677.h
+++ b/sound/soc/codecs/rt5677.h
@@ -1507,6 +1507,9 @@
1507#define RT5677_GPIO5_FUNC_GPIO (0x0 << 9) 1507#define RT5677_GPIO5_FUNC_GPIO (0x0 << 9)
1508#define RT5677_GPIO5_FUNC_DMIC (0x1 << 9) 1508#define RT5677_GPIO5_FUNC_DMIC (0x1 << 9)
1509 1509
1510#define RT5677_FIRMWARE1 "rt5677_dsp_fw1.bin"
1511#define RT5677_FIRMWARE2 "rt5677_dsp_fw2.bin"
1512
1510/* System Clock Source */ 1513/* System Clock Source */
1511enum { 1514enum {
1512 RT5677_SCLK_S_MCLK, 1515 RT5677_SCLK_S_MCLK,
@@ -1546,6 +1549,8 @@ struct rt5677_priv {
1546 struct snd_soc_codec *codec; 1549 struct snd_soc_codec *codec;
1547 struct rt5677_platform_data pdata; 1550 struct rt5677_platform_data pdata;
1548 struct regmap *regmap; 1551 struct regmap *regmap;
1552 const struct firmware *fw1, *fw2;
1553 struct mutex dsp_cmd_lock;
1549 1554
1550 int sysclk; 1555 int sysclk;
1551 int sysclk_src; 1556 int sysclk_src;
@@ -1559,6 +1564,7 @@ struct rt5677_priv {
1559#ifdef CONFIG_GPIOLIB 1564#ifdef CONFIG_GPIOLIB
1560 struct gpio_chip gpio_chip; 1565 struct gpio_chip gpio_chip;
1561#endif 1566#endif
1567 bool dsp_vad_en;
1562}; 1568};
1563 1569
1564#endif /* __RT5677_H__ */ 1570#endif /* __RT5677_H__ */