Skip to content

Commit

Permalink
[ALSA] oxygen: add control filter to model struct
Browse files Browse the repository at this point in the history
Allow the models to modify mixer controls before they are added to the
card.

Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
Clemens Ladisch authored and Jaroslav Kysela committed Jan 31, 2008
1 parent e85e092 commit ccc80fb
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
14 changes: 12 additions & 2 deletions sound/pci/oxygen/oxygen.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/

#include <linux/pci.h>
#include <sound/control.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
Expand Down Expand Up @@ -244,18 +245,27 @@ static void set_ak5385_params(struct oxygen *chip,

static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0);

static int ak4396_control_filter(struct snd_kcontrol_new *template)
{
if (!strcmp(template->name, "Master Playback Volume")) {
template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
template->tlv.p = ak4396_db_scale;
}
return 0;
}

static const struct oxygen_model model_generic = {
.shortname = "C-Media CMI8788",
.longname = "C-Media Oxygen HD Audio",
.chip = "CMI8788",
.owner = THIS_MODULE,
.init = generic_init,
.control_filter = ak4396_control_filter,
.cleanup = generic_cleanup,
.set_dac_params = set_ak4396_params,
.set_adc_params = set_wm8785_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
.dac_tlv = ak4396_db_scale,
.used_channels = OXYGEN_CHANNEL_A |
OXYGEN_CHANNEL_C |
OXYGEN_CHANNEL_SPDIF |
Expand All @@ -269,12 +279,12 @@ static const struct oxygen_model model_meridian = {
.chip = "CMI8788",
.owner = THIS_MODULE,
.init = meridian_init,
.control_filter = ak4396_control_filter,
.cleanup = generic_cleanup,
.set_dac_params = set_ak4396_params,
.set_adc_params = set_ak5385_params,
.update_dac_volume = update_ak4396_volume,
.update_dac_mute = update_ak4396_mute,
.dac_tlv = ak4396_db_scale,
.used_channels = OXYGEN_CHANNEL_B |
OXYGEN_CHANNEL_C |
OXYGEN_CHANNEL_SPDIF |
Expand Down
5 changes: 2 additions & 3 deletions sound/pci/oxygen/oxygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct pci_dev;
struct snd_card;
struct snd_pcm_substream;
struct snd_pcm_hw_params;
struct snd_kcontrol_new;
struct snd_rawmidi;
struct oxygen_model;

Expand Down Expand Up @@ -71,6 +72,7 @@ struct oxygen_model {
const char *chip;
struct module *owner;
void (*init)(struct oxygen *chip);
int (*control_filter)(struct snd_kcontrol_new *template);
int (*mixer_init)(struct oxygen *chip);
void (*cleanup)(struct oxygen *chip);
void (*set_dac_params)(struct oxygen *chip,
Expand All @@ -79,10 +81,7 @@ struct oxygen_model {
struct snd_pcm_hw_params *params);
void (*update_dac_volume)(struct oxygen *chip);
void (*update_dac_mute)(struct oxygen *chip);
const unsigned int *dac_tlv;
u8 used_channels;
u8 cd_in_from_video_in;
u8 dac_minimum_volume;
u8 function_flags;
};

Expand Down
20 changes: 7 additions & 13 deletions sound/pci/oxygen/oxygen_mixer.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,9 @@
static int dac_volume_info(struct snd_kcontrol *ctl,
struct snd_ctl_elem_info *info)
{
struct oxygen *chip = ctl->private_data;

info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
info->count = 8;
info->value.integer.min = chip->model->dac_minimum_volume;
info->value.integer.min = 0;
info->value.integer.max = 0xff;
return 0;
}
Expand Down Expand Up @@ -525,14 +523,10 @@ static const struct snd_kcontrol_new controls[] = {
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Master Playback Volume",
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
SNDRV_CTL_ELEM_ACCESS_TLV_READ,
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
.info = dac_volume_info,
.get = dac_volume_get,
.put = dac_volume_put,
.tlv = {
.p = NULL, /* set later */
},
},
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
Expand Down Expand Up @@ -635,18 +629,18 @@ static int add_controls(struct oxygen *chip,
[CONTROL_AUX_CAPTURE_SWITCH] = "Aux Capture Switch",
};
unsigned int i, j;
struct snd_kcontrol_new template;
struct snd_kcontrol *ctl;
int err;

for (i = 0; i < count; ++i) {
template = controls[i];
err = chip->model->control_filter(&template);
if (err < 0)
return err;
ctl = snd_ctl_new1(&controls[i], chip);
if (!ctl)
return -ENOMEM;
if (!strcmp(ctl->id.name, "Master Playback Volume"))
ctl->tlv.p = chip->model->dac_tlv;
else if (chip->model->cd_in_from_video_in &&
!strncmp(ctl->id.name, "CD Capture ", 11))
ctl->private_value ^= AC97_CD ^ AC97_VIDEO;
err = snd_ctl_add(chip->card, ctl);
if (err < 0)
return err;
Expand Down
28 changes: 25 additions & 3 deletions sound/pci/oxygen/virtuoso.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <sound/ac97_codec.h>
#include <sound/control.h>
#include <sound/core.h>
#include <sound/initval.h>
Expand Down Expand Up @@ -167,6 +169,16 @@ static void set_cs5381_params(struct oxygen *chip,
oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, value, 0x000c);
}

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 alt_switch_get(struct snd_kcontrol *ctl,
struct snd_ctl_elem_value *value)
{
Expand Down Expand Up @@ -207,6 +219,18 @@ static const struct snd_kcontrol_new alt_switch = {

static const DECLARE_TLV_DB_SCALE(pcm1796_db_scale, -12000, 50, 0);

static int xonar_control_filter(struct snd_kcontrol_new *template)
{
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)) {
template->private_value ^= AC97_CD ^ AC97_VIDEO;
}
return 0;
}

static int xonar_mixer_init(struct oxygen *chip)
{
return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip));
Expand All @@ -217,19 +241,17 @@ static const struct oxygen_model model_xonar = {
.longname = "Asus Virtuoso 200",
.chip = "AV200",
.init = xonar_init,
.control_filter = xonar_control_filter,
.mixer_init = xonar_mixer_init,
.cleanup = xonar_cleanup,
.set_dac_params = set_pcm1796_params,
.set_adc_params = set_cs5381_params,
.update_dac_volume = update_pcm1796_volume,
.update_dac_mute = update_pcm1796_mute,
.dac_tlv = pcm1796_db_scale,
.used_channels = OXYGEN_CHANNEL_B |
OXYGEN_CHANNEL_C |
OXYGEN_CHANNEL_SPDIF |
OXYGEN_CHANNEL_MULTICH,
.cd_in_from_video_in = 1,
.dac_minimum_volume = 15,
.function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5,
};

Expand Down

0 comments on commit ccc80fb

Please sign in to comment.