[ALSA] oxygen: generalize handling of DAC volume limits

Add fields for the DAC volume limits to the module structure so that
model drivers do not need to install their own control info handlers.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index b67888f..bf39c72 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -153,6 +153,8 @@
 		       PLAYBACK_1_TO_SPDIF |
 		       CAPTURE_0_FROM_I2S_1,
 	.dac_channels = 2,
+	.dac_volume_min = 0,
+	.dac_volume_max = 255,
 	.function_flags = OXYGEN_FUNCTION_SPI,
 	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c
index b3b7771..7181697 100644
--- a/sound/pci/oxygen/oxygen.c
+++ b/sound/pci/oxygen/oxygen.c
@@ -278,6 +278,8 @@
 		       CAPTURE_1_FROM_SPDIF |
 		       CAPTURE_2_FROM_AC97_1,
 	.dac_channels = 8,
+	.dac_volume_min = 0,
+	.dac_volume_max = 255,
 	.function_flags = OXYGEN_FUNCTION_SPI |
 			  OXYGEN_FUNCTION_ENABLE_SPI_4_5,
 	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
@@ -303,6 +305,8 @@
 		       CAPTURE_1_FROM_SPDIF |
 		       CAPTURE_2_FROM_AC97_1,
 	.dac_channels = 8,
+	.dac_volume_min = 0,
+	.dac_volume_max = 255,
 	.misc_flags = OXYGEN_MISC_MIDI,
 	.function_flags = OXYGEN_FUNCTION_SPI |
 			  OXYGEN_FUNCTION_ENABLE_SPI_4_5,
diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h
index 7efbf54..36f2f81 100644
--- a/sound/pci/oxygen/oxygen.h
+++ b/sound/pci/oxygen/oxygen.h
@@ -103,6 +103,8 @@
 	size_t model_data_size;
 	unsigned int pcm_dev_cfg;
 	u8 dac_channels;
+	u8 dac_volume_min;
+	u8 dac_volume_max;
 	u8 misc_flags;
 	u8 function_flags;
 	u16 dac_i2s_format;
diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c
index 39e4b7a..b7aa9fc 100644
--- a/sound/pci/oxygen/oxygen_lib.c
+++ b/sound/pci/oxygen/oxygen_lib.c
@@ -221,7 +221,7 @@
 
 	chip->dac_routing = 1;
 	for (i = 0; i < 8; ++i)
-		chip->dac_volume[i] = 0xff;
+		chip->dac_volume[i] = chip->model->dac_volume_max;
 	chip->spdif_playback_enable = 1;
 	chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL |
 		(IEC958_AES1_CON_PCM_CODER << OXYGEN_SPDIF_CATEGORY_SHIFT);
diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c
index 2cb9144..056581e 100644
--- a/sound/pci/oxygen/oxygen_mixer.c
+++ b/sound/pci/oxygen/oxygen_mixer.c
@@ -32,8 +32,8 @@
 
 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 	info->count = chip->model->dac_channels;
-	info->value.integer.min = 0;
-	info->value.integer.max = 0xff;
+	info->value.integer.min = chip->model->dac_volume_min;
+	info->value.integer.max = chip->model->dac_volume_max;
 	return 0;
 }
 
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c
index 6f5c253..37f53a8 100644
--- a/sound/pci/oxygen/virtuoso.c
+++ b/sound/pci/oxygen/virtuoso.c
@@ -219,10 +219,7 @@
 static void xonar_dx_init(struct oxygen *chip)
 {
 	struct xonar_data *data = chip->model_data;
-	unsigned int i;
 
-	for (i = 0; i < 8; ++i)
-		chip->dac_volume[i] = 127;
 	data->anti_pop_delay = 800;
 	data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE;
 	data->ext_power_reg = OXYGEN_GPI_DATA;
@@ -414,26 +411,6 @@
 	}
 }
 
-static int pcm1796_volume_info(struct snd_kcontrol *ctl,
-			       struct snd_ctl_elem_info *info)
-{
-	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	info->count = 8;
-	info->value.integer.min = 0x0f;
-	info->value.integer.max = 0xff;
-	return 0;
-}
-
-static int cs4362a_volume_info(struct snd_kcontrol *ctl,
-			       struct snd_ctl_elem_info *info)
-{
-	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-	info->count = 8;
-	info->value.integer.min = 0;
-	info->value.integer.max = 127;
-	return 0;
-}
-
 static int alt_switch_get(struct snd_kcontrol *ctl,
 			  struct snd_ctl_elem_value *value)
 {
@@ -526,7 +503,6 @@
 {
 	if (!strcmp(template->name, "Master Playback Volume")) {
 		template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
-		template->info = pcm1796_volume_info;
 		template->tlv.p = pcm1796_db_scale;
 	} else if (!strncmp(template->name, "CD Capture ", 11)) {
 		/* CD in is actually connected to the video in pin */
@@ -539,7 +515,6 @@
 {
 	if (!strcmp(template->name, "Master Playback Volume")) {
 		template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
-		template->info = cs4362a_volume_info;
 		template->tlv.p = cs4362a_db_scale;
 	} else if (!strncmp(template->name, "CD Capture ", 11)) {
 		return 1; /* no CD input */
@@ -577,6 +552,8 @@
 			       CAPTURE_0_FROM_I2S_2 |
 			       CAPTURE_1_FROM_SPDIF,
 		.dac_channels = 8,
+		.dac_volume_min = 0x0f,
+		.dac_volume_max = 0xff,
 		.misc_flags = OXYGEN_MISC_MIDI,
 		.function_flags = OXYGEN_FUNCTION_SPI |
 				  OXYGEN_FUNCTION_ENABLE_SPI_4_5,
@@ -603,6 +580,8 @@
 			       CAPTURE_0_FROM_I2S_2 |
 			       CAPTURE_1_FROM_SPDIF,
 		.dac_channels = 8,
+		.dac_volume_min = 0x0f,
+		.dac_volume_max = 0xff,
 		.misc_flags = OXYGEN_MISC_MIDI,
 		.function_flags = OXYGEN_FUNCTION_SPI |
 				  OXYGEN_FUNCTION_ENABLE_SPI_4_5,
@@ -629,6 +608,8 @@
 			       PLAYBACK_1_TO_SPDIF |
 			       CAPTURE_0_FROM_I2S_2,
 		.dac_channels = 8,
+		.dac_volume_min = 0,
+		.dac_volume_max = 127,
 		.function_flags = OXYGEN_FUNCTION_2WIRE,
 		.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
 		.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,