~ubuntu-branches/ubuntu/maverick/linux-backports-modules-2.6.32/maverick

« back to all changes in this revision

Viewing changes to updates/alsa-driver/alsa-kernel/sh/sh_dac_audio.c

  • Committer: Bazaar Package Importer
  • Author(s): Andy Whitcroft, Andy Whitcroft
  • Date: 2010-02-04 23:15:51 UTC
  • Revision ID: james.westby@ubuntu.com-20100204231551-vjz5pkvxclukjxm1
Tags: 2.6.32-12.1
[ Andy Whitcroft ]

* initial LBM for lucid
* drop generated files
* printchanges -- rebase tree does not have stable tags use changelog
* printenv -- add revisions to printenv output
* formally rename compat-wireless to linux-backports-modules-wireless
* Update to compat-wireless-2.6.33-rc5
* update nouveau to mainline 2.6.33-rc4
* add new LBM package for nouveau
* nouveau -- fix major numbers and proc entry names
* fix up firmware installs for -wireless
* clean up UPDATE-NOVEAU
* update Nouveau to v2.6.33-rc6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * sh_dac_audio.c - SuperH DAC audio driver for ALSA
 
3
 *
 
4
 * Copyright (c) 2009 by Rafael Ignacio Zurita <rizurita@yahoo.com>
 
5
 *
 
6
 *
 
7
 * Based on sh_dac_audio.c (Copyright (C) 2004, 2005 by Andriy Skulysh)
 
8
 *
 
9
 *   This program is free software; you can redistribute it and/or modify
 
10
 *   it under the terms of the GNU General Public License as published by
 
11
 *   the Free Software Foundation; either version 2 of the License, or
 
12
 *   (at your option) any later version.
 
13
 *
 
14
 *   This program is distributed in the hope that it will be useful,
 
15
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 *   GNU General Public License for more details.
 
18
 *
 
19
 *   You should have received a copy of the GNU General Public License
 
20
 *   along with this program; if not, write to the Free Software
 
21
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 
22
 *
 
23
 */
 
24
 
 
25
#include <linux/hrtimer.h>
 
26
#include <linux/interrupt.h>
 
27
#include <linux/io.h>
 
28
#include <linux/platform_device.h>
 
29
#include <sound/core.h>
 
30
#include <sound/initval.h>
 
31
#include <sound/pcm.h>
 
32
#include <sound/sh_dac_audio.h>
 
33
#include <asm/clock.h>
 
34
#include <asm/hd64461.h>
 
35
#include <mach/hp6xx.h>
 
36
#include <cpu/dac.h>
 
37
 
 
38
MODULE_AUTHOR("Rafael Ignacio Zurita <rizurita@yahoo.com>");
 
39
MODULE_DESCRIPTION("SuperH DAC audio driver");
 
40
MODULE_LICENSE("GPL");
 
41
MODULE_SUPPORTED_DEVICE("{{SuperH DAC audio support}}");
 
42
 
 
43
/* Module Parameters */
 
44
static int index = SNDRV_DEFAULT_IDX1;
 
45
static char *id = SNDRV_DEFAULT_STR1;
 
46
module_param(index, int, 0444);
 
47
MODULE_PARM_DESC(index, "Index value for SuperH DAC audio.");
 
48
module_param(id, charp, 0444);
 
49
MODULE_PARM_DESC(id, "ID string for SuperH DAC audio.");
 
50
 
 
51
/* main struct */
 
52
struct snd_sh_dac {
 
53
        struct snd_card *card;
 
54
        struct snd_pcm_substream *substream;
 
55
        struct hrtimer hrtimer;
 
56
        ktime_t wakeups_per_second;
 
57
 
 
58
        int rate;
 
59
        int empty;
 
60
        char *data_buffer, *buffer_begin, *buffer_end;
 
61
        int processed; /* bytes proccesed, to compare with period_size */
 
62
        int buffer_size;
 
63
        struct dac_audio_pdata *pdata;
 
64
};
 
65
 
 
66
 
 
67
static void dac_audio_start_timer(struct snd_sh_dac *chip)
 
68
{
 
69
        hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
 
70
                      HRTIMER_MODE_REL);
 
71
}
 
72
 
 
73
static void dac_audio_stop_timer(struct snd_sh_dac *chip)
 
74
{
 
75
        hrtimer_cancel(&chip->hrtimer);
 
76
}
 
77
 
 
78
static void dac_audio_reset(struct snd_sh_dac *chip)
 
79
{
 
80
        dac_audio_stop_timer(chip);
 
81
        chip->buffer_begin = chip->buffer_end = chip->data_buffer;
 
82
        chip->processed = 0;
 
83
        chip->empty = 1;
 
84
}
 
85
 
 
86
static void dac_audio_set_rate(struct snd_sh_dac *chip)
 
