mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
Add support for new clock rate and mute gpios.
Signed-off-by: Baswaraj K <jaikumar@cem-solutions.net> Reviewed-by: Deepak <deepak@zilogic.com> Reviewed-by: BabuSubashChandar <babusubashchandar@zilogic.com>
This commit is contained in:
committed by
Phil Elwell
parent
f10ad96532
commit
8ecb17cc77
@@ -47,6 +47,7 @@
|
||||
boss_dac: __overlay__ {
|
||||
compatible = "allo,boss-dac";
|
||||
i2s-controller = <&i2s>;
|
||||
mute-gpios = <&gpio 6 1>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -894,6 +894,7 @@ CONFIG_SND_AUDIOINJECTOR_OCTO_SOUNDCARD=m
|
||||
CONFIG_SND_DIGIDAC1_SOUNDCARD=m
|
||||
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO=m
|
||||
CONFIG_SND_BCM2708_SOC_DIONAUDIO_LOCO_V2=m
|
||||
CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC=m
|
||||
CONFIG_SND_BCM2708_SOC_ALLO_PIANO_DAC=m
|
||||
CONFIG_SND_BCM2708_SOC_FE_PI_AUDIO=m
|
||||
CONFIG_SND_PISOUND=m
|
||||
|
||||
@@ -17,7 +17,7 @@ endif
|
||||
|
||||
# hardware specific clock types
|
||||
# please keep this section sorted lexicographically by file path name
|
||||
obj-$(CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC) += clk-allo-dac-45Mhz.o
|
||||
obj-$(CONFIG_SND_BCM2708_SOC_ALLO_BOSS_DAC) += clk-allo-dac.o
|
||||
obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
|
||||
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
|
||||
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
|
||||
|
||||
@@ -110,7 +110,7 @@ static int clk_allo_dac_probe(struct platform_device *pdev)
|
||||
|
||||
init.name = "clk-allo-dac";
|
||||
init.ops = &clk_allo_dac_rate_ops;
|
||||
init.flags = CLK_IS_ROOT | CLK_IS_BASIC;
|
||||
init.flags = CLK_IS_BASIC;
|
||||
init.parent_names = NULL;
|
||||
init.num_parents = 0;
|
||||
|
||||
@@ -176,11 +176,11 @@ config SND_BCM2708_SOC_FE_PI_AUDIO
|
||||
Say Y or M if you want to add support for Fe-Pi-Audio.
|
||||
|
||||
config SND_BCM2708_SOC_ALLO_BOSS_DAC
|
||||
tristate "Support for allo Boss DAC"
|
||||
tristate "Support for Allo Boss DAC"
|
||||
depends on SND_BCM2708_SOC_I2S || SND_BCM2835_SOC_I2S
|
||||
select SND_SOC_PCM512x_I2C
|
||||
help
|
||||
Say Y or M if you want to add support for allo Boss DAC.
|
||||
Say Y or M if you want to add support for Allo Boss DAC.
|
||||
|
||||
|
||||
config SND_PISOUND
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
* ALSA ASoC Machine Driver for Allo Boss DAC
|
||||
*
|
||||
* Author: Baswaraj K <jaikumar@cem-solutions.net>
|
||||
* Copyright 2016
|
||||
* based on code by Daniel Matuschek, Stuart MacLean <stuart@hifiberry.com>
|
||||
* Copyright 2017
|
||||
* based on code by Daniel Matuschek,
|
||||
* Stuart MacLean <stuart@hifiberry.com>
|
||||
* based on code by Florian Meier <florian.meier@koalo.de>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -17,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
@@ -36,6 +38,8 @@ struct pcm512x_priv {
|
||||
struct clk *sclk;
|
||||
};
|
||||
|
||||
static struct gpio_desc *mute_gpio;
|
||||
|
||||
/* Clock rate of CLK44EN attached to GPIO6 pin */
|
||||
#define CLK_44EN_RATE 45158400UL
|
||||
/* Clock rate of CLK48EN attached to GPIO3 pin */
|
||||
@@ -111,6 +115,7 @@ static int snd_allo_boss_clk_for_rate(int sample_rate)
|
||||
case 44100:
|
||||
case 88200:
|
||||
case 176400:
|
||||
case 352800:
|
||||
type = ALLO_BOSS_CLK44EN;
|
||||
break;
|
||||
default:
|
||||
@@ -138,7 +143,7 @@ static void snd_allo_boss_set_sclk(struct snd_soc_codec *codec,
|
||||
static int snd_allo_boss_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct pcm512x_priv *priv;
|
||||
struct pcm512x_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
|
||||
if (slave)
|
||||
snd_soc_allo_boss_master = false;
|
||||
@@ -150,15 +155,22 @@ static int snd_allo_boss_init(struct snd_soc_pcm_runtime *rtd)
|
||||
struct snd_soc_dai_link *dai = rtd->dai_link;
|
||||
|
||||
dai->name = "BossDAC";
|
||||
dai->stream_name = "BossDAC";
|
||||
dai->stream_name = "Boss DAC HiFi [Master]";
|
||||
dai->dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF
|
||||
| SND_SOC_DAIFMT_CBM_CFM;
|
||||
|
||||
snd_soc_update_bits(codec, PCM512x_BCLK_LRCLK_CFG, 0x31, 0x11);
|
||||
snd_soc_update_bits(codec, PCM512x_MASTER_MODE, 0x03, 0x03);
|
||||
snd_soc_update_bits(codec, PCM512x_MASTER_CLKDIV_2, 0x7f, 63);
|
||||
/*
|
||||
* Default sclk to CLK_48EN_RATE, otherwise codec
|
||||
* pcm512x_dai_startup_master method could call
|
||||
* snd_pcm_hw_constraint_ratnums using CLK_44EN/64
|
||||
* which will mask 384k sample rate.
|
||||
*/
|
||||
if (!IS_ERR(priv->sclk))
|
||||
clk_set_rate(priv->sclk, CLK_48EN_RATE);
|
||||
} else {
|
||||
priv = snd_soc_codec_get_drvdata(codec);
|
||||
priv->sclk = ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
@@ -218,6 +230,52 @@ static int snd_allo_boss_set_bclk_ratio_pro(
|
||||
return snd_soc_dai_set_bclk_ratio(cpu_dai, bratio);
|
||||
}
|
||||
|
||||
static void snd_allo_boss_gpio_mute(struct snd_soc_card *card)
|
||||
{
|
||||
if (mute_gpio)
|
||||
gpiod_set_value_cansleep(mute_gpio, 1);
|
||||
}
|
||||
|
||||
static void snd_allo_boss_gpio_unmute(struct snd_soc_card *card)
|
||||
{
|
||||
if (mute_gpio)
|
||||
gpiod_set_value_cansleep(mute_gpio, 0);
|
||||
}
|
||||
|
||||
static int snd_allo_boss_set_bias_level(struct snd_soc_card *card,
|
||||
struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd;
|
||||
struct snd_soc_dai *codec_dai;
|
||||
|
||||
rtd = snd_soc_get_pcm_runtime(card, card->dai_link[0].name);
|
||||
codec_dai = rtd->codec_dai;
|
||||
|
||||
if (dapm->dev != codec_dai->dev)
|
||||
return 0;
|
||||
|
||||
switch (level) {
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
if (dapm->bias_level != SND_SOC_BIAS_STANDBY)
|
||||
break;
|
||||
/* UNMUTE DAC */
|
||||
snd_allo_boss_gpio_unmute(card);
|
||||
break;
|
||||
|
||||
case SND_SOC_BIAS_STANDBY:
|
||||
if (dapm->bias_level != SND_SOC_BIAS_PREPARE)
|
||||
break;
|
||||
/* MUTE DAC */
|
||||
snd_allo_boss_gpio_mute(card);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_allo_boss_hw_params(
|
||||
struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params)
|
||||
{
|
||||
@@ -239,23 +297,6 @@ static int snd_allo_boss_hw_params(
|
||||
ret = snd_allo_boss_update_rate_den(
|
||||
substream, params);
|
||||
} else {
|
||||
if (snd_allo_boss_is_sclk(rtd->codec)) {
|
||||
snd_soc_update_bits(rtd->codec, PCM512x_PLL_EN,
|
||||
PCM512x_PLLE, 0x01);
|
||||
snd_soc_update_bits(rtd->codec, PCM512x_PLL_REF,
|
||||
PCM512x_SREF, PCM512x_SREF_BCK);
|
||||
dev_dbg(rtd->codec->dev,
|
||||
"Setting BCLK as input clock and Enable PLL\n");
|
||||
} else {
|
||||
snd_soc_update_bits(rtd->codec, PCM512x_PLL_EN,
|
||||
PCM512x_PLLE, 0x00);
|
||||
snd_soc_update_bits(rtd->codec, PCM512x_PLL_REF,
|
||||
PCM512x_SREF, PCM512x_SREF_SCK);
|
||||
|
||||
dev_dbg(rtd->codec->dev,
|
||||
"Setting SCLK as input clock and disabled PLL\n");
|
||||
}
|
||||
|
||||
ret = snd_soc_dai_set_bclk_ratio(cpu_dai, sample_bits * 2);
|
||||
}
|
||||
return ret;
|
||||
@@ -266,8 +307,23 @@ static int snd_allo_boss_startup(
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
|
||||
snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x08);
|
||||
snd_allo_boss_gpio_mute(card);
|
||||
|
||||
if (snd_soc_allo_boss_master) {
|
||||
struct pcm512x_priv *priv = snd_soc_codec_get_drvdata(codec);
|
||||
/*
|
||||
* Default sclk to CLK_48EN_RATE, otherwise codec
|
||||
* pcm512x_dai_startup_master method could call
|
||||
* snd_pcm_hw_constraint_ratnums using CLK_44EN/64
|
||||
* which will mask 384k sample rate.
|
||||
*/
|
||||
if (!IS_ERR(priv->sclk))
|
||||
clk_set_rate(priv->sclk, CLK_48EN_RATE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -280,11 +336,21 @@ static void snd_allo_boss_shutdown(
|
||||
snd_soc_update_bits(codec, PCM512x_GPIO_CONTROL_1, 0x08, 0x00);
|
||||
}
|
||||
|
||||
static int snd_allo_boss_prepare(
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_card *card = rtd->card;
|
||||
|
||||
snd_allo_boss_gpio_unmute(card);
|
||||
return 0;
|
||||
}
|
||||
/* machine stream operations */
|
||||
static struct snd_soc_ops snd_allo_boss_ops = {
|
||||
.hw_params = snd_allo_boss_hw_params,
|
||||
.startup = snd_allo_boss_startup,
|
||||
.shutdown = snd_allo_boss_shutdown,
|
||||
.prepare = snd_allo_boss_prepare,
|
||||
};
|
||||
|
||||
static struct snd_soc_dai_link snd_allo_boss_dai[] = {
|
||||
@@ -335,19 +401,40 @@ static int snd_allo_boss_probe(struct platform_device *pdev)
|
||||
digital_gain_0db_limit = !of_property_read_bool(
|
||||
pdev->dev.of_node, "allo,24db_digital_gain");
|
||||
slave = of_property_read_bool(pdev->dev.of_node,
|
||||
"allo,slave");
|
||||
"allo,slave");
|
||||
|
||||
mute_gpio = devm_gpiod_get_optional(&pdev->dev, "mute",
|
||||
GPIOD_OUT_LOW);
|
||||
if (IS_ERR(mute_gpio)) {
|
||||
ret = PTR_ERR(mute_gpio);
|
||||
dev_err(&pdev->dev,
|
||||
"failed to get mute gpio: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mute_gpio)
|
||||
snd_allo_boss.set_bias_level =
|
||||
snd_allo_boss_set_bias_level;
|
||||
|
||||
ret = snd_soc_register_card(&snd_allo_boss);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"snd_soc_register_card() failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mute_gpio)
|
||||
snd_allo_boss_gpio_mute(&snd_allo_boss);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = snd_soc_register_card(&snd_allo_boss);
|
||||
if (ret)
|
||||
dev_err(&pdev->dev,
|
||||
"snd_soc_register_card() failed: %d\n", ret);
|
||||
|
||||
return ret;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int snd_allo_boss_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_allo_boss_gpio_mute(&snd_allo_boss);
|
||||
return snd_soc_unregister_card(&snd_allo_boss);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user