Compare commits

..

1 commit

Author SHA1 Message Date
Hin-Tak Leung
bf7e70416b Attempt to fix mis-match to "5.15.84.x 2023-01-23 11:53:11 +00:00
8 changed files with 46 additions and 56 deletions

View file

@ -5,7 +5,7 @@ The drivers for [ReSpeaker Mic Hat](https://www.seeedstudio.com/ReSpeaker-2-Mics
### Install seeed-voicecard ### Install seeed-voicecard
Get the seeed voice card source code and install all linux kernel drivers Get the seeed voice card source code and install all linux kernel drivers
```bash ```bash
git clone https://github.com/HinTak/seeed-voicecard git clone https://github.com/respeaker/seeed-voicecard
cd seeed-voicecard cd seeed-voicecard
sudo ./install.sh sudo ./install.sh
sudo reboot sudo reboot

View file

@ -955,7 +955,7 @@ void ac101_aif_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai
AC101_DBG("stream = %s, play: %d, capt: %d, active: %d\n", AC101_DBG("stream = %s, play: %d, capt: %d, active: %d\n",
snd_pcm_stream_str(substream), snd_pcm_stream_str(substream),
codec_dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active, codec_dai->stream[SNDRV_PCM_STREAM_CAPTURE].active, codec_dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], codec_dai->stream_active[SNDRV_PCM_STREAM_CAPTURE],
snd_soc_dai_active(codec_dai)); snd_soc_dai_active(codec_dai));
if (!snd_soc_dai_active(codec_dai)) { if (!snd_soc_dai_active(codec_dai)) {
@ -1080,7 +1080,7 @@ int ac101_hw_params(struct snd_pcm_substream *substream,
freq_out = _FREQ_24_576K; freq_out = _FREQ_24_576K;
for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) { for (i = 0; i < ARRAY_SIZE(codec_aif1_fs); i++) {
if (codec_aif1_fs[i].samp_rate == params_rate(params)) { if (codec_aif1_fs[i].samp_rate == params_rate(params)) {
if (codec_dai->stream[SNDRV_PCM_STREAM_CAPTURE].active && dmic_used && codec_aif1_fs[i].samp_rate == 44100) { if (codec_dai->stream_active[SNDRV_PCM_STREAM_CAPTURE] && dmic_used && codec_aif1_fs[i].samp_rate == 44100) {
ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x4<<AIF1_FS)); ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), (0x4<<AIF1_FS));
} else { } else {
ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), ((codec_aif1_fs[i].srbit)<<AIF1_FS)); ac101_update_bits(codec, AIF_SR_CTRL, (0xf<<AIF1_FS), ((codec_aif1_fs[i].srbit)<<AIF1_FS));
@ -1280,13 +1280,11 @@ int ac101_trigger(struct snd_pcm_substream *substream, int cmd,
ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1), (0x1<<MOD_RESET_AIF1)); ret = ret || ac101_update_bits(codec, MOD_RST_CTRL, (0x1<<MOD_RESET_AIF1), (0x1<<MOD_RESET_AIF1));
} }
spin_unlock_irqrestore(&ac10x->lock, flags); spin_unlock_irqrestore(&ac10x->lock, flags);
ac101_set_clock(1, substream, cmd, dai);
#endif #endif
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
ac101_set_clock(0, NULL, 0, NULL);
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;

40
ac108.c
View file

