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