Use RUNTIME_PM_OPS() instead of the old SET_RUNTIME_PM_OPS().
This means we don't need __maybe_unused on the functions.
Fixes: 73cfbfa9ca ("ALSA: hda/cs35l56: Add driver for Cirrus Logic CS35L56 amplifier")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230919081153.19793-1-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In cs35l56_hda_read_acpi() do not return if ACPI _SUB is missing.
A missing _SUB means that the driver cannot load a system-specific
firmware, because the firmware is identified by the _SUB. But it can
fallback to a generic firmware. Unfortunately this was being handled
by immediately returning 0, which would skip the remaining ACPI
configuration in cs35l56_hda_read_acpi() and so it would not get the
RESET GPIO.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 73cfbfa9ca ("ALSA: hda/cs35l56: Add driver for Cirrus Logic CS35L56 amplifier")
Link: https://lore.kernel.org/r/20230914152525.20829-1-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The final return in cs35l56_hda_posture_get() was returning the
value of 'ret', but ret is always zero at this point. So this
can be a simple 'return 0'.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230914140852.7112-1-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Driver remove() must call pm_runtime_dont_use_autosuspend().
Drivers that call pm_runtime_use_autosuspend() must disable
it in driver remove(). Unfortunately until recently this was
only mentioned in 1 line in a 900+ line document so most
people hadn't noticed this. It has only recently been added
to the kerneldoc of pm_runtime_use_autosuspend().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 73cfbfa9ca ("ALSA: hda/cs35l56: Add driver for Cirrus Logic CS35L56 amplifier")
Link: https://lore.kernel.org/r/20230908101223.2656901-1-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
The ACPI nodes for CS35L56 can contain an extra I2CSerialBusV2 that
is not a real device, it is an alias address.
This alias address will not be in the cirrus,dev-index array, so reject
any instantions with a device address not found in the array.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-10-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A tuning patch is always needed to enable the ASP audio port.
If the BIOS did not patch the firmware, then it is mandatory to
have a .bin file.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-9-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
A RAM firmware can only be downloaded if the CS35L56 is currently
running from ROM firmware. The driver must not try to overwrite
the RAM if the CS35L56 is already running from that RAM.
Firmware can be downloaded in these two cases:
- The BIOS has already patched the firmware (secured mode).
In this case the firmware files will only contain tunings that
are safe to overwrite.
- The CS35L56 is running the built-in ROM firmware.
After a RAM firmware has been downloaded it can only be cleared by
hard resetting CS35L56. Some systems only hard-reset during
power-on and do not give the driver control of hard reset.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-8-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
If cs35l56_hda_fw_load() successfully called cs_dsp_power_up() the error
path must balance that with a call to cs_dsp_power_down().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-7-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
In cs35l56_hda_unbind() cs_dsp_power_down() must be called to cleanup
before calling cs_dsp_remove cs_dsp_remove().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-6-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Always call cs_dsp_power_up() and cs_dsp_run() in
cs35l56_hda_fw_load() even if there aren't any firmware files
to download. Also, if there aren't any firmware files to
download there is no need to do cs35l56_firmware_shutdown() and
cs35l56_system_reset().
If there aren't any firmware files there's no need to write
anything to the CS35L56 registers to make it work - it will
already be running the ROM firmware. So it's not strictly
necessary to start cs_dsp.
But it's perfectly ok to call cs_dsp_power_up() and
cs_dsp_run() without downloading any firmware. This avoids
having to support a state where audio is playing but cs_dsp
is not running.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-5-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
When firmware is reloaded after a system resume cs_dsp_power_down() should
be called before calling cs_dsp_power_up().
The fw_patched flag should also be cleared and only set again if the
firmware download succeeded.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-4-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Only call regcache_mark_dirty() in cs35l56_hda_fw_load() if
the CS35L56 was SYSTEM_RESET.
recache_mark_dirty() changes the behaviour of regcache_sync()
to write out cache values that are not the default value, and
skip cache values that are the default.
AUDIO_REINIT does not reset the registers. regcache_mark_dirty()
after AUDIO_REINIT could cause the regcache_sync() to sync
registers incorrectly because it will assume that all registers
have reset to default.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-3-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Move the call to cs_dsp_run() in cs35l56_hda_fw_load() so that it
is after the CS35L56 has been reset/reinit'd and the regmap
cache has been synced.
cs_dsp_run() syncs up ALSA control cache values with the DSP memory
so this must not be done until the firmware has reinitialized.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20230731165726.7940-2-rf@opensource.cirrus.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Smatch complains that this return should be a goto:
sound/pci/hda/cs35l56_hda.c:910 cs35l56_hda_common_probe()
warn: missing unwind goto?
The goto error disables cansleep so that seems reasonable.
Fixes: 73cfbfa9ca ("ALSA: hda/cs35l56: Add driver for Cirrus Logic CS35L56 amplifier")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Reviewed-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/465160f4-b7cf-41d5-931e-d6c9e68fa3c7@moroto.mountain
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Add a driver for the Cirrus Logic CS35L56 amplifier. This uses the same
component binding API as the CS35L41 driver. This is not a standalone
HDA device; it provides control of the CS35L56 for systems that use a
combination of an HDA codec and CS35L56 amplifiers with audio routed
through the HDA codec.
The CS35L56 combines a high-performance mono audio amplifier, Class-H
tracking inductive boost converter, Halo Core(TM) DSP and a DC-DC boost
converter supporting Class-H tracking.
Control interfaces are I2C or SPI through the standard Linux I2C or SPI
bus framework.
Most chip functionality is controlled by on-board ROM firmware that is
always running. Firmware patches can be applied by the driver in the form
of a .wmfw file (firmware patch) and/or a .bin file (system tuning).
Signed-off-by: Simon Trimmer <simont@opensource.cirrus.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Reviewed-by: Takashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20230721132120.5523-12-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>