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