Skip to content

Commit

Permalink
odroid-c2:Support HiFi-Shield-2 sound card driver.
Browse files Browse the repository at this point in the history
Change-Id: I7fbf8a926460ec222cbb9e36fdfb72f891c09fcf
  • Loading branch information
ckkim committed Sep 8, 2016
1 parent 200d200 commit 5bcf1b7
Show file tree
Hide file tree
Showing 13 changed files with 1,276 additions and 1 deletion.
52 changes: 52 additions & 0 deletions Documentation/devicetree/bindings/sound/pcm512x.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
PCM512x audio CODECs

These devices support both I2C and SPI (configured with pin strapping
on the board).

Required properties:

- compatible : One of "ti,pcm5121", "ti,pcm5122", "ti,pcm5141" or
"ti,pcm5142"

- reg : the I2C address of the device for I2C, the chip select
number for SPI.

- AVDD-supply, DVDD-supply, and CPVDD-supply : power supplies for the
device, as covered in bindings/regulator/regulator.txt

Optional properties:

- clocks : A clock specifier for the clock connected as SCLK. If this
is absent the device will be configured to clock from BCLK. If pll-in
and pll-out are specified in addition to a clock, the device is
configured to accept clock input on a specified gpio pin.

- pll-in, pll-out : gpio pins used to connect the pll using <1>
through <6>. The device will be configured for clock input on the
given pll-in pin and PLL output on the given pll-out pin. An
external connection from the pll-out pin to the SCLK pin is assumed.

Examples:

pcm5122: pcm5122@4c {
compatible = "ti,pcm5122";
reg = <0x4c>;

AVDD-supply = <&reg_3v3_analog>;
DVDD-supply = <&reg_1v8>;
CPVDD-supply = <&reg_3v3>;
};


pcm5142: pcm5142@4c {
compatible = "ti,pcm5142";
reg = <0x4c>;

AVDD-supply = <&reg_3v3_analog>;
DVDD-supply = <&reg_1v8>;
CPVDD-supply = <&reg_3v3>;

clocks = <&sck>;
pll-in = <3>;
pll-out = <6>;
};
8 changes: 8 additions & 0 deletions arch/arm64/boot/dts/meson64_odroidc2.dts
Original file line number Diff line number Diff line change
Expand Up @@ -647,6 +647,14 @@
sound-dai = <&pcm5102_codec>;
};
};

odroid_dac2{
compatible = "sound_card, odroid_dac2";
aml,sound_card = "ODROID-DAC2";
pinctrl-names = "odroid_i2s";
pinctrl-0 = <&audio_pins>;
status = "okay";
};
/* END OF AUDIO board specific */