87
{
 
88
        chip->wakeups_per_second = ktime_set(0, 1000000000 / chip->rate);
 
89
}
 
90
 
 
91
 
 
92
/* PCM INTERFACE */
 
93
 
 
94
static struct snd_pcm_hardware snd_sh_dac_pcm_hw = {
 
95
        .info                   = (SNDRV_PCM_INFO_MMAP |
 
96
                                        SNDRV_PCM_INFO_MMAP_VALID |
 
97
                                        SNDRV_PCM_INFO_INTERLEAVED |
 
98
                                        SNDRV_PCM_INFO_HALF_DUPLEX),
 
99
        .formats                = SNDRV_PCM_FMTBIT_U8,
 
100
        .rates                  = SNDRV_PCM_RATE_8000,
 
101
        .rate_min               = 8000,
 
102
        .rate_max               = 8000,
 
103
        .channels_min           = 1,
 
104
        .channels_max           = 1,
 
105
        .buffer_bytes_max       = (48*1024),
 
106
        .period_bytes_min       = 1,
 
107
        .period_bytes_max       = (48*1024),
 
108
        .periods_min            = 1,
 
109
        .periods_max            = 1024,
 
110
};
 
111
 
 
112
static int snd_sh_dac_pcm_open(struct snd_pcm_substream *substream)
 
113
{
 
114
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
115
        struct snd_pcm_runtime *runtime = substream->runtime;
 
116
 
 
117
        runtime->hw = snd_sh_dac_pcm_hw;
 
118
 
 
119
        chip->substream = substream;
 
120
        chip->buffer_begin = chip->buffer_end = chip->data_buffer;
 
121
        chip->processed = 0;
 
122
        chip->empty = 1;
 
123
 
 
124
        chip->pdata->start(chip->pdata);
 
125
 
 
126
        return 0;
 
127
}
 
128
 
 
129
static int snd_sh_dac_pcm_close(struct snd_pcm_substream *substream)
 
130
{
 
131
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
132
 
 
133
        chip->substream = NULL;
 
134
 
 
135
        dac_audio_stop_timer(chip);
 
136
        chip->pdata->stop(chip->pdata);
 
137
 
 
138
        return 0;
 
139
}
 
140
 
 
141
static int snd_sh_dac_pcm_hw_params(struct snd_pcm_substream *substream,
 
142
                                struct snd_pcm_hw_params *hw_params)
 
143
{
 
144
        return snd_pcm_lib_malloc_pages(substream,
 
145
                        params_buffer_bytes(hw_params));
 
146
}
 
147
 
 
148
static int snd_sh_dac_pcm_hw_free(struct snd_pcm_substream *substream)
 
149
{
 
150
        return snd_pcm_lib_free_pages(substream);
 
151
}
 
152
 
 
153
static int snd_sh_dac_pcm_prepare(struct snd_pcm_substream *substream)
 
154
{
 
155
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
156
        struct snd_pcm_runtime *runtime = chip->substream->runtime;
 
157
 
 
158
        chip->buffer_size = runtime->buffer_size;
 
159
        memset(chip->data_buffer, 0, chip->pdata->buffer_size);
 
160
 
 
161
        return 0;
 
162
}
 
163
 
 
164
static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 
165
{
 
166
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
167
 
 
168
        switch (cmd) {
 
169
        case SNDRV_PCM_TRIGGER_START:
 
170
                dac_audio_start_timer(chip);
 
171
                break;
 
172
        case SNDRV_PCM_TRIGGER_STOP:
 
173
                chip->buffer_begin = chip->buffer_end = chip->data_buffer;
 
174
                chip->processed = 0;
 
175
                chip->empty = 1;
 
176
                dac_audio_stop_timer(chip);
 
177
                break;
 
178
        default:
 
179
                 return -EINVAL;
 
180
        }
 
181
 
 
182
        return 0;
 
183
}
 
184
 
 
185
static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, int channel,
 
186
        snd_pcm_uframes_t pos, void __user *src, snd_pcm_uframes_t count)
 
187
{
 
188
        /* channel is not used (interleaved data) */
 
189
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
190
        struct snd_pcm_runtime *runtime = substream->runtime;
 
191
        ssize_t b_count = frames_to_bytes(runtime , count);
 
192
        ssize_t b_pos = frames_to_bytes(runtime , pos);
 
193
 
 
194
        if (count < 0)
 
195
                return -EINVAL;
 
196
 
 
197
        if (!count)
 
198
                return 0;
 
199
 
 
200
        memcpy_toio(chip->data_buffer + b_pos, src, b_count);
 
201
        chip->buffer_end = chip->data_buffer + b_pos + b_count;
 
202
 
 
203
        if (chip->empty) {
 
204
                chip->empty = 0;
 
205
                dac_audio_start_timer(chip);
 
206
        }
 
207
 
 
208
        return 0;
 
209
}
 
