Currently, snd_hdac_power_up()/down() helpers checks whether the codec
is being in pm (suspend/resume), and skips the call of runtime get/put
during it. This is needed as there are lots of power up/down
sequences called in the paths that are also used in the PM itself. An
example is found in hda_codec.c::codec_exec_verb(), where this can
power up the codec while it may be called again in its power up
sequence, too.
The above works in most cases, but sometimes we really want to wait
for the real power up. For example, the control element get/put may
want explicit power up so that the value change is assured to reach to
the hardware. Using the current snd_hdac_power_up(), however,
results in a race, e.g. when it's called during the runtime suspend is
being performed. In the worst case, as found in patch_ca0132.c, it
can even lead to the deadlock because the code assumes the power up
while it was skipped due to the check above.
For dealing with such cases, this patch makes snd_hdac_power_up() and
_down() to two variants: with and without in_pm flag check. The
version with pm flag check is named as snd_hdac_power_up_pm() while
the version without pm flag check is still kept as
snd_hdac_power_up(). (Just because the usage of the former is fewer.)
Then finally, the patch replaces each call potentially done in PM with
the new _pm() variant.
In theory, we can implement a unified version -- if we can distinguish
the current context whether it's in the pm path. But such an
implementation is cumbersome, so leave the code like this a bit messy
way for now...
Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96271
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The 16bit COEF read/write is pretty standard for many codecs, and they
can be cached in most cases -- more importantly, they need to be
restored at resume. For making this easier, add the cache support to
regmap. If the codec driver wants to cache the COEF access, set
codec->cache_coef flag and issue AC_VERB_GET_PROC_COEF with the coef
index in LSB 8 bits.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Codecs may have own vendor-specific verbs, and we need to allow each
driver to give such verbs for cached accesses. Here a verb can be put
into a single array and looked through it at readable and writeable
callbacks.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The amp hash table was used for recording the cached reads of some
capability values like pin caps or amp caps. Now all these are moved
to regmap as well.
One addition to the regmap helper is codec->caps_overwriting flag.
This is set in snd_hdac_override_parm(), and the regmap helper accepts
any register while this flag is set, so that it can overwrite even the
read-only verb like AC_VERB_PARAMETERS. The flag is cleared
immediately in snd_hdac_override_parm(), as it's a once-off flag.
Along with these changes, the no longer needed amp hash and relevant
fields are removed from hda_codec struct now.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Sometimes we need the uncached reads, e.g. for refreshing the tree.
This patch provides the helper function for that and uses it for
refreshing widgets, reading subtrees and the whole proc reads.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Let's start converting the access functions to regmap.
The first one is the simplest, just converting the codec parameter
read helper function snd_hda_param_read().
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch adds an infrastructure to support regmap-based verb
accesses. Because o the asymmetric nature of HD-audio verbs,
especially the amp verbs, we need to translate the verbs as a sort of
pseudo registers to be mapped uniquely in regmap.
In this patch, a pseudo register is built from the NID, the
AC_VERB_GET_* and 8bit parameters, i.e. almost in the form to be sent
to HD-audio bus but without codec address field. OTOH, for writing,
the same pseudo register is translated to AC_VERB_SET_* automatically.
The AC_VERB_SET_AMP_* verb is re-encoded from the corresponding
AC_VERB_GET_AMP_* verb and parameter at writing.
Some verbs has a single command for read but multiple for writes. A
write for such a verb is split automatically to multiple verbs.
The patch provides also a few handy helper functions. They are
designed to be accessible even without regmap. When no regmap is set
up (e.g. before the codec device instantiation), the direct hardware
access is used. Also, it tries to avoid the unnecessary power-up.
The power up/down sequence is performed only on demand.
The codec driver needs to call snd_hdac_regmap_exit() and
snd_hdac_regmap_exit() at probe and remove if it wants the regmap
access.
There is one flag added to hdac_device. When the flag lazy_cache is
set, regmap helper ignores a write for a suspended device and returns
as if it was actually written. It reduces the hardware access pretty
much, e.g. when adjusting the mixer volume while in idle. This
assumes that the driver will sync the cache later at resume properly,
so use it carefully.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Add an overriding exec_verb op to struct hdac_device so that the call
via snd_hdac_exec_verb() can switch to a different route depending on
the setup. The codec driver sets this field so that it can handle the
errors or applying quirks appropriately. Furthermore, this mechanism
will be used for smooth transition for the regmap support in later
patches.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This patch changes the sysfs files assigned to the codec device on the
bus which were formerly identical with hwdep sysfs files. Now it
shows only a few core parameter, vendor_id, subsystem_id, revision_id,
afg, mfg, vendor_name and chip_name.
In addition, now a widget tree is added to the bus device sysfs
directory for showing the widget topology and attributes. It's just a
flat tree consisting of subdirectories named as the widget NID
including various attributes like widget capability bits. The AFG
(usually NID 0x01) is always found there, and it contains always
amp_in_caps, amp_out_caps and power_caps files. Each of these
attributes show a single value. The rest are the widget nodes
belonging to that AFG. Note that the child node might not start from
0x02 but from another value like 0x0a.
Each child node may contain caps, pin_caps, amp_in_caps, amp_out_caps,
power_caps and connections files. The caps (representing the widget
capability bits) always contain a value. The rest may contain
value(s) if the attribute exists on the node. Only connections file
show multiple values while other attributes have zero or one single
value.
An example of ls -R output is like below:
% ls -R /sys/bus/hdaudio/devices/hdaudioC0D0/
/sys/bus/hdaudio/devices/hdaudioC0D0/widgets/:
01/ 04/ 07/ 0a/ 0d/ 10/ 13/ 16/ 19/ 1c/ 1f/ 22/
02/ 05/ 08/ 0b/ 0e/ 11/ 14/ 17/ 1a/ 1d/ 20/ 23/
03/ 06/ 09/ 0c/ 0f/ 12/ 15/ 18/ 1b/ 1e/ 21/
/sys/bus/hdaudio/devices/hdaudioC0D0/widgets/01:
amp_in_caps amp_out_caps power_caps
/sys/bus/hdaudio/devices/hdaudioC0D0/widgets/02:
amp_in_caps amp_out_caps caps connections pin_caps pin_cfg
power_caps
/sys/bus/hdaudio/devices/hdaudioC0D0/widgets/03:
.....
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Now some codes and functionalities of hda_codec struct are moved to
hdac_device struct. A few basic attributes like the codec address,
vendor ID number, FG numbers, etc are moved to hdac_device, and they
are accessed like codec->core.addr. The basic verb exec functions are
moved, too.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A few basic codes for communicating over HD-audio bus are moved to
struct hdac_bus now. It has only command and get_response ops in
addition to the unsolicited event handling.
Note that the codec-side tracing support is disabled temporarily
during this transition due to the code shuffling. It will be
re-enabled later once when all pieces are settled down.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Define the common hd-audio driver and device types to bind over
snd_hda_bus_type publicly. This allows to implement other type of
device and driver code over hd-audio bus.
Now both struct hda_codec and struct hda_codec_driver inherit these
new struct hdac_device and struct hdac_driver, respectively.
The bus registration is done in subsys_initcall() to assure it
before any other driver registrations.
Signed-off-by: Takashi Iwai <tiwai@suse.de>