]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/digsy_mtc/cmd_mtc.c
dc167719f48eb4d20d3d8d1a0c8b6357f00a010b
[karo-tx-uboot.git] / board / digsy_mtc / cmd_mtc.c
1 /*
2  * (C) Copyright 2009
3  * Werner Pfister <Pfister_Werner@intercontrol.de>
4  *
5  * (C) Copyright 2009 Semihalf, Grzegorz Bernacki
6  *
7  * See file CREDITS for list of people who contributed to this
8  * project.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23  * MA 02111-1307 USA
24  */
25
26 #include <common.h>
27 #include <command.h>
28 #include <mpc5xxx.h>
29 #include "spi.h"
30 #include "cmd_mtc.h"
31
32 DECLARE_GLOBAL_DATA_PTR;
33
34 static const char *led_names[] = {
35         "diag",
36         "can1",
37         "can2",
38         "can3",
39         "can4",
40         "usbpwr",
41         "usbbusy",
42         "user1",
43         "user2",
44         ""
45 };
46
47 static void mtc_calculate_checksum(tx_msp_cmd *packet)
48 {
49         int i;
50         uchar *buff;
51
52         buff = (uchar *) packet;
53
54         for (i = 0; i < 6; i++)
55                 packet->cks += buff[i];
56 }
57
58 static int do_mtc_led(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
59 {
60         tx_msp_cmd pcmd;
61         rx_msp_cmd prx;
62         int err = 0;
63         int i;
64
65         if (argc < 2) {
66                 cmd_usage(cmdtp);
67                 return -1;
68         }
69
70         memset(&pcmd, 0, sizeof(pcmd));
71         memset(&prx, 0, sizeof(prx));
72
73         pcmd.cmd = CMD_SET_LED;
74
75         pcmd.cmd_val0 = 0xff;
76         for (i = 0; strlen(led_names[i]) != 0; i++) {
77                 if (strncmp(argv[1], led_names[i], strlen(led_names[i])) == 0) {
78                         pcmd.cmd_val0 = i;
79                         break;
80                 }
81         }
82
83         if (pcmd.cmd_val0 == 0xff) {
84                 printf("Usage:\n%s\n", cmdtp->help);
85                 return -1;
86         }
87
88         if (argc >= 3) {
89                 if (strncmp(argv[2], "red", 3) == 0)
90                         pcmd.cmd_val1 = 1;
91                 else if (strncmp(argv[2], "green", 5) == 0)
92                         pcmd.cmd_val1 = 2;
93                 else if (strncmp(argv[2], "orange", 6) == 0)
94                         pcmd.cmd_val1 = 3;
95                 else
96                         pcmd.cmd_val1 = 0;
97         }
98
99         if (argc >= 4)
100                 pcmd.cmd_val2 = simple_strtol(argv[3], NULL, 10);
101         else
102                 pcmd.cmd_val2 = 0;
103
104         mtc_calculate_checksum(&pcmd);
105         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
106                        SPI_XFER_BEGIN | SPI_XFER_END);
107
108         return err;
109 }
110
111 static int do_mtc_key(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
112 {
113         tx_msp_cmd pcmd;
114         rx_msp_cmd prx;
115         int err = 0;
116
117         memset(&pcmd, 0, sizeof(pcmd));
118         memset(&prx, 0, sizeof(prx));
119
120         pcmd.cmd = CMD_GET_VIM;
121
122         mtc_calculate_checksum(&pcmd);
123         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
124                        SPI_XFER_BEGIN | SPI_XFER_END);
125
126         if (!err) {
127                 /* function returns '0' if key is pressed */
128                 err = (prx.input & 0x80) ? 0 : 1;
129         }
130
131         return err;
132 }
133
134 static int do_mtc_digout(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
135 {
136         tx_msp_cmd pcmd;
137         rx_msp_cmd prx;
138         int err = 0;
139         uchar channel_mask = 0;
140
141         if (argc < 3) {
142                 cmd_usage(cmdtp);
143                 return -1;
144         }
145
146         if (strncmp(argv[1], "on", 2) == 0)
147                 channel_mask |= 1;
148         if (strncmp(argv[2], "on", 2) == 0)
149                 channel_mask |= 2;
150
151         memset(&pcmd, 0, sizeof(pcmd));
152         memset(&prx, 0, sizeof(prx));
153
154         pcmd.cmd = CMD_GET_VIM;
155         pcmd.user_out = channel_mask;
156
157         mtc_calculate_checksum(&pcmd);
158         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
159                        SPI_XFER_BEGIN | SPI_XFER_END);
160
161         return err;
162 }
163
164 static int do_mtc_digin(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
165 {
166         tx_msp_cmd pcmd;
167         rx_msp_cmd prx;
168         int err = 0;
169         uchar channel_num = 0;
170
171         if (argc < 2) {
172                 cmd_usage(cmdtp);
173                 return -1;
174         }
175
176         channel_num = simple_strtol(argv[1], NULL, 10);
177         if ((channel_num != 1) && (channel_num != 2)) {
178                 printf("mtc digin: invalid parameter - must be '1' or '2'\n");
179                 return -1;
180         }
181
182         memset(&pcmd, 0, sizeof(pcmd));
183         memset(&prx, 0, sizeof(prx));
184
185         pcmd.cmd = CMD_GET_VIM;
186
187         mtc_calculate_checksum(&pcmd);
188         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
189                        SPI_XFER_BEGIN | SPI_XFER_END);
190
191         if (!err) {
192                 /* function returns '0' when digin is on */
193                 err = (prx.input & channel_num) ? 0 : 1;
194         }
195
196         return err;
197 }
198
199 static int do_mtc_appreg(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
200 {
201         tx_msp_cmd pcmd;
202         rx_msp_cmd prx;
203         int err;
204         char buf[5];
205
206         /* read appreg */
207         memset(&pcmd, 0, sizeof(pcmd));
208         memset(&prx, 0, sizeof(prx));
209
210         pcmd.cmd = CMD_WD_PARA;
211         pcmd.cmd_val0 = 5;      /* max. Count */
212         pcmd.cmd_val1 = 5;      /* max. Time */
213         pcmd.cmd_val2 = 0;      /* =0 means read appreg */
214
215         mtc_calculate_checksum(&pcmd);
216         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
217                        SPI_XFER_BEGIN | SPI_XFER_END);
218         if (!err) {
219                 sprintf(buf, "%d", prx.ack2);
220                 setenv("appreg", buf);
221         }
222
223         return err;
224 }
225
226 static int do_mtc_version(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
227 {
228         tx_msp_cmd pcmd;
229         rx_msp_cmd prx;
230         int err = 0;
231
232         memset(&pcmd, 0, sizeof(pcmd));
233         memset(&prx, 0, sizeof(prx));
234
235         pcmd.cmd = CMD_FW_VERSION;
236
237         mtc_calculate_checksum(&pcmd);
238         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
239                        SPI_XFER_BEGIN | SPI_XFER_END);
240
241         if (!err) {
242                 printf("FW V%d.%d.%d / HW %d\n",
243                        prx.ack0, prx.ack1, prx.ack3, prx.ack2);
244         }
245
246         return err;
247 }
248
249 static int do_mtc_state(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
250 {
251         tx_msp_cmd pcmd;
252         rx_msp_cmd prx;
253         int err = 0;
254
255         memset(&pcmd, 0, sizeof(pcmd));
256         memset(&prx, 0, sizeof(prx));
257
258         pcmd.cmd = CMD_WD_WDSTATE;
259         pcmd.cmd_val2 = 1;
260
261         mtc_calculate_checksum(&pcmd);
262         err = spi_xfer(NULL, MTC_TRANSFER_SIZE, &pcmd, &prx,
263                        SPI_XFER_BEGIN | SPI_XFER_END);
264
265         if (!err) {
266                 printf("State     %02Xh\n", prx.state);
267                 printf("Input     %02Xh\n", prx.input);
268                 printf("UserWD    %02Xh\n", prx.ack2);
269                 printf("Sys WD    %02Xh\n", prx.ack3);
270                 printf("WD Timout %02Xh\n", prx.ack0);
271                 printf("eSysState %02Xh\n", prx.ack1);
272         }
273
274         return err;
275 }
276
277 static int do_mtc_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
278
279 cmd_tbl_t cmd_mtc_sub[] = {
280         U_BOOT_CMD_MKENT(led, 3, 1, do_mtc_led,
281         "set state of leds",
282         "[ledname] [state] [blink]\n"
283         " - lednames: diag can1 can2 can3 can4 usbpwr usbbusy user1 user2\n"
284         " - state: off red green orange\n"
285         " - blink: blink interval in 100ms steps (1 - 10; 0 = static)\n"),
286         U_BOOT_CMD_MKENT(key, 0, 1, do_mtc_key,
287         "returns state of user key\n", ""),
288         U_BOOT_CMD_MKENT(version, 0, 1, do_mtc_version,
289         "returns firmware version of supervisor uC\n", ""),
290         U_BOOT_CMD_MKENT(appreg, 0, 1, do_mtc_appreg,
291         "reads appreg value and stores in environment variable 'appreg'\n", ""),
292         U_BOOT_CMD_MKENT(digin, 1, 1, do_mtc_digin,
293         "returns state of digital input",
294         "<channel_num> - get state of digital input (1 or 2)\n"),
295         U_BOOT_CMD_MKENT(digout, 2, 1, do_mtc_digout,
296         "sets digital outputs",
297         "<on|off> <on|off>- set state of digital output 1 and 2\n"),
298         U_BOOT_CMD_MKENT(state, 0, 1, do_mtc_state,
299         "displays state\n", ""),
300         U_BOOT_CMD_MKENT(help, 4, 1, do_mtc_help, "get help",
301         "[command] - get help for command\n"),
302 };
303
304 static int do_mtc_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
305 {
306         extern int _do_help(cmd_tbl_t *cmd_start, int cmd_items,
307                             cmd_tbl_t *cmdtp, int flag,
308                             int argc, char *argv[]);
309 #ifdef CONFIG_SYS_LONGHELP
310         puts("mtc ");
311 #endif
312         return _do_help(&cmd_mtc_sub[0],
313                         ARRAY_SIZE(cmd_mtc_sub), cmdtp, flag, argc, argv);
314 }
315
316 /* Relocate the command table function pointers when running in RAM */
317 int mtc_cmd_init_r(void)
318 {
319         cmd_tbl_t *cmdtp;
320
321         for (cmdtp = &cmd_mtc_sub[0]; cmdtp !=
322              &cmd_mtc_sub[ARRAY_SIZE(cmd_mtc_sub)]; cmdtp++) {
323                 ulong addr;
324
325                 addr = (ulong)(cmdtp->cmd) + gd->reloc_off;
326                 cmdtp->cmd =
327                     (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
328
329                 addr = (ulong)(cmdtp->name) + gd->reloc_off;
330                 cmdtp->name = (char *)addr;
331
332                 if (cmdtp->usage) {
333                         addr = (ulong)(cmdtp->usage) + gd->reloc_off;
334                         cmdtp->usage = (char *)addr;
335                 }
336 #ifdef CONFIG_SYS_LONGHELP
337                 if (cmdtp->help) {
338                         addr = (ulong)(cmdtp->help) + gd->reloc_off;
339                         cmdtp->help = (char *)addr;
340                 }
341 #endif
342         }
343         return 0;
344 }
345
346 int cmd_mtc(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
347 {
348         cmd_tbl_t *c;
349         int err = 0;
350
351         c = find_cmd_tbl(argv[1], &cmd_mtc_sub[0], ARRAY_SIZE(cmd_mtc_sub));
352         if (c) {
353                 argc--;
354                 argv++;
355                 return c->cmd(c, flag, argc, argv);
356         } else {
357                 /* Unrecognized command */
358                 cmd_usage(cmdtp);
359                 return 1;
360         }
361
362         return err;
363 }
364
365 U_BOOT_CMD(mtc, 5, 1, cmd_mtc,
366         "mtc     - special commands for digsyMTC\n",
367         "[subcommand] [args...]\n"
368         "Subcommands list:\n"
369         "led [ledname] [state] [blink] - set state of leds\n"
370         "  [ledname]: diag can1 can2 can3 can4 usbpwr usbbusy user1 user2\n"
371         "  [state]: off red green orange\n"
372         "  [blink]: blink interval in 100ms steps (1 - 10; 0 = static)\n"
373         "key - returns state of user key\n"
374         "version - returns firmware version of supervisor uC\n"
375         "appreg - reads appreg value and stores in environment variable"
376         " 'appreg'\n"
377         "digin [channel] - returns state of digital input (1 or 2)\n"
378         "digout <on|off> <on|off> - sets state of two digital outputs\n"
379         "help [subcommand] - get help for subcommand\n"
380 );