Commit 83af57dd authored by Takashi Iwai's avatar Takashi Iwai

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: default avatarTakashi Iwai <tiwai@suse.de>
parent 412bbe7d
...@@ -188,69 +188,20 @@ static void had_substream_put(struct snd_intelhad *intelhaddata) ...@@ -188,69 +188,20 @@ static void had_substream_put(struct snd_intelhad *intelhaddata)
} }
/* Register access functions */ /* Register access functions */
static inline void static void had_read_register(struct snd_intelhad *ctx, u32 reg, u32 *val)
mid_hdmi_audio_read(struct snd_intelhad *ctx, u32 reg, u32 *val)
{ {
*val = ioread32(ctx->mmio_start + ctx->had_config_offset + reg); *val = ioread32(ctx->mmio_start + ctx->had_config_offset + reg);
} }
static inline void static void had_write_register(struct snd_intelhad *ctx, u32 reg, u32 val)
mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val)
{ {
iowrite32(val, ctx->mmio_start + ctx->had_config_offset + reg); 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 * 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. * updating AUD_CONFIG register.
* This is because: * This is because:
* Bit6 of AUD_CONFIG register is writeonly due to a silicon bug on VLV2 * 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, ...@@ -267,24 +218,25 @@ static void snd_intelhad_enable_audio(struct snd_pcm_substream *substream,
bool enable) bool enable)
{ {
union aud_cfg cfg_val = {.regval = 0}; 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. * If substream is NULL, there is no active stream.
* In this case just set channels to 2 * In this case just set channels to 2
*/ */
channels = substream ? substream->runtime->channels : 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) if (enable)
data |= 1; cfg_val.regx.aud_en = 1;
mask = AUD_CONFIG_CH_MASK | 1; mask = AUD_CONFIG_CH_MASK | 1;
dev_dbg(intelhaddata->dev, "%s : data = %x, mask =%x\n", had_read_register(intelhaddata, AUD_CONFIG, &val);
__func__, data, mask); val &= ~mask;
val |= cfg_val.regval;
had_read_modify(intelhaddata, AUD_CONFIG, data, mask); had_write_register(intelhaddata, AUD_CONFIG, val);
} }
/* enable / disable the audio interface */ /* enable / disable the audio interface */
...@@ -293,10 +245,10 @@ static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable) ...@@ -293,10 +245,10 @@ static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable)
u32 status_reg; u32 status_reg;
if (enable) { 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; status_reg |= HDMI_AUDIO_BUFFER_DONE | HDMI_AUDIO_UNDERRUN;
mid_hdmi_audio_write(ctx, AUD_HDMI_STATUS, status_reg); had_write_register(ctx, AUD_HDMI_STATUS, status_reg);
mid_hdmi_audio_read(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, ...@@ -401,6 +353,13 @@ static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream,
cfg_val.regx.layout = LAYOUT1; cfg_val.regx.layout = LAYOUT1;
cfg_val.regx.val_bit = 1; 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); had_write_register(intelhaddata, AUD_CONFIG, cfg_val.regval);
return 0; return 0;
} }
...@@ -1684,15 +1643,15 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) ...@@ -1684,15 +1643,15 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id)
u32 audio_stat, audio_reg; u32 audio_stat, audio_reg;
audio_reg = AUD_HDMI_STATUS; 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) { 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); had_process_buffer_underrun(ctx);
} }
if (audio_stat & HDMI_AUDIO_BUFFER_DONE) { 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); had_process_buffer_done(ctx);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment