hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/codecs/pcm512x.c
....@@ -1,17 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Driver for the PCM512x CODECs
34 *
45 * Author: Mark Brown <broonie@kernel.org>
56 * Copyright 2014 Linaro Ltd
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful, but
12
- * WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- * General Public License for more details.
157 */
168
179
....@@ -53,6 +45,9 @@
5345 unsigned long overclock_pll;
5446 unsigned long overclock_dac;
5547 unsigned long overclock_dsp;
48
+ int mute;
49
+ struct mutex mutex;
50
+ unsigned int bclk_ratio;
5651 };
5752
5853 /*
....@@ -384,6 +379,61 @@
384379 SOC_ENUM_SINGLE(PCM512x_DIGITAL_MUTE_2, PCM512x_VEDS_SHIFT, 4,
385380 pcm512x_ramp_step_text);
386381
382
+static int pcm512x_update_mute(struct pcm512x_priv *pcm512x)
383
+{
384
+ return regmap_update_bits(
385
+ pcm512x->regmap, PCM512x_MUTE, PCM512x_RQML | PCM512x_RQMR,
386
+ (!!(pcm512x->mute & 0x5) << PCM512x_RQML_SHIFT)
387
+ | (!!(pcm512x->mute & 0x3) << PCM512x_RQMR_SHIFT));
388
+}
389
+
390
+static int pcm512x_digital_playback_switch_get(struct snd_kcontrol *kcontrol,
391
+ struct snd_ctl_elem_value *ucontrol)
392
+{
393
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
394
+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
395
+
396
+ mutex_lock(&pcm512x->mutex);
397
+ ucontrol->value.integer.value[0] = !(pcm512x->mute & 0x4);
398
+ ucontrol->value.integer.value[1] = !(pcm512x->mute & 0x2);
399
+ mutex_unlock(&pcm512x->mutex);
400
+
401
+ return 0;
402
+}
403
+
404
+static int pcm512x_digital_playback_switch_put(struct snd_kcontrol *kcontrol,
405
+ struct snd_ctl_elem_value *ucontrol)
406
+{
407
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
408
+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
409
+ int ret, changed = 0;
410
+
411
+ mutex_lock(&pcm512x->mutex);
412
+
413
+ if ((pcm512x->mute & 0x4) == (ucontrol->value.integer.value[0] << 2)) {
414
+ pcm512x->mute ^= 0x4;
415
+ changed = 1;
416
+ }
417
+ if ((pcm512x->mute & 0x2) == (ucontrol->value.integer.value[1] << 1)) {
418
+ pcm512x->mute ^= 0x2;
419
+ changed = 1;
420
+ }
421
+
422
+ if (changed) {
423
+ ret = pcm512x_update_mute(pcm512x);
424
+ if (ret != 0) {
425
+ dev_err(component->dev,
426
+ "Failed to update digital mute: %d\n", ret);
427
+ mutex_unlock(&pcm512x->mutex);
428
+ return ret;
429
+ }
430
+ }
431
+
432
+ mutex_unlock(&pcm512x->mutex);
433
+
434
+ return changed;
435
+}
436
+
387437 static const struct snd_kcontrol_new pcm512x_controls[] = {
388438 SOC_DOUBLE_R_TLV("Digital Playback Volume", PCM512x_DIGITAL_VOLUME_2,
389439 PCM512x_DIGITAL_VOLUME_3, 0, 255, 1, digital_tlv),
....@@ -391,8 +441,15 @@
391441 PCM512x_LAGN_SHIFT, PCM512x_RAGN_SHIFT, 1, 1, analog_tlv),
392442 SOC_DOUBLE_TLV("Analogue Playback Boost Volume", PCM512x_ANALOG_GAIN_BOOST,
393443 PCM512x_AGBL_SHIFT, PCM512x_AGBR_SHIFT, 1, 0, boost_tlv),
394
-SOC_DOUBLE("Digital Playback Switch", PCM512x_MUTE, PCM512x_RQML_SHIFT,
395
- PCM512x_RQMR_SHIFT, 1, 1),
444
+{
445
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
446
+ .name = "Digital Playback Switch",
447
+ .index = 0,
448
+ .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,
449
+ .info = snd_ctl_boolean_stereo_info,
450
+ .get = pcm512x_digital_playback_switch_get,
451
+ .put = pcm512x_digital_playback_switch_put
452
+},
396453
397454 SOC_SINGLE("Deemphasis Switch", PCM512x_DSP, PCM512x_DEMP_SHIFT, 1, 1),
398455 SOC_ENUM("DSP Program", pcm512x_dsp_program),
....@@ -851,16 +908,21 @@
851908 int fssp;
852909 int gpio;
853910
854
- lrclk_div = snd_soc_params_to_frame_size(params);
855
- if (lrclk_div == 0) {
856
- dev_err(dev, "No LRCLK?\n");
857
- return -EINVAL;
911
+ if (pcm512x->bclk_ratio > 0) {
912
+ lrclk_div = pcm512x->bclk_ratio;
913
+ } else {
914
+ lrclk_div = snd_soc_params_to_frame_size(params);
915
+
916
+ if (lrclk_div == 0) {
917
+ dev_err(dev, "No LRCLK?\n");
918
+ return -EINVAL;
919
+ }
858920 }
859921
860922 if (!pcm512x->pll_out) {
861923 sck_rate = clk_get_rate(pcm512x->sclk);
862
- bclk_div = params->rate_den * 64 / lrclk_div;
863
- bclk_rate = DIV_ROUND_CLOSEST(sck_rate, bclk_div);
924
+ bclk_rate = params_rate(params) * lrclk_div;
925
+ bclk_div = DIV_ROUND_CLOSEST(sck_rate, bclk_rate);
864926
865927 mck_rate = sck_rate;
866928 } else {
....@@ -1319,10 +1381,73 @@
13191381 return 0;
13201382 }
13211383
1384
+static int pcm512x_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
1385
+{
1386
+ struct snd_soc_component *component = dai->component;
1387
+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1388
+
1389
+ if (ratio > 256)
1390
+ return -EINVAL;
1391
+
1392
+ pcm512x->bclk_ratio = ratio;
1393
+
1394
+ return 0;
1395
+}
1396
+
1397
+static int pcm512x_mute(struct snd_soc_dai *dai, int mute, int direction)
1398
+{
1399
+ struct snd_soc_component *component = dai->component;
1400
+ struct pcm512x_priv *pcm512x = snd_soc_component_get_drvdata(component);
1401
+ int ret;
1402
+ unsigned int mute_det;
1403
+
1404
+ mutex_lock(&pcm512x->mutex);
1405
+
1406
+ if (mute) {
1407
+ pcm512x->mute |= 0x1;
1408
+ ret = regmap_update_bits(pcm512x->regmap, PCM512x_MUTE,
1409
+ PCM512x_RQML | PCM512x_RQMR,
1410
+ PCM512x_RQML | PCM512x_RQMR);
1411
+ if (ret != 0) {
1412
+ dev_err(component->dev,
1413
+ "Failed to set digital mute: %d\n", ret);
1414
+ goto unlock;
1415
+ }
1416
+
1417
+ regmap_read_poll_timeout(pcm512x->regmap,
1418
+ PCM512x_ANALOG_MUTE_DET,
1419
+ mute_det, (mute_det & 0x3) == 0,
1420
+ 200, 10000);
1421
+ } else {
1422
+ pcm512x->mute &= ~0x1;
1423
+ ret = pcm512x_update_mute(pcm512x);
1424
+ if (ret != 0) {
1425
+ dev_err(component->dev,
1426
+ "Failed to update digital mute: %d\n", ret);
1427
+ goto unlock;
1428
+ }
1429
+
1430
+ regmap_read_poll_timeout(pcm512x->regmap,
1431
+ PCM512x_ANALOG_MUTE_DET,
1432
+ mute_det,
1433
+ (mute_det & 0x3)
1434
+ == ((~pcm512x->mute >> 1) & 0x3),
1435
+ 200, 10000);
1436
+ }
1437
+
1438
+unlock:
1439
+ mutex_unlock(&pcm512x->mutex);
1440
+
1441
+ return ret;
1442
+}
1443
+
13221444 static const struct snd_soc_dai_ops pcm512x_dai_ops = {
13231445 .startup = pcm512x_dai_startup,
13241446 .hw_params = pcm512x_hw_params,
13251447 .set_fmt = pcm512x_set_fmt,
1448
+ .mute_stream = pcm512x_mute,
1449
+ .set_bclk_ratio = pcm512x_set_bclk_ratio,
1450
+ .no_capture_mute = 1,
13261451 };
13271452
13281453 static struct snd_soc_dai_driver pcm512x_dai = {
....@@ -1388,6 +1513,8 @@
13881513 if (!pcm512x)
13891514 return -ENOMEM;
13901515
1516
+ mutex_init(&pcm512x->mutex);
1517
+
13911518 dev_set_drvdata(dev, pcm512x);
13921519 pcm512x->regmap = regmap;
13931520
....@@ -1406,8 +1533,9 @@
14061533 pcm512x->supply_nb[2].notifier_call = pcm512x_regulator_event_2;
14071534
14081535 for (i = 0; i < ARRAY_SIZE(pcm512x->supplies); i++) {
1409
- ret = regulator_register_notifier(pcm512x->supplies[i].consumer,
1410
- &pcm512x->supply_nb[i]);
1536
+ ret = devm_regulator_register_notifier(
1537
+ pcm512x->supplies[i].consumer,
1538
+ &pcm512x->supply_nb[i]);
14111539 if (ret != 0) {
14121540 dev_err(dev,
14131541 "Failed to register regulator notifier: %d\n",