1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/* $OpenBSD: arcofi_dio.c,v 1.1 2011/12/21 23:12:03 miod Exp $ */
/*
* Copyright (c) 2011 Miodrag Vallat.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/device.h>
#include <machine/autoconf.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <sys/audioio.h>
#include <dev/audio_if.h>
#include <dev/ic/arcofivar.h>
#include <hp300/dev/dioreg.h>
#include <hp300/dev/diovar.h>
#include <hp300/dev/diodevs.h>
void arcofi_dio_attach(struct device *, struct device *, void *);
int arcofi_dio_match(struct device *, void *, void *);
struct arcofi_dio_softc {
struct arcofi_softc sc_arcofi;
struct isr sc_isr;
};
const struct cfattach arcofi_dio_ca = {
sizeof(struct arcofi_dio_softc),
arcofi_dio_match,
arcofi_dio_attach
};
extern struct hp300_bus_space_tag hp300_mem_tag; /* XXX */
int
arcofi_dio_match(struct device *parent, void *match, void *vaa)
{
struct dio_attach_args *da = vaa;
if (da->da_id != DIO_DEVICE_ID_AUDIO)
return 0;
return 1;
}
void
arcofi_dio_attach(struct device *parent, struct device *self, void *vaa)
{
struct arcofi_dio_softc *adsc = (struct arcofi_dio_softc *)self;
struct arcofi_softc *sc = &adsc->sc_arcofi;
struct dio_attach_args *da = vaa;
bus_addr_t base;
unsigned int u;
int ipl;
for (u = 0; u < ARCOFI_NREGS; u++)
sc->sc_reg[u] = (u << 1) | 0x01;
base = (bus_addr_t)dio_scodetopa(da->da_scode);
sc->sc_iot = &hp300_mem_tag;
/*
* XXX We request BUS_SPACE_MAP_LINEAR only to be able to use DIO_IPL
* XXX below; this ought to be provided in the attach_args
*/
if (bus_space_map(sc->sc_iot, base, DIOII_SIZEOFF, BUS_SPACE_MAP_LINEAR,
&sc->sc_ioh) != 0) {
printf(": can't map registers\n");
return;
}
ipl = DIO_IPL(bus_space_vaddr(sc->sc_iot, sc->sc_ioh));
sc->sc_sih = softintr_establish(IPL_SOFT, &arcofi_swintr, sc);
if (sc->sc_sih == NULL) {
printf(": can't register soft interrupt\n");
return;
}
adsc->sc_isr.isr_func = arcofi_hwintr;
adsc->sc_isr.isr_arg = sc;
adsc->sc_isr.isr_ipl = ipl;
adsc->sc_isr.isr_priority = IPL_AUDIO;
dio_intr_establish(&adsc->sc_isr, self->dv_xname);
printf(" ipl %d\n", ipl);
arcofi_attach(sc, "dio");
}
|