1 /* $NetBSD: putflash.c,v 1.1 2024/12/16 16:37:40 brad Exp $ */ 2 3 /* 4 * Copyright (c) 2024 Brad Spencer <brad@anduin.eldar.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #ifdef __RCSID 20 __RCSID("$NetBSD: putflash.c,v 1.1 2024/12/16 16:37:40 brad Exp $"); 21 #endif 22 23 /* Functions to parse stuff */ 24 25 #include <stdio.h> 26 #include <errno.h> 27 #include <string.h> 28 #include <stdbool.h> 29 30 #include <dev/usb/umcpmio_hid_reports.h> 31 #include <dev/usb/umcpmio_io.h> 32 #include <sys/ioctl.h> 33 34 #undef EXTERN 35 #define EXTERN 36 #include "putflash.h" 37 38 39 int 40 parse_flash_gp_req(int fd, struct mcp2221_put_flash_req *req, char *argv[], int start, int end, bool debug) 41 { 42 int error = 0; 43 struct umcpmio_ioctl_get_flash current_flash; 44 int arggood = false; 45 46 current_flash.subcode = MCP2221_FLASH_SUBCODE_GP; 47 error = ioctl(fd, UMCPMIO_GET_FLASH, ¤t_flash); 48 49 if (debug) 50 fprintf(stderr,"CURRENT FLASH: error=%d\n",error); 51 52 if (!error) { 53 int argcount = start; 54 uint8_t *gp; 55 56 uint8_t *bbuf = (uint8_t *)¤t_flash.get_flash_res; 57 if (debug) { 58 fprintf(stderr,"CURRENT REQ:\n"); 59 for(int i=0;i < MCP2221_RES_BUFFER_SIZE;i++) { 60 fprintf(stderr,"%02x ",bbuf[i]); 61 } 62 fprintf(stderr,"\n"); 63 } 64 65 /* When flash is put, you put ALL of a particular subcode, so 66 * you have to do a get + put */ 67 68 req->u.gp.gp0_settings = current_flash.get_flash_res.u.gp.gp0_settings; 69 req->u.gp.gp1_settings = current_flash.get_flash_res.u.gp.gp1_settings; 70 req->u.gp.gp2_settings = current_flash.get_flash_res.u.gp.gp2_settings; 71 req->u.gp.gp3_settings = current_flash.get_flash_res.u.gp.gp3_settings; 72 73 if (debug) 74 fprintf(stderr,"CURRENT FLASH: %02x %02x %02x %02x\n", current_flash.get_flash_res.u.gp.gp0_settings, current_flash.get_flash_res.u.gp.gp1_settings, current_flash.get_flash_res.u.gp.gp2_settings, current_flash.get_flash_res.u.gp.gp3_settings); 75 76 while (argcount < end) { 77 gp = NULL; 78 if (strncmp(argv[argcount],"GP0",4) == 0) { 79 gp = (uint8_t *)&req->u.gp.gp0_settings; 80 } 81 if (strncmp(argv[argcount],"GP1",4) == 0) { 82 gp = (uint8_t *)&req->u.gp.gp1_settings; 83 } 84 if (strncmp(argv[argcount],"GP2",4) == 0) { 85 gp = (uint8_t *)&req->u.gp.gp2_settings; 86 } 87 if (strncmp(argv[argcount],"GP3",4) == 0) { 88 gp = (uint8_t *)&req->u.gp.gp3_settings; 89 } 90 if (gp == NULL) { 91 if (debug) 92 fprintf(stderr,"NOT GPn: %d %s\n",argcount,argv[argcount]); 93 error = EINVAL; 94 break; 95 } 96 argcount++; 97 if (argcount < end) { 98 arggood = false; 99 if (strncmp(argv[argcount],"GPIO_PIN_INPUT",15) == 0) { 100 *gp &= MCP2221_FLASH_GPIO_VALUE_MASK; 101 *gp |= MCP2221_FLASH_GPIO_INPUT; 102 arggood = true; 103 } 104 if (strncmp(argv[argcount],"GPIO_PIN_OUTPUT",16) == 0) { 105 *gp &= MCP2221_FLASH_GPIO_VALUE_MASK; 106 arggood = true; 107 } 108 if (strncmp(argv[argcount],"GPIO_PIN_ALT0",14) == 0) { 109 *gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT); 110 *gp &= ~MCP2221_FLASH_PIN_TYPE_MASK; 111 *gp |= MCP2221_FLASH_PIN_IS_ALT0; 112 arggood = true; 113 } 114 if (strncmp(argv[argcount],"GPIO_PIN_ALT1",14) == 0) { 115 *gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT); 116 *gp &= ~MCP2221_FLASH_PIN_TYPE_MASK; 117 *gp |= MCP2221_FLASH_PIN_IS_ALT1; 118 arggood = true; 119 } 120 if (strncmp(argv[argcount],"GPIO_PIN_ALT2",14) == 0) { 121 *gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT); 122 *gp &= ~MCP2221_FLASH_PIN_TYPE_MASK; 123 *gp |= MCP2221_FLASH_PIN_IS_ALT2; 124 arggood = true; 125 } 126 if (strncmp(argv[argcount],"GPIO_PIN_ALT3",14) == 0) { 127 *gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT); 128 *gp &= ~MCP2221_FLASH_PIN_TYPE_MASK; 129 *gp |= MCP2221_FLASH_PIN_IS_DED; 130 arggood = true; 131 } 132 if (strncmp(argv[argcount],"DEFAULT_OUTPUT_ZERO",20) == 0) { 133 *gp &= ~MCP2221_FLASH_GPIO_VALUE_MASK; 134 arggood = true; 135 } 136 if (strncmp(argv[argcount],"DEFAULT_OUTPUT_ONE",19) == 0) { 137 *gp |= MCP2221_FLASH_GPIO_VALUE_MASK; 138 arggood = true; 139 } 140 if (!arggood) { 141 if (debug) 142 fprintf(stderr,"BAD ARGUMENT: %d %s\n",argcount,argv[argcount]); 143 error = EINVAL; 144 break; 145 } 146 } else { 147 error = EINVAL; 148 } 149 150 argcount++; 151 } 152 } 153 154 return(error); 155 } 156