ALSA: hda - Use regmap for command verb caches, too
authorTakashi Iwai <tiwai@suse.de>
Thu, 26 Feb 2015 11:34:49 +0000 (12:34 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 23 Mar 2015 12:19:41 +0000 (13:19 +0100)
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>
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_generic.c
sound/pci/hda/patch_analog.c
sound/pci/hda/patch_conexant.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_si3054.c
sound/pci/hda/patch_sigmatel.c

index b27f250088c15dc65df763f3407914add6e64f1f..41851f9b48c1130229fd1d72a68a90a550334152 100644 (file)
@@ -807,10 +807,6 @@ static void hda_jackpoll_work(struct work_struct *work)
                              codec->jackpoll_interval);
 }
 
-static void init_hda_cache(struct hda_cache_rec *cache,
-                          unsigned int record_size);
-static void free_hda_cache(struct hda_cache_rec *cache);
-
 /* release all pincfg lists */
 static void free_init_pincfgs(struct hda_codec *codec)
 {
@@ -929,9 +925,6 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
        codec->proc_widget_hook = NULL;
        codec->spec = NULL;
 
-       free_hda_cache(&codec->cmd_cache);
-       init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
-
        /* free only driver_pins so that init_pins + user_pins are restored */
        snd_array_free(&codec->driver_pins);
        snd_array_free(&codec->cvt_setups);
@@ -994,7 +987,6 @@ static void snd_hda_codec_dev_release(struct device *dev)
        free_init_pincfgs(codec);
        snd_hdac_device_exit(&codec->core);
        snd_hda_sysfs_clear(codec);
-       free_hda_cache(&codec->cmd_cache);
        kfree(codec->modelname);
        kfree(codec->wcaps);
        kfree(codec);
@@ -1047,8 +1039,6 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
        codec->addr = codec_addr;
        mutex_init(&codec->spdif_mutex);
        mutex_init(&codec->control_mutex);
-       mutex_init(&codec->hash_mutex);
-       init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
        snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
        snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
        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)
  * amp access functions
  */
 
-/* FIXME: more better hash key? */
-#define HDA_HASH_KEY(nid, dir, idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
-#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
-#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
-#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
-#define INFO_AMP_CAPS  (1<<0)
-#define INFO_AMP_VOL(ch)       (1 << (1 + (ch)))
-
-/* initialize the hash table */
-static void init_hda_cache(struct hda_cache_rec *cache,
-                                    unsigned int record_size)
-{
-       memset(cache, 0, sizeof(*cache));
-       memset(cache->hash, 0xff, sizeof(cache->hash));
-       snd_array_init(&cache->buf, record_size, 64);
-}
-
-static void free_hda_cache(struct hda_cache_rec *cache)
-{
-       snd_array_free(&cache->buf);
-}
-
-/* query the hash.  allocate an entry if not found. */
-static struct hda_cache_head  *get_hash(struct hda_cache_rec *cache, u32 key)
-{
-       u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
-       u16 cur = cache->hash[idx];
-       struct hda_cache_head *info;
-
-       while (cur != 0xffff) {
-               info = snd_array_elem(&cache->buf, cur);
-               if (info->key == key)
-                       return info;
-               cur = info->next;
-       }
-       return NULL;
-}
-
-/* query the hash.  allocate an entry if not found. */
-static struct hda_cache_head  *get_alloc_hash(struct hda_cache_rec *cache,
-                                             u32 key)
-{
-       struct hda_cache_head *info = get_hash(cache, key);
-       if (!info) {
-               u16 idx, cur;
-               /* add a new hash entry */
-               info = snd_array_new(&cache->buf);
-               if (!info)
-                       return NULL;
-               cur = snd_array_index(&cache->buf, info);
-               info->key = key;
-               info->val = 0;
-               info->dirty = 0;
-               idx = key % (u16)ARRAY_SIZE(cache->hash);
-               info->next = cache->hash[idx];
-               cache->hash[idx] = cur;
-       }
-       return info;
-}
-
 /**
  * query_amp_caps - query AMP capabilities
  * @codec: the HD-auio codec
@@ -2589,25 +2519,35 @@ static unsigned int convert_to_spdif_status(unsigned short val)
 
 /* set digital convert verbs both for the given NID and its slaves */
 static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
