1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ANSI_X3.4-1968"><title>Full Code Example</title><meta name="generator" content="DocBook XSL Stylesheets V1.78.1"><link rel="home" href="index.html" title="Writing an ALSA Driver"><link rel="up" href="basic-flow.html" title="Chapter 2. Basic Flow for PCI Drivers"><link rel="prev" href="basic-flow.html" title="Chapter 2. Basic Flow for PCI Drivers"><link rel="next" href="basic-flow-constructor.html" title="Constructor"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Full Code Example</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="basic-flow.html">Prev</a> </td><th width="60%" align="center">Chapter 2. Basic Flow for PCI Drivers</th><td width="20%" align="right"> <a accesskey="n" href="basic-flow-constructor.html">Next</a></td></tr></table><hr></div><div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="basic-flow-example"></a>Full Code Example</h2></div></div></div><p> 2 The code example is shown below. Some parts are kept 3 unimplemented at this moment but will be filled in the 4 next sections. The numbers in the comment lines of the 5 <code class="function">snd_mychip_probe()</code> function 6 refer to details explained in the following section. 7 8 </p><div class="example"><a name="idp1090981916"></a><p class="title"><b>Example 2.1. Basic Flow for PCI Drivers - Example</b></p><div class="example-contents"><pre class="programlisting"> 9 10 #include <linux/init.h> 11 #include <linux/pci.h> 12 #include <linux/slab.h> 13 #include <sound/core.h> 14 #include <sound/initval.h> 15 16 /* module parameters (see "Module Parameters") */ 17 /* SNDRV_CARDS: maximum number of cards supported by this module */ 18 static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 19 static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 20 static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 21 22 /* definition of the chip-specific record */ 23 struct mychip { 24 struct snd_card *card; 25 /* the rest of the implementation will be in section 26 * "PCI Resource Management" 27 */ 28 }; 29 30 /* chip-specific destructor 31 * (see "PCI Resource Management") 32 */ 33 static int snd_mychip_free(struct mychip *chip) 34 { 35 .... /* will be implemented later... */ 36 } 37 38 /* component-destructor 39 * (see "Management of Cards and Components") 40 */ 41 static int snd_mychip_dev_free(struct snd_device *device) 42 { 43 return snd_mychip_free(device->device_data); 44 } 45 46 /* chip-specific constructor 47 * (see "Management of Cards and Components") 48 */ 49 static int snd_mychip_create(struct snd_card *card, 50 struct pci_dev *pci, 51 struct mychip **rchip) 52 { 53 struct mychip *chip; 54 int err; 55 static struct snd_device_ops ops = { 56 .dev_free = snd_mychip_dev_free, 57 }; 58 59 *rchip = NULL; 60 61 /* check PCI availability here 62 * (see "PCI Resource Management") 63 */ 64 .... 65 66 /* allocate a chip-specific data with zero filled */ 67 chip = kzalloc(sizeof(*chip), GFP_KERNEL); 68 if (chip == NULL) 69 return -ENOMEM; 70 71 chip->card = card; 72 73 /* rest of initialization here; will be implemented 74 * later, see "PCI Resource Management" 75 */ 76 .... 77 78 err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); 79 if (err < 0) { 80 snd_mychip_free(chip); 81 return err; 82 } 83 84 *rchip = chip; 85 return 0; 86 } 87 88 /* constructor -- see "Constructor" sub-section */ 89 static int snd_mychip_probe(struct pci_dev *pci, 90 const struct pci_device_id *pci_id) 91 { 92 static int dev; 93 struct snd_card *card; 94 struct mychip *chip; 95 int err; 96 97 /* (1) */ 98 if (dev >= SNDRV_CARDS) 99 return -ENODEV; 100 if (!enable[dev]) { 101 dev++; 102 return -ENOENT; 103 } 104 105 /* (2) */ 106 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 107 0, &card); 108 if (err < 0) 109 return err; 110 111 /* (3) */ 112 err = snd_mychip_create(card, pci, &chip); 113 if (err < 0) { 114 snd_card_free(card); 115 return err; 116 } 117 118 /* (4) */ 119 strcpy(card->driver, "My Chip"); 120 strcpy(card->shortname, "My Own Chip 123"); 121 sprintf(card->longname, "%s at 0x%lx irq %i", 122 card->shortname, chip->ioport, chip->irq); 123 124 /* (5) */ 125 .... /* implemented later */ 126 127 /* (6) */ 128 err = snd_card_register(card); 129 if (err < 0) { 130 snd_card_free(card); 131 return err; 132 } 133 134 /* (7) */ 135 pci_set_drvdata(pci, card); 136 dev++; 137 return 0; 138 } 139 140 /* destructor -- see the "Destructor" sub-section */ 141 static void snd_mychip_remove(struct pci_dev *pci) 142 { 143 snd_card_free(pci_get_drvdata(pci)); 144 pci_set_drvdata(pci, NULL); 145 } 146 147 </pre></div></div><p><br class="example-break"> 148 </p></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="basic-flow.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="basic-flow.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="basic-flow-constructor.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Chapter 2. Basic Flow for PCI Drivers </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Constructor</td></tr></table></div></body></html> 149