[bug report] ASoC: cpcap: new codec
Hello Sebastian Reichel,
The patch f6cdf2d3445d: "ASoC: cpcap: new codec" from Feb 23, 2018, leads to the following static checker warning:
sound/soc/codecs/cpcap.c:1276 cpcap_voice_hw_params() warn: 'CPCAP_BIT_MIC1_RX_TIMESLOT0' is a shifter (not for '|=').
sound/soc/codecs/cpcap.c:1279 cpcap_voice_hw_params() warn: 'CPCAP_BIT_MIC2_TIMESLOT0' is a shifter (not for '|=').
sound/soc/codecs/cpcap.c 1253 static int cpcap_voice_hw_params(struct snd_pcm_substream *substream, 1254 struct snd_pcm_hw_params *params, 1255 struct snd_soc_dai *dai) 1256 { 1257 struct snd_soc_component *component = dai->component; 1258 struct device *dev = component->dev; 1259 struct cpcap_audio *cpcap = snd_soc_component_get_drvdata(component); 1260 static const u16 reg_cdi = CPCAP_REG_CDI; 1261 int rate = params_rate(params); 1262 int channels = params_channels(params); 1263 int direction = substream->stream; 1264 u16 val, mask; 1265 int err; 1266 1267 dev_dbg(dev, "Voice setup HW params: rate=%d, direction=%d, chan=%d", 1268 rate, direction, channels); 1269 1270 err = cpcap_set_samprate(cpcap, CPCAP_DAI_VOICE, rate); 1271 if (err) 1272 return err; 1273 1274 if (direction == SNDRV_PCM_STREAM_CAPTURE) { 1275 mask = 0x0000; 1276 mask |= CPCAP_BIT_MIC1_RX_TIMESLOT0; ^^^^^^^^^^^^^^^^^^^^^^^^^^^ This should probably be BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0).
1277 mask |= CPCAP_BIT_MIC1_RX_TIMESLOT1; 1278 mask |= CPCAP_BIT_MIC1_RX_TIMESLOT2; 1279 mask |= CPCAP_BIT_MIC2_TIMESLOT0; ^^^^^^^^^^^^^^^^^^^^^^^^
Same for all the others as well I guess.
1280 mask |= CPCAP_BIT_MIC2_TIMESLOT1; 1281 mask |= CPCAP_BIT_MIC2_TIMESLOT2; 1282 val = 0x0000; 1283 if (channels >= 2) 1284 val = BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Here it's BIT(CPCAP_BIT_MIC1_RX_TIMESLOT0).
1285 err = regmap_update_bits(cpcap->regmap, reg_cdi, mask, val); 1286 if (err) 1287 return err; 1288 } 1289 1290 return 0; 1291 }
regards, dan carpenter
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);
* Sebastian Reichel sre@kernel.org [210123 17:30]:
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.
I just tried recording with arecord -D plughw:CARD=Audio,DEV=1 | hd but only see the header and no data.. DEV=0 won't produce anything, maybe I have the alsamixer settings wrong. Let me know if you want me to try something else.
I do have the pending voice call patches applied on top, voice calls work just fine with your patch. So as it looks correct to me:
Reviewed-by: Tony Lindgren tony@atomide.com
On Sat, 23 Jan 2021 18:29:45 +0100, Sebastian Reichel wrote:
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.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/1] ASoC: cpcap: fix microphone timeslot mask commit: de5bfae2fd962a9da99f56382305ec7966a604b9
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
participants (4)
-
Dan Carpenter
-
Mark Brown
-
Sebastian Reichel
-
Tony Lindgren