Move: simple-audio-card -> seeed-voicecard, module removing & inserting again supported
This commit is contained in:
parent
d660a92d73
commit
d0d9107c91
12 changed files with 141 additions and 191 deletions
6
Makefile
6
Makefile
|
@ -1,11 +1,11 @@
|
||||||
snd-soc-wm8960-objs := wm8960.o
|
snd-soc-wm8960-objs := wm8960.o
|
||||||
snd-soc-ac108-objs := ac108.o ac101.o
|
snd-soc-ac108-objs := ac108.o ac101.o
|
||||||
snd-soc-simple-card-objs := simple-card.o
|
snd-soc-seeed-voicecard-objs := seeed-voicecard.o
|
||||||
|
|
||||||
|
|
||||||
obj-m += snd-soc-wm8960.o
|
obj-m += snd-soc-wm8960.o
|
||||||
obj-m += snd-soc-ac108.o
|
obj-m += snd-soc-ac108.o
|
||||||
obj-m += snd-soc-simple-card.o
|
obj-m += snd-soc-seeed-voicecard.o
|
||||||
|
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
ifneq ($(DEBUG),0)
|
ifneq ($(DEBUG),0)
|
||||||
|
@ -23,5 +23,5 @@ clean:
|
||||||
install:
|
install:
|
||||||
sudo cp snd-soc-ac108.ko /lib/modules/$(shell uname -r)/kernel/sound/soc/codecs/
|
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-wm8960.ko /lib/modules/$(shell uname -r)/kernel/sound/soc/codecs/
|
||||||
sudo cp snd-soc-simple-card.ko /lib/modules/$(shell uname -r)/kernel/sound/soc/generic/
|
sudo cp snd-soc-seeed-voicecard.ko /lib/modules/$(shell uname -r)/kernel/sound/soc/bcm/
|
||||||
sudo depmod -a
|
sudo depmod -a
|
||||||
|
|
7
ac101.c
7
ac101.c
|
@ -675,7 +675,7 @@ static int ac101_aif1clk(struct snd_soc_codec* codec, int event, int quick) {
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* spin_lock move to simple_card_trigger */
|
/* spin_lock move to machine trigger */
|
||||||
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
case SND_SOC_DAPM_PRE_PMU:
|
case SND_SOC_DAPM_PRE_PMU:
|
||||||
|
@ -1437,7 +1437,7 @@ int ac101_codec_probe(struct snd_soc_codec *codec)
|
||||||
mutex_init(&ac10x->dac_mutex);
|
mutex_init(&ac10x->dac_mutex);
|
||||||
|
|
||||||
#if _MASTER_MULTI_CODEC == _MASTER_AC101
|
#if _MASTER_MULTI_CODEC == _MASTER_AC101
|
||||||
asoc_simple_card_register_set_clock(SNDRV_PCM_STREAM_PLAYBACK, ac101_set_clock);
|
seeed_voice_card_register_set_clock(SNDRV_PCM_STREAM_PLAYBACK, ac101_set_clock);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
set_configuration(ac10x->codec);
|
set_configuration(ac10x->codec);
|
||||||
|
@ -1476,12 +1476,11 @@ int ac101_codec_remove(struct snd_soc_codec *codec)
|
||||||
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
struct ac10x_priv *ac10x = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
if (ac10x->irq) {
|
if (ac10x->irq) {
|
||||||
devm_free_irq(codec->dev, ac10x->irq, NULL);
|
/* devm_free_irq(codec->dev, ac10x->irq, NULL); */
|
||||||
ac10x->irq = 0;
|
ac10x->irq = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
ac108.c
31
ac108.c
|
@ -987,7 +987,7 @@ static int ac108_set_clock(int y_start_n_stop) {
|
||||||
|
|
||||||
dev_dbg(ac10x->codec->dev, "%s() L%d cmd:%d\n", __func__, __LINE__, y_start_n_stop);
|
dev_dbg(ac10x->codec->dev, "%s() L%d cmd:%d\n", __func__, __LINE__, y_start_n_stop);
|
||||||
|
|
||||||
/* spin_lock move to simple_card_trigger */
|
/* spin_lock move to machine trigger */
|
||||||
|
|
||||||
if (y_start_n_stop) {
|
if (y_start_n_stop) {
|
||||||
if (ac10x->sysclk_en == 0) {
|
if (ac10x->sysclk_en == 0) {
|
||||||
|
@ -1069,7 +1069,7 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* delayed clock starting, move to simple_card_trigger() */
|
/* 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:
|
||||||
|
@ -1389,7 +1389,7 @@ static int ac108_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i
|
||||||
int ret = 0, index;
|
int ret = 0, index;
|
||||||
|
|
||||||
if (ac10x == NULL) {
|
if (ac10x == NULL) {
|
||||||
ac10x = devm_kzalloc(&i2c->dev, sizeof(struct ac10x_priv), GFP_KERNEL);
|
ac10x = kzalloc(sizeof(struct ac10x_priv), GFP_KERNEL);
|
||||||
if (ac10x == NULL) {
|
if (ac10x == NULL) {
|
||||||
dev_err(&i2c->dev, "Unable to allocate ac10x private data\n");
|
dev_err(&i2c->dev, "Unable to allocate ac10x private data\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -1450,7 +1450,7 @@ __ret:
|
||||||
/* It's time to bind codec to i2c[_MASTER_INDEX] when all i2c are ready */
|
/* It's time to bind codec to i2c[_MASTER_INDEX] when all i2c are ready */
|
||||||
if ((ac10x->codec_cnt != 0 && ac10x->tdm_chips_cnt < 2)
|
if ((ac10x->codec_cnt != 0 && ac10x->tdm_chips_cnt < 2)
|
||||||
|| (ac10x->i2c[0] && ac10x->i2c[1] && ac10x->i2c101)) {
|
|| (ac10x->i2c[0] && ac10x->i2c[1] && ac10x->i2c101)) {
|
||||||
asoc_simple_card_register_set_clock(SNDRV_PCM_STREAM_CAPTURE, ac108_set_clock);
|
seeed_voice_card_register_set_clock(SNDRV_PCM_STREAM_CAPTURE, ac108_set_clock);
|
||||||
/* no playback stream */
|
/* no playback stream */
|
||||||
if (! ac10x->i2c101) {
|
if (! ac10x->i2c101) {
|
||||||
memset(&ac108_dai[_MASTER_INDEX]->playback, '\0', sizeof ac108_dai[_MASTER_INDEX]->playback);
|
memset(&ac108_dai[_MASTER_INDEX]->playback, '\0', sizeof ac108_dai[_MASTER_INDEX]->playback);
|
||||||
|
@ -1465,13 +1465,30 @@ __ret:
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ac108_i2c_remove(struct i2c_client *i2c) {
|
static int ac108_i2c_remove(struct i2c_client *i2c) {
|
||||||
if (ac10x->i2c101) {
|
|
||||||
ac101_remove(ac10x->i2c101);
|
|
||||||
}
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
if (i2c == ac10x->i2c101) {
|
||||||
|
ac101_remove(ac10x->i2c101);
|
||||||
|
ac10x->i2c101 = NULL;
|
||||||
|
goto __ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i2c == ac10x->i2c[0]) {
|
||||||
|
ac10x->i2c[0] = NULL;
|
||||||
|
}
|
||||||
|
if (i2c == ac10x->i2c[1]) {
|
||||||
|
ac10x->i2c[1] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sysfs_remove_group(&i2c->dev.kobj, &ac108_debug_attr_group);
|
||||||
|
|
||||||
|
__ret:
|
||||||
|
if (!ac10x->i2c[0] && !ac10x->i2c[1] && !ac10x->i2c101) {
|
||||||
|
kfree(ac10x);
|
||||||
|
ac10x = NULL;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
ac10x.h
4
ac10x.h
|
@ -113,8 +113,8 @@ int ac101_probe(struct i2c_client *i2c, const struct i2c_device_id *id);
|
||||||
void ac101_shutdown(struct i2c_client *i2c);
|
void ac101_shutdown(struct i2c_client *i2c);
|
||||||
int ac101_remove(struct i2c_client *i2c);
|
int ac101_remove(struct i2c_client *i2c);
|
||||||
|
|
||||||
/* simple card export */
|
/* seeed voice card export */
|
||||||
int asoc_simple_card_register_set_clock(int stream, int (*set_clock)(int));
|
int seeed_voice_card_register_set_clock(int stream, int (*set_clock)(int));
|
||||||
|
|
||||||
int ac10x_fill_regcache(struct device* dev, struct regmap* map);
|
int ac10x_fill_regcache(struct device* dev, struct regmap* map);
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ PACKAGE_NAME="seeed-voicecard"
|
||||||
PACKAGE_VERSION="0.3"
|
PACKAGE_VERSION="0.3"
|
||||||
BUILT_MODULE_NAME[0]="snd-soc-wm8960"
|
BUILT_MODULE_NAME[0]="snd-soc-wm8960"
|
||||||
BUILT_MODULE_NAME[1]="snd-soc-ac108"
|
BUILT_MODULE_NAME[1]="snd-soc-ac108"
|
||||||
BUILT_MODULE_NAME[2]="snd-soc-simple-card"
|
BUILT_MODULE_NAME[2]="snd-soc-seeed-voicecard"
|
||||||
DEST_MODULE_LOCATION[0]="/kernel/sound/soc/codecs"
|
DEST_MODULE_LOCATION[0]="/kernel/sound/soc/codecs"
|
||||||
DEST_MODULE_LOCATION[1]="/kernel/sound/soc/codecs"
|
DEST_MODULE_LOCATION[1]="/kernel/sound/soc/codecs"
|
||||||
DEST_MODULE_LOCATION[2]="/kernel/sound/soc/generic"
|
DEST_MODULE_LOCATION[2]="/kernel/sound/soc/bcm"
|
||||||
AUTOINSTALL="yes"
|
AUTOINSTALL="yes"
|
||||||
|
|
|
@ -60,8 +60,8 @@ cp seeed-8mic-voicecard.dtbo /boot/overlays
|
||||||
# install -D ac108_plugin/libasound_module_pcm_ac108.so /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_ac108.so
|
# install -D ac108_plugin/libasound_module_pcm_ac108.so /usr/lib/arm-linux-gnueabihf/alsa-lib/libasound_module_pcm_ac108.so
|
||||||
|
|
||||||
#set kernel moduels
|
#set kernel moduels
|
||||||
grep -q "snd-soc-simple-card" /etc/modules || \
|
grep -q "snd-soc-seeed-voicecard" /etc/modules || \
|
||||||
echo "snd-soc-simple-card" >> /etc/modules
|
echo "snd-soc-seeed-voicecard" >> /etc/modules
|
||||||
grep -q "snd-soc-ac108" /etc/modules || \
|
grep -q "snd-soc-ac108" /etc/modules || \
|
||||||
echo "snd-soc-ac108" >> /etc/modules
|
echo "snd-soc-ac108" >> /etc/modules
|
||||||
grep -q "snd-soc-wm8960" /etc/modules || \
|
grep -q "snd-soc-wm8960" /etc/modules || \
|
||||||
|
|
|
@ -44,24 +44,24 @@
|
||||||
target = <&sound>;
|
target = <&sound>;
|
||||||
|
|
||||||
sound_overlay: __overlay__ {
|
sound_overlay: __overlay__ {
|
||||||
compatible = "simple-audio-card";
|
compatible = "seeed-voicecard";
|
||||||
simple-audio-card,format = "dsp_a";
|
seeed-voice-card,format = "dsp_a";
|
||||||
simple-audio-card,name = "seeed-4mic-voicecard";
|
seeed-voice-card,name = "seeed-4mic-voicecard";
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
simple-audio-card,bitclock-master = <&codec_dai>;
|
seeed-voice-card,bitclock-master = <&codec_dai>;
|
||||||
simple-audio-card,frame-master = <&codec_dai>;
|
seeed-voice-card,frame-master = <&codec_dai>;
|
||||||
simple-audio-card,channels-playback-override = <4>;
|
seeed-voice-card,channels-playback-override = <4>;
|
||||||
simple-audio-card,channels-capture-override = <4>;
|
seeed-voice-card,channels-capture-override = <4>;
|
||||||
|
|
||||||
cpu_dai: simple-audio-card,cpu {
|
cpu_dai: seeed-voice-card,cpu {
|
||||||
sound-dai = <&i2s>;
|
sound-dai = <&i2s>;
|
||||||
dai-tdm-slot-num = <2>;
|
dai-tdm-slot-num = <2>;
|
||||||
dai-tdm-slot-width = <32>;
|
dai-tdm-slot-width = <32>;
|
||||||
dai-tdm-slot-tx-mask = <1 1 0 0>;
|
dai-tdm-slot-tx-mask = <1 1 0 0>;
|
||||||
dai-tdm-slot-rx-mask = <1 1 0 0>;
|
dai-tdm-slot-rx-mask = <1 1 0 0>;
|
||||||
};
|
};
|
||||||
codec_dai: simple-audio-card,codec {
|
codec_dai: seeed-voice-card,codec {
|
||||||
sound-dai = <&ac108_a>;
|
sound-dai = <&ac108_a>;
|
||||||
clocks = <&ac108_mclk>;
|
clocks = <&ac108_mclk>;
|
||||||
};
|
};
|
||||||
|
@ -69,7 +69,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
__overrides__ {
|
__overrides__ {
|
||||||
card-name = <&sound_overlay>,"seeed-voicecard,name";
|
card-name = <&sound_overlay>,"seeed-voice-card,name";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -76,13 +76,13 @@
|
||||||
target = <&sound>;
|
target = <&sound>;
|
||||||
|
|
||||||
sound_overlay: __overlay__ {
|
sound_overlay: __overlay__ {
|
||||||
compatible = "simple-audio-card";
|
compatible = "seeed-voicecard";
|
||||||
simple-audio-card,name = "seeed-8mic-voicecard";
|
seeed-voice-card,name = "seeed-8mic-voicecard";
|
||||||
simple-audio-card,channels-playback-override = <8>;
|
seeed-voice-card,channels-playback-override = <8>;
|
||||||
simple-audio-card,channels-capture-override = <8>;
|
seeed-voice-card,channels-capture-override = <8>;
|
||||||
status = "okay";
|
status = "okay";
|
||||||
|
|
||||||
simple-audio-card,dai-link@0 {
|
seeed-voice-card,dai-link@0 {
|
||||||
format = "dsp_a";
|
format = "dsp_a";
|
||||||
bitclock-master = <&codec0_dai>;
|
bitclock-master = <&codec0_dai>;
|
||||||
frame-master = <&codec0_dai>;
|
frame-master = <&codec0_dai>;
|
||||||
|
@ -107,7 +107,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
__overrides__ {
|
__overrides__ {
|
||||||
card-name = <&sound_overlay>,"seeed-voicecard,name";
|
card-name = <&sound_overlay>,"seeed-voice-card,name";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Binary file not shown.
|
@ -1,5 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* ASoC simple sound card support
|
* 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.
|
* Copyright (C) 2012 Renesas Solutions Corp.
|
||||||
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
* Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
|
||||||
|
@ -18,10 +23,9 @@
|
||||||
#include <linux/of_gpio.h>
|
#include <linux/of_gpio.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <sound/jack.h>
|
|
||||||
#include <sound/simple_card.h>
|
|
||||||
#include <sound/soc-dai.h>
|
|
||||||
#include <sound/soc.h>
|
#include <sound/soc.h>
|
||||||
|
#include <sound/soc-dai.h>
|
||||||
|
#include <sound/simple_card_utils.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* single codec:
|
* single codec:
|
||||||
|
@ -30,15 +34,9 @@
|
||||||
*/
|
*/
|
||||||
#define _SINGLE_CODEC 1
|
#define _SINGLE_CODEC 1
|
||||||
|
|
||||||
struct asoc_simple_jack {
|
struct seeed_card_data {
|
||||||
struct snd_soc_jack jack;
|
|
||||||
struct snd_soc_jack_pin pin;
|
|
||||||
struct snd_soc_jack_gpio gpio;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct simple_card_data {
|
|
||||||
struct snd_soc_card snd_card;
|
struct snd_soc_card snd_card;
|
||||||
struct simple_dai_props {
|
struct seeed_dai_props {
|
||||||
struct asoc_simple_dai cpu_dai;
|
struct asoc_simple_dai cpu_dai;
|
||||||
struct asoc_simple_dai codec_dai;
|
struct asoc_simple_dai codec_dai;
|
||||||
unsigned int mclk_fs;
|
unsigned int mclk_fs;
|
||||||
|
@ -48,87 +46,35 @@ struct simple_card_data {
|
||||||
unsigned channels_playback_override;
|
unsigned channels_playback_override;
|
||||||
unsigned channels_capture_default;
|
unsigned channels_capture_default;
|
||||||
unsigned channels_capture_override;
|
unsigned channels_capture_override;
|
||||||
struct asoc_simple_jack hp_jack;
|
|
||||||
struct asoc_simple_jack mic_jack;
|
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define simple_priv_to_dev(priv) ((priv)->snd_card.dev)
|
struct seeed_card_info {
|
||||||
#define simple_priv_to_link(priv, i) ((priv)->snd_card.dai_link + (i))
|
const char *name;
|
||||||
#define simple_priv_to_props(priv, i) ((priv)->dai_props + (i))
|
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_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 DAI "sound-dai"
|
||||||
#define CELL "#sound-dai-cells"
|
#define CELL "#sound-dai-cells"
|
||||||
#define PREFIX "simple-audio-card,"
|
#define PREFIX "seeed-voice-card,"
|
||||||
|
|
||||||
#define asoc_simple_card_init_hp(card, sjack, prefix)\
|
static int seeed_voice_card_startup(struct snd_pcm_substream *substream)
|
||||||
asoc_simple_card_init_jack(card, sjack, 1, prefix)
|
|
||||||
#define asoc_simple_card_init_mic(card, sjack, prefix)\
|
|
||||||
asoc_simple_card_init_jack(card, sjack, 0, prefix)
|
|
||||||
static int asoc_simple_card_init_jack(struct snd_soc_card *card,
|
|
||||||
struct asoc_simple_jack *sjack,
|
|
||||||
int is_hp, char *prefix)
|
|
||||||
{
|
|
||||||
struct device *dev = card->dev;
|
|
||||||
enum of_gpio_flags flags;
|
|
||||||
char prop[128];
|
|
||||||
char *pin_name;
|
|
||||||
char *gpio_name;
|
|
||||||
int mask;
|
|
||||||
int det;
|
|
||||||
|
|
||||||
sjack->gpio.gpio = -ENOENT;
|
|
||||||
|
|
||||||
if (is_hp) {
|
|
||||||
snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
|
|
||||||
pin_name = "Headphones";
|
|
||||||
gpio_name = "Headphone detection";
|
|
||||||
mask = SND_JACK_HEADPHONE;
|
|
||||||
} else {
|
|
||||||
snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
|
|
||||||
pin_name = "Mic Jack";
|
|
||||||
gpio_name = "Mic detection";
|
|
||||||
mask = SND_JACK_MICROPHONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
det = of_get_named_gpio_flags(dev->of_node, prop, 0, &flags);
|
|
||||||
if (det == -EPROBE_DEFER)
|
|
||||||
return -EPROBE_DEFER;
|
|
||||||
|
|
||||||
if (gpio_is_valid(det)) {
|
|
||||||
sjack->pin.pin = pin_name;
|
|
||||||
sjack->pin.mask = mask;
|
|
||||||
|
|
||||||
sjack->gpio.name = gpio_name;
|
|
||||||
sjack->gpio.report = mask;
|
|
||||||
sjack->gpio.gpio = det;
|
|
||||||
sjack->gpio.invert = !!(flags & OF_GPIO_ACTIVE_LOW);
|
|
||||||
sjack->gpio.debounce_time = 150;
|
|
||||||
|
|
||||||
snd_soc_card_jack_new(card, pin_name, mask,
|
|
||||||
&sjack->jack,
|
|
||||||
&sjack->pin, 1);
|
|
||||||
|
|
||||||
snd_soc_jack_add_gpios(&sjack->jack, 1,
|
|
||||||
&sjack->gpio);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void asoc_simple_card_remove_jack(struct asoc_simple_jack *sjack)
|
|
||||||
{
|
|
||||||
if (gpio_is_valid(sjack->gpio.gpio))
|
|
||||||
snd_soc_jack_free_gpios(&sjack->jack, 1, &sjack->gpio);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
|
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||||
struct simple_dai_props *dai_props =
|
struct seeed_dai_props *dai_props =
|
||||||
simple_priv_to_props(priv, rtd->num);
|
seeed_priv_to_props(priv, rtd->num);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = clk_prepare_enable(dai_props->cpu_dai.clk);
|
ret = clk_prepare_enable(dai_props->cpu_dai.clk);
|
||||||
|
@ -153,12 +99,12 @@ static int asoc_simple_card_startup(struct snd_pcm_substream *substream)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
|
static void seeed_voice_card_shutdown(struct snd_pcm_substream *substream)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||||
struct simple_dai_props *dai_props =
|
struct seeed_dai_props *dai_props =
|
||||||
simple_priv_to_props(priv, rtd->num);
|
seeed_priv_to_props(priv, rtd->num);
|
||||||
|
|
||||||
rtd->cpu_dai->driver->playback.channels_min = priv->channels_playback_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->playback.channels_max = priv->channels_playback_default;
|
||||||
|
@ -170,15 +116,15 @@ static void asoc_simple_card_shutdown(struct snd_pcm_substream *substream)
|
||||||
clk_disable_unprepare(dai_props->codec_dai.clk);
|
clk_disable_unprepare(dai_props->codec_dai.clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asoc_simple_card_hw_params(struct snd_pcm_substream *substream,
|
static int seeed_voice_card_hw_params(struct snd_pcm_substream *substream,
|
||||||
struct snd_pcm_hw_params *params)
|
struct snd_pcm_hw_params *params)
|
||||||
{
|
{
|
||||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||||
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
||||||
struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||||
struct simple_dai_props *dai_props =
|
struct seeed_dai_props *dai_props =
|
||||||
simple_priv_to_props(priv, rtd->num);
|
seeed_priv_to_props(priv, rtd->num);
|
||||||
unsigned int mclk, mclk_fs = 0;
|
unsigned int mclk, mclk_fs = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -207,19 +153,19 @@ err:
|
||||||
#define _SET_CLOCK_CNT 2
|
#define _SET_CLOCK_CNT 2
|
||||||
static int (* _set_clock[_SET_CLOCK_CNT])(int y_start_n_stop);
|
static int (* _set_clock[_SET_CLOCK_CNT])(int y_start_n_stop);
|
||||||
|
|
||||||
int asoc_simple_card_register_set_clock(int stream, int (*set_clock)(int)) {
|
int seeed_voice_card_register_set_clock(int stream, int (*set_clock)(int)) {
|
||||||
if (! _set_clock[stream]) {
|
if (! _set_clock[stream]) {
|
||||||
_set_clock[stream] = set_clock;
|
_set_clock[stream] = set_clock;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(asoc_simple_card_register_set_clock);
|
EXPORT_SYMBOL(seeed_voice_card_register_set_clock);
|
||||||
|
|
||||||
static int asoc_simple_card_trigger(struct snd_pcm_substream *substream, int cmd)
|
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_pcm_runtime *rtd = substream->private_data;
|
||||||
struct snd_soc_dai *dai = rtd->codec_dai;
|
struct snd_soc_dai *dai = rtd->codec_dai;
|
||||||
struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -257,20 +203,20 @@ static int asoc_simple_card_trigger(struct snd_pcm_substream *substream, int cmd
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct snd_soc_ops asoc_simple_card_ops = {
|
static struct snd_soc_ops seeed_voice_card_ops = {
|
||||||
.startup = asoc_simple_card_startup,
|
.startup = seeed_voice_card_startup,
|
||||||
.shutdown = asoc_simple_card_shutdown,
|
.shutdown = seeed_voice_card_shutdown,
|
||||||
.hw_params = asoc_simple_card_hw_params,
|
.hw_params = seeed_voice_card_hw_params,
|
||||||
.trigger = asoc_simple_card_trigger,
|
.trigger = seeed_voice_card_trigger,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
|
static int seeed_voice_card_dai_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
{
|
{
|
||||||
struct simple_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
struct seeed_card_data *priv = snd_soc_card_get_drvdata(rtd->card);
|
||||||
struct snd_soc_dai *codec = rtd->codec_dai;
|
struct snd_soc_dai *codec = rtd->codec_dai;
|
||||||
struct snd_soc_dai *cpu = rtd->cpu_dai;
|
struct snd_soc_dai *cpu = rtd->cpu_dai;
|
||||||
struct simple_dai_props *dai_props =
|
struct seeed_dai_props *dai_props =
|
||||||
simple_priv_to_props(priv, rtd->num);
|
seeed_priv_to_props(priv, rtd->num);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
|
ret = asoc_simple_card_init_dai(codec, &dai_props->codec_dai);
|
||||||
|
@ -281,25 +227,17 @@ static int asoc_simple_card_dai_init(struct snd_soc_pcm_runtime *rtd)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = asoc_simple_card_init_hp(rtd->card, &priv->hp_jack, PREFIX);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = asoc_simple_card_init_mic(rtd->card, &priv->hp_jack, PREFIX);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asoc_simple_card_dai_link_of(struct device_node *node,
|
static int seeed_voice_card_dai_link_of(struct device_node *node,
|
||||||
struct simple_card_data *priv,
|
struct seeed_card_data *priv,
|
||||||
int idx,
|
int idx,
|
||||||
bool is_top_level_node)
|
bool is_top_level_node)
|
||||||
{
|
{
|
||||||
struct device *dev = simple_priv_to_dev(priv);
|
struct device *dev = seeed_priv_to_dev(priv);
|
||||||
struct snd_soc_dai_link *dai_link = simple_priv_to_link(priv, idx);
|
struct snd_soc_dai_link *dai_link = seeed_priv_to_link(priv, idx);
|
||||||
struct simple_dai_props *dai_props = simple_priv_to_props(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 *cpu_dai = &dai_props->cpu_dai;
|
||||||
struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
|
struct asoc_simple_dai *codec_dai = &dai_props->codec_dai;
|
||||||
struct device_node *cpu = NULL;
|
struct device_node *cpu = NULL;
|
||||||
|
@ -409,8 +347,8 @@ static int asoc_simple_card_dai_link_of(struct device_node *node,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto dai_link_of_err;
|
goto dai_link_of_err;
|
||||||
|
|
||||||
dai_link->ops = &asoc_simple_card_ops;
|
dai_link->ops = &seeed_voice_card_ops;
|
||||||
dai_link->init = asoc_simple_card_dai_init;
|
dai_link->init = seeed_voice_card_dai_init;
|
||||||
|
|
||||||
dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
|
dev_dbg(dev, "\tname : %s\n", dai_link->stream_name);
|
||||||
dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
|
dev_dbg(dev, "\tformat : %04x\n", dai_link->dai_fmt);
|
||||||
|
@ -434,10 +372,10 @@ dai_link_of_err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asoc_simple_card_parse_aux_devs(struct device_node *node,
|
static int seeed_voice_card_parse_aux_devs(struct device_node *node,
|
||||||
struct simple_card_data *priv)
|
struct seeed_card_data *priv)
|
||||||
{
|
{
|
||||||
struct device *dev = simple_priv_to_dev(priv);
|
struct device *dev = seeed_priv_to_dev(priv);
|
||||||
struct device_node *aux_node;
|
struct device_node *aux_node;
|
||||||
int i, n, len;
|
int i, n, len;
|
||||||
|
|
||||||
|
@ -464,10 +402,10 @@ static int asoc_simple_card_parse_aux_devs(struct device_node *node,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asoc_simple_card_parse_of(struct device_node *node,
|
static int seeed_voice_card_parse_of(struct device_node *node,
|
||||||
struct simple_card_data *priv)
|
struct seeed_card_data *priv)
|
||||||
{
|
{
|
||||||
struct device *dev = simple_priv_to_dev(priv);
|
struct device *dev = seeed_priv_to_dev(priv);
|
||||||
struct device_node *dai_link;
|
struct device_node *dai_link;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -502,7 +440,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
|
||||||
|
|
||||||
for_each_child_of_node(node, np) {
|
for_each_child_of_node(node, np) {
|
||||||
dev_dbg(dev, "\tlink %d:\n", i);
|
dev_dbg(dev, "\tlink %d:\n", i);
|
||||||
ret = asoc_simple_card_dai_link_of(np, priv,
|
ret = seeed_voice_card_dai_link_of(np, priv,
|
||||||
i, false);
|
i, false);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
of_node_put(np);
|
of_node_put(np);
|
||||||
|
@ -512,7 +450,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* For single DAI link & old style of DT node */
|
/* For single DAI link & old style of DT node */
|
||||||
ret = asoc_simple_card_dai_link_of(node, priv, 0, true);
|
ret = seeed_voice_card_dai_link_of(node, priv, 0, true);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto card_parse_end;
|
goto card_parse_end;
|
||||||
}
|
}
|
||||||
|
@ -521,7 +459,7 @@ static int asoc_simple_card_parse_of(struct device_node *node,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto card_parse_end;
|
goto card_parse_end;
|
||||||
|
|
||||||
ret = asoc_simple_card_parse_aux_devs(node, priv);
|
ret = seeed_voice_card_parse_aux_devs(node, priv);
|
||||||
|
|
||||||
priv->channels_playback_default = 0;
|
priv->channels_playback_default = 0;
|
||||||
priv->channels_playback_override = 2;
|
priv->channels_playback_override = 2;
|
||||||
|
@ -542,11 +480,11 @@ card_parse_end:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asoc_simple_card_probe(struct platform_device *pdev)
|
static int seeed_voice_card_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct simple_card_data *priv;
|
struct seeed_card_data *priv;
|
||||||
struct snd_soc_dai_link *dai_link;
|
struct snd_soc_dai_link *dai_link;
|
||||||
struct simple_dai_props *dai_props;
|
struct seeed_dai_props *dai_props;
|
||||||
struct device_node *np = pdev->dev.of_node;
|
struct device_node *np = pdev->dev.of_node;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
int num, ret;
|
int num, ret;
|
||||||
|
@ -577,18 +515,18 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
|
||||||
priv->snd_card.num_links = num;
|
priv->snd_card.num_links = num;
|
||||||
|
|
||||||
if (np && of_device_is_available(np)) {
|
if (np && of_device_is_available(np)) {
|
||||||
ret = asoc_simple_card_parse_of(np, priv);
|
ret = seeed_voice_card_parse_of(np, priv);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (ret != -EPROBE_DEFER)
|
if (ret != -EPROBE_DEFER)
|
||||||
dev_err(dev, "parse error %d\n", ret);
|
dev_err(dev, "parse error %d\n", ret);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
struct asoc_simple_card_info *cinfo;
|
struct seeed_card_info *cinfo;
|
||||||
|
|
||||||
cinfo = dev->platform_data;
|
cinfo = dev->platform_data;
|
||||||
if (!cinfo) {
|
if (!cinfo) {
|
||||||
dev_err(dev, "no info for asoc-simple-card\n");
|
dev_err(dev, "no info for seeed-voice-card\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -597,7 +535,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
|
||||||
!cinfo->codec ||
|
!cinfo->codec ||
|
||||||
!cinfo->platform ||
|
!cinfo->platform ||
|
||||||
!cinfo->cpu_dai.name) {
|
!cinfo->cpu_dai.name) {
|
||||||
dev_err(dev, "insufficient asoc_simple_card_info settings\n");
|
dev_err(dev, "insufficient seeed_voice_card_info settings\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +547,7 @@ static int asoc_simple_card_probe(struct platform_device *pdev)
|
||||||
dai_link->cpu_dai_name = cinfo->cpu_dai.name;
|
dai_link->cpu_dai_name = cinfo->cpu_dai.name;
|
||||||
dai_link->codec_dai_name = cinfo->codec_dai.name;
|
dai_link->codec_dai_name = cinfo->codec_dai.name;
|
||||||
dai_link->dai_fmt = cinfo->daifmt;
|
dai_link->dai_fmt = cinfo->daifmt;
|
||||||
dai_link->init = asoc_simple_card_dai_init;
|
dai_link->init = seeed_voice_card_dai_init;
|
||||||
memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
|
memcpy(&priv->dai_props->cpu_dai, &cinfo->cpu_dai,
|
||||||
sizeof(priv->dai_props->cpu_dai));
|
sizeof(priv->dai_props->cpu_dai));
|
||||||
memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
|
memcpy(&priv->dai_props->codec_dai, &cinfo->codec_dai,
|
||||||
|
@ -630,36 +568,32 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int asoc_simple_card_remove(struct platform_device *pdev)
|
static int seeed_voice_card_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
struct snd_soc_card *card = platform_get_drvdata(pdev);
|
||||||
struct simple_card_data *priv = snd_soc_card_get_drvdata(card);
|
|
||||||
|
|
||||||
asoc_simple_card_remove_jack(&priv->hp_jack);
|
|
||||||
asoc_simple_card_remove_jack(&priv->mic_jack);
|
|
||||||
|
|
||||||
return asoc_simple_card_clean_reference(card);
|
return asoc_simple_card_clean_reference(card);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id asoc_simple_of_match[] = {
|
static const struct of_device_id seeed_voice_of_match[] = {
|
||||||
{ .compatible = "simple-audio-card", },
|
{ .compatible = "seeed-voicecard", },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, asoc_simple_of_match);
|
MODULE_DEVICE_TABLE(of, seeed_voice_of_match);
|
||||||
|
|
||||||
static struct platform_driver asoc_simple_card = {
|
static struct platform_driver seeed_voice_card = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "asoc-simple-card",
|
.name = "seeed-voicecard",
|
||||||
.pm = &snd_soc_pm_ops,
|
.pm = &snd_soc_pm_ops,
|
||||||
.of_match_table = asoc_simple_of_match,
|
.of_match_table = seeed_voice_of_match,
|
||||||
},
|
},
|
||||||
.probe = asoc_simple_card_probe,
|
.probe = seeed_voice_card_probe,
|
||||||
.remove = asoc_simple_card_remove,
|
.remove = seeed_voice_card_remove,
|
||||||
};
|
};
|
||||||
|
|
||||||
module_platform_driver(asoc_simple_card);
|
module_platform_driver(seeed_voice_card);
|
||||||
|
|
||||||
MODULE_ALIAS("platform:asoc-simple-card");
|
MODULE_ALIAS("platform:seeed-voice-card");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
MODULE_DESCRIPTION("ASoC Simple Sound Card");
|
MODULE_DESCRIPTION("ASoC SEEED Voice Card");
|
||||||
MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
|
MODULE_AUTHOR("PeterYang<linsheng.yang@seeed.cc>");
|
|
@ -25,7 +25,7 @@ rm -rf /etc/voicecard/ || true
|
||||||
echo "disabled seeed-voicecard.service "
|
echo "disabled seeed-voicecard.service "
|
||||||
systemctl disable seeed-voicecard.service
|
systemctl disable seeed-voicecard.service
|
||||||
|
|
||||||
echo "remove seeed-vocecard"
|
echo "remove seeed-voicecard"
|
||||||
rm /usr/bin/seeed-voicecard || true
|
rm /usr/bin/seeed-voicecard || true
|
||||||
rm /lib/systemd/system/seeed-voicecard.service || true
|
rm /lib/systemd/system/seeed-voicecard.service || true
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ rm -rf /var/lib/dkms/seeed-voicecard || true
|
||||||
echo "remove kernel modules"
|
echo "remove kernel modules"
|
||||||
rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-wm8960.ko || true
|
rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-wm8960.ko || true
|
||||||
rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-ac108.ko || true
|
rm /lib/modules/${uname_r}/kernel/sound/soc/codecs/snd-soc-ac108.ko || true
|
||||||
rm /lib/modules/${uname_r}/kernel/sound/soc/generic/snd-soc-simple-card.ko || true
|
rm /lib/modules/${uname_r}/kernel/sound/soc/bcm/snd-soc-seeed-voicecard.ko || true
|
||||||
|
|
||||||
echo "------------------------------------------------------"
|
echo "------------------------------------------------------"
|
||||||
echo "Please reboot your raspberry pi to apply all settings"
|
echo "Please reboot your raspberry pi to apply all settings"
|
||||||
|
|
Loading…
Reference in a new issue