lkml.org 
[lkml]   [2021]   [Jan]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCHv1] ASoC: cpcap: fix microphone timeslot mask
    Date
    The correct mask is 0x1f8 (Bit 3-8), but due to missing BIT() 0xf (Bit
    0-3) was set instead. This means setting of CPCAP_BIT_MIC1_RX_TIMESLOT0
    (Bit 3) still worked (part of both masks). On the other hand the code
    does not properly clear the other MIC timeslot bits. I think this
    is not a problem, since they are probably initialized to 0 and not
    touched by the driver anywhere else. But the mask also contains some
    wrong bits, that will be cleared. Bit 0 (CPCAP_BIT_SMB_CDC) should be
    safe, since the driver enforces it to be 0 anyways.

    Bit 1-2 are CPCAP_BIT_FS_INV and CPCAP_BIT_CLK_INV. This means enabling
    audio recording forces the codec into SND_SOC_DAIFMT_NB_NF mode, which
    is obviously bad.

    The bug probably remained undetected, because there are not many use
    cases for routing microphone to the CPU on platforms using cpcap and
    user base is small. I do remember having some issues with bad sound
    quality when testing voice recording back when I wrote the driver.
    It probably was this bug.

    Fixes: f6cdf2d3445d ("ASoC: cpcap: new codec")
    Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
    Signed-off-by: Sebastian Reichel <sre@kernel.org>
    ---
    Hi,

    This is compile tested only, since I currently do not have
    my Droid 4 ready for running some tests. Maybe Tony, Pavel or
    Merlijn can give it a go using e.g. arecord.

    Thanks,

    -- Sebastian
    ---
    sound/soc/codecs/cpcap.c | 12 ++++++------
    1 file changed, 6 insertions(+), 6 deletions(-)

    diff --git a/sound/soc/codecs/cpcap.c b/sound/soc/codecs/cpcap.c
    index e266d993ab2a..05bbacd0d174 100644
    --- a/sound/soc/codecs/cpcap.c
    +++ b/sound/soc/codecs/cpcap.c
    @@ -1273,12 +1273,12 @@ static int cpcap_voice_hw_params(struct snd_pcm_substream *substream,

    if (direction == SNDRV_PCM_STREAM_CAPTURE) {
    mask = 0x0000;
    - mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0;
    - mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1;
    - mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2;
    - mask |= CPCAP_BIT_MIC2_TIMESLOT0;
    - mask |= CPCAP_BIT_MIC2_TIMESLOT1;
    - mask |= CPCAP_BIT_MIC2_TIMESLOT2;
    + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
    + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT1);
    + mask |= BIT(CPCAP_BIT_MIC1_RX_TIMESLOT2);
    + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT0);
    + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT1);
    + mask |= BIT(CPCAP_BIT_MIC2_TIMESLOT2);
    val = 0x0000;
    if (channels >= 2)
    val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0);
    --
    2.29.2
    \
     
     \ /
      Last update: 2021-01-23 18:32    [W:2.504 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site