aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2015-02-26 06:34:49 -0500
committerTakashi Iwai <tiwai@suse.de>2015-03-23 08:19:41 -0400
commita551d91473e5e3a591f6fe86ac5a5fb460c3f96a (patch)
tree575e8ddcf88929d8fa8b50a9e32bec147f4f5820 /sound/pci
parent5e56bcea5017b7b7808df60f21ef01738b6e1a25 (diff)
ALSA: hda - Use regmap for command verb caches, too
Like the previous patches, this patch converts also to the regmap, at this time, the cached verb writes are the target. But this conversion needs a bit more caution than before. - In the old code, we just record any verbs as is, and restore them at resume. For the regmap scheme, this doesn't work, since a few verbs like AMP or DIGI_CONVERT are asymmetrical. Such verbs are converted either to the dedicated function (snd_hda_regmap_xxx_amp()) or changed to the unified verb. - Some verbs have to be declared as vendor-specific ones before accessing via regmap. Also, the minor optimization with codec->cached_write flag is dropped in a few places, as this would confuse the operation. Further optimizations will be brought in the later patches, if any. This conversion ends up with a drop of significant amount of codes, mostly the helper codes that are no longer used. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/hda_codec.c271
-rw-r--r--sound/pci/hda/hda_codec.h34
-rw-r--r--sound/pci/hda/hda_generic.c14
-rw-r--r--sound/pci/hda/patch_analog.c16
-rw-r--r--sound/pci/hda/patch_conexant.c5
-rw-r--r--sound/pci/hda/patch_hdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c2
-rw-r--r--sound/pci/hda/patch_si3054.c4
-rw-r--r--sound/pci/hda/patch_sigmatel.c25
9 files changed, 64 insertions, 309 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index b27f250088c1..41851f9b48c1 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -807,10 +807,6 @@ static void hda_jackpoll_work(struct work_struct *work)
807 codec->jackpoll_interval); 807 codec->jackpoll_interval);
808} 808}
809 809
810static void init_hda_cache(struct hda_cache_rec *cache,
811 unsigned int record_size);
812static void free_hda_cache(struct hda_cache_rec *cache);
813
814/* release all pincfg lists */ 810/* release all pincfg lists */
815static void free_init_pincfgs(struct hda_codec *codec) 811static void free_init_pincfgs(struct hda_codec *codec)
816{ 812{
@@ -929,9 +925,6 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
929 codec->proc_widget_hook = NULL; 925 codec->proc_widget_hook = NULL;
930 codec->spec = NULL; 926 codec->spec = NULL;
931 927
932 free_hda_cache(&codec->cmd_cache);
933 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
934
935 /* free only driver_pins so that init_pins + user_pins are restored */ 928 /* free only driver_pins so that init_pins + user_pins are restored */
936 snd_array_free(&codec->driver_pins); 929 snd_array_free(&codec->driver_pins);
937 snd_array_free(&codec->cvt_setups); 930 snd_array_free(&codec->cvt_setups);
@@ -994,7 +987,6 @@ static void snd_hda_codec_dev_release(struct device *dev)
994 free_init_pincfgs(codec); 987 free_init_pincfgs(codec);
995 snd_hdac_device_exit(&codec->core); 988 snd_hdac_device_exit(&codec->core);
996 snd_hda_sysfs_clear(codec); 989 snd_hda_sysfs_clear(codec);
997 free_hda_cache(&codec->cmd_cache);
998 kfree(codec->modelname); 990 kfree(codec->modelname);
999 kfree(codec->wcaps); 991 kfree(codec->wcaps);
1000 kfree(codec); 992 kfree(codec);
@@ -1047,8 +1039,6 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
1047 codec->addr = codec_addr; 1039 codec->addr = codec_addr;
1048 mutex_init(&codec->spdif_mutex); 1040 mutex_init(&codec->spdif_mutex);
1049 mutex_init(&codec->control_mutex); 1041 mutex_init(&codec->control_mutex);
1050 mutex_init(&codec->hash_mutex);
1051 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
1052 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32); 1042 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
1053 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32); 1043 snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
1054 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); 1044 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
@@ -1316,66 +1306,6 @@ static void hda_cleanup_all_streams(struct hda_codec *codec)
1316 * amp access functions 1306 * amp access functions
1317 */ 1307 */
1318 1308
1319/* FIXME: more better hash key? */
1320#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
1321#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
1322#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1323#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
1324#define INFO_AMP_CAPS (1<<0)
1325#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
1326
1327/* initialize the hash table */
1328static void init_hda_cache(struct hda_cache_rec *cache,
1329 unsigned int record_size)
1330{
1331 memset(cache, 0, sizeof(*cache));
1332 memset(cache->hash, 0xff, sizeof(cache->hash));
1333 snd_array_init(&cache->buf, record_size, 64);
1334}
1335
1336static void free_hda_cache(struct hda_cache_rec *cache)
1337{
1338 snd_array_free(&cache->buf);
1339}
1340
1341/* query the hash. allocate an entry if not found. */
1342static struct hda_cache_head *get_hash(struct hda_cache_rec *cache, u32 key)
1343{
1344 u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
1345 u16 cur = cache->hash[idx];
1346 struct hda_cache_head *info;
1347
1348 while (cur != 0xffff) {
1349 info = snd_array_elem(&cache->buf, cur);
1350 if (info->key == key)
1351 return info;
1352 cur = info->next;
1353 }
1354 return NULL;
1355}
1356
1357/* query the hash. allocate an entry if not found. */
1358static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1359 u32 key)
1360{
1361 struct hda_cache_head *info = get_hash(cache, key);
1362 if (!info) {
1363 u16 idx, cur;
1364 /* add a new hash entry */
1365 info = snd_array_new(&cache->buf);
1366 if (!info)
1367 return NULL;
1368 cur = snd_array_index(&cache->buf, info);
1369 info->key = key;
1370 info->val = 0;
1371 info->dirty = 0;
1372 idx = key % (u16)ARRAY_SIZE(cache->hash);
1373 info->next = cache->hash[idx];
1374 cache->hash[idx] = cur;
1375 }
1376 return info;
1377}
1378
1379/** 1309/**
1380 * query_amp_caps - query AMP capabilities 1310 * query_amp_caps - query AMP capabilities
1381 * @codec: the HD-auio codec 1311 * @codec: the HD-auio codec
@@ -2589,25 +2519,35 @@ static unsigned int convert_to_spdif_status(unsigned short val)
2589 2519
2590/* set digital convert verbs both for the given NID and its slaves */ 2520/* set digital convert verbs both for the given NID and its slaves */
2591static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, 2521static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
2592 int verb, int val) 2522 int mask, int val)
2593{ 2523{
2594 const hda_nid_t *d; 2524 const hda_nid_t *d;
2595 2525
2596 snd_hda_codec_write_cache(codec, nid, 0, verb, val); 2526 snd_hdac_regmap_update(&codec->core, nid, AC_VERB_SET_DIGI_CONVERT_1,
2527 mask, val);
2597 d = codec->slave_dig_outs; 2528 d = codec->slave_dig_outs;
2598 if (!d) 2529 if (!d)
2599 return; 2530 return;
2600 for (; *d; d++) 2531 for (; *d; d++)
2601 snd_hda_codec_write_cache(codec, *d, 0, verb, val); 2532 snd_hdac_regmap_update(&codec->core, nid,
2533 AC_VERB_SET_DIGI_CONVERT_1, mask, val);
2602} 2534}
2603 2535
2604static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid, 2536static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
2605 int dig1, int dig2) 2537 int dig1, int dig2)
2606{ 2538{
2607 if (dig1 != -1) 2539 unsigned int mask = 0;
2608 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1); 2540 unsigned int val = 0;
2609 if (dig2 != -1) 2541
2610 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2); 2542 if (dig1 != -1) {
2543 mask |= 0xff;
2544 val = dig1;
2545 }
2546 if (dig2 != -1) {
2547 mask |= 0xff00;
2548 val |= dig2 << 8;
2549 }
2550 set_dig_out(codec, nid, mask, val);
2611} 2551}
2612 2552
2613static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, 2553static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
@@ -2740,6 +2680,7 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
2740 struct snd_kcontrol *kctl; 2680 struct snd_kcontrol *kctl;
2741 struct snd_kcontrol_new *dig_mix; 2681 struct snd_kcontrol_new *dig_mix;
2742 int idx = 0; 2682 int idx = 0;
2683 int val = 0;
2743 const int spdif_index = 16; 2684 const int spdif_index = 16;
2744 struct hda_spdif_out *spdif; 2685 struct hda_spdif_out *spdif;
2745 struct hda_bus *bus = codec->bus; 2686 struct hda_bus *bus = codec->bus;
@@ -2780,8 +2721,9 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
2780 return err; 2721 return err;
2781 } 2722 }
2782 spdif->nid = cvt_nid; 2723 spdif->nid = cvt_nid;
2783 spdif->ctls = snd_hda_codec_read(codec, cvt_nid, 0, 2724 snd_hdac_regmap_read(&codec->core, cvt_nid,
2784 AC_VERB_GET_DIGI_CONVERT_1, 0); 2725 AC_VERB_GET_DIGI_CONVERT_1, &val);
2726 spdif->ctls = val;
2785 spdif->status = convert_to_spdif_status(spdif->ctls); 2727 spdif->status = convert_to_spdif_status(spdif->ctls);
2786 return 0; 2728 return 0;
2787} 2729}
@@ -2925,8 +2867,8 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
2925 change = codec->spdif_in_enable != val; 2867 change = codec->spdif_in_enable != val;
2926 if (change) { 2868 if (change) {
2927 codec->spdif_in_enable = val; 2869 codec->spdif_in_enable = val;
2928 snd_hda_codec_write_cache(codec, nid, 0, 2870 snd_hdac_regmap_write(&codec->core, nid,
2929 AC_VERB_SET_DIGI_CONVERT_1, val); 2871 AC_VERB_SET_DIGI_CONVERT_1, val);
2930 } 2872 }
2931 mutex_unlock(&codec->spdif_mutex); 2873 mutex_unlock(&codec->spdif_mutex);
2932 return change; 2874 return change;
@@ -2937,10 +2879,11 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2937{ 2879{
2938 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 2880 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2939 hda_nid_t nid = kcontrol->private_value; 2881 hda_nid_t nid = kcontrol->private_value;
2940 unsigned short val; 2882 unsigned int val;
2941 unsigned int sbits; 2883 unsigned int sbits;
2942 2884
2943 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0); 2885 snd_hdac_regmap_read(&codec->core, nid,
2886 AC_VERB_GET_DIGI_CONVERT_1, &val);
2944 sbits = convert_to_spdif_status(val); 2887 sbits = convert_to_spdif_status(val);
2945 ucontrol->value.iec958.status[0] = sbits; 2888 ucontrol->value.iec958.status[0] = sbits;
2946 ucontrol->value.iec958.status[1] = sbits >> 8; 2889 ucontrol->value.iec958.status[1] = sbits >> 8;
@@ -3006,154 +2949,6 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
3006} 2949}
3007EXPORT_SYMBOL_GPL(snd_hda_create_spdif_in_ctls); 2950EXPORT_SYMBOL_GPL(snd_hda_create_spdif_in_ctls);
3008 2951
3009/*
3010 * command cache
3011 */
3012
3013/* build a 31bit cache key with the widget id and the command parameter */
3014#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
3015#define get_cmd_cache_nid(key) ((key) & 0xff)
3016#define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff)
3017
3018/**
3019 * snd_hda_codec_write_cache - send a single command with caching
3020 * @codec: the HDA codec
3021 * @nid: NID to send the command
3022 * @flags: optional bit flags
3023 * @verb: the verb to send
3024 * @parm: the parameter for the verb
3025 *
3026 * Send a single command without waiting for response.
3027 *
3028 * Returns 0 if successful, or a negative error code.
3029 */
3030int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
3031 int flags, unsigned int verb, unsigned int parm)
3032{
3033 int err;
3034 struct hda_cache_head *c;
3035 u32 key;
3036 unsigned int cache_only;
3037
3038 cache_only = codec->cached_write;
3039 if (!cache_only) {
3040 err = snd_hda_codec_write(codec, nid, flags, verb, parm);
3041 if (err < 0)
3042 return err;
3043 }
3044
3045 /* parm may contain the verb stuff for get/set amp */
3046 verb = verb | (parm >> 8);
3047 parm &= 0xff;
3048 key = build_cmd_cache_key(nid, verb);
3049 mutex_lock(&codec->bus->core.cmd_mutex);
3050 c = get_alloc_hash(&codec->cmd_cache, key);
3051 if (c) {
3052 c->val = parm;
3053 c->dirty = cache_only;
3054 }
3055 mutex_unlock(&codec->bus->core.cmd_mutex);
3056 return 0;
3057}
3058EXPORT_SYMBOL_GPL(snd_hda_codec_write_cache);
3059
3060/**
3061 * snd_hda_codec_update_cache - check cache and write the cmd only when needed
3062 * @codec: the HDA codec
3063 * @nid: NID to send the command
3064 * @flags: optional bit flags
3065 * @verb: the verb to send
3066 * @parm: the parameter for the verb
3067 *
3068 * This function works like snd_hda_codec_write_cache(), but it doesn't send
3069 * command if the parameter is already identical with the cached value.
3070 * If not, it sends the command and refreshes the cache.
3071 *
3072 * Returns 0 if successful, or a negative error code.
3073 */
3074int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
3075 int flags, unsigned int verb, unsigned int parm)
3076{
3077 struct hda_cache_head *c;
3078 u32 key;
3079
3080 /* parm may contain the verb stuff for get/set amp */
3081 verb = verb | (parm >> 8);
3082 parm &= 0xff;
3083 key = build_cmd_cache_key(nid, verb);
3084 mutex_lock(&codec->bus->core.cmd_mutex);
3085 c = get_hash(&codec->cmd_cache, key);
3086 if (c && c->val == parm) {
3087 mutex_unlock(&codec->bus->core.cmd_mutex);
3088 return 0;
3089 }
3090 mutex_unlock(&codec->bus->core.cmd_mutex);
3091 return snd_hda_codec_write_cache(codec, nid, flags, verb, parm);
3092}
3093EXPORT_SYMBOL_GPL(snd_hda_codec_update_cache);
3094
3095/**
3096 * snd_hda_codec_resume_cache - Resume the all commands from the cache
3097 * @codec: HD-audio codec
3098 *
3099 * Execute all verbs recorded in the command caches to resume.
3100 */
3101void snd_hda_codec_resume_cache(struct hda_codec *codec)
3102{
3103 int i;
3104
3105 mutex_lock(&codec->hash_mutex);
3106 codec->cached_write = 0;
3107 for (i = 0; i < codec->cmd_cache.buf.used; i++) {
3108 struct hda_cache_head *buffer;
3109 u32 key;
3110
3111 buffer = snd_array_elem(&codec->cmd_cache.buf, i);
3112 key = buffer->key;
3113 if (!key)
3114 continue;
3115 if (!buffer->dirty)
3116 continue;
3117 buffer->dirty = 0;
3118 mutex_unlock(&codec->hash_mutex);
3119 snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0,
3120 get_cmd_cache_cmd(key), buffer->val);
3121 mutex_lock(&codec->hash_mutex);
3122 }
3123 mutex_unlock(&codec->hash_mutex);
3124}
3125EXPORT_SYMBOL_GPL(snd_hda_codec_resume_cache);
3126
3127/**
3128 * snd_hda_sequence_write_cache - sequence writes with caching
3129 * @codec: the HDA codec
3130 * @seq: VERB array to send
3131 *
3132 * Send the commands sequentially from the given array.
3133 * Thte commands are recorded on cache for power-save and resume.
3134 * The array must be terminated with NID=0.
3135 */
3136void snd_hda_sequence_write_cache(struct hda_codec *codec,
3137 const struct hda_verb *seq)
3138{
3139 for (; seq->nid; seq++)
3140 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
3141 seq->param);
3142}
3143EXPORT_SYMBOL_GPL(snd_hda_sequence_write_cache);
3144
3145/**
3146 * snd_hda_codec_flush_cache - Execute all pending (cached) amps / verbs
3147 * @codec: HD-audio codec
3148 */
3149void snd_hda_codec_flush_cache(struct hda_codec *codec)
3150{
3151 if (codec->core.regmap)
3152 regcache_sync(codec->core.regmap);
3153 snd_hda_codec_resume_cache(codec);
3154}
3155EXPORT_SYMBOL_GPL(snd_hda_codec_flush_cache);
3156
3157/** 2952/**
3158 * snd_hda_codec_set_power_to_all - Set the power state to all widgets 2953 * snd_hda_codec_set_power_to_all - Set the power state to all widgets
3159 * @codec: the HDA codec 2954 * @codec: the HDA codec
@@ -3354,17 +3149,6 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
3354 return state; 3149 return state;
3355} 3150}
3356 3151
3357/* mark all entries of cmd and amp caches dirty */
3358static void hda_mark_cmd_cache_dirty(struct hda_codec *codec)
3359{
3360 int i;
3361 for (i = 0; i < codec->cmd_cache.buf.used; i++) {
3362 struct hda_cache_head *cmd;
3363 cmd = snd_array_elem(&codec->cmd_cache.buf, i);
3364 cmd->dirty = 1;
3365 }
3366}
3367
3368/* 3152/*
3369 * kick up codec; used both from PM and power-save 3153 * kick up codec; used both from PM and power-save
3370 */ 3154 */
@@ -3375,8 +3159,6 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3375 if (codec->core.regmap) 3159 if (codec->core.regmap)
3376 regcache_mark_dirty(codec->core.regmap); 3160 regcache_mark_dirty(codec->core.regmap);
3377 3161
3378 hda_mark_cmd_cache_dirty(codec);
3379
3380 codec->power_jiffies = jiffies; 3162 codec->power_jiffies = jiffies;
3381 3163
3382 hda_set_power_state(codec, AC_PWRST_D0); 3164 hda_set_power_state(codec, AC_PWRST_D0);
@@ -3390,7 +3172,6 @@ static void hda_call_codec_resume(struct hda_codec *codec)
3390 codec->patch_ops.init(codec); 3172 codec->patch_ops.init(codec);
3391 if (codec->core.regmap) 3173 if (codec->core.regmap)
3392 regcache_sync(codec->core.regmap); 3174 regcache_sync(codec->core.regmap);
3393 snd_hda_codec_resume_cache(codec);
3394 } 3175 }
3395 3176
3396 if (codec->jackpoll_interval) 3177 if (codec->jackpoll_interval)
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 6af801a5bf89..26cbb1fa9729 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -155,19 +155,6 @@ struct hda_codec_ops {
155 void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on); 155 void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
156}; 156};
157 157
158/* record for amp information cache */
159struct hda_cache_head {
160 u32 key:31; /* hash key */
161 u32 dirty:1;
162 u16 val; /* assigned value */
163 u16 next;
164};
165
166struct hda_cache_rec {
167 u16 hash[64]; /* hash table for index */
168 struct snd_array buf; /* record entries */
169};
170
171/* PCM callbacks */ 158/* PCM callbacks */
172struct hda_pcm_ops { 159struct hda_pcm_ops {
173 int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec, 160 int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
@@ -251,13 +238,10 @@ struct hda_codec {
251 struct snd_array mixers; /* list of assigned mixer elements */ 238 struct snd_array mixers; /* list of assigned mixer elements */
252 struct snd_array nids; /* list of mapped mixer elements */ 239 struct snd_array nids; /* list of mapped mixer elements */
253 240
254 struct hda_cache_rec cmd_cache; /* cache for other commands */
255
256 struct list_head conn_list; /* linked-list of connection-list */ 241 struct list_head conn_list; /* linked-list of connection-list */
257 242
258 struct mutex spdif_mutex; 243 struct mutex spdif_mutex;
259 struct mutex control_mutex; 244 struct mutex control_mutex;
260 struct mutex hash_mutex;
261 struct snd_array spdif_out; 245 struct snd_array spdif_out;
262 unsigned int spdif_in_enable; /* SPDIF input enable? */ 246 unsigned int spdif_in_enable; /* SPDIF input enable? */
263 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ 247 const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */
@@ -406,15 +390,15 @@ snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
406} 390}
407 391
408/* cached write */ 392/* cached write */
409int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, 393static inline int
410 int flags, unsigned int verb, unsigned int parm); 394snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
411void snd_hda_sequence_write_cache(struct hda_codec *codec, 395 int flags, unsigned int verb, unsigned int parm)
412 const struct hda_verb *seq); 396{
413int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid, 397 return snd_hdac_regmap_write(&codec->core, nid, verb, parm);
414 int flags, unsigned int verb, unsigned int parm); 398}
415void snd_hda_codec_resume_cache(struct hda_codec *codec); 399
416/* both for cmd & amp caches */ 400#define snd_hda_codec_update_cache(codec, nid, flags, verb, parm) \
417void snd_hda_codec_flush_cache(struct hda_codec *codec); 401 snd_hda_codec_write_cache(codec, nid, flags, verb, parm)
418 402
419/* the struct for codec->pin_configs */ 403/* the struct for codec->pin_configs */
420struct hda_pincfg { 404struct hda_pincfg {
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index 4850f92c89c4..f7ccef5559de 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -3381,11 +3381,6 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,
3381 imux = &spec->input_mux; 3381 imux = &spec->input_mux;
3382 adc_idx = kcontrol->id.index; 3382 adc_idx = kcontrol->id.index;
3383 mutex_lock(&codec->control_mutex); 3383 mutex_lock(&codec->control_mutex);
3384 /* we use the cache-only update at first since multiple input paths
3385 * may shared the same amp; by updating only caches, the redundant
3386 * writes to hardware can be reduced.
3387 */
3388 codec->cached_write = 1;
3389 for (i = 0; i < imux->num_items; i++) { 3384 for (i = 0; i < imux->num_items; i++) {
3390 path = get_input_path(codec, adc_idx, i); 3385 path = get_input_path(codec, adc_idx, i);
3391 if (!path || !path->ctls[type]) 3386 if (!path || !path->ctls[type])
@@ -3393,12 +3388,9 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,
3393 kcontrol->private_value = path->ctls[type]; 3388 kcontrol->private_value = path->ctls[type];
3394 err = func(kcontrol, ucontrol); 3389 err = func(kcontrol, ucontrol);
3395 if (err < 0) 3390 if (err < 0)
3396 goto error; 3391 break;
3397 } 3392 }
3398 error:
3399 codec->cached_write = 0;
3400 mutex_unlock(&codec->control_mutex); 3393 mutex_unlock(&codec->control_mutex);
3401 snd_hda_codec_flush_cache(codec); /* flush the updates */
3402 if (err >= 0 && spec->cap_sync_hook) 3394 if (err >= 0 && spec->cap_sync_hook)
3403 spec->cap_sync_hook(codec, kcontrol, ucontrol); 3395 spec->cap_sync_hook(codec, kcontrol, ucontrol);
3404 return err; 3396 return err;
@@ -5760,8 +5752,6 @@ int snd_hda_gen_init(struct hda_codec *codec)
5760 5752
5761 snd_hda_apply_verbs(codec); 5753 snd_hda_apply_verbs(codec);
5762 5754
5763 codec->cached_write = 1;
5764
5765 init_multi_out(codec); 5755 init_multi_out(codec);
5766 init_extra_out(codec); 5756 init_extra_out(codec);
5767 init_multi_io(codec); 5757 init_multi_io(codec);
@@ -5777,7 +5767,7 @@ int snd_hda_gen_init(struct hda_codec *codec)
5777 /* call init functions of standard auto-mute helpers */ 5767 /* call init functions of standard auto-mute helpers */
5778 update_automute_all(codec); 5768 update_automute_all(codec);
5779 5769
5780 snd_hda_codec_flush_cache(codec); 5770 regcache_sync(codec->core.regmap);
5781 5771
5782 if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook) 5772 if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook)
5783 snd_hda_sync_vmaster_hook(&spec->vmaster_mute); 5773 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 2278e83234b5..231f89029779 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -777,7 +777,6 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
777 return 0; 777 return 0;
778 778
779 mutex_lock(&codec->control_mutex); 779 mutex_lock(&codec->control_mutex);
780 codec->cached_write = 1;
781 path = snd_hda_get_path_from_idx(codec, 780 path = snd_hda_get_path_from_idx(codec,
782 spec->smux_paths[spec->cur_smux]); 781 spec->smux_paths[spec->cur_smux]);
783 if (path) 782 if (path)
@@ -786,9 +785,7 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
786 if (path) 785 if (path)
787 snd_hda_activate_path(codec, path, true, true); 786 snd_hda_activate_path(codec, path, true, true);
788 spec->cur_smux = val; 787 spec->cur_smux = val;
789 codec->cached_write = 0;
790 mutex_unlock(&codec->control_mutex); 788 mutex_unlock(&codec->control_mutex);
791 snd_hda_codec_flush_cache(codec); /* flush the updates */
792 return 1; 789 return 1;
793} 790}
794 791
@@ -1004,18 +1001,17 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
1004 const struct hda_fixup *fix, int action) 1001 const struct hda_fixup *fix, int action)
1005{ 1002{
1006 struct ad198x_spec *spec = codec->spec; 1003 struct ad198x_spec *spec = codec->spec;
1007 static const struct hda_verb gpio_init_verbs[] = {
1008 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
1009 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
1010 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
1011 {},
1012 };
1013 1004
1014 switch (action) { 1005 switch (action) {
1015 case HDA_FIXUP_ACT_PRE_PROBE: 1006 case HDA_FIXUP_ACT_PRE_PROBE:
1016 spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook; 1007 spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
1017 spec->gen.own_eapd_ctl = 1; 1008 spec->gen.own_eapd_ctl = 1;
1018 snd_hda_sequence_write_cache(codec, gpio_init_verbs); 1009 snd_hda_codec_write_cache(codec, 0x01, 0,
1010 AC_VERB_SET_GPIO_MASK, 0x02);
1011 snd_hda_codec_write_cache(codec, 0x01, 0,
1012 AC_VERB_SET_GPIO_DIRECTION, 0x02);
1013 snd_hda_codec_write_cache(codec, 0x01, 0,
1014 AC_VERB_SET_GPIO_DATA, 0x02);
1019 break; 1015 break;
1020 case HDA_FIXUP_ACT_PROBE: 1016 case HDA_FIXUP_ACT_PROBE:
1021 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 1017 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 1e21f9fbd54b..f8f0dfbef149 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -302,6 +302,7 @@ static void cxt_fixup_headphone_mic(struct hda_codec *codec,
302 switch (action) { 302 switch (action) {
303 case HDA_FIXUP_ACT_PRE_PROBE: 303 case HDA_FIXUP_ACT_PRE_PROBE:
304 spec->parse_flags |= HDA_PINCFG_HEADPHONE_MIC; 304 spec->parse_flags |= HDA_PINCFG_HEADPHONE_MIC;
305 snd_hdac_regmap_add_vendor_verb(&codec->core, 0x410);
305 break; 306 break;
306 case HDA_FIXUP_ACT_PROBE: 307 case HDA_FIXUP_ACT_PROBE:
307 spec->gen.cap_sync_hook = cxt_update_headset_mode_hook; 308 spec->gen.cap_sync_hook = cxt_update_headset_mode_hook;
@@ -409,15 +410,11 @@ static void olpc_xo_automic(struct hda_codec *codec,
409 struct hda_jack_callback *jack) 410 struct hda_jack_callback *jack)
410{ 411{
411 struct conexant_spec *spec = codec->spec; 412 struct conexant_spec *spec = codec->spec;
412 int saved_cached_write = codec->cached_write;
413 413
414 codec->cached_write = 1;
415 /* in DC mode, we don't handle automic */ 414 /* in DC mode, we don't handle automic */
416 if (!spec->dc_enable) 415 if (!spec->dc_enable)
417 snd_hda_gen_mic_autoswitch(codec, jack); 416 snd_hda_gen_mic_autoswitch(codec, jack);
418 olpc_xo_update_mic_pins(codec); 417 olpc_xo_update_mic_pins(codec);
419 snd_hda_codec_flush_cache(codec);
420 codec->cached_write = saved_cached_write;
421 if (spec->dc_enable) 418 if (spec->dc_enable)
422 olpc_xo_update_mic_boost(codec); 419 olpc_xo_update_mic_boost(codec);
423} 420}
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 04c5ab20eb76..ca0c05e1c42e 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -2212,7 +2212,6 @@ static int generic_hdmi_resume(struct hda_codec *codec)
2212 2212
2213 codec->patch_ops.init(codec); 2213 codec->patch_ops.init(codec);
2214 regcache_sync(codec->core.regmap); 2214 regcache_sync(codec->core.regmap);
2215 snd_hda_codec_resume_cache(codec);
2216 2215
2217 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 2216 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
2218 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); 2217 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
@@ -2299,6 +2298,7 @@ static void intel_haswell_fixup_enable_dp12(struct hda_codec *codec)
2299 2298
2300 /* enable DP1.2 mode */ 2299 /* enable DP1.2 mode */
2301 vendor_param |= INTEL_EN_DP12; 2300 vendor_param |= INTEL_EN_DP12;
2301 snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB);
2302 snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0, 2302 snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0,
2303 INTEL_SET_VENDOR_VERB, vendor_param); 2303 INTEL_SET_VENDOR_VERB, vendor_param);
2304} 2304}
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index a440e539230f..d44cb7e37094 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -800,7 +800,6 @@ static int alc_resume(struct hda_codec *codec)
800 msleep(150); /* to avoid pop noise */ 800 msleep(150); /* to avoid pop noise */
801 codec->patch_ops.init(codec); 801 codec->patch_ops.init(codec);
802 regcache_sync(codec->core.regmap); 802 regcache_sync(codec->core.regmap);
803 snd_hda_codec_resume_cache(codec);
804 hda_call_check_power_status(codec, 0x01); 803 hda_call_check_power_status(codec, 0x01);
805 return 0; 804 return 0;
806} 805}
@@ -3059,7 +3058,6 @@ static int alc269_resume(struct hda_codec *codec)
3059 } 3058 }
3060 3059
3061 regcache_sync(codec->core.regmap); 3060 regcache_sync(codec->core.regmap);
3062 snd_hda_codec_resume_cache(codec);
3063 hda_call_check_power_status(codec, 0x01); 3061 hda_call_check_power_status(codec, 0x01);
3064 3062
3065 /* on some machine, the BIOS will clear the codec gpio data when enter 3063 /* on some machine, the BIOS will clear the codec gpio data when enter
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c
index 49b4868797a5..5104bebb2286 100644
--- a/sound/pci/hda/patch_si3054.c
+++ b/sound/pci/hda/patch_si3054.c
@@ -222,6 +222,10 @@ static int si3054_init(struct hda_codec *codec)
222 unsigned wait_count; 222 unsigned wait_count;
223 u16 val; 223 u16 val;
224 224
225 if (snd_hdac_regmap_add_vendor_verb(&codec->core,
226 SI3054_VERB_WRITE_NODE))
227 return -ENOMEM;
228
225 snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0); 229 snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0);
226 snd_hda_codec_write(codec, codec->core.mfg, 0, AC_VERB_SET_STREAM_FORMAT, 0); 230 snd_hda_codec_write(codec, codec->core.mfg, 0, AC_VERB_SET_STREAM_FORMAT, 0);
227 SET_REG(codec, SI3054_LINE_RATE, 9600); 231 SET_REG(codec, SI3054_LINE_RATE, 9600);
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index b314551749f1..43c99ce4a520 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -1050,12 +1050,9 @@ static const struct hda_verb stac92hd71bxx_core_init[] = {
1050 {} 1050 {}
1051}; 1051};
1052 1052
1053static const struct hda_verb stac92hd71bxx_unmute_core_init[] = { 1053static const hda_nid_t stac92hd71bxx_unmute_nids[] = {
1054 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ 1054 /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
1055 { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1055 0x0f, 0x0a, 0x0d, 0
1056 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1057 { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1058 {}
1059}; 1056};
1060 1057
1061static const struct hda_verb stac925x_core_init[] = { 1058static const struct hda_verb stac925x_core_init[] = {
@@ -4269,6 +4266,10 @@ static int stac_parse_auto_config(struct hda_codec *codec)
4269 4266
4270 if (spec->aloopback_ctl && 4267 if (spec->aloopback_ctl &&
4271 snd_hda_get_bool_hint(codec, "loopback") == 1) { 4268 snd_hda_get_bool_hint(codec, "loopback") == 1) {
4269 unsigned int wr_verb =
4270 spec->aloopback_ctl->private_value >> 16;
4271 if (snd_hdac_regmap_add_vendor_verb(&codec->core, wr_verb))
4272 return -ENOMEM;
4272 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl)) 4273 if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
4273 return -ENOMEM; 4274 return -ENOMEM;
4274 } 4275 }
@@ -4688,7 +4689,7 @@ static int patch_stac92hd95(struct hda_codec *codec)
4688static int patch_stac92hd71bxx(struct hda_codec *codec) 4689static int patch_stac92hd71bxx(struct hda_codec *codec)
4689{ 4690{
4690 struct sigmatel_spec *spec; 4691 struct sigmatel_spec *spec;
4691 const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; 4692 const hda_nid_t *unmute_nids = stac92hd71bxx_unmute_nids;
4692 int err; 4693 int err;
4693 4694
4694 err = alloc_stac_spec(codec); 4695 err = alloc_stac_spec(codec);
@@ -4713,7 +4714,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
4713 switch (codec->core.vendor_id) { 4714 switch (codec->core.vendor_id) {
4714 case 0x111d76b6: /* 4 Port without Analog Mixer */ 4715 case 0x111d76b6: /* 4 Port without Analog Mixer */
4715 case 0x111d76b7: 4716 case 0x111d76b7:
4716 unmute_init++; 4717 unmute_nids++;
4717 break; 4718 break;
4718 case 0x111d7608: /* 5 Port with Analog Mixer */ 4719 case 0x111d7608: /* 5 Port with Analog Mixer */
4719 if ((codec->core.revision_id & 0xf) == 0 || 4720 if ((codec->core.revision_id & 0xf) == 0 ||
@@ -4721,7 +4722,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
4721 spec->stream_delay = 40; /* 40 milliseconds */ 4722 spec->stream_delay = 40; /* 40 milliseconds */
4722 4723
4723 /* disable VSW */ 4724 /* disable VSW */
4724 unmute_init++; 4725 unmute_nids++;
4725 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); 4726 snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
4726 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); 4727 snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
4727 break; 4728 break;
@@ -4735,8 +4736,12 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
4735 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB) 4736 if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
4736 snd_hda_add_verbs(codec, stac92hd71bxx_core_init); 4737 snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
4737 4738
4738 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) 4739 if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) {
4739 snd_hda_sequence_write_cache(codec, unmute_init); 4740 const hda_nid_t *p;
4741 for (p = unmute_nids; *p; p++)
4742 snd_hda_codec_amp_init_stereo(codec, *p, HDA_INPUT, 0,
4743 0xff, 0x00);
4744 }
4740 4745
4741 spec->aloopback_ctl = &stac92hd71bxx_loopback; 4746 spec->aloopback_ctl = &stac92hd71bxx_loopback;
4742 spec->aloopback_mask = 0x50; 4747 spec->aloopback_mask = 0x50;