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