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