Compare commits

...

335 commits

Author SHA1 Message Date
Jacopo Maroli
c3f0119ae9 [PATCH] fix channel ordering 2024-11-22 17:05:21 +01:00
Hin-Tak Leung
c693d203d9 Merge remote-tracking branch 'origin/v6.1' into v6.5 2024-01-10 15:54:35 +00:00
HinTak
005fc23648
Merge pull request #23 from makermelissa/fix-install-config
Fix /boot/config.txt for bookworm installs
2024-01-10 15:53:37 +00:00
Melissa LeBlanc-Williams
58082f3fe8 Fix /boot/config.txt for bookworm installs 2024-01-05 10:46:23 -08:00
Hin-Tak Leung
cc37c8fb52 v6.5: ASoC: soc-core.c: add index on snd_soc_of_get_dai_name()
commit 3c8b5861850c734add65233e538d4a8c2dff95d9
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Tue Jun 20 02:14:11 2023 +0000

    ASoC: soc-core.c: add index on snd_soc_of_get_dai_name()

    Current snd_soc_of_get_dai_name() doesn't accept index
    for #sound-dai-cells. It is not useful for user.
    This patch adds it.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Link: https://lore.kernel.org/r/87pm5qdgng.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2023-10-04 23:18:04 +01:00
Hin-Tak Leung
c3a2d96ba2 Changing install URL to point to mine. 2023-08-03 23:30:03 +01:00
Hin-Tak Leung
7aef82f3be Merge remote-tracking branch 'origin/v6.1' into v6.4 2023-08-02 02:10:52 +01:00
Hin-Tak Leung
4ab8158c18 Fine tuning the regex from discussion in the last pull 2023-08-02 02:08:55 +01:00
Hin-Tak Leung
8f377d1eaa Fine tuning the regex from discussion in the last pull 2023-08-02 02:07:04 +01:00
Hin-Tak Leung
aaa2090dbf Merge remote-tracking branch 'origin/v6.1' into v6.4 2023-08-02 02:01:48 +01:00
HinTak
f25e76508f
Merge pull request #7 from hellow554/v6.1
fix detection of kernel modules on 64-bit image
2023-08-02 01:59:17 +01:00
Hin-Tak Leung
a46c3f6324 Re-store support for v6.3 in the v6.4 branch 2023-07-27 02:08:40 +01:00
Hin-Tak Leung
2a40c7dbff v6.4: switch to use c2c_params instead of params
commit 99fddc1618ff64cc71bd51dbf83bd13e74778fe0
Merge: 72456c24c8357 1ea63f29c2771
Author: Mark Brown <broonie@kernel.org>
Date:   Wed Apr 5 16:35:09 2023 +0100

    ASoC: clarify Codec2Codec params

    Merge series from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

    ASoC is supporting Codec2Codec, but its parameter name is
    "params" and "num_params" which are very unclear naming.

    This patch-set clarifies it by replacing to c2c_params / num_c2c_params.

commit 1ea63f29c27712d6b9c45af67cd71299d849c5e3
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Sun Apr 2 23:00:17 2023 +0000

    ASoC: soc.h: remove unused params/num_params

    No drivers are using params/num_params any more.
    Let's remove these.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Link: https://lore.kernel.org/r/87iledc2ke.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>

commit e7a73b05542d82e209af450dd90b730255f6e775
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Sun Apr 2 23:00:07 2023 +0000

    ASoC: samsung: switch to use c2c_params instead of params

    ASoC is now using c2c_params instead of params. This patch replace it.
    num_c2c_params (was num_params) was not mandatory before,
    but let's set it by this patch.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Link: https://lore.kernel.org/r/87jzytc2kp.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>

commit 433f4a1697fae78c34377de1ef3abd26aec8214e
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Sun Apr 2 22:59:57 2023 +0000

    ASoC: meson: switch to use c2c_params instead of params

    ASoC is now using c2c_params instead of params. This patch replace it.
    num_c2c_params (was num_params) was not mandatory before,
    but let's set it by this patch.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Link: https://lore.kernel.org/r/87lej9c2ky.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>

commit 7ddc7f91beb285246e926e3adf0b292b071aea33
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Sun Apr 2 22:59:35 2023 +0000

    ASoC: soc.h: clarify Codec2Codec params

    snd_soc_dai_link has params/num_params, but it is unclear that
    params for what. This patch clarify it is params for Codec2Codec.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Link: https://lore.kernel.org/r/87o7o5c2lk.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2023-07-27 01:52:33 +01:00
Marcel Hellwig
f69370b841 fix detection of kernel modules on 64-bit image
The lib modules folder looks like `/lib/modules/6.1.21-v8+/build`, which
means that the previous regex doesn't capture anything after the `-` and
therefore it fails to detect the kernel version.
The regex now aligns with the other detection method and this works fine
on my machine™
2023-06-28 09:23:38 +02:00
Hin-Tak Leung
a03624a0ce v6.3: cleanup Playback/Capture data for snd_soc_dai
commit 3653480c68120dc16ebfeb80e529200dbbd98f92
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Tue Jan 31 02:02:04 2023 +0000

    ASoC: soc-dai.h: cleanup Playback/Capture data for snd_soc_dai

    Current snd_soc_dai has data for Playback/Capture, but it is very
    random. Someone is array (A), someone is playback/capture (B),
    and someone is tx/rx (C);

            struct snd_soc_dai {
                    ...
    (A)             unsigned int stream_active[SNDRV_PCM_STREAM_LAST + 1];

    (B)             struct snd_soc_dapm_widget *playback_widget;
    (B)             struct snd_soc_dapm_widget *capture_widget;

    (B)             void *playback_dma_data;
    (B)             void *capture_dma_data;

                    ...

    (C)             unsigned int tx_mask;
    (C)             unsigned int rx_mask;
            };

    Because of it, the code was very complicated.
    This patch creates new data structure to merge these into one,
    and tidyup the code.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Reviewed-by: Charles Keepax <ckeepax@opensource.cirrus.com>
    Link: https://lore.kernel.org/r/87cz6vea1v.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2023-06-16 23:49:29 +01:00
Hin-Tak Leung
0bb3ca6c98 v6.3: use simple i2c probe
commit a00f6d3723f5617222ab8df228228c3c2c84e3ec
Author: Stephen Kitt <steve@sk2.org>
Date:   Wed Oct 12 18:36:47 2022 +0200

    drivers/i2c: use simple i2c probe

    All these drivers have an i2c probe function which doesn't use the
    "struct i2c_device_id *id" parameter, so they can trivially be
    converted to the "probe_new" style of probe with a single argument.

    This is part of an ongoing transition to single-argument i2c probe
    functions. Old-style probe functions involve a call to i2c_match_id:
    in drivers/i2c/i2c-core-base.c,

             /*
              * When there are no more users of probe(),
              * rename probe_new to probe.
              */
             if (driver->probe_new)
                     status = driver->probe_new(client);
             else if (driver->probe)
                     status = driver->probe(client,
                                            i2c_match_id(driver->id_table, client));
             else
                     status = -EINVAL;

    Drivers which don't need the second parameter can be declared using
    probe_new instead, avoiding the call to i2c_match_id. Drivers which do
    can still be converted to probe_new-style, calling i2c_match_id
    themselves (as is done currently for of_match_id).

    This change was done using the following Coccinelle script, and fixed
    up for whitespace changes:

    @ rule1 @
    identifier fn;
    identifier client, id;
    @@

    - static int fn(struct i2c_client *client, const struct i2c_device_id *id)
    + static int fn(struct i2c_client *client)
    {
    ...when != id
    }

    @ rule2 depends on rule1 @
    identifier rule1.fn;
    identifier driver;
    @@

    struct i2c_driver driver = {
    -       .probe
    +       .probe_new
                    =
    (
                       fn
    |
    -                  &fn
    +                  fn
    )
                    ,
    };

    Signed-off-by: Stephen Kitt <steve@sk2.org>
    Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-06-16 23:36:50 +01:00
Hin-Tak Leung
18e297d2d8 64-bit-only kernel package does not have /boot/kernel.img ; use /boot/kernel8.img for version detection.
http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230405-1_arm64.deb
9a716f09695f1e6c9f951a6bc9e4ff22
27025792 Apr  5 20:13

6.1.21-v8+
2023-04-16 19:19:19 +01:00
Hin-Tak Leung
280bb390a2 Remove garbage before "Linux version"
Kernel 6.1 onwards seems to have strings re-arranged so that a newline
no long happens right before the "Linux version" string.

Tested with:

4650945eaabe1297985759ef8e3d4153  archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230306-1_armhf.deb
93830b458685feabf2262f474be4a0e0  archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230317-1_armhf.deb
5449f3dd337c594491f3e73b6ee97cbf  archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230405-1_armhf.deb

29384 5.15.84+
28712 6.1.19+ 6.1.21+
2023-04-16 19:11:24 +01:00
Hin-Tak Leung
19ca5aeb50 64-bit-only kernel package does not have /boot/kernel.img ; use /boot/kernel8.img for version detection.
http://archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230405-1_arm64.deb
9a716f09695f1e6c9f951a6bc9e4ff22
27025792 Apr  5 20:13

6.1.21-v8+
2023-04-16 18:56:16 +01:00
Hin-Tak Leung
ebd1fa605c Raspbian has 64-bit kernel on 32-bit userspace 2023-04-14 00:09:12 +01:00
Hin-Tak Leung
a57389693c Remove garbage before "Linux version"
Kernel 6.1 onwards seems to have strings re-arranged so that a newline
no long happens right before the "Linux version" string.

Tested with:

4650945eaabe1297985759ef8e3d4153  archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230306-1_armhf.deb
93830b458685feabf2262f474be4a0e0  archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230317-1_armhf.deb
5449f3dd337c594491f3e73b6ee97cbf  archive.raspberrypi.org/debian/pool/main/r/raspberrypi-firmware/raspberrypi-kernel_1.20230405-1_armhf.deb

29384 5.15.84+
28712 6.1.19+ 6.1.21+
2023-04-10 20:36:18 +01:00
Hin-Tak Leung
977a7ff321 Attempt to fix mis-match to "5.15.84.x 2023-01-23 11:53:49 +00:00
Hin-Tak Leung
4d0e36d426 v6.1: i2c: Make remove callback return void
commit ed5c2f5fd10dda07263f79f338a512c0f49f76f5
Author: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Date:   Mon Aug 15 10:02:30 2022 +0200

    i2c: Make remove callback return void

    The value returned by an i2c driver's remove function is mostly ignored.
    (Only an error message is printed if the value is non-zero that the
    error is ignored.)

    So change the prototype of the remove function to return no value. This
    way driver authors are not tempted to assume that passing an error to
    the upper layer is a good idea. All drivers are adapted accordingly.
    There is no intended change of behaviour, all callbacks were prepared to
    return 0 before.

    Reviewed-by: Peter Senna Tschudin <peter.senna@gmail.com>
    Reviewed-by: Jeremy Kerr <jk@codeconstruct.com.au>
    Reviewed-by: Benjamin Mugnier <benjamin.mugnier@foss.st.com>
    Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
    Reviewed-by: Crt Mori <cmo@melexis.com>
    Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
    Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Acked-by: Marek Behún <kabel@kernel.org> # for leds-turris-omnia
    Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
    Reviewed-by: Petr Machata <petrm@nvidia.com> # for mlxsw
    Reviewed-by: Maximilian Luz <luzmaximilian@gmail.com> # for surface3_power
    Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> # for bmc150-accel-i2c + kxcjk-1013
    Reviewed-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> # for media/* + staging/media/*
    Acked-by: Miguel Ojeda <ojeda@kernel.org> # for auxdisplay/ht16k33 + auxdisplay/lcd2s
    Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com> # for versaclock5
    Reviewed-by: Ajay Gupta <ajayg@nvidia.com> # for ucsi_ccg
    Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> # for iio
    Acked-by: Peter Rosin <peda@axentia.se> # for i2c-mux-*, max9860
    Acked-by: Adrien Grassein <adrien.grassein@gmail.com> # for lontium-lt8912b
    Reviewed-by: Jean Delvare <jdelvare@suse.de> # for hwmon, i2c-core and i2c/muxes
    Acked-by: Corey Minyard <cminyard@mvista.com> # for IPMI
    Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
    Acked-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
    Acked-by: Sebastian Reichel <sebastian.reichel@collabora.com> # for drivers/power
    Acked-by: Krzysztof Hałasa <khalasa@piap.pl>
    Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Signed-off-by: Wolfram Sang <wsa@kernel.org>
2023-01-18 00:14:00 +00:00
Hin-Tak Leung
99bbf880e9 v6.0: ASoC: simple-card-utils: Move snd_soc_component_is_codec to be local
commit 28086d05ada6d03daa886aad0e469854b811311c
Author: Charles Keepax <ckeepax@opensource.cirrus.com>
Date:   Thu May 19 16:43:18 2022 +0100

    ASoC: simple-card-utils: Move snd_soc_component_is_codec to be local

    The helper function snd_soc_component_is_codec is based off the
    presence of the non_legacy_dai_naming flag. This isn't super robust
    as CPU side components may also specify this flag, and indeed the
    kernel already contains a couple that do. After componentisation there
    isn't really a totally robust solution to identifying what is a CODEC
    driver, without introducing a flag specifically for that purpose, and
    really the desirable direction to move in is that the distinction
    doesn't matter.

    This patch does two things to try to mitigate these problems. Firstly,
    now that all the other users of the helper function have been removed,
    it makes the helper function local to the driver rather, than being
    part of the core. This should help to discourage any new code from
    being created that depends on the CODEC driver distinction. Secondly,
    it updates the helper function itself to use the endianness flag
    rather than the non_legacy_dai_naming flag. The endianness flag is
    definitely invalid on a CPU side component, so it a more reliable
    indicator that the device is definitely a CODEC. The vast majority of
    buses require the CODEC to set the endianness flag, so the number of
    corner cases should be fairly minimal. It is worth noting that CODECs
    sending audio over SPI, or built into the CPU CODECs are potential
    corner cases, however the hope is that in most cases those types of
    devices do not consitute a simple audio card.

    Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
    Link: https://lore.kernel.org/r/20220519154318.2153729-57-ckeepax@opensource.cirrus.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2022-10-30 22:45:19 +00:00
Hin-Tak Leung
8dbe3726b7 v6.0: ASoC: simple-card-utils: Make asoc_simple_clean_reference() return void
commit e6f08af6340eaf88e9eeff71bd4533eee9a04119
Author: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
Date:   Sun Jun 5 17:35:37 2022 +0200

    ASoC: simple-card-utils: Make asoc_simple_clean_reference() return void

    asoc_simple_clean_reference() returns zero unconditionally. Letting it
    return void instead makes it easier to see in the caller that there is no
    error to handle.

    This is a preparation for making platform remove callbacks return void.

    Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
    Link: https://lore.kernel.org/r/20220605153537.26591-1-u.kleine-koenig@pengutronix.de
    Signed-off-by: Mark Brown <broonie@kernel.org>
2022-10-30 22:37:13 +00:00
Hin-Tak Leung
e452172d8c v6.0: ASoC: wm*: Remove now redundant non_legacy_dai_naming flag
commit 01936221278c5af60d82b8e78ca74caa491c0d31
Author: Charles Keepax <ckeepax@opensource.cirrus.com>
Date:   Thu Jun 23 13:52:50 2022 +0100

    ASoC: soc-component: Remove non_legacy_dai_naming flag

    Now all the users are moved over to the new legacy_dai_naming flag,
    remove the now unused old flag.

    Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
    Link: https://lore.kernel.org/r/20220623125250.2355471-97-ckeepax@opensource.cirrus.com
    Signed-off-by: Mark Brown <broonie@kernel.org>

commit 02004449dbe6ec05b5b64a88824939b8fe474b82
Author: Charles Keepax <ckeepax@opensource.cirrus.com>
Date:   Thu Jun 23 13:52:19 2022 +0100

    ASoC: wm*: Remove now redundant non_legacy_dai_naming flag

    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-66-ckeepax@opensource.cirrus.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2022-10-30 22:29:10 +00:00
Hin-Tak Leung
a8ee041f21 v5.16: ASoC: soc-component: add snd_soc_component_is_codec()
commit 01e90ee15e81f57d309d0ce1f0e16869e011b800
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Oct 18 11:05:24 2021 +0900

    ASoC: soc-component: add snd_soc_component_is_codec()

    Checking .non_legacy_dai_naming is not readable.
    Let's add new snd_soc_component_is_codec().

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Link: https://lore.kernel.org/r/87h7dft7dn.wl-kuninori.morimoto.gx@renesas.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2022-10-30 22:25:19 +00:00
Hin-Tak Leung
6bf1dbd04e v5.13: cope with multi-support at asoc_simple_canonicalize_*()
commit c826ec0391c83f06354a4ebb25c7b2480c18f33a
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Apr 12 08:52:45 2021 +0900

    ASoC: simple-card-utils: multi support at asoc_simple_canonicalize_cpu/platform()

    Current asoc_simple_canonicalize_cpu/platform() is assuming single CPU,
    single Platform, but we want to support Multi support.
    This patch is prepare for it.
2021-10-09 00:55:55 +01:00
Hin-Tak Leung
b093f59250 v5.13: Conditionally re-adding asoc_simple_parse_xxx()
commit e25704f84ca2b586e8e65d1b2ab686205b3076fe
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Apr 12 08:52:13 2021 +0900

    ASoC: simple-card-utils: remove asoc_simple_parse_xxx()

    ASoC is now supporting multi DAI, but, current
    simple-card / audio-graph are assuming fixed single DAI.

    Now, asoc_simple_parse_xxx() macro is assuming single DAI.
    To support multi-CPU/Codec, this patch unpack asoc_simple_parse_xxx()
    macro, and uses "&dai_link->cpus[i]" instead of "dai_link->cpus".

$ git log --format=oneline v5.12..v5.13 -- include/sound/simple_card_utils.h
f6fcc820e0c96664e2f21c0d6bb60630243ef36a ASoC: audio-graph: move audio_graph_remove() to simple-card-utils.c
1a456b1c6be13514a8fc5c1a99e6763f491d17e9 ASoC: audio-graph: move audio_graph_card_probe() to simple-card-utils.c
343e55e71877415a23372388b3e0c59a9bba42f6 ASoC: simple-card-utils: Increase maximum number of links to 128
fcfd763bef4ff7f6371790979a6ceac9c4ac425a ASoC: simple-card-utils: tidyup asoc_simple_parse_convert()
3919249e80995ed5f125f94d05fcb6171f79e732 ASoC: simple-card-utils: tidyup dev_dbg() to use 1 line
33cd6b191f1cdb5f332717a80ce26f661f53e924 ASoC: simple-card-utils: tidyup debug info for clock
c826ec0391c83f06354a4ebb25c7b2480c18f33a ASoC: simple-card-utils: multi support at asoc_simple_canonicalize_cpu/platform()
9830d3e99f51fc1c1c6ab8be7778fd205af198ad ASoC: simple-card-utils: add simple_props_to_xxx() macro
40d8cbe70e71be170e0a4fe6ab112d9aaa9cfb18 ASoC: simple-card-utils: indicate missing CPU/Codec numbers for debug
ac813c625ad5c3ee98a99e1b37659a0d85178978 ASoC: simple-card-utils: indicate dai_fmt if exist
e25704f84ca2b586e8e65d1b2ab686205b3076fe ASoC: simple-card-utils: remove asoc_simple_parse_xxx()
fafc05aadd4b6ce5c161135de9d3a653fc054543 ASoC: simple-card-utils: use for_each_prop_xxx()
f899006d558546a8ee39c93f816eb3847c5bc6c0 ASoC: simple-card-utils: remove li->dais/li->conf
205eb17eddb473c3159743c7d3aaf68db37b7231 ASoC: simple-card-utils: share dummy DAI and reduce memory
f2138aed231c88d5c4fa8d06aa15ad19685087c2 ASoC: simple-card-utils: enable flexible CPU/Codec/Platform
050c7950fd706fec229af9f30e8ce254cea9b675 ASoC: simple-card-utils: alloc dai_link information for CPU/Codec/Platform
2021-10-09 00:45:09 +01:00
Hin-Tak Leung
8fa56e18bb Merge remote-tracking branch 'upstream/master' into v5.9
Not really a merge.
2021-09-16 23:57:03 +01:00
AIWintermuteAI
dd9391fb78 added 64-bit system installation script 2021-08-20 07:23:35 +01:00
AIWintermuteAI
d840f77541
Update install.sh 2021-08-19 09:56:53 +08:00
AIWintermuteAI
bd7623e9fb added reboot warning if active kernel version doesn't match updated kernel version 2021-08-17 03:28:54 +01:00
Baozhu Zuo
17e2875d4d
delete snd-soc-wm8960.ko first
see 14075fb3b5
2021-08-16 11:22:46 +08:00
Hin-Tak Leung
b595b95b21 Revert "libasound_module_pcm_ac108.so is no longer installed, so libasound2-plugins shouldn't be needed"
This reverts commit 8b2094fc23.

See #304 regarding missing libasound2-plugins.
2021-08-05 13:48:14 +08:00
Hin-Tak Leung
48dbb3f815 Revert "libasound_module_pcm_ac108.so is no longer installed, so libasound2-plugins shouldn't be needed"
This reverts commit 8b2094fc23.

See #304 regarding /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_rate_samplerate.so
2021-08-04 12:00:51 +01:00
AIWintermuteAI
41a09a3b67 added issue template 2021-07-22 18:37:38 +08:00
AIWintermuteAI
81e0f0879d
automation 2021-07-21 15:21:38 +08:00
HinTak
d841b2a0fb
Merge branch 'respeaker:master' into v5.9 2021-07-04 16:42:56 +01:00
Hin-Tak Leung
f9427ea449 remove reference to removed option "--compat-kernel" 2021-07-03 07:54:34 +01:00
AIWintermuteAI
efa999f0f3 added image and information about tech support scope 2021-06-30 03:35:28 +01:00
AIWintermuteAI
d688a02f14 simplified and updated README after merge 2021-06-29 06:51:27 +01:00
Hin-Tak Leung
a1a51f8aab v5.12: symmetric_rates renamed symmetric_rate
commit fa31a2c787aeaf61d02b2a57bd9765ca5e67d949
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Jan 15 13:56:30 2021 +0900

    ASoC: soc-dai.h: remove symmetric_rates/samplebits

    All drivers are using new name.
    Let's remove old one.

commit f14654ddf2e982537ab476d392a87fcbf90374c3
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Jan 15 13:52:54 2021 +0900

    ASoC: sync parameter naming : rate / sample_bits

    snd_pcm_runtime / snd_soc_dai / snd_soc_dai_driver / snd_soc_dai_link
    have related parameter which is similar but not same naming.
2021-05-31 19:17:06 +01:00
pcmulder
31d750c981 Added g++ to ubuntu-prerequisite.sh
On a fresh install I was missing g++ to run the buildme part. I propose we add it for future users.
2021-05-27 22:05:01 +01:00
Hin-Tak Leung
c8d97904ce adjusting back-to-v4.19.diff to recent changes 2021-04-27 15:57:01 +01:00
Hin-Tak Leung
c5f3836dd8 missed one simple_priv_to_card() to seeed_priv_to_card() earlier 2021-04-27 15:48:33 +01:00
Hin-Tak Leung
19067f3333 Second/Alternative change to correct for 5.5+ change in trigger order
The idea is the same as the previous attempt: calls ac101_trigger() just
before set_clock(1).

https://github.com/respeaker/seeed-voicecard/issues/290
    6mics / linear 4 mics: fails to record against v5.10 kernel
https://github.com/raspberrypi/linux/issues/4279
    [regression] alsa system call blocks on record between 5.4.83 and 5.5.19

In v5.5,

commit 4378f1fbe924054a09ff0d4e39e1a581b9245252
Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
Date:   Fri Sep 27 10:16:46 2019 +0300

    ASoC: soc-pcm: Use different sequence for start/stop trigger

    On stream stop currently we stop the DMA first followed by the CPU DAI.
    This can cause underflow (playback) or overflow (capture) on the DAI side
    as the DMA is no longer feeding data while the DAI is still active.
    It can be observed easily if the DAI side does not have FIFO (or it is
    disabled) to survive the time while the DMA is stopped, but still can
    happen on relatively slow CPUs when relatively high sampling rate is used:
    the FIFO is drained between the time the DMA is stopped and the DAI is
    stopped.

    It can only fixed by using different sequence within trigger for 'stop' and
    'start':
    case SNDRV_PCM_TRIGGER_START:
    case SNDRV_PCM_TRIGGER_RESUME:
    case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
            Trigger order: dai_link, DMA, CPU DAI then the codec

    case SNDRV_PCM_TRIGGER_STOP:
    case SNDRV_PCM_TRIGGER_SUSPEND:
    case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
            Trigger order: codec, CPU DAI, DMA then dai_link

    Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
    Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
    Link: https://lore.kernel.org/r/20190927071646.22319-1-peter.ujfalusi@ti.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2021-04-27 02:49:25 +01:00
Hin-Tak Leung
5793cf6bf0 Revert "Operational change to correct for 5.5+ change in trigger order; REVISIT!"
This reverts commit e553d4f851.
2021-04-27 02:49:08 +01:00
Hin-Tak Leung
ffcdafb798 adjust back-to-v5.4.diff for recent code changes 2021-04-25 00:13:42 +01:00
Hin-Tak Leung
e553d4f851 Operational change to correct for 5.5+ change in trigger order; REVISIT!
Need to revisit, and do in a different way.

https://github.com/respeaker/seeed-voicecard/issues/290
    6mics / linear 4 mics: fails to record against v5.10 kernel
https://github.com/raspberrypi/linux/issues/4279
    [regression] alsa system call blocks on record between 5.4.83 and 5.5.19

In v5.5,

commit 4378f1fbe924054a09ff0d4e39e1a581b9245252
Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
Date:   Fri Sep 27 10:16:46 2019 +0300

    ASoC: soc-pcm: Use different sequence for start/stop trigger

    On stream stop currently we stop the DMA first followed by the CPU DAI.
    This can cause underflow (playback) or overflow (capture) on the DAI side
    as the DMA is no longer feeding data while the DAI is still active.
    It can be observed easily if the DAI side does not have FIFO (or it is
    disabled) to survive the time while the DMA is stopped, but still can
    happen on relatively slow CPUs when relatively high sampling rate is used:
    the FIFO is drained between the time the DMA is stopped and the DAI is
    stopped.

    It can only fixed by using different sequence within trigger for 'stop' and
    'start':
    case SNDRV_PCM_TRIGGER_START:
    case SNDRV_PCM_TRIGGER_RESUME:
    case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
            Trigger order: dai_link, DMA, CPU DAI then the codec

    case SNDRV_PCM_TRIGGER_STOP:
    case SNDRV_PCM_TRIGGER_SUSPEND:
    case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
            Trigger order: codec, CPU DAI, DMA then dai_link

    Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
    Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
    Link: https://lore.kernel.org/r/20190927071646.22319-1-peter.ujfalusi@ti.com
    Signed-off-by: Mark Brown <broonie@kernel.org>
2021-04-25 00:13:42 +01:00
Hin-Tak Leung
de70691526 v5.7: this code was added with 5.7 - "for_each_rtd_components"
The correct incantation is:

git log 95cfc0a0aaf575207152dd7601e782702565a6f1 ^v5.7
2021-04-25 00:13:42 +01:00
Hin-Tak Leung
1774a54301 Additional debug code to where the *_trigger()'s finish. 2021-04-25 00:13:42 +01:00
Hin-Tak Leung
af484de3af v4.17: replace codec to component
https://www.alsa-project.org/pipermail/alsa-devel/2018-January/thread.html#131069

https://www.alsa-project.org/pipermail/alsa-devel/2018-January/131070.html
[alsa-devel] [PATCH v2 00/39] ASoC: replace platform/codec component   Kuninori Morimoto

https://www.alsa-project.org/pipermail/alsa-devel/2018-January/131111.html
[alsa-devel] [PATCH v2 000/186] ASoC: replace codec component   Kuninori Morimoto
2021-04-25 00:13:42 +01:00
Hin-Tak Leung
9796ad49ff Additional debug statement 2021-04-25 00:13:42 +01:00
Hin-Tak Leung
43b6034266 Breaking the spinlock into two halves, and possible fix to spinlock issue 2021-04-25 00:13:42 +01:00
Hin-Tak Leung
eab694c170 Not writing dtoverlay=seeed-*mic-voicecard to /boot/config.txt
It is easier for debugging, and easier for switching cards around, too.
2021-04-25 00:13:42 +01:00
Hin-Tak Leung
fdd67ea2c4 Move call to asoc_simple_canonicalize_platform() later to match upstream - likely does not matter.
commit fe7ed4dec2e6289eab81dd18c0d613c0851d85a1
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Jan 21 16:40:59 2019 +0900

    ASoC: simple-card: rename to asoc_simple_card_canonicalize_platform()

    Current simple-card is using asoc_simple_card_canonicalize_dailink().
    Its naming is "dailink", but is for "platform".
    We already have asoc_simple_card_canonicalize_cpu() for "cpu",
    let's follow same naming rule.
    It never return error, so, void function is better idea.

    Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
    Signed-off-by: Mark Brown <broonie@kernel.org>
