dm: sandbox: Allow selection of sample rate and channels
[pandora-u-boot.git] / drivers / sound / sandbox.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2013 Google, Inc
4  */
5
6 #include <common.h>
7 #include <audio_codec.h>
8 #include <dm.h>
9 #include <i2s.h>
10 #include <sound.h>
11 #include <asm/sdl.h>
12
13 struct sandbox_codec_priv {
14         int interface;
15         int rate;
16         int mclk_freq;
17         int bits_per_sample;
18         uint channels;
19 };
20
21 struct sandbox_i2s_priv {
22         int sum;        /* Use to sum the provided audio data */
23 };
24
25 struct sandbox_sound_priv {
26         int setup_called;
27         int sum;        /* Use to sum the provided audio data */
28 };
29
30 void sandbox_get_codec_params(struct udevice *dev, int *interfacep, int *ratep,
31                               int *mclk_freqp, int *bits_per_samplep,
32                               uint *channelsp)
33 {
34         struct sandbox_codec_priv *priv = dev_get_priv(dev);
35
36         *interfacep = priv->interface;
37         *ratep = priv->rate;
38         *mclk_freqp = priv->mclk_freq;
39         *bits_per_samplep = priv->bits_per_sample;
40         *channelsp = priv->channels;
41 }
42
43 int sandbox_get_i2s_sum(struct udevice *dev)
44 {
45         struct sandbox_i2s_priv *priv = dev_get_priv(dev);
46
47         return priv->sum;
48 }
49
50 int sandbox_get_setup_called(struct udevice *dev)
51 {
52         struct sandbox_sound_priv *priv = dev_get_priv(dev);
53
54         return priv->setup_called;
55 }
56
57 int sandbox_get_sound_sum(struct udevice *dev)
58 {
59         struct sandbox_sound_priv *priv = dev_get_priv(dev);
60
61         return priv->sum;
62 }
63
64 static int sandbox_codec_set_params(struct udevice *dev, int interface,
65                                     int rate, int mclk_freq,
66                                     int bits_per_sample, uint channels)
67 {
68         struct sandbox_codec_priv *priv = dev_get_priv(dev);
69
70         priv->interface = interface;
71         priv->rate = rate;
72         priv->mclk_freq = mclk_freq;
73         priv->bits_per_sample = bits_per_sample;
74         priv->channels = channels;
75
76         return 0;
77 }
78
79 static int sandbox_i2s_tx_data(struct udevice *dev, void *data,
80                                uint data_size)
81 {
82         struct sandbox_i2s_priv *priv = dev_get_priv(dev);
83         int i;
84
85         for (i = 0; i < data_size; i++)
86                 priv->sum += ((uint8_t *)data)[i];
87
88         return sandbox_sdl_sound_play(data, data_size);
89 }
90
91 static int sandbox_i2s_probe(struct udevice *dev)
92 {
93         struct i2s_uc_priv *uc_priv = dev_get_uclass_priv(dev);
94
95         /* Use hard-coded values here */
96         uc_priv->rfs = 256;
97         uc_priv->bfs = 32;
98         uc_priv->audio_pll_clk = 192000000;
99         uc_priv->samplingrate = 48000;
100         uc_priv->bitspersample = 16;
101         uc_priv->channels = 2;
102         uc_priv->id = 1;
103
104         /* Ignore any error here - we'll just have no sound */
105         sandbox_sdl_sound_init(uc_priv->samplingrate, uc_priv->channels);
106
107         return 0;
108 }
109
110 static int sandbox_sound_setup(struct udevice *dev)
111 {
112         struct sandbox_sound_priv *priv = dev_get_priv(dev);
113
114         priv->setup_called++;
115
116         return 0;
117 }
118
119 static int sandbox_sound_play(struct udevice *dev, void *data, uint data_size)
120 {
121         struct sound_uc_priv *uc_priv = dev_get_uclass_priv(dev);
122         struct sandbox_sound_priv *priv = dev_get_priv(dev);
123         int i;
124
125         for (i = 0; i < data_size; i++)
126                 priv->sum += ((uint8_t *)data)[i];
127
128         return i2s_tx_data(uc_priv->i2s, data, data_size);
129 }
130
131 static int sandbox_sound_probe(struct udevice *dev)
132 {
133         return sound_find_codec_i2s(dev);
134 }
135
136 static const struct audio_codec_ops sandbox_codec_ops = {
137         .set_params     = sandbox_codec_set_params,
138 };
139
140 static const struct udevice_id sandbox_codec_ids[] = {
141         { .compatible = "sandbox,audio-codec" },
142         { }
143 };
144
145 U_BOOT_DRIVER(sandbox_codec) = {
146         .name           = "sandbox_codec",
147         .id             = UCLASS_AUDIO_CODEC,
148         .of_match       = sandbox_codec_ids,
149         .ops            = &sandbox_codec_ops,
150         .priv_auto_alloc_size   = sizeof(struct sandbox_codec_priv),
151 };
152
153 static const struct i2s_ops sandbox_i2s_ops = {
154         .tx_data        = sandbox_i2s_tx_data,
155 };
156
157 static const struct udevice_id sandbox_i2s_ids[] = {
158         { .compatible = "sandbox,i2s" },
159         { }
160 };
161
162 U_BOOT_DRIVER(sandbox_i2s) = {
163         .name           = "sandbox_i2s",
164         .id             = UCLASS_I2S,
165         .of_match       = sandbox_i2s_ids,
166         .ops            = &sandbox_i2s_ops,
167         .probe          = sandbox_i2s_probe,
168         .priv_auto_alloc_size   = sizeof(struct sandbox_i2s_priv),
169 };
170
171 static const struct sound_ops sandbox_sound_ops = {
172         .setup  = sandbox_sound_setup,
173         .play   = sandbox_sound_play,
174 };
175
176 static const struct udevice_id sandbox_sound_ids[] = {
177         { .compatible = "sandbox,sound" },
178         { }
179 };
180
181 U_BOOT_DRIVER(sandbox_sound) = {
182         .name           = "sandbox_sound",
183         .id             = UCLASS_SOUND,
184         .of_match       = sandbox_sound_ids,
185         .ops            = &sandbox_sound_ops,
186         .priv_auto_alloc_size   = sizeof(struct sandbox_sound_priv),
187         .probe          = sandbox_sound_probe,
188 };