210
 
 
211
static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream,
 
212
                                  int channel, snd_pcm_uframes_t pos,
 
213
                                  snd_pcm_uframes_t count)
 
214
{
 
215
        /* channel is not used (interleaved data) */
 
216
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
217
        struct snd_pcm_runtime *runtime = substream->runtime;
 
218
        ssize_t b_count = frames_to_bytes(runtime , count);
 
219
        ssize_t b_pos = frames_to_bytes(runtime , pos);
 
220
 
 
221
        if (count < 0)
 
222
                return -EINVAL;
 
223
 
 
224
        if (!count)
 
225
                return 0;
 
226
 
 
227
        memset_io(chip->data_buffer + b_pos, 0, b_count);
 
228
        chip->buffer_end = chip->data_buffer + b_pos + b_count;
 
229
 
 
230
        if (chip->empty) {
 
231
                chip->empty = 0;
 
232
                dac_audio_start_timer(chip);
 
233
        }
 
234
 
 
235
        return 0;
 
236
}
 
237
 
 
238
static
 
239
snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream)
 
240
{
 
241
        struct snd_sh_dac *chip = snd_pcm_substream_chip(substream);
 
242
        int pointer = chip->buffer_begin - chip->data_buffer;
 
243
 
 
244
        return pointer;
 
245
}
 
246
 
 
247
/* pcm ops */
 
248
static struct snd_pcm_ops snd_sh_dac_pcm_ops = {
 
249
        .open           = snd_sh_dac_pcm_open,
 
250
        .close          = snd_sh_dac_pcm_close,
 
251
        .ioctl          = snd_pcm_lib_ioctl,
 
252
        .hw_params      = snd_sh_dac_pcm_hw_params,
 
253
        .hw_free        = snd_sh_dac_pcm_hw_free,
 
254
        .prepare        = snd_sh_dac_pcm_prepare,
 
255
        .trigger        = snd_sh_dac_pcm_trigger,
 
256
        .pointer        = snd_sh_dac_pcm_pointer,
 
257
        .copy           = snd_sh_dac_pcm_copy,
 
258
        .silence        = snd_sh_dac_pcm_silence,
 
259
        .mmap           = snd_pcm_lib_mmap_iomem,
 
260
};
 
261
 
 
262
static int __devinit snd_sh_dac_pcm(struct snd_sh_dac *chip, int device)
 
263
{
 
264
        int err;
 
265
        struct snd_pcm *pcm;
 
266
 
 
267
        /* device should be always 0 for us */
 
268
        err = snd_pcm_new(chip->card, "SH_DAC PCM", device, 1, 0, &pcm);
 
269
        if (err < 0)
 
270
                return err;
 
271
 
 
272
        pcm->private_data = chip;
 
273
        strcpy(pcm->name, "SH_DAC PCM");
 
274
        snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sh_dac_pcm_ops);
 
275
 
 
276
        /* buffer size=48K */
 
277
        snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS,
 
278
                                          snd_dma_continuous_data(GFP_KERNEL),
 
279
                                                        48 * 1024,
 
280
                                                        48 * 1024);
 
281
 
 
282
        return 0;
 
283
}
 
284
/* END OF PCM INTERFACE */
 
285
 
 
286
 
 
287
/* driver .remove  --  destructor */
 
288
static int snd_sh_dac_remove(struct platform_device *devptr)
 
289
{
 
290
        snd_card_free(platform_get_drvdata(devptr));
 
291
        platform_set_drvdata(devptr, NULL);
 
292
 
 
293
        return 0;
 
294
}
 
295
 
 
296
/* free -- it has been defined by create */
 
297
static int snd_sh_dac_free(struct snd_sh_dac *chip)
 
298
{
 
299
        /* release the data */
 
300
        kfree(chip->data_buffer);
 
301
        kfree(chip);
 
302
 
 
303
        return 0;
 
304
}
 
305
 
 
306
static int snd_sh_dac_dev_free(struct snd_device *device)
 
307
{
 
308
        struct snd_sh_dac *chip = device->device_data;
 
309
 
 
310
        return snd_sh_dac_free(chip);
 
311
}
 
312
 
 
313
static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle)
 