2021-04-25 00:13:28 +01:00
Hin-Tak Leung
f8d47b5c64 2nd parameter of asoc_simple_init_dai_link_params() not used 2021-04-24 20:50:05 +01:00
Hin-Tak Leung
47d09dba0e v5.6: codec2codec DAI links
commit 95cfc0a0aaf575207152dd7601e782702565a6f1
Author: Samuel Holland <samuel@sholland.org>
Date:   Wed Mar 4 23:11:43 2020 -0600

    ASoC: simple-card: Add support for codec2codec DAI links

    Following the example in cb2cf0de1174 ("ASoC: soc-core: care Codec <->
    Codec case by non_legacy_dai_naming"), determine if a DAI link contains
    only codec DAIs by examining the non_legacy_dai_naming flag in each
    DAI's component.

    For now, we assume there is only one or a small set of valid PCM stream
    parameters, so num_params == 1 is good enough. We also assume that the
    same params are valid for all supported streams. params is set to the
    subset of parameters common among all DAIs, and then the existing code
    automatically chooses the highest quality of the remaining values when
    the link is brought up.
2021-04-24 20:49:53 +01:00
Hin-Tak Leung
d692927067 adjust asoc_simple_debug_info() for seeed priv structures 2021-04-24 20:49:36 +01:00
Hin-Tak Leung
14317817f8 v5.1 "ASoC: simple-card-utils: add asoc_simple_debug_info()"
commit 0580dde59438686d60762b6da9229ebec693b94f
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:54:42 2019 +0900

    ASoC: simple-card-utils: add asoc_simple_debug_info()

    Current simple-card-utils has dev_dbg(), but people want to
    add #define DEBUG at simple-card/audio-graph, not simple-card-utils.
    And, people want to get all information.
    This patch adds new asoc_simple_debug_info() to indicates information.
2021-04-24 20:49:19 +01:00
Hin-Tak Leung
3ba6aec5bb adjust v4.19 backport patch to "fix silly mistake in "v5.8: ..."" 2021-04-11 22:59:11 +01:00
Hin-Tak Leung
8b2094fc23 libasound_module_pcm_ac108.so is no longer installed, so libasound2-plugins shouldn't be needed 2021-04-08 21:07:35 +01:00
Hin-Tak Leung
c84b644247 adjust v5.4 backport patch to "fix silly mistake in "v5.8: ..."" 2021-04-08 18:07:20 +01:00
Hin-Tak Leung
8e1c59be7e fix silly mistake in "v5.8: struct snd_soc_dai->active replaced by snd_soc_dai_active(snd_soc_dai)" 2021-04-08 04:01:13 +01:00
Hin-Tak Leung
f289f5586e backport patch for 5.8 2021-04-07 21:48:15 +01:00
Hin-Tak Leung
3ad10c131c remove non-coding changes in back-to-v4.19.diff 2021-04-01 00:48:07 +01:00
Hin-Tak Leung
cbb5e082f2 hook up backport patches with dkms 2021-04-01 00:41:04 +01:00
Hin-Tak Leung
43532cfada rename to v5.4, since 5.4 is LTS 2021-04-01 00:40:13 +01:00
Hin-Tak Leung
eea6066d70 generating backport-patch with "git diff origin/v5.9..origin/v4.19" 2021-04-01 00:31:04 +01:00
Hin-Tak Leung
44d47226dc generating backport-patch with "git diff origin/v5.9..origin/v5.5" 2021-04-01 00:30:34 +01:00
Hin-Tak Leung
50dbe24b78 v5.9: snd_soc_component_read32() merged into snd_soc_component_read()
commit 39853b1438bf9b07349c8c44b48f6c2eda6f8840
Merge: d6fea46e086b 5b554b0a29ce
Author: Mark Brown <broonie@kernel.org>
Date:   Mon Jun 22 15:36:06 2020 +0100

    Merge series "ASoC: merge snd_soc_component_read() and snd_soc_component_read32()" from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

$ git diff d6fea46e086b...5b554b0a29ce

commit 5b554b0a29ce9610e3c237c77a1f76db87454b72
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Tue Jun 16 14:21:55 2020 +0900

    ASoC: remove snd_soc_component_read32()

    No driver is using snd_soc_component_read32() anymore.
    This patch removes it.
2020-11-27 00:12:31 +00:00
Hin-Tak Leung
ebcf755c1a v5.9: .digital_mute merged into .mute_stream with adjustments
Reference:

commit e2978c45e5ed3bab7f69477b882ef588185b30cc
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Jul 17 09:21:54 2020 +0900

    ASoC: soc-dai: remove .digital_mute

    All drivers are now using .mute_stream.
    Let's remove .digital_mute.

commit 22e9b54307987787efa0ee534aa9e31982ec1161
Merge: dc9584c5a3b8 a0234d0e6014
Author: Mark Brown <broonie@kernel.org>
Date:   Fri Jul 17 14:47:04 2020 +0100

    Merge series "ASoC: merge .digital_mute() into .mute_stream()" from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

    These are v4 digital_mute() patch which adjusts
    to atmel which had conflict on v3.

    v3 -> v4
            - tidyup for atmel which had conflict

$ git diff dc9584c5a3b8...a0234d0e6014

commit bdd0c277d9846977ec3f175341d4e7475ed26ef7
Merge: d235b2823698 50891431aaad
Author: Mark Brown <broonie@kernel.org>
Date:   Thu Jul 16 23:51:51 2020 +0100

    Merge series "ASoC: merge .digital_mute() into .mute_stream()" from Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>:

    These are v3 patch-set.
    ALSA SoC has 2 mute callbacks (= .digital_mute(), .mute_stream()).
    But the difference between these 2 are very small.
            .digital_mute() is for Playback
            .mute_stream()  is for Playback/Capture

    This patch-set adds new .no_capture_mute flag and emulate
    .digital_mute() by .mute_stream().

    v2 -> v3
            - uses "xxx_mute_stream" for .mute_stream naming
              if it was better
            - removed verbose Cc email address

$ git diff d235b2823698...50891431aaad

commit 350d993510115e3d9e78f1b3359bff7b68e88418
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Thu Jul 9 10:55:41 2020 +0900

    ASoC: soc-dai.c: add .no_capture_mute support
2020-11-27 00:07:47 +00:00
Hin-Tak Leung
484c03d4c8 Merge branch 'v5.7' into v5.8 2020-10-04 19:17:42 +01:00
Hin-Tak Leung
a79b7d94a5 Merge branch 'v5.5' into v5.7 2020-10-04 19:17:19 +01:00
turmary
87f42ed64d Add: document about "query sound card number" 2020-10-04 19:15:39 +01:00
Hin-Tak Leung
379f791b3c Not a merge - just marking not-interested
Merge branch 'rel-v5.5' of git://github.com/respeaker/seeed-voicecard into v5.5
2020-10-04 19:14:30 +01:00
turmary
8cce4e8ffa Add: document about "query sound card number" 2020-09-30 15:04:47 +08:00
turmary
ac2bf5f638 Move: dkms module removing to the position before kernel update 2020-09-30 10:39:23 +08:00
Hin-Tak Leung
4b7559b320 Not a merge - just marking not-interested
Merge branch 'rel-v5.5' of git://github.com/respeaker/seeed-voicecard into v5.5
2020-09-29 22:35:57 +01:00
turmary
526d0ddef9 Add: error message if old kernel package install failed 2020-09-29 11:07:29 +08:00
turmary
6fb0c63581 Add: unload codec driver when uninstall 2020-09-29 11:06:23 +08:00
turmary
06e054aa06 Move: volume name in state configuration 2020-09-29 00:20:39 +08:00
turmary
1a7fbee50e Move: volume widget name to ALSA tradition style 2020-09-29 00:20:39 +08:00
turmary
7e635f5d57 Remove: debug only or wrong widget 2020-09-29 00:20:38 +08:00
turmary
7461921407 Add: clear title for each install/uninstall steps 2020-09-29 00:20:38 +08:00
Hin-Tak Leung
794d7a3527 Merge branch 'v5.7' into v5.8 2020-09-28 17:11:24 +01:00
Hin-Tak Leung
c206a43374 Merge branch 'v5.5' into v5.7 2020-09-28 17:11:03 +01:00
Hin-Tak Leung
e0f9a554fc stop systemd service before diabling in uninstall, taken from upstream c1c2e5ca 2020-09-28 17:02:11 +01:00
Hin-Tak Leung
e85006b775 Not a merge - just marking not-interested
Merge branch 'rel-v5.5' of git://github.com/respeaker/seeed-voicecard into v5.5
2020-09-28 16:56:01 +01:00
Hin-Tak Leung
921ac8fba5 Following Standard ALSA Control Names convention
See kernel documentation, e.g. v5.5:Documentation/sound/designs/control-names.rst

Fixes https://github.com/respeaker/seeed-voicecard/issues/247
2020-09-28 16:38:30 +01:00
turmary
30ceb546fa Move: volume name in state configuration 2020-09-28 18:14:32 +08:00
turmary
e1110617b2 Move: volume name widget to ALSA tradition 2020-09-28 18:04:40 +08:00
turmary
a891e0260e Remove: debug only or wrong widget 2020-09-28 18:03:18 +08:00
turmary
c1c2e5ca56 Add: clear title for each install/uninstall steps 2020-09-28 08:45:45 +01:00
turmary
f1a46d63cc Add: service message direct to standard output and also /var/log/seeed-voicecard.log 2020-09-28 08:44:56 +01:00
Hin-Tak Leung
2e8586d547 Not a merge - just marking not-interested
Merge branch 'rel-v5.5' of git://github.com/respeaker/seeed-voicecard into v5.5
2020-09-27 18:19:25 +01:00
Hin-Tak Leung
ac1dddeaed Not a merge - just marking not-interested
Merge branch 'master' of git://github.com/respeaker/seeed-voicecard into v5.5
2020-09-27 18:18:08 +01:00
turmary
6a30a3efc6 Remove: useless dd message in get_kernel_version() 2020-09-27 18:12:57 +01:00
Andre Marschalek
84247b0037 Update seeed-voicecard to avoid systemd error messages because of failed service start
systemctl restart seeed-voicecard.service
Job for seeed-voicecard.service failed because the control process exited with error code.
See "systemctl status seeed-voicecard.service" and "journalctl -xe" for details.
2020-09-27 11:16:06 +01:00
Andre Marschalek
9bb3afb358 Update seeed-voicecard
to avoid systemd error messages because of failed service start

systemctl restart seeed-voicecard.service
Job for seeed-voicecard.service failed because the control process exited with error code.
See "systemctl status seeed-voicecard.service" and "journalctl -xe" for details.
2020-09-27 18:11:31 +08:00
turmary
2baddde5ba Fix: install ubuntu kernel only if debian kernel install failed 2020-09-27 11:03:03 +01:00
turmary
b5def1af8e Add: script option --keep-kernel to not change current kernel 2020-09-27 11:01:51 +01:00
turmary
0abc6ed072 Add: checking current directory when installing 2020-09-27 11:00:37 +01:00
turmary
30216a9c7c Add: probing kernel postfix automatically for dkms 2020-09-27 09:15:41 +01:00
turmary
6af23967a5 Add: prevent install package again in download_install_debpkg() 2020-09-27 09:14:54 +01:00
turmary
74620fbdbf Remove: useless dd message in get_kernel_version() 2020-09-27 09:13:55 +01:00
turmary
4cec9e73df Fix: probing architecture when installing specific package 2020-09-27 09:12:35 +01:00
turmary
957b1298d5 Add: more convenience error message about /boot free space 2020-09-27 08:09:25 +01:00
KillingJacky
901b451bd5 add an cmd line option for choosing compile with compatible kernel; clean up more when uninstalling 2020-09-27 06:49:19 +01:00
Psycho
b83519eb82 English correction 2020-09-27 06:49:19 +01:00
turmary
1372794704 Revert "Don't force kernel downgrade"
This reverts commit 30276c80bc.
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
19cfed5bd7 Adding missing shebang
This script has no bash-ism, so /bin/sh (dash on Debian/Ubuntu) is fine.
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
6875869cb2 emit warning for calling ac108_set_sysclk() with unexpected arguments
Don't know why Seeed Studio staff did not put it in.

Conflicts:
	ac108.c
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
9285159a7d Apparently, snd_soc_dai_set_bclk_ratio should be used where snd_soc_dai_set_tdm_slot is.
See, for example,

commit b78b30e32a19f1ac79c26e0a3e9f7bc7385a02a2
Author: j-schambacher <joerg@i2audio.com>
Date:   Tue May 19 13:56:17 2020 +0200

    Switch to snd_soc_dai_set_bclk_ratio
    Replaces obsolete function snd_soc_dai_set_tdm_slot
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
90144a2f2e updating for Ubuntu location of dkms-generated kernel modules 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
cbd6da78fc updating non-standard PATH for Ubuntu in uninstall.sh 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
cf98b67079 rebuilt dtbo on current Raspbian 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
c4c112dcaf relocating fixed-clock entry, based on upstream advice
See upstream -
https://github.com/raspberrypi/documentation/issues/1671
https://github.com/raspberrypi/documentation/pull/1673

Quoted here:

* Only Device Tree nodes at the top level of the tree and children of
  a bus node will be probed. For nodes added at run-time there is the
  further limitation that the bus must register for notifications of
  the addition and removal of children. However, there are exceptions
  that break this rule and cause confusion: the kernel explicitly
  scans the entire tree for some device types - clocks and interrupt
  controller being the two main ones - in order to (for clocks)
  initialise them early and/or (for interrupt controllers) in a
  particular order. This search mechanism only happens during booting
  and so doesn't work for nodes added by an overlay at run-time. It is
  therefore recommended for overlays to place fixed-clock nodes in the
  root of the tree unless it is guaranteed that the overlay will not
  be used at run-time.
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
9722cb01e4 Revert "temporary work-around for not being able to read sysclk from dts for ac10x"
This reverts commit 138d22226e.
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
f4f303f9bd Use pr_warn() for recoverable errors, not pr_info() 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
de23c61210 Use pr_info() for just routine information, not pr_warn() 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
cca7bbfe2a comment about Raspberry Pi 4 having two HDMI ports
The if-endif block below around the amixer call fixes
https://github.com/respeaker/seeed-voicecard/issues/239
https://github.com/respeaker/seeed-voicecard/issues/240
https://github.com/respeaker/seeed-voicecard/issues/243
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
5ca9ab45df Use logic from raspi-config to determine if bcm2835 routing option exists or not
The snd_bcm2835.enable_compat_alsa option:

    enable_compat_alsa:Enables ALSA compatibility virtual audio device (bool)

is off these days, since the beginning of 2020 apparently.

Reference:

    raspi-config (20200120) buster; urgency=medium

      * Add audio switching for discrete internal ALSA devices

     -- Simon Long <simon@raspberrypi.org>  Mon, 20 Jan 2020 11:38:37 +0000
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
8c25d81890 update check_kernel_headers() for Ubuntu header packages 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
f47375e54d Add reference to Ubuntu kernel package names
Signed-off-by: Hin-Tak Leung <htl10@users.sourceforge.net>
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
1f7323417b temporary work-around for not being able to read sysclk from dts for ac10x
The "sysclk = 24000000" value is supposed to come from the "clock-frequency"
field of ac108_mclk / ac10x_mclk, but somehow it isn't on 5.4 (vs 4.19). This
is a temporary work-around. For some strange unknown reasons, this affects
only the square 4-mic device, but not the linear 4-mic nor the 6-mics device.
The other two devices have two ac108's, and seem to work fine without it.

In v4.19:
seeed_voice_card_probe [snd_soc_seeed_voicecard]
 -> devm_snd_soc_register_card [snd_soc_core]
 -> snd_soc_register_card [snd_soc_core]
 -> seeed_voice_card_dai_init [snd_soc_seeed_voicecard]
 -> asoc_simple_card_init_dai [snd_soc_simple_card_utils]
 -> snd_soc_dai_set_sysclk [snd_soc_core]
 -> ac108_set_sysclk [snd_soc_ac108]

In 5.4:
seeed_voice_card_probe [snd_soc_seeed_voicecard]
 -> devm_snd_soc_register_card [snd_soc_core]
 -> snd_soc_register_card [snd_soc_core]
 -> snd_soc_instantiate_card [snd_soc_core]
 -> seeed_voice_card_dai_init [snd_soc_seeed_voicecard]
 -> asoc_simple_init_dai.part.0 [snd_soc_seeed_voicecard]
 -> snd_soc_dai_set_sysclk [snd_soc_core]
 -> ac108_set_sysclk [snd_soc_ac108]

Which results in the "ac108_set_sysclk  :24000000" kernel message.

Note the extra snd_soc_instantiate_card(), and the copied/renamed
asoc_simple_init_dai() - it became static and not-available to other drivers
in v5.x.

See https://github.com/respeaker/seeed-voicecard/issues/246
2020-09-27 05:09:34 +01:00
Hin-Tak Leung
e82e6fde67 make the config un-install directory configurable, for Ubuntu 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
cd899a83d5 make the overlay un-install directory configurable, for Ubuntu 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
e750de0ecc Allow kernel images to be elsewhere - Ubuntu kernel is not at Raspbian location 2020-09-27 05:09:34 +01:00
Hin-Tak Leung
efaa210d79 Merge branch 'v5.7' into v5.8 2020-09-26 23:08:22 +01:00
Hin-Tak Leung
e6e5240922 Merge branch 'v5.5' into v5.7 2020-09-26 23:08:00 +01:00
Hin-Tak Leung
8ea751c4e9 Adding missing shebang
This script has no bash-ism, so /bin/sh (dash on Debian/Ubuntu) is fine.
2020-09-18 01:06:57 +01:00
Hin-Tak Leung
e2529f9eee Merge branch 'v5.7' into v5.8 2020-09-14 14:56:27 +01:00
Hin-Tak Leung
6aff6e0b33 Merge branch 'v5.5' into v5.7 2020-09-14 14:55:59 +01:00
Hin-Tak Leung
bb09e9d24b emit warning for calling ac108_set_sysclk() with unexpected arguments
Don't know why Seeed Studio staff did not put it in.

Conflicts:
	ac108.c
2020-09-14 14:49:22 +01:00
Hin-Tak Leung
edddb2fbe4 Apparently, snd_soc_dai_set_bclk_ratio should be used where snd_soc_dai_set_tdm_slot is.
See, for example,

commit b78b30e32a19f1ac79c26e0a3e9f7bc7385a02a2
Author: j-schambacher <joerg@i2audio.com>
Date:   Tue May 19 13:56:17 2020 +0200

    Switch to snd_soc_dai_set_bclk_ratio
    Replaces obsolete function snd_soc_dai_set_tdm_slot
2020-09-14 14:48:18 +01:00
Hin-Tak Leung
655d7fe57b updating for Ubuntu location of dkms-generated kernel modules 2020-09-14 14:47:08 +01:00
Hin-Tak Leung
d64e994982 updating non-standard PATH for Ubuntu in uninstall.sh 2020-09-14 14:46:45 +01:00
Hin-Tak Leung
673305fc4e rebuilt dtbo on current Raspbian 2020-09-14 14:46:10 +01:00
Hin-Tak Leung
47d97e7bd5 relocating fixed-clock entry, based on upstream advice
See upstream -
https://github.com/raspberrypi/documentation/issues/1671
https://github.com/raspberrypi/documentation/pull/1673

Quoted here:

* Only Device Tree nodes at the top level of the tree and children of
  a bus node will be probed. For nodes added at run-time there is the
  further limitation that the bus must register for notifications of
  the addition and removal of children. However, there are exceptions
  that break this rule and cause confusion: the kernel explicitly
  scans the entire tree for some device types - clocks and interrupt
  controller being the two main ones - in order to (for clocks)
  initialise them early and/or (for interrupt controllers) in a
  particular order. This search mechanism only happens during booting
  and so doesn't work for nodes added by an overlay at run-time. It is
  therefore recommended for overlays to place fixed-clock nodes in the
  root of the tree unless it is guaranteed that the overlay will not
  be used at run-time.
2020-09-14 14:41:47 +01:00
Hin-Tak Leung
955707d944 Revert "temporary work-around for not being able to read sysclk from dts for ac10x"
This reverts commit 138d22226e.
2020-09-14 14:26:40 +01:00
Hin-Tak Leung
cf2a5fe807 Use pr_warn() for recoverable errors, not pr_info() 2020-09-13 18:24:25 +01:00
Hin-Tak Leung
471f88b337 Use pr_info() for just routine information, not pr_warn() 2020-09-13 18:18:30 +01:00
Hin-Tak Leung
d5b71a009d Merge branch 'v5.7' into v5.8 2020-09-12 00:30:16 +01:00
Hin-Tak Leung
bccf557d62 Merge branch 'v5.5' into v5.7 2020-09-12 00:29:40 +01:00
Hin-Tak Leung
a5095cd7b2 comment about Raspberry Pi 4 having two HDMI ports
The if-endif block below around the amixer call fixes
https://github.com/respeaker/seeed-voicecard/issues/239
https://github.com/respeaker/seeed-voicecard/issues/240
https://github.com/respeaker/seeed-voicecard/issues/243
2020-09-10 23:21:45 +01:00
Hin-Tak Leung
bcdc10e193 Merge branch 'v5.7' into v5.8 2020-09-09 03:34:47 +01:00
Hin-Tak Leung
ebb9a9d82a Merge branch 'v5.5' into v5.7 2020-09-09 03:34:14 +01:00
Hin-Tak Leung
783eff8779 Use logic from raspi-config to determine if bcm2835 routing option exists or not
The snd_bcm2835.enable_compat_alsa option:

    enable_compat_alsa:Enables ALSA compatibility virtual audio device (bool)

is off these days, since the beginning of 2020 apparently.

Reference:

    raspi-config (20200120) buster; urgency=medium

      * Add audio switching for discrete internal ALSA devices

     -- Simon Long <simon@raspberrypi.org>  Mon, 20 Jan 2020 11:38:37 +0000
2020-09-09 03:32:10 +01:00
Hin-Tak Leung
ec5fc9d9b8 Merge remote-tracking branch 'origin/v5.7' into v5.8 2020-09-04 23:52:34 +01:00
Hin-Tak Leung
bb1422182b Merge remote-tracking branch 'origin/v5.5' into v5.7 2020-09-04 23:50:14 +01:00
Hin-Tak Leung
f2b2516426 update check_kernel_headers() for Ubuntu header packages 2020-09-04 23:47:28 +01:00
Hin-Tak Leung
e26006d40c Add reference to Ubuntu kernel package names
Signed-off-by: Hin-Tak Leung <htl10@users.sourceforge.net>
2020-09-04 23:47:18 +01:00
Hin-Tak Leung
138d22226e temporary work-around for not being able to read sysclk from dts for ac10x
The "sysclk = 24000000" value is supposed to come from the "clock-frequency"
field of ac108_mclk / ac10x_mclk, but somehow it isn't on 5.4 (vs 4.19). This
is a temporary work-around. For some strange unknown reasons, this affects
only the square 4-mic device, but not the linear 4-mic nor the 6-mics device.
The other two devices have two ac108's, and seem to work fine without it.

In v4.19:
seeed_voice_card_probe [snd_soc_seeed_voicecard]
 -> devm_snd_soc_register_card [snd_soc_core]
 -> snd_soc_register_card [snd_soc_core]
 -> seeed_voice_card_dai_init [snd_soc_seeed_voicecard]
 -> asoc_simple_card_init_dai [snd_soc_simple_card_utils]
 -> snd_soc_dai_set_sysclk [snd_soc_core]
 -> ac108_set_sysclk [snd_soc_ac108]

In 5.4:
seeed_voice_card_probe [snd_soc_seeed_voicecard]
 -> devm_snd_soc_register_card [snd_soc_core]
 -> snd_soc_register_card [snd_soc_core]
 -> snd_soc_instantiate_card [snd_soc_core]
 -> seeed_voice_card_dai_init [snd_soc_seeed_voicecard]
 -> asoc_simple_init_dai.part.0 [snd_soc_seeed_voicecard]
 -> snd_soc_dai_set_sysclk [snd_soc_core]
 -> ac108_set_sysclk [snd_soc_ac108]

Which results in the "ac108_set_sysclk  :24000000" kernel message.

Note the extra snd_soc_instantiate_card(), and the copied/renamed
asoc_simple_init_dai() - it became static and not-available to other drivers
in v5.x.

See https://github.com/respeaker/seeed-voicecard/issues/246
2020-09-04 20:44:32 +01:00
Hin-Tak Leung
a24da444df v5.8: snd_soc_pcm_runtime->cpu_dai/codec_dai/cpu_dais/codec_dais removed
perl -pi -e 's/rtd->cpu_dai/asoc_rtd_to_cpu\(rtd, 0\)/' seeed-voicecard.c
perl -pi -e 's/rtd->codec_dai/asoc_rtd_to_codec\(rtd, 0\)/' seeed-voicecard.c

commit 1729025b04b9f242dca37f50dba8dd3705eb1ea1
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Mar 30 10:48:27 2020 +0900

    ASoC: soc-core: remove cpu_dai/codec_dai/cpu_dais/codec_dais

    No-one is using cpu_dai/codec_dai/cpu_dais/codec_dais.
    Let's remove these from snd_soc_pcm_runtime

commit c2233a266178f8937cc26a84cd7672334b5424b7
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Mar 30 10:47:37 2020 +0900

    ASoC: soc: use asoc_rtd_to_cpu() / asoc_rtd_to_codec() macro for DAI pointer
2020-08-30 19:20:19 +01:00
Hin-Tak Leung
c3adcde556 v5.8: struct snd_soc_dai->active replaced by snd_soc_dai_active(snd_soc_dai)
commit 0812a08ac8d054efc6cf2895d3b0e82c8731f8e9
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri May 15 09:48:02 2020 +0900

    ASoC: cleanup dai / component active code

    No one is using dai->active, snd_soc_component_is_active().
    Let's remove these.

commit efffd9b344adbf813e3ae6f6136df80000bf2833
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri May 15 09:46:37 2020 +0900

    ASoC: soc-dai: add snd_soc_dai_active()

    Current snd_soc_dai_action() is updating
    dai->stream_active for Playback/Capture (A),
    dai->active        for DAI (B)

            void snd_soc_dai_action(struct snd_soc_dai *dai,
                                    int stream, int action)
            {
    (A)             dai->stream_active[stream]      += action;
    (B)             dai->active                     += action;
                    dai->component->active          += action;
            }

    But, these are very verbose, because we can calculate
    DAI active from stream_active.

    This patch adds snd_soc_dai_active() which calculate
    DAI active from DAI stream_active.
2020-08-30 19:19:57 +01:00
Hin-Tak Leung
1452d85e0f Merge branch 'v5.5' into v5.7 2020-08-27 13:17:54 +01:00
Hin-Tak Leung
329c8090ea make the config un-install directory configurable, for Ubuntu 2020-08-27 13:17:20 +01:00
Hin-Tak Leung
53c0db449b make the overlay un-install directory configurable, for Ubuntu 2020-08-27 13:15:03 +01:00
Hin-Tak Leung
89f8a76646 Allow kernel images to be elsewhere - Ubuntu kernel is not at Raspbian location 2020-08-24 12:04:38 +01:00
Hin-Tak Leung
39c134f430 Merge branch 'v5.5' into v5.7 2020-08-24 11:00:38 +01:00
Hin-Tak Leung
17944791bb Merge git://github.com/respeaker/seeed-voicecard into v5.5
This is not a merge - just to note that we don't care about those two
changes upstream.
2020-08-24 10:58:42 +01:00
Hin-Tak Leung
df68ab22d6 Merge remote-tracking branch 'origin/v5.5' into v5.7 2020-08-23 20:43:08 +01:00
Hin-Tak Leung
88aae48c41 adding new ubuntu-prerequisite.sh script
notes and typo
2020-08-23 20:37:52 +01:00
Hin-Tak Leung
6bcd4cad2f /opt/vc/bin is not on standard $PATH on Ubuntu 2020-08-23 20:37:20 +01:00
Hin-Tak Leung
7f88e11fd0 adding advice to run ./ubuntu-prerequisite.sh in install.sh 2020-08-23 20:37:07 +01:00
Hin-Tak Leung
60e90d6fae Ubuntu kernels is not at /boot/kernel.img. Revisit for Raspbian
check running kernel agree with installed kernel, and ask the user to reboot before continue

Ubuntu kernels are not installed at /boot/kernel.img
2020-08-23 20:35:44 +01:00
Hin-Tak Leung
5cefec4cca make the config file configurable, for Ubuntu 2020-08-23 20:34:32 +01:00
Hin-Tak Leung
1f9c1464ab make the overlay install directory configurable, for Ubuntu 2020-08-23 20:34:25 +01:00
Hin-Tak Leung
71f01070d8 spelling 2020-08-21 16:27:08 +01:00
Psycho
19d1e6eb88 English correction 2020-08-20 08:16:13 +08:00
Hin-Tak Leung
07dc49259a remove "-c 1" and also protect with test for older kernel / alsa
The "-c 1" was simply wrong. The default (-c 0) sound device of
older kernel / alsa has a numid=3 selector for auto vs headphone vs hdmi .
Newer kernel simply has multiple devices. Also, headphone is -c 0 .

$ amixer contents
numid=2,iface=MIXER,name='Headphone Playback Switch'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=1,iface=MIXER,name='Headphone Playback Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=-10239,max=400,step=0
  : values=-2000
  | dBscale-min=-102.39dB,step=0.01dB,mute=1

TODO: For now, broadly dividing by kernel v4.x vs v5.x is good enough, but
it would be nice to find out when / which kernel /alsa this is relevant.

closes https://github.com/respeaker/seeed-voicecard/issues/240
2020-08-18 23:30:21 +01:00
Hin-Tak Leung
d8775ccb93 Use pr_info() for regular information 2020-08-18 08:22:32 +01:00
Hin-Tak Leung
c3ddbb521d likely v5 kernels behave like late 4.x, regarding dynamic dtoverlay; untested, and possibly revisit. 2020-08-18 08:22:19 +01:00
Hin-Tak Leung
1456785779 Merge remote-tracking branch 'origin/v5.5' into v5.7 2020-08-09 10:07:09 +01:00
Hin-Tak Leung
02eccbcd55 mask amixer failures - some user have different numbered / multiple audio devices 2020-08-09 10:06:21 +01:00
Hin-Tak Leung
131ee8187d Merge branch 'v5.7' into v5.7 2020-08-05 06:26:08 +01:00
Hin-Tak Leung
ed615d2318 Merge remote-tracking branch 'origin/v5.5' into v5.7 2020-08-05 06:20:32 +01:00
Hin-Tak Leung
2cc009619e Merge branch 'ubuntu' into v5.5 2020-08-05 06:10:37 +01:00
Hin-Tak Leung
aaf0cc2c61 move files in place, to capture hhuysqt <1020988872@qq.com>'s ubuntu-porting work
git rm seeed-voicecard.c
git mv seeed-voicecard-v5.3.c seeed-voicecard.c
2020-08-05 06:07:36 +01:00
Hin-Tak Leung
a6db04e724 Merge branch 'wrong-initialization-fix' into v5.5
Conflicts:
	seeed-voicecard.c
2020-08-05 05:59:37 +01:00
Hin-Tak Leung
0be1de9750 Revert previous over-zealous "rename asoc_simple_card_xxx() to asoc_simple_()"
Two of them should not have been changed, as they were protected and intended
for older kernels.
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
fcbc3b6d6b copy asoc_simple_card_init_dai() from v5.7:sound/soc/generic/simple-card-utils.c
It was made private in v5.2:

commit ad934ca8010843482d61fda46786449a9bc99e10
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:55:52 2019 +0900

    ASoC: simple-card-utils: share asoc_simple_dai_init()
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
c2b419c286 Revert "asoc_simple_card_init_dai is not exported, but asoc_simple_dai_init is, and does more"
This reverts commit de22f92298.

That commit was wrong: seeed_priv_to_props() is not identical to simple_priv_props().

Conflicts:
	seeed-voicecard.c
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
ed094dece5 v5.2: comments
The init code was extracted into asoc_simple_card_init_priv(), with
additional comments.

commit 65a5056b21202eff7f54243e587183f4bb6ed352
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:56:26 2019 +0900

    ASoC: simple-card-utils: share asoc_simple_card_init_priv()

    The difference between simple-card / audio-graph are just using
    OF graph style, or not. In other words, other things should be same.
    This means, simple-card/audio-graph common functions should be
    implemented at simple-card-utils, and its own functions should be
    implemented at each files.

    Current simple-card / audio-graph are initializing each priv,
    but it is same operation.
    This patch adds new asoc_simple_card_init_priv() and initialize
    priv by same operation.
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
51966603da v5.3: support snd_soc_dai_link_component style for cpu
commit f107294c6422e772773b53dbf802186175b6289e
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Thu Jun 6 13:07:35 2019 +0900

    ASoC: simple-card: support snd_soc_dai_link_component style for cpu

    ASoC supports modern style dai_link (= snd_soc_dai_link_component) for
    CPU. legacy style dai_link (= cpu_dai_name, cpu_name, cpu_of_node) are
    no longer needed.
    This patch switches to modern style.
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
6afe18224a v5.1: add .num_platform for dai_link
commit 910fdcabedd2354d161b1beab6ad7dc7e859651d
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Jan 21 09:32:32 2019 +0900

    ASoC: soc-core: add .num_platform for dai_link

    Current snd_soc_dai_link is starting to use snd_soc_dai_link_component
    (= modern) style for Platform, but it is still assuming single Platform
    so far. We will need to have multi Platform support in the not far
    future.

    Currently only simple card is using it as sound card driver,
    and other drivers are converted to it from legacy style by
    snd_soc_init_platform().
    To avoid future problem of multi Platform support, let's add
    num_platforms before it is too late.

    In the same time, to make it same naming mothed, "platform" should
    be "platforms". This patch fixup it too.
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
953fa50f4f v4.20: support snd_soc_dai_link_component style for platform
commit e58f41e41185c6906bd11c73c4e76aa5fc3ea685
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Aug 31 03:10:33 2018 +0000

    ASoC: simple-card: support snd_soc_dai_link_component style for platform

    Current ASoC is supporting snd_soc_dai_link_component for binding,
    it is more useful than current legacy style.
    Currently only codec is supporting it as multicodec (= codecs).
    CPU will support multi style in the future.
    We want to have it on Platform too in the future.

    If all Codec/CPU/Platform are replaced into snd_soc_dai_link_component
    style, we can remove legacy complex style.
    This patch supports snd_soc_dai_link_component style
    for simple-card for platform.
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
4396e4f834 v4.20: support snd_soc_dai_link_component style for codec
commit 710af9196ce614ee02185c2ec55e617a71843183
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Aug 31 03:08:24 2018 +0000

    ASoC: simple-card: support snd_soc_dai_link_component style for codec

    Current ASoC is supporting snd_soc_dai_link_component for binding,
    it is more useful than current legacy style.
    Currently only codec is supporting it as multicodec (= codecs).
    CPU will support multi style in the future.
    We want to have it on Platform too in the future.

    If all Codec/CPU/Platform are replaced into snd_soc_dai_link_component
    style, we can remove legacy complex style.
    This patch supports snd_soc_dai_link_component style
    for simple-card for codec.
2020-08-05 05:45:31 +01:00
Hin-Tak Leung
26754b0821 Revert previous over-zealous "rename asoc_simple_card_xxx() to asoc_simple_()"
Two of them should not have been changed, as they were protected and intended
for older kernels.
2020-08-05 05:26:01 +01:00
Hin-Tak Leung
af8668ff97 copy asoc_simple_card_init_dai() from v5.7:sound/soc/generic/simple-card-utils.c
It was made private in v5.2:

commit ad934ca8010843482d61fda46786449a9bc99e10
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:55:52 2019 +0900

    ASoC: simple-card-utils: share asoc_simple_dai_init()
2020-08-05 04:54:46 +01:00
Hin-Tak Leung
2d08bb0b35 Revert "asoc_simple_card_init_dai is not exported, but asoc_simple_dai_init is, and does more"
This reverts commit de22f92298.

That commit was wrong: seeed_priv_to_props() is not identical to simple_priv_props().

Conflicts:
	seeed-voicecard.c
2020-08-05 04:54:46 +01:00
Hin-Tak Leung
c2f81c1f23 v5.2: comments
The init code was extracted into asoc_simple_card_init_priv(), with
additional comments.

commit 65a5056b21202eff7f54243e587183f4bb6ed352
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:56:26 2019 +0900

    ASoC: simple-card-utils: share asoc_simple_card_init_priv()

    The difference between simple-card / audio-graph are just using
    OF graph style, or not. In other words, other things should be same.
    This means, simple-card/audio-graph common functions should be
    implemented at simple-card-utils, and its own functions should be
    implemented at each files.

    Current simple-card / audio-graph are initializing each priv,
    but it is same operation.
    This patch adds new asoc_simple_card_init_priv() and initialize
    priv by same operation.
2020-08-05 04:54:38 +01:00
Hin-Tak Leung
63fa92db39 v5.3: support snd_soc_dai_link_component style for cpu
commit f107294c6422e772773b53dbf802186175b6289e
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Thu Jun 6 13:07:35 2019 +0900

    ASoC: simple-card: support snd_soc_dai_link_component style for cpu

    ASoC supports modern style dai_link (= snd_soc_dai_link_component) for
    CPU. legacy style dai_link (= cpu_dai_name, cpu_name, cpu_of_node) are
    no longer needed.
    This patch switches to modern style.
2020-08-05 02:37:32 +01:00
Hin-Tak Leung
d2c0f1b5c9 v5.1: add .num_platform for dai_link
commit 910fdcabedd2354d161b1beab6ad7dc7e859651d
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Jan 21 09:32:32 2019 +0900

    ASoC: soc-core: add .num_platform for dai_link

    Current snd_soc_dai_link is starting to use snd_soc_dai_link_component
    (= modern) style for Platform, but it is still assuming single Platform
    so far. We will need to have multi Platform support in the not far
    future.

    Currently only simple card is using it as sound card driver,
    and other drivers are converted to it from legacy style by
    snd_soc_init_platform().
    To avoid future problem of multi Platform support, let's add
    num_platforms before it is too late.

    In the same time, to make it same naming mothed, "platform" should
    be "platforms". This patch fixup it too.
2020-08-05 02:18:23 +01:00
Hin-Tak Leung
775005d865 v4.20: support snd_soc_dai_link_component style for platform
commit e58f41e41185c6906bd11c73c4e76aa5fc3ea685
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Aug 31 03:10:33 2018 +0000

    ASoC: simple-card: support snd_soc_dai_link_component style for platform

    Current ASoC is supporting snd_soc_dai_link_component for binding,
    it is more useful than current legacy style.
    Currently only codec is supporting it as multicodec (= codecs).
    CPU will support multi style in the future.
    We want to have it on Platform too in the future.

    If all Codec/CPU/Platform are replaced into snd_soc_dai_link_component
    style, we can remove legacy complex style.
    This patch supports snd_soc_dai_link_component style
    for simple-card for platform.
2020-08-05 02:07:32 +01:00
Hin-Tak Leung
8c80018c3e v4.20: support snd_soc_dai_link_component style for codec
commit 710af9196ce614ee02185c2ec55e617a71843183
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Fri Aug 31 03:08:24 2018 +0000

    ASoC: simple-card: support snd_soc_dai_link_component style for codec

    Current ASoC is supporting snd_soc_dai_link_component for binding,
    it is more useful than current legacy style.
    Currently only codec is supporting it as multicodec (= codecs).
    CPU will support multi style in the future.
    We want to have it on Platform too in the future.

    If all Codec/CPU/Platform are replaced into snd_soc_dai_link_component
    style, we can remove legacy complex style.
    This patch supports snd_soc_dai_link_component style
    for simple-card for codec.
2020-08-05 01:42:57 +01:00
Hin-Tak Leung
076d12f7fb Revert partial-fix, in preparation for proper fix.
Revert "Fix dai_link->cpus etc used without backing storage."

This reverts commit 97146337cb.
2020-08-05 01:24:35 +01:00
Baozhu Zuo
c0f1dfa8bb Please use the 4.19 kernel first, 5.4 kernel support is still under development. 2020-08-03 09:07:51 +08:00
Hin-Tak Leung
67f7942cfd Merge remote-tracking branch 'origin/v5.5' into v5.7 2020-07-30 10:09:42 +01:00
HinTak
86c198d7dc
Merge pull request #4 from rotdrop/feature/support-ubuntu-server
Support ubuntu-server with /boot/firmware/overlays
2020-07-30 10:05:21 +01:00
HinTak
1d4abfa41d
Merge pull request #3 from rotdrop/bugfix/uninitialized-cpu-codec-platform
Fix dai_link->cpus etc used without backing storage.
2020-07-30 10:03:23 +01:00
Claus-Justus Heine
f52ed1b363 Support ubuntu-server with /boot/firmware/overlays 2020-07-29 22:26:34 +02:00
Claus-Justus Heine
97146337cb Fix dai_link->cpus etc used without backing storage. 2020-07-29 18:57:37 +02:00
Hin-Tak Leung
1046e30108 Merge remote-tracking branch 'upstream/master' into v5.5
Conflicts:
	install.sh
2020-07-25 05:37:50 +01:00
Hin-Tak Leung
97fd3f2eab Merge remote-tracking branch 'upstream/master' into v5.7
Conflicts:
	install.sh
2020-07-25 05:34:36 +01:00
Hin-Tak Leung
60d2a5129d Adjust for v5.7, "ASoC: soc-pcm: merge playback/cature_active into stream_active"
perl -pi -e 's(->capture_active)(->stream_active\[SNDRV_PCM_STREAM_CAPTURE\])g' *.c
perl -pi -e 's(->playback_active)(->stream_active\[SNDRV_PCM_STREAM_PLAYBACK\])g' *.c

commit 0f6011fd79a2fb92cb80177fd6bdc8aac3a3cd93
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Feb 17 17:28:15 2020 +0900

    ASoC: soc-pcm: merge playback/cature_active into stream_active

    DAI has playback_active and capture_active to care usage count.
    OTOH, we have SNDRV_PCM_STREAM_PLAYBACK/CAPTURE.
    But because of this kind of implementation mismatch,
    ALSA SoC has many verbose code.

    To solve this issue, this patch merge playback_active/capture_active
    into stream_active[2];
2020-07-25 05:22:34 +01:00
Jack Shao
6b4133b5f0
Merge pull request #224 from HinTak/suppress-fallthrough-warning
Suppress fallthrough warning
2020-04-28 09:59:04 +08:00
Hin-Tak Leung
0ed11aa9a4 compatibility - fallthrough' pseudo keyword was introduced in v5.4
commit 294f69e662d1570703e9b56e95be37a9fd3afba5
Author: Joe Perches <joe@perches.com>
Date:   Sat Oct 5 09:46:42 2019 -0700

    compiler_attributes.h: Add 'fallthrough' pseudo keyword for switch/case use
2020-04-27 21:30:34 +01:00
Hin-Tak Leung
2e1940bb0f compatibility - fallthrough' pseudo keyword was introduced in v5.4
commit 294f69e662d1570703e9b56e95be37a9fd3afba5
Author: Joe Perches <joe@perches.com>
Date:   Sat Oct 5 09:46:42 2019 -0700

    compiler_attributes.h: Add 'fallthrough' pseudo keyword for switch/case use
2020-04-27 21:17:56 +01:00
Jack Shao
6c6dfaa7d3
Merge pull request #225 from KillingJacky/master
remove the default kernel downgrade
2020-04-27 15:26:35 +08:00
KillingJacky
468b40eee5 fix typo 2020-04-27 08:19:50 +01:00
Jack Shao
07a6c4659e
update README.md explaining the cmd line option --compat-kernel 2020-04-27 15:16:05 +08:00
KillingJacky
ad4d66d3f7 add an cmd line option for choosing compile with compatible kernel; clean up more when uninstalling 2020-04-27 07:58:47 +01:00
Hin-Tak Leung
add12477e9 use the kernel's way of suppressing fallthrough
See include/linux/compiler_attributes.h:

/*
 * Add the pseudo keyword 'fallthrough' so case statement blocks
 * must end with any of these keywords:
 *   break;
 *   fallthrough;
 *   goto <label>;
 *   return [expression];
 *
 *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
 */
-if __has_attribute(__fallthrough__)
- define fallthrough                    __attribute__((__fallthrough__))
-else
- define fallthrough                    do {} while (0)  /* fallthrough */
-endif
2020-04-27 01:10:51 +01:00
Hin-Tak Leung
74d65bfcbd use the kernel's way of suppressing fallthrough
See include/linux/compiler_attributes.h:

/*
 * Add the pseudo keyword 'fallthrough' so case statement blocks
 * must end with any of these keywords:
 *   break;
 *   fallthrough;
 *   goto <label>;
 *   return [expression];
 *
 *  gcc: https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html#Statement-Attributes
 */
-if __has_attribute(__fallthrough__)
- define fallthrough                    __attribute__((__fallthrough__))
-else
- define fallthrough                    do {} while (0)  /* fallthrough */
-endif
2020-04-27 01:07:51 +01:00
Hin-Tak Leung
deed034f31 suppress another "this statement may fall through" warning
The whole warning is quite long but looks like this:

  CC [M]  seeed-voicecard/ac108.o
In file included from ./include/linux/printk.h:331,
                 from ./include/linux/kernel.h:15,
                 from ./include/linux/list.h:9,
                 from ./include/linux/module.h:12,
                 from seeed-voicecard/ac108.c:15:
seeed-voicecard/ac108.c: In function ‘ac108_set_fmt’:
./include/linux/dynamic_debug.h:122:52: warning: this statement may fall through [-Wimplicit-fallthrough=]
  122 | #define __dynamic_func_call(id, fmt, func, ...) do { \
      |                                                    ^
./include/linux/dynamic_debug.h:143:2: note: in expansion of macro ‘__dynamic_func_call’
  143 |  __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
      |  ^~~~~~~~~~~~~~~~~~~
./include/linux/dynamic_debug.h:157:2: note: in expansion of macro ‘_dynamic_func_call’
  157 |  _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
      |  ^~~~~~~~~~~~~~~~~~
./include/linux/device.h:1795:2: note: in expansion of macro ‘dynamic_dev_dbg’
 1795 |  dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
      |  ^~~~~~~~~~~~~~~
seeed-voicecard/ac108.c:866:4: note: in expansion of macro ‘dev_dbg’
  866 |    dev_dbg(dai->dev, "used as slave when AC101 is master\n");
      |    ^~~~~~~
seeed-voicecard/ac108.c:868:2: note: here
  868 |  case SND_SOC_DAIFMT_CBS_CFS:    /*AC108 Slave*/
      |  ^~~~
2020-04-27 00:15:00 +01:00
Hin-Tak Leung
2563020e29 suppress "this statement may fall through" warning
The semi-colon is needed, to prevent the comment being parsed as part of the "if {...}" statement.

The warning looks like this:

seeed-voicecard/wm8960.c: In function ‘wm8960_hw_params’:
seeed-voicecard/wm8960.c:752:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
  752 |   if ((iface & 0x3) != 0) {
      |      ^
seeed-voicecard/wm8960.c:757:2: note: here
  757 |  default:
      |  ^~~~~~~
2020-04-27 00:14:47 +01:00
Hin-Tak Leung
30276c80bc Don't force kernel downgrade
Revert "Fix: try to use a specific version kernel & headers"

This reverts commit ae32476755.

Conflicts:
	install.sh
2020-04-26 23:47:45 +01:00
Hin-Tak Leung
82c8d1024a suppress another "this statement may fall through" warning
The whole warning is quite long but looks like this:

  CC [M]  seeed-voicecard/ac108.o
In file included from ./include/linux/printk.h:331,
                 from ./include/linux/kernel.h:15,
                 from ./include/linux/list.h:9,
                 from ./include/linux/module.h:12,
                 from seeed-voicecard/ac108.c:15:
seeed-voicecard/ac108.c: In function ‘ac108_set_fmt’:
./include/linux/dynamic_debug.h:122:52: warning: this statement may fall through [-Wimplicit-fallthrough=]
  122 | #define __dynamic_func_call(id, fmt, func, ...) do { \
      |                                                    ^
./include/linux/dynamic_debug.h:143:2: note: in expansion of macro ‘__dynamic_func_call’
  143 |  __dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
      |  ^~~~~~~~~~~~~~~~~~~
./include/linux/dynamic_debug.h:157:2: note: in expansion of macro ‘_dynamic_func_call’
  157 |  _dynamic_func_call(fmt,__dynamic_dev_dbg,   \
      |  ^~~~~~~~~~~~~~~~~~
./include/linux/device.h:1795:2: note: in expansion of macro ‘dynamic_dev_dbg’
 1795 |  dynamic_dev_dbg(dev, dev_fmt(fmt), ##__VA_ARGS__)
      |  ^~~~~~~~~~~~~~~
seeed-voicecard/ac108.c:866:4: note: in expansion of macro ‘dev_dbg’
  866 |    dev_dbg(dai->dev, "used as slave when AC101 is master\n");
      |    ^~~~~~~
seeed-voicecard/ac108.c:868:2: note: here
  868 |  case SND_SOC_DAIFMT_CBS_CFS:    /*AC108 Slave*/
      |  ^~~~
2020-04-26 23:39:25 +01:00
Hin-Tak Leung
476378c156 suppress "this statement may fall through" warning
The semi-colon is needed, to prevent the comment being parsed as part of the "if {...}" statement.

The warning looks like this:

seeed-voicecard/wm8960.c: In function ‘wm8960_hw_params’:
seeed-voicecard/wm8960.c:752:6: warning: this statement may fall through [-Wimplicit-fallthrough=]
  752 |   if ((iface & 0x3) != 0) {
      |      ^
seeed-voicecard/wm8960.c:757:2: note: here
  757 |  default:
      |  ^~~~~~~
2020-04-26 23:27:54 +01:00
Hin-Tak Leung
4c15036368 copy asoc_simple_card_parse_dai() from v5.4:sound/soc/generic/simple-card.c
Towards the end of the series in asoc-v5.2:

commit 8f7f298a333761a528e103cda3b42f3a416ad1ee
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:56:36 2019 +0900

    ASoC: simple-card-utils: separate asoc_simple_card_parse_dai()

    The difference between simple-card / audio-graph are just using
    OF graph style, or not. In other words, other things should be same.
    This means, simple-card/audio-graph common functions should be
    implemented at simple-card-utils, and its own functions should be
    implemented at each files.

    Current simple-card / audio-graph are using
    asoc_simple_card_parse_dai() which is different implementation.
    But, these are implemanted at simple-card-utils.
    It should be implemanted at each files.
    This patch separate these into each files.

$ git log --format=oneline 0580dde59438686d60762b6da9229ebec693b94f^..ad11e59f52d6fc75037ac3cb66dc711b83c1bbf8
ad11e59f52d6fc75037ac3cb66dc711b83c1bbf8 ASoC: simple-card-utils: rename asoc_simple_card_xxx() to asoc_simple_()
8f7f298a333761a528e103cda3b42f3a416ad1ee ASoC: simple-card-utils: separate asoc_simple_card_parse_dai()
65a5056b21202eff7f54243e587183f4bb6ed352 ASoC: simple-card-utils: share asoc_simple_card_init_priv()
629f75440a68220a78aef9d8569831824890c47d ASoC: simple-card-utils: share asoc_simple_be_hw_params_fixup()
ad934ca8010843482d61fda46786449a9bc99e10 ASoC: simple-card-utils: share asoc_simple_dai_init()
f48dcbb6d47d870cf3a03f453c923dd262158c66 ASoC: simple-card-utils: share asoc_simple_hw_param()
686911b46fb5a08df142fe22b6c06dc6fbd3ba65 ASoC: simple-card-utils: share asoc_simple_shutdown()
f38df5bf0c9cb905fa9d5abc86c3a00128cdbba5 ASoC: simple-card-utils: share asoc_simple_startup()
e59289cda8dec0153fa396864c8ba8092ec3b80d ASoC: simple_card_utils: share common priv for simple-card/audio-graph
0580dde59438686d60762b6da9229ebec693b94f ASoC: simple-card-utils: add asoc_simple_debug_info()
2020-04-26 22:48:50 +01:00
Hin-Tak Leung
cb9bf1c913 adjust for changes in aux_dev
In 5.4:

commit a48b561d873d1d9fda55782d275eff94ec647863
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Thu Aug 8 14:54:39 2019 +0900

    ASoC: soc-core: remove legacy style of aux_dev
2020-04-24 05:13:41 +01:00
Hin-Tak Leung
37a37a6d16 adjust for modern style dai_link
In v5.3:

commit f107294c6422e772773b53dbf802186175b6289e
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Thu Jun 6 13:07:35 2019 +0900

    ASoC: simple-card: support snd_soc_dai_link_component style for cpu
2020-04-24 04:58:58 +01:00
Hin-Tak Leung
de22f92298 asoc_simple_card_init_dai is not exported, but asoc_simple_dai_init is, and does more
In v5.2:

commit ad934ca8010843482d61fda46786449a9bc99e10
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:55:52 2019 +0900

    ASoC: simple-card-utils: share asoc_simple_dai_init()
2020-04-24 04:33:49 +01:00
Hin-Tak Leung
72d3c9e2f6 DAI and CELL not used in macros.
In v5.2:

commit 8f7f298a333761a528e103cda3b42f3a416ad1ee
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:56:36 2019 +0900

    ASoC: simple-card-utils: separate asoc_simple_card_parse_dai()
2020-04-24 04:03:19 +01:00
Hin-Tak Leung
b9272dcee8 asoc_simple_card_canonicalize_platform returns void, and always successful
In v5.1:

commit fe7ed4dec2e6289eab81dd18c0d613c0851d85a1
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Jan 21 16:40:59 2019 +0900

    ASoC: simple-card: rename to asoc_simple_card_canonicalize_platform()

    Current simple-card is using asoc_simple_card_canonicalize_dailink().
    Its naming is "dailink", but is for "platform".
    We already have asoc_simple_card_canonicalize_cpu() for "cpu",
    let's follow same naming rule.
    It never return error, so, void function is better idea.
2020-04-24 03:50:41 +01:00
Hin-Tak Leung
61022875b3 asoc_simple_canonicalize_dailink() to asoc_simple_canonicalize_platform()
In v5.1:

commit fe7ed4dec2e6289eab81dd18c0d613c0851d85a1
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Mon Jan 21 16:40:59 2019 +0900

    ASoC: simple-card: rename to asoc_simple_card_canonicalize_platform()
2020-04-24 03:43:13 +01:00
Hin-Tak Leung
41c71f1b45 rename asoc_simple_card_xxx() to asoc_simple_()
First appeared in v5.2:

commit ad11e59f52d6fc75037ac3cb66dc711b83c1bbf8
Author: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Date:   Wed Mar 20 13:56:50 2019 +0900

    ASoC: simple-card-utils: rename asoc_simple_card_xxx() to asoc_simple_()
2020-04-24 03:35:45 +01:00
Hin-Tak Leung
8c5ffaeed3 LINUX_VERSION_IS_GEQ macro from Linux kernel backports package 2020-04-24 02:27:58 +01:00
hhuysqt
920ef83b63 Add: compatible to linux kernel 5.3.0 or higher 2020-03-30 12:23:36 +08:00
HinTak
48463b9a50 Correct typo
Fix typo in comment.
2020-03-30 09:01:36 +08:00
mxklb
2da704e872 Check for enough space on /boot volume (check #209) 2020-02-15 16:38:04 +08:00
HinTak
d6f808b278 fix typo 2020-01-29 14:32:30 +08:00
SamhithPottem
873580cfd5 Update install.sh (#182) to --force-yes install 2019-10-23 11:16:55 +08:00
turmary
ae32476755 Fix: try to use a specific version kernel & headers 2019-10-22 15:59:07 +01:00
Baozhu Zuo
277aeacb81
The latest kernel of raspberry PI is unstable, so do this anyway to make sure the driver loads correctly 2019-07-25 19:39:07 +08:00
Baozhu Zuo
08f0d96d68
raspberry pi 4 use the v7l+ suffix as the kernel identifier 2019-07-25 19:30:04 +08:00
turmary
da5f90473b Fix: removing asound.conf when detecting i2c addresses 2019-05-22 10:39:09 +08:00
turmary
0ea5d2bd98 Fix: dtoverlay on Linux v4.19 failed in phandle insertion 2019-05-21 12:18:25 +08:00
Baozhu Zuo
c7026a4048
remove sleep , accelerate the seeed-voicecard service startup 2019-04-17 14:58:21 +08:00
Baozhu Zuo
11e9db79b5
remove sleep , accelerate the seeed-voicecard service startup 2019-04-17 14:58:07 +08:00
turmary
90d2673610 Add: kernel headers checking after action rpi-update 2019-04-16 09:34:10 +08:00
Norbert Preining
09728d1c82 allow installation in qemu
Currently, installation is only supported on real hardware, but not
running in QEMU. Change the check to make sure the necessary
directories and programs are available instead of bailing out
on non-Raspberry archs.
2019-03-30 14:19:47 +08:00
respeaker
b98fce84e0 Add: compatible to linux-4.18 or higher 2019-03-14 03:13:25 +00:00
Pernat1y
6c6b9ab7de Install packages for Arch Linux 2019-01-28 09:23:40 +08:00
Pernat1y
27b6cdf252 Make grep searches more precise 2019-01-28 09:23:40 +08:00
Baozhu Zuo
f5b82b6b7d
Merge pull request #123 from baorepo/patch-1
test hardware mic phase position
2018-12-25 09:37:27 +08:00
Baozhu Zuo
5744fd1bbb
test hardware mic phase position
baozhu@bz:/tmp$ python wave_test.py record.wav 
2
['448.8125', '446.65625', '-0.1875', '330.8125', '448.375', '450.59375', '451.0']
['448.78125', '448.5625', '-0.1875', '-0.125', '448.3125', '-0.125', '-450.78125']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.0625', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.25']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.25']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.25']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.25']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '0.21875']
['0.0', '0.0', '0.0', '-0.09375', '-0.09375', '-0.09375', '-0.96875']
['0.03125', '0.0', '-0.0625', '-0.09375', '-0.0625', '-0.09375', '-23.0625']
['0.0', '0.0', '-0.0625', '-0.09375', '-0.0625', '-0.09375', '-23.125']
done
48000
2018-12-25 09:36:27 +08:00
turmary
95f4fe0688 Fix: remove spin lock in machine trigger 2018-11-27 09:47:44 +00:00
turmary
3392bf394b Fix: try to stop aif clock in thread environment 2018-11-07 18:33:55 -10:00
turmary
0965139ead Optimize: simplify AC101 debug message 2018-11-07 15:29:06 -10:00
Jack Shao
be0812c70b update: more convenient way to apply udev rules 2018-10-11 17:54:51 +08:00
KillingJacky
dfc7b404a5 change asound.state for 4mic array, lower down PGA to reduce static noise 2018-09-29 14:49:19 +08:00
Baozhu Zuo
deeddaabb4
seeed-voicecard: if the board detect seeed-voicecard then resetup asound.conf and asound.state 2018-09-29 14:36:01 +08:00
Yihui Xiong
bfe6978ef4 update 6 mic gain controls 2018-08-06 06:32:46 +00:00
Yihui Xiong
67b4504964
Update asound_6mic.conf 2018-08-01 18:54:25 +08:00
Baozhu Zuo
bca16c68c4
Update README.md 2018-07-30 15:51:18 +08:00
Baozhu Zuo
ab0b28d08f
Update README.md 2018-07-30 15:44:47 +08:00
Baozhu Zuo
a73335b8d0
Merge pull request #92 from respeaker/dev
Dev
2018-07-26 08:58:15 +08:00
Baozhu Zuo
58c6233325 use sound card id 2018-07-24 11:39:01 +08:00
Baozhu Zuo
f85c98c4e0 4mic doesnt have output interface, delete it 2018-07-24 11:38:38 +08:00
Baozhu Zuo
7009515ec9 use link to replase copy operation 2018-07-24 11:31:21 +08:00
Baozhu Zuo
8c499c2268 create git repo to manage voicecard configs 2018-07-24 11:30:22 +08:00
Baozhu Zuo
9a9f4368b4 use card id to identify cards 2018-07-24 11:28:55 +08:00
Baozhu Zuo
3d56af9d3c
Merge pull request #78 from respeaker/pulse
Merge seeed-voicecard pulseaudio settings
2018-05-30 10:46:42 +08:00
jerryyip
3074de1f86 init 2018-05-30 10:36:10 +08:00
jerryyip
33ddbd39d3 init pulse setting 2018-05-29 19:15:32 +08:00
Peter.Yang
983d4834bb Optimize: doc about software pcm ac101 2018-05-21 09:52:38 +00:00
turmary
a8d0a23583 Fix: ac101 i2c accessing is too often. 2018-05-21 03:33:46 +00:00
Peter.Yang
ccac09b842 Fix: reset ac101/ac108 chips after fill cache 2018-05-11 07:37:53 +00:00
turmary
0548a6d0a3 Fix: close work_switch when codec removeing 2018-04-24 04:28:14 +00:00
Peter.Yang
d0d9107c91 Move: simple-audio-card -> seeed-voicecard, module removing & inserting again supported 2018-04-04 09:36:18 +00:00
Peter.Yang
d660a92d73 Add: headset detection for 6-Mics Circular Array Kit and 4-Mics Linear Array Kit 2018-04-02 08:43:20 +00:00
Peter.Yang
8211f4c000 Fix: 4MIC recording by portaudio & pyaudio 2018-04-02 07:59:17 +00:00
Baozhu Zuo
86329f0719 Fix 2mic hat install failed 2018-03-30 03:21:40 +00:00
Peter.Yang
031bbb3a1a Fix: simple-card adapt to kernel version 4.9 & 4.14 2018-03-30 02:37:57 +00:00
Peter.Yang
80e0478c91 Update: doc about limit for doing capture & playback the same time 2018-03-29 08:29:55 +00:00
Peter.Yang
860d38fc47 Fix: i2c access fail when AC108 as master, support make DEBUG=1 2018-03-27 03:13:53 +00:00
Peter.Yang
1901914b56 Fix: limit of capture starting first. 2018-03-24 12:22:02 +00:00
Peter.Yang
7e1f29af35 Fix: clear the "PuPu" noise again after ac101 as Master 2018-03-24 11:05:46 +00:00
Peter.Yang
d3d95d0296 Fix: i2c access fail & channels miss order 2018-03-24 10:01:33 +00:00
Peter.Yang
22f495491a Fix: ac101 as master, ac108 pll source from ac101 bclk 2018-03-23 03:25:52 +00:00
Peter.Yang
235485652b Optimize: names & disable sample rate 96K 2018-03-13 08:30:43 +00:00
Peter.Yang
9dce807fb7 Fix: clear the "PuPu" noise at the very beginning of playback 2018-03-13 03:40:16 +00:00
Peter.Yang
d6744a76d2 Update: coherence picture 2018-03-12 10:05:37 +00:00
Peter.Yang
829ae64abe Add: Doc & tools about coherence 2018-03-12 06:39:43 +00:00
Peter.Yang
a98c728f33 Add: Doc pictures of 6-mics circular array kit/4-mics linear array kit 2018-03-09 06:47:06 +00:00
Peter.Yang
6b6552bf9c Move: ac101 pll clock source set to bclk if it's slave mode 2018-03-07 06:34:33 +00:00
Peter.Yang
cff392127f Fix: ac101 noise import by PLL frequncy deviation 2018-03-06 09:37:14 +00:00
Peter.Yang
0d30a1599d Add: Doc for 6-Mics Circular Array Kit & 4-Mics Linear Array Kit 2018-03-02 09:28:01 +00:00
Peter.Yang
0f5ff56d1e Add: append plug for 4mic pcm ac108 2018-02-27 09:12:42 +00:00
Peter.Yang
b8f9bb38fd Move: register access from i2c_master_XXX to regmap_XXX 2018-02-27 09:05:55 +00:00
Peter.Yang
2f31ac4ea4 Fix: ac101 stereo widgets get/put interface 2018-02-27 02:58:10 +00:00
Peter.Yang
00d123836f Fix: channels widgets order for 6mic 2018-02-25 09:51:37 +00:00
Peter.Yang
d225c664d7 Fix: asound configuration for pcm ac108 2018-02-25 02:42:50 +00:00
Baozhu Zuo
b462e8a724 fix i2c cannt auto load on raspbian lite os 2018-02-16 16:01:47 +08:00
Peter.Yang
e2266a2791 Fix: service configuration error for asound.conf 2018-02-11 14:29:10 +00:00
Peter.Yang
12d155f6ea Add: 4mic OK after merge 2018-02-10 08:57:30 +00:00
peter.yang
1c1643003f Merge tracking branch 'install' to probe drivers by appliation. 2018-02-10 15:18:47 +08:00
peter.yang
18eec1abfa Merge: ac108 & ac101 as single codec module 2018-02-10 15:16:01 +08:00
peter.yang
fa4b566d9a Move: rename ac108 -> ac10x 2018-02-10 11:36:18 +08:00
peter.yang
560008e8fd Remove: not used code 2018-02-07 17:35:12 +08:00
peter.yang
cf52966d00 Add: multi codec support in simple-card 2018-02-07 14:02:45 +08:00
peter.yang
edb5a1da65 Merge: ac108 work for 4mic & 8mic 2018-02-05 10:45:55 +08:00
Baozhu Zuo
3fdc0c4345
Update README.md 2018-02-01 16:52:35 +08:00
Baozhu Zuo
3a0a0e8b57
Update README.md 2018-02-01 16:42:49 +08:00
Baozhu Zuo
f49d896613 update readme add dkms version 2018-02-01 16:07:26 +08:00
Baozhu Zuo
73ff8fe114 add seeed-voicecard manger service 2018-02-01 16:07:02 +08:00
Baozhu Zuo
8b84b891cd use seeed-voicecard service to manager all the card
Changes to be committed:
	modified:   install.sh
	modified:   uninstall.sh
2018-02-01 16:04:31 +08:00
Baozhu Zuo
7170b7fcb2 change dmix to plughw to playback 2018-02-01 15:57:45 +08:00
peter.yang
add8afa699 Add: capturing & playing in Audacity is OK 2018-01-30 19:19:13 +08:00
peter.yang
995c17c160 Add: export start-clock interface in ac101 to simple-card 2018-01-30 19:12:47 +08:00
peter.yang
10e0f12b16 Fix: master device same as codec device 2018-01-30 19:07:57 +08:00
peter.yang
d8b60f1116 Bugfix: crash due to device probing order 2018-01-29 19:14:28 +08:00
peter.yang
780db6f6ab Add: speaker out is OK 2018-01-26 11:08:09 +08:00
peter.yang
b032c0664d Add: ac101 dsp_a mode, tdm enabled, 8 slot, 32bit OK 2018-01-24 20:18:58 +08:00
peter.yang
56da9a526c Bugfix: AC101 miss channels order in cpu_dai, channel map IN(0,1,2,3,4,5,6,7)->OUT(2,3,4,5,6,7,0,1) 2018-01-23 16:46:15 +08:00
peter.yang
c3367740d5 Remove: widgets and routes isnt for volume controlling 2018-01-23 16:19:00 +08:00
peter.yang
156697545a Remove: switch detecting 2018-01-22 16:08:32 +08:00
peter.yang
aec1941ae1 Add: ac101 dsp_a mode, playing 2 in 8 channels OK 2018-01-19 19:25:15 +08:00
peter.yang
7aae0e3353 add original ac101 reference driver 2018-01-12 16:37:28 +08:00
root
188be2636f Fix: API name to DECLARE_TLV_DB_RANGE 2017-12-15 07:47:08 +00:00
peter.yang
a62c615114 Add capturing volume controls 2017-11-29 09:17:52 +00:00
peter.yang
0cb24e58d2 Fix: pcm playback & capture stream can work together,
all with 8 channels.
2017-11-23 10:15:59 +00:00
peter.yang
07b67878dc Add 2 channels playback stream 2017-11-22 09:05:22 +00:00
peter.yang
5607fed986 override channels in dts setting 2017-11-22 07:33:59 +00:00
peter.yang
878027066d Bugfix: miss channels order in cpu_dai 2017-11-20 01:22:28 +00:00
peter.yang
5028a91201 pcm format 8 channels, using two ac108 chips 2017-11-16 06:57:55 +00:00
peter.yang
7f4b5849a7 pcm format 4 channels: no need ac108_plugin 2017-11-10 09:00:23 +00:00
peter.yang
3fd4021f45 Add original RPI simple-card driver 2017-11-10 08:52:24 +00:00
Baozhu Zuo
b9d9cde471 Merge pull request #12 from Lance0312/create-alsa-lib
Copy shared library using install -D
2017-10-24 22:17:58 +08:00
Lance Chen
8094f7c3ab
Copy shared library using install -D
/usr/lib/arm-linux-gnueabihf/alsa-lib/ might not exist
2017-10-24 21:42:24 +08:00
Baozhu Zuo
3fed3fdc8a asound.conf is different between 2mic and 4mic 2017-10-18 15:51:54 +08:00
42 changed files with 7111 additions and 1830 deletions

View file

@ -1,18 +1,52 @@
#
# Peter Yang <turmary@126.com>
# Copyright (c) 2019 Seeed Studio
#
# MIT License
#
uname_r=$(shell uname -r)
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language
ifneq ($(KERNELRELEASE),)
# $(warning KERNELVERSION=$(KERNELVERSION))
snd-soc-wm8960-objs := wm8960.o
snd-soc-ac108-objs := ac108.o
snd-soc-ac108-objs := ac108.o ac101.o
snd-soc-seeed-voicecard-objs := seeed-voicecard.o
obj-m += snd-soc-wm8960.o
obj-m += snd-soc-ac108.o
obj-m += snd-soc-seeed-voicecard.o
ifdef DEBUG
ifneq ($(DEBUG),0)
ccflags-y += -DDEBUG -DAC101_DEBG
endif
endif
else
DEST := /lib/modules/$(uname_r)/kernel
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
make -C /lib/modules/$(uname_r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
make -C /lib/modules/$(uname_r)/build M=$(PWD) clean
install:
sudo cp snd-soc-ac108.ko /lib/modules/$(shell uname -r)/kernel/sound/soc/codecs/
sudo cp snd-soc-wm8960.ko /lib/modules/$(shell uname -r)/kernel/sound/soc/codecs/
sudo cp snd-soc-ac108.ko ${DEST}/sound/soc/codecs/
sudo cp snd-soc-wm8960.ko ${DEST}/sound/soc/codecs/
sudo cp snd-soc-seeed-voicecard.ko ${DEST}/sound/soc/bcm/
sudo depmod -a
.PHONY: all clean install
endif

167
README.md
View file

@ -1,149 +1,64 @@
# seeed-voicecard
[![Join the chat at https://gitter.im/seeed-voicecard/Lobby](https://badges.gitter.im/seeed-voicecard/Lobby.svg)](https://gitter.im/seeed-voicecard/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
The drivers for [ReSpeaker Mic Hat](https://www.seeedstudio.com/ReSpeaker-2-Mics-Pi-HAT-p-2874.html), [ReSpeaker 4 Mic Array](https://www.seeedstudio.com/ReSpeaker-4-Mic-Array-for-Raspberry-Pi-p-2941.html), [6-Mics Circular Array Kit](), and [4-Mics Linear Array Kit]() for Raspberry Pi.
The drivers of [ReSpeaker Mic Hat](https://www.seeedstudio.com/ReSpeaker-2-Mics-Pi-HAT-p-2874.html) and [ReSpeaker 4 Mic Array](https://www.seeedstudio.com/ReSpeaker-4-Mic-Array-for-Raspberry-Pi-p-2941.html) for Raspberry Pi.
## ReSpeaker Mic Hat
[![](https://github.com/SeeedDocument/MIC_HATv1.0_for_raspberrypi/blob/master/img/mic_hatv1.0.png?raw=true)](https://www.seeedstudio.com/ReSpeaker-2-Mics-Pi-HAT-p-2874.html)
While the upstream wm8960 codec is not currently supported by current Pi kernel builds, upstream wm8960 has some bugs, we had fixed it. we must it build manually.
Get the seeed voice card source code.
### Install seeed-voicecard
Get the seeed voice card source code and install all linux kernel drivers
```bash
git clone https://github.com/respeaker/seeed-voicecard
git clone https://github.com/HinTak/seeed-voicecard
cd seeed-voicecard
#for ReSpeaker 2-mic
sudo ./install.sh 2mic
sudo ./install.sh
sudo reboot
```
## ReSpeaker Documentation
Check that the sound card name matches the source code seeed-voicecard.
Up to date documentation for reSpeaker products can be found in [Seeed Studio Wiki](https://wiki.seeedstudio.com/ReSpeaker/)!
![](https://files.seeedstudio.com/wiki/ReSpeakerProductGuide/img/Raspberry_Pi_Mic_Array_Solutions.png)
### Coherence
Estimate the magnitude squared coherence using Welchs method.
![4-mics-linear-array-kit coherence](https://user-images.githubusercontent.com/3901856/37277486-beb1dd96-261f-11e8-898b-84405bfc7cea.png)
Note: 'CO 1-2' means the coherence between channel 1 and channel 2.
```bash
#for ReSpeaker 2-mic
pi@raspberrypi:~/seeed-voicecard $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
Subdevices: 8/8
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
Subdevice #4: subdevice #4
Subdevice #5: subdevice #5
Subdevice #6: subdevice #6
Subdevice #7: subdevice #7
card 0: ALSA [bcm2835 ALSA], device 1: bcm2835 ALSA [bcm2835 IEC958/HDMI]
Subdevices: 1/1
Subdevice #0: subdevice #0
card 1: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
pi@raspberrypi:~/seeed-voicecard $ arecord -l
**** List of CAPTURE Hardware Devices ****
card 1: seeed2micvoicec [seeed-2mic-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm8960-hifi-0 []
Subdevices: 1/1
Subdevice #0: subdevice #0
pi@raspberrypi:~/seeed-voicecard $
# How to get the coherence of the captured audio(a.wav for example).
sudo apt install python-numpy python-scipy python-matplotlib
python tools/coherence.py a.wav
# Requirement of the input audio file:
- format: WAV(Microsoft) signed 16-bit PCM
- channels: >=2
```
#### Next step
Go to https://github.com/respeaker/mic_hat to build voice enabled projects with Google Assistant SDK or Alexa Voice Service.
## ReSpeaker 4 Mic Array
[![](https://github.com/SeeedDocument/ReSpeaker-4-Mic-Array-for-Raspberry-Pi/blob/master/img/features.png?raw=true)](https://www.seeedstudio.com/ReSpeaker-4-Mic-Array-for-Raspberry-Pi-p-2941.html)
The 4 Mic Array uses ac108 which includes 4 ADCs, we also write ac108 rapberry pi linux kernel driver.
```bash
git clone https://github.com/respeaker/seeed-voicecard
cd seeed-voicecard
sudo ./install.sh 4mic
#reboot your Raspbian OS
sudo reboot
```
Check that the sound card name matches the source code seeed-voicecard.
```bash
#for ReSpeaker 4-mic
pi@raspberrypi:~ $ arecord -L
null
Discard all samples (playback) or generate zero samples (capture)
playback
capture
dmixed
array
ac108
default:CARD=seeed4micvoicec
seeed-4mic-voicecard,
Default Audio Device
sysdefault:CARD=seeed4micvoicec
seeed-4mic-voicecard,
Default Audio Device
dmix:CARD=seeed4micvoicec,DEV=0
seeed-4mic-voicecard,
Direct sample mixing device
dsnoop:CARD=seeed4micvoicec,DEV=0
seeed-4mic-voicecard,
Direct sample snooping device
hw:CARD=seeed4micvoicec,DEV=0
seeed-4mic-voicecard,
Direct hardware device without any conversions
plughw:CARD=seeed4micvoicec,DEV=0
seeed-4mic-voicecard,
Hardware device with all software conversions
pi@raspberrypi:~ $
```
If you want to change the alsa settings, You can use `sudo alsactl --file=asound.state store` to save it.
Test:
```bash
#for ReSpeaker 2-mic
#It will capture sound an playback on hw:1
arecord -f cd -Dhw:1 | aplay -Dhw:1
```
```bash
#for ReSpeaker 4-mic
#It will capture sound on AC108 and save as a.wav
arecord -Dac108 -f S32_LE -r 16000 -c 4 a.wav
```
### uninstall seeed-voicecard
If you want to upgrade the driver , you need uninstall the driver first.
```
pi@raspberrypi:~/seeed-voicecard $ sudo ./uninstall.sh 4mic
delete dtoverlay=seeed-4mic-voicecard in /boot/config.txt
delete snd-soc-ac108 in /etc/modules
------------------------------------------------------
Please reboot your raspberry pi to apply all settings
Thank you!
------------------------------------------------------
pi@raspberrypi:~/seeed-voicecard $ sudo ./uninstall.sh 2mic
delete dtoverlay=seeed-2mic-voicecard in /boot/config.txt
remove seeed-2mic-voicecard.dtbo in /boot/overlays
remove snd-soc-wm8960.ko
delete snd-soc-wm8960 in /etc/modules
pi@raspberrypi:~/seeed-voicecard $ sudo ./uninstall.sh
...
------------------------------------------------------
Please reboot your raspberry pi to apply all settings
Thank you!
------------------------------------------------------
```
### with Google Assistant
if you run the assistant but the playback is speed up considerably, try to configure alsa:
```bash
sudo cp asound.conf /etc/asound.conf
```
If the alsa configuration doesn't solve the issue, try to use pulseaudio. See [#4](https://github.com/respeaker/seeed-voicecard/issues/4)
Enjoy !
### Technical support
For hardware testing purposes we made a Rasperry Pi OS 5.10.17-v7l+ 32-bit image with reSpeaker drivers pre-installed, which you can download by clicking on [this link](https://files.seeedstudio.com/linux/Raspberry%20Pi%204%20reSpeaker/2021-05-07-raspios-buster-armhf-lite-respeaker.img.xz).
We provide official support for using reSpeaker with the following OS:
- 32-bit Raspberry Pi OS
- 64-bit Raspberry Pi OS
And following hardware platforms:
- Raspberry Pi 3 (all models), Raspberry Pi 4 (all models)
Anything beyond the scope of official support is considered to be community supported. Support for other OS/hardware platforms can be added, provided MOQ requirements can be met.
If you have a technical problem when using reSpeaker with one of the officially supported platforms/OS, feel free to create an issue on Github. For general questions or suggestions, please use [Seeed forum](https://forum.seeedstudio.com/c/products/respeaker/15).

1701
ac101.c Normal file

File diff suppressed because it is too large Load diff

432
ac101_regs.h Normal file
View file

@ -0,0 +1,432 @@
/*
* ac101_regs.h
*
* (C) Copyright 2017-2018
* Seeed Technology Co., Ltd. <www.seeedstudio.com>
*
* PeterYang <linsheng.yang@seeed.cc>
*
* (C) Copyright 2010-2017
* Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
* huangxin <huangxin@reuuimllatech.com>
*
* some simple description for this code
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
*/
#ifndef __AC101_REGS_H__
#define __AC101_REGS_H__
/*pll source*/
#define AC101_MCLK1 1
#define AC101_MCLK2 2
#define AC101_BCLK1 3
#define AC101_BCLK2 4
#define AIF1_CLK 1
#define AIF2_CLK 2
#define CHIP_AUDIO_RST 0x0
#define PLL_CTRL1 0x1
#define PLL_CTRL2 0x2
#define SYSCLK_CTRL 0x3
#define MOD_CLK_ENA 0x4
#define MOD_RST_CTRL 0x5
#define AIF_SR_CTRL 0x6
#define AIF1_CLK_CTRL 0x10
#define AIF1_ADCDAT_CTRL 0x11
#define AIF1_DACDAT_CTRL 0x12
#define AIF1_MXR_SRC 0x13
#define AIF1_VOL_CTRL1 0x14
#define AIF1_VOL_CTRL2 0x15
#define AIF1_VOL_CTRL3 0x16
#define AIF1_VOL_CTRL4 0x17
#define AIF1_MXR_GAIN 0x18
#define AIF1_RXD_CTRL 0x19
#define ADC_DIG_CTRL 0x40
#define ADC_VOL_CTRL 0x41
#define ADC_DBG_CTRL 0x42
#define HMIC_CTRL1 0x44
#define HMIC_CTRL2 0x45
#define HMIC_STS 0x46
#define DAC_DIG_CTRL 0x48
#define DAC_VOL_CTRL 0x49
#define DAC_DBG_CTRL 0x4a
#define DAC_MXR_SRC 0x4c
#define DAC_MXR_GAIN 0x4d
#define ADC_APC_CTRL 0x50
#define ADC_SRC 0x51
#define ADC_SRCBST_CTRL 0x52
#define OMIXER_DACA_CTRL 0x53
#define OMIXER_SR 0x54
#define OMIXER_BST1_CTRL 0x55
#define HPOUT_CTRL 0x56
#define ESPKOUT_CTRL 0x57
#define SPKOUT_CTRL 0x58
#define LOUT_CTRL 0x59
#define ADDA_TUNE1 0x5a
#define ADDA_TUNE2 0x5b
#define ADDA_TUNE3 0x5c
#define HPOUT_STR 0x5d
/*CHIP_AUDIO_RST*/
#define AC101_CHIP_ID 0x0101
/*PLL_CTRL1*/
#define DPLL_DAC_BIAS 14
#define PLL_POSTDIV_M 8
#define CLOSE_LOOP 6
#define INT 0
/*PLL_CTRL2*/
#define PLL_EN 15
#define PLL_LOCK_STATUS 14
#define PLL_PREDIV_NI 4
#define PLL_POSTDIV_NF 0
/*SYSCLK_CTRL*/
#define PLLCLK_ENA 15
#define PLLCLK_SRC 12
#define AIF1CLK_ENA 11
#define AIF1CLK_SRC 8
#define AIF2CLK_ENA 7
#define AIF2CLK_SRC 4
#define SYSCLK_ENA 3
#define SYSCLK_SRC 0
/*MOD_CLK_ENA*/
#define MOD_CLK_AIF1 15
#define MOD_CLK_AIF2 14
#define MOD_CLK_AIF3 13
#define MOD_CLK_SRC1 11
#define MOD_CLK_SRC2 10
#define MOD_CLK_HPF_AGC 7
#define MOD_CLK_HPF_DRC 6
#define MOD_CLK_ADC_DIG 3
#define MOD_CLK_DAC_DIG 2
/*MOD_RST_CTRL*/
#define MOD_RESET_CTL 0
#define MOD_RESET_AIF1 15
#define MOD_RESET_AIF2 14
#define MOD_RESET_AIF3 13
#define MOD_RESET_SRC1 11
#define MOD_RESET_SRC2 10
#define MOD_RESET_HPF_AGC 7
#define MOD_RESET_HPF_DRC 6
#define MOD_RESET_ADC_DIG 3
#define MOD_RESET_DAC_DIG 2
/*AIF_SR_CTRL*/
#define AIF1_FS 12 //AIF1 Sample Rate
#define AIF2_FS 8 //AIF2 Sample Rate
#define SRC1_ENA 3
#define SRC1_SRC 2
#define SRC2_ENA 1
#define SRC2_SRC 0
/*AIF1LCK_CTRL*/
#define AIF1_MSTR_MOD 15
#define AIF1_BCLK_INV 14
#define AIF1_LRCK_INV 13
#define AIF1_BCLK_DIV 9
#define AIF1_LRCK_DIV 6
#define AIF1_WORK_SIZ 4
#define AIF1_DATA_FMT 2
#define DSP_MONO_PCM 1
#define AIF1_TDMM_ENA 0
/*AIF1_ADCDAT_CTRL*/
#define AIF1_AD0L_ENA 15
#define AIF1_AD0R_ENA 14
#define AIF1_AD1L_ENA 13
#define AIF1_AD1R_ENA 12
#define AIF1_AD0L_SRC 10
#define AIF1_AD0R_SRC 8
#define AIF1_AD1L_SRC 6
#define AIF1_AD1R_SRC 4
#define AIF1_ADCP_ENA 3
#define AIF1_ADUL_ENA 2
#define AIF1_SLOT_SIZ 0
/*AIF1_DACDAT_CTRL*/
#define AIF1_DA0L_ENA 15
#define AIF1_DA0R_ENA 14
#define AIF1_DA1L_ENA 13
#define AIF1_DA1R_ENA 12
#define AIF1_DA0L_SRC 10
#define AIF1_DA0R_SRC 8
#define AIF1_DA1L_SRC 6
#define AIF1_DA1R_SRC 4
#define AIF1_DACP_ENA 3
#define AIF1_DAUL_ENA 2
#define AIF1_SLOT_SIZ 0
/*AIF1_MXR_SRC*/
#define AIF1_AD0L_AIF1_DA0L_MXR 15
#define AIF1_AD0L_AIF2_DACL_MXR 14
#define AIF1_AD0L_ADCL_MXR 13
#define AIF1_AD0L_AIF2_DACR_MXR 12
#define AIF1_AD0R_AIF1_DA0R_MXR 11
#define AIF1_AD0R_AIF2_DACR_MXR 10
#define AIF1_AD0R_ADCR_MXR 9
#define AIF1_AD0R_AIF2_DACL_MXR 8
#define AIF1_AD1L_AIF2_DACL_MXR 7
#define AIF1_AD1L_ADCL_MXR 6
#define AIF1_AD1L_MXR_SRC 6
#define AIF1_AD1R_AIF2_DACR_MXR 3
#define AIF1_AD1R_ADCR_MXR 2
#define AIF1_AD1R_MXR_SRC 2
/*AIF1_VOL_CTRL1*/
#define AIF1_AD0L_VOL 8
#define AIF1_AD0R_VOL 0
/*AIF1_VOL_CTRL2*/
#define AIF1_AD1L_VOL 8
#define AIF1_AD1R_VOL 0
/*AIF1_VOL_CTRL3*/
#define AIF1_DA0L_VOL 8
#define AIF1_DA0R_VOL 0
/*AIF1_VOL_CTRL4*/
#define AIF1_DA1L_VOL 8
#define AIF1_DA1R_VOL 0
/*AIF1_MXR_GAIN*/
#define AIF1_AD0L_MXR_GAIN 12
#define AIF1_AD0R_MXR_GAIN 8
#define AIF1_AD1L_MXR_GAIN 6
#define AIF1_AD1R_MXR_GAIN 2
/*AIF1_RXD_CTRL*/
#define AIF1_N_DATA_DISCARD 8
/*ADC_DIG_CTRL*/
#define ENAD 15
#define ENDM 14
#define ADFIR32 13
#define ADOUT_DTS 2
#define ADOUT_DLY 1
/*ADC_VOL_CTRL*/
#define ADC_VOL_L 8
#define ADC_VOL_R 0
/*ADC_DBG_CTRL*/
#define ADSW 15
#define DMIC_CLK_PIN_CTRL 12
/*HMIC_CTRL1*/
#define HMIC_M 12
#define HMIC_N 8
#define HMIC_DATA_IRQ_MODE 7
#define HMIC_TH1_HYSTERESIS 5
#define HMIC_PULLOUT_IRQ 4
#define HMIC_PLUGIN_IRQ 3
#define HMIC_KEYUP_IRQ 2
#define HMIC_KEYDOWN_IRQ 1
#define HMIC_DATA_IRQ_EN 0
/*HMIC_CTRL2*/
#define HMIC_SAMPLE_SELECT 14
#define HMIC_TH2_HYSTERESIS 13
#define HMIC_TH2 8
#define HMIC_SF 6
#define KEYUP_CLEAR 5
#define HMIC_TH1 0
/*HMIC_STS*/
#define HMIC_DATA 8
#define GET_HMIC_DATA(r) (((r) >> HMIC_DATA) & 0x1F)
#define HMIC_PULLOUT_PEND 4
#define HMIC_PLUGIN_PEND 3
#define HMIC_KEYUP_PEND 2
#define HMKC_KEYDOWN_PEND 1
#define HMIC_DATA_PEND 0
#define HMIC_PEND_ALL (0x1F)
/*DAC_DIG_CTRL*/
#define ENDA 15
#define ENHPF 14
#define DAFIR32 13
#define MODQU 8
/*DAC_VOL_CTRL*/
#define DAC_VOL_L 8
#define DAC_VOL_R 0
/*DAC_DBG_CTRL*/
#define DASW 15
#define ENDWA_N 14
#define DAC_MOD_DBG 13
#define DAC_PTN_SEL 6
#define DVC 0
/*DAC_MXR_SRC*/
#define DACL_MXR_AIF1_DA0L 15
#define DACL_MXR_AIF1_DA1L 14
#define DACL_MXR_AIF2_DACL 13
#define DACL_MXR_ADCL 12
#define DACL_MXR_SRC 12
#define DACR_MXR_AIF1_DA0R 11
#define DACR_MXR_AIF1_DA1R 10
#define DACR_MXR_AIF2_DACR 9
#define DACR_MXR_ADCR 8
#define DACR_MXR_SRC 8
/*DAC_MXR_GAIN*/
#define DACL_MXR_GAIN 12
#define DACR_MXR_GAIN 8
/*ADC_APC_CTRL*/
#define ADCREN 15
#define ADCRG 12
#define ADCLEN 11
#define ADCLG 8
#define MBIASEN 7
#define MMIC_BIAS_CHOP_EN 6
#define MMIC_BIAS_CHOP_CKS 4
#define HBIASMOD 2
#define HBIASEN 1
#define HBIASADCEN 0
/*ADC_SRC*/
#define RADCMIXMUTEMIC1BOOST (13)
#define RADCMIXMUTEMIC2BOOST (12)
#define RADCMIXMUTELINEINLR (11)
#define RADCMIXMUTELINEINR (10)
#define RADCMIXMUTEAUXINR (9)
#define RADCMIXMUTEROUTPUT (8)
#define RADCMIXMUTELOUTPUT (7)
#define LADCMIXMUTEMIC1BOOST (6)
#define LADCMIXMUTEMIC2BOOST (5)
#define LADCMIXMUTELINEINLR (4)
#define LADCMIXMUTELINEINL (3)
#define LADCMIXMUTEAUXINL (2)
#define LADCMIXMUTELOUTPUT (1)
#define LADCMIXMUTEROUTPUT (0)
/*ADC_SRCBST_CTRL*/
#define MIC1AMPEN 15
#define ADC_MIC1G 12
#define MIC2AMPEN 11
#define ADC_MIC2G 8
#define MIC2SLT 7
#define LINEIN_PREG 4
#define AUXI_PREG 0
/*OMIXER_DACA_CTRL*/
#define DACAREN 15
#define DACALEN 14
#define RMIXEN 13
#define LMIXEN 12
#define HPOUTPUTENABLE 8
/*OMIXER_SR*/
#define RMIXMUTEMIC1BOOST (13)
#define RMIXMUTEMIC2BOOST (12)
#define RMIXMUTELINEINLR (11)
#define RMIXMUTELINEINR (10)
#define RMIXMUTEAUXINR (9)
#define RMIXMUTEDACR (8)
#define RMIXMUTEDACL (7)
#define LMIXMUTEMIC1BOOST (6)
#define LMIXMUTEMIC2BOOST (5)
#define LMIXMUTELINEINLR (4)
#define LMIXMUTELINEINL (3)
#define LMIXMUTEAUXINL (2)
#define LMIXMUTEDACL (1)
#define LMIXMUTEDACR (0)
/*OMIXER_BST1_CTRL*/
#define BIASVOLTAGE 12
#define AXG 9
#define OMIXER_MIC1G 6
#define OMIXER_MIC2G 3
#define LINEING 0
/*HPOUT_CTRL*/
#define RHPS 15
#define LHPS 14
#define RHPPA_MUTE 13
#define LHPPA_MUTE 12
#define HPPA_EN 11
#define HP_VOL 4
#define HPPA_DEL 2
#define HPPA_IS 0
/*ESPKOUT_CTRL*/
#define EAR_RAMP_TIME 11
#define ESPA_OUT_CURRENT 9
#define ESPSR 7
#define ESPPA_MUTE 6
#define ESPPA_EN 5
#define ESP_VOL 0
/*SPKOUT_CTRL*/
#define HPCALICKS 13
#define RSPKS 12
#define RSPKINVEN 11
#define RSPK_EN 9
#define LSPKS 8
#define LSPKINVEN 7
#define LSPK_EN 5
#define SPK_VOL 0
/*LOUT_CTRL*/
#define LINEOUTG 5
#define LINEOUTEN 4
#define LINEOUTS0 3
#define LINEOUTS1 2
#define LINEOUTS2 1
#define LINEOUTS3 0
/*ADDA_TUNE1*/
#define CURRENT_TEST_SELECT 14
#define BIHE_CTRL 12
#define DITHER 11
#define DITHER_CLK 9
#define ZERO_CROSSOVER_EN 8
#define ZERO_CROSSOVER_TIME 7
#define EAR_SPEED_SELECT 6
#define REF_CHOPPEN_CKS 4
#define OPMIC_BIAS_CUR 0
/*ADDA_TUNE2*/
#define OPDAC_BIAS_CUR 14
#define OPDRV_BIAS_CUR 12
#define OPMIX_BIAS_CUR 10
#define OPEAR_BIAS_CUR 8
#define OPVR_BIAS_CUR 6
#define OPAAF_BIAS_CUR 4
#define OPADC1_BIAS_CUR 2
#define OPADC2_BIAS_CUR 0
/*ADDA_TUNE3*/
#define LDOEN 15
#define LDO_SEL 12
#define BIASCALIVERIFY 11
#define BIASMODE 10
#define BIASCALIDATA 9
#define OSCS 1
#define OSCEN 0
/*HPOUT_STR*/
#define HPVL_SOFT_MOD 14
#define HPVL_STEP_CTRL 8
#define DACA_CHND_ENA 7
#define HPPA_MXRD_ENA 6
#define HPVL_CTRL_OUT 0
#endif//__AC101_REGS_H__

1579
ac108.c

File diff suppressed because it is too large Load diff

367
ac108_6mic.state Normal file
View file

@ -0,0 +1,367 @@
state.ALSA {
control.1 {
iface MIXER
name 'PCM Playback Volume'
value 400
comment {
access 'read write'
type INTEGER
count 1
range '-10239 - 400'
dbmin -9999999
dbmax 400
dbvalue.0 400
}
}
control.2 {
iface MIXER
name 'PCM Playback Switch'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.3 {
iface MIXER
name 'PCM Playback Route'
value 1
comment {
access 'read write'
type INTEGER
count 1
range '0 - 2'
}
}
control.4 {
iface PCM
name 'IEC958 Playback Default'
value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
comment {
access 'read write'
type IEC958
count 1
}
}
control.5 {
iface PCM
name 'IEC958 Playback Con Mask'
value '0200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
comment {
access read
type IEC958
count 1
}
}
control.6 {
iface PCM
name 'IEC958 Playback PCM Stream'
value '0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
comment {
access 'read write inactive'
type IEC958
count 1
}
}
}
state.seeed8micvoicec {
control.1 {
iface MIXER
name 'CH1 digital volume'
value 208
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 3675
}
}
control.2 {
iface MIXER
name 'CH2 digital volume'
value 208
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 3675
}
}
control.3 {
iface MIXER
name 'CH3 digital volume'
value 208
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 3675
}
}
control.4 {
iface MIXER
name 'CH4 digital volume'
value 208
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 3675
}
}
control.5 {
iface MIXER
name 'ADC1 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.6 {
iface MIXER
name 'ADC2 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.7 {
iface MIXER
name 'ADC3 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.8 {
iface MIXER
name 'ADC4 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.9 {
iface MIXER
name 'CH5 digital volume'
value 208
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 3675
}
}
control.10 {
iface MIXER
name 'CH6 digital volume'
value 208
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 3675
}
}
control.11 {
iface MIXER
name 'CH7 digital volume'
value 198
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 2925
}
}
control.12 {
iface MIXER
name 'CH8 digital volume'
value 198
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 2925
}
}
control.13 {
iface MIXER
name 'ADC5 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.14 {
iface MIXER
name 'ADC6 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.15 {
iface MIXER
name 'ADC7 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.16 {
iface MIXER
name 'ADC8 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.17 {
iface MIXER
name 'DAC volume'
value.0 0
value.1 0
comment {
access 'read write'
type INTEGER
count 2
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 -11925
dbvalue.1 -11925
}
}
control.18 {
iface MIXER
name 'DAC mixer gain'
value.0 0
value.1 0
comment {
access 'read write'
type INTEGER
count 2
range '0 - 15'
dbmin -600
dbmax 8400
dbvalue.0 -600
dbvalue.1 -600
}
}
control.19 {
iface MIXER
name 'digital volume'
value 51
comment {
access 'read write'
type INTEGER
count 1
range '0 - 63'
dbmin -7308
dbmax 0
dbvalue.0 -1392
}
}
control.20 {
iface MIXER
name 'Speaker Playback Volume'
value 25
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin -4800
dbmax -150
dbvalue.0 -1050
}
}
control.21 {
iface MIXER
name 'Headphone Playback Volume'
value 52
comment {
access 'read write'
type INTEGER
count 1
range '0 - 63'
dbmin -6300
dbmax 0
dbvalue.0 -1100
}
}
}

View file

@ -68,202 +68,106 @@ state.ALSA {
state.seeed4micvoicec {
control.1 {
iface MIXER
name 'OUT1 Mute'
value false
name 'CH1 digital volume'
value 222
comment {
access 'read write'
type BOOLEAN
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 4725
}
}
control.2 {
iface MIXER
name 'OUT2 Mute'
value true
name 'CH2 digital volume'
value 222
comment {
access 'read write'
type BOOLEAN
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 4725
}
}
control.3 {
iface MIXER
name 'TX1 Channel1~8 enable'
value '1-4 channels '
name 'CH3 digital volume'
value 222
comment {
access 'read write'
type ENUMERATED
type INTEGER
count 1
item.0 'disable all'
item.1 '1-1 channels '
item.2 '1-2 channels '
item.3 '1-3 channels '
item.4 '1-4 channels '
item.5 '1-5 channels '
item.6 '1-6 channels '
item.7 '1-7 channels '
item.8 '1-8 channels '
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 4725
}
}
control.4 {
iface MIXER
name 'TX1 Channel9~16 enable'
value 'disable all'
name 'CH4 digital volume'
value 222
comment {
access 'read write'
type ENUMERATED
type INTEGER
count 1
item.0 'disable all'
item.1 '8-9 channels '
item.2 '8-10 channels '
item.3 '8-11 channels '
item.4 '8-12 channels '
item.5 '8-13 channels '
item.6 '8-14 channels '
item.7 '8-15 channels '
item.8 '8-16 channels '
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 4725
}
}
control.5 {
iface MIXER
name 'TX2 Channel1~8 enable'
value 'disable all'
name 'ADC1 PGA gain'
value 0
comment {
access 'read write'
type ENUMERATED
type INTEGER
count 1
item.0 'disable all'
item.1 '1-1 channels '
item.2 '1-2 channels '
item.3 '1-3 channels '
item.4 '1-4 channels '
item.5 '1-5 channels '
item.6 '1-6 channels '
item.7 '1-7 channels '
item.8 '1-8 channels '
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.6 {
iface MIXER
name 'TX2 Channel9~16 enable'
value 'disable all'
name 'ADC2 PGA gain'
value 0
comment {
access 'read write'
type ENUMERATED
type INTEGER
count 1
item.0 'disable all'
item.1 '8-9 channels '
item.2 '8-10 channels '
item.3 '8-11 channels '
item.4 '8-12 channels '
item.5 '8-13 channels '
item.6 '8-14 channels '
item.7 '8-15 channels '
item.8 '8-16 channels '
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.7 {
iface MIXER
name 'CH1 digital volume'
value 181
name 'ADC3 PGA gain'
value 0
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 1650
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 0
}
}
control.8 {
iface MIXER
name 'CH2 digital volume'
value 181
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 1650
}
}
control.9 {
iface MIXER
name 'CH3 digital volume'
value 181
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 1650
}
}
control.10 {
iface MIXER
name 'CH4 digital volume'
value 181
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 1650
}
}
control.11 {
iface MIXER
name 'ADC1 PGA gain'
value 27
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 2700
}
}
control.12 {
iface MIXER
name 'ADC2 PGA gain'
value 27
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 2700
}
}
control.13 {
iface MIXER
name 'ADC3 PGA gain'
value 27
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 2700
}
}
control.14 {
iface MIXER
name 'ADC4 PGA gain'
value 27
value 0
comment {
access 'read write'
type INTEGER
@ -271,683 +175,7 @@ state.seeed4micvoicec {
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 2700
}
}
control.15 {
iface MIXER
name 'Tx1 Channels'
value '4 channels '
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1 channels '
item.1 '2 channels '
item.2 '3 channels '
item.3 '4 channels '
item.4 '5 channels '
item.5 '6 channels '
item.6 '7 channels '
item.7 '8 channels '
item.8 '9 channels '
item.9 '10 channels '
item.10 '11 channels '
item.11 '12 channels '
item.12 '13 channels '
item.13 '14 channels '
item.14 '15 channels '
item.15 '16 channels '
}
}
control.16 {
iface MIXER
name 'Tx2 Channels'
value '1 channels '
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1 channels '
item.1 '2 channels '
item.2 '3 channels '
item.3 '4 channels '
item.4 '5 channels '
item.5 '6 channels '
item.6 '7 channels '
item.7 '8 channels '
item.8 '9 channels '
item.9 '10 channels '
item.10 '11 channels '
item.11 '12 channels '
item.12 '13 channels '
item.13 '14 channels '
item.14 '15 channels '
item.15 '16 channels '
}
}
control.17 {
iface MIXER
name 'Tx1 Channels 1 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.18 {
iface MIXER
name 'Tx1 Channels 2 MAP'
value '2st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.19 {
iface MIXER
name 'Tx1 Channels 3 MAP'
value '3st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.20 {
iface MIXER
name 'Tx1 Channels 4 MAP'
value '4st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.21 {
iface MIXER
name 'Tx1 Channels 5 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.22 {
iface MIXER
name 'Tx1 Channels 6 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.23 {
iface MIXER
name 'Tx1 Channels 7 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.24 {
iface MIXER
name 'Tx1 Channels 8 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.25 {
iface MIXER
name 'Tx1 Channels 9 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.26 {
iface MIXER
name 'Tx1 Channels 10 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.27 {
iface MIXER
name 'Tx1 Channels 11 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.28 {
iface MIXER
name 'Tx1 Channels 12 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.29 {
iface MIXER
name 'Tx1 Channels 13 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.30 {
iface MIXER
name 'Tx1 Channels 14 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.31 {
iface MIXER
name 'Tx1 Channels 15 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.32 {
iface MIXER
name 'Tx1 Channels 16 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.33 {
iface MIXER
name 'Tx2 Channels 1 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.34 {
iface MIXER
name 'Tx2 Channels 2 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.35 {
iface MIXER
name 'Tx2 Channels 3 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.36 {
iface MIXER
name 'Tx2 Channels 4 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.37 {
iface MIXER
name 'Tx2 Channels 5 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.38 {
iface MIXER
name 'Tx2 Channels 6 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.39 {
iface MIXER
name 'Tx2 Channels 7 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.40 {
iface MIXER
name 'Tx2 Channels 8 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.41 {
iface MIXER
name 'Tx2 Channels 9 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.42 {
iface MIXER
name 'Tx2 Channels 10 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.43 {
iface MIXER
name 'Tx2 Channels 11 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.44 {
iface MIXER
name 'Tx2 Channels 12 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.45 {
iface MIXER
name 'Tx2 Channels 13 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.46 {
iface MIXER
name 'Tx2 Channels 14 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.47 {
iface MIXER
name 'Tx2 Channels 15 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.48 {
iface MIXER
name 'Tx2 Channels 16 MAP'
value '1st adc sample'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 '1st adc sample'
item.1 '2st adc sample'
item.2 '3st adc sample'
item.3 '4st adc sample'
}
}
control.49 {
iface MIXER
name 'ADC4 Source'
value 'Analog ADC4'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'Analog ADC1'
item.1 'Analog ADC2'
item.2 'Analog ADC3'
item.3 'Analog ADC4'
}
}
control.50 {
iface MIXER
name 'ADC3 Source'
value 'Analog ADC3'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'Analog ADC1'
item.1 'Analog ADC2'
item.2 'Analog ADC3'
item.3 'Analog ADC4'
}
}
control.51 {
iface MIXER
name 'ADC2 Source'
value 'Analog ADC2'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'Analog ADC1'
item.1 'Analog ADC2'
item.2 'Analog ADC3'
item.3 'Analog ADC4'
}
}
control.52 {
iface MIXER
name 'ADC1 Source'
value 'Analog ADC1'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'Analog ADC1'
item.1 'Analog ADC2'
item.2 'Analog ADC3'
item.3 'Analog ADC4'
}
}
control.53 {
iface MIXER
name 'ADC1 Digital Mixer gc'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.54 {
iface MIXER
name 'ADC1 Digital Mixer src'
value 'ADC1 data'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.55 {
iface MIXER
name 'ADC2 Digital Mixer gc'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.56 {
iface MIXER
name 'ADC2 Digital Mixer src'
value 'ADC2 data'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.57 {
iface MIXER
name 'ADC3 Digital Mixer gc'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.58 {
iface MIXER
name 'ADC3 Digital Mixer src'
value 'ADC3 data'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.59 {
iface MIXER
name 'ADC4 Digital Mixer gc'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
}
}
control.60 {
iface MIXER
name 'ADC4 Digital Mixer src'
value 'ADC4 data'
comment {
access 'read write'
type ENUMERATED
count 1
item.0 'disable all'
item.1 'ADC1 data'
item.2 'ADC2 data'
item.3 'ADC3 data'
item.4 'ADC4 data'
dbvalue.0 0
}
}
}

126
ac10x.h Normal file
View file

@ -0,0 +1,126 @@
/*
* ac10x.h
*
* (C) Copyright 2017-2018
* Seeed Technology Co., Ltd. <www.seeedstudio.com>
*
* PeterYang <linsheng.yang@seeed.cc>
*
* (C) Copyright 2010-2017
* Reuuimlla Technology Co., Ltd. <www.reuuimllatech.com>
* huangxin <huangxin@reuuimllatech.com>
*
* some simple description for this code
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
*/
#ifndef __AC10X_H__
#define __AC10X_H__
#define AC101_I2C_ID 4
#define _MASTER_AC108 0
#define _MASTER_AC101 1
#define _MASTER_MULTI_CODEC _MASTER_AC101
/* enable headset detecting & headset button pressing */
#define CONFIG_AC101_SWITCH_DETECT
/* obsolete */
#define CONFIG_AC10X_TRIG_LOCK 0
#ifdef AC101_DEBG
#define AC101_DBG(format,args...) printk("[AC101] %s() L%d " format, __func__, __LINE__, ##args)
#else
#define AC101_DBG(...)
#endif
#include "sound-compatible-4.18.h"
#ifdef CONFIG_AC101_SWITCH_DETECT
enum headphone_mode_u {
HEADPHONE_IDLE,
FOUR_HEADPHONE_PLUGIN,
THREE_HEADPHONE_PLUGIN,
};
#endif
struct ac10x_priv {
struct i2c_client *i2c[4];
struct regmap* i2cmap[4];
int codec_cnt;
unsigned sysclk;
#define _FREQ_24_576K 24576000
#define _FREQ_22_579K 22579200
unsigned mclk; /* master clock or aif_clock/aclk */
int clk_id;
unsigned char i2s_mode;
unsigned char data_protocol;
struct delayed_work dlywork;
int tdm_chips_cnt;
int sysclk_en;
/* member for ac101 .begin */
struct snd_soc_codec *codec;
struct i2c_client *i2c101;
struct regmap* regmap101;
struct mutex dac_mutex;
u8 dac_enable;
spinlock_t lock;
u8 aif1_clken;
struct work_struct codec_resume;
struct gpio_desc* gpiod_spk_amp_gate;
#ifdef CONFIG_AC101_SWITCH_DETECT
struct gpio_desc* gpiod_irq;
long irq;
volatile int irq_cntr;
volatile int pullout_cntr;
volatile int state;
enum headphone_mode_u mode;
struct work_struct work_switch;
struct work_struct work_clear_irq;
struct input_dev* inpdev;
#endif
/* member for ac101 .end */
};
/* AC101 DAI operations */
int ac101_audio_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai);
void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *codec_dai);
int ac101_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt);
int ac101_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *codec_dai);
int ac101_trigger(struct snd_pcm_substream *substream, int cmd,
struct snd_soc_dai *dai);
int ac101_aif_mute(struct snd_soc_dai *codec_dai, int mute);
/* codec driver specific */
int ac101_codec_probe(struct snd_soc_codec *codec);
int ac101_codec_remove(struct snd_soc_codec *codec);
int ac101_codec_suspend(struct snd_soc_codec *codec);
int ac101_codec_resume(struct snd_soc_codec *codec);
int ac101_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level);
/* i2c device specific */
int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id);
void ac101_shutdown(struct i2c_client *i2c);
int ac101_remove(struct i2c_client *i2c);
/* seeed voice card export */
int seeed_voice_card_register_set_clock(int stream, int (*set_clock)(int, struct snd_pcm_substream *, int, struct snd_soc_dai *));
int ac10x_fill_regcache(struct device* dev, struct regmap* map);
#endif//__AC10X_H__

View file

@ -1,11 +1,15 @@
# The IPC key of dmix or dsnoop plugin must be unique
# If 555555 or 666666 is used by other processes, use another one
# pcm.!default {
# type asym
# playback.pcm "playback"
# capture.pcm "capture"
# }
# use samplerate to resample as speexdsp resample is bad
defaults.pcm.rate_converter "samplerate"
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "capture"
}
pcm.playback {
type plug
@ -19,21 +23,16 @@ pcm.capture {
pcm.dmixed {
type dmix
slave.pcm "hw:0,0"
slave.pcm "hw:seeed2micvoicec"
ipc_key 555555
}
pcm.array {
type dsnoop
slave {
pcm "hw:0,0"
pcm "hw:seeed2micvoicec"
channels 2
}
ipc_key 666666
}
pcm.ac108 {
type ac108
slavepcm "hw:1,0"
channels 4
}

33
asound_4mic.conf Normal file
View file

@ -0,0 +1,33 @@
# The IPC key of dmix or dsnoop plugin must be unique
# If 555555 or 666666 is used by other processes, use another one
# use samplerate to resample as speexdsp resample is bad
defaults.pcm.rate_converter "samplerate"
pcm.!default {
type asym
playback.pcm "playback"
capture.pcm "ac108"
}
pcm.playback {
type plug
slave.pcm "hw:ALSA"
}
# pcm.dmixed {
# type dmix
# slave.pcm "hw:0,0"
# ipc_key 555555
# }
pcm.ac108 {
type plug
slave.pcm "hw:seeed4micvoicec"
}
# pcm.multiapps {
# type dsnoop
# ac108-slavepcm "hw:1,0"
# ipc_key 666666
# }

90
asound_6mic.conf Normal file
View file

@ -0,0 +1,90 @@
# The IPC key of dmix or dsnoop plugin must be unique
# If 555555 or 666666 is used by other processes, use another one
# use samplerate to resample as speexdsp resample is broken
defaults.pcm.rate_converter "samplerate"
pcm.!default {
type asym
playback.pcm "dmixer"
capture.pcm "ac108"
}
pcm.ac108 {
type plug
slave {
rate 48000
format S32_LE
pcm "hw:seeed8micvoicec"
}
}
# pcm.multiapps {
# type plug
# slave.pcm {
# type dsnoop
# slave {
# rate 48000
# format S32_LE
# pcm "hw:seeed8micvoicec"
# }
# ipc_key 666666
# }
# }
pcm.dmixer {
type plug
slave {
pcm {
type dmix
ipc_key 555555
slave {
pcm "hw:seeed8micvoicec"
format S32_LE
channels 8
}
bindings {
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
}
}
channels 8
format S32_LE
rate 48000
}
ttable.0.0 1
ttable.1.1 1
ttable.0.2 1
ttable.1.3 1
ttable.0.4 1
ttable.1.5 1
ttable.0.6 1
ttable.1.7 1
}
pcm.ac101 {
type plug
slave {
pcm "hw:seeed8micvoicec"
channels 8
format S32_LE
rate 48000
}
ttable.0.0 1
ttable.1.1 1
ttable.0.2 1
ttable.1.3 1
ttable.0.4 1
ttable.1.5 1
ttable.0.6 1
ttable.1.7 1
}

View file

@ -1,7 +1,10 @@
#!/bin/sh
#dtoverlay -r seeed-2mic-voicecard
DTC_FLAGS="-b 0 -Wno-unit_address_vs_reg -I dts -O dtb"
dtc -@ -I dts -O dtb -o seeed-2mic-voicecard.dtbo seeed-2mic-voicecard-overlay.dts
dtc -@ -I dts -O dtb -o seeed-4mic-voicecard.dtbo seeed-4mic-voicecard-overlay.dts
dtc -@ $DTC_FLAGS -o seeed-2mic-voicecard.dtbo seeed-2mic-voicecard-overlay.dts
dtc -@ $DTC_FLAGS -o seeed-4mic-voicecard.dtbo seeed-4mic-voicecard-overlay.dts
dtc -@ $DTC_FLAGS -o seeed-8mic-voicecard.dtbo seeed-8mic-voicecard-overlay.dts
# cp *.dtbo /boot/overlays
# dtoverlay seeed-2mic-voicecard

View file

@ -1,7 +1,15 @@
PACKAGE_NAME="seeed-voicecard"
PACKAGE_VERSION="0.2"
PACKAGE_VERSION="0.3"
BUILT_MODULE_NAME[0]="snd-soc-wm8960"
BUILT_MODULE_NAME[1]="snd-soc-ac108"
BUILT_MODULE_NAME[2]="snd-soc-seeed-voicecard"
DEST_MODULE_LOCATION[0]="/kernel/sound/soc/codecs"
DEST_MODULE_LOCATION[1]="/kernel/sound/soc/codecs"
DEST_MODULE_LOCATION[2]="/kernel/sound/soc/bcm"
PATCH[0]="back-to-v4.19.diff"
PATCH[1]="back-to-v5.4.diff"
PATCH[2]="back-to-v5.8.diff"
PATCH_MATCH[0]="^4\.19\.*"
PATCH_MATCH[1]="^5\.4\.*"
PATCH_MATCH[2]="^5\.8\.*"
AUTOINSTALL="yes"

View file

@ -5,34 +5,134 @@ if [[ $EUID -ne 0 ]]; then
exit 1
fi
is_Raspberry=$(cat /proc/device-tree/model | awk '{print $1}')
if [ "x${is_Raspberry}" != "xRaspberry" ] ; then
echo "Sorry, this drivers only works on raspberry pi"
# Check for enough space on /boot volume
boot_line=$(df -h | grep /boot | head -n 1)
if [ "x${boot_line}" = "x" ]; then
echo "Warning: /boot volume not found .."
else
boot_space=$(echo $boot_line | awk '{print $4;}')
free_space=$(echo "${boot_space%?}")
unit="${boot_space: -1}"
if [[ "$unit" = "K" ]]; then
echo "Error: Not enough space left ($boot_space) on /boot"
exit 1
elif [[ "$unit" = "M" ]]; then
if [ "$free_space" -lt "25" ]; then
echo "Error: Not enough space left ($boot_space) on /boot"
exit 1
fi
fi
fi
#
# make sure that we are on something ARM/Raspberry related
# either a bare metal Raspberry or a qemu session with
# Raspberry stuff available
# - check for /boot/overlays
# - dtparam and dtoverlay is available
errorFound=0
OVERLAYS=/boot/overlays
[ -d /boot/firmware/overlays ] && OVERLAYS=/boot/firmware/overlays
if [ ! -d $OVERLAYS ] ; then
echo "$OVERLAYS not found or not a directory" 1>&2
errorFound=1
fi
# should we also check for alsactl and amixer used in seeed-voicecard?
PATH=$PATH:/opt/vc/bin
for cmd in dtparam dtoverlay ; do
if ! which $cmd &>/dev/null ; then
echo "$cmd not found" 1>&2
echo "You may need to run ./ubuntu-prerequisite.sh"
errorFound=1
fi
done
if [ $errorFound = 1 ] ; then
echo "Errors found, exiting." 1>&2
exit 1
fi
ver="0.2"
card=$1
if [ "x${card}" = "x" ] ; then
echo "Usage: ./install 2mic|4mic"
exit 1
fi
ver="0.3"
uname_r=$(uname -r)
# we create a dir with this version to ensure that 'dkms remove' won't delete
# the sources during kernel updates
marker="0.0.0"
apt update
apt-get -y install raspberrypi-kernel-headers raspberrypi-kernel
apt-get -y install dkms
_VER_RUN=
function get_kernel_version() {
local ZIMAGE IMG_OFFSET
_VER_RUN=""
[ -z "$_VER_RUN" ] && {
ZIMAGE=/boot/kernel.img
[ -f /boot/firmware/vmlinuz ] && ZIMAGE=/boot/firmware/vmlinuz
# 64-bit-only kernel package
[ ! -f /boot/kernel.img ] && [ -f /boot/kernel8.img ] && ZIMAGE=/boot/kernel8.img
IMG_OFFSET=$(LC_ALL=C grep -abo $'\x1f\x8b\x08\x00' $ZIMAGE | head -n 1 | cut -d ':' -f 1)
_VER_RUN=$(dd if=$ZIMAGE obs=64K ibs=4 skip=$(( IMG_OFFSET / 4)) 2>/dev/null | zcat | grep -a -m1 "Linux version" | LC_ALL=C sed -e 's/^.*Linux/Linux/' | strings | awk '{ print $3; }')
}
echo "$_VER_RUN"
return 0
}
function check_kernel_headers() {
VER_RUN=$(get_kernel_version)
VER_HDR=$(dpkg -L raspberrypi-kernel-headers | egrep -m1 "/lib/modules/[^\/]+/build" | awk -F'/' '{ print $4; }')
[ "X$VER_RUN" == "X$VER_HDR" ] && {
return 0
}
VER_HDR=$(dpkg -L linux-headers-$VER_RUN | egrep -m1 "/lib/modules/[^\/]+/build" | awk -F'/' '{ print $4; }')
[ "X$VER_RUN" == "X$VER_HDR" ] && {
return 0
}
# echo RUN=$VER_RUN HDR=$VER_HDR
echo " !!! Your kernel version is $VER_RUN"
echo " Not found *** corresponding *** kernel headers with apt-get."
echo " This may occur if you have ran 'rpi-update'."
echo " Choose *** y *** will revert the kernel to version $VER_HDR then continue."
echo " Choose *** N *** will exit without this driver support, by default."
read -p "Would you like to proceed? (y/N)" -n 1 -r -s
echo
if ! [[ $REPLY =~ ^[Yy]$ ]]; then
exit 1;
fi
apt-get -y --reinstall install raspberrypi-kernel
}
# update and install required packages
which apt &>/dev/null
if [[ $? -eq 0 ]]; then
apt update -y
# Raspbian kernel packages
apt-get -y install raspberrypi-kernel-headers raspberrypi-kernel
# Recent Raspbian has 64-bit kernel on 32-bit userspace
apt-get -y install gcc-aarch64-linux-gnu
# Ubuntu kernel packages
apt-get -y install linux-raspi linux-headers-raspi linux-image-raspi
apt-get -y install dkms git i2c-tools libasound2-plugins
# rpi-update checker
check_kernel_headers
fi
# Arch Linux
which pacman &>/dev/null
if [[ $? -eq 0 ]]; then
pacman -Syu --needed git gcc automake make dkms linux-raspberrypi-headers i2c-tools
fi
# locate currently installed kernels (may be different to running kernel if
# it's just been updated)
kernels=$(ls /lib/modules | sed "s/^/-k /")
uname_r=$(uname -r)
base_ver=$(get_kernel_version)
base_ver=${base_ver%%[-+]*}
#kernels="${base_ver}+ ${base_ver}-v7+ ${base_ver}-v7l+"
kernels=$(uname -r)
function install_module {
local _i
src=$1
mod=$2
@ -41,67 +141,81 @@ function install_module {
fi
if [[ -e /usr/src/$mod-$ver || -e /var/lib/dkms/$mod/$ver ]]; then
dkms remove -m $mod -v $ver --all
dkms remove --force -m $mod -v $ver --all
rm -rf /usr/src/$mod-$ver
fi
mkdir -p /usr/src/$mod-$ver
cp -a $src/* /usr/src/$mod-$ver/
dkms add -m $mod -v $ver
dkms build $kernels -m $mod -v $ver && dkms install $kernels -m $mod -v $ver
for _i in $kernels; do
dkms build -k $_i -m $mod -v $ver && {
dkms install --force -k $_i -m $mod -v $ver
}
done
mkdir -p /var/lib/dkms/$mod/$ver/$marker
}
if [ ! -f "/boot/overlays/seeed-4mic-voicecard.dtbo" ] && [ ! -f "/lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-ac108.ko" ] ; then
install_module "./" "seeed-voicecard"
cp seeed-2mic-voicecard.dtbo /boot/overlays
cp seeed-4mic-voicecard.dtbo /boot/overlays
cp ac108_plugin/libasound_module_pcm_ac108.so /usr/lib/arm-linux-gnueabihf/alsa-lib/
cp asound.conf /etc/
else
echo "card driver already installed"
fi
grep -q "snd-soc-ac108" /etc/modules || \
install_module "./" "seeed-voicecard"
# install dtbos
cp seeed-2mic-voicecard.dtbo $OVERLAYS
cp seeed-4mic-voicecard.dtbo $OVERLAYS
cp seeed-8mic-voicecard.dtbo $OVERLAYS
#install alsa plugins
# no need this plugin now
# install -D ac108_plugin/libasound_module_pcm_ac108.so /usr/lib/arm-linux-gnueabihf/alsa-lib/
rm -f /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_ac108.so
#set kernel modules
grep -q "^snd-soc-seeed-voicecard$" /etc/modules || \
echo "snd-soc-seeed-voicecard" >> /etc/modules
grep -q "^snd-soc-ac108$" /etc/modules || \
echo "snd-soc-ac108" >> /etc/modules
grep -q "snd-soc-wm8960" /etc/modules || \
echo "snd-soc-wm8960" >> /etc/modules
grep -q "^snd-soc-wm8960$" /etc/modules || \
echo "snd-soc-wm8960" >> /etc/modules
#set dtoverlays
CONFIG=/boot/config.txt
[ -f /boot/firmware/config.txt ] && CONFIG=/boot/firmware/config.txt
[ -f /boot/firmware/usercfg.txt ] && CONFIG=/boot/firmware/usercfg.txt
sed -i -e 's:#dtparam=i2c_arm=on:dtparam=i2c_arm=on:g' $CONFIG || true
grep -q "^dtoverlay=i2s-mmap$" $CONFIG || \
echo "dtoverlay=i2s-mmap" >> $CONFIG
grep -q "dtoverlay=i2s-mmap" /boot/config.txt || \
echo "dtoverlay=i2s-mmap" >> /boot/config.txt
grep -q "^dtparam=i2s=on$" $CONFIG || \
echo "dtparam=i2s=on" >> $CONFIG
#install config files
mkdir /etc/voicecard || true
cp *.conf /etc/voicecard
cp *.state /etc/voicecard
grep -q "dtparam=i2s=on" /boot/config.txt || \
echo "dtparam=i2s=on" >> /boot/config.txt
#create git repo
git_email=$(git config --global --get user.email)
git_name=$(git config --global --get user.name)
if [ "x${git_email}" == "x" ] || [ "x${git_name}" == "x" ] ; then
echo "setup git config"
git config --global user.email "respeaker@seeed.cc"
git config --global user.name "respeaker"
fi
echo "git init"
git --git-dir=/etc/voicecard/.git init
echo "git add --all"
git --git-dir=/etc/voicecard/.git --work-tree=/etc/voicecard/ add --all
echo "git commit -m \"origin configures\""
git --git-dir=/etc/voicecard/.git --work-tree=/etc/voicecard/ commit -m "origin configures"
has_2mic=$(grep seeed-2mic-voicecard /boot/config.txt)
has_4mic=$(grep seeed-4mic-voicecard /boot/config.txt)
case "${card}" in
"2mic")
echo "cp wm8960_asound.state /var/lib/alsa/asound.state"
cp wm8960_asound.state /var/lib/alsa/asound.state
if [ "x${has_4mic}" != x ] ; then
echo "has 4mic before, now remove it"
sed -i "s/dtoverlay=seeed-4mic-voicecard//g" /boot/config.txt
fi
grep -q "dtoverlay=seeed-2mic-voicecard" /boot/config.txt || \
echo "dtoverlay=seeed-2mic-voicecard" >> /boot/config.txt
;;
"4mic")
echo "cp ac108_asound.state /var/lib/alsa/asound.state"
cp ac108_asound.state /var/lib/alsa/asound.state
if [ "x${has_2mic}" != x ] ; then
echo "has 2mic before, now remove it"
sed -i "s/dtoverlay=seeed-2mic-voicecard//g" /boot/config.txt
fi
grep -q "dtoverlay=seeed-4mic-voicecard" /boot/config.txt || \
echo "dtoverlay=seeed-4mic-voicecard" >> /boot/config.txt
;;
*)
echo "Please use 2mic or 4mic"
;;
esac
cp seeed-voicecard /usr/bin/
cp seeed-voicecard.service /lib/systemd/system/
systemctl enable seeed-voicecard.service
systemctl start seeed-voicecard
echo "------------------------------------------------------"
echo "Please reboot your raspberry pi to apply all settings"

454
patches/back-to-v4.19.diff Normal file
View file

@ -0,0 +1,454 @@
diff --git a/ac101.c b/ac101.c
index 23837a7..41c15f3 100644
--- a/ac101.c
+++ b/ac101.c
@@ -955,10 +955,10 @@ void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai
AC101_DBG("stream = %s, play: %d, capt: %d, active: %d\n",
snd_pcm_stream_str(substream),
- codec_dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], codec_dai->stream_active[SNDRV_PCM_STREAM_CAPTURE],
- snd_soc_dai_active(codec_dai));
+ codec_dai->playback_active, codec_dai->capture_active,
+ codec_dai->active);
- if (!snd_soc_dai_active(codec_dai)) {
+ if (!codec_dai->active) {
ac10x->aif1_clken = 1;
ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
} else {
@@ -1080,7 +1080,7 @@ int ac101_hw_params(struct snd_pcm_substream *substream,
freq_out = _FREQ_24_576K;
for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
- if (codec_dai->stream_active[SNDRV_PCM_STREAM_CAPTURE] && dmic_used && codec_aif1_fs[i].samp_rate == 44100) {
+ if (codec_dai->capture_active && dmic_used && codec_aif1_fs[i].samp_rate == 44100) {
ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x4<<AIF1_FS));
} else {
ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), ((codec_aif1_fs[i].srbit)<<AIF1_FS));
diff --git a/ac108.c b/ac108.c
index d5dd12d..0a8c462 100644
--- a/ac108.c
+++ b/ac108.c
@@ -653,7 +653,7 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
dev_dbg(dai->dev, "%s() stream=%s play:%d capt:%d +++\n", __func__,
snd_pcm_stream_str(substream),
- dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]);
+ dai->playback_active, dai->capture_active);
if (ac10x->i2c101) {
ret = ac101_hw_params(substream, params, dai);
@@ -664,8 +664,8 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
}
}
- if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE && dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK])
- || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai->stream_active[SNDRV_PCM_STREAM_CAPTURE])) {
+ if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE && dai->playback_active)
+ || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai->capture_active)) {
/* not configure hw_param twice */
/* return 0; */
}
@@ -810,9 +810,6 @@ static int ac108_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int fr
struct ac10x_priv *ac10x = snd_soc_dai_get_drvdata(dai);
- if (freq != 24000000 || clk_id != SYSCLK_SRC_PLL)
- dev_warn(dai->dev, "ac108_set_sysclk freq = %d clk = %d\n", freq, clk_id);
-
freq = 24000000;
clk_id = SYSCLK_SRC_PLL;
@@ -1124,7 +1121,7 @@ void ac108_aif_shutdown(struct snd_pcm_substream *substream,
}
}
-int ac108_aif_mute(struct snd_soc_dai *dai, int mute, int direction) {
+int ac108_aif_mute(struct snd_soc_dai *dai, int mute) {
struct snd_soc_codec *codec = dai->codec;
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
@@ -1145,13 +1142,12 @@ static const struct snd_soc_dai_ops ac108_dai_ops = {
.hw_params = ac108_hw_params,
.prepare = ac108_prepare,
.trigger = ac108_trigger,
- .mute_stream = ac108_aif_mute,
+ .digital_mute = ac108_aif_mute,
/*DAI format configuration*/
.set_fmt = ac108_set_fmt,
// .hw_free = ac108_hw_free,
- .no_capture_mute = 1,
};
static struct snd_soc_dai_driver ac108_dai0 = {
diff --git a/seeed-voicecard.c b/seeed-voicecard.c
index b90af93..af6db74 100644
--- a/seeed-voicecard.c
+++ b/seeed-voicecard.c
@@ -28,8 +28,6 @@
#include <sound/simple_card_utils.h>
#include "ac10x.h"
-#define LINUX_VERSION_IS_GEQ(x1,x2,x3) (LINUX_VERSION_CODE >= KERNEL_VERSION(x1,x2,x3))
-
/*
* single codec:
* 0 - allow multi codec
@@ -42,9 +40,6 @@ struct seeed_card_data {
struct seeed_dai_props {
struct asoc_simple_dai cpu_dai;
struct asoc_simple_dai codec_dai;
- struct snd_soc_dai_link_component cpus; /* single cpu */
- struct snd_soc_dai_link_component codecs; /* single codec */
- struct snd_soc_dai_link_component platforms;
unsigned int mclk_fs;
} *dai_props;
unsigned int mclk_fs;
@@ -97,16 +92,16 @@ static int seeed_voice_card_startup(struct snd_pcm_substream *substream)
if (ret)
clk_disable_unprepare(dai_props->cpu_dai.clk);
- if (asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min) {
- priv->channels_playback_default = asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min;
+ if (rtd->cpu_dai->driver->playback.channels_min) {
+ priv->channels_playback_default = rtd->cpu_dai->driver->playback.channels_min;
}
- if (asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min) {
- priv->channels_capture_default = asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min;
+ if (rtd->cpu_dai->driver->capture.channels_min) {
+ priv->channels_capture_default = rtd->cpu_dai->driver->capture.channels_min;
}
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min = priv->channels_playback_override;
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_max = priv->channels_playback_override;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min = priv->channels_capture_override;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_max = priv->channels_capture_override;
+ rtd->cpu_dai->driver->playback.channels_min = priv->channels_playback_override;
+ rtd->cpu_dai->driver->playback.channels_max = priv->channels_playback_override;
+ rtd->cpu_dai->driver->capture.channels_min = priv->channels_capture_override;
+ rtd->cpu_dai->driver->capture.channels_max = priv->channels_capture_override;
return ret;
}
@@ -118,10 +113,10 @@ static void seeed_voice_card_shutdown(struct snd_pcm_substream *substream)
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min = priv->channels_playback_default;
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_max = priv->channels_playback_default;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min = priv->channels_capture_default;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_max = priv->channels_capture_default;
+ rtd->cpu_dai->driver->playback.channels_min = priv->channels_playback_default;
+ rtd->cpu_dai->driver->playback.channels_max = priv->channels_playback_default;
+ rtd->cpu_dai->driver->capture.channels_min = priv->channels_capture_default;
+ rtd->cpu_dai->driver->capture.channels_max = priv->channels_capture_default;
clk_disable_unprepare(dai_props->cpu_dai.clk);
@@ -132,8 +127,8 @@ static int seeed_voice_card_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
@@ -197,7 +192,7 @@ static void work_cb_codec_clk(struct work_struct *work)
static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_dai *dai = rtd->codec_dai;
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
#if CONFIG_AC10X_TRIG_LOCK
unsigned long flags;
@@ -206,7 +201,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd,
- dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]);
+ dai->playback_active, dai->capture_active);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -228,7 +223,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/* capture channel resync, if overrun */
- if (dai->stream_active[SNDRV_PCM_STREAM_CAPTURE] && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (dai->capture_active && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
break;
}
@@ -248,7 +243,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d;finished %d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd,
- dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE], ret);
+ dai->playback_active, dai->capture_active, ret);
return ret;
}
@@ -387,8 +382,8 @@ static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd)
static int seeed_voice_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
- struct snd_soc_dai *codec = asoc_rtd_to_codec(rtd, 0);
- struct snd_soc_dai *cpu = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec = rtd->codec_dai;
+ struct snd_soc_dai *cpu = rtd->cpu_dai;
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
int ret;
@@ -453,19 +448,20 @@ static int seeed_voice_card_dai_link_of(struct device_node *node,
goto dai_link_of_err;
}
- ret = asoc_simple_parse_daifmt(dev, node, codec,
+ ret = asoc_simple_card_parse_daifmt(dev, node, codec,
prefix, &dai_link->dai_fmt);
if (ret < 0)
goto dai_link_of_err;
of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);
- ret = asoc_simple_parse_cpu(cpu, dai_link, &single_cpu);
+ ret = asoc_simple_card_parse_cpu(cpu, dai_link,
+ DAI, CELL, &single_cpu);
if (ret < 0)
goto dai_link_of_err;
#if _SINGLE_CODEC
- ret = asoc_simple_parse_codec(codec, dai_link);
+ ret = asoc_simple_card_parse_codec(codec, dai_link, DAI, CELL);
if (ret < 0)
goto dai_link_of_err;
#else
@@ -477,7 +473,7 @@ static int seeed_voice_card_dai_link_of(struct device_node *node,
dev_dbg(dev, "dai_link num_codecs = %d\n", dai_link->num_codecs);
#endif
- ret = asoc_simple_parse_platform(plat, dai_link);
+ ret = asoc_simple_card_parse_platform(plat, dai_link, DAI, CELL);
if (ret < 0)
goto dai_link_of_err;
@@ -502,7 +498,7 @@ static int seeed_voice_card_dai_link_of(struct device_node *node,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,10,0)
ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai);
#else
- ret = asoc_simple_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);
+ ret = asoc_simple_card_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);
#endif
if (ret < 0)
goto dai_link_of_err;
@@ -510,16 +506,16 @@ static int seeed_voice_card_dai_link_of(struct device_node *node,
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,10,0)
ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai);
#else
- ret = asoc_simple_parse_clk_codec(dev, codec, dai_link, codec_dai);
+ ret = asoc_simple_card_parse_clk_codec(dev, codec, dai_link, codec_dai);
#endif
if (ret < 0)
goto dai_link_of_err;
- ret = asoc_simple_set_dailink_name(dev, dai_link,
+ ret = asoc_simple_card_set_dailink_name(dev, dai_link,
"%s-%s",
- dai_link->cpus->dai_name,
+ dai_link->cpu_dai_name,
#if _SINGLE_CODEC
- dai_link->codecs->dai_name
+ dai_link->codec_dai_name
#else
dai_link->codecs[0].dai_name
#endif
@@ -533,19 +529,21 @@ static int seeed_voice_card_dai_link_of(struct device_node *node,
dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
dev_dbg(dev, "\tcpu : %s / %d\n",
- dai_link->cpus->dai_name,
+ dai_link->cpu_dai_name,
dai_props->cpu_dai.sysclk);
dev_dbg(dev, "\tcodec : %s / %d\n",
#if _SINGLE_CODEC
- dai_link->codecs->dai_name,
+ dai_link->codec_dai_name,
#else
dai_link->codecs[0].dai_name,
#endif
dai_props->codec_dai.sysclk);
- asoc_simple_canonicalize_cpu(dai_link, single_cpu);
+ asoc_simple_card_canonicalize_cpu(dai_link, single_cpu);
#if _SINGLE_CODEC
- asoc_simple_canonicalize_platform(dai_link);
+ ret = asoc_simple_card_canonicalize_dailink(dai_link);
+ if (ret < 0)
+ goto dai_link_of_err;
#endif
dai_link_of_err:
@@ -578,7 +576,7 @@ static int seeed_voice_card_parse_aux_devs(struct device_node *node,
aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
if (!aux_node)
return -EINVAL;
- priv->snd_card.aux_dev[i].dlc.of_node = aux_node;
+ priv->snd_card.aux_dev[i].codec_of_node = aux_node;
}
priv->snd_card.num_aux_devs = n;
@@ -638,7 +636,7 @@ static int seeed_voice_card_parse_of(struct device_node *node,
goto card_parse_end;
}
- ret = asoc_simple_parse_card_name(&priv->snd_card, PREFIX);
+ ret = asoc_simple_card_parse_card_name(&priv->snd_card, PREFIX);
if (ret < 0)
goto card_parse_end;
@@ -743,7 +741,7 @@ static int seeed_voice_card_probe(struct platform_device *pdev)
struct seeed_dai_props *dai_props;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
- int num, ret, i;
+ int num, ret;
/* Get the number of DAI links */
if (np && of_get_child_by_name(np, PREFIX "dai-link"))
@@ -761,25 +759,6 @@ static int seeed_voice_card_probe(struct platform_device *pdev)
if (!dai_props || !dai_link)
return -ENOMEM;
- /*
- * Use snd_soc_dai_link_component instead of legacy style
- * It is codec only. but cpu/platform will be supported in the future.
- * see
- * soc-core.c :: snd_soc_init_multicodec()
- *
- * "platform" might be removed
- * see
- * simple-card-utils.c :: asoc_simple_canonicalize_platform()
- */
- for (i = 0; i < num; i++) {
- dai_link[i].cpus = &dai_props[i].cpus;
- dai_link[i].num_cpus = 1;
- dai_link[i].codecs = &dai_props[i].codecs;
- dai_link[i].num_codecs = 1;
- dai_link[i].platforms = &dai_props[i].platforms;
- dai_link[i].num_platforms = 1;
- }
-
priv->dai_props = dai_props;
priv->dai_link = dai_link;
@@ -798,9 +777,6 @@ static int seeed_voice_card_probe(struct platform_device *pdev)
}
} else {
struct seeed_card_info *cinfo;
- struct snd_soc_dai_link_component *cpus;
- struct snd_soc_dai_link_component *codecs;
- struct snd_soc_dai_link_component *platform;
cinfo = dev->platform_data;
if (!cinfo) {
@@ -817,19 +793,13 @@ static int seeed_voice_card_probe(struct platform_device *pdev)
return -EINVAL;
}
- cpus = dai_link->cpus;
- cpus->dai_name = cinfo->cpu_dai.name;
-
- codecs = dai_link->codecs;
- codecs->name = cinfo->codec;
- codecs->dai_name = cinfo->codec_dai.name;
-
- platform = dai_link->platforms;
- platform->name = cinfo->platform;
-
priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name;
dai_link->name = cinfo->name;
dai_link->stream_name = cinfo->name;
+ dai_link->platform_name = cinfo->platform;
+ dai_link->codec_name = cinfo->codec;
+ dai_link->cpu_dai_name = cinfo->cpu_dai.name;
+ dai_link->codec_dai_name = cinfo->codec_dai.name;
dai_link->dai_fmt = cinfo->daifmt;
dai_link->init = seeed_voice_card_dai_init;
memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
@@ -853,7 +823,7 @@ static int seeed_voice_card_probe(struct platform_device *pdev)
return ret;
err:
- asoc_simple_clean_reference(&priv->snd_card);
+ asoc_simple_card_clean_reference(&priv->snd_card);
return ret;
}
@@ -865,7 +835,7 @@ static int seeed_voice_card_remove(struct platform_device *pdev)
if (cancel_work_sync(&priv->work_codec_clk) != 0) {
}
- return asoc_simple_clean_reference(card);
+ return asoc_simple_card_clean_reference(card);
}
static const struct of_device_id seeed_voice_of_match[] = {
diff --git a/sound-compatible-4.18.h b/sound-compatible-4.18.h
index 550b3a7..6c1a014 100644
--- a/sound-compatible-4.18.h
+++ b/sound-compatible-4.18.h
@@ -16,6 +16,10 @@
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
+#ifndef __has_attribute
+# define __has_attribute(x) __GCC4_has_attribute_##x
+# define __GCC4_has_attribute___fallthrough__ 0
+#endif
#if __has_attribute(__fallthrough__)
# define fallthrough __attribute__((__fallthrough__))
#else
@@ -31,11 +35,7 @@
#define snd_soc_codec_get_dapm snd_soc_component_get_dapm
#define snd_soc_codec_get_bias_level snd_soc_component_get_bias_level
#define snd_soc_kcontrol_codec snd_soc_kcontrol_component
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)
-#define snd_soc_read snd_soc_component_read
-#else
#define snd_soc_read snd_soc_component_read32
-#endif
#define snd_soc_register_codec devm_snd_soc_register_component
#define snd_soc_unregister_codec snd_soc_unregister_component
#define snd_soc_update_bits snd_soc_component_update_bits
diff --git a/wm8960.c b/wm8960.c
index 465c6dc..34d4dad 100644
--- a/wm8960.c
+++ b/wm8960.c
@@ -796,7 +796,7 @@ static int wm8960_hw_free(struct snd_pcm_substream *substream,
return 0;
}
-static int wm8960_mute(struct snd_soc_dai *dai, int mute, int direction)
+static int wm8960_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
@@ -1236,12 +1236,11 @@ static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
static const struct snd_soc_dai_ops wm8960_dai_ops = {
.hw_params = wm8960_hw_params,
.hw_free = wm8960_hw_free,
- .mute_stream = wm8960_mute,
+ .digital_mute = wm8960_mute,
.set_fmt = wm8960_set_dai_fmt,
.set_clkdiv = wm8960_set_dai_clkdiv,
.set_pll = wm8960_set_dai_pll,
.set_sysclk = wm8960_set_dai_sysclk,
- .no_capture_mute = 1,
};
static struct snd_soc_dai_driver wm8960_dai = {

245
patches/back-to-v5.4.diff Normal file
View file

@ -0,0 +1,245 @@
diff --git a/ac101.c b/ac101.c
index be9b1d8..343f030 100644
--- a/ac101.c
+++ b/ac101.c
@@ -955,10 +955,10 @@ void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai
AC101_DBG("stream = %s, play: %d, capt: %d, active: %d\n",
snd_pcm_stream_str(substream),
- codec_dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], codec_dai->stream_active[SNDRV_PCM_STREAM_CAPTURE],
- snd_soc_dai_active(codec_dai));
+ codec_dai->playback_active, codec_dai->capture_active,
+ codec_dai->active);
- if (!snd_soc_dai_active(codec_dai)) {
+ if (!codec_dai->active) {
ac10x->aif1_clken = 1;
ac101_aif1clk(codec, SND_SOC_DAPM_POST_PMD, 0);
} else {
@@ -1080,7 +1080,7 @@ int ac101_hw_params(struct snd_pcm_substream *substream,
freq_out = _FREQ_24_576K;
for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
- if (codec_dai->stream_active[SNDRV_PCM_STREAM_CAPTURE] && dmic_used && codec_aif1_fs[i].samp_rate == 44100) {
+ if (codec_dai->capture_active && dmic_used && codec_aif1_fs[i].samp_rate == 44100) {
ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x4<<AIF1_FS));
} else {
ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), ((codec_aif1_fs[i].srbit)<<AIF1_FS));
diff --git a/ac108.c b/ac108.c
index 4663df0..12ab27b 100644
--- a/ac108.c
+++ b/ac108.c
@@ -653,7 +653,7 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
dev_dbg(dai->dev, "%s() stream=%s play:%d capt:%d +++\n", __func__,
snd_pcm_stream_str(substream),
- dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]);
+ dai->playback_active, dai->capture_active);
if (ac10x->i2c101) {
ret = ac101_hw_params(substream, params, dai);
@@ -664,8 +664,8 @@ static int ac108_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_h
}
}
- if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE && dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK])
- || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai->stream_active[SNDRV_PCM_STREAM_CAPTURE])) {
+ if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE && dai->playback_active)
+ || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai->capture_active)) {
/* not configure hw_param twice */
/* return 0; */
}
@@ -1124,7 +1124,7 @@ void ac108_aif_shutdown(struct snd_pcm_substream *substream,
}
}
-int ac108_aif_mute(struct snd_soc_dai *dai, int mute, int direction) {
+int ac108_aif_mute(struct snd_soc_dai *dai, int mute) {
struct snd_soc_codec *codec = dai->codec;
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
@@ -1145,13 +1145,12 @@ static const struct snd_soc_dai_ops ac108_dai_ops = {
.hw_params = ac108_hw_params,
.prepare = ac108_prepare,
.trigger = ac108_trigger,
- .mute_stream = ac108_aif_mute,
+ .digital_mute = ac108_aif_mute,
/*DAI format configuration*/
.set_fmt = ac108_set_fmt,
// .hw_free = ac108_hw_free,
- .no_capture_mute = 1,
};
static struct snd_soc_dai_driver ac108_dai0 = {
diff --git a/seeed-voicecard.c b/seeed-voicecard.c
index c6d9048..43535aa 100644
--- a/seeed-voicecard.c
+++ b/seeed-voicecard.c
@@ -96,16 +96,16 @@ static int seeed_voice_card_startup(struct snd_pcm_substream *substream)
if (ret)
clk_disable_unprepare(dai_props->cpu_dai.clk);
- if (asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min) {
- priv->channels_playback_default = asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min;
+ if (rtd->cpu_dai->driver->playback.channels_min) {
+ priv->channels_playback_default = rtd->cpu_dai->driver->playback.channels_min;
}
- if (asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min) {
- priv->channels_capture_default = asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min;
+ if (rtd->cpu_dai->driver->capture.channels_min) {
+ priv->channels_capture_default = rtd->cpu_dai->driver->capture.channels_min;
}
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min = priv->channels_playback_override;
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_max = priv->channels_playback_override;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min = priv->channels_capture_override;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_max = priv->channels_capture_override;
+ rtd->cpu_dai->driver->playback.channels_min = priv->channels_playback_override;
+ rtd->cpu_dai->driver->playback.channels_max = priv->channels_playback_override;
+ rtd->cpu_dai->driver->capture.channels_min = priv->channels_capture_override;
+ rtd->cpu_dai->driver->capture.channels_max = priv->channels_capture_override;
return ret;
}
@@ -117,10 +117,10 @@ static void seeed_voice_card_shutdown(struct snd_pcm_substream *substream)
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min = priv->channels_playback_default;
- asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_max = priv->channels_playback_default;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min = priv->channels_capture_default;
- asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_max = priv->channels_capture_default;
+ rtd->cpu_dai->driver->playback.channels_min = priv->channels_playback_default;
+ rtd->cpu_dai->driver->playback.channels_max = priv->channels_playback_default;
+ rtd->cpu_dai->driver->capture.channels_min = priv->channels_capture_default;
+ rtd->cpu_dai->driver->capture.channels_max = priv->channels_capture_default;
clk_disable_unprepare(dai_props->cpu_dai.clk);
@@ -131,8 +131,8 @@ static int seeed_voice_card_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
- struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec_dai = rtd->codec_dai;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
@@ -196,7 +196,7 @@ static void work_cb_codec_clk(struct work_struct *work)
static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
+ struct snd_soc_dai *dai = rtd->codec_dai;
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
#if CONFIG_AC10X_TRIG_LOCK
unsigned long flags;
@@ -205,7 +205,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd,
- dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]);
+ dai->playback_active, dai->capture_active);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
@@ -227,7 +227,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/* capture channel resync, if overrun */
- if (dai->stream_active[SNDRV_PCM_STREAM_CAPTURE] && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (dai->capture_active && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
break;
}
@@ -252,7 +247,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d;finished %d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd,
- dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE], ret);
+ dai->playback_active, dai->capture_active, ret);
return ret;
}
@@ -337,8 +337,8 @@ static int asoc_simple_init_dai(struct snd_soc_dai *dai,
static int seeed_voice_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
- struct snd_soc_dai *codec = asoc_rtd_to_codec(rtd, 0);
- struct snd_soc_dai *cpu = asoc_rtd_to_cpu(rtd, 0);
+ struct snd_soc_dai *codec = rtd->codec_dai;
+ struct snd_soc_dai *cpu = rtd->cpu_dai;
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
int ret;
@@ -636,11 +636,11 @@ static int seeed_voice_card_probe(struct platform_device *pdev)
* Use snd_soc_dai_link_component instead of legacy style
* It is codec only. but cpu/platform will be supported in the future.
* see
- * soc-core.c :: snd_soc_init_multicodec()
+ * soc-core.c :: snd_soc_init_multicodec()
*
* "platform" might be removed
* see
- * simple-card-utils.c :: asoc_simple_canonicalize_platform()
+ * simple-card-utils.c :: asoc_simple_canonicalize_platform()
*/
for (i = 0; i < num; i++) {
dai_link[i].cpus = &dai_props[i].cpus;
diff --git a/sound-compatible-4.18.h b/sound-compatible-4.18.h
index 080325b..eefa7de 100644
--- a/sound-compatible-4.18.h
+++ b/sound-compatible-4.18.h
@@ -16,6 +16,10 @@
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
+#ifndef __has_attribute
+# define __has_attribute(x) __GCC4_has_attribute_##x
+# define __GCC4_has_attribute___fallthrough__ 0
+#endif
#if __has_attribute(__fallthrough__)
# define fallthrough __attribute__((__fallthrough__))
#else
@@ -31,11 +35,7 @@
#define snd_soc_codec_get_dapm snd_soc_component_get_dapm
#define snd_soc_codec_get_bias_level snd_soc_component_get_bias_level
#define snd_soc_kcontrol_codec snd_soc_kcontrol_component
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)
-#define snd_soc_read snd_soc_component_read
-#else
#define snd_soc_read snd_soc_component_read32
-#endif
#define snd_soc_register_codec devm_snd_soc_register_component
#define snd_soc_unregister_codec snd_soc_unregister_component
#define snd_soc_update_bits snd_soc_component_update_bits
diff --git a/wm8960.c b/wm8960.c
index 465c6dc..34d4dad 100644
--- a/wm8960.c
+++ b/wm8960.c
@@ -796,7 +796,7 @@ static int wm8960_hw_free(struct snd_pcm_substream *substream,
return 0;
}
-static int wm8960_mute(struct snd_soc_dai *dai, int mute, int direction)
+static int wm8960_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
@@ -1236,12 +1236,11 @@ static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
static const struct snd_soc_dai_ops wm8960_dai_ops = {
.hw_params = wm8960_hw_params,
.hw_free = wm8960_hw_free,
- .mute_stream = wm8960_mute,
+ .digital_mute = wm8960_mute,
.set_fmt = wm8960_set_dai_fmt,
.set_clkdiv = wm8960_set_dai_clkdiv,
.set_pll = wm8960_set_dai_pll,
.set_sysclk = wm8960_set_dai_sysclk,
- .no_capture_mute = 1,
};
static struct snd_soc_dai_driver wm8960_dai = {

71
patches/back-to-v5.8.diff Normal file
View file

@ -0,0 +1,71 @@
diff --git a/ac108.c b/ac108.c
index 4663df0..67edeae 100644
--- a/ac108.c
+++ b/ac108.c
@@ -1124,7 +1124,7 @@ void ac108_aif_shutdown(struct snd_pcm_substream *substream,
}
}
-int ac108_aif_mute(struct snd_soc_dai *dai, int mute, int direction) {
+int ac108_aif_mute(struct snd_soc_dai *dai, int mute) {
struct snd_soc_codec *codec = dai->codec;
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
@@ -1145,13 +1145,12 @@ static const struct snd_soc_dai_ops ac108_dai_ops = {
.hw_params = ac108_hw_params,
.prepare = ac108_prepare,
.trigger = ac108_trigger,
- .mute_stream = ac108_aif_mute,
+ .digital_mute = ac108_aif_mute,
/*DAI format configuration*/
.set_fmt = ac108_set_fmt,
// .hw_free = ac108_hw_free,
- .no_capture_mute = 1,
};
static struct snd_soc_dai_driver ac108_dai0 = {
diff --git a/sound-compatible-4.18.h b/sound-compatible-4.18.h
index 080325b..faed848 100644
--- a/sound-compatible-4.18.h
+++ b/sound-compatible-4.18.h
@@ -31,11 +31,7 @@
#define snd_soc_codec_get_dapm snd_soc_component_get_dapm
#define snd_soc_codec_get_bias_level snd_soc_component_get_bias_level
#define snd_soc_kcontrol_codec snd_soc_kcontrol_component
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)
-#define snd_soc_read snd_soc_component_read
-#else
#define snd_soc_read snd_soc_component_read32
-#endif
#define snd_soc_register_codec devm_snd_soc_register_component
#define snd_soc_unregister_codec snd_soc_unregister_component
#define snd_soc_update_bits snd_soc_component_update_bits
diff --git a/wm8960.c b/wm8960.c
index 465c6dc..34d4dad 100644
--- a/wm8960.c
+++ b/wm8960.c
@@ -796,7 +796,7 @@ static int wm8960_hw_free(struct snd_pcm_substream *substream,
return 0;
}
-static int wm8960_mute(struct snd_soc_dai *dai, int mute, int direction)
+static int wm8960_mute(struct snd_soc_dai *dai, int mute)
{
struct snd_soc_codec *codec = dai->codec;
@@ -1236,12 +1236,11 @@ static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
static const struct snd_soc_dai_ops wm8960_dai_ops = {
.hw_params = wm8960_hw_params,
.hw_free = wm8960_hw_free,
- .mute_stream = wm8960_mute,
+ .digital_mute = wm8960_mute,
.set_fmt = wm8960_set_dai_fmt,
.set_clkdiv = wm8960_set_dai_clkdiv,
.set_pll = wm8960_set_dai_pll,
.set_sysclk = wm8960_set_dai_sysclk,
- .no_capture_mute = 1,
};
static struct snd_soc_dai_driver wm8960_dai = {

View file

@ -0,0 +1,8 @@
SUBSYSTEM!="sound", GOTO="seeedvoicecard_end"
ACTION!="change", GOTO="seeedvoicecard_end"
KERNEL!="card*", GOTO="seeedvoicecard_end"
ATTR{id}=="seeed4micvoicec",ENV{PULSE_PROFILE_SET}="seeed-voicecard-4mic.conf"
ATTR{id}=="seeed8micvoicec",ENV{PULSE_PROFILE_SET}="seeed-voicecard-8mic.conf"
LABEL="seeedvoicecard_end"

251
pulseaudio/README.md Normal file
View file

@ -0,0 +1,251 @@
# PulseAudio Configuration for seeed-voicecard
Follow this guide if you want to use your seeed-voicecard as a default source/sink of pulseaudio.
### Prerequisites
1. Download PulseAudio
```
sudo apt install -y pulseaudio
```
2. PulseAudio Profiles
```
cd seeed-voicecard/pulseaudio
sudo cp pulse_config_4mic/seeed-voicecard.conf /usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard-4mic.conf
sudo cp pulse_config_6mic/seeed-voicecard.conf /usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard-8mic.conf
```
3. Add `udev` Rules
During the system start, when the card "seeed4micvoicec" is detected, the PULSE_PROFILE_SET variable will be set in the udev database, and PulseAudio will be forced to use `seeed-voicecard-4mic.conf`. Similarly, if the card "seeed8micvoicec" is detected, PulseAudio will be forced to use `seeed-voicecard-8mic.conf`.
```
sudo cp 91-seeedvoicecard.rules /etc/udev/rules.d/91-seeedvoicecard.rules
```
### ReSpeaker 4 Mic Array
<!--
1. Download pulseaudio
```
sudo apt install pulseaudio
```
2. First, you need to write [a profile for pulse](https://www.freedesktop.org/wiki/Software/PulseAudio/Backends/ALSA/Profiles/)
```
cd seeed-voicecard
cd pulseaudio
cd pulse_config_4mic
sudo cp seeed-voicecard.conf /usr/share/pulseaudio/alsa-mixer/profile-sets/
```
3. Edit `udev rules`
During the system start, when the card "seeed4micvoicec" is detected, the PULSE_PROFILE_SET variable will be set in the udev database, and PulseAudio will be forced to use `seeed-voicecard.conf`.
```
# have a look at /lib/udev/rules.d/90-pulseaudio.rules
sudo vim /lib/udev/rules.d/90-pulseaudio.rules
# add the following lines at about line 87(behind the setting for some laptops and before the line GOTO="pulseaudio_end")
# Seeed Voicecard
ATTR{id}=="seeed4micvoicec",ATTR{number}=="1",ENV{PULSE_PROFILE_SET}="seeed-voicecard.conf"
```
![](./udev_rules_4mic.png)
The value of `ATTR{number}` can be found with:
```
udevadm info -a -p /sys/class/sound/card0/
# or udevadm info -a -p /sys/class/sound/card1/
```
For example, in Raspberry Pi, we can find `ATTR{id}=="seeed4micvoicec"` and `ATTR{number}=="1"` with command `udevadm info -a -p /sys/class/sound/card1/`:
```
pi@raspberrypi:~ $ udevadm info -a -p /sys/class/sound/card1/
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/platform/soc/soc:sound/sound/card1':
KERNEL=="card1"
SUBSYSTEM=="sound"
DRIVER==""
ATTR{id}=="seeed4micvoicec"
ATTR{number}=="1"
looking at parent device '/devices/platform/soc/soc:sound':
KERNELS=="soc:sound"
SUBSYSTEMS=="platform"
DRIVERS=="seeed-voicecard"
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS==""
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
``` -->
1. config `default.pa` and `daemon.conf`
```
sudo cp pulse_config_4mic/default.pa /etc/pulse/
sudo cp pulse_config_4mic/daemon.conf /etc/pulse/
```
2. reboot raspberry pi and check
```
sudo reboot
pulseaudio --start # start pulse at first
pactl info # check the setting
Server String: /run/user/1000/pulse/native
Library Protocol Version: 32
Server Protocol Version: 32
Is Local: yes
Client Index: 18
Tile Size: 65496
User Name: pi
Host Name: raspberrypi
Server Name: pulseaudio
Server Version: 10.0
Default Sample Specification: s16le 4ch 96000Hz
Default Channel Map: front-left,front-center,front-right,rear-center
Default Sink: alsa_output.platform-soc_audio.analog-stereo
Default Source: alsa_input.platform-soc_sound.seeed-source
Cookie: 3b12:70b3
```
### 6-Mics Circular Array Kit and 4-Mics Linear Array
<!--
1. Download pulseaudio
```
sudo apt install pulseaudio
```
2. First, you need to write [a profile for pulse](https://www.freedesktop.org/wiki/Software/PulseAudio/Backends/ALSA/Profiles/)
```
cd seeed-voicecard
cd pulseaudio
cd pulse_config_6mic
sudo cp seeed-voicecard.conf /usr/share/pulseaudio/alsa-mixer/profile-sets/
```
3. Edit `udev rules`
During the system start, when the card "seeed8micvoicec" is detected, the PULSE_PROFILE_SET variable will be set in the udev database, and PulseAudio will be forced to use `seeed-voicecard.conf`.
```
# have a look at /lib/udev/rules.d/90-pulseaudio.rules
sudo vim /lib/udev/rules.d/90-pulseaudio.rules
# add the following lines at about line 87(behind the setting for some laptops and before the line GOTO="pulseaudio_end")
# Seeed Voicecard
ATTR{id}=="seeed8micvoicec",ATTR{number}=="1",ENV{PULSE_PROFILE_SET}="seeed-voicecard.conf"
```
![](./udev_rules_6mic.png)
The value of `ATTR{number}` can be found with:
```
udevadm info -a -p /sys/class/sound/card0/
# or udevadm info -a -p /sys/class/sound/card1/
```
For example, in Raspberry Pi, we can find `ATTR{id}=="seeed8micvoicec"` and `ATTR{number}=="1"` with command `udevadm info -a -p /sys/class/sound/card1/`:
```
pi@raspberrypi:~ $ udevadm info -a -p /sys/class/sound/card1/
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device '/devices/platform/soc/soc:sound/sound/card1':
KERNEL=="card1"
SUBSYSTEM=="sound"
DRIVER==""
ATTR{id}=="seeed8micvoicec"
ATTR{number}=="1"
looking at parent device '/devices/platform/soc/soc:sound':
KERNELS=="soc:sound"
SUBSYSTEMS=="platform"
DRIVERS=="seeed-voicecard"
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform/soc':
KERNELS=="soc"
SUBSYSTEMS=="platform"
DRIVERS==""
ATTRS{driver_override}=="(null)"
looking at parent device '/devices/platform':
KERNELS=="platform"
SUBSYSTEMS==""
DRIVERS==""
``` -->
1. config `default.pa` and `daemon.conf`
```
sudo cp pulse_config_6mic/default.pa /etc/pulse/
sudo cp pulse_config_6mic/daemon.conf /etc/pulse/
```
2. reboot raspberry pi and check
```
sudo reboot
pulseaudio --start # start pulse at first
pactl info # check the setting
# The output should be like this
# You could see the default sink is seeed-2ch and default source is seeed-8ch
pi@raspberrypi:~ $ pactl info
Server String: /run/user/1000/pulse/native
Library Protocol Version: 32
Server Protocol Version: 32
Is Local: yes
Client Index: 6
Tile Size: 65496
User Name: pi
Host Name: raspberrypi
Server Name: pulseaudio
Server Version: 10.0
Default Sample Specification: s32le 8ch 96000Hz
Default Channel Map: front-left,front-left-of-center,front-center,front-right,front-right-of-center,rear-center,aux0,aux1
Default Sink: alsa_output.platform-soc_sound.seeed-2ch
Default Source: alsa_input.platform-soc_sound.seeed-8ch
Cookie: 3523:e5af
```
### FAQ
1. Default Sink/Source not right
Make sure there is no any other daemon or using the audio device. Then check profile and udev rules.
`pacmd list-sinks` and `pacmd list-sources` can be used to show the avaiable sinks/sources, after pulseaudio is started.
2. Can't start PulseAudio
Check `default.pa` and `daemon.conf`
3. How to get PulseAudio started automatically
Normally the PulseAudio server is started automatically. If you want to disable it, you can set `autospawn = no` in `~/.config/pulse/client.conf` or `/etc/pulse/client.conf`.
[Click this for more details](https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Running/).
4. Why the default sample rate is 96000? What if my audio's sample rate is not the same as the default?
For the other sample rate audio, PulseAudio will resample it into 96K, which means that if your audio's sample rate is lower than 96K, it will get smoothing.

View file

@ -0,0 +1,87 @@
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for
## more information. Default values are commented out. Use either ; or # for
## commenting.
; daemonize = no
; fail = yes
; allow-module-loading = yes
; allow-exit = yes
; use-pid-file = yes
; system-instance = no
; local-server-type = user
; enable-shm = yes
; enable-memfd = yes
; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
; lock-memory = no
; cpu-limit = no
; high-priority = yes
; nice-level = -11
; realtime-scheduling = yes
; realtime-priority = 5
; exit-idle-time = 20
; scache-idle-time = 20
; dl-search-path = (depends on architecture)
; load-default-script-file = yes
; default-script-file = /etc/pulse/default.pa
; log-target = auto
; log-level = notice
; log-meta = no
; log-time = no
; log-backtrace = 0
; resample-method = speex-float-1
; enable-remixing = yes
; enable-lfe-remixing = no
; lfe-crossover-freq = 0
; flat-volumes = yes
; rlimit-fsize = -1
; rlimit-data = -1
; rlimit-stack = -1
; rlimit-core = -1
; rlimit-as = -1
; rlimit-rss = -1
; rlimit-nproc = -1
; rlimit-nofile = 256
; rlimit-memlock = -1
; rlimit-locks = -1
; rlimit-sigpending = -1
; rlimit-msgqueue = -1
; rlimit-nice = 31
; rlimit-rtprio = 9
; rlimit-rttime = 200000
default-sample-format = s16le
default-sample-rate = 96000
; alternate-sample-rate = 48000
default-sample-channels = 4
; default-channel-map = front-left,front-right
; default-fragments = 4
; default-fragment-size-msec = 25
; enable-deferred-volume = yes
; deferred-volume-safety-margin-usec = 8000
; deferred-volume-extra-delay-usec = 0

View file

@ -0,0 +1,144 @@
#!/usr/bin/pulseaudio -nF
#
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
# This startup script is used only if PulseAudio is started per-user
# (i.e. not in system mode)
.fail
### Automatically restore the volume of streams and devices
load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore
### Automatically augment property information from .desktop files
### stored in /usr/share/application
load-module module-augment-properties
### Should be after module-*-restore but before module-*-detect
load-module module-switch-on-port-available
### Load audio drivers statically
### (it's probably better to not load these drivers manually, but instead
### use module-udev-detect -- see below -- for doing this automatically)
#load-module module-alsa-sink device="hw:1,0" channels=8 rate=48000 format=s32le
#load-module module-alsa-source device="hw:1,0" channels=8 rate=48000 format=s32le
#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#load-module module-null-sink
#load-module module-pipe-sink
### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect
#channels=8 rate=48000 format=s32le
.else
### Use the static hardware detection module (for systems that lack udev support)
load-module module-detect
.endif
### Automatically connect sink and source if JACK server is present
.ifexists module-jackdbus-detect.so
.nofail
load-module module-jackdbus-detect channels=2
.fail
.endif
### Automatically load driver modules for Bluetooth hardware
.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif
.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif
### Load several protocols
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix
.endif
load-module module-native-protocol-unix
### Network access (may be configured with paprefs, so leave this commented
### here if you plan to use paprefs)
#load-module module-esound-protocol-tcp
#load-module module-native-protocol-tcp
#load-module module-zeroconf-publish
### Load the RTP receiver module (also configured via paprefs, see above)
#load-module module-rtp-recv
### Load the RTP sender module (also configured via paprefs, see above)
#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
#load-module module-rtp-send source=rtp.monitor
### Load additional modules from GConf settings. This can be configured with the paprefs tool.
### Please keep in mind that the modules configured by paprefs might conflict with manually
### loaded modules.
.ifexists module-gconf.so
.nofail
load-module module-gconf
.fail
.endif
### Automatically restore the default sink/source when changed by the user
### during runtime
### NOTE: This should be loaded as early as possible so that subsequent modules
### that look up the default sink/source get the right value
load-module module-default-device-restore
### Automatically move streams to the default sink if the sink they are
### connected to dies, similar for sources
load-module module-rescue-streams
### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink
### Honour intended role device property
load-module module-intended-roles
### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle
### If autoexit on idle is enabled we want to make sure we only quit
### when no local session needs us anymore.
.ifexists module-console-kit.so
load-module module-console-kit
.endif
.ifexists module-systemd-login.so
load-module module-systemd-login
.endif
### Enable positioned event sounds
load-module module-position-event-sounds
### Cork music/video streams when a phone stream is active
load-module module-role-cork
### Modules to allow autoloading of filters (such as echo cancellation)
### on demand. module-filter-heuristics tries to determine what filters
### make sense, and module-filter-apply does the heavy-lifting of
### loading modules and rerouting streams.
load-module module-filter-heuristics
load-module module-filter-apply
### Make some devices default
#set-default-sink output
#set-default-source input
set-default-source alsa_input.platform-soc_sound.seeed-source
set-default-sink alsa_output.platform-soc_sound.seeed-sink

View file

@ -0,0 +1,17 @@
# /usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voicecard.conf
[General]
auto-profiles = no
[Mapping seeed-source]
device-strings = hw:%f
channel-map = front-left,front-right,rear-left,rear-right
exact-channels = false
fallback = yes
paths-input = seeed-source
priority = 3
direction = input
[Profile input:seeed-source]
input-mappings = seeed-source
priority = 5
skip-probe = yes

View file

@ -0,0 +1,87 @@
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
## Configuration file for the PulseAudio daemon. See pulse-daemon.conf(5) for
## more information. Default values are commented out. Use either ; or # for
## commenting.
; daemonize = no
; fail = yes
; allow-module-loading = yes
; allow-exit = yes
; use-pid-file = yes
; system-instance = no
; local-server-type = user
; enable-shm = yes
; enable-memfd = yes
; shm-size-bytes = 0 # setting this 0 will use the system-default, usually 64 MiB
; lock-memory = no
; cpu-limit = no
; high-priority = yes
; nice-level = -11
; realtime-scheduling = yes
; realtime-priority = 5
; exit-idle-time = 20
; scache-idle-time = 20
; dl-search-path = (depends on architecture)
; load-default-script-file = yes
; default-script-file = /etc/pulse/default.pa
; log-target = auto
; log-level = notice
; log-meta = no
; log-time = no
; log-backtrace = 0
; resample-method = speex-float-1
; enable-remixing = yes
; enable-lfe-remixing = no
; lfe-crossover-freq = 0
; flat-volumes = yes
; rlimit-fsize = -1
; rlimit-data = -1
; rlimit-stack = -1
; rlimit-core = -1
; rlimit-as = -1
; rlimit-rss = -1
; rlimit-nproc = -1
; rlimit-nofile = 256
; rlimit-memlock = -1
; rlimit-locks = -1
; rlimit-sigpending = -1
; rlimit-msgqueue = -1
; rlimit-nice = 31
; rlimit-rtprio = 9
; rlimit-rttime = 200000
default-sample-format = s32le
default-sample-rate = 96000
; alternate-sample-rate = 48000
default-sample-channels = 8
; default-channel-map = front-left,front-right
; default-fragments = 4
; default-fragment-size-msec = 25
; enable-deferred-volume = yes
; deferred-volume-safety-margin-usec = 8000
; deferred-volume-extra-delay-usec = 0

View file

@ -0,0 +1,143 @@
#!/usr/bin/pulseaudio -nF
#
# This file is part of PulseAudio.
#
# PulseAudio is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# PulseAudio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
# This startup script is used only if PulseAudio is started per-user
# (i.e. not in system mode)
.fail
### Automatically restore the volume of streams and devices
load-module module-device-restore
load-module module-stream-restore
load-module module-card-restore
### Automatically augment property information from .desktop files
### stored in /usr/share/application
load-module module-augment-properties
### Should be after module-*-restore but before module-*-detect
load-module module-switch-on-port-available
### Load audio drivers statically
### (it's probably better to not load these drivers manually, but instead
### use module-udev-detect -- see below -- for doing this automatically)
#load-module module-alsa-sink device="hw:1,0" channels=8 rate=48000 format=s32le
#load-module module-alsa-source device="hw:1,0" channels=8 rate=48000 format=s32le
#load-module module-oss device="/dev/dsp" sink_name=output source_name=input
#load-module module-oss-mmap device="/dev/dsp" sink_name=output source_name=input
#load-module module-null-sink
#load-module module-pipe-sink
### Automatically load driver modules depending on the hardware available
.ifexists module-udev-detect.so
load-module module-udev-detect
#channels=8 rate=48000 format=s32le
.else
### Use the static hardware detection module (for systems that lack udev support)
load-module module-detect
.endif
### Automatically connect sink and source if JACK server is present
.ifexists module-jackdbus-detect.so
.nofail
load-module module-jackdbus-detect channels=2
.fail
.endif
### Automatically load driver modules for Bluetooth hardware
.ifexists module-bluetooth-policy.so
load-module module-bluetooth-policy
.endif
.ifexists module-bluetooth-discover.so
load-module module-bluetooth-discover
.endif
### Load several protocols
.ifexists module-esound-protocol-unix.so
load-module module-esound-protocol-unix
.endif
load-module module-native-protocol-unix
### Network access (may be configured with paprefs, so leave this commented
### here if you plan to use paprefs)
#load-module module-esound-protocol-tcp
#load-module module-native-protocol-tcp
#load-module module-zeroconf-publish
### Load the RTP receiver module (also configured via paprefs, see above)
#load-module module-rtp-recv
### Load the RTP sender module (also configured via paprefs, see above)
#load-module module-null-sink sink_name=rtp format=s16be channels=2 rate=44100 sink_properties="device.description='RTP Multicast Sink'"
#load-module module-rtp-send source=rtp.monitor
### Load additional modules from GConf settings. This can be configured with the paprefs tool.
### Please keep in mind that the modules configured by paprefs might conflict with manually
### loaded modules.
.ifexists module-gconf.so
.nofail
load-module module-gconf
.fail
.endif
### Automatically restore the default sink/source when changed by the user
### during runtime
### NOTE: This should be loaded as early as possible so that subsequent modules
### that look up the default sink/source get the right value
load-module module-default-device-restore
### Automatically move streams to the default sink if the sink they are
### connected to dies, similar for sources
load-module module-rescue-streams
### Make sure we always have a sink around, even if it is a null sink.
load-module module-always-sink
### Honour intended role device property
load-module module-intended-roles
### Automatically suspend sinks/sources that become idle for too long
load-module module-suspend-on-idle
### If autoexit on idle is enabled we want to make sure we only quit
### when no local session needs us anymore.
.ifexists module-console-kit.so
load-module module-console-kit
.endif
.ifexists module-systemd-login.so
load-module module-systemd-login
.endif
### Enable positioned event sounds
load-module module-position-event-sounds
### Cork music/video streams when a phone stream is active
load-module module-role-cork
### Modules to allow autoloading of filters (such as echo cancellation)
### on demand. module-filter-heuristics tries to determine what filters
### make sense, and module-filter-apply does the heavy-lifting of
### loading modules and rerouting streams.
load-module module-filter-heuristics
load-module module-filter-apply
### Make some devices default
#set-default-sink output
#set-default-source input
set-default-source alsa_input.platform-soc_sound.seeed-8ch
set-default-sink alsa_output.platform-soc_sound.seeed-2ch

View file

@ -0,0 +1,34 @@
# /usr/share/pulseaudio/alsa-mixer/profile-sets/seeed-voiced.conf
[General]
auto-profiles = no
[Mapping seeed-8ch]
device-strings = hw:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
exact-channels = false
fallback = yes
paths-input = seeed-8ch
priority = 3
direction = input
[Mapping seeed-2ch]
device-strings = hw:%f
channel-map = front-left,front-right,rear-left,rear-right,front-center,lfe,side-left,side-right
exact-channels = false
exact-channels = false
fallback = yes
paths-output = seeed-2ch
direction = output
priority = 2
[Profile output:seeed-2ch+input:seeed-8ch]
output-mappings = seeed-2ch
input-mappings = seeed-8ch
priority = 100
skip-probe = yes
[Profile output:seeed-2ch]
output-mappings = seeed-2ch
priority = 4
skip-probe = yes
[Profile input:seeed-8ch]
input-mappings = seeed-8ch
priority = 5
skip-probe = yes

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 KiB

View file

@ -38,44 +38,8 @@
};
};
fragment@3 {
target = <&sound>;
master_overlay: __dormant__ {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "seeed-2mic-voicecard";
simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>;
status = "okay";
simple-audio-card,widgets =
"Microphone", "Mic Jack",
"Line", "Line In",
"Line", "Line Out",
"Speaker", "Speaker",
"Headphone", "Headphone Jack";
simple-audio-card,routing =
"Headphone Jack", "HP_L",
"Headphone Jack", "HP_R",
"Speaker", "SPK_LP",
"Speaker", "SPK_LN",
"LINPUT1", "Mic Jack",
"LINPUT3", "Mic Jack",
"RINPUT1", "Mic Jack",
"RINPUT2", "Mic Jack";
simple-audio-card,cpu {
sound-dai = <&i2s>;
};
dailink0_master: simple-audio-card,codec {
sound-dai = <&wm8960>;
clocks = <&wm8960_mclk>;
clock-names = "mclk";
};
};
};
fragment@4 {
target = <&sound>;
slave_overlay: __overlay__ {
compatible = "simple-audio-card";
@ -114,8 +78,7 @@
};
__overrides__ {
alsaname = <&master_overlay>,"simple-audio-card,name",
<&slave_overlay>,"simple-audio-card,name";
alsaname = <&slave_overlay>,"simple-audio-card,name";
compatible = <&wm8960>,"compatible";
master = <0>,"=2!3";
};

Binary file not shown.

View file

@ -2,25 +2,28 @@
/plugin/;
/ {
compatible = "brcm,bcm2708";
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2s>;
__overlay__ {
#sound-dai-cells = <0>;
status = "okay";
};
};
};
fragment@1 {
target-path = "/clocks";
__overlay__ {
ac108_mclk: codec-mclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
};
};
};
fragment@2 {
fragment@1 {
target-path = "/";
__overlay__ {
ac108_mclk: codec-mclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
};
};
};
fragment@2 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
@ -31,36 +34,42 @@
compatible = "x-power,ac108_0";
reg = <0x3b>;
#sound-dai-cells = <0>;
data-protocol = <1>;
data-protocol = <0>;
};
};
};
};
fragment@3 {
target = <&sound>;
fragment@3 {
target = <&sound>;
sound_overlay: __overlay__ {
compatible = "simple-audio-card";
simple-audio-card,format = "i2s";
simple-audio-card,name = "seeed-4mic-voicecard";
status = "okay";
simple-audio-card,bitclock-master = <&dailink0_slave>;
simple-audio-card,frame-slave = <&dailink0_slave>;
dailink0_slave: simple-audio-card,cpu {
sound-dai = <&i2s>;
};
codec_dai: simple-audio-card,codec {
sound-dai = <&ac108_a>;
clocks = <&ac108_mclk>;
};
};
};
__overrides__ {
card-name = <&sound_overlay>,"seeed-voicecard,name";
};
sound_overlay: __overlay__ {
compatible = "seeed-voicecard";
seeed-voice-card,format = "dsp_a";
seeed-voice-card,name = "seeed-4mic-voicecard";
status = "okay";
seeed-voice-card,bitclock-master = <&codec_dai>;
seeed-voice-card,frame-master = <&codec_dai>;
seeed-voice-card,channels-playback-override = <4>;
seeed-voice-card,channels-capture-override = <4>;
cpu_dai: seeed-voice-card,cpu {
sound-dai = <&i2s>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
dai-tdm-slot-tx-mask = <1 1 0 0>;
dai-tdm-slot-rx-mask = <1 1 0 0>;
};
codec_dai: seeed-voice-card,codec {
sound-dai = <&ac108_a>;
clocks = <&ac108_mclk>;
};
};
};
__overrides__ {
card-name = <&sound_overlay>,"seeed-voice-card,name";
};
};

