Merge branch 'for-next' into for-linus
Preparation for 4.19 merge material. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Этот коммит содержится в:
@@ -2941,19 +2941,3 @@ int snd_ac97_tune_hardware(struct snd_ac97 *ac97,
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(snd_ac97_tune_hardware);
|
||||
|
||||
/*
|
||||
* INIT part
|
||||
*/
|
||||
|
||||
static int __init alsa_ac97_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_ac97_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_ac97_init)
|
||||
module_exit(alsa_ac97_exit)
|
||||
|
@@ -1484,12 +1484,9 @@ static struct snd_pcm_hardware snd_ali_capture =
|
||||
static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime)
|
||||
{
|
||||
struct snd_ali_voice *pvoice = runtime->private_data;
|
||||
struct snd_ali *codec;
|
||||
|
||||
if (pvoice) {
|
||||
codec = pvoice->codec;
|
||||
if (pvoice)
|
||||
snd_ali_free_voice(pvoice->codec, pvoice);
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_ali_open(struct snd_pcm_substream *substream, int rec,
|
||||
|
@@ -311,27 +311,29 @@ static void print_hwparams(struct snd_pcm_substream *substream,
|
||||
snd_pcm_format_width(params_format(p)) / 8);
|
||||
}
|
||||
|
||||
#define INVALID_FORMAT (__force snd_pcm_format_t)(-1)
|
||||
|
||||
static snd_pcm_format_t hpi_to_alsa_formats[] = {
|
||||
-1, /* INVALID */
|
||||
INVALID_FORMAT, /* INVALID */
|
||||
SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */
|
||||
SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */
|
||||
-1, /* HPI_FORMAT_MPEG_L1 3 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_MPEG_L1 3 */
|
||||
SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L2 4 */
|
||||
SNDRV_PCM_FORMAT_MPEG, /* HPI_FORMAT_MPEG_L3 5 */
|
||||
-1, /* HPI_FORMAT_DOLBY_AC2 6 */
|
||||
-1, /* HPI_FORMAT_DOLBY_AC3 7 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_DOLBY_AC2 6 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_DOLBY_AC3 7 */
|
||||
SNDRV_PCM_FORMAT_S16_BE,/* HPI_FORMAT_PCM16_BIGENDIAN 8 */
|
||||
-1, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
|
||||
-1, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_HITS 9 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_INSERTS 10 */
|
||||
SNDRV_PCM_FORMAT_S32, /* HPI_FORMAT_PCM32_SIGNED 11 */
|
||||
-1, /* HPI_FORMAT_RAW_BITSTREAM 12 */
|
||||
-1, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_RAW_BITSTREAM 12 */
|
||||
INVALID_FORMAT, /* HPI_FORMAT_AA_TAGIT1_HITS_EX1 13 */
|
||||
SNDRV_PCM_FORMAT_FLOAT, /* HPI_FORMAT_PCM32_FLOAT 14 */
|
||||
#if 1
|
||||
/* ALSA can't handle 3 byte sample size together with power-of-2
|
||||
* constraint on buffer_bytes, so disable this format
|
||||
*/
|
||||
-1
|
||||
INVALID_FORMAT
|
||||
#else
|
||||
/* SNDRV_PCM_FORMAT_S24_3LE */ /* HPI_FORMAT_PCM24_SIGNED 15 */
|
||||
#endif
|
||||
@@ -1023,7 +1025,7 @@ static u64 snd_card_asihpi_playback_formats(struct snd_card_asihpi *asihpi,
|
||||
format, sample_rate, 128000, 0);
|
||||
if (!err)
|
||||
err = hpi_outstream_query_format(h_stream, &hpi_format);
|
||||
if (!err && (hpi_to_alsa_formats[format] != -1))
|
||||
if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
|
||||
formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
|
||||
}
|
||||
return formats;
|
||||
@@ -1205,7 +1207,7 @@ static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi,
|
||||
format, sample_rate, 128000, 0);
|
||||
if (!err)
|
||||
err = hpi_instream_query_format(h_stream, &hpi_format);
|
||||
if (!err && (hpi_to_alsa_formats[format] != -1))
|
||||
if (!err && (hpi_to_alsa_formats[format] != INVALID_FORMAT))
|
||||
formats |= pcm_format_to_bits(hpi_to_alsa_formats[format]);
|
||||
}
|
||||
return formats;
|
||||
|
@@ -635,7 +635,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
{
|
||||
struct hpi_message hm;
|
||||
struct hpi_response hr;
|
||||
u32 max_streams;
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
|
||||
memset(&hm, 0, sizeof(hm));
|
||||
@@ -660,10 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
pao->type = hr.u.ax.info.adapter_type;
|
||||
pao->index = hr.u.ax.info.adapter_index;
|
||||
|
||||
max_streams =
|
||||
hr.u.ax.info.num_outstreams +
|
||||
hr.u.ax.info.num_instreams;
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE,
|
||||
"got adapter info type %x index %d serial %d\n",
|
||||
hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
|
||||
|
@@ -207,10 +207,10 @@ struct atiixp;
|
||||
*/
|
||||
|
||||
struct atiixp_dma_desc {
|
||||
u32 addr; /* DMA buffer address */
|
||||
__le32 addr; /* DMA buffer address */
|
||||
u16 status; /* status bits */
|
||||
u16 size; /* size of the packet in dwords */
|
||||
u32 next; /* address of the next packet descriptor */
|
||||
__le32 next; /* address of the next packet descriptor */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -183,10 +183,10 @@ struct atiixp_modem;
|
||||
*/
|
||||
|
||||
struct atiixp_dma_desc {
|
||||
u32 addr; /* DMA buffer address */
|
||||
__le32 addr; /* DMA buffer address */
|
||||
u16 status; /* status bits */
|
||||
u16 size; /* size of the packet in dwords */
|
||||
u32 next; /* address of the next packet descriptor */
|
||||
__le32 next; /* address of the next packet descriptor */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@@ -241,7 +241,7 @@ static int vortex_core_init(vortex_t * card);
|
||||
static int vortex_core_shutdown(vortex_t * card);
|
||||
static void vortex_enable_int(vortex_t * card);
|
||||
static irqreturn_t vortex_interrupt(int irq, void *dev_id);
|
||||
static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v);
|
||||
static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v);
|
||||
|
||||
/* Connection stuff. */
|
||||
static void vortex_connect_default(vortex_t * vortex, int en);
|
||||
|
@@ -2770,7 +2770,7 @@ static int vortex_core_shutdown(vortex_t * vortex)
|
||||
|
||||
/* Alsa support. */
|
||||
|
||||
static int vortex_alsafmt_aspfmt(int alsafmt, vortex_t *v)
|
||||
static int vortex_alsafmt_aspfmt(snd_pcm_format_t alsafmt, vortex_t *v)
|
||||
{
|
||||
int fmt;
|
||||
|
||||
|
@@ -228,14 +228,14 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea
|
||||
unsigned int periods, unsigned int period_bytes)
|
||||
{
|
||||
unsigned int i, offset;
|
||||
u32 *risc;
|
||||
__le32 *risc;
|
||||
|
||||
if (chip->dma_risc.area == NULL) {
|
||||
if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(chip->pci),
|
||||
PAGE_ALIGN(MAX_RISC_SIZE), &chip->dma_risc) < 0)
|
||||
return -ENOMEM;
|
||||
}
|
||||
risc = (u32 *)chip->dma_risc.area;
|
||||
risc = (__le32 *)chip->dma_risc.area;
|
||||
offset = 0;
|
||||
*risc++ = cpu_to_le32(RISC_SYNC | RISC_SYNC_FM1);
|
||||
*risc++ = cpu_to_le32(0);
|
||||
|
@@ -73,13 +73,10 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
|
||||
{
|
||||
struct proc_scb_info * scb_info = entry->private_data;
|
||||
struct dsp_scb_descriptor * scb = scb_info->scb_desc;
|
||||
struct dsp_spos_instance * ins;
|
||||
struct snd_cs46xx *chip = scb_info->chip;
|
||||
int j,col;
|
||||
void __iomem *dst = chip->region.idx[1].remap_addr + DSP_PARAMETER_BYTE_OFFSET;
|
||||
|
||||
ins = chip->dsp_spos_instance;
|
||||
|
||||
mutex_lock(&chip->spos_mutex);
|
||||
snd_iprintf(buffer,"%04x %s:\n",scb->address,scb->scb_name);
|
||||
|
||||
|
@@ -192,8 +192,6 @@ static void process_bm0_irq(struct cs5535audio *cs5535au)
|
||||
bm_stat = cs_readb(cs5535au, ACC_BM0_STATUS);
|
||||
spin_unlock(&cs5535au->reg_lock);
|
||||
if (bm_stat & EOP) {
|
||||
struct cs5535audio_dma *dma;
|
||||
dma = cs5535au->playback_substream->runtime->private_data;
|
||||
snd_pcm_period_elapsed(cs5535au->playback_substream);
|
||||
} else {
|
||||
dev_err(cs5535au->card->dev,
|
||||
@@ -208,11 +206,8 @@ static void process_bm1_irq(struct cs5535audio *cs5535au)
|
||||
spin_lock(&cs5535au->reg_lock);
|
||||
bm_stat = cs_readb(cs5535au, ACC_BM1_STATUS);
|
||||
spin_unlock(&cs5535au->reg_lock);
|
||||
if (bm_stat & EOP) {
|
||||
struct cs5535audio_dma *dma;
|
||||
dma = cs5535au->capture_substream->runtime->private_data;
|
||||
if (bm_stat & EOP)
|
||||
snd_pcm_period_elapsed(cs5535au->capture_substream);
|
||||
}
|
||||
}
|
||||
|
||||
static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id)
|
||||
|
@@ -1319,7 +1319,7 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
|
||||
break;
|
||||
|
||||
hw_write_20kx(hw, PLLCTL, pllctl);
|
||||
mdelay(40);
|
||||
msleep(40);
|
||||
}
|
||||
if (i >= 3) {
|
||||
dev_alert(hw->card->dev, "PLL initialization failed!!!\n");
|
||||
@@ -1407,7 +1407,7 @@ static int hw_reset_dac(struct hw *hw)
|
||||
/* To be effective, need to reset the DAC twice. */
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* set gpio */
|
||||
mdelay(100);
|
||||
msleep(100);
|
||||
gpioorg = (u16)hw_read_20kx(hw, GPIO);
|
||||
gpioorg &= 0xfffd;
|
||||
hw_write_20kx(hw, GPIO, gpioorg);
|
||||
@@ -2030,7 +2030,7 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||
hw_write_20kx(hw, GIE, 0);
|
||||
/* Reset all SRC pending interrupts */
|
||||
hw_write_20kx(hw, SRCIP, 0);
|
||||
mdelay(30);
|
||||
msleep(30);
|
||||
|
||||
/* Detect the card ID and configure GPIO accordingly. */
|
||||
switch (hw->model) {
|
||||
|
@@ -1316,12 +1316,12 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
|
||||
set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
|
||||
set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
msleep(40);
|
||||
|
||||
pllctl = hw_read_20kx(hw, PLL_CTL);
|
||||
set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
msleep(40);
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
pllstat = hw_read_20kx(hw, PLL_STAT);
|
||||
@@ -1584,7 +1584,7 @@ static void hw_dac_stop(struct hw *hw)
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data &= 0xFFFFFFFD;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(10);
|
||||
usleep_range(10000, 11000);
|
||||
}
|
||||
|
||||
static void hw_dac_start(struct hw *hw)
|
||||
@@ -1593,7 +1593,7 @@ static void hw_dac_start(struct hw *hw)
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data |= 0x2;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
msleep(50);
|
||||
}
|
||||
|
||||
static void hw_dac_reset(struct hw *hw)
|
||||
@@ -1864,11 +1864,11 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
usleep_range(10000, 11000);
|
||||
/* Return the ADC to normal operation. */
|
||||
data |= (0x1 << 15);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
msleep(50);
|
||||
|
||||
/* I2C write to register offset 0x0B to set ADC LRCLK polarity */
|
||||
/* invert bit, interface format to I2S, word length to 24-bit, */
|
||||
|
@@ -938,17 +938,18 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer)
|
||||
struct sum *sum;
|
||||
struct amixer *amix_d, *amix_s;
|
||||
enum CT_AMIXER_CTL i, j;
|
||||
enum CT_SUM_CTL k;
|
||||
|
||||
/* Build topology from destination to source */
|
||||
|
||||
/* Set up Master mixer */
|
||||
for (i = AMIXER_MASTER_F, j = SUM_IN_F;
|
||||
i <= AMIXER_MASTER_S; i++, j++) {
|
||||
for (i = AMIXER_MASTER_F, k = SUM_IN_F;
|
||||
i <= AMIXER_MASTER_S; i++, k++) {
|
||||
amix_d = mixer->amixers[i*CHN_NUM];
|
||||
sum = mixer->sums[j*CHN_NUM];
|
||||
sum = mixer->sums[k*CHN_NUM];
|
||||
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
|
||||
amix_d = mixer->amixers[i*CHN_NUM+1];
|
||||
sum = mixer->sums[j*CHN_NUM+1];
|
||||
sum = mixer->sums[k*CHN_NUM+1];
|
||||
amix_d->ops->setup(amix_d, &sum->rsc, INIT_VOL, NULL);
|
||||
}
|
||||
|
||||
@@ -972,12 +973,12 @@ static int ct_mixer_topology_build(struct ct_mixer *mixer)
|
||||
amix_d->ops->setup(amix_d, &amix_s->rsc, INIT_VOL, NULL);
|
||||
|
||||
/* Set up PCM-in mixer */
|
||||
for (i = AMIXER_PCM_F, j = SUM_IN_F; i <= AMIXER_PCM_S; i++, j++) {
|
||||
for (i = AMIXER_PCM_F, k = SUM_IN_F; i <= AMIXER_PCM_S; i++, k++) {
|
||||
amix_d = mixer->amixers[i*CHN_NUM];
|
||||
sum = mixer->sums[j*CHN_NUM];
|
||||
sum = mixer->sums[k*CHN_NUM];
|
||||
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
|
||||
amix_d = mixer->amixers[i*CHN_NUM+1];
|
||||
sum = mixer->sums[j*CHN_NUM+1];
|
||||
sum = mixer->sums[k*CHN_NUM+1];
|
||||
amix_d->ops->setup(amix_d, NULL, INIT_VOL, sum);
|
||||
}
|
||||
|
||||
|
@@ -713,6 +713,7 @@ static int pcm_prepare(struct snd_pcm_substream *substream)
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S32_BE:
|
||||
format.data_are_bigendian = 1;
|
||||
/* fall through */
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
format.bits_per_sample = 32;
|
||||
break;
|
||||
@@ -764,6 +765,7 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
|
||||
pipe->last_counter = 0;
|
||||
pipe->position = 0;
|
||||
*pipe->dma_counter = 0;
|
||||
/* fall through */
|
||||
case PIPE_STATE_PAUSED:
|
||||
pipe->state = PIPE_STATE_STARTED;
|
||||
break;
|
||||
|
@@ -294,7 +294,7 @@
|
||||
|
||||
|
||||
struct audiopipe {
|
||||
volatile u32 *dma_counter; /* Commpage register that contains
|
||||
volatile __le32 *dma_counter; /* Commpage register that contains
|
||||
* the current dma position
|
||||
* (lower 32 bits only)
|
||||
*/
|
||||
|
@@ -73,19 +73,21 @@ register. write_control_reg sends the new control register value to the DSP. */
|
||||
static int write_control_reg(struct echoaudio *chip, u32 ctl, u32 frq,
|
||||
char force)
|
||||
{
|
||||
__le32 ctl_reg, frq_reg;
|
||||
|
||||
if (wait_handshake(chip))
|
||||
return -EIO;
|
||||
|
||||
dev_dbg(chip->card->dev,
|
||||
"WriteControlReg: Setting 0x%x, 0x%x\n", ctl, frq);
|
||||
|
||||
ctl = cpu_to_le32(ctl);
|
||||
frq = cpu_to_le32(frq);
|
||||
ctl_reg = cpu_to_le32(ctl);
|
||||
frq_reg = cpu_to_le32(frq);
|
||||
|
||||
if (ctl != chip->comm_page->control_register ||
|
||||
frq != chip->comm_page->e3g_frq_register || force) {
|
||||
chip->comm_page->e3g_frq_register = frq;
|
||||
chip->comm_page->control_register = ctl;
|
||||
if (ctl_reg != chip->comm_page->control_register ||
|
||||
frq_reg != chip->comm_page->e3g_frq_register || force) {
|
||||
chip->comm_page->e3g_frq_register = frq_reg;
|
||||
chip->comm_page->control_register = ctl_reg;
|
||||
clear_handshake(chip);
|
||||
return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
|
||||
}
|
||||
|
@@ -679,7 +679,7 @@ static int restore_dsp_rettings(struct echoaudio *chip)
|
||||
/* Gina20/Darla20 only. Should be harmless for other cards. */
|
||||
chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
|
||||
chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
|
||||
chip->comm_page->handshake = 0xffffffff;
|
||||
chip->comm_page->handshake = cpu_to_le32(0xffffffff);
|
||||
|
||||
/* Restore output busses */
|
||||
for (i = 0; i < num_busses_out(chip); i++) {
|
||||
@@ -989,7 +989,7 @@ static int init_dsp_comm_page(struct echoaudio *chip)
|
||||
/* Init the comm page */
|
||||
chip->comm_page->comm_size =
|
||||
cpu_to_le32(sizeof(struct comm_page));
|
||||
chip->comm_page->handshake = 0xffffffff;
|
||||
chip->comm_page->handshake = cpu_to_le32(0xffffffff);
|
||||
chip->comm_page->midi_out_free_count =
|
||||
cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
|
||||
chip->comm_page->sample_rate = cpu_to_le32(44100);
|
||||
@@ -1087,7 +1087,7 @@ static int allocate_pipes(struct echoaudio *chip, struct audiopipe *pipe,
|
||||
/* The counter register is where the DSP writes the 32 bit DMA
|
||||
position for a pipe. The DSP is constantly updating this value as
|
||||
it moves data. The DMA counter is in units of bytes, not samples. */
|
||||
pipe->dma_counter = &chip->comm_page->position[pipe_index];
|
||||
pipe->dma_counter = (__le32 *)&chip->comm_page->position[pipe_index];
|
||||
*pipe->dma_counter = 0;
|
||||
return pipe_index;
|
||||
}
|
||||
|
@@ -627,8 +627,8 @@ sg_entry struct is read by the DSP, so all values must be little-endian. */
|
||||
#define MAX_SGLIST_ENTRIES 512
|
||||
|
||||
struct sg_entry {
|
||||
u32 addr;
|
||||
u32 size;
|
||||
__le32 addr;
|
||||
__le32 size;
|
||||
};
|
||||
|
||||
|
||||
@@ -643,18 +643,18 @@ struct sg_entry {
|
||||
****************************************************************************/
|
||||
|
||||
struct comm_page { /* Base Length*/
|
||||
u32 comm_size; /* size of this object 0x000 4 */
|
||||
u32 flags; /* See Appendix A below 0x004 4 */
|
||||
u32 unused; /* Unused entry 0x008 4 */
|
||||
u32 sample_rate; /* Card sample rate in Hz 0x00c 4 */
|
||||
u32 handshake; /* DSP command handshake 0x010 4 */
|
||||
u32 cmd_start; /* Chs. to start mask 0x014 4 */
|
||||
u32 cmd_stop; /* Chs. to stop mask 0x018 4 */
|
||||
u32 cmd_reset; /* Chs. to reset mask 0x01c 4 */
|
||||
u16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */
|
||||
__le32 comm_size; /* size of this object 0x000 4 */
|
||||
__le32 flags; /* See Appendix A below 0x004 4 */
|
||||
__le32 unused; /* Unused entry 0x008 4 */
|
||||
__le32 sample_rate; /* Card sample rate in Hz 0x00c 4 */
|
||||
__le32 handshake; /* DSP command handshake 0x010 4 */
|
||||
__le32 cmd_start; /* Chs. to start mask 0x014 4 */
|
||||
__le32 cmd_stop; /* Chs. to stop mask 0x018 4 */
|
||||
__le32 cmd_reset; /* Chs. to reset mask 0x01c 4 */
|
||||
__le16 audio_format[DSP_MAXPIPES]; /* Chs. audio format 0x020 32*2 */
|
||||
struct sg_entry sglist_addr[DSP_MAXPIPES];
|
||||
/* Chs. Physical sglist addrs 0x060 32*8 */
|
||||
u32 position[DSP_MAXPIPES];
|
||||
__le32 position[DSP_MAXPIPES];
|
||||
/* Positions for ea. ch. 0x160 32*4 */
|
||||
s8 vu_meter[DSP_MAXPIPES];
|
||||
/* VU meters 0x1e0 32*1 */
|
||||
@@ -666,28 +666,28 @@ struct comm_page { /* Base Length*/
|
||||
/* Input gain 0x230 16*1 */
|
||||
s8 monitors[MONITOR_ARRAY_SIZE];
|
||||
/* Monitor map 0x240 0x180 */
|
||||
u32 play_coeff[MAX_PLAY_TAPS];
|
||||
__le32 play_coeff[MAX_PLAY_TAPS];
|
||||
/* Gina/Darla play filters - obsolete 0x3c0 168*4 */
|
||||
u32 rec_coeff[MAX_REC_TAPS];
|
||||
__le32 rec_coeff[MAX_REC_TAPS];
|
||||
/* Gina/Darla record filters - obsolete 0x660 192*4 */
|
||||
u16 midi_input[MIDI_IN_BUFFER_SIZE];
|
||||
__le16 midi_input[MIDI_IN_BUFFER_SIZE];
|
||||
/* MIDI input data transfer buffer 0x960 256*2 */
|
||||
u8 gd_clock_state; /* Chg Gina/Darla clock state 0xb60 1 */
|
||||
u8 gd_spdif_status; /* Chg. Gina/Darla S/PDIF state 0xb61 1 */
|
||||
u8 gd_resampler_state; /* Should always be 3 0xb62 1 */
|
||||
u8 filler2; /* 0xb63 1 */
|
||||
u32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */
|
||||
u16 input_clock; /* Chg. Input clock state 0xb68 2 */
|
||||
u16 output_clock; /* Chg. Output clock state 0xb6a 2 */
|
||||
u32 status_clocks; /* Current Input clock state 0xb6c 4 */
|
||||
u32 ext_box_status; /* External box status 0xb70 4 */
|
||||
u32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */
|
||||
u32 midi_out_free_count;
|
||||
__le32 nominal_level_mask; /* -10 level enable mask 0xb64 4 */
|
||||
__le16 input_clock; /* Chg. Input clock state 0xb68 2 */
|
||||
__le16 output_clock; /* Chg. Output clock state 0xb6a 2 */
|
||||
__le32 status_clocks; /* Current Input clock state 0xb6c 4 */
|
||||
__le32 ext_box_status; /* External box status 0xb70 4 */
|
||||
__le32 cmd_add_buffer; /* Pipes to add (obsolete) 0xb74 4 */
|
||||
__le32 midi_out_free_count;
|
||||
/* # of bytes free in MIDI output FIFO 0xb78 4 */
|
||||
u32 unused2; /* Cyclic pipes 0xb7c 4 */
|
||||
u32 control_register;
|
||||
__le32 unused2; /* Cyclic pipes 0xb7c 4 */
|
||||
__le32 control_register;
|
||||
/* Mona, Gina24, Layla24, 3G ctrl reg 0xb80 4 */
|
||||
u32 e3g_frq_register; /* 3G frequency register 0xb84 4 */
|
||||
__le32 e3g_frq_register; /* 3G frequency register 0xb84 4 */
|
||||
u8 filler[24]; /* filler 0xb88 24*1 */
|
||||
s8 vmixer[VMIXER_ARRAY_SIZE];
|
||||
/* Vmixer levels 0xba0 64*1 */
|
||||
|
@@ -63,6 +63,8 @@ the control register. write_control_reg sends the new control register
|
||||
value to the DSP. */
|
||||
static int write_control_reg(struct echoaudio *chip, u32 value, char force)
|
||||
{
|
||||
__le32 reg_value;
|
||||
|
||||
/* Handle the digital input auto-mute */
|
||||
if (chip->digital_in_automute)
|
||||
value |= GML_DIGITAL_IN_AUTO_MUTE;
|
||||
@@ -72,11 +74,11 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force)
|
||||
dev_dbg(chip->card->dev, "write_control_reg: 0x%x\n", value);
|
||||
|
||||
/* Write the control register */
|
||||
value = cpu_to_le32(value);
|
||||
if (value != chip->comm_page->control_register || force) {
|
||||
reg_value = cpu_to_le32(value);
|
||||
if (reg_value != chip->comm_page->control_register || force) {
|
||||
if (wait_handshake(chip))
|
||||
return -EIO;
|
||||
chip->comm_page->control_register = value;
|
||||
chip->comm_page->control_register = reg_value;
|
||||
clear_handshake(chip);
|
||||
return send_vector(chip, DSP_VC_WRITE_CONTROL_REG);
|
||||
}
|
||||
|
@@ -70,11 +70,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
|
||||
loopend = sampleend;
|
||||
|
||||
/* be sure loop points start < end */
|
||||
if (sp->v.loopstart >= sp->v.loopend) {
|
||||
int tmp = sp->v.loopstart;
|
||||
sp->v.loopstart = sp->v.loopend;
|
||||
sp->v.loopend = tmp;
|
||||
}
|
||||
if (sp->v.loopstart >= sp->v.loopend)
|
||||
swap(sp->v.loopstart, sp->v.loopend);
|
||||
|
||||
/* compute true data size to be loaded */
|
||||
truesize = sp->v.size + BLANK_HEAD_SIZE;
|
||||
|
@@ -526,7 +526,7 @@ static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
|
||||
if (!test_bit(gpr, icode->gpr_valid))
|
||||
continue;
|
||||
if (in_kernel)
|
||||
val = *(u32 *)&icode->gpr_map[gpr];
|
||||
val = *(__force u32 *)&icode->gpr_map[gpr];
|
||||
else if (get_user(val, &icode->gpr_map[gpr]))
|
||||
return -EFAULT;
|
||||
snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
|
||||
@@ -560,8 +560,8 @@ static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
|
||||
if (!test_bit(tram, icode->tram_valid))
|
||||
continue;
|
||||
if (in_kernel) {
|
||||
val = *(u32 *)&icode->tram_data_map[tram];
|
||||
addr = *(u32 *)&icode->tram_addr_map[tram];
|
||||
val = *(__force u32 *)&icode->tram_data_map[tram];
|
||||
addr = *(__force u32 *)&icode->tram_addr_map[tram];
|
||||
} else {
|
||||
if (get_user(val, &icode->tram_data_map[tram]) ||
|
||||
get_user(addr, &icode->tram_addr_map[tram]))
|
||||
@@ -611,8 +611,8 @@ static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
|
||||
if (!test_bit(pc / 2, icode->code_valid))
|
||||
continue;
|
||||
if (in_kernel) {
|
||||
lo = *(u32 *)&icode->code[pc + 0];
|
||||
hi = *(u32 *)&icode->code[pc + 1];
|
||||
lo = *(__force u32 *)&icode->code[pc + 0];
|
||||
hi = *(__force u32 *)&icode->code[pc + 1];
|
||||
} else {
|
||||
if (get_user(lo, &icode->code[pc + 0]) ||
|
||||
get_user(hi, &icode->code[pc + 1]))
|
||||
@@ -666,7 +666,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
|
||||
if (!_tlv)
|
||||
return NULL;
|
||||
if (in_kernel)
|
||||
memcpy(data, (void *)_tlv, sizeof(data));
|
||||
memcpy(data, (__force void *)_tlv, sizeof(data));
|
||||
else if (copy_from_user(data, _tlv, sizeof(data)))
|
||||
return NULL;
|
||||
if (data[1] >= MAX_TLV_SIZE)
|
||||
@@ -676,7 +676,7 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
|
||||
return NULL;
|
||||
memcpy(tlv, data, sizeof(data));
|
||||
if (in_kernel) {
|
||||
memcpy(tlv + 2, (void *)(_tlv + 2), data[1]);
|
||||
memcpy(tlv + 2, (__force void *)(_tlv + 2), data[1]);
|
||||
} else if (copy_from_user(tlv + 2, _tlv + 2, data[1])) {
|
||||
kfree(tlv);
|
||||
return NULL;
|
||||
@@ -693,7 +693,7 @@ static int copy_gctl(struct snd_emu10k1 *emu,
|
||||
|
||||
if (emu->support_tlv) {
|
||||
if (in_kernel)
|
||||
memcpy(gctl, (void *)&_gctl[idx], sizeof(*gctl));
|
||||
memcpy(gctl, (__force void *)&_gctl[idx], sizeof(*gctl));
|
||||
else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
@@ -701,7 +701,7 @@ static int copy_gctl(struct snd_emu10k1 *emu,
|
||||
|
||||
octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
|
||||
if (in_kernel)
|
||||
memcpy(gctl, (void *)&octl[idx], sizeof(*octl));
|
||||
memcpy(gctl, (__force void *)&octl[idx], sizeof(*octl));
|
||||
else if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
|
||||
return -EFAULT;
|
||||
gctl->tlv = NULL;
|
||||
@@ -735,7 +735,7 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
|
||||
for (i = 0, _id = icode->gpr_del_controls;
|
||||
i < icode->gpr_del_control_count; i++, _id++) {
|
||||
if (in_kernel)
|
||||
id = *(struct snd_ctl_elem_id *)_id;
|
||||
id = *(__force struct snd_ctl_elem_id *)_id;
|
||||
else if (copy_from_user(&id, _id, sizeof(id)))
|
||||
return -EFAULT;
|
||||
if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
|
||||
@@ -833,7 +833,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
|
||||
knew.device = gctl->id.device;
|
||||
knew.subdevice = gctl->id.subdevice;
|
||||
knew.info = snd_emu10k1_gpr_ctl_info;
|
||||
knew.tlv.p = copy_tlv(gctl->tlv, in_kernel);
|
||||
knew.tlv.p = copy_tlv((__force const unsigned int __user *)gctl->tlv, in_kernel);
|
||||
if (knew.tlv.p)
|
||||
knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READ;
|
||||
@@ -897,7 +897,7 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
|
||||
for (i = 0, _id = icode->gpr_del_controls;
|
||||
i < icode->gpr_del_control_count; i++, _id++) {
|
||||
if (in_kernel)
|
||||
id = *(struct snd_ctl_elem_id *)_id;
|
||||
id = *(__force struct snd_ctl_elem_id *)_id;
|
||||
else if (copy_from_user(&id, _id, sizeof(id)))
|
||||
return -EFAULT;
|
||||
down_write(&card->controls_rwsem);
|
||||
|
@@ -290,7 +290,7 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
unsigned int silent_page, tmp;
|
||||
int voice, stereo, w_16;
|
||||
unsigned char attn, send_amount[8];
|
||||
unsigned char send_amount[8];
|
||||
unsigned char send_routing[8];
|
||||
unsigned long flags;
|
||||
unsigned int pitch_target;
|
||||
@@ -313,7 +313,6 @@ static void snd_emu10k1_pcm_init_voice(struct snd_emu10k1 *emu,
|
||||
|
||||
/* volume parameters */
|
||||
if (extra) {
|
||||
attn = 0;
|
||||
memset(send_routing, 0, sizeof(send_routing));
|
||||
send_routing[0] = 0;
|
||||
send_routing[1] = 1;
|
||||
@@ -779,7 +778,7 @@ static int snd_emu10k1_playback_trigger(struct snd_pcm_substream *substream,
|
||||
case SNDRV_PCM_TRIGGER_START:
|
||||
snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra); /* do we need this? */
|
||||
snd_emu10k1_playback_invalidate_cache(emu, 0, epcm->voices[0]);
|
||||
/* follow thru */
|
||||
/* fall through */
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
if (cmd == SNDRV_PCM_TRIGGER_PAUSE_RELEASE)
|
||||
@@ -929,7 +928,7 @@ static int snd_emu10k1_efx_playback_trigger(struct snd_pcm_substream *substream,
|
||||
}
|
||||
snd_emu10k1_playback_invalidate_cache(emu, 1, epcm->extra);
|
||||
|
||||
/* follow thru */
|
||||
/* fall through */
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
|
||||
case SNDRV_PCM_TRIGGER_RESUME:
|
||||
snd_emu10k1_playback_prepare_voice(emu, epcm->extra, 1, 1, NULL);
|
||||
|
@@ -2392,7 +2392,7 @@ static int snd_audiopci_probe(struct pci_dev *pci,
|
||||
static int dev;
|
||||
struct snd_card *card;
|
||||
struct ensoniq *ensoniq;
|
||||
int err, pcm_devs[2];
|
||||
int err;
|
||||
|
||||
if (dev >= SNDRV_CARDS)
|
||||
return -ENODEV;
|
||||
@@ -2412,7 +2412,6 @@ static int snd_audiopci_probe(struct pci_dev *pci,
|
||||
}
|
||||
card->private_data = ensoniq;
|
||||
|
||||
pcm_devs[0] = 0; pcm_devs[1] = 1;
|
||||
#ifdef CHIP1370
|
||||
if ((err = snd_ensoniq_1370_mixer(ensoniq)) < 0) {
|
||||
snd_card_free(card);
|
||||
|
@@ -6,111 +6,18 @@
|
||||
#if IS_ENABLED(CONFIG_DELL_LAPTOP)
|
||||
#include <linux/dell-led.h>
|
||||
|
||||
enum {
|
||||
MICMUTE_LED_ON,
|
||||
MICMUTE_LED_OFF,
|
||||
MICMUTE_LED_FOLLOW_CAPTURE,
|
||||
MICMUTE_LED_FOLLOW_MUTE,
|
||||
};
|
||||
|
||||
static int dell_led_mode = MICMUTE_LED_FOLLOW_MUTE;
|
||||
static int dell_capture;
|
||||
static int dell_led_value;
|
||||
static int (*dell_micmute_led_set_func)(int);
|
||||
static void (*dell_old_cap_hook)(struct hda_codec *,
|
||||
struct snd_kcontrol *,
|
||||
struct snd_ctl_elem_value *);
|
||||
|
||||
static void call_micmute_led_update(void)
|
||||
static void dell_micmute_update(struct hda_codec *codec)
|
||||
{
|
||||
int val;
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
|
||||
switch (dell_led_mode) {
|
||||
case MICMUTE_LED_ON:
|
||||
val = 1;
|
||||
break;
|
||||
case MICMUTE_LED_OFF:
|
||||
val = 0;
|
||||
break;
|
||||
case MICMUTE_LED_FOLLOW_CAPTURE:
|
||||
val = dell_capture;
|
||||
break;
|
||||
case MICMUTE_LED_FOLLOW_MUTE:
|
||||
default:
|
||||
val = !dell_capture;
|
||||
break;
|
||||
}
|
||||
|
||||
if (val == dell_led_value)
|
||||
return;
|
||||
dell_led_value = val;
|
||||
dell_micmute_led_set_func(dell_led_value);
|
||||
dell_micmute_led_set_func(spec->micmute_led.led_value);
|
||||
}
|
||||
|
||||
static void update_dell_wmi_micmute_led(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
if (dell_old_cap_hook)
|
||||
dell_old_cap_hook(codec, kcontrol, ucontrol);
|
||||
|
||||
if (!ucontrol || !dell_micmute_led_set_func)
|
||||
return;
|
||||
if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
|
||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
||||
dell_capture = (ucontrol->value.integer.value[0] ||
|
||||
ucontrol->value.integer.value[1]);
|
||||
call_micmute_led_update();
|
||||
}
|
||||
}
|
||||
|
||||
static int dell_mic_mute_led_mode_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
static const char * const texts[] = {
|
||||
"On", "Off", "Follow Capture", "Follow Mute",
|
||||
};
|
||||
|
||||
return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
|
||||
}
|
||||
|
||||
static int dell_mic_mute_led_mode_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
ucontrol->value.enumerated.item[0] = dell_led_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dell_mic_mute_led_mode_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
unsigned int mode;
|
||||
|
||||
mode = ucontrol->value.enumerated.item[0];
|
||||
if (mode > MICMUTE_LED_FOLLOW_MUTE)
|
||||
mode = MICMUTE_LED_FOLLOW_MUTE;
|
||||
if (mode == dell_led_mode)
|
||||
return 0;
|
||||
dell_led_mode = mode;
|
||||
call_micmute_led_update();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new dell_mic_mute_mode_ctls[] = {
|
||||
{
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Mic Mute-LED Mode",
|
||||
.info = dell_mic_mute_led_mode_info,
|
||||
.get = dell_mic_mute_led_mode_get,
|
||||
.put = dell_mic_mute_led_mode_put,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
static void alc_fixup_dell_wmi(struct hda_codec *codec,
|
||||
const struct hda_fixup *fix, int action)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
bool removefunc = false;
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PROBE) {
|
||||
@@ -121,25 +28,14 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec,
|
||||
return;
|
||||
}
|
||||
|
||||
removefunc = true;
|
||||
if (dell_micmute_led_set_func(false) >= 0) {
|
||||
dell_led_value = 0;
|
||||
if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch)
|
||||
codec_dbg(codec, "Skipping micmute LED control due to several ADCs");
|
||||
else {
|
||||
dell_old_cap_hook = spec->gen.cap_sync_hook;
|
||||
spec->gen.cap_sync_hook = update_dell_wmi_micmute_led;
|
||||
removefunc = false;
|
||||
add_mixer(spec, dell_mic_mute_mode_ctls);
|
||||
}
|
||||
}
|
||||
|
||||
removefunc = (dell_micmute_led_set_func(false) < 0) ||
|
||||
(snd_hda_gen_add_micmute_led(codec,
|
||||
dell_micmute_update) <= 0);
|
||||
}
|
||||
|
||||
if (dell_micmute_led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
|
||||
symbol_put(dell_micmute_led_set);
|
||||
dell_micmute_led_set_func = NULL;
|
||||
dell_old_cap_hook = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -37,15 +37,8 @@
|
||||
#include "hda_jack.h"
|
||||
#include <sound/hda_hwdep.h>
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#define codec_in_pm(codec) atomic_read(&(codec)->core.in_pm)
|
||||
#define hda_codec_is_power_on(codec) \
|
||||
(!pm_runtime_suspended(hda_codec_dev(codec)))
|
||||
#else
|
||||
#define codec_in_pm(codec) 0
|
||||
#define hda_codec_is_power_on(codec) 1
|
||||
#endif
|
||||
|
||||
#define codec_in_pm(codec) snd_hdac_is_in_pm(&codec->core)
|
||||
#define hda_codec_is_power_on(codec) snd_hdac_is_power_on(&codec->core)
|
||||
#define codec_has_epss(codec) \
|
||||
((codec)->core.power_caps & AC_PWRST_EPSS)
|
||||
#define codec_has_clkstop(codec) \
|
||||
@@ -858,6 +851,39 @@ static void snd_hda_codec_dev_release(struct device *dev)
|
||||
kfree(codec);
|
||||
}
|
||||
|
||||
#define DEV_NAME_LEN 31
|
||||
|
||||
static int snd_hda_codec_device_init(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec **codecp)
|
||||
{
|
||||
char name[DEV_NAME_LEN];
|
||||
struct hda_codec *codec;
|
||||
int err;
|
||||
|
||||
dev_dbg(card->dev, "%s: entry\n", __func__);
|
||||
|
||||
if (snd_BUG_ON(!bus))
|
||||
return -EINVAL;
|
||||
if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
|
||||
return -EINVAL;
|
||||
|
||||
codec = kzalloc(sizeof(*codec), GFP_KERNEL);
|
||||
if (!codec)
|
||||
return -ENOMEM;
|
||||
|
||||
sprintf(name, "hdaudioC%dD%d", card->number, codec_addr);
|
||||
err = snd_hdac_device_init(&codec->core, &bus->core, name, codec_addr);
|
||||
if (err < 0) {
|
||||
kfree(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
codec->core.type = HDA_DEV_LEGACY;
|
||||
*codecp = codec;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/**
|
||||
* snd_hda_codec_new - create a HDA codec
|
||||
* @bus: the bus to assign
|
||||
@@ -869,7 +895,19 @@ static void snd_hda_codec_dev_release(struct device *dev)
|
||||
int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec **codecp)
|
||||
{
|
||||
struct hda_codec *codec;
|
||||
int ret;
|
||||
|
||||
ret = snd_hda_codec_device_init(bus, card, codec_addr, codecp);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return snd_hda_codec_device_new(bus, card, codec_addr, *codecp);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_new);
|
||||
|
||||
int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec *codec)
|
||||
{
|
||||
char component[31];
|
||||
hda_nid_t fg;
|
||||
int err;
|
||||
@@ -879,25 +917,14 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
|
||||
.dev_free = snd_hda_codec_dev_free,
|
||||
};
|
||||
|
||||
dev_dbg(card->dev, "%s: entry\n", __func__);
|
||||
|
||||
if (snd_BUG_ON(!bus))
|
||||
return -EINVAL;
|
||||
if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
|
||||
return -EINVAL;
|
||||
|
||||
codec = kzalloc(sizeof(*codec), GFP_KERNEL);
|
||||
if (!codec)
|
||||
return -ENOMEM;
|
||||
|
||||
sprintf(component, "hdaudioC%dD%d", card->number, codec_addr);
|
||||
err = snd_hdac_device_init(&codec->core, &bus->core, component,
|
||||
codec_addr);
|
||||
if (err < 0) {
|
||||
kfree(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
codec->core.dev.release = snd_hda_codec_dev_release;
|
||||
codec->core.type = HDA_DEV_LEGACY;
|
||||
codec->core.exec_verb = codec_exec_verb;
|
||||
|
||||
codec->bus = bus;
|
||||
@@ -957,15 +984,13 @@ int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
if (codecp)
|
||||
*codecp = codec;
|
||||
return 0;
|
||||
|
||||
error:
|
||||
put_device(hda_codec_dev(codec));
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_new);
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_device_new);
|
||||
|
||||
/**
|
||||
* snd_hda_codec_update_widgets - Refresh widget caps and pin defaults
|
||||
@@ -2846,14 +2871,13 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int state;
|
||||
|
||||
atomic_inc(&codec->core.in_pm);
|
||||
|
||||
snd_hdac_enter_pm(&codec->core);
|
||||
if (codec->patch_ops.suspend)
|
||||
codec->patch_ops.suspend(codec);
|
||||
hda_cleanup_all_streams(codec);
|
||||
state = hda_set_power_state(codec, AC_PWRST_D3);
|
||||
update_power_acct(codec, true);
|
||||
atomic_dec(&codec->core.in_pm);
|
||||
snd_hdac_leave_pm(&codec->core);
|
||||
return state;
|
||||
}
|
||||
|
||||
@@ -2862,8 +2886,7 @@ static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
|
||||
*/
|
||||
static void hda_call_codec_resume(struct hda_codec *codec)
|
||||
{
|
||||
atomic_inc(&codec->core.in_pm);
|
||||
|
||||
snd_hdac_enter_pm(&codec->core);
|
||||
if (codec->core.regmap)
|
||||
regcache_mark_dirty(codec->core.regmap);
|
||||
|
||||
@@ -2886,7 +2909,7 @@ static void hda_call_codec_resume(struct hda_codec *codec)
|
||||
hda_jackpoll_work(&codec->jackpoll_work.work);
|
||||
else
|
||||
snd_hda_jack_report_sync(codec);
|
||||
atomic_dec(&codec->core.in_pm);
|
||||
snd_hdac_leave_pm(&codec->core);
|
||||
}
|
||||
|
||||
static int hda_codec_runtime_suspend(struct device *dev)
|
||||
@@ -2992,6 +3015,7 @@ int snd_hda_codec_build_controls(struct hda_codec *codec)
|
||||
sync_power_up_states(codec);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_build_controls);
|
||||
|
||||
/*
|
||||
* PCM stuff
|
||||
@@ -3197,6 +3221,7 @@ int snd_hda_codec_parse_pcms(struct hda_codec *codec)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_codec_parse_pcms);
|
||||
|
||||
/* assign all PCMs of the given codec */
|
||||
int snd_hda_codec_build_pcms(struct hda_codec *codec)
|
||||
@@ -3252,8 +3277,8 @@ int snd_hda_add_new_ctls(struct hda_codec *codec,
|
||||
for (; knew->name; knew++) {
|
||||
struct snd_kcontrol *kctl;
|
||||
int addr = 0, idx = 0;
|
||||
if (knew->iface == -1) /* skip this codec private value */
|
||||
continue;
|
||||
if (knew->iface == (__force snd_ctl_elem_iface_t)-1)
|
||||
continue; /* skip this codec private value */
|
||||
for (;;) {
|
||||
kctl = snd_ctl_new1(knew, codec);
|
||||
if (!kctl)
|
||||
@@ -3843,7 +3868,7 @@ EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl);
|
||||
* This function is a helper to set a pin ctl value more safely.
|
||||
* It corrects the pin ctl value via snd_hda_correct_pin_ctl(), stores the
|
||||
* value in pin target array via snd_hda_codec_set_pin_target(), then
|
||||
* actually writes the value via either snd_hda_codec_update_cache() or
|
||||
* actually writes the value via either snd_hda_codec_write_cache() or
|
||||
* snd_hda_codec_write() depending on @cached flag.
|
||||
*/
|
||||
int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
|
||||
@@ -3852,7 +3877,7 @@ int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
|
||||
val = snd_hda_correct_pin_ctl(codec, pin, val);
|
||||
snd_hda_codec_set_pin_target(codec, pin, val);
|
||||
if (cached)
|
||||
return snd_hda_codec_update_cache(codec, pin, 0,
|
||||
return snd_hda_codec_write_cache(codec, pin, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val);
|
||||
else
|
||||
return snd_hda_codec_write(codec, pin, 0,
|
||||
|
@@ -84,6 +84,7 @@ struct hda_bus {
|
||||
*/
|
||||
typedef int (*hda_codec_patch_t)(struct hda_codec *);
|
||||
|
||||
#define HDA_CODEC_ID_SKIP_PROBE 0x00000001
|
||||
#define HDA_CODEC_ID_GENERIC_HDMI 0x00000101
|
||||
#define HDA_CODEC_ID_GENERIC 0x00000201
|
||||
|
||||
@@ -308,6 +309,8 @@ struct hda_codec {
|
||||
*/
|
||||
int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec **codecp);
|
||||
int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
|
||||
unsigned int codec_addr, struct hda_codec *codec);
|
||||
int snd_hda_codec_configure(struct hda_codec *codec);
|
||||
int snd_hda_codec_update_widgets(struct hda_codec *codec);
|
||||
|
||||
@@ -382,9 +385,6 @@ snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
|
||||
return snd_hdac_regmap_write(&codec->core, nid, verb, parm);
|
||||
}
|
||||
|
||||
#define snd_hda_codec_update_cache(codec, nid, flags, verb, parm) \
|
||||
snd_hda_codec_write_cache(codec, nid, flags, verb, parm)
|
||||
|
||||
/* the struct for codec->pin_configs */
|
||||
struct hda_pincfg {
|
||||
hda_nid_t nid;
|
||||
|
@@ -209,7 +209,7 @@ static void parse_user_hints(struct hda_codec *codec)
|
||||
*/
|
||||
|
||||
#define update_pin_ctl(codec, pin, val) \
|
||||
snd_hda_codec_update_cache(codec, pin, 0, \
|
||||
snd_hda_codec_write_cache(codec, pin, 0, \
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val)
|
||||
|
||||
/* restore the pinctl based on the cached value */
|
||||
@@ -898,7 +898,7 @@ void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
|
||||
hda_nid_t nid = path->path[i];
|
||||
|
||||
if (enable && path->multi[i])
|
||||
snd_hda_codec_update_cache(codec, nid, 0,
|
||||
snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_CONNECT_SEL,
|
||||
path->idx[i]);
|
||||
if (has_amp_in(codec, path, i))
|
||||
@@ -930,7 +930,7 @@ static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable)
|
||||
return;
|
||||
if (codec->inv_eapd)
|
||||
enable = !enable;
|
||||
snd_hda_codec_update_cache(codec, pin, 0,
|
||||
snd_hda_codec_write_cache(codec, pin, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE,
|
||||
enable ? 0x02 : 0x00);
|
||||
}
|
||||
@@ -3899,6 +3899,142 @@ static int parse_mic_boost(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* mic mute LED hook helpers
|
||||
*/
|
||||
enum {
|
||||
MICMUTE_LED_ON,
|
||||
MICMUTE_LED_OFF,
|
||||
MICMUTE_LED_FOLLOW_CAPTURE,
|
||||
MICMUTE_LED_FOLLOW_MUTE,
|
||||
};
|
||||
|
||||
static void call_micmute_led_update(struct hda_codec *codec)
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
unsigned int val;
|
||||
|
||||
switch (spec->micmute_led.led_mode) {
|
||||
case MICMUTE_LED_ON:
|
||||
val = 1;
|
||||
break;
|
||||
case MICMUTE_LED_OFF:
|
||||
val = 0;
|
||||
break;
|
||||
case MICMUTE_LED_FOLLOW_CAPTURE:
|
||||
val = !!spec->micmute_led.capture;
|
||||
break;
|
||||
case MICMUTE_LED_FOLLOW_MUTE:
|
||||
default:
|
||||
val = !spec->micmute_led.capture;
|
||||
break;
|
||||
}
|
||||
|
||||
if (val == spec->micmute_led.led_value)
|
||||
return;
|
||||
spec->micmute_led.led_value = val;
|
||||
if (spec->micmute_led.update)
|
||||
spec->micmute_led.update(codec);
|
||||
}
|
||||
|
||||
static void update_micmute_led(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
unsigned int mask;
|
||||
|
||||
if (spec->micmute_led.old_hook)
|
||||
spec->micmute_led.old_hook(codec, kcontrol, ucontrol);
|
||||
|
||||
if (!ucontrol)
|
||||
return;
|
||||
mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
|
||||
if (!strcmp("Capture Switch", ucontrol->id.name)) {
|
||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
||||
if (ucontrol->value.integer.value[0] ||
|
||||
ucontrol->value.integer.value[1])
|
||||
spec->micmute_led.capture |= mask;
|
||||
else
|
||||
spec->micmute_led.capture &= ~mask;
|
||||
call_micmute_led_update(codec);
|
||||
}
|
||||
}
|
||||
|
||||
static int micmute_led_mode_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
static const char * const texts[] = {
|
||||
"On", "Off", "Follow Capture", "Follow Mute",
|
||||
};
|
||||
|
||||
return snd_ctl_enum_info(uinfo, 1, ARRAY_SIZE(texts), texts);
|
||||
}
|
||||
|
||||
static int micmute_led_mode_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
|
||||
ucontrol->value.enumerated.item[0] = spec->micmute_led.led_mode;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int micmute_led_mode_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
unsigned int mode;
|
||||
|
||||
mode = ucontrol->value.enumerated.item[0];
|
||||
if (mode > MICMUTE_LED_FOLLOW_MUTE)
|
||||
mode = MICMUTE_LED_FOLLOW_MUTE;
|
||||
if (mode == spec->micmute_led.led_mode)
|
||||
return 0;
|
||||
spec->micmute_led.led_mode = mode;
|
||||
call_micmute_led_update(codec);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new micmute_led_mode_ctl = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Mic Mute-LED Mode",
|
||||
.info = micmute_led_mode_info,
|
||||
.get = micmute_led_mode_get,
|
||||
.put = micmute_led_mode_put,
|
||||
};
|
||||
|
||||
/**
|
||||
* snd_hda_gen_add_micmute_led - helper for setting up mic mute LED hook
|
||||
* @codec: the HDA codec
|
||||
* @hook: the callback for updating LED
|
||||
*
|
||||
* Called from the codec drivers for offering the mic mute LED controls.
|
||||
* When established, it sets up cap_sync_hook and triggers the callback at
|
||||
* each time when the capture mixer switch changes. The callback is supposed
|
||||
* to update the LED accordingly.
|
||||
*
|
||||
* Returns 0 if the hook is established or a negative error code.
|
||||
*/
|
||||
int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
|
||||
void (*hook)(struct hda_codec *))
|
||||
{
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
|
||||
spec->micmute_led.led_mode = MICMUTE_LED_FOLLOW_MUTE;
|
||||
spec->micmute_led.capture = 0;
|
||||
spec->micmute_led.led_value = 0;
|
||||
spec->micmute_led.old_hook = spec->cap_sync_hook;
|
||||
spec->micmute_led.update = hook;
|
||||
spec->cap_sync_hook = update_micmute_led;
|
||||
if (!snd_hda_gen_add_kctl(spec, NULL, &micmute_led_mode_ctl))
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_hda_gen_add_micmute_led);
|
||||
|
||||
/*
|
||||
* parse digital I/Os and set up NIDs in BIOS auto-parse mode
|
||||
*/
|
||||
@@ -5837,7 +5973,7 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec)
|
||||
hda_nid_t nid = pin->nid;
|
||||
if (is_jack_detectable(codec, nid) &&
|
||||
!snd_hda_jack_tbl_get(codec, nid))
|
||||
snd_hda_codec_update_cache(codec, nid, 0,
|
||||
snd_hda_codec_write_cache(codec, nid, 0,
|
||||
AC_VERB_SET_UNSOLICITED_ENABLE, 0);
|
||||
}
|
||||
}
|
||||
|
@@ -86,6 +86,16 @@ struct badness_table {
|
||||
extern const struct badness_table hda_main_out_badness;
|
||||
extern const struct badness_table hda_extra_out_badness;
|
||||
|
||||
struct hda_micmute_hook {
|
||||
unsigned int led_mode;
|
||||
unsigned int capture;
|
||||
unsigned int led_value;
|
||||
void (*update)(struct hda_codec *codec);
|
||||
void (*old_hook)(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
};
|
||||
|
||||
struct hda_gen_spec {
|
||||
char stream_name_analog[32]; /* analog PCM stream */
|
||||
const struct hda_pcm_stream *stream_analog_playback;
|
||||
@@ -276,6 +286,9 @@ struct hda_gen_spec {
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol);
|
||||
|
||||
/* mic mute LED hook; called via cap_sync_hook */
|
||||
struct hda_micmute_hook micmute_led;
|
||||
|
||||
/* PCM hooks */
|
||||
void (*pcm_playback_hook)(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
@@ -342,4 +355,7 @@ unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
|
||||
void snd_hda_gen_stream_pm(struct hda_codec *codec, hda_nid_t nid, bool on);
|
||||
int snd_hda_gen_fix_pin_power(struct hda_codec *codec, hda_nid_t pin);
|
||||
|
||||
int snd_hda_gen_add_micmute_led(struct hda_codec *codec,
|
||||
void (*hook)(struct hda_codec *));
|
||||
|
||||
#endif /* __SOUND_HDA_GENERIC_H */
|
||||
|
@@ -1319,15 +1319,16 @@ static const struct vga_switcheroo_client_ops azx_vs_ops = {
|
||||
static int register_vga_switcheroo(struct azx *chip)
|
||||
{
|
||||
struct hda_intel *hda = container_of(chip, struct hda_intel, chip);
|
||||
struct pci_dev *p;
|
||||
int err;
|
||||
|
||||
if (!hda->use_vga_switcheroo)
|
||||
return 0;
|
||||
/* FIXME: currently only handling DIS controller
|
||||
* is there any machine with two switchable HDMI audio controllers?
|
||||
*/
|
||||
err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops,
|
||||
VGA_SWITCHEROO_DIS);
|
||||
|
||||
p = get_bound_vga(chip->pci);
|
||||
err = vga_switcheroo_register_audio_client(chip->pci, &azx_vs_ops, p);
|
||||
pci_dev_put(p);
|
||||
|
||||
if (err < 0)
|
||||
return err;
|
||||
hda->vga_switcheroo_registered = 1;
|
||||
@@ -1429,7 +1430,7 @@ static struct pci_dev *get_bound_vga(struct pci_dev *pci)
|
||||
p = pci_get_domain_bus_and_slot(pci_domain_nr(pci->bus),
|
||||
pci->bus->number, 0);
|
||||
if (p) {
|
||||
if ((p->class >> 8) == PCI_CLASS_DISPLAY_VGA)
|
||||
if ((p->class >> 16) == PCI_BASE_CLASS_DISPLAY)
|
||||
return p;
|
||||
pci_dev_put(p);
|
||||
}
|
||||
@@ -2535,7 +2536,8 @@ static const struct pci_device_id azx_ids[] = {
|
||||
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
|
||||
/* AMD Raven */
|
||||
{ PCI_DEVICE(0x1022, 0x15e3),
|
||||
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB },
|
||||
.driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB |
|
||||
AZX_DCAPS_PM_RUNTIME },
|
||||
/* ATI HDMI */
|
||||
{ PCI_DEVICE(0x1002, 0x0002),
|
||||
.driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
|
||||
|
@@ -148,7 +148,7 @@ static void ad_vmaster_eapd_hook(void *private_data, int enabled)
|
||||
return;
|
||||
if (codec->inv_eapd)
|
||||
enabled = !enabled;
|
||||
snd_hda_codec_update_cache(codec, spec->eapd_nid, 0,
|
||||
snd_hda_codec_write_cache(codec, spec->eapd_nid, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE,
|
||||
enabled ? 0x02 : 0x00);
|
||||
}
|
||||
@@ -991,7 +991,7 @@ static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled)
|
||||
|
||||
if (spec->eapd_nid)
|
||||
ad_vmaster_eapd_hook(private_data, enabled);
|
||||
snd_hda_codec_update_cache(codec, 0x01, 0,
|
||||
snd_hda_codec_write_cache(codec, 0x01, 0,
|
||||
AC_VERB_SET_GPIO_DATA,
|
||||
enabled ? 0x00 : 0x02);
|
||||
}
|
||||
|
@@ -897,7 +897,7 @@ struct ca0132_spec {
|
||||
const struct hda_verb *base_init_verbs;
|
||||
const struct hda_verb *base_exit_verbs;
|
||||
const struct hda_verb *chip_init_verbs;
|
||||
const struct hda_verb *sbz_init_verbs;
|
||||
const struct hda_verb *desktop_init_verbs;
|
||||
struct hda_verb *spec_init_verbs;
|
||||
struct auto_pin_cfg autocfg;
|
||||
|
||||
@@ -965,9 +965,11 @@ struct ca0132_spec {
|
||||
long cur_ctl_vals[TUNING_CTLS_COUNT];
|
||||
#endif
|
||||
/*
|
||||
* Sound Blaster Z PCI region 2 iomem, used for input and output
|
||||
* switching, and other unknown commands.
|
||||
* The Recon3D, Sound Blaster Z, Sound Blaster ZxR, and Sound Blaster
|
||||
* AE-5 all use PCI region 2 to toggle GPIO and other currently unknown
|
||||
* things.
|
||||
*/
|
||||
bool use_pci_mmio;
|
||||
void __iomem *mem_base;
|
||||
|
||||
/*
|
||||
@@ -994,6 +996,7 @@ enum {
|
||||
QUIRK_ALIENWARE_M17XR4,
|
||||
QUIRK_SBZ,
|
||||
QUIRK_R3DI,
|
||||
QUIRK_R3D,
|
||||
};
|
||||
|
||||
static const struct hda_pintbl alienware_pincfgs[] = {
|
||||
@@ -1025,6 +1028,21 @@ static const struct hda_pintbl sbz_pincfgs[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
/* Recon3D pin configs taken from Windows Driver */
|
||||
static const struct hda_pintbl r3d_pincfgs[] = {
|
||||
{ 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */
|
||||
{ 0x0c, 0x014510f0 }, /* SPDIF Out 1 */
|
||||
{ 0x0d, 0x014510f0 }, /* Digital Out */
|
||||
{ 0x0e, 0x01c520f0 }, /* SPDIF In */
|
||||
{ 0x0f, 0x0221401f }, /* Port A -- BackPanel HP */
|
||||
{ 0x10, 0x01016011 }, /* Port D -- Center/LFE or FP Hp */
|
||||
{ 0x11, 0x01011014 }, /* Port B -- LineMicIn2 / Rear L/R */
|
||||
{ 0x12, 0x02a090f0 }, /* Port C -- LineIn1 */
|
||||
{ 0x13, 0x908700f0 }, /* What U Hear In*/
|
||||
{ 0x18, 0x50d000f0 }, /* N/A */
|
||||
{}
|
||||
};
|
||||
|
||||
/* Recon3D integrated pin configs taken from Windows Driver */
|
||||
static const struct hda_pintbl r3di_pincfgs[] = {
|
||||
{ 0x0b, 0x01014110 }, /* Port G -- Lineout FRONT L/R */
|
||||
@@ -1050,6 +1068,7 @@ static const struct snd_pci_quirk ca0132_quirks[] = {
|
||||
SND_PCI_QUIRK(0x1458, 0xA016, "Recon3Di", QUIRK_R3DI),
|
||||
SND_PCI_QUIRK(0x1458, 0xA026, "Gigabyte G1.Sniper Z97", QUIRK_R3DI),
|
||||
SND_PCI_QUIRK(0x1458, 0xA036, "Gigabyte GA-Z170X-Gaming 7", QUIRK_R3DI),
|
||||
SND_PCI_QUIRK(0x1102, 0x0013, "Recon3D", QUIRK_R3D),
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -3072,6 +3091,24 @@ static bool dspload_wait_loaded(struct hda_codec *codec)
|
||||
* Setup GPIO for the other variants of Core3D.
|
||||
*/
|
||||
|
||||
/*
|
||||
* For cards with PCI-E region2 (Sound Blaster Z/ZxR, Recon3D, and AE-5)
|
||||
* the mmio address 0x320 is used to set GPIO pins. The format for the data
|
||||
* The first eight bits are just the number of the pin. So far, I've only seen
|
||||
* this number go to 7.
|
||||
*/
|
||||
static void ca0132_mmio_gpio_set(struct hda_codec *codec, unsigned int gpio_pin,
|
||||
bool enable)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
unsigned short gpio_data;
|
||||
|
||||
gpio_data = gpio_pin & 0xF;
|
||||
gpio_data |= ((enable << 8) & 0x100);
|
||||
|
||||
writew(gpio_data, spec->mem_base + 0x320);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets up the GPIO pins so that they are discoverable. If this isn't done,
|
||||
* the card shows as having no GPIO pins.
|
||||
@@ -3947,15 +3984,19 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
||||
/*speaker out config*/
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
writew(0x0007, spec->mem_base + 0x320);
|
||||
writew(0x0104, spec->mem_base + 0x320);
|
||||
writew(0x0101, spec->mem_base + 0x320);
|
||||
ca0132_mmio_gpio_set(codec, 7, false);
|
||||
ca0132_mmio_gpio_set(codec, 4, true);
|
||||
ca0132_mmio_gpio_set(codec, 1, true);
|
||||
chipio_set_control_param(codec, 0x0D, 0x18);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
chipio_set_control_param(codec, 0x0D, 0x24);
|
||||
r3di_gpio_out_set(codec, R3DI_LINE_OUT);
|
||||
break;
|
||||
case QUIRK_R3D:
|
||||
chipio_set_control_param(codec, 0x0D, 0x24);
|
||||
ca0132_mmio_gpio_set(codec, 1, true);
|
||||
break;
|
||||
}
|
||||
|
||||
/* disable headphone node */
|
||||
@@ -3983,15 +4024,19 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
||||
/* Headphone out config*/
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
writew(0x0107, spec->mem_base + 0x320);
|
||||
writew(0x0104, spec->mem_base + 0x320);
|
||||
writew(0x0001, spec->mem_base + 0x320);
|
||||
ca0132_mmio_gpio_set(codec, 7, true);
|
||||
ca0132_mmio_gpio_set(codec, 4, true);
|
||||
ca0132_mmio_gpio_set(codec, 1, false);
|
||||
chipio_set_control_param(codec, 0x0D, 0x12);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
chipio_set_control_param(codec, 0x0D, 0x21);
|
||||
r3di_gpio_out_set(codec, R3DI_HEADPHONE_OUT);
|
||||
break;
|
||||
case QUIRK_R3D:
|
||||
chipio_set_control_param(codec, 0x0D, 0x21);
|
||||
ca0132_mmio_gpio_set(codec, 0x1, false);
|
||||
break;
|
||||
}
|
||||
|
||||
snd_hda_codec_write(codec, spec->out_pins[0], 0,
|
||||
@@ -4025,15 +4070,19 @@ static int ca0132_alt_select_out(struct hda_codec *codec)
|
||||
/* Surround out config*/
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
writew(0x0007, spec->mem_base + 0x320);
|
||||
writew(0x0104, spec->mem_base + 0x320);
|
||||
writew(0x0101, spec->mem_base + 0x320);
|
||||
ca0132_mmio_gpio_set(codec, 7, false);
|
||||
ca0132_mmio_gpio_set(codec, 4, true);
|
||||
ca0132_mmio_gpio_set(codec, 1, true);
|
||||
chipio_set_control_param(codec, 0x0D, 0x18);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
chipio_set_control_param(codec, 0x0D, 0x24);
|
||||
r3di_gpio_out_set(codec, R3DI_LINE_OUT);
|
||||
break;
|
||||
case QUIRK_R3D:
|
||||
ca0132_mmio_gpio_set(codec, 1, true);
|
||||
chipio_set_control_param(codec, 0x0D, 0x24);
|
||||
break;
|
||||
}
|
||||
/* enable line out node */
|
||||
pin_ctl = snd_hda_codec_read(codec, spec->out_pins[0], 0,
|
||||
@@ -4291,7 +4340,8 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
|
||||
case REAR_MIC:
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
writew(0x0000, spec->mem_base + 0x320);
|
||||
case QUIRK_R3D:
|
||||
ca0132_mmio_gpio_set(codec, 0, false);
|
||||
tmp = FLOAT_THREE;
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
@@ -4323,7 +4373,8 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
|
||||
ca0132_mic_boost_set(codec, 0);
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
writew(0x0000, spec->mem_base + 0x320);
|
||||
case QUIRK_R3D:
|
||||
ca0132_mmio_gpio_set(codec, 0, false);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
r3di_gpio_mic_set(codec, R3DI_REAR_MIC);
|
||||
@@ -4349,8 +4400,9 @@ static int ca0132_alt_select_in(struct hda_codec *codec)
|
||||
case FRONT_MIC:
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
writew(0x0100, spec->mem_base + 0x320);
|
||||
writew(0x0005, spec->mem_base + 0x320);
|
||||
case QUIRK_R3D:
|
||||
ca0132_mmio_gpio_set(codec, 0, true);
|
||||
ca0132_mmio_gpio_set(codec, 5, false);
|
||||
tmp = FLOAT_THREE;
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
@@ -5516,8 +5568,7 @@ static int ca0132_alt_add_effect_slider(struct hda_codec *codec, hda_nid_t nid,
|
||||
|
||||
sprintf(namestr, "FX: %s %s Volume", pfx, dirstr[dir]);
|
||||
|
||||
knew.tlv.c = 0;
|
||||
knew.tlv.p = 0;
|
||||
knew.tlv.c = NULL;
|
||||
|
||||
switch (nid) {
|
||||
case XBASS_XOVER:
|
||||
@@ -5729,11 +5780,11 @@ static const struct snd_kcontrol_new ca0132_mixer[] = {
|
||||
};
|
||||
|
||||
/*
|
||||
* SBZ specific control mixer. Removes auto-detect for mic, and adds surround
|
||||
* controls. Also sets both the Front Playback and Capture Volume controls to
|
||||
* alt so they set the DSP's decibel level.
|
||||
* Desktop specific control mixer. Removes auto-detect for mic, and adds
|
||||
* surround controls. Also sets both the Front Playback and Capture Volume
|
||||
* controls to alt so they set the DSP's decibel level.
|
||||
*/
|
||||
static const struct snd_kcontrol_new sbz_mixer[] = {
|
||||
static const struct snd_kcontrol_new desktop_mixer[] = {
|
||||
CA0132_ALT_CODEC_VOL("Front Playback Volume", 0x02, HDA_OUTPUT),
|
||||
CA0132_CODEC_MUTE("Front Playback Switch", VNID_SPK, HDA_OUTPUT),
|
||||
HDA_CODEC_VOLUME("Surround Playback Volume", 0x04, 0, HDA_OUTPUT),
|
||||
@@ -5804,8 +5855,8 @@ static int ca0132_build_controls(struct hda_codec *codec)
|
||||
*/
|
||||
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT;
|
||||
for (i = 0; i < num_fx; i++) {
|
||||
/* SBZ breaks if Echo Cancellation is used */
|
||||
if (spec->quirk == QUIRK_SBZ) {
|
||||
/* SBZ and R3D break if Echo Cancellation is used. */
|
||||
if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3D) {
|
||||
if (i == (ECHO_CANCELLATION - IN_EFFECT_START_NID +
|
||||
OUT_EFFECTS_COUNT))
|
||||
continue;
|
||||
@@ -6187,10 +6238,10 @@ static void ca0132_refresh_widget_caps(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
/*
|
||||
* Recon3Di r3di_setup_defaults sub functions.
|
||||
* Recon3D r3d_setup_defaults sub functions.
|
||||
*/
|
||||
|
||||
static void r3di_dsp_scp_startup(struct hda_codec *codec)
|
||||
static void r3d_dsp_scp_startup(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
@@ -6211,7 +6262,7 @@ static void r3di_dsp_scp_startup(struct hda_codec *codec)
|
||||
|
||||
}
|
||||
|
||||
static void r3di_dsp_initial_mic_setup(struct hda_codec *codec)
|
||||
static void r3d_dsp_initial_mic_setup(struct hda_codec *codec)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
@@ -6421,10 +6472,10 @@ static void ca0132_setup_defaults(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup default parameters for Recon3Di DSP.
|
||||
* Setup default parameters for Recon3D/Recon3Di DSP.
|
||||
*/
|
||||
|
||||
static void r3di_setup_defaults(struct hda_codec *codec)
|
||||
static void r3d_setup_defaults(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
unsigned int tmp;
|
||||
@@ -6434,9 +6485,9 @@ static void r3di_setup_defaults(struct hda_codec *codec)
|
||||
if (spec->dsp_state != DSP_DOWNLOADED)
|
||||
return;
|
||||
|
||||
r3di_dsp_scp_startup(codec);
|
||||
r3d_dsp_scp_startup(codec);
|
||||
|
||||
r3di_dsp_initial_mic_setup(codec);
|
||||
r3d_dsp_initial_mic_setup(codec);
|
||||
|
||||
/*remove DSP headroom*/
|
||||
tmp = FLOAT_ZERO;
|
||||
@@ -6450,7 +6501,8 @@ static void r3di_setup_defaults(struct hda_codec *codec)
|
||||
/* Set speaker source? */
|
||||
dspio_set_uint_param(codec, 0x32, 0x00, tmp);
|
||||
|
||||
r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
|
||||
if (spec->quirk == QUIRK_R3DI)
|
||||
r3di_gpio_dsp_status_set(codec, R3DI_DSP_DOWNLOADED);
|
||||
|
||||
/* Setup effect defaults */
|
||||
num_fx = OUT_EFFECTS_COUNT + IN_EFFECTS_COUNT + 1;
|
||||
@@ -6462,7 +6514,6 @@ static void r3di_setup_defaults(struct hda_codec *codec)
|
||||
ca0132_effects[idx].def_vals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6727,7 +6778,12 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
|
||||
|
||||
static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
|
||||
{
|
||||
ca0132_select_mic(codec);
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
if (spec->use_alt_functions)
|
||||
ca0132_alt_select_in(codec);
|
||||
else
|
||||
ca0132_select_mic(codec);
|
||||
}
|
||||
|
||||
static void ca0132_init_unsol(struct hda_codec *codec)
|
||||
@@ -6798,8 +6854,8 @@ static struct hda_verb ca0132_init_verbs0[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
/* Extra init verbs for SBZ */
|
||||
static struct hda_verb sbz_init_verbs[] = {
|
||||
/* Extra init verbs for desktop cards. */
|
||||
static struct hda_verb ca0132_init_verbs1[] = {
|
||||
{0x15, 0x70D, 0x20},
|
||||
{0x15, 0x70E, 0x19},
|
||||
{0x15, 0x707, 0x00},
|
||||
@@ -6891,16 +6947,12 @@ static void sbz_region2_exit(struct hda_codec *codec)
|
||||
writeb(0x0, spec->mem_base + 0x100);
|
||||
for (i = 0; i < 8; i++)
|
||||
writeb(0xb3, spec->mem_base + 0x304);
|
||||
/*
|
||||
* I believe these are GPIO, with the right most hex digit being the
|
||||
* gpio pin, and the second digit being on or off. We see this more in
|
||||
* the input/output select functions.
|
||||
*/
|
||||
writew(0x0000, spec->mem_base + 0x320);
|
||||
writew(0x0001, spec->mem_base + 0x320);
|
||||
writew(0x0104, spec->mem_base + 0x320);
|
||||
writew(0x0005, spec->mem_base + 0x320);
|
||||
writew(0x0007, spec->mem_base + 0x320);
|
||||
|
||||
ca0132_mmio_gpio_set(codec, 0, false);
|
||||
ca0132_mmio_gpio_set(codec, 1, false);
|
||||
ca0132_mmio_gpio_set(codec, 4, true);
|
||||
ca0132_mmio_gpio_set(codec, 5, false);
|
||||
ca0132_mmio_gpio_set(codec, 7, false);
|
||||
}
|
||||
|
||||
static void sbz_set_pin_ctl_default(struct hda_codec *codec)
|
||||
@@ -6916,7 +6968,7 @@ static void sbz_set_pin_ctl_default(struct hda_codec *codec)
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00);
|
||||
}
|
||||
|
||||
static void sbz_clear_unsolicited(struct hda_codec *codec)
|
||||
static void ca0132_clear_unsolicited(struct hda_codec *codec)
|
||||
{
|
||||
hda_nid_t pins[7] = {0x0B, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13};
|
||||
unsigned int i;
|
||||
@@ -6969,21 +7021,22 @@ static void sbz_exit_chip(struct hda_codec *codec)
|
||||
|
||||
chipio_set_control_param(codec, 0x0D, 0x24);
|
||||
|
||||
sbz_clear_unsolicited(codec);
|
||||
ca0132_clear_unsolicited(codec);
|
||||
sbz_set_pin_ctl_default(codec);
|
||||
|
||||
snd_hda_codec_write(codec, 0x0B, 0,
|
||||
AC_VERB_SET_EAPD_BTLENABLE, 0x00);
|
||||
|
||||
if (dspload_is_loaded(codec))
|
||||
dsp_reset(codec);
|
||||
|
||||
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
|
||||
VENDOR_CHIPIO_CT_EXTENSIONS_ENABLE, 0x00);
|
||||
|
||||
sbz_region2_exit(codec);
|
||||
}
|
||||
|
||||
static void r3d_exit_chip(struct hda_codec *codec)
|
||||
{
|
||||
ca0132_clear_unsolicited(codec);
|
||||
snd_hda_codec_write(codec, 0x01, 0, 0x793, 0x00);
|
||||
snd_hda_codec_write(codec, 0x01, 0, 0x794, 0x5b);
|
||||
}
|
||||
|
||||
static void ca0132_exit_chip(struct hda_codec *codec)
|
||||
{
|
||||
/* put any chip cleanup stuffs here. */
|
||||
@@ -7098,9 +7151,27 @@ static void sbz_pre_dsp_setup(struct hda_codec *codec)
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44);
|
||||
}
|
||||
|
||||
/*
|
||||
* Extra commands that don't really fit anywhere else.
|
||||
*/
|
||||
static void r3d_pre_dsp_setup(struct hda_codec *codec)
|
||||
{
|
||||
|
||||
snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfc);
|
||||
snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfd);
|
||||
snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xfe);
|
||||
snd_hda_codec_write(codec, 0x15, 0, 0xd00, 0xff);
|
||||
|
||||
chipio_write(codec, 0x18b0a4, 0x000000c2);
|
||||
|
||||
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
|
||||
VENDOR_CHIPIO_8051_ADDRESS_LOW, 0x1E);
|
||||
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
|
||||
VENDOR_CHIPIO_8051_ADDRESS_HIGH, 0x1C);
|
||||
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0,
|
||||
VENDOR_CHIPIO_8051_DATA_WRITE, 0x5B);
|
||||
|
||||
snd_hda_codec_write(codec, 0x11, 0,
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x44);
|
||||
}
|
||||
|
||||
static void r3di_pre_dsp_setup(struct hda_codec *codec)
|
||||
{
|
||||
chipio_write(codec, 0x18b0a4, 0x000000c2);
|
||||
@@ -7125,13 +7196,12 @@ static void r3di_pre_dsp_setup(struct hda_codec *codec)
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, 0x04);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These are sent before the DSP is downloaded. Not sure
|
||||
* what they do, or if they're necessary. Could possibly
|
||||
* be removed. Figure they're better to leave in.
|
||||
*/
|
||||
static void sbz_region2_startup(struct hda_codec *codec)
|
||||
static void ca0132_mmio_init(struct hda_codec *codec)
|
||||
{
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
@@ -7171,7 +7241,7 @@ static void ca0132_alt_init(struct hda_codec *codec)
|
||||
ca0132_gpio_init(codec);
|
||||
sbz_pre_dsp_setup(codec);
|
||||
snd_hda_sequence_write(codec, spec->chip_init_verbs);
|
||||
snd_hda_sequence_write(codec, spec->sbz_init_verbs);
|
||||
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
codec_dbg(codec, "R3DI alt_init");
|
||||
@@ -7182,6 +7252,11 @@ static void ca0132_alt_init(struct hda_codec *codec)
|
||||
snd_hda_sequence_write(codec, spec->chip_init_verbs);
|
||||
snd_hda_codec_write(codec, WIDGET_CHIP_CTRL, 0, 0x6FF, 0xC4);
|
||||
break;
|
||||
case QUIRK_R3D:
|
||||
r3d_pre_dsp_setup(codec);
|
||||
snd_hda_sequence_write(codec, spec->chip_init_verbs);
|
||||
snd_hda_sequence_write(codec, spec->desktop_init_verbs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7218,8 +7293,8 @@ static int ca0132_init(struct hda_codec *codec)
|
||||
spec->dsp_state = DSP_DOWNLOAD_INIT;
|
||||
spec->curr_chip_addx = INVALID_CHIP_ADDRESS;
|
||||
|
||||
if (spec->quirk == QUIRK_SBZ)
|
||||
sbz_region2_startup(codec);
|
||||
if (spec->use_pci_mmio)
|
||||
ca0132_mmio_init(codec);
|
||||
|
||||
snd_hda_power_up_pm(codec);
|
||||
|
||||
@@ -7236,14 +7311,13 @@ static int ca0132_init(struct hda_codec *codec)
|
||||
|
||||
ca0132_refresh_widget_caps(codec);
|
||||
|
||||
if (spec->quirk == QUIRK_SBZ)
|
||||
writew(0x0107, spec->mem_base + 0x320);
|
||||
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_R3DI:
|
||||
r3di_setup_defaults(codec);
|
||||
case QUIRK_R3D:
|
||||
r3d_setup_defaults(codec);
|
||||
break;
|
||||
case QUIRK_SBZ:
|
||||
sbz_setup_defaults(codec);
|
||||
break;
|
||||
default:
|
||||
ca0132_setup_defaults(codec);
|
||||
@@ -7274,20 +7348,12 @@ static int ca0132_init(struct hda_codec *codec)
|
||||
ca0132_gpio_setup(codec);
|
||||
|
||||
snd_hda_sequence_write(codec, spec->spec_init_verbs);
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
sbz_setup_defaults(codec);
|
||||
if (spec->use_alt_functions) {
|
||||
ca0132_alt_select_out(codec);
|
||||
ca0132_alt_select_in(codec);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
ca0132_alt_select_out(codec);
|
||||
ca0132_alt_select_in(codec);
|
||||
break;
|
||||
default:
|
||||
} else {
|
||||
ca0132_select_out(codec);
|
||||
ca0132_select_mic(codec);
|
||||
break;
|
||||
}
|
||||
|
||||
snd_hda_jack_report_sync(codec);
|
||||
@@ -7316,16 +7382,17 @@ static void ca0132_free(struct hda_codec *codec)
|
||||
case QUIRK_SBZ:
|
||||
sbz_exit_chip(codec);
|
||||
break;
|
||||
case QUIRK_R3D:
|
||||
r3d_exit_chip(codec);
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
r3di_gpio_shutdown(codec);
|
||||
snd_hda_sequence_write(codec, spec->base_exit_verbs);
|
||||
ca0132_exit_chip(codec);
|
||||
break;
|
||||
default:
|
||||
snd_hda_sequence_write(codec, spec->base_exit_verbs);
|
||||
ca0132_exit_chip(codec);
|
||||
break;
|
||||
}
|
||||
|
||||
snd_hda_sequence_write(codec, spec->base_exit_verbs);
|
||||
ca0132_exit_chip(codec);
|
||||
|
||||
snd_hda_power_down(codec);
|
||||
if (spec->mem_base)
|
||||
iounmap(spec->mem_base);
|
||||
@@ -7386,8 +7453,15 @@ static void ca0132_config(struct hda_codec *codec)
|
||||
spec->unsol_tag_amic1 = 0x11;
|
||||
break;
|
||||
case QUIRK_SBZ:
|
||||
codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__);
|
||||
snd_hda_apply_pincfgs(codec, sbz_pincfgs);
|
||||
case QUIRK_R3D:
|
||||
if (spec->quirk == QUIRK_SBZ) {
|
||||
codec_dbg(codec, "%s: QUIRK_SBZ applied.\n", __func__);
|
||||
snd_hda_apply_pincfgs(codec, sbz_pincfgs);
|
||||
}
|
||||
if (spec->quirk == QUIRK_R3D) {
|
||||
codec_dbg(codec, "%s: QUIRK_R3D applied.\n", __func__);
|
||||
snd_hda_apply_pincfgs(codec, r3d_pincfgs);
|
||||
}
|
||||
|
||||
spec->num_outputs = 2;
|
||||
spec->out_pins[0] = 0x0B; /* Line out */
|
||||
@@ -7473,8 +7547,8 @@ static int ca0132_prepare_verbs(struct hda_codec *codec)
|
||||
struct ca0132_spec *spec = codec->spec;
|
||||
|
||||
spec->chip_init_verbs = ca0132_init_verbs0;
|
||||
if (spec->quirk == QUIRK_SBZ)
|
||||
spec->sbz_init_verbs = sbz_init_verbs;
|
||||
if (spec->quirk == QUIRK_SBZ || spec->quirk == QUIRK_R3D)
|
||||
spec->desktop_init_verbs = ca0132_init_verbs1;
|
||||
spec->spec_init_verbs = kcalloc(NUM_SPEC_VERBS,
|
||||
sizeof(struct hda_verb),
|
||||
GFP_KERNEL);
|
||||
@@ -7530,25 +7604,19 @@ static int patch_ca0132(struct hda_codec *codec)
|
||||
else
|
||||
spec->quirk = QUIRK_NONE;
|
||||
|
||||
/* Setup BAR Region 2 for Sound Blaster Z */
|
||||
if (spec->quirk == QUIRK_SBZ) {
|
||||
spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
|
||||
if (spec->mem_base == NULL) {
|
||||
codec_warn(codec, "pci_iomap failed!");
|
||||
codec_info(codec, "perhaps this is not an SBZ?");
|
||||
spec->quirk = QUIRK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
spec->dsp_state = DSP_DOWNLOAD_INIT;
|
||||
spec->num_mixers = 1;
|
||||
|
||||
/* Set which mixers each quirk uses. */
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
spec->mixers[0] = sbz_mixer;
|
||||
spec->mixers[0] = desktop_mixer;
|
||||
snd_hda_codec_set_name(codec, "Sound Blaster Z");
|
||||
break;
|
||||
case QUIRK_R3D:
|
||||
spec->mixers[0] = desktop_mixer;
|
||||
snd_hda_codec_set_name(codec, "Recon3D");
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
spec->mixers[0] = r3di_mixer;
|
||||
snd_hda_codec_set_name(codec, "Recon3Di");
|
||||
@@ -7558,19 +7626,34 @@ static int patch_ca0132(struct hda_codec *codec)
|
||||
break;
|
||||
}
|
||||
|
||||
/* Setup whether or not to use alt functions/controls */
|
||||
/* Setup whether or not to use alt functions/controls/pci_mmio */
|
||||
switch (spec->quirk) {
|
||||
case QUIRK_SBZ:
|
||||
case QUIRK_R3D:
|
||||
spec->use_alt_controls = true;
|
||||
spec->use_alt_functions = true;
|
||||
spec->use_pci_mmio = true;
|
||||
break;
|
||||
case QUIRK_R3DI:
|
||||
spec->use_alt_controls = true;
|
||||
spec->use_alt_functions = true;
|
||||
spec->use_pci_mmio = false;
|
||||
break;
|
||||
default:
|
||||
spec->use_alt_controls = false;
|
||||
spec->use_alt_functions = false;
|
||||
spec->use_pci_mmio = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (spec->use_pci_mmio) {
|
||||
spec->mem_base = pci_iomap(codec->bus->pci, 2, 0xC20);
|
||||
if (spec->mem_base == NULL) {
|
||||
codec_warn(codec, "pci_iomap failed! Setting quirk to QUIRK_NONE.");
|
||||
spec->quirk = QUIRK_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
spec->base_init_verbs = ca0132_base_init_verbs;
|
||||
spec->base_exit_verbs = ca0132_base_exit_verbs;
|
||||
|
||||
|
@@ -1096,25 +1096,6 @@ static int cs421x_init(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cs421x_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
struct cs_spec *spec = codec->spec;
|
||||
int err;
|
||||
|
||||
err = snd_hda_gen_build_controls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (spec->gen.autocfg.speaker_outs &&
|
||||
spec->vendor_nid == CS4210_VENDOR_NID) {
|
||||
err = snd_hda_ctl_add(codec, 0,
|
||||
snd_ctl_new1(&cs421x_speaker_boost_ctl, codec));
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fix_volume_caps(struct hda_codec *codec, hda_nid_t dac)
|
||||
{
|
||||
unsigned int caps;
|
||||
@@ -1144,6 +1125,14 @@ static int cs421x_parse_auto_config(struct hda_codec *codec)
|
||||
return err;
|
||||
|
||||
parse_cs421x_digital(codec);
|
||||
|
||||
if (spec->gen.autocfg.speaker_outs &&
|
||||
spec->vendor_nid == CS4210_VENDOR_NID) {
|
||||
if (!snd_hda_gen_add_kctl(&spec->gen, NULL,
|
||||
&cs421x_speaker_boost_ctl))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1175,7 +1164,7 @@ static int cs421x_suspend(struct hda_codec *codec)
|
||||
#endif
|
||||
|
||||
static const struct hda_codec_ops cs421x_patch_ops = {
|
||||
.build_controls = cs421x_build_controls,
|
||||
.build_controls = snd_hda_gen_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cs421x_init,
|
||||
.free = cs_free,
|
||||
|
@@ -37,8 +37,6 @@
|
||||
struct conexant_spec {
|
||||
struct hda_gen_spec gen;
|
||||
|
||||
unsigned int beep_amp;
|
||||
|
||||
/* extra EAPD pins */
|
||||
unsigned int num_eapds;
|
||||
hda_nid_t eapds[4];
|
||||
@@ -62,65 +60,48 @@ struct conexant_spec {
|
||||
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
static inline void set_beep_amp(struct conexant_spec *spec, hda_nid_t nid,
|
||||
int idx, int dir)
|
||||
{
|
||||
spec->gen.beep_nid = nid;
|
||||
spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
|
||||
}
|
||||
/* additional beep mixers; the actual parameters are overwritten at build */
|
||||
/* additional beep mixers; private_value will be overwritten */
|
||||
static const struct snd_kcontrol_new cxt_beep_mixer[] = {
|
||||
HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* create beep controls if needed */
|
||||
static int add_beep_ctls(struct hda_codec *codec)
|
||||
static int set_beep_amp(struct conexant_spec *spec, hda_nid_t nid,
|
||||
int idx, int dir)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
int err;
|
||||
struct snd_kcontrol_new *knew;
|
||||
unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
|
||||
int i;
|
||||
|
||||
if (spec->beep_amp) {
|
||||
const struct snd_kcontrol_new *knew;
|
||||
for (knew = cxt_beep_mixer; knew->name; knew++) {
|
||||
struct snd_kcontrol *kctl;
|
||||
kctl = snd_ctl_new1(knew, codec);
|
||||
if (!kctl)
|
||||
return -ENOMEM;
|
||||
kctl->private_value = spec->beep_amp;
|
||||
err = snd_hda_ctl_add(codec, 0, kctl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
spec->gen.beep_nid = nid;
|
||||
for (i = 0; i < ARRAY_SIZE(cxt_beep_mixer); i++) {
|
||||
knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
|
||||
&cxt_beep_mixer[i]);
|
||||
if (!knew)
|
||||
return -ENOMEM;
|
||||
knew->private_value = beep_amp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define set_beep_amp(spec, nid, idx, dir) /* NOP */
|
||||
#define add_beep_ctls(codec) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Automatic parser for CX20641 & co
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
static void cx_auto_parse_beep(struct hda_codec *codec)
|
||||
static int cx_auto_parse_beep(struct hda_codec *codec)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
hda_nid_t nid;
|
||||
|
||||
for_each_hda_codec_node(nid, codec)
|
||||
if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
|
||||
set_beep_amp(spec, nid, 0, HDA_OUTPUT);
|
||||
break;
|
||||
}
|
||||
if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP)
|
||||
return set_beep_amp(spec, nid, 0, HDA_OUTPUT);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define cx_auto_parse_beep(codec)
|
||||
#define cx_auto_parse_beep(codec) 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Automatic parser for CX20641 & co
|
||||
*/
|
||||
|
||||
/* parse EAPDs */
|
||||
static void cx_auto_parse_eapd(struct hda_codec *codec)
|
||||
{
|
||||
@@ -179,21 +160,6 @@ static void cx_auto_vmaster_hook_mute_led(void *private_data, int enabled)
|
||||
enabled ? 0x00 : 0x02);
|
||||
}
|
||||
|
||||
static int cx_auto_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = snd_hda_gen_build_controls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = add_beep_ctls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cx_auto_init(struct hda_codec *codec)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
@@ -236,7 +202,7 @@ static void cx_auto_free(struct hda_codec *codec)
|
||||
}
|
||||
|
||||
static const struct hda_codec_ops cx_auto_patch_ops = {
|
||||
.build_controls = cx_auto_build_controls,
|
||||
.build_controls = snd_hda_gen_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = cx_auto_init,
|
||||
.reboot_notify = cx_auto_reboot_notify,
|
||||
@@ -345,6 +311,7 @@ static void cxt_fixup_headphone_mic(struct hda_codec *codec,
|
||||
snd_hdac_regmap_add_vendor_verb(&codec->core, 0x410);
|
||||
break;
|
||||
case HDA_FIXUP_ACT_PROBE:
|
||||
WARN_ON(spec->gen.cap_sync_hook);
|
||||
spec->gen.cap_sync_hook = cxt_update_headset_mode_hook;
|
||||
spec->gen.automute_hook = cxt_update_headset_mode;
|
||||
break;
|
||||
@@ -376,7 +343,7 @@ static void cxt_fixup_headset_mic(struct hda_codec *codec,
|
||||
* control. */
|
||||
|
||||
#define update_mic_pin(codec, nid, val) \
|
||||
snd_hda_codec_update_cache(codec, nid, 0, \
|
||||
snd_hda_codec_write_cache(codec, nid, 0, \
|
||||
AC_VERB_SET_PIN_WIDGET_CONTROL, val)
|
||||
|
||||
static const struct hda_input_mux olpc_xo_dc_bias = {
|
||||
@@ -697,16 +664,12 @@ static void cxt_fixup_gpio_mute_hook(void *private_data, int enabled)
|
||||
}
|
||||
|
||||
/* turn on/off mic-mute LED via GPIO per capture hook */
|
||||
static void cxt_fixup_gpio_mic_mute_hook(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static void cxt_gpio_micmute_update(struct hda_codec *codec)
|
||||
{
|
||||
struct conexant_spec *spec = codec->spec;
|
||||
|
||||
if (ucontrol)
|
||||
cxt_update_gpio_led(codec, spec->gpio_mic_led_mask,
|
||||
ucontrol->value.integer.value[0] ||
|
||||
ucontrol->value.integer.value[1]);
|
||||
cxt_update_gpio_led(codec, spec->gpio_mic_led_mask,
|
||||
spec->gen.micmute_led.led_value);
|
||||
}
|
||||
|
||||
|
||||
@@ -723,11 +686,11 @@ static void cxt_fixup_mute_led_gpio(struct hda_codec *codec,
|
||||
|
||||
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
|
||||
spec->gen.vmaster_mute.hook = cxt_fixup_gpio_mute_hook;
|
||||
spec->gen.cap_sync_hook = cxt_fixup_gpio_mic_mute_hook;
|
||||
spec->gpio_led = 0;
|
||||
spec->mute_led_polarity = 0;
|
||||
spec->gpio_mute_led_mask = 0x01;
|
||||
spec->gpio_mic_led_mask = 0x02;
|
||||
snd_hda_gen_add_micmute_led(codec, cxt_gpio_micmute_update);
|
||||
}
|
||||
snd_hda_add_verbs(codec, gpio_init);
|
||||
if (spec->gpio_led)
|
||||
@@ -1039,7 +1002,6 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
||||
codec->spec = spec;
|
||||
codec->patch_ops = cx_auto_patch_ops;
|
||||
|
||||
cx_auto_parse_beep(codec);
|
||||
cx_auto_parse_eapd(codec);
|
||||
spec->gen.own_eapd_ctl = 1;
|
||||
if (spec->dynamic_eapd)
|
||||
@@ -1099,6 +1061,10 @@ static int patch_conexant_auto(struct hda_codec *codec)
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
err = cx_auto_parse_beep(codec);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* Some laptops with Conexant chips show stalls in S3 resume,
|
||||
* which falls into the single-cmd mode.
|
||||
* Better to make reset, then.
|
||||
|
@@ -177,13 +177,13 @@ struct hdmi_spec {
|
||||
|
||||
/* i915/powerwell (Haswell+/Valleyview+) specific */
|
||||
bool use_acomp_notifier; /* use i915 eld_notify callback for hotplug */
|
||||
struct i915_audio_component_audio_ops i915_audio_ops;
|
||||
struct drm_audio_component_audio_ops drm_audio_ops;
|
||||
|
||||
struct hdac_chmap chmap;
|
||||
hda_nid_t vendor_nid;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_HDA_I915
|
||||
#ifdef CONFIG_SND_HDA_COMPONENT
|
||||
static inline bool codec_has_acomp(struct hda_codec *codec)
|
||||
{
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
@@ -339,13 +339,13 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
|
||||
if (!per_pin) {
|
||||
/* no pin is bound to the pcm */
|
||||
uinfo->count = 0;
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return 0;
|
||||
goto unlock;
|
||||
}
|
||||
eld = &per_pin->sink_eld;
|
||||
uinfo->count = eld->eld_valid ? eld->eld_size : 0;
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -357,6 +357,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
struct hdmi_spec_per_pin *per_pin;
|
||||
struct hdmi_eld *eld;
|
||||
int pcm_idx;
|
||||
int err = 0;
|
||||
|
||||
pcm_idx = kcontrol->private_value;
|
||||
mutex_lock(&spec->pcm_lock);
|
||||
@@ -365,16 +366,15 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
/* no pin is bound to the pcm */
|
||||
memset(ucontrol->value.bytes.data, 0,
|
||||
ARRAY_SIZE(ucontrol->value.bytes.data));
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return 0;
|
||||
goto unlock;
|
||||
}
|
||||
eld = &per_pin->sink_eld;
|
||||
|
||||
eld = &per_pin->sink_eld;
|
||||
if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
|
||||
eld->eld_size > ELD_MAX_SIZE) {
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
snd_BUG();
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
memset(ucontrol->value.bytes.data, 0,
|
||||
@@ -382,9 +382,10 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
|
||||
if (eld->eld_valid)
|
||||
memcpy(ucontrol->value.bytes.data, eld->eld_buffer,
|
||||
eld->eld_size);
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
|
||||
return 0;
|
||||
unlock:
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new eld_bytes_ctl = {
|
||||
@@ -1209,8 +1210,8 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
pin_idx = hinfo_to_pin_index(codec, hinfo);
|
||||
if (!spec->dyn_pcm_assign) {
|
||||
if (snd_BUG_ON(pin_idx < 0)) {
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
} else {
|
||||
/* no pin is assigned to the PCM
|
||||
@@ -1218,16 +1219,13 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
*/
|
||||
if (pin_idx < 0) {
|
||||
err = hdmi_pcm_open_no_pin(hinfo, codec, substream);
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return err;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
err = hdmi_choose_cvt(codec, pin_idx, &cvt_idx);
|
||||
if (err < 0) {
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
per_cvt = get_cvt(spec, cvt_idx);
|
||||
/* Claim converter */
|
||||
@@ -1264,12 +1262,11 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
per_cvt->assigned = 0;
|
||||
hinfo->nid = 0;
|
||||
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return -ENODEV;
|
||||
err = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
/* Store the updated parameters */
|
||||
runtime->hw.channels_min = hinfo->channels_min;
|
||||
runtime->hw.channels_max = hinfo->channels_max;
|
||||
@@ -1278,7 +1275,9 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
|
||||
|
||||
snd_pcm_hw_constraint_step(substream->runtime, 0,
|
||||
SNDRV_PCM_HW_PARAM_CHANNELS, 2);
|
||||
return 0;
|
||||
unlock:
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1867,7 +1866,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
struct snd_pcm_runtime *runtime = substream->runtime;
|
||||
bool non_pcm;
|
||||
int pinctl;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
mutex_lock(&spec->pcm_lock);
|
||||
pin_idx = hinfo_to_pin_index(codec, hinfo);
|
||||
@@ -1879,13 +1878,12 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
pin_cvt_fixup(codec, NULL, cvt_nid);
|
||||
snd_hda_codec_setup_stream(codec, cvt_nid,
|
||||
stream_tag, 0, format);
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return 0;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (snd_BUG_ON(pin_idx < 0)) {
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
per_pin = get_pin(spec, pin_idx);
|
||||
pin_nid = per_pin->pin_nid;
|
||||
@@ -1924,6 +1922,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
|
||||
/* snd_hda_set_dev_select() has been called before */
|
||||
err = spec->ops.setup_stream(codec, cvt_nid, pin_nid,
|
||||
stream_tag, format);
|
||||
unlock:
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return err;
|
||||
}
|
||||
@@ -1945,6 +1944,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
|
||||
struct hdmi_spec_per_cvt *per_cvt;
|
||||
struct hdmi_spec_per_pin *per_pin;
|
||||
int pinctl;
|
||||
int err = 0;
|
||||
|
||||
if (hinfo->nid) {
|
||||
pcm_idx = hinfo_to_pcm_index(codec, hinfo);
|
||||
@@ -1963,14 +1963,12 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
|
||||
snd_hda_spdif_ctls_unassign(codec, pcm_idx);
|
||||
clear_bit(pcm_idx, &spec->pcm_in_use);
|
||||
pin_idx = hinfo_to_pin_index(codec, hinfo);
|
||||
if (spec->dyn_pcm_assign && pin_idx < 0) {
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return 0;
|
||||
}
|
||||
if (spec->dyn_pcm_assign && pin_idx < 0)
|
||||
goto unlock;
|
||||
|
||||
if (snd_BUG_ON(pin_idx < 0)) {
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
per_pin = get_pin(spec, pin_idx);
|
||||
|
||||
@@ -1989,10 +1987,11 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
|
||||
per_pin->setup = false;
|
||||
per_pin->channels = 0;
|
||||
mutex_unlock(&per_pin->lock);
|
||||
unlock:
|
||||
mutex_unlock(&spec->pcm_lock);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct hda_pcm_ops generic_ops = {
|
||||
@@ -2288,7 +2287,7 @@ static void generic_hdmi_free(struct hda_codec *codec)
|
||||
int pin_idx, pcm_idx;
|
||||
|
||||
if (codec_has_acomp(codec))
|
||||
snd_hdac_i915_register_notifier(NULL);
|
||||
snd_hdac_acomp_register_notifier(&codec->bus->core, NULL);
|
||||
|
||||
for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
|
||||
struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
|
||||
@@ -2471,6 +2470,38 @@ static void haswell_set_power_state(struct hda_codec *codec, hda_nid_t fg,
|
||||
snd_hda_codec_set_power_to_all(codec, fg, power_state);
|
||||
}
|
||||
|
||||
/* There is a fixed mapping between audio pin node and display port.
|
||||
* on SNB, IVY, HSW, BSW, SKL, BXT, KBL:
|
||||
* Pin Widget 5 - PORT B (port = 1 in i915 driver)
|
||||
* Pin Widget 6 - PORT C (port = 2 in i915 driver)
|
||||
* Pin Widget 7 - PORT D (port = 3 in i915 driver)
|
||||
*
|
||||
* on VLV, ILK:
|
||||
* Pin Widget 4 - PORT B (port = 1 in i915 driver)
|
||||
* Pin Widget 5 - PORT C (port = 2 in i915 driver)
|
||||
* Pin Widget 6 - PORT D (port = 3 in i915 driver)
|
||||
*/
|
||||
static int intel_base_nid(struct hda_codec *codec)
|
||||
{
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x80860054: /* ILK */
|
||||
case 0x80862804: /* ILK */
|
||||
case 0x80862882: /* VLV */
|
||||
return 4;
|
||||
default:
|
||||
return 5;
|
||||
}
|
||||
}
|
||||
|
||||
static int intel_pin2port(void *audio_ptr, int pin_nid)
|
||||
{
|
||||
int base_nid = intel_base_nid(audio_ptr);
|
||||
|
||||
if (WARN_ON(pin_nid < base_nid || pin_nid >= base_nid + 3))
|
||||
return -1;
|
||||
return pin_nid - base_nid + 1; /* intel port is 1-based */
|
||||
}
|
||||
|
||||
static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
|
||||
{
|
||||
struct hda_codec *codec = audio_ptr;
|
||||
@@ -2481,16 +2512,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
|
||||
if (port < 1 || port > 3)
|
||||
return;
|
||||
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x80860054: /* ILK */
|
||||
case 0x80862804: /* ILK */
|
||||
case 0x80862882: /* VLV */
|
||||
pin_nid = port + 0x03;
|
||||
break;
|
||||
default:
|
||||
pin_nid = port + 0x04;
|
||||
break;
|
||||
}
|
||||
pin_nid = port + intel_base_nid(codec) - 1; /* intel port is 1-based */
|
||||
|
||||
/* skip notification during system suspend (but not in runtime PM);
|
||||
* the state will be updated at resume
|
||||
@@ -2498,7 +2520,7 @@ static void intel_pin_eld_notify(void *audio_ptr, int port, int pipe)
|
||||
if (snd_power_get_state(codec->card) != SNDRV_CTL_POWER_D0)
|
||||
return;
|
||||
/* ditto during suspend/resume process itself */
|
||||
if (atomic_read(&(codec)->core.in_pm))
|
||||
if (snd_hdac_is_in_pm(&codec->core))
|
||||
return;
|
||||
|
||||
snd_hdac_i915_set_bclk(&codec->bus->core);
|
||||
@@ -2511,14 +2533,16 @@ static void register_i915_notifier(struct hda_codec *codec)
|
||||
struct hdmi_spec *spec = codec->spec;
|
||||
|
||||
spec->use_acomp_notifier = true;
|
||||
spec->i915_audio_ops.audio_ptr = codec;
|
||||
spec->drm_audio_ops.audio_ptr = codec;
|
||||
/* intel_audio_codec_enable() or intel_audio_codec_disable()
|
||||
* will call pin_eld_notify with using audio_ptr pointer
|
||||
* We need make sure audio_ptr is really setup
|
||||
*/
|
||||
wmb();
|
||||
spec->i915_audio_ops.pin_eld_notify = intel_pin_eld_notify;
|
||||
snd_hdac_i915_register_notifier(&spec->i915_audio_ops);
|
||||
spec->drm_audio_ops.pin2port = intel_pin2port;
|
||||
spec->drm_audio_ops.pin_eld_notify = intel_pin_eld_notify;
|
||||
snd_hdac_acomp_register_notifier(&codec->bus->core,
|
||||
&spec->drm_audio_ops);
|
||||
}
|
||||
|
||||
/* setup_stream ops override for HSW+ */
|
||||
@@ -2551,6 +2575,8 @@ static int alloc_intel_hdmi(struct hda_codec *codec)
|
||||
/* requires i915 binding */
|
||||
if (!codec->bus->core.audio_component) {
|
||||
codec_info(codec, "No i915 binding for Intel HDMI/DP codec\n");
|
||||
/* set probe_id here to prevent generic fallback binding */
|
||||
codec->probe_id = HDA_CODEC_ID_SKIP_PROBE;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
@@ -332,33 +332,15 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask,
|
||||
}
|
||||
|
||||
/* hook for controlling mic-mute LED GPIO */
|
||||
static void stac_capture_led_hook(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static void stac_capture_led_update(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
unsigned int mask;
|
||||
bool cur_mute, prev_mute;
|
||||
|
||||
if (!kcontrol || !ucontrol)
|
||||
return;
|
||||
|
||||
mask = 1U << snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
|
||||
prev_mute = !spec->mic_enabled;
|
||||
if (ucontrol->value.integer.value[0] ||
|
||||
ucontrol->value.integer.value[1])
|
||||
spec->mic_enabled |= mask;
|
||||
if (spec->gen.micmute_led.led_value)
|
||||
spec->gpio_data |= spec->mic_mute_led_gpio;
|
||||
else
|
||||
spec->mic_enabled &= ~mask;
|
||||
cur_mute = !spec->mic_enabled;
|
||||
if (cur_mute != prev_mute) {
|
||||
if (cur_mute)
|
||||
spec->gpio_data |= spec->mic_mute_led_gpio;
|
||||
else
|
||||
spec->gpio_data &= ~spec->mic_mute_led_gpio;
|
||||
stac_gpio_set(codec, spec->gpio_mask,
|
||||
spec->gpio_dir, spec->gpio_data);
|
||||
}
|
||||
spec->gpio_data &= ~spec->mic_mute_led_gpio;
|
||||
stac_gpio_set(codec, spec->gpio_mask, spec->gpio_dir, spec->gpio_data);
|
||||
}
|
||||
|
||||
static int stac_vrefout_set(struct hda_codec *codec,
|
||||
@@ -4656,8 +4638,7 @@ static void stac_setup_gpio(struct hda_codec *codec)
|
||||
spec->gpio_dir |= spec->mic_mute_led_gpio;
|
||||
spec->mic_enabled = 0;
|
||||
spec->gpio_data |= spec->mic_mute_led_gpio;
|
||||
|
||||
spec->gen.cap_sync_hook = stac_capture_led_hook;
|
||||
snd_hda_gen_add_micmute_led(codec, stac_capture_led_update);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -90,13 +90,6 @@ enum VIA_HDA_CODEC {
|
||||
struct via_spec {
|
||||
struct hda_gen_spec gen;
|
||||
|
||||
/* codec parameterization */
|
||||
const struct snd_kcontrol_new *mixers[6];
|
||||
unsigned int num_mixers;
|
||||
|
||||
const struct hda_verb *init_verbs[5];
|
||||
unsigned int num_iverbs;
|
||||
|
||||
/* HP mode source */
|
||||
unsigned int dmic_enabled;
|
||||
enum VIA_HDA_CODEC codec_type;
|
||||
@@ -107,8 +100,6 @@ struct via_spec {
|
||||
/* work to check hp jack state */
|
||||
int hp_work_active;
|
||||
int vt1708_jack_detect;
|
||||
|
||||
unsigned int beep_amp;
|
||||
};
|
||||
|
||||
static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec);
|
||||
@@ -262,69 +253,51 @@ static int via_pin_power_ctl_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new via_pin_power_ctl_enum[] = {
|
||||
{
|
||||
static const struct snd_kcontrol_new via_pin_power_ctl_enum = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Dynamic Power-Control",
|
||||
.info = via_pin_power_ctl_info,
|
||||
.get = via_pin_power_ctl_get,
|
||||
.put = via_pin_power_ctl_put,
|
||||
},
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
#ifdef CONFIG_SND_HDA_INPUT_BEEP
|
||||
static inline void set_beep_amp(struct via_spec *spec, hda_nid_t nid,
|
||||
int idx, int dir)
|
||||
{
|
||||
spec->gen.beep_nid = nid;
|
||||
spec->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
|
||||
}
|
||||
|
||||
/* additional beep mixers; the actual parameters are overwritten at build */
|
||||
static const struct snd_kcontrol_new cxt_beep_mixer[] = {
|
||||
static const struct snd_kcontrol_new via_beep_mixer[] = {
|
||||
HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT),
|
||||
HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
|
||||
/* create beep controls if needed */
|
||||
static int add_beep_ctls(struct hda_codec *codec)
|
||||
static int set_beep_amp(struct via_spec *spec, hda_nid_t nid,
|
||||
int idx, int dir)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
int err;
|
||||
struct snd_kcontrol_new *knew;
|
||||
unsigned int beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir);
|
||||
int i;
|
||||
|
||||
if (spec->beep_amp) {
|
||||
const struct snd_kcontrol_new *knew;
|
||||
for (knew = cxt_beep_mixer; knew->name; knew++) {
|
||||
struct snd_kcontrol *kctl;
|
||||
kctl = snd_ctl_new1(knew, codec);
|
||||
if (!kctl)
|
||||
return -ENOMEM;
|
||||
kctl->private_value = spec->beep_amp;
|
||||
err = snd_hda_ctl_add(codec, 0, kctl);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
spec->gen.beep_nid = nid;
|
||||
for (i = 0; i < ARRAY_SIZE(via_beep_mixer); i++) {
|
||||
knew = snd_hda_gen_add_kctl(&spec->gen, NULL,
|
||||
&via_beep_mixer[i]);
|
||||
if (!knew)
|
||||
return -ENOMEM;
|
||||
knew->private_value = beep_amp;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void auto_parse_beep(struct hda_codec *codec)
|
||||
static int auto_parse_beep(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
hda_nid_t nid;
|
||||
|
||||
for_each_hda_codec_node(nid, codec)
|
||||
if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP) {
|
||||
set_beep_amp(spec, nid, 0, HDA_OUTPUT);
|
||||
break;
|
||||
}
|
||||
if (get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_BEEP)
|
||||
return set_beep_amp(spec, nid, 0, HDA_OUTPUT);
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
#define set_beep_amp(spec, nid, idx, dir) /* NOP */
|
||||
#define add_beep_ctls(codec) 0
|
||||
#define auto_parse_beep(codec)
|
||||
#define auto_parse_beep(codec) 0
|
||||
#endif
|
||||
|
||||
/* check AA path's mute status */
|
||||
@@ -403,30 +376,6 @@ static void analog_low_current_mode(struct hda_codec *codec)
|
||||
return __analog_low_current_mode(codec, false);
|
||||
}
|
||||
|
||||
static int via_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
int err, i;
|
||||
|
||||
err = snd_hda_gen_build_controls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = add_beep_ctls(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
spec->mixers[spec->num_mixers++] = via_pin_power_ctl_enum;
|
||||
|
||||
for (i = 0; i < spec->num_mixers; i++) {
|
||||
err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void via_playback_pcm_hook(struct hda_pcm_stream *hinfo,
|
||||
struct hda_codec *codec,
|
||||
struct snd_pcm_substream *substream,
|
||||
@@ -481,7 +430,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid)
|
||||
static int via_init(struct hda_codec *codec);
|
||||
|
||||
static const struct hda_codec_ops via_patch_ops = {
|
||||
.build_controls = via_build_controls,
|
||||
.build_controls = snd_hda_gen_build_controls,
|
||||
.build_pcms = snd_hda_gen_build_pcms,
|
||||
.init = via_init,
|
||||
.free = via_free,
|
||||
@@ -545,16 +494,13 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new vt1708_jack_detect_ctl[] = {
|
||||
{
|
||||
static const struct snd_kcontrol_new vt1708_jack_detect_ctl = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Jack Detect",
|
||||
.count = 1,
|
||||
.info = snd_ctl_boolean_mono_info,
|
||||
.get = vt1708_jack_detect_get,
|
||||
.put = vt1708_jack_detect_put,
|
||||
},
|
||||
{} /* terminator */
|
||||
};
|
||||
|
||||
static const struct badness_table via_main_out_badness = {
|
||||
@@ -586,12 +532,17 @@ static int via_parse_auto_config(struct hda_codec *codec)
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
auto_parse_beep(codec);
|
||||
|
||||
err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = auto_parse_beep(codec);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &via_pin_power_ctl_enum))
|
||||
return -ENOMEM;
|
||||
|
||||
/* disable widget PM at start for compatibility */
|
||||
codec->power_save_node = 0;
|
||||
spec->gen.power_down_unused = 0;
|
||||
@@ -600,12 +551,6 @@ static int via_parse_auto_config(struct hda_codec *codec)
|
||||
|
||||
static int via_init(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < spec->num_iverbs; i++)
|
||||
snd_hda_sequence_write(codec, spec->init_verbs[i]);
|
||||
|
||||
/* init power states */
|
||||
__analog_low_current_mode(codec, true);
|
||||
|
||||
@@ -623,7 +568,7 @@ static int vt1708_build_controls(struct hda_codec *codec)
|
||||
int err;
|
||||
int old_interval = codec->jackpoll_interval;
|
||||
codec->jackpoll_interval = msecs_to_jiffies(100);
|
||||
err = via_build_controls(codec);
|
||||
err = snd_hda_gen_build_controls(codec);
|
||||
codec->jackpoll_interval = old_interval;
|
||||
return err;
|
||||
}
|
||||
@@ -684,22 +629,29 @@ static int patch_vt1708(struct hda_codec *codec)
|
||||
vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID);
|
||||
vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID);
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt1708_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* add jack detect on/off control */
|
||||
spec->mixers[spec->num_mixers++] = vt1708_jack_detect_ctl;
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1708_init_verbs;
|
||||
if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1708_jack_detect_ctl)) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* clear jackpoll_interval again; it's set dynamically */
|
||||
codec->jackpoll_interval = 0;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int patch_vt1709(struct hda_codec *codec)
|
||||
@@ -715,12 +667,14 @@ static int patch_vt1709(struct hda_codec *codec)
|
||||
spec->gen.mixer_nid = 0x18;
|
||||
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int patch_vt1708S(struct hda_codec *codec);
|
||||
@@ -741,12 +695,14 @@ static int patch_vt1708B(struct hda_codec *codec)
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Patch for VT1708S */
|
||||
@@ -791,16 +747,20 @@ static int patch_vt1708S(struct hda_codec *codec)
|
||||
if (codec->core.vendor_id == 0x11064397)
|
||||
snd_hda_codec_set_name(codec, "VT1705");
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt1708S_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1708S_init_verbs;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Patch for VT1702 */
|
||||
@@ -832,16 +792,20 @@ static int patch_vt1702(struct hda_codec *codec)
|
||||
(0x5 << AC_AMPCAP_STEP_SIZE_SHIFT) |
|
||||
(1 << AC_AMPCAP_MUTE_SHIFT));
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt1702_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1702_init_verbs;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Patch for VT1718S */
|
||||
@@ -904,16 +868,20 @@ static int patch_vt1718S(struct hda_codec *codec)
|
||||
override_mic_boost(codec, 0x29, 0, 3, 40);
|
||||
add_secret_dac_path(codec);
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt1718S_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1718S_init_verbs;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Patch for VT1716S */
|
||||
@@ -955,9 +923,9 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
|
||||
HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT),
|
||||
{
|
||||
static const struct snd_kcontrol_new vt1716s_dmic_mixer_vol =
|
||||
HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT);
|
||||
static const struct snd_kcontrol_new vt1716s_dmic_mixer_sw = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Digital Mic Capture Switch",
|
||||
.subdevice = HDA_SUBDEV_NID_FLAG | 0x26,
|
||||
@@ -965,16 +933,12 @@ static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = {
|
||||
.info = vt1716s_dmic_info,
|
||||
.get = vt1716s_dmic_get,
|
||||
.put = vt1716s_dmic_put,
|
||||
},
|
||||
{} /* end */
|
||||
};
|
||||
|
||||
|
||||
/* mono-out mixer elements */
|
||||
static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = {
|
||||
HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT),
|
||||
{ } /* end */
|
||||
};
|
||||
static const struct snd_kcontrol_new vt1716S_mono_out_mixer =
|
||||
HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT);
|
||||
|
||||
static const struct hda_verb vt1716S_init_verbs[] = {
|
||||
/* Enable Boost Volume backdoor */
|
||||
@@ -1000,19 +964,27 @@ static int patch_vt1716S(struct hda_codec *codec)
|
||||
override_mic_boost(codec, 0x1a, 0, 3, 40);
|
||||
override_mic_boost(codec, 0x1e, 0, 3, 40);
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt1716S_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716s_dmic_mixer_vol) ||
|
||||
!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716s_dmic_mixer_sw) ||
|
||||
!snd_hda_gen_add_kctl(&spec->gen, NULL, &vt1716S_mono_out_mixer)) {
|
||||
err = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1716S_init_verbs;
|
||||
|
||||
spec->mixers[spec->num_mixers++] = vt1716s_dmic_mixer;
|
||||
spec->mixers[spec->num_mixers++] = vt1716S_mono_out_mixer;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* for vt2002P */
|
||||
@@ -1107,19 +1079,23 @@ static int patch_vt2002P(struct hda_codec *codec)
|
||||
snd_hda_pick_fixup(codec, NULL, vt2002p_fixups, via_fixups);
|
||||
snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
|
||||
|
||||
if (spec->codec_type == VT1802)
|
||||
err = snd_hda_add_verbs(codec, vt1802_init_verbs);
|
||||
else
|
||||
err = snd_hda_add_verbs(codec, vt2002P_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
if (spec->codec_type == VT1802)
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1802_init_verbs;
|
||||
else
|
||||
spec->init_verbs[spec->num_iverbs++] = vt2002P_init_verbs;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* for vt1812 */
|
||||
@@ -1148,16 +1124,20 @@ static int patch_vt1812(struct hda_codec *codec)
|
||||
override_mic_boost(codec, 0x29, 0, 3, 40);
|
||||
add_secret_dac_path(codec);
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt1812_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt1812_init_verbs;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* patch for vt3476 */
|
||||
@@ -1185,16 +1165,20 @@ static int patch_vt3476(struct hda_codec *codec)
|
||||
spec->gen.mixer_nid = 0x3f;
|
||||
add_secret_dac_path(codec);
|
||||
|
||||
err = snd_hda_add_verbs(codec, vt3476_init_verbs);
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
/* automatic parse from the BIOS config */
|
||||
err = via_parse_auto_config(codec);
|
||||
if (err < 0) {
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
spec->init_verbs[spec->num_iverbs++] = vt3476_init_verbs;
|
||||
if (err < 0)
|
||||
goto error;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
via_free(codec);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -27,17 +27,11 @@ static void update_tpacpi_mute_led(void *private_data, int enabled)
|
||||
led_set_func(TPACPI_LED_MUTE, !enabled);
|
||||
}
|
||||
|
||||
static void update_tpacpi_micmute_led(struct hda_codec *codec,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
static void update_tpacpi_micmute(struct hda_codec *codec)
|
||||
{
|
||||
if (!ucontrol || !led_set_func)
|
||||
return;
|
||||
if (strcmp("Capture Switch", ucontrol->id.name) == 0 && ucontrol->id.index == 0) {
|
||||
/* TODO: How do I verify if it's a mono or stereo here? */
|
||||
bool val = ucontrol->value.integer.value[0] || ucontrol->value.integer.value[1];
|
||||
led_set_func(TPACPI_LED_MICMUTE, !val);
|
||||
}
|
||||
struct hda_gen_spec *spec = codec->spec;
|
||||
|
||||
led_set_func(TPACPI_LED_MICMUTE, spec->micmute_led.led_value);
|
||||
}
|
||||
|
||||
static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
@@ -63,15 +57,10 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
|
||||
spec->vmaster_mute.hook = update_tpacpi_mute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) {
|
||||
if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch)
|
||||
codec_dbg(codec,
|
||||
"Skipping micmute LED control due to several ADCs");
|
||||
else {
|
||||
spec->cap_sync_hook = update_tpacpi_micmute_led;
|
||||
removefunc = false;
|
||||
}
|
||||
}
|
||||
if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0 &&
|
||||
snd_hda_gen_add_micmute_led(codec,
|
||||
update_tpacpi_micmute) > 0)
|
||||
removefunc = false;
|
||||
}
|
||||
|
||||
if (led_set_func && (action == HDA_FIXUP_ACT_FREE || removefunc)) {
|
||||
|
@@ -179,18 +179,6 @@ int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init alsa_ice1712_akm4xxx_module_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit alsa_ice1712_akm4xxx_module_exit(void)
|
||||
{
|
||||
}
|
||||
|
||||
module_init(alsa_ice1712_akm4xxx_module_init)
|
||||
module_exit(alsa_ice1712_akm4xxx_module_exit)
|
||||
|
||||
EXPORT_SYMBOL(snd_ice1712_akm4xxx_init);
|
||||
EXPORT_SYMBOL(snd_ice1712_akm4xxx_free);
|
||||
EXPORT_SYMBOL(snd_ice1712_akm4xxx_build_controls);
|
||||
|
@@ -314,26 +314,7 @@ static struct snd_kcontrol_new prodigy_hd2_controls[] = {
|
||||
|
||||
/* --------------- */
|
||||
|
||||
/*
|
||||
* Logarithmic volume values for WM87*6
|
||||
* Computed as 20 * Log10(255 / x)
|
||||
*/
|
||||
static const unsigned char wm_vol[256] = {
|
||||
127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23,
|
||||
23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17,
|
||||
17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13,
|
||||
13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||
11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
#define WM_VOL_MAX (sizeof(wm_vol) - 1)
|
||||
#define WM_VOL_MAX 255
|
||||
#define WM_VOL_MUTE 0x8000
|
||||
|
||||
|
||||
|
@@ -351,7 +351,7 @@ enum {
|
||||
struct ichdev {
|
||||
unsigned int ichd; /* ich device number */
|
||||
unsigned long reg_offset; /* offset to bmaddr */
|
||||
u32 *bdbar; /* CPU address (32bit) */
|
||||
__le32 *bdbar; /* CPU address (32bit) */
|
||||
unsigned int bdbar_addr; /* PCI bus address (32bit) */
|
||||
struct snd_pcm_substream *substream;
|
||||
unsigned int physbuf; /* physical address (32bit) */
|
||||
@@ -677,7 +677,7 @@ static void snd_intel8x0_ali_codec_write(struct snd_ac97 *ac97, unsigned short r
|
||||
static void snd_intel8x0_setup_periods(struct intel8x0 *chip, struct ichdev *ichdev)
|
||||
{
|
||||
int idx;
|
||||
u32 *bdbar = ichdev->bdbar;
|
||||
__le32 *bdbar = ichdev->bdbar;
|
||||
unsigned long port = ichdev->reg_offset;
|
||||
|
||||
iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
|
||||
@@ -3143,7 +3143,7 @@ static int snd_intel8x0_create(struct snd_card *card,
|
||||
int_sta_masks = 0;
|
||||
for (i = 0; i < chip->bdbars_count; i++) {
|
||||
ichdev = &chip->ichd[i];
|
||||
ichdev->bdbar = ((u32 *)chip->bdbars.area) +
|
||||
ichdev->bdbar = ((__le32 *)chip->bdbars.area) +
|
||||
(i * ICH_MAX_FRAGS * 2);
|
||||
ichdev->bdbar_addr = chip->bdbars.addr +
|
||||
(i * sizeof(u32) * ICH_MAX_FRAGS * 2);
|
||||
|
@@ -168,7 +168,7 @@ enum { ALID_MDMIN, ALID_MDMOUT, ALID_MDMLAST = ALID_MDMOUT };
|
||||
struct ichdev {
|
||||
unsigned int ichd; /* ich device number */
|
||||
unsigned long reg_offset; /* offset to bmaddr */
|
||||
u32 *bdbar; /* CPU address (32bit) */
|
||||
__le32 *bdbar; /* CPU address (32bit) */
|
||||
unsigned int bdbar_addr; /* PCI bus address (32bit) */
|
||||
struct snd_pcm_substream *substream;
|
||||
unsigned int physbuf; /* physical address (32bit) */
|
||||
@@ -395,7 +395,7 @@ static unsigned short snd_intel8x0m_codec_read(struct snd_ac97 *ac97,
|
||||
static void snd_intel8x0m_setup_periods(struct intel8x0m *chip, struct ichdev *ichdev)
|
||||
{
|
||||
int idx;
|
||||
u32 *bdbar = ichdev->bdbar;
|
||||
__le32 *bdbar = ichdev->bdbar;
|
||||
unsigned long port = ichdev->reg_offset;
|
||||
|
||||
iputdword(chip, port + ICH_REG_OFF_BDBAR, ichdev->bdbar_addr);
|
||||
@@ -1217,7 +1217,7 @@ static int snd_intel8x0m_create(struct snd_card *card,
|
||||
int_sta_masks = 0;
|
||||
for (i = 0; i < chip->bdbars_count; i++) {
|
||||
ichdev = &chip->ichd[i];
|
||||
ichdev->bdbar = ((u32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
|
||||
ichdev->bdbar = ((__le32 *)chip->bdbars.area) + (i * ICH_MAX_FRAGS * 2);
|
||||
ichdev->bdbar_addr = chip->bdbars.addr + (i * sizeof(u32) * ICH_MAX_FRAGS * 2);
|
||||
int_sta_masks |= ichdev->int_sta_mask;
|
||||
}
|
||||
|
@@ -1326,7 +1326,7 @@ static int snd_korg1212_copy_to(struct snd_pcm_substream *substream,
|
||||
}
|
||||
#endif
|
||||
if (in_kernel)
|
||||
memcpy((void *)dst, src, size);
|
||||
memcpy((__force void *)dst, src, size);
|
||||
else if (copy_to_user(dst, src, size))
|
||||
return -EFAULT;
|
||||
src++;
|
||||
@@ -1365,7 +1365,7 @@ static int snd_korg1212_copy_from(struct snd_pcm_substream *substream,
|
||||
}
|
||||
#endif
|
||||
if (in_kernel)
|
||||
memcpy((void *)dst, src, size);
|
||||
memcpy(dst, (__force void *)src, size);
|
||||
else if (copy_from_user(dst, src, size))
|
||||
return -EFAULT;
|
||||
dst++;
|
||||
|
@@ -369,9 +369,9 @@ static int setup_corb_rirb(struct lola *chip)
|
||||
return err;
|
||||
|
||||
chip->corb.addr = chip->rb.addr;
|
||||
chip->corb.buf = (u32 *)chip->rb.area;
|
||||
chip->corb.buf = (__le32 *)chip->rb.area;
|
||||
chip->rirb.addr = chip->rb.addr + 2048;
|
||||
chip->rirb.buf = (u32 *)(chip->rb.area + 2048);
|
||||
chip->rirb.buf = (__le32 *)(chip->rb.area + 2048);
|
||||
|
||||
/* disable ringbuffer DMAs */
|
||||
lola_writeb(chip, BAR0, RIRBCTL, 0);
|
||||
|
@@ -220,7 +220,7 @@ struct lola_bar {
|
||||
|
||||
/* CORB/RIRB */
|
||||
struct lola_rb {
|
||||
u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */
|
||||
__le32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */
|
||||
dma_addr_t addr; /* physical address of CORB/RIRB buffer */
|
||||
unsigned short rp, wp; /* read/write pointers */
|
||||
int cmds; /* number of pending requests */
|
||||
@@ -275,7 +275,7 @@ struct lola_mixer_array {
|
||||
struct lola_mixer_widget {
|
||||
unsigned int nid;
|
||||
unsigned int caps;
|
||||
struct lola_mixer_array __user *array;
|
||||
struct lola_mixer_array __iomem *array;
|
||||
struct lola_mixer_array *array_saved;
|
||||
unsigned int src_stream_outs;
|
||||
unsigned int src_phys_ins;
|
||||
|
@@ -316,10 +316,10 @@ static int lola_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
* set up a BDL entry
|
||||
*/
|
||||
static int setup_bdle(struct snd_pcm_substream *substream,
|
||||
struct lola_stream *str, u32 **bdlp,
|
||||
struct lola_stream *str, __le32 **bdlp,
|
||||
int ofs, int size)
|
||||
{
|
||||
u32 *bdl = *bdlp;
|
||||
__le32 *bdl = *bdlp;
|
||||
|
||||
while (size > 0) {
|
||||
dma_addr_t addr;
|
||||
@@ -355,14 +355,14 @@ static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm,
|
||||
struct snd_pcm_substream *substream,
|
||||
struct lola_stream *str)
|
||||
{
|
||||
u32 *bdl;
|
||||
__le32 *bdl;
|
||||
int i, ofs, periods, period_bytes;
|
||||
|
||||
period_bytes = str->period_bytes;
|
||||
periods = str->bufsize / period_bytes;
|
||||
|
||||
/* program the initial BDL entries */
|
||||
bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
|
||||
bdl = (__le32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index);
|
||||
ofs = 0;
|
||||
str->frags = 0;
|
||||
for (i = 0; i < periods; i++) {
|
||||
|
@@ -2103,7 +2103,7 @@ static const u16 minisrc_lpf[MINISRC_LPF_LEN] = {
|
||||
static void snd_m3_assp_init(struct snd_m3 *chip)
|
||||
{
|
||||
unsigned int i;
|
||||
const u16 *data;
|
||||
const __le16 *data;
|
||||
|
||||
/* zero kernel data */
|
||||
for (i = 0; i < (REV_B_DATA_MEMORY_UNIT_LENGTH * NUM_UNITS_KERNEL_DATA) / 2; i++)
|
||||
@@ -2121,7 +2121,7 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
|
||||
KDATA_DMA_XFER0);
|
||||
|
||||
/* write kernel into code memory.. */
|
||||
data = (const u16 *)chip->assp_kernel_image->data;
|
||||
data = (const __le16 *)chip->assp_kernel_image->data;
|
||||
for (i = 0 ; i * 2 < chip->assp_kernel_image->size; i++) {
|
||||
snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
|
||||
REV_B_CODE_MEMORY_BEGIN + i,
|
||||
@@ -2134,7 +2134,7 @@ static void snd_m3_assp_init(struct snd_m3 *chip)
|
||||
* drop it there. It seems that the minisrc doesn't
|
||||
* need vectors, so we won't bother with them..
|
||||
*/
|
||||
data = (const u16 *)chip->assp_minisrc_image->data;
|
||||
data = (const __le16 *)chip->assp_minisrc_image->data;
|
||||
for (i = 0; i * 2 < chip->assp_minisrc_image->size; i++) {
|
||||
snd_m3_assp_write(chip, MEMTYPE_INTERNAL_CODE,
|
||||
0x400 + i, le16_to_cpu(data[i]));
|
||||
|
@@ -182,6 +182,7 @@ static int mixart_set_clock(struct mixart_mgr *mgr,
|
||||
case PIPE_RUNNING:
|
||||
if(rate != 0)
|
||||
break;
|
||||
/* fall through */
|
||||
default:
|
||||
if(rate == 0)
|
||||
return 0; /* nothing to do */
|
||||
|
@@ -107,7 +107,7 @@ static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp,
|
||||
#ifndef __BIG_ENDIAN
|
||||
size /= 4; /* u32 size */
|
||||
for(i=0; i < size; i++) {
|
||||
((u32*)resp->data)[i] = be32_to_cpu(((u32*)resp->data)[i]);
|
||||
((u32*)resp->data)[i] = be32_to_cpu(((__be32*)resp->data)[i]);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -519,7 +519,7 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id)
|
||||
/* Traces are text: the swapped msg_data has to be swapped back ! */
|
||||
int i;
|
||||
for(i=0; i<(resp.size/4); i++) {
|
||||
(mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]);
|
||||
((__be32*)mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]);
|
||||
}
|
||||
#endif
|
||||
((char*)mixart_msg_data)[resp.size - 1] = 0;
|
||||
@@ -540,7 +540,7 @@ irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id)
|
||||
dev_err(&mgr->pci->dev,
|
||||
"canceled notification %x !\n", msg);
|
||||
}
|
||||
/* no break, continue ! */
|
||||
/* fall through */
|
||||
case MSG_TYPE_ANSWER:
|
||||
/* answer or notification to a message we are waiting for*/
|
||||
mutex_lock(&mgr->msg_lock);
|
||||
|
@@ -73,30 +73,30 @@ static int mixart_wait_nice_for_register_value(struct mixart_mgr *mgr,
|
||||
*/
|
||||
struct snd_mixart_elf32_ehdr {
|
||||
u8 e_ident[16];
|
||||
u16 e_type;
|
||||
u16 e_machine;
|
||||
u32 e_version;
|
||||
u32 e_entry;
|
||||
u32 e_phoff;
|
||||
u32 e_shoff;
|
||||
u32 e_flags;
|
||||
u16 e_ehsize;
|
||||
u16 e_phentsize;
|
||||
u16 e_phnum;
|
||||
u16 e_shentsize;
|
||||
u16 e_shnum;
|
||||
u16 e_shstrndx;
|
||||
__be16 e_type;
|
||||
__be16 e_machine;
|
||||
__be32 e_version;
|
||||
__be32 e_entry;
|
||||
__be32 e_phoff;
|
||||
__be32 e_shoff;
|
||||
__be32 e_flags;
|
||||
__be16 e_ehsize;
|
||||
__be16 e_phentsize;
|
||||
__be16 e_phnum;
|
||||
__be16 e_shentsize;
|
||||
__be16 e_shnum;
|
||||
__be16 e_shstrndx;
|
||||
};
|
||||
|
||||
struct snd_mixart_elf32_phdr {
|
||||
u32 p_type;
|
||||
u32 p_offset;
|
||||
u32 p_vaddr;
|
||||
u32 p_paddr;
|
||||
u32 p_filesz;
|
||||
u32 p_memsz;
|
||||
u32 p_flags;
|
||||
u32 p_align;
|
||||
__be32 p_type;
|
||||
__be32 p_offset;
|
||||
__be32 p_vaddr;
|
||||
__be32 p_paddr;
|
||||
__be32 p_filesz;
|
||||
__be32 p_memsz;
|
||||
__be32 p_flags;
|
||||
__be32 p_align;
|
||||
};
|
||||
|
||||
static int mixart_load_elf(struct mixart_mgr *mgr, const struct firmware *dsp )
|
||||
|
@@ -26,19 +26,19 @@
|
||||
#include <sound/hwdep.h>
|
||||
|
||||
#ifndef readl_be
|
||||
#define readl_be(x) be32_to_cpu(__raw_readl(x))
|
||||
#define readl_be(x) be32_to_cpu((__force __be32)__raw_readl(x))
|
||||
#endif
|
||||
|
||||
#ifndef writel_be
|
||||
#define writel_be(data,addr) __raw_writel(cpu_to_be32(data),addr)
|
||||
#define writel_be(data,addr) __raw_writel((__force u32)cpu_to_be32(data),addr)
|
||||
#endif
|
||||
|
||||
#ifndef readl_le
|
||||
#define readl_le(x) le32_to_cpu(__raw_readl(x))
|
||||
#define readl_le(x) le32_to_cpu((__force __le32)__raw_readl(x))
|
||||
#endif
|
||||
|
||||
#ifndef writel_le
|
||||
#define writel_le(data,addr) __raw_writel(cpu_to_le32(data),addr)
|
||||
#define writel_le(data,addr) __raw_writel((__force u32)cpu_to_le32(data),addr)
|
||||
#endif
|
||||
|
||||
#define MIXART_MEM(mgr,x) ((mgr)->mem[0].virt + (x))
|
||||
|
@@ -470,10 +470,10 @@ struct snd_riptide {
|
||||
};
|
||||
|
||||
struct sgd { /* scatter gather desriptor */
|
||||
u32 dwNextLink;
|
||||
u32 dwSegPtrPhys;
|
||||
u32 dwSegLen;
|
||||
u32 dwStat_Ctl;
|
||||
__le32 dwNextLink;
|
||||
__le32 dwSegPtrPhys;
|
||||
__le32 dwSegLen;
|
||||
__le32 dwStat_Ctl;
|
||||
};
|
||||
|
||||
struct pcmhw { /* pcm descriptor */
|
||||
@@ -1017,7 +1017,7 @@ getsamplerate(struct cmdif *cif, unsigned char *intdec, unsigned int *rate)
|
||||
static int
|
||||
setsampleformat(struct cmdif *cif,
|
||||
unsigned char mixer, unsigned char id,
|
||||
unsigned char channels, unsigned char format)
|
||||
unsigned char channels, snd_pcm_format_t format)
|
||||
{
|
||||
unsigned char w, ch, sig, order;
|
||||
|
||||
|
@@ -1433,14 +1433,12 @@ static int snd_sonicvibes_midi(struct sonicvibes *sonic,
|
||||
{
|
||||
struct snd_mpu401 * mpu = rmidi->private_data;
|
||||
struct snd_card *card = sonic->card;
|
||||
struct snd_rawmidi_str *dir;
|
||||
unsigned int idx;
|
||||
int err;
|
||||
|
||||
mpu->private_data = sonic;
|
||||
mpu->open_input = snd_sonicvibes_midi_input_open;
|
||||
mpu->close_input = snd_sonicvibes_midi_input_close;
|
||||
dir = &rmidi->streams[SNDRV_RAWMIDI_STREAM_OUTPUT];
|
||||
for (idx = 0; idx < ARRAY_SIZE(snd_sonicvibes_midi_controls); idx++)
|
||||
if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_sonicvibes_midi_controls[idx], sonic))) < 0)
|
||||
return err;
|
||||
|
@@ -123,7 +123,7 @@ static int snd_trident_probe(struct pci_dev *pci,
|
||||
} else {
|
||||
strcpy(card->shortname, "Trident ");
|
||||
}
|
||||
strcat(card->shortname, card->driver);
|
||||
strcat(card->shortname, str);
|
||||
sprintf(card->longname, "%s PCI Audio at 0x%lx, irq %d",
|
||||
card->shortname, trident->port, trident->irq);
|
||||
|
||||
|
@@ -264,7 +264,7 @@ struct snd_trident_memblk_arg {
|
||||
};
|
||||
|
||||
struct snd_trident_tlb {
|
||||
unsigned int * entries; /* 16k-aligned TLB table */
|
||||
__le32 *entries; /* 16k-aligned TLB table */
|
||||
dma_addr_t entries_dmaaddr; /* 16k-aligned PCI address to TLB table */
|
||||
unsigned long * shadow_entries; /* shadow entries with virtual addresses */
|
||||
struct snd_dma_buffer buffer;
|
||||
|
@@ -3359,7 +3359,7 @@ static int snd_trident_tlb_alloc(struct snd_trident *trident)
|
||||
dev_err(trident->card->dev, "unable to allocate TLB buffer\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
trident->tlb.entries = (unsigned int*)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
|
||||
trident->tlb.entries = (__le32 *)ALIGN((unsigned long)trident->tlb.buffer.area, SNDRV_TRIDENT_MAX_PAGES * 4);
|
||||
trident->tlb.entries_dmaaddr = ALIGN(trident->tlb.buffer.addr, SNDRV_TRIDENT_MAX_PAGES * 4);
|
||||
/* allocate shadow TLB page table (virtual addresses) */
|
||||
trident->tlb.shadow_entries =
|
||||
|
@@ -185,50 +185,50 @@
|
||||
*/
|
||||
|
||||
struct snd_ymfpci_playback_bank {
|
||||
u32 format;
|
||||
u32 loop_default;
|
||||
u32 base; /* 32-bit address */
|
||||
u32 loop_start; /* 32-bit offset */
|
||||
u32 loop_end; /* 32-bit offset */
|
||||
u32 loop_frac; /* 8-bit fraction - loop_start */
|
||||
u32 delta_end; /* pitch delta end */
|
||||
u32 lpfK_end;
|
||||
u32 eg_gain_end;
|
||||
u32 left_gain_end;
|
||||
u32 right_gain_end;
|
||||
u32 eff1_gain_end;
|
||||
u32 eff2_gain_end;
|
||||
u32 eff3_gain_end;
|
||||
u32 lpfQ;
|
||||
u32 status;
|
||||
u32 num_of_frames;
|
||||
u32 loop_count;
|
||||
u32 start;
|
||||
u32 start_frac;
|
||||
u32 delta;
|
||||
u32 lpfK;
|
||||
u32 eg_gain;
|
||||
u32 left_gain;
|
||||
u32 right_gain;
|
||||
u32 eff1_gain;
|
||||
u32 eff2_gain;
|
||||
u32 eff3_gain;
|
||||
u32 lpfD1;
|
||||
u32 lpfD2;
|
||||
__le32 format;
|
||||
__le32 loop_default;
|
||||
__le32 base; /* 32-bit address */
|
||||
__le32 loop_start; /* 32-bit offset */
|
||||
__le32 loop_end; /* 32-bit offset */
|
||||
__le32 loop_frac; /* 8-bit fraction - loop_start */
|
||||
__le32 delta_end; /* pitch delta end */
|
||||
__le32 lpfK_end;
|
||||
__le32 eg_gain_end;
|
||||
__le32 left_gain_end;
|
||||
__le32 right_gain_end;
|
||||
__le32 eff1_gain_end;
|
||||
__le32 eff2_gain_end;
|
||||
__le32 eff3_gain_end;
|
||||
__le32 lpfQ;
|
||||
__le32 status;
|
||||
__le32 num_of_frames;
|
||||
__le32 loop_count;
|
||||
__le32 start;
|
||||
__le32 start_frac;
|
||||
__le32 delta;
|
||||
__le32 lpfK;
|
||||
__le32 eg_gain;
|
||||
__le32 left_gain;
|
||||
__le32 right_gain;
|
||||
__le32 eff1_gain;
|
||||
__le32 eff2_gain;
|
||||
__le32 eff3_gain;
|
||||
__le32 lpfD1;
|
||||
__le32 lpfD2;
|
||||
};
|
||||
|
||||
struct snd_ymfpci_capture_bank {
|
||||
u32 base; /* 32-bit address */
|
||||
u32 loop_end; /* 32-bit offset */
|
||||
u32 start; /* 32-bit offset */
|
||||
u32 num_of_loops; /* counter */
|
||||
__le32 base; /* 32-bit address */
|
||||
__le32 loop_end; /* 32-bit offset */
|
||||
__le32 start; /* 32-bit offset */
|
||||
__le32 num_of_loops; /* counter */
|
||||
};
|
||||
|
||||
struct snd_ymfpci_effect_bank {
|
||||
u32 base; /* 32-bit address */
|
||||
u32 loop_end; /* 32-bit offset */
|
||||
u32 start; /* 32-bit offset */
|
||||
u32 temp;
|
||||
__le32 base; /* 32-bit address */
|
||||
__le32 loop_end; /* 32-bit offset */
|
||||
__le32 start; /* 32-bit offset */
|
||||
__le32 temp;
|
||||
};
|
||||
|
||||
struct snd_ymfpci_pcm;
|
||||
@@ -316,7 +316,7 @@ struct snd_ymfpci {
|
||||
dma_addr_t work_base_addr;
|
||||
struct snd_dma_buffer ac3_tmp_base;
|
||||
|
||||
u32 *ctrl_playback;
|
||||
__le32 *ctrl_playback;
|
||||
struct snd_ymfpci_playback_bank *bank_playback[YDSXG_PLAYBACK_VOICES][2];
|
||||
struct snd_ymfpci_capture_bank *bank_capture[YDSXG_CAPTURE_VOICES][2];
|
||||
struct snd_ymfpci_effect_bank *bank_effect[YDSXG_EFFECT_VOICES][2];
|
||||
|
@@ -336,7 +336,7 @@ static void snd_ymfpci_pcm_interrupt(struct snd_ymfpci *chip, struct snd_ymfpci_
|
||||
unsigned int subs = ypcm->substream->number;
|
||||
unsigned int next_bank = 1 - chip->active_bank;
|
||||
struct snd_ymfpci_playback_bank *bank;
|
||||
u32 volume;
|
||||
__le32 volume;
|
||||
|
||||
bank = &voice->bank[next_bank];
|
||||
volume = cpu_to_le32(chip->pcm_mixer[subs].left << 15);
|
||||
@@ -505,7 +505,7 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int
|
||||
u32 lpfK = snd_ymfpci_calc_lpfK(runtime->rate);
|
||||
struct snd_ymfpci_playback_bank *bank;
|
||||
unsigned int nbank;
|
||||
u32 vol_left, vol_right;
|
||||
__le32 vol_left, vol_right;
|
||||
u8 use_left, use_right;
|
||||
unsigned long flags;
|
||||
|
||||
@@ -2135,7 +2135,7 @@ static int snd_ymfpci_memalloc(struct snd_ymfpci *chip)
|
||||
|
||||
chip->bank_base_playback = ptr;
|
||||
chip->bank_base_playback_addr = ptr_addr;
|
||||
chip->ctrl_playback = (u32 *)ptr;
|
||||
chip->ctrl_playback = (__le32 *)ptr;
|
||||
chip->ctrl_playback[0] = cpu_to_le32(YDSXG_PLAYBACK_VOICES);
|
||||
ptr += ALIGN(playback_ctrl_size, 0x100);
|
||||
ptr_addr += ALIGN(playback_ctrl_size, 0x100);
|
||||
|
Ссылка в новой задаче
Block a user