Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/arm/freescale/imx/imx6_audmux.c
39536 views
1
/*-
2
* Copyright (c) 2015 Ruslan Bukin <[email protected]>
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
11
* notice, this list of conditions and the following disclaimer in the
12
* documentation and/or other materials provided with the distribution.
13
*
14
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24
* SUCH DAMAGE.
25
*/
26
27
/*
28
* i.MX6 Digital Audio Multiplexer (AUDMUX)
29
* Chapter 16, i.MX 6Dual/6Quad Applications Processor Reference Manual,
30
* Rev. 1, 04/2013
31
*/
32
33
#include <sys/param.h>
34
#include <sys/systm.h>
35
#include <sys/bus.h>
36
#include <sys/kernel.h>
37
#include <sys/module.h>
38
#include <sys/malloc.h>
39
#include <sys/endian.h>
40
#include <sys/rman.h>
41
#include <sys/timeet.h>
42
#include <sys/timetc.h>
43
44
#include <dev/ofw/openfirm.h>
45
#include <dev/ofw/ofw_bus.h>
46
#include <dev/ofw/ofw_bus_subr.h>
47
48
#include <machine/bus.h>
49
#include <machine/cpu.h>
50
#include <machine/intr.h>
51
52
#define READ4(_sc, _reg) \
53
bus_space_read_4(_sc->bst, _sc->bsh, _reg)
54
#define WRITE4(_sc, _reg, _val) \
55
bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
56
57
#define AUDMUX_PTCR(n) (0x8 * (n - 1)) /* Port Timing Control Register */
58
#define PTCR_TFS_DIR (1 << 31) /* Transmit Frame Sync Direction Control */
59
#define PTCR_TFSEL_S 27 /* Transmit Frame Sync Select */
60
#define PTCR_TFSEL_M 0xf
61
#define PTCR_TCLKDIR (1 << 26) /* Transmit Clock Direction Control */
62
#define PTCR_TCSEL_S 22 /* Transmit Clock Select. */
63
#define PTCR_TCSEL_M 0xf
64
#define PTCR_RFS_DIR (1 << 21) /* Receive Frame Sync Direction Control */
65
#define PTCR_SYN (1 << 11)
66
#define AUDMUX_PDCR(n) (0x8 * (n - 1) + 0x4) /* Port Data Control Reg */
67
#define PDCR_RXDSEL_S 13 /* Receive Data Select */
68
#define PDCR_RXDSEL_M 0x3
69
#define PDCR_RXDSEL_PORT(n) (n - 1)
70
71
struct audmux_softc {
72
struct resource *res[1];
73
bus_space_tag_t bst;
74
bus_space_handle_t bsh;
75
void *ih;
76
};
77
78
static struct resource_spec audmux_spec[] = {
79
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
80
{ -1, 0 }
81
};
82
83
static int
84
audmux_probe(device_t dev)
85
{
86
87
if (!ofw_bus_status_okay(dev))
88
return (ENXIO);
89
90
if (!ofw_bus_is_compatible(dev, "fsl,imx6q-audmux"))
91
return (ENXIO);
92
93
device_set_desc(dev, "i.MX6 Digital Audio Multiplexer");
94
return (BUS_PROBE_DEFAULT);
95
}
96
97
static int
98
audmux_configure(struct audmux_softc *sc,
99
int ssi_port, int audmux_port)
100
{
101
uint32_t reg;
102
103
/* Direction: output */
104
reg = (PTCR_TFS_DIR | PTCR_TCLKDIR | PTCR_SYN);
105
WRITE4(sc, AUDMUX_PTCR(audmux_port), reg);
106
107
/* Select source */
108
reg = (PDCR_RXDSEL_PORT(ssi_port) << PDCR_RXDSEL_S);
109
WRITE4(sc, AUDMUX_PDCR(audmux_port), reg);
110
111
return (0);
112
}
113
114
static int
115
audmux_attach(device_t dev)
116
{
117
struct audmux_softc *sc;
118
119
sc = device_get_softc(dev);
120
121
if (bus_alloc_resources(dev, audmux_spec, sc->res)) {
122
device_printf(dev, "could not allocate resources\n");
123
return (ENXIO);
124
}
125
126
/* Memory interface */
127
sc->bst = rman_get_bustag(sc->res[0]);
128
sc->bsh = rman_get_bushandle(sc->res[0]);
129
130
/*
131
* Direct SSI1 output to AUDMUX5 pins.
132
* TODO: dehardcore this.
133
*/
134
audmux_configure(sc, 1, 5);
135
136
return (0);
137
};
138
139
static device_method_t audmux_methods[] = {
140
/* Device interface */
141
DEVMETHOD(device_probe, audmux_probe),
142
DEVMETHOD(device_attach, audmux_attach),
143
{ 0, 0 }
144
};
145
146
static driver_t audmux_driver = {
147
"audmux",
148
audmux_methods,
149
sizeof(struct audmux_softc),
150
};
151
152
DRIVER_MODULE(audmux, simplebus, audmux_driver, 0, 0);
153
154