2 * ALSA ASoC Machine Driver for Allo Piano DAC
4 * Author: Baswaraj K <jaikumar@cem-solutions.net>
6 * based on code by Daniel Matuschek <info@crazy-audio.com>
7 * based on code by Florian Meier <florian.meier@koalo.de>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * version 2 as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
19 #include <linux/module.h>
20 #include <linux/platform_device.h>
22 #include <sound/core.h>
23 #include <sound/pcm.h>
24 #include <sound/pcm_params.h>
25 #include <sound/soc.h>
27 static bool digital_gain_0db_limit
= true;
29 static int snd_allo_piano_dac_init(struct snd_soc_pcm_runtime
*rtd
)
31 if (digital_gain_0db_limit
) {
33 struct snd_soc_card
*card
= rtd
->card
;
35 ret
= snd_soc_limit_volume(card
, "Digital Playback Volume",
38 dev_warn(card
->dev
, "Failed to set volume limit: %d\n",
45 static int snd_allo_piano_dac_hw_params(
46 struct snd_pcm_substream
*substream
, struct snd_pcm_hw_params
*params
)
48 struct snd_soc_pcm_runtime
*rtd
= substream
->private_data
;
49 struct snd_soc_dai
*cpu_dai
= rtd
->cpu_dai
;
51 unsigned int sample_bits
=
52 snd_pcm_format_physical_width(params_format(params
));
54 return snd_soc_dai_set_bclk_ratio(cpu_dai
, sample_bits
* 2);
57 /* machine stream operations */
58 static struct snd_soc_ops snd_allo_piano_dac_ops
= {
59 .hw_params
= snd_allo_piano_dac_hw_params
,
62 static struct snd_soc_dai_link snd_allo_piano_dac_dai
[] = {
65 .stream_name
= "Piano DAC HiFi",
66 .cpu_dai_name
= "bcm2708-i2s.0",
67 .codec_dai_name
= "pcm512x-hifi",
68 .platform_name
= "bcm2708-i2s.0",
69 .codec_name
= "pcm512x.1-004c",
70 .dai_fmt
= SND_SOC_DAIFMT_I2S
|
71 SND_SOC_DAIFMT_NB_NF
|
72 SND_SOC_DAIFMT_CBS_CFS
,
73 .ops
= &snd_allo_piano_dac_ops
,
74 .init
= snd_allo_piano_dac_init
,
78 /* audio machine driver */
79 static struct snd_soc_card snd_allo_piano_dac
= {
82 .dai_link
= snd_allo_piano_dac_dai
,
83 .num_links
= ARRAY_SIZE(snd_allo_piano_dac_dai
),
86 static int snd_allo_piano_dac_probe(struct platform_device
*pdev
)
90 snd_allo_piano_dac
.dev
= &pdev
->dev
;
92 if (pdev
->dev
.of_node
) {
93 struct device_node
*i2s_node
;
94 struct snd_soc_dai_link
*dai
;
96 dai
= &snd_allo_piano_dac_dai
[0];
97 i2s_node
= of_parse_phandle(pdev
->dev
.of_node
,
101 dai
->cpu_dai_name
= NULL
;
102 dai
->cpu_of_node
= i2s_node
;
103 dai
->platform_name
= NULL
;
104 dai
->platform_of_node
= i2s_node
;
107 digital_gain_0db_limit
= !of_property_read_bool(
108 pdev
->dev
.of_node
, "allo,24db_digital_gain");
111 ret
= snd_soc_register_card(&snd_allo_piano_dac
);
114 "snd_soc_register_card() failed: %d\n", ret
);
119 static int snd_allo_piano_dac_remove(struct platform_device
*pdev
)
121 return snd_soc_unregister_card(&snd_allo_piano_dac
);
124 static const struct of_device_id snd_allo_piano_dac_of_match
[] = {
125 { .compatible
= "allo,piano-dac", },
128 MODULE_DEVICE_TABLE(of
, snd_allo_piano_dac_of_match
);
130 static struct platform_driver snd_allo_piano_dac_driver
= {
132 .name
= "snd-allo-piano-dac",
133 .owner
= THIS_MODULE
,
134 .of_match_table
= snd_allo_piano_dac_of_match
,
136 .probe
= snd_allo_piano_dac_probe
,
137 .remove
= snd_allo_piano_dac_remove
,
140 module_platform_driver(snd_allo_piano_dac_driver
);
142 MODULE_AUTHOR("Baswaraj K <jaikumar@cem-solutions.net>");
143 MODULE_DESCRIPTION("ALSA ASoC Machine Driver for Allo Piano DAC");
144 MODULE_LICENSE("GPL v2");