-                       int verb, int val)
+                       int mask, int val)
 {
        const hda_nid_t *d;
 
-       snd_hda_codec_write_cache(codec, nid, 0, verb, val);
+       snd_hdac_regmap_update(&codec->core, nid, AC_VERB_SET_DIGI_CONVERT_1,
+                              mask, val);
        d = codec->slave_dig_outs;
        if (!d)
                return;
        for (; *d; d++)
-               snd_hda_codec_write_cache(codec, *d, 0, verb, val);
+               snd_hdac_regmap_update(&codec->core, nid,
+                                      AC_VERB_SET_DIGI_CONVERT_1, mask, val);
 }
 
 static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
                                       int dig1, int dig2)
 {
-       if (dig1 != -1)
-               set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1);
-       if (dig2 != -1)
-               set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2);
+       unsigned int mask = 0;
+       unsigned int val = 0;
+
+       if (dig1 != -1) {
+               mask |= 0xff;
+               val = dig1;
+       }
+       if (dig2 != -1) {
+               mask |= 0xff00;
+               val |= dig2 << 8;
+       }
+       set_dig_out(codec, nid, mask, val);
 }
 
 static 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,
        struct snd_kcontrol *kctl;
        struct snd_kcontrol_new *dig_mix;
        int idx = 0;
+       int val = 0;
        const int spdif_index = 16;
        struct hda_spdif_out *spdif;
        struct hda_bus *bus = codec->bus;
@@ -2780,8 +2721,9 @@ int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
                        return err;
        }
        spdif->nid = cvt_nid;
-       spdif->ctls = snd_hda_codec_read(codec, cvt_nid, 0,
-                                        AC_VERB_GET_DIGI_CONVERT_1, 0);
+       snd_hdac_regmap_read(&codec->core, cvt_nid,
+                            AC_VERB_GET_DIGI_CONVERT_1, &val);
+       spdif->ctls = val;
        spdif->status = convert_to_spdif_status(spdif->ctls);
        return 0;
 }
@@ -2925,8 +2867,8 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
        change = codec->spdif_in_enable != val;
        if (change) {
                codec->spdif_in_enable = val;
-               snd_hda_codec_write_cache(codec, nid, 0,
-                                         AC_VERB_SET_DIGI_CONVERT_1, val);
+               snd_hdac_regmap_write(&codec->core, nid,
+                                     AC_VERB_SET_DIGI_CONVERT_1, val);
        }
        mutex_unlock(&codec->spdif_mutex);
        return change;
@@ -2937,10 +2879,11 @@ static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
 {
        struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
        hda_nid_t nid = kcontrol->private_value;
-       unsigned short val;
+       unsigned int val;
        unsigned int sbits;
 
-       val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0);
+       snd_hdac_regmap_read(&codec->core, nid,
+                            AC_VERB_GET_DIGI_CONVERT_1, &val);
        sbits = convert_to_spdif_status(val);
        ucontrol->value.iec958.status[0] = sbits;
        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)
 }
 EXPORT_SYMBOL_GPL(snd_hda_create_spdif_in_ctls);
 
