Merge pull request #7 from respeaker/dev

merage dev branch
This commit is contained in:
Baozhu Zuo 2017-09-14 20:24:05 +08:00 committed by GitHub
commit af15d8c5a0
21 changed files with 3764 additions and 38 deletions

View file

@ -1,4 +1,10 @@
obj-m := wm8960.o snd-soc-wm8960-objs := wm8960.o
snd-soc-ac108-objs := ac108.o
obj-m += snd-soc-wm8960.o
obj-m += snd-soc-ac108.o
all: all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
@ -7,5 +13,6 @@ clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
install: install:
sudo cp wm8960.ko /lib/modules/$(shell uname -r) 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 depmod -a sudo depmod -a

View file

@ -4,17 +4,23 @@
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. 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.
We also write ac108 rapberry pi linux kernel driver.
Get the seeed voice card source code. Get the seeed voice card source code.
``` ```
git clone https://github.com/respeaker/seeed-voicecard git clone https://github.com/respeaker/seeed-voicecard
cd seeed-voicecard cd seeed-voicecard
sudo ./install.sh #2mic
sudo ./install.sh 2mic
#4mic
sudo ./install.sh 4mic
reboot reboot
``` ```
Check that the sound card name matches the source code seeed-voicecard. Check that the sound card name matches the source code seeed-voicecard.
``` ```
#2mic
pi@raspberrypi:~/seeed-voicecard$ aplay -l pi@raspberrypi:~/seeed-voicecard$ aplay -l
**** List of PLAYBACK Hardware Devices **** **** List of PLAYBACK Hardware Devices ****
card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA] card 0: ALSA [bcm2835 ALSA], device 0: bcm2835 ALSA [bcm2835 ALSA]
@ -34,16 +40,45 @@ card 1: seeedvoicecard [seeed-voicecard], device 0: bcm2835-i2s-wm8960-hifi wm89
Subdevices: 1/1 Subdevices: 1/1
Subdevice #0: subdevice #0 Subdevice #0: subdevice #0
pi@raspberrypi:~/seeed-voicecard$ pi@raspberrypi:~/seeed-voicecard$
```
Next apply the alsa controls setting #4mic
``` pi@raspberrypi:~ $ arecord -L
sudo alsactl --file=asound.state restore 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. If you want to change the alsa settings, You can use `sudo alsactl --file=asound.state store` to save it.
Test: Test:
``` ```
#2mic
arecord -f cd -Dhw:1 | aplay -Dhw:1 arecord -f cd -Dhw:1 | aplay -Dhw:1
#4mic
arecord -Dac108 -f S32_LE -r 16000 -c 4 a.wav
``` ```
### with Google Assistant ### with Google Assistant

1297
ac108.c Normal file

File diff suppressed because it is too large Load diff

774
ac108.h Executable file
View file