Binary file not shown.

View file

@ -0,0 +1,118 @@
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2708";
fragment@0 {
target = <&i2s>;
__overlay__ {
#sound-dai-cells = <0>;
status = "okay";
};
};
fragment@1 {
target-path = "/";
__overlay__ {
ac10x_mclk: codec-mclk {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <24000000>;
};
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
spk_amp_pins: spk_pins {
brcm,pins = <17 22>;
brcm,function = <1 0>; /* out in */
brcm,pull = <0 0>; /* - - */
};
gpclk0_pins: gpclk0_pins {
brcm,pins = <4>;
brcm,function = <4>; /* alt func 0 */
brcm,pull = <0>; /* - */
};
};
};
fragment@3 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
ac101: ac101@1a{
compatible = "x-power,ac101";
pinctrl-names = "default";
pinctrl-0 = <&spk_amp_pins &gpclk0_pins>;
spk-amp-switch-gpios = <&gpio 17 0>;
switch-irq-gpios = <&gpio 22 0>;
reg = <0x1a>;
#sound-dai-cells = <0>;
};
ac108_a: ac108@35{
compatible = "x-power,ac108_0";
reg = <0x35>;
#sound-dai-cells = <0>;
data-protocol = <0>;
tdm-chips-count = <2>;
};
ac108_b: ac108@3b{
compatible = "x-power,ac108_1";
reg = <0x3b>;
#sound-dai-cells = <0>;
data-protocol = <0>;
tdm-chips-count = <2>;
};
};
};
fragment@4 {
target = <&sound>;
sound_overlay: __overlay__ {
compatible = "seeed-voicecard";
seeed-voice-card,name = "seeed-8mic-voicecard";
seeed-voice-card,channels-playback-override = <8>;
seeed-voice-card,channels-capture-override = <8>;
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
seeed-voice-card,dai-link@0 {
format = "dsp_a";
bitclock-master = <&codec0_dai>;
frame-master = <&codec0_dai>;
/* bitclock-inversion; */
/* frame-inversion; */
reg = <0>;
cpu {
sound-dai = <&i2s>;
dai-tdm-slot-num = <2>;
dai-tdm-slot-width = <32>;
dai-tdm-slot-tx-mask = <1 1 0 0>;
dai-tdm-slot-rx-mask = <1 1 0 0>;
};
codec0_dai: codec {
sound-dai = <&ac108_a>;
clocks = <&ac10x_mclk>;
system-clock-id = <1>;
};
};
};
};
__overrides__ {
card-name = <&sound_overlay>,"seeed-voice-card,name";
};
};