314
{
 
315
        struct snd_sh_dac *chip = container_of(handle, struct snd_sh_dac,
 
316
                                               hrtimer);
 
317
        struct snd_pcm_runtime *runtime = chip->substream->runtime;
 
318
        ssize_t b_ps = frames_to_bytes(runtime, runtime->period_size);
 
319
 
 
320
        if (!chip->empty) {
 
321
                sh_dac_output(*chip->buffer_begin, chip->pdata->channel);
 
322
                chip->buffer_begin++;
 
323
 
 
324
                chip->processed++;
 
325
                if (chip->processed >= b_ps) {
 
326
                        chip->processed -= b_ps;
 
327
                        snd_pcm_period_elapsed(chip->substream);
 
328
                }
 
329
 
 
330
                if (chip->buffer_begin == (chip->data_buffer +
 
331
                                           chip->buffer_size - 1))
 
332
                        chip->buffer_begin = chip->data_buffer;
 
333
 
 
334
                if (chip->buffer_begin == chip->buffer_end)
 
335
                        chip->empty = 1;
 
336
 
 
337
        }
 
338
 
 
339
        if (!chip->empty)
 
340
                hrtimer_start(&chip->hrtimer, chip->wakeups_per_second,
 
341
                              HRTIMER_MODE_REL);
 
342
 
 
343
        return HRTIMER_NORESTART;
 
344
}
 
345
 
 
346
/* create  --  chip-specific constructor for the cards components */
 
347
static int __devinit snd_sh_dac_create(struct snd_card *card,
 
348
                                       struct platform_device *devptr,
 
349
                                       struct snd_sh_dac **rchip)
 
350
{
 
351
        struct snd_sh_dac *chip;
 
352
        int err;
 
353
 
 
354
        static struct snd_device_ops ops = {
 
355
                   .dev_free = snd_sh_dac_dev_free,
 
356
        };
 
357
 
 
358
        *rchip = NULL;
 
359
 
 
360
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
 
361
        if (chip == NULL)
 
362
                return -ENOMEM;
 
363
 
 
364
        chip->card = card;
 
365
 
 
366
        hrtimer_init(&chip->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
 
367
        chip->hrtimer.function = sh_dac_audio_timer;
 
368
 
 
369
        dac_audio_reset(chip);
 
370
        chip->rate = 8000;
 
371
        dac_audio_set_rate(chip);
 
372
 
 
373
        chip->pdata = devptr->dev.platform_data;
 
374
 
 
375
        chip->data_buffer = kmalloc(chip->pdata->buffer_size, GFP_KERNEL);
 
376
        if (chip->data_buffer == NULL) {
 
377
                kfree(chip);
 
378
                return -ENOMEM;
 
379
        }
 
380
 
 
381
        err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
 
382
        if (err < 0) {
 
383
                snd_sh_dac_free(chip);
 
384
                return err;
 
385
        }
 
386
 
 
387
        *rchip = chip;
 
388
 
 
389
        return 0;
 
390
}
 
391
 
 
392
/* driver .probe  --  constructor */
 
393
static int __devinit snd_sh_dac_probe(struct platform_device *devptr)
 
394
{
 
395
        struct snd_sh_dac *chip;
 
396
        struct snd_card *card;
 
397
        int err;
 
398
 
 
399
        err = snd_card_create(index, id, THIS_MODULE, 0, &card);
 
400
        if (err < 0) {
 
401
                        snd_printk(KERN_ERR "cannot allocate the card\n");
 
402
                        return err;
 
403
        }
 
404
 
 
405
        err = snd_sh_dac_create(card, devptr, &chip);
 
406
        if (err < 0)
 
407
                goto probe_error;
 
408
 
 
409
        err = snd_sh_dac_pcm(chip, 0);
 
410
        if (err < 0)
 
411
                goto probe_error;
 
412
 
 
413
        strcpy(card->driver, "snd_sh_dac");
 
414
        strcpy(card->shortname, "SuperH DAC audio driver");
 
415
        printk(KERN_INFO "%s %s", card->longname, card->shortname);
 
416
 
 
417
        err = snd_card_register(card);
 
418
        if (err < 0)
 
419
                goto probe_error;
 
420
 
 
421
        snd_printk("ALSA driver for SuperH DAC audio");
 
422
 
 
423
        platform_set_drvdata(devptr, card);
 
424
        return 0;
 
425
 
 
426
probe_error:
 
427
        snd_card_free(card);
 
428
        return err;
 
429
}
 
430
 
 
431
/*
 
432
 * "driver" definition
 
433
 */
 
434
static struct platform_driver driver = {
 
435
        .probe  = snd_sh_dac_probe,
 
436
        .remove = snd_sh_dac_remove,
 
437
        .driver = {
 
438
                .name = "dac_audio",
 
439
        },
 
440
};
 
441
 
 
442
static int __init sh_dac_init(void)
 
443
{
 
444
        return platform_driver_register(&driver);
 
445
}
 
446
 
 
447
static void __exit sh_dac_exit(void)
 
448
{
 
449
        platform_driver_unregister(&driver);
 
450
}
 
451
 
 
452
module_init(sh_dac_init);
 
453
module_exit(sh_dac_exit);