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