]> git.pld-linux.org Git - packages/kernel.git/blob - linux-2.4.2-i810_audio.patch
- obsolete
[packages/kernel.git] / linux-2.4.2-i810_audio.patch
1 --- Linux/drivers/sound/i810_audio.c    Tue Apr 17 18:06:46 2001
2 +++ linux/drivers/sound/i810_audio.c    Tue Apr 17 18:14:17 2001
3 @@ -323,6 +323,10 @@
4         struct i810_channel *(*alloc_rec_pcm_channel)(struct i810_card *);
5         struct i810_channel *(*alloc_rec_mic_channel)(struct i810_card *);
6         void (*free_pcm_channel)(struct i810_card *, int chan);
7 +
8 +       /* We have a *very* long init time possibly, so use this to block */
9 +       /* attempts to open our devices before we are ready (stops oops'es) */
10 +       int initializing;
11  };
12  
13  static struct i810_card *devs = NULL;
14 @@ -1738,7 +1742,9 @@
15  
16         /* find an avaiable virtual channel (instance of /dev/dsp) */
17         while (card != NULL) {
18 -               for (i = 0; i < NR_HW_CH; i++) {
19 +               for (i = 0; i < 50 && card->initializing; i++)
20 +                       schedule_timeout(HZ/20);
21 +               for (i = 0; i < NR_HW_CH && !card->initializing; i++) {
22                         if (card->states[i] == NULL) {
23                                 state = card->states[i] = (struct i810_state *)
24                                         kmalloc(sizeof(struct i810_state), GFP_KERNEL);
25 @@ -1885,13 +1887,16 @@
26         int minor = MINOR(inode->i_rdev);
27         struct i810_card *card = devs;
28  
29 -       for (card = devs; card != NULL; card = card->next)
30 -               for (i = 0; i < NR_AC97; i++)
31 +       for (card = devs; card != NULL; card = card->next) {
32 +               for (i = 0; i < 50 && card->initializing; i++)
33 +                       schedule_timeout(HZ/20);
34 +               for (i = 0; i < NR_AC97 && !card->initializing; i++)
35                         if (card->ac97_codec[i] != NULL &&
36                             card->ac97_codec[i]->dev_mixer == minor) {
37                                 file->private_data = card->ac97_codec[i];
38                                 return 0;
39                         }
40 +       }
41         return -ENODEV;
42  }
43  
44 @@ -2023,6 +2028,75 @@
45         return num_ac97;
46  }
47  
48 +static void __init i810_configure_clocking (void)
49 +{
50 +       struct i810_card *card;
51 +       struct i810_state *state;
52 +       struct dmabuf *dmabuf;
53 +       unsigned int i, offset, new_offset;
54 +       unsigned long flags;
55 +
56 +       card = devs;
57 +       /* We could try to set the clocking for multiple cards, but can you even have
58 +        * more than one i810 in a machine?  Besides, clocking is global, so unless
59 +        * someone actually thinks more than one i810 in a machine is possible and
60 +        * decides to rewrite that little bit, setting the rate for more than one card
61 +        * is a waste of time.
62 +        */
63 +       if(card != NULL) {
64 +               state = card->states[0] = (struct i810_state *)
65 +                                       kmalloc(sizeof(struct i810_state), GFP_KERNEL);
66 +               if (state == NULL)
67 +                       return;
68 +               memset(state, 0, sizeof(struct i810_state));
69 +               dmabuf = &state->dmabuf;
70 +
71 +               dmabuf->write_channel = card->alloc_pcm_channel(card);
72 +               state->virt = 0;
73 +               state->card = card;
74 +               state->magic = I810_STATE_MAGIC;
75 +               init_waitqueue_head(&dmabuf->wait);
76 +               init_MUTEX(&state->open_sem);
77 +               dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
78 +               dmabuf->trigger = PCM_ENABLE_OUTPUT;
79 +               i810_set_dac_rate(state, 48000);
80 +               if(prog_dmabuf(state, 0) != 0) {
81 +                       goto config_out_nodmabuf;
82 +               }
83 +               if(dmabuf->dmasize < 16384) {
84 +                       goto config_out;
85 +               }
86 +               dmabuf->count = dmabuf->dmasize;
87 +               outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
88 +               save_flags(flags);
89 +               cli();
90 +               start_dac(state);
91 +               offset = i810_get_dma_addr(state, 0);
92 +               mdelay(50);
93 +               new_offset = i810_get_dma_addr(state, 0);
94 +               stop_dac(state);
95 +               outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
96 +               restore_flags(flags);
97 +               i = new_offset - offset;
98 +#ifdef DEBUG
99 +               printk("i810_audio: %d bytes in 50 milliseconds\n", i);
100 +#endif
101 +               if(i == 0)
102 +                       goto config_out;
103 +               i = i / 4 * 20;
104 +               if (i > 48500 || i < 47500) {
105 +                       clocking = clocking * clocking / i;
106 +                       printk("i810_audio: setting clocking to %d\n", clocking);
107 +               }
108 +config_out:
109 +               dealloc_dmabuf(state);
110 +config_out_nodmabuf:
111 +               state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
112 +               kfree(state);
113 +               card->states[0] = NULL;
114 +       }
115 +}
116 +
117  /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
118     until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
119     
120 @@ -2030,21 +2104,21 @@
121  {
122         struct i810_card *card;
123  
124 -       if (pci_enable_device(pci_dev))
125 -               return -EIO;
126 -
127 -       if (pci_set_dma_mask(pci_dev, I810_DMA_MASK)) {
128 +       if (!pci_dma_supported(pci_dev, I810_DMA_MASK)) {
129                 printk(KERN_ERR "intel810: architecture does not support"
130                        " 32bit PCI busmaster DMA\n");
131                 return -ENODEV;
132         }
133  
134 +       if (pci_enable_device(pci_dev))
135 +               return -EIO;
136         if ((card = kmalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) {
137                 printk(KERN_ERR "i810_audio: out of memory\n");
138                 return -ENOMEM;
139         }
140         memset(card, 0, sizeof(*card));
141  
142 +       card->initializing = 1;
143         card->iobase = pci_resource_start (pci_dev, 1);
144         card->ac97base = pci_resource_start (pci_dev, 0);
145         card->pci_dev = pci_dev;
146 @@ -2108,6 +2182,11 @@
147                 return -ENODEV;
148         }
149         pci_dev->driver_data = card;
150 +       pci_dev->dma_mask = I810_DMA_MASK;
151 +       if(clocking == 48000) {
152 +               i810_configure_clocking();
153 +       }
154 +       card->initializing = 0;
155         return 0;
156  }
157  
158 @@ -2146,75 +2225,6 @@
159         remove:         i810_remove,
160  };
161  
162 -static void __init i810_configure_clocking (void)
163 -{
164 -       struct i810_card *card;
165 -       struct i810_state *state;
166 -       struct dmabuf *dmabuf;
167 -       unsigned int i, offset, new_offset;
168 -       unsigned long flags;
169 -
170 -       card = devs;
171 -       /* We could try to set the clocking for multiple cards, but can you even have
172 -        * more than one i810 in a machine?  Besides, clocking is global, so unless
173 -        * someone actually thinks more than one i810 in a machine is possible and
174 -        * decides to rewrite that little bit, setting the rate for more than one card
175 -        * is a waste of time.
176 -        */
177 -       if(card != NULL) {
178 -               state = card->states[0] = (struct i810_state *)
179 -                                       kmalloc(sizeof(struct i810_state), GFP_KERNEL);
180 -               if (state == NULL)
181 -                       return;
182 -               memset(state, 0, sizeof(struct i810_state));
183 -               dmabuf = &state->dmabuf;
184 -
185 -               dmabuf->write_channel = card->alloc_pcm_channel(card);
186 -               state->virt = 0;
187 -               state->card = card;
188 -               state->magic = I810_STATE_MAGIC;
189 -               init_waitqueue_head(&dmabuf->wait);
190 -               init_MUTEX(&state->open_sem);
191 -               dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT;
192 -               dmabuf->trigger = PCM_ENABLE_OUTPUT;
193 -               i810_set_dac_rate(state, 48000);
194 -               if(prog_dmabuf(state, 0) != 0) {
195 -                       goto config_out_nodmabuf;
196 -               }
197 -               if(dmabuf->dmasize < 16384) {
198 -                       goto config_out;
199 -               }
200 -               dmabuf->count = dmabuf->dmasize;
201 -               outb(31,card->iobase+dmabuf->write_channel->port+OFF_LVI);
202 -               save_flags(flags);
203 -               cli();
204 -               start_dac(state);
205 -               offset = i810_get_dma_addr(state, 0);
206 -               mdelay(50);
207 -               new_offset = i810_get_dma_addr(state, 0);
208 -               stop_dac(state);
209 -               outb(2,card->iobase+dmabuf->write_channel->port+OFF_CR);
210 -               restore_flags(flags);
211 -               i = new_offset - offset;
212 -#ifdef DEBUG
213 -               printk("i810_audio: %d bytes in 50 milliseconds\n", i);
214 -#endif
215 -               if(i == 0)
216 -                       goto config_out;
217 -               i = i / 4 * 20;
218 -               if (i > 48500 || i < 47500) {
219 -                       clocking = clocking * clocking / i;
220 -                       printk("i810_audio: setting clocking to %d\n", clocking);
221 -               }
222 -config_out:
223 -               dealloc_dmabuf(state);
224 -config_out_nodmabuf:
225 -               state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num);
226 -               kfree(state);
227 -               card->states[0] = NULL;
228 -       }
229 -}
230 -
231  static int __init i810_init_module (void)
232  {
233         if (!pci_present())   /* No PCI bus in this machine! */
234 @@ -2229,9 +2239,6 @@
235         }
236         if(ftsodell != 0) {
237                 printk("i810_audio: ftsodell is now a deprecated option.\n");
238 -       }
239 -       if(clocking == 48000) {
240 -               i810_configure_clocking();
241         }
242         return 0;
243  }
This page took 0.060818 seconds and 3 git commands to generate.