All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] ALSA: hda/via - fix occasionally no sound with VT1802
       [not found] <tencent_F4C3EF827E2193D1C7323B9F51D53CA91D0A@qq.com>
@ 2021-11-23  8:25 ` Takashi Iwai
  2021-11-23  8:39   ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQUxTQTogaGRhL3ZpYSAtIGZpeCBvY2Nhc2lvbmFsbHkgbm8gc291bmQgd2l0aCBWVDE4MDI=?= =?gb18030?B?taXH+tGtu7c=?=
  0 siblings, 1 reply; 2+ messages in thread
From: Takashi Iwai @ 2021-11-23  8:25 UTC (permalink / raw)
  To: tianyucode; +Cc: alsa-devel, tianyu, tiwai

On Tue, 23 Nov 2021 09:07:14 +0100,
tianyucode wrote:
> 
> From: tianyu <tianyu@kylinos.cn>
> 
> Hi guys, I'm a new guy for audio driver.
> 
> I have encountered a problem. When using the VT1802 codec,
> there will be no sound occasionally. After checking the initialization process,
> I found that the cause of the problem is that the power state does not have
> hda_set_power_state(codec, AC_PWRST_D0).
> 
> 1. The power state is set to AC_PWRST_D0 during the first initialization:
> 
> azx_probe_continue
> 	azx_probe_codecs
> 		snd_hda_codec_new
> 			snd_hda_codec_device_new
> 				hda_set_power_state(codec, AC_PWRST_D0);
> 
> 2. Then, the power state is set to AC_PWRST_D3 in VT1802, but not set in realtek (ALC269).
> 
> azx_probe_continue
> 	azx_codec_configure
> 		…
> 		patch_vt2002
> 			via_parse_auto_config
> 				snd_hda_gen_parse_auto_config
> 					add_all_pin_power_ctls
> 						add_pin_power_ctls
> 							set_path_power
> 
> static void add_all_pin_power_ctls(struct hda_codec *codec, bool on)
> {
> 	/**/
> 	if (!codec->power_save_node)
> 		return;
> 
> 	add_pin_power_ctls(codec, cfg->line_outs, cfg->line_out_pins, on);
> 	/**/
> }
> 
> The power_save_node is set to 0 in patch_alc269 and it returns here,
> but it is set to 1 in VT1802.
> 
> patch_vt2002P
> 	via_new_spec
> 		codec->power_save_node = 1;
> 	via_parse_auto_config
> 		snd_hda_gen_parse_auto_config
> 		codec->power_save_node = 0;//it set to 0 here,but add_all_pin_power_ctls has been done
> 
> patch_alc269
> 	codec->power_save_node = 0;
> 
> 3. Next there is a suspend and resume process, the resume process will also set the
> power state to AC_PWRST_D0, but I think there is a problem with this process.
> 
> (1)suspend:
> 
> azx_probe_continue
> 	snd_card_register
> 		..
> 		snd_hda_codec_dev_register
> 			snd_hda_codec_register
> 				snd_hda_power_down
> 					pm_runtime_put_autosuspend
> 					__pm_runtime_suspend(dev, RPM_GET_PUT | RPM_ASYNC | RPM_AUTO);
> 						rpm_suspend
> 
> static int rpm_suspend(struct device *dev, int rpmflags)
> {
> 	/**/
> 	if (rpmflags & RPM_ASYNC) {
> 		dev->power.request = (rpmflags & RPM_AUTO) ?
> 		    RPM_REQ_AUTOSUSPEND : RPM_REQ_SUSPEND;
> 		if (!dev->power.request_pending) {
> 			dev->power.request_pending = true;
> 			queue_work(pm_wq, &dev->power.work);
> 		}
> 		goto out;
> 	}
> 
> 	__update_runtime_status(dev, RPM_SUSPENDING);
> 
> 	/**/
> 	retval = rpm_callback(callback, dev);
> 	__update_runtime_status(dev, RPM_SUSPENDED);
> 	/**/
> }
> 
> The first call to rpm_suspend has the RPM_ASYNC flag, so queue_work is called,
> and the work queue is used to enter rpm_suspend
> 
> pm_runtime_init
> 	INIT_WORK(&dev->power.work, pm_runtime_work);
> 
> (2)resume:
> 
> azx_probe_continue
> 	set_default_power_save
> 		snd_hda_set_power_save(&chip->bus, val * 1000);
> 			codec_set_power_save(c, delay);
> 
> int val = power_save;
> static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;//It is 0 in my .config
> 
> static void codec_set_power_save(struct hda_codec *codec, int delay)
> {
> 	struct device *dev = hda_codec_dev(codec);
> 	if (delay == 0 && codec->auto_runtime_pm)
> 		delay = 3000;
> 
> 	if (delay > 0) {
> 		pm_runtime_set_autosuspend_delay(dev, delay);
> 		pm_runtime_use_autosuspend(dev);
> 		pm_runtime_allow(dev);
> 		if (!pm_runtime_suspended(dev))
> 			pm_runtime_mark_last_busy(dev);
> 	} else {
> 		pm_runtime_dont_use_autosuspend(dev);
> 		pm_runtime_forbid(dev);
> 	}
> }
> 
> pm_runtime_forbid
> 	rpm_resume(dev, 0);
> 
> static int rpm_resume(struct device *dev, int rpmflags)
> {
> 	/**/
> 	if (dev->power.runtime_status == RPM_ACTIVE) {
> 		retval = 1;
> 		goto out;
> 	}
> 
> 	/**/
> 	_update_runtime_status(dev, RPM_RESUMING);
> 	retval = rpm_callback(callback, dev);
> 	/**/
> 	__update_runtime_status(dev, RPM_ACTIVE);
> 	/**/
> }
> 
> The callback functions of suspend and resume are as follows, which set the power state:
> 
> hda_call_codec_suspend
> 	state = hda_set_power_state(codec, AC_PWRST_D3);
> 
> hda_call_codec_resume
> 	hda_set_power_state(codec, AC_PWRST_D0);
> 
> You can see that the resume function relies on dev->power.runtime_status,
> and the status is set in rpm_suspend. The operation of rpm_suspend depends
> on the scheduling of the work queue. I added print debugging on my machine,
> and occasionally there will be pm_runtime_work in Run after rpm_resume.
> At this time, the suspend and resume processes are not performed correctly.
> In VT1802, the power_state is still D3, and the machine has no sound.
> 
> 4. I searched the Internet and did not find the relevant modification,
> but found the commit 317d9313925c (ALSA: hda/realtek-Set default power save node to 0).
> 
> Does VIA need to be modified like this?
> 
> Since I am not familiar with ALSA and runtime pm, so come here to consult.

For VIA codecs, there is an additional fixup table to turn off the
power_save_node.  Add an entry with the PCI SSID of your device to
vt2002p_fixups[] table with VIA_FIXUP_POWER_SAVE.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 2+ messages in thread

* =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQUxTQTogaGRhL3ZpYSAtIGZpeCBvY2Nhc2lvbmFsbHkgbm8gc291bmQgd2l0aCBWVDE4MDI=?=
  2021-11-23  8:25 ` [PATCH] ALSA: hda/via - fix occasionally no sound with VT1802 Takashi Iwai
