linux-old/drivers/sound/btaudio.c
<<
>>
Prefs
   1/*
   2    btaudio - bt878 audio dma driver for linux 2.4.x
   3
   4    (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
   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 as published by
   8    the Free Software Foundation; either version 2 of the License, or
   9    (at your option) any later version.
  10
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15
  16    You should have received a copy of the GNU General Public License
  17    along with this program; if not, write to the Free Software
  18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19
  20*/
  21
  22#include <linux/version.h>
  23#include <linux/module.h>
  24#include <linux/errno.h>
  25#include <linux/pci.h>
  26#include <linux/sched.h>
  27#include <linux/signal.h>
  28#include <linux/types.h>
  29#include <linux/wrapper.h>
  30#include <linux/interrupt.h>
  31#include <linux/init.h>
  32#include <linux/poll.h>
  33#include <linux/sound.h>
  34#include <linux/soundcard.h>
  35#include <linux/slab.h>
  36#include <linux/kdev_t.h>
  37#include <asm/uaccess.h>
  38#include <asm/io.h>
  39
  40
  41/* mmio access */
  42#define btwrite(dat,adr)    writel((dat), (bta->mmio+(adr)))
  43#define btread(adr)         readl(bta->mmio+(adr))
  44
  45#define btand(dat,adr)      btwrite((dat) & btread(adr), adr)
  46#define btor(dat,adr)       btwrite((dat) | btread(adr), adr)
  47#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
  48
  49/* registers (shifted because bta->mmio is long) */
  50#define REG_INT_STAT      (0x100 >> 2)
  51#define REG_INT_MASK      (0x104 >> 2)
  52#define REG_GPIO_DMA_CTL  (0x10c >> 2)
  53#define REG_PACKET_LEN    (0x110 >> 2)
  54#define REG_RISC_STRT_ADD (0x114 >> 2)
  55#define REG_RISC_COUNT    (0x120 >> 2)
  56
  57/* IRQ bits - REG_INT_(STAT|MASK) */
  58#define IRQ_SCERR         (1 << 19)
  59#define IRQ_OCERR         (1 << 18)
  60#define IRQ_PABORT        (1 << 17)
  61#define IRQ_RIPERR        (1 << 16)
  62#define IRQ_PPERR         (1 << 15)
  63#define IRQ_FDSR          (1 << 14)
  64#define IRQ_FTRGT         (1 << 13)
  65#define IRQ_FBUS          (1 << 12)
  66#define IRQ_RISCI         (1 << 11)
  67#define IRQ_OFLOW         (1 <<  3)
  68
  69#define IRQ_BTAUDIO       (IRQ_SCERR | IRQ_OCERR | IRQ_PABORT | IRQ_RIPERR |\
  70                           IRQ_PPERR | IRQ_FDSR  | IRQ_FTRGT  | IRQ_FBUS   |\
  71                           IRQ_RISCI)
  72
  73/* REG_GPIO_DMA_CTL bits */
  74#define DMA_CTL_A_PWRDN   (1 << 26)
  75#define DMA_CTL_DA_SBR    (1 << 14)
  76#define DMA_CTL_DA_ES2    (1 << 13)
  77#define DMA_CTL_ACAP_EN   (1 <<  4)
  78#define DMA_CTL_RISC_EN   (1 <<  1)
  79#define DMA_CTL_FIFO_EN   (1 <<  0)
  80
  81/* RISC instructions */
  82#define RISC_WRITE        (0x01 << 28)
  83#define RISC_JUMP         (0x07 << 28)
  84#define RISC_SYNC         (0x08 << 28)
  85
  86/* RISC bits */
  87#define RISC_WR_SOL       (1 << 27)
  88#define RISC_WR_EOL       (1 << 26)
  89#define RISC_IRQ          (1 << 24)
  90#define RISC_SYNC_RESYNC  (1 << 15)
  91#define RISC_SYNC_FM1     0x06
  92#define RISC_SYNC_VRO     0x0c
  93
  94#define HWBASE_AD (448000)
  95
  96/* -------------------------------------------------------------- */
  97
  98struct btaudio {
  99        /* linked list */
 100        struct btaudio *next;
 101
 102        /* device info */
 103        int            dsp_digital;
 104        int            dsp_analog;
 105        int            mixer_dev;
 106        struct pci_dev *pci;
 107        unsigned int   irq;
 108        unsigned long  mem;
 109        unsigned long  *mmio;
 110
 111        /* locking */
 112        int            users;
 113        struct semaphore lock;
 114
 115        /* risc instructions */
 116        unsigned int   risc_size;
 117        unsigned long  *risc_cpu;
 118        dma_addr_t     risc_dma;
 119
 120        /* audio data */
 121        unsigned int   buf_size;
 122        unsigned char  *buf_cpu;
 123        dma_addr_t     buf_dma;
 124
 125        /* buffer setup */
 126        int line_bytes;
 127        int line_count;
 128        int block_bytes;
 129        int block_count;
 130
 131        /* read fifo management */
 132        int recording;
 133        int dma_block;
 134        int read_offset;
 135        int read_count;
 136        wait_queue_head_t readq;
 137
 138        /* settings */
 139        int gain[3];
 140        int source;
 141        int bits;
 142        int decimation;
 143        int mixcount;
 144        int sampleshift;
 145        int channels;
 146        int analog;
 147        int rate;
 148};
 149
 150struct cardinfo {
 151        char *name;
 152        int rate;
 153};
 154
 155static struct btaudio *btaudios = NULL;
 156static unsigned int debug = 0;
 157static unsigned int irq_debug = 0;
 158
 159/* -------------------------------------------------------------- */
 160
 161#define BUF_DEFAULT 128*1024
 162#define BUF_MIN         8192
 163
 164static int alloc_buffer(struct btaudio *bta)
 165{
 166        if (NULL == bta->buf_cpu) {
 167                for (bta->buf_size = BUF_DEFAULT; bta->buf_size >= BUF_MIN;
 168                     bta->buf_size = bta->buf_size >> 1) {
 169                        bta->buf_cpu = pci_alloc_consistent
 170                                (bta->pci, bta->buf_size, &bta->buf_dma);
 171                        if (NULL != bta->buf_cpu)
 172                                break;
 173                }
 174                if (NULL == bta->buf_cpu)
 175                        return -ENOMEM;
 176                memset(bta->buf_cpu,0,bta->buf_size);
 177        }
 178        if (NULL == bta->risc_cpu) {
 179                bta->risc_size = PAGE_SIZE;
 180                bta->risc_cpu = pci_alloc_consistent
 181                        (bta->pci, bta->risc_size, &bta->risc_dma);
 182                if (NULL == bta->risc_cpu)
 183                        return -ENOMEM;
 184        }
 185        return 0;
 186}
 187
 188static void free_buffer(struct btaudio *bta)
 189{
 190        if (NULL != bta->buf_cpu) {
 191                pci_free_consistent(bta->pci, bta->buf_size,
 192                                    bta->buf_cpu, bta->buf_dma);
 193                bta->buf_cpu = NULL;
 194        }
 195        if (NULL != bta->risc_cpu) {
 196                pci_free_consistent(bta->pci, bta->risc_size,
 197                                    bta->risc_cpu, bta->risc_dma);
 198                bta->risc_cpu = NULL;
 199        }
 200}
 201
 202static int make_risc(struct btaudio *bta)
 203{
 204        int rp, bp, line, block;
 205        unsigned long risc;
 206
 207        bta->block_bytes = bta->buf_size >> 4;
 208        bta->block_count = 1 << 4;
 209        bta->line_bytes  = bta->block_bytes;
 210        bta->line_count  = bta->block_count;
 211        while (bta->line_bytes > 4095) {
 212                bta->line_bytes >>= 1;
 213                bta->line_count <<= 1;
 214        }
 215        if (bta->line_count > 255)
 216                return -EINVAL;
 217        if (debug)
 218                printk(KERN_DEBUG
 219                       "btaudio: bufsize=%d - bs=%d bc=%d - ls=%d, lc=%d\n",
 220                       bta->buf_size,bta->block_bytes,bta->block_count,
 221                       bta->line_bytes,bta->line_count);
 222        rp = 0; bp = 0;
 223        block = 0;
 224        bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_FM1);
 225        bta->risc_cpu[rp++] = cpu_to_le32(0);
 226        for (line = 0; line < bta->line_count; line++) {
 227                risc  = RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL;
 228                risc |= bta->line_bytes;
 229                if (0 == (bp & (bta->block_bytes-1))) {
 230                        risc |= RISC_IRQ;
 231                        risc |= (block  & 0x0f) << 16;
 232                        risc |= (~block & 0x0f) << 20;
 233                        block++;
 234                }
 235                bta->risc_cpu[rp++] = cpu_to_le32(risc);
 236                bta->risc_cpu[rp++] = cpu_to_le32(bta->buf_dma + bp);
 237                bp += bta->line_bytes;
 238        }
 239        bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_VRO);
 240        bta->risc_cpu[rp++] = cpu_to_le32(0);
 241        bta->risc_cpu[rp++] = cpu_to_le32(RISC_JUMP); 
 242        bta->risc_cpu[rp++] = cpu_to_le32(bta->risc_dma);
 243        return 0;
 244}
 245
 246static int start_recording(struct btaudio *bta)
 247{
 248        int ret;
 249
 250        if (0 != (ret = alloc_buffer(bta)))
 251                return ret;
 252        if (0 != (ret = make_risc(bta)))
 253                return ret;
 254
 255        btwrite(bta->risc_dma, REG_RISC_STRT_ADD);
 256        btwrite((bta->line_count << 16) | bta->line_bytes,
 257                REG_PACKET_LEN);
 258        btwrite(IRQ_BTAUDIO, REG_INT_MASK);
 259        if (bta->analog) {
 260                btwrite(DMA_CTL_ACAP_EN |
 261                        DMA_CTL_RISC_EN |
 262                        DMA_CTL_FIFO_EN |
 263                        DMA_CTL_DA_ES2  |
 264                        ((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) |
 265                        (bta->gain[bta->source] << 28) |
 266                        (bta->source            << 24) |
 267                        (bta->decimation        <<  8),
 268                        REG_GPIO_DMA_CTL);
 269        } else {
 270                btwrite(DMA_CTL_ACAP_EN |
 271                        DMA_CTL_RISC_EN |
 272                        DMA_CTL_FIFO_EN |
 273                        DMA_CTL_DA_ES2  |
 274                        DMA_CTL_A_PWRDN |
 275                        (1 << 6)   |
 276                        ((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) |
 277                        (bta->gain[bta->source] << 28) |
 278                        (bta->source            << 24) |
 279                        (bta->decimation        <<  8),
 280                        REG_GPIO_DMA_CTL);
 281        }
 282        bta->dma_block = 0;
 283        bta->read_offset = 0;
 284        bta->read_count = 0;
 285        bta->recording = 1;
 286        if (debug)
 287                printk(KERN_DEBUG "btaudio: recording started\n");
 288        return 0;
 289}
 290
 291static void stop_recording(struct btaudio *bta)
 292{
 293        btand(~15, REG_GPIO_DMA_CTL);
 294        bta->recording = 0;
 295        if (debug)
 296                printk(KERN_DEBUG "btaudio: recording stopped\n");
 297}
 298
 299
 300/* -------------------------------------------------------------- */
 301
 302static int btaudio_mixer_open(struct inode *inode, struct file *file)
 303{
 304        int minor = minor(inode->i_rdev);
 305        struct btaudio *bta;
 306
 307        for (bta = btaudios; bta != NULL; bta = bta->next)
 308                if (bta->mixer_dev == minor)
 309                        break;
 310        if (NULL == bta)
 311                return -ENODEV;
 312
 313        if (debug)
 314                printk("btaudio: open mixer [%d]\n",minor);
 315        file->private_data = bta;
 316        return 0;
 317}
 318
 319static int btaudio_mixer_release(struct inode *inode, struct file *file)
 320{
 321        return 0;
 322}
 323
 324static int btaudio_mixer_ioctl(struct inode *inode, struct file *file,
 325                               unsigned int cmd, unsigned long arg)
 326{
 327        struct btaudio *bta = file->private_data;
 328        int ret,val=0,i=0;
 329
 330        if (cmd == SOUND_MIXER_INFO) {
 331                mixer_info info;
 332                memset(&info,0,sizeof(info));
 333                strncpy(info.id,"bt878",sizeof(info.id)-1);
 334                strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)-1);
 335                info.modify_counter = bta->mixcount;
 336                if (copy_to_user((void *)arg, &info, sizeof(info)))
 337                        return -EFAULT;
 338                return 0;
 339        }
 340        if (cmd == SOUND_OLD_MIXER_INFO) {
 341                _old_mixer_info info;
 342                memset(&info,0,sizeof(info));
 343                strncpy(info.id,"bt878",sizeof(info.id)-1);
 344                strncpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)-1);
 345                if (copy_to_user((void *)arg, &info, sizeof(info)))
 346                        return -EFAULT;
 347                return 0;
 348        }
 349        if (cmd == OSS_GETVERSION)
 350                return put_user(SOUND_VERSION, (int *)arg);
 351
 352        /* read */
 353        if (_SIOC_DIR(cmd) & _SIOC_WRITE)
 354                if (get_user(val, (int *)arg))
 355                        return -EFAULT;
 356
 357        switch (cmd) {
 358        case MIXER_READ(SOUND_MIXER_CAPS):
 359                ret = SOUND_CAP_EXCL_INPUT;
 360                break;
 361        case MIXER_READ(SOUND_MIXER_STEREODEVS):
 362                ret = 0;
 363                break;
 364        case MIXER_READ(SOUND_MIXER_RECMASK):
 365        case MIXER_READ(SOUND_MIXER_DEVMASK):
 366                ret = SOUND_MASK_LINE1|SOUND_MASK_LINE2|SOUND_MASK_LINE3;
 367                break;
 368
 369        case MIXER_WRITE(SOUND_MIXER_RECSRC):
 370                if (val & SOUND_MASK_LINE1 && bta->source != 0)
 371                        bta->source = 0;
 372                else if (val & SOUND_MASK_LINE2 && bta->source != 1)
 373                        bta->source = 1;
 374                else if (val & SOUND_MASK_LINE3 && bta->source != 2)
 375                        bta->source = 2;
 376                btaor((bta->gain[bta->source] << 28) |
 377                      (bta->source            << 24),
 378                      0x0cffffff, REG_GPIO_DMA_CTL);
 379        case MIXER_READ(SOUND_MIXER_RECSRC):
 380                switch (bta->source) {
 381                case 0:  ret = SOUND_MASK_LINE1; break;
 382                case 1:  ret = SOUND_MASK_LINE2; break;
 383                case 2:  ret = SOUND_MASK_LINE3; break;
 384                default: ret = 0;
 385                }
 386                break;
 387
 388        case MIXER_WRITE(SOUND_MIXER_LINE1):
 389        case MIXER_WRITE(SOUND_MIXER_LINE2):
 390        case MIXER_WRITE(SOUND_MIXER_LINE3):
 391                if (MIXER_WRITE(SOUND_MIXER_LINE1) == cmd)
 392                        i = 0;
 393                if (MIXER_WRITE(SOUND_MIXER_LINE2) == cmd)
 394                        i = 1;
 395                if (MIXER_WRITE(SOUND_MIXER_LINE3) == cmd)
 396                        i = 2;
 397                bta->gain[i] = (val & 0xff) * 15 / 100;
 398                if (bta->gain[i] > 15) bta->gain[i] = 15;
 399                if (bta->gain[i] <  0) bta->gain[i] =  0;
 400                if (i == bta->source)
 401                        btaor((bta->gain[bta->source]<<28),
 402                              0x0fffffff, REG_GPIO_DMA_CTL);
 403                ret  = bta->gain[i] * 100 / 15;
 404                ret |= ret << 8;
 405                break;
 406
 407        case MIXER_READ(SOUND_MIXER_LINE1):
 408        case MIXER_READ(SOUND_MIXER_LINE2):
 409        case MIXER_READ(SOUND_MIXER_LINE3):
 410                if (MIXER_READ(SOUND_MIXER_LINE1) == cmd)
 411                        i = 0;
 412                if (MIXER_READ(SOUND_MIXER_LINE2) == cmd)
 413                        i = 1;
 414                if (MIXER_READ(SOUND_MIXER_LINE3) == cmd)
 415                        i = 2;
 416                ret  = bta->gain[i] * 100 / 15;
 417                ret |= ret << 8;
 418                break;
 419
 420        default:
 421                return -EINVAL;
 422        }
 423        if (put_user(ret, (int *)arg))
 424                return -EFAULT;
 425        return 0;
 426}
 427
 428static struct file_operations btaudio_mixer_fops = {
 429        owner:   THIS_MODULE,
 430        llseek:  no_llseek,
 431        open:    btaudio_mixer_open,
 432        release: btaudio_mixer_release,
 433        ioctl:   btaudio_mixer_ioctl,
 434};
 435
 436/* -------------------------------------------------------------- */
 437
 438static int btaudio_dsp_open(struct inode *inode, struct file *file,
 439                            struct btaudio *bta, int analog)
 440{
 441        down(&bta->lock);
 442        if (bta->users)
 443                goto busy;
 444        bta->users++;
 445        file->private_data = bta;
 446
 447        bta->analog = analog;
 448        bta->dma_block = 0;
 449        bta->read_offset = 0;
 450        bta->read_count = 0;
 451        bta->sampleshift = 0;
 452
 453        up(&bta->lock);
 454        return 0;
 455
 456 busy:
 457        up(&bta->lock);
 458        return -EBUSY;
 459}
 460
 461static int btaudio_dsp_open_digital(struct inode *inode, struct file *file)
 462{
 463        int minor = minor(inode->i_rdev);
 464        struct btaudio *bta;
 465
 466        for (bta = btaudios; bta != NULL; bta = bta->next)
 467                if (bta->dsp_digital == minor)
 468                        break;
 469        if (NULL == bta)
 470                return -ENODEV;
 471        
 472        if (debug)
 473                printk("btaudio: open digital dsp [%d]\n",minor);
 474        return btaudio_dsp_open(inode,file,bta,0);
 475}
 476
 477static int btaudio_dsp_open_analog(struct inode *inode, struct file *file)
 478{
 479        int minor = minor(inode->i_rdev);
 480        struct btaudio *bta;
 481
 482        for (bta = btaudios; bta != NULL; bta = bta->next)
 483                if (bta->dsp_analog == minor)
 484                        break;
 485        if (NULL == bta)
 486                return -ENODEV;
 487
 488        if (debug)
 489                printk("btaudio: open analog dsp [%d]\n",minor);
 490        return btaudio_dsp_open(inode,file,bta,1);
 491}
 492
 493static int btaudio_dsp_release(struct inode *inode, struct file *file)
 494{
 495        struct btaudio *bta = file->private_data;
 496
 497        down(&bta->lock);
 498        if (bta->recording)
 499                stop_recording(bta);
 500        bta->users--;
 501        up(&bta->lock);
 502        return 0;
 503}
 504
 505static ssize_t btaudio_dsp_read(struct file *file, char *buffer,
 506                                size_t swcount, loff_t *ppos)
 507{
 508        struct btaudio *bta = file->private_data;
 509        int hwcount = swcount << bta->sampleshift;
 510        int nsrc, ndst, err, ret = 0;
 511        DECLARE_WAITQUEUE(wait, current);
 512
 513        add_wait_queue(&bta->readq, &wait);
 514        down(&bta->lock);
 515        while (swcount > 0) {
 516                if (0 == bta->read_count) {
 517                        if (!bta->recording) {
 518                                if (0 != (err = start_recording(bta))) {
 519                                        if (0 == ret)
 520                                                ret = err;
 521                                        break;
 522                                }
 523                        }
 524                        if (file->f_flags & O_NONBLOCK) {
 525                                if (0 == ret)
 526                                        ret = -EAGAIN;
 527                                break;
 528                        }
 529                        up(&bta->lock);
 530                        current->state = TASK_INTERRUPTIBLE;
 531                        schedule();
 532                        down(&bta->lock);
 533                        if(signal_pending(current)) {
 534                                if (0 == ret)
 535                                        ret = -EINTR;
 536                                break;
 537                        }
 538                }
 539                nsrc = (bta->read_count < hwcount) ? bta->read_count : hwcount;
 540                if (nsrc > bta->buf_size - bta->read_offset)
 541                        nsrc = bta->buf_size - bta->read_offset;
 542                ndst = nsrc >> bta->sampleshift;
 543                
 544                if ((bta->analog  && 0 == bta->sampleshift) ||
 545                    (!bta->analog && 2 == bta->channels)) {
 546                        /* just copy */
 547                        if (copy_to_user(buffer + ret, bta->buf_cpu + bta->read_offset, nsrc)) {
 548                                if (0 == ret)
 549                                        ret = -EFAULT;
 550                                break;
 551                        }
 552
 553                } else if (!bta->analog) {
 554                        /* stereo => mono (digital audio) */
 555                        __s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset);
 556                        __s16 *dst = (__s16*)(buffer + ret);
 557                        __s16 avg;
 558                        int n = ndst>>1;
 559                        if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
 560                                if (0 == ret)
 561                                        ret = -EFAULT;
 562                                break;
 563                        }
 564                        for (; n; n--, dst++) {
 565                                avg  = (__s16)le16_to_cpu(*src) / 2; src++;
 566                                avg += (__s16)le16_to_cpu(*src) / 2; src++;
 567                                __put_user(cpu_to_le16(avg),(__u16*)(dst));
 568                        }
 569
 570                } else if (8 == bta->bits) {
 571                        /* copy + byte downsampling (audio A/D) */
 572                        __u8 *src = bta->buf_cpu + bta->read_offset;
 573                        __u8 *dst = buffer + ret;
 574                        int n = ndst;
 575                        if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
 576                                if (0 == ret)
 577                                        ret = -EFAULT;
 578                                break;
 579                        }
 580                        for (; n; n--, src += (1 << bta->sampleshift), dst++)
 581                                __put_user(*src,(__u8*)(dst));
 582
 583                } else {
 584                        /* copy + word downsampling (audio A/D) */
 585                        __u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset);
 586                        __u16 *dst = (__u16*)(buffer + ret);
 587                        int n = ndst>>1;
 588                        if (0 != verify_area(VERIFY_WRITE,dst,ndst)) {
 589                                if (0 == ret)
 590                                        ret = -EFAULT;
 591                                break;
 592                        }
 593                        for (; n; n--, src += (1 << bta->sampleshift), dst++)
 594                                __put_user(*src,(__u16*)(dst));
 595                }
 596
 597                ret     += ndst;
 598                swcount -= ndst;
 599                hwcount -= nsrc;
 600                bta->read_count  -= nsrc;
 601                bta->read_offset += nsrc;
 602                if (bta->read_offset == bta->buf_size)
 603                        bta->read_offset = 0;
 604        }
 605        up(&bta->lock);
 606        remove_wait_queue(&bta->readq, &wait);
 607        current->state = TASK_RUNNING;
 608        return ret;
 609}
 610
 611static ssize_t btaudio_dsp_write(struct file *file, const char *buffer,
 612                                 size_t count, loff_t *ppos)
 613{
 614        return -EINVAL;
 615}
 616
 617static int btaudio_dsp_ioctl(struct inode *inode, struct file *file,
 618                             unsigned int cmd, unsigned long arg)
 619{
 620        struct btaudio *bta = file->private_data;
 621        int s, i, ret, val = 0;
 622        
 623        switch (cmd) {
 624        case OSS_GETVERSION:
 625                return put_user(SOUND_VERSION, (int *)arg);
 626        case SNDCTL_DSP_GETCAPS:
 627                return 0;
 628
 629        case SNDCTL_DSP_SPEED:
 630                if (get_user(val, (int*)arg))
 631                        return -EFAULT;
 632                if (bta->analog) {
 633                        for (s = 0; s < 16; s++)
 634                                if (val << s >= HWBASE_AD*4/15)
 635                                        break;
 636                        for (i = 15; i >= 5; i--)
 637                                if (val << s <= HWBASE_AD*4/i)
 638                                        break;
 639                        bta->sampleshift = s;
 640                        bta->decimation  = i;
 641                        if (debug)
 642                                printk(KERN_DEBUG "btaudio: rate: req=%d  "
 643                                       "dec=%d shift=%d hwrate=%d swrate=%d\n",
 644                                       val,i,s,(HWBASE_AD*4/i),(HWBASE_AD*4/i)>>s);
 645                } else {
 646                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
 647                        bta->decimation  = 0;
 648                }
 649                if (bta->recording) {
 650                        down(&bta->lock);
 651                        stop_recording(bta);
 652                        start_recording(bta);
 653                        up(&bta->lock);
 654                }
 655                /* fall through */
 656        case SOUND_PCM_READ_RATE:
 657                if (bta->analog) {
 658                        return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, (int*)arg);
 659                } else {
 660                        return put_user(bta->rate, (int*)arg);
 661                }
 662
 663        case SNDCTL_DSP_STEREO:
 664                if (!bta->analog) {
 665                        if (get_user(val, (int*)arg))
 666                                return -EFAULT;
 667                        bta->channels    = (val > 0) ? 2 : 1;
 668                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
 669                        if (debug)
 670                                printk(KERN_INFO
 671                                       "btaudio: stereo=%d channels=%d\n",
 672                                       val,bta->channels);
 673                } else {
 674                        if (val == 1)
 675                                return -EFAULT;
 676                        else {
 677                                bta->channels = 1;
 678                                if (debug)
 679                                        printk(KERN_INFO
 680                                               "btaudio: stereo=0 channels=1\n");
 681                        }
 682                }
 683                return put_user((bta->channels)-1, (int *)arg);
 684
 685        case SNDCTL_DSP_CHANNELS:
 686                if (!bta->analog) {
 687                        if (get_user(val, (int*)arg))
 688                                return -EFAULT;
 689                        bta->channels    = (val > 1) ? 2 : 1;
 690                        bta->sampleshift = (bta->channels == 2) ? 0 : 1;
 691                        if (debug)
 692                                printk(KERN_DEBUG
 693                                       "btaudio: val=%d channels=%d\n",
 694                                       val,bta->channels);
 695                }
 696                /* fall through */
 697        case SOUND_PCM_READ_CHANNELS:
 698                return put_user(bta->channels, (int *)arg);
 699                
 700        case SNDCTL_DSP_GETFMTS: /* Returns a mask */
 701                if (bta->analog)
 702                        return put_user(AFMT_S16_LE|AFMT_S8, (int*)arg);
 703                else
 704                        return put_user(AFMT_S16_LE, (int*)arg);
 705
 706        case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/
 707                if (get_user(val, (int*)arg))
 708                        return -EFAULT;
 709                if (val != AFMT_QUERY) {
 710                        if (bta->analog)
 711                                bta->bits = (val == AFMT_S8) ? 8 : 16;
 712                        else
 713                                bta->bits = 16;
 714                        if (bta->recording) {
 715                                down(&bta->lock);
 716                                stop_recording(bta);
 717                                start_recording(bta);
 718                                up(&bta->lock);
 719                        }
 720                }
 721                if (debug)
 722                        printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits);
 723                return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8,
 724                                (int*)arg);
 725                break;
 726        case SOUND_PCM_READ_BITS:
 727                return put_user(bta->bits, (int*)arg);
 728
 729        case SNDCTL_DSP_NONBLOCK:
 730                file->f_flags |= O_NONBLOCK;
 731                return 0;
 732
 733        case SNDCTL_DSP_RESET:
 734                if (bta->recording) {
 735                        down(&bta->lock);
 736                        stop_recording(bta);
 737                        up(&bta->lock);
 738                }
 739                return 0;
 740        case SNDCTL_DSP_GETBLKSIZE:
 741                if (!bta->recording) {
 742                        if (0 != (ret = alloc_buffer(bta)))
 743                                return ret;
 744                        if (0 != (ret = make_risc(bta)))
 745                                return ret;
 746                }
 747                return put_user(bta->block_bytes>>bta->sampleshift,(int*)arg);
 748
 749        case SNDCTL_DSP_SYNC:
 750                /* NOP */
 751                return 0;
 752        case SNDCTL_DSP_GETISPACE:
 753        {
 754                audio_buf_info info;
 755                if (!bta->recording)
 756                        return -EINVAL;
 757                info.fragsize = bta->block_bytes>>bta->sampleshift;
 758                info.fragstotal = bta->block_count;
 759                info.bytes = bta->read_count;
 760                info.fragments = info.bytes / info.fragsize;
 761                if (debug)
 762                        printk(KERN_DEBUG "btaudio: SNDCTL_DSP_GETISPACE "
 763                               "returns %d/%d/%d/%d\n",
 764                               info.fragsize, info.fragstotal,
 765                               info.bytes, info.fragments);
 766                if (copy_to_user((void *)arg, &info, sizeof(info)))
 767                        return -EFAULT;
 768                return 0;
 769        }
 770#if 0 /* TODO */
 771        case SNDCTL_DSP_GETTRIGGER:
 772        case SNDCTL_DSP_SETTRIGGER:
 773        case SNDCTL_DSP_SETFRAGMENT:
 774#endif
 775        default:
 776                return -EINVAL;
 777        }
 778}
 779
 780static unsigned int btaudio_dsp_poll(struct file *file, struct poll_table_struct *wait)
 781{
 782        struct btaudio *bta = file->private_data;
 783        unsigned int mask = 0;
 784
 785        poll_wait(file, &bta->readq, wait);
 786
 787        if (0 != bta->read_count)
 788                mask |= (POLLIN | POLLRDNORM);
 789
 790        return mask;
 791}
 792
 793static struct file_operations btaudio_digital_dsp_fops = {
 794        owner:   THIS_MODULE,
 795        llseek:  no_llseek,
 796        open:    btaudio_dsp_open_digital,
 797        release: btaudio_dsp_release,
 798        read:    btaudio_dsp_read,
 799        write:   btaudio_dsp_write,
 800        ioctl:   btaudio_dsp_ioctl,
 801        poll:    btaudio_dsp_poll,
 802};
 803
 804static struct file_operations btaudio_analog_dsp_fops = {
 805        owner:   THIS_MODULE,
 806        llseek:  no_llseek,
 807        open:    btaudio_dsp_open_analog,
 808        release: btaudio_dsp_release,
 809        read:    btaudio_dsp_read,
 810        write:   btaudio_dsp_write,
 811        ioctl:   btaudio_dsp_ioctl,
 812        poll:    btaudio_dsp_poll,
 813};
 814
 815/* -------------------------------------------------------------- */
 816
 817static char *irq_name[] = { "", "", "", "OFLOW", "", "", "", "", "", "", "",
 818                            "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR",
 819                            "RIPERR", "PABORT", "OCERR", "SCERR" };
 820
 821static void btaudio_irq(int irq, void *dev_id, struct pt_regs * regs)
 822{
 823        int count = 0;
 824        u32 stat,astat;
 825        struct btaudio *bta = dev_id;
 826
 827        for (;;) {
 828                count++;
 829                stat  = btread(REG_INT_STAT);
 830                astat = stat & btread(REG_INT_MASK);
 831                if (!astat)
 832                        return;
 833                btwrite(astat,REG_INT_STAT);
 834
 835                if (irq_debug) {
 836                        int i;
 837                        printk(KERN_DEBUG "btaudio: irq loop=%d risc=%x, bits:",
 838                               count, stat>>28);
 839                        for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) {
 840                                if (stat & (1 << i))
 841                                        printk(" %s",irq_name[i]);
 842                                if (astat & (1 << i))
 843                                        printk("*");
 844                        }
 845                        printk("\n");
 846                }
 847                if (stat & IRQ_RISCI) {
 848                        int blocks;
 849                        blocks = (stat >> 28) - bta->dma_block;
 850                        if (blocks < 0)
 851                                blocks += bta->block_count;
 852                        bta->dma_block = stat >> 28;
 853                        if (bta->read_count + 2*bta->block_bytes > bta->buf_size) {
 854                                stop_recording(bta);
 855                                printk(KERN_INFO "btaudio: buffer overrun\n");
 856                        }
 857                        if (blocks > 0) {
 858                                bta->read_count += blocks * bta->block_bytes;
 859                                wake_up_interruptible(&bta->readq);
 860                        }
 861                }
 862                if (count > 10) {
 863                        printk(KERN_WARNING
 864                               "btaudio: Oops - irq mask cleared\n");
 865                        btwrite(0, REG_INT_MASK);
 866                }
 867        }
 868        return;
 869}
 870
 871/* -------------------------------------------------------------- */
 872
 873static unsigned int dsp1 = -1;
 874static unsigned int dsp2 = -1;
 875static unsigned int mixer = -1;
 876static int latency = -1;
 877static int digital = 1;
 878static int analog = 1;
 879static int rate = 0;
 880
 881#define BTA_OSPREY200 1
 882
 883static struct cardinfo cards[] = {
 884        [0] = {
 885                name: "default",
 886                rate: 32000,
 887        },
 888        [BTA_OSPREY200] = {
 889                name: "Osprey 200",
 890                rate: 44100,
 891        },
 892};
 893
 894static int __devinit btaudio_probe(struct pci_dev *pci_dev,
 895                                   const struct pci_device_id *pci_id)
 896{
 897        struct btaudio *bta;
 898        struct cardinfo *card = &cards[pci_id->driver_data];
 899        unsigned char revision,lat;
 900        int rc = -EBUSY;
 901
 902        if (pci_enable_device(pci_dev))
 903                return -EIO;
 904        if (!request_mem_region(pci_resource_start(pci_dev,0),
 905                                pci_resource_len(pci_dev,0),
 906                                "btaudio")) {
 907                return -EBUSY;
 908        }
 909
 910        bta = kmalloc(sizeof(*bta),GFP_ATOMIC);
 911        if (!bta) {
 912                rc = -ENOMEM;
 913                goto fail0;
 914        }
 915        memset(bta,0,sizeof(*bta));
 916
 917        bta->pci  = pci_dev;
 918        bta->irq  = pci_dev->irq;
 919        bta->mem  = pci_resource_start(pci_dev,0);
 920        bta->mmio = ioremap(pci_resource_start(pci_dev,0),
 921                            pci_resource_len(pci_dev,0));
 922
 923        bta->source     = 1;
 924        bta->bits       = 8;
 925        bta->channels   = 1;
 926        if (bta->analog) {
 927                bta->decimation  = 15;
 928        } else {
 929                bta->decimation  = 0;
 930                bta->sampleshift = 1;
 931        }
 932
 933        /* sample rate */
 934        bta->rate = card->rate;
 935        if (rate)
 936                bta->rate = rate;
 937        
 938        init_MUTEX(&bta->lock);
 939        init_waitqueue_head(&bta->readq);
 940
 941        if (-1 != latency) {
 942                printk(KERN_INFO "btaudio: setting pci latency timer to %d\n",
 943                       latency);
 944                pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
 945        }
 946        pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision);
 947        pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &lat);
 948        printk(KERN_INFO "btaudio: Bt%x (rev %d) at %02x:%02x.%x, ",
 949               pci_dev->device,revision,pci_dev->bus->number,
 950               PCI_SLOT(pci_dev->devfn),PCI_FUNC(pci_dev->devfn));
 951        printk("irq: %d, latency: %d, mmio: 0x%lx\n",
 952               bta->irq, lat, bta->mem);
 953        printk("btaudio: using card config \"%s\"\n", card->name);
 954
 955        /* init hw */
 956        btwrite(0, REG_GPIO_DMA_CTL);
 957        btwrite(0, REG_INT_MASK);
 958        btwrite(~0x0UL, REG_INT_STAT);
 959        pci_set_master(pci_dev);
 960
 961        if ((rc = request_irq(bta->irq, btaudio_irq, SA_SHIRQ|SA_INTERRUPT,
 962                              "btaudio",(void *)bta)) < 0) {
 963                printk(KERN_WARNING
 964                       "btaudio: can't request irq (rc=%d)\n",rc);
 965                goto fail1;
 966        }
 967
 968        /* register devices */
 969        if (digital) {
 970                rc = bta->dsp_digital =
 971                        register_sound_dsp(&btaudio_digital_dsp_fops,dsp1);
 972                if (rc < 0) {
 973                        printk(KERN_WARNING
 974                               "btaudio: can't register digital dsp (rc=%d)\n",rc);
 975                        goto fail2;
 976                }
 977                printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n",
 978                       bta->dsp_digital >> 4);
 979        }
 980        if (analog) {
 981                rc = bta->dsp_analog =
 982                        register_sound_dsp(&btaudio_analog_dsp_fops,dsp2);
 983                if (rc < 0) {
 984                        printk(KERN_WARNING
 985                               "btaudio: can't register analog dsp (rc=%d)\n",rc);
 986                        goto fail3;
 987                }
 988                printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n",
 989                       bta->dsp_analog >> 4);
 990                rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops,mixer);
 991                if (rc < 0) {
 992                        printk(KERN_WARNING
 993                               "btaudio: can't register mixer (rc=%d)\n",rc);
 994                        goto fail4;
 995                }
 996                printk(KERN_INFO "btaudio: registered device mixer%d\n",
 997                       bta->mixer_dev >> 4);
 998        }
 999
