Commit b8df15b2 authored by Lu Guanqun's avatar Lu Guanqun Committed by Greg Kroah-Hartman

intel_sst: add Master Volume

With this patch, Master Volume will control AUDIOLVOL(0x10c) and
AUDIORVOL(0x10d); while PCM Volume will control HPLVOL(0x123) and
HPRVOL(0x124).
Signed-off-by: default avatarLu Guanqun <guanqun.lu@intel.com>
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent e1bfee26
...@@ -57,9 +57,9 @@ ...@@ -57,9 +57,9 @@
#define MAX_CHANNEL_DMIC 5 #define MAX_CHANNEL_DMIC 5
#define FIFO_SIZE 0 /* fifo not being used */ #define FIFO_SIZE 0 /* fifo not being used */
#define INTEL_MAD "Intel MAD" #define INTEL_MAD "Intel MAD"
#define MAX_CTRL_MRST 7 #define MAX_CTRL_MRST 8
#define MAX_CTRL_MFLD 7 #define MAX_CTRL_MFLD 7
#define MAX_CTRL 7 #define MAX_CTRL 8
#define MAX_VENDORS 4 #define MAX_VENDORS 4
/* TODO +6 db */ /* TODO +6 db */
#define MAX_VOL 64 #define MAX_VOL 64
...@@ -145,6 +145,8 @@ struct snd_control_val { ...@@ -145,6 +145,8 @@ struct snd_control_val {
int playback_vol_min; int playback_vol_min;
int capture_vol_max; int capture_vol_max;
int capture_vol_min; int capture_vol_min;
int master_vol_max;
int master_vol_min;
}; };
struct mad_stream_pvt { struct mad_stream_pvt {
...@@ -175,6 +177,7 @@ enum _widget_ctrl { ...@@ -175,6 +177,7 @@ enum _widget_ctrl {
PLAYBACK_MUTE, PLAYBACK_MUTE,
CAPTURE_VOL, CAPTURE_VOL,
CAPTURE_MUTE, CAPTURE_MUTE,
MASTER_VOL,
MASTER_MUTE MASTER_MUTE
}; };
enum _widget_ctrl_mfld { enum _widget_ctrl_mfld {
......
...@@ -80,9 +80,11 @@ struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = { ...@@ -80,9 +80,11 @@ struct snd_control_val intelmad_ctrl_val[MAX_VENDORS] = {
}, },
{ {
.playback_vol_max = 0, .playback_vol_max = 0,
.playback_vol_min = -126, .playback_vol_min = -31,
.capture_vol_max = 0, .capture_vol_max = 0,
.capture_vol_min = -31, .capture_vol_min = -31,
.master_vol_max = 0,
.master_vol_min = -126,
}, },
}; };
...@@ -159,6 +161,15 @@ static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol, ...@@ -159,6 +161,15 @@ static int snd_intelmad_playback_volume_info(struct snd_kcontrol *kcontrol,
return 0; return 0;
} }
static int snd_intelmad_master_volume_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
snd_intelmad_volume_info(uinfo, STEREO_CNTL,
intelmad_ctrl_val[sst_card_vendor_id].master_vol_max,
intelmad_ctrl_val[sst_card_vendor_id].master_vol_min);
return 0;
}
/** /**
* snd_intelmad_device_info_mrst - provides information about the devices available * snd_intelmad_device_info_mrst - provides information about the devices available
* *
...@@ -281,6 +292,11 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol, ...@@ -281,6 +292,11 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,
case CAPTURE_VOL: case CAPTURE_VOL:
cntl_list[0] = PMIC_SND_CAPTURE_VOL; cntl_list[0] = PMIC_SND_CAPTURE_VOL;
break; break;
case MASTER_VOL:
cntl_list[0] = PMIC_SND_RIGHT_MASTER_VOL;
cntl_list[1] = PMIC_SND_LEFT_MASTER_VOL;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -291,7 +307,8 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol, ...@@ -291,7 +307,8 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol,
if (ret_val) if (ret_val)
return ret_val; return ret_val;
if (kcontrol->id.numid == PLAYBACK_VOL) { if (kcontrol->id.numid == PLAYBACK_VOL ||
kcontrol->id.numid == MASTER_VOL) {
ret_val = scard_ops->get_vol(cntl_list[1], &value); ret_val = scard_ops->get_vol(cntl_list[1], &value);
uval->value.integer.value[1] = value; uval->value.integer.value[1] = value;
} }
...@@ -399,6 +416,12 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol, ...@@ -399,6 +416,12 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,
case CAPTURE_VOL: case CAPTURE_VOL:
cntl_list[0] = PMIC_SND_CAPTURE_VOL; cntl_list[0] = PMIC_SND_CAPTURE_VOL;
break; break;
case MASTER_VOL:
cntl_list[0] = PMIC_SND_LEFT_MASTER_VOL;
cntl_list[1] = PMIC_SND_RIGHT_MASTER_VOL;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
...@@ -408,7 +431,8 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol, ...@@ -408,7 +431,8 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol,
if (ret_val) if (ret_val)
return ret_val; return ret_val;
if (kcontrol->id.numid == PLAYBACK_VOL) if (kcontrol->id.numid == PLAYBACK_VOL ||
kcontrol->id.numid == MASTER_VOL)
ret_val = scard_ops->set_vol(cntl_list[1], ret_val = scard_ops->set_vol(cntl_list[1],
uval->value.integer.value[1]); uval->value.integer.value[1]);
return ret_val; return ret_val;
...@@ -753,7 +777,6 @@ static int snd_intelmad_device_dmic_info_mfld(struct snd_kcontrol *kcontrol, ...@@ -753,7 +777,6 @@ static int snd_intelmad_device_dmic_info_mfld(struct snd_kcontrol *kcontrol,
return 0; return 0;
} }
struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = { struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
...@@ -809,6 +832,15 @@ struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = { ...@@ -809,6 +832,15 @@ struct snd_kcontrol_new snd_intelmad_controls_mrst[MAX_CTRL] __devinitdata = {
.put = snd_intelmad_mute_set, .put = snd_intelmad_mute_set,
.private_value = 0, .private_value = 0,
}, },
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Volume",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = snd_intelmad_master_volume_info,
.get = snd_intelmad_volume_get,
.put = snd_intelmad_volume_set,
.private_value = 0,
},
{ {
.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Switch", .name = "Master Playback Switch",
......
...@@ -111,6 +111,8 @@ enum pmic_controls { ...@@ -111,6 +111,8 @@ enum pmic_controls {
PMIC_SND_RIGHT_SPEAKER_MUTE = 0x0015, PMIC_SND_RIGHT_SPEAKER_MUTE = 0x0015,
PMIC_SND_RECEIVER_VOL = 0x0016, PMIC_SND_RECEIVER_VOL = 0x0016,
PMIC_SND_RECEIVER_MUTE = 0x0017, PMIC_SND_RECEIVER_MUTE = 0x0017,
PMIC_SND_LEFT_MASTER_VOL = 0x0018,
PMIC_SND_RIGHT_MASTER_VOL = 0x0019,
/* Other controls */ /* Other controls */
PMIC_SND_MUTE_ALL = 0x0020, PMIC_SND_MUTE_ALL = 0x0020,
PMIC_MAX_CONTROLS = 0x0020, PMIC_MAX_CONTROLS = 0x0020,
......
...@@ -787,9 +787,8 @@ static int nc_set_vol(int dev_id, int value) ...@@ -787,9 +787,8 @@ static int nc_set_vol(int dev_id, int value)
case PMIC_SND_LEFT_PB_VOL: case PMIC_SND_LEFT_PB_VOL:
pr_debug("PMIC_SND_LEFT_HP_VOL %d\n", value); pr_debug("PMIC_SND_LEFT_HP_VOL %d\n", value);
sc_access[0].value = -value; sc_access[0].value = -value;
sc_access[0].reg_addr = AUDIOLVOL; sc_access[0].reg_addr = HPLVOL;
sc_access[0].mask = sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
entries = 1; entries = 1;
break; break;
...@@ -800,12 +799,29 @@ static int nc_set_vol(int dev_id, int value) ...@@ -800,12 +799,29 @@ static int nc_set_vol(int dev_id, int value)
sc_access[0].reg_addr = RMUTE; sc_access[0].reg_addr = RMUTE;
sc_access[0].mask = MASK2; sc_access[0].mask = MASK2;
} else { } else {
sc_access[0].value = -value;
sc_access[0].reg_addr = HPRVOL;
sc_access[0].mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
}
entries = 1;
break;
case PMIC_SND_LEFT_MASTER_VOL:
pr_debug("PMIC_SND_LEFT_MASTER_VOL value %d\n", value);
sc_access[0].value = -value;
sc_access[0].reg_addr = AUDIOLVOL;
sc_access[0].mask =
(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
entries = 1;
break;
case PMIC_SND_RIGHT_MASTER_VOL:
pr_debug("PMIC_SND_RIGHT_MASTER_VOL value %d\n", value);
sc_access[0].value = -value; sc_access[0].value = -value;
sc_access[0].reg_addr = AUDIORVOL; sc_access[0].reg_addr = AUDIORVOL;
sc_access[0].mask = sc_access[0].mask =
(MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
entries = 1; entries = 1;
}
break; break;
default: default:
...@@ -970,18 +986,30 @@ static int nc_get_vol(int dev_id, int *value) ...@@ -970,18 +986,30 @@ static int nc_get_vol(int dev_id, int *value)
mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5);
break; break;
case PMIC_SND_RIGHT_PB_VOL: case PMIC_SND_LEFT_MASTER_VOL:
pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n"); pr_debug("GET_VOLUME_PMIC_LEFT_MASTER_VOL\n");
sc_access.reg_addr = AUDIOLVOL; sc_access.reg_addr = AUDIOLVOL;
mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
break; break;
case PMIC_SND_LEFT_PB_VOL: case PMIC_SND_RIGHT_MASTER_VOL:
pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n"); pr_debug("GET_VOLUME_PMIC_RIGHT_MASTER_VOL\n");
sc_access.reg_addr = AUDIORVOL; sc_access.reg_addr = AUDIORVOL;
mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6);
break; break;
case PMIC_SND_RIGHT_PB_VOL:
pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n");
sc_access.reg_addr = HPRVOL;
mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
break;
case PMIC_SND_LEFT_PB_VOL:
pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n");
sc_access.reg_addr = HPLVOL;
mask = (MASK0|MASK1|MASK2|MASK3|MASK4);
break;
default: default:
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment