From 4812dcc437fbe0ddc2319dae7c31254f57d4ae44 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 15:58:15 +0100 Subject: ALSA: x86: Remove v1 ops and structs The v1 code refers to Medfield/Clovertrail. It's not used at all in the current driver, and probably won't be ever. Let's clean this up, then we can go to the next stage of cleanup tasks. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 206 +------------------------------------------ 1 file changed, 1 insertion(+), 205 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 5ce139c1b21d..1e0bc72a8f63 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -280,23 +280,12 @@ static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, return had_read_modify(AUD_CONFIG, data, mask); } -static void snd_intelhad_enable_audio_v1(struct snd_pcm_substream *substream, - u8 enable) -{ - had_read_modify(AUD_CONFIG, enable, BIT(0)); -} - static void snd_intelhad_enable_audio_v2(struct snd_pcm_substream *substream, u8 enable) { had_read_modify_aud_config_v2(substream, enable, BIT(0)); } -static void snd_intelhad_reset_audio_v1(u8 reset) -{ - had_write_register(AUD_HDMI_STATUS, reset); -} - static void snd_intelhad_reset_audio_v2(u8 reset) { had_write_register(AUD_HDMI_STATUS_v2, reset); @@ -320,7 +309,7 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, IEC958_AES0_NONAUDIO)>>1; ch_stat0.status_0_regx.clk_acc = (intelhaddata->aes_bits & IEC958_AES3_CON_CLOCK)>>4; - cfg_val.cfg_regx.val_bit = ch_stat0.status_0_regx.lpcm_id; + cfg_val.cfg_regx_v2.val_bit = ch_stat0.status_0_regx.lpcm_id; switch (substream->runtime->rate) { case AUD_SAMPLE_RATE_32: @@ -401,58 +390,6 @@ static int snd_intelhad_prog_audio_ctrl_v2(struct snd_pcm_substream *substream, return 0; } -/** - * function to initialize audio - * registers and buffer confgiuration registers - * This function is called in the prepare callback - */ -static int snd_intelhad_prog_audio_ctrl_v1(struct snd_pcm_substream *substream, - struct snd_intelhad *intelhaddata) -{ - union aud_cfg cfg_val = {.cfg_regval = 0}; - union aud_buf_config buf_cfg = {.buf_cfgval = 0}; - u8 channels; - - had_prog_status_reg(substream, intelhaddata); - - buf_cfg.buf_cfg_regx.fifo_width = FIFO_THRESHOLD; - buf_cfg.buf_cfg_regx.aud_delay = 0; - had_write_register(AUD_BUF_CONFIG, buf_cfg.buf_cfgval); - - channels = substream->runtime->channels; - - switch (channels) { - case 1: - case 2: - cfg_val.cfg_regx.num_ch = CH_STEREO; - cfg_val.cfg_regx.layout = LAYOUT0; - break; - - case 3: - case 4: - cfg_val.cfg_regx.num_ch = CH_THREE_FOUR; - cfg_val.cfg_regx.layout = LAYOUT1; - break; - - case 5: - case 6: - cfg_val.cfg_regx.num_ch = CH_FIVE_SIX; - cfg_val.cfg_regx.layout = LAYOUT1; - break; - - case 7: - case 8: - cfg_val.cfg_regx.num_ch = CH_SEVEN_EIGHT; - cfg_val.cfg_regx.layout = LAYOUT1; - break; - - } - - cfg_val.cfg_regx.val_bit = 1; - had_write_register(AUD_CONFIG, cfg_val.cfg_regval); - return 0; -} - /* * Compute derived values in channel_allocations[]. */ @@ -659,56 +596,6 @@ static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata, return 0; } -/** - * snd_intelhad_prog_dip_v1 - to initialize Data Island Packets registers - * - * @substream:substream for which the prepare function is called - * @intelhaddata:substream private data - * - * This function is called in the prepare callback - */ -static void snd_intelhad_prog_dip_v1(struct snd_pcm_substream *substream, - struct snd_intelhad *intelhaddata) -{ - int i; - union aud_ctrl_st ctrl_state = {.ctrl_val = 0}; - union aud_info_frame2 frame2 = {.fr2_val = 0}; - union aud_info_frame3 frame3 = {.fr3_val = 0}; - u8 checksum = 0; - int channels; - - channels = substream->runtime->channels; - - had_write_register(AUD_CNTL_ST, ctrl_state.ctrl_val); - - frame2.fr2_regx.chnl_cnt = substream->runtime->channels - 1; - - frame3.fr3_regx.chnl_alloc = snd_intelhad_channel_allocation( - intelhaddata, channels); - - /*Calculte the byte wide checksum for all valid DIP words*/ - for (i = 0; i < BYTES_PER_WORD; i++) - checksum += (HDMI_INFO_FRAME_WORD1 >> i*BITS_PER_BYTE) & MASK_BYTE0; - for (i = 0; i < BYTES_PER_WORD; i++) - checksum += (frame2.fr2_val >> i*BITS_PER_BYTE) & MASK_BYTE0; - for (i = 0; i < BYTES_PER_WORD; i++) - checksum += (frame3.fr3_val >> i*BITS_PER_BYTE) & MASK_BYTE0; - - frame2.fr2_regx.chksum = -(checksum); - - had_write_register(AUD_HDMIW_INFOFR, HDMI_INFO_FRAME_WORD1); - had_write_register(AUD_HDMIW_INFOFR, frame2.fr2_val); - had_write_register(AUD_HDMIW_INFOFR, frame3.fr3_val); - - /* program remaining DIP words with zero */ - for (i = 0; i < HAD_MAX_DIP_WORDS-VALID_DIP_WORDS; i++) - had_write_register(AUD_HDMIW_INFOFR, 0x0); - - ctrl_state.ctrl_regx.dip_freq = 1; - ctrl_state.ctrl_regx.dip_en_sta = 1; - had_write_register(AUD_CNTL_ST, ctrl_state.ctrl_val); -} - /** * snd_intelhad_prog_dip_v2 - to initialize Data Island Packets registers * @@ -928,32 +815,6 @@ static int had_calculate_maud_value(u32 aud_samp_freq, u32 link_rate) return maud_val; } -/** - * snd_intelhad_prog_cts_v1 - Program HDMI audio CTS value - * - * @aud_samp_freq: sampling frequency of audio data - * @tmds: sampling frequency of the display data - * @n_param: N value, depends on aud_samp_freq - * @intelhaddata:substream private data - * - * Program CTS register based on the audio and display sampling frequency - */ -static void snd_intelhad_prog_cts_v1(u32 aud_samp_freq, u32 tmds, - u32 link_rate, u32 n_param, - struct snd_intelhad *intelhaddata) -{ - u32 cts_val; - u64 dividend, divisor; - - /* Calculate CTS according to HDMI 1.3a spec*/ - dividend = (u64)tmds * n_param*1000; - divisor = 128 * aud_samp_freq; - cts_val = div64_u64(dividend, divisor); - pr_debug("TMDS value=%d, N value=%d, CTS Value=%d\n", - tmds, n_param, cts_val); - had_write_register(AUD_HDMI_CTS, (BIT(20) | cts_val)); -} - /** * snd_intelhad_prog_cts_v2 - Program HDMI audio CTS value * @@ -1026,31 +887,6 @@ static int had_calculate_n_value(u32 aud_samp_freq) return n_val; } -/** - * snd_intelhad_prog_n_v1 - Program HDMI audio N value - * - * @aud_samp_freq: sampling frequency of audio data - * @n_param: N value, depends on aud_samp_freq - * @intelhaddata:substream private data - * - * This function is called in the prepare callback. - * It programs based on the audio and display sampling frequency - */ -static int snd_intelhad_prog_n_v1(u32 aud_samp_freq, u32 *n_param, - struct snd_intelhad *intelhaddata) -{ - s32 n_val; - - n_val = had_calculate_n_value(aud_samp_freq); - - if (n_val < 0) - return n_val; - - had_write_register(AUD_N_ENABLE, (BIT(20) | n_val)); - *n_param = n_val; - return 0; -} - /** * snd_intelhad_prog_n_v2 - Program HDMI audio N value * @@ -1087,35 +923,6 @@ static int snd_intelhad_prog_n_v2(u32 aud_samp_freq, u32 *n_param, return 0; } -static void had_clear_underrun_intr_v1(struct snd_intelhad *intelhaddata) -{ - u32 hdmi_status, i = 0; - - /* Handle Underrun interrupt within Audio Unit */ - had_write_register(AUD_CONFIG, 0); - /* Reset buffer pointers */ - had_write_register(AUD_HDMI_STATUS, 1); - had_write_register(AUD_HDMI_STATUS, 0); - /** - * The interrupt status 'sticky' bits might not be cleared by - * setting '1' to that bit once... - */ - do { /* clear bit30, 31 AUD_HDMI_STATUS */ - had_read_register(AUD_HDMI_STATUS, &hdmi_status); - pr_debug("HDMI status =0x%x\n", hdmi_status); - if (hdmi_status & AUD_CONFIG_MASK_UNDERRUN) { - i++; - hdmi_status &= (AUD_CONFIG_MASK_SRDBG | - AUD_CONFIG_MASK_FUNCRST); - hdmi_status |= ~AUD_CONFIG_MASK_UNDERRUN; - had_write_register(AUD_HDMI_STATUS, hdmi_status); - } else - break; - } while (i < MAX_CNT); - if (i >= MAX_CNT) - pr_err("Unable to clear UNDERRUN bits\n"); -} - static void had_clear_underrun_intr_v2(struct snd_intelhad *intelhaddata) { u32 hdmi_status, i = 0; @@ -1775,16 +1582,6 @@ static struct snd_intel_had_interface had_interface = { .resume = hdmi_audio_resume, }; -static struct had_ops had_ops_v1 = { - .enable_audio = snd_intelhad_enable_audio_v1, - .reset_audio = snd_intelhad_reset_audio_v1, - .prog_n = snd_intelhad_prog_n_v1, - .prog_cts = snd_intelhad_prog_cts_v1, - .audio_ctrl = snd_intelhad_prog_audio_ctrl_v1, - .prog_dip = snd_intelhad_prog_dip_v1, - .handle_underrun = had_clear_underrun_intr_v1, -}; - static struct had_ops had_ops_v2 = { .enable_audio = snd_intelhad_enable_audio_v2, .reset_audio = snd_intelhad_reset_audio_v2, @@ -1934,7 +1731,6 @@ int hdmi_audio_probe(void *deviceptr) } intelhaddata->hw_silence = 1; - had_ops_v1 = had_ops_v1; /* unused */ intelhaddata->ops = &had_ops_v2; return retval; -- cgit From 76296ef0ecec9bb887be22105744e429c6a5422a Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 16:09:11 +0100 Subject: ALSA: x86: Drop indirect calls of had_ops We have only a single implementation of had_ops, hence there is no merit to use the indirect calls at all. Let's replace it with the direct calls -- which allows the compiler more optimizations. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 85 +++++++++++++++++++------------------------- 1 file changed, 37 insertions(+), 48 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 1e0bc72a8f63..84ce4e09ada5 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -280,13 +280,12 @@ static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, return had_read_modify(AUD_CONFIG, data, mask); } -static void snd_intelhad_enable_audio_v2(struct snd_pcm_substream *substream, - u8 enable) +void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, u8 enable) { had_read_modify_aud_config_v2(substream, enable, BIT(0)); } -static void snd_intelhad_reset_audio_v2(u8 reset) +static void snd_intelhad_reset_audio(u8 reset) { had_write_register(AUD_HDMI_STATUS_v2, reset); } @@ -359,13 +358,13 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, return 0; } -/** +/* * function to initialize audio * registers and buffer confgiuration registers * This function is called in the prepare callback */ -static int snd_intelhad_prog_audio_ctrl_v2(struct snd_pcm_substream *substream, - struct snd_intelhad *intelhaddata) +static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream, + struct snd_intelhad *intelhaddata) { union aud_cfg cfg_val = {.cfg_regval = 0}; union aud_buf_config buf_cfg = {.buf_cfgval = 0}; @@ -596,16 +595,16 @@ static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata, return 0; } -/** - * snd_intelhad_prog_dip_v2 - to initialize Data Island Packets registers +/* + * snd_intelhad_prog_dip - to initialize Data Island Packets registers * * @substream:substream for which the prepare function is called * @intelhaddata:substream private data * * This function is called in the prepare callback */ -static void snd_intelhad_prog_dip_v2(struct snd_pcm_substream *substream, - struct snd_intelhad *intelhaddata) +static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, + struct snd_intelhad *intelhaddata) { int i; union aud_ctrl_st ctrl_state = {.ctrl_val = 0}; @@ -815,8 +814,8 @@ static int had_calculate_maud_value(u32 aud_samp_freq, u32 link_rate) return maud_val; } -/** - * snd_intelhad_prog_cts_v2 - Program HDMI audio CTS value +/* + * snd_intelhad_prog_cts - Program HDMI audio CTS value * * @aud_samp_freq: sampling frequency of audio data * @tmds: sampling frequency of the display data @@ -825,9 +824,9 @@ static int had_calculate_maud_value(u32 aud_samp_freq, u32 link_rate) * * Program CTS register based on the audio and display sampling frequency */ -static void snd_intelhad_prog_cts_v2(u32 aud_samp_freq, u32 tmds, - u32 link_rate, u32 n_param, - struct snd_intelhad *intelhaddata) +static void snd_intelhad_prog_cts(u32 aud_samp_freq, u32 tmds, + u32 link_rate, u32 n_param, + struct snd_intelhad *intelhaddata) { u32 cts_val; u64 dividend, divisor; @@ -887,8 +886,8 @@ static int had_calculate_n_value(u32 aud_samp_freq) return n_val; } -/** - * snd_intelhad_prog_n_v2 - Program HDMI audio N value +/* + * snd_intelhad_prog_n - Program HDMI audio N value * * @aud_samp_freq: sampling frequency of audio data * @n_param: N value, depends on aud_samp_freq @@ -897,8 +896,8 @@ static int had_calculate_n_value(u32 aud_samp_freq) * This function is called in the prepare callback. * It programs based on the audio and display sampling frequency */ -static int snd_intelhad_prog_n_v2(u32 aud_samp_freq, u32 *n_param, - struct snd_intelhad *intelhaddata) +static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param, + struct snd_intelhad *intelhaddata) { s32 n_val; @@ -923,7 +922,7 @@ static int snd_intelhad_prog_n_v2(u32 aud_samp_freq, u32 *n_param, return 0; } -static void had_clear_underrun_intr_v2(struct snd_intelhad *intelhaddata) +void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) { u32 hdmi_status, i = 0; @@ -1209,7 +1208,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, caps = HDMI_AUDIO_BUFFER_DONE; retval = had_set_caps(HAD_SET_ENABLE_AUDIO_INT, &caps); retval = had_set_caps(HAD_SET_ENABLE_AUDIO, NULL); - intelhaddata->ops->enable_audio(substream, 1); + snd_intelhad_enable_audio(substream, 1); pr_debug("Processed _Start\n"); @@ -1232,10 +1231,10 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, */ caps = HDMI_AUDIO_BUFFER_DONE; had_set_caps(HAD_SET_DISABLE_AUDIO_INT, &caps); - intelhaddata->ops->enable_audio(substream, 0); + snd_intelhad_enable_audio(substream, 0); /* Reset buffer pointers */ - intelhaddata->ops->reset_audio(1); - intelhaddata->ops->reset_audio(0); + snd_intelhad_reset_audio(1); + snd_intelhad_reset_audio(0); stream->stream_status = STREAM_DROPPED; had_set_caps(HAD_SET_DISABLE_AUDIO, NULL); break; @@ -1304,8 +1303,8 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) had_get_caps(HAD_GET_ELD, &intelhaddata->eeld); had_get_caps(HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); - retval = intelhaddata->ops->prog_n(substream->runtime->rate, &n_param, - intelhaddata); + retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, + intelhaddata); if (retval) { pr_err("programming N value failed %#x\n", retval); goto prep_end; @@ -1315,13 +1314,13 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) had_get_caps(HAD_GET_LINK_RATE, &link_rate); - intelhaddata->ops->prog_cts(substream->runtime->rate, - disp_samp_freq, link_rate, - n_param, intelhaddata); + snd_intelhad_prog_cts(substream->runtime->rate, + disp_samp_freq, link_rate, + n_param, intelhaddata); - intelhaddata->ops->prog_dip(substream, intelhaddata); + snd_intelhad_prog_dip(substream, intelhaddata); - retval = intelhaddata->ops->audio_ctrl(substream, intelhaddata); + retval = snd_intelhad_audio_ctrl(substream, intelhaddata); /* Prog buffer address */ retval = snd_intelhad_prog_buffer(intelhaddata, @@ -1431,7 +1430,7 @@ int hdmi_audio_mode_change(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); /* Disable Audio */ - intelhaddata->ops->enable_audio(substream, 0); + snd_intelhad_enable_audio(substream, 0); /* Update CTS value */ retval = had_get_caps(HAD_GET_DISPLAY_RATE, &disp_samp_freq); @@ -1440,8 +1439,8 @@ int hdmi_audio_mode_change(struct snd_pcm_substream *substream) goto out; } - retval = intelhaddata->ops->prog_n(substream->runtime->rate, &n_param, - intelhaddata); + retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, + intelhaddata); if (retval) { pr_err("programming N value failed %#x\n", retval); goto out; @@ -1450,12 +1449,12 @@ int hdmi_audio_mode_change(struct snd_pcm_substream *substream) if (intelhaddata->dp_output) had_get_caps(HAD_GET_LINK_RATE, &link_rate); - intelhaddata->ops->prog_cts(substream->runtime->rate, - disp_samp_freq, link_rate, - n_param, intelhaddata); + snd_intelhad_prog_cts(substream->runtime->rate, + disp_samp_freq, link_rate, + n_param, intelhaddata); /* Enable Audio */ - intelhaddata->ops->enable_audio(substream, 1); + snd_intelhad_enable_audio(substream, 1); out: return retval; @@ -1582,15 +1581,6 @@ static struct snd_intel_had_interface had_interface = { .resume = hdmi_audio_resume, }; -static struct had_ops had_ops_v2 = { - .enable_audio = snd_intelhad_enable_audio_v2, - .reset_audio = snd_intelhad_reset_audio_v2, - .prog_n = snd_intelhad_prog_n_v2, - .prog_cts = snd_intelhad_prog_cts_v2, - .audio_ctrl = snd_intelhad_prog_audio_ctrl_v2, - .prog_dip = snd_intelhad_prog_dip_v2, - .handle_underrun = had_clear_underrun_intr_v2, -}; /** * hdmi_audio_probe - to create sound card instance for HDMI audio playabck * @@ -1731,7 +1721,6 @@ int hdmi_audio_probe(void *deviceptr) } intelhaddata->hw_silence = 1; - intelhaddata->ops = &had_ops_v2; return retval; err: -- cgit From f23df8071b178dcfa4f6014baf9323ddaa33e1fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 16:29:39 +0100 Subject: ALSA: x86: Replace indirect register ops with direct calls Now about the indirect register ops: they are replaced with direct calls, too. The read / write / modify ops are simply replaced with the corresponding functions. The difference is that we calculate the offset inside the function now. So all the had_config_offset references in the caller side are dropped. This also simplifies the DP-audio check in hdmi_audio_write() and hdmi_audio_rmw(). The hdmi_audio_get_register_base is dropped since it's no longer used when the base address and config offset are referred in the read/write functions. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 84ce4e09ada5..d101a27e4a27 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -205,8 +205,7 @@ int had_read_register(u32 offset, u32 *data) retval = had_get_hwstate(intelhaddata); if (!retval) - retval = intelhaddata->reg_ops.hdmi_audio_read_register( - offset + intelhaddata->audio_cfg_offset, data); + retval = mid_hdmi_audio_read(offset, data); return retval; } @@ -218,8 +217,7 @@ int had_write_register(u32 offset, u32 data) retval = had_get_hwstate(intelhaddata); if (!retval) - retval = intelhaddata->reg_ops.hdmi_audio_write_register( - offset + intelhaddata->audio_cfg_offset, data); + retval = mid_hdmi_audio_write(offset, data); return retval; } @@ -231,9 +229,7 @@ int had_read_modify(u32 offset, u32 data, u32 mask) retval = had_get_hwstate(intelhaddata); if (!retval) - retval = intelhaddata->reg_ops.hdmi_audio_read_modify( - offset + intelhaddata->audio_cfg_offset, - data, mask); + retval = mid_hdmi_audio_rmw(offset, data, mask); return retval; } @@ -1622,7 +1618,6 @@ int hdmi_audio_probe(void *deviceptr) retval = mid_hdmi_audio_setup( ops_cb.intel_had_event_call_back, - &(intelhaddata->reg_ops), &(intelhaddata->query_ops)); if (retval) { pr_err("querying display driver APIs failed %#x\n", retval); -- cgit From 9eca88c881f1c74c7f5dda3c67cb0b4178429e93 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 16:37:06 +0100 Subject: ALSA: x86: Replace indirect query_ops with direct calls Like the previous patch, this replaces the indirect query_ops calls via direct function calls. They are only get_caps and set_caps, so fairly straightforward at this time. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index d101a27e4a27..a4c2f3f8d669 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -179,8 +179,7 @@ int had_get_caps(enum had_caps_list query, void *caps) retval = had_get_hwstate(intelhaddata); if (!retval) - retval = intelhaddata->query_ops.hdmi_audio_get_caps(query, - caps); + retval = mid_hdmi_audio_get_caps(query, caps); return retval; } @@ -192,8 +191,7 @@ int had_set_caps(enum had_caps_list set_element, void *caps) retval = had_get_hwstate(intelhaddata); if (!retval) - retval = intelhaddata->query_ops.hdmi_audio_set_caps( - set_element, caps); + retval = mid_hdmi_audio_set_caps(set_element, caps); return retval; } @@ -1616,9 +1614,7 @@ int hdmi_audio_probe(void *deviceptr) /* registering with display driver to get access to display APIs */ - retval = mid_hdmi_audio_setup( - ops_cb.intel_had_event_call_back, - &(intelhaddata->query_ops)); + retval = mid_hdmi_audio_setup(ops_cb.intel_had_event_call_back); if (retval) { pr_err("querying display driver APIs failed %#x\n", retval); goto free_hadstream; -- cgit From 6f9ecc76f4e04b111160d789f36a8c5bf1cc9ab6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 16:52:06 +0100 Subject: ALSA: x86: Drop snd_intel_had_interface indirect calls Yet another indirection is killed: at this time, it's snd_intel_had_interface. It contains also the name string, but it's nowhere used, thus we can kill it, too. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index a4c2f3f8d669..bff46061e5c5 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1568,13 +1568,6 @@ static struct snd_kcontrol_new had_control_iec958 = { .put = had_iec958_put }; -static struct snd_intel_had_interface had_interface = { - .name = "hdmi-audio", - .query = hdmi_audio_query, - .suspend = hdmi_audio_suspend, - .resume = hdmi_audio_resume, -}; - /** * hdmi_audio_probe - to create sound card instance for HDMI audio playabck * @@ -1704,7 +1697,7 @@ int hdmi_audio_probe(void *deviceptr) pm_runtime_enable(intelhaddata->dev); mutex_unlock(&had_mutex); - retval = mid_hdmi_audio_register(&had_interface, intelhaddata); + retval = mid_hdmi_audio_register(intelhaddata); if (retval) { pr_err("registering with display driver failed %#x\n", retval); snd_card_free(card); -- cgit From 79dda75a2cfc5628f25338122d24ee8789b367cf Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 17:23:39 +0100 Subject: ALSA: x86: Pass snd_intelhad object to helpers For reducing the global variable reference, keep snd_intelhad object in the context and pass it to each helper. It's a preliminary change for further cleanup. This also includes the simplification of the probe procedure: the LPE platform driver directly gets the created snd_intelhad object by hdmi_audio_probe(), and passes it to each helper and destructor, hdmi_audio_remove(). The hdmi_audio_probe() function doesn't call the back-registration any longer, which is fairly useless. The LPE platform driver initializes the stuff instead at the right place, and calls the wq after the object creation in the probe function itself. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 143 ++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 70 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index bff46061e5c5..45ba16e27323 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -42,7 +42,6 @@ static DEFINE_MUTEX(had_mutex); /*standard module options for ALSA. This module supports only one card*/ static int hdmi_card_index = SNDRV_DEFAULT_IDX1; static char *hdmi_card_id = SNDRV_DEFAULT_STR1; -static struct snd_intelhad *had_data; static int underrun_count; module_param_named(index, hdmi_card_index, int, 0444); @@ -172,10 +171,10 @@ int had_get_hwstate(struct snd_intelhad *intelhaddata) return 0; } -int had_get_caps(enum had_caps_list query, void *caps) +int had_get_caps(struct snd_intelhad *intelhaddata, + enum had_caps_list query, void *caps) { int retval; - struct snd_intelhad *intelhaddata = had_data; retval = had_get_hwstate(intelhaddata); if (!retval) @@ -184,10 +183,10 @@ int had_get_caps(enum had_caps_list query, void *caps) return retval; } -int had_set_caps(enum had_caps_list set_element, void *caps) +int had_set_caps(struct snd_intelhad *intelhaddata, + enum had_caps_list set_element, void *caps) { int retval; - struct snd_intelhad *intelhaddata = had_data; retval = had_get_hwstate(intelhaddata); if (!retval) @@ -196,10 +195,9 @@ int had_set_caps(enum had_caps_list set_element, void *caps) return retval; } -int had_read_register(u32 offset, u32 *data) +int had_read_register(struct snd_intelhad *intelhaddata, u32 offset, u32 *data) { int retval; - struct snd_intelhad *intelhaddata = had_data; retval = had_get_hwstate(intelhaddata); if (!retval) @@ -208,10 +206,9 @@ int had_read_register(u32 offset, u32 *data) return retval; } -int had_write_register(u32 offset, u32 data) +int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) { int retval; - struct snd_intelhad *intelhaddata = had_data; retval = had_get_hwstate(intelhaddata); if (!retval) @@ -220,10 +217,10 @@ int had_write_register(u32 offset, u32 data) return retval; } -int had_read_modify(u32 offset, u32 data, u32 mask) +int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, + u32 data, u32 mask) { int retval; - struct snd_intelhad *intelhaddata = had_data; retval = had_get_hwstate(intelhaddata); if (!retval) @@ -253,6 +250,7 @@ int had_read_modify(u32 offset, u32 data, u32 mask) static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, u32 data, u32 mask) { + struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream); union aud_cfg cfg_val = {.cfg_regval = 0}; u8 channels; @@ -271,7 +269,7 @@ static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, pr_debug("%s : data = %x, mask =%x\n", __func__, data, mask); - return had_read_modify(AUD_CONFIG, data, mask); + return had_read_modify(intelhaddata, AUD_CONFIG, data, mask); } void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, u8 enable) @@ -279,9 +277,10 @@ void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, u8 enable) had_read_modify_aud_config_v2(substream, enable, BIT(0)); } -static void snd_intelhad_reset_audio(u8 reset) +static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata, + u8 reset) { - had_write_register(AUD_HDMI_STATUS_v2, reset); + had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, reset); } /** @@ -334,7 +333,8 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, break; } - had_write_register(AUD_CH_STATUS_0, ch_stat0.status_0_regval); + had_write_register(intelhaddata, + AUD_CH_STATUS_0, ch_stat0.status_0_regval); format = substream->runtime->format; @@ -348,7 +348,8 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, ch_stat1.status_1_regx.max_wrd_len = 0; ch_stat1.status_1_regx.wrd_len = 0; } - had_write_register(AUD_CH_STATUS_1, ch_stat1.status_1_regval); + had_write_register(intelhaddata, + AUD_CH_STATUS_1, ch_stat1.status_1_regval); return 0; } @@ -369,7 +370,7 @@ static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream, buf_cfg.buf_cfg_regx_v2.audio_fifo_watermark = FIFO_THRESHOLD; buf_cfg.buf_cfg_regx_v2.dma_fifo_watermark = DMA_FIFO_THRESHOLD; buf_cfg.buf_cfg_regx_v2.aud_delay = 0; - had_write_register(AUD_BUF_CONFIG, buf_cfg.buf_cfgval); + had_write_register(intelhaddata, AUD_BUF_CONFIG, buf_cfg.buf_cfgval); channels = substream->runtime->channels; cfg_val.cfg_regx_v2.num_ch = channels - 2; @@ -379,7 +380,7 @@ static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream, cfg_val.cfg_regx_v2.layout = LAYOUT1; cfg_val.cfg_regx_v2.val_bit = 1; - had_write_register(AUD_CONFIG, cfg_val.cfg_regval); + had_write_register(intelhaddata, AUD_CONFIG, cfg_val.cfg_regval); return 0; } @@ -479,8 +480,8 @@ void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) return; } - had_get_caps(HAD_GET_ELD, &intelhaddata->eeld); - had_get_caps(HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); + had_get_caps(intelhaddata, HAD_GET_ELD, &intelhaddata->eeld); + had_get_caps(intelhaddata, HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); pr_debug("eeld.speaker_allocation_block = %x\n", intelhaddata->eeld.speaker_allocation_block); @@ -610,7 +611,7 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, channels = substream->runtime->channels; - had_write_register(AUD_CNTL_ST, ctrl_state.ctrl_val); + had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.ctrl_val); if (intelhaddata->dp_output) { info_frame = DP_INFO_FRAME_WORD1; @@ -633,17 +634,17 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, frame2.fr2_regx.chksum = -(checksum); } - had_write_register(AUD_HDMIW_INFOFR_v2, info_frame); - had_write_register(AUD_HDMIW_INFOFR_v2, frame2.fr2_val); - had_write_register(AUD_HDMIW_INFOFR_v2, frame3.fr3_val); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, info_frame); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, frame2.fr2_val); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, frame3.fr3_val); /* program remaining DIP words with zero */ for (i = 0; i < HAD_MAX_DIP_WORDS-VALID_DIP_WORDS; i++) - had_write_register(AUD_HDMIW_INFOFR_v2, 0x0); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, 0x0); ctrl_state.ctrl_regx.dip_freq = 1; ctrl_state.ctrl_regx.dip_en_sta = 1; - had_write_register(AUD_CNTL_ST, ctrl_state.ctrl_val); + had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.ctrl_val); } /** @@ -696,10 +697,12 @@ int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, intelhaddata->buf_info[i].buf_size = ring_buf_size - (period_bytes*i); - had_write_register(AUD_BUF_A_ADDR + (i * HAD_REG_WIDTH), + had_write_register(intelhaddata, + AUD_BUF_A_ADDR + (i * HAD_REG_WIDTH), intelhaddata->buf_info[i].buf_addr | BIT(0) | BIT(1)); - had_write_register(AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH), + had_write_register(intelhaddata, + AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH), period_bytes); intelhaddata->buf_info[i].is_valid = true; } @@ -716,8 +719,9 @@ int snd_intelhad_read_len(struct snd_intelhad *intelhaddata) u32 len[4]; for (i = 0; i < 4 ; i++) { - had_read_register(AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH), - &len[i]); + had_read_register(intelhaddata, + AUD_BUF_A_LENGTH + (i * HAD_REG_WIDTH), + &len[i]); if (!len[i]) retval++; } @@ -836,7 +840,7 @@ static void snd_intelhad_prog_cts(u32 aud_samp_freq, u32 tmds, } pr_debug("TMDS value=%d, N value=%d, CTS Value=%d\n", tmds, n_param, cts_val); - had_write_register(AUD_HDMI_CTS, (BIT(24) | cts_val)); + had_write_register(intelhaddata, AUD_HDMI_CTS, (BIT(24) | cts_val)); } static int had_calculate_n_value(u32 aud_samp_freq) @@ -911,7 +915,7 @@ static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param, if (n_val < 0) return n_val; - had_write_register(AUD_N_ENABLE, (BIT(24) | n_val)); + had_write_register(intelhaddata, AUD_N_ENABLE, (BIT(24) | n_val)); *n_param = n_val; return 0; } @@ -921,20 +925,22 @@ void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) u32 hdmi_status, i = 0; /* Handle Underrun interrupt within Audio Unit */ - had_write_register(AUD_CONFIG, 0); + had_write_register(intelhaddata, AUD_CONFIG, 0); /* Reset buffer pointers */ - had_write_register(AUD_HDMI_STATUS_v2, 1); - had_write_register(AUD_HDMI_STATUS_v2, 0); + had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, 1); + had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, 0); /** * The interrupt status 'sticky' bits might not be cleared by * setting '1' to that bit once... */ do { /* clear bit30, 31 AUD_HDMI_STATUS */ - had_read_register(AUD_HDMI_STATUS_v2, &hdmi_status); + had_read_register(intelhaddata, AUD_HDMI_STATUS_v2, + &hdmi_status); pr_debug("HDMI status =0x%x\n", hdmi_status); if (hdmi_status & AUD_CONFIG_MASK_UNDERRUN) { i++; - had_write_register(AUD_HDMI_STATUS_v2, hdmi_status); + had_write_register(intelhaddata, + AUD_HDMI_STATUS_v2, hdmi_status); } else break; } while (i < MAX_CNT); @@ -1200,8 +1206,9 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, * caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; */ caps = HDMI_AUDIO_BUFFER_DONE; - retval = had_set_caps(HAD_SET_ENABLE_AUDIO_INT, &caps); - retval = had_set_caps(HAD_SET_ENABLE_AUDIO, NULL); + retval = had_set_caps(intelhaddata, HAD_SET_ENABLE_AUDIO_INT, + &caps); + retval = had_set_caps(intelhaddata, HAD_SET_ENABLE_AUDIO, NULL); snd_intelhad_enable_audio(substream, 1); pr_debug("Processed _Start\n"); @@ -1224,13 +1231,13 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, * caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; */ caps = HDMI_AUDIO_BUFFER_DONE; - had_set_caps(HAD_SET_DISABLE_AUDIO_INT, &caps); + had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO_INT, &caps); snd_intelhad_enable_audio(substream, 0); /* Reset buffer pointers */ - snd_intelhad_reset_audio(1); - snd_intelhad_reset_audio(0); + snd_intelhad_reset_audio(intelhaddata, 1); + snd_intelhad_reset_audio(intelhaddata, 0); stream->stream_status = STREAM_DROPPED; - had_set_caps(HAD_SET_DISABLE_AUDIO, NULL); + had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO, NULL); break; default: @@ -1288,14 +1295,15 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) /* Get N value in KHz */ - retval = had_get_caps(HAD_GET_DISPLAY_RATE, &disp_samp_freq); + retval = had_get_caps(intelhaddata, HAD_GET_DISPLAY_RATE, + &disp_samp_freq); if (retval) { pr_err("querying display sampling freq failed %#x\n", retval); goto prep_end; } - had_get_caps(HAD_GET_ELD, &intelhaddata->eeld); - had_get_caps(HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); + had_get_caps(intelhaddata, HAD_GET_ELD, &intelhaddata->eeld); + had_get_caps(intelhaddata, HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, intelhaddata); @@ -1305,7 +1313,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) } if (intelhaddata->dp_output) - had_get_caps(HAD_GET_LINK_RATE, &link_rate); + had_get_caps(intelhaddata, HAD_GET_LINK_RATE, &link_rate); snd_intelhad_prog_cts(substream->runtime->rate, @@ -1325,7 +1333,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) * FL, FR, C, LFE, RL, RR */ - had_write_register(AUD_BUF_CH_SWAP, SWAP_LFE_CENTER); + had_write_register(intelhaddata, AUD_BUF_CH_SWAP, SWAP_LFE_CENTER); prep_end: return retval; @@ -1361,7 +1369,8 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( */ buf_id = intelhaddata->curr_buf % 4; - had_read_register(AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t); + had_read_register(intelhaddata, + AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t); if ((t == 0) || (t == ((u32)-1L))) { underrun_count++; @@ -1427,7 +1436,8 @@ int hdmi_audio_mode_change(struct snd_pcm_substream *substream) snd_intelhad_enable_audio(substream, 0); /* Update CTS value */ - retval = had_get_caps(HAD_GET_DISPLAY_RATE, &disp_samp_freq); + retval = had_get_caps(intelhaddata, HAD_GET_DISPLAY_RATE, + &disp_samp_freq); if (retval) { pr_err("querying display sampling freq failed %#x\n", retval); goto out; @@ -1441,7 +1451,7 @@ int hdmi_audio_mode_change(struct snd_pcm_substream *substream) } if (intelhaddata->dp_output) - had_get_caps(HAD_GET_LINK_RATE, &link_rate); + had_get_caps(intelhaddata, HAD_GET_LINK_RATE, &link_rate); snd_intelhad_prog_cts(substream->runtime->rate, disp_samp_freq, link_rate, @@ -1568,16 +1578,17 @@ static struct snd_kcontrol_new had_control_iec958 = { .put = had_iec958_put }; -/** +/* * hdmi_audio_probe - to create sound card instance for HDMI audio playabck * - *@haddata: pointer to HAD private data - *@card_id: card for which probe is called + * @devptr: platform device + * @had_ret: pointer to store the created snd_intelhad object * - * This function is called when the hdmi cable is plugged in. This function + * This function is called when the platform device is probed. This function * creates and registers the sound card with ALSA */ -int hdmi_audio_probe(void *deviceptr) +int hdmi_audio_probe(struct platform_device *devptr, + struct snd_intelhad **had_ret) { int retval; struct snd_pcm *pcm; @@ -1585,7 +1596,6 @@ int hdmi_audio_probe(void *deviceptr) struct had_callback_ops ops_cb; struct snd_intelhad *intelhaddata; struct had_pvt_data *had_stream; - struct platform_device *devptr = deviceptr; pr_debug("Enter %s\n", __func__); @@ -1602,7 +1612,6 @@ int hdmi_audio_probe(void *deviceptr) goto free_haddata; } - had_data = intelhaddata; ops_cb.intel_had_event_call_back = had_event_handler; /* registering with display driver to get access to display APIs */ @@ -1697,16 +1706,11 @@ int hdmi_audio_probe(void *deviceptr) pm_runtime_enable(intelhaddata->dev); mutex_unlock(&had_mutex); - retval = mid_hdmi_audio_register(intelhaddata); - if (retval) { - pr_err("registering with display driver failed %#x\n", retval); - snd_card_free(card); - goto free_hadstream; - } intelhaddata->hw_silence = 1; + *had_ret = intelhaddata; - return retval; + return 0; err: snd_card_free(card); unlock_mutex: @@ -1722,7 +1726,7 @@ free_haddata: return retval; } -/** +/* * hdmi_audio_remove - removes the alsa card * *@haddata: pointer to HAD private data @@ -1730,9 +1734,8 @@ free_haddata: * This function is called when the hdmi cable is un-plugged. This function * free the sound card. */ -int hdmi_audio_remove(void *pdevptr) +int hdmi_audio_remove(struct snd_intelhad *intelhaddata) { - struct snd_intelhad *intelhaddata = had_data; int caps; pr_debug("Enter %s\n", __func__); @@ -1742,8 +1745,8 @@ int hdmi_audio_remove(void *pdevptr) if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; - had_set_caps(HAD_SET_DISABLE_AUDIO_INT, &caps); - had_set_caps(HAD_SET_DISABLE_AUDIO, NULL); + had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO_INT, &caps); + had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO, NULL); } snd_card_free(intelhaddata->card); kfree(intelhaddata->private_data); -- cgit From dd895f2e9b013a5387372dbf3a7d8405aaeb494e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 17:31:29 +0100 Subject: ALSA: x86: Drop useless mutex at probe had_mutex is (supposedly) used to protect the concurrent calls of hdmi_audio_probe(). But we may have only one device at most, so it's utterly useless. Drop it. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 45ba16e27323..7165f14d5229 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -37,8 +37,6 @@ #include #include "intel_hdmi_audio.h" -static DEFINE_MUTEX(had_mutex); - /*standard module options for ALSA. This module supports only one card*/ static int hdmi_card_index = SNDRV_DEFAULT_IDX1; static char *hdmi_card_id = SNDRV_DEFAULT_STR1; @@ -1621,7 +1619,7 @@ int hdmi_audio_probe(struct platform_device *devptr, pr_err("querying display driver APIs failed %#x\n", retval); goto free_hadstream; } - mutex_lock(&had_mutex); + spin_lock_init(&intelhaddata->had_spinlock); intelhaddata->drv_status = HAD_DRV_DISCONNECTED; pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", @@ -1632,7 +1630,7 @@ int hdmi_audio_probe(struct platform_device *devptr, THIS_MODULE, 0, &card); if (retval) - goto unlock_mutex; + goto free_hadstream; intelhaddata->card = card; intelhaddata->card_id = hdmi_card_id; intelhaddata->card_index = card->number; @@ -1705,16 +1703,12 @@ int hdmi_audio_probe(struct platform_device *devptr, pm_runtime_set_active(intelhaddata->dev); pm_runtime_enable(intelhaddata->dev); - mutex_unlock(&had_mutex); - intelhaddata->hw_silence = 1; *had_ret = intelhaddata; return 0; err: snd_card_free(card); -unlock_mutex: - mutex_unlock(&had_mutex); free_hadstream: kfree(had_stream); pm_runtime_disable(intelhaddata->dev); -- cgit From 437af8f2946231ee141bc2a8d37063a8bb6047b0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 17:38:00 +0100 Subject: ALSA: x86: Call event callback directly Currently the driver calls the event callback stored in its ctx pointer, but it's obviously inefficient. Replace it with the direct calls. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 7165f14d5229..571ec07a3611 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1591,7 +1591,6 @@ int hdmi_audio_probe(struct platform_device *devptr, int retval; struct snd_pcm *pcm; struct snd_card *card; - struct had_callback_ops ops_cb; struct snd_intelhad *intelhaddata; struct had_pvt_data *had_stream; @@ -1610,16 +1609,6 @@ int hdmi_audio_probe(struct platform_device *devptr, goto free_haddata; } - ops_cb.intel_had_event_call_back = had_event_handler; - - /* registering with display driver to get access to display APIs */ - - retval = mid_hdmi_audio_setup(ops_cb.intel_had_event_call_back); - if (retval) { - pr_err("querying display driver APIs failed %#x\n", retval); - goto free_hadstream; - } - spin_lock_init(&intelhaddata->had_spinlock); intelhaddata->drv_status = HAD_DRV_DISCONNECTED; pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", -- cgit From bf8b24f8169096050795b552a778faaac349c73c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 18:09:01 +0100 Subject: ALSA: x86: Drop the global platform device reference Instead of referring to the global hlpe_pdev variable, pass the platform device object to each function properly. Accessing to the global object is really ugly and error-prone. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 571ec07a3611..ed9db2ebe9cf 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -172,11 +172,12 @@ int had_get_hwstate(struct snd_intelhad *intelhaddata) int had_get_caps(struct snd_intelhad *intelhaddata, enum had_caps_list query, void *caps) { + struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); if (!retval) - retval = mid_hdmi_audio_get_caps(query, caps); + retval = mid_hdmi_audio_get_caps(pdev, query, caps); return retval; } @@ -184,33 +185,36 @@ int had_get_caps(struct snd_intelhad *intelhaddata, int had_set_caps(struct snd_intelhad *intelhaddata, enum had_caps_list set_element, void *caps) { + struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); if (!retval) - retval = mid_hdmi_audio_set_caps(set_element, caps); + retval = mid_hdmi_audio_set_caps(pdev, set_element, caps); return retval; } int had_read_register(struct snd_intelhad *intelhaddata, u32 offset, u32 *data) { + struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); if (!retval) - retval = mid_hdmi_audio_read(offset, data); + retval = mid_hdmi_audio_read(pdev, offset, data); return retval; } int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) { + struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); if (!retval) - retval = mid_hdmi_audio_write(offset, data); + retval = mid_hdmi_audio_write(pdev, offset, data); return retval; } @@ -218,11 +222,12 @@ int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, u32 data, u32 mask) { + struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); if (!retval) - retval = mid_hdmi_audio_rmw(offset, data, mask); + retval = mid_hdmi_audio_rmw(pdev, offset, data, mask); return retval; } -- cgit From 6ddb3ab66f94109c524859ba4dd9d43772893676 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 30 Jan 2017 18:17:44 +0100 Subject: ALSA: x86: Move the global underrun_count to struct snd_intelhad The last one is in intel_hdmi_audio.c, underrun_count: this can be embedded in snd_intelhad object. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index ed9db2ebe9cf..e08691110a48 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -40,7 +40,6 @@ /*standard module options for ALSA. This module supports only one card*/ static int hdmi_card_index = SNDRV_DEFAULT_IDX1; static char *hdmi_card_id = SNDRV_DEFAULT_STR1; -static int underrun_count; module_param_named(index, hdmi_card_index, int, 0444); MODULE_PARM_DESC(index, @@ -969,7 +968,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); had_stream = intelhaddata->private_data; runtime = substream->runtime; - underrun_count = 0; + intelhaddata->underrun_count = 0; pm_runtime_get(intelhaddata->dev); @@ -1376,19 +1375,19 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &t); if ((t == 0) || (t == ((u32)-1L))) { - underrun_count++; + intelhaddata->underrun_count++; pr_debug("discovered buffer done for buf %d, count = %d\n", - buf_id, underrun_count); + buf_id, intelhaddata->underrun_count); - if (underrun_count > (HAD_MIN_PERIODS/2)) { + if (intelhaddata->underrun_count > (HAD_MIN_PERIODS/2)) { pr_debug("assume audio_codec_reset, underrun = %d - do xrun\n", - underrun_count); - underrun_count = 0; + intelhaddata->underrun_count); + intelhaddata->underrun_count = 0; return SNDRV_PCM_POS_XRUN; } } else { /* Reset Counter */ - underrun_count = 0; + intelhaddata->underrun_count = 0; } t = intelhaddata->buf_info[buf_id].buf_size - t; -- cgit From 0e18060f99a42c20f87d64eb30e5f424509643ae Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 07:53:56 +0100 Subject: ALSA: x86: Drop unused hw_silence field It's nowhere used. Let's drop it. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index e08691110a48..efc56544af17 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1696,7 +1696,6 @@ int hdmi_audio_probe(struct platform_device *devptr, pm_runtime_set_active(intelhaddata->dev); pm_runtime_enable(intelhaddata->dev); - intelhaddata->hw_silence = 1; *had_ret = intelhaddata; return 0; -- cgit From dae15a9d960e513d5b60c00c306cddd87465f1c4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 08:02:16 +0100 Subject: ALSA: x86: Move dma_mask debug print into intel_hdmi_lpe_audio.c It belongs to the right place. And, remove a few sanity checks (e.g. NULL card) and debug prints as well. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index efc56544af17..49cb95072a88 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1600,8 +1600,6 @@ int hdmi_audio_probe(struct platform_device *devptr, pr_debug("Enter %s\n", __func__); - pr_debug("hdmi_audio_probe dma_mask: %p\n", devptr->dev.dma_mask); - /* allocate memory for saving internal context and working */ intelhaddata = kzalloc(sizeof(*intelhaddata), GFP_KERNEL); if (!intelhaddata) @@ -1653,15 +1651,6 @@ int hdmi_audio_probe(struct platform_device *devptr, retval = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, NULL, HAD_MAX_BUFFER, HAD_MAX_BUFFER); - - if (card->dev == NULL) - pr_debug("card->dev is NULL!!!!! Should not be this case\n"); - else if (card->dev->dma_mask == NULL) - pr_debug("hdmi_audio_probe dma_mask is NULL!!!!!\n"); - else - pr_debug("hdmi_audio_probe dma_mask is : %p\n", - card->dev->dma_mask); - if (retval) goto err; -- cgit From 5647aec26640ffdf099d51b3403eaeac10d74147 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 08:14:34 +0100 Subject: ALSA: x86: Embed snd_intelhad into snd_card Instead of allocating snd_intelhad struct, use the card's private_data and embed it. It simplifies the code a lot. While we're at it, embed had_stream into snd_intelhad struct instead of individually allocating, and rename had_pvt_data to a bit more specific name, had_stream_data. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 77 ++++++++------------------------------------ 1 file changed, 13 insertions(+), 64 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 49cb95072a88..dfc4452afee1 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -961,12 +961,12 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) struct snd_intelhad *intelhaddata; struct snd_pcm_runtime *runtime; struct had_stream_pvt *stream; - struct had_pvt_data *had_stream; + struct had_stream_data *had_stream; int retval; pr_debug("snd_intelhad_open called\n"); intelhaddata = snd_pcm_substream_chip(substream); - had_stream = intelhaddata->private_data; + had_stream = &intelhaddata->stream_data; runtime = substream->runtime; intelhaddata->underrun_count = 0; @@ -1180,13 +1180,13 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, unsigned long flag_irq; struct snd_intelhad *intelhaddata; struct had_stream_pvt *stream; - struct had_pvt_data *had_stream; + struct had_stream_data *had_stream; pr_debug("snd_intelhad_pcm_trigger called\n"); intelhaddata = snd_pcm_substream_chip(substream); stream = substream->runtime->private_data; - had_stream = intelhaddata->private_data; + had_stream = &intelhaddata->stream_data; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -1262,13 +1262,13 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) u32 link_rate = 0; struct snd_intelhad *intelhaddata; struct snd_pcm_runtime *runtime; - struct had_pvt_data *had_stream; + struct had_stream_data *had_stream; pr_debug("snd_intelhad_pcm_prepare called\n"); intelhaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; - had_stream = intelhaddata->private_data; + had_stream = &intelhaddata->stream_data; if (had_get_hwstate(intelhaddata)) { pr_err("%s: HDMI cable plugged-out\n", __func__); @@ -1479,31 +1479,6 @@ struct snd_pcm_ops snd_intelhad_playback_ops = { .mmap = snd_intelhad_pcm_mmap, }; -/** - * snd_intelhad_create - to crete alsa card instance - * - * @intelhaddata: pointer to internal context - * @card: pointer to card - * - * This function is called when the hdmi cable is plugged in - */ -static int snd_intelhad_create( - struct snd_intelhad *intelhaddata, - struct snd_card *card) -{ - int retval; - static struct snd_device_ops ops = { - }; - - pr_debug("snd_intelhad_create called\n"); - - if (!intelhaddata) - return -EINVAL; - - /* ALSA api to register the device */ - retval = snd_device_new(card, SNDRV_DEV_LOWLEVEL, intelhaddata, &ops); - return retval; -} /** * snd_intelhad_pcm_free - to free the memory allocated * @@ -1596,36 +1571,24 @@ int hdmi_audio_probe(struct platform_device *devptr, struct snd_pcm *pcm; struct snd_card *card; struct snd_intelhad *intelhaddata; - struct had_pvt_data *had_stream; pr_debug("Enter %s\n", __func__); - /* allocate memory for saving internal context and working */ - intelhaddata = kzalloc(sizeof(*intelhaddata), GFP_KERNEL); - if (!intelhaddata) - return -ENOMEM; - - had_stream = kzalloc(sizeof(*had_stream), GFP_KERNEL); - if (!had_stream) { - retval = -ENOMEM; - goto free_haddata; - } + /* create a card instance with ALSA framework */ + retval = snd_card_new(&devptr->dev, hdmi_card_index, hdmi_card_id, + THIS_MODULE, sizeof(*intelhaddata), &card); + if (retval) + return retval; + intelhaddata = card->private_data; spin_lock_init(&intelhaddata->had_spinlock); intelhaddata->drv_status = HAD_DRV_DISCONNECTED; pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); - /* create a card instance with ALSA framework */ - retval = snd_card_new(&devptr->dev, hdmi_card_index, hdmi_card_id, - THIS_MODULE, 0, &card); - - if (retval) - goto free_hadstream; intelhaddata->card = card; intelhaddata->card_id = hdmi_card_id; intelhaddata->card_index = card->number; - intelhaddata->private_data = had_stream; intelhaddata->flag_underrun = 0; intelhaddata->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; strncpy(card->driver, INTEL_HAD, strlen(INTEL_HAD)); @@ -1654,12 +1617,6 @@ int hdmi_audio_probe(struct platform_device *devptr, if (retval) goto err; - /* internal function call to register device with ALSA */ - retval = snd_intelhad_create(intelhaddata, card); - if (retval) - goto err; - - card->private_data = &intelhaddata; retval = snd_card_register(card); if (retval) goto err; @@ -1688,15 +1645,9 @@ int hdmi_audio_probe(struct platform_device *devptr, *had_ret = intelhaddata; return 0; + err: snd_card_free(card); -free_hadstream: - kfree(had_stream); - pm_runtime_disable(intelhaddata->dev); - intelhaddata->dev = NULL; -free_haddata: - kfree(intelhaddata); - intelhaddata = NULL; pr_err("Error returned from %s api %#x\n", __func__, retval); return retval; } @@ -1724,8 +1675,6 @@ int hdmi_audio_remove(struct snd_intelhad *intelhaddata) had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO, NULL); } snd_card_free(intelhaddata->card); - kfree(intelhaddata->private_data); - kfree(intelhaddata); return 0; } -- cgit From 36ec0d99bbd7bb392bf64059cbda1818ee2be5a2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 08:47:05 +0100 Subject: ALSA: x86: Call snd_card_register() at the end The card registration should be done at the last stage of the probe procedure. Otherwise user-space may access to the device before the whole initialization is done. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index dfc4452afee1..82f42a6c363c 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1586,6 +1586,7 @@ int hdmi_audio_probe(struct platform_device *devptr, pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); + intelhaddata->dev = &devptr->dev; intelhaddata->card = card; intelhaddata->card_id = hdmi_card_id; intelhaddata->card_index = card->number; @@ -1617,10 +1618,6 @@ int hdmi_audio_probe(struct platform_device *devptr, if (retval) goto err; - retval = snd_card_register(card); - if (retval) - goto err; - /* IEC958 controls */ retval = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958_mask, intelhaddata)); @@ -1638,7 +1635,10 @@ int hdmi_audio_probe(struct platform_device *devptr, if (retval < 0) goto err; - intelhaddata->dev = &devptr->dev; + retval = snd_card_register(card); + if (retval) + goto err; + pm_runtime_set_active(intelhaddata->dev); pm_runtime_enable(intelhaddata->dev); -- cgit From da8648097497505d05d8cff6892351f99c029791 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 13:52:22 +0100 Subject: ALSA: x86: Flatten two abstraction layers This is the final stage for a big clean-up series. Here we flatten the two layers into one. Formerly, the implementation was split to HDMI "shell" that talks with the platform device, and HDMI audio part that communicates via caps and other event handlers. All these would be good if there were multiple instantiations or if there were data protection. But neither are true in our case. That said, it'll be easier to have a flat driver structure in the end. In this patch, the former struct hdmi_lpe_audio_ctx is forged into the existing struct snd_intelhad. The latter has already a few members that are basically the copy from the former. Only a few new members for the lowlevel I/O are added by this change. Then, the had_get_caps() and had_set_caps() are simply replaced with the direct calls to copy the data in the struct fields. Also, the had_event_handler() calls are replaced with the direct call for each event as well. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 476 ++++++++++++++++++++++++++++--------------- 1 file changed, 315 insertions(+), 161 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 82f42a6c363c..1594f826cf31 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #include "intel_hdmi_audio.h" /*standard module options for ALSA. This module supports only one card*/ @@ -168,72 +170,75 @@ int had_get_hwstate(struct snd_intelhad *intelhaddata) return 0; } -int had_get_caps(struct snd_intelhad *intelhaddata, - enum had_caps_list query, void *caps) +static inline void +mid_hdmi_audio_read(struct snd_intelhad *ctx, u32 reg, u32 *val) { - struct platform_device *pdev = to_platform_device(intelhaddata->dev); - int retval; - - retval = had_get_hwstate(intelhaddata); - if (!retval) - retval = mid_hdmi_audio_get_caps(pdev, query, caps); - - return retval; + *val = ioread32(ctx->mmio_start + ctx->had_config_offset + reg); } -int had_set_caps(struct snd_intelhad *intelhaddata, - enum had_caps_list set_element, void *caps) +static inline void +mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val) { - struct platform_device *pdev = to_platform_device(intelhaddata->dev); - int retval; - - retval = had_get_hwstate(intelhaddata); - if (!retval) - retval = mid_hdmi_audio_set_caps(pdev, set_element, caps); - - return retval; + iowrite32(val, ctx->mmio_start + ctx->had_config_offset + reg); } int had_read_register(struct snd_intelhad *intelhaddata, u32 offset, u32 *data) { - struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); - if (!retval) - retval = mid_hdmi_audio_read(pdev, offset, data); + if (retval) + return retval; - return retval; + 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; + } } int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) { - struct platform_device *pdev = to_platform_device(intelhaddata->dev); int retval; retval = had_get_hwstate(intelhaddata); - if (!retval) - retval = mid_hdmi_audio_write(pdev, offset, data); + if (retval) + return retval; - return retval; + fixup_dp_config(intelhaddata, offset, &data); + mid_hdmi_audio_write(intelhaddata, offset, data); + return 0; } int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, u32 data, u32 mask) { - struct platform_device *pdev = to_platform_device(intelhaddata->dev); + u32 val_tmp; int retval; retval = had_get_hwstate(intelhaddata); - if (!retval) - retval = mid_hdmi_audio_rmw(pdev, offset, data, mask); + if (retval) + return retval; - return retval; + 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; } -/** - * function to read-modify - * AUD_CONFIG register on VLV2.The had_read_modify() function should not - * directly be used on VLV2 for updating AUD_CONFIG register. + +/* + * function to read-modify AUD_CONFIG register on VLV2. + * The had_read_modify() function 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 * HDMI IP. As a result a read-modify of AUD_CONFIG regiter will always @@ -249,10 +254,10 @@ int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, * @mask : mask * */ -static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, +static int had_read_modify_aud_config_v2(struct snd_intelhad *intelhaddata, u32 data, u32 mask) { - struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream); + struct snd_pcm_substream *substream; union aud_cfg cfg_val = {.cfg_regval = 0}; u8 channels; @@ -260,7 +265,8 @@ static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, * If substream is NULL, there is no active stream. * In this case just set channels to 2 */ - if (substream) + substream = intelhaddata->stream_info.had_substream; + if (substream && substream->runtime) channels = substream->runtime->channels; else channels = 2; @@ -274,9 +280,23 @@ static int had_read_modify_aud_config_v2(struct snd_pcm_substream *substream, return had_read_modify(intelhaddata, AUD_CONFIG, data, mask); } -void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, u8 enable) +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_v2, &status_reg); + status_reg |= HDMI_AUDIO_BUFFER_DONE | HDMI_AUDIO_UNDERRUN; + mid_hdmi_audio_write(ctx, AUD_HDMI_STATUS_v2, status_reg); + mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS_v2, &status_reg); + } +} + +void snd_intelhad_enable_audio(struct snd_intelhad *intelhaddata, + bool enable) { - had_read_modify_aud_config_v2(substream, enable, BIT(0)); + had_read_modify_aud_config_v2(intelhaddata, enable ? BIT(0) : 0, + BIT(0)); } static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata, @@ -437,7 +457,7 @@ static int snd_intelhad_channel_allocation(struct snd_intelhad *intelhaddata, */ for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { - if (intelhaddata->eeld.speaker_allocation_block & (1 << i)) + if (intelhaddata->eld.speaker_allocation_block & (1 << i)) spk_mask |= eld_speaker_allocation_bits[i]; } @@ -482,11 +502,8 @@ void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) return; } - had_get_caps(intelhaddata, HAD_GET_ELD, &intelhaddata->eeld); - had_get_caps(intelhaddata, HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); - - pr_debug("eeld.speaker_allocation_block = %x\n", - intelhaddata->eeld.speaker_allocation_block); + pr_debug("eld.speaker_allocation_block = %x\n", + intelhaddata->eld.speaker_allocation_block); /* WA: Fix the max channel supported to 8 */ @@ -497,14 +514,14 @@ void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) */ /* if 0x2F < eld < 0x4F fall back to 0x2f, else fall back to 0x4F */ - eld_high = intelhaddata->eeld.speaker_allocation_block & eld_high_mask; + eld_high = intelhaddata->eld.speaker_allocation_block & eld_high_mask; if ((eld_high & (eld_high-1)) && (eld_high > 0x1F)) { /* eld_high & (eld_high-1): if more than 1 bit set */ /* 0x1F: 7 channels */ for (i = 1; i < 4; i++) { high_msb = eld_high & (0x80 >> i); if (high_msb) { - intelhaddata->eeld.speaker_allocation_block &= + intelhaddata->eld.speaker_allocation_block &= high_msb | 0xF; break; } @@ -512,7 +529,7 @@ void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) } for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { - if (intelhaddata->eeld.speaker_allocation_block & (1 << i)) + if (intelhaddata->eld.speaker_allocation_block & (1 << i)) spk_mask |= eld_speaker_allocation_bits[i]; } @@ -1176,7 +1193,7 @@ static int snd_intelhad_hw_free(struct snd_pcm_substream *substream) static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { - int caps, retval = 0; + int retval = 0; unsigned long flag_irq; struct snd_intelhad *intelhaddata; struct had_stream_pvt *stream; @@ -1203,15 +1220,8 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, had_stream->stream_type = HAD_RUNNING_STREAM; /* Enable Audio */ - /* - * ToDo: Need to enable UNDERRUN interrupts as well - * caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; - */ - caps = HDMI_AUDIO_BUFFER_DONE; - retval = had_set_caps(intelhaddata, HAD_SET_ENABLE_AUDIO_INT, - &caps); - retval = had_set_caps(intelhaddata, HAD_SET_ENABLE_AUDIO, NULL); - snd_intelhad_enable_audio(substream, 1); + snd_intelhad_enable_audio_int(intelhaddata, true); + snd_intelhad_enable_audio(intelhaddata, true); pr_debug("Processed _Start\n"); @@ -1228,18 +1238,13 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, had_stream->stream_type = HAD_INIT; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irq); /* Disable Audio */ - /* - * ToDo: Need to disable UNDERRUN interrupts as well - * caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; - */ - caps = HDMI_AUDIO_BUFFER_DONE; - had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO_INT, &caps); - snd_intelhad_enable_audio(substream, 0); + snd_intelhad_enable_audio_int(intelhaddata, false); + snd_intelhad_enable_audio(intelhaddata, false); /* Reset buffer pointers */ snd_intelhad_reset_audio(intelhaddata, 1); snd_intelhad_reset_audio(intelhaddata, 0); stream->stream_status = STREAM_DROPPED; - had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO, NULL); + snd_intelhad_enable_audio_int(intelhaddata, false); break; default: @@ -1297,15 +1302,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) /* Get N value in KHz */ - retval = had_get_caps(intelhaddata, HAD_GET_DISPLAY_RATE, - &disp_samp_freq); - if (retval) { - pr_err("querying display sampling freq failed %#x\n", retval); - goto prep_end; - } - - had_get_caps(intelhaddata, HAD_GET_ELD, &intelhaddata->eeld); - had_get_caps(intelhaddata, HAD_GET_DP_OUTPUT, &intelhaddata->dp_output); + disp_samp_freq = intelhaddata->tmds_clock_speed; retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, intelhaddata); @@ -1315,8 +1312,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) } if (intelhaddata->dp_output) - had_get_caps(intelhaddata, HAD_GET_LINK_RATE, &link_rate); - + link_rate = intelhaddata->link_rate; snd_intelhad_prog_cts(substream->runtime->rate, disp_samp_freq, link_rate, @@ -1425,25 +1421,22 @@ static int snd_intelhad_pcm_mmap(struct snd_pcm_substream *substream, vma->vm_end - vma->vm_start, vma->vm_page_prot); } -int hdmi_audio_mode_change(struct snd_pcm_substream *substream) +static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata) { + struct snd_pcm_substream *substream; int retval = 0; u32 disp_samp_freq, n_param; u32 link_rate = 0; - struct snd_intelhad *intelhaddata; - intelhaddata = snd_pcm_substream_chip(substream); + substream = intelhaddata->stream_info.had_substream; + if (!substream || !substream->runtime) + return 0; /* Disable Audio */ - snd_intelhad_enable_audio(substream, 0); + snd_intelhad_enable_audio(intelhaddata, false); /* Update CTS value */ - retval = had_get_caps(intelhaddata, HAD_GET_DISPLAY_RATE, - &disp_samp_freq); - if (retval) { - pr_err("querying display sampling freq failed %#x\n", retval); - goto out; - } + disp_samp_freq = intelhaddata->tmds_clock_speed; retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, intelhaddata); @@ -1453,14 +1446,14 @@ int hdmi_audio_mode_change(struct snd_pcm_substream *substream) } if (intelhaddata->dp_output) - had_get_caps(intelhaddata, HAD_GET_LINK_RATE, &link_rate); + link_rate = intelhaddata->link_rate; snd_intelhad_prog_cts(substream->runtime->rate, disp_samp_freq, link_rate, n_param, intelhaddata); /* Enable Audio */ - snd_intelhad_enable_audio(substream, 1); + snd_intelhad_enable_audio(intelhaddata, true); out: return retval; @@ -1555,129 +1548,290 @@ static struct snd_kcontrol_new had_control_iec958 = { .put = had_iec958_put }; +static void _had_wq(struct work_struct *work) +{ + struct snd_intelhad *ctx = + container_of(work, struct snd_intelhad, hdmi_audio_wq); + + had_process_hot_plug(ctx); +} + +static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) +{ + struct snd_intelhad *ctx = dev_id; + u32 audio_stat, audio_reg; + + audio_reg = AUD_HDMI_STATUS_v2; + mid_hdmi_audio_read(ctx, audio_reg, &audio_stat); + + if (audio_stat & HDMI_AUDIO_UNDERRUN) { + mid_hdmi_audio_write(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_process_buffer_done(ctx); + } + + return IRQ_HANDLED; +} + +static void notify_audio_lpe(struct platform_device *pdev) +{ + struct snd_intelhad *ctx = platform_get_drvdata(pdev); + struct intel_hdmi_lpe_audio_pdata *pdata = pdev->dev.platform_data; + + if (pdata->hdmi_connected != true) { + + dev_dbg(&pdev->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", + __func__); + + if (ctx->state == hdmi_connector_status_connected) { + + ctx->state = hdmi_connector_status_disconnected; + + had_process_hot_unplug(ctx); + } else + dev_dbg(&pdev->dev, "%s: Already Unplugged!\n", + __func__); + + } else { + struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld; + + switch (eld->pipe_id) { + case 0: + ctx->had_config_offset = AUDIO_HDMI_CONFIG_A; + break; + case 1: + ctx->had_config_offset = AUDIO_HDMI_CONFIG_B; + break; + case 2: + ctx->had_config_offset = AUDIO_HDMI_CONFIG_C; + break; + default: + dev_dbg(&pdev->dev, "Invalid pipe %d\n", + eld->pipe_id); + break; + } + + memcpy(&ctx->eld, eld->eld_data, sizeof(ctx->eld)); + + had_process_hot_plug(ctx); + + ctx->state = hdmi_connector_status_connected; + + dev_dbg(&pdev->dev, "%s: HAD_NOTIFY_ELD : port = %d, tmds = %d\n", + __func__, eld->port_id, pdata->tmds_clock_speed); + + if (pdata->tmds_clock_speed) { + ctx->tmds_clock_speed = pdata->tmds_clock_speed; + ctx->dp_output = pdata->dp_output; + ctx->link_rate = pdata->link_rate; + + /* Process mode change if stream is active */ + if (ctx->stream_data.stream_type == HAD_RUNNING_STREAM) + hdmi_audio_mode_change(ctx); + } + } +} + +/* release resources */ +static void hdmi_lpe_audio_free(struct snd_card *card) +{ + struct snd_intelhad *ctx = card->private_data; + + if (ctx->mmio_start) + iounmap(ctx->mmio_start); + if (ctx->irq >= 0) + free_irq(ctx->irq, ctx); +} + /* - * hdmi_audio_probe - to create sound card instance for HDMI audio playabck - * - * @devptr: platform device - * @had_ret: pointer to store the created snd_intelhad object + * hdmi_lpe_audio_probe - start bridge with i915 * - * This function is called when the platform device is probed. This function - * creates and registers the sound card with ALSA + * This function is called when the i915 driver creates the + * hdmi-lpe-audio platform device. Card creation is deferred until a + * hot plug event is received */ -int hdmi_audio_probe(struct platform_device *devptr, - struct snd_intelhad **had_ret) +static int hdmi_lpe_audio_probe(struct platform_device *pdev) { - int retval; - struct snd_pcm *pcm; struct snd_card *card; - struct snd_intelhad *intelhaddata; + struct snd_intelhad *ctx; + struct snd_pcm *pcm; + struct intel_hdmi_lpe_audio_pdata *pdata; + int irq; + struct resource *res_mmio; + int ret; + unsigned long flags; + + dev_dbg(&pdev->dev, "Enter %s\n", __func__); + dev_dbg(&pdev->dev, "dma_mask: %p\n", pdev->dev.dma_mask); + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "%s: quit: pdata not allocated by i915!!\n", __func__); + return -EINVAL; + } - pr_debug("Enter %s\n", __func__); + /* get resources */ + irq = platform_get_irq(pdev, 0); + if (irq < 0) { + dev_err(&pdev->dev, "Could not get irq resource\n"); + return -ENODEV; + } + + res_mmio = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res_mmio) { + dev_err(&pdev->dev, "Could not get IO_MEM resources\n"); + return -ENXIO; + } /* create a card instance with ALSA framework */ - retval = snd_card_new(&devptr->dev, hdmi_card_index, hdmi_card_id, - THIS_MODULE, sizeof(*intelhaddata), &card); - if (retval) - return retval; + ret = snd_card_new(&pdev->dev, hdmi_card_index, hdmi_card_id, + THIS_MODULE, sizeof(*ctx), &card); + if (ret) + return ret; + + ctx = card->private_data; + spin_lock_init(&ctx->had_spinlock); + ctx->drv_status = HAD_DRV_DISCONNECTED; + ctx->dev = &pdev->dev; + ctx->card = card; + ctx->card_id = hdmi_card_id; + ctx->card_index = card->number; + ctx->flag_underrun = 0; + ctx->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; + strcpy(card->driver, INTEL_HAD); + strcpy(card->shortname, INTEL_HAD); + + ctx->irq = -1; + ctx->tmds_clock_speed = DIS_SAMPLE_RATE_148_5; + INIT_WORK(&ctx->hdmi_audio_wq, _had_wq); + ctx->state = hdmi_connector_status_disconnected; + + card->private_free = hdmi_lpe_audio_free; + + /* assume pipe A as default */ + ctx->had_config_offset = AUDIO_HDMI_CONFIG_A; + + platform_set_drvdata(pdev, ctx); + + dev_dbg(&pdev->dev, "%s: mmio_start = 0x%x, mmio_end = 0x%x\n", + __func__, (unsigned int)res_mmio->start, + (unsigned int)res_mmio->end); + + ctx->mmio_start = ioremap_nocache(res_mmio->start, + (size_t)(resource_size(res_mmio))); + if (!ctx->mmio_start) { + dev_err(&pdev->dev, "Could not get ioremap\n"); + ret = -EACCES; + goto err; + } - intelhaddata = card->private_data; - spin_lock_init(&intelhaddata->had_spinlock); - intelhaddata->drv_status = HAD_DRV_DISCONNECTED; - pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", - __func__, __LINE__); + /* setup interrupt handler */ + ret = request_irq(irq, display_pipe_interrupt_handler, 0, + pdev->name, ctx); + if (ret < 0) { + dev_err(&pdev->dev, "request_irq failed\n"); + goto err; + } - intelhaddata->dev = &devptr->dev; - intelhaddata->card = card; - intelhaddata->card_id = hdmi_card_id; - intelhaddata->card_index = card->number; - intelhaddata->flag_underrun = 0; - intelhaddata->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; - strncpy(card->driver, INTEL_HAD, strlen(INTEL_HAD)); - strncpy(card->shortname, INTEL_HAD, strlen(INTEL_HAD)); - - retval = snd_pcm_new(card, INTEL_HAD, PCM_INDEX, MAX_PB_STREAMS, - MAX_CAP_STREAMS, &pcm); - if (retval) + ctx->irq = irq; + + ret = snd_pcm_new(card, INTEL_HAD, PCM_INDEX, MAX_PB_STREAMS, + MAX_CAP_STREAMS, &pcm); + if (ret) goto err; /* setup private data which can be retrieved when required */ - pcm->private_data = intelhaddata; + pcm->private_data = ctx; pcm->private_free = snd_intelhad_pcm_free; pcm->info_flags = 0; strncpy(pcm->name, card->shortname, strlen(card->shortname)); - /* setup the ops for palyabck */ + /* setup the ops for playabck */ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_intelhad_playback_ops); /* allocate dma pages for ALSA stream operations * memory allocated is based on size, not max value * thus using same argument for max & size */ - retval = snd_pcm_lib_preallocate_pages_for_all(pcm, + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, NULL, HAD_MAX_BUFFER, HAD_MAX_BUFFER); - if (retval) - goto err; /* IEC958 controls */ - retval = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958_mask, - intelhaddata)); - if (retval < 0) + ret = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958_mask, ctx)); + if (ret < 0) goto err; - retval = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958, - intelhaddata)); - if (retval < 0) + ret = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958, ctx)); + if (ret < 0) goto err; init_channel_allocations(); /* Register channel map controls */ - retval = had_register_chmap_ctls(intelhaddata, pcm); - if (retval < 0) + ret = had_register_chmap_ctls(ctx, pcm); + if (ret < 0) goto err; - retval = snd_card_register(card); - if (retval) + ret = snd_card_register(card); + if (ret) goto err; - pm_runtime_set_active(intelhaddata->dev); - pm_runtime_enable(intelhaddata->dev); + spin_lock_irqsave(&pdata->lpe_audio_slock, flags); + pdata->notify_audio_lpe = notify_audio_lpe; + if (pdata->notify_pending) { - *had_ret = intelhaddata; + dev_dbg(&pdev->dev, "%s: handle pending notification\n", __func__); + notify_audio_lpe(pdev); + pdata->notify_pending = false; + } + spin_unlock_irqrestore(&pdata->lpe_audio_slock, flags); + + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); + + schedule_work(&ctx->hdmi_audio_wq); return 0; err: snd_card_free(card); - pr_err("Error returned from %s api %#x\n", __func__, retval); - return retval; + return ret; } /* - * hdmi_audio_remove - removes the alsa card + * hdmi_lpe_audio_remove - stop bridge with i915 * - *@haddata: pointer to HAD private data - * - * This function is called when the hdmi cable is un-plugged. This function - * free the sound card. + * This function is called when the platform device is destroyed. The sound + * card should have been removed on hot plug event. */ -int hdmi_audio_remove(struct snd_intelhad *intelhaddata) +static int hdmi_lpe_audio_remove(struct platform_device *pdev) { - int caps; - - pr_debug("Enter %s\n", __func__); + struct snd_intelhad *ctx = platform_get_drvdata(pdev); - if (!intelhaddata) - return 0; + dev_dbg(&pdev->dev, "Enter %s\n", __func__); - if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { - caps = HDMI_AUDIO_UNDERRUN | HDMI_AUDIO_BUFFER_DONE; - had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO_INT, &caps); - had_set_caps(intelhaddata, HAD_SET_DISABLE_AUDIO, NULL); - } - snd_card_free(intelhaddata->card); + if (ctx->drv_status != HAD_DRV_DISCONNECTED) + snd_intelhad_enable_audio_int(ctx, false); + snd_card_free(ctx->card); return 0; } +static struct platform_driver hdmi_lpe_audio_driver = { + .driver = { + .name = "hdmi-lpe-audio", + }, + .probe = hdmi_lpe_audio_probe, + .remove = hdmi_lpe_audio_remove, + .suspend = hdmi_lpe_audio_suspend, + .resume = hdmi_lpe_audio_resume +}; + +module_platform_driver(hdmi_lpe_audio_driver); +MODULE_ALIAS("platform:hdmi_lpe_audio"); + MODULE_AUTHOR("Sailaja Bandarupalli "); MODULE_AUTHOR("Ramesh Babu K V "); MODULE_AUTHOR("Vaibhav Agarwal "); -- cgit From 372d855f87b535005e392094afff9927bc000cf9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 13:57:58 +0100 Subject: ALSA: x86: Fold intel_hdmi_audio_if.c into main file As the very last step, we fold intel_hdmi_audio_if.c into the main file, intel_hdmi_audio.c. This is merely a cleanup, and no functional change. By this move, we can mark all functions and variables as static, which allows the compiler more optimizations. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 391 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 375 insertions(+), 16 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 1594f826cf31..effe93b58273 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -157,8 +157,7 @@ static const struct snd_pcm_hardware snd_intel_hadstream = { }; /* Register access functions */ - -int had_get_hwstate(struct snd_intelhad *intelhaddata) +static int had_get_hwstate(struct snd_intelhad *intelhaddata) { /* Check for device presence -SW state */ if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { @@ -182,7 +181,8 @@ mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val) iowrite32(val, ctx->mmio_start + ctx->had_config_offset + reg); } -int had_read_register(struct snd_intelhad *intelhaddata, u32 offset, u32 *data) +static int had_read_register(struct snd_intelhad *intelhaddata, + u32 offset, u32 *data) { int retval; @@ -203,7 +203,8 @@ static void fixup_dp_config(struct snd_intelhad *intelhaddata, } } -int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) +static int had_write_register(struct snd_intelhad *intelhaddata, + u32 offset, u32 data) { int retval; @@ -216,8 +217,8 @@ int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) return 0; } -int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, - u32 data, u32 mask) +static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, + u32 data, u32 mask) { u32 val_tmp; int retval; @@ -280,7 +281,7 @@ static int had_read_modify_aud_config_v2(struct snd_intelhad *intelhaddata, return had_read_modify(intelhaddata, AUD_CONFIG, data, mask); } -void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable) +static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable) { u32 status_reg; @@ -292,8 +293,8 @@ void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable) } } -void snd_intelhad_enable_audio(struct snd_intelhad *intelhaddata, - bool enable) +static void snd_intelhad_enable_audio(struct snd_intelhad *intelhaddata, + bool enable) { had_read_modify_aud_config_v2(intelhaddata, enable ? BIT(0) : 0, BIT(0)); @@ -488,7 +489,7 @@ static int spk_to_chmap(int spk) return 0; } -void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) +static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) { int i = 0, c = 0; int spk_mask = 0; @@ -675,7 +676,7 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, * * This function programs ring buffer address and length into registers. */ -int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, +static int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, int start, int end) { u32 ring_buf_addr, ring_buf_size, period_bytes; @@ -732,7 +733,7 @@ int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, return 0; } -int snd_intelhad_read_len(struct snd_intelhad *intelhaddata) +static int snd_intelhad_read_len(struct snd_intelhad *intelhaddata) { int i, retval = 0; u32 len[4]; @@ -939,7 +940,7 @@ static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param, return 0; } -void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) +static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) { u32 hdmi_status, i = 0; @@ -1459,8 +1460,364 @@ out: return retval; } -/*PCM operations structure and the calls back for the same */ -struct snd_pcm_ops snd_intelhad_playback_ops = { +/* + * hdmi_lpe_audio_suspend - power management suspend function + * + * @pdev: platform device + * + * This function is called by client driver to suspend the + * hdmi audio. + */ +static int hdmi_lpe_audio_suspend(struct platform_device *pdev, + pm_message_t state) +{ + struct had_stream_data *had_stream; + unsigned long flag_irqs; + struct snd_pcm_substream *substream; + struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); + + pr_debug("Enter:%s\n", __func__); + + had_stream = &intelhaddata->stream_data; + substream = intelhaddata->stream_info.had_substream; + + if (intelhaddata->dev->power.runtime_status != RPM_SUSPENDED) { + pr_err("audio stream is active\n"); + return -EAGAIN; + } + + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_debug("had not connected\n"); + return 0; + } + + if (intelhaddata->drv_status == HAD_DRV_SUSPENDED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_debug("had already suspended\n"); + return 0; + } + + intelhaddata->drv_status = HAD_DRV_SUSPENDED; + pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_SUSPENDED\n", + __func__, __LINE__); + + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + snd_intelhad_enable_audio_int(intelhaddata, false); + pr_debug("Exit:%s", __func__); + return 0; +} + +/* + * hdmi_lpe_audio_resume - power management resume function + * + *@pdev: platform device + * + * This function is called by client driver to resume the + * hdmi audio. + */ +static int hdmi_lpe_audio_resume(struct platform_device *pdev) +{ + struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); + unsigned long flag_irqs; + + pr_debug("Enter:%s\n", __func__); + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_debug("had not connected\n"); + return 0; + } + + if (intelhaddata->drv_status != HAD_DRV_SUSPENDED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_err("had is not in suspended state\n"); + return 0; + } + + if (had_get_hwstate(intelhaddata)) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_err("Failed to resume. Device not accessible\n"); + return -ENODEV; + } + + intelhaddata->drv_status = HAD_DRV_CONNECTED; + pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", + __func__, __LINE__); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + snd_intelhad_enable_audio_int(intelhaddata, true); + pr_debug("Exit:%s", __func__); + return 0; +} + +static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, + enum intel_had_aud_buf_type buf_id) +{ + int i, intr_count = 0; + enum intel_had_aud_buf_type buff_done; + u32 buf_size, buf_addr; + struct had_stream_data *had_stream; + unsigned long flag_irqs; + + had_stream = &intelhaddata->stream_data; + + buff_done = buf_id; + + intr_count = snd_intelhad_read_len(intelhaddata); + if (intr_count > 1) { + /* In case of active playback */ + pr_err("Driver detected %d missed buffer done interrupt(s)!!!!\n", + (intr_count - 1)); + if (intr_count > 3) + return intr_count; + + buf_id += (intr_count - 1); + /* Reprogram registers*/ + for (i = buff_done; i < buf_id; i++) { + int j = i % 4; + + buf_size = intelhaddata->buf_info[j].buf_size; + buf_addr = intelhaddata->buf_info[j].buf_addr; + had_write_register(intelhaddata, + AUD_BUF_A_LENGTH + + (j * HAD_REG_WIDTH), buf_size); + had_write_register(intelhaddata, + AUD_BUF_A_ADDR+(j * HAD_REG_WIDTH), + (buf_addr | BIT(0) | BIT(1))); + } + buf_id = buf_id % 4; + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + intelhaddata->buff_done = buf_id; + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + } + + return intr_count; +} + +static int had_process_buffer_done(struct snd_intelhad *intelhaddata) +{ + u32 len = 1; + enum intel_had_aud_buf_type buf_id; + enum intel_had_aud_buf_type buff_done; + struct pcm_stream_info *stream; + u32 buf_size; + struct had_stream_data *had_stream; + int intr_count; + enum had_status_stream stream_type; + unsigned long flag_irqs; + + had_stream = &intelhaddata->stream_data; + stream = &intelhaddata->stream_info; + intr_count = 1; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_err("%s:Device already disconnected\n", __func__); + return 0; + } + buf_id = intelhaddata->curr_buf; + intelhaddata->buff_done = buf_id; + buff_done = intelhaddata->buff_done; + buf_size = intelhaddata->buf_info[buf_id].buf_size; + stream_type = had_stream->stream_type; + + pr_debug("Enter:%s buf_id=%d\n", __func__, buf_id); + + /* Every debug statement has an implication + * of ~5msec. Thus, avoid having >3 debug statements + * for each buffer_done handling. + */ + + /* Check for any intr_miss in case of active playback */ + if (had_stream->stream_type == HAD_RUNNING_STREAM) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + intr_count = had_chk_intrmiss(intelhaddata, buf_id); + if (!intr_count || (intr_count > 3)) { + pr_err("HAD SW state in non-recoverable!!! mode\n"); + pr_err("Already played stale data\n"); + return 0; + } + buf_id += (intr_count - 1); + buf_id = buf_id % 4; + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + } + + intelhaddata->buf_info[buf_id].is_valid = true; + if (intelhaddata->valid_buf_cnt-1 == buf_id) { + if (had_stream->stream_type >= HAD_RUNNING_STREAM) + intelhaddata->curr_buf = HAD_BUF_TYPE_A; + } else + intelhaddata->curr_buf = buf_id + 1; + + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + + if (had_get_hwstate(intelhaddata)) { + pr_err("HDMI cable plugged-out\n"); + return 0; + } + + /*Reprogram the registers with addr and length*/ + had_write_register(intelhaddata, + AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), + buf_size); + had_write_register(intelhaddata, + AUD_BUF_A_ADDR + (buf_id * HAD_REG_WIDTH), + intelhaddata->buf_info[buf_id].buf_addr | + BIT(0) | BIT(1)); + + had_read_register(intelhaddata, + AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), + &len); + pr_debug("%s:Enabled buf[%d]\n", __func__, buf_id); + + /* In case of actual data, + * report buffer_done to above ALSA layer + */ + buf_size = intelhaddata->buf_info[buf_id].buf_size; + if (stream_type >= HAD_RUNNING_STREAM) { + intelhaddata->stream_info.buffer_rendered += + (intr_count * buf_size); + stream->period_elapsed(stream->had_substream); + } + + return 0; +} + +static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) +{ + enum intel_had_aud_buf_type buf_id; + struct pcm_stream_info *stream; + struct had_stream_data *had_stream; + enum had_status_stream stream_type; + unsigned long flag_irqs; + int drv_status; + + had_stream = &intelhaddata->stream_data; + stream = &intelhaddata->stream_info; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + buf_id = intelhaddata->curr_buf; + stream_type = had_stream->stream_type; + intelhaddata->buff_done = buf_id; + drv_status = intelhaddata->drv_status; + if (stream_type == HAD_RUNNING_STREAM) + intelhaddata->curr_buf = HAD_BUF_TYPE_A; + + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + + pr_debug("Enter:%s buf_id=%d, stream_type=%d\n", + __func__, buf_id, stream_type); + + snd_intelhad_handle_underrun(intelhaddata); + + if (drv_status == HAD_DRV_DISCONNECTED) { + pr_err("%s:Device already disconnected\n", __func__); + return 0; + } + + if (stream_type == HAD_RUNNING_STREAM) { + /* Report UNDERRUN error to above layers */ + intelhaddata->flag_underrun = 1; + stream->period_elapsed(stream->had_substream); + } + + return 0; +} + +static int had_process_hot_plug(struct snd_intelhad *intelhaddata) +{ + enum intel_had_aud_buf_type buf_id; + struct snd_pcm_substream *substream; + struct had_stream_data *had_stream; + unsigned long flag_irqs; + + pr_debug("Enter:%s\n", __func__); + + substream = intelhaddata->stream_info.had_substream; + had_stream = &intelhaddata->stream_data; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + if (intelhaddata->drv_status == HAD_DRV_CONNECTED) { + pr_debug("Device already connected\n"); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + return 0; + } + buf_id = intelhaddata->curr_buf; + intelhaddata->buff_done = buf_id; + intelhaddata->drv_status = HAD_DRV_CONNECTED; + pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", + __func__, __LINE__); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + + pr_debug("Processing HOT_PLUG, buf_id = %d\n", buf_id); + + /* Safety check */ + if (substream) { + pr_debug("There should not be active PB from ALSA\n"); + pr_debug("Signifies, cable is plugged-in even before\n"); + pr_debug("processing snd_pcm_disconnect\n"); + /* Set runtime->state to hw_params done */ + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); + } + + had_build_channel_allocation_map(intelhaddata); + + return 0; +} + +static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) +{ + enum intel_had_aud_buf_type buf_id; + struct had_stream_data *had_stream; + unsigned long flag_irqs; + + pr_debug("Enter:%s\n", __func__); + + had_stream = &intelhaddata->stream_data; + buf_id = intelhaddata->curr_buf; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + pr_debug("Device already disconnected\n"); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + return 0; + + } else { + /* Disable Audio */ + snd_intelhad_enable_audio_int(intelhaddata, false); + snd_intelhad_enable_audio(intelhaddata, false); + } + + intelhaddata->drv_status = HAD_DRV_DISCONNECTED; + pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", + __func__, __LINE__); + + /* Report to above ALSA layer */ + if (intelhaddata->stream_info.had_substream != NULL) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + pr_debug("%s: unlock -> sending pcm_stop -> lock\n", __func__); + snd_pcm_stop(intelhaddata->stream_info.had_substream, + SNDRV_PCM_STATE_SETUP); + spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + } + + had_stream->stream_type = HAD_INIT; + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + kfree(intelhaddata->chmap->chmap); + intelhaddata->chmap->chmap = NULL; + intelhaddata->audio_reg_base = NULL; + pr_debug("%s: unlocked -> returned\n", __func__); + + return 0; +} + +/* PCM operations structure and the calls back for the same */ +static struct snd_pcm_ops snd_intelhad_playback_ops = { .open = snd_intelhad_open, .close = snd_intelhad_close, .ioctl = snd_pcm_lib_ioctl, @@ -1472,7 +1829,7 @@ struct snd_pcm_ops snd_intelhad_playback_ops = { .mmap = snd_intelhad_pcm_mmap, }; -/** +/* * snd_intelhad_pcm_free - to free the memory allocated * * @pcm: pointer to pcm instance @@ -1505,6 +1862,7 @@ static int had_iec958_get(struct snd_kcontrol *kcontrol, (intelhaddata->aes_bits >> 24) & 0xff; return 0; } + static int had_iec958_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1514,6 +1872,7 @@ static int had_iec958_mask_get(struct snd_kcontrol *kcontrol, ucontrol->value.iec958.status[3] = 0xff; return 0; } + static int had_iec958_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { -- cgit From c75b0476245ad01306e4ea510bb3f7591767079f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 15:49:15 +0100 Subject: ALSA: x86: Replace pr_xxx() with dev_xxx() dev_xxx() helpers give a tidier output in general. While we're at it, remove many useless debug prints (e.g. the ones at each function entry), replace some too verbose errors with debugs, and use WARN_ON() for some serious errors. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 205 ++++++++++++++++++------------------------- 1 file changed, 84 insertions(+), 121 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index effe93b58273..41105092c114 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -21,8 +21,6 @@ * ALSA driver for Intel HDMI audio */ -#define pr_fmt(fmt) "had: " fmt - #include #include #include @@ -160,11 +158,8 @@ static const struct snd_pcm_hardware snd_intel_hadstream = { static int had_get_hwstate(struct snd_intelhad *intelhaddata) { /* Check for device presence -SW state */ - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - pr_debug("%s:Device not connected:%d\n", __func__, - intelhaddata->drv_status); + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) return -ENODEV; - } return 0; } @@ -276,7 +271,8 @@ static int had_read_modify_aud_config_v2(struct snd_intelhad *intelhaddata, data = data | cfg_val.cfg_regval; mask = mask | AUD_CONFIG_CH_MASK_V2; - pr_debug("%s : data = %x, mask =%x\n", __func__, data, mask); + dev_dbg(intelhaddata->dev, "%s : data = %x, mask =%x\n", + __func__, data, mask); return had_read_modify(intelhaddata, AUD_CONFIG, data, mask); } @@ -318,8 +314,6 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, union aud_ch_status_1 ch_stat1 = {.status_1_regval = 0}; int format; - pr_debug("Entry %s\n", __func__); - ch_stat0.status_0_regx.lpcm_id = (intelhaddata->aes_bits & IEC958_AES0_NONAUDIO)>>1; ch_stat0.status_0_regx.clk_acc = (intelhaddata->aes_bits & @@ -415,8 +409,6 @@ static void init_channel_allocations(void) int i, j; struct cea_channel_speaker_allocation *p; - pr_debug("%s: Enter\n", __func__); - for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { p = channel_allocations + i; p->channels = 0; @@ -472,7 +464,7 @@ static int snd_intelhad_channel_allocation(struct snd_intelhad *intelhaddata, } } - pr_debug("HDMI: select CA 0x%x for %d\n", ca, channels); + dev_dbg(intelhaddata->dev, "select CA 0x%x for %d\n", ca, channels); return ca; } @@ -503,7 +495,7 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) return; } - pr_debug("eld.speaker_allocation_block = %x\n", + dev_dbg(intelhaddata->dev, "eld.speaker_allocation_block = %x\n", intelhaddata->eld.speaker_allocation_block); /* WA: Fix the max channel supported to 8 */ @@ -583,10 +575,8 @@ static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol, if (intelhaddata->chmap->chmap == NULL) return -ENODATA; chmap = intelhaddata->chmap->chmap; - for (i = 0; i < chmap->channels; i++) { + for (i = 0; i < chmap->channels; i++) ucontrol->value.integer.value[i] = chmap->map[i]; - pr_debug("chmap->map[%d] = %d\n", i, chmap->map[i]); - } return 0; } @@ -684,11 +674,8 @@ static int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, struct snd_pcm_substream *substream; substream = intelhaddata->stream_info.had_substream; - if (!substream) { - pr_err("substream is NULL\n"); - dump_stack(); + if (WARN_ON(!substream)) return 0; - } ring_buf_addr = substream->runtime->dma_addr; ring_buf_size = snd_pcm_lib_buffer_bytes(substream); @@ -726,9 +713,10 @@ static int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, period_bytes); intelhaddata->buf_info[i].is_valid = true; } - pr_debug("%s:buf[%d-%d] addr=%#x and size=%d\n", __func__, start, end, - intelhaddata->buf_info[start].buf_addr, - intelhaddata->buf_info[start].buf_size); + dev_dbg(intelhaddata->dev, "%s:buf[%d-%d] addr=%#x and size=%d\n", + __func__, start, end, + intelhaddata->buf_info[start].buf_addr, + intelhaddata->buf_info[start].buf_size); intelhaddata->valid_buf_cnt = num_periods; return 0; } @@ -747,7 +735,8 @@ static int snd_intelhad_read_len(struct snd_intelhad *intelhaddata) } if (retval != 1) { for (i = 0; i < 4 ; i++) - pr_debug("buf[%d] size=%d\n", i, len[i]); + dev_dbg(intelhaddata->dev, "buf[%d] size=%d\n", + i, len[i]); } return retval; @@ -858,7 +847,7 @@ static void snd_intelhad_prog_cts(u32 aud_samp_freq, u32 tmds, divisor = 128 * aud_samp_freq; cts_val = div64_u64(dividend, divisor); } - pr_debug("TMDS value=%d, N value=%d, CTS Value=%d\n", + dev_dbg(intelhaddata->dev, "TMDS value=%d, N value=%d, CTS Value=%d\n", tmds, n_param, cts_val); had_write_register(intelhaddata, AUD_HDMI_CTS, (BIT(24) | cts_val)); } @@ -956,7 +945,7 @@ static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) do { /* clear bit30, 31 AUD_HDMI_STATUS */ had_read_register(intelhaddata, AUD_HDMI_STATUS_v2, &hdmi_status); - pr_debug("HDMI status =0x%x\n", hdmi_status); + dev_dbg(intelhaddata->dev, "HDMI status =0x%x\n", hdmi_status); if (hdmi_status & AUD_CONFIG_MASK_UNDERRUN) { i++; had_write_register(intelhaddata, @@ -965,7 +954,7 @@ static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) break; } while (i < MAX_CNT); if (i >= MAX_CNT) - pr_err("Unable to clear UNDERRUN bits\n"); + dev_err(intelhaddata->dev, "Unable to clear UNDERRUN bits\n"); } /** @@ -982,7 +971,6 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) struct had_stream_data *had_stream; int retval; - pr_debug("snd_intelhad_open called\n"); intelhaddata = snd_pcm_substream_chip(substream); had_stream = &intelhaddata->stream_data; runtime = substream->runtime; @@ -991,14 +979,15 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) pm_runtime_get(intelhaddata->dev); if (had_get_hwstate(intelhaddata)) { - pr_err("%s: HDMI cable plugged-out\n", __func__); + dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", + __func__); retval = -ENODEV; goto exit_put_handle; } /* Check, if device already in use */ if (runtime->private_data) { - pr_err("Device already in use\n"); + dev_dbg(intelhaddata->dev, "Device already in use\n"); retval = -EBUSY; goto exit_put_handle; } @@ -1025,7 +1014,8 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) retval = snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64); if (retval < 0) { - pr_err("%s:step_size=64 failed,err=%d\n", __func__, retval); + dev_dbg(intelhaddata->dev, "%s:step_size=64 failed,err=%d\n", + __func__, retval); goto exit_err; } @@ -1048,8 +1038,6 @@ static void had_period_elapsed(void *had_substream) struct snd_pcm_substream *substream = had_substream; struct had_stream_pvt *stream; - /* pr_debug("had_period_elapsed called\n"); */ - if (!substream || !substream->runtime) return; stream = substream->runtime->private_data; @@ -1070,9 +1058,6 @@ static int snd_intelhad_init_stream(struct snd_pcm_substream *substream) { struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream); - pr_debug("snd_intelhad_init_stream called\n"); - - pr_debug("setting buffer ptr param\n"); intelhaddata->stream_info.period_elapsed = had_period_elapsed; intelhaddata->stream_info.had_substream = substream; intelhaddata->stream_info.buffer_ptr = 0; @@ -1093,15 +1078,11 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) struct snd_intelhad *intelhaddata; struct snd_pcm_runtime *runtime; - pr_debug("snd_intelhad_close called\n"); - intelhaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; - if (!runtime->private_data) { - pr_debug("close() might have called after failed open"); + if (WARN_ON(!runtime->private_data)) return 0; - } intelhaddata->stream_info.buffer_rendered = 0; intelhaddata->stream_info.buffer_ptr = 0; @@ -1111,7 +1092,8 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) /* Check if following drv_status modification is required - VA */ if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { intelhaddata->drv_status = HAD_DRV_CONNECTED; - pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", + dev_dbg(intelhaddata->dev, + "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", __func__, __LINE__); } kfree(runtime->private_data); @@ -1132,25 +1114,27 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) static int snd_intelhad_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) { + struct snd_intelhad *intelhaddata; unsigned long addr; int pages, buf_size, retval; - pr_debug("snd_intelhad_hw_params called\n"); - if (!hw_params) return -EINVAL; + intelhaddata = snd_pcm_substream_chip(substream); buf_size = params_buffer_bytes(hw_params); retval = snd_pcm_lib_malloc_pages(substream, buf_size); if (retval < 0) return retval; - pr_debug("%s:allocated memory = %d\n", __func__, buf_size); + dev_dbg(intelhaddata->dev, "%s:allocated memory = %d\n", + __func__, buf_size); /* mark the pages as uncached region */ addr = (unsigned long) substream->runtime->dma_area; pages = (substream->runtime->dma_bytes + PAGE_SIZE - 1) / PAGE_SIZE; retval = set_memory_uc(addr, pages); if (retval) { - pr_err("set_memory_uc failed.Error:%d\n", retval); + dev_err(intelhaddata->dev, "set_memory_uc failed.Error:%d\n", + retval); return retval; } memset(substream->runtime->dma_area, 0, buf_size); @@ -1172,8 +1156,6 @@ static int snd_intelhad_hw_free(struct snd_pcm_substream *substream) unsigned long addr; u32 pages; - pr_debug("snd_intelhad_hw_free called\n"); - /* mark back the pages as cached/writeback region before the free */ if (substream->runtime->dma_area != NULL) { addr = (unsigned long) substream->runtime->dma_area; @@ -1200,19 +1182,16 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, struct had_stream_pvt *stream; struct had_stream_data *had_stream; - pr_debug("snd_intelhad_pcm_trigger called\n"); - intelhaddata = snd_pcm_substream_chip(substream); stream = substream->runtime->private_data; had_stream = &intelhaddata->stream_data; switch (cmd) { case SNDRV_PCM_TRIGGER_START: - pr_debug("Trigger Start\n"); - /* Disable local INTRs till register prgmng is done */ if (had_get_hwstate(intelhaddata)) { - pr_err("_START: HDMI cable plugged-out\n"); + dev_dbg(intelhaddata->dev, + "_START: HDMI cable plugged-out\n"); retval = -ENODEV; break; } @@ -1223,18 +1202,14 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, /* Enable Audio */ snd_intelhad_enable_audio_int(intelhaddata, true); snd_intelhad_enable_audio(intelhaddata, true); - - pr_debug("Processed _Start\n"); - break; case SNDRV_PCM_TRIGGER_STOP: - pr_debug("Trigger Stop\n"); spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irq); intelhaddata->stream_info.str_id = 0; intelhaddata->curr_buf = 0; - /* Stop reporting BUFFER_DONE/UNDERRUN to above layers*/ + /* Stop reporting BUFFER_DONE/UNDERRUN to above layers */ had_stream->stream_type = HAD_INIT; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irq); @@ -1270,27 +1245,28 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime; struct had_stream_data *had_stream; - pr_debug("snd_intelhad_pcm_prepare called\n"); - intelhaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; had_stream = &intelhaddata->stream_data; if (had_get_hwstate(intelhaddata)) { - pr_err("%s: HDMI cable plugged-out\n", __func__); + dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", + __func__); retval = -ENODEV; goto prep_end; } - pr_debug("period_size=%d\n", + dev_dbg(intelhaddata->dev, "period_size=%d\n", (int)frames_to_bytes(runtime, runtime->period_size)); - pr_debug("periods=%d\n", runtime->periods); - pr_debug("buffer_size=%d\n", (int)snd_pcm_lib_buffer_bytes(substream)); - pr_debug("rate=%d\n", runtime->rate); - pr_debug("channels=%d\n", runtime->channels); + dev_dbg(intelhaddata->dev, "periods=%d\n", runtime->periods); + dev_dbg(intelhaddata->dev, "buffer_size=%d\n", + (int)snd_pcm_lib_buffer_bytes(substream)); + dev_dbg(intelhaddata->dev, "rate=%d\n", runtime->rate); + dev_dbg(intelhaddata->dev, "channels=%d\n", runtime->channels); if (intelhaddata->stream_info.str_id) { - pr_debug("_prepare is called for existing str_id#%d\n", + dev_dbg(intelhaddata->dev, + "_prepare is called for existing str_id#%d\n", intelhaddata->stream_info.str_id); retval = snd_intelhad_pcm_trigger(substream, SNDRV_PCM_TRIGGER_STOP); @@ -1308,7 +1284,8 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, intelhaddata); if (retval) { - pr_err("programming N value failed %#x\n", retval); + dev_err(intelhaddata->dev, + "programming N value failed %#x\n", retval); goto prep_end; } @@ -1354,8 +1331,6 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( u32 t; int buf_id; - /* pr_debug("snd_intelhad_pcm_pointer called\n"); */ - intelhaddata = snd_pcm_substream_chip(substream); if (intelhaddata->flag_underrun) { @@ -1373,11 +1348,13 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( if ((t == 0) || (t == ((u32)-1L))) { intelhaddata->underrun_count++; - pr_debug("discovered buffer done for buf %d, count = %d\n", + dev_dbg(intelhaddata->dev, + "discovered buffer done for buf %d, count = %d\n", buf_id, intelhaddata->underrun_count); if (intelhaddata->underrun_count > (HAD_MIN_PERIODS/2)) { - pr_debug("assume audio_codec_reset, underrun = %d - do xrun\n", + dev_dbg(intelhaddata->dev, + "assume audio_codec_reset, underrun = %d - do xrun\n", intelhaddata->underrun_count); intelhaddata->underrun_count = 0; return SNDRV_PCM_POS_XRUN; @@ -1412,10 +1389,6 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( static int snd_intelhad_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { - - pr_debug("snd_intelhad_pcm_mmap called\n"); - - pr_debug("entry with prot:%s\n", __func__); vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); return remap_pfn_range(vma, vma->vm_start, substream->dma_buffer.addr >> PAGE_SHIFT, @@ -1442,7 +1415,8 @@ static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata) retval = snd_intelhad_prog_n(substream->runtime->rate, &n_param, intelhaddata); if (retval) { - pr_err("programming N value failed %#x\n", retval); + dev_err(intelhaddata->dev, + "programming N value failed %#x\n", retval); goto out; } @@ -1476,13 +1450,11 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, struct snd_pcm_substream *substream; struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); - pr_debug("Enter:%s\n", __func__); - had_stream = &intelhaddata->stream_data; substream = intelhaddata->stream_info.had_substream; if (intelhaddata->dev->power.runtime_status != RPM_SUSPENDED) { - pr_err("audio stream is active\n"); + dev_err(intelhaddata->dev, "audio stream is active\n"); return -EAGAIN; } @@ -1490,23 +1462,23 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("had not connected\n"); + dev_dbg(intelhaddata->dev, "had not connected\n"); return 0; } if (intelhaddata->drv_status == HAD_DRV_SUSPENDED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("had already suspended\n"); + dev_dbg(intelhaddata->dev, "had already suspended\n"); return 0; } intelhaddata->drv_status = HAD_DRV_SUSPENDED; - pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_SUSPENDED\n", + dev_dbg(intelhaddata->dev, + "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_SUSPENDED\n", __func__, __LINE__); spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); snd_intelhad_enable_audio_int(intelhaddata, false); - pr_debug("Exit:%s", __func__); return 0; } @@ -1523,33 +1495,32 @@ static int hdmi_lpe_audio_resume(struct platform_device *pdev) struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); unsigned long flag_irqs; - pr_debug("Enter:%s\n", __func__); - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("had not connected\n"); + dev_dbg(intelhaddata->dev, "had not connected\n"); return 0; } if (intelhaddata->drv_status != HAD_DRV_SUSPENDED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_err("had is not in suspended state\n"); + dev_err(intelhaddata->dev, "had is not in suspended state\n"); return 0; } if (had_get_hwstate(intelhaddata)) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_err("Failed to resume. Device not accessible\n"); + dev_err(intelhaddata->dev, + "Failed to resume. Device not accessible\n"); return -ENODEV; } intelhaddata->drv_status = HAD_DRV_CONNECTED; - pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", + dev_dbg(intelhaddata->dev, + "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); snd_intelhad_enable_audio_int(intelhaddata, true); - pr_debug("Exit:%s", __func__); return 0; } @@ -1569,8 +1540,9 @@ static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, intr_count = snd_intelhad_read_len(intelhaddata); if (intr_count > 1) { /* In case of active playback */ - pr_err("Driver detected %d missed buffer done interrupt(s)!!!!\n", - (intr_count - 1)); + dev_err(intelhaddata->dev, + "Driver detected %d missed buffer done interrupt(s)\n", + (intr_count - 1)); if (intr_count > 3) return intr_count; @@ -1616,7 +1588,8 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_err("%s:Device already disconnected\n", __func__); + dev_dbg(intelhaddata->dev, + "%s:Device already disconnected\n", __func__); return 0; } buf_id = intelhaddata->curr_buf; @@ -1625,8 +1598,6 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) buf_size = intelhaddata->buf_info[buf_id].buf_size; stream_type = had_stream->stream_type; - pr_debug("Enter:%s buf_id=%d\n", __func__, buf_id); - /* Every debug statement has an implication * of ~5msec. Thus, avoid having >3 debug statements * for each buffer_done handling. @@ -1637,8 +1608,8 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); intr_count = had_chk_intrmiss(intelhaddata, buf_id); if (!intr_count || (intr_count > 3)) { - pr_err("HAD SW state in non-recoverable!!! mode\n"); - pr_err("Already played stale data\n"); + dev_err(intelhaddata->dev, + "HAD SW state in non-recoverable mode\n"); return 0; } buf_id += (intr_count - 1); @@ -1656,7 +1627,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); if (had_get_hwstate(intelhaddata)) { - pr_err("HDMI cable plugged-out\n"); + dev_dbg(intelhaddata->dev, "HDMI cable plugged-out\n"); return 0; } @@ -1672,7 +1643,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) had_read_register(intelhaddata, AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), &len); - pr_debug("%s:Enabled buf[%d]\n", __func__, buf_id); + dev_dbg(intelhaddata->dev, "%s:Enabled buf[%d]\n", __func__, buf_id); /* In case of actual data, * report buffer_done to above ALSA layer @@ -1709,13 +1680,14 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("Enter:%s buf_id=%d, stream_type=%d\n", + dev_dbg(intelhaddata->dev, "Enter:%s buf_id=%d, stream_type=%d\n", __func__, buf_id, stream_type); snd_intelhad_handle_underrun(intelhaddata); if (drv_status == HAD_DRV_DISCONNECTED) { - pr_err("%s:Device already disconnected\n", __func__); + dev_dbg(intelhaddata->dev, + "%s:Device already disconnected\n", __func__); return 0; } @@ -1735,31 +1707,30 @@ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) struct had_stream_data *had_stream; unsigned long flag_irqs; - pr_debug("Enter:%s\n", __func__); - substream = intelhaddata->stream_info.had_substream; had_stream = &intelhaddata->stream_data; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_CONNECTED) { - pr_debug("Device already connected\n"); + dev_dbg(intelhaddata->dev, "Device already connected\n"); spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); return 0; } buf_id = intelhaddata->curr_buf; intelhaddata->buff_done = buf_id; intelhaddata->drv_status = HAD_DRV_CONNECTED; - pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", + dev_dbg(intelhaddata->dev, + "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", __func__, __LINE__); spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("Processing HOT_PLUG, buf_id = %d\n", buf_id); + dev_dbg(intelhaddata->dev, "Processing HOT_PLUG, buf_id = %d\n", + buf_id); /* Safety check */ if (substream) { - pr_debug("There should not be active PB from ALSA\n"); - pr_debug("Signifies, cable is plugged-in even before\n"); - pr_debug("processing snd_pcm_disconnect\n"); + dev_dbg(intelhaddata->dev, + "Force to stop the active stream by disconnection\n"); /* Set runtime->state to hw_params done */ snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); } @@ -1775,15 +1746,13 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) struct had_stream_data *had_stream; unsigned long flag_irqs; - pr_debug("Enter:%s\n", __func__); - had_stream = &intelhaddata->stream_data; buf_id = intelhaddata->curr_buf; spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - pr_debug("Device already disconnected\n"); + dev_dbg(intelhaddata->dev, "Device already disconnected\n"); spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); return 0; @@ -1794,13 +1763,13 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) } intelhaddata->drv_status = HAD_DRV_DISCONNECTED; - pr_debug("%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", + dev_dbg(intelhaddata->dev, + "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); /* Report to above ALSA layer */ if (intelhaddata->stream_info.had_substream != NULL) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - pr_debug("%s: unlock -> sending pcm_stop -> lock\n", __func__); snd_pcm_stop(intelhaddata->stream_info.had_substream, SNDRV_PCM_STATE_SETUP); spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); @@ -1811,7 +1780,6 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) kfree(intelhaddata->chmap->chmap); intelhaddata->chmap->chmap = NULL; intelhaddata->audio_reg_base = NULL; - pr_debug("%s: unlocked -> returned\n", __func__); return 0; } @@ -1837,7 +1805,6 @@ static struct snd_pcm_ops snd_intelhad_playback_ops = { */ static void snd_intelhad_pcm_free(struct snd_pcm *pcm) { - pr_debug("Freeing PCM preallocated pages\n"); snd_pcm_lib_preallocate_free_for_all(pcm); } @@ -1879,7 +1846,6 @@ static int had_iec958_put(struct snd_kcontrol *kcontrol, unsigned int val; struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol); - pr_debug("entered had_iec958_put\n"); val = (ucontrol->value.iec958.status[0] << 0) | (ucontrol->value.iec958.status[1] << 8) | (ucontrol->value.iec958.status[2] << 16) | @@ -2024,7 +1990,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) int ret; unsigned long flags; - dev_dbg(&pdev->dev, "Enter %s\n", __func__); dev_dbg(&pdev->dev, "dma_mask: %p\n", pdev->dev.dma_mask); pdata = pdev->dev.platform_data; @@ -2170,8 +2135,6 @@ static int hdmi_lpe_audio_remove(struct platform_device *pdev) { struct snd_intelhad *ctx = platform_get_drvdata(pdev); - dev_dbg(&pdev->dev, "Enter %s\n", __func__); - if (ctx->drv_status != HAD_DRV_DISCONNECTED) snd_intelhad_enable_audio_int(ctx, false); snd_card_free(ctx->card); -- cgit From e29c0f967261b0f6a95e05a224341be8f59df2d5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 17:27:48 +0100 Subject: ALSA: x86: Fix for CONFIG_PM=n The direct access to power.runtime_status is taboo, let's use a helper macro to avoid the compile error with CONFIG_PM=n. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 41105092c114..fbfbf5e2b5ad 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1453,7 +1453,7 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, had_stream = &intelhaddata->stream_data; substream = intelhaddata->stream_info.had_substream; - if (intelhaddata->dev->power.runtime_status != RPM_SUSPENDED) { + if (!pm_runtime_status_suspended(intelhaddata->dev)) { dev_err(intelhaddata->dev, "audio stream is active\n"); return -EAGAIN; } -- cgit From df76df12f178642cac616b86a762d2ee749fe402 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 16:04:10 +0100 Subject: ALSA: x86: Remove indirect call of snd_pcm_period_elapsed() Again another indirect call... Let's straighten it up. Also define the had_stream field with a proper type instead of a void pointer. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index fbfbf5e2b5ad..8b25687601ac 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1028,14 +1028,12 @@ exit_put_handle: return retval; } -/** +/* * had_period_elapsed - updates the hardware pointer status - * @had_substream:substream for which the stream function is called - * + * @had_substream: substream for which the stream function is called */ -static void had_period_elapsed(void *had_substream) +static void had_period_elapsed(struct snd_pcm_substream *substream) { - struct snd_pcm_substream *substream = had_substream; struct had_stream_pvt *stream; if (!substream || !substream->runtime) @@ -1058,7 +1056,6 @@ static int snd_intelhad_init_stream(struct snd_pcm_substream *substream) { struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream); - intelhaddata->stream_info.period_elapsed = had_period_elapsed; intelhaddata->stream_info.had_substream = substream; intelhaddata->stream_info.buffer_ptr = 0; intelhaddata->stream_info.buffer_rendered = 0; @@ -1648,11 +1645,11 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) /* In case of actual data, * report buffer_done to above ALSA layer */ - buf_size = intelhaddata->buf_info[buf_id].buf_size; + buf_size = intelhaddata->buf_info[buf_id].buf_size; if (stream_type >= HAD_RUNNING_STREAM) { intelhaddata->stream_info.buffer_rendered += (intr_count * buf_size); - stream->period_elapsed(stream->had_substream); + had_period_elapsed(stream->had_substream); } return 0; @@ -1694,7 +1691,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) if (stream_type == HAD_RUNNING_STREAM) { /* Report UNDERRUN error to above layers */ intelhaddata->flag_underrun = 1; - stream->period_elapsed(stream->had_substream); + had_period_elapsed(stream->had_substream); } return 0; -- cgit From e9d65abfa63fad3da372a3852dcade88b5506f4c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 16:11:27 +0100 Subject: ALSA: x86: Drop unused fields from snd_intelhad struct Also change the flag_underrun to bool to be clearer. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 8b25687601ac..0a14f5dacb00 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -593,9 +593,8 @@ static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata, return err; intelhaddata->chmap->private_data = intelhaddata; - intelhaddata->kctl = intelhaddata->chmap->kctl; - intelhaddata->kctl->info = had_chmap_ctl_info; - intelhaddata->kctl->get = had_chmap_ctl_get; + intelhaddata->chmap->kctl->info = had_chmap_ctl_info; + intelhaddata->chmap->kctl->get = had_chmap_ctl_get; intelhaddata->chmap->chmap = NULL; return 0; } @@ -1331,7 +1330,7 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( intelhaddata = snd_pcm_substream_chip(substream); if (intelhaddata->flag_underrun) { - intelhaddata->flag_underrun = 0; + intelhaddata->flag_underrun = false; return SNDRV_PCM_POS_XRUN; } @@ -1690,7 +1689,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) if (stream_type == HAD_RUNNING_STREAM) { /* Report UNDERRUN error to above layers */ - intelhaddata->flag_underrun = 1; + intelhaddata->flag_underrun = true; had_period_elapsed(stream->had_substream); } @@ -1776,7 +1775,6 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); kfree(intelhaddata->chmap->chmap); intelhaddata->chmap->chmap = NULL; - intelhaddata->audio_reg_base = NULL; return 0; } @@ -2019,9 +2017,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ctx->drv_status = HAD_DRV_DISCONNECTED; ctx->dev = &pdev->dev; ctx->card = card; - ctx->card_id = hdmi_card_id; - ctx->card_index = card->number; - ctx->flag_underrun = 0; + ctx->flag_underrun = false; ctx->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; strcpy(card->driver, INTEL_HAD); strcpy(card->shortname, INTEL_HAD); -- cgit From f6a82a0c01e51dd494b6eb68861473368355e58b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 16:17:14 +0100 Subject: ALSA: x86: Drop superfluous PCM private_free snd_pcm_lib_preallocate_free_for_all() doesn't have to be called from each driver as it's called in the PCM core. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 0a14f5dacb00..28eb980d2d2e 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1792,17 +1792,6 @@ static struct snd_pcm_ops snd_intelhad_playback_ops = { .mmap = snd_intelhad_pcm_mmap, }; -/* - * snd_intelhad_pcm_free - to free the memory allocated - * - * @pcm: pointer to pcm instance - * This function is called when the device is removed - */ -static void snd_intelhad_pcm_free(struct snd_pcm *pcm) -{ - snd_pcm_lib_preallocate_free_for_all(pcm); -} - static int had_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2063,7 +2052,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) /* setup private data which can be retrieved when required */ pcm->private_data = ctx; - pcm->private_free = snd_intelhad_pcm_free; pcm->info_flags = 0; strncpy(pcm->name, card->shortname, strlen(card->shortname)); /* setup the ops for playabck */ -- cgit From 99b2ab9d3aa08824dfefd7d9ad9f2b4c19555d05 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 16:26:10 +0100 Subject: ALSA: x86: Fix sleep-in-atomic via i915 notification i915 notification is executed in a spinlock, thus it must not sleep; i.e. we can't use kmalloc with GFP_KERNEL or such. For making it working properly, move the notification handler in a work, and handle it gracefully. We have already such a work, and it was used just at the start. This can be re-used in a more generic hotplug handling. Also, the patch adds the proper call of cancel_work_sync() to the destructor. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 51 +++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 27 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 28eb980d2d2e..ab199b5deaa5 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1857,14 +1857,6 @@ static struct snd_kcontrol_new had_control_iec958 = { .put = had_iec958_put }; -static void _had_wq(struct work_struct *work) -{ - struct snd_intelhad *ctx = - container_of(work, struct snd_intelhad, hdmi_audio_wq); - - had_process_hot_plug(ctx); -} - static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) { struct snd_intelhad *ctx = dev_id; @@ -1889,21 +1881,28 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) static void notify_audio_lpe(struct platform_device *pdev) { struct snd_intelhad *ctx = platform_get_drvdata(pdev); - struct intel_hdmi_lpe_audio_pdata *pdata = pdev->dev.platform_data; - - if (pdata->hdmi_connected != true) { - dev_dbg(&pdev->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", - __func__); + schedule_work(&ctx->hdmi_audio_wq); +} - if (ctx->state == hdmi_connector_status_connected) { +static void had_audio_wq(struct work_struct *work) +{ + struct snd_intelhad *ctx = + container_of(work, struct snd_intelhad, hdmi_audio_wq); + struct intel_hdmi_lpe_audio_pdata *pdata = ctx->dev->platform_data; - ctx->state = hdmi_connector_status_disconnected; + if (!pdata->hdmi_connected) { + dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", + __func__); - had_process_hot_unplug(ctx); - } else - dev_dbg(&pdev->dev, "%s: Already Unplugged!\n", + if (ctx->state != hdmi_connector_status_connected) { + dev_dbg(ctx->dev, "%s: Already Unplugged!\n", __func__); + return; + } + + ctx->state = hdmi_connector_status_disconnected; + had_process_hot_unplug(ctx); } else { struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld; @@ -1919,7 +1918,7 @@ static void notify_audio_lpe(struct platform_device *pdev) ctx->had_config_offset = AUDIO_HDMI_CONFIG_C; break; default: - dev_dbg(&pdev->dev, "Invalid pipe %d\n", + dev_dbg(ctx->dev, "Invalid pipe %d\n", eld->pipe_id); break; } @@ -1930,7 +1929,7 @@ static void notify_audio_lpe(struct platform_device *pdev) ctx->state = hdmi_connector_status_connected; - dev_dbg(&pdev->dev, "%s: HAD_NOTIFY_ELD : port = %d, tmds = %d\n", + dev_dbg(ctx->dev, "%s: HAD_NOTIFY_ELD : port = %d, tmds = %d\n", __func__, eld->port_id, pdata->tmds_clock_speed); if (pdata->tmds_clock_speed) { @@ -1950,6 +1949,8 @@ static void hdmi_lpe_audio_free(struct snd_card *card) { struct snd_intelhad *ctx = card->private_data; + cancel_work_sync(&ctx->hdmi_audio_wq); + if (ctx->mmio_start) iounmap(ctx->mmio_start); if (ctx->irq >= 0) @@ -2013,7 +2014,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ctx->irq = -1; ctx->tmds_clock_speed = DIS_SAMPLE_RATE_148_5; - INIT_WORK(&ctx->hdmi_audio_wq, _had_wq); + INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq); ctx->state = hdmi_connector_status_disconnected; card->private_free = hdmi_lpe_audio_free; @@ -2086,17 +2087,13 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) spin_lock_irqsave(&pdata->lpe_audio_slock, flags); pdata->notify_audio_lpe = notify_audio_lpe; - if (pdata->notify_pending) { - - dev_dbg(&pdev->dev, "%s: handle pending notification\n", __func__); - notify_audio_lpe(pdev); - pdata->notify_pending = false; - } + pdata->notify_pending = false; spin_unlock_irqrestore(&pdata->lpe_audio_slock, flags); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); + dev_dbg(&pdev->dev, "%s: handle pending notification\n", __func__); schedule_work(&ctx->hdmi_audio_wq); return 0; -- cgit From caa2a61a702a2a391b2fb695fc245ca5b8a4ffd8 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 16:38:22 +0100 Subject: ALSA: x86: Remove superfluous check at resume The had_get_hwstate() is identical with drv_status==DISCONECTED, which was already checked before the call. And, returning an error at resume is simply bad. That is, we should just kill this check. Also, spewing an error at resume for drv_status!=SUSPENDED is also annoying, as this is the normal case when the suspend was called without the monitor connection. Make it debug, too. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index ab199b5deaa5..835e0f2c4f0b 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1454,7 +1454,6 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, return -EAGAIN; } - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); @@ -1500,17 +1499,10 @@ static int hdmi_lpe_audio_resume(struct platform_device *pdev) if (intelhaddata->drv_status != HAD_DRV_SUSPENDED) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - dev_err(intelhaddata->dev, "had is not in suspended state\n"); + dev_dbg(intelhaddata->dev, "had is not in suspended state\n"); return 0; } - if (had_get_hwstate(intelhaddata)) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - dev_err(intelhaddata->dev, - "Failed to resume. Device not accessible\n"); - return -ENODEV; - } - intelhaddata->drv_status = HAD_DRV_CONNECTED; dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", -- cgit From 79f439ea4007b94beeb8ba1e00e71f9d128b0f90 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 16:46:44 +0100 Subject: ALSA: x86: Drop had_get_hwstate() The helper function isn't clearer than the plain condition check "if (drv_status == HDA_DRV_DISCONNECTED)". By expanding this, the compiler could even catch the possible uninitialized cases, so we could fix them, too. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 42 ++++++++++++++---------------------------- 1 file changed, 14 insertions(+), 28 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 835e0f2c4f0b..7c6549a10c1c 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -155,15 +155,6 @@ static const struct snd_pcm_hardware snd_intel_hadstream = { }; /* Register access functions */ -static int had_get_hwstate(struct snd_intelhad *intelhaddata) -{ - /* Check for device presence -SW state */ - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) - return -ENODEV; - - return 0; -} - static inline void mid_hdmi_audio_read(struct snd_intelhad *ctx, u32 reg, u32 *val) { @@ -179,11 +170,8 @@ mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val) static int had_read_register(struct snd_intelhad *intelhaddata, u32 offset, u32 *data) { - int retval; - - retval = had_get_hwstate(intelhaddata); - if (retval) - return retval; + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + return -ENODEV; mid_hdmi_audio_read(intelhaddata, offset, data); return 0; @@ -201,11 +189,8 @@ static void fixup_dp_config(struct snd_intelhad *intelhaddata, static int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) { - int retval; - - retval = had_get_hwstate(intelhaddata); - if (retval) - return retval; + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + return -ENODEV; fixup_dp_config(intelhaddata, offset, &data); mid_hdmi_audio_write(intelhaddata, offset, data); @@ -216,11 +201,9 @@ static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, u32 data, u32 mask) { u32 val_tmp; - int retval; - retval = had_get_hwstate(intelhaddata); - if (retval) - return retval; + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + return -ENODEV; mid_hdmi_audio_read(intelhaddata, offset, &val_tmp); val_tmp &= ~mask; @@ -930,7 +913,7 @@ static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param, static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) { - u32 hdmi_status, i = 0; + u32 hdmi_status = 0, i = 0; /* Handle Underrun interrupt within Audio Unit */ had_write_register(intelhaddata, AUD_CONFIG, 0); @@ -977,7 +960,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) pm_runtime_get(intelhaddata->dev); - if (had_get_hwstate(intelhaddata)) { + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", __func__); retval = -ENODEV; @@ -1185,7 +1168,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: /* Disable local INTRs till register prgmng is done */ - if (had_get_hwstate(intelhaddata)) { + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "_START: HDMI cable plugged-out\n"); retval = -ENODEV; @@ -1245,7 +1228,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) runtime = substream->runtime; had_stream = &intelhaddata->stream_data; - if (had_get_hwstate(intelhaddata)) { + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", __func__); retval = -ENODEV; @@ -1329,6 +1312,9 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( intelhaddata = snd_pcm_substream_chip(substream); + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + return SNDRV_PCM_POS_XRUN; + if (intelhaddata->flag_underrun) { intelhaddata->flag_underrun = false; return SNDRV_PCM_POS_XRUN; @@ -1614,7 +1600,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); - if (had_get_hwstate(intelhaddata)) { + if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "HDMI cable plugged-out\n"); return 0; } -- cgit From 2e52f5e518fb79aca459fcd25c3b8f185aa4bcf7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 17:09:13 +0100 Subject: ALSA: x86: Tidy up codes Clean up codes, fix indentations, correct comments, etc. No functional change. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 148 +++++++++++++++++-------------------------- 1 file changed, 59 insertions(+), 89 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 7c6549a10c1c..46db4883f0b5 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -285,7 +285,7 @@ static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata, had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, reset); } -/** +/* * initialize audio channel status registers * This function is called in the prepare callback */ @@ -298,9 +298,9 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, int format; ch_stat0.status_0_regx.lpcm_id = (intelhaddata->aes_bits & - IEC958_AES0_NONAUDIO)>>1; + IEC958_AES0_NONAUDIO) >> 1; ch_stat0.status_0_regx.clk_acc = (intelhaddata->aes_bits & - IEC958_AES3_CON_CLOCK)>>4; + IEC958_AES3_CON_CLOCK) >> 4; cfg_val.cfg_regx_v2.val_bit = ch_stat0.status_0_regx.lpcm_id; switch (substream->runtime->rate) { @@ -330,9 +330,8 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, default: /* control should never come here */ return -EINVAL; - break; - } + had_write_register(intelhaddata, AUD_CH_STATUS_0, ch_stat0.status_0_regval); @@ -348,6 +347,7 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, ch_stat1.status_1_regx.max_wrd_len = 0; ch_stat1.status_1_regx.wrd_len = 0; } + had_write_register(intelhaddata, AUD_CH_STATUS_1, ch_stat1.status_1_regval); return 0; @@ -466,14 +466,14 @@ static int spk_to_chmap(int spk) static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) { - int i = 0, c = 0; + int i, c; int spk_mask = 0; struct snd_pcm_chmap_elem *chmap; u8 eld_high, eld_high_mask = 0xF0; u8 high_msb; chmap = kzalloc(sizeof(*chmap), GFP_KERNEL); - if (chmap == NULL) { + if (!chmap) { intelhaddata->chmap->chmap = NULL; return; } @@ -514,7 +514,7 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) for (c = 0; c < channel_allocations[i].channels; c++) { chmap->map[c] = spk_to_chmap( channel_allocations[i].speakers[ - (MAX_SPEAKERS - 1)-c]); + (MAX_SPEAKERS - 1) - c]); } chmap->channels = channel_allocations[i].channels; intelhaddata->chmap->chmap = chmap; @@ -550,12 +550,12 @@ static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol, { struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); struct snd_intelhad *intelhaddata = info->private_data; - int i = 0; + int i; const struct snd_pcm_chmap_elem *chmap; if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) return -ENODEV; - if (intelhaddata->chmap->chmap == NULL) + if (!intelhaddata->chmap->chmap) return -ENODATA; chmap = intelhaddata->chmap->chmap; for (i = 0; i < chmap->channels; i++) @@ -567,7 +567,7 @@ static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol, static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata, struct snd_pcm *pcm) { - int err = 0; + int err; err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, NULL, 0, (unsigned long)intelhaddata, @@ -615,7 +615,7 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, frame3.fr3_regx.chnl_alloc = snd_intelhad_channel_allocation( intelhaddata, channels); - /*Calculte the byte wide checksum for all valid DIP words*/ + /* Calculte the byte wide checksum for all valid DIP words */ for (i = 0; i < BYTES_PER_WORD; i++) checksum += (info_frame >> i*BITS_PER_BYTE) & MASK_BYTE0; for (i = 0; i < BYTES_PER_WORD; i++) @@ -639,10 +639,8 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.ctrl_val); } -/** - * snd_intelhad_prog_buffer - programs buffer - * address and length registers - * +/* + * snd_intelhad_prog_buffer - programs buffer address and length registers * @substream:substream for which the prepare function is called * @intelhaddata:substream private data * @@ -684,7 +682,7 @@ static int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, intelhaddata->buf_info[i].buf_size = period_bytes; else intelhaddata->buf_info[i].buf_size = ring_buf_size - - (period_bytes*i); + (i * period_bytes); had_write_register(intelhaddata, AUD_BUF_A_ADDR + (i * HAD_REG_WIDTH), @@ -728,7 +726,7 @@ static int had_calculate_maud_value(u32 aud_samp_freq, u32 link_rate) { u32 maud_val; - /* Select maud according to DP 1.2 spec*/ + /* Select maud according to DP 1.2 spec */ if (link_rate == DP_2_7_GHZ) { switch (aud_samp_freq) { case AUD_SAMPLE_RATE_32: @@ -836,41 +834,41 @@ static void snd_intelhad_prog_cts(u32 aud_samp_freq, u32 tmds, static int had_calculate_n_value(u32 aud_samp_freq) { - s32 n_val; + int n_val; /* Select N according to HDMI 1.3a spec*/ switch (aud_samp_freq) { case AUD_SAMPLE_RATE_32: n_val = 4096; - break; + break; case AUD_SAMPLE_RATE_44_1: n_val = 6272; - break; + break; case AUD_SAMPLE_RATE_48: n_val = 6144; - break; + break; case AUD_SAMPLE_RATE_88_2: n_val = 12544; - break; + break; case AUD_SAMPLE_RATE_96: n_val = 12288; - break; + break; case AUD_SAMPLE_RATE_176_4: n_val = 25088; - break; + break; case HAD_MAX_RATE: n_val = 24576; - break; + break; default: n_val = -EINVAL; - break; + break; } return n_val; } @@ -888,7 +886,7 @@ static int had_calculate_n_value(u32 aud_samp_freq) static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param, struct snd_intelhad *intelhaddata) { - s32 n_val; + int n_val; if (intelhaddata->dp_output) { /* @@ -920,7 +918,7 @@ static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) /* Reset buffer pointers */ had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, 1); had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, 0); - /** + /* * The interrupt status 'sticky' bits might not be cleared by * setting '1' to that bit once... */ @@ -939,7 +937,7 @@ static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) dev_err(intelhaddata->dev, "Unable to clear UNDERRUN bits\n"); } -/** +/* * snd_intelhad_open - stream initializations are done here * @substream:substream for which the stream function is called * @@ -1029,25 +1027,8 @@ static void had_period_elapsed(struct snd_pcm_substream *substream) snd_pcm_period_elapsed(substream); } -/** - * snd_intelhad_init_stream - internal function to initialize stream info - * @substream:substream for which the stream function is called - * - */ -static int snd_intelhad_init_stream(struct snd_pcm_substream *substream) -{ - struct snd_intelhad *intelhaddata = snd_pcm_substream_chip(substream); - - intelhaddata->stream_info.had_substream = substream; - intelhaddata->stream_info.buffer_ptr = 0; - intelhaddata->stream_info.buffer_rendered = 0; - intelhaddata->stream_info.sfreq = substream->runtime->rate; - return 0; -} - -/** - * snd_intelhad_close- to free parameteres when stream is stopped - * +/* + * snd_intelhad_close - to free parameteres when stream is stopped * @substream: substream for which the function is called * * This function is called by ALSA framework when stream is stopped @@ -1081,11 +1062,10 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) return 0; } -/** - * snd_intelhad_hw_params- to setup the hardware parameters - * like allocating the buffers - * - * @substream: substream for which the function is called +/* + * snd_intelhad_hw_params - to setup the hardware parameters + * like allocating the buffers + * @substream: substream for which the function is called * @hw_params: hardware parameters * * This function is called by ALSA framework when hardware params are set @@ -1121,14 +1101,12 @@ static int snd_intelhad_hw_params(struct snd_pcm_substream *substream, return retval; } -/** - * snd_intelhad_hw_free- to release the resources allocated during - * hardware params setup - * +/* + * snd_intelhad_hw_free - to release the resources allocated during + * hardware params setup * @substream: substream for which the function is called * * This function is called by ALSA framework before close callback. - * */ static int snd_intelhad_hw_free(struct snd_pcm_substream *substream) { @@ -1146,10 +1124,11 @@ static int snd_intelhad_hw_free(struct snd_pcm_substream *substream) return 0; } -/** +/* * snd_intelhad_pcm_trigger - stream activities are handled here - * @substream:substream for which the stream function is called - * @cmd:the stream commamd thats requested from upper layer + * @substream: substream for which the stream function is called + * @cmd: the stream commamd thats requested from upper layer + * * This function is called whenever an a stream activity is invoked */ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, @@ -1208,10 +1187,9 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, return retval; } -/** - * snd_intelhad_pcm_prepare- internal preparation before starting a stream - * - * @substream: substream for which the function is called +/* + * snd_intelhad_pcm_prepare - internal preparation before starting a stream + * @substream: substream for which the function is called * * This function is called when a stream is started for internal preparation. */ @@ -1252,10 +1230,10 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) return retval; } - retval = snd_intelhad_init_stream(substream); - if (retval) - goto prep_end; - + intelhaddata->stream_info.had_substream = substream; + intelhaddata->stream_info.buffer_ptr = 0; + intelhaddata->stream_info.buffer_rendered = 0; + intelhaddata->stream_info.sfreq = substream->runtime->rate; /* Get N value in KHz */ disp_samp_freq = intelhaddata->tmds_clock_speed; @@ -1294,10 +1272,9 @@ prep_end: return retval; } -/** +/* * snd_intelhad_pcm_pointer- to send the current buffer pointerprocessed by hw - * - * @substream: substream for which the function is called + * @substream: substream for which the function is called * * This function is called by ALSA framework to get the current hw buffer ptr * when a period is elapsed @@ -1359,11 +1336,10 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( return intelhaddata->stream_info.buffer_ptr; } -/** +/* * snd_intelhad_pcm_mmap- mmaps a kernel buffer to user space for copying data - * - * @substream: substream for which the function is called - * @vma: struct instance of memory VMM memory area + * @substream: substream for which the function is called + * @vma: struct instance of memory VMM memory area * * This function is called by OS when a user space component * tries to get mmap memory from driver @@ -1418,11 +1394,9 @@ out: /* * hdmi_lpe_audio_suspend - power management suspend function - * * @pdev: platform device * - * This function is called by client driver to suspend the - * hdmi audio. + * This function is called to suspend the hdmi audio. */ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, pm_message_t state) @@ -1465,11 +1439,9 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, /* * hdmi_lpe_audio_resume - power management resume function + * @pdev: platform device * - *@pdev: platform device - * - * This function is called by client driver to resume the - * hdmi audio. + * This function is called to resume the hdmi audio. */ static int hdmi_lpe_audio_resume(struct platform_device *pdev) { @@ -1605,7 +1577,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) return 0; } - /*Reprogram the registers with addr and length*/ + /* Reprogram the registers with addr and length */ had_write_register(intelhaddata, AUD_BUF_A_LENGTH + (buf_id * HAD_REG_WIDTH), buf_size); @@ -1939,8 +1911,7 @@ static void hdmi_lpe_audio_free(struct snd_card *card) * hdmi_lpe_audio_probe - start bridge with i915 * * This function is called when the i915 driver creates the - * hdmi-lpe-audio platform device. Card creation is deferred until a - * hot plug event is received + * hdmi-lpe-audio platform device. */ static int hdmi_lpe_audio_probe(struct platform_device *pdev) { @@ -2084,8 +2055,7 @@ err: /* * hdmi_lpe_audio_remove - stop bridge with i915 * - * This function is called when the platform device is destroyed. The sound - * card should have been removed on hot plug event. + * This function is called when the platform device is destroyed. */ static int hdmi_lpe_audio_remove(struct platform_device *pdev) { -- cgit From 4151ee845ad8230d18ac4a0e0bf1037180c6d2d9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 31 Jan 2017 18:14:15 +0100 Subject: ALSA: x86: Remove _v[12] suffices Although we dropped the most of the obsoleted *_v1 definitions and codes, some codes still keep the _v1 or _v2 suffices. Now they are ripped off. The only thing to be done carefully here is the definition of control offsets. The original code defines enum hdmi_ctrl_reg_offset_v1 and a few new elements just for v2 on its top. After this cleanup, we remove the old AUD_HDMI_STATUS and AUD_HDMIW_INFOFR definitions and replace with the v2 values. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 46db4883f0b5..84b374cc183f 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -249,10 +249,10 @@ static int had_read_modify_aud_config_v2(struct snd_intelhad *intelhaddata, channels = substream->runtime->channels; else channels = 2; - cfg_val.cfg_regx_v2.num_ch = channels - 2; + cfg_val.cfg_regx.num_ch = channels - 2; data = data | cfg_val.cfg_regval; - mask = mask | AUD_CONFIG_CH_MASK_V2; + mask = mask | AUD_CONFIG_CH_MASK; dev_dbg(intelhaddata->dev, "%s : data = %x, mask =%x\n", __func__, data, mask); @@ -265,10 +265,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_v2, &status_reg); + mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS, &status_reg); status_reg |= HDMI_AUDIO_BUFFER_DONE | HDMI_AUDIO_UNDERRUN; - mid_hdmi_audio_write(ctx, AUD_HDMI_STATUS_v2, status_reg); - mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS_v2, &status_reg); + mid_hdmi_audio_write(ctx, AUD_HDMI_STATUS, status_reg); + mid_hdmi_audio_read(ctx, AUD_HDMI_STATUS, &status_reg); } } @@ -282,7 +282,7 @@ static void snd_intelhad_enable_audio(struct snd_intelhad *intelhaddata, static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata, u8 reset) { - had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, reset); + had_write_register(intelhaddata, AUD_HDMI_STATUS, reset); } /* @@ -301,7 +301,7 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, IEC958_AES0_NONAUDIO) >> 1; ch_stat0.status_0_regx.clk_acc = (intelhaddata->aes_bits & IEC958_AES3_CON_CLOCK) >> 4; - cfg_val.cfg_regx_v2.val_bit = ch_stat0.status_0_regx.lpcm_id; + cfg_val.cfg_regx.val_bit = ch_stat0.status_0_regx.lpcm_id; switch (substream->runtime->rate) { case AUD_SAMPLE_RATE_32: @@ -367,19 +367,19 @@ static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream, had_prog_status_reg(substream, intelhaddata); - buf_cfg.buf_cfg_regx_v2.audio_fifo_watermark = FIFO_THRESHOLD; - buf_cfg.buf_cfg_regx_v2.dma_fifo_watermark = DMA_FIFO_THRESHOLD; - buf_cfg.buf_cfg_regx_v2.aud_delay = 0; + buf_cfg.buf_cfg_regx.audio_fifo_watermark = FIFO_THRESHOLD; + buf_cfg.buf_cfg_regx.dma_fifo_watermark = DMA_FIFO_THRESHOLD; + buf_cfg.buf_cfg_regx.aud_delay = 0; had_write_register(intelhaddata, AUD_BUF_CONFIG, buf_cfg.buf_cfgval); channels = substream->runtime->channels; - cfg_val.cfg_regx_v2.num_ch = channels - 2; + cfg_val.cfg_regx.num_ch = channels - 2; if (channels <= 2) - cfg_val.cfg_regx_v2.layout = LAYOUT0; + cfg_val.cfg_regx.layout = LAYOUT0; else - cfg_val.cfg_regx_v2.layout = LAYOUT1; + cfg_val.cfg_regx.layout = LAYOUT1; - cfg_val.cfg_regx_v2.val_bit = 1; + cfg_val.cfg_regx.val_bit = 1; had_write_register(intelhaddata, AUD_CONFIG, cfg_val.cfg_regval); return 0; } @@ -626,13 +626,13 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, frame2.fr2_regx.chksum = -(checksum); } - had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, info_frame); - had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, frame2.fr2_val); - had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, frame3.fr3_val); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR, info_frame); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame2.fr2_val); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame3.fr3_val); /* program remaining DIP words with zero */ for (i = 0; i < HAD_MAX_DIP_WORDS-VALID_DIP_WORDS; i++) - had_write_register(intelhaddata, AUD_HDMIW_INFOFR_v2, 0x0); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR, 0x0); ctrl_state.ctrl_regx.dip_freq = 1; ctrl_state.ctrl_regx.dip_en_sta = 1; @@ -916,20 +916,20 @@ static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) /* Handle Underrun interrupt within Audio Unit */ had_write_register(intelhaddata, AUD_CONFIG, 0); /* Reset buffer pointers */ - had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, 1); - had_write_register(intelhaddata, AUD_HDMI_STATUS_v2, 0); + had_write_register(intelhaddata, AUD_HDMI_STATUS, 1); + had_write_register(intelhaddata, AUD_HDMI_STATUS, 0); /* * The interrupt status 'sticky' bits might not be cleared by * setting '1' to that bit once... */ do { /* clear bit30, 31 AUD_HDMI_STATUS */ - had_read_register(intelhaddata, AUD_HDMI_STATUS_v2, + had_read_register(intelhaddata, AUD_HDMI_STATUS, &hdmi_status); dev_dbg(intelhaddata->dev, "HDMI status =0x%x\n", hdmi_status); if (hdmi_status & AUD_CONFIG_MASK_UNDERRUN) { i++; had_write_register(intelhaddata, - AUD_HDMI_STATUS_v2, hdmi_status); + AUD_HDMI_STATUS, hdmi_status); } else break; } while (i < MAX_CNT); @@ -1812,7 +1812,7 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) struct snd_intelhad *ctx = dev_id; u32 audio_stat, audio_reg; - audio_reg = AUD_HDMI_STATUS_v2; + audio_reg = AUD_HDMI_STATUS; mid_hdmi_audio_read(ctx, audio_reg, &audio_stat); if (audio_stat & HDMI_AUDIO_UNDERRUN) { -- cgit From 4a5ddb2cb1ef624300d1e66e9e6974cd37b7012f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 16:45:38 +0100 Subject: ALSA: x86: Constfy tables Some tables can be defined as const. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 84b374cc183f..81b6c26a8646 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -51,7 +51,7 @@ MODULE_PARM_DESC(id, /* * ELD SA bits in the CEA Speaker Allocation data block */ -static int eld_speaker_allocation_bits[] = { +static const int eld_speaker_allocation_bits[] = { [0] = FL | FR, [1] = LFE, [2] = FC, @@ -114,7 +114,7 @@ static struct cea_channel_speaker_allocation channel_allocations[] = { { .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, }; -static struct channel_map_table map_tables[] = { +static const struct channel_map_table map_tables[] = { { SNDRV_CHMAP_FL, 0x00, FL }, { SNDRV_CHMAP_FR, 0x01, FR }, { SNDRV_CHMAP_RL, 0x04, RL }, @@ -455,7 +455,7 @@ static int snd_intelhad_channel_allocation(struct snd_intelhad *intelhaddata, /* from speaker bit mask to ALSA API channel position */ static int spk_to_chmap(int spk) { - struct channel_map_table *t = map_tables; + const struct channel_map_table *t = map_tables; for (; t->map; t++) { if (t->spk_mask == spk) -- cgit From bcce775ca8d66a5222ac2d28e5388b5a6c2d9ad6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 17:18:20 +0100 Subject: ALSA: x86: Remove superfluous irqsave flags We don't need to use irqsave/irqrestore versions for each spin lock, but judge the context properly and use the simpler versions. Also add some (still simplistic) comments to functions. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 71 ++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 38 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 81b6c26a8646..046af2367fba 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1135,7 +1135,6 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { int retval = 0; - unsigned long flag_irq; struct snd_intelhad *intelhaddata; struct had_stream_pvt *stream; struct had_stream_data *had_stream; @@ -1163,14 +1162,14 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_STOP: - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irq); + spin_lock(&intelhaddata->had_spinlock); intelhaddata->stream_info.str_id = 0; intelhaddata->curr_buf = 0; /* Stop reporting BUFFER_DONE/UNDERRUN to above layers */ had_stream->stream_type = HAD_INIT; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irq); + spin_unlock(&intelhaddata->had_spinlock); /* Disable Audio */ snd_intelhad_enable_audio_int(intelhaddata, false); snd_intelhad_enable_audio(intelhaddata, false); @@ -1402,7 +1401,6 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, pm_message_t state) { struct had_stream_data *had_stream; - unsigned long flag_irqs; struct snd_pcm_substream *substream; struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); @@ -1414,15 +1412,15 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, return -EAGAIN; } - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irq(&intelhaddata->had_spinlock); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); dev_dbg(intelhaddata->dev, "had not connected\n"); return 0; } if (intelhaddata->drv_status == HAD_DRV_SUSPENDED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); dev_dbg(intelhaddata->dev, "had already suspended\n"); return 0; } @@ -1432,7 +1430,7 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_SUSPENDED\n", __func__, __LINE__); - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); snd_intelhad_enable_audio_int(intelhaddata, false); return 0; } @@ -1446,17 +1444,16 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, static int hdmi_lpe_audio_resume(struct platform_device *pdev) { struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); - unsigned long flag_irqs; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irq(&intelhaddata->had_spinlock); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); dev_dbg(intelhaddata->dev, "had not connected\n"); return 0; } if (intelhaddata->drv_status != HAD_DRV_SUSPENDED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); dev_dbg(intelhaddata->dev, "had is not in suspended state\n"); return 0; } @@ -1465,7 +1462,7 @@ static int hdmi_lpe_audio_resume(struct platform_device *pdev) dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); snd_intelhad_enable_audio_int(intelhaddata, true); return 0; } @@ -1477,7 +1474,6 @@ static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, enum intel_had_aud_buf_type buff_done; u32 buf_size, buf_addr; struct had_stream_data *had_stream; - unsigned long flag_irqs; had_stream = &intelhaddata->stream_data; @@ -1507,14 +1503,13 @@ static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, (buf_addr | BIT(0) | BIT(1))); } buf_id = buf_id % 4; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); intelhaddata->buff_done = buf_id; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); } return intr_count; } +/* called from irq handler */ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) { u32 len = 1; @@ -1525,15 +1520,15 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) struct had_stream_data *had_stream; int intr_count; enum had_status_stream stream_type; - unsigned long flag_irqs; + unsigned long flags; had_stream = &intelhaddata->stream_data; stream = &intelhaddata->stream_info; intr_count = 1; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irqsave(&intelhaddata->had_spinlock, flags); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); dev_dbg(intelhaddata->dev, "%s:Device already disconnected\n", __func__); return 0; @@ -1551,16 +1546,16 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) /* Check for any intr_miss in case of active playback */ if (had_stream->stream_type == HAD_RUNNING_STREAM) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); intr_count = had_chk_intrmiss(intelhaddata, buf_id); if (!intr_count || (intr_count > 3)) { + spin_unlock_irqrestore(&intelhaddata->had_spinlock, + flags); dev_err(intelhaddata->dev, "HAD SW state in non-recoverable mode\n"); return 0; } buf_id += (intr_count - 1); buf_id = buf_id % 4; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); } intelhaddata->buf_info[buf_id].is_valid = true; @@ -1570,7 +1565,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) } else intelhaddata->curr_buf = buf_id + 1; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "HDMI cable plugged-out\n"); @@ -1604,19 +1599,20 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) return 0; } +/* called from irq handler */ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct pcm_stream_info *stream; struct had_stream_data *had_stream; enum had_status_stream stream_type; - unsigned long flag_irqs; + unsigned long flags; int drv_status; had_stream = &intelhaddata->stream_data; stream = &intelhaddata->stream_info; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irqsave(&intelhaddata->had_spinlock, flags); buf_id = intelhaddata->curr_buf; stream_type = had_stream->stream_type; intelhaddata->buff_done = buf_id; @@ -1624,7 +1620,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) if (stream_type == HAD_RUNNING_STREAM) intelhaddata->curr_buf = HAD_BUF_TYPE_A; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); dev_dbg(intelhaddata->dev, "Enter:%s buf_id=%d, stream_type=%d\n", __func__, buf_id, stream_type); @@ -1646,20 +1642,20 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) return 0; } +/* process hot plug, called from wq */ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct snd_pcm_substream *substream; struct had_stream_data *had_stream; - unsigned long flag_irqs; substream = intelhaddata->stream_info.had_substream; had_stream = &intelhaddata->stream_data; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irq(&intelhaddata->had_spinlock); if (intelhaddata->drv_status == HAD_DRV_CONNECTED) { dev_dbg(intelhaddata->dev, "Device already connected\n"); - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); return 0; } buf_id = intelhaddata->curr_buf; @@ -1668,7 +1664,7 @@ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", __func__, __LINE__); - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); dev_dbg(intelhaddata->dev, "Processing HOT_PLUG, buf_id = %d\n", buf_id); @@ -1686,20 +1682,20 @@ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) return 0; } +/* process hot unplug, called from wq */ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct had_stream_data *had_stream; - unsigned long flag_irqs; had_stream = &intelhaddata->stream_data; buf_id = intelhaddata->curr_buf; - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irq(&intelhaddata->had_spinlock); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "Device already disconnected\n"); - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); return 0; } else { @@ -1715,14 +1711,14 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) /* Report to above ALSA layer */ if (intelhaddata->stream_info.had_substream != NULL) { - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); snd_pcm_stop(intelhaddata->stream_info.had_substream, SNDRV_PCM_STATE_SETUP); - spin_lock_irqsave(&intelhaddata->had_spinlock, flag_irqs); + spin_lock_irq(&intelhaddata->had_spinlock); } had_stream->stream_type = HAD_INIT; - spin_unlock_irqrestore(&intelhaddata->had_spinlock, flag_irqs); + spin_unlock_irq(&intelhaddata->had_spinlock); kfree(intelhaddata->chmap->chmap); intelhaddata->chmap->chmap = NULL; @@ -1922,7 +1918,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) int irq; struct resource *res_mmio; int ret; - unsigned long flags; dev_dbg(&pdev->dev, "dma_mask: %p\n", pdev->dev.dma_mask); @@ -2034,10 +2029,10 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) if (ret) goto err; - spin_lock_irqsave(&pdata->lpe_audio_slock, flags); + spin_lock_irq(&pdata->lpe_audio_slock); pdata->notify_audio_lpe = notify_audio_lpe; pdata->notify_pending = false; - spin_unlock_irqrestore(&pdata->lpe_audio_slock, flags); + spin_unlock_irq(&pdata->lpe_audio_slock); pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); -- cgit From 8f8d1d7fe009c320d80ed1c7b0c1d3d48b538965 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 17:24:02 +0100 Subject: ALSA: x86: Fix racy access to chmap The access to chmap can be racy against the hotplug process, where it recreates the chmap on the fly. For protecting against it, a mutex is introduced in this patch. It's also used for protecting the change / reference of eld and state fields, too. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 046af2367fba..c0cb59e6a89b 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -555,11 +555,17 @@ static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol, if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) return -ENODEV; - if (!intelhaddata->chmap->chmap) + + mutex_lock(&intelhaddata->mutex); + if (!intelhaddata->chmap->chmap) { + mutex_unlock(&intelhaddata->mutex); return -ENODATA; + } + chmap = intelhaddata->chmap->chmap; for (i = 0; i < chmap->channels; i++) ucontrol->value.integer.value[i] = chmap->map[i]; + mutex_unlock(&intelhaddata->mutex); return 0; } @@ -1352,6 +1358,7 @@ static int snd_intelhad_pcm_mmap(struct snd_pcm_substream *substream, vma->vm_end - vma->vm_start, vma->vm_page_prot); } +/* process mode change of the running stream; called in mutex */ static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata) { struct snd_pcm_substream *substream; @@ -1642,7 +1649,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) return 0; } -/* process hot plug, called from wq */ +/* process hot plug, called from wq with mutex locked */ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; @@ -1682,7 +1689,7 @@ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) return 0; } -/* process hot unplug, called from wq */ +/* process hot unplug, called from wq with mutex locked */ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; @@ -1751,12 +1758,14 @@ static int had_iec958_get(struct snd_kcontrol *kcontrol, { struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol); + mutex_lock(&intelhaddata->mutex); ucontrol->value.iec958.status[0] = (intelhaddata->aes_bits >> 0) & 0xff; ucontrol->value.iec958.status[1] = (intelhaddata->aes_bits >> 8) & 0xff; ucontrol->value.iec958.status[2] = (intelhaddata->aes_bits >> 16) & 0xff; ucontrol->value.iec958.status[3] = (intelhaddata->aes_bits >> 24) & 0xff; + mutex_unlock(&intelhaddata->mutex); return 0; } @@ -1775,16 +1784,19 @@ static int had_iec958_put(struct snd_kcontrol *kcontrol, { unsigned int val; struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol); + int changed = 0; val = (ucontrol->value.iec958.status[0] << 0) | (ucontrol->value.iec958.status[1] << 8) | (ucontrol->value.iec958.status[2] << 16) | (ucontrol->value.iec958.status[3] << 24); + mutex_lock(&intelhaddata->mutex); if (intelhaddata->aes_bits != val) { intelhaddata->aes_bits = val; - return 1; + changed = 1; } - return 1; + mutex_unlock(&intelhaddata->mutex); + return changed; } static struct snd_kcontrol_new had_control_iec958_mask = { @@ -1837,6 +1849,7 @@ static void had_audio_wq(struct work_struct *work) container_of(work, struct snd_intelhad, hdmi_audio_wq); struct intel_hdmi_lpe_audio_pdata *pdata = ctx->dev->platform_data; + mutex_lock(&ctx->mutex); if (!pdata->hdmi_connected) { dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", __func__); @@ -1844,12 +1857,11 @@ static void had_audio_wq(struct work_struct *work) if (ctx->state != hdmi_connector_status_connected) { dev_dbg(ctx->dev, "%s: Already Unplugged!\n", __func__); - return; + } else { + ctx->state = hdmi_connector_status_disconnected; + had_process_hot_unplug(ctx); } - ctx->state = hdmi_connector_status_disconnected; - had_process_hot_unplug(ctx); - } else { struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld; @@ -1888,6 +1900,7 @@ static void had_audio_wq(struct work_struct *work) hdmi_audio_mode_change(ctx); } } + mutex_unlock(&ctx->mutex); } /* release resources */ @@ -1948,6 +1961,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ctx = card->private_data; spin_lock_init(&ctx->had_spinlock); + mutex_init(&ctx->mutex); ctx->drv_status = HAD_DRV_DISCONNECTED; ctx->dev = &pdev->dev; ctx->card = card; -- cgit From d0e9b1a23ca3dbe24e88c6671218b9031e37db96 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 17:37:36 +0100 Subject: ALSA: x86: Drop flag_underrun field The flag_underrun flag is used to indicate to escalate the XRUN reporting at the next position inquiry, but there is a much simpler method to achieve it: just call snd_pcm_stop_xrun(). Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index c0cb59e6a89b..9ecdd9ad0199 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1297,11 +1297,6 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) return SNDRV_PCM_POS_XRUN; - if (intelhaddata->flag_underrun) { - intelhaddata->flag_underrun = false; - return SNDRV_PCM_POS_XRUN; - } - /* Use a hw register to calculate sub-period position reports. * This makes PulseAudio happier. */ @@ -1642,8 +1637,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) if (stream_type == HAD_RUNNING_STREAM) { /* Report UNDERRUN error to above layers */ - intelhaddata->flag_underrun = true; - had_period_elapsed(stream->had_substream); + snd_pcm_stop_xrun(stream->had_substream); } return 0; @@ -1965,7 +1959,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ctx->drv_status = HAD_DRV_DISCONNECTED; ctx->dev = &pdev->dev; ctx->card = card; - ctx->flag_underrun = false; ctx->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; strcpy(card->driver, INTEL_HAD); strcpy(card->shortname, INTEL_HAD); -- cgit From 0e9c67d7c88ce7054288e3b61deb09bfa59f8920 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 17:53:19 +0100 Subject: ALSA: x86: Drop superfluous state field The state field keeps the connection state and it's basically as same as drv_status field. Drop this redundancy. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 56 ++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 36 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 9ecdd9ad0199..621be602addd 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1644,7 +1644,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) } /* process hot plug, called from wq with mutex locked */ -static int had_process_hot_plug(struct snd_intelhad *intelhaddata) +static void had_process_hot_plug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct snd_pcm_substream *substream; @@ -1657,8 +1657,9 @@ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) if (intelhaddata->drv_status == HAD_DRV_CONNECTED) { dev_dbg(intelhaddata->dev, "Device already connected\n"); spin_unlock_irq(&intelhaddata->had_spinlock); - return 0; + return; } + buf_id = intelhaddata->curr_buf; intelhaddata->buff_done = buf_id; intelhaddata->drv_status = HAD_DRV_CONNECTED; @@ -1679,12 +1680,10 @@ static int had_process_hot_plug(struct snd_intelhad *intelhaddata) } had_build_channel_allocation_map(intelhaddata); - - return 0; } /* process hot unplug, called from wq with mutex locked */ -static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) +static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct had_stream_data *had_stream; @@ -1697,14 +1696,14 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "Device already disconnected\n"); spin_unlock_irq(&intelhaddata->had_spinlock); - return 0; + return; - } else { - /* Disable Audio */ - snd_intelhad_enable_audio_int(intelhaddata, false); - snd_intelhad_enable_audio(intelhaddata, false); } + /* Disable Audio */ + snd_intelhad_enable_audio_int(intelhaddata, false); + snd_intelhad_enable_audio(intelhaddata, false); + intelhaddata->drv_status = HAD_DRV_DISCONNECTED; dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", @@ -1722,8 +1721,6 @@ static int had_process_hot_unplug(struct snd_intelhad *intelhaddata) spin_unlock_irq(&intelhaddata->had_spinlock); kfree(intelhaddata->chmap->chmap); intelhaddata->chmap->chmap = NULL; - - return 0; } /* PCM operations structure and the calls back for the same */ @@ -1847,18 +1844,13 @@ static void had_audio_wq(struct work_struct *work) if (!pdata->hdmi_connected) { dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", __func__); - - if (ctx->state != hdmi_connector_status_connected) { - dev_dbg(ctx->dev, "%s: Already Unplugged!\n", - __func__); - } else { - ctx->state = hdmi_connector_status_disconnected; - had_process_hot_unplug(ctx); - } - + had_process_hot_unplug(ctx); } else { struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld; + dev_dbg(ctx->dev, "%s: HAD_NOTIFY_ELD : port = %d, tmds = %d\n", + __func__, eld->port_id, pdata->tmds_clock_speed); + switch (eld->pipe_id) { case 0: ctx->had_config_offset = AUDIO_HDMI_CONFIG_A; @@ -1877,22 +1869,15 @@ static void had_audio_wq(struct work_struct *work) memcpy(&ctx->eld, eld->eld_data, sizeof(ctx->eld)); - had_process_hot_plug(ctx); - - ctx->state = hdmi_connector_status_connected; + ctx->dp_output = pdata->dp_output; + ctx->tmds_clock_speed = pdata->tmds_clock_speed; + ctx->link_rate = pdata->link_rate; - dev_dbg(ctx->dev, "%s: HAD_NOTIFY_ELD : port = %d, tmds = %d\n", - __func__, eld->port_id, pdata->tmds_clock_speed); - - if (pdata->tmds_clock_speed) { - ctx->tmds_clock_speed = pdata->tmds_clock_speed; - ctx->dp_output = pdata->dp_output; - ctx->link_rate = pdata->link_rate; + had_process_hot_plug(ctx); - /* Process mode change if stream is active */ - if (ctx->stream_data.stream_type == HAD_RUNNING_STREAM) - hdmi_audio_mode_change(ctx); - } + /* Process mode change if stream is active */ + if (ctx->stream_data.stream_type == HAD_RUNNING_STREAM) + hdmi_audio_mode_change(ctx); } mutex_unlock(&ctx->mutex); } @@ -1966,7 +1951,6 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ctx->irq = -1; ctx->tmds_clock_speed = DIS_SAMPLE_RATE_148_5; INIT_WORK(&ctx->hdmi_audio_wq, had_audio_wq); - ctx->state = hdmi_connector_status_disconnected; card->private_free = hdmi_lpe_audio_free; -- cgit From fa5dfe6a01481a8fa00469be42ea32beb468a501 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 22:03:26 +0100 Subject: ALSA: x86: Drop redundant had_stream_pvt The had_stream_pvt struct assigned to PCM runtime private data tracks merely the stream running status, and the very same information is carried by had_stream->stream_type. Kill it. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 46 ++++---------------------------------------- 1 file changed, 4 insertions(+), 42 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 621be602addd..88e9a91f28a0 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -953,7 +953,6 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) { struct snd_intelhad *intelhaddata; struct snd_pcm_runtime *runtime; - struct had_stream_pvt *stream; struct had_stream_data *had_stream; int retval; @@ -968,31 +967,16 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", __func__); retval = -ENODEV; - goto exit_put_handle; - } - - /* Check, if device already in use */ - if (runtime->private_data) { - dev_dbg(intelhaddata->dev, "Device already in use\n"); - retval = -EBUSY; - goto exit_put_handle; + goto error; } /* set the runtime hw parameter with local snd_pcm_hardware struct */ runtime->hw = snd_intel_hadstream; - stream = kzalloc(sizeof(*stream), GFP_KERNEL); - if (!stream) { - retval = -ENOMEM; - goto exit_put_handle; - } - stream->stream_status = STREAM_INIT; - runtime->private_data = stream; - retval = snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (retval < 0) - goto exit_err; + goto error; /* Make sure, that the period size is always aligned * 64byte boundary @@ -1002,15 +986,12 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) if (retval < 0) { dev_dbg(intelhaddata->dev, "%s:step_size=64 failed,err=%d\n", __func__, retval); - goto exit_err; + goto error; } return retval; -exit_err: - kfree(stream); -exit_put_handle: + error: pm_runtime_put(intelhaddata->dev); - runtime->private_data = NULL; return retval; } @@ -1020,16 +1001,8 @@ exit_put_handle: */ static void had_period_elapsed(struct snd_pcm_substream *substream) { - struct had_stream_pvt *stream; - if (!substream || !substream->runtime) return; - stream = substream->runtime->private_data; - if (!stream) - return; - - if (stream->stream_status != STREAM_RUNNING) - return; snd_pcm_period_elapsed(substream); } @@ -1042,13 +1015,8 @@ static void had_period_elapsed(struct snd_pcm_substream *substream) static int snd_intelhad_close(struct snd_pcm_substream *substream) { struct snd_intelhad *intelhaddata; - struct snd_pcm_runtime *runtime; intelhaddata = snd_pcm_substream_chip(substream); - runtime = substream->runtime; - - if (WARN_ON(!runtime->private_data)) - return 0; intelhaddata->stream_info.buffer_rendered = 0; intelhaddata->stream_info.buffer_ptr = 0; @@ -1062,8 +1030,6 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", __func__, __LINE__); } - kfree(runtime->private_data); - runtime->private_data = NULL; pm_runtime_put(intelhaddata->dev); return 0; } @@ -1142,11 +1108,9 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, { int retval = 0; struct snd_intelhad *intelhaddata; - struct had_stream_pvt *stream; struct had_stream_data *had_stream; intelhaddata = snd_pcm_substream_chip(substream); - stream = substream->runtime->private_data; had_stream = &intelhaddata->stream_data; switch (cmd) { @@ -1158,7 +1122,6 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, retval = -ENODEV; break; } - stream->stream_status = STREAM_RUNNING; had_stream->stream_type = HAD_RUNNING_STREAM; @@ -1182,7 +1145,6 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, /* Reset buffer pointers */ snd_intelhad_reset_audio(intelhaddata, 1); snd_intelhad_reset_audio(intelhaddata, 0); - stream->stream_status = STREAM_DROPPED; snd_intelhad_enable_audio_int(intelhaddata, false); break; -- cgit From 7d9e79869ba2a8a552f4c2cf1df44cf9a0822f02 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 1 Feb 2017 22:25:58 +0100 Subject: ALSA: x86: Drop unused fields from pcm_stream_info The struct pcm_stream_info contains a few unused or useless fields. str_id is always zero, buffer_ptr is volatile, never read, and sfreq is nowhere referred. Kill them. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 88e9a91f28a0..907e420cd90d 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1019,8 +1019,6 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); intelhaddata->stream_info.buffer_rendered = 0; - intelhaddata->stream_info.buffer_ptr = 0; - intelhaddata->stream_info.str_id = 0; intelhaddata->stream_info.had_substream = NULL; /* Check if following drv_status modification is required - VA */ @@ -1132,7 +1130,6 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_STOP: spin_lock(&intelhaddata->had_spinlock); - intelhaddata->stream_info.str_id = 0; intelhaddata->curr_buf = 0; /* Stop reporting BUFFER_DONE/UNDERRUN to above layers */ @@ -1188,19 +1185,8 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(intelhaddata->dev, "rate=%d\n", runtime->rate); dev_dbg(intelhaddata->dev, "channels=%d\n", runtime->channels); - if (intelhaddata->stream_info.str_id) { - dev_dbg(intelhaddata->dev, - "_prepare is called for existing str_id#%d\n", - intelhaddata->stream_info.str_id); - retval = snd_intelhad_pcm_trigger(substream, - SNDRV_PCM_TRIGGER_STOP); - return retval; - } - intelhaddata->stream_info.had_substream = substream; - intelhaddata->stream_info.buffer_ptr = 0; intelhaddata->stream_info.buffer_rendered = 0; - intelhaddata->stream_info.sfreq = substream->runtime->rate; /* Get N value in KHz */ disp_samp_freq = intelhaddata->tmds_clock_speed; @@ -1292,10 +1278,7 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( intelhaddata->stream_info.ring_buf_size, &(bytes_rendered)); - intelhaddata->stream_info.buffer_ptr = bytes_to_frames( - substream->runtime, - bytes_rendered + t); - return intelhaddata->stream_info.buffer_ptr; + return bytes_to_frames(substream->runtime, bytes_rendered + t); } /* -- cgit From 313d9f28c1d5e0254ca16f2df0f1b737e30c0993 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 13:00:12 +0100 Subject: ALSA: x86: Properly manage PCM substream lifetype The PCM substream is referred not only in the PCM callbacks but also in the irq handler and in the hotplug/unplug codes. The latter code paths don't take the PCM lock, thus the PCM may be released unexpectedly while calling PCM helper functions or accessing pcm->runtime fields. This patch implements a simple refcount to assure the PCM substream accessibility while the other codes are accessing. It needed some code refactoring in the relevant functions for avoiding the doubly spinlocks. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 169 ++++++++++++++++++++++++------------------- 1 file changed, 96 insertions(+), 73 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 907e420cd90d..c209d9498c0e 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -154,6 +154,36 @@ static const struct snd_pcm_hardware snd_intel_hadstream = { .fifo_size = HAD_FIFO_SIZE, }; +/* Get the active PCM substream; + * Call had_substream_put() for unreferecing. + * Don't call this inside had_spinlock, as it takes by itself + */ +static struct snd_pcm_substream * +had_substream_get(struct snd_intelhad *intelhaddata) +{ + struct snd_pcm_substream *substream; + unsigned long flags; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flags); + substream = intelhaddata->stream_info.substream; + if (substream) + intelhaddata->stream_info.substream_refcount++; + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); + return substream; +} + +/* Unref the active PCM substream; + * Don't call this inside had_spinlock, as it takes by itself + */ +static void had_substream_put(struct snd_intelhad *intelhaddata) +{ + unsigned long flags; + + spin_lock_irqsave(&intelhaddata->had_spinlock, flags); + intelhaddata->stream_info.substream_refcount--; + spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); +} + /* Register access functions */ static inline void mid_hdmi_audio_read(struct snd_intelhad *ctx, u32 reg, u32 *val) @@ -215,7 +245,8 @@ static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, } /* - * function to read-modify AUD_CONFIG register on VLV2. + * enable / disable audio configuration + * * The had_read_modify() function should not directly be used on VLV2 for * updating AUD_CONFIG register. * This is because: @@ -227,39 +258,33 @@ static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, * causes the "channels" field to be updated as 0xy binary resulting in * bad audio. The fix is to always write the AUD_CONFIG[6:4] with * appropriate value when doing read-modify of AUD_CONFIG register. - * - * @substream: the current substream or NULL if no active substream - * @data : data to be written - * @mask : mask - * */ -static int had_read_modify_aud_config_v2(struct snd_intelhad *intelhaddata, - u32 data, u32 mask) +static void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, + struct snd_intelhad *intelhaddata, + bool enable) { - struct snd_pcm_substream *substream; union aud_cfg cfg_val = {.cfg_regval = 0}; - u8 channels; + u8 channels, data, mask; /* * If substream is NULL, there is no active stream. * In this case just set channels to 2 */ - substream = intelhaddata->stream_info.had_substream; - if (substream && substream->runtime) - channels = substream->runtime->channels; - else - channels = 2; + channels = substream ? substream->runtime->channels : 2; cfg_val.cfg_regx.num_ch = channels - 2; - data = data | cfg_val.cfg_regval; - mask = mask | AUD_CONFIG_CH_MASK; + data = cfg_val.cfg_regval; + if (enable) + data |= 1; + mask = AUD_CONFIG_CH_MASK | 1; dev_dbg(intelhaddata->dev, "%s : data = %x, mask =%x\n", __func__, data, mask); - return had_read_modify(intelhaddata, AUD_CONFIG, data, mask); + had_read_modify(intelhaddata, AUD_CONFIG, data, mask); } +/* enable / disable the audio interface */ static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable) { u32 status_reg; @@ -272,13 +297,6 @@ static void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable) } } -static void snd_intelhad_enable_audio(struct snd_intelhad *intelhaddata, - bool enable) -{ - had_read_modify_aud_config_v2(intelhaddata, enable ? BIT(0) : 0, - BIT(0)); -} - static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata, u8 reset) { @@ -647,21 +665,17 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, /* * snd_intelhad_prog_buffer - programs buffer address and length registers - * @substream:substream for which the prepare function is called - * @intelhaddata:substream private data + * @substream: substream for which the prepare function is called + * @intelhaddata: substream private data * * This function programs ring buffer address and length into registers. */ -static int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata, - int start, int end) +static int snd_intelhad_prog_buffer(struct snd_pcm_substream *substream, + struct snd_intelhad *intelhaddata, + int start, int end) { u32 ring_buf_addr, ring_buf_size, period_bytes; u8 i, num_periods; - struct snd_pcm_substream *substream; - - substream = intelhaddata->stream_info.had_substream; - if (WARN_ON(!substream)) - return 0; ring_buf_addr = substream->runtime->dma_addr; ring_buf_size = snd_pcm_lib_buffer_bytes(substream); @@ -989,23 +1003,17 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) goto error; } + spin_lock_irq(&intelhaddata->had_spinlock); + intelhaddata->stream_info.substream = substream; + intelhaddata->stream_info.substream_refcount++; + spin_unlock_irq(&intelhaddata->had_spinlock); + return retval; error: pm_runtime_put(intelhaddata->dev); return retval; } -/* - * had_period_elapsed - updates the hardware pointer status - * @had_substream: substream for which the stream function is called - */ -static void had_period_elapsed(struct snd_pcm_substream *substream) -{ - if (!substream || !substream->runtime) - return; - snd_pcm_period_elapsed(substream); -} - /* * snd_intelhad_close - to free parameteres when stream is stopped * @substream: substream for which the function is called @@ -1019,7 +1027,15 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); intelhaddata->stream_info.buffer_rendered = 0; - intelhaddata->stream_info.had_substream = NULL; + spin_lock_irq(&intelhaddata->had_spinlock); + intelhaddata->stream_info.substream = NULL; + intelhaddata->stream_info.substream_refcount--; + while (intelhaddata->stream_info.substream_refcount > 0) { + spin_unlock_irq(&intelhaddata->had_spinlock); + cpu_relax(); + spin_lock_irq(&intelhaddata->had_spinlock); + } + spin_unlock_irq(&intelhaddata->had_spinlock); /* Check if following drv_status modification is required - VA */ if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { @@ -1125,7 +1141,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, /* Enable Audio */ snd_intelhad_enable_audio_int(intelhaddata, true); - snd_intelhad_enable_audio(intelhaddata, true); + snd_intelhad_enable_audio(substream, intelhaddata, true); break; case SNDRV_PCM_TRIGGER_STOP: @@ -1138,7 +1154,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, spin_unlock(&intelhaddata->had_spinlock); /* Disable Audio */ snd_intelhad_enable_audio_int(intelhaddata, false); - snd_intelhad_enable_audio(intelhaddata, false); + snd_intelhad_enable_audio(substream, intelhaddata, false); /* Reset buffer pointers */ snd_intelhad_reset_audio(intelhaddata, 1); snd_intelhad_reset_audio(intelhaddata, 0); @@ -1185,7 +1201,6 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(intelhaddata->dev, "rate=%d\n", runtime->rate); dev_dbg(intelhaddata->dev, "channels=%d\n", runtime->channels); - intelhaddata->stream_info.had_substream = substream; intelhaddata->stream_info.buffer_rendered = 0; /* Get N value in KHz */ @@ -1211,7 +1226,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) retval = snd_intelhad_audio_ctrl(substream, intelhaddata); /* Prog buffer address */ - retval = snd_intelhad_prog_buffer(intelhaddata, + retval = snd_intelhad_prog_buffer(substream, intelhaddata, HAD_BUF_TYPE_A, HAD_BUF_TYPE_D); /* @@ -1306,12 +1321,12 @@ static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata) u32 disp_samp_freq, n_param; u32 link_rate = 0; - substream = intelhaddata->stream_info.had_substream; - if (!substream || !substream->runtime) + substream = had_substream_get(intelhaddata); + if (!substream) return 0; /* Disable Audio */ - snd_intelhad_enable_audio(intelhaddata, false); + snd_intelhad_enable_audio(substream, intelhaddata, false); /* Update CTS value */ disp_samp_freq = intelhaddata->tmds_clock_speed; @@ -1332,9 +1347,10 @@ static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata) n_param, intelhaddata); /* Enable Audio */ - snd_intelhad_enable_audio(intelhaddata, true); + snd_intelhad_enable_audio(substream, intelhaddata, true); out: + had_substream_put(intelhaddata); return retval; } @@ -1348,11 +1364,9 @@ static int hdmi_lpe_audio_suspend(struct platform_device *pdev, pm_message_t state) { struct had_stream_data *had_stream; - struct snd_pcm_substream *substream; struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); had_stream = &intelhaddata->stream_data; - substream = intelhaddata->stream_info.had_substream; if (!pm_runtime_status_suspended(intelhaddata->dev)) { dev_err(intelhaddata->dev, "audio stream is active\n"); @@ -1463,10 +1477,10 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) enum intel_had_aud_buf_type buf_id; enum intel_had_aud_buf_type buff_done; struct pcm_stream_info *stream; + struct snd_pcm_substream *substream; u32 buf_size; struct had_stream_data *had_stream; int intr_count; - enum had_status_stream stream_type; unsigned long flags; had_stream = &intelhaddata->stream_data; @@ -1484,7 +1498,6 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) intelhaddata->buff_done = buf_id; buff_done = intelhaddata->buff_done; buf_size = intelhaddata->buf_info[buf_id].buf_size; - stream_type = had_stream->stream_type; /* Every debug statement has an implication * of ~5msec. Thus, avoid having >3 debug statements @@ -1536,11 +1549,13 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) /* In case of actual data, * report buffer_done to above ALSA layer */ - buf_size = intelhaddata->buf_info[buf_id].buf_size; - if (stream_type >= HAD_RUNNING_STREAM) { + substream = had_substream_get(intelhaddata); + if (substream) { + buf_size = intelhaddata->buf_info[buf_id].buf_size; intelhaddata->stream_info.buffer_rendered += (intr_count * buf_size); - had_period_elapsed(stream->had_substream); + snd_pcm_period_elapsed(substream); + had_substream_put(intelhaddata); } return 0; @@ -1552,6 +1567,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) enum intel_had_aud_buf_type buf_id; struct pcm_stream_info *stream; struct had_stream_data *had_stream; + struct snd_pcm_substream *substream; enum had_status_stream stream_type; unsigned long flags; int drv_status; @@ -1582,7 +1598,11 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) if (stream_type == HAD_RUNNING_STREAM) { /* Report UNDERRUN error to above layers */ - snd_pcm_stop_xrun(stream->had_substream); + substream = had_substream_get(intelhaddata); + if (substream) { + snd_pcm_stop_xrun(substream); + had_substream_put(intelhaddata); + } } return 0; @@ -1595,7 +1615,6 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata) struct snd_pcm_substream *substream; struct had_stream_data *had_stream; - substream = intelhaddata->stream_info.had_substream; had_stream = &intelhaddata->stream_data; spin_lock_irq(&intelhaddata->had_spinlock); @@ -1617,11 +1636,13 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata) buf_id); /* Safety check */ + substream = had_substream_get(intelhaddata); if (substream) { dev_dbg(intelhaddata->dev, "Force to stop the active stream by disconnection\n"); /* Set runtime->state to hw_params done */ snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); + had_substream_put(intelhaddata); } had_build_channel_allocation_map(intelhaddata); @@ -1632,38 +1653,40 @@ static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct had_stream_data *had_stream; + struct snd_pcm_substream *substream; had_stream = &intelhaddata->stream_data; buf_id = intelhaddata->curr_buf; + substream = had_substream_get(intelhaddata); + spin_lock_irq(&intelhaddata->had_spinlock); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "Device already disconnected\n"); spin_unlock_irq(&intelhaddata->had_spinlock); - return; + goto out; } /* Disable Audio */ snd_intelhad_enable_audio_int(intelhaddata, false); - snd_intelhad_enable_audio(intelhaddata, false); + snd_intelhad_enable_audio(substream, intelhaddata, false); intelhaddata->drv_status = HAD_DRV_DISCONNECTED; dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); + had_stream->stream_type = HAD_INIT; + spin_unlock_irq(&intelhaddata->had_spinlock); /* Report to above ALSA layer */ - if (intelhaddata->stream_info.had_substream != NULL) { - spin_unlock_irq(&intelhaddata->had_spinlock); - snd_pcm_stop(intelhaddata->stream_info.had_substream, - SNDRV_PCM_STATE_SETUP); - spin_lock_irq(&intelhaddata->had_spinlock); - } + if (substream) + snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP); - had_stream->stream_type = HAD_INIT; - spin_unlock_irq(&intelhaddata->had_spinlock); + out: + if (substream) + had_substream_put(intelhaddata); kfree(intelhaddata->chmap->chmap); intelhaddata->chmap->chmap = NULL; } -- cgit From 182cdf23dbf6672954ac646871bf5902050268c7 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 14:43:39 +0100 Subject: ALSA: x86: Implement runtime PM Although the driver has some PM callbacks, it doesn't do it right: - the suspend callback doesn't handle to suspend the running PCM, - the runtime PM ops are missing, - pm_runtime_get_sync() isn't used at the right place. This patch covers the above and provides the basic runtime PM functionality. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 127 +++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 77 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index c209d9498c0e..04ff7f14fe12 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -975,7 +975,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) runtime = substream->runtime; intelhaddata->underrun_count = 0; - pm_runtime_get(intelhaddata->dev); + pm_runtime_get_sync(intelhaddata->dev); if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", @@ -1129,6 +1129,8 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + case SNDRV_PCM_TRIGGER_RESUME: /* Disable local INTRs till register prgmng is done */ if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, @@ -1145,6 +1147,8 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, break; case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_SUSPEND: spin_lock(&intelhaddata->had_spinlock); intelhaddata->curr_buf = 0; @@ -1354,80 +1358,6 @@ out: return retval; } -/* - * hdmi_lpe_audio_suspend - power management suspend function - * @pdev: platform device - * - * This function is called to suspend the hdmi audio. - */ -static int hdmi_lpe_audio_suspend(struct platform_device *pdev, - pm_message_t state) -{ - struct had_stream_data *had_stream; - struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); - - had_stream = &intelhaddata->stream_data; - - if (!pm_runtime_status_suspended(intelhaddata->dev)) { - dev_err(intelhaddata->dev, "audio stream is active\n"); - return -EAGAIN; - } - - spin_lock_irq(&intelhaddata->had_spinlock); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - spin_unlock_irq(&intelhaddata->had_spinlock); - dev_dbg(intelhaddata->dev, "had not connected\n"); - return 0; - } - - if (intelhaddata->drv_status == HAD_DRV_SUSPENDED) { - spin_unlock_irq(&intelhaddata->had_spinlock); - dev_dbg(intelhaddata->dev, "had already suspended\n"); - return 0; - } - - intelhaddata->drv_status = HAD_DRV_SUSPENDED; - dev_dbg(intelhaddata->dev, - "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_SUSPENDED\n", - __func__, __LINE__); - - spin_unlock_irq(&intelhaddata->had_spinlock); - snd_intelhad_enable_audio_int(intelhaddata, false); - return 0; -} - -/* - * hdmi_lpe_audio_resume - power management resume function - * @pdev: platform device - * - * This function is called to resume the hdmi audio. - */ -static int hdmi_lpe_audio_resume(struct platform_device *pdev) -{ - struct snd_intelhad *intelhaddata = platform_get_drvdata(pdev); - - spin_lock_irq(&intelhaddata->had_spinlock); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { - spin_unlock_irq(&intelhaddata->had_spinlock); - dev_dbg(intelhaddata->dev, "had not connected\n"); - return 0; - } - - if (intelhaddata->drv_status != HAD_DRV_SUSPENDED) { - spin_unlock_irq(&intelhaddata->had_spinlock); - dev_dbg(intelhaddata->dev, "had is not in suspended state\n"); - return 0; - } - - intelhaddata->drv_status = HAD_DRV_CONNECTED; - dev_dbg(intelhaddata->dev, - "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", - __func__, __LINE__); - spin_unlock_irq(&intelhaddata->had_spinlock); - snd_intelhad_enable_audio_int(intelhaddata, true); - return 0; -} - static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, enum intel_had_aud_buf_type buf_id) { @@ -1808,6 +1738,7 @@ static void had_audio_wq(struct work_struct *work) container_of(work, struct snd_intelhad, hdmi_audio_wq); struct intel_hdmi_lpe_audio_pdata *pdata = ctx->dev->platform_data; + pm_runtime_get_sync(ctx->dev); mutex_lock(&ctx->mutex); if (!pdata->hdmi_connected) { dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", @@ -1848,6 +1779,44 @@ static void had_audio_wq(struct work_struct *work) hdmi_audio_mode_change(ctx); } mutex_unlock(&ctx->mutex); + pm_runtime_put(ctx->dev); +} + +/* + * PM callbacks + */ + +static int hdmi_lpe_audio_runtime_suspend(struct device *dev) +{ + struct snd_intelhad *ctx = dev_get_drvdata(dev); + struct snd_pcm_substream *substream; + + substream = had_substream_get(ctx); + if (substream) { + snd_pcm_suspend(substream); + had_substream_put(ctx); + } + + return 0; +} + +static int hdmi_lpe_audio_suspend(struct device *dev) +{ + struct snd_intelhad *ctx = dev_get_drvdata(dev); + int err; + + err = hdmi_lpe_audio_runtime_suspend(dev); + if (!err) + snd_power_change_state(ctx->card, SNDRV_CTL_POWER_D3hot); + return err; +} + +static int hdmi_lpe_audio_resume(struct device *dev) +{ + struct snd_intelhad *ctx = dev_get_drvdata(dev); + + snd_power_change_state(ctx->card, SNDRV_CTL_POWER_D0); + return 0; } /* release resources */ @@ -2021,14 +1990,18 @@ static int hdmi_lpe_audio_remove(struct platform_device *pdev) return 0; } +static const struct dev_pm_ops hdmi_lpe_audio_pm = { + SET_SYSTEM_SLEEP_PM_OPS(hdmi_lpe_audio_suspend, hdmi_lpe_audio_resume) + SET_RUNTIME_PM_OPS(hdmi_lpe_audio_runtime_suspend, NULL, NULL) +}; + static struct platform_driver hdmi_lpe_audio_driver = { .driver = { .name = "hdmi-lpe-audio", + .pm = &hdmi_lpe_audio_pm, }, .probe = hdmi_lpe_audio_probe, .remove = hdmi_lpe_audio_remove, - .suspend = hdmi_lpe_audio_suspend, - .resume = hdmi_lpe_audio_resume }; module_platform_driver(hdmi_lpe_audio_driver); -- cgit From f69bd104b5cded0db547636fddd9512d7e6cfbf3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 14:57:22 +0100 Subject: ALSA: x86: Move stream status into pcm_stream_info The only remaining field in struct had_stream_data is stream_type that holds the current stream status. Such information fits better in struct pcm_stream_info, so move it as a boolean "running" field to be clearer. This allows us to get rid or had_stream_data definition and references. Also, the superfluous status check get removed in a couple of places where we can call PCM helpers in anyway. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 50 ++++++++++++-------------------------------- 1 file changed, 13 insertions(+), 37 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 04ff7f14fe12..985b7e8d4eae 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -967,11 +967,9 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) { struct snd_intelhad *intelhaddata; struct snd_pcm_runtime *runtime; - struct had_stream_data *had_stream; int retval; intelhaddata = snd_pcm_substream_chip(substream); - had_stream = &intelhaddata->stream_data; runtime = substream->runtime; intelhaddata->underrun_count = 0; @@ -1122,10 +1120,8 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, { int retval = 0; struct snd_intelhad *intelhaddata; - struct had_stream_data *had_stream; intelhaddata = snd_pcm_substream_chip(substream); - had_stream = &intelhaddata->stream_data; switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -1139,7 +1135,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, break; } - had_stream->stream_type = HAD_RUNNING_STREAM; + intelhaddata->stream_info.running = true; /* Enable Audio */ snd_intelhad_enable_audio_int(intelhaddata, true); @@ -1154,7 +1150,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, /* Stop reporting BUFFER_DONE/UNDERRUN to above layers */ - had_stream->stream_type = HAD_INIT; + intelhaddata->stream_info.running = false; spin_unlock(&intelhaddata->had_spinlock); /* Disable Audio */ snd_intelhad_enable_audio_int(intelhaddata, false); @@ -1184,11 +1180,9 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) u32 link_rate = 0; struct snd_intelhad *intelhaddata; struct snd_pcm_runtime *runtime; - struct had_stream_data *had_stream; intelhaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; - had_stream = &intelhaddata->stream_data; if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", @@ -1364,9 +1358,6 @@ static inline int had_chk_intrmiss(struct snd_intelhad *intelhaddata, int i, intr_count = 0; enum intel_had_aud_buf_type buff_done; u32 buf_size, buf_addr; - struct had_stream_data *had_stream; - - had_stream = &intelhaddata->stream_data; buff_done = buf_id; @@ -1409,11 +1400,9 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) struct pcm_stream_info *stream; struct snd_pcm_substream *substream; u32 buf_size; - struct had_stream_data *had_stream; int intr_count; unsigned long flags; - had_stream = &intelhaddata->stream_data; stream = &intelhaddata->stream_info; intr_count = 1; @@ -1435,7 +1424,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) */ /* Check for any intr_miss in case of active playback */ - if (had_stream->stream_type == HAD_RUNNING_STREAM) { + if (stream->running) { intr_count = had_chk_intrmiss(intelhaddata, buf_id); if (!intr_count || (intr_count > 3)) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, @@ -1450,7 +1439,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) intelhaddata->buf_info[buf_id].is_valid = true; if (intelhaddata->valid_buf_cnt-1 == buf_id) { - if (had_stream->stream_type >= HAD_RUNNING_STREAM) + if (stream->running) intelhaddata->curr_buf = HAD_BUF_TYPE_A; } else intelhaddata->curr_buf = buf_id + 1; @@ -1496,27 +1485,23 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct pcm_stream_info *stream; - struct had_stream_data *had_stream; struct snd_pcm_substream *substream; - enum had_status_stream stream_type; unsigned long flags; int drv_status; - had_stream = &intelhaddata->stream_data; stream = &intelhaddata->stream_info; spin_lock_irqsave(&intelhaddata->had_spinlock, flags); buf_id = intelhaddata->curr_buf; - stream_type = had_stream->stream_type; intelhaddata->buff_done = buf_id; drv_status = intelhaddata->drv_status; - if (stream_type == HAD_RUNNING_STREAM) + if (stream->running) intelhaddata->curr_buf = HAD_BUF_TYPE_A; spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); - dev_dbg(intelhaddata->dev, "Enter:%s buf_id=%d, stream_type=%d\n", - __func__, buf_id, stream_type); + dev_dbg(intelhaddata->dev, "Enter:%s buf_id=%d, stream_running=%d\n", + __func__, buf_id, stream->running); snd_intelhad_handle_underrun(intelhaddata); @@ -1526,13 +1511,11 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) return 0; } - if (stream_type == HAD_RUNNING_STREAM) { - /* Report UNDERRUN error to above layers */ - substream = had_substream_get(intelhaddata); - if (substream) { - snd_pcm_stop_xrun(substream); - had_substream_put(intelhaddata); - } + /* Report UNDERRUN error to above layers */ + substream = had_substream_get(intelhaddata); + if (substream) { + snd_pcm_stop_xrun(substream); + had_substream_put(intelhaddata); } return 0; @@ -1543,9 +1526,6 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; struct snd_pcm_substream *substream; - struct had_stream_data *had_stream; - - had_stream = &intelhaddata->stream_data; spin_lock_irq(&intelhaddata->had_spinlock); if (intelhaddata->drv_status == HAD_DRV_CONNECTED) { @@ -1582,10 +1562,8 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata) static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) { enum intel_had_aud_buf_type buf_id; - struct had_stream_data *had_stream; struct snd_pcm_substream *substream; - had_stream = &intelhaddata->stream_data; buf_id = intelhaddata->curr_buf; substream = had_substream_get(intelhaddata); @@ -1607,7 +1585,6 @@ static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); - had_stream->stream_type = HAD_INIT; spin_unlock_irq(&intelhaddata->had_spinlock); /* Report to above ALSA layer */ @@ -1775,8 +1752,7 @@ static void had_audio_wq(struct work_struct *work) had_process_hot_plug(ctx); /* Process mode change if stream is active */ - if (ctx->stream_data.stream_type == HAD_RUNNING_STREAM) - hdmi_audio_mode_change(ctx); + hdmi_audio_mode_change(ctx); } mutex_unlock(&ctx->mutex); pm_runtime_put(ctx->dev); -- cgit From df0435db1db9e385acdc0a354896d2c0e878dbd5 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 15:37:11 +0100 Subject: ALSA: x86: Use the standard ELD bytes definitions We have some constants defined in drm/drm_edid.h, and clean up our own definitions. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 985b7e8d4eae..496d3e92b2a8 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -451,7 +451,7 @@ static int snd_intelhad_channel_allocation(struct snd_intelhad *intelhaddata, */ for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { - if (intelhaddata->eld.speaker_allocation_block & (1 << i)) + if (intelhaddata->eld[DRM_ELD_SPEAKER] & (1 << i)) spk_mask |= eld_speaker_allocation_bits[i]; } @@ -496,8 +496,8 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) return; } - dev_dbg(intelhaddata->dev, "eld.speaker_allocation_block = %x\n", - intelhaddata->eld.speaker_allocation_block); + dev_dbg(intelhaddata->dev, "eld speaker = %x\n", + intelhaddata->eld[DRM_ELD_SPEAKER]); /* WA: Fix the max channel supported to 8 */ @@ -508,14 +508,14 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) */ /* if 0x2F < eld < 0x4F fall back to 0x2f, else fall back to 0x4F */ - eld_high = intelhaddata->eld.speaker_allocation_block & eld_high_mask; + eld_high = intelhaddata->eld[DRM_ELD_SPEAKER] & eld_high_mask; if ((eld_high & (eld_high-1)) && (eld_high > 0x1F)) { /* eld_high & (eld_high-1): if more than 1 bit set */ /* 0x1F: 7 channels */ for (i = 1; i < 4; i++) { high_msb = eld_high & (0x80 >> i); if (high_msb) { - intelhaddata->eld.speaker_allocation_block &= + intelhaddata->eld[DRM_ELD_SPEAKER] &= high_msb | 0xF; break; } @@ -523,7 +523,7 @@ static void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata) } for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { - if (intelhaddata->eld.speaker_allocation_block & (1 << i)) + if (intelhaddata->eld[DRM_ELD_SPEAKER] & (1 << i)) spk_mask |= eld_speaker_allocation_bits[i]; } @@ -1743,7 +1743,7 @@ static void had_audio_wq(struct work_struct *work) break; } - memcpy(&ctx->eld, eld->eld_data, sizeof(ctx->eld)); + memcpy(ctx->eld, eld->eld_data, sizeof(ctx->eld)); ctx->dp_output = pdata->dp_output; ctx->tmds_clock_speed = pdata->tmds_clock_speed; -- cgit From 7ceba75f21e4ecb520b110ffada72cc0c9f5c072 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 15:58:35 +0100 Subject: ALSA: x86: Reduce redundant register field names Currently each register definition contains the own prefix in the union struct itself; for example, union aud_ch_status_0 has status_0_regx and status_0_regval fields. These are simply superfluous, since usually the type of the variable is seen in its declaration or in its name. In this patch, we cut off these prefixes. Now all register definitions have regx and regval fields consistently, instead. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 102 +++++++++++++++++++++---------------------- 1 file changed, 51 insertions(+), 51 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 496d3e92b2a8..f825d514500e 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -263,7 +263,7 @@ static void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, struct snd_intelhad *intelhaddata, bool enable) { - union aud_cfg cfg_val = {.cfg_regval = 0}; + union aud_cfg cfg_val = {.regval = 0}; u8 channels, data, mask; /* @@ -271,9 +271,9 @@ static void snd_intelhad_enable_audio(struct snd_pcm_substream *substream, * In this case just set channels to 2 */ channels = substream ? substream->runtime->channels : 2; - cfg_val.cfg_regx.num_ch = channels - 2; + cfg_val.regx.num_ch = channels - 2; - data = cfg_val.cfg_regval; + data = cfg_val.regval; if (enable) data |= 1; mask = AUD_CONFIG_CH_MASK | 1; @@ -310,39 +310,39 @@ static void snd_intelhad_reset_audio(struct snd_intelhad *intelhaddata, static int had_prog_status_reg(struct snd_pcm_substream *substream, struct snd_intelhad *intelhaddata) { - union aud_cfg cfg_val = {.cfg_regval = 0}; - union aud_ch_status_0 ch_stat0 = {.status_0_regval = 0}; - union aud_ch_status_1 ch_stat1 = {.status_1_regval = 0}; + union aud_cfg cfg_val = {.regval = 0}; + union aud_ch_status_0 ch_stat0 = {.regval = 0}; + union aud_ch_status_1 ch_stat1 = {.regval = 0}; int format; - ch_stat0.status_0_regx.lpcm_id = (intelhaddata->aes_bits & + ch_stat0.regx.lpcm_id = (intelhaddata->aes_bits & IEC958_AES0_NONAUDIO) >> 1; - ch_stat0.status_0_regx.clk_acc = (intelhaddata->aes_bits & + ch_stat0.regx.clk_acc = (intelhaddata->aes_bits & IEC958_AES3_CON_CLOCK) >> 4; - cfg_val.cfg_regx.val_bit = ch_stat0.status_0_regx.lpcm_id; + cfg_val.regx.val_bit = ch_stat0.regx.lpcm_id; switch (substream->runtime->rate) { case AUD_SAMPLE_RATE_32: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_32KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_32KHZ; break; case AUD_SAMPLE_RATE_44_1: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_44KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_44KHZ; break; case AUD_SAMPLE_RATE_48: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_48KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_48KHZ; break; case AUD_SAMPLE_RATE_88_2: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_88KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_88KHZ; break; case AUD_SAMPLE_RATE_96: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_96KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_96KHZ; break; case AUD_SAMPLE_RATE_176_4: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_176KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_176KHZ; break; case AUD_SAMPLE_RATE_192: - ch_stat0.status_0_regx.samp_freq = CH_STATUS_MAP_192KHZ; + ch_stat0.regx.samp_freq = CH_STATUS_MAP_192KHZ; break; default: @@ -351,23 +351,23 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, } had_write_register(intelhaddata, - AUD_CH_STATUS_0, ch_stat0.status_0_regval); + AUD_CH_STATUS_0, ch_stat0.regval); format = substream->runtime->format; if (format == SNDRV_PCM_FORMAT_S16_LE) { - ch_stat1.status_1_regx.max_wrd_len = MAX_SMPL_WIDTH_20; - ch_stat1.status_1_regx.wrd_len = SMPL_WIDTH_16BITS; + ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_20; + ch_stat1.regx.wrd_len = SMPL_WIDTH_16BITS; } else if (format == SNDRV_PCM_FORMAT_S24_LE) { - ch_stat1.status_1_regx.max_wrd_len = MAX_SMPL_WIDTH_24; - ch_stat1.status_1_regx.wrd_len = SMPL_WIDTH_24BITS; + ch_stat1.regx.max_wrd_len = MAX_SMPL_WIDTH_24; + ch_stat1.regx.wrd_len = SMPL_WIDTH_24BITS; } else { - ch_stat1.status_1_regx.max_wrd_len = 0; - ch_stat1.status_1_regx.wrd_len = 0; + ch_stat1.regx.max_wrd_len = 0; + ch_stat1.regx.wrd_len = 0; } had_write_register(intelhaddata, - AUD_CH_STATUS_1, ch_stat1.status_1_regval); + AUD_CH_STATUS_1, ch_stat1.regval); return 0; } @@ -379,26 +379,26 @@ static int had_prog_status_reg(struct snd_pcm_substream *substream, static int snd_intelhad_audio_ctrl(struct snd_pcm_substream *substream, struct snd_intelhad *intelhaddata) { - union aud_cfg cfg_val = {.cfg_regval = 0}; - union aud_buf_config buf_cfg = {.buf_cfgval = 0}; + union aud_cfg cfg_val = {.regval = 0}; + union aud_buf_config buf_cfg = {.regval = 0}; u8 channels; had_prog_status_reg(substream, intelhaddata); - buf_cfg.buf_cfg_regx.audio_fifo_watermark = FIFO_THRESHOLD; - buf_cfg.buf_cfg_regx.dma_fifo_watermark = DMA_FIFO_THRESHOLD; - buf_cfg.buf_cfg_regx.aud_delay = 0; - had_write_register(intelhaddata, AUD_BUF_CONFIG, buf_cfg.buf_cfgval); + buf_cfg.regx.audio_fifo_watermark = FIFO_THRESHOLD; + buf_cfg.regx.dma_fifo_watermark = DMA_FIFO_THRESHOLD; + buf_cfg.regx.aud_delay = 0; + had_write_register(intelhaddata, AUD_BUF_CONFIG, buf_cfg.regval); channels = substream->runtime->channels; - cfg_val.cfg_regx.num_ch = channels - 2; + cfg_val.regx.num_ch = channels - 2; if (channels <= 2) - cfg_val.cfg_regx.layout = LAYOUT0; + cfg_val.regx.layout = LAYOUT0; else - cfg_val.cfg_regx.layout = LAYOUT1; + cfg_val.regx.layout = LAYOUT1; - cfg_val.cfg_regx.val_bit = 1; - had_write_register(intelhaddata, AUD_CONFIG, cfg_val.cfg_regval); + cfg_val.regx.val_bit = 1; + had_write_register(intelhaddata, AUD_CONFIG, cfg_val.regval); return 0; } @@ -618,49 +618,49 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, struct snd_intelhad *intelhaddata) { int i; - union aud_ctrl_st ctrl_state = {.ctrl_val = 0}; - union aud_info_frame2 frame2 = {.fr2_val = 0}; - union aud_info_frame3 frame3 = {.fr3_val = 0}; + union aud_ctrl_st ctrl_state = {.regval = 0}; + union aud_info_frame2 frame2 = {.regval = 0}; + union aud_info_frame3 frame3 = {.regval = 0}; u8 checksum = 0; u32 info_frame; int channels; channels = substream->runtime->channels; - had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.ctrl_val); + had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.regval); if (intelhaddata->dp_output) { info_frame = DP_INFO_FRAME_WORD1; - frame2.fr2_val = 1; + frame2.regval = 1; } else { info_frame = HDMI_INFO_FRAME_WORD1; - frame2.fr2_regx.chnl_cnt = substream->runtime->channels - 1; + frame2.regx.chnl_cnt = substream->runtime->channels - 1; - frame3.fr3_regx.chnl_alloc = snd_intelhad_channel_allocation( + frame3.regx.chnl_alloc = snd_intelhad_channel_allocation( intelhaddata, channels); /* Calculte the byte wide checksum for all valid DIP words */ for (i = 0; i < BYTES_PER_WORD; i++) - checksum += (info_frame >> i*BITS_PER_BYTE) & MASK_BYTE0; + checksum += (info_frame >> (i * 8)) & 0xff; for (i = 0; i < BYTES_PER_WORD; i++) - checksum += (frame2.fr2_val >> i*BITS_PER_BYTE) & MASK_BYTE0; + checksum += (frame2.regval >> (i * 8)) & 0xff; for (i = 0; i < BYTES_PER_WORD; i++) - checksum += (frame3.fr3_val >> i*BITS_PER_BYTE) & MASK_BYTE0; + checksum += (frame3.regval >> (i * 8)) & 0xff; - frame2.fr2_regx.chksum = -(checksum); + frame2.regx.chksum = -(checksum); } had_write_register(intelhaddata, AUD_HDMIW_INFOFR, info_frame); - had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame2.fr2_val); - had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame3.fr3_val); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame2.regval); + had_write_register(intelhaddata, AUD_HDMIW_INFOFR, frame3.regval); /* program remaining DIP words with zero */ for (i = 0; i < HAD_MAX_DIP_WORDS-VALID_DIP_WORDS; i++) had_write_register(intelhaddata, AUD_HDMIW_INFOFR, 0x0); - ctrl_state.ctrl_regx.dip_freq = 1; - ctrl_state.ctrl_regx.dip_en_sta = 1; - had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.ctrl_val); + ctrl_state.regx.dip_freq = 1; + ctrl_state.regx.dip_en_sta = 1; + had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.regval); } /* -- cgit From 03c3437755881a9f6f1b5f8c05e62edf7898a87f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 16:19:03 +0100 Subject: ALSA: x86: Clean up unused defines and inclusions Many defines and constants are left unused. Clean them up. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index f825d514500e..82f48fbcd74b 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -21,19 +21,21 @@ * ALSA driver for Intel HDMI audio */ +#include #include #include #include #include #include -#include +#include #include -#include #include +#include +#include #include #include #include -#include +#include #include #include "intel_hdmi_audio.h" @@ -929,6 +931,8 @@ static int snd_intelhad_prog_n(u32 aud_samp_freq, u32 *n_param, return 0; } +#define MAX_CNT 0xFF + static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) { u32 hdmi_status = 0, i = 0; -- cgit From 4aedb9465f717a8393bb5f40581eb7942af12506 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 16:38:39 +0100 Subject: ALSA: x86: Create ELD control element Like other drivers, expose the ELD bytes via a control element so that user-space can parse it. For the simplicity, the code to register the ctl elements is refactored using an array. Also, since ELD ctl read copies the bytes also during disconnection, clear the ELD bytes at hot-unplug, in order to avoid the leak of the previous bogus ELD. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 72 +++++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 21 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 82f48fbcd74b..f49520117dd6 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -1669,22 +1669,52 @@ static int had_iec958_put(struct snd_kcontrol *kcontrol, return changed; } -static struct snd_kcontrol_new had_control_iec958_mask = { - .access = SNDRV_CTL_ELEM_ACCESS_READ, - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK), - .info = had_iec958_info, /* shared */ - .get = had_iec958_mask_get, -}; +static int had_ctl_eld_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; + uinfo->count = HDMI_MAX_ELD_BYTES; + return 0; +} -static struct snd_kcontrol_new had_control_iec958 = { - .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), - .info = had_iec958_info, - .get = had_iec958_get, - .put = had_iec958_put +static int had_ctl_eld_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_intelhad *intelhaddata = snd_kcontrol_chip(kcontrol); + + mutex_lock(&intelhaddata->mutex); + memcpy(ucontrol->value.bytes.data, intelhaddata->eld, + HDMI_MAX_ELD_BYTES); + mutex_unlock(&intelhaddata->mutex); + return 0; +} + +static struct snd_kcontrol_new had_controls[] = { + { + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK), + .info = had_iec958_info, /* shared */ + .get = had_iec958_mask_get, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), + .info = had_iec958_info, + .get = had_iec958_get, + .put = had_iec958_put, + }, + { + .access = (SNDRV_CTL_ELEM_ACCESS_READ | + SNDRV_CTL_ELEM_ACCESS_VOLATILE), + .iface = SNDRV_CTL_ELEM_IFACE_PCM, + .name = "ELD", + .info = had_ctl_eld_info, + .get = had_ctl_eld_get, + }, }; + static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) { struct snd_intelhad *ctx = dev_id; @@ -1724,6 +1754,7 @@ static void had_audio_wq(struct work_struct *work) if (!pdata->hdmi_connected) { dev_dbg(ctx->dev, "%s: Event: HAD_NOTIFY_HOT_UNPLUG\n", __func__); + memset(ctx->eld, 0, sizeof(ctx->eld)); /* clear the old ELD */ had_process_hot_unplug(ctx); } else { struct intel_hdmi_lpe_audio_eld *eld = &pdata->eld; @@ -1826,7 +1857,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) struct intel_hdmi_lpe_audio_pdata *pdata; int irq; struct resource *res_mmio; - int ret; + int i, ret; dev_dbg(&pdev->dev, "dma_mask: %p\n", pdev->dev.dma_mask); @@ -1918,13 +1949,12 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) SNDRV_DMA_TYPE_DEV, NULL, HAD_MAX_BUFFER, HAD_MAX_BUFFER); - /* IEC958 controls */ - ret = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958_mask, ctx)); - if (ret < 0) - goto err; - ret = snd_ctl_add(card, snd_ctl_new1(&had_control_iec958, ctx)); - if (ret < 0) - goto err; + /* create controls */ + for (i = 0; i < ARRAY_SIZE(had_controls); i++) { + ret = snd_ctl_add(card, snd_ctl_new1(&had_controls[i], ctx)); + if (ret < 0) + goto err; + } init_channel_allocations(); -- cgit From 36ed34662f1944ebf553b30fcba1abab1703d125 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 17:06:38 +0100 Subject: ALSA: x86: Set CA bits for DisplayPort too This is a guess work. Usually the DP audio info frame is just 8-bit shifted from HDMI AI, so let's try to put CA in DIP frame 2 [24-31]. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index f49520117dd6..24a18b88c927 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -626,20 +626,20 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, u8 checksum = 0; u32 info_frame; int channels; + int ca; channels = substream->runtime->channels; had_write_register(intelhaddata, AUD_CNTL_ST, ctrl_state.regval); + ca = snd_intelhad_channel_allocation(intelhaddata, channels); if (intelhaddata->dp_output) { info_frame = DP_INFO_FRAME_WORD1; - frame2.regval = 1; + frame2.regval = (substream->runtime->channels - 1) | (ca << 24); } else { info_frame = HDMI_INFO_FRAME_WORD1; frame2.regx.chnl_cnt = substream->runtime->channels - 1; - - frame3.regx.chnl_alloc = snd_intelhad_channel_allocation( - intelhaddata, channels); + frame3.regx.chnl_alloc = ca; /* Calculte the byte wide checksum for all valid DIP words */ for (i = 0; i < BYTES_PER_WORD; i++) -- cgit From 44684f61b23c68786834dd2a99d4a68d40a13308 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 17:27:40 +0100 Subject: ALSA: x86: Simplify comments It's a stand-alone small driver code, and we don't have to describe too much formalized comments in kernel-doc style for local functions at all. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 66 ++++++++++---------------------------------- 1 file changed, 14 insertions(+), 52 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 24a18b88c927..5613c675ce70 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -609,11 +609,7 @@ static int had_register_chmap_ctls(struct snd_intelhad *intelhaddata, } /* - * snd_intelhad_prog_dip - to initialize Data Island Packets registers - * - * @substream:substream for which the prepare function is called - * @intelhaddata:substream private data - * + * Initialize Data Island Packets registers * This function is called in the prepare callback */ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, @@ -666,10 +662,7 @@ static void snd_intelhad_prog_dip(struct snd_pcm_substream *substream, } /* - * snd_intelhad_prog_buffer - programs buffer address and length registers - * @substream: substream for which the prepare function is called - * @intelhaddata: substream private data - * + * Programs buffer address and length registers * This function programs ring buffer address and length into registers. */ static int snd_intelhad_prog_buffer(struct snd_pcm_substream *substream, @@ -824,7 +817,7 @@ static int had_calculate_maud_value(u32 aud_samp_freq, u32 link_rate) } /* - * snd_intelhad_prog_cts - Program HDMI audio CTS value + * Program HDMI audio CTS value * * @aud_samp_freq: sampling frequency of audio data * @tmds: sampling frequency of the display data @@ -896,7 +889,7 @@ static int had_calculate_n_value(u32 aud_samp_freq) } /* - * snd_intelhad_prog_n - Program HDMI audio N value + * Program HDMI audio N value * * @aud_samp_freq: sampling frequency of audio data * @n_param: N value, depends on aud_samp_freq @@ -962,10 +955,7 @@ static void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata) } /* - * snd_intelhad_open - stream initializations are done here - * @substream:substream for which the stream function is called - * - * This function is called whenever a PCM stream is opened + * ALSA PCM open callback */ static int snd_intelhad_open(struct snd_pcm_substream *substream) { @@ -1017,10 +1007,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) } /* - * snd_intelhad_close - to free parameteres when stream is stopped - * @substream: substream for which the function is called - * - * This function is called by ALSA framework when stream is stopped + * ALSA PCM close callback */ static int snd_intelhad_close(struct snd_pcm_substream *substream) { @@ -1051,12 +1038,7 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) } /* - * snd_intelhad_hw_params - to setup the hardware parameters - * like allocating the buffers - * @substream: substream for which the function is called - * @hw_params: hardware parameters - * - * This function is called by ALSA framework when hardware params are set + * ALSA PCM hw_params callback */ static int snd_intelhad_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *hw_params) @@ -1090,11 +1072,7 @@ static int snd_intelhad_hw_params(struct snd_pcm_substream *substream, } /* - * snd_intelhad_hw_free - to release the resources allocated during - * hardware params setup - * @substream: substream for which the function is called - * - * This function is called by ALSA framework before close callback. + * ALSA PCM hw_free callback */ static int snd_intelhad_hw_free(struct snd_pcm_substream *substream) { @@ -1113,11 +1091,7 @@ static int snd_intelhad_hw_free(struct snd_pcm_substream *substream) } /* - * snd_intelhad_pcm_trigger - stream activities are handled here - * @substream: substream for which the stream function is called - * @cmd: the stream commamd thats requested from upper layer - * - * This function is called whenever an a stream activity is invoked + * ALSA PCM trigger callback */ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, int cmd) @@ -1172,10 +1146,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, } /* - * snd_intelhad_pcm_prepare - internal preparation before starting a stream - * @substream: substream for which the function is called - * - * This function is called when a stream is started for internal preparation. + * ALSA PCM prepare callback */ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) { @@ -1243,14 +1214,10 @@ prep_end: } /* - * snd_intelhad_pcm_pointer- to send the current buffer pointerprocessed by hw - * @substream: substream for which the function is called - * - * This function is called by ALSA framework to get the current hw buffer ptr - * when a period is elapsed + * ALSA PCM pointer callback */ -static snd_pcm_uframes_t snd_intelhad_pcm_pointer( - struct snd_pcm_substream *substream) +static snd_pcm_uframes_t +snd_intelhad_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_intelhad *intelhaddata; u32 bytes_rendered = 0; @@ -1299,12 +1266,7 @@ static snd_pcm_uframes_t snd_intelhad_pcm_pointer( } /* - * snd_intelhad_pcm_mmap- mmaps a kernel buffer to user space for copying data - * @substream: substream for which the function is called - * @vma: struct instance of memory VMM memory area - * - * This function is called by OS when a user space component - * tries to get mmap memory from driver + * ALSA PCM mmap callback */ static int snd_intelhad_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) -- cgit From 73997b050c995f34f3617d344f1e767d15b2477d Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 17:38:50 +0100 Subject: ALSA: x86: Yet more tidy-up and clean-ups - Add a few more comments to functions. - Move the initialization of some PCM state variables to open and prepare callbacks, where these are clearer places. - Remove superfluous NULL checks. - Get rid of the bogus drv_status change to CONNECTED at close; this doesn't make any sense. Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 68 +++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 32 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index 5613c675ce70..f032610d1287 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -965,7 +965,6 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; - intelhaddata->underrun_count = 0; pm_runtime_get_sync(intelhaddata->dev); @@ -989,17 +988,20 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) */ retval = snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 64); - if (retval < 0) { - dev_dbg(intelhaddata->dev, "%s:step_size=64 failed,err=%d\n", - __func__, retval); + if (retval < 0) goto error; - } + /* expose PCM substream */ spin_lock_irq(&intelhaddata->had_spinlock); intelhaddata->stream_info.substream = substream; intelhaddata->stream_info.substream_refcount++; spin_unlock_irq(&intelhaddata->had_spinlock); + /* these are cleared in prepare callback, but just to be sure */ + intelhaddata->curr_buf = 0; + intelhaddata->underrun_count = 0; + intelhaddata->stream_info.buffer_rendered = 0; + return retval; error: pm_runtime_put(intelhaddata->dev); @@ -1015,7 +1017,7 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); - intelhaddata->stream_info.buffer_rendered = 0; + /* unreference and sync with the pending PCM accesses */ spin_lock_irq(&intelhaddata->had_spinlock); intelhaddata->stream_info.substream = NULL; intelhaddata->stream_info.substream_refcount--; @@ -1026,13 +1028,6 @@ static int snd_intelhad_close(struct snd_pcm_substream *substream) } spin_unlock_irq(&intelhaddata->had_spinlock); - /* Check if following drv_status modification is required - VA */ - if (intelhaddata->drv_status != HAD_DRV_DISCONNECTED) { - intelhaddata->drv_status = HAD_DRV_CONNECTED; - dev_dbg(intelhaddata->dev, - "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", - __func__, __LINE__); - } pm_runtime_put(intelhaddata->dev); return 0; } @@ -1047,9 +1042,6 @@ static int snd_intelhad_hw_params(struct snd_pcm_substream *substream, unsigned long addr; int pages, buf_size, retval; - if (!hw_params) - return -EINVAL; - intelhaddata = snd_pcm_substream_chip(substream); buf_size = params_buffer_bytes(hw_params); retval = snd_pcm_lib_malloc_pages(substream, buf_size); @@ -1124,7 +1116,6 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_SUSPEND: spin_lock(&intelhaddata->had_spinlock); - intelhaddata->curr_buf = 0; /* Stop reporting BUFFER_DONE/UNDERRUN to above layers */ @@ -1174,6 +1165,8 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) dev_dbg(intelhaddata->dev, "rate=%d\n", runtime->rate); dev_dbg(intelhaddata->dev, "channels=%d\n", runtime->channels); + intelhaddata->curr_buf = 0; + intelhaddata->underrun_count = 0; intelhaddata->stream_info.buffer_rendered = 0; /* Get N value in KHz */ @@ -1247,7 +1240,6 @@ snd_intelhad_pcm_pointer(struct snd_pcm_substream *substream) dev_dbg(intelhaddata->dev, "assume audio_codec_reset, underrun = %d - do xrun\n", intelhaddata->underrun_count); - intelhaddata->underrun_count = 0; return SNDRV_PCM_POS_XRUN; } } else { @@ -1277,6 +1269,21 @@ static int snd_intelhad_pcm_mmap(struct snd_pcm_substream *substream, vma->vm_end - vma->vm_start, vma->vm_page_prot); } +/* + * ALSA PCM ops + */ +static const struct snd_pcm_ops snd_intelhad_playback_ops = { + .open = snd_intelhad_open, + .close = snd_intelhad_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = snd_intelhad_hw_params, + .hw_free = snd_intelhad_hw_free, + .prepare = snd_intelhad_pcm_prepare, + .trigger = snd_intelhad_pcm_trigger, + .pointer = snd_intelhad_pcm_pointer, + .mmap = snd_intelhad_pcm_mmap, +}; + /* process mode change of the running stream; called in mutex */ static int hdmi_audio_mode_change(struct snd_intelhad *intelhaddata) { @@ -1564,18 +1571,9 @@ static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) intelhaddata->chmap->chmap = NULL; } -/* PCM operations structure and the calls back for the same */ -static struct snd_pcm_ops snd_intelhad_playback_ops = { - .open = snd_intelhad_open, - .close = snd_intelhad_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_intelhad_hw_params, - .hw_free = snd_intelhad_hw_free, - .prepare = snd_intelhad_pcm_prepare, - .trigger = snd_intelhad_pcm_trigger, - .pointer = snd_intelhad_pcm_pointer, - .mmap = snd_intelhad_pcm_mmap, -}; +/* + * ALSA iec958 and ELD controls + */ static int had_iec958_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -1651,7 +1649,7 @@ static int had_ctl_eld_get(struct snd_kcontrol *kcontrol, return 0; } -static struct snd_kcontrol_new had_controls[] = { +static const struct snd_kcontrol_new had_controls[] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1676,7 +1674,9 @@ static struct snd_kcontrol_new had_controls[] = { }, }; - +/* + * audio interrupt handler + */ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) { struct snd_intelhad *ctx = dev_id; @@ -1698,6 +1698,9 @@ static irqreturn_t display_pipe_interrupt_handler(int irq, void *dev_id) return IRQ_HANDLED; } +/* + * monitor plug/unplug notification from i915; just kick off the work + */ static void notify_audio_lpe(struct platform_device *pdev) { struct snd_intelhad *ctx = platform_get_drvdata(pdev); @@ -1705,6 +1708,7 @@ static void notify_audio_lpe(struct platform_device *pdev) schedule_work(&ctx->hdmi_audio_wq); } +/* the work to handle monitor hot plug/unplug */ static void had_audio_wq(struct work_struct *work) { struct snd_intelhad *ctx = -- cgit From 91b0cb0cc07bcb5114df2897531f4ea41c148c8e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 2 Feb 2017 17:46:49 +0100 Subject: ALSA: x86: Rename drv_status to connected After the rewrite of the runtime PM code, we have only two driver status: CONNECTED and DISCONNECTED. So it's clearer to use a boolean flag, and name it easier one, "connected". Signed-off-by: Takashi Iwai --- sound/x86/intel_hdmi_audio.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'sound/x86/intel_hdmi_audio.c') diff --git a/sound/x86/intel_hdmi_audio.c b/sound/x86/intel_hdmi_audio.c index f032610d1287..c83f02c2593e 100644 --- a/sound/x86/intel_hdmi_audio.c +++ b/sound/x86/intel_hdmi_audio.c @@ -202,7 +202,7 @@ mid_hdmi_audio_write(struct snd_intelhad *ctx, u32 reg, u32 val) static int had_read_register(struct snd_intelhad *intelhaddata, u32 offset, u32 *data) { - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + if (!intelhaddata->connected) return -ENODEV; mid_hdmi_audio_read(intelhaddata, offset, data); @@ -221,7 +221,7 @@ static void fixup_dp_config(struct snd_intelhad *intelhaddata, static int had_write_register(struct snd_intelhad *intelhaddata, u32 offset, u32 data) { - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + if (!intelhaddata->connected) return -ENODEV; fixup_dp_config(intelhaddata, offset, &data); @@ -234,7 +234,7 @@ static int had_read_modify(struct snd_intelhad *intelhaddata, u32 offset, { u32 val_tmp; - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + if (!intelhaddata->connected) return -ENODEV; mid_hdmi_audio_read(intelhaddata, offset, &val_tmp); @@ -556,7 +556,7 @@ static int had_chmap_ctl_info(struct snd_kcontrol *kcontrol, struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol); struct snd_intelhad *intelhaddata = info->private_data; - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + if (!intelhaddata->connected) return -ENODEV; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = HAD_MAX_CHANNEL; @@ -573,7 +573,7 @@ static int had_chmap_ctl_get(struct snd_kcontrol *kcontrol, int i; const struct snd_pcm_chmap_elem *chmap; - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + if (!intelhaddata->connected) return -ENODEV; mutex_lock(&intelhaddata->mutex); @@ -968,7 +968,7 @@ static int snd_intelhad_open(struct snd_pcm_substream *substream) pm_runtime_get_sync(intelhaddata->dev); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + if (!intelhaddata->connected) { dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", __func__); retval = -ENODEV; @@ -1098,7 +1098,7 @@ static int snd_intelhad_pcm_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: case SNDRV_PCM_TRIGGER_RESUME: /* Disable local INTRs till register prgmng is done */ - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + if (!intelhaddata->connected) { dev_dbg(intelhaddata->dev, "_START: HDMI cable plugged-out\n"); retval = -ENODEV; @@ -1150,7 +1150,7 @@ static int snd_intelhad_pcm_prepare(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + if (!intelhaddata->connected) { dev_dbg(intelhaddata->dev, "%s: HDMI cable plugged-out\n", __func__); retval = -ENODEV; @@ -1219,7 +1219,7 @@ snd_intelhad_pcm_pointer(struct snd_pcm_substream *substream) intelhaddata = snd_pcm_substream_chip(substream); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) + if (!intelhaddata->connected) return SNDRV_PCM_POS_XRUN; /* Use a hw register to calculate sub-period position reports. @@ -1380,7 +1380,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) intr_count = 1; spin_lock_irqsave(&intelhaddata->had_spinlock, flags); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + if (!intelhaddata->connected) { spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); dev_dbg(intelhaddata->dev, "%s:Device already disconnected\n", __func__); @@ -1419,7 +1419,7 @@ static int had_process_buffer_done(struct snd_intelhad *intelhaddata) spin_unlock_irqrestore(&intelhaddata->had_spinlock, flags); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + if (!intelhaddata->connected) { dev_dbg(intelhaddata->dev, "HDMI cable plugged-out\n"); return 0; } @@ -1460,14 +1460,14 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) struct pcm_stream_info *stream; struct snd_pcm_substream *substream; unsigned long flags; - int drv_status; + int connected; stream = &intelhaddata->stream_info; spin_lock_irqsave(&intelhaddata->had_spinlock, flags); buf_id = intelhaddata->curr_buf; intelhaddata->buff_done = buf_id; - drv_status = intelhaddata->drv_status; + connected = intelhaddata->connected; if (stream->running) intelhaddata->curr_buf = HAD_BUF_TYPE_A; @@ -1478,7 +1478,7 @@ static int had_process_buffer_underrun(struct snd_intelhad *intelhaddata) snd_intelhad_handle_underrun(intelhaddata); - if (drv_status == HAD_DRV_DISCONNECTED) { + if (!connected) { dev_dbg(intelhaddata->dev, "%s:Device already disconnected\n", __func__); return 0; @@ -1501,7 +1501,7 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata) struct snd_pcm_substream *substream; spin_lock_irq(&intelhaddata->had_spinlock); - if (intelhaddata->drv_status == HAD_DRV_CONNECTED) { + if (intelhaddata->connected) { dev_dbg(intelhaddata->dev, "Device already connected\n"); spin_unlock_irq(&intelhaddata->had_spinlock); return; @@ -1509,7 +1509,7 @@ static void had_process_hot_plug(struct snd_intelhad *intelhaddata) buf_id = intelhaddata->curr_buf; intelhaddata->buff_done = buf_id; - intelhaddata->drv_status = HAD_DRV_CONNECTED; + intelhaddata->connected = true; dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_CONNECTED\n", __func__, __LINE__); @@ -1543,7 +1543,7 @@ static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) spin_lock_irq(&intelhaddata->had_spinlock); - if (intelhaddata->drv_status == HAD_DRV_DISCONNECTED) { + if (!intelhaddata->connected) { dev_dbg(intelhaddata->dev, "Device already disconnected\n"); spin_unlock_irq(&intelhaddata->had_spinlock); goto out; @@ -1554,7 +1554,7 @@ static void had_process_hot_unplug(struct snd_intelhad *intelhaddata) snd_intelhad_enable_audio_int(intelhaddata, false); snd_intelhad_enable_audio(substream, intelhaddata, false); - intelhaddata->drv_status = HAD_DRV_DISCONNECTED; + intelhaddata->connected = false; dev_dbg(intelhaddata->dev, "%s @ %d:DEBUG PLUG/UNPLUG : HAD_DRV_DISCONNECTED\n", __func__, __LINE__); @@ -1855,7 +1855,7 @@ static int hdmi_lpe_audio_probe(struct platform_device *pdev) ctx = card->private_data; spin_lock_init(&ctx->had_spinlock); mutex_init(&ctx->mutex); - ctx->drv_status = HAD_DRV_DISCONNECTED; + ctx->connected = false; ctx->dev = &pdev->dev; ctx->card = card; ctx->aes_bits = SNDRV_PCM_DEFAULT_CON_SPDIF; @@ -1960,7 +1960,7 @@ static int hdmi_lpe_audio_remove(struct platform_device *pdev) { struct snd_intelhad *ctx = platform_get_drvdata(pdev); - if (ctx->drv_status != HAD_DRV_DISCONNECTED) + if (ctx->connected) snd_intelhad_enable_audio_int(ctx, false); snd_card_free(ctx->card); return 0; -- cgit