aml_sensor0: aml-sensor@0 {
Expand Down
6 changes: 5 additions & 1 deletion arch/arm64/configs/odroidc2_defconfig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#
# Automatically generated file; DO NOT EDIT.
# Linux/arm64 3.14.65 Kernel Configuration
# Linux/arm64 3.14.77 Kernel Configuration
#
CONFIG_ARM64=y
CONFIG_ARM64_HAS_SG_CHAIN=y
Expand Down Expand Up @@ -3285,9 +3285,13 @@ CONFIG_SND_AML_M8_SOC=y
# CONFIG_SND_AML_M8 is not set
CONFIG_SND_ODROID_HDMI=y
CONFIG_SND_ODROID_DAC=m
CONFIG_SND_ODROID_DAC2=m
# CONFIG_SND_AML_G9TV is not set
CONFIG_SND_SOC_I2C_AND_SPI=y
CONFIG_SND_SOC_PCM5102=m
CONFIG_SND_SOC_PCM512x=m
CONFIG_SND_SOC_PCM512x_I2C=m
# CONFIG_SND_SOC_PCM512x_SPI is not set
# CONFIG_SND_SIMPLE_CARD is not set
# CONFIG_SOUND_PRIME is not set
CONFIG_AC97_BUS=m
Expand Down
5 changes: 5 additions & 0 deletions sound/soc/aml/m8/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ menuconfig SND_ODROID_DAC
depends on SND_AML_M8_SOC
select SND_SOC_PCM5102

menuconfig SND_ODROID_DAC2
tristate "ODROID HiFi-Shield2(pcm5242) Support"
depends on SND_AML_M8_SOC
select SND_SOC_PCM512x_I2C

menuconfig SND_AML_G9TV
tristate "AML-SND-G9TV Board"
depends on SND_AML_M8_SOC && SWITCH
Expand Down
2 changes: 2 additions & 0 deletions sound/soc/aml/m8/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,10 @@ obj-$(CONFIG_SND_AML_M8) += snd-soc-aml-m8.o
#ODROID Machine support
snd-soc-odroid-hdmi-objs := odroid_hdmi.o
snd-soc-odroid-dac-objs := odroid_dac.o
snd-soc-odroid-dac2-objs := odroid_dac2.o
obj-$(CONFIG_SND_ODROID_HDMI) += snd-soc-odroid-hdmi.o
obj-$(CONFIG_SND_ODROID_DAC) += snd-soc-odroid-dac.o
obj-$(CONFIG_SND_ODROID_DAC2) += snd-soc-odroid-dac2.o

#AML G9TV Machine support
snd-soc-aml-g9tv-objs := aml_g9tv.o
Expand Down
217 changes: 217 additions & 0 deletions sound/soc/aml/m8/odroid_dac2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/*
* sound/soc/aml/m8/aml_m8.c
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* 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
* (at your option) any later version.
*
* 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/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/timer.h>
#include <linux/workqueue.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/delay.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
/* #include <sound/soc-dapm.h> */
#include <sound/jack.h>
#include <linux/switch.h>
/* #include <linux/amlogic/saradc.h> */
#include <linux/amlogic/iomap.h>

/* #include "aml_i2s_dai.h" */
#include "aml_i2s.h"
#include "odroid_dac2.h"
#include "aml_audio_hw.h"
#include <linux/amlogic/sound/audin_regs.h>
#include <linux/of.h>
#include <linux/pinctrl/consumer.h>
#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/of_gpio.h>
#include <linux/io.h>
/* extern struct device *spdif_dev; */

#define DRV_NAME "odroid_dac2"

static int dac2_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 *codec_dai = rtd->codec_dai;
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
int ret;

/* set codec DAI configuration */
ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS);
if (ret < 0)
return ret;

/* set cpu DAI configuration */
ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S |
SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM);
if (ret < 0)
return ret;

/* set cpu DAI clock */
ret = snd_soc_dai_set_sysclk(
cpu_dai, 0, params_rate(params)*256, SND_SOC_CLOCK_OUT);
if (ret < 0)
return ret;
return 0;
}

static struct snd_soc_ops odroid_ops = {
.hw_params = dac2_hw_params,
};

static int dac2_set_bias_level(struct snd_soc_card *card,
struct snd_soc_dapm_context *dapm, enum snd_soc_bias_level level)
{
int ret = 0;
struct dac2_private_data *p_dac2;

p_dac2 = snd_soc_card_get_drvdata(card);
if (p_dac2->bias_level == (int)level)
return 0;

p_dac2->bias_level = (int)level;
return ret;
}
static struct snd_soc_dai_link dac2_dai_link[] = {
{
.name = "SND_PCM5242",
.stream_name = "I2S",
.cpu_dai_name = "I2S",
.platform_name = "i2s_platform",
.codec_name = "pcm512x.1-004c",
.codec_dai_name = "pcm512x-hifi",
.ops = &odroid_ops,
},
};

static struct snd_soc_card aml_snd_soc_card = {
.driver_name = "SOC-Audio",
.dai_link = &dac2_dai_link[0],
.num_links = ARRAY_SIZE(dac2_dai_link),
.set_bias_level = dac2_set_bias_level,
};

static int dac2_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &aml_snd_soc_card;
struct dac2_private_data *p_dac2;
int ret = 0;

#ifdef CONFIG_OF
p_dac2 = devm_kzalloc(&pdev->dev,
sizeof(struct dac2_private_data), GFP_KERNEL);
if (!p_dac2) {
dev_err(&pdev->dev, "Can't allocate dac2_private_data\n");
ret = -ENOMEM;
goto err;
}