@ -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__, dev_dbg(dai->dev, "%s() stream=%s play:%d capt:%d +++\n", __func__,
snd_pcm_stream_str(substream), snd_pcm_stream_str(substream),
dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active, dai->stream[SNDRV_PCM_STREAM_CAPTURE].active); dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]);
if (ac10x->i2c101) { if (ac10x->i2c101) {
ret = ac101_hw_params(substream, params, dai); 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[SNDRV_PCM_STREAM_PLAYBACK].active) if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE && dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK])
|| (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai->stream[SNDRV_PCM_STREAM_CAPTURE].active)) { || (substream->stream == SNDRV_PCM_STREAM_PLAYBACK && dai->stream_active[SNDRV_PCM_STREAM_CAPTURE])) {
/* not configure hw_param twice */ /* not configure hw_param twice */
/* return 0; */ /* return 0; */
} }
@ -999,7 +999,7 @@ static int ac108_set_clock(int y_start_n_stop, struct snd_pcm_substream *substre
/* spin_lock move to machine trigger */ /* spin_lock move to machine trigger */
if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) { if (y_start_n_stop && ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
ac101_trigger(substream, cmd, dai); ac101_trigger(substream, cmd, dai);
} }
if (y_start_n_stop && ac10x->sysclk_en == 0) { if (y_start_n_stop && ac10x->sysclk_en == 0) {
@ -1073,12 +1073,15 @@ static int ac108_trigger(struct snd_pcm_substream *substream, int cmd,
ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x0 << TXEN | 0x0 << GEN, ac10x); ac108_multi_update_bits(I2S_CTRL, 0x1 << TXEN | 0x1 << GEN, 0x0 << TXEN | 0x0 << GEN, ac10x);
} }
spin_unlock_irqrestore(&ac10x->lock, flags); spin_unlock_irqrestore(&ac10x->lock, flags);
ac108_set_clock(1, substream, cmd, dai);
/* delayed clock starting, move to machine trigger() */
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
ac108_set_clock(0, substream, cmd, dai); if (ac10x->i2c101 && _MASTER_MULTI_CODEC == _MASTER_AC101) {
ac101_trigger(substream, cmd, dai);
}
break; break;
default: default:
ret = -EINVAL; ret = -EINVAL;
@ -1407,15 +1410,7 @@ static const struct regmap_config ac108_regmap = {
.max_register = 0xDF, .max_register = 0xDF,
.cache_type = REGCACHE_FLAT, .cache_type = REGCACHE_FLAT,
}; };
static const struct i2c_device_id ac108_i2c_id[] = { static int ac108_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) {
{ "ac108_0", 0 },
{ "ac108_1", 1 },
{ "ac108_2", 2 },
{ "ac108_3", 3 },
{ "ac101", AC101_I2C_ID },
{ }
};
static int ac108_i2c_probe(struct i2c_client *i2c) {
struct device_node *np = i2c->dev.of_node; struct device_node *np = i2c->dev.of_node;
unsigned int val = 0; unsigned int val = 0;
int ret = 0, index; int ret = 0, index;
@ -1428,11 +1423,11 @@ static int ac108_i2c_probe(struct i2c_client *i2c) {
} }
} }
index = (int)i2c_match_id(ac108_i2c_id, i2c)->driver_data; index = (int)i2c_id->driver_data;
if (index == AC101_I2C_ID) { if (index == AC101_I2C_ID) {
ac10x->i2c101 = i2c; ac10x->i2c101 = i2c;
i2c_set_clientdata(i2c, ac10x); i2c_set_clientdata(i2c, ac10x);
ret = ac101_probe(i2c, i2c_match_id(ac108_i2c_id, i2c)); ret = ac101_probe(i2c, i2c_id);
if (ret) { if (ret) {
ac10x->i2c101 = NULL; ac10x->i2c101 = NULL;
return ret; return ret;
@ -1498,7 +1493,7 @@ __ret:
return ret; return ret;
} }
static void ac108_i2c_remove(struct i2c_client *i2c) { static int ac108_i2c_remove(struct i2c_client *i2c) {
if (ac10x->codec != NULL) { if (ac10x->codec != NULL) {
snd_soc_unregister_codec(&ac10x->i2c[_MASTER_INDEX]->dev); snd_soc_unregister_codec(&ac10x->i2c[_MASTER_INDEX]->dev);
ac10x->codec = NULL; ac10x->codec = NULL;
@ -1523,8 +1518,17 @@ __ret:
kfree(ac10x); kfree(ac10x);
ac10x = NULL; ac10x = NULL;
} }
return 0;
} }
static const struct i2c_device_id ac108_i2c_id[] = {
{ "ac108_0", 0 },
{ "ac108_1", 1 },
{ "ac108_2", 2 },
{ "ac108_3", 3 },
{ "ac101", AC101_I2C_ID },
{ }
};
MODULE_DEVICE_TABLE(i2c, ac108_i2c_id); MODULE_DEVICE_TABLE(i2c, ac108_i2c_id);
static const struct of_device_id ac108_of_match[] = { static const struct of_device_id ac108_of_match[] = {

View file

@ -67,10 +67,8 @@ function get_kernel_version() {
[ -z "$_VER_RUN" ] && { [ -z "$_VER_RUN" ] && {
ZIMAGE=/boot/kernel.img ZIMAGE=/boot/kernel.img
[ -f /boot/firmware/vmlinuz ] && ZIMAGE=/boot/firmware/vmlinuz [ -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) 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; }') _VER_RUN=$(dd if=$ZIMAGE obs=64K ibs=4 skip=$(( IMG_OFFSET / 4)) 2>/dev/null | zcat | grep -a -m1 "Linux version" | strings | awk '{ print $3; }')
} }
echo "$_VER_RUN" echo "$_VER_RUN"
return 0 return 0
@ -78,11 +76,11 @@ function get_kernel_version() {
function check_kernel_headers() { function check_kernel_headers() {
VER_RUN=$(get_kernel_version) VER_RUN=$(get_kernel_version)
VER_HDR=$(dpkg -L raspberrypi-kernel-headers | egrep -m1 "/lib/modules/[^\/]+/build" | awk -F'/' '{ print $4; }') VER_HDR=$(dpkg -L raspberrypi-kernel-headers | egrep -m1 "/lib/modules/[^-]+/build" | awk -F'/' '{ print $4; }')
[ "X$VER_RUN" == "X$VER_HDR" ] && { [ "X$VER_RUN" == "X$VER_HDR" ] && {
return 0 return 0
} }
VER_HDR=$(dpkg -L linux-headers-$VER_RUN | egrep -m1 "/lib/modules/[^\/]+/build" | awk -F'/' '{ print $4; }') VER_HDR=$(dpkg -L linux-headers-$VER_RUN | egrep -m1 "/lib/modules/[[:print:]]+/build" | awk -F'/' '{ print $4; }')
[ "X$VER_RUN" == "X$VER_HDR" ] && { [ "X$VER_RUN" == "X$VER_HDR" ] && {
return 0 return 0
} }
@ -108,8 +106,6 @@ if [[ $? -eq 0 ]]; then
apt update -y apt update -y
# Raspbian kernel packages # Raspbian kernel packages
apt-get -y install raspberrypi-kernel-headers raspberrypi-kernel 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 # Ubuntu kernel packages
apt-get -y install linux-raspi linux-headers-raspi linux-image-raspi apt-get -y install linux-raspi linux-headers-raspi linux-image-raspi
apt-get -y install dkms git i2c-tools libasound2-plugins apt-get -y install dkms git i2c-tools libasound2-plugins
@ -181,7 +177,6 @@ grep -q "^snd-soc-wm8960$" /etc/modules || \
#set dtoverlays #set dtoverlays
CONFIG=/boot/config.txt CONFIG=/boot/config.txt
[ -f /boot/firmware/config.txt ] && CONFIG=/boot/firmware/config.txt
[ -f /boot/firmware/usercfg.txt ] && CONFIG=/boot/firmware/usercfg.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 sed -i -e 's:#dtparam=i2c_arm=on:dtparam=i2c_arm=on:g' $CONFIG || true

View file

@ -42,9 +42,7 @@ function get_kernel_version() {
[ -z "$_VER_RUN" ] && { [ -z "$_VER_RUN" ] && {
ZIMAGE=/boot/kernel.img ZIMAGE=/boot/kernel.img
IMG_OFFSET=$(LC_ALL=C grep -abo $'\x1f\x8b\x08\x00' $ZIMAGE | head -n 1 | cut -d ':' -f 1) IMG_OFFSET=$(LC_ALL=C grep -abo $'\x1f\x8b\x08\x00' $ZIMAGE | head -n 1 | cut -d ':' -f 1)
# 64-bit-only kernel package _VER_RUN=$(dd if=$ZIMAGE obs=64K ibs=4 skip=$(( IMG_OFFSET / 4)) | zcat | grep -a -m1 "Linux version" | strings | awk '{ print $3; }')
[ ! -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" echo "$_VER_RUN"
return 0 return 0

View file

@ -220,7 +220,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", dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd, __FUNCTION__, snd_pcm_stream_str(substream), cmd,
dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active, dai->stream[SNDRV_PCM_STREAM_CAPTURE].active); dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE]);
switch (cmd) { switch (cmd) {
case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_START:
@ -231,8 +231,8 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
/* I know it will degrades performance, but I have no choice */ /* I know it will degrades performance, but I have no choice */
spin_lock_irqsave(&priv->lock, flags); spin_lock_irqsave(&priv->lock, flags);
#endif #endif
// if (_set_clock[SNDRV_PCM_STREAM_CAPTURE]) _set_clock[SNDRV_PCM_STREAM_CAPTURE](1, substream, cmd, dai); 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 (_set_clock[SNDRV_PCM_STREAM_PLAYBACK]) _set_clock[SNDRV_PCM_STREAM_PLAYBACK](1, substream, cmd, dai);
#if CONFIG_AC10X_TRIG_LOCK #if CONFIG_AC10X_TRIG_LOCK
spin_unlock_irqrestore(&priv->lock, flags); spin_unlock_irqrestore(&priv->lock, flags);
#endif #endif
@ -242,7 +242,7 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
/* capture channel resync, if overrun */ /* capture channel resync, if overrun */
if (dai->stream[SNDRV_PCM_STREAM_CAPTURE].active && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (dai->stream_active[SNDRV_PCM_STREAM_CAPTURE] && substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
break; break;
} }
@ -252,8 +252,8 @@ static int seeed_voice_card_trigger(struct snd_pcm_substream *substream, int cmd
if (0 != schedule_work(&priv->work_codec_clk)) { if (0 != schedule_work(&priv->work_codec_clk)) {
} }
} else { } 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_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 */ 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; break;
default: default:
@ -262,7 +262,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", dev_dbg(rtd->card->dev, "%s() stream=%s cmd=%d play:%d, capt:%d;finished %d\n",
__FUNCTION__, snd_pcm_stream_str(substream), cmd, __FUNCTION__, snd_pcm_stream_str(substream), cmd,
dai->stream[SNDRV_PCM_STREAM_PLAYBACK].active, dai->stream[SNDRV_PCM_STREAM_CAPTURE].active, ret); dai->stream_active[SNDRV_PCM_STREAM_PLAYBACK], dai->stream_active[SNDRV_PCM_STREAM_CAPTURE], ret);
return ret; return ret;
} }
@ -311,7 +311,7 @@ static int asoc_simple_parse_dai(struct device_node *node,
* 2) user need to rebind Sound Card everytime * 2) user need to rebind Sound Card everytime
* if he unbinded CPU or Codec. * if he unbinded CPU or Codec.
*/ */
ret = snd_soc_of_get_dai_name(node, &dlc->dai_name, 0); ret = snd_soc_of_get_dai_name(node, &dlc->dai_name);
if (ret < 0) if (ret < 0)
return ret; return ret;
@ -396,14 +396,8 @@ static int asoc_simple_init_dai_link_params(struct snd_soc_pcm_runtime *rtd)
params->channels_min = hw.channels_min; params->channels_min = hw.channels_min;
params->channels_max = hw.channels_max; 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->params = params;
dai_link->num_params = 1; dai_link->num_params = 1;
#endif
return 0; return 0;
} }

View file

@ -14,7 +14,6 @@ fi
uname_r=$(uname -r) uname_r=$(uname -r)
CONFIG=/boot/config.txt CONFIG=/boot/config.txt
[ -f /boot/firmware/config.txt ] && CONFIG=/boot/firmware/config.txt
[ -f /boot/firmware/usercfg.txt ] && CONFIG=/boot/firmware/usercfg.txt [ -f /boot/firmware/usercfg.txt ] && CONFIG=/boot/firmware/usercfg.txt
get_overlay() { get_overlay() {

View file

@ -1318,7 +1318,8 @@ static void wm8960_set_pdata_from_of(struct i2c_client *i2c,
pdata->shared_lrclk = true; pdata->shared_lrclk = true;
} }
static int wm8960_i2c_probe(struct i2c_client *i2c) static int wm8960_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{ {
struct wm8960_data *pdata = dev_get_platdata(&i2c->dev); struct wm8960_data *pdata = dev_get_platdata(&i2c->dev);
struct wm8960_priv *wm8960; struct wm8960_priv *wm8960;
@ -1383,9 +1384,10 @@ static int wm8960_i2c_probe(struct i2c_client *i2c)
return ret; return ret;
} }
static void wm8960_i2c_remove(struct i2c_client *client) static int wm8960_i2c_remove(struct i2c_client *client)
{ {
snd_soc_unregister_codec(&client->dev); snd_soc_unregister_codec(&client->dev);
return 0;
} }
static const struct i2c_device_id wm8960_i2c_id[] = { static const struct i2c_device_id wm8960_i2c_id[] = {