xref: /netbsd-src/sys/dev/fdt/cdnsiic_fdt.c (revision 500d9e354b86dde34cf571e589358512d97c67b8)
1*500d9e35Sjmcneill /* $NetBSD: cdnsiic_fdt.c,v 1.1 2022/11/05 17:31:37 jmcneill Exp $ */
2*500d9e35Sjmcneill 
3*500d9e35Sjmcneill /*-
4*500d9e35Sjmcneill  * Copyright (c) 2022 Jared McNeill <jmcneill@invisible.ca>
5*500d9e35Sjmcneill  * All rights reserved.
6*500d9e35Sjmcneill  *
7*500d9e35Sjmcneill  * Redistribution and use in source and binary forms, with or without
8*500d9e35Sjmcneill  * modification, are permitted provided that the following conditions
9*500d9e35Sjmcneill  * are met:
10*500d9e35Sjmcneill  * 1. Redistributions of source code must retain the above copyright
11*500d9e35Sjmcneill  *    notice, this list of conditions and the following disclaimer.
12*500d9e35Sjmcneill  * 2. Redistributions in binary form must reproduce the above copyright
13*500d9e35Sjmcneill  *    notice, this list of conditions and the following disclaimer in the
14*500d9e35Sjmcneill  *    documentation and/or other materials provided with the distribution.
15*500d9e35Sjmcneill  *
16*500d9e35Sjmcneill  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*500d9e35Sjmcneill  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*500d9e35Sjmcneill  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*500d9e35Sjmcneill  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*500d9e35Sjmcneill  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*500d9e35Sjmcneill  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*500d9e35Sjmcneill  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*500d9e35Sjmcneill  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*500d9e35Sjmcneill  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*500d9e35Sjmcneill  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*500d9e35Sjmcneill  * POSSIBILITY OF SUCH DAMAGE.
27*500d9e35Sjmcneill  */
28*500d9e35Sjmcneill 
29*500d9e35Sjmcneill #include <sys/cdefs.h>
30*500d9e35Sjmcneill 
31*500d9e35Sjmcneill __KERNEL_RCSID(0, "$NetBSD: cdnsiic_fdt.c,v 1.1 2022/11/05 17:31:37 jmcneill Exp $");
32*500d9e35Sjmcneill 
33*500d9e35Sjmcneill #include <sys/param.h>
34*500d9e35Sjmcneill #include <sys/bus.h>
35*500d9e35Sjmcneill #include <sys/device.h>
36*500d9e35Sjmcneill #include <sys/intr.h>
37*500d9e35Sjmcneill #include <sys/systm.h>
38*500d9e35Sjmcneill #include <sys/time.h>
39*500d9e35Sjmcneill #include <sys/kmem.h>
40*500d9e35Sjmcneill 
41*500d9e35Sjmcneill #include <dev/i2c/i2cvar.h>
42*500d9e35Sjmcneill 
43*500d9e35Sjmcneill #include <dev/fdt/fdtvar.h>
44*500d9e35Sjmcneill #include <dev/ic/cdnsiicvar.h>
45*500d9e35Sjmcneill 
46*500d9e35Sjmcneill static const struct device_compatible_entry compat_data[] = {
47*500d9e35Sjmcneill 	{ .compat = "cdns,i2c-r1p10" },
48*500d9e35Sjmcneill 	{ .compat = "cdns,i2c-r1p14" },
49*500d9e35Sjmcneill 	DEVICE_COMPAT_EOL
50*500d9e35Sjmcneill };
51*500d9e35Sjmcneill 
52*500d9e35Sjmcneill static int
cdnsiic_fdt_match(device_t parent,cfdata_t cf,void * aux)53*500d9e35Sjmcneill cdnsiic_fdt_match(device_t parent, cfdata_t cf, void *aux)
54*500d9e35Sjmcneill {
55*500d9e35Sjmcneill 	struct fdt_attach_args * const faa = aux;
56*500d9e35Sjmcneill 
57*500d9e35Sjmcneill 	return of_compatible_match(faa->faa_phandle, compat_data);
58*500d9e35Sjmcneill }
59*500d9e35Sjmcneill 
60*500d9e35Sjmcneill static void
cdnsiic_fdt_attach(device_t parent,device_t self,void * aux)61*500d9e35Sjmcneill cdnsiic_fdt_attach(device_t parent, device_t self, void *aux)
62*500d9e35Sjmcneill {
63*500d9e35Sjmcneill 	struct cdnsiic_softc * const sc = device_private(self);
64*500d9e35Sjmcneill 	struct fdt_attach_args * const faa = aux;
65*500d9e35Sjmcneill 	const int phandle = faa->faa_phandle;
66*500d9e35Sjmcneill 	bus_addr_t addr;
67*500d9e35Sjmcneill 	bus_size_t size;
68*500d9e35Sjmcneill 	int error;
69*500d9e35Sjmcneill 
70*500d9e35Sjmcneill 	if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
71*500d9e35Sjmcneill 		aprint_error(": couldn't get registers\n");
72*500d9e35Sjmcneill 		return;
73*500d9e35Sjmcneill 	}
74*500d9e35Sjmcneill 
75*500d9e35Sjmcneill 	sc->sc_pclk = fdtbus_clock_get_index(phandle, 0);
76*500d9e35Sjmcneill 	if (sc->sc_pclk == NULL || clk_enable(sc->sc_pclk) != 0) {
77*500d9e35Sjmcneill 		aprint_error(": couldn't enable pclk\n");
78*500d9e35Sjmcneill 		return;
79*500d9e35Sjmcneill 	}
80*500d9e35Sjmcneill 
81*500d9e35Sjmcneill 	if (of_getprop_uint32(phandle, "clock-frequency", &sc->sc_bus_freq))
82*500d9e35Sjmcneill 		sc->sc_bus_freq = 100000;
83*500d9e35Sjmcneill 
84*500d9e35Sjmcneill 	sc->sc_dev = self;
85*500d9e35Sjmcneill 	sc->sc_bst = faa->faa_bst;
86*500d9e35Sjmcneill 	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
87*500d9e35Sjmcneill 		aprint_error(": couldn't map registers\n");
88*500d9e35Sjmcneill 		return;
89*500d9e35Sjmcneill 	}
90*500d9e35Sjmcneill 
91*500d9e35Sjmcneill 	error = cdnsiic_attach(sc);
92*500d9e35Sjmcneill 	if (error != 0) {
93*500d9e35Sjmcneill 		aprint_error_dev(self, "init failed, error = %d\n", error);
94*500d9e35Sjmcneill 		return;
95*500d9e35Sjmcneill 	}
96*500d9e35Sjmcneill 
97*500d9e35Sjmcneill 	fdtbus_register_i2c_controller(&sc->sc_ic, phandle);
98*500d9e35Sjmcneill 
99*500d9e35Sjmcneill 	fdtbus_attach_i2cbus(self, phandle, &sc->sc_ic, iicbus_print);
100*500d9e35Sjmcneill }
101*500d9e35Sjmcneill 
102*500d9e35Sjmcneill CFATTACH_DECL_NEW(cdnsiic_fdt, sizeof(struct cdnsiic_softc),
103*500d9e35Sjmcneill     cdnsiic_fdt_match, cdnsiic_fdt_attach, NULL, NULL);
104