forked from Minki/linux
ALSA: x86: Don't check connection in lowlevel accessors
The lowlevel register read/write don't have to be careful about the connection state. It should be checked in the caller side instead. By dropping the check, we can simplify the code, and readability. This patch also refacors the functions slightly: namely, - drop the useless always-zero return values - fold the inline functions to the main accessor functions themselves - move the DP audio hack for AUD_CONFIG to the caller side - simplify snd_intelhad_eanble_audio() and drop the unused had_read_modify() Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
412bbe7d5b
commit
83af57dd51
@ -188,69 +188,20 @@ static void had_substream_put(struct snd_intelhad *intelhaddata)
|
||||
}
|
||||
|
||||
/* Register access functions */
|
||||
static inline void
|
||||
mid_hdmi_audio_read(struct snd_intelhad *ctx, u32 reg, u32 *val)
|
||||
static void had_read_register(struct snd_intelhad *ctx, u32 reg, u32 *val)
|
||||
{
|
||||
*val = ioread32(ctx->mmio_start + ctx->had_config_offset + reg);
|
||||
}
|
||||
|
||||
static inline void
|
||||
mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val)
|
||||
static void had_write_register(struct snd_intelhad *ctx, u32 reg, u32 val)
|
||||
{
|
||||
iowrite32(val, ctx->mmio_start + ctx->had_config_offset + reg);
|
||||
}
|
||||
|
||||
static int had_read_register(struct snd_intelhad *intelhaddata,
|
||||
u32 offset, u32 *data)
|
||||
{
|
||||
if (!intelhaddata->connected)
|
||||
return -ENODEV;
|
||||
|
||||
mid_hdmi_audio_read(intelhaddata, offset, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fixup_dp_config(struct snd_intelhad *intelhaddata,
|
||||
u32 offset, u32 *data)
|
||||
{
|
||||
if (intelhaddata->dp_output) {
|
||||
if (offset == AUD_CONFIG && (*data & AUD_CONFIG_VALID_BIT))
|
||||
*data |= AUD_CONFIG_DP_MODE | AUD_CONFIG_BLOCK_BIT;
|
||||
}
|
||||
}
|
||||
|
||||
static int had_write_register(struct snd_intelhad *intelhaddata,
|
||||
u32 offset, u32 data)
|
||||
{
|
||||
if (!intelhaddata->connected)
|
||||
return -ENODEV;
|
||||
|
||||
fixup_dp_config(intelhaddata, offset, &data);
|
||||
mid_hdmi_audio_write(intelhaddata, offset, data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset,
|
||||
u32 data, u32 mask)
|
||||
{
|
||||
u32 val_tmp;
|
||||
|
||||
if (!intelhaddata->connected)
|
||||
return -ENODEV;
|
||||
|
||||
mid_hdmi_audio_read(intelhaddata, offset, &val_tmp);
|
||||
val_tmp &= ~mask;
|
||||
val_tmp |= (data & mask);
|
||||
|
||||
fixup_dp_config(intelhaddata, offset, &val_tmp);
|
||||
mid_hdmi_audio_write(intelhaddata, offset, val_tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* enable / disable audio configuration
|
||||
*
|
||||
* The had_read_modify() function should not directly be used on VLV2 for
|
||||
* The normal read/modify should not directly be used on VLV2 for
|
||||
* updating AUD_CONFIG register.
|
||||
* This is because:
|
||||
* Bit6 of AUD_CONFIG register is writeonly due to a silicon bug on VLV2
|
||||
@ -267,24 +218,25 @@ static void snd_intelhad_enable_audio(struct snd_pcm_substream *substream,
|
||||
bool enable)
|
||||
{
|
||||
union aud_cfg cfg_val = {.regval = 0};
|
||||
u8 channels, data, mask;
|
||||
u8 channels;
|
||||
u32 mask, val;
|
||||
|
||||
/*
|
||||
* If substream is NULL, there is no active stream.
|
||||
* In this case just set channels to 2
|
||||
*/
|
||||
channels = substream ? substream->runtime->channels : 2;
|
||||
cfg_val.regx.num_ch = channels - 2;
|
||||
dev_dbg(intelhaddata->dev, "enable %d, ch=%d\n", enable, channels);
|
||||
|
||||
data = cfg_val.regval;
|
||||
cfg_val.regx.num_ch = channels - 2;
|
||||
if (enable)
|
||||
data |= 1;
|
||||
cfg_val.regx.aud_en = 1;
|
||||
mask = AUD_CONFIG_CH_MASK | 1;
|
||||
|
||||
dev_dbg(intelhaddata->dev, "%s : data = %x, mask =%x\n",
|
||||
__func__, data, mask);
|
||||
|
||||
had_read_modify(intelhaddata, AUD_CONFIG, data, mask);
|
||||
had_read_register(intelhaddata, AUD_CONFIG, &val);
|
||||
val &= ~mask;
|
||||
val |= cfg_val.regval;
|
||||
had_write_register(intelhaddata, AUD_CONFIG, val);
|
||||
}
|
||||
|
||||
/* enable / disable the audio interface */
|
||||
@ -293,10 +245,10 @@ static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable)
|
||||
u32 status_reg;
|
||||
|
||||
if (enable) {
|
||||
mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS, &status_reg);
|
||||
had_read_register(ctx, AUD_HDMI_STATUS, &status_reg);
|
||||
status_reg |= HDMI_AUDIO_BUFFER_DONE | HDMI_AUDIO_UNDERRUN;
|
||||
mid_hdmi_audio_write(ctx, AUD_HDMI_STATUS, status_reg);
|
||||
mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS, &status_reg);
|
||||
had_write_register(ctx, AUD_HDMI_STATUS, status_reg);
|
||||
had_read_register(ctx, AUD_HDMI_STATUS, &status_reg);
|
||||
}
|
||||
}
|
||||
|
||||
@ -401,6 +353,13 @@ static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream,
|
||||
cfg_val.regx.layout = LAYOUT1;
|
||||
|
||||
cfg_val.regx.val_bit = 1;
|
||||
|
||||
/* fix up the DP bits */
|
||||
if (intelhaddata->dp_output) {
|
||||
cfg_val.regx.dp_modei = 1;
|
||||
cfg_val.regx.set = 1;
|
||||
}
|
||||
|
||||
had_write_register(intelhaddata, AUD_CONFIG, cfg_val.regval);
|
||||
return 0;
|
||||
}
|
||||
@ -1684,15 +1643,15 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id)
|
||||
u32 audio_stat, audio_reg;
|
||||
|
||||
audio_reg = AUD_HDMI_STATUS;
|
||||
mid_hdmi_audio_read(ctx, audio_reg, &audio_stat);
|
||||
had_read_register(ctx, audio_reg, &audio_stat);
|
||||
|
||||
if (audio_stat & HDMI_AUDIO_UNDERRUN) {
|
||||
mid_hdmi_audio_write(ctx, audio_reg, HDMI_AUDIO_UNDERRUN);
|
||||
had_write_register(ctx, audio_reg, HDMI_AUDIO_UNDERRUN);
|
||||
had_process_buffer_underrun(ctx);
|
||||
}
|
||||
|
||||
if (audio_stat & HDMI_AUDIO_BUFFER_DONE) {
|
||||
mid_hdmi_audio_write(ctx, audio_reg, HDMI_AUDIO_BUFFER_DONE);
|
||||
had_write_register(ctx, audio_reg, HDMI_AUDIO_BUFFER_DONE);
|
||||
had_process_buffer_done(ctx);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user