hdspe.c (317cec3c43aa82a60e43427c6f1382bdd9e6810f) hdspe.c (20a9f7715e7cfd20bad3bef79bf0d42a42162030)
1/*-
1/*-
2 * Copyright (c) 2012 Ruslan Bukin <br@bsdpad.com>
2 * Copyright (c) 2012-2016 Ruslan Bukin <br@bsdpad.com>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 71 unchanged lines hidden (view full) ---

82 { 34, 35, "adat", 1, 1 },
83
84 { 0, 0, NULL, 0, 0 },
85};
86
87static void
88hdspe_intr(void *p)
89{
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright

--- 71 unchanged lines hidden (view full) ---

82 { 34, 35, "adat", 1, 1 },
83
84 { 0, 0, NULL, 0, 0 },
85};
86
87static void
88hdspe_intr(void *p)
89{
90 struct sc_info *sc = (struct sc_info *)p;
91 struct sc_pcminfo *scp;
90 struct sc_pcminfo *scp;
91 struct sc_info *sc;
92 device_t *devlist;
92 device_t *devlist;
93 int devcount, status;
94 int i, err;
93 int devcount;
94 int status;
95 int err;
96 int i;
95
97
98 sc = (struct sc_info *)p;
99
96 snd_mtxlock(sc->lock);
97
98 status = hdspe_read_1(sc, HDSPE_STATUS_REG);
99 if (status & HDSPE_AUDIO_IRQ_PENDING) {
100 if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0)
101 return;
102
103 for (i = 0; i < devcount; i++) {

--- 7 unchanged lines hidden (view full) ---

111 }
112
113 snd_mtxunlock(sc->lock);
114}
115
116static void
117hdspe_dmapsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
118{
100 snd_mtxlock(sc->lock);
101
102 status = hdspe_read_1(sc, HDSPE_STATUS_REG);
103 if (status & HDSPE_AUDIO_IRQ_PENDING) {
104 if ((err = device_get_children(sc->dev, &devlist, &devcount)) != 0)
105 return;
106
107 for (i = 0; i < devcount; i++) {

--- 7 unchanged lines hidden (view full) ---

115 }
116
117 snd_mtxunlock(sc->lock);
118}
119
120static void
121hdspe_dmapsetmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
122{
123 struct sc_info *sc;
124
125 sc = (struct sc_info *)arg;
126
119#if 0
127#if 0
120 struct sc_info *sc = (struct sc_info *)arg;
121 device_printf(sc->dev, "hdspe_dmapsetmap()\n");
122#endif
123}
124
125static int
126hdspe_alloc_resources(struct sc_info *sc)
127{
128
129 /* Allocate resource. */
130 sc->csid = PCIR_BAR(0);
131 sc->cs = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
132 &sc->csid, RF_ACTIVE);
133
134 if (!sc->cs) {
135 device_printf(sc->dev, "Unable to map SYS_RES_MEMORY.\n");
136 return (ENXIO);
137 }
128 device_printf(sc->dev, "hdspe_dmapsetmap()\n");
129#endif
130}
131
132static int
133hdspe_alloc_resources(struct sc_info *sc)
134{
135
136 /* Allocate resource. */
137 sc->csid = PCIR_BAR(0);
138 sc->cs = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
139 &sc->csid, RF_ACTIVE);
140
141 if (!sc->cs) {
142 device_printf(sc->dev, "Unable to map SYS_RES_MEMORY.\n");
143 return (ENXIO);
144 }
145
138 sc->cst = rman_get_bustag(sc->cs);
139 sc->csh = rman_get_bushandle(sc->cs);
140
146 sc->cst = rman_get_bustag(sc->cs);
147 sc->csh = rman_get_bushandle(sc->cs);
148
141
142 /* Allocate interrupt resource. */
143 sc->irqid = 0;
144 sc->irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &sc->irqid,
145 RF_ACTIVE | RF_SHAREABLE);
146
147 if (!sc->irq ||
148 bus_setup_intr(sc->dev, sc->irq, INTR_MPSAFE | INTR_TYPE_AV,
149 NULL, hdspe_intr, sc, &sc->ih)) {

--- 52 unchanged lines hidden (view full) ---

202 bzero(sc->rbuf, sc->bufsize);
203
204 return (0);
205}
206
207static void
208hdspe_map_dmabuf(struct sc_info *sc)
209{
149 /* Allocate interrupt resource. */
150 sc->irqid = 0;
151 sc->irq = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, &sc->irqid,
152 RF_ACTIVE | RF_SHAREABLE);
153
154 if (!sc->irq ||
155 bus_setup_intr(sc->dev, sc->irq, INTR_MPSAFE | INTR_TYPE_AV,
156 NULL, hdspe_intr, sc, &sc->ih)) {

--- 52 unchanged lines hidden (view full) ---

209 bzero(sc->rbuf, sc->bufsize);
210
211 return (0);
212}
213
214static void
215hdspe_map_dmabuf(struct sc_info *sc)
216{
210 uint32_t paddr,raddr;
217 uint32_t paddr, raddr;
211 int i;
212
213 paddr = vtophys(sc->pbuf);
214 raddr = vtophys(sc->rbuf);
215
216 for (i = 0; i < HDSPE_MAX_SLOTS * 16; i++) {
217 hdspe_write_4(sc, HDSPE_PAGE_ADDR_BUF_OUT + 4 * i,
218 paddr + i * 4096);

--- 8 unchanged lines hidden (view full) ---

227 uint32_t rev;
228
229 if (pci_get_vendor(dev) == PCI_VENDOR_XILINX &&
230 pci_get_device(dev) == PCI_DEVICE_XILINX_HDSPE) {
231 rev = pci_get_revid(dev);
232 switch (rev) {
233 case PCI_REVISION_AIO:
234 device_set_desc(dev, "RME HDSPe AIO");
218 int i;
219
220 paddr = vtophys(sc->pbuf);
221 raddr = vtophys(sc->rbuf);
222
223 for (i = 0; i < HDSPE_MAX_SLOTS * 16; i++) {
224 hdspe_write_4(sc, HDSPE_PAGE_ADDR_BUF_OUT + 4 * i,
225 paddr + i * 4096);

--- 8 unchanged lines hidden (view full) ---

234 uint32_t rev;
235
236 if (pci_get_vendor(dev) == PCI_VENDOR_XILINX &&
237 pci_get_device(dev) == PCI_DEVICE_XILINX_HDSPE) {
238 rev = pci_get_revid(dev);
239 switch (rev) {
240 case PCI_REVISION_AIO:
241 device_set_desc(dev, "RME HDSPe AIO");
235 return 0;
242 return (0);
236 case PCI_REVISION_RAYDAT:
237 device_set_desc(dev, "RME HDSPe RayDAT");
243 case PCI_REVISION_RAYDAT:
244 device_set_desc(dev, "RME HDSPe RayDAT");
238 return 0;
245 return (0);
239 }
240 }
241
242 return (ENXIO);
243}
244
245static int
246hdspe_init(struct sc_info *sc)

--- 25 unchanged lines hidden (view full) ---

272 /* Set DDS value. */
273 period /= sc->speed;
274 hdspe_write_4(sc, HDSPE_FREQ_REG, period);
275
276 /* Other settings. */
277 sc->settings_register = 0;
278 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
279
246 }
247 }
248
249 return (ENXIO);
250}
251
252static int
253hdspe_init(struct sc_info *sc)

--- 25 unchanged lines hidden (view full) ---

279 /* Set DDS value. */
280 period /= sc->speed;
281 hdspe_write_4(sc, HDSPE_FREQ_REG, period);
282
283 /* Other settings. */
284 sc->settings_register = 0;
285 hdspe_write_4(sc, HDSPE_SETTINGS_REG, sc->settings_register);
286
280 return 0;
287 return (0);
281}
282
283static int
284hdspe_attach(device_t dev)
285{
288}
289
290static int
291hdspe_attach(device_t dev)
292{
286 struct sc_info *sc;
287 struct sc_pcminfo *scp;
288 struct hdspe_channel *chan_map;
293 struct hdspe_channel *chan_map;
294 struct sc_pcminfo *scp;
295 struct sc_info *sc;
289 uint32_t rev;
290 int i, err;
291
292#if 0
293 device_printf(dev, "hdspe_attach()\n");
294#endif
295
296 sc = device_get_softc(dev);

--- 8 unchanged lines hidden (view full) ---

305 sc->type = AIO;
306 chan_map = chan_map_aio;
307 break;
308 case PCI_REVISION_RAYDAT:
309 sc->type = RAYDAT;
310 chan_map = chan_map_rd;
311 break;
312 default:
296 uint32_t rev;
297 int i, err;
298
299#if 0
300 device_printf(dev, "hdspe_attach()\n");
301#endif
302
303 sc = device_get_softc(dev);

--- 8 unchanged lines hidden (view full) ---

312 sc->type = AIO;
313 chan_map = chan_map_aio;
314 break;
315 case PCI_REVISION_RAYDAT:
316 sc->type = RAYDAT;
317 chan_map = chan_map_rd;
318 break;
319 default:
313 return ENXIO;
320 return (ENXIO);
314 }
315
316 /* Allocate resources. */
317 err = hdspe_alloc_resources(sc);
318 if (err) {
319 device_printf(dev, "Unable to allocate system resources.\n");
321 }
322
323 /* Allocate resources. */
324 err = hdspe_alloc_resources(sc);
325 if (err) {
326 device_printf(dev, "Unable to allocate system resources.\n");
320 return ENXIO;
327 return (ENXIO);
321 }
322
323 if (hdspe_init(sc) != 0)
328 }
329
330 if (hdspe_init(sc) != 0)
324 return ENXIO;
331 return (ENXIO);
325
326 for (i = 0; i < HDSPE_MAX_CHANS && chan_map[i].descr != NULL; i++) {
327 scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO);
328 scp->hc = &chan_map[i];
329 scp->sc = sc;
330 scp->dev = device_add_child(dev, "pcm", -1);
331 device_set_ivars(scp->dev, scp);
332 }