BIN
seeed-8mic-voicecard.dtbo Normal file

Binary file not shown.

163
seeed-voicecard Executable file
View file

@ -0,0 +1,163 @@
#!/bin/bash
#
# Copyright (c) 2018 Baozhu Zuo <zuobaozhu@gmail.com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
set -x
#exec 1>/var/log/$(basename $0).log 2>&1
export PATH=$PATH:/opt/vc/bin
OVERLAYS=/boot/overlays
[ -d /boot/firmware/overlays ] && OVERLAYS=/boot/firmware/overlays
#enable i2c interface
dtparam -d $OVERLAYS i2c_arm=on
modprobe i2c-dev
#enable spi interface
dtparam -d $OVERLAYS spi=on
_VER_RUN=
function get_kernel_version() {
local ZIMAGE IMG_OFFSET
_VER_RUN=""
[ -z "$_VER_RUN" ] && {
ZIMAGE=/boot/kernel.img
IMG_OFFSET=$(LC_ALL=C grep -abo $'\x1f\x8b\x08\x00' $ZIMAGE | head -n 1 | cut -d ':' -f 1)
# 64-bit-only kernel package
[ ! -f /boot/kernel.img ] && [ -f /boot/kernel8.img ] && ZIMAGE=/boot/kernel8.img
_VER_RUN=$(dd if=$ZIMAGE obs=64K ibs=4 skip=$(( IMG_OFFSET / 4)) 2>/dev/null | zcat | grep -a -m1 "Linux version" | LC_ALL=C sed -e 's/^.*Linux/Linux/' | strings | awk '{ print $3; }')
}
echo "$_VER_RUN"
return 0
}
CONFIG=/boot/config.txt
[ -f /boot/firmware/usercfg.txt ] && CONFIG=/boot/firmware/usercfg.txt
get_overlay() {
ov=$1
if grep -q -E "^dtoverlay=$ov" $CONFIG; then
echo 0
else
echo 1
fi
}
do_overlay() {
ov=$1
RET=$2
DEFAULT=--defaultno
CURRENT=0
if [ $(get_overlay $ov) -eq 0 ]; then
DEFAULT=
CURRENT=1
fi
if [ $RET -eq $CURRENT ]; then
ASK_TO_REBOOT=1
fi
if [ $RET -eq 0 ]; then
sed $CONFIG -i -e "s/^#dtoverlay=$ov/dtoverlay=$ov/"
if ! grep -q -E "^dtoverlay=$ov" $CONFIG; then
printf "dtoverlay=$ov\n" >> $CONFIG
fi
STATUS=enabled
elif [ $RET -eq 1 ]; then
sed $CONFIG -i -e "s/^dtoverlay=$ov/#dtoverlay=$ov/"
STATUS=disabled
else
return $RET
fi
}
is_1a=$(i2cdetect -y 1 0x1a 0x1a | egrep "(1a|UU)" | awk '{print $2}')
is_35=$(i2cdetect -y 1 0x35 0x35 | egrep "(35|UU)" | awk '{print $2}')
is_3b=$(i2cdetect -y 1 0x3b 0x3b | egrep "(3b|UU)" | awk '{print $2}')
RPI_HATS="seeed-2mic-voicecard seeed-4mic-voicecard seeed-8mic-voicecard"
overlay=""
if [ "x${is_1a}" != "x" ] && [ "x${is_35}" == "x" ] ; then
echo "install 2mic"
overlay=seeed-2mic-voicecard
asound_conf=/etc/voicecard/asound_2mic.conf
asound_state=/etc/voicecard/wm8960_asound.state
fi
if [ "x${is_3b}" != "x" ] && [ "x${is_35}" == "x" ] ; then
echo "install 4mic"
overlay=seeed-4mic-voicecard
asound_conf=/etc/voicecard/asound_4mic.conf
asound_state=/etc/voicecard/ac108_asound.state
fi
if [ "x${is_3b}" != "x" ] && [ "x${is_35}" != "x" ] ; then
echo "install 6mic"
overlay=seeed-8mic-voicecard
asound_conf=/etc/voicecard/asound_6mic.conf
asound_state=/etc/voicecard/ac108_6mic.state
fi
if [ "$overlay" ]; then
echo Install $overlay ...
# Remove old configuration
rm /etc/asound.conf
rm /var/lib/alsa/asound.state
kernel_ver=$(uname -r) # get_kernel_version)
# echo kernel_ver=$kernel_ver
# TODO: dynamic dtoverlay Bug of v4.19.x
# no DT node phandle inserted.
if [[ "$kernel_ver" =~ ^4\.19.*$ || "$kernel_ver" =~ ^5\.*$ ]]; then
for i in $RPI_HATS; do
if [ "$i" == "$overlay" ]; then
/bin/true #do_overlay $overlay 0
else
echo Uninstall $i ...
/bin/true #do_overlay $i 1
fi
done
fi
#make sure the driver loads correctly
dtoverlay -d $OVERLAYS $overlay || true
echo "create $overlay asound configure file"
ln -s $asound_conf /etc/asound.conf
echo "create $overlay asound status file"
ln -s $asound_state /var/lib/alsa/asound.state
fi
alsactl restore
#Force 3.5mm ('headphone') jack
# The Raspberry Pi 4, released on 24th Jun 2019, has two HDMI ports,
# and can drive two displays with audios for two users simultaneously,
# in a "multiseat" configuration. The earlier single virtual ALSA
# option for re-directing audio playback between headphone jack and HDMI
# via a 'Routing' mixer setting was turned off eventually to allow
# simultaneous usage of all 3 playback devices.
if aplay -l | grep -q "bcm2835 ALSA"; then
amixer cset numid=3 1 || true
fi