@ -0,0 +1,774 @@
/*
* ac108.h -- ac108 ALSA Soc Audio driver
*
* Author: panjunwen
*
* 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.
*
*/
#ifndef _AC108_H
#define _AC108_H
/*** AC108 Codec Register Define***/
//Chip Reset
#define CHIP_RST 0x00
#define CHIP_RST_VAL 0x12
//Power Control
#define PWR_CTRL1 0x01
#define PWR_CTRL2 0x02
#define PWR_CTRL3 0x03
#define PWR_CTRL4 0x04
#define PWR_CTRL5 0x05
#define PWR_CTRL6 0x06
#define PWR_CTRL7 0x07
#define PWR_CTRL8 0x08
#define PWR_CTRL9 0x09
//PLL Configure Control
#define PLL_CTRL1 0x10
#define PLL_CTRL2 0x11
#define PLL_CTRL3 0x12
#define PLL_CTRL4 0x13
#define PLL_CTRL5 0x14
#define PLL_CTRL6 0x16
#define PLL_CTRL7 0x17
#define PLL_LOCK_CTRL 0x18
//System Clock Control
#define SYSCLK_CTRL 0x20
#define MOD_CLK_EN 0x21
#define MOD_RST_CTRL 0x22
#define DSM_CLK_CTRL 0x25
//I2S Common Control
#define I2S_CTRL 0x30
#define I2S_BCLK_CTRL 0x31
#define I2S_LRCK_CTRL1 0x32
#define I2S_LRCK_CTRL2 0x33
#define I2S_FMT_CTRL1 0x34
#define I2S_FMT_CTRL2 0x35
#define I2S_FMT_CTRL3 0x36
//I2S TX1 Control
#define I2S_TX1_CTRL1 0x38
#define I2S_TX1_CTRL2 0x39
#define I2S_TX1_CTRL3 0x3A
#define I2S_TX1_CHMP_CTRL1 0x3C
#define I2S_TX1_CHMP_CTRL2 0x3D
#define I2S_TX1_CHMP_CTRL3 0x3E
#define I2S_TX1_CHMP_CTRL4 0x3F
//I2S TX2 Control
#define I2S_TX2_CTRL1 0x40
#define I2S_TX2_CTRL2 0x41
#define I2S_TX2_CTRL3 0x42
#define I2S_TX2_CHMP_CTRL1 0x44
#define I2S_TX2_CHMP_CTRL2 0x45
#define I2S_TX2_CHMP_CTRL3 0x46
#define I2S_TX2_CHMP_CTRL4 0x47
//I2S RX1 Control
#define I2S_RX1_CTRL1 0x50
#define I2S_RX1_CHMP_CTRL1 0x54
#define I2S_RX1_CHMP_CTRL2 0x55
#define I2S_RX1_CHMP_CTRL3 0x56
#define I2S_RX1_CHMP_CTRL4 0x57
//I2S Loopback Debug
#define I2S_LPB_DEBUG 0x58
//ADC Common Control
#define ADC_SPRC 0x60
#define ADC_DIG_EN 0x61
#define DMIC_EN 0x62
#define ADC_DSR 0x63
#define ADC_FIR 0x64
#define ADC_DDT_CTRL 0x65
//HPF Control
#define HPF_EN 0x66
#define HPF_COEF_REGH1 0x67
#define HPF_COEF_REGH2 0x68
#define HPF_COEF_REGL1 0x69
#define HPF_COEF_REGL2 0x6A
#define HPF_GAIN_REGH1 0x6B
#define HPF_GAIN_REGH2 0x6C
#define HPF_GAIN_REGL1 0x6D
#define HPF_GAIN_REGL2 0x6E
//ADC Digital Channel Volume Control
#define ADC1_DVOL_CTRL 0x70
#define ADC2_DVOL_CTRL 0x71
#define ADC3_DVOL_CTRL 0x72
#define ADC4_DVOL_CTRL 0x73
//ADC Digital Mixer Source and Gain Control
#define ADC1_DMIX_SRC 0x76
#define ADC2_DMIX_SRC 0x77
#define ADC3_DMIX_SRC 0x78
#define ADC4_DMIX_SRC 0x79
//ADC Digital Debug Control
#define ADC_DIG_DEBUG 0x7F
//I2S Pad Drive Control
#define I2S_DAT_PADDRV_CTRL 0x80
#define I2S_CLK_PADDRV_CTRL 0x81
//Analog PGA Control
#define ANA_PGA1_CTRL 0x90
#define ANA_PGA2_CTRL 0x91
#define ANA_PGA3_CTRL 0x92
#define ANA_PGA4_CTRL 0x93
//MIC Offset Control
#define MIC_OFFSET_CTRL1 0x96
#define MIC_OFFSET_CTRL2 0x97
#define MIC1_OFFSET_STATU1 0x98
#define MIC1_OFFSET_STATU2 0x99
#define MIC2_OFFSET_STATU1 0x9A
#define MIC2_OFFSET_STATU2 0x9B
#define MIC3_OFFSET_STATU1 0x9C
#define MIC3_OFFSET_STATU2 0x9D
#define MIC4_OFFSET_STATU1 0x9E
#define MIC4_OFFSET_STATU2 0x9F
//ADC1 Analog Control
#define ANA_ADC1_CTRL1 0xA0
#define ANA_ADC1_CTRL2 0xA1
#define ANA_ADC1_CTRL3 0xA2
#define ANA_ADC1_CTRL4 0xA3
#define ANA_ADC1_CTRL5 0xA4
#define ANA_ADC1_CTRL6 0xA5
#define ANA_ADC1_CTRL7 0xA6
//ADC2 Analog Control
#define ANA_ADC2_CTRL1 0xA7
#define ANA_ADC2_CTRL2 0xA8
#define ANA_ADC2_CTRL3 0xA9
#define ANA_ADC2_CTRL4 0xAA
#define ANA_ADC2_CTRL5 0xAB
#define ANA_ADC2_CTRL6 0xAC
#define ANA_ADC2_CTRL7 0xAD
//ADC3 Analog Control
#define ANA_ADC3_CTRL1 0xAE
#define ANA_ADC3_CTRL2 0xAF
#define ANA_ADC3_CTRL3 0xB0
#define ANA_ADC3_CTRL4 0xB1
#define ANA_ADC3_CTRL5 0xB2
#define ANA_ADC3_CTRL6 0xB3
#define ANA_ADC3_CTRL7 0xB4
//ADC4 Analog Control
#define ANA_ADC4_CTRL1 0xB5
#define ANA_ADC4_CTRL2 0xB6
#define ANA_ADC4_CTRL3 0xB7
#define ANA_ADC4_CTRL4 0xB8
#define ANA_ADC4_CTRL5 0xB9
#define ANA_ADC4_CTRL6 0xBA
#define ANA_ADC4_CTRL7 0xBB
//GPIO Configure
#define GPIO_CFG1 0xC0
#define GPIO_CFG2 0xC1
#define GPIO_DAT 0xC2
#define GPIO_DRV 0xC3
#define GPIO_PULL 0xC4
#define GPIO_INT_CFG 0xC5
#define GPIO_INT_EN 0xC6
#define GPIO_INT_STATUS 0xC7
//Misc
#define BGTC_DAT 0xD1
#define BGVC_DAT 0xD2
#define PRNG_CLK_CTRL 0xDF
/*** AC108 Codec Register Bit Define***/
/*PWR_CTRL1*/
#define CP12_CTRL 4
#define CP12_SENSE_SELECT 3
/*PWR_CTRL2*/
#define CP12_SENSE_FILT 6
#define CP12_COMP_FF_EN 3
#define CP12_FORCE_ENABLE 2
#define CP12_FORCE_RSTB 1
/*PWR_CTRL3*/
#define LDO33DIG_CTRL 0
/*PWR_CTRL6*/
#define LDO33ANA_2XHDRM 2
#define LDO33ANA_ENABLE 0
/*PWR_CTRL7*/
#define VREF_SEL 3
#define VREF_FASTSTART_ENABLE 1
#define VREF_ENABLE 0
/*PWR_CTRL9*/
#define VREFP_FASTSTART_ENABLE 7
#define VREFP_RESCTRL 5
#define VREFP_LPMODE 4
#define IGEN_TRIM 1
#define VREFP_ENABLE 0
/*PLL_CTRL1*/
#define PLL_IBIAS 4
#define PLL_NDET 3
#define PLL_LOCKED_STATUS 2
#define PLL_COM_EN 1
#define PLL_EN 0
/*PLL_CTRL2*/
#define PLL_PREDIV2 5
#define PLL_PREDIV1 0
/*PLL_CTRL3*/
#define PLL_LOOPDIV_MSB 0
/*PLL_CTRL4*/
#define PLL_LOOPDIV_LSB 0
/*PLL_CTRL5*/
#define PLL_POSTDIV2 5
#define PLL_POSTDIV1 0
/*PLL_CTRL6*/
#define PLL_LDO 6
#define PLL_CP 0
/*PLL_CTRL7*/
#define PLL_CAP 6
#define PLL_RES 4
#define PLL_TEST_EN 0
/*PLL_LOCK_CTRL*/
#define LOCK_LEVEL1 2
#define LOCK_LEVEL2 1
#define PLL_LOCK_EN 0
/*SYSCLK_CTRL*/
#define PLLCLK_EN 7
#define PLLCLK_SRC 4
#define SYSCLK_SRC 3
#define SYSCLK_EN 0
/*MOD_CLK_EN & MOD_RST_CTRL*/
#define I2S 7
#define ADC_DIGITAL 4
#define MIC_OFFSET_CALIBRATION 1
#define ADC_ANALOG 0
/*DSM_CLK_CTRL*/
#define MIC_OFFSET_DIV 4
#define DSM_CLK_SEL 0
/*I2S_CTRL*/
#define BCLK_IOEN 7
#define LRCK_IOEN 6
#define SDO2_EN 5
#define SDO1_EN 4
#define TXEN 2
#define RXEN 1
#define GEN 0
/*I2S_BCLK_CTRL*/
#define EDGE_TRANSFER 5
#define BCLK_POLARITY 4
#define BCLKDIV 0
/*I2S_LRCK_CTRL1*/
#define LRCK_POLARITY 4
#define LRCK_PERIODH 0
/*I2S_LRCK_CTRL2*/
#define LRCK_PERIODL 0
/*I2S_FMT_CTRL1*/
#define ENCD_SEL 6
#define MODE_SEL 4
#define TX2_OFFSET 3
#define TX1_OFFSET 2
#define TX_SLOT_HIZ 1
#define TX_STATE 0
/*I2S_FMT_CTRL2*/
#define SLOT_WIDTH_SEL 4
#define SAMPLE_RESOLUTION 0
/*I2S_FMT_CTRL3*/
#define TX_MLS 7
#define SEXT 5
#define OUT2_MUTE 4
#define OUT1_MUTE 3
#define LRCK_WIDTH 2
#define TX_PDM 0
/*I2S_TX1_CTRL1*/
#define TX1_CHSEL 0
/*I2S_TX1_CTRL2*/
#define TX1_CH8_EN 7
#define TX1_CH7_EN 6
#define TX1_CH6_EN 5
#define TX1_CH5_EN 4
#define TX1_CH4_EN 3
#define TX1_CH3_EN 2
#define TX1_CH2_EN 1
#define TX1_CH1_EN 0
/*I2S_TX1_CTRL3*/
#define TX1_CH16_EN 7
#define TX1_CH15_EN 6
#define TX1_CH14_EN 5
#define TX1_CH13_EN 4
#define TX1_CH12_EN 3
#define TX1_CH11_EN 2
#define TX1_CH10_EN 1
#define TX1_CH9_EN 0
/*I2S_TX1_CHMP_CTRL1*/
#define TX1_CH4_MAP 6
#define TX1_CH3_MAP 4
#define TX1_CH2_MAP 2
#define TX1_CH1_MAP 0
/*I2S_TX1_CHMP_CTRL2*/
#define TX1_CH8_MAP 6
#define TX1_CH7_MAP 4
#define TX1_CH6_MAP 2
#define TX1_CH5_MAP 0
/*I2S_TX1_CHMP_CTRL3*/
#define TX1_CH12_MAP 6
#define TX1_CH11_MAP 4
#define TX1_CH10_MAP 2
#define TX1_CH9_MAP 0
/*I2S_TX1_CHMP_CTRL4*/
#define TX1_CH16_MAP 6
#define TX1_CH15_MAP 4
#define TX1_CH14_MAP 2
#define TX1_CH13_MAP 0
/*I2S_TX2_CTRL1*/
#define TX2_CHSEL 0
/*I2S_TX2_CHMP_CTRL1*/
#define TX2_CH4_MAP 6
#define TX2_CH3_MAP 4
#define TX2_CH2_MAP 2
#define TX2_CH1_MAP 0
/*I2S_TX2_CHMP_CTRL2*/
#define TX2_CH8_MAP 6
#define TX2_CH7_MAP 4
#define TX2_CH6_MAP 2
#define TX2_CH5_MAP 0
/*I2S_TX2_CHMP_CTRL3*/
#define TX2_CH12_MAP 6
#define TX2_CH11_MAP 4
#define TX2_CH10_MAP 2
#define TX2_CH9_MAP 0
/*I2S_TX2_CHMP_CTRL4*/
#define TX2_CH16_MAP 6
#define TX2_CH15_MAP 4
#define TX2_CH14_MAP 2
#define TX2_CH13_MAP 0
/*I2S_RX1_CTRL1*/
#define RX1_CHSEL 0
/*I2S_RX1_CHMP_CTRL1*/
#define RX1_CH4_MAP 6
#define RX1_CH3_MAP 4
#define RX1_CH2_MAP 2
#define RX1_CH1_MAP 0
/*I2S_RX1_CHMP_CTRL2*/
#define RX1_CH8_MAP 6
#define RX1_CH7_MAP 4
#define RX1_CH6_MAP 2
#define RX1_CH5_MAP 0
/*I2S_RX1_CHMP_CTRL3*/
#define RX1_CH12_MAP 6
#define RX1_CH11_MAP 4
#define RX1_CH10_MAP 2
#define RX1_CH9_MAP 0
/*I2S_RX1_CHMP_CTRL4*/
#define RX1_CH16_MAP 6
#define RX1_CH15_MAP 4
#define RX1_CH14_MAP 2
#define RX1_CH13_MAP 0
/*I2S_LPB_DEBUG*/
#define I2S_LPB_DEBUG_EN 0
/*ADC_SPRC*/
#define ADC_FS_I2S1 0
/*ADC_DIG_EN*/
#define DG_EN 4
#define ENAD4 3
#define ENAD3 2
#define ENAD2 1
#define ENAD1 0
/*DMIC_EN*/
#define DMIC2_EN 1
#define DMIC1_EN 0
/*ADC_DSR*/
#define DIG_ADC4_SRS 6
#define DIG_ADC3_SRS 4
#define DIG_ADC2_SRS 2
#define DIG_ADC1_SRS 0
/*ADC_DDT_CTRL*/
#define ADOUT_DLY_EN 2
#define ADOUT_DTS 0
/*HPF_EN*/
#define DIG_ADC4_HPF_EN 3
#define DIG_ADC3_HPF_EN 2
#define DIG_ADC2_HPF_EN 1
#define DIG_ADC1_HPF_EN 0
/*ADC1_DMIX_SRC*/
#define ADC1_ADC4_DMXL_GC 7
#define ADC1_ADC3_DMXL_GC 6
#define ADC1_ADC2_DMXL_GC 5
#define ADC1_ADC1_DMXL_GC 4
#define ADC1_ADC4_DMXL_SRC 3
#define ADC1_ADC3_DMXL_SRC 2
#define ADC1_ADC2_DMXL_SRC 1
#define ADC1_ADC1_DMXL_SRC 0
/*ADC2_DMIX_SRC*/
#define ADC2_ADC4_DMXL_GC 7
#define ADC2_ADC3_DMXL_GC 6
#define ADC2_ADC2_DMXL_GC 5
#define ADC2_ADC1_DMXL_GC 4
#define ADC2_ADC4_DMXL_SRC 3
#define ADC2_ADC3_DMXL_SRC 2
#define ADC2_ADC2_DMXL_SRC 1
#define ADC2_ADC1_DMXL_SRC 0
/*ADC3_DMIX_SRC*/
#define ADC3_ADC4_DMXL_GC 7
#define ADC3_ADC3_DMXL_GC 6
#define ADC3_ADC2_DMXL_GC 5
#define ADC3_ADC1_DMXL_GC 4
#define ADC3_ADC4_DMXL_SRC 3
#define ADC3_ADC3_DMXL_SRC 2
#define ADC3_ADC2_DMXL_SRC 1
#define ADC3_ADC1_DMXL_SRC 0
/*ADC4_DMIX_SRC*/
#define ADC4_ADC4_DMXL_GC 7
#define ADC4_ADC3_DMXL_GC 6
#define ADC4_ADC2_DMXL_GC 5
#define ADC4_ADC1_DMXL_GC 4
#define ADC4_ADC4_DMXL_SRC 3
#define ADC4_ADC3_DMXL_SRC 2
#define ADC4_ADC2_DMXL_SRC 1
#define ADC4_ADC1_DMXL_SRC 0
/*ADC_DIG_DEBUG*/
#define ADC_PTN_SEL 0
/*I2S_DAT_PADDRV_CTRL*/
#define TX2_DAT_DRV 4
#define TX1_DAT_DRV 0
/*I2S_CLK_PADDRV_CTRL*/
#define LRCK_DRV 4
#define BCLK_DRV 0
/*ANA_PGA1_CTRL*/
#define ADC1_ANALOG_PGA 1
#define ADC1_ANALOG_PGA_STEP 0
/*ANA_PGA2_CTRL*/
#define ADC2_ANALOG_PGA 1
#define ADC2_ANALOG_PGA_STEP 0
/*ANA_PGA3_CTRL*/
#define ADC3_ANALOG_PGA 1
#define ADC3_ANALOG_PGA_STEP 0
/*ANA_PGA4_CTRL*/
#define ADC4_ANALOG_PGA 1
#define ADC4_ANALOG_PGA_STEP 0
/*MIC_OFFSET_CTRL1*/
#define MIC_OFFSET_CAL_EN4 3
#define MIC_OFFSET_CAL_EN3 2
#define MIC_OFFSET_CAL_EN2 1
#define MIC_OFFSET_CAL_EN1 0
/*MIC_OFFSET_CTRL2*/
#define MIC_OFFSET_CAL_GAIN 3
#define MIC_OFFSET_CAL_CHANNEL 1
#define MIC_OFFSET_CAL_EN_ONCE 0
/*MIC1_OFFSET_STATU1*/
#define MIC1_OFFSET_CAL_DONE 7
#define MIC1_OFFSET_CAL_RUN_STA 6
#define MIC1_OFFSET_MSB 0
/*MIC1_OFFSET_STATU2*/
#define MIC1_OFFSET_LSB 0
/*MIC2_OFFSET_STATU1*/
#define MIC2_OFFSET_CAL_DONE 7
#define MIC2_OFFSET_CAL_RUN_STA 6
#define MIC2_OFFSET_MSB 0
/*MIC2_OFFSET_STATU2*/
#define MIC2_OFFSET_LSB 0
/*MIC3_OFFSET_STATU1*/
#define MIC3_OFFSET_CAL_DONE 7
#define MIC3_OFFSET_CAL_RUN_STA 6
#define MIC3_OFFSET_MSB 0
/*MIC3_OFFSET_STATU2*/
#define MIC3_OFFSET_LSB 0
/*MIC4_OFFSET_STATU1*/
#define MIC4_OFFSET_CAL_DONE 7
#define MIC4_OFFSET_CAL_RUN_STA 6
#define MIC4_OFFSET_MSB 0
/*MIC4_OFFSET_STATU2*/
#define MIC4_OFFSET_LSB 0
/*ANA_ADC1_CTRL1*/
#define ADC1_PGA_BYPASS 7
#define ADC1_PGA_BYP_RCM 6
#define ADC1_PGA_CTRL_RCM 4
#define ADC1_PGA_MUTE 3
#define ADC1_DSM_ENABLE 2
#define ADC1_PGA_ENABLE 1
#define ADC1_MICBIAS_EN 0
/*ANA_ADC1_CTRL3*/
#define ADC1_ANA_CAL_EN 5
#define ADC1_SEL_OUT_EDGE 3
#define ADC1_DSM_DISABLE 2
#define ADC1_VREFP_DISABLE 1
#define ADC1_AAF_DISABLE 0
/*ANA_ADC1_CTRL6*/
#define PGA_CTRL_TC 6
#define PGA_CTRL_RC 4
#define PGA_CTRL_I_LIN 2
#define PGA_CTRL_I_IN 0
/*ANA_ADC1_CTRL7*/
#define PGA_CTRL_HI_Z 7
#define PGA_CTRL_SHORT_RF 6
#define PGA_CTRL_VCM_VG 4
#define PGA_CTRL_VCM_IN 0
/*ANA_ADC2_CTRL1*/
#define ADC2_PGA_BYPASS 7
#define ADC2_PGA_BYP_RCM 6
#define ADC2_PGA_CTRL_RCM 4
#define ADC2_PGA_MUTE 3
#define ADC2_DSM_ENABLE 2
#define ADC2_PGA_ENABLE 1
#define ADC2_MICBIAS_EN 0
/*ANA_ADC2_CTRL3*/
#define ADC2_ANA_CAL_EN 5
#define ADC2_SEL_OUT_EDGE 3
#define ADC2_DSM_DISABLE 2
#define ADC2_VREFP_DISABLE 1
#define ADC2_AAF_DISABLE 0
/*ANA_ADC2_CTRL6*/
#define PGA_CTRL_IBOOST 7
#define PGA_CTRL_IQCTRL 6
#define PGA_CTRL_OABIAS 4
#define PGA_CTRL_CMLP_DIS 3
#define PGA_CTRL_PDB_RIN 2
#define PGA_CTRL_PEAKDET 0
/*ANA_ADC2_CTRL7*/
#define AAF_LPMODE_EN 7
#define AAF_STG2_IB_SEL 4
#define AAFDSM_IB_DIV2 3
#define AAF_STG1_IB_SEL 0
/*ANA_ADC3_CTRL1*/
#define ADC3_PGA_BYPASS 7
#define ADC3_PGA_BYP_RCM 6
#define ADC3_PGA_CTRL_RCM 4
#define ADC3_PGA_MUTE 3
#define ADC3_DSM_ENABLE 2
#define ADC3_PGA_ENABLE 1
#define ADC3_MICBIAS_EN 0
/*ANA_ADC3_CTRL3*/
#define ADC3_ANA_CAL_EN 5
#define ADC3_INVERT_CLK 4
#define ADC3_SEL_OUT_EDGE 3
#define ADC3_DSM_DISABLE 2
#define ADC3_VREFP_DISABLE 1
#define ADC3_AAF_DISABLE 0
/*ANA_ADC3_CTRL7*/
#define DSM_COMP_IB_SEL 6
#define DSM_OTA_CTRL 4
#define DSM_LPMODE 3
#define DSM_OTA_IB_SEL 0
/*ANA_ADC4_CTRL1*/
#define ADC4_PGA_BYPASS 7
#define ADC4_PGA_BYP_RCM 6
#define ADC4_PGA_CTRL_RCM 4
#define ADC4_PGA_MUTE 3
#define ADC4_DSM_ENABLE 2
#define ADC4_PGA_ENABLE 1
#define ADC4_MICBIAS_EN 0
/*ANA_ADC4_CTRL3*/
#define ADC4_ANA_CAL_EN 5
#define ADC4_SEL_OUT_EDGE 3
#define ADC4_DSM_DISABLE 2
#define ADC4_VREFP_DISABLE 1
#define ADC4_AAF_DISABLE 0
/*ANA_ADC4_CTRL6*/
#define DSM_DEMOFF 5
#define DSM_EN_DITHER 4
#define DSM_VREFP_LPMODE 2
#define DSM_VREFP_OUTCTRL 0
/*ANA_ADC4_CTRL7*/
#define CK8M_EN 5
#define OSC_EN 4
#define ADC4_CLK_GATING 3
#define ADC3_CLK_GATING 2
#define ADC2_CLK_GATING 1
#define ADC1_CLK_GATING 0
/*GPIO_CFG1*/
#define GPIO2_SELECT 4
#define GPIO1_SELECT 0
/*GPIO_CFG2*/
#define GPIO4_SELECT 4
#define GPIO3_SELECT 0
/*GPIO_DAT*///order???
#define GPIO4_DAT 3
#define GPIO3_DAT 2
#define GPIO2_DAT 1
#define GPIO1_DAT 0
/*GPIO_DRV*/
#define GPIO4_DRV 6
#define GPIO3_DRV 4
#define GPIO2_DRV 2
#define GPIO1_DRV 0
/*GPIO_PULL*/
#define GPIO4_PULL 6
#define GPIO3_PULL 4
#define GPIO2_PULL 2
#define GPIO1_PULL 0
/*GPIO_INT_CFG*/
#define GPIO4_EINT_CFG 6
#define GPIO3_EINT_CFG 4
#define GPIO2_EINT_CFG 2
#define GPIO1_EINT_CFG 0
/*GPIO_INT_EN*///order???
#define GPIO4_EINT_EN 3
#define GPIO3_EINT_EN 2
#define GPIO2_EINT_EN 1
#define GPIO1_EINT_EN 0
/*GPIO_INT_STATUS*///order???
#define GPIO4_EINT_STA 3
#define GPIO3_EINT_STA 2
#define GPIO2_EINT_STA 1
#define GPIO1_EINT_STA 0
/*PRNG_CLK_CTRL*/
#define PRNG_CLK_EN 1
#define PRNG_CLK_POS 0
/*** Some Config Value ***/
//[SYSCLK_CTRL]: PLLCLK_SRC
#define PLLCLK_SRC_MCLK 0
#define PLLCLK_SRC_BCLK 1
#define PLLCLK_SRC_GPIO2 2
#define PLLCLK_SRC_GPIO3 3
//[SYSCLK_CTRL]: SYSCLK_SRC
#define SYSCLK_SRC_MCLK 0
#define SYSCLK_SRC_PLL 1
//I2S BCLK POLARITY Control
#define BCLK_NORMAL_DRIVE_N_SAMPLE_P 0
#define BCLK_INVERT_DRIVE_P_SAMPLE_N 1
//I2S LRCK POLARITY Control
#define LRCK_LEFT_LOW_RIGHT_HIGH 0
#define LRCK_LEFT_HIGH_RIGHT_LOW 1
//I2S Format Selection
#define PCM_FORMAT 0
#define LEFT_JUSTIFIED_FORMAT 1
#define RIGHT_JUSTIFIED_FORMAT 2
//I2S data protocol types
#define IS_ENCODING_MODE 0
#endif