-/*
- * command cache
- */
-
-/* build a 31bit cache key with the widget id and the command parameter */
-#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
-#define get_cmd_cache_nid(key)         ((key) & 0xff)
-#define get_cmd_cache_cmd(key)         (((key) >> 8) & 0xffff)
-
-/**
- * snd_hda_codec_write_cache - send a single command with caching
- * @codec: the HDA codec
- * @nid: NID to send the command
- * @flags: optional bit flags
- * @verb: the verb to send
- * @parm: the parameter for the verb
- *
- * Send a single command without waiting for response.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
-                             int flags, unsigned int verb, unsigned int parm)
-{
-       int err;
-       struct hda_cache_head *c;
-       u32 key;
-       unsigned int cache_only;
-
-       cache_only = codec->cached_write;
-       if (!cache_only) {
-               err = snd_hda_codec_write(codec, nid, flags, verb, parm);
-               if (err < 0)
-                       return err;
-       }
-
-       /* parm may contain the verb stuff for get/set amp */
-       verb = verb | (parm >> 8);
-       parm &= 0xff;
-       key = build_cmd_cache_key(nid, verb);
-       mutex_lock(&codec->bus->core.cmd_mutex);
-       c = get_alloc_hash(&codec->cmd_cache, key);
-       if (c) {
-               c->val = parm;
-               c->dirty = cache_only;
-       }
-       mutex_unlock(&codec->bus->core.cmd_mutex);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(snd_hda_codec_write_cache);
-
-/**
- * snd_hda_codec_update_cache - check cache and write the cmd only when needed
- * @codec: the HDA codec
- * @nid: NID to send the command
- * @flags: optional bit flags
- * @verb: the verb to send
- * @parm: the parameter for the verb
- *
- * This function works like snd_hda_codec_write_cache(), but it doesn't send
- * command if the parameter is already identical with the cached value.
- * If not, it sends the command and refreshes the cache.
- *
- * Returns 0 if successful, or a negative error code.
- */
-int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
-                              int flags, unsigned int verb, unsigned int parm)
-{
-       struct hda_cache_head *c;
-       u32 key;
-
-       /* parm may contain the verb stuff for get/set amp */
-       verb = verb | (parm >> 8);
-       parm &= 0xff;
-       key = build_cmd_cache_key(nid, verb);
-       mutex_lock(&codec->bus->core.cmd_mutex);
-       c = get_hash(&codec->cmd_cache, key);
-       if (c && c->val == parm) {
-               mutex_unlock(&codec->bus->core.cmd_mutex);
-               return 0;
-       }
-       mutex_unlock(&codec->bus->core.cmd_mutex);
-       return snd_hda_codec_write_cache(codec, nid, flags, verb, parm);
-}
-EXPORT_SYMBOL_GPL(snd_hda_codec_update_cache);
-
-/**
- * snd_hda_codec_resume_cache - Resume the all commands from the cache
- * @codec: HD-audio codec
- *
- * Execute all verbs recorded in the command caches to resume.
- */
-void snd_hda_codec_resume_cache(struct hda_codec *codec)
-{
-       int i;
-
-       mutex_lock(&codec->hash_mutex);
-       codec->cached_write = 0;
-       for (i = 0; i < codec->cmd_cache.buf.used; i++) {
-               struct hda_cache_head *buffer;
-               u32 key;
-
-               buffer = snd_array_elem(&codec->cmd_cache.buf, i);
-               key = buffer->key;
-               if (!key)
-                       continue;
-               if (!buffer->dirty)
-                       continue;
-               buffer->dirty = 0;
-               mutex_unlock(&codec->hash_mutex);
-               snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0,
-                                   get_cmd_cache_cmd(key), buffer->val);
-               mutex_lock(&codec->hash_mutex);
-       }
-       mutex_unlock(&codec->hash_mutex);
-}
-EXPORT_SYMBOL_GPL(snd_hda_codec_resume_cache);
-
-/**
- * snd_hda_sequence_write_cache - sequence writes with caching
- * @codec: the HDA codec
- * @seq: VERB array to send
- *
- * Send the commands sequentially from the given array.
- * Thte commands are recorded on cache for power-save and resume.
- * The array must be terminated with NID=0.
- */
-void snd_hda_sequence_write_cache(struct hda_codec *codec,
-                                 const struct hda_verb *seq)
-{
-       for (; seq->nid; seq++)
-               snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
-                                         seq->param);
-}
-EXPORT_SYMBOL_GPL(snd_hda_sequence_write_cache);
-
-/**
- * snd_hda_codec_flush_cache - Execute all pending (cached) amps / verbs
- * @codec: HD-audio codec
- */
-void snd_hda_codec_flush_cache(struct hda_codec *codec)
-{
-       if (codec->core.regmap)
-               regcache_sync(codec->core.regmap);
-       snd_hda_codec_resume_cache(codec);
-}
-EXPORT_SYMBOL_GPL(snd_hda_codec_flush_cache);
-
 /**
  * snd_hda_codec_set_power_to_all - Set the power state to all widgets
  * @codec: the HDA codec
@@ -3354,17 +3149,6 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
        return state;
 }
 
-/* mark all entries of cmd and amp caches dirty */
-static void hda_mark_cmd_cache_dirty(struct hda_codec *codec)
-{
-       int i;
-       for (i = 0; i < codec->cmd_cache.buf.used; i++) {
-               struct hda_cache_head *cmd;
-               cmd = snd_array_elem(&codec->cmd_cache.buf, i);
-               cmd->dirty = 1;
-       }
-}
-
 /*
  * kick up codec; used both from PM and power-save
  */
@@ -3375,8 +3159,6 @@ static void hda_call_codec_resume(struct hda_codec *codec)
        if (codec->core.regmap)
                regcache_mark_dirty(codec->core.regmap);
 
-       hda_mark_cmd_cache_dirty(codec);
-
        codec->power_jiffies = jiffies;
 
        hda_set_power_state(codec, AC_PWRST_D0);