1000        /* hook into linked list */
1001        bta->next = btaudios;
1002        btaudios = bta;
1003
1004        pci_set_drvdata(pci_dev,bta);
1005        return 0;
1006
1007 fail4:
1008        unregister_sound_dsp(bta->dsp_analog);
1009 fail3:
1010        if (digital)
1011                unregister_sound_dsp(bta->dsp_digital);
1012 fail2:
1013        free_irq(bta->irq,bta); 
1014 fail1:
1015        kfree(bta);
1016 fail0:
1017        release_mem_region(pci_resource_start(pci_dev,0),
1018                           pci_resource_len(pci_dev,0));
1019        return rc;
1020}
1021
1022static void __devexit btaudio_remove(struct pci_dev *pci_dev)
1023{
1024        struct btaudio *bta = pci_get_drvdata(pci_dev);
1025        struct btaudio *walk;
1026
1027        /* turn off all DMA / IRQs */
1028        btand(~15, REG_GPIO_DMA_CTL);
1029        btwrite(0, REG_INT_MASK);
1030        btwrite(~0x0UL, REG_INT_STAT);
1031
1032        /* unregister devices */
1033        if (digital) {
1034                unregister_sound_dsp(bta->dsp_digital);
1035        }
1036        if (analog) {
1037                unregister_sound_dsp(bta->dsp_analog);
1038                unregister_sound_mixer(bta->mixer_dev);
1039        }
1040
1041        /* free resources */
1042        free_buffer(bta);
1043        free_irq(bta->irq,bta);
1044        release_mem_region(pci_resource_start(pci_dev,0),
1045                           pci_resource_len(pci_dev,0));
1046
1047        /* remove from linked list */
1048        if (bta == btaudios) {
1049                btaudios = NULL;
1050        } else {
1051                for (walk = btaudios; walk->next != bta; walk = walk->next)
1052                        ; /* if (NULL == walk->next) BUG(); */
1053                walk->next = bta->next;
1054        }
1055
1056        pci_set_drvdata(pci_dev, NULL);
1057        kfree(bta);
1058        return;
1059}
1060
1061/* -------------------------------------------------------------- */
1062
1063static struct pci_device_id btaudio_pci_tbl[] __devinitdata = {
1064        {
1065                vendor:       PCI_VENDOR_ID_BROOKTREE,
1066                device:       0x0878,
1067                subvendor:    0x0070,
1068                subdevice:    0xff01,
1069                driver_data:  BTA_OSPREY200,
1070        },{
1071                vendor:       PCI_VENDOR_ID_BROOKTREE,
1072                device:       0x0878,
1073                subvendor:    PCI_ANY_ID,
1074                subdevice:    PCI_ANY_ID,
1075        },{
1076                vendor:       PCI_VENDOR_ID_BROOKTREE,
1077                device:       0x0878,
1078                subvendor:    PCI_ANY_ID,
1079                subdevice:    PCI_ANY_ID,
1080        },{
1081                /* --- end of list --- */
1082        }
1083};
1084
1085static struct pci_driver btaudio_pci_driver = {
1086        name:     "btaudio",
1087        id_table: btaudio_pci_tbl,
1088        probe:    btaudio_probe,
1089        remove:   __devexit_p(btaudio_remove),
1090};
1091
1092static int btaudio_init_module(void)
1093{
1094        printk(KERN_INFO "btaudio: driver version 0.7 loaded [%s%s%s]\n",
1095               digital ? "digital" : "",
1096               analog && digital ? "+" : "",
1097               analog ? "analog" : "");
1098        return pci_module_init(&btaudio_pci_driver);
1099}
1100
1101static void btaudio_cleanup_module(void)
1102{
1103        pci_unregister_driver(&btaudio_pci_driver);
1104        return;
1105}
1106
1107module_init(btaudio_init_module);
1108module_exit(btaudio_cleanup_module);
1109
1110MODULE_PARM(dsp1,"i");
1111MODULE_PARM(dsp2,"i");
1112MODULE_PARM(mixer,"i");
1113MODULE_PARM(debug,"i");
1114MODULE_PARM(irq_debug,"i");
1115MODULE_PARM(digital,"i");
1116MODULE_PARM(analog,"i");
1117MODULE_PARM(rate,"i");
1118MODULE_PARM(latency,"i");
1119MODULE_PARM_DESC(latency,"pci latency timer");
1120
1121MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl);
1122MODULE_DESCRIPTION("bt878 audio dma driver");
1123MODULE_AUTHOR("Gerd Knorr");
1124MODULE_LICENSE("GPL");
1125
1126/*
1127 * Local variables:
1128 * c-basic-offset: 8
1129 * End:
1130 */
1131
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.