953
ac108_asound.state Normal file
View file

@ -0,0 +1,953 @@
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 0
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.seeed4micvoicec {
control.1 {
iface MIXER
name 'OUT1 Mute'
value false
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.2 {
iface MIXER
name 'OUT2 Mute'
value true
comment {
access 'read write'
type BOOLEAN
count 1
}
}
control.3 {
iface MIXER
name 'TX1 Channel1~8 enable'
value '1-4 channels '
comment {
access 'read write'
type ENUMERATED
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 '
}
}
control.4 {
iface MIXER
name 'TX1 Channel9~16 enable'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
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 '
}
}
control.5 {
iface MIXER
name 'TX2 Channel1~8 enable'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
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 '
}
}
control.6 {
iface MIXER
name 'TX2 Channel9~16 enable'
value 'disable all'
comment {
access 'read write'
type ENUMERATED
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 '
}
}
control.7 {
iface MIXER
name 'CH1 digital volume'
value 181
comment {
access 'read write'
type INTEGER
count 1
range '0 - 255'
dbmin -11925
dbmax 7200
dbvalue.0 1650
}
}
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
comment {
access 'read write'
type INTEGER
count 1
range '0 - 31'
dbmin 0
dbmax 3100
dbvalue.0 2700
}
}
control.15 {
iface MIXER
name 'Tx1 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.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'
}
}
}

