1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Support for Digigram Lola PCI-e boards |
4 | * |
5 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> |
6 | */ |
7 | |
8 | #include <linux/kernel.h> |
9 | #include <linux/init.h> |
10 | #include <linux/module.h> |
11 | #include <linux/dma-mapping.h> |
12 | #include <linux/delay.h> |
13 | #include <linux/interrupt.h> |
14 | #include <linux/slab.h> |
15 | #include <linux/pci.h> |
16 | #include <sound/core.h> |
17 | #include <sound/control.h> |
18 | #include <sound/pcm.h> |
19 | #include <sound/initval.h> |
20 | #include "lola.h" |
21 | |
22 | /* Standard options */ |
23 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
24 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
25 | static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
26 | |
27 | module_param_array(index, int, NULL, 0444); |
28 | MODULE_PARM_DESC(index, "Index value for Digigram Lola driver." ); |
29 | module_param_array(id, charp, NULL, 0444); |
30 | MODULE_PARM_DESC(id, "ID string for Digigram Lola driver." ); |
31 | module_param_array(enable, bool, NULL, 0444); |
32 | MODULE_PARM_DESC(enable, "Enable Digigram Lola driver." ); |
33 | |
34 | /* Lola-specific options */ |
35 | |
36 | /* for instance use always max granularity which is compatible |
37 | * with all sample rates |
38 | */ |
39 | static int granularity[SNDRV_CARDS] = { |
40 | [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX |
41 | }; |
42 | |
43 | /* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */ |
44 | static int sample_rate_min[SNDRV_CARDS] = { |
45 | [0 ... (SNDRV_CARDS - 1) ] = 16000 |
46 | }; |
47 | |
48 | module_param_array(granularity, int, NULL, 0444); |
49 | MODULE_PARM_DESC(granularity, "Granularity value" ); |
50 | module_param_array(sample_rate_min, int, NULL, 0444); |
51 | MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate" ); |
52 | |
53 | /* |
54 | */ |
55 | |
56 | MODULE_LICENSE("GPL" ); |
57 | MODULE_DESCRIPTION("Digigram Lola driver" ); |
58 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>" ); |
59 | |
60 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
61 | static int debug; |
62 | module_param(debug, int, 0644); |
63 | #define verbose_debug(fmt, args...) \ |
64 | do { if (debug > 1) pr_debug(SFX fmt, ##args); } while (0) |
65 | #else |
66 | #define verbose_debug(fmt, args...) |
67 | #endif |
68 | |
69 | /* |
70 | * pseudo-codec read/write via CORB/RIRB |
71 | */ |
72 | |
73 | static int corb_send_verb(struct lola *chip, unsigned int nid, |
74 | unsigned int verb, unsigned int data, |
75 | unsigned int extdata) |
76 | { |
77 | unsigned long flags; |
78 | int ret = -EIO; |
79 | |
80 | chip->last_cmd_nid = nid; |
81 | chip->last_verb = verb; |
82 | chip->last_data = data; |
83 | chip->last_extdata = extdata; |
84 | data |= (nid << 20) | (verb << 8); |
85 | |
86 | spin_lock_irqsave(&chip->reg_lock, flags); |
87 | if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) { |
88 | unsigned int wp = chip->corb.wp + 1; |
89 | wp %= LOLA_CORB_ENTRIES; |
90 | chip->corb.wp = wp; |
91 | chip->corb.buf[wp * 2] = cpu_to_le32(data); |
92 | chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata); |
93 | lola_writew(chip, BAR0, CORBWP, wp); |
94 | chip->rirb.cmds++; |
95 | smp_wmb(); |
96 | ret = 0; |
97 | } |
98 | spin_unlock_irqrestore(lock: &chip->reg_lock, flags); |
99 | return ret; |
100 | } |
101 | |
102 | static void lola_queue_unsol_event(struct lola *chip, unsigned int res, |
103 | unsigned int res_ex) |
104 | { |
105 | lola_update_ext_clock_freq(chip, val: res); |
106 | } |
107 | |
108 | /* retrieve RIRB entry - called from interrupt handler */ |
109 | static void lola_update_rirb(struct lola *chip) |
110 | { |
111 | unsigned int rp, wp; |
112 | u32 res, res_ex; |
113 | |
114 | wp = lola_readw(chip, BAR0, RIRBWP); |
115 | if (wp == chip->rirb.wp) |
116 | return; |
117 | chip->rirb.wp = wp; |
118 | |
119 | while (chip->rirb.rp != wp) { |
120 | chip->rirb.rp++; |
121 | chip->rirb.rp %= LOLA_CORB_ENTRIES; |
122 | |
123 | rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */ |
124 | res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]); |
125 | res = le32_to_cpu(chip->rirb.buf[rp]); |
126 | if (res_ex & LOLA_RIRB_EX_UNSOL_EV) |
127 | lola_queue_unsol_event(chip, res, res_ex); |
128 | else if (chip->rirb.cmds) { |
129 | chip->res = res; |
130 | chip->res_ex = res_ex; |
131 | smp_wmb(); |
132 | chip->rirb.cmds--; |
133 | } |
134 | } |
135 | } |
136 | |
137 | static int rirb_get_response(struct lola *chip, unsigned int *val, |
138 | unsigned int *extval) |
139 | { |
140 | unsigned long timeout; |
141 | |
142 | again: |
143 | timeout = jiffies + msecs_to_jiffies(m: 1000); |
144 | for (;;) { |
145 | if (chip->polling_mode) { |
146 | spin_lock_irq(lock: &chip->reg_lock); |
147 | lola_update_rirb(chip); |
148 | spin_unlock_irq(lock: &chip->reg_lock); |
149 | } |
150 | if (!chip->rirb.cmds) { |
151 | *val = chip->res; |
152 | if (extval) |
153 | *extval = chip->res_ex; |
154 | verbose_debug("get_response: %x, %x\n" , |
155 | chip->res, chip->res_ex); |
156 | if (chip->res_ex & LOLA_RIRB_EX_ERROR) { |
157 | dev_warn(chip->card->dev, "RIRB ERROR: " |
158 | "NID=%x, verb=%x, data=%x, ext=%x\n" , |
159 | chip->last_cmd_nid, |
160 | chip->last_verb, chip->last_data, |
161 | chip->last_extdata); |
162 | return -EIO; |
163 | } |
164 | return 0; |
165 | } |
166 | if (time_after(jiffies, timeout)) |
167 | break; |
168 | udelay(20); |
169 | cond_resched(); |
170 | } |
171 | dev_warn(chip->card->dev, "RIRB response error\n" ); |
172 | if (!chip->polling_mode) { |
173 | dev_warn(chip->card->dev, "switching to polling mode\n" ); |
174 | chip->polling_mode = 1; |
175 | goto again; |
176 | } |
177 | return -EIO; |
178 | } |
179 | |
180 | /* aynchronous write of a codec verb with data */ |
181 | int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb, |
182 | unsigned int data, unsigned int extdata) |
183 | { |
184 | verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n" , |
185 | nid, verb, data, extdata); |
186 | return corb_send_verb(chip, nid, verb, data, extdata); |
187 | } |
188 | |
189 | /* write a codec verb with data and read the returned status */ |
190 | int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb, |
191 | unsigned int data, unsigned int extdata, |
192 | unsigned int *val, unsigned int *extval) |
193 | { |
194 | int err; |
195 | |
196 | verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n" , |
197 | nid, verb, data, extdata); |
198 | err = corb_send_verb(chip, nid, verb, data, extdata); |
199 | if (err < 0) |
200 | return err; |
201 | err = rirb_get_response(chip, val, extval); |
202 | return err; |
203 | } |
204 | |
205 | /* flush all pending codec writes */ |
206 | int lola_codec_flush(struct lola *chip) |
207 | { |
208 | unsigned int tmp; |
209 | return rirb_get_response(chip, val: &tmp, NULL); |
210 | } |
211 | |
212 | /* |
213 | * interrupt handler |
214 | */ |
215 | static irqreturn_t lola_interrupt(int irq, void *dev_id) |
216 | { |
217 | struct lola *chip = dev_id; |
218 | unsigned int notify_ins, notify_outs, error_ins, error_outs; |
219 | int handled = 0; |
220 | int i; |
221 | |
222 | notify_ins = notify_outs = error_ins = error_outs = 0; |
223 | spin_lock(lock: &chip->reg_lock); |
224 | for (;;) { |
225 | unsigned int status, in_sts, out_sts; |
226 | unsigned int reg; |
227 | |
228 | status = lola_readl(chip, BAR1, DINTSTS); |
229 | if (!status || status == -1) |
230 | break; |
231 | |
232 | in_sts = lola_readl(chip, BAR1, DIINTSTS); |
233 | out_sts = lola_readl(chip, BAR1, DOINTSTS); |
234 | |
235 | /* clear Input Interrupts */ |
236 | for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) { |
237 | if (!(in_sts & (1 << i))) |
238 | continue; |
239 | in_sts &= ~(1 << i); |
240 | reg = lola_dsd_read(chip, i, STS); |
241 | if (reg & LOLA_DSD_STS_DESE) /* error */ |
242 | error_ins |= (1 << i); |
243 | if (reg & LOLA_DSD_STS_BCIS) /* notify */ |
244 | notify_ins |= (1 << i); |
245 | /* clear */ |
246 | lola_dsd_write(chip, i, STS, reg); |
247 | } |
248 | |
249 | /* clear Output Interrupts */ |
250 | for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) { |
251 | if (!(out_sts & (1 << i))) |
252 | continue; |
253 | out_sts &= ~(1 << i); |
254 | reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS); |
255 | if (reg & LOLA_DSD_STS_DESE) /* error */ |
256 | error_outs |= (1 << i); |
257 | if (reg & LOLA_DSD_STS_BCIS) /* notify */ |
258 | notify_outs |= (1 << i); |
259 | lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg); |
260 | } |
261 | |
262 | if (status & LOLA_DINT_CTRL) { |
263 | unsigned char rbsts; /* ring status is byte access */ |
264 | rbsts = lola_readb(chip, BAR0, RIRBSTS); |
265 | rbsts &= LOLA_RIRB_INT_MASK; |
266 | if (rbsts) |
267 | lola_writeb(chip, BAR0, RIRBSTS, rbsts); |
268 | rbsts = lola_readb(chip, BAR0, CORBSTS); |
269 | rbsts &= LOLA_CORB_INT_MASK; |
270 | if (rbsts) |
271 | lola_writeb(chip, BAR0, CORBSTS, rbsts); |
272 | |
273 | lola_update_rirb(chip); |
274 | } |
275 | |
276 | if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) { |
277 | /* clear global fifo error interrupt */ |
278 | lola_writel(chip, BAR1, DINTSTS, |
279 | (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR))); |
280 | } |
281 | handled = 1; |
282 | } |
283 | spin_unlock(lock: &chip->reg_lock); |
284 | |
285 | lola_pcm_update(chip, pcm: &chip->pcm[CAPT], bits: notify_ins); |
286 | lola_pcm_update(chip, pcm: &chip->pcm[PLAY], bits: notify_outs); |
287 | |
288 | return IRQ_RETVAL(handled); |
289 | } |
290 | |
291 | |
292 | /* |
293 | * controller |
294 | */ |
295 | static int reset_controller(struct lola *chip) |
296 | { |
297 | unsigned int gctl = lola_readl(chip, BAR0, GCTL); |
298 | unsigned long end_time; |
299 | |
300 | if (gctl) { |
301 | /* to be sure */ |
302 | lola_writel(chip, BAR1, BOARD_MODE, 0); |
303 | return 0; |
304 | } |
305 | |
306 | chip->cold_reset = 1; |
307 | lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET); |
308 | end_time = jiffies + msecs_to_jiffies(m: 200); |
309 | do { |
310 | msleep(msecs: 1); |
311 | gctl = lola_readl(chip, BAR0, GCTL); |
312 | if (gctl) |
313 | break; |
314 | } while (time_before(jiffies, end_time)); |
315 | if (!gctl) { |
316 | dev_err(chip->card->dev, "cannot reset controller\n" ); |
317 | return -EIO; |
318 | } |
319 | return 0; |
320 | } |
321 | |
322 | static void lola_irq_enable(struct lola *chip) |
323 | { |
324 | unsigned int val; |
325 | |
326 | /* enalbe all I/O streams */ |
327 | val = (1 << chip->pcm[PLAY].num_streams) - 1; |
328 | lola_writel(chip, BAR1, DOINTCTL, val); |
329 | val = (1 << chip->pcm[CAPT].num_streams) - 1; |
330 | lola_writel(chip, BAR1, DIINTCTL, val); |
331 | |
332 | /* enable global irqs */ |
333 | val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR | |
334 | LOLA_DINT_MUERR; |
335 | lola_writel(chip, BAR1, DINTCTL, val); |
336 | } |
337 | |
338 | static void lola_irq_disable(struct lola *chip) |
339 | { |
340 | lola_writel(chip, BAR1, DINTCTL, 0); |
341 | lola_writel(chip, BAR1, DIINTCTL, 0); |
342 | lola_writel(chip, BAR1, DOINTCTL, 0); |
343 | } |
344 | |
345 | static int setup_corb_rirb(struct lola *chip) |
346 | { |
347 | unsigned char tmp; |
348 | unsigned long end_time; |
349 | |
350 | chip->rb = snd_devm_alloc_pages(dev: &chip->pci->dev, SNDRV_DMA_TYPE_DEV, |
351 | PAGE_SIZE); |
352 | if (!chip->rb) |
353 | return -ENOMEM; |
354 | |
355 | chip->corb.addr = chip->rb->addr; |
356 | chip->corb.buf = (__le32 *)chip->rb->area; |
357 | chip->rirb.addr = chip->rb->addr + 2048; |
358 | chip->rirb.buf = (__le32 *)(chip->rb->area + 2048); |
359 | |
360 | /* disable ringbuffer DMAs */ |
361 | lola_writeb(chip, BAR0, RIRBCTL, 0); |
362 | lola_writeb(chip, BAR0, CORBCTL, 0); |
363 | |
364 | end_time = jiffies + msecs_to_jiffies(m: 200); |
365 | do { |
366 | if (!lola_readb(chip, BAR0, RIRBCTL) && |
367 | !lola_readb(chip, BAR0, CORBCTL)) |
368 | break; |
369 | msleep(msecs: 1); |
370 | } while (time_before(jiffies, end_time)); |
371 | |
372 | /* CORB set up */ |
373 | lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr); |
374 | lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr)); |
375 | /* set the corb size to 256 entries */ |
376 | lola_writeb(chip, BAR0, CORBSIZE, 0x02); |
377 | /* set the corb write pointer to 0 */ |
378 | lola_writew(chip, BAR0, CORBWP, 0); |
379 | /* reset the corb hw read pointer */ |
380 | lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR); |
381 | /* enable corb dma */ |
382 | lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN); |
383 | /* clear flags if set */ |
384 | tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK; |
385 | if (tmp) |
386 | lola_writeb(chip, BAR0, CORBSTS, tmp); |
387 | chip->corb.wp = 0; |
388 | |
389 | /* RIRB set up */ |
390 | lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr); |
391 | lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr)); |
392 | /* set the rirb size to 256 entries */ |
393 | lola_writeb(chip, BAR0, RIRBSIZE, 0x02); |
394 | /* reset the rirb hw write pointer */ |
395 | lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR); |
396 | /* set N=1, get RIRB response interrupt for new entry */ |
397 | lola_writew(chip, BAR0, RINTCNT, 1); |
398 | /* enable rirb dma and response irq */ |
399 | lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN); |
400 | /* clear flags if set */ |
401 | tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK; |
402 | if (tmp) |
403 | lola_writeb(chip, BAR0, RIRBSTS, tmp); |
404 | chip->rirb.rp = chip->rirb.cmds = 0; |
405 | |
406 | return 0; |
407 | } |
408 | |
409 | static void stop_corb_rirb(struct lola *chip) |
410 | { |
411 | /* disable ringbuffer DMAs */ |
412 | lola_writeb(chip, BAR0, RIRBCTL, 0); |
413 | lola_writeb(chip, BAR0, CORBCTL, 0); |
414 | } |
415 | |
416 | static void lola_reset_setups(struct lola *chip) |
417 | { |
418 | /* update the granularity */ |
419 | lola_set_granularity(chip, val: chip->granularity, force: true); |
420 | /* update the sample clock */ |
421 | lola_set_clock_index(chip, idx: chip->clock.cur_index); |
422 | /* enable unsolicited events of the clock widget */ |
423 | lola_enable_clock_events(chip); |
424 | /* update the analog gains */ |
425 | lola_setup_all_analog_gains(chip, CAPT, mute: false); /* input, update */ |
426 | /* update SRC configuration if applicable */ |
427 | lola_set_src_config(chip, src_mask: chip->input_src_mask, update: false); |
428 | /* update the analog outputs */ |
429 | lola_setup_all_analog_gains(chip, PLAY, mute: false); /* output, update */ |
430 | } |
431 | |
432 | static int lola_parse_tree(struct lola *chip) |
433 | { |
434 | unsigned int val; |
435 | int nid, err; |
436 | |
437 | err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val); |
438 | if (err < 0) { |
439 | dev_err(chip->card->dev, "Can't read VENDOR_ID\n" ); |
440 | return err; |
441 | } |
442 | val >>= 16; |
443 | if (val != 0x1369) { |
444 | dev_err(chip->card->dev, "Unknown codec vendor 0x%x\n" , val); |
445 | return -EINVAL; |
446 | } |
447 | |
448 | err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val); |
449 | if (err < 0) { |
450 | dev_err(chip->card->dev, "Can't read FUNCTION_TYPE\n" ); |
451 | return err; |
452 | } |
453 | if (val != 1) { |
454 | dev_err(chip->card->dev, "Unknown function type %d\n" , val); |
455 | return -EINVAL; |
456 | } |
457 | |
458 | err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val); |
459 | if (err < 0) { |
460 | dev_err(chip->card->dev, "Can't read SPECCAPS\n" ); |
461 | return err; |
462 | } |
463 | chip->lola_caps = val; |
464 | chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps); |
465 | chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps); |
466 | dev_dbg(chip->card->dev, "speccaps=0x%x, pins in=%d, out=%d\n" , |
467 | chip->lola_caps, |
468 | chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins); |
469 | |
470 | if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT || |
471 | chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) { |
472 | dev_err(chip->card->dev, "Invalid Lola-spec caps 0x%x\n" , val); |
473 | return -EINVAL; |
474 | } |
475 | |
476 | nid = 0x02; |
477 | err = lola_init_pcm(chip, CAPT, nidp: &nid); |
478 | if (err < 0) |
479 | return err; |
480 | err = lola_init_pcm(chip, PLAY, nidp: &nid); |
481 | if (err < 0) |
482 | return err; |
483 | |
484 | err = lola_init_pins(chip, CAPT, nidp: &nid); |
485 | if (err < 0) |
486 | return err; |
487 | err = lola_init_pins(chip, PLAY, nidp: &nid); |
488 | if (err < 0) |
489 | return err; |
490 | |
491 | if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) { |
492 | err = lola_init_clock_widget(chip, nid); |
493 | if (err < 0) |
494 | return err; |
495 | nid++; |
496 | } |
497 | if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) { |
498 | err = lola_init_mixer_widget(chip, nid); |
499 | if (err < 0) |
500 | return err; |
501 | nid++; |
502 | } |
503 | |
504 | /* enable unsolicited events of the clock widget */ |
505 | err = lola_enable_clock_events(chip); |
506 | if (err < 0) |
507 | return err; |
508 | |
509 | /* if last ResetController was not a ColdReset, we don't know |
510 | * the state of the card; initialize here again |
511 | */ |
512 | if (!chip->cold_reset) { |
513 | lola_reset_setups(chip); |
514 | chip->cold_reset = 1; |
515 | } else { |
516 | /* set the granularity if it is not the default */ |
517 | if (chip->granularity != LOLA_GRANULARITY_MIN) |
518 | lola_set_granularity(chip, val: chip->granularity, force: true); |
519 | } |
520 | |
521 | return 0; |
522 | } |
523 | |
524 | static void lola_stop_hw(struct lola *chip) |
525 | { |
526 | stop_corb_rirb(chip); |
527 | lola_irq_disable(chip); |
528 | } |
529 | |
530 | static void lola_free(struct snd_card *card) |
531 | { |
532 | struct lola *chip = card->private_data; |
533 | |
534 | if (chip->initialized) |
535 | lola_stop_hw(chip); |
536 | lola_free_mixer(chip); |
537 | } |
538 | |
539 | static int lola_create(struct snd_card *card, struct pci_dev *pci, int dev) |
540 | { |
541 | struct lola *chip = card->private_data; |
542 | int err; |
543 | unsigned int dever; |
544 | |
545 | err = pcim_enable_device(pdev: pci); |
546 | if (err < 0) |
547 | return err; |
548 | |
549 | spin_lock_init(&chip->reg_lock); |
550 | mutex_init(&chip->open_mutex); |
551 | chip->card = card; |
552 | chip->pci = pci; |
553 | chip->irq = -1; |
554 | card->private_free = lola_free; |
555 | |
556 | chip->granularity = granularity[dev]; |
557 | switch (chip->granularity) { |
558 | case 8: |
559 | chip->sample_rate_max = 48000; |
560 | break; |
561 | case 16: |
562 | chip->sample_rate_max = 96000; |
563 | break; |
564 | case 32: |
565 | chip->sample_rate_max = 192000; |
566 | break; |
567 | default: |
568 | dev_warn(chip->card->dev, |
569 | "Invalid granularity %d, reset to %d\n" , |
570 | chip->granularity, LOLA_GRANULARITY_MAX); |
571 | chip->granularity = LOLA_GRANULARITY_MAX; |
572 | chip->sample_rate_max = 192000; |
573 | break; |
574 | } |
575 | chip->sample_rate_min = sample_rate_min[dev]; |
576 | if (chip->sample_rate_min > chip->sample_rate_max) { |
577 | dev_warn(chip->card->dev, |
578 | "Invalid sample_rate_min %d, reset to 16000\n" , |
579 | chip->sample_rate_min); |
580 | chip->sample_rate_min = 16000; |
581 | } |
582 | |
583 | err = pcim_iomap_regions(pdev: pci, mask: (1 << 0) | (1 << 2), DRVNAME); |
584 | if (err < 0) |
585 | return err; |
586 | |
587 | chip->bar[0].addr = pci_resource_start(pci, 0); |
588 | chip->bar[0].remap_addr = pcim_iomap_table(pdev: pci)[0]; |
589 | chip->bar[1].addr = pci_resource_start(pci, 2); |
590 | chip->bar[1].remap_addr = pcim_iomap_table(pdev: pci)[2]; |
591 | |
592 | pci_set_master(dev: pci); |
593 | |
594 | err = reset_controller(chip); |
595 | if (err < 0) |
596 | return err; |
597 | |
598 | if (devm_request_irq(dev: &pci->dev, irq: pci->irq, handler: lola_interrupt, IRQF_SHARED, |
599 | KBUILD_MODNAME, dev_id: chip)) { |
600 | dev_err(chip->card->dev, "unable to grab IRQ %d\n" , pci->irq); |
601 | return -EBUSY; |
602 | } |
603 | chip->irq = pci->irq; |
604 | card->sync_irq = chip->irq; |
605 | |
606 | dever = lola_readl(chip, BAR1, DEVER); |
607 | chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff; |
608 | chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff; |
609 | chip->version = (dever >> 24) & 0xff; |
610 | dev_dbg(chip->card->dev, "streams in=%d, out=%d, version=0x%x\n" , |
611 | chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams, |
612 | chip->version); |
613 | |
614 | /* Test LOLA_BAR1_DEVER */ |
615 | if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT || |
616 | chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT || |
617 | (!chip->pcm[CAPT].num_streams && |
618 | !chip->pcm[PLAY].num_streams)) { |
619 | dev_err(chip->card->dev, "invalid DEVER = %x\n" , dever); |
620 | return -EINVAL; |
621 | } |
622 | |
623 | err = setup_corb_rirb(chip); |
624 | if (err < 0) |
625 | return err; |
626 | |
627 | strcpy(p: card->driver, q: "Lola" ); |
628 | strscpy(card->shortname, "Digigram Lola" , sizeof(card->shortname)); |
629 | snprintf(buf: card->longname, size: sizeof(card->longname), |
630 | fmt: "%s at 0x%lx irq %i" , |
631 | card->shortname, chip->bar[0].addr, chip->irq); |
632 | strcpy(p: card->mixername, q: card->shortname); |
633 | |
634 | lola_irq_enable(chip); |
635 | |
636 | chip->initialized = 1; |
637 | return 0; |
638 | } |
639 | |
640 | static int __lola_probe(struct pci_dev *pci, |
641 | const struct pci_device_id *pci_id) |
642 | { |
643 | static int dev; |
644 | struct snd_card *card; |
645 | struct lola *chip; |
646 | int err; |
647 | |
648 | if (dev >= SNDRV_CARDS) |
649 | return -ENODEV; |
650 | if (!enable[dev]) { |
651 | dev++; |
652 | return -ENOENT; |
653 | } |
654 | |
655 | err = snd_devm_card_new(parent: &pci->dev, idx: index[dev], xid: id[dev], THIS_MODULE, |
656 | extra_size: sizeof(*chip), card_ret: &card); |
657 | if (err < 0) { |
658 | dev_err(&pci->dev, "Error creating card!\n" ); |
659 | return err; |
660 | } |
661 | chip = card->private_data; |
662 | |
663 | err = lola_create(card, pci, dev); |
664 | if (err < 0) |
665 | return err; |
666 | |
667 | err = lola_parse_tree(chip); |
668 | if (err < 0) |
669 | return err; |
670 | |
671 | err = lola_create_pcm(chip); |
672 | if (err < 0) |
673 | return err; |
674 | |
675 | err = lola_create_mixer(chip); |
676 | if (err < 0) |
677 | return err; |
678 | |
679 | lola_proc_debug_new(chip); |
680 | |
681 | err = snd_card_register(card); |
682 | if (err < 0) |
683 | return err; |
684 | |
685 | pci_set_drvdata(pdev: pci, data: card); |
686 | dev++; |
687 | return 0; |
688 | } |
689 | |
690 | static int lola_probe(struct pci_dev *pci, |
691 | const struct pci_device_id *pci_id) |
692 | { |
693 | return snd_card_free_on_error(dev: &pci->dev, ret: __lola_probe(pci, pci_id)); |
694 | } |
695 | |
696 | /* PCI IDs */ |
697 | static const struct pci_device_id lola_ids[] = { |
698 | { PCI_VDEVICE(DIGIGRAM, 0x0001) }, |
699 | { 0, } |
700 | }; |
701 | MODULE_DEVICE_TABLE(pci, lola_ids); |
702 | |
703 | /* pci_driver definition */ |
704 | static struct pci_driver lola_driver = { |
705 | .name = KBUILD_MODNAME, |
706 | .id_table = lola_ids, |
707 | .probe = lola_probe, |
708 | }; |
709 | |
710 | module_pci_driver(lola_driver); |
711 | |