Skip to content
Permalink
Browse files

Audiophonics I-Sabre 9038Q2M DAC driver

Signed-off-by: Audiophonics <contact@audiophonics.fr>
  • Loading branch information...
audiophonics authored and pelwell committed Apr 5, 2019
1 parent 1026f58 commit d65a0f76d3adcf86a6f5c614c68edb3aeb3b8590
@@ -55,6 +55,7 @@ dtbo-$(CONFIG_ARCH_BCM2835) += \
hy28a.dtbo \
hy28b.dtbo \
hy28b-2017.dtbo \
i-sabre-q2m.dtbo \
i2c-bcm2708.dtbo \
i2c-gpio.dtbo \
i2c-mux.dtbo \
@@ -869,6 +869,12 @@ Params: speed Display SPI bus speed
ledgpio GPIO used to control backlight


Name: i-sabre-q2m
Info: Configures the Audiophonics I-SABRE Q2M DAC
Load: dtoverlay=i-sabre-q2m
Params: <None>


Name: i2c-bcm2708
Info: Fall back to the i2c_bcm2708 driver for the i2c_arm bus.
Load: dtoverlay=i2c-bcm2708
@@ -0,0 +1,39 @@
// Definitions for I-Sabre Q2M
/dts-v1/;
/plugin/;

/ {
compatible = "brcm,bcm2708";

fragment@0 {
target = <&sound>;
frag0: __overlay__ {
compatible = "audiophonics,i-sabre-q2m";
i2s-controller = <&i2s>;
status = "okay";
};
};

fragment@1 {
target = <&i2s>;
__overlay__ {
status = "okay";
};
};

fragment@2 {
target = <&i2c1>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";

i-sabre-codec@48 {
#sound-dai-cells = <0>;
compatible = "audiophonics,i-sabre-codec";
reg = <0x48>;
status = "okay";
};
};
};
};
@@ -916,6 +916,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m
CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m
CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m
CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m
@@ -909,6 +909,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m
CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m
CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m
CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m
@@ -804,6 +804,7 @@ CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC=m
CONFIG_SND_BCM2708_SOC_JUSTBOOM_DIGI=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC=m
CONFIG_SND_BCM2708_SOC_IQAUDIO_DIGI=m
CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M=m
CONFIG_SND_BCM2708_SOC_ADAU1977_ADC=m
CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD=m
CONFIG_SND_AUDIOSENSE_PI=m
@@ -123,6 +123,13 @@ config SND_BCM2708_SOC_IQAUDIO_DIGI
help
Say Y or M if you want to add support for IQAudIO Digital IO board.

config SND_BCM2708_SOC_I_SABRE_Q2M
tristate "Support for Audiophonics I-Sabre Q2M DAC"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
select SND_SOC_I_SABRE_CODEC
help
Say Y or M if you want to add support for Audiophonics I-SABRE Q2M DAC

config SND_BCM2708_SOC_ADAU1977_ADC
tristate "Support for ADAU1977 ADC"
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
@@ -19,6 +19,7 @@ snd-soc-justboom-dac-objs := justboom-dac.o
snd-soc-rpi-cirrus-objs := rpi-cirrus.o
snd-soc-rpi-proto-objs := rpi-proto.o
snd-soc-iqaudio-dac-objs := iqaudio-dac.o
snd-soc-i-sabre-q2m-objs := i-sabre-q2m.o
snd-soc-audioinjector-pi-soundcard-objs := audioinjector-pi-soundcard.o
snd-soc-audioinjector-octo-soundcard-objs := audioinjector-octo-soundcard.o
snd-soc-audiosense-pi-objs := audiosense-pi.o
@@ -42,6 +43,7 @@ obj-$(CONFIG_SND_BCM2708_SOC_JUSTBOOM_DAC) += snd-soc-justboom-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_CIRRUS) += snd-soc-rpi-cirrus.o
obj-$(CONFIG_SND_BCM2708_SOC_RPI_PROTO) += snd-soc-rpi-proto.o
obj-$(CONFIG_SND_BCM2708_SOC_IQAUDIO_DAC) += snd-soc-iqaudio-dac.o
obj-$(CONFIG_SND_BCM2708_SOC_I_SABRE_Q2M) += snd-soc-i-sabre-q2m.o
obj-$(CONFIG_SND_AUDIOINJECTOR_PI_SOUNDCARD) += snd-soc-audioinjector-pi-soundcard.o
obj-$(CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD) += snd-soc-audioinjector-octo-soundcard.o
obj-$(CONFIG_SND_AUDIOSENSE_PI) += snd-soc-audiosense-pi.o
@@ -0,0 +1,157 @@
/*
* ASoC Driver for I-Sabre Q2M
*
* Author: Satoru Kawase
* Modified by: Xiao Qingyong
* Update kernel v4.18+ by : Audiophonics
* Copyright 2018 Audiophonics
*
* 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.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <sound/core.h>
#include <sound/soc.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>

#include "../codecs/i-sabre-codec.h"


static int snd_rpi_i_sabre_q2m_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_component *component = rtd->codec_dai->component;
unsigned int value;

/* Device ID */
value = snd_soc_component_read32(component, ISABRECODEC_REG_01);
dev_info(component->card->dev, "Audiophonics Device ID : %02X\n", value);

/* API revision */
value = snd_soc_component_read32(component, ISABRECODEC_REG_02);
dev_info(component->card->dev, "Audiophonics API revision : %02X\n", value);

return 0;
}