58
ac108_plugin/Makefile Normal file
View file

@ -0,0 +1,58 @@
# Quiet (set to @ for a quite compile)
Q ?= @
#Q ?=
# Build Tools
CC := gcc
CFLAGS += -I. -Wall -funroll-loops -ffast-math -fPIC -DPIC -O0 -g
LD := gcc
LDFLAGS += -Wall -shared -lasound
SND_PCM_OBJECTS = pcm_ac108.o
SND_PCM_LIBS =
SND_PCM_BIN = libasound_module_pcm_ac108.so
#SND_CTL_OBJECTS = ctl_ac108.o ladspa_utils.o
#SND_CTL_LIBS =
#SND_CTL_BIN = libasound_module_ctl_ac108.so
MULTIARCH:=$(shell gcc --print-multiarch)
LIBDIR = lib/$(MULTIARCH)
.PHONY: all clean dep load_default
all: Makefile $(SND_PCM_BIN) $(SND_CTL_BIN)
dep:
@echo DEP $@
$(Q)for i in *.c; do $(CC) -MM $(CFLAGS) "$${i}" ; done > makefile.dep
-include makefile.dep
$(SND_PCM_BIN): $(SND_PCM_OBJECTS)
@echo LD $@
$(Q)$(LD) $(LDFLAGS) $(SND_PCM_LIBS) $(SND_PCM_OBJECTS) -o $(SND_PCM_BIN)
#$(SND_CTL_BIN): $(SND_CTL_OBJECTS)
# @echo LD $@
# $(Q)$(LD) $(LDFLAGS) $(SND_CTL_LIBS) $(SND_CTL_OBJECTS) -o $(SND_CTL_BIN)
%.o: %.c
@echo GCC $<
$(Q)$(CC) -c $(CFLAGS) $(CPPFLAGS) $<
clean:
@echo Cleaning...
$(Q)rm -vf *.o *.so
install: all
@echo Installing...
$(Q)mkdir -p ${DESTDIR}/usr/$(LIBDIR)/alsa-lib/
$(Q)install -m 644 $(SND_PCM_BIN) ${DESTDIR}/usr/$(LIBDIR)/alsa-lib/
#$(Q)install -m 644 $(SND_CTL_BIN) ${DESTDIR}/usr/$(LIBDIR)/alsa-lib/
uninstall:
@echo Un-installing...
$(Q)rm ${DESTDIR}/usr/lib/alsa-lib/$(SND_PCM_BIN)
#$(Q)rm ${DESTDIR}/usr/lib/alsa-lib/$(SND_CTL_BIN)