@@ -3390,7 +3172,6 @@ static void hda_call_codec_resume(struct hda_codec *codec)
                        codec->patch_ops.init(codec);
                if (codec->core.regmap)
                        regcache_sync(codec->core.regmap);
-               snd_hda_codec_resume_cache(codec);
        }
 
        if (codec->jackpoll_interval)
index 6af801a5bf89f28a0bc5a60a01b8f34d0195eb5a..26cbb1fa97294dbc32a03a235a409c0ed52cdae8 100644 (file)
@@ -155,19 +155,6 @@ struct hda_codec_ops {
        void (*stream_pm)(struct hda_codec *codec, hda_nid_t nid, bool on);
 };
 
-/* record for amp information cache */
-struct hda_cache_head {
-       u32 key:31;             /* hash key */
-       u32 dirty:1;
-       u16 val;                /* assigned value */
-       u16 next;
-};
-
-struct hda_cache_rec {
-       u16 hash[64];                   /* hash table for index */
-       struct snd_array buf;           /* record entries */
-};
-
 /* PCM callbacks */
 struct hda_pcm_ops {
        int (*open)(struct hda_pcm_stream *info, struct hda_codec *codec,
@@ -251,13 +238,10 @@ struct hda_codec {
        struct snd_array mixers;        /* list of assigned mixer elements */
        struct snd_array nids;          /* list of mapped mixer elements */
 
-       struct hda_cache_rec cmd_cache; /* cache for other commands */
-
        struct list_head conn_list;     /* linked-list of connection-list */
 
        struct mutex spdif_mutex;
        struct mutex control_mutex;
-       struct mutex hash_mutex;
        struct snd_array spdif_out;
        unsigned int spdif_in_enable;   /* SPDIF input enable? */
        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)
 }
 
 /* cached write */
-int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
-                             int flags, unsigned int verb, unsigned int parm);
-void snd_hda_sequence_write_cache(struct hda_codec *codec,
-                                 const struct hda_verb *seq);
-int snd_hda_codec_update_cache(struct hda_codec *codec, hda_nid_t nid,
-                             int flags, unsigned int verb, unsigned int parm);
-void snd_hda_codec_resume_cache(struct hda_codec *codec);
-/* both for cmd & amp caches */
-void snd_hda_codec_flush_cache(struct hda_codec *codec);
+static inline int
+snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
+                         int flags, unsigned int verb, unsigned int parm)
+{
+       return snd_hdac_regmap_write(&codec->core, nid, verb, parm);
+}
+
+#define snd_hda_codec_update_cache(codec, nid, flags, verb, parm) \
+       snd_hda_codec_write_cache(codec, nid, flags, verb, parm)
 
 /* the struct for codec->pin_configs */
 struct hda_pincfg {
index 4850f92c89c4c785c8a882dcf5b0c2862a0edbf7..f7ccef5559deac7e77d5f5bc7fe1b155d5f17d30 100644 (file)
@@ -3381,11 +3381,6 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,
        imux = &spec->input_mux;
        adc_idx = kcontrol->id.index;
        mutex_lock(&codec->control_mutex);
-       /* we use the cache-only update at first since multiple input paths
-        * may shared the same amp; by updating only caches, the redundant
-        * writes to hardware can be reduced.
-        */
-       codec->cached_write = 1;
        for (i = 0; i < imux->num_items; i++) {
                path = get_input_path(codec, adc_idx, i);
                if (!path || !path->ctls[type])
@@ -3393,12 +3388,9 @@ static int cap_put_caller(struct snd_kcontrol *kcontrol,
                kcontrol->private_value = path->ctls[type];
                err = func(kcontrol, ucontrol);
                if (err < 0)
-                       goto error;
+                       break;
        }
- error:
-       codec->cached_write = 0;
        mutex_unlock(&codec->control_mutex);
-       snd_hda_codec_flush_cache(codec); /* flush the updates */
        if (err >= 0 && spec->cap_sync_hook)
                spec->cap_sync_hook(codec, kcontrol, ucontrol);
        return err;
@@ -5760,8 +5752,6 @@ int snd_hda_gen_init(struct hda_codec *codec)
 
        snd_hda_apply_verbs(codec);
 
-       codec->cached_write = 1;
-
        init_multi_out(codec);
        init_extra_out(codec);
        init_multi_io(codec);
@@ -5777,7 +5767,7 @@ int snd_hda_gen_init(struct hda_codec *codec)
        /* call init functions of standard auto-mute helpers */
        update_automute_all(codec);
 
-       snd_hda_codec_flush_cache(codec);
+       regcache_sync(codec->core.regmap);
 
        if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook)
                snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
index 2278e83234b578831024f85dd7d27eac0e768275..231f89029779a02f5525416056b6e01dfc6c5c30 100644 (file)
@@ -777,7 +777,6 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
                return 0;
 
        mutex_lock(&codec->control_mutex);
-       codec->cached_write = 1;
        path = snd_hda_get_path_from_idx(codec,
                                         spec->smux_paths[spec->cur_smux]);
        if (path)
@@ -786,9 +785,7 @@ static int ad1988_auto_smux_enum_put(struct snd_kcontrol *kcontrol,
        if (path)
                snd_hda_activate_path(codec, path, true, true);
        spec->cur_smux = val;
-       codec->cached_write = 0;
        mutex_unlock(&codec->control_mutex);
-       snd_hda_codec_flush_cache(codec); /* flush the updates */
        return 1;
 }
 
@@ -1004,18 +1001,17 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
                                 const struct hda_fixup *fix, int action)
 {
        struct ad198x_spec *spec = codec->spec;
-       static const struct hda_verb gpio_init_verbs[] = {
-               {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
-               {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
-               {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
-               {},
-       };
 
        switch (action) {
        case HDA_FIXUP_ACT_PRE_PROBE:
                spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
                spec->gen.own_eapd_ctl = 1;
-               snd_hda_sequence_write_cache(codec, gpio_init_verbs);
+               snd_hda_codec_write_cache(codec, 0x01, 0,
+                                         AC_VERB_SET_GPIO_MASK, 0x02);
+               snd_hda_codec_write_cache(codec, 0x01, 0,
+                                         AC_VERB_SET_GPIO_DIRECTION, 0x02);
+               snd_hda_codec_write_cache(codec, 0x01, 0,
+                                         AC_VERB_SET_GPIO_DATA, 0x02);
                break;
        case HDA_FIXUP_ACT_PROBE:
                if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
index 1e21f9fbd54b93474ef18ae7b7df4f8da59ace01..f8f0dfbef1494538f2d2a370dc792cf860e68868 100644 (file)
@@ -302,6 +302,7 @@ static void cxt_fixup_headphone_mic(struct hda_codec *codec,
        switch (action) {
        case HDA_FIXUP_ACT_PRE_PROBE:
                spec->parse_flags |= HDA_PINCFG_HEADPHONE_MIC;
+               snd_hdac_regmap_add_vendor_verb(&codec->core, 0x410);
                break;
        case HDA_FIXUP_ACT_PROBE:
                spec->gen.cap_sync_hook = cxt_update_headset_mode_hook;
@@ -409,15 +410,11 @@ static void olpc_xo_automic(struct hda_codec *codec,
                            struct hda_jack_callback *jack)
 {
        struct conexant_spec *spec = codec->spec;
-       int saved_cached_write = codec->cached_write;
 
-       codec->cached_write = 1;
        /* in DC mode, we don't handle automic */
        if (!spec->dc_enable)
                snd_hda_gen_mic_autoswitch(codec, jack);
        olpc_xo_update_mic_pins(codec);
-       snd_hda_codec_flush_cache(codec);
-       codec->cached_write = saved_cached_write;
        if (spec->dc_enable)
                olpc_xo_update_mic_boost(codec);
 }
index 04c5ab20eb7676073807c4306a27618a5d821c32..ca0c05e1c42ede99cb1cf35f9b447687017be5cc 100644 (file)
@@ -2212,7 +2212,6 @@ static int generic_hdmi_resume(struct hda_codec *codec)
 
        codec->patch_ops.init(codec);
        regcache_sync(codec->core.regmap);
-       snd_hda_codec_resume_cache(codec);
 
        for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
                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)
 
        /* enable DP1.2 mode */
        vendor_param |= INTEL_EN_DP12;
+       snd_hdac_regmap_add_vendor_verb(&codec->core, INTEL_SET_VENDOR_VERB);
        snd_hda_codec_write_cache(codec, INTEL_VENDOR_NID, 0,
                                INTEL_SET_VENDOR_VERB, vendor_param);
 }
index a440e539230fc08028c30d8a44d2a328997bf0e2..d44cb7e37094f210d2a2f4135ef202544c2de8bb 100644 (file)
@@ -800,7 +800,6 @@ static int alc_resume(struct hda_codec *codec)
                msleep(150); /* to avoid pop noise */
        codec->patch_ops.init(codec);
        regcache_sync(codec->core.regmap);
-       snd_hda_codec_resume_cache(codec);
        hda_call_check_power_status(codec, 0x01);
        return 0;
 }
@@ -3059,7 +3058,6 @@ static int alc269_resume(struct hda_codec *codec)
        }
 
        regcache_sync(codec->core.regmap);
-       snd_hda_codec_resume_cache(codec);
        hda_call_check_power_status(codec, 0x01);
 
        /* on some machine, the BIOS will clear the codec gpio data when enter
index 49b4868797a59b40ad7b1a86d13c868ed73bd97f..5104bebb228699f1a04e754429f57e31622a521a 100644 (file)
@@ -222,6 +222,10 @@ static int si3054_init(struct hda_codec *codec)
        unsigned wait_count;
        u16 val;
 
+       if (snd_hdac_regmap_add_vendor_verb(&codec->core,
+                                           SI3054_VERB_WRITE_NODE))
+               return -ENOMEM;
+
        snd_hda_codec_write(codec, AC_NODE_ROOT, 0, AC_VERB_SET_CODEC_RESET, 0);
        snd_hda_codec_write(codec, codec->core.mfg, 0, AC_VERB_SET_STREAM_FORMAT, 0);
        SET_REG(codec, SI3054_LINE_RATE, 9600);
index b314551749f1798675714c19616da2c42532d9c3..43c99ce4a520c3fc24a720f6c76ba4222403ad3b 100644 (file)
@@ -1050,12 +1050,9 @@ static const struct hda_verb stac92hd71bxx_core_init[] = {
        {}
 };
 
-static const struct hda_verb stac92hd71bxx_unmute_core_init[] = {
+static const hda_nid_t stac92hd71bxx_unmute_nids[] = {
        /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */
-       { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
-       {}
+       0x0f, 0x0a, 0x0d, 0
 };
 
 static const struct hda_verb stac925x_core_init[] = {
@@ -4269,6 +4266,10 @@ static int stac_parse_auto_config(struct hda_codec *codec)
 
        if (spec->aloopback_ctl &&
            snd_hda_get_bool_hint(codec, "loopback") == 1) {
+               unsigned int wr_verb =
+                       spec->aloopback_ctl->private_value >> 16;
+               if (snd_hdac_regmap_add_vendor_verb(&codec->core, wr_verb))
+                       return -ENOMEM;
                if (!snd_hda_gen_add_kctl(&spec->gen, NULL, spec->aloopback_ctl))
                        return -ENOMEM;
        }
@@ -4688,7 +4689,7 @@ static int patch_stac92hd95(struct hda_codec *codec)
 static int patch_stac92hd71bxx(struct hda_codec *codec)
 {
        struct sigmatel_spec *spec;
-       const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init;
+       const hda_nid_t *unmute_nids = stac92hd71bxx_unmute_nids;
        int err;
 
        err = alloc_stac_spec(codec);
@@ -4713,7 +4714,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
        switch (codec->core.vendor_id) {
        case 0x111d76b6: /* 4 Port without Analog Mixer */
        case 0x111d76b7:
-               unmute_init++;
+               unmute_nids++;
                break;
        case 0x111d7608: /* 5 Port with Analog Mixer */
                if ((codec->core.revision_id & 0xf) == 0 ||
@@ -4721,7 +4722,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
                        spec->stream_delay = 40; /* 40 milliseconds */
 
                /* disable VSW */
-               unmute_init++;
+               unmute_nids++;
                snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0);
                snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3);
                break;
@@ -4735,8 +4736,12 @@ static int patch_stac92hd71bxx(struct hda_codec *codec)
        if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB)
                snd_hda_add_verbs(codec, stac92hd71bxx_core_init);
 
-       if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP)
-               snd_hda_sequence_write_cache(codec, unmute_init);
+       if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) {
+               const hda_nid_t *p;
+               for (p = unmute_nids; *p; p++)
+                       snd_hda_codec_amp_init_stereo(codec, *p, HDA_INPUT, 0,
+                                                     0xff, 0x00);
+       }
 
        spec->aloopback_ctl = &stac92hd71bxx_loopback;
        spec->aloopback_mask = 0x50;