#define __NO_VERSION__
/*
* Driver for Digigram pcxhr compatible soundcards
*
* mixer callbacks
*
* Copyright (c) 2004 by Digigram <alsa@digigram.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <sound/core.h>
#include "pcxhr.h"
#include "pcxhr_hwdep.h"
#include "pcxhr_core.h"
#include <sound/control.h>
#include <sound/tlv.h>
#include <sound/asoundef.h>
#include "pcxhr_mixer.h"
#include "pcxhr_mix22.h"
#define PCXHR_LINE_CAPTURE_LEVEL_MIN 0 /* -112.0 dB */
#define PCXHR_LINE_CAPTURE_LEVEL_MAX 255 /* +15.5 dB */
#define PCXHR_LINE_CAPTURE_ZERO_LEVEL 224 /* 0.0 dB ( 0 dBu -> 0 dBFS ) */
#define PCXHR_LINE_PLAYBACK_LEVEL_MIN 0 /* -104.0 dB */
#define PCXHR_LINE_PLAYBACK_LEVEL_MAX 128 /* +24.0 dB */
#define PCXHR_LINE_PLAYBACK_ZERO_LEVEL 104 /* 0.0 dB ( 0 dBFS -> 0 dBu ) */
static const DECLARE_TLV_DB_SCALE(db_scale_analog_capture, -11200, 50, 1550);
static const DECLARE_TLV_DB_SCALE(db_scale_analog_playback, -10400, 100, 2400);
static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_capture, -11150, 50, 1600);
static const DECLARE_TLV_DB_SCALE(db_scale_a_hr222_playback, -2550, 50, 2400);
static int pcxhr_update_analog_audio_level(struct snd_pcxhr *chip,
int is_capture, int channel)
{
int err, vol;
struct pcxhr_rmh rmh;
pcxhr_init_rmh(&rmh, CMD_ACCESS_IO_WRITE);
if (is_capture) {
rmh.cmd[0] |= IO_NUM_REG_IN_ANA_LEVEL;
rmh.cmd[2] = chip->analog_capture_volume[channel];
} else {
rmh.cmd[0] |= IO_NUM_REG_OUT_ANA_LEVEL;
if (chip->analog_playback_active[channel])
vol = chip->analog_playback_volume[channel];
else
vol = PCXHR_LINE_PLAYBACK_LEVEL_MIN;
/* playback analog levels are inversed */
rmh.cmd[2] = PCXHR_LINE_PLAYBACK_LEVEL_MAX - vol;
}
rmh.cmd[1] = 1 << ((2 * chip->chip_idx) + channel); /* audio mask */
rmh.cmd_len = 3;
err = pcxhr_send_msg(chip->mgr, &rmh);
if (err < 0) {
snd_printk(KERN_DEBUG "error update_analog_audio_level card(%d)"
" is_capture(%d) err(%x)\n",
chip->chip_idx, is_capture, err);
return -EINVAL;
}
return 0;
}
/*
* analog level control
*/
static int pcxhr_analog_vol_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
{
struct snd_pcxhr *c