brcm2708: update against latest rpi-3.10.y branch
[openwrt.git] / target / linux / brcm2708 / patches-3.10 / 0061-Merge-pull-request-286-from-martinezjavier-rpi-3.6.y.patch
1 From 5d42dfcf42ba987a03d8b5f2dfa30e9cb2dc4721 Mon Sep 17 00:00:00 2001
2 From: popcornmix <popcornmix@gmail.com>
3 Date: Fri, 26 Apr 2013 10:08:31 -0700
4 Subject: [PATCH 061/174] Merge pull request #286 from
5  martinezjavier/rpi-3.6.y-dev
6
7 add mmap support and some cleanups to bcm2835 ALSA driver
8 ---
9  sound/arm/bcm2835-pcm.c   | 69 ++++++++++++++++++++++--------------
10  sound/arm/bcm2835-vchiq.c | 89 +++++++++++++++++++++++++++++++++--------------
11  sound/arm/bcm2835.c       | 34 +++++++++---------
12  sound/arm/bcm2835.h       |  2 ++
13  4 files changed, 124 insertions(+), 70 deletions(-)
14
15 --- a/sound/arm/bcm2835-pcm.c
16 +++ b/sound/arm/bcm2835-pcm.c
17 @@ -19,7 +19,8 @@
18  
19  /* hardware definition */
20  static struct snd_pcm_hardware snd_bcm2835_playback_hw = {
21 -       .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER),
22 +       .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER |
23 +                SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID),
24         .formats = SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE,
25         .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000,
26         .rate_min = 8000,
27 @@ -251,6 +252,12 @@ static int snd_bcm2835_pcm_prepare(struc
28  
29         audio_info(" .. IN\n");
30  
31 +       memset(&alsa_stream->pcm_indirect, 0, sizeof(alsa_stream->pcm_indirect));
32 +
33 +       alsa_stream->pcm_indirect.hw_buffer_size =
34 +       alsa_stream->pcm_indirect.sw_buffer_size =
35 +               snd_pcm_lib_buffer_bytes(substream);
36 +
37         alsa_stream->buffer_size = snd_pcm_lib_buffer_bytes(substream);
38         alsa_stream->period_size = snd_pcm_lib_period_bytes(substream);
39         alsa_stream->pos = 0;
40 @@ -263,6 +270,32 @@ static int snd_bcm2835_pcm_prepare(struc
41         return 0;
42  }
43  
44 +static void snd_bcm2835_pcm_transfer(struct snd_pcm_substream *substream,
45 +                                   struct snd_pcm_indirect *rec, size_t bytes)
46 +{
47 +       struct snd_pcm_runtime *runtime = substream->runtime;
48 +       bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
49 +       void *src = (void *)(substream->runtime->dma_area + rec->sw_data);
50 +       int err;
51 +
52 +       err = bcm2835_audio_write(alsa_stream, bytes, src);
53 +       if (err)
54 +               audio_error(" Failed to transfer to alsa device (%d)\n", err);
55 +
56 +}
57 +
58 +static int snd_bcm2835_pcm_ack(struct snd_pcm_substream *substream)
59 +{
60 +       struct snd_pcm_runtime *runtime = substream->runtime;
61 +       bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
62 +       struct snd_pcm_indirect *pcm_indirect = &alsa_stream->pcm_indirect;
63 +
64 +       pcm_indirect->hw_queue_size = runtime->hw.buffer_bytes_max;
65 +       snd_pcm_indirect_playback_transfer(substream, pcm_indirect,
66 +                                          snd_bcm2835_pcm_transfer);
67 +       return 0;
68 +}
69 +
70  /* trigger callback */
71  static int snd_bcm2835_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
72  {
73 @@ -279,6 +312,11 @@ static int snd_bcm2835_pcm_trigger(struc
74                 if (!alsa_stream->running) {
75                         err = bcm2835_audio_start(alsa_stream);
76                         if (err == 0) {
77 +                               alsa_stream->pcm_indirect.hw_io =
78 +                               alsa_stream->pcm_indirect.hw_data =
79 +                                       bytes_to_frames(runtime,
80 +                                                       alsa_stream->pos);
81 +                               substream->ops->ack(substream);
82                                 alsa_stream->running = 1;
83                                 alsa_stream->draining = 1;
84                         } else {
85 @@ -327,30 +365,9 @@ snd_bcm2835_pcm_pointer(struct snd_pcm_s
86                       alsa_stream->pos);
87  
88         audio_info(" .. OUT\n");
89 -       return bytes_to_frames(runtime, alsa_stream->pos);
90 -}
91 -
92 -static int snd_bcm2835_pcm_copy(struct snd_pcm_substream *substream,
93 -                               int channel, snd_pcm_uframes_t pos, void *src,
94 -                               snd_pcm_uframes_t count)
95 -{
96 -       int ret;
97 -       struct snd_pcm_runtime *runtime = substream->runtime;
98 -       bcm2835_alsa_stream_t *alsa_stream = runtime->private_data;
99 -
100 -       audio_info(" .. IN\n");
101 -       audio_debug("copy.......... (%d) hwptr=%d appl=%d pos=%d\n",
102 -                     frames_to_bytes(runtime, count), frames_to_bytes(runtime,
103 -                                                                      runtime->
104 -                                                                      status->
105 -                                                                      hw_ptr),
106 -                     frames_to_bytes(runtime, runtime->control->appl_ptr),
107 -                     alsa_stream->pos);
108 -       ret =
109 -           bcm2835_audio_write(alsa_stream, frames_to_bytes(runtime, count),
110 -                               src);
111 -       audio_info(" .. OUT\n");
112 -       return ret;
113 +       return snd_pcm_indirect_playback_pointer(substream,
114 +                                                &alsa_stream->pcm_indirect,
115 +                                                alsa_stream->pos);
116  }
117  
118  static int snd_bcm2835_pcm_lib_ioctl(struct snd_pcm_substream *substream,
119 @@ -372,7 +389,7 @@ static struct snd_pcm_ops snd_bcm2835_pl
120         .prepare = snd_bcm2835_pcm_prepare,
121         .trigger = snd_bcm2835_pcm_trigger,
122         .pointer = snd_bcm2835_pcm_pointer,
123 -       .copy = snd_bcm2835_pcm_copy,
124 +       .ack = snd_bcm2835_pcm_ack,
125  };
126  
127  /* create a pcm device */
128 --- a/sound/arm/bcm2835-vchiq.c
129 +++ b/sound/arm/bcm2835-vchiq.c
130 @@ -27,6 +27,7 @@
131  #include <linux/delay.h>
132  #include <linux/atomic.h>
133  #include <linux/module.h>
134 +#include <linux/completion.h>
135  
136  #include "bcm2835.h"
137  
138 @@ -37,6 +38,10 @@
139  
140  /* ---- Private Constants and Types ------------------------------------------ */
141  
142 +#define BCM2835_AUDIO_STOP           0
143 +#define BCM2835_AUDIO_START          1
144 +#define BCM2835_AUDIO_WRITE          2
145 +
146  /* Logging macros (for remapping to other logging mechanisms, i.e., printf) */
147  #ifdef AUDIO_DEBUG_ENABLE
148         #define LOG_ERR( fmt, arg... )   pr_err( "%s:%d " fmt, __func__, __LINE__, ##arg)
149 @@ -53,7 +58,7 @@
150  typedef struct opaque_AUDIO_INSTANCE_T {
151         uint32_t num_connections;
152         VCHI_SERVICE_HANDLE_T vchi_handle[VCHI_MAX_NUM_CONNECTIONS];
153 -       struct semaphore msg_avail_event;
154 +       struct completion msg_avail_comp;
155         struct mutex vchi_mutex;
156         bcm2835_alsa_stream_t *alsa_stream;
157         int32_t result;
158 @@ -70,27 +75,35 @@ bool force_bulk = false;
159  
160  static int bcm2835_audio_stop_worker(bcm2835_alsa_stream_t * alsa_stream);
161  static int bcm2835_audio_start_worker(bcm2835_alsa_stream_t * alsa_stream);
162 +static int bcm2835_audio_write_worker(bcm2835_alsa_stream_t *alsa_stream,
163 +                                     uint32_t count, void *src);
164  
165  typedef struct {
166         struct work_struct my_work;
167         bcm2835_alsa_stream_t *alsa_stream;
168 -       int x;
169 +       int cmd;
170 +       void *src;
171 +       uint32_t count;
172  } my_work_t;
173  
174  static void my_wq_function(struct work_struct *work)
175  {
176         my_work_t *w = (my_work_t *) work;
177         int ret = -9;
178 -       LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->x);
179 -       switch (w->x) {
180 -       case 1:
181 +       LOG_DBG(" .. IN %p:%d\n", w->alsa_stream, w->cmd);
182 +       switch (w->cmd) {
183 +       case BCM2835_AUDIO_START:
184                 ret = bcm2835_audio_start_worker(w->alsa_stream);
185                 break;
186 -       case 2:
187 +       case BCM2835_AUDIO_STOP:
188                 ret = bcm2835_audio_stop_worker(w->alsa_stream);
189                 break;
190 +       case BCM2835_AUDIO_WRITE:
191 +               ret = bcm2835_audio_write_worker(w->alsa_stream, w->count,
192 +                                                w->src);
193 +               break;
194         default:
195 -               LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->x);
196 +               LOG_ERR(" Unexpected work: %p:%d\n", w->alsa_stream, w->cmd);
197                 break;
198         }
199         kfree((void *)work);
200 @@ -107,7 +120,7 @@ int bcm2835_audio_start(bcm2835_alsa_str
201                 if (work) {
202                         INIT_WORK((struct work_struct *)work, my_wq_function);
203                         work->alsa_stream = alsa_stream;
204 -                       work->x = 1;
205 +                       work->cmd = BCM2835_AUDIO_START;
206                         if (queue_work
207                             (alsa_stream->my_wq, (struct work_struct *)work))
208                                 ret = 0;
209 @@ -128,7 +141,31 @@ int bcm2835_audio_stop(bcm2835_alsa_stre
210                 if (work) {
211                         INIT_WORK((struct work_struct *)work, my_wq_function);
212                         work->alsa_stream = alsa_stream;
213 -                       work->x = 2;
214 +                       work->cmd = BCM2835_AUDIO_STOP;
215 +                       if (queue_work
216 +                           (alsa_stream->my_wq, (struct work_struct *)work))
217 +                               ret = 0;
218 +               } else
219 +                       LOG_ERR(" .. Error: NULL work kmalloc\n");
220 +       }
221 +       LOG_DBG(" .. OUT %d\n", ret);
222 +       return ret;
223 +}
224 +
225 +int bcm2835_audio_write(bcm2835_alsa_stream_t *alsa_stream,
226 +                       uint32_t count, void *src)
227 +{
228 +       int ret = -1;
229 +       LOG_DBG(" .. IN\n");
230 +       if (alsa_stream->my_wq) {
231 +               my_work_t *work = kmalloc(sizeof(my_work_t), GFP_ATOMIC);
232 +                /*--- Queue some work (item 1) ---*/
233 +               if (work) {
234 +                       INIT_WORK((struct work_struct *)work, my_wq_function);
235 +                       work->alsa_stream = alsa_stream;
236 +                       work->cmd = BCM2835_AUDIO_WRITE;
237 +                       work->src = src;
238 +                       work->count = count;
239                         if (queue_work
240                             (alsa_stream->my_wq, (struct work_struct *)work))
241                                 ret = 0;
242 @@ -178,7 +215,7 @@ static void audio_vchi_callback(void *pa
243                     (" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_RESULT, success=%d\n",
244                      instance, m.u.result.success);
245                 instance->result = m.u.result.success;
246 -               up(&instance->msg_avail_event);
247 +               complete(&instance->msg_avail_comp);
248         } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) {
249                 irq_handler_t callback = (irq_handler_t) m.u.complete.callback;
250                 LOG_DBG
251 @@ -435,8 +472,8 @@ static int bcm2835_audio_set_ctls_chan(b
252         m.u.control.dest = chip->dest;
253         m.u.control.volume = chip->volume;
254  
255 -       /* Create the message available event */
256 -       sema_init(&instance->msg_avail_event, 0);
257 +       /* Create the message available completion */
258 +       init_completion(&instance->msg_avail_comp);
259  
260         /* Send the message to the videocore */
261         success = vchi_msg_queue(instance->vchi_handle[0],
262 @@ -452,11 +489,10 @@ static int bcm2835_audio_set_ctls_chan(b
263         }
264  
265         /* We are expecting a reply from the videocore */
266 -       if (down_interruptible(&instance->msg_avail_event)) {
267 +       ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
268 +       if (ret) {
269                 LOG_ERR("%s: failed on waiting for event (status=%d)\n",
270                         __func__, success);
271 -
272 -               ret = -1;
273                 goto unlock;
274         }
275  
276 @@ -539,8 +575,8 @@ int bcm2835_audio_set_params(bcm2835_als
277         m.u.config.samplerate = samplerate;
278         m.u.config.bps = bps;
279  
280 -       /* Create the message available event */
281 -       sema_init(&instance->msg_avail_event, 0);
282 +       /* Create the message available completion */
283 +       init_completion(&instance->msg_avail_comp);
284  
285         /* Send the message to the videocore */
286         success = vchi_msg_queue(instance->vchi_handle[0],
287 @@ -556,11 +592,10 @@ int bcm2835_audio_set_params(bcm2835_als
288         }
289  
290         /* We are expecting a reply from the videocore */
291 -       if (down_interruptible(&instance->msg_avail_event)) {
292 +       ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
293 +       if (ret) {
294                 LOG_ERR("%s: failed on waiting for event (status=%d)\n",
295                         __func__, success);
296 -
297 -               ret = -1;
298                 goto unlock;
299         }
300  
301 @@ -688,8 +723,8 @@ int bcm2835_audio_close(bcm2835_alsa_str
302  
303         m.type = VC_AUDIO_MSG_TYPE_CLOSE;
304  
305 -       /* Create the message available event */
306 -       sema_init(&instance->msg_avail_event, 0);
307 +       /* Create the message available completion */
308 +       init_completion(&instance->msg_avail_comp);
309  
310         /* Send the message to the videocore */
311         success = vchi_msg_queue(instance->vchi_handle[0],
312 @@ -702,11 +737,11 @@ int bcm2835_audio_close(bcm2835_alsa_str
313                 ret = -1;
314                 goto unlock;
315         }
316 -       if (down_interruptible(&instance->msg_avail_event)) {
317 +
318 +       ret = wait_for_completion_interruptible(&instance->msg_avail_comp);
319 +       if (ret) {
320                 LOG_ERR("%s: failed on waiting for event (status=%d)",
321                         __func__, success);
322 -
323 -               ret = -1;
324                 goto unlock;
325         }
326         if (instance->result != 0) {
327 @@ -732,8 +767,8 @@ unlock:
328         return ret;
329  }
330  
331 -int bcm2835_audio_write(bcm2835_alsa_stream_t * alsa_stream, uint32_t count,
332 -                       void *src)
333 +int bcm2835_audio_write_worker(bcm2835_alsa_stream_t *alsa_stream,
334 +                              uint32_t count, void *src)
335  {
336         VC_AUDIO_MSG_T m;
337         AUDIO_INSTANCE_T *instance = alsa_stream->instance;
338 --- a/sound/arm/bcm2835.c
339 +++ b/sound/arm/bcm2835.c
340 @@ -110,20 +110,20 @@ static int snd_bcm2835_alsa_probe(struct
341  
342         err = snd_bcm2835_create(g_card, pdev, &chip);
343         if (err < 0) {
344 -               printk(KERN_ERR "Failed to create bcm2835 chip\n");
345 +               dev_err(&pdev->dev, "Failed to create bcm2835 chip\n");
346                 goto out_bcm2835_create;
347         }
348  
349         g_chip = chip;
350         err = snd_bcm2835_new_pcm(chip);
351         if (err < 0) {
352 -               printk(KERN_ERR "Failed to create new BCM2835 pcm device\n");
353 +               dev_err(&pdev->dev, "Failed to create new BCM2835 pcm device\n");
354                 goto out_bcm2835_new_pcm;
355         }
356  
357         err = snd_bcm2835_new_ctl(chip);
358         if (err < 0) {
359 -               printk(KERN_ERR "Failed to create new BCM2835 ctl\n");
360 +               dev_err(&pdev->dev, "Failed to create new BCM2835 ctl\n");
361                 goto out_bcm2835_new_ctl;
362         }
363  
364 @@ -139,14 +139,14 @@ add_register_map:
365         if (dev == 0) {
366                 err = snd_card_register(card);
367                 if (err < 0) {
368 -                       printk(KERN_ERR
369 -                              "Failed to register bcm2835 ALSA card \n");
370 +                       dev_err(&pdev->dev,
371 +                               "Failed to register bcm2835 ALSA card \n");
372                         goto out_card_register;
373                 }
374                 platform_set_drvdata(pdev, card);
375 -               printk(KERN_INFO "bcm2835 ALSA card created!\n");
376 +               audio_info("bcm2835 ALSA card created!\n");
377         } else {
378 -               printk(KERN_INFO "bcm2835 ALSA chip created!\n");
379 +               audio_info("bcm2835 ALSA chip created!\n");
380                 platform_set_drvdata(pdev, (void *)dev);
381         }
382  
383 @@ -160,11 +160,11 @@ out_bcm2835_new_pcm:
384  out_bcm2835_create:
385         BUG_ON(!g_card);
386         if (snd_card_free(g_card))
387 -               printk(KERN_ERR "Failed to free Registered alsa card\n");
388 +               dev_err(&pdev->dev, "Failed to free Registered alsa card\n");
389         g_card = NULL;
390  out:
391         dev = SNDRV_CARDS;      /* stop more avail_substreams from being probed */
392 -       printk(KERN_ERR "BCM2835 ALSA Probe failed !!\n");
393 +       dev_err(&pdev->dev, "BCM2835 ALSA Probe failed !!\n");
394         return err;
395  }
396  
397 @@ -326,49 +326,49 @@ static int bcm2835_alsa_device_init(void
398         int err;
399         err = platform_driver_register(&bcm2835_alsa0_driver);
400         if (err) {
401 -               printk("Error registering bcm2835_alsa0_driver %d .\n", err);
402 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
403                 goto out;
404         }
405  
406         err = platform_driver_register(&bcm2835_alsa1_driver);
407         if (err) {
408 -               printk("Error registering bcm2835_alsa1_driver %d .\n", err);
409 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
410                 goto unregister_0;
411         }
412  
413         err = platform_driver_register(&bcm2835_alsa2_driver);
414         if (err) {
415 -               printk("Error registering bcm2835_alsa2_driver %d .\n", err);
416 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
417                 goto unregister_1;
418         }
419  
420         err = platform_driver_register(&bcm2835_alsa3_driver);
421         if (err) {
422 -               printk("Error registering bcm2835_alsa3_driver %d .\n", err);
423 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
424                 goto unregister_2;
425         }
426  
427         err = platform_driver_register(&bcm2835_alsa4_driver);
428         if (err) {
429 -               printk("Error registering bcm2835_alsa4_driver %d .\n", err);
430 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
431                 goto unregister_3;
432         }
433  
434         err = platform_driver_register(&bcm2835_alsa5_driver);
435         if (err) {
436 -               printk("Error registering bcm2835_alsa5_driver %d .\n", err);
437 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
438                 goto unregister_4;
439         }
440  
441         err = platform_driver_register(&bcm2835_alsa6_driver);
442         if (err) {
443 -               printk("Error registering bcm2835_alsa6_driver %d .\n", err);
444 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
445                 goto unregister_5;
446         }
447  
448         err = platform_driver_register(&bcm2835_alsa7_driver);
449         if (err) {
450 -               printk("Error registering bcm2835_alsa7_driver %d .\n", err);
451 +               pr_err("Error registering bcm2835_alsa0_driver %d .\n", err);
452                 goto unregister_6;
453         }
454  
455 --- a/sound/arm/bcm2835.h
456 +++ b/sound/arm/bcm2835.h
457 @@ -23,6 +23,7 @@
458  #include <sound/initval.h>
459  #include <sound/pcm.h>
460  #include <sound/pcm_params.h>
461 +#include <sound/pcm-indirect.h>
462  #include <linux/workqueue.h>
463  
464  /*
465 @@ -110,6 +111,7 @@ typedef struct bcm2835_chip {
466  typedef struct bcm2835_alsa_stream {
467         bcm2835_chip_t *chip;
468         struct snd_pcm_substream *substream;
469 +       struct snd_pcm_indirect pcm_indirect;
470  
471         struct semaphore buffers_update_sem;
472         struct semaphore control_sem;