1 1.5 thorpej /* $NetBSD: tsciic.c,v 1.5 2025/09/15 13:23:00 thorpej Exp $ */ 2 1.1 jdc 3 1.1 jdc /* 4 1.1 jdc * Copyright (c) 2013 The NetBSD Foundation, Inc. 5 1.1 jdc * All rights reserved. 6 1.1 jdc * 7 1.1 jdc * This code is derived from software contributed to The NetBSD Foundation 8 1.1 jdc * by Julian Coleman. 9 1.1 jdc * 10 1.1 jdc * Redistribution and use in source and binary forms, with or without 11 1.1 jdc * modification, are permitted provided that the following conditions 12 1.1 jdc * are met: 13 1.1 jdc * 1. Redistributions of source code must retain the above copyright 14 1.1 jdc * notice, this list of conditions and the following disclaimer. 15 1.1 jdc * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 jdc * notice, this list of conditions and the following disclaimer in the 17 1.1 jdc * documentation and/or other materials provided with the distribution. 18 1.1 jdc * 19 1.1 jdc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 jdc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 jdc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 jdc * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 jdc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 jdc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 jdc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 jdc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 jdc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 jdc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 jdc * POSSIBILITY OF SUCH DAMAGE. 30 1.1 jdc */ 31 1.1 jdc 32 1.1 jdc #include <sys/cdefs.h> 33 1.1 jdc 34 1.5 thorpej __KERNEL_RCSID(0, "$NetBSD: tsciic.c,v 1.5 2025/09/15 13:23:00 thorpej Exp $"); 35 1.1 jdc 36 1.1 jdc #include <sys/param.h> 37 1.1 jdc #include <sys/systm.h> 38 1.1 jdc #include <sys/device.h> 39 1.1 jdc 40 1.1 jdc #include <alpha/pci/tsreg.h> 41 1.1 jdc #include <alpha/pci/tsvar.h> 42 1.1 jdc 43 1.1 jdc #include <dev/i2c/i2cvar.h> 44 1.1 jdc #include <dev/i2c/i2c_bitbang.h> 45 1.1 jdc #include <dev/i2c/ddcvar.h> 46 1.1 jdc 47 1.1 jdc /* I2C glue */ 48 1.1 jdc static int tsciic_send_start(void *, int); 49 1.1 jdc static int tsciic_send_stop(void *, int); 50 1.1 jdc static int tsciic_initiate_xfer(void *, i2c_addr_t, int); 51 1.1 jdc static int tsciic_read_byte(void *, uint8_t *, int); 52 1.1 jdc static int tsciic_write_byte(void *, uint8_t, int); 53 1.1 jdc 54 1.1 jdc /* I2C bitbang glue */ 55 1.1 jdc static void tsciicbb_set_bits(void *, uint32_t); 56 1.1 jdc static void tsciicbb_set_dir(void *, uint32_t); 57 1.1 jdc static uint32_t tsciicbb_read(void *); 58 1.1 jdc 59 1.1 jdc #define MPD_BIT_SDA 0x01 60 1.1 jdc #define MPD_BIT_SCL 0x02 61 1.1 jdc static const struct i2c_bitbang_ops tsciicbb_ops = { 62 1.1 jdc tsciicbb_set_bits, 63 1.1 jdc tsciicbb_set_dir, 64 1.1 jdc tsciicbb_read, 65 1.1 jdc { 66 1.1 jdc MPD_BIT_SDA, 67 1.1 jdc MPD_BIT_SCL, 68 1.1 jdc 0, 69 1.1 jdc 0 70 1.1 jdc } 71 1.1 jdc }; 72 1.1 jdc 73 1.1 jdc void 74 1.3 thorpej tsciic_init(device_t self) 75 1.3 thorpej { 76 1.1 jdc struct tsciic_softc *sc = device_private(self); 77 1.1 jdc 78 1.2 thorpej iic_tag_init(&sc->sc_i2c); 79 1.1 jdc sc->sc_i2c.ic_cookie = sc; 80 1.1 jdc sc->sc_i2c.ic_send_start = tsciic_send_start; 81 1.1 jdc sc->sc_i2c.ic_send_stop = tsciic_send_stop; 82 1.1 jdc sc->sc_i2c.ic_initiate_xfer = tsciic_initiate_xfer; 83 1.1 jdc sc->sc_i2c.ic_read_byte = tsciic_read_byte; 84 1.1 jdc sc->sc_i2c.ic_write_byte = tsciic_write_byte; 85 1.1 jdc 86 1.5 thorpej iicbus_attach(self, &sc->sc_i2c); 87 1.1 jdc } 88 1.1 jdc 89 1.1 jdc /* I2C bitbanging */ 90 1.1 jdc static void 91 1.1 jdc tsciicbb_set_bits(void *cookie, uint32_t bits) 92 1.1 jdc { 93 1.1 jdc uint64_t val; 94 1.1 jdc 95 1.1 jdc val = (bits & MPD_BIT_SDA ? MPD_DS : 0) | 96 1.1 jdc (bits & MPD_BIT_SCL ? MPD_CKS : 0); 97 1.1 jdc alpha_mb(); 98 1.1 jdc STQP(TS_C_MPD) = val; 99 1.1 jdc alpha_mb(); 100 1.1 jdc } 101 1.1 jdc 102 1.1 jdc static void 103 1.1 jdc tsciicbb_set_dir(void *cookie, uint32_t dir) 104 1.1 jdc { 105 1.1 jdc /* Nothing to do */ 106 1.1 jdc } 107 1.1 jdc 108 1.1 jdc static uint32_t 109 1.1 jdc tsciicbb_read(void *cookie) 110 1.1 jdc { 111 1.1 jdc uint64_t val; 112 1.1 jdc uint32_t bits; 113 1.1 jdc 114 1.1 jdc val = LDQP(TS_C_MPD); 115 1.1 jdc bits = (val & MPD_DR ? MPD_BIT_SDA : 0) | 116 1.1 jdc (val & MPD_CKR ? MPD_BIT_SCL : 0); 117 1.1 jdc return bits; 118 1.1 jdc } 119 1.1 jdc 120 1.1 jdc /* higher level I2C stuff */ 121 1.1 jdc static int 122 1.1 jdc tsciic_send_start(void *cookie, int flags) 123 1.1 jdc { 124 1.1 jdc return (i2c_bitbang_send_start(cookie, flags, &tsciicbb_ops)); 125 1.1 jdc } 126 1.1 jdc 127 1.1 jdc static int 128 1.1 jdc tsciic_send_stop(void *cookie, int flags) 129 1.1 jdc { 130 1.1 jdc return (i2c_bitbang_send_stop(cookie, flags, &tsciicbb_ops)); 131 1.1 jdc } 132 1.1 jdc 133 1.1 jdc static int 134 1.1 jdc tsciic_initiate_xfer(void *cookie, i2c_addr_t addr, int flags) 135 1.1 jdc { 136 1.1 jdc return (i2c_bitbang_initiate_xfer(cookie, addr, flags, 137 1.1 jdc &tsciicbb_ops)); 138 1.1 jdc } 139 1.1 jdc 140 1.1 jdc static int 141 1.1 jdc tsciic_read_byte(void *cookie, uint8_t *valp, int flags) 142 1.1 jdc { 143 1.1 jdc return (i2c_bitbang_read_byte(cookie, valp, flags, &tsciicbb_ops)); 144 1.1 jdc } 145 1.1 jdc 146 1.1 jdc static int 147 1.1 jdc tsciic_write_byte(void *cookie, uint8_t val, int flags) 148 1.1 jdc { 149 1.1 jdc return (i2c_bitbang_write_byte(cookie, val, flags, &tsciicbb_ops)); 150 1.1 jdc } 151