putflash.c revision 1.3 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, ¤t_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 *)¤t_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