Lines Matching +full:i2s +full:- +full:out

1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright 2006-2008 Johannes Berg <johannes@sipsolutions.net>
12 #include <linux/dma-mapping.h>
27 MODULE_DESCRIPTION("Apple Soundbus: I2S support");
32 " no layout-id property is present");
35 { .name = "i2s" },
46 r->size = (numcmds + 3) * sizeof(struct dbdma_cmd); in alloc_dbdma_descriptor_ring()
48 * enough or until we get some macio-specific versions in alloc_dbdma_descriptor_ring()
50 r->space = dma_alloc_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, in alloc_dbdma_descriptor_ring()
51 r->size, &r->bus_addr, GFP_KERNEL); in alloc_dbdma_descriptor_ring()
52 if (!r->space) in alloc_dbdma_descriptor_ring()
53 return -ENOMEM; in alloc_dbdma_descriptor_ring()
55 r->cmds = (void*)DBDMA_ALIGN(r->space); in alloc_dbdma_descriptor_ring()
56 r->bus_cmd_start = r->bus_addr + in alloc_dbdma_descriptor_ring()
57 (dma_addr_t)((char*)r->cmds - (char*)r->space); in alloc_dbdma_descriptor_ring()
65 if (!r->space) return; in free_dbdma_descriptor_ring()
67 dma_free_coherent(&macio_get_pci_dev(i2sdev->macio)->dev, in free_dbdma_descriptor_ring()
68 r->size, r->space, r->bus_addr); in free_dbdma_descriptor_ring()
77 iounmap(i2sdev->intfregs); in i2sbus_release_dev()
78 iounmap(i2sdev->out.dbdma); in i2sbus_release_dev()
79 iounmap(i2sdev->in.dbdma); in i2sbus_release_dev()
81 release_and_free_resource(i2sdev->allocated_resource[i]); in i2sbus_release_dev()
82 free_dbdma_descriptor_ring(i2sdev, &i2sdev->out.dbdma_ring); in i2sbus_release_dev()
83 free_dbdma_descriptor_ring(i2sdev, &i2sdev->in.dbdma_ring); in i2sbus_release_dev()
85 free_irq(i2sdev->interrupts[i], i2sdev); in i2sbus_release_dev()
86 i2sbus_control_remove_dev(i2sdev->control, i2sdev); in i2sbus_release_dev()
87 mutex_destroy(&i2sdev->lock); in i2sbus_release_dev()
96 spin_lock(&dev->low_lock); in i2sbus_bus_intr()
97 intreg = in_le32(&dev->intfregs->intr_ctl); in i2sbus_bus_intr()
100 out_le32(&dev->intfregs->intr_ctl, intreg); in i2sbus_bus_intr()
102 spin_unlock(&dev->low_lock); in i2sbus_bus_intr()
110 * mapping in various registers, thanks to bugs in Apple device-trees.
111 * We could instead key off the machine model and the name of the i2s
112 * node (i2s-a). This we'll do when we move it all to macio_asic.c
113 * and have that export items for each sub-node too.
119 int pindex, rc = -ENXIO; in i2sbus_get_and_fixup_rsrc()
124 * Normal machines just fetch the resource from the i2s-X node. in i2sbus_get_and_fixup_rsrc()
128 * case the i2s-modem node, if we ever want to handle it, uses the in i2sbus_get_and_fixup_rsrc()
141 rc = -ENXIO; in i2sbus_get_and_fixup_rsrc()
144 res->start += reg[index * 2]; in i2sbus_get_and_fixup_rsrc()
145 res->end = res->start + reg[index * 2 + 1] - 1; in i2sbus_get_and_fixup_rsrc()
173 if (strncmp(node_name, "i2s-", 4)) in i2sbus_add_dev()
188 const u32 *id = of_get_property(sound, "layout-id", NULL); in i2sbus_add_dev()
192 snprintf(dev->sound.modalias, 32, in i2sbus_add_dev()
193 "sound-layout-%d", layout); in i2sbus_add_dev()
196 id = of_get_property(sound, "device-id", NULL); in i2sbus_add_dev()
198 * We probably cannot handle all device-id machines, in i2sbus_add_dev()
203 snprintf(dev->sound.modalias, 32, in i2sbus_add_dev()
204 "aoa-device-id-%d", *id); in i2sbus_add_dev()
206 layout = -1; in i2sbus_add_dev()
210 /* for the time being, until we can handle non-layout-id in i2sbus_add_dev()
212 * layout-id property or we haven't been forced to attach. in i2sbus_add_dev()
213 * When there are two i2s busses and only one has a layout-id, in i2sbus_add_dev()
221 mutex_init(&dev->lock); in i2sbus_add_dev()
222 spin_lock_init(&dev->low_lock); in i2sbus_add_dev()
223 dev->sound.ofdev.archdata.dma_mask = macio->ofdev.archdata.dma_mask; in i2sbus_add_dev()
224 dev->sound.ofdev.dev.of_node = np; in i2sbus_add_dev()
225 dev->sound.ofdev.dev.dma_mask = &dev->sound.ofdev.archdata.dma_mask; in i2sbus_add_dev()
226 dev->sound.ofdev.dev.parent = &macio->ofdev.dev; in i2sbus_add_dev()
227 dev->sound.ofdev.dev.release = i2sbus_release_dev; in i2sbus_add_dev()
228 dev->sound.attach_codec = i2sbus_attach_codec; in i2sbus_add_dev()
229 dev->sound.detach_codec = i2sbus_detach_codec; in i2sbus_add_dev()
230 dev->sound.pcmid = -1; in i2sbus_add_dev()
231 dev->macio = macio; in i2sbus_add_dev()
232 dev->control = control; in i2sbus_add_dev()
233 dev->bus_number = node_name[4] - 'a'; in i2sbus_add_dev()
234 INIT_LIST_HEAD(&dev->sound.codec_list); in i2sbus_add_dev()
237 dev->interrupts[i] = -1; in i2sbus_add_dev()
238 snprintf(dev->rnames[i], sizeof(dev->rnames[i]), in i2sbus_add_dev()
243 if (request_irq(irq, ints[i], 0, dev->rnames[i], dev)) in i2sbus_add_dev()
245 dev->interrupts[i] = irq; in i2sbus_add_dev()
249 /* Resource handling is problematic as some device-trees contain in i2sbus_add_dev()
256 if (i2sbus_get_and_fixup_rsrc(np,i,layout,&dev->resources[i])) in i2sbus_add_dev()
258 /* If only we could use our resource dev->resources[i]... in i2sbus_add_dev()
262 dev->allocated_resource[i] = in i2sbus_add_dev()
263 request_mem_region(dev->resources[i].start, in i2sbus_add_dev()
264 resource_size(&dev->resources[i]), in i2sbus_add_dev()
265 dev->rnames[i]); in i2sbus_add_dev()
266 if (!dev->allocated_resource[i]) { in i2sbus_add_dev()
272 r = &dev->resources[aoa_resource_i2smmio]; in i2sbus_add_dev()
276 dev->intfregs = ioremap(r->start, rlen); in i2sbus_add_dev()
278 r = &dev->resources[aoa_resource_txdbdma]; in i2sbus_add_dev()
282 dev->out.dbdma = ioremap(r->start, rlen); in i2sbus_add_dev()
284 r = &dev->resources[aoa_resource_rxdbdma]; in i2sbus_add_dev()
288 dev->in.dbdma = ioremap(r->start, rlen); in i2sbus_add_dev()
290 if (!dev->intfregs || !dev->out.dbdma || !dev->in.dbdma) in i2sbus_add_dev()
293 if (alloc_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring, in i2sbus_add_dev()
296 if (alloc_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring, in i2sbus_add_dev()
300 if (i2sbus_control_add_dev(dev->control, dev)) { in i2sbus_add_dev()
305 if (soundbus_add_one(&dev->sound)) { in i2sbus_add_dev()
307 if (dev->sound.ofdev.dev.kobj.state_initialized) { in i2sbus_add_dev()
308 soundbus_dev_put(&dev->sound); in i2sbus_add_dev()
315 i2sbus_control_cell(dev->control, dev, 1); in i2sbus_add_dev()
316 i2sbus_control_enable(dev->control, dev); in i2sbus_add_dev()
317 i2sbus_control_clock(dev->control, dev, 1); in i2sbus_add_dev()
322 if (dev->interrupts[i] != -1) in i2sbus_add_dev()
323 free_irq(dev->interrupts[i], dev); in i2sbus_add_dev()
324 free_dbdma_descriptor_ring(dev, &dev->out.dbdma_ring); in i2sbus_add_dev()
325 free_dbdma_descriptor_ring(dev, &dev->in.dbdma_ring); in i2sbus_add_dev()
326 iounmap(dev->intfregs); in i2sbus_add_dev()
327 iounmap(dev->out.dbdma); in i2sbus_add_dev()
328 iounmap(dev->in.dbdma); in i2sbus_add_dev()
330 release_and_free_resource(dev->allocated_resource[i]); in i2sbus_add_dev()
331 mutex_destroy(&dev->lock); in i2sbus_add_dev()
347 return -ENODEV; in i2sbus_probe()
350 for_each_child_of_node(dev->ofdev.dev.of_node, np) { in i2sbus_probe()
352 of_device_is_compatible(np, "i2s-modem")) { in i2sbus_probe()
360 return -ENODEV; in i2sbus_probe()
363 dev_set_drvdata(&dev->ofdev.dev, control); in i2sbus_probe()
370 struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); in i2sbus_remove()
373 list_for_each_entry_safe(i2sdev, tmp, &control->list, item) in i2sbus_remove()
374 soundbus_remove_one(&i2sdev->sound); in i2sbus_remove()
380 struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); in i2sbus_suspend()
385 list_for_each_entry(i2sdev, &control->list, item) { in i2sbus_suspend()
387 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { in i2sbus_suspend()
389 if (cii->codec->suspend) in i2sbus_suspend()
390 err = cii->codec->suspend(cii, state); in i2sbus_suspend()
404 struct i2sbus_control *control = dev_get_drvdata(&dev->ofdev.dev); in i2sbus_resume()
409 list_for_each_entry(i2sdev, &control->list, item) { in i2sbus_resume()
410 /* reset i2s bus format etc. */ in i2sbus_resume()
413 /* Notify codecs so they can re-initialize */ in i2sbus_resume()
414 list_for_each_entry(cii, &i2sdev->sound.codec_list, list) { in i2sbus_resume()
416 if (cii->codec->resume) in i2sbus_resume()
417 err = cii->codec->resume(cii); in i2sbus_resume()
434 .name = "soundbus-i2s",