You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'sound-4.7-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull more sound updates from Takashi Iwai: "This is the second update round for 4.7-rc1. Most of changes are about the pending ASoC updates and fixes, including a few new drivers. Below are some highlights: ASoC: - New drivers for MAX98371 and TAS5720 - SPI support for TLV320AIC32x4, along with the module split - TDM support for STI Uniperf IPs - Remaining topology API fixes / updates HDA: - A couple of Dell quirks and new Realtek codec support" * tag 'sound-4.7-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (63 commits) ALSA: hda - Fix headset mic detection problem for one Dell machine spi: spi-ep93xx: Fix the PTR_ERR() argument ALSA: hda/realtek - Add support for ALC295/ALC3254 ASoC: kirkwood: fix build failure ALSA: hda - Fix headphone noise on Dell XPS 13 9360 ASoC: ak4642: Enable cache usage to fix crashes on resume ASoC: twl6040: Disconnect AUX output pads on digital mute ASoC: tlv320aic32x4: Properly implement the positive and negative pins into the mixers rcar: src: skip disabled-SRC nodes ASoC: max98371 Remove duplicate entry in max98371_reg ASoC: twl6040: Select LPPLL during standby ASoC: rsnd: don't use prohibited number to PDMACHCRn.SRS ASoC: simple-card: Add pm callbacks to platform driver ASoC: pxa: Fix module autoload for platform drivers ASoC: topology: Fix memory leak in widget creation ASoC: Add max98371 codec driver ASoC: rsnd: count .probe/.remove for rsnd_mod_call() ASoC: topology: Check size mismatch of ABI objects before parsing ASoC: topology: Check failure to create a widget ASoC: add support for TAS5720 digital amplifier ...
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
max98371 codec
|
||||
|
||||
This device supports I2C mode only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "maxim,max98371"
|
||||
- reg : The chip select number on the I2C bus
|
||||
|
||||
Example:
|
||||
|
||||
&i2c {
|
||||
max98371: max98371@0x31 {
|
||||
compatible = "maxim,max98371";
|
||||
reg = <0x31>;
|
||||
};
|
||||
};
|
||||
@@ -1,15 +1,16 @@
|
||||
MT8173 with RT5650 RT5676 CODECS
|
||||
MT8173 with RT5650 RT5676 CODECS and HDMI via I2S
|
||||
|
||||
Required properties:
|
||||
- compatible : "mediatek,mt8173-rt5650-rt5676"
|
||||
- mediatek,audio-codec: the phandles of rt5650 and rt5676 codecs
|
||||
and of the hdmi encoder node
|
||||
- mediatek,platform: the phandle of MT8173 ASoC platform
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "mediatek,mt8173-rt5650-rt5676";
|
||||
mediatek,audio-codec = <&rt5650 &rt5676>;
|
||||
mediatek,audio-codec = <&rt5650 &rt5676 &hdmi0>;
|
||||
mediatek,platform = <&afe>;
|
||||
};
|
||||
|
||||
|
||||
@@ -5,11 +5,21 @@ Required properties:
|
||||
- mediatek,audio-codec: the phandles of rt5650 codecs
|
||||
- mediatek,platform: the phandle of MT8173 ASoC platform
|
||||
|
||||
Optional subnodes:
|
||||
- codec-capture : the subnode of rt5650 codec capture
|
||||
Required codec-capture subnode properties:
|
||||
- sound-dai: audio codec dai name on capture path
|
||||
<&rt5650 0> : Default setting. Connect rt5650 I2S1 for capture. (dai_name = rt5645-aif1)
|
||||
<&rt5650 1> : Connect rt5650 I2S2 for capture. (dai_name = rt5645-aif2)
|
||||
|
||||
Example:
|
||||
|
||||
sound {
|
||||
compatible = "mediatek,mt8173-rt5650";
|
||||
mediatek,audio-codec = <&rt5650>;
|
||||
mediatek,platform = <&afe>;
|
||||
codec-capture {
|
||||
sound-dai = <&rt5650 1>;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -37,17 +37,18 @@ Required properties:
|
||||
|
||||
- dai-name: DAI name that describes the IP.
|
||||
|
||||
- IP mode: IP working mode depending on associated codec.
|
||||
"HDMI" connected to HDMI codec and support IEC HDMI formats (player only).
|
||||
"SPDIF" connected to SPDIF codec and support SPDIF formats (player only).
|
||||
"PCM" PCM standard mode for I2S or TDM bus.
|
||||
"TDM" TDM mode for TDM bus.
|
||||
|
||||
Required properties ("st,sti-uni-player" compatibility only):
|
||||
- clocks: CPU_DAI IP clock source, listed in the same order than the
|
||||
CPU_DAI properties.
|
||||
|
||||
- uniperiph-id: internal SOC IP instance ID.
|
||||
|
||||
- IP mode: IP working mode depending on associated codec.
|
||||
"HDMI" connected to HDMI codec IP and IEC HDMI formats.
|
||||
"SPDIF"connected to SPDIF codec and support SPDIF formats.
|
||||
"PCM" PCM standard mode for I2S or TDM bus.
|
||||
|
||||
Optional properties:
|
||||
- pinctrl-0: defined for CPU_DAI@1 and CPU_DAI@4 to describe I2S PIOs for
|
||||
external codecs connection.
|
||||
@@ -56,6 +57,22 @@ Optional properties:
|
||||
|
||||
Example:
|
||||
|
||||
sti_uni_player1: sti-uni-player@1 {
|
||||
compatible = "st,sti-uni-player";
|
||||
status = "okay";
|
||||
#sound-dai-cells = <0>;
|
||||
st,syscfg = <&syscfg_core>;
|
||||
clocks = <&clk_s_d0_flexgen CLK_PCM_1>;
|
||||
reg = <0x8D81000 0x158>;
|
||||
interrupts = <GIC_SPI 85 IRQ_TYPE_NONE>;
|
||||
dmas = <&fdma0 3 0 1>;
|
||||
st,dai-name = "Uni Player #1 (I2S)";
|
||||
dma-names = "tx";
|
||||
st,uniperiph-id = <1>;
|
||||
st,version = <5>;
|
||||
st,mode = "TDM";
|
||||
};
|
||||
|
||||
sti_uni_player2: sti-uni-player@2 {
|
||||
compatible = "st,sti-uni-player";
|
||||
status = "okay";
|
||||
@@ -65,7 +82,7 @@ Example:
|
||||
reg = <0x8D82000 0x158>;
|
||||
interrupts = <GIC_SPI 86 IRQ_TYPE_NONE>;
|
||||
dmas = <&fdma0 4 0 1>;
|
||||
dai-name = "Uni Player #1 (DAC)";
|
||||
dai-name = "Uni Player #2 (DAC)";
|
||||
dma-names = "tx";
|
||||
uniperiph-id = <2>;
|
||||
version = <5>;
|
||||
@@ -82,7 +99,7 @@ Example:
|
||||
interrupts = <GIC_SPI 89 IRQ_TYPE_NONE>;
|
||||
dmas = <&fdma0 7 0 1>;
|
||||
dma-names = "tx";
|
||||
dai-name = "Uni Player #1 (PIO)";
|
||||
dai-name = "Uni Player #3 (SPDIF)";
|
||||
uniperiph-id = <3>;
|
||||
version = <5>;
|
||||
mode = "SPDIF";
|
||||
@@ -99,6 +116,7 @@ Example:
|
||||
dma-names = "rx";
|
||||
dai-name = "Uni Reader #1 (HDMI RX)";
|
||||
version = <3>;
|
||||
st,mode = "PCM";
|
||||
};
|
||||
|
||||
2) sti-sas-codec: internal audio codec IPs driver
|
||||
@@ -152,4 +170,20 @@ Example of audio card declaration:
|
||||
sound-dai = <&sti_sasg_codec 0>;
|
||||
};
|
||||
};
|
||||
simple-audio-card,dai-link@2 {
|
||||
/* TDM playback */
|
||||
format = "left_j";
|
||||
frame-inversion = <1>;
|
||||
cpu {
|
||||
sound-dai = <&sti_uni_player1>;
|
||||
dai-tdm-slot-num = <16>;
|
||||
dai-tdm-slot-width = <16>;
|
||||
dai-tdm-slot-tx-mask =
|
||||
<1 1 1 1 0 0 0 0 0 0 1 1 0 0 1 1>;
|
||||
};
|
||||
|
||||
codec {
|
||||
sound-dai = <&sti_sasg_codec 3>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Texas Instruments TAS5711/TAS5717/TAS5719 stereo power amplifiers
|
||||
Texas Instruments TAS5711/TAS5717/TAS5719/TAS5721 stereo power amplifiers
|
||||
|
||||
The codec is controlled through an I2C interface. It also has two other
|
||||
signals that can be wired up to GPIOs: reset (strongly recommended), and
|
||||
@@ -6,7 +6,11 @@ powerdown (optional).
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: "ti,tas5711", "ti,tas5717", or "ti,tas5719"
|
||||
- compatible: should be one of the following:
|
||||
- "ti,tas5711",
|
||||
- "ti,tas5717",
|
||||
- "ti,tas5719",
|
||||
- "ti,tas5721"
|
||||
- reg: The I2C address of the device
|
||||
- #sound-dai-cells: must be equal to 0
|
||||
|
||||
@@ -25,6 +29,8 @@ Optional properties:
|
||||
- PVDD_B-supply: regulator phandle for the PVDD_B supply (5711)
|
||||
- PVDD_C-supply: regulator phandle for the PVDD_C supply (5711)
|
||||
- PVDD_D-supply: regulator phandle for the PVDD_D supply (5711)
|
||||
- DRVDD-supply: regulator phandle for the DRVDD supply (5721)
|
||||
- PVDD-supply: regulator phandle for the PVDD supply (5721)
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
Texas Instruments TAS5720 Mono Audio amplifier
|
||||
|
||||
The TAS5720 serial control bus communicates through the I2C protocol only. The
|
||||
serial bus is also used for periodic codec fault checking/reporting during
|
||||
audio playback. For more product information please see the links below:
|
||||
|
||||
http://www.ti.com/product/TAS5720L
|
||||
http://www.ti.com/product/TAS5720M
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "ti,tas5720"
|
||||
- reg : I2C slave address
|
||||
- dvdd-supply : phandle to a 3.3-V supply for the digital circuitry
|
||||
- pvdd-supply : phandle to a supply used for the Class-D amp and the analog
|
||||
|
||||
Example:
|
||||
|
||||
tas5720: tas5720@6c {
|
||||
status = "okay";
|
||||
compatible = "ti,tas5720";
|
||||
reg = <0x6c>;
|
||||
dvdd-supply = <&vdd_3v3_reg>;
|
||||
pvdd-supply = <&_supply_reg>;
|
||||
};
|
||||
@@ -567,7 +567,7 @@ static void ep93xx_spi_dma_transfer(struct ep93xx_spi *espi)
|
||||
txd = ep93xx_spi_dma_prepare(espi, DMA_MEM_TO_DEV);
|
||||
if (IS_ERR(txd)) {
|
||||
ep93xx_spi_dma_finish(espi, DMA_DEV_TO_MEM);
|
||||
dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(rxd));
|
||||
dev_err(&espi->pdev->dev, "DMA TX failed: %ld\n", PTR_ERR(txd));
|
||||
msg->status = PTR_ERR(txd);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -134,6 +134,7 @@
|
||||
#define TWL6040_HFDACENA (1 << 0)
|
||||
#define TWL6040_HFPGAENA (1 << 1)
|
||||
#define TWL6040_HFDRVENA (1 << 4)
|
||||
#define TWL6040_HFSWENA (1 << 6)
|
||||
|
||||
/* VIBCTLL/R (0x18/0x1A) fields */
|
||||
|
||||
|
||||
@@ -116,6 +116,14 @@
|
||||
#define SND_SOC_TPLG_STREAM_PLAYBACK 0
|
||||
#define SND_SOC_TPLG_STREAM_CAPTURE 1
|
||||
|
||||
/* vendor tuple types */
|
||||
#define SND_SOC_TPLG_TUPLE_TYPE_UUID 0
|
||||
#define SND_SOC_TPLG_TUPLE_TYPE_STRING 1
|
||||
#define SND_SOC_TPLG_TUPLE_TYPE_BOOL 2
|
||||
#define SND_SOC_TPLG_TUPLE_TYPE_BYTE 3
|
||||
#define SND_SOC_TPLG_TUPLE_TYPE_WORD 4
|
||||
#define SND_SOC_TPLG_TUPLE_TYPE_SHORT 5
|
||||
|
||||
/*
|
||||
* Block Header.
|
||||
* This header precedes all object and object arrays below.
|
||||
@@ -132,6 +140,35 @@ struct snd_soc_tplg_hdr {
|
||||
__le32 count; /* number of elements in block */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* vendor tuple for uuid */
|
||||
struct snd_soc_tplg_vendor_uuid_elem {
|
||||
__le32 token;
|
||||
char uuid[16];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* vendor tuple for a bool/byte/short/word value */
|
||||
struct snd_soc_tplg_vendor_value_elem {
|
||||
__le32 token;
|
||||
__le32 value;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* vendor tuple for string */
|
||||
struct snd_soc_tplg_vendor_string_elem {
|
||||
__le32 token;
|
||||
char string[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct snd_soc_tplg_vendor_array {
|
||||
__le32 size; /* size in bytes of the array, including all elements */
|
||||
__le32 type; /* SND_SOC_TPLG_TUPLE_TYPE_ */
|
||||
__le32 num_elems; /* number of elements in array */
|
||||
union {
|
||||
struct snd_soc_tplg_vendor_uuid_elem uuid[0];
|
||||
struct snd_soc_tplg_vendor_value_elem value[0];
|
||||
struct snd_soc_tplg_vendor_string_elem string[0];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
* Private data.
|
||||
* All topology objects may have private data that can be used by the driver or
|
||||
@@ -139,7 +176,10 @@ struct snd_soc_tplg_hdr {
|
||||
*/
|
||||
struct snd_soc_tplg_private {
|
||||
__le32 size; /* in bytes of private data */
|
||||
char data[0];
|
||||
union {
|
||||
char data[0];
|
||||
struct snd_soc_tplg_vendor_array array[0];
|
||||
};
|
||||
} __attribute__((packed));
|
||||
|
||||
/*
|
||||
@@ -383,7 +423,7 @@ struct snd_soc_tplg_pcm {
|
||||
__le32 size; /* in bytes of this structure */
|
||||
char pcm_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
char dai_name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
|
||||
__le32 pcm_id; /* unique ID - used to match */
|
||||
__le32 pcm_id; /* unique ID - used to match with DAI link */
|
||||
__le32 dai_id; /* unique ID - used to match */
|
||||
__le32 playback; /* supports playback mode */
|
||||
__le32 capture; /* supports capture mode */
|
||||
|
||||
@@ -335,6 +335,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
|
||||
case 0x10ec0283:
|
||||
case 0x10ec0286:
|
||||
case 0x10ec0288:
|
||||
case 0x10ec0295:
|
||||
case 0x10ec0298:
|
||||
alc_update_coef_idx(codec, 0x10, 1<<9, 0);
|
||||
break;
|
||||
@@ -907,6 +908,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
|
||||
{ 0x10ec0298, 0x1028, 0, "ALC3266" },
|
||||
{ 0x10ec0256, 0x1028, 0, "ALC3246" },
|
||||
{ 0x10ec0225, 0x1028, 0, "ALC3253" },
|
||||
{ 0x10ec0295, 0x1028, 0, "ALC3254" },
|
||||
{ 0x10ec0670, 0x1025, 0, "ALC669X" },
|
||||
{ 0x10ec0676, 0x1025, 0, "ALC679X" },
|
||||
{ 0x10ec0282, 0x1043, 0, "ALC3229" },
|
||||
@@ -3697,6 +3699,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
|
||||
alc_process_coef_fw(codec, coef0668);
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
}
|
||||
@@ -3797,6 +3800,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
|
||||
snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
|
||||
snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
@@ -3854,6 +3858,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
|
||||
|
||||
switch (codec->core.vendor_id) {
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
case 0x10ec0255:
|
||||
@@ -3957,6 +3962,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
|
||||
alc_process_coef_fw(codec, coef0688);
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
}
|
||||
@@ -4038,6 +4044,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
|
||||
alc_process_coef_fw(codec, coef0688);
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
break;
|
||||
}
|
||||
@@ -4121,6 +4128,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
|
||||
is_ctia = (val & 0x1c02) == 0x1c02;
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
alc_process_coef_fw(codec, coef0225);
|
||||
msleep(800);
|
||||
val = alc_read_coef_idx(codec, 0x46);
|
||||
@@ -5466,8 +5474,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
|
||||
SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
|
||||
SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
|
||||
SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
|
||||
SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
|
||||
SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
|
||||
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
|
||||
@@ -5710,6 +5719,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
|
||||
SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
|
||||
{0x14, 0x90170110},
|
||||
{0x21, 0x02211020}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
{0x14, 0x90170130},
|
||||
{0x21, 0x02211040}),
|
||||
SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
|
||||
{0x12, 0x90a60140},
|
||||
{0x14, 0x90170110},
|
||||
@@ -6033,6 +6045,7 @@ static int patch_alc269(struct hda_codec *codec)
|
||||
alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
|
||||
break;
|
||||
case 0x10ec0225:
|
||||
case 0x10ec0295:
|
||||
spec->codec_variant = ALC269_TYPE_ALC225;
|
||||
break;
|
||||
case 0x10ec0234:
|
||||
@@ -6979,6 +6992,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
|
||||
HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
|
||||
HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
|
||||
HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
|
||||
HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
|
||||
|
||||
@@ -43,6 +43,7 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_AK5386
|
||||
select SND_SOC_ALC5623 if I2C
|
||||
select SND_SOC_ALC5632 if I2C
|
||||
select SND_SOC_BT_SCO
|
||||
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
|
||||
select SND_SOC_CS35L32 if I2C
|
||||
select SND_SOC_CS42L51_I2C if I2C
|
||||
@@ -64,7 +65,6 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_DA732X if I2C
|
||||
select SND_SOC_DA9055 if I2C
|
||||
select SND_SOC_DMIC
|
||||
select SND_SOC_BT_SCO
|
||||
select SND_SOC_ES8328_SPI if SPI_MASTER
|
||||
select SND_SOC_ES8328_I2C if I2C
|
||||
select SND_SOC_GTM601
|
||||
@@ -79,6 +79,7 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_MAX98090 if I2C
|
||||
select SND_SOC_MAX98095 if I2C
|
||||
select SND_SOC_MAX98357A if GPIOLIB
|
||||
select SND_SOC_MAX98371 if I2C
|
||||
select SND_SOC_MAX9867 if I2C
|
||||
select SND_SOC_MAX98925 if I2C
|
||||
select SND_SOC_MAX98926 if I2C
|
||||
@@ -126,12 +127,14 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_TAS2552 if I2C
|
||||
select SND_SOC_TAS5086 if I2C
|
||||
select SND_SOC_TAS571X if I2C
|
||||
select SND_SOC_TAS5720 if I2C
|
||||
select SND_SOC_TFA9879 if I2C
|
||||
select SND_SOC_TLV320AIC23_I2C if I2C
|
||||
select SND_SOC_TLV320AIC23_SPI if SPI_MASTER
|
||||
select SND_SOC_TLV320AIC26 if SPI_MASTER
|
||||
select SND_SOC_TLV320AIC31XX if I2C
|
||||
select SND_SOC_TLV320AIC32X4 if I2C
|
||||
select SND_SOC_TLV320AIC32X4_I2C if I2C
|
||||
select SND_SOC_TLV320AIC32X4_SPI if SPI_MASTER
|
||||
select SND_SOC_TLV320AIC3X if I2C
|
||||
select SND_SOC_TPA6130A2 if I2C
|
||||
select SND_SOC_TLV320DAC33 if I2C
|
||||
@@ -367,6 +370,9 @@ config SND_SOC_ALC5623
|
||||
config SND_SOC_ALC5632
|
||||
tristate
|
||||
|
||||
config SND_SOC_BT_SCO
|
||||
tristate
|
||||
|
||||
config SND_SOC_CQ0093VC
|
||||
tristate
|
||||
|
||||
@@ -473,9 +479,6 @@ config SND_SOC_DA732X
|
||||
config SND_SOC_DA9055
|
||||
tristate
|
||||
|
||||
config SND_SOC_BT_SCO
|
||||
tristate
|
||||
|
||||
config SND_SOC_DMIC
|
||||
tristate
|
||||
|
||||
@@ -529,6 +532,9 @@ config SND_SOC_MAX98095
|
||||
config SND_SOC_MAX98357A
|
||||
tristate
|
||||
|
||||
config SND_SOC_MAX98371
|
||||
tristate
|
||||
|
||||
config SND_SOC_MAX9867
|
||||
tristate
|
||||
|
||||
@@ -748,9 +754,16 @@ config SND_SOC_TAS5086
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_TAS571X
|
||||
tristate "Texas Instruments TAS5711/TAS5717/TAS5719 power amplifiers"
|
||||
tristate "Texas Instruments TAS5711/TAS5717/TAS5719/TAS5721 power amplifiers"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_TAS5720
|
||||
tristate "Texas Instruments TAS5720 Mono Audio amplifier"
|
||||
depends on I2C
|
||||
help
|
||||
Enable support for Texas Instruments TAS5720L/M high-efficiency mono
|
||||
Class-D audio power amplifiers.
|
||||
|
||||
config SND_SOC_TFA9879
|
||||
tristate "NXP Semiconductors TFA9879 amplifier"
|
||||
depends on I2C
|
||||
@@ -780,6 +793,16 @@ config SND_SOC_TLV320AIC31XX
|
||||
config SND_SOC_TLV320AIC32X4
|
||||
tristate
|
||||
|
||||
config SND_SOC_TLV320AIC32X4_I2C
|
||||
tristate
|
||||
depends on I2C
|
||||
select SND_SOC_TLV320AIC32X4
|
||||
|
||||
config SND_SOC_TLV320AIC32X4_SPI
|
||||
tristate
|
||||
depends on SPI_MASTER
|
||||
select SND_SOC_TLV320AIC32X4
|
||||
|
||||
config SND_SOC_TLV320AIC3X
|
||||
tristate "Texas Instruments TLV320AIC3x CODECs"
|
||||
depends on I2C
|
||||
@@ -920,7 +943,8 @@ config SND_SOC_WM8955
|
||||
tristate
|
||||
|
||||
config SND_SOC_WM8960
|
||||
tristate
|
||||
tristate "Wolfson Microelectronics WM8960 CODEC"
|
||||
depends on I2C
|
||||
|
||||
config SND_SOC_WM8961
|
||||
tristate
|
||||
|
||||
@@ -32,6 +32,7 @@ snd-soc-ak4642-objs := ak4642.o
|
||||
snd-soc-ak4671-objs := ak4671.o
|
||||
snd-soc-ak5386-objs := ak5386.o
|
||||
snd-soc-arizona-objs := arizona.o
|
||||
snd-soc-bt-sco-objs := bt-sco.o
|
||||
snd-soc-cq93vc-objs := cq93vc.o
|
||||
snd-soc-cs35l32-objs := cs35l32.o
|
||||
snd-soc-cs42l51-objs := cs42l51.o
|
||||
@@ -55,7 +56,6 @@ snd-soc-da7218-objs := da7218.o
|
||||
snd-soc-da7219-objs := da7219.o da7219-aad.o
|
||||
snd-soc-da732x-objs := da732x.o
|
||||
snd-soc-da9055-objs := da9055.o
|
||||
snd-soc-bt-sco-objs := bt-sco.o
|
||||
snd-soc-dmic-objs := dmic.o
|
||||
snd-soc-es8328-objs := es8328.o
|
||||
snd-soc-es8328-i2c-objs := es8328-i2c.o
|
||||
@@ -74,6 +74,7 @@ snd-soc-max98088-objs := max98088.o
|
||||
snd-soc-max98090-objs := max98090.o
|
||||
snd-soc-max98095-objs := max98095.o
|
||||
snd-soc-max98357a-objs := max98357a.o
|
||||
snd-soc-max98371-objs := max98371.o
|
||||
snd-soc-max9867-objs := max9867.o
|
||||
snd-soc-max98925-objs := max98925.o
|
||||
snd-soc-max98926-objs := max98926.o
|
||||
@@ -131,6 +132,7 @@ snd-soc-stac9766-objs := stac9766.o
|
||||
snd-soc-sti-sas-objs := sti-sas.o
|
||||
snd-soc-tas5086-objs := tas5086.o
|
||||
snd-soc-tas571x-objs := tas571x.o
|
||||
snd-soc-tas5720-objs := tas5720.o
|
||||
snd-soc-tfa9879-objs := tfa9879.o
|
||||
snd-soc-tlv320aic23-objs := tlv320aic23.o
|
||||
snd-soc-tlv320aic23-i2c-objs := tlv320aic23-i2c.o
|
||||
@@ -138,6 +140,8 @@ snd-soc-tlv320aic23-spi-objs := tlv320aic23-spi.o
|
||||
snd-soc-tlv320aic26-objs := tlv320aic26.o
|
||||
snd-soc-tlv320aic31xx-objs := tlv320aic31xx.o
|
||||
snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
|
||||
snd-soc-tlv320aic32x4-i2c-objs := tlv320aic32x4-i2c.o
|
||||
snd-soc-tlv320aic32x4-spi-objs := tlv320aic32x4-spi.o
|
||||
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
|
||||
snd-soc-tlv320dac33-objs := tlv320dac33.o
|
||||
snd-soc-ts3a227e-objs := ts3a227e.o
|
||||
@@ -243,6 +247,7 @@ obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o
|
||||
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
|
||||
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
|
||||
obj-$(CONFIG_SND_SOC_ARIZONA) += snd-soc-arizona.o
|
||||
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
|
||||
obj-$(CONFIG_SND_SOC_CQ0093VC) += snd-soc-cq93vc.o
|
||||
obj-$(CONFIG_SND_SOC_CS35L32) += snd-soc-cs35l32.o
|
||||
obj-$(CONFIG_SND_SOC_CS42L51) += snd-soc-cs42l51.o
|
||||
@@ -266,7 +271,6 @@ obj-$(CONFIG_SND_SOC_DA7218) += snd-soc-da7218.o
|
||||
obj-$(CONFIG_SND_SOC_DA7219) += snd-soc-da7219.o
|
||||
obj-$(CONFIG_SND_SOC_DA732X) += snd-soc-da732x.o
|
||||
obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
|
||||
obj-$(CONFIG_SND_SOC_BT_SCO) += snd-soc-bt-sco.o
|
||||
obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
|
||||
obj-$(CONFIG_SND_SOC_ES8328) += snd-soc-es8328.o
|
||||
obj-$(CONFIG_SND_SOC_ES8328_I2C)+= snd-soc-es8328-i2c.o
|
||||
@@ -339,6 +343,7 @@ obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o
|
||||
obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o
|
||||
obj-$(CONFIG_SND_SOC_TAS5086) += snd-soc-tas5086.o
|
||||
obj-$(CONFIG_SND_SOC_TAS571X) += snd-soc-tas571x.o
|
||||
obj-$(CONFIG_SND_SOC_TAS5720) += snd-soc-tas5720.o
|
||||
obj-$(CONFIG_SND_SOC_TFA9879) += snd-soc-tfa9879.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23) += snd-soc-tlv320aic23.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC23_I2C) += snd-soc-tlv320aic23-i2c.o
|
||||
@@ -346,6 +351,8 @@ obj-$(CONFIG_SND_SOC_TLV320AIC23_SPI) += snd-soc-tlv320aic23-spi.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC31XX) += snd-soc-tlv320aic31xx.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC32X4_I2C) += snd-soc-tlv320aic32x4-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC32X4_SPI) += snd-soc-tlv320aic32x4-spi.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
|
||||
obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
|
||||
obj-$(CONFIG_SND_SOC_TS3A227E) += snd-soc-ts3a227e.o
|
||||
|
||||
@@ -560,6 +560,7 @@ static const struct regmap_config ak4642_regmap = {
|
||||
.max_register = FIL1_3,
|
||||
.reg_defaults = ak4642_reg,
|
||||
.num_reg_defaults = NUM_AK4642_REG_DEFAULTS,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config ak4643_regmap = {
|
||||
@@ -568,6 +569,7 @@ static const struct regmap_config ak4643_regmap = {
|
||||
.max_register = SPK_MS,
|
||||
.reg_defaults = ak4643_reg,
|
||||
.num_reg_defaults = ARRAY_SIZE(ak4643_reg),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct regmap_config ak4648_regmap = {
|
||||
@@ -576,6 +578,7 @@ static const struct regmap_config ak4648_regmap = {
|
||||
.max_register = EQ_FBEQE,
|
||||
.reg_defaults = ak4648_reg,
|
||||
.num_reg_defaults = ARRAY_SIZE(ak4648_reg),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static const struct ak4642_drvdata ak4642_drvdata = {
|
||||
|
||||
@@ -0,0 +1,441 @@
|
||||
/*
|
||||
* max98371.c -- ALSA SoC Stereo MAX98371 driver
|
||||
*
|
||||
* Copyright 2015-16 Maxim Integrated Products
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/pcm_params.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/tlv.h>
|
||||
#include "max98371.h"
|
||||
|
||||
static const char *const monomix_text[] = {
|
||||
"Left", "Right", "LeftRightDiv2",
|
||||
};
|
||||
|
||||
static const char *const hpf_cutoff_txt[] = {
|
||||
"Disable", "DC Block", "50Hz",
|
||||
"100Hz", "200Hz", "400Hz", "800Hz",
|
||||
};
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(max98371_monomix, MAX98371_MONOMIX_CFG, 0,
|
||||
monomix_text);
|
||||
|
||||
static SOC_ENUM_SINGLE_DECL(max98371_hpf_cutoff, MAX98371_HPF, 0,
|
||||
hpf_cutoff_txt);
|
||||
|
||||
static const DECLARE_TLV_DB_RANGE(max98371_dht_min_gain,
|
||||
0, 1, TLV_DB_SCALE_ITEM(537, 66, 0),
|
||||
2, 3, TLV_DB_SCALE_ITEM(677, 82, 0),
|
||||
4, 5, TLV_DB_SCALE_ITEM(852, 104, 0),
|
||||
6, 7, TLV_DB_SCALE_ITEM(1072, 131, 0),
|
||||
8, 9, TLV_DB_SCALE_ITEM(1350, 165, 0),
|
||||
10, 11, TLV_DB_SCALE_ITEM(1699, 101, 0),
|
||||
);
|
||||
|
||||
static const DECLARE_TLV_DB_RANGE(max98371_dht_max_gain,
|
||||
0, 1, TLV_DB_SCALE_ITEM(537, 66, 0),
|
||||
2, 3, TLV_DB_SCALE_ITEM(677, 82, 0),
|
||||
4, 5, TLV_DB_SCALE_ITEM(852, 104, 0),
|
||||
6, 7, TLV_DB_SCALE_ITEM(1072, 131, 0),
|
||||
8, 9, TLV_DB_SCALE_ITEM(1350, 165, 0),
|
||||
10, 11, TLV_DB_SCALE_ITEM(1699, 208, 0),
|
||||
);
|
||||
|
||||
static const DECLARE_TLV_DB_RANGE(max98371_dht_rot_gain,
|
||||
0, 1, TLV_DB_SCALE_ITEM(-50, -50, 0),
|
||||
2, 6, TLV_DB_SCALE_ITEM(-100, -100, 0),
|
||||
7, 8, TLV_DB_SCALE_ITEM(-800, -200, 0),
|
||||
9, 11, TLV_DB_SCALE_ITEM(-1200, -300, 0),
|
||||
12, 13, TLV_DB_SCALE_ITEM(-2000, -200, 0),
|
||||
14, 15, TLV_DB_SCALE_ITEM(-2500, -500, 0),
|
||||
);
|
||||
|
||||
static const struct reg_default max98371_reg[] = {
|
||||
{ 0x01, 0x00 },
|
||||
{ 0x02, 0x00 },
|
||||
{ 0x03, 0x00 },
|
||||
{ 0x04, 0x00 },
|
||||
{ 0x05, 0x00 },
|
||||
{ 0x06, 0x00 },
|
||||
{ 0x07, 0x00 },
|
||||
{ 0x08, 0x00 },
|
||||
{ 0x09, 0x00 },
|
||||
{ 0x0A, 0x00 },
|
||||
{ 0x10, 0x06 },
|
||||
{ 0x11, 0x08 },
|
||||
{ 0x14, 0x80 },
|
||||
{ 0x15, 0x00 },
|
||||
{ 0x16, 0x00 },
|
||||
{ 0x18, 0x00 },
|
||||
{ 0x19, 0x00 },
|
||||
{ 0x1C, 0x00 },
|
||||
{ 0x1D, 0x00 },
|
||||
{ 0x1E, 0x00 },
|
||||
{ 0x1F, 0x00 },
|
||||
{ 0x20, 0x00 },
|
||||
{ 0x21, 0x00 },
|
||||
{ 0x22, 0x00 },
|
||||
{ 0x23, 0x00 },
|
||||
{ 0x24, 0x00 },
|
||||
{ 0x25, 0x00 },
|
||||
{ 0x26, 0x00 },
|
||||
{ 0x27, 0x00 },
|
||||
{ 0x28, 0x00 },
|
||||
{ 0x29, 0x00 },
|
||||
{ 0x2A, 0x00 },
|
||||
{ 0x2B, 0x00 },
|
||||
{ 0x2C, 0x00 },
|
||||
{ 0x2D, 0x00 },
|
||||
{ 0x2E, 0x0B },
|
||||
{ 0x31, 0x00 },
|
||||
{ 0x32, 0x18 },
|
||||
{ 0x33, 0x00 },
|
||||
{ 0x34, 0x00 },
|
||||
{ 0x36, 0x00 },
|
||||
{ 0x37, 0x00 },
|
||||
{ 0x38, 0x00 },
|
||||
{ 0x39, 0x00 },
|
||||
{ 0x3A, 0x00 },
|
||||
{ 0x3B, 0x00 },
|
||||
{ 0x3C, 0x00 },
|
||||
{ 0x3D, 0x00 },
|
||||
{ 0x3E, 0x00 },
|
||||
{ 0x3F, 0x00 },
|
||||
{ 0x40, 0x00 },
|
||||
{ 0x41, 0x00 },
|
||||
{ 0x42, 0x00 },
|
||||
{ 0x43, 0x00 },
|
||||
{ 0x4A, 0x00 },
|
||||
{ 0x4B, 0x00 },
|
||||
{ 0x4C, 0x00 },
|
||||
{ 0x4D, 0x00 },
|
||||
{ 0x4E, 0x00 },
|
||||
{ 0x50, 0x00 },
|
||||
{ 0x51, 0x00 },
|
||||
{ 0x55, 0x00 },
|
||||
{ 0x58, 0x00 },
|
||||
{ 0x59, 0x00 },
|
||||
{ 0x5C, 0x00 },
|
||||
{ 0xFF, 0x43 },
|
||||
};
|
||||
|
||||
static bool max98371_volatile_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case MAX98371_IRQ_CLEAR1:
|
||||
case MAX98371_IRQ_CLEAR2:
|
||||
case MAX98371_IRQ_CLEAR3:
|
||||
case MAX98371_VERSION:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool max98371_readable_register(struct device *dev, unsigned int reg)
|
||||
{
|
||||
switch (reg) {
|
||||
case MAX98371_SOFT_RESET:
|
||||
return false;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
static const DECLARE_TLV_DB_RANGE(max98371_gain_tlv,
|
||||
0, 7, TLV_DB_SCALE_ITEM(0, 50, 0),
|
||||
8, 10, TLV_DB_SCALE_ITEM(400, 100, 0)
|
||||
);
|
||||
|
||||
static const DECLARE_TLV_DB_RANGE(max98371_noload_gain_tlv,
|
||||
0, 11, TLV_DB_SCALE_ITEM(950, 100, 0),
|
||||
);
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(digital_tlv, -6300, 50, 1);
|
||||
|
||||
static const struct snd_kcontrol_new max98371_snd_controls[] = {
|
||||
SOC_SINGLE_TLV("Speaker Volume", MAX98371_GAIN,
|
||||
MAX98371_GAIN_SHIFT, (1<<MAX98371_GAIN_WIDTH)-1, 0,
|
||||
max98371_gain_tlv),
|
||||
SOC_SINGLE_TLV("Digital Volume", MAX98371_DIGITAL_GAIN, 0,
|
||||
(1<<MAX98371_DIGITAL_GAIN_WIDTH)-1, 1, digital_tlv),
|
||||
SOC_SINGLE_TLV("Speaker DHT Max Volume", MAX98371_GAIN,
|
||||
0, (1<<MAX98371_DHT_MAX_WIDTH)-1, 0,
|
||||
max98371_dht_max_gain),
|
||||
SOC_SINGLE_TLV("Speaker DHT Min Volume", MAX98371_DHT_GAIN,
|
||||
0, (1<<MAX98371_DHT_GAIN_WIDTH)-1, 0,
|
||||
max98371_dht_min_gain),
|
||||
SOC_SINGLE_TLV("Speaker DHT Rotation Volume", MAX98371_DHT_GAIN,
|
||||
0, (1<<MAX98371_DHT_ROT_WIDTH)-1, 0,
|
||||
max98371_dht_rot_gain),
|
||||
SOC_SINGLE("DHT Attack Step", MAX98371_DHT, MAX98371_DHT_STEP, 3, 0),
|
||||
SOC_SINGLE("DHT Attack Rate", MAX98371_DHT, 0, 7, 0),
|
||||
SOC_ENUM("Monomix Select", max98371_monomix),
|
||||
SOC_ENUM("HPF Cutoff", max98371_hpf_cutoff),
|
||||
};
|
||||
|
||||
static int max98371_dai_set_fmt(struct snd_soc_dai *codec_dai,
|
||||
unsigned int fmt)
|
||||
{
|
||||
struct snd_soc_codec *codec = codec_dai->codec;
|
||||
struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
|
||||
unsigned int val = 0;
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
|
||||
case SND_SOC_DAIFMT_CBS_CFS:
|
||||
break;
|
||||
default:
|
||||
dev_err(codec->dev, "DAI clock mode unsupported");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
|
||||
case SND_SOC_DAIFMT_I2S:
|
||||
val |= 0;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_RIGHT_J:
|
||||
val |= MAX98371_DAI_RIGHT;
|
||||
break;
|
||||
case SND_SOC_DAIFMT_LEFT_J:
|
||||
val |= MAX98371_DAI_LEFT;
|
||||
break;
|
||||
default:
|
||||
dev_err(codec->dev, "DAI wrong mode unsupported");
|
||||
return -EINVAL;
|
||||
}
|
||||
regmap_update_bits(max98371->regmap, MAX98371_FMT,
|
||||
MAX98371_FMT_MODE_MASK, val);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int max98371_dai_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params,
|
||||
struct snd_soc_dai *dai)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
struct max98371_priv *max98371 = snd_soc_codec_get_drvdata(codec);
|
||||
int blr_clk_ratio, ch_size, channels = params_channels(params);
|
||||
int rate = params_rate(params);
|
||||
|
||||
switch (params_format(params)) {
|
||||
case SNDRV_PCM_FORMAT_S8:
|
||||
regmap_update_bits(max98371->regmap, MAX98371_FMT,
|
||||
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_16);
|
||||
ch_size = 8;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S16_LE:
|
||||
regmap_update_bits(max98371->regmap, MAX98371_FMT,
|
||||
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_16);
|
||||
ch_size = 16;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
regmap_update_bits(max98371->regmap, MAX98371_FMT,
|
||||
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_32);
|
||||
ch_size = 24;
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
regmap_update_bits(max98371->regmap, MAX98371_FMT,
|
||||
MAX98371_FMT_MASK, MAX98371_DAI_CHANSZ_32);
|
||||
ch_size = 32;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* BCLK/LRCLK ratio calculation */
|
||||
blr_clk_ratio = channels * ch_size;
|
||||
switch (blr_clk_ratio) {
|
||||
case 32:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_DAI_CLK,
|
||||
MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_32);
|
||||
break;
|
||||
case 48:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_DAI_CLK,
|
||||
MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_48);
|
||||
break;
|
||||
case 64:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_DAI_CLK,
|
||||
MAX98371_DAI_BSEL_MASK, MAX98371_DAI_BSEL_64);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (rate) {
|
||||
case 32000:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_SPK_SR,
|
||||
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_32);
|
||||
break;
|
||||
case 44100:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_SPK_SR,
|
||||
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_44);
|
||||
break;
|
||||
case 48000:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_SPK_SR,
|
||||
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_48);
|
||||
break;
|
||||
case 88200:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_SPK_SR,
|
||||
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_88);
|
||||
break;
|
||||
case 96000:
|
||||
regmap_update_bits(max98371->regmap,
|
||||
MAX98371_SPK_SR,
|
||||
MAX98371_SPK_SR_MASK, MAX98371_SPK_SR_96);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* enabling both the RX channels*/
|
||||
regmap_update_bits(max98371->regmap, MAX98371_MONOMIX_SRC,
|
||||
MAX98371_MONOMIX_SRC_MASK, MONOMIX_RX_0_1);
|
||||
regmap_update_bits(max98371->regmap, MAX98371_DAI_CHANNEL,
|
||||
MAX98371_CHANNEL_MASK, MAX98371_CHANNEL_MASK);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget max98371_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_DAC("DAC", NULL, MAX98371_SPK_ENABLE, 0, 0),
|
||||
SND_SOC_DAPM_SUPPLY("Global Enable", MAX98371_GLOBAL_ENABLE,
|
||||
0, 0, NULL, 0),
|
||||
SND_SOC_DAPM_OUTPUT("SPK_OUT"),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route max98371_audio_map[] = {
|
||||
{"DAC", NULL, "HiFi Playback"},
|
||||
{"SPK_OUT", NULL, "DAC"},
|
||||
{"SPK_OUT", NULL, "Global Enable"},
|
||||
};
|
||||
|
||||
#define MAX98371_RATES SNDRV_PCM_RATE_8000_48000
|
||||
#define MAX98371_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | \
|
||||
SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE)
|
||||
|
||||
static const struct snd_soc_dai_ops max98371_dai_ops = {
|
||||
.set_fmt = max98371_dai_set_fmt,
|
||||
.hw_params = max98371_dai_hw_params,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_driver max98371_dai[] = {
|
||||
{
|
||||
.name = "max98371-aif1",
|
||||
.playback = {
|
||||
.stream_name = "HiFi Playback",
|
||||
.channels_min = 1,
|
||||
.channels_max = 2,
|
||||
.rates = SNDRV_PCM_RATE_8000_48000,
|
||||
.formats = MAX98371_FORMATS,
|
||||
},
|
||||
.ops = &max98371_dai_ops,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct snd_soc_codec_driver max98371_codec = {
|
||||
.controls = max98371_snd_controls,
|
||||
.num_controls = ARRAY_SIZE(max98371_snd_controls),
|
||||
.dapm_routes = max98371_audio_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(max98371_audio_map),
|
||||
.dapm_widgets = max98371_dapm_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(max98371_dapm_widgets),
|
||||
};
|
||||
|
||||
static const struct regmap_config max98371_regmap = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = MAX98371_VERSION,
|
||||
.reg_defaults = max98371_reg,
|
||||
.num_reg_defaults = ARRAY_SIZE(max98371_reg),
|
||||
.volatile_reg = max98371_volatile_register,
|
||||
.readable_reg = max98371_readable_register,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int max98371_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct max98371_priv *max98371;
|
||||
int ret, reg;
|
||||
|
||||
max98371 = devm_kzalloc(&i2c->dev,
|
||||
sizeof(*max98371), GFP_KERNEL);
|
||||
if (!max98371)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, max98371);
|
||||
max98371->regmap = devm_regmap_init_i2c(i2c, &max98371_regmap);
|
||||
if (IS_ERR(max98371->regmap)) {
|
||||
ret = PTR_ERR(max98371->regmap);
|
||||
dev_err(&i2c->dev,
|
||||
"Failed to allocate regmap: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_read(max98371->regmap, MAX98371_VERSION, ®);
|
||||
if (ret < 0) {
|
||||
dev_info(&i2c->dev, "device error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
dev_info(&i2c->dev, "device version %x\n", reg);
|
||||
|
||||
ret = snd_soc_register_codec(&i2c->dev, &max98371_codec,
|
||||
max98371_dai, ARRAY_SIZE(max98371_dai));
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c->dev, "Failed to register codec: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int max98371_i2c_remove(struct i2c_client *client)
|
||||
{
|
||||
snd_soc_unregister_codec(&client->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct i2c_device_id max98371_i2c_id[] = {
|
||||
{ "max98371", 0 },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, max98371_i2c_id);
|
||||
|
||||
static const struct of_device_id max98371_of_match[] = {
|
||||
{ .compatible = "maxim,max98371", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max98371_of_match);
|
||||
|
||||
static struct i2c_driver max98371_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "max98371",
|
||||
.owner = THIS_MODULE,
|
||||
.pm = NULL,
|
||||
.of_match_table = of_match_ptr(max98371_of_match),
|
||||
},
|
||||
.probe = max98371_i2c_probe,
|
||||
.remove = max98371_i2c_remove,
|
||||
.id_table = max98371_i2c_id,
|
||||
};
|
||||
|
||||
module_i2c_driver(max98371_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("anish kumar <yesanishhere@gmail.com>");
|
||||
MODULE_DESCRIPTION("ALSA SoC MAX98371 driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* max98371.h -- MAX98371 ALSA SoC Audio driver
|
||||
*
|
||||
* Copyright 2011-2012 Maxim Integrated Products
|
||||
*
|
||||
* 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 _MAX98371_H
|
||||
#define _MAX98371_H
|
||||
|
||||
#define MAX98371_IRQ_CLEAR1 0x01
|
||||
#define MAX98371_IRQ_CLEAR2 0x02
|
||||
#define MAX98371_IRQ_CLEAR3 0x03
|
||||
#define MAX98371_DAI_CLK 0x10
|
||||
#define MAX98371_DAI_BSEL_MASK 0xF
|
||||
#define MAX98371_DAI_BSEL_32 2
|
||||
#define MAX98371_DAI_BSEL_48 3
|
||||
#define MAX98371_DAI_BSEL_64 4
|
||||
#define MAX98371_SPK_SR 0x11
|
||||
#define MAX98371_SPK_SR_MASK 0xF
|
||||
#define MAX98371_SPK_SR_32 6
|
||||
#define MAX98371_SPK_SR_44 7
|
||||
#define MAX98371_SPK_SR_48 8
|
||||
#define MAX98371_SPK_SR_88 10
|
||||
#define MAX98371_SPK_SR_96 11
|
||||
#define MAX98371_DAI_CHANNEL 0x15
|
||||
#define MAX98371_CHANNEL_MASK 0x3
|
||||
#define MAX98371_MONOMIX_SRC 0x18
|
||||
#define MAX98371_MONOMIX_CFG 0x19
|
||||
#define MAX98371_HPF 0x1C
|
||||
#define MAX98371_MONOMIX_SRC_MASK 0xFF
|
||||
#define MONOMIX_RX_0_1 ((0x1)<<(4))
|
||||
#define M98371_DAI_CHANNEL_I2S 0x3
|
||||
#define MAX98371_DIGITAL_GAIN 0x2D
|
||||
#define MAX98371_DIGITAL_GAIN_WIDTH 0x7
|
||||
#define MAX98371_GAIN 0x2E
|
||||
#define MAX98371_GAIN_SHIFT 0x4
|
||||
#define MAX98371_GAIN_WIDTH 0x4
|
||||
#define MAX98371_DHT_MAX_WIDTH 4
|
||||
#define MAX98371_FMT 0x14
|
||||
#define MAX98371_CHANSZ_WIDTH 6
|
||||
#define MAX98371_FMT_MASK ((0x3)<<(MAX98371_CHANSZ_WIDTH))
|
||||
#define MAX98371_FMT_MODE_MASK ((0x7)<<(3))
|
||||
#define MAX98371_DAI_LEFT ((0x1)<<(3))
|
||||
#define MAX98371_DAI_RIGHT ((0x2)<<(3))
|
||||
#define MAX98371_DAI_CHANSZ_16 ((1)<<(MAX98371_CHANSZ_WIDTH))
|
||||
#define MAX98371_DAI_CHANSZ_24 ((2)<<(MAX98371_CHANSZ_WIDTH))
|
||||
#define MAX98371_DAI_CHANSZ_32 ((3)<<(MAX98371_CHANSZ_WIDTH))
|
||||
#define MAX98371_DHT 0x32
|
||||
#define MAX98371_DHT_STEP 0x3
|
||||
#define MAX98371_DHT_GAIN 0x31
|
||||
#define MAX98371_DHT_GAIN_WIDTH 0x4
|
||||
#define MAX98371_DHT_ROT_WIDTH 0x4
|
||||
#define MAX98371_SPK_ENABLE 0x4A
|
||||
#define MAX98371_GLOBAL_ENABLE 0x50
|
||||
#define MAX98371_SOFT_RESET 0x51
|
||||
#define MAX98371_VERSION 0xFF
|
||||
|
||||
|
||||
struct max98371_priv {
|
||||
struct regmap *regmap;
|
||||
struct snd_soc_codec *codec;
|
||||
};
|
||||
#endif
|
||||
+23
-28
@@ -276,6 +276,8 @@ static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic)
|
||||
} else {
|
||||
*mic = false;
|
||||
regmap_write(rt298->regmap, RT298_SET_MIC1, 0x20);
|
||||
regmap_update_bits(rt298->regmap,
|
||||
RT298_CBJ_CTRL1, 0x0400, 0x0000);
|
||||
}
|
||||
} else {
|
||||
regmap_read(rt298->regmap, RT298_GET_HP_SENSE, &buf);
|
||||
@@ -482,6 +484,26 @@ static int rt298_adc_event(struct snd_soc_dapm_widget *w,
|
||||
snd_soc_update_bits(codec,
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0),
|
||||
0x7080, 0x7000);
|
||||
/* If MCLK doesn't exist, reset AD filter */
|
||||
if (!(snd_soc_read(codec, RT298_VAD_CTRL) & 0x200)) {
|
||||
pr_info("NO MCLK\n");
|
||||
switch (nid) {
|
||||
case RT298_ADC_IN1:
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_D_FILTER_CTRL, 0x2, 0x2);
|
||||
mdelay(10);
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_D_FILTER_CTRL, 0x2, 0x0);
|
||||
break;
|
||||
case RT298_ADC_IN2:
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_D_FILTER_CTRL, 0x4, 0x4);
|
||||
mdelay(10);
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_D_FILTER_CTRL, 0x4, 0x0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
snd_soc_update_bits(codec,
|
||||
@@ -520,30 +542,12 @@ static int rt298_mic1_event(struct snd_soc_dapm_widget *w,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rt298_vref_event(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol, int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_CBJ_CTRL1, 0x0400, 0x0000);
|
||||
mdelay(50);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_dapm_widget rt298_dapm_widgets[] = {
|
||||
|
||||
SND_SOC_DAPM_SUPPLY_S("HV", 1, RT298_POWER_CTRL1,
|
||||
12, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY("VREF", RT298_POWER_CTRL1,
|
||||
0, 1, rt298_vref_event, SND_SOC_DAPM_PRE_PMU),
|
||||
0, 1, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("BG_MBIAS", 1, RT298_POWER_CTRL2,
|
||||
1, 0, NULL, 0),
|
||||
SND_SOC_DAPM_SUPPLY_S("LDO1", 1, RT298_POWER_CTRL2,
|
||||
@@ -934,18 +938,9 @@ static int rt298_set_bias_level(struct snd_soc_codec *codec,
|
||||
}
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_ON:
|
||||
mdelay(30);
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_CBJ_CTRL1, 0x0400, 0x0400);
|
||||
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
snd_soc_write(codec,
|
||||
RT298_SET_AUDIO_POWER, AC_PWRST_D3);
|
||||
snd_soc_update_bits(codec,
|
||||
RT298_CBJ_CTRL1, 0x0400, 0x0000);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -137,6 +137,7 @@
|
||||
#define RT298_A_BIAS_CTRL2 0x02
|
||||
#define RT298_POWER_CTRL1 0x03
|
||||
#define RT298_A_BIAS_CTRL3 0x04
|
||||
#define RT298_D_FILTER_CTRL 0x05
|
||||
#define RT298_POWER_CTRL2 0x08
|
||||
#define RT298_I2S_CTRL1 0x09
|
||||
#define RT298_I2S_CTRL2 0x0a
|
||||
@@ -148,6 +149,7 @@
|
||||
#define RT298_IRQ_CTRL 0x33
|
||||
#define RT298_WIND_FILTER_CTRL 0x46
|
||||
#define RT298_PLL_CTRL1 0x49
|
||||
#define RT298_VAD_CTRL 0x4e
|
||||
#define RT298_CBJ_CTRL1 0x4f
|
||||
#define RT298_CBJ_CTRL2 0x50
|
||||
#define RT298_PLL_CTRL 0x63
|
||||
|
||||
@@ -1241,60 +1241,46 @@ static int rt5677_dmic_use_asrc(struct snd_soc_dapm_widget *source,
|
||||
regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
|
||||
asrc_setting = (asrc_setting & RT5677_AD_STO1_CLK_SEL_MASK) >>
|
||||
RT5677_AD_STO1_CLK_SEL_SFT;
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 10:
|
||||
regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
|
||||
asrc_setting = (asrc_setting & RT5677_AD_STO2_CLK_SEL_MASK) >>
|
||||
RT5677_AD_STO2_CLK_SEL_SFT;
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 9:
|
||||
regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
|
||||
asrc_setting = (asrc_setting & RT5677_AD_STO3_CLK_SEL_MASK) >>
|
||||
RT5677_AD_STO3_CLK_SEL_SFT;
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
regmap_read(rt5677->regmap, RT5677_ASRC_5, &asrc_setting);
|
||||
asrc_setting = (asrc_setting & RT5677_AD_STO4_CLK_SEL_MASK) >>
|
||||
RT5677_AD_STO4_CLK_SEL_SFT;
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting);
|
||||
asrc_setting = (asrc_setting & RT5677_AD_MONOL_CLK_SEL_MASK) >>
|
||||
RT5677_AD_MONOL_CLK_SEL_SFT;
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
regmap_read(rt5677->regmap, RT5677_ASRC_6, &asrc_setting);
|
||||
asrc_setting = (asrc_setting & RT5677_AD_MONOR_CLK_SEL_MASK) >>
|
||||
RT5677_AD_MONOR_CLK_SEL_SFT;
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (asrc_setting >= RT5677_CLK_SEL_I2S1_ASRC &&
|
||||
asrc_setting <= RT5677_CLK_SEL_I2S6_ASRC)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+129
-12
@@ -4,6 +4,9 @@
|
||||
* Copyright (C) 2015 Google, Inc.
|
||||
* Copyright (c) 2013 Daniel Mack <zonque@gmail.com>
|
||||
*
|
||||
* TAS5721 support:
|
||||
* Copyright (C) 2016 Petr Kulhavy, Barix AG <petr@barix.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
@@ -57,6 +60,10 @@ static int tas571x_register_size(struct tas571x_private *priv, unsigned int reg)
|
||||
case TAS571X_CH1_VOL_REG:
|
||||
case TAS571X_CH2_VOL_REG:
|
||||
return priv->chip->vol_reg_size;
|
||||
case TAS571X_INPUT_MUX_REG:
|
||||
case TAS571X_CH4_SRC_SELECT_REG:
|
||||
case TAS571X_PWM_MUX_REG:
|
||||
return 4;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
@@ -167,6 +174,23 @@ static int tas571x_hw_params(struct snd_pcm_substream *substream,
|
||||
TAS571X_SDI_FMT_MASK, val);
|
||||
}
|
||||
|
||||
static int tas571x_mute(struct snd_soc_dai *dai, int mute)
|
||||
{
|
||||
struct snd_soc_codec *codec = dai->codec;
|
||||
u8 sysctl2;
|
||||
int ret;
|
||||
|
||||
sysctl2 = mute ? TAS571X_SYS_CTRL_2_SDN_MASK : 0;
|
||||
|
||||
ret = snd_soc_update_bits(codec,
|
||||
TAS571X_SYS_CTRL_2_REG,
|
||||
TAS571X_SYS_CTRL_2_SDN_MASK,
|
||||
sysctl2);
|
||||
usleep_range(1000, 2000);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int tas571x_set_bias_level(struct snd_soc_codec *codec,
|
||||
enum snd_soc_bias_level level)
|
||||
{
|
||||
@@ -214,6 +238,7 @@ static int tas571x_set_bias_level(struct snd_soc_codec *codec,
|
||||
static const struct snd_soc_dai_ops tas571x_dai_ops = {
|
||||
.set_fmt = tas571x_set_dai_fmt,
|
||||
.hw_params = tas571x_hw_params,
|
||||
.digital_mute = tas571x_mute,
|
||||
};
|
||||
|
||||
static const char *const tas5711_supply_names[] = {
|
||||
@@ -241,6 +266,26 @@ static const struct snd_kcontrol_new tas5711_controls[] = {
|
||||
1, 1),
|
||||
};
|
||||
|
||||
static const struct regmap_range tas571x_readonly_regs_range[] = {
|
||||
regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_DEV_ID_REG),
|
||||
};
|
||||
|
||||
static const struct regmap_range tas571x_volatile_regs_range[] = {
|
||||
regmap_reg_range(TAS571X_CLK_CTRL_REG, TAS571X_ERR_STATUS_REG),
|
||||
regmap_reg_range(TAS571X_OSC_TRIM_REG, TAS571X_OSC_TRIM_REG),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tas571x_write_regs = {
|
||||
.no_ranges = tas571x_readonly_regs_range,
|
||||
.n_no_ranges = ARRAY_SIZE(tas571x_readonly_regs_range),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table tas571x_volatile_regs = {
|
||||
.yes_ranges = tas571x_volatile_regs_range,
|
||||
.n_yes_ranges = ARRAY_SIZE(tas571x_volatile_regs_range),
|
||||
|
||||
};
|
||||
|
||||
static const struct reg_default tas5711_reg_defaults[] = {
|
||||
{ 0x04, 0x05 },
|
||||
{ 0x05, 0x40 },
|
||||
@@ -260,6 +305,8 @@ static const struct regmap_config tas5711_regmap_config = {
|
||||
.reg_defaults = tas5711_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(tas5711_reg_defaults),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.wr_table = &tas571x_write_regs,
|
||||
.volatile_table = &tas571x_volatile_regs,
|
||||
};
|
||||
|
||||
static const struct tas571x_chip tas5711_chip = {
|
||||
@@ -314,6 +361,8 @@ static const struct regmap_config tas5717_regmap_config = {
|
||||
.reg_defaults = tas5717_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(tas5717_reg_defaults),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.wr_table = &tas571x_write_regs,
|
||||
.volatile_table = &tas571x_volatile_regs,
|
||||
};
|
||||
|
||||
/* This entry is reused for tas5719 as the software interface is identical. */
|
||||
@@ -326,6 +375,77 @@ static const struct tas571x_chip tas5717_chip = {
|
||||
.vol_reg_size = 2,
|
||||
};
|
||||
|
||||
static const char *const tas5721_supply_names[] = {
|
||||
"AVDD",
|
||||
"DVDD",
|
||||
"DRVDD",
|
||||
"PVDD",
|
||||
};
|
||||
|
||||
static const struct snd_kcontrol_new tas5721_controls[] = {
|
||||
SOC_SINGLE_TLV("Master Volume",
|
||||
TAS571X_MVOL_REG,
|
||||
0, 0xff, 1, tas5711_volume_tlv),
|
||||
SOC_DOUBLE_R_TLV("Speaker Volume",
|
||||
TAS571X_CH1_VOL_REG,
|
||||
TAS571X_CH2_VOL_REG,
|
||||
0, 0xff, 1, tas5711_volume_tlv),
|
||||
SOC_DOUBLE("Speaker Switch",
|
||||
TAS571X_SOFT_MUTE_REG,
|
||||
TAS571X_SOFT_MUTE_CH1_SHIFT, TAS571X_SOFT_MUTE_CH2_SHIFT,
|
||||
1, 1),
|
||||
};
|
||||
|
||||
static const struct reg_default tas5721_reg_defaults[] = {
|
||||
{TAS571X_CLK_CTRL_REG, 0x6c},
|
||||
{TAS571X_DEV_ID_REG, 0x00},
|
||||
{TAS571X_ERR_STATUS_REG, 0x00},
|
||||
{TAS571X_SYS_CTRL_1_REG, 0xa0},
|
||||
{TAS571X_SDI_REG, 0x05},
|
||||
{TAS571X_SYS_CTRL_2_REG, 0x40},
|
||||
{TAS571X_SOFT_MUTE_REG, 0x00},
|
||||
{TAS571X_MVOL_REG, 0xff},
|
||||
{TAS571X_CH1_VOL_REG, 0x30},
|
||||
{TAS571X_CH2_VOL_REG, 0x30},
|
||||
{TAS571X_CH3_VOL_REG, 0x30},
|
||||
{TAS571X_VOL_CFG_REG, 0x91},
|
||||
{TAS571X_MODULATION_LIMIT_REG, 0x02},
|
||||
{TAS571X_IC_DELAY_CH1_REG, 0xac},
|
||||
{TAS571X_IC_DELAY_CH2_REG, 0x54},
|
||||
{TAS571X_IC_DELAY_CH3_REG, 0xac},
|
||||
{TAS571X_IC_DELAY_CH4_REG, 0x54},
|
||||
{TAS571X_PWM_CH_SDN_GROUP_REG, 0x30},
|
||||
{TAS571X_START_STOP_PERIOD_REG, 0x0f},
|
||||
{TAS571X_OSC_TRIM_REG, 0x82},
|
||||
{TAS571X_BKND_ERR_REG, 0x02},
|
||||
{TAS571X_INPUT_MUX_REG, 0x17772},
|
||||
{TAS571X_CH4_SRC_SELECT_REG, 0x4303},
|
||||
{TAS571X_PWM_MUX_REG, 0x1021345},
|
||||
};
|
||||
|
||||
static const struct regmap_config tas5721_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xff,
|
||||
.reg_read = tas571x_reg_read,
|
||||
.reg_write = tas571x_reg_write,
|
||||
.reg_defaults = tas5721_reg_defaults,
|
||||
.num_reg_defaults = ARRAY_SIZE(tas5721_reg_defaults),
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.wr_table = &tas571x_write_regs,
|
||||
.volatile_table = &tas571x_volatile_regs,
|
||||
};
|
||||
|
||||
|
||||
static const struct tas571x_chip tas5721_chip = {
|
||||
.supply_names = tas5721_supply_names,
|
||||
.num_supply_names = ARRAY_SIZE(tas5721_supply_names),
|
||||
.controls = tas5711_controls,
|
||||
.num_controls = ARRAY_SIZE(tas5711_controls),
|
||||
.regmap_config = &tas5721_regmap_config,
|
||||
.vol_reg_size = 1,
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget tas571x_dapm_widgets[] = {
|
||||
SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0),
|
||||
SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0),
|
||||
@@ -386,11 +506,10 @@ static int tas571x_i2c_probe(struct i2c_client *client,
|
||||
i2c_set_clientdata(client, priv);
|
||||
|
||||
of_id = of_match_device(tas571x_of_match, dev);
|
||||
if (!of_id) {
|
||||
dev_err(dev, "Unknown device type\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
priv->chip = of_id->data;
|
||||
if (of_id)
|
||||
priv->chip = of_id->data;
|
||||
else
|
||||
priv->chip = (void *) id->driver_data;
|
||||
|
||||
priv->mclk = devm_clk_get(dev, "mclk");
|
||||
if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) {
|
||||
@@ -445,10 +564,6 @@ static int tas571x_i2c_probe(struct i2c_client *client,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap, TAS571X_SYS_CTRL_2_REG,
|
||||
TAS571X_SYS_CTRL_2_SDN_MASK, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
memcpy(&priv->codec_driver, &tas571x_codec, sizeof(priv->codec_driver));
|
||||
priv->codec_driver.controls = priv->chip->controls;
|
||||
@@ -486,14 +601,16 @@ static const struct of_device_id tas571x_of_match[] = {
|
||||
{ .compatible = "ti,tas5711", .data = &tas5711_chip, },
|
||||
{ .compatible = "ti,tas5717", .data = &tas5717_chip, },
|
||||
{ .compatible = "ti,tas5719", .data = &tas5717_chip, },
|
||||
{ .compatible = "ti,tas5721", .data = &tas5721_chip, },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tas571x_of_match);
|
||||
|
||||
static const struct i2c_device_id tas571x_i2c_id[] = {
|
||||
{ "tas5711", 0 },
|
||||
{ "tas5717", 0 },
|
||||
{ "tas5719", 0 },
|
||||
{ "tas5711", (kernel_ulong_t) &tas5711_chip },
|
||||
{ "tas5717", (kernel_ulong_t) &tas5717_chip },
|
||||
{ "tas5719", (kernel_ulong_t) &tas5717_chip },
|
||||
{ "tas5721", (kernel_ulong_t) &tas5721_chip },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tas571x_i2c_id);
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
#define _TAS571X_H
|
||||
|
||||
/* device registers */
|
||||
#define TAS571X_CLK_CTRL_REG 0x00
|
||||
#define TAS571X_DEV_ID_REG 0x01
|
||||
#define TAS571X_ERR_STATUS_REG 0x02
|
||||
#define TAS571X_SYS_CTRL_1_REG 0x03
|
||||
#define TAS571X_SDI_REG 0x04
|
||||
#define TAS571X_SDI_FMT_MASK 0x0f
|
||||
|
||||
@@ -27,7 +31,25 @@
|
||||
#define TAS571X_MVOL_REG 0x07
|
||||
#define TAS571X_CH1_VOL_REG 0x08
|
||||
#define TAS571X_CH2_VOL_REG 0x09
|
||||
#define TAS571X_CH3_VOL_REG 0x0a
|
||||
#define TAS571X_VOL_CFG_REG 0x0e
|
||||
#define TAS571X_MODULATION_LIMIT_REG 0x10
|
||||
#define TAS571X_IC_DELAY_CH1_REG 0x11
|
||||
#define TAS571X_IC_DELAY_CH2_REG 0x12
|
||||
#define TAS571X_IC_DELAY_CH3_REG 0x13
|
||||
#define TAS571X_IC_DELAY_CH4_REG 0x14
|
||||
|
||||
#define TAS571X_PWM_CH_SDN_GROUP_REG 0x19 /* N/A on TAS5717, TAS5719 */
|
||||
#define TAS571X_PWM_CH1_SDN_MASK (1<<0)
|
||||
#define TAS571X_PWM_CH2_SDN_SHIFT (1<<1)
|
||||
#define TAS571X_PWM_CH3_SDN_SHIFT (1<<2)
|
||||
#define TAS571X_PWM_CH4_SDN_SHIFT (1<<3)
|
||||
|
||||
#define TAS571X_START_STOP_PERIOD_REG 0x1a
|
||||
#define TAS571X_OSC_TRIM_REG 0x1b
|
||||
#define TAS571X_BKND_ERR_REG 0x1c
|
||||
#define TAS571X_INPUT_MUX_REG 0x20
|
||||
#define TAS571X_CH4_SRC_SELECT_REG 0x21
|
||||
#define TAS571X_PWM_MUX_REG 0x25
|
||||
|
||||
#endif /* _TAS571X_H */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user