926
seeed-voicecard.c Normal file
View file

@ -0,0 +1,926 @@
/*
* SEEED voice card
*
* (C) Copyright 2017-2018
* Seeed Technology Co., Ltd. <www.seeedstudio.com>
*
* base on ASoC simple sound card support
*
* Copyright (C) 2012 Renesas Solutions Corp.
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
/* #undef DEBUG */
#include <linux/version.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/string.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
#include <sound/simple_card_utils.h>
#include "ac10x.h"
#define LINUX_VERSION_IS_GEQ(x1,x2,x3) (LINUX_VERSION_CODE >= KERNEL_VERSION(x1,x2,x3))
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
#define asoc_simple_parse_clk_cpu(dev, node, dai_link, simple_dai) \
asoc_simple_parse_clk(dev, node, simple_dai, dai_link->cpus)
#define asoc_simple_parse_clk_codec(dev, node, dai_link, simple_dai) \
asoc_simple_parse_clk(dev, node, simple_dai, dai_link->codecs)
#define asoc_simple_parse_cpu(node, dai_link, is_single_link) \
asoc_simple_parse_dai(node, dai_link->cpus, is_single_link)
#define asoc_simple_parse_codec(node, dai_link) \
asoc_simple_parse_dai(node, dai_link->codecs, NULL)
#define asoc_simple_parse_platform(node, dai_link) \
asoc_simple_parse_dai(node, dai_link->platforms, NULL)
#endif
/*
* single codec:
* 0 - allow multi codec
* 1 - yes
*/
#define _SINGLE_CODEC 1
struct seeed_card_data {
struct snd_soc_card snd_card;
struct seeed_dai_props {
struct asoc_simple_dai cpu_dai;
struct asoc_simple_dai codec_dai;
struct snd_soc_dai_link_component cpus; /* single cpu */
struct snd_soc_dai_link_component codecs; /* single codec */
struct snd_soc_dai_link_component platforms;
unsigned int mclk_fs;
} *dai_props;
unsigned int mclk_fs;
unsigned channels_playback_default;
unsigned channels_playback_override;
unsigned channels_capture_default;
unsigned channels_capture_override;
struct snd_soc_dai_link *dai_link;
#if CONFIG_AC10X_TRIG_LOCK
spinlock_t lock;
#endif
struct work_struct work_codec_clk;
#define TRY_STOP_MAX 3
int try_stop;
};
struct seeed_card_info {
const char *name;
const char *card;
const char *codec;
const char *platform;
unsigned int daifmt;
struct asoc_simple_dai cpu_dai;
struct asoc_simple_dai codec_dai;
};
#define seeed_priv_to_card(priv) (&(priv)->snd_card)
#define seeed_priv_to_dev(priv) ((priv)->snd_card.dev)
#define seeed_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
#define seeed_priv_to_props(priv, i) ((priv)->dai_props + (i))
#define DAI "sound-dai"
#define CELL "#sound-dai-cells"
#define PREFIX "seeed-voice-card,"
static int seeed_voice_card_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
int ret;
ret = clk_prepare_enable(dai_props->cpu_dai.clk);
if (ret)
return ret;
ret = clk_prepare_enable(dai_props->codec_dai.clk);
if (ret)
clk_disable_unprepare(dai_props->cpu_dai.clk);
if (asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min) {
priv->channels_playback_default = asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min;
}
if (asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min) {
priv->channels_capture_default = asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min;
}
asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min = priv->channels_playback_override;
asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_max = priv->channels_playback_override;
asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min = priv->channels_capture_override;
asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_max = priv->channels_capture_override;
return ret;
}
static void seeed_voice_card_shutdown(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_min = priv->channels_playback_default;
asoc_rtd_to_cpu(rtd, 0)->driver->playback.channels_max = priv->channels_playback_default;
asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_min = priv->channels_capture_default;
asoc_rtd_to_cpu(rtd, 0)->driver->capture.channels_max = priv->channels_capture_default;
clk_disable_unprepare(dai_props->cpu_dai.clk);
clk_disable_unprepare(dai_props->codec_dai.clk);
}
static int seeed_voice_card_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
unsigned int mclk, mclk_fs = 0;
int ret = 0;
if (priv->mclk_fs)
mclk_fs = priv->mclk_fs;
else if (dai_props->mclk_fs)
mclk_fs = dai_props->mclk_fs;
if (mclk_fs) {
mclk = params_rate(params) * mclk_fs;
ret = snd_soc_dai_set_sysclk(codec_dai, 0, mclk,
SND_SOC_CLOCK_IN);
if (ret && ret != -ENOTSUPP)
goto err;
ret = snd_soc_dai_set_sysclk(cpu_dai, 0, mclk,
SND_SOC_CLOCK_OUT);
if (ret && ret != -ENOTSUPP)
goto err;
}
return 0;
err:
return ret;
}
#define _SET_CLOCK_CNT 2
static int (* _set_clock[_SET_CLOCK_CNT])(int y_start_n_stop, struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai);
int seeed_voice_card_register_set_clock(int stream, int (*set_clock)(int, struct snd_pcm_substream *, int, struct snd_soc_dai *)) {
if (! _set_clock[stream]) {
_set_clock[stream] = set_clock;
}
return 0;
}
EXPORT_SYMBOL(seeed_voice_card_register_set_clock);
/*
* work_cb_codec_clk: clear audio codec inner clock.
*/
static void work_cb_codec_clk(struct work_struct *work)
{
struct seeed_card_data *priv = container_of(work, struct seeed_card_data, work_codec_clk);
int r = 0;
if (_set_clock[SNDRV_PCM_STREAM_CAPTURE]) {
r = r || _set_clock[SNDRV_PCM_STREAM_CAPTURE](0, NULL, 0, NULL); /* not using 2nd to 4th arg if 1st == 0 */
}
if (_set_clock[SNDRV_PCM_STREAM_PLAYBACK]) {
r = r || _set_clock[SNDRV_PCM_STREAM_PLAYBACK](0, NULL, 0, NULL); /* not using 2nd to 4th arg if 1st == 0 */
}
if (r && priv->try_stop++ < TRY_STOP_MAX) {
if (0 != schedule_work(&priv->work_codec_clk)) {}
}
return;
}
static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *dai = asoc_rtd_to_codec(rtd, 0);
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
#if CONFIG_AC10X_TRIG_LOCK
unsigned long flags;
#endif
int ret = 0;
dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd,
dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active, dai->stream[SNDRV_PCM_STREAM_CAPTURE].active);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
if (cancel_work_sync(&priv->work_codec_clk) != 0) {}
#if CONFIG_AC10X_TRIG_LOCK
/* I know it will degrades performance, but I have no choice */
spin_lock_irqsave(&priv->lock, flags);
#endif
// if (_set_clock[SNDRV_PCM_STREAM_CAPTURE]) _set_clock[SNDRV_PCM_STREAM_CAPTURE](1, substream, cmd, dai);
// if (_set_clock[SNDRV_PCM_STREAM_PLAYBACK]) _set_clock[SNDRV_PCM_STREAM_PLAYBACK](1, substream, cmd, dai);
#if CONFIG_AC10X_TRIG_LOCK
spin_unlock_irqrestore(&priv->lock, flags);
#endif
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/* capture channel resync, if overrun */
if (dai->stream[SNDRV_PCM_STREAM_CAPTURE].active && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
break;
}
/* interrupt environment */
if (in_irq() || in_nmi() || in_serving_softirq()) {
priv->try_stop = 0;
if (0 != schedule_work(&priv->work_codec_clk)) {
}
} else {
// if (_set_clock[SNDRV_PCM_STREAM_CAPTURE]) _set_clock[SNDRV_PCM_STREAM_CAPTURE](0, NULL, 0, NULL); /* not using 2nd to 4th arg if 1st == 0 */
// if (_set_clock[SNDRV_PCM_STREAM_PLAYBACK]) _set_clock[SNDRV_PCM_STREAM_PLAYBACK](0, NULL, 0, NULL); /* not using 2nd to 4th arg if 1st == 0 */
}
break;
default:
ret = -EINVAL;
}
dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d;finished %d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd,
dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active, dai->stream[SNDRV_PCM_STREAM_CAPTURE].active, ret);
return ret;
}
static struct snd_soc_ops seeed_voice_card_ops = {
.startup = seeed_voice_card_startup,
.shutdown = seeed_voice_card_shutdown,
.hw_params = seeed_voice_card_hw_params,
.trigger = seeed_voice_card_trigger,
};
static int asoc_simple_parse_dai(struct device_node *node,
struct snd_soc_dai_link_component *dlc,
int *is_single_link)
{
struct of_phandle_args args;
int ret;
if (!node)
return 0;
/*
* Get node via "sound-dai = <&phandle port>"
* it will be used as xxx_of_node on soc_bind_dai_link()
*/
ret = of_parse_phandle_with_args(node, DAI, CELL, 0, &args);
if (ret)
return ret;
/*
* FIXME
*
* Here, dlc->dai_name is pointer to CPU/Codec DAI name.
* If user unbinded CPU or Codec driver, but not for Sound Card,
* dlc->dai_name is keeping unbinded CPU or Codec
* driver's pointer.
*
* If user re-bind CPU or Codec driver again, ALSA SoC will try
* to rebind Card via snd_soc_try_rebind_card(), but because of
* above reason, it might can't bind Sound Card.
* Because Sound Card is pointing to released dai_name pointer.
*
* To avoid this rebind Card issue,
* 1) It needs to alloc memory to keep dai_name eventhough
* CPU or Codec driver was unbinded, or
* 2) user need to rebind Sound Card everytime
* if he unbinded CPU or Codec.
*/
ret = snd_soc_of_get_dai_name(node, &dlc->dai_name, 0);
if (ret < 0)
return ret;
dlc->of_node = args.np;
if (is_single_link)
*is_single_link = !args.args_count;
return 0;
}
static int asoc_simple_init_dai(struct snd_soc_dai *dai,
struct asoc_simple_dai *simple_dai)
{
int ret;
if (!simple_dai)
return 0;
if (simple_dai->sysclk) {
ret = snd_soc_dai_set_sysclk(dai, 0, simple_dai->sysclk,
simple_dai->clk_direction);
if (ret && ret != -ENOTSUPP) {
dev_err(dai->dev, "simple-card: set_sysclk error\n");
return ret;
}
}
if (simple_dai->slots) {
ret = snd_soc_dai_set_bclk_ratio(dai,
simple_dai->slots *
simple_dai->slot_width);
if (ret && ret != -ENOTSUPP) {
dev_err(dai->dev, "simple-card: set_tdm_slot error\n");
return ret;
}
}
return 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0)
static inline int asoc_simple_component_is_codec(struct snd_soc_component *component)
{
return component->driver->endianness;
}
static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_dai_link *dai_link = rtd->dai_link;
struct snd_soc_component *component;
struct snd_soc_pcm_stream *params;
struct snd_pcm_hardware hw;
int i, ret, stream;
/* Only Codecs */
for_each_rtd_components(rtd, i, component) {
if (!asoc_simple_component_is_codec(component))
return 0;
}
/* Assumes the capabilities are the same for all supported streams */
for (stream = 0; stream < 2; stream++) {
ret = snd_soc_runtime_calc_hw(rtd, &hw, stream);
if (ret == 0)
break;
}
if (ret < 0) {
dev_err(rtd->dev, "simple-card: no valid dai_link params\n");
return ret;
}
params = devm_kzalloc(rtd->dev, sizeof(*params), GFP_KERNEL);
if (!params)
return -ENOMEM;
params->formats = hw.formats;
params->rates = hw.rates;
params->rate_min = hw.rate_min;
params->rate_max = hw.rate_max;
params->channels_min = hw.channels_min;
params->channels_max = hw.channels_max;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,4,0)
dai_link->c2c_params = params;
dai_link->num_c2c_params = 1;
#else
/* apparently this goes back to 5.6.x */
dai_link->params = params;
dai_link->num_params = 1;
#endif
return 0;
}
#endif
static int seeed_voice_card_dai_init(struct snd_soc_pcm_runtime *rtd)
{
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
struct snd_soc_dai *codec = asoc_rtd_to_codec(rtd, 0);
struct snd_soc_dai *cpu = asoc_rtd_to_cpu(rtd, 0);
struct seeed_dai_props *dai_props =
seeed_priv_to_props(priv, rtd->num);
int ret;
ret = asoc_simple_init_dai(codec, &dai_props->codec_dai);
if (ret < 0)
return ret;
ret = asoc_simple_init_dai(cpu, &dai_props->cpu_dai);
if (ret < 0)
return ret;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0)
ret = asoc_simple_init_dai_link_params(rtd);
if (ret < 0)
return ret;
#endif
dev_dbg(rtd->card->dev, "codec \"%s\" mapping to cpu \"%s\"\n", codec->name, cpu->name);
return 0;
}
static int seeed_voice_card_dai_link_of(struct device_node *node,
struct seeed_card_data *priv,
int idx,
bool is_top_level_node)
{
struct device *dev = seeed_priv_to_dev(priv);
struct snd_soc_dai_link *dai_link = seeed_priv_to_link(priv, idx);
struct seeed_dai_props *dai_props = seeed_priv_to_props(priv, idx);
struct asoc_simple_dai *cpu_dai = &dai_props->cpu_dai;
struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
struct device_node *cpu = NULL;
struct device_node *plat = NULL;
struct device_node *codec = NULL;
char prop[128];
char *prefix = "";
int ret, single_cpu;
/* For single DAI link & old style of DT node */
if (is_top_level_node)
prefix = PREFIX;
snprintf(prop, sizeof(prop), "%scpu", prefix);
cpu = of_get_child_by_name(node, prop);
if (!cpu) {
ret = -EINVAL;
dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
goto dai_link_of_err;
}
snprintf(prop, sizeof(prop), "%splat", prefix);
plat = of_get_child_by_name(node, prop);
snprintf(prop, sizeof(prop), "%scodec", prefix);
codec = of_get_child_by_name(node, prop);
if (!codec) {
ret = -EINVAL;
dev_err(dev, "%s: Can't find %s DT node\n", __func__, prop);
goto dai_link_of_err;
}
ret = asoc_simple_parse_daifmt(dev, node, codec,
prefix, &dai_link->dai_fmt);
if (ret < 0)
goto dai_link_of_err;
of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);
ret = asoc_simple_parse_cpu(cpu, dai_link, &single_cpu);
if (ret < 0)
goto dai_link_of_err;
#if _SINGLE_CODEC
ret = asoc_simple_parse_codec(codec, dai_link);
if (ret < 0)
goto dai_link_of_err;
#else
ret = snd_soc_of_get_dai_link_codecs(dev, codec, dai_link);
if (ret < 0) {
dev_err(dev, "parse codec info error %d\n", ret);
goto dai_link_of_err;
}
dev_dbg(dev, "dai_link num_codecs = %d\n", dai_link->num_codecs);
#endif
ret = asoc_simple_parse_platform(plat, dai_link);
if (ret < 0)
goto dai_link_of_err;
ret = snd_soc_of_parse_tdm_slot(cpu, &cpu_dai->tx_slot_mask,
&cpu_dai->rx_slot_mask,
&cpu_dai->slots,
&cpu_dai->slot_width);
dev_dbg(dev, "cpu_dai : slot,width,tx,rx = %d,%d,%d,%d\n",
cpu_dai->slots, cpu_dai->slot_width,
cpu_dai->tx_slot_mask, cpu_dai->rx_slot_mask
);
if (ret < 0)
goto dai_link_of_err;
ret = snd_soc_of_parse_tdm_slot(codec, &codec_dai->tx_slot_mask,
&codec_dai->rx_slot_mask,
&codec_dai->slots,
&codec_dai->slot_width);
if (ret < 0)
goto dai_link_of_err;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,10,0)
ret = asoc_simple_card_parse_clk_cpu(cpu, dai_link, cpu_dai);
#else
ret = asoc_simple_parse_clk_cpu(dev, cpu, dai_link, cpu_dai);
#endif
if (ret < 0)
goto dai_link_of_err;
#if LINUX_VERSION_CODE <= KERNEL_VERSION(4,10,0)
ret = asoc_simple_card_parse_clk_codec(codec, dai_link, codec_dai);
#else
ret = asoc_simple_parse_clk_codec(dev, codec, dai_link, codec_dai);
#endif
if (ret < 0)
goto dai_link_of_err;
ret = asoc_simple_set_dailink_name(dev, dai_link,
"%s-%s",
dai_link->cpus->dai_name,
#if _SINGLE_CODEC
dai_link->codecs->dai_name
#else
dai_link->codecs[0].dai_name
#endif
);
if (ret < 0)
goto dai_link_of_err;
dai_link->ops = &seeed_voice_card_ops;
dai_link->init = seeed_voice_card_dai_init;
dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
dev_dbg(dev, "\tcpu : %s / %d\n",
dai_link->cpus->dai_name,
dai_props->cpu_dai.sysclk);
dev_dbg(dev, "\tcodec : %s / %d\n",
#if _SINGLE_CODEC
dai_link->codecs->dai_name,
#else
dai_link->codecs[0].dai_name,
#endif
dai_props->codec_dai.sysclk);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,13,0)
asoc_simple_canonicalize_cpu(dai_link->cpus, single_cpu);
#if _SINGLE_CODEC
asoc_simple_canonicalize_platform(dai_link->platforms, dai_link->cpus);
#endif
#else
asoc_simple_canonicalize_cpu(dai_link, single_cpu);
#if _SINGLE_CODEC
asoc_simple_canonicalize_platform(dai_link);
#endif
#endif
dai_link_of_err:
of_node_put(cpu);
of_node_put(codec);
return ret;
}
static int seeed_voice_card_parse_aux_devs(struct device_node *node,
struct seeed_card_data *priv)
{
struct device *dev = seeed_priv_to_dev(priv);
struct device_node *aux_node;
int i, n, len;
if (!of_find_property(node, PREFIX "aux-devs", &len))
return 0; /* Ok to have no aux-devs */
n = len / sizeof(__be32);
if (n <= 0)
return -EINVAL;
priv->snd_card.aux_dev = devm_kzalloc(dev,
n * sizeof(*priv->snd_card.aux_dev), GFP_KERNEL);
if (!priv->snd_card.aux_dev)
return -ENOMEM;
for (i = 0; i < n; i++) {
aux_node = of_parse_phandle(node, PREFIX "aux-devs", i);
if (!aux_node)
return -EINVAL;
priv->snd_card.aux_dev[i].dlc.of_node = aux_node;
}
priv->snd_card.num_aux_devs = n;
return 0;
}
static int seeed_voice_card_parse_of(struct device_node *node,
struct seeed_card_data *priv)
{
struct device *dev = seeed_priv_to_dev(priv);
struct device_node *dai_link;
int ret;
if (!node)
return -EINVAL;
dai_link = of_get_child_by_name(node, PREFIX "dai-link");
/* The off-codec widgets */
if (of_property_read_bool(node, PREFIX "widgets")) {
ret = snd_soc_of_parse_audio_simple_widgets(&priv->snd_card,
PREFIX "widgets");
if (ret)
goto card_parse_end;
}
/* DAPM routes */
if (of_property_read_bool(node, PREFIX "routing")) {
ret = snd_soc_of_parse_audio_routing(&priv->snd_card,
PREFIX "routing");
if (ret)
goto card_parse_end;
}
/* Factor to mclk, used in hw_params() */
of_property_read_u32(node, PREFIX "mclk-fs", &priv->mclk_fs);
/* Single/Muti DAI link(s) & New style of DT node */
if (dai_link) {
struct device_node *np = NULL;
int i = 0;
for_each_child_of_node(node, np) {
dev_dbg(dev, "\tlink %d:\n", i);
ret = seeed_voice_card_dai_link_of(np, priv,
i, false);
if (ret < 0) {
of_node_put(np);
goto card_parse_end;
}
i++;
}
} else {
/* For single DAI link & old style of DT node */
ret = seeed_voice_card_dai_link_of(node, priv, 0, true);
if (ret < 0)
goto card_parse_end;
}
ret = asoc_simple_parse_card_name(&priv->snd_card, PREFIX);
if (ret < 0)
goto card_parse_end;
ret = seeed_voice_card_parse_aux_devs(node, priv);
priv->channels_playback_default = 0;
priv->channels_playback_override = 2;
priv->channels_capture_default = 0;
priv->channels_capture_override = 2;
of_property_read_u32(node, PREFIX "channels-playback-default",
&priv->channels_playback_default);
of_property_read_u32(node, PREFIX "channels-playback-override",
&priv->channels_playback_override);
of_property_read_u32(node, PREFIX "channels-capture-default",
&priv->channels_capture_default);
of_property_read_u32(node, PREFIX "channels-capture-override",
&priv->channels_capture_override);
card_parse_end:
of_node_put(dai_link);
return ret;
}
#ifdef DEBUG
inline void seeed_debug_dai(struct seeed_card_data *priv,
char *name,
struct asoc_simple_dai *dai)
{
struct device *dev = seeed_priv_to_dev(priv);
if (dai->name)
dev_dbg(dev, "%s dai name = %s\n",
name, dai->name);
if (dai->sysclk)
dev_dbg(dev, "%s sysclk = %d\n",
name, dai->sysclk);
dev_dbg(dev, "%s direction = %s\n",
name, dai->clk_direction ? "OUT" : "IN");
if (dai->slots)
dev_dbg(dev, "%s slots = %d\n", name, dai->slots);
if (dai->slot_width)
dev_dbg(dev, "%s slot width = %d\n", name, dai->slot_width);
if (dai->tx_slot_mask)
dev_dbg(dev, "%s tx slot mask = %d\n", name, dai->tx_slot_mask);
if (dai->rx_slot_mask)
dev_dbg(dev, "%s rx slot mask = %d\n", name, dai->rx_slot_mask);
if (dai->clk)
dev_dbg(dev, "%s clk %luHz\n", name, clk_get_rate(dai->clk));
}
inline void seeed_debug_info(struct seeed_card_data *priv)
{
struct snd_soc_card *card = seeed_priv_to_card(priv);
struct device *dev = seeed_priv_to_dev(priv);
int i;
if (card->name)
dev_dbg(dev, "Card Name: %s\n", card->name);
for (i = 0; i < card->num_links; i++) {
struct seeed_dai_props *props = seeed_priv_to_props(priv, i);
struct snd_soc_dai_link *link = seeed_priv_to_link(priv, i);
dev_dbg(dev, "DAI%d\n", i);
seeed_debug_dai(priv, "cpu", &props->cpu_dai);
seeed_debug_dai(priv, "codec", &props->codec_dai);
if (link->name)
dev_dbg(dev, "dai name = %s\n", link->name);
dev_dbg(dev, "dai format = %04x\n", link->dai_fmt);
/*
if (props->adata.convert_rate)
dev_dbg(dev, "convert_rate = %d\n",
props->adata.convert_rate);
if (props->adata.convert_channels)
dev_dbg(dev, "convert_channels = %d\n",
props->adata.convert_channels);
if (props->codec_conf && props->codec_conf->name_prefix)
dev_dbg(dev, "name prefix = %s\n",
props->codec_conf->name_prefix);
*/
if (props->mclk_fs)
dev_dbg(dev, "mclk-fs = %d\n",
props->mclk_fs);
}
}
#else
#define seeed_debug_info(priv)
#endif /* DEBUG */
static int seeed_voice_card_probe(struct platform_device *pdev)
{
struct seeed_card_data *priv;
struct snd_soc_dai_link *dai_link;
struct seeed_dai_props *dai_props;
struct device_node *np = pdev->dev.of_node;
struct device *dev = &pdev->dev;
int num, ret, i;
/* Get the number of DAI links */
if (np && of_get_child_by_name(np, PREFIX "dai-link"))
num = of_get_child_count(np);
else
num = 1;
/* Allocate the private data and the DAI link array */
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
dai_props = devm_kzalloc(dev, sizeof(*dai_props) * num, GFP_KERNEL);
dai_link = devm_kzalloc(dev, sizeof(*dai_link) * num, GFP_KERNEL);
if (!dai_props || !dai_link)
return -ENOMEM;
/*
* Use snd_soc_dai_link_component instead of legacy style
* It is codec only. but cpu/platform will be supported in the future.
* see
* soc-core.c :: snd_soc_init_multicodec()
*
* "platform" might be removed
* see
* simple-card-utils.c :: asoc_simple_canonicalize_platform()
*/
for (i = 0; i < num; i++) {
dai_link[i].cpus = &dai_props[i].cpus;
dai_link[i].num_cpus = 1;
dai_link[i].codecs = &dai_props[i].codecs;
dai_link[i].num_codecs = 1;
dai_link[i].platforms = &dai_props[i].platforms;
dai_link[i].num_platforms = 1;
}
priv->dai_props = dai_props;
priv->dai_link = dai_link;
/* Init snd_soc_card */
priv->snd_card.owner = THIS_MODULE;
priv->snd_card.dev = dev;
priv->snd_card.dai_link = priv->dai_link;
priv->snd_card.num_links = num;
if (np && of_device_is_available(np)) {
ret = seeed_voice_card_parse_of(np, priv);
if (ret < 0) {
if (ret != -EPROBE_DEFER)
dev_err(dev, "parse error %d\n", ret);
goto err;
}
} else {
struct seeed_card_info *cinfo;
struct snd_soc_dai_link_component *cpus;
struct snd_soc_dai_link_component *codecs;
struct snd_soc_dai_link_component *platform;
cinfo = dev->platform_data;
if (!cinfo) {
dev_err(dev, "no info for seeed-voice-card\n");
return -EINVAL;
}
if (!cinfo->name ||
!cinfo->codec_dai.name ||
!cinfo->codec ||
!cinfo->platform ||
!cinfo->cpu_dai.name) {
dev_err(dev, "insufficient seeed_voice_card_info settings\n");
return -EINVAL;
}
cpus = dai_link->cpus;
cpus->dai_name = cinfo->cpu_dai.name;
codecs = dai_link->codecs;
codecs->name = cinfo->codec;
codecs->dai_name = cinfo->codec_dai.name;
platform = dai_link->platforms;
platform->name = cinfo->platform;
priv->snd_card.name = (cinfo->card) ? cinfo->card : cinfo->name;
dai_link->name = cinfo->name;
dai_link->stream_name = cinfo->name;
dai_link->dai_fmt = cinfo->daifmt;
dai_link->init = seeed_voice_card_dai_init;
memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
sizeof(priv->dai_props->cpu_dai));
memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
sizeof(priv->dai_props->codec_dai));
}
snd_soc_card_set_drvdata(&priv->snd_card, priv);
#if CONFIG_AC10X_TRIG_LOCK
spin_lock_init(&priv->lock);
#endif
INIT_WORK(&priv->work_codec_clk, work_cb_codec_clk);
seeed_debug_info(priv);
ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);
if (ret >= 0)
return ret;
err:
asoc_simple_clean_reference(&priv->snd_card);
return ret;
}
static int seeed_voice_card_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct seeed_card_data *priv = snd_soc_card_get_drvdata(card);
if (cancel_work_sync(&priv->work_codec_clk) != 0) {
}
asoc_simple_clean_reference(card);
return 0;
}
static const struct of_device_id seeed_voice_of_match[] = {
{ .compatible = "seeed-voicecard", },
{},
};
MODULE_DEVICE_TABLE(of, seeed_voice_of_match);
static struct platform_driver seeed_voice_card = {
.driver = {
.name = "seeed-voicecard",
.pm = &snd_soc_pm_ops,
.of_match_table = seeed_voice_of_match,
},
.probe = seeed_voice_card_probe,
.remove = seeed_voice_card_remove,
};
module_platform_driver(seeed_voice_card);
MODULE_ALIAS("platform:seeed-voice-card");
MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("ASoC SEEED Voice Card");
MODULE_AUTHOR("PeterYang<linsheng.yang@seeed.cc>");

