xref: /netbsd-src/usr.sbin/umcpmioctl/putflash.c (revision 3bfaa97146632a7fff2425e11c47d4964bacef79)
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, &current_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 *)&current_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