Lines Matching +full:wp +full:- +full:controller
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for Digigram Lola PCI-e boards
11 #include <linux/dma-mapping.h>
34 /* Lola-specific options */
40 [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX
45 [0 ... (SNDRV_CARDS - 1) ] = 16000
71 * pseudo-codec read/write via CORB/RIRB
79 int ret = -EIO; in corb_send_verb()
81 chip->last_cmd_nid = nid; in corb_send_verb()
82 chip->last_verb = verb; in corb_send_verb()
83 chip->last_data = data; in corb_send_verb()
84 chip->last_extdata = extdata; in corb_send_verb()
87 spin_lock_irqsave(&chip->reg_lock, flags); in corb_send_verb()
88 if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) { in corb_send_verb()
89 unsigned int wp = chip->corb.wp + 1; in corb_send_verb() local
90 wp %= LOLA_CORB_ENTRIES; in corb_send_verb()
91 chip->corb.wp = wp; in corb_send_verb()
92 chip->corb.buf[wp * 2] = cpu_to_le32(data); in corb_send_verb()
93 chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata); in corb_send_verb()
94 lola_writew(chip, BAR0, CORBWP, wp); in corb_send_verb()
95 chip->rirb.cmds++; in corb_send_verb()
99 spin_unlock_irqrestore(&chip->reg_lock, flags); in corb_send_verb()
109 /* retrieve RIRB entry - called from interrupt handler */
112 unsigned int rp, wp; in lola_update_rirb() local
115 wp = lola_readw(chip, BAR0, RIRBWP); in lola_update_rirb()
116 if (wp == chip->rirb.wp) in lola_update_rirb()
118 chip->rirb.wp = wp; in lola_update_rirb()
120 while (chip->rirb.rp != wp) { in lola_update_rirb()
121 chip->rirb.rp++; in lola_update_rirb()
122 chip->rirb.rp %= LOLA_CORB_ENTRIES; in lola_update_rirb()
124 rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */ in lola_update_rirb()
125 res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]); in lola_update_rirb()
126 res = le32_to_cpu(chip->rirb.buf[rp]); in lola_update_rirb()
129 else if (chip->rirb.cmds) { in lola_update_rirb()
130 chip->res = res; in lola_update_rirb()
131 chip->res_ex = res_ex; in lola_update_rirb()
133 chip->rirb.cmds--; in lola_update_rirb()
146 if (chip->polling_mode) { in rirb_get_response()
147 spin_lock_irq(&chip->reg_lock); in rirb_get_response()
149 spin_unlock_irq(&chip->reg_lock); in rirb_get_response()
151 if (!chip->rirb.cmds) { in rirb_get_response()
152 *val = chip->res; in rirb_get_response()
154 *extval = chip->res_ex; in rirb_get_response()
156 chip->res, chip->res_ex); in rirb_get_response()
157 if (chip->res_ex & LOLA_RIRB_EX_ERROR) { in rirb_get_response()
158 dev_warn(chip->card->dev, "RIRB ERROR: " in rirb_get_response()
160 chip->last_cmd_nid, in rirb_get_response()
161 chip->last_verb, chip->last_data, in rirb_get_response()
162 chip->last_extdata); in rirb_get_response()
163 return -EIO; in rirb_get_response()
172 dev_warn(chip->card->dev, "RIRB response error\n"); in rirb_get_response()
173 if (!chip->polling_mode) { in rirb_get_response()
174 dev_warn(chip->card->dev, "switching to polling mode\n"); in rirb_get_response()
175 chip->polling_mode = 1; in rirb_get_response()
178 return -EIO; in rirb_get_response()
224 spin_lock(&chip->reg_lock); in lola_interrupt()
230 if (!status || status == -1) in lola_interrupt()
237 for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) { in lola_interrupt()
251 for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) { in lola_interrupt()
284 spin_unlock(&chip->reg_lock); in lola_interrupt()
286 lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins); in lola_interrupt()
287 lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs); in lola_interrupt()
294 * controller
307 chip->cold_reset = 1; in reset_controller()
317 dev_err(chip->card->dev, "cannot reset controller\n"); in reset_controller()
318 return -EIO; in reset_controller()
328 val = (1 << chip->pcm[PLAY].num_streams) - 1; in lola_irq_enable()
330 val = (1 << chip->pcm[CAPT].num_streams) - 1; in lola_irq_enable()
353 &chip->pci->dev, in setup_corb_rirb()
354 PAGE_SIZE, &chip->rb); in setup_corb_rirb()
358 chip->corb.addr = chip->rb.addr; in setup_corb_rirb()
359 chip->corb.buf = (__le32 *)chip->rb.area; in setup_corb_rirb()
360 chip->rirb.addr = chip->rb.addr + 2048; in setup_corb_rirb()
361 chip->rirb.buf = (__le32 *)(chip->rb.area + 2048); in setup_corb_rirb()
376 lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr); in setup_corb_rirb()
377 lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr)); in setup_corb_rirb()
390 chip->corb.wp = 0; in setup_corb_rirb()
393 lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr); in setup_corb_rirb()
394 lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr)); in setup_corb_rirb()
407 chip->rirb.rp = chip->rirb.cmds = 0; in setup_corb_rirb()
422 lola_set_granularity(chip, chip->granularity, true); in lola_reset_setups()
424 lola_set_clock_index(chip, chip->clock.cur_index); in lola_reset_setups()
430 lola_set_src_config(chip, chip->input_src_mask, false); in lola_reset_setups()
442 dev_err(chip->card->dev, "Can't read VENDOR_ID\n"); in lola_parse_tree()
447 dev_err(chip->card->dev, "Unknown codec vendor 0x%x\n", val); in lola_parse_tree()
448 return -EINVAL; in lola_parse_tree()
453 dev_err(chip->card->dev, "Can't read FUNCTION_TYPE\n"); in lola_parse_tree()
457 dev_err(chip->card->dev, "Unknown function type %d\n", val); in lola_parse_tree()
458 return -EINVAL; in lola_parse_tree()
463 dev_err(chip->card->dev, "Can't read SPECCAPS\n"); in lola_parse_tree()
466 chip->lola_caps = val; in lola_parse_tree()
467 chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps); in lola_parse_tree()
468 chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps); in lola_parse_tree()
469 dev_dbg(chip->card->dev, "speccaps=0x%x, pins in=%d, out=%d\n", in lola_parse_tree()
470 chip->lola_caps, in lola_parse_tree()
471 chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins); in lola_parse_tree()
473 if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT || in lola_parse_tree()
474 chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) { in lola_parse_tree()
475 dev_err(chip->card->dev, "Invalid Lola-spec caps 0x%x\n", val); in lola_parse_tree()
476 return -EINVAL; in lola_parse_tree()
494 if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) { in lola_parse_tree()
500 if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) { in lola_parse_tree()
515 if (!chip->cold_reset) { in lola_parse_tree()
517 chip->cold_reset = 1; in lola_parse_tree()
520 if (chip->granularity != LOLA_GRANULARITY_MIN) in lola_parse_tree()
521 lola_set_granularity(chip, chip->granularity, true); in lola_parse_tree()
535 if (chip->initialized) in lola_free()
539 if (chip->irq >= 0) in lola_free()
540 free_irq(chip->irq, (void *)chip); in lola_free()
541 iounmap(chip->bar[0].remap_addr); in lola_free()
542 iounmap(chip->bar[1].remap_addr); in lola_free()
543 if (chip->rb.area) in lola_free()
544 snd_dma_free_pages(&chip->rb); in lola_free()
545 pci_release_regions(chip->pci); in lola_free()
546 pci_disable_device(chip->pci); in lola_free()
552 lola_free(device->device_data); in lola_dev_free()
575 return -ENOMEM; in lola_create()
578 spin_lock_init(&chip->reg_lock); in lola_create()
579 mutex_init(&chip->open_mutex); in lola_create()
580 chip->card = card; in lola_create()
581 chip->pci = pci; in lola_create()
582 chip->irq = -1; in lola_create()
584 chip->granularity = granularity[dev]; in lola_create()
585 switch (chip->granularity) { in lola_create()
587 chip->sample_rate_max = 48000; in lola_create()
590 chip->sample_rate_max = 96000; in lola_create()
593 chip->sample_rate_max = 192000; in lola_create()
596 dev_warn(chip->card->dev, in lola_create()
598 chip->granularity, LOLA_GRANULARITY_MAX); in lola_create()
599 chip->granularity = LOLA_GRANULARITY_MAX; in lola_create()
600 chip->sample_rate_max = 192000; in lola_create()
603 chip->sample_rate_min = sample_rate_min[dev]; in lola_create()
604 if (chip->sample_rate_min > chip->sample_rate_max) { in lola_create()
605 dev_warn(chip->card->dev, in lola_create()
607 chip->sample_rate_min); in lola_create()
608 chip->sample_rate_min = 16000; in lola_create()
618 chip->bar[0].addr = pci_resource_start(pci, 0); in lola_create()
619 chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0); in lola_create()
620 chip->bar[1].addr = pci_resource_start(pci, 2); in lola_create()
621 chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2); in lola_create()
622 if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) { in lola_create()
623 dev_err(chip->card->dev, "ioremap error\n"); in lola_create()
624 err = -ENXIO; in lola_create()
634 if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED, in lola_create()
636 dev_err(chip->card->dev, "unable to grab IRQ %d\n", pci->irq); in lola_create()
637 err = -EBUSY; in lola_create()
640 chip->irq = pci->irq; in lola_create()
641 card->sync_irq = chip->irq; in lola_create()
644 chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff; in lola_create()
645 chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff; in lola_create()
646 chip->version = (dever >> 24) & 0xff; in lola_create()
647 dev_dbg(chip->card->dev, "streams in=%d, out=%d, version=0x%x\n", in lola_create()
648 chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams, in lola_create()
649 chip->version); in lola_create()
652 if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT || in lola_create()
653 chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT || in lola_create()
654 (!chip->pcm[CAPT].num_streams && in lola_create()
655 !chip->pcm[PLAY].num_streams)) { in lola_create()
656 dev_err(chip->card->dev, "invalid DEVER = %x\n", dever); in lola_create()
657 err = -EINVAL; in lola_create()
667 dev_err(chip->card->dev, "Error creating device [card]!\n"); in lola_create()
671 strcpy(card->driver, "Lola"); in lola_create()
672 strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname)); in lola_create()
673 snprintf(card->longname, sizeof(card->longname), in lola_create()
675 card->shortname, chip->bar[0].addr, chip->irq); in lola_create()
676 strcpy(card->mixername, card->shortname); in lola_create()
680 chip->initialized = 1; in lola_create()
698 return -ENODEV; in lola_probe()
701 return -ENOENT; in lola_probe()
704 err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, in lola_probe()
707 dev_err(&pci->dev, "Error creating card!\n"); in lola_probe()
714 card->private_data = chip; in lola_probe()