12
seeed-voicecard.service Normal file
View file

@ -0,0 +1,12 @@
[Unit]
Description=Seeed Voicecard service
After=alsa-restore.service
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/seeed-voicecard
User=root
[Install]
WantedBy=sysinit.target

47
sound-compatible-4.18.h Normal file
View file

@ -0,0 +1,47 @@
/*
* (C) Copyright 2017-2018
* Seeed Technology Co., Ltd. <www.seeedstudio.com>
*
* PeterYang <linsheng.yang@seeed.cc>
*/
#ifndef __SOUND_COMPATIBLE_4_18_H__
#define __SOUND_COMPATIBLE_4_18_H__
#include <linux/version.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0)
#define __NO_SND_SOC_CODEC_DRV 1
#else
#define __NO_SND_SOC_CODEC_DRV 0
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(5,4,0)
#if __has_attribute(__fallthrough__)
# define fallthrough __attribute__((__fallthrough__))
#else
# define fallthrough do {} while (0) /* fallthrough */
#endif
#endif
#if __NO_SND_SOC_CODEC_DRV
#define codec component
#define snd_soc_codec snd_soc_component
#define snd_soc_codec_driver snd_soc_component_driver
#define snd_soc_codec_get_drvdata snd_soc_component_get_drvdata
#define snd_soc_codec_get_dapm snd_soc_component_get_dapm
#define snd_soc_codec_get_bias_level snd_soc_component_get_bias_level
#define snd_soc_kcontrol_codec snd_soc_kcontrol_component
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,9,0)
#define snd_soc_read snd_soc_component_read
#else
#define snd_soc_read snd_soc_component_read32
#endif
#define snd_soc_register_codec devm_snd_soc_register_component
#define snd_soc_unregister_codec snd_soc_unregister_component
#define snd_soc_update_bits snd_soc_component_update_bits
#define snd_soc_write snd_soc_component_write
#define snd_soc_add_codec_controls snd_soc_add_component_controls
#endif
#endif//__SOUND_COMPATIBLE_4_18_H__

