linux-old/drivers/sound/skeleton.c
<<
>>
Prefs
   1/*
   2 *      PCI sound skeleton example
   3 *
   4 *      (c) 1998 Red Hat Software
   5 *
   6 *      This software may be used and distributed according to the 
   7 *      terms of the GNU General Public License, incorporated herein by 
   8 *      reference.
   9 *
  10 *      This example is designed to be built in the linux/drivers/sound
  11 *      directory as part of a kernel build. The example is modular only
  12 *      drop me a note once you have a working modular driver and want
  13 *      to integrate it with the main code.
  14 *              -- Alan <alan@redhat.com>
  15 *
  16 *      This is a first draft. Please report any errors, corrections or
  17 *      improvements to me.
  18 */
  19
  20#include <linux/module.h>
  21#include <linux/delay.h>
  22#include <linux/errno.h>
  23#include <linux/fs.h>
  24#include <linux/kernel.h>
  25#include <linux/pci.h>
  26
  27#include <asm/io.h>
  28
  29#include "sound_config.h"
  30
  31/*
  32 *      Define our PCI vendor ID here
  33 */
  34 
  35#ifndef PCI_VENDOR_MYIDENT
  36#define PCI_VENDOR_MYIDENT                      0x125D
  37
  38/*
  39 *      PCI identity for the card.
  40 */
  41 
  42#define PCI_DEVICE_ID_MYIDENT_MYCARD1           0x1969
  43#endif
  44
  45#define CARD_NAME       "ExampleWave 3D Pro Ultra ThingyWotsit"
  46
  47#define MAX_CARDS       8
  48
  49/*
  50 *      Each address_info object holds the information about one of
  51 *      our card resources. In this case the MSS emulation of our
  52 *      ficticious card. Its used to manage and attach things.
  53 */
  54 
  55static struct address_info      mss_data[MAX_CARDS];
  56static int                      cards = 0;
  57
  58/*
  59 *      Install the actual card. This is an example
  60 */
  61
  62static int mycard_install(struct pci_dev *pcidev)
  63{
  64        int iobase;
  65        int mssbase;
  66        int mpubase;
  67        u8 x;
  68        u16 w;
  69        u32 v;
  70        int i;
  71        int dma;
  72
  73        /*
  74         *      Our imaginary code has its I/O on PCI address 0, a
  75         *      MSS on PCI address 1 and an MPU on address 2
  76         *
  77         *      For the example we will only initialise the MSS
  78         */
  79                
  80        iobase = pci_resource_start(pcidev, 0);
  81        mssbase = pci_resource_start(pcidev, 1);
  82        mpubase = pci_resource_start(pcidev, 2);
  83        
  84        /*
  85         *      Reset the board
  86         */
  87         
  88        /*
  89         *      Wait for completion. udelay() waits in microseconds
  90         */
  91         
  92        udelay(100);
  93        
  94        /*
  95         *      Ok card ready. Begin setup proper. You might for example
  96         *      load the firmware here
  97         */
  98        
  99        dma = card_specific_magic(ioaddr);
 100        
 101        /*
 102         *      Turn on legacy mode (example), There are also byte and
 103         *      dword (32bit) PCI configuration function calls
 104         */
 105
 106        pci_read_config_word(pcidev, 0x40, &w);
 107        w&=~(1<<15);                    /* legacy decode on */
 108        w|=(1<<14);                     /* Reserved write as 1 in this case */
 109        w|=(1<<3)|(1<<1)|(1<<0);        /* SB on , FM on, MPU on */
 110        pci_write_config_word(pcidev, 0x40, w);
 111        
 112        /*
 113         *      Let the user know we found his toy.
 114         */
 115         
 116        printk(KERN_INFO "Programmed "CARD_NAME" at 0x%X to legacy mode.\n",
 117                iobase);
 118                
 119        /*
 120         *      Now set it up the description of the card
 121         */
 122         
 123        mss_data[cards].io_base = mssbase;
 124        mss_data[cards].irq = pcidev->irq;
 125        mss_data[cards].dma = dma;
 126        
 127        /*
 128         *      Check there is an MSS present
 129         */
 130
 131        if(ad1848_detect(mssbase, NULL, mss_data[cards].osp)==0)
 132                return 0;
 133                
 134        /*
 135         *      Initialize it
 136         */
 137         
 138        mss_data[cards].slots[3] = ad1848_init("MyCard MSS 16bit", 
 139                        mssbase,
 140                        mss_data[cards].irq,
 141                        mss_data[cards].dma,
 142                        mss_data[cards].dma,
 143                        0,
 144                        0,
 145                        THIS_MODULE);
 146
 147        cards++;        
 148        return 1;
 149}
 150
 151
 152/*
 153 *      This loop walks the PCI configuration database and finds where
 154 *      the sound cards are.
 155 */
 156 
 157int init_mycard(void)
 158{
 159        struct pci_dev *pcidev=NULL;
 160        int count=0;
 161                
 162        if(!pci_present())
 163                return -ENODEV;
 164        
 165                
 166        while((pcidev = pci_find_device(PCI_VENDOR_MYIDENT, PCI_DEVICE_ID_MYIDENT_MYCARD1, pcidev))!=NULL)
 167        {
 168                if (pci_enable_device(pcidev))
 169                        continue;
 170                count+=mycard_install(pcidev);
 171                if(count)
 172                        return 0;
 173                if(count==MAX_CARDS)
 174                        break;
 175        }
 176        
 177        if(count==0)
 178                return -ENODEV;
 179        return 0;
 180}
 181
 182/*
 183 *      This function is called when the user or kernel loads the 
 184 *      module into memory.
 185 */
 186
 187
 188int init_module(void)
 189{
 190        if(init_mycard()<0)
 191        {
 192                printk(KERN_ERR "No "CARD_NAME" cards found.\n");
 193                return -ENODEV;
 194        }
 195
 196        return 0;
 197}
 198
 199/*
 200 *      This is called when it is removed. It will only be removed 
 201 *      when its use count is 0.
 202 */
 203 
 204void cleanup_module(void)
 205{
 206        for(i=0;i< cards; i++)
 207        {
 208                /*
 209                 *      Free attached resources
 210                 */
 211                 
 212                ad1848_unload(mss_data[i].io_base,
 213                              mss_data[i].irq,
 214                              mss_data[i].dma,
 215                              mss_data[i].dma,
 216                              0);
 217                /*
 218                 *      And disconnect the device from the kernel
 219                 */
 220                sound_unload_audiodevice(mss_data[i].slots[3]);
 221        }
 222}
 223
 224
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.