1 1.1 brad /* $NetBSD: i2cspi.c,v 1.1 2021/12/07 17:39:55 brad Exp $ */ 2 1.1 brad 3 1.1 brad /* 4 1.1 brad * Copyright (c) 2021 Brad Spencer <brad (at) anduin.eldar.org> 5 1.1 brad * 6 1.1 brad * Permission to use, copy, modify, and distribute this software for any 7 1.1 brad * purpose with or without fee is hereby granted, provided that the above 8 1.1 brad * copyright notice and this permission notice appear in all copies. 9 1.1 brad * 10 1.1 brad * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 1.1 brad * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 1.1 brad * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 1.1 brad * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 1.1 brad * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 1.1 brad * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 1.1 brad * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 1.1 brad */ 18 1.1 brad 19 1.1 brad #ifdef __RCSID 20 1.1 brad __RCSID("$NetBSD: i2cspi.c,v 1.1 2021/12/07 17:39:55 brad Exp $"); 21 1.1 brad #endif 22 1.1 brad 23 1.1 brad /* Functions that know how to talk to scmd(4) */ 24 1.1 brad 25 1.1 brad #include <inttypes.h> 26 1.1 brad #include <stdbool.h> 27 1.1 brad #include <stdio.h> 28 1.1 brad #include <stdlib.h> 29 1.1 brad #include <unistd.h> 30 1.1 brad #include <err.h> 31 1.1 brad #include <fcntl.h> 32 1.1 brad #include <string.h> 33 1.1 brad #include <limits.h> 34 1.1 brad #include <errno.h> 35 1.1 brad 36 1.1 brad #include <dev/ic/scmdreg.h> 37 1.1 brad 38 1.1 brad #include "scmdctl.h" 39 1.1 brad #include "responses.h" 40 1.1 brad 41 1.1 brad #define EXTERN 42 1.1 brad #include "i2cspi.h" 43 1.1 brad 44 1.1 brad int i2cspi_clear(int, bool); 45 1.1 brad int i2cspi_read_register(int, bool, int, uint8_t, uint8_t, uint8_t *); 46 1.1 brad int i2cspi_write_register(int, bool, int, uint8_t, uint8_t); 47 1.1 brad 48 1.1 brad 49 1.1 brad /* The scmd(4) presents the register space as a linear chunk that can 50 1.1 brad * be seek to read and written to without any real messing around 51 1.1 brad */ 52 1.1 brad static int 53 1.1 brad i2cspi_phy_read_register(int fd, bool debug, uint8_t reg, int rlen, uint8_t *buf) 54 1.1 brad { 55 1.1 brad int err; 56 1.1 brad 57 1.1 brad if (rlen <= 0) 58 1.1 brad return EINVAL; 59 1.1 brad 60 1.1 brad err = lseek(fd, reg, SEEK_SET); 61 1.1 brad if (err != -1) { 62 1.1 brad err = read(fd, buf, rlen); 63 1.1 brad if (err == -1) 64 1.1 brad err = errno; 65 1.1 brad else 66 1.1 brad err = 0; 67 1.1 brad } else { 68 1.1 brad err = errno; 69 1.1 brad } 70 1.1 brad 71 1.1 brad if (debug) 72 1.1 brad fprintf(stderr,"i2cspi_phy_read_register: reg: 0x%02X: rlen: %d: return err: %d\n",reg, rlen, err); 73 1.1 brad 74 1.1 brad return err; 75 1.1 brad } 76 1.1 brad 77 1.1 brad static int 78 1.1 brad i2cspi_phy_write_register(int fd, bool debug, uint8_t reg, uint8_t buf) 79 1.1 brad { 80 1.1 brad int err; 81 1.1 brad 82 1.1 brad err = lseek(fd, reg, SEEK_SET); 83 1.1 brad if (err != -1) { 84 1.1 brad err = write(fd, &buf, 1); 85 1.1 brad if (err == -1) 86 1.1 brad err = errno; 87 1.1 brad else 88 1.1 brad err = 0; 89 1.1 brad } else { 90 1.1 brad err = errno; 91 1.1 brad } 92 1.1 brad 93 1.1 brad if (debug) 94 1.1 brad fprintf(stderr,"i2cspi_phy_write_register: reg: 0x%02X: return err: %d\n",reg, err); 95 1.1 brad 96 1.1 brad return err; 97 1.1 brad } 98 1.1 brad 99 1.1 brad int 100 1.1 brad i2cspi_clear(int fd, bool debug) 101 1.1 brad { 102 1.1 brad return 0; 103 1.1 brad } 104 1.1 brad 105 1.1 brad int 106 1.1 brad i2cspi_read_register(int fd, bool debug, int a_module, uint8_t reg, uint8_t reg_end, uint8_t *r) 107 1.1 brad { 108 1.1 brad if (reg > SCMD_LAST_REG || 109 1.1 brad reg_end > SCMD_LAST_REG) 110 1.1 brad return EINVAL; 111 1.1 brad 112 1.1 brad if (reg_end < reg) 113 1.1 brad return EINVAL; 114 1.1 brad 115 1.1 brad if (debug) 116 1.1 brad fprintf(stderr,"i2cspi_read_register: reg: %d ; reg_rend: %d ; rlen: %d\n",reg, reg_end, reg_end - reg + 1); 117 1.1 brad 118 1.1 brad return i2cspi_phy_read_register(fd, debug, reg + (SCMD_REG_SIZE * a_module), reg_end - reg + 1, r); 119 1.1 brad } 120 1.1 brad 121 1.1 brad int 122 1.1 brad i2cspi_write_register(int fd, bool debug, int a_module, uint8_t reg, uint8_t reg_v) 123 1.1 brad { 124 1.1 brad int err; 125 1.1 brad 126 1.1 brad if (reg > SCMD_LAST_REG) 127 1.1 brad return EINVAL; 128 1.1 brad 129 1.1 brad err = i2cspi_phy_write_register(fd, debug, reg + (SCMD_REG_SIZE * a_module), reg_v); 130 1.1 brad 131 1.1 brad return err; 132 1.1 brad } 133