44
tools/coherence.py Normal file
View file

@ -0,0 +1,44 @@
"""
Estimate the magnitude squared coherence estimate,
- requirements
sudo apt install python-numpy python-scipy python-matplotlib
"""
import sys
import wave
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
if len(sys.argv) < 2:
print('Usage: python {} audio.wav'.format(sys.argv[0]))
sys.exit(1)
wav = wave.open(sys.argv[1], 'rb')
channels = wav.getnchannels()
frames = wav.readframes(wav.getnframes())
fs = wav.getframerate()
wav.close()
print("channels: %d" % channels)
print("rate : %d" % fs)
print("frames : %d" % wav.getnframes())
array = np.fromstring(frames, dtype='int16')
ch0 = array[0::channels]
fig, ax = plt.subplots()
for ch in range(1, channels):
f, c = signal.coherence(ch0, array[ch::channels], fs, nperseg=1024)
ax.semilogy(f, c, label="CO 1-%d" % (ch + 1))
legend = ax.legend(loc='lower right', shadow=True, fontsize='small')
plt.xlabel('frequency [Hz]')
plt.ylabel('Coherence')
plt.show()

83
tools/phase_test.py Normal file
View file

@ -0,0 +1,83 @@
import sys
import wave
import numpy as np
if len(sys.argv) != 2:
print('Usage: {} multi.wav'.format(sys.argv[0]))
sys.exit(1)
multi = wave.open(sys.argv[1], 'rb')
rate = multi.getframerate()
channels = multi.getnchannels()
if channels <= 1:
sys.exit(1)
N = rate
window = np.hanning(N)
interp = 4*8
max_offset = int(rate * 0.1 / 340 * interp)
def gcc_phat(sig, refsig, fs=1, max_tau=None, interp=16):
'''
This function computes the offset between the signal sig and the reference signal refsig
using the Generalized Cross Correlation - Phase Transform (GCC-PHAT)method.
'''
# make sure the length for the FFT is larger or equal than len(sig) + len(refsig)
n = sig.shape[0] + refsig.shape[0]
# Generalized Cross Correlation Phase Transform
SIG = np.fft.rfft(sig, n=n)
REFSIG = np.fft.rfft(refsig, n=n)
R = SIG * np.conj(REFSIG)
#R /= np.abs(R)
cc = np.fft.irfft(R, n=(interp * n))
max_shift = int(interp * n / 2)
if max_tau:
max_shift = np.minimum(int(interp * fs * max_tau), max_shift)
cc = np.concatenate((cc[-max_shift:], cc[:max_shift+1]))
# find max cross correlation index
shift = np.argmax(np.abs(cc)) - max_shift
tau = shift / float(interp * fs)
return tau, cc
print(multi.getsampwidth())
while True:
data = multi.readframes(N)
if len(data) != multi.getsampwidth() * N * channels:
print("done")
break
if multi.getsampwidth() == 2:
data = np.fromstring(data, dtype='int16')
else:
data = np.fromstring(data, dtype='int32')
ref_buf = data[0::channels]
offsets = []
for ch in range(1, channels):
sig_buf = data[ch::channels]
tau, _ = gcc_phat(sig_buf * window, ref_buf * window, fs=1, max_tau=max_offset, interp=interp)
# tau, _ = gcc_phat(sig_buf, ref_buf, fs=rate, max_tau=1)
offsets.append(tau)
print(offsets)
print(multi.getframerate())
multi.close()