5
ac108_plugin/README.md Normal file
View file

@ -0,0 +1,5 @@
#seeed-4mic-voicecard alsa plugin
```
sudo apt install libasound2-dev
make && sudo make install
```

Binary file not shown.

479
ac108_plugin/pcm_ac108.c Normal file
View file

@ -0,0 +1,479 @@
//https://github.com/HazouPH/android_device_motorola_smi-plus/blob/48029b4afc307c73181b108a5b0155b9f20856ca/smi-modules/alsa-lib_module_voice/pcm_voice.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <alsa/asoundlib.h>
#include <alsa/pcm_external.h>
#include <alsa/pcm_plugin.h>
#include <math.h>
#define ARRAY_SIZE(ary) (sizeof(ary)/sizeof(ary[0]))
#define AC108_FRAME_SIZE 4096
struct ac108_t {
snd_pcm_ioplug_t io;
snd_pcm_t *slave;
snd_pcm_hw_params_t *hw_params;
unsigned int last_size;
unsigned int ptr;
void *buf;
unsigned int latency; // Delay in usec
unsigned int bufferSize; // Size of sample buffer
};
/* set up the fixed parameters of slave PCM hw_parmas */
static int ac108_slave_hw_params_half(struct ac108_t *rec, unsigned int rate,snd_pcm_format_t format) {
int err;
snd_pcm_uframes_t bufferSize = rec->bufferSize;
unsigned int latency = rec->latency;
unsigned int buffer_time = 0;
unsigned int period_time = 0;
if ((err = snd_pcm_hw_params_malloc(&rec->hw_params)) < 0) return err;
if ((err = snd_pcm_hw_params_any(rec->slave, rec->hw_params)) < 0) {
SNDERR("Cannot get slave hw_params");
goto out;
}
if ((err = snd_pcm_hw_params_set_access(rec->slave, rec->hw_params,
SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
SNDERR("Cannot set slave access RW_INTERLEAVED");
goto out;
}
if ((err = snd_pcm_hw_params_set_channels(rec->slave, rec->hw_params, 2)) < 0) {
SNDERR("Cannot set slave channels 2");
goto out;
}
if ((err = snd_pcm_hw_params_set_format(rec->slave, rec->hw_params,
format)) < 0) {
SNDERR("Cannot set slave format");
goto out;
}
if ((err = snd_pcm_hw_params_set_rate(rec->slave, rec->hw_params, rate, 0)) < 0) {
SNDERR("Cannot set slave rate %d", rate);
goto out;
}
err = snd_pcm_hw_params_get_buffer_time_max(rec->hw_params,
&buffer_time, 0);
if (buffer_time > 80000)
buffer_time = 80000;
period_time = buffer_time / 4;
err = snd_pcm_hw_params_set_period_time_near(rec->slave, rec->hw_params,
&period_time, 0);
if (err < 0) {
fprintf(stderr,"Unable to set_period_time_near");
goto out;
}
err = snd_pcm_hw_params_set_buffer_time_near(rec->slave, rec->hw_params,
&buffer_time, 0);
if (err < 0) {
fprintf(stderr,"Unable to set_buffer_time_near");
goto out;
}
rec->bufferSize = bufferSize;
rec->latency = latency;
return 0;
out:
free(rec->hw_params);
rec->hw_params = NULL;
return err;
}
/*
* start and stop callbacks - just trigger slave PCM
*/
static int ac108_start(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
if(!rec->slave) {
fprintf(stderr, "slave is lost\n");
}
return snd_pcm_start(rec->slave);
}
static int ac108_stop(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
return snd_pcm_drop(rec->slave);
}
/*
* pointer callback
*
* Calculate the current position from the delay of slave PCM
*/
static snd_pcm_sframes_t ac108_pointer(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
int err, size;
assert(rec);
size = snd_pcm_avail(rec->slave);
if (size < 0) return size;
size = size /2;
if (size > rec->last_size) {
rec->ptr += size - rec->last_size;
rec->ptr %= io->buffer_size;
}
rec->last_size = size;
//fprintf(stderr, "%s :%d %d %d %d\n", __func__, rec->ptr,size, io->appl_ptr, io->hw_ptr);
return rec->ptr;
}
/*
* transfer callback
*/
static snd_pcm_sframes_t ac108_transfer(snd_pcm_ioplug_t *io,
const snd_pcm_channel_area_t *areas,
snd_pcm_uframes_t offset,
snd_pcm_uframes_t size) {
struct ac108_t *rec = io->private_data;
char *buf;
ssize_t result;
int err;
/* we handle only an interleaved buffer */
buf = (char *)areas->addr + (areas->first + areas->step * offset) / 8;
result = snd_pcm_readi(rec->slave, buf, size*2);
if (result <= 0) {
fprintf(stderr, "%s out error:%d %d\n", __func__, result);
return result;
}
rec->last_size -= size;
return size;
}
/*
* poll-related callbacks - just pass to slave PCM
*/
static int ac108_poll_descriptors_count(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
//fprintf(stderr, "%s\n", __FUNCTION__);
return snd_pcm_poll_descriptors_count(rec->slave);
}
static int ac108_poll_descriptors(snd_pcm_ioplug_t *io, struct pollfd *pfd,
unsigned int space) {
struct ac108_t *rec = io->private_data;
//fprintf(stderr, "%s\n", __FUNCTION__);
return snd_pcm_poll_descriptors(rec->slave, pfd, space);
}
static int ac108_poll_revents(snd_pcm_ioplug_t *io, struct pollfd *pfd,
unsigned int nfds, unsigned short *revents) {
struct ac108_t *rec = io->private_data;
//fprintf(stderr, "%s\n", __FUNCTION__);
return snd_pcm_poll_descriptors_revents(rec->slave, pfd, nfds, revents);
}
/*
* close callback
*/
static int ac108_close(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
if (rec->slave) return snd_pcm_close(rec->slave);
return 0;
}
static int setSoftwareParams(struct ac108_t *rec) {
snd_pcm_sw_params_t *softwareParams;
int err;
snd_pcm_uframes_t bufferSize = 0;
snd_pcm_uframes_t periodSize = 0;
snd_pcm_uframes_t startThreshold, stopThreshold;
snd_pcm_sw_params_alloca(&softwareParams);
// Get the current software parameters
err = snd_pcm_sw_params_current(rec->slave, softwareParams);
if (err < 0) {
fprintf(stderr, "Unable to get software parameters: %s", snd_strerror(err));
goto done;
}
// Configure ALSA to start the transfer when the buffer is almost full.
snd_pcm_get_params(rec->slave, &bufferSize, &periodSize);
startThreshold = 1;
stopThreshold = bufferSize;
err = snd_pcm_sw_params_set_start_threshold(rec->slave, softwareParams,
startThreshold);
if (err < 0) {
fprintf(stderr, "Unable to set start threshold to %lu frames: %s",
startThreshold, snd_strerror(err));
goto done;
}
err = snd_pcm_sw_params_set_stop_threshold(rec->slave, softwareParams,
stopThreshold);
if (err < 0) {
fprintf(stderr, "Unable to set stop threshold to %lu frames: %s",
stopThreshold, snd_strerror(err));
goto done;
}
// Allow the transfer to start when at least periodSize samples can be
// processed.
err = snd_pcm_sw_params_set_avail_min(rec->slave, softwareParams,
periodSize);
if (err < 0) {
fprintf(stderr, "Unable to configure available minimum to %lu: %s",
periodSize, snd_strerror(err));
goto done;
}
// Commit the software parameters back to the device.
err = snd_pcm_sw_params(rec->slave, softwareParams);
if (err < 0) fprintf(stderr, "Unable to configure software parameters: %s",
snd_strerror(err));
return 0;
done:
snd_pcm_sw_params_free(softwareParams);
return err;
}
/*
* hw_params callback
*
* Set up slave PCM according to the current parameters
*/
//static int ac108_hw_params(snd_pcm_ioplug_t *io,
// snd_pcm_hw_params_t *params ATTRIBUTE_UNUSED) {
static int ac108_hw_params(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
snd_pcm_sw_params_t *sparams;
snd_pcm_uframes_t period_size;
snd_pcm_uframes_t buffer_size;
int err;
if (!rec->hw_params) {
err = ac108_slave_hw_params_half(rec, io->rate*2,io->format);
if (err < 0) {
fprintf(stderr, "ac108_slave_hw_params_half error\n");
return err;
}
}
period_size = io->period_size;
if ((err = snd_pcm_hw_params_set_period_size_near(rec->slave, rec->hw_params,
&period_size, NULL)) < 0) {
SNDERR("Cannot set slave period size %ld", period_size);
return err;
}
buffer_size = io->buffer_size;
if ((err = snd_pcm_hw_params_set_buffer_size_near(rec->slave, rec->hw_params,
&buffer_size)) < 0) {
SNDERR("Cannot set slave buffer size %ld", buffer_size);
return err;
}
if ((err = snd_pcm_hw_params(rec->slave, rec->hw_params)) < 0) {
SNDERR("Cannot set slave hw_params");
return err;
}
setSoftwareParams(rec);
return 0;
}
/*
* hw_free callback
*/
static int ac108_hw_free(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
free(rec->hw_params);
if (rec->buf != NULL) {
free(rec->buf);
rec->buf = NULL;
}
rec->hw_params = NULL;
return snd_pcm_hw_free(rec->slave);
}
static int ac108_prepare(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
rec->ptr = 0;
rec->last_size =0;
if (rec->buf == NULL) {
rec->buf = malloc(io->buffer_size);
}
return snd_pcm_prepare(rec->slave);
}
static int ac108_drain(snd_pcm_ioplug_t *io) {
struct ac108_t *rec = io->private_data;
return snd_pcm_drain(rec->slave);
}
static int ac108_sw_params(snd_pcm_ioplug_t *io, snd_pcm_sw_params_t *params) {
struct ac108_t *rec = io->private_data;
return 0;
}
static int ac108_delay(snd_pcm_ioplug_t * io, snd_pcm_sframes_t * delayp){
return 0;
}
/*
* callback table
*/
static snd_pcm_ioplug_callback_t a108_ops = {
.start = ac108_start,
.stop = ac108_stop,
.pointer = ac108_pointer,
.transfer = ac108_transfer,
.poll_descriptors_count = ac108_poll_descriptors_count,
.poll_descriptors = ac108_poll_descriptors,
.poll_revents = ac108_poll_revents,
.close = ac108_close,
.hw_params = ac108_hw_params,
.hw_free = ac108_hw_free,
// .sw_params = ac108_sw_params,
.prepare = ac108_prepare,
.drain = ac108_drain,
.delay = ac108_delay,
};
static int ac108_set_hw_constraint(struct ac108_t *rec) {
static unsigned int accesses[] = {
SND_PCM_ACCESS_RW_INTERLEAVED,
SND_PCM_ACCESS_RW_NONINTERLEAVED
};
unsigned int formats[] = { SND_PCM_FORMAT_S32,
SND_PCM_FORMAT_S16 };
int err;
snd_pcm_uframes_t buffer_max;
unsigned int period_bytes, max_periods;
err = snd_pcm_ioplug_set_param_list(&rec->io,
SND_PCM_IOPLUG_HW_ACCESS,
ARRAY_SIZE(accesses),
accesses);
if (err < 0) return err;
if ((err = snd_pcm_ioplug_set_param_list(&rec->io, SND_PCM_IOPLUG_HW_FORMAT,
ARRAY_SIZE(formats), formats)) < 0 ||
(err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_CHANNELS,
1, 4)) < 0 ||
(err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_RATE,
8000, 96000)) < 0) return err;
err = snd_pcm_ioplug_set_param_minmax(&rec->io,
SND_PCM_IOPLUG_HW_BUFFER_BYTES,
1, 4 * 1024 * 1024);
if (err < 0) return err;
err = snd_pcm_ioplug_set_param_minmax(&rec->io,
SND_PCM_IOPLUG_HW_PERIOD_BYTES,
128, 2 * 1024 * 1024);
if (err < 0) return err;
err = snd_pcm_ioplug_set_param_minmax(&rec->io, SND_PCM_IOPLUG_HW_PERIODS,
3, 1024);
return 0;
}
/*
/*
* Main entry point
*/
SND_PCM_PLUGIN_DEFINE_FUNC(ac108) {
snd_config_iterator_t i, next;
int err;
const char *card = NULL;
const char *pcm_string = NULL;
snd_pcm_format_t format = SND_PCM_FORMAT_S32_LE;
char devstr[128], tmpcard[8];
struct ac108_t *rec;
int channels;
struct pollfd fds;
if (stream != SND_PCM_STREAM_CAPTURE) {
SNDERR("a108 is only for capture");
return -EINVAL;
}
snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id;
if (snd_config_get_id(n, &id) < 0) continue;
if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0 || strcmp(id, "hint") == 0) continue;
if (strcmp(id, "slavepcm") == 0) {
if (snd_config_get_string(n, &pcm_string) < 0) {
SNDERR("ac108 slavepcm must be a string");
return -EINVAL;
}
continue;
}
if (strcmp(id, "channels") == 0) {
long val;
if (snd_config_get_integer(n, &val) < 0) {
SNDERR("Invalid type for %s", id);
return -EINVAL;
}
channels = val;
if (channels != 2 && channels != 4 && channels != 6) {
SNDERR("channels must be 2, 4 or 6");
return -EINVAL;
}
continue;
}
}
rec = calloc(1, sizeof(*rec));
if (!rec) {
SNDERR("cannot allocate");
return -ENOMEM;
}
err = snd_pcm_open(&rec->slave, pcm_string, stream, mode);
if (err < 0) goto error;
//SND_PCM_NONBLOCK
rec->io.version = SND_PCM_IOPLUG_VERSION;
rec->io.name = "AC108 decode Plugin";
rec->io.mmap_rw = 0;
rec->io.callback = &a108_ops;
rec->io.private_data = rec;
err = snd_pcm_ioplug_create(&rec->io, name, stream, mode);
if (err < 0) goto error;
if ((err = ac108_set_hw_constraint(rec)) < 0) {
snd_pcm_ioplug_delete(&rec->io);
return err;
}
*pcmp = rec->io.pcm;
return 0;
error:
if (rec->slave) snd_pcm_close(rec->slave);
free(rec);
return err;
}
SND_PCM_PLUGIN_SYMBOL(ac108);