@ 2021-11-23  8:39   ` =?gb18030?B?taXH+tGtu7c=?=
  0 siblings, 0 replies; 2+ messages in thread
From: =?gb18030?B?taXH+tGtu7c=?= @ 2021-11-23  8:39 UTC (permalink / raw)
  To: =?gb18030?B?VGFrYXNoaSBJd2Fp?=
  Cc: =?gb18030?B?YWxzYS1kZXZlbA==?=, =?gb18030?B?dGlhbnl1?=,
	=?gb18030?B?dGl3YWk=?=

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="gb18030", Size: 6500 bytes --]

Is my guess on this question correct? I am afraid that this parameter will have other effects




------------------&nbsp;ԭʼÓʼþ&nbsp;------------------
·¢¼þÈË:                                                                                                                        "Takashi Iwai"                                                                                    <tiwai@suse.de&gt;;
·¢ËÍʱ¼ä:&nbsp;2021Äê11ÔÂ23ÈÕ(ÐÇÆÚ¶þ) ÏÂÎç4:25
ÊÕ¼þÈË:&nbsp;"µ¥ÇúÑ­»·"<tianyucode@foxmail.com&gt;;
³­ËÍ:&nbsp;"perex"<perex@perex.cz&gt;;"tiwai"<tiwai@suse.com&gt;;"alsa-devel"<alsa-devel@alsa-project.org&gt;;"tianyu"<tianyu@kylinos.cn&gt;;
Ö÷Ìâ:&nbsp;Re: [PATCH] ALSA: hda/via - fix occasionally no sound with VT1802



On Tue, 23 Nov 2021 09:07:14 +0100,
tianyucode wrote:
&gt; 
&gt; From: tianyu <tianyu@kylinos.cn&gt;
&gt; 
&gt; Hi guys, I'm a new guy for audio driver.
&gt; 
&gt; I have encountered a problem. When using the VT1802 codec,
&gt; there will be no sound occasionally. After checking the initialization process,
&gt; I found that the cause of the problem is that the power state does not have
&gt; hda_set_power_state(codec, AC_PWRST_D0).
&gt; 
&gt; 1. The power state is set to AC_PWRST_D0 during the first initialization£º
&gt; 
&gt; azx_probe_continue
&gt; 	azx_probe_codecs
&gt; 		snd_hda_codec_new
&gt; 			snd_hda_codec_device_new
&gt; 				hda_set_power_state(codec, AC_PWRST_D0);
&gt; 
&gt; 2. Then, the power state is set to AC_PWRST_D3 in VT1802, but not set in realtek (ALC269).
&gt; 
&gt; azx_probe_continue
&gt; 	azx_codec_configure
&gt; 		¡­
&gt; 		patch_vt2002
&gt; 			via_parse_auto_config
&gt; 				snd_hda_gen_parse_auto_config
&gt; 					add_all_pin_power_ctls
&gt; 						add_pin_power_ctls
&gt; 							set_path_power
&gt; 
&gt; static void add_all_pin_power_ctls(struct hda_codec *codec, bool on)
&gt; {
&gt; 	/**/
&gt; 	if (!codec-&gt;power_save_node)
&gt; 		return;
&gt; 
&gt; 	add_pin_power_ctls(codec, cfg-&gt;line_outs, cfg-&gt;line_out_pins, on);
&gt; 	/**/
&gt; }
&gt; 
&gt; The power_save_node is set to 0 in patch_alc269 and it returns here,
&gt; but it is set to 1 in VT1802.
&gt; 
&gt; patch_vt2002P
&gt; 	via_new_spec
&gt; 		codec-&gt;power_save_node = 1;
&gt; 	via_parse_auto_config
&gt; 		snd_hda_gen_parse_auto_config
&gt; 		codec-&gt;power_save_node = 0;//it set to 0 here,but add_all_pin_power_ctls has been done
&gt; 
&gt; patch_alc269
&gt; 	codec-&gt;power_save_node = 0;
&gt; 
&gt; 3. Next there is a suspend and resume process, the resume process will also set the
&gt; power state to AC_PWRST_D0, but I think there is a problem with this process.
&gt; 
&gt; (1)suspend:
&gt; 
&gt; azx_probe_continue
&gt; 	snd_card_register
&gt; 		..
&gt; 		snd_hda_codec_dev_register
&gt; 			snd_hda_codec_register
&gt; 				snd_hda_power_down
&gt; 					pm_runtime_put_autosuspend
&gt; 					__pm_runtime_suspend(dev, RPM_GET_PUT | RPM_ASYNC | RPM_AUTO);
&gt; 						rpm_suspend
&gt; 
&gt; static int rpm_suspend(struct device *dev, int rpmflags)
&gt; {
&gt; 	/**/
&gt; 	if (rpmflags &amp; RPM_ASYNC) {
&gt; 		dev-&gt;power.request = (rpmflags &amp; RPM_AUTO) ?
&gt; 		&nbsp;&nbsp;&nbsp; RPM_REQ_AUTOSUSPEND : RPM_REQ_SUSPEND;
&gt; 		if (!dev-&gt;power.request_pending) {
&gt; 			dev-&gt;power.request_pending = true;
&gt; 			queue_work(pm_wq, &amp;dev-&gt;power.work);
&gt; 		}
&gt; 		goto out;
&gt; 	}
&gt; 
&gt; 	__update_runtime_status(dev, RPM_SUSPENDING);
&gt; 
&gt; 	/**/
&gt; 	retval = rpm_callback(callback, dev);
&gt; 	__update_runtime_status(dev, RPM_SUSPENDED);
&gt; 	/**/
&gt; }
&gt; 
&gt; The first call to rpm_suspend has the RPM_ASYNC flag, so queue_work is called,
&gt; and the work queue is used to enter rpm_suspend
&gt; 
&gt; pm_runtime_init
&gt; 	INIT_WORK(&amp;dev-&gt;power.work, pm_runtime_work);
&gt; 
&gt; (2)resume:
&gt; 
&gt; azx_probe_continue
&gt; 	set_default_power_save
&gt; 		snd_hda_set_power_save(&amp;chip-&gt;bus, val * 1000);
&gt; 			codec_set_power_save(c, delay);
&gt; 
&gt; int val = power_save;
&gt; static int power_save = CONFIG_SND_HDA_POWER_SAVE_DEFAULT;//It is 0 in my .config
&gt; 
&gt; static void codec_set_power_save(struct hda_codec *codec, int delay)
&gt; {
&gt; 	struct device *dev = hda_codec_dev(codec);
&gt; 	if (delay == 0 &amp;&amp; codec-&gt;auto_runtime_pm)
&gt; 		delay = 3000;
&gt; 
&gt; 	if (delay &gt; 0) {
&gt; 		pm_runtime_set_autosuspend_delay(dev, delay);
&gt; 		pm_runtime_use_autosuspend(dev);
&gt; 		pm_runtime_allow(dev);
&gt; 		if (!pm_runtime_suspended(dev))
&gt; 			pm_runtime_mark_last_busy(dev);
&gt; 	} else {
&gt; 		pm_runtime_dont_use_autosuspend(dev);
&gt; 		pm_runtime_forbid(dev);
&gt; 	}
&gt; }
&gt; 
&gt; pm_runtime_forbid
&gt; 	rpm_resume(dev, 0);
&gt; 
&gt; static int rpm_resume(struct device *dev, int rpmflags)
&gt; {
&gt; 	/**/
&gt; 	if (dev-&gt;power.runtime_status == RPM_ACTIVE) {
&gt; 		retval = 1;
&gt; 		goto out;
&gt; 	}
&gt; 
&gt; 	/**/
&gt; 	_update_runtime_status(dev, RPM_RESUMING);
&gt; 	retval = rpm_callback(callback, dev);
&gt; 	/**/
&gt; 	__update_runtime_status(dev, RPM_ACTIVE);
&gt; 	/**/
&gt; }
&gt; 
&gt; The callback functions of suspend and resume are as follows, which set the power state:
&gt; 
&gt; hda_call_codec_suspend
&gt; 	state = hda_set_power_state(codec, AC_PWRST_D3);
&gt; 
&gt; hda_call_codec_resume
&gt; 	hda_set_power_state(codec, AC_PWRST_D0);
&gt; 
&gt; You can see that the resume function relies on dev-&gt;power.runtime_status,
&gt; and the status is set in rpm_suspend. The operation of rpm_suspend depends
&gt; on the scheduling of the work queue. I added print debugging on my machine,
&gt; and occasionally there will be pm_runtime_work in Run after rpm_resume.
&gt; At this time, the suspend and resume processes are not performed correctly.
&gt; In VT1802, the power_state is still D3, and the machine has no sound.
&gt; 
&gt; 4. I searched the Internet and did not find the relevant modification,
&gt; but found the commit 317d9313925c (ALSA: hda/realtek-Set default power save node to 0).
&gt; 
&gt; Does VIA need to be modified like this?
&gt; 
&gt; Since I am not familiar with ALSA and runtime pm, so come here to consult.

For VIA codecs, there is an additional fixup table to turn off the
power_save_node.&nbsp; Add an entry with the PCI SSID of your device to
vt2002p_fixups[] table with VIA_FIXUP_POWER_SAVE.


thanks,

Takashi

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-11-23  8:40 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <tencent_F4C3EF827E2193D1C7323B9F51D53CA91D0A@qq.com>
2021-11-23  8:25 ` [PATCH] ALSA: hda/via - fix occasionally no sound with VT1802 Takashi Iwai
2021-11-23  8:39   ` =?gb18030?B?u9i4tKO6IFtQQVRDSF0gQUxTQTogaGRhL3ZpYSAtIGZpeCBvY2Nhc2lvbmFsbHkgbm8gc291bmQgd2l0aCBWVDE4MDI=?= =?gb18030?B?taXH+tGtu7c=?=

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.