Home | History | Annotate | Line # | Download | only in umcpmioctl
      1  1.3  rillig /*	$NetBSD: putflash.c,v 1.3 2025/03/22 06:09:48 rillig Exp $	*/
      2  1.1    brad 
      3  1.1    brad /*
      4  1.1    brad  * Copyright (c) 2024 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.3  rillig #include <sys/cdefs.h>
     20  1.1    brad #ifdef __RCSID
     21  1.3  rillig __RCSID("$NetBSD: putflash.c,v 1.3 2025/03/22 06:09:48 rillig Exp $");
     22  1.1    brad #endif
     23  1.1    brad 
     24  1.1    brad /* Functions to parse stuff */
     25  1.1    brad 
     26  1.1    brad #include <stdio.h>
     27  1.1    brad #include <errno.h>
     28  1.1    brad #include <string.h>
     29  1.1    brad #include <stdbool.h>
     30  1.1    brad 
     31  1.1    brad #include <dev/usb/umcpmio_hid_reports.h>
     32  1.1    brad #include <dev/usb/umcpmio_io.h>
     33  1.1    brad #include <sys/ioctl.h>
     34  1.1    brad 
     35  1.1    brad #undef EXTERN
     36  1.1    brad #define EXTERN
     37  1.1    brad #include "putflash.h"
     38  1.1    brad 
     39  1.1    brad 
     40  1.1    brad int
     41  1.1    brad parse_flash_gp_req(int fd, struct mcp2221_put_flash_req *req, char *argv[], int start, int end, bool debug)
     42  1.1    brad {
     43  1.1    brad 	int error = 0;
     44  1.1    brad 	struct umcpmio_ioctl_get_flash current_flash;
     45  1.1    brad 	int arggood = false;
     46  1.1    brad 
     47  1.1    brad 	current_flash.subcode = MCP2221_FLASH_SUBCODE_GP;
     48  1.1    brad 	error = ioctl(fd, UMCPMIO_GET_FLASH, &current_flash);
     49  1.1    brad 
     50  1.1    brad 	if (debug)
     51  1.2  rillig 		fprintf(stderr, "CURRENT FLASH: error=%d\n", error);
     52  1.1    brad 
     53  1.1    brad 	if (!error) {
     54  1.1    brad 		int argcount = start;
     55  1.1    brad 		uint8_t *gp;
     56  1.1    brad 
     57  1.1    brad 		uint8_t *bbuf = (uint8_t *)&current_flash.get_flash_res;
     58  1.1    brad 		if (debug) {
     59  1.2  rillig 			fprintf(stderr, "CURRENT REQ:\n");
     60  1.2  rillig 			for (int i = 0; i < MCP2221_RES_BUFFER_SIZE; i++) {
     61  1.2  rillig 				fprintf(stderr, "%02x ", bbuf[i]);
     62  1.1    brad 			}
     63  1.2  rillig 			fprintf(stderr, "\n");
     64  1.1    brad 		}
     65  1.1    brad 
     66  1.2  rillig 		/*
     67  1.2  rillig 		 * When flash is put, you put ALL of a particular subcode, so
     68  1.2  rillig 		 * you have to do a get + put
     69  1.2  rillig 		 */
     70  1.1    brad 
     71  1.1    brad 		req->u.gp.gp0_settings = current_flash.get_flash_res.u.gp.gp0_settings;
     72  1.1    brad 		req->u.gp.gp1_settings = current_flash.get_flash_res.u.gp.gp1_settings;
     73  1.1    brad 		req->u.gp.gp2_settings = current_flash.get_flash_res.u.gp.gp2_settings;
     74  1.1    brad 		req->u.gp.gp3_settings = current_flash.get_flash_res.u.gp.gp3_settings;
     75  1.1    brad 
     76  1.1    brad 		if (debug)
     77  1.2  rillig 			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);
     78  1.1    brad 
     79  1.1    brad 		while (argcount < end) {
     80  1.1    brad 			gp = NULL;
     81  1.2  rillig 			if (strncmp(argv[argcount], "GP0", 4) == 0) {
     82  1.1    brad 				gp = (uint8_t *)&req->u.gp.gp0_settings;
     83  1.1    brad 			}
     84  1.2  rillig 			if (strncmp(argv[argcount], "GP1", 4) == 0) {
     85  1.1    brad 				gp = (uint8_t *)&req->u.gp.gp1_settings;
     86  1.1    brad 			}
     87  1.2  rillig 			if (strncmp(argv[argcount], "GP2", 4) == 0) {
     88  1.1    brad 				gp = (uint8_t *)&req->u.gp.gp2_settings;
     89  1.1    brad 			}
     90  1.2  rillig 			if (strncmp(argv[argcount], "GP3", 4) == 0) {
     91  1.1    brad 				gp = (uint8_t *)&req->u.gp.gp3_settings;
     92  1.1    brad 			}
     93  1.1    brad 			if (gp == NULL) {
     94  1.1    brad 				if (debug)
     95  1.2  rillig 					fprintf(stderr, "NOT GPn: %d %s\n", argcount, argv[argcount]);
     96  1.1    brad 				error = EINVAL;
     97  1.1    brad 				break;
     98  1.1    brad 			}
     99  1.1    brad 			argcount++;
    100  1.1    brad 			if (argcount < end) {
    101  1.1    brad 				arggood = false;
    102  1.2  rillig 				if (strncmp(argv[argcount], "GPIO_PIN_INPUT", 15) == 0) {
    103  1.1    brad 					*gp &= MCP2221_FLASH_GPIO_VALUE_MASK;
    104  1.1    brad 					*gp |= MCP2221_FLASH_GPIO_INPUT;
    105  1.1    brad 					arggood = true;
    106  1.1    brad 				}
    107  1.2  rillig 				if (strncmp(argv[argcount], "GPIO_PIN_OUTPUT", 16) == 0) {
    108  1.1    brad 					*gp &= MCP2221_FLASH_GPIO_VALUE_MASK;
    109  1.1    brad 					arggood = true;
    110  1.1    brad 				}
    111  1.2  rillig 				if (strncmp(argv[argcount], "GPIO_PIN_ALT0", 14) == 0) {
    112  1.1    brad 					*gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT);
    113  1.1    brad 					*gp &= ~MCP2221_FLASH_PIN_TYPE_MASK;
    114  1.1    brad 					*gp |= MCP2221_FLASH_PIN_IS_ALT0;
    115  1.1    brad 					arggood = true;
    116  1.1    brad 				}
    117  1.2  rillig 				if (strncmp(argv[argcount], "GPIO_PIN_ALT1", 14) == 0) {
    118  1.1    brad 					*gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT);
    119  1.1    brad 					*gp &= ~MCP2221_FLASH_PIN_TYPE_MASK;
    120  1.1    brad 					*gp |= MCP2221_FLASH_PIN_IS_ALT1;
    121  1.1    brad 					arggood = true;
    122  1.1    brad 				}
    123  1.2  rillig 				if (strncmp(argv[argcount], "GPIO_PIN_ALT2", 14) == 0) {
    124  1.1    brad 					*gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT);
    125  1.1    brad 					*gp &= ~MCP2221_FLASH_PIN_TYPE_MASK;
    126  1.1    brad 					*gp |= MCP2221_FLASH_PIN_IS_ALT2;
    127  1.1    brad 					arggood = true;
    128  1.1    brad 				}
    129  1.2  rillig 				if (strncmp(argv[argcount], "GPIO_PIN_ALT3", 14) == 0) {
    130  1.1    brad 					*gp &= (MCP2221_FLASH_GPIO_VALUE_MASK | MCP2221_FLASH_GPIO_INPUT);
    131  1.1    brad 					*gp &= ~MCP2221_FLASH_PIN_TYPE_MASK;
    132  1.1    brad 					*gp |= MCP2221_FLASH_PIN_IS_DED;
    133  1.1    brad 					arggood = true;
    134  1.1    brad 				}
    135  1.2  rillig 				if (strncmp(argv[argcount], "DEFAULT_OUTPUT_ZERO", 20) == 0) {
    136  1.1    brad 					*gp &= ~MCP2221_FLASH_GPIO_VALUE_MASK;
    137  1.1    brad 					arggood = true;
    138  1.1    brad 				}
    139  1.2  rillig 				if (strncmp(argv[argcount], "DEFAULT_OUTPUT_ONE", 19) == 0) {
    140  1.1    brad 					*gp |= MCP2221_FLASH_GPIO_VALUE_MASK;
    141  1.1    brad 					arggood = true;
    142  1.1    brad 				}
    143  1.1    brad 				if (!arggood) {
    144  1.1    brad 					if (debug)
    145  1.2  rillig 						fprintf(stderr, "BAD ARGUMENT: %d %s\n", argcount, argv[argcount]);
    146  1.1    brad 					error = EINVAL;
    147  1.1    brad 					break;
    148  1.1    brad 				}
    149  1.1    brad 			} else {
    150  1.1    brad 				error = EINVAL;
    151  1.1    brad 			}
    152  1.1    brad 
    153  1.1    brad 			argcount++;
    154  1.1    brad 		}
    155  1.1    brad 	}
    156  1.1    brad 
    157  1.2  rillig 	return (error);
    158  1.1    brad }
    159