--- 18 unchanged lines hidden (view full) ---

351hdspe_detach(device_t dev)
352{
353 struct sc_info *sc;
354 int err;
355
356 sc = device_get_softc(dev);
357 if (sc == NULL) {
358 device_printf(dev,"Can't detach: softc is null.\n");
332
333 for (i = 0; i < HDSPE_MAX_CHANS && chan_map[i].descr != NULL; i++) {
334 scp = malloc(sizeof(struct sc_pcminfo), M_DEVBUF, M_NOWAIT | M_ZERO);
335 scp->hc = &chan_map[i];
336 scp->sc = sc;
337 scp->dev = device_add_child(dev, "pcm", -1);
338 device_set_ivars(scp->dev, scp);
339 }

--- 18 unchanged lines hidden (view full) ---

358hdspe_detach(device_t dev)
359{
360 struct sc_info *sc;
361 int err;
362
363 sc = device_get_softc(dev);
364 if (sc == NULL) {
365 device_printf(dev,"Can't detach: softc is null.\n");
359 return 0;
366 return (0);
360 }
361
362 err = device_delete_children(dev);
363 if (err)
364 return (err);
365
366 hdspe_dmafree(sc);
367
368 if (sc->ih)
369 bus_teardown_intr(dev, sc->irq, sc->ih);
370 if (sc->dmat)
371 bus_dma_tag_destroy(sc->dmat);
372 if (sc->irq)
373 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
374 if (sc->cs)
375 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs);
376 if (sc->lock)
377 snd_mtxfree(sc->lock);
378
367 }
368
369 err = device_delete_children(dev);
370 if (err)
371 return (err);
372
373 hdspe_dmafree(sc);
374
375 if (sc->ih)
376 bus_teardown_intr(dev, sc->irq, sc->ih);
377 if (sc->dmat)
378 bus_dma_tag_destroy(sc->dmat);
379 if (sc->irq)
380 bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
381 if (sc->cs)
382 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BAR(0), sc->cs);
383 if (sc->lock)
384 snd_mtxfree(sc->lock);
385
379 return 0;
386 return (0);
380}
381
382static device_method_t hdspe_methods[] = {
383 DEVMETHOD(device_probe, hdspe_probe),
384 DEVMETHOD(device_attach, hdspe_attach),
385 DEVMETHOD(device_detach, hdspe_detach),
386 { 0, 0 }
387};
388
389static driver_t hdspe_driver = {
390 "hdspe",
391 hdspe_methods,
392 PCM_SOFTC_SIZE,
393};
394
395static devclass_t hdspe_devclass;
396
397DRIVER_MODULE(snd_hdspe, pci, hdspe_driver, hdspe_devclass, 0, 0);
387}
388
389static device_method_t hdspe_methods[] = {
390 DEVMETHOD(device_probe, hdspe_probe),
391 DEVMETHOD(device_attach, hdspe_attach),
392 DEVMETHOD(device_detach, hdspe_detach),
393 { 0, 0 }
394};
395
396static driver_t hdspe_driver = {
397 "hdspe",
398 hdspe_methods,
399 PCM_SOFTC_SIZE,
400};
401
402static devclass_t hdspe_devclass;
403
404DRIVER_MODULE(snd_hdspe, pci, hdspe_driver, hdspe_devclass, 0, 0);