]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/digsy_mtc/cmd_mtc.c
9e377cd30d27627a871b3c721aa5afcb81454edb
[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_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);
250
251 cmd_tbl_t cmd_mtc_sub[] = {
252         U_BOOT_CMD_MKENT(led, 3, 1, do_mtc_led,
253         "set state of leds",
254         "[ledname] [state] [blink]\n"
255         " - lednames: diag can1 can2 can3 can4 usbpwr usbbusy user1 user2\n"
256         " - state: off red green orange\n"
257         " - blink: blink interval in 100ms steps (1 - 10; 0 = static)\n"),
258         U_BOOT_CMD_MKENT(key, 0, 1, do_mtc_key,
259         "returns state of user key\n", ""),
260         U_BOOT_CMD_MKENT(version, 0, 1, do_mtc_version,
261         "returns firmware version of supervisor uC\n", ""),
262         U_BOOT_CMD_MKENT(appreg, 0, 1, do_mtc_appreg,
263         "reads appreg value and stores in environment variable 'appreg'\n", ""),
264         U_BOOT_CMD_MKENT(digin, 1, 1, do_mtc_digin,
265         "returns state of digital input",
266         "<channel_num> - get state of digital input (1 or 2)\n"),
267         U_BOOT_CMD_MKENT(digout, 2, 1, do_mtc_digout,
268         "sets digital outputs",
269         "<on|off> <on|off>- set state of digital output 1 and 2\n"),
270         U_BOOT_CMD_MKENT(help, 4, 1, do_mtc_help, "get help",
271         "[command] - get help for command\n"),
272 };
273
274 static int do_mtc_help(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
275 {
276         extern int _do_help(cmd_tbl_t *cmd_start, int cmd_items,
277                             cmd_tbl_t *cmdtp, int flag,
278                             int argc, char *argv[]);
279 #ifdef CONFIG_SYS_LONGHELP
280         puts("mtc ");
281 #endif
282         return _do_help(&cmd_mtc_sub[0],
283                         ARRAY_SIZE(cmd_mtc_sub), cmdtp, flag, argc, argv);
284 }
285
286 /* Relocate the command table function pointers when running in RAM */
287 int mtc_cmd_init_r(void)
288 {
289         cmd_tbl_t *cmdtp;
290
291         for (cmdtp = &cmd_mtc_sub[0]; cmdtp !=
292              &cmd_mtc_sub[ARRAY_SIZE(cmd_mtc_sub)]; cmdtp++) {
293                 ulong addr;
294
295                 addr = (ulong)(cmdtp->cmd) + gd->reloc_off;
296                 cmdtp->cmd =
297                     (int (*)(struct cmd_tbl_s *, int, int, char *[]))addr;
298
299                 addr = (ulong)(cmdtp->name) + gd->reloc_off;
300                 cmdtp->name = (char *)addr;
301
302                 if (cmdtp->usage) {
303                         addr = (ulong)(cmdtp->usage) + gd->reloc_off;
304                         cmdtp->usage = (char *)addr;
305                 }
306 #ifdef CONFIG_SYS_LONGHELP
307                 if (cmdtp->help) {
308                         addr = (ulong)(cmdtp->help) + gd->reloc_off;
309                         cmdtp->help = (char *)addr;
310                 }
311 #endif
312         }
313         return 0;
314 }
315
316 int cmd_mtc(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
317 {
318         cmd_tbl_t *c;
319         int err = 0;
320
321         c = find_cmd_tbl(argv[1], &cmd_mtc_sub[0], ARRAY_SIZE(cmd_mtc_sub));
322         if (c) {
323                 argc--;
324                 argv++;
325                 return c->cmd(c, flag, argc, argv);
326         } else {
327                 /* Unrecognized command */
328                 cmd_usage(cmdtp);
329                 return 1;
330         }
331
332         return err;
333 }
334
335 U_BOOT_CMD(mtc, 5, 1, cmd_mtc,
336            "mtc     - special commands for digsyMTC\n",
337            "[subcommand] [args...]\n"
338            "Subcommands list:\n"
339            "led [ledname] [state] [blink] - set state of leds\n"
340            "  [ledname]: diag can1 can2 can3 can4 usbpwr usbbusy user1 user2\n"
341            "  [state]: off red green orange\n"
342            "  [blink]: blink interval in 100ms steps (1 - 10; 0 = static)\n"
343            "key - returns state of user key\n"
344            "version - returns firmware version of supervisor uC\n"
345            "appreg - reads appreg value and stores in environment variable"
346            " 'appreg'\n"
347            "digin [channel] - returns state of digital input (1 or 2)\n"
348            "digout <on|off> <on|off> - sets state of two digital outputs\n"
349            "help [subcommand] - get help for subcommand\n");
350