ofw_i2c_subr.c revision 1.3 1 1.3 thorpej /* $NetBSD: ofw_i2c_subr.c,v 1.3 2025/09/18 02:51:04 thorpej Exp $ */
2 1.1 thorpej
3 1.1 thorpej /*
4 1.1 thorpej * Copyright 1998
5 1.1 thorpej * Digital Equipment Corporation. All rights reserved.
6 1.1 thorpej *
7 1.1 thorpej * This software is furnished under license and may be used and
8 1.1 thorpej * copied only in accordance with the following terms and conditions.
9 1.1 thorpej * Subject to these conditions, you may download, copy, install,
10 1.1 thorpej * use, modify and distribute this software in source and/or binary
11 1.1 thorpej * form. No title or ownership is transferred hereby.
12 1.1 thorpej *
13 1.1 thorpej * 1) Any source code used, modified or distributed must reproduce
14 1.1 thorpej * and retain this copyright notice and list of conditions as
15 1.1 thorpej * they appear in the source file.
16 1.1 thorpej *
17 1.1 thorpej * 2) No right is granted to use any trade name, trademark, or logo of
18 1.1 thorpej * Digital Equipment Corporation. Neither the "Digital Equipment
19 1.1 thorpej * Corporation" name nor any trademark or logo of Digital Equipment
20 1.1 thorpej * Corporation may be used to endorse or promote products derived
21 1.1 thorpej * from this software without the prior written permission of
22 1.1 thorpej * Digital Equipment Corporation.
23 1.1 thorpej *
24 1.1 thorpej * 3) This software is provided "AS-IS" and any express or implied
25 1.1 thorpej * warranties, including but not limited to, any implied warranties
26 1.1 thorpej * of merchantability, fitness for a particular purpose, or
27 1.1 thorpej * non-infringement are disclaimed. In no event shall DIGITAL be
28 1.1 thorpej * liable for any damages whatsoever, and in particular, DIGITAL
29 1.1 thorpej * shall not be liable for special, indirect, consequential, or
30 1.1 thorpej * incidental damages or damages for lost profits, loss of
31 1.1 thorpej * revenue or loss of use, whether such damages arise in contract,
32 1.1 thorpej * negligence, tort, under statute, in equity, at law or otherwise,
33 1.1 thorpej * even if advised of the possibility of such damage.
34 1.1 thorpej */
35 1.1 thorpej
36 1.1 thorpej #include <sys/cdefs.h>
37 1.3 thorpej __KERNEL_RCSID(0, "$NetBSD: ofw_i2c_subr.c,v 1.3 2025/09/18 02:51:04 thorpej Exp $");
38 1.1 thorpej
39 1.1 thorpej #include <sys/param.h>
40 1.1 thorpej #include <sys/device.h>
41 1.1 thorpej #include <sys/kmem.h>
42 1.1 thorpej #include <sys/systm.h>
43 1.1 thorpej #include <dev/ofw/openfirm.h>
44 1.1 thorpej #include <dev/i2c/i2cvar.h>
45 1.1 thorpej
46 1.1 thorpej /*
47 1.1 thorpej * Iterate over the subtree of a i2c controller node.
48 1.1 thorpej * Add all sub-devices into an array as part of the controller's
49 1.1 thorpej * device properties.
50 1.1 thorpej * This is used by the i2c bus attach code to do direct configuration.
51 1.1 thorpej */
52 1.2 thorpej prop_array_t
53 1.2 thorpej of_copy_i2c_devs(int ofnode, size_t cell_size, int addr_shift)
54 1.1 thorpej {
55 1.1 thorpej int node, len;
56 1.1 thorpej char name[32];
57 1.1 thorpej uint64_t reg64;
58 1.1 thorpej uint32_t reg32;
59 1.1 thorpej uint64_t addr;
60 1.1 thorpej prop_array_t array = NULL;
61 1.1 thorpej prop_dictionary_t dev;
62 1.3 thorpej devhandle_t child_devhandle;
63 1.1 thorpej
64 1.1 thorpej for (node = OF_child(ofnode); node; node = OF_peer(node)) {
65 1.1 thorpej if (OF_getprop(node, "name", name, sizeof(name)) <= 0)
66 1.1 thorpej continue;
67 1.1 thorpej len = OF_getproplen(node, "reg");
68 1.1 thorpej addr = 0;
69 1.1 thorpej if (cell_size == 8 && len >= sizeof(reg64)) {
70 1.1 thorpej if (OF_getprop(node, "reg", ®64, sizeof(reg64))
71 1.1 thorpej < sizeof(reg64))
72 1.1 thorpej continue;
73 1.1 thorpej addr = be64toh(reg64);
74 1.1 thorpej /*
75 1.1 thorpej * The i2c bus number (0 or 1) is encoded in bit 33
76 1.1 thorpej * of the register, but we encode it in bit 8 of
77 1.1 thorpej * i2c_addr_t.
78 1.1 thorpej */
79 1.1 thorpej if (addr & 0x100000000)
80 1.1 thorpej addr = (addr & 0xff) | 0x100;
81 1.1 thorpej } else if (cell_size == 4 && len >= sizeof(reg32)) {
82 1.1 thorpej if (OF_getprop(node, "reg", ®32, sizeof(reg32))
83 1.1 thorpej < sizeof(reg32))
84 1.1 thorpej continue;
85 1.1 thorpej addr = be32toh(reg32);
86 1.1 thorpej } else {
87 1.1 thorpej continue;
88 1.1 thorpej }
89 1.1 thorpej addr >>= addr_shift;
90 1.1 thorpej if (addr == 0) continue;
91 1.1 thorpej
92 1.1 thorpej if (array == NULL)
93 1.1 thorpej array = prop_array_create();
94 1.1 thorpej
95 1.1 thorpej dev = prop_dictionary_create();
96 1.1 thorpej prop_dictionary_set_string(dev, "name", name);
97 1.1 thorpej prop_dictionary_set_uint32(dev, "addr", addr);
98 1.3 thorpej child_devhandle = devhandle_from_of(devhandle_invalid(), node);
99 1.3 thorpej prop_dictionary_set_data(dev, "devhandle", &child_devhandle,
100 1.3 thorpej sizeof(child_devhandle));
101 1.1 thorpej of_to_dataprop(dev, node, "compatible", "compatible");
102 1.1 thorpej prop_array_add(array, dev);
103 1.1 thorpej prop_object_release(dev);
104 1.1 thorpej }
105 1.1 thorpej
106 1.2 thorpej return array;
107 1.1 thorpej }
108