| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Only report a button state change if the interrupt status shows that
there was a button event.
Previously the code would always drop into the button reporting at the
end of interrupt handling if the jack was present. If neither of the
button report interrupts were pending it would report all buttons
released. This could then lead to a button being reported as released
while it is still pressed.
Fixes: c5b8ee0879bc ("ASoC: cs42l42: Report jack and button detection")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220815123138.3810249-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
| |
The ASoC core has now been changed to default to the non-legacy DAI
naming, as such drivers using the new scheme no longer need to specify
the non_legacy_dai_naming flag.
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220623125250.2355471-50-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
cppcheck warning:
sound/soc/codecs/cs42l42.c:1704:28: style: The statement 'if
(cs42l42->plug_state!=CS42L42_TS_TRANS)
cs42l42->plug_state=CS42L42_TS_TRANS' is logically equivalent to
'cs42l42->plug_state=CS42L42_TS_TRANS'. [duplicateConditionalAssign]
if (cs42l42->plug_state != CS42L42_TS_TRANS)
^
sound/soc/codecs/cs42l42.c:1705:25: note: Assignment
'cs42l42->plug_state=CS42L42_TS_TRANS'
cs42l42->plug_state = CS42L42_TS_TRANS;
^
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com>
Link: https://lore.kernel.org/r/20220520211719.607543-3-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The i2c probe functions here don't use the id information provided in
their second argument, so the single-parameter i2c probe function
("probe_new") can be used instead.
This avoids scanning the identifier tables during probes.
Signed-off-by: Stephen Kitt <steve@sk2.org>
Reviewed-by: Wolfram Sang <wsa+renesas@sang-engineering.com>
Reviewed-by: Lucas Tanure <tanureal@opensource.cirrus.com>
Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220325170734.1216018-1-steve@sk2.org
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
DETECT_MODE and PLL_START must be zero while HP_PDN and ADC_PDN are
both 1. If this condition is broken it can discharge FILT+ and it
can then take up to 1 second for FILT+ to recharge.
There is no workaround required for this, simply avoiding settings
and sequences that would break the requirement. The driver already
meets the requirement.
But it is not obvious from reading the code that this requirement
exists, or what is ensuring it is met. So it would not currently be
obvious to someone changing the code that there is certain special
behaviour that must be maintained.
To avoid accidental breakage in the future:
- Add comments into the register definitions to warn about this so
that anyone changing the code around DETECT_MODE and PLL_START is
aware of this requirement.
- Add a comment where PLL_START is written to 1 to highlight the
requirement and why it is satisfied.
- Add a comment in cs42l42_setup_hs_type_detect() when DETECT_MODE is
initialized.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220304144015.398656-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add system suspend functions to handle clean power-down on suspend and
restoring registers on resume.
The jack state could change during suspend. Plug->unplug and unplug->plug
are straightforward because this looks no different from any other plug
state change - there will be a plugged or unplugged interrupt pending.
The jack could be unplugged and a different type of jack plugged, and on
resume the plug state would not have changed. Setting plug_state back to
TS_TRANS (transitioning) will make the next plug interrupt after resume
run a type detection.
During system suspend any jack plug/unplug and button events will not be
reported or generate a system wakeup. If the plug state or headset type
has changed it will be reported after resume.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220121120412.672284-4-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Rename jack_detect_mutex to irq_lock and make it lock the entire IRQ
handling.
The jack_detect_mutex was introduced to synchronize registering an
ALSA jack handler, via cs42l42_set_jack(), with the jack state
processing in the IRQ handler, and was taken only around the
relevant part of the IRQ handling code.
System suspend will need to synchronize with the IRQ handler thread
so will need a similar mutex that surrounds all of the IRQ handling.
Repurposing the existing jack_detect_mutex is the simplest option.
It does no harm for a call to cs42l42_set_jack() to additionally
block the first few lines of IRQ handling, and the only interrupts
used by the driver are all for jack handling.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220121120412.672284-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a plug event is detect report the full state of all status
bits, don't assume that there will have been a previous unplug
event to clear all the bits. Report the state of both HEADPHONE
and MICROPHONE bits according to detected type, and clear all the
button status bits. The current button status is already checked
and reported at the end of the function.
During a system suspend the jack could be unplugged and plugged,
possibly changing the jack type. On resume the interrupt status will
indicate a plug event - there will not be an unplug event to clear
the bits.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220121120412.672284-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When a jack handler is registered in cs42l42_set_jack() the
initial state should be reported if an attached headphone/headset
has already been detected.
The jack detect sequence takes around 1 second: typically long
enough for the machine driver to probe and register the jack handler
in time to receive the first report from the interrupt handler. So
it is possible on some systems that the correct initial state was seen
simply because of lucky timing. Modular builds were more likely to
miss the reporting of the initial state.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 4ca239f33737 ("ASoC: cs42l42: Always enable TS_PLUG and TS_UNPLUG interrupts")
Link: https://lore.kernel.org/r/20211119124854.58939-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
| |
Now that struct cs42l42_private has pll_config, the current PLL
configuration can be looked up directly in pll_ratio_table. This
makes the pll_divout member of cs42l42_private redundant since it
was only a copy of the value from pll_ratio_table.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211116163901.45390-5-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When reporting a jack unplug there's no need to make the reported
flags conditional on which flags were reported during the plug
event. It's perfectly safe to report all flags and buttons as
not-present and let the higher code filter for changes.
There's also no need to make two separate snd_soc_jack_report()
calls for presence flags and button flags. It can all be done in
one report.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211116163901.45390-4-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The RS_PLUG and RS_UNPLUG interrupt masks are always written as 1 so
those writes are redundant and can be deleted.
This makes it completely clear in the code that only the TS_PLUG and
TS_UNPLUG masks are being changed.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211116163901.45390-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are multiple places where DETECT_MODE is included in a register
write, but in every case it is written as 0. Removing these redundant
writes makes the code less cluttered and also makes it obvious that
DETECT_MODE is never changed.
A single initialization to 0 is added to cs42l42_setup_hs_type_detect().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211116163901.45390-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
This adds an ALSA control so that the slow-start audio ramp feature
can be disabled. This is useful for high-definition audio applications.
The register field is unusual in that it is a 3-bit field with only
two valid values, 000=off and 111=on.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211101101006.13092-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The setting from the cirrus,ts-inv property should be applied to the
TIP_SENSE_INV bit, as this is the one that actually affects the jack
detect block. The TS_INV bit only swaps the meaning of the PLUG and
UNPLUG interrupts and should always be 1 for the interrupts to have
the normal meaning.
Due to some misunderstanding the driver had been implemented to
configure the TS_INV bit based on the jack switch polarity. This made
the interrupts behave the correct way around, but left the jack detect
block, button detect and analogue circuits always interpreting an open
switch as unplugged.
The signal chain inside the codec is:
SENSE pin -> TIP_SENSE_INV -> TS_INV -> (invert) -> interrupts
|
v
Jack detect,
button detect and
analog control
As the TIP_SENSE_INV already performs the necessary inversion the
TS_INV bit never needs to change. It must always be 1 to yield the
expected interrupt behaviour.
Some extra confusion has arisen because of the additional invert in the
interrupt path, meaning that a value applied to the TS_INV bit produces
the opposite effect of applying it to the TIP_SENSE_INV bit. The ts-inv
property has therefore always had the opposite effect to what might be
expected (0 = inverted, 1 = not inverted). To maintain the meaning of
the ts-inv property it must be inverted when applied to TIP_SENSE_INV.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20211028140902.11786-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Relying on devm to free the irq handler on probe failure leaves a
small window of opportunity for an interrupt to become pending and
then the handler to run after the chip has been reset and powered
off.
For safety cs42l42_probe() should free the irq in the error path.
As the irq is now disabled by the driver in probe() and remove()
there is no point allocating it as a devres-managed item, so
convert to plain non-devres.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211026125722.10220-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
| |
Driver remove() should assert RESET and disable the supplies.
probe() fail was disabling supplies but it didn't assert reset or
put the codec into a power-down state.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211026125722.10220-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The interrupt handling code was getting the struct device* from a
struct snd_soc_component* stored in struct cs42l42_private. If the
interrupt was asserted before ASoC calls component_probe() the
snd_soc_component* will be NULL.
The stored snd_soc_component* is not actually used for anything other
than indirectly getting the struct device*. Remove it, and store the
struct device* in struct cs42l42_private.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211025112258.9282-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The driver has runtime_suspend and runtime_resume callbacks, but
pm_runtime is never enabled so these functions won't be called. They
could not be used anyway because the runtime_suspend would cause jack
detect to stop working.
These functions are unused - delete them.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211018164431.5871-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|\ |
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The headset type detection must run to set the analogue switches
correctly for the attached headset type. Without this only headsets
with wiring matching the chip default will have a functioning mic.
commit c26a5289e865 ("ASoC: cs42l42: Add support for set_jack calls")
moved the interrupt unmasking to the component set_jack() callback.
But it's not mandatory for a machine driver to register a struct
snd_soc_jack handler. Without a registered handler the type detection
would not have run and so the mic would not work on some types of
headset.
This patch restores the unmasking of TS_PLUG and TS_UNPLUG interrupts
during probe.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-17-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The driver must free the IRQ in remove() to prevent the potential race
where an IRQ starts to be handled while the driver is being removed but
devres has not yet called free_irq(). However, the driver can run without
an interrupt but devm_free_irq() will hit a WARN() if no devres-managed
interrupt was ever created.
Fix this by only attempting to create the interrupt handler if the hardware
config specified an interrupt, and failing probe() if the interrupt could
not be created. This means that in cs42l42_remove() an interrupt must have
been registered if the irq number is valid and therefore it is safe to call
devm_free_irq().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-16-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
OSC_SWITCH_STATUS is a volatile register indicating the current state
of the clock switch logic.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-15-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
According to the datasheet the SRC MCLK must be as near as possible to
(125 * sample rate). This means it should be ~6MHz for rates up to 48k
and ~12MHz for rates above that. As per datasheet table 4-21.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-14-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
After enabling the HP or ADC by writing the corresponding PDN=0,
it takes around 20 milliseconds for it to power up and the midrail
supply to be stable. Add this wait into a DAPM widget callback.
If HP and ADC are both powering up in a DAPM sequence, there's no
need to do the wait twice. The widget will perform one wait in the
POST_PMU if there was a PRE_PMU for one or both.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-13-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
It isn't possible to switch MCLK between 12MHz and 24MHz rate groups
on-the-fly - this can only be done when cs42l42 is powered-down.
All "normal" SCLK rates use an MCLK in the 12MHz group, so change the
configs for SCLK > 12.288 MHz to use the PLL to generate an MCLK in
the 12MHz group.
As this means MCLK_DIV is always 0 it can be removed from the pll
configuration setup.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-12-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The driver currently only supports configuring for sample rates <= 96k
and it isn't possible to setup a configuration that will support all
sample rates up to 192k.
For sample rates up to 96k MCLK is in the 12MHz group.
However, although 192k only requires an I2S clock in the 12MHz group,
the cs42l42 audio path is not natively 192k so the audio must be
resampled. But for 192k the SRC requires a 24MHz MCLK.
It is not possible to switch MCLK between 12MHz and 24MHz groups
on-the-fly. The 12MHz group supports all sample rates up to 96k.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-11-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The driver can run without an interrupt so if devm_request_threaded_irq()
failed, the probe() just carried on. But if this was EPROBE_DEFER the
driver would continue without an interrupt instead of deferring to wait
for the interrupt to become available.
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-6-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Volatile registers don't need a default value.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20211015133619.4698-5-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Some registers had wrong default values in cs42l42_reg_defaults[].
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20211015133619.4698-4-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
An I2S frame always has two slots (left and right) even when sending
mono. The right channel (channel 2) of ASP TX will always have the
same bit width as the left channel and will always be on the high
phase of LRCLK.
The previous implementation always passed the field masks for both
channels to snd_soc_component_update_bits() but for mono the written value
only contained the settings for channel 1. The result was that for mono
channel 2 was set to 8-bit (which is an invalid configuration) with both
channels on the low phase of LRCLK.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 585e7079de0e ("ASoC: cs42l42: Add Capture Support")
Link: https://lore.kernel.org/r/20211015133619.4698-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
When capture and playback substreams are both running at the same time,
cs42l42_pcm_hw_params() would be called for each direction. The first
call will configure the PLL. The second call must not write the PLL
configuration registers again if the first substream is already running,
as this could destabilize the PLL.
The DAI is marked symmetric sample bits and sample rate, so the two
directions will always have the same SCLK (I2S always has 2 channel slots
so the DAI does not need to require symmetric channels to guarantee the
same SCLK). However, since cs42l42_pll_config() is checking for an active
stream it may as well test that the requested SCLK is the same as the
currently active configuration.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211015133619.4698-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Ensure the default 0dB playback path is always used.
The code that set FULL_SCALE_VOL based on LOAD_DET_RCSTAT was
spurious, and resulted in a -6dB attenuation being accidentally
inserted into the playback path.
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20211011144903.28915-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
detection
Some headsets require very different comparator thresholds for type detection,
as well as longer settling times. In order to detect a larger number of headsets,
use 2 thresholds to give maximum coverage (1.25V and 1.75V), as well as a longer
settling time of 100ms. This will not affect default audotodetect mode
and applies to manual mode type detection only.
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210927111437.18113-1-vitalyr@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|\ \
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
from Vitaly Rodionov <vitalyr@opensource.cirrus.com>:
For some headsets CS42L42 autodetect mode is not working correctly.
They will be detected as unknown types or as headphones. According
to the CS42L42 datasheet, if the headset autodetect failed,
then the driver should switch to manual mode and perform a manual steps sequence.
These steps were missing in the current driver code. This patch will add manual
mode fallback steps in case autodetect failed. The default behavior is not affected,
manual mode runs only when autodetect failed.
Tested for regression with autodetect with all known headsets - no regression.
Tested with all headsets customers reported as false detected:
Gumdrop DropTech B1 - detected as headset OK
HUAWEI AM115 - detected as headset OK
UGREEN EP103 - detected as headset OK
HONOR AM116 - detected as headset OK
Stefan Binding (1):
ASoC: cs42l42: Implement Manual Type detection as fallback
sound/soc/codecs/cs42l42.c | 104 ++++++++++++++++++++++++++++++++-----
sound/soc/codecs/cs42l42.h | 54 +++++++++++++++++++
2 files changed, 146 insertions(+), 12 deletions(-)
--
2.25.1
|
| |/
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Some headsets are not detected correctly by Automatic Type Detection
on cs42l42. Instead, Manual Type Detection can be used to give a
more accurate value.
Signed-off-by: Stefan Binding <sbinding@opensource.cirrus.com>
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210916102750.9212-2-vitalyr@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|/
|
|
|
|
| |
Signed-off-by: Vitaly Rodionov <vitalyr@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210916110932.10293-1-vitalyr@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
| |
Add the current authors of this module.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210805161111.10410-8-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If the machine driver doesn't call snd_soc_dai_set_sysclk() the
SCLK is assumed to be sample_rate * sample_bits * 2 (that is, the
rate necessary for a standard I2S frame).
But 24-bit samples can be sent in either a 24-bit slot or a 32-bit
slot. If the PLL is configured for a 24-bit slot, but a 32-bit slot is
used, cs42l42 will be overclocked.
Ultimately it is the machine driver's responsibilty to call
snd_soc_dai_set_sysclk() if SLK will be different from the standard
I2S rate. However, it is convenient to assume 32-bit slots to allow
this common case without needing special machine driver support. The
machine driver then only has to set SCLK if the slots are 24-bit, but
if it fails to do this cs42l42 won't be overclocked.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210805161111.10410-7-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
| |
If the machine driver calls snd_set_sysclk() with an unsupported
SCLK frequency, return an error instead of letting hw_params() fail.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210805161111.10410-6-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
| |
44.1kHz 16-bit standard I2S gives a SCLK of 1.4112 MHz. Add
a PLL configuration for this.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210805161111.10410-5-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I2S always has two LRCLK phases and both CH1 and CH2 of the RX
must be enabled (corresponding to the low and high phases of LRCLK.)
The selection of the valid data channels is done by setting the DAC
CHA_SEL and CHB_SEL. CHA_SEL is always the first (left) channel,
CHB_SEL depends on the number of active channels.
Previously for mono ASP CH2 was not enabled, the result was playing
mono data would not produce any audio output.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 621d65f3b868 ("ASoC: cs42l42: Provide finer control on playback path")
Link: https://lore.kernel.org/r/20210805161111.10410-4-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The lowest valid SCLK corresponds to 44.1 kHz at 16-bit. Sample
rates less than this would produce SCLK below the minimum when using
a normal I2S frame. A constraint must be applied to prevent this.
The constraint is not applied if the machine driver sets SCLK, to
allow setups where the host generates additional bits per LRCLK
phase to increase the SCLK frequency. In these cases the machine
driver would always have to inform this driver of the actual SCLK,
and it must select a legal SCLK.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210805161111.10410-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
An I2S frame starts on the falling edge of LRCLK so ASP_STP must
be 0.
At the same time, move other format settings in the same register
from cs42l42_pll_config() to cs42l42_set_dai_fmt() where you'd
expect to find them, and merge into a single write.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20210805161111.10410-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Both SCLK and PLL clocks must be running to drive the glitch-free mux
behind MCLK_SRC_SEL and complete the switchover.
This patch moves the writing of MCLK_SRC_SEL to when the PLL is started
and stopped, so that it only transitions while the PLL is running.
The unconditional write MCLK_SRC_SEL=0 in cs42l42_mute_stream() is safe
because if the PLL is not running MCLK_SRC_SEL is already 0.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 43fc357199f9 ("ASoC: cs42l42: Set clock source for both ways of stream")
Link: https://lore.kernel.org/r/20210805161111.10410-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The driver was defining two ALSA controls that both change the same
register field for the wind noise filter corner frequency. The filter
response has two corners, at different frequencies, and the duplicate
controls most likely were an attempt to be able to set the value using
either of the frequencies.
However, having two controls changing the same field can be problematic
and it is unnecessary. Both frequencies are related to each other so
setting one implies exactly what the other would be.
Removing a control affects user-side code, but there is currently no
known use of the removed control so it would be best to remove it now
before it becomes a problem.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20210803160834.9005-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
| |
The underlying register field has inverted sense (0 = enabled) so
the control definition must be marked as inverted.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20210803160834.9005-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
| |
An I2S frame always has a left and right channel slot even if mono
data is being sent. So if channels==1 the actual bitclock frequency
is 2 * snd_soc_params_to_bclk(params).
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2cdba9b045c7 ("ASoC: cs42l42: Use bclk from hw_params if set_sysclk was not called")
Link: https://lore.kernel.org/r/20210729170929.6589-3-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
| |
The driver has no support for left-justified protocol so it should
not have been allowing this to be passed to cs42l42_set_dai_fmt().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Link: https://lore.kernel.org/r/20210729170929.6589-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The ADC volume is a signed 8-bit number with range -97 to +12,
with -97 being mute. Use a SOC_SINGLE_S8_TLV() to define this
and fix the DECLARE_TLV_DB_SCALE() to have the correct start and
mute flag.
Fixes: 2c394ca79604 ("ASoC: Add support for CS42L42 codec")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210729170929.6589-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
|