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