ALSA: hda - Handle get/set power verb symmetrically via regmap
authorTakashi Iwai <tiwai@suse.de>
Mon, 9 Mar 2015 21:19:47 +0000 (22:19 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 23 Mar 2015 12:19:43 +0000 (13:19 +0100)
HD-audio has quite a few asymmetrical ways of accessing verbs, and one
of typical ones is GET/SET_POWER_STATE verbs.  While it takes only the
power state for setting, it returns a combination of states for
getting.  For making the state handling simpler, this patch adds a
code to translate the value returned from GET_POWER_STATE to return
only the actual state or -1 for error.  In that way, the driver can
simplify the power state management.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
sound/hda/hdac_regmap.c

index fb4a02e0319f7aca9ee9cd2d6494853d6e89f17d..2eea8d4e6a7fe007fa0bfde67cb2c2d8bb39ea44 100644 (file)
@@ -191,13 +191,24 @@ static int hda_reg_write_stereo_amp(struct hdac_device *codec,
 static int hda_reg_read(void *context, unsigned int reg, unsigned int *val)
 {
        struct hdac_device *codec = context;
+       int err;
 
        if (!codec_is_running(codec))
                return -EAGAIN;
        reg |= (codec->addr << 28);
        if (is_stereo_amp_verb(reg))
                return hda_reg_read_stereo_amp(codec, reg, val);
-       return snd_hdac_exec_verb(codec, reg, 0, val);
+       err = snd_hdac_exec_verb(codec, reg, 0, val);
+       if (err < 0)
+               return err;
+       /* special handling for asymmetric reads */
+       if (get_verb(reg) == AC_VERB_GET_POWER_STATE) {
+               if (*val & AC_PWRST_ERROR)
+                       *val = -1;
+               else /* take only the actual state */
+                       *val = (*val >> 4) & 0x0f;
+       }
+       return 0;
 }
 
 static int hda_reg_write(void *context, unsigned int reg, unsigned int val)