BIN
ac108_plugin/pcm_ac108.o Normal file

Binary file not shown.

View file

@ -1,11 +1,11 @@
# The IPC key of dmix or dsnoop plugin must be unique # The IPC key of dmix or dsnoop plugin must be unique
# If 555555 or 666666 is used by other processes, use another one # If 555555 or 666666 is used by other processes, use another one
pcm.!default { # pcm.!default {
type asym # type asym
playback.pcm "playback" # playback.pcm "playback"
capture.pcm "capture" # capture.pcm "capture"
} # }
pcm.playback { pcm.playback {
type plug type plug
@ -32,3 +32,8 @@ pcm.array {
ipc_key 666666 ipc_key 666666
} }
pcm.ac108 {
type ac108
slavepcm "hw:1,0"
channels 4
}

View file

@ -1,4 +1,7 @@
dtoverlay -r seeed-voicecard #dtoverlay -r seeed-2mic-voicecard
dtc -@ -I dts -O dtb -o seeed-voicecard.dtbo seeed-voicecard-overlay.dts
cp seeed-voicecard.dtbo /boot/overlays dtc -@ -I dts -O dtb -o seeed-2mic-voicecard.dtbo seeed-2mic-voicecard-overlay.dts
dtoverlay seeed-voicecard dtc -@ -I dts -O dtb -o seeed-4mic-voicecard.dtbo seeed-4mic-voicecard-overlay.dts
# cp *.dtbo /boot/overlays
# dtoverlay seeed-2mic-voicecard

View file

@ -1,5 +1,7 @@
PACKAGE_NAME="seeed-voicecard" PACKAGE_NAME="seeed-voicecard"
PACKAGE_VERSION="0.1" PACKAGE_VERSION="0.2"
BUILT_MODULE_NAME[0]="wm8960" BUILT_MODULE_NAME[0]="snd-soc-wm8960"
BUILT_MODULE_NAME[1]="snd-soc-ac108"
DEST_MODULE_LOCATION[0]="/kernel/sound/soc/codecs" DEST_MODULE_LOCATION[0]="/kernel/sound/soc/codecs"
DEST_MODULE_LOCATION[1]="/kernel/sound/soc/codecs"
AUTOINSTALL="yes" AUTOINSTALL="yes"

View file

@ -5,8 +5,19 @@ if [[ $EUID -ne 0 ]]; then
exit 1 exit 1
fi 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"
exit 1
fi
ver="0.1" ver="0.2"
card=$1
if [ "x${card}" = "x" ] ; then
echo "Usage: ./install 2mic|4mic"
exit 1
fi
# we create a dir with this version to ensure that 'dkms remove' won't delete # we create a dir with this version to ensure that 'dkms remove' won't delete
# the sources during kernel updates # the sources during kernel updates
@ -19,6 +30,7 @@ apt-get -y install dkms
# locate currently installed kernels (may be different to running kernel if # locate currently installed kernels (may be different to running kernel if
# it's just been updated) # it's just been updated)
kernels=$(ls /lib/modules | sed "s/^/-k /") kernels=$(ls /lib/modules | sed "s/^/-k /")
uname_r=$(uname -r)
function install_module { function install_module {
src=$1 src=$1
@ -39,28 +51,58 @@ function install_module {
mkdir -p /var/lib/dkms/$mod/$ver/$marker 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" 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 || \
echo "snd-soc-ac108" >> /etc/modules
grep -q "snd-soc-wm8960" /etc/modules || \
echo "snd-soc-wm8960" >> /etc/modules
(
cp seeed-voicecard.dtbo /boot/overlays
cp asound.state /var/lib/alsa/asound.state
)
echo 'wm8960' | sudo tee --append /etc/modules > /dev/null
sed -i \
-e "s/^dtparam=audio=on/#\0/" \
-e "s/^#\(dtparam=i2s=on\)/\1/" \
/boot/config.txt
grep -q "dtoverlay=i2s-mmap" /boot/config.txt || \ grep -q "dtoverlay=i2s-mmap" /boot/config.txt || \
echo "dtoverlay=i2s-mmap" >> /boot/config.txt echo "dtoverlay=i2s-mmap" >> /boot/config.txt
grep -q "dtoverlay=seeed-voicecard" /boot/config.txt || \
echo "dtoverlay=seeed-voicecard" >> /boot/config.txt
grep -q "dtparam=i2s=on" /boot/config.txt || \ grep -q "dtparam=i2s=on" /boot/config.txt || \
echo "dtparam=i2s=on" >> /boot/config.txt echo "dtparam=i2s=on" >> /boot/config.txt
has_2mic=$(grep seeed-2mic-voicecard /boot/config.txt)
has_4mic=$(grep seeed-2mic-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
echo "------------------------------------------------------" echo "------------------------------------------------------"
echo "Please reboot your raspberry pi to apply all settings" echo "Please reboot your raspberry pi to apply all settings"
echo "Enjoy!" echo "Enjoy!"

View file

@ -43,7 +43,7 @@
master_overlay: __dormant__ { master_overlay: __dormant__ {
compatible = "simple-audio-card"; compatible = "simple-audio-card";
simple-audio-card,format = "i2s"; simple-audio-card,format = "i2s";
simple-audio-card,name = "seeed-voicecard"; simple-audio-card,name = "seeed-2mic-voicecard";
simple-audio-card,bitclock-master = <&dailink0_master>; simple-audio-card,bitclock-master = <&dailink0_master>;
simple-audio-card,frame-master = <&dailink0_master>; simple-audio-card,frame-master = <&dailink0_master>;
status = "okay"; status = "okay";
@ -80,7 +80,7 @@
slave_overlay: __overlay__ { slave_overlay: __overlay__ {
compatible = "simple-audio-card"; compatible = "simple-audio-card";
simple-audio-card,format = "i2s"; simple-audio-card,format = "i2s";
simple-audio-card,name = "seeed-voicecard"; simple-audio-card,name = "seeed-2mic-voicecard";
status = "okay"; status = "okay";
simple-audio-card,widgets = simple-audio-card,widgets =
"Microphone", "Mic Jack", "Microphone", "Mic Jack",

BIN
seeed-2mic-voicecard.dtbo Normal file

Binary file not shown.

View file

@ -0,0 +1,66 @@
/dts-v1/;
/plugin/;
/ {
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 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
ac108_a: ac108@3b{
compatible = "x-power,ac108_0";
reg = <0x3b>;
#sound-dai-cells = <0>;
data-protocol = <1>;
};
};
};
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";
};
};

BIN
seeed-4mic-voicecard.dtbo Normal file

Binary file not shown.

Binary file not shown.

BIN
wm8960.ko

Binary file not shown.