37
ubuntu-prerequisite.sh Executable file
View file

@ -0,0 +1,37 @@
#!/bin/bash
# Copyright (c) Hin-Tak Leung 2020
#
# Overview:
# This script compiles and install the Broadcom VideoCore tools,
# configure the dynamic loader for the non-standard library location,
# and update the loader cache.
#
# A few steps explicitly requires root privilege, which are
# marked with "sudo". The rest is just checking for duplicate/previous
# action.
#
# This derived from my command history on ubuntu 20.04.1 .YMMV
sudo apt install -y git gcc g++ make alsa-utils cmake
git clone git://github.com/raspberrypi/userland.git
pushd userland/
arch=$(uname -m)
if [[ "$arch" =~ aarch64 ]]; then
./buildme --aarch64
else
./buildme
fi
# ./buildme already includes "sudo make install" at the end
popd
# matches Raspbian's location:
if [ ! -f /etc/ld.so.conf.d/00-vmcs.conf ] ; then
echo "/opt/vc/lib" | sudo tee -a /etc/ld.so.conf.d/00-vmcs.conf
sudo ldconfig -v
else
echo "/etc/ld.so.conf.d/00-vmcs.conf exists - no need to update ld.cache!"
fi

View file

@ -12,71 +12,87 @@ if [ "x${is_Raspberry}" != "xRaspberry" ] ; then
fi
uname_r=$(uname -r)
card=$1
if [ x${card} = "x" ] ; then
echo "Usage: ./uninstall 2mic|4mic"
exit 1
fi
if [ x${card} = "x2mic" ] ; then
echo "delete dtoverlay=seeed-2mic-voicecard in /boot/config.txt"
sed -i "s/dtoverlay=seeed-2mic-voicecard//g" /boot/config.txt
if [ -f /boot/overlays/seeed-2mic-voicecard.dtbo ] ; then
echo "remove seeed-2mic-voicecard.dtbo in /boot/overlays"
rm /boot/overlays/seeed-2mic-voicecard.dtbo
fi
CONFIG=/boot/config.txt
[ -f /boot/firmware/config.txt ] && CONFIG=/boot/firmware/config.txt
[ -f /boot/firmware/usercfg.txt ] && CONFIG=/boot/firmware/usercfg.txt
if [ -f /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-wm8960.ko ] ; then
echo "remove snd-soc-wm8960.ko"
rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-wm8960.ko
fi
get_overlay() {
ov=$1
if grep -q -E "^dtoverlay=$ov" $CONFIG; then
echo 0
else
echo 1
fi
}
if [ -d /var/lib/dkms/seeed-voicecard ] ; then
echo "remove seeed-voicecard dkms"
rm -rf /var/lib/dkms/seeed-voicecard
fi
do_overlay() {
ov=$1
RET=$2
DEFAULT=--defaultno
CURRENT=0
if [ $(get_overlay $ov) -eq 0 ]; then
DEFAULT=
CURRENT=1
fi
if [ $RET -eq $CURRENT ]; then
ASK_TO_REBOOT=1
fi
if [ $RET -eq 0 ]; then
sed $CONFIG -i -e "s/^#dtoverlay=$ov/dtoverlay=$ov/"
if ! grep -q -E "^dtoverlay=$ov" $CONFIG; then
printf "dtoverlay=$ov\n" >> $CONFIG
fi
STATUS=enabled
elif [ $RET -eq 1 ]; then
sed $CONFIG -i -e "s/^dtoverlay=$ov/#dtoverlay=$ov/"
STATUS=disabled
else
return $RET
fi
}
echo "delete snd-soc-wm8960 in /etc/modules"
sed -i "s/snd-soc-wm8960//g" /etc/modules
RPI_HATS="seeed-2mic-voicecard seeed-4mic-voicecard seeed-8mic-voicecard"
if [ -f /var/lib/alsa/asound.state ] ; then
echo "remove wm8960_asound.state"
rm /var/lib/alsa/asound.state
fi
fi
PATH=$PATH:/opt/vc/bin
echo "remove dtbos"
for i in $RPI_HATS; do
dtoverlay -r $i
done
OVERLAYS=/boot/overlays
[ -d /boot/firmware/overlays ] && OVERLAYS=/boot/firmware/overlays
if [ x${card} = "x4mic" ] ; then
echo "delete dtoverlay=seeed-4mic-voicecard in /boot/config.txt"
sed -i "s/dtoverlay=seeed-4mic-voicecard//g" /boot/config.txt
if [ -f /boot/overlays/seeed-4mic-voicecard.dtbo ] ; then
echo "remove seeed-4mic-voicecard.dtbo in /boot/overlays"
rm /boot/overlays/seeed-4mic-voicecard.dtbo
fi
rm ${OVERLAYS}/seeed-2mic-voicecard.dtbo || true
rm ${OVERLAYS}/seeed-4mic-voicecard.dtbo || true
rm ${OVERLAYS}/seeed-8mic-voicecard.dtbo || true
if [ -f /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-ac108.ko ] ; then
echo "remove snd-soc-ac108.ko"
rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-ac108.ko
fi
echo "remove alsa configs"
rm -rf /etc/voicecard/ || true
if [ -d /var/lib/dkms/seeed-voicecard ] ; then
echo "remove seeed-voicecard dkms"
rm -rf /var/lib/dkms/seeed-voicecard
fi
echo "disabled seeed-voicecard.service "
systemctl stop seeed-voicecard.service
systemctl disable seeed-voicecard.service
echo "delete snd-soc-ac108 in /etc/modules"
sed -i "s/snd-soc-ac108//g" /etc/modules
echo "remove seeed-voicecard"
rm /usr/bin/seeed-voicecard || true
rm /lib/systemd/system/seeed-voicecard.service || true
if [ -f /var/lib/alsa/asound.state ] ; then
echo "remove ac108_asound.state"
rm /var/lib/alsa/asound.state
fi
if [ -f /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_ac108.so ] ; then
echo "remove libasound_module_pcm_ac108.so in /usr/lib/arm-linux-gnueabihf/alsa-lib/ "
rm /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_ac108.so
fi
fi
echo "remove dkms"
rm -rf /var/lib/dkms/seeed-voicecard || true
echo "remove kernel modules"
rm /lib/modules/*/kernel/sound/soc/codecs/snd-soc-wm8960.ko || true
rm /lib/modules/*/kernel/sound/soc/codecs/snd-soc-ac108.ko || true
rm /lib/modules/*/kernel/sound/soc/bcm/snd-soc-seeed-voicecard.ko || true
rm /lib/modules/*/updates/dkms/snd-soc-wm8960.ko || true
rm /lib/modules/*/updates/dkms/snd-soc-ac108.ko || true
rm /lib/modules/*/updates/dkms/snd-soc-seeed-voicecard.ko || true
echo "remove $CONFIG configuration"
for i in $RPI_HATS; do
echo Uninstall $i ...
do_overlay $i 1
done
echo "------------------------------------------------------"
echo "Please reboot your raspberry pi to apply all settings"

View file

@ -25,6 +25,7 @@
#include <sound/initval.h>
#include <sound/tlv.h>
#include <sound/wm8960.h>
#include "sound-compatible-4.18.h"
#include "wm8960.h"
@ -226,10 +227,11 @@ static const DECLARE_TLV_DB_SCALE(dac_tlv, -12750, 50, 1);
static const DECLARE_TLV_DB_SCALE(bypass_tlv, -2100, 300, 0);
static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1);
static const DECLARE_TLV_DB_SCALE(lineinboost_tlv, -1500, 300, 1);
static const SNDRV_CTL_TLVD_DECLARE_DB_RANGE(micboost_tlv,
static const DECLARE_TLV_DB_RANGE(micboost_tlv,
0, 1, TLV_DB_SCALE_ITEM(0, 1300, 0),
2, 3, TLV_DB_SCALE_ITEM(2000, 900, 0),
);
static const struct snd_kcontrol_new wm8960_snd_controls[] = {
SOC_DOUBLE_R_TLV("Capture Volume", WM8960_LINVOL, WM8960_RINVOL,
@ -506,7 +508,11 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec)
* list each time to find the desired power state do so now
* and save the result.
*/
#if __NO_SND_SOC_CODEC_DRV
list_for_each_entry(w, &codec->card->widgets, list) {
#else
list_for_each_entry(w, &codec->component.card->widgets, list) {
#endif
if (w->dapm != dapm)
continue;
if (strcmp(w->name, "LOUT1 PGA") == 0)
@ -747,6 +753,7 @@ static int wm8960_hw_params(struct snd_pcm_substream *substream,
iface |= 0x000c;
break;
}
fallthrough;
default:
dev_err(codec->dev, "unsupported width %d\n",
params_width(params));
@ -789,7 +796,7 @@ static int wm8960_hw_free(struct snd_pcm_substream *substream,
return 0;
}
static int wm8960_mute(struct snd_soc_dai *dai, int mute)
static int wm8960_mute(struct snd_soc_dai *dai, int mute, int direction)
{
struct snd_soc_codec *codec = dai->codec;
@ -1229,11 +1236,12 @@ static int wm8960_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
static const struct snd_soc_dai_ops wm8960_dai_ops = {
.hw_params = wm8960_hw_params,
.hw_free = wm8960_hw_free,
.digital_mute = wm8960_mute,
.mute_stream = wm8960_mute,
.set_fmt = wm8960_set_dai_fmt,
.set_clkdiv = wm8960_set_dai_clkdiv,
.set_pll = wm8960_set_dai_pll,
.set_sysclk = wm8960_set_dai_sysclk,
.no_capture_mute = 1,
};
static struct snd_soc_dai_driver wm8960_dai = {
@ -1251,7 +1259,11 @@ static struct snd_soc_dai_driver wm8960_dai = {
.rates = WM8960_RATES,
.formats = WM8960_FORMATS,},
.ops = &wm8960_dai_ops,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,12,0)
.symmetric_rate = 1,
#else
.symmetric_rates = 1,
#endif
};
static int wm8960_probe(struct snd_soc_codec *codec)
@ -1274,7 +1286,12 @@ static int wm8960_probe(struct snd_soc_codec *codec)
static const struct snd_soc_codec_driver soc_codec_dev_wm8960 = {
.probe = wm8960_probe,
.set_bias_level = wm8960_set_bias_level,
.suspend_bias_off = true,
.suspend_bias_off = true,
#if __NO_SND_SOC_CODEC_DRV
.idle_bias_on = 1,
.use_pmdown_time = 1,
.endianness = 1,
#endif
};
static const struct regmap_config wm8960_regmap = {
@ -1301,8 +1318,7 @@ static void wm8960_set_pdata_from_of(struct i2c_client *i2c,
pdata->shared_lrclk = true;
}
static int wm8960_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int wm8960_i2c_probe(struct i2c_client *i2c)
{
struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
struct wm8960_priv *wm8960;
@ -1367,10 +1383,9 @@ static int wm8960_i2c_probe(struct i2c_client *i2c,
return ret;
}
static int wm8960_i2c_remove(struct i2c_client *client)
static void wm8960_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
return 0;
}
static const struct i2c_device_id wm8960_i2c_id[] = {