1/* 2 * linux/drivers/sound/vidc.c 3 * 4 * Copyright (C) 1997-2000 by Russell King <rmk@arm.linux.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * VIDC20 audio driver. 11 * 12 * The VIDC20 sound hardware consists of the VIDC20 itself, a DAC and a DMA 13 * engine. The DMA transfers fixed-format (16-bit little-endian linear) 14 * samples to the VIDC20, which then transfers this data serially to the 15 * DACs. The samplerate is controlled by the VIDC. 16 * 17 * We currently support a mixer device, but it is currently non-functional. 18 */ 19 20#include <linux/gfp.h> 21#include <linux/init.h> 22#include <linux/module.h> 23#include <linux/kernel.h> 24#include <linux/interrupt.h> 25 26#include <mach/hardware.h> 27#include <asm/dma.h> 28#include <asm/io.h> 29#include <asm/hardware/iomd.h> 30#include <asm/irq.h> 31#include <asm/system.h> 32 33#include "sound_config.h" 34#include "vidc.h" 35 36#ifndef _SIOC_TYPE 37#define _SIOC_TYPE(x) _IOC_TYPE(x) 38#endif 39#ifndef _SIOC_NR 40#define _SIOC_NR(x) _IOC_NR(x) 41#endif 42 43#define VIDC_SOUND_CLOCK (250000) 44#define VIDC_SOUND_CLOCK_EXT (176400) 45 46/* 47 * When using SERIAL SOUND mode (external DAC), the number of physical 48 * channels is fixed at 2. 49 */ 50static int vidc_busy; 51static int vidc_adev; 52static int vidc_audio_rate; 53static char vidc_audio_format; 54static char vidc_audio_channels; 55 56static unsigned char vidc_level_l[SOUND_MIXER_NRDEVICES] = { 57 85, /* master */ 58 50, /* bass */ 59 50, /* treble */ 60 0, /* synth */ 61 75, /* pcm */ 62 0, /* speaker */ 63 100, /* ext line */ 64 0, /* mic */ 65 100, /* CD */ 66 0, 67}; 68 69static unsigned char vidc_level_r[SOUND_MIXER_NRDEVICES] = { 70 85, /* master */ 71 50, /* bass */ 72 50, /* treble */ 73 0, /* synth */ 74 75, /* pcm */ 75 0, /* speaker */ 76 100, /* ext line */ 77 0, /* mic */ 78 100, /* CD */ 79 0, 80}; 81 82static unsigned int vidc_audio_volume_l; /* left PCM vol, 0 - 65536 */ 83static unsigned int vidc_audio_volume_r; /* right PCM vol, 0 - 65536 */ 84 85extern void vidc_update_filler(int bits, int channels); 86extern int softoss_dev; 87 88static void 89vidc_mixer_set(int mdev, unsigned int level) 90{ 91 unsigned int lev_l = level & 0x007f; 92 unsigned int lev_r = (level & 0x7f00) >> 8; 93 unsigned int mlev_l, mlev_r; 94 95 if (lev_l > 100) 96 lev_l = 100; 97 if (lev_r > 100) 98 lev_r = 100; 99 100#define SCALE(lev,master) ((lev) * (master) * 65536 / 10000) 101 102 mlev_l = vidc_level_l[SOUND_MIXER_VOLUME]; 103 mlev_r = vidc_level_r[SOUND_MIXER_VOLUME]; 104 105 switch (mdev) { 106 case SOUND_MIXER_VOLUME: 107 case SOUND_MIXER_PCM: 108 vidc_level_l[mdev] = lev_l; 109 vidc_level_r[mdev] = lev_r; 110 111 vidc_audio_volume_l = SCALE(lev_l, mlev_l); 112 vidc_audio_volume_r = SCALE(lev_r, mlev_r); 113/*printk("VIDC: PCM vol %05X %05X\n", vidc_audio_volume_l, vidc_audio_volume_r);*/ 114 break; 115 } 116#undef SCALE 117} 118 119static int vidc_mixer_ioctl(int dev, unsigned int cmd, void __user *arg) 120{ 121 unsigned int val; 122 unsigned int mdev; 123 124 if (_SIOC_TYPE(cmd) != 'M') 125 return -EINVAL; 126 127 mdev = _SIOC_NR(cmd); 128 129 if (_SIOC_DIR(cmd) & _SIOC_WRITE) { 130 if (get_user(val, (unsigned int __user *)arg)) 131 return -EFAULT; 132 133 if (mdev < SOUND_MIXER_NRDEVICES) 134 vidc_mixer_set(mdev, val); 135 else 136 return -EINVAL; 137 } 138 139 /* 140 * Return parameters 141 */ 142 switch (mdev) { 143 case SOUND_MIXER_RECSRC: 144 val = 0; 145 break; 146 147 case SOUND_MIXER_DEVMASK: 148 val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH; 149 break; 150 151 case SOUND_MIXER_STEREODEVS: 152 val = SOUND_MASK_VOLUME | SOUND_MASK_PCM | SOUND_MASK_SYNTH; 153 break; 154 155 case SOUND_MIXER_RECMASK: 156 val = 0; 157 break; 158 159 case SOUND_MIXER_CAPS: 160 val = 0; 161 break; 162 163 default: 164 if (mdev < SOUND_MIXER_NRDEVICES) 165 val = vidc_level_l[mdev] | vidc_level_r[mdev] << 8; 166 else 167 return -EINVAL; 168 } 169 170 return put_user(val, (unsigned int __user *)arg) ? -EFAULT : 0; 171} 172 173static unsigned int vidc_audio_set_format(int dev, unsigned int fmt) 174{ 175 switch (fmt) { 176 default: 177 fmt = AFMT_S16_LE; 178 case AFMT_U8: 179 case AFMT_S8: 180 case AFMT_S16_LE: 181 vidc_audio_format = fmt; 182 vidc_update_filler(vidc_audio_format, vidc_audio_channels); 183 case AFMT_QUERY: 184 break; 185 } 186 return vidc_audio_format; 187} 188 189#define my_abs(i) ((i)<0 ? -(i) : (i)) 190 191static int vidc_audio_set_speed(int dev, int rate) 192{ 193 if (rate) { 194 unsigned int hwctrl, hwrate, hwrate_ext, rate_int, rate_ext; 195 unsigned int diff_int, diff_ext; 196 unsigned int newsize, new2size; 197 198 hwctrl = 0x00000003; 199 200 /* Using internal clock */ 201 hwrate = (((VIDC_SOUND_CLOCK * 2) / rate) + 1) >> 1; 202 if (hwrate < 3) 203 hwrate = 3; 204 if (hwrate > 255) 205 hwrate = 255; 206 207 /* Using exernal clock */ 208 hwrate_ext = (((VIDC_SOUND_CLOCK_EXT * 2) / rate) + 1) >> 1; 209 if (hwrate_ext < 3) 210 hwrate_ext = 3; 211 if (hwrate_ext > 255) 212 hwrate_ext = 255; 213 214 rate_int = VIDC_SOUND_CLOCK / hwrate; 215 rate_ext = VIDC_SOUND_CLOCK_EXT / hwrate_ext; 216 217 /* Chose between external and internal clock */ 218 diff_int = my_abs(rate_ext-rate); 219 diff_ext = my_abs(rate_int-rate); 220 if (diff_ext < diff_int) { 221 /*printk("VIDC: external %d %d %d\n", rate, rate_ext, hwrate_ext);*/ 222 hwrate=hwrate_ext; 223 hwctrl=0x00000002; 224 /* Allow roughly 0.4% tolerance */ 225 if (diff_ext > (rate/256)) 226 rate=rate_ext; 227 } else { 228 /*printk("VIDC: internal %d %d %d\n", rate, rate_int, hwrate);*/ 229 hwctrl=0x00000003; 230 /* Allow rougly 0.4% tolerance */ 231 if (diff_int > (rate/256)) 232 rate=rate_int; 233 } 234 235 vidc_writel(0xb0000000 | (hwrate - 2)); 236 vidc_writel(0xb1000000 | hwctrl); 237 238 newsize = (10000 / hwrate) & ~3; 239 if (newsize < 208) 240 newsize = 208; 241 if (newsize > 4096) 242 newsize = 4096; 243 for (new2size = 128; new2size < newsize; new2size <<= 1); 244 if (new2size - newsize > newsize - (new2size >> 1)) 245 new2size >>= 1; 246 if (new2size > 4096) { 247 printk(KERN_ERR "VIDC: error: dma buffer (%d) %d > 4K\n", 248 newsize, new2size); 249 new2size = 4096; 250 } 251 /*printk("VIDC: dma size %d\n", new2size);*/ 252 dma_bufsize = new2size; 253 vidc_audio_rate = rate; 254 } 255 return vidc_audio_rate; 256} 257 258static short vidc_audio_set_channels(int dev, short channels) 259{ 260 switch (channels) { 261 default: 262 channels = 2; 263 case 1: 264 case 2: 265 vidc_audio_channels = channels; 266 vidc_update_filler(vidc_audio_format, vidc_audio_channels); 267 case 0: 268 break; 269 } 270 return vidc_audio_channels; 271} 272 273/* 274 * Open the device 275 */ 276static int vidc_audio_open(int dev, int mode) 277{ 278 /* This audio device does not have recording capability */ 279 if (mode == OPEN_READ) 280 return -EPERM; 281 282 if (vidc_busy) 283 return -EBUSY; 284 285 vidc_busy = 1; 286 return 0; 287} 288 289/* 290 * Close the device 291 */ 292static void vidc_audio_close(int dev) 293{ 294 vidc_busy = 0; 295} 296 297/* 298 * Output a block via DMA to sound device. 299 * 300 * We just set the DMA start and count; the DMA interrupt routine 301 * will take care of formatting the samples (via the appropriate 302 * vidc_filler routine), and flag via vidc_audio_dma_interrupt when 303 * more data is required. 304 */ 305static void 306vidc_audio_output_block(int dev, unsigned long buf, int total_count, int one) 307{ 308 struct dma_buffparms *dmap = audio_devs[dev]->dmap_out; 309 unsigned long flags; 310 311 local_irq_save(flags); 312 dma_start = buf - (unsigned long)dmap->raw_buf_phys + (unsigned long)dmap->raw_buf; 313 dma_count = total_count; 314 local_irq_restore(flags); 315} 316 317static void 318vidc_audio_start_input(int dev, unsigned long buf, int count, int intrflag) 319{ 320} 321 322static int vidc_audio_prepare_for_input(int dev, int bsize, int bcount) 323{ 324 return -EINVAL; 325} 326 327static irqreturn_t vidc_audio_dma_interrupt(void) 328{ 329 DMAbuf_outputintr(vidc_adev, 1); 330 return IRQ_HANDLED; 331} 332 333/* 334 * Prepare for outputting samples. 335 * 336 * Each buffer that will be passed will be `bsize' bytes long, 337 * with a total of `bcount' buffers. 338 */ 339static int vidc_audio_prepare_for_output(int dev, int bsize, int bcount) 340{ 341 struct audio_operations *adev = audio_devs[dev]; 342 343 dma_interrupt = NULL; 344 adev->dmap_out->flags |= DMA_NODMA; 345 346 return 0; 347} 348 349/* 350 * Stop our current operation. 351 */ 352static void vidc_audio_reset(int dev) 353{ 354 dma_interrupt = NULL; 355} 356 357static int vidc_audio_local_qlen(int dev) 358{ 359 return /*dma_count !=*/ 0; 360} 361 362static void vidc_audio_trigger(int dev, int enable_bits) 363{ 364 struct audio_operations *adev = audio_devs[dev]; 365 366 if (enable_bits & PCM_ENABLE_OUTPUT) { 367 if (!(adev->dmap_out->flags & DMA_ACTIVE)) { 368 unsigned long flags; 369 370 local_irq_save(flags); 371 372 /* prevent recusion */ 373 adev->dmap_out->flags |= DMA_ACTIVE; 374 375 dma_interrupt = vidc_audio_dma_interrupt; 376 vidc_sound_dma_irq(0, NULL); 377 iomd_writeb(DMA_CR_E | 0x10, IOMD_SD0CR); 378 379 local_irq_restore(flags); 380 } 381 } 382} 383 384static struct audio_driver vidc_audio_driver = 385{ 386 .owner = THIS_MODULE, 387 .open = vidc_audio_open, 388 .close = vidc_audio_close, 389 .output_block = vidc_audio_output_block, 390 .start_input = vidc_audio_start_input, 391 .prepare_for_input = vidc_audio_prepare_for_input, 392 .prepare_for_output = vidc_audio_prepare_for_output, 393 .halt_io = vidc_audio_reset, 394 .local_qlen = vidc_audio_local_qlen, 395 .trigger = vidc_audio_trigger, 396 .set_speed = vidc_audio_set_speed, 397 .set_bits = vidc_audio_set_format, 398 .set_channels = vidc_audio_set_channels 399}; 400 401static struct mixer_operations vidc_mixer_operations = { 402 .owner = THIS_MODULE, 403 .id = "VIDC", 404 .name = "VIDCsound", 405 .ioctl = vidc_mixer_ioctl 406}; 407 408void vidc_update_filler(int format, int channels) 409{ 410#define TYPE(fmt,ch) (((fmt)<<2) | ((ch)&3)) 411 412 switch (TYPE(format, channels)) { 413 default: 414 case TYPE(AFMT_U8, 1): 415 vidc_filler = vidc_fill_1x8_u; 416 break; 417 418 case TYPE(AFMT_U8, 2): 419 vidc_filler = vidc_fill_2x8_u; 420 break; 421 422 case TYPE(AFMT_S8, 1): 423 vidc_filler = vidc_fill_1x8_s; 424 break; 425 426 case TYPE(AFMT_S8, 2): 427 vidc_filler = vidc_fill_2x8_s; 428 break; 429 430 case TYPE(AFMT_S16_LE, 1): 431 vidc_filler = vidc_fill_1x16_s; 432 break; 433 434 case TYPE(AFMT_S16_LE, 2): 435 vidc_filler = vidc_fill_2x16_s; 436 break; 437 } 438} 439 440static void __init attach_vidc(struct address_info *hw_config) 441{ 442 char name[32]; 443 int i, adev; 444 445 sprintf(name, "VIDC %d-bit sound", hw_config->card_subtype); 446 conf_printf(name, hw_config); 447 memset(dma_buf, 0, sizeof(dma_buf)); 448 449 adev = sound_install_audiodrv(AUDIO_DRIVER_VERSION, name, 450 &vidc_audio_driver, sizeof(vidc_audio_driver), 451 DMA_AUTOMODE, AFMT_U8 | AFMT_S8 | AFMT_S16_LE, 452 NULL, hw_config->dma, hw_config->dma2); 453 454 if (adev < 0) 455 goto audio_failed; 456 457 /* 458 * 1024 bytes => 64 buffers 459 */ 460 audio_devs[adev]->min_fragment = 10; 461 audio_devs[adev]->mixer_dev = num_mixers; 462 463 audio_devs[adev]->mixer_dev = 464 sound_install_mixer(MIXER_DRIVER_VERSION, 465 name, &vidc_mixer_operations, 466 sizeof(vidc_mixer_operations), NULL); 467 468 if (audio_devs[adev]->mixer_dev < 0) 469 goto mixer_failed; 470 471 for (i = 0; i < 2; i++) { 472 dma_buf[i] = get_zeroed_page(GFP_KERNEL); 473 if (!dma_buf[i]) { 474 printk(KERN_ERR "%s: can't allocate required buffers\n", 475 name); 476 goto mem_failed; 477 } 478 dma_pbuf[i] = virt_to_phys((void *)dma_buf[i]); 479 } 480 481 if (sound_alloc_dma(hw_config->dma, hw_config->name)) { 482 printk(KERN_ERR "%s: DMA %d is in use\n", name, hw_config->dma); 483 goto dma_failed; 484 } 485 486 if (request_irq(hw_config->irq, vidc_sound_dma_irq, 0, 487 hw_config->name, &dma_start)) { 488 printk(KERN_ERR "%s: IRQ %d is in use\n", name, hw_config->irq); 489 goto irq_failed; 490 } 491 vidc_adev = adev; 492 vidc_mixer_set(SOUND_MIXER_VOLUME, (85 | 85 << 8)); 493 494 return; 495 496irq_failed: 497 sound_free_dma(hw_config->dma); 498dma_failed: 499mem_failed: 500 for (i = 0; i < 2; i++) 501 free_page(dma_buf[i]); 502 sound_unload_mixerdev(audio_devs[adev]->mixer_dev); 503mixer_failed: 504 sound_unload_audiodev(adev); 505audio_failed: 506 return; 507} 508 509static int __init probe_vidc(struct address_info *hw_config) 510{ 511 hw_config->irq = IRQ_DMAS0; 512 hw_config->dma = DMA_VIRTUAL_SOUND; 513 hw_config->dma2 = -1; 514 hw_config->card_subtype = 16; 515 hw_config->name = "VIDC20"; 516 return 1; 517} 518 519static void __exit unload_vidc(struct address_info *hw_config) 520{ 521 int i, adev = vidc_adev; 522 523 vidc_adev = -1; 524 525 free_irq(hw_config->irq, &dma_start); 526 sound_free_dma(hw_config->dma); 527 528 if (adev >= 0) { 529 sound_unload_mixerdev(audio_devs[adev]->mixer_dev); 530 sound_unload_audiodev(adev); 531 for (i = 0; i < 2; i++) 532 free_page(dma_buf[i]); 533 } 534} 535 536static struct address_info cfg; 537 538static int __init init_vidc(void) 539{ 540 if (probe_vidc(&cfg) == 0) 541 return -ENODEV; 542 543 attach_vidc(&cfg); 544 545 return 0; 546} 547 548static void __exit cleanup_vidc(void) 549{ 550 unload_vidc(&cfg); 551} 552 553module_init(init_vidc); 554module_exit(cleanup_vidc); 555 556MODULE_AUTHOR("Russell King"); 557MODULE_DESCRIPTION("VIDC20 audio driver"); 558MODULE_LICENSE("GPL"); 559