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