static int snd_rpi_i_sabre_q2m_hw_params(
struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int bclk_ratio;

bclk_ratio = snd_pcm_format_physical_width(
params_format(params)) * params_channels(params);
return snd_soc_dai_set_bclk_ratio(cpu_dai, bclk_ratio);
}

/* machine stream operations */
static struct snd_soc_ops snd_rpi_i_sabre_q2m_ops = {
.hw_params = snd_rpi_i_sabre_q2m_hw_params,
};


static struct snd_soc_dai_link snd_rpi_i_sabre_q2m_dai[] = {
{
.name = "I-Sabre Q2M",
.stream_name = "I-Sabre Q2M DAC",
.cpu_dai_name = "bcm2708-i2s.0",
.codec_dai_name = "i-sabre-codec-dai",
.platform_name = "bcm2708-i2s.0",
.codec_name = "i-sabre-codec-i2c.1-0048",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS,
.init = snd_rpi_i_sabre_q2m_init,
.ops = &snd_rpi_i_sabre_q2m_ops,
}
};

/* audio machine driver */
static struct snd_soc_card snd_rpi_i_sabre_q2m = {
.name = "I-Sabre Q2M DAC",
.owner = THIS_MODULE,
.dai_link = snd_rpi_i_sabre_q2m_dai,
.num_links = ARRAY_SIZE(snd_rpi_i_sabre_q2m_dai)
};


static int snd_rpi_i_sabre_q2m_probe(struct platform_device *pdev)
{
int ret = 0;

snd_rpi_i_sabre_q2m.dev = &pdev->dev;
if (pdev->dev.of_node) {
struct device_node *i2s_node;
struct snd_soc_dai_link *dai;

dai = &snd_rpi_i_sabre_q2m_dai[0];
i2s_node = of_parse_phandle(pdev->dev.of_node,
"i2s-controller", 0);
if (i2s_node) {
dai->cpu_dai_name = NULL;
dai->cpu_of_node = i2s_node;
dai->platform_name = NULL;
dai->platform_of_node = i2s_node;
} else {
dev_err(&pdev->dev,
"Property 'i2s-controller' missing or invalid\n");
return (-EINVAL);
}

dai->name = "I-Sabre Q2M";
dai->stream_name = "I-Sabre Q2M DAC";
dai->dai_fmt = SND_SOC_DAIFMT_I2S
| SND_SOC_DAIFMT_NB_NF
| SND_SOC_DAIFMT_CBS_CFS;
}

/* Wait for registering codec driver */
mdelay(50);

ret = snd_soc_register_card(&snd_rpi_i_sabre_q2m);
if (ret) {
dev_err(&pdev->dev,
"snd_soc_register_card() failed: %d\n", ret);
}

return ret;
}

static int snd_rpi_i_sabre_q2m_remove(struct platform_device *pdev)
{
return snd_soc_unregister_card(&snd_rpi_i_sabre_q2m);
}

static const struct of_device_id snd_rpi_i_sabre_q2m_of_match[] = {
{ .compatible = "audiophonics,i-sabre-q2m", },
{}
};
MODULE_DEVICE_TABLE(of, snd_rpi_i_sabre_q2m_of_match);

static struct platform_driver snd_rpi_i_sabre_q2m_driver = {
.driver = {
.name = "snd-rpi-i-sabre-q2m",
.owner = THIS_MODULE,
.of_match_table = snd_rpi_i_sabre_q2m_of_match,
},
.probe = snd_rpi_i_sabre_q2m_probe,
.remove = snd_rpi_i_sabre_q2m_remove,
};
module_platform_driver(snd_rpi_i_sabre_q2m_driver);

MODULE_DESCRIPTION("ASoC Driver for I-Sabre Q2M");
MODULE_AUTHOR("Audiophonics <http://www.audiophonics.fr>");
MODULE_LICENSE("GPL");
@@ -85,6 +85,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ICS43432
select SND_SOC_INNO_RK3036
select SND_SOC_ISABELLE if I2C
select SND_SOC_I_SABRE_CODEC if I2C
select SND_SOC_JZ4740_CODEC
select SND_SOC_LM4857 if I2C
select SND_SOC_LM49453 if I2C
@@ -1322,4 +1323,8 @@ config SND_SOC_TPA6130A2
tristate "Texas Instruments TPA6130A2 headphone amplifier"
depends on I2C

config SND_SOC_I_SABRE_CODEC
tristate "Audiophonics I-SABRE Codec"
depends on I2C

endmenu
@@ -81,6 +81,7 @@ snd-soc-hdac-hdmi-objs := hdac_hdmi.o
snd-soc-ics43432-objs := ics43432.o
snd-soc-inno-rk3036-objs := inno_rk3036.o
snd-soc-isabelle-objs := isabelle.o
snd-soc-i-sabre-codec-objs := i-sabre-codec.o
snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o
@@ -343,6 +344,7 @@ obj-$(CONFIG_SND_SOC_HDAC_HDMI) += snd-soc-hdac-hdmi.o
obj-$(CONFIG_SND_SOC_ICS43432) += snd-soc-ics43432.o
obj-$(CONFIG_SND_SOC_INNO_RK3036) += snd-soc-inno-rk3036.o
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
obj-$(CONFIG_SND_SOC_I_SABRE_CODEC) += snd-soc-i-sabre-codec.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_LM4857) += snd-soc-lm4857.o
Oops, something went wrong.

0 comments on commit d65a0f7

Please sign in to comment.
You can’t perform that action at this time.