card->dev = &pdev->dev;
platform_set_drvdata(pdev, card);
snd_soc_card_set_drvdata(card, p_dac2);
if (!(pdev->dev.of_node)) {
dev_err(&pdev->dev, "Must be instantiated using device tree\n");
ret = -EINVAL;
goto err;
}
ret = of_property_read_string(pdev->dev.of_node,
"pinctrl-names",
&p_dac2->pinctrl_name);
p_dac2->pin_ctl =
devm_pinctrl_get_select(&pdev->dev, p_dac2->pinctrl_name);

ret = snd_soc_of_parse_card_name(card, "aml,sound_card");
if (ret)
goto err;

ret = snd_soc_register_card(card);
if (ret) {
dev_err(&pdev->dev, "snd_soc_register_card failed (%d)\n",
ret);
goto err;
}
return 0;
#endif

err:
return ret;
}

static int dac2_remove(struct platform_device *pdev)
{
struct snd_soc_card *card = platform_get_drvdata(pdev);
struct dac2_private_data *p_dac2;

p_dac2 = snd_soc_card_get_drvdata(card);
if (p_dac2->pin_ctl)
devm_pinctrl_put(p_dac2->pin_ctl);

snd_soc_unregister_card(card);
return 0;
}

#ifdef CONFIG_USE_OF
static const struct of_device_id dac2_dt_match[] = {
{ .compatible = "sound_card, odroid_dac2", },
{},
};
#else
#define dac2_dt_match NULL
#endif

static struct platform_driver dac2_driver = {
.probe = dac2_probe,
.remove = dac2_remove,
.driver = {
.name = DRV_NAME,
.owner = THIS_MODULE,
.pm = &snd_soc_pm_ops,
.of_match_table = dac2_dt_match,
},
};

static int __init dac2_init(void)
{
return platform_driver_register(&dac2_driver);
}

static void __exit dac2_exit(void)
{
platform_driver_unregister(&dac2_driver);
}

#ifdef CONFIG_DEFERRED_MODULE_INIT
deferred_module_init(dac2_init);
#else
module_init(dac2_init);
#endif
module_exit(dac2_exit);

/* Module information */
MODULE_AUTHOR("Hardkernel, Inc.");
MODULE_DESCRIPTION("ODROID HiFi Shield-2 Asoc driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRV_NAME);
31 changes: 31 additions & 0 deletions sound/soc/aml/m8/odroid_dac2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* sound/soc/aml/m8/aml_m8.h
*
* Copyright (C) 2015 Amlogic, Inc. All rights reserved.
*
* 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
* (at your option) any later version.
*
* 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.
*
*/

#ifndef AML_M8_H
#define AML_M8_H

#include <sound/soc.h>
#include <linux/gpio/consumer.h>
struct dac2_private_data {
int bias_level;
const char *pinctrl_name;
struct pinctrl *pin_ctl;
void *data;
};

#endif

17 changes: 17 additions & 0 deletions sound/soc/codecs/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ config SND_SOC_ALL_CODECS
select SND_SOC_DUMMY_CODEC
select SND_SOC_PCM2BT
select SND_SOC_PCM5102
select SND_SOC_PCM512x_I2C if I2C
select SND_SOC_PCM512x_SPI if SPI_MASTER
help
Normally ASoC codec drivers are only built if a machine driver which
uses them is also built since they are only usable with a machine
Expand Down Expand Up @@ -566,3 +568,18 @@ config SND_SOC_PCM2BT

config SND_SOC_PCM5102
tristate

config SND_SOC_PCM512x
tristate

config SND_SOC_PCM512x_I2C
tristate "Texas Instruments PCM512x CODECs - I2C"
depends on I2C
select SND_SOC_PCM512x
select REGMAP_I2C

config SND_SOC_PCM512x_SPI
tristate "Texas Instruments PCM512x CODECs - SPI"
depends on SPI_MASTER
select SND_SOC_PCM512x
select REGMAP_SPI
Loading

0 comments on commit 5bcf1b7

Please sign in to comment.