xref: /rk3399_rockchip-uboot/drivers/dfu/dfu_mmc.c (revision cb383cd21d5d6aa6de5cfc59f14e8e3a56e2931f)
1*cb383cd2SLukasz Majewski /*
2*cb383cd2SLukasz Majewski  * dfu.c -- DFU back-end routines
3*cb383cd2SLukasz Majewski  *
4*cb383cd2SLukasz Majewski  * Copyright (C) 2012 Samsung Electronics
5*cb383cd2SLukasz Majewski  * author: Lukasz Majewski <l.majewski@samsung.com>
6*cb383cd2SLukasz Majewski  *
7*cb383cd2SLukasz Majewski  * This program is free software; you can redistribute it and/or modify
8*cb383cd2SLukasz Majewski  * it under the terms of the GNU General Public License as published by
9*cb383cd2SLukasz Majewski  * the Free Software Foundation; either version 2 of the License, or
10*cb383cd2SLukasz Majewski  * (at your option) any later version.
11*cb383cd2SLukasz Majewski  *
12*cb383cd2SLukasz Majewski  * This program is distributed in the hope that it will be useful,
13*cb383cd2SLukasz Majewski  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*cb383cd2SLukasz Majewski  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15*cb383cd2SLukasz Majewski  * GNU General Public License for more details.
16*cb383cd2SLukasz Majewski  *
17*cb383cd2SLukasz Majewski  * You should have received a copy of the GNU General Public License
18*cb383cd2SLukasz Majewski  * along with this program; if not, write to the Free Software
19*cb383cd2SLukasz Majewski  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20*cb383cd2SLukasz Majewski  */
21*cb383cd2SLukasz Majewski 
22*cb383cd2SLukasz Majewski #include <common.h>
23*cb383cd2SLukasz Majewski #include <malloc.h>
24*cb383cd2SLukasz Majewski #include <dfu.h>
25*cb383cd2SLukasz Majewski 
26*cb383cd2SLukasz Majewski enum dfu_mmc_op {
27*cb383cd2SLukasz Majewski 	DFU_OP_READ = 1,
28*cb383cd2SLukasz Majewski 	DFU_OP_WRITE,
29*cb383cd2SLukasz Majewski };
30*cb383cd2SLukasz Majewski 
31*cb383cd2SLukasz Majewski static int mmc_block_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
32*cb383cd2SLukasz Majewski 			void *buf, long *len)
33*cb383cd2SLukasz Majewski {
34*cb383cd2SLukasz Majewski 	char cmd_buf[DFU_CMD_BUF_SIZE];
35*cb383cd2SLukasz Majewski 
36*cb383cd2SLukasz Majewski 	sprintf(cmd_buf, "mmc %s 0x%x %x %x",
37*cb383cd2SLukasz Majewski 		op == DFU_OP_READ ? "read" : "write",
38*cb383cd2SLukasz Majewski 		(unsigned int) buf,
39*cb383cd2SLukasz Majewski 		dfu->data.mmc.lba_start,
40*cb383cd2SLukasz Majewski 		dfu->data.mmc.lba_size);
41*cb383cd2SLukasz Majewski 
42*cb383cd2SLukasz Majewski 	if (op == DFU_OP_READ)
43*cb383cd2SLukasz Majewski 		*len = dfu->data.mmc.lba_blk_size * dfu->data.mmc.lba_size;
44*cb383cd2SLukasz Majewski 
45*cb383cd2SLukasz Majewski 	debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf);
46*cb383cd2SLukasz Majewski 	return run_command(cmd_buf, 0);
47*cb383cd2SLukasz Majewski }
48*cb383cd2SLukasz Majewski 
49*cb383cd2SLukasz Majewski static inline int mmc_block_write(struct dfu_entity *dfu, void *buf, long *len)
50*cb383cd2SLukasz Majewski {
51*cb383cd2SLukasz Majewski 	return mmc_block_op(DFU_OP_WRITE, dfu, buf, len);
52*cb383cd2SLukasz Majewski }
53*cb383cd2SLukasz Majewski 
54*cb383cd2SLukasz Majewski static inline int mmc_block_read(struct dfu_entity *dfu, void *buf, long *len)
55*cb383cd2SLukasz Majewski {
56*cb383cd2SLukasz Majewski 	return mmc_block_op(DFU_OP_READ, dfu, buf, len);
57*cb383cd2SLukasz Majewski }
58*cb383cd2SLukasz Majewski 
59*cb383cd2SLukasz Majewski static int mmc_file_op(enum dfu_mmc_op op, struct dfu_entity *dfu,
60*cb383cd2SLukasz Majewski 			void *buf, long *len)
61*cb383cd2SLukasz Majewski {
62*cb383cd2SLukasz Majewski 	char cmd_buf[DFU_CMD_BUF_SIZE];
63*cb383cd2SLukasz Majewski 	char *str_env;
64*cb383cd2SLukasz Majewski 	int ret;
65*cb383cd2SLukasz Majewski 
66*cb383cd2SLukasz Majewski 	sprintf(cmd_buf, "fat%s mmc %d:%d 0x%x %s %lx",
67*cb383cd2SLukasz Majewski 		op == DFU_OP_READ ? "load" : "write",
68*cb383cd2SLukasz Majewski 		dfu->data.mmc.dev, dfu->data.mmc.part,
69*cb383cd2SLukasz Majewski 		(unsigned int) buf, dfu->name, *len);
70*cb383cd2SLukasz Majewski 
71*cb383cd2SLukasz Majewski 	debug("%s: %s 0x%p\n", __func__, cmd_buf, cmd_buf);
72*cb383cd2SLukasz Majewski 
73*cb383cd2SLukasz Majewski 	ret = run_command(cmd_buf, 0);
74*cb383cd2SLukasz Majewski 	if (ret) {
75*cb383cd2SLukasz Majewski 		puts("dfu: Read error!\n");
76*cb383cd2SLukasz Majewski 		return ret;
77*cb383cd2SLukasz Majewski 	}
78*cb383cd2SLukasz Majewski 
79*cb383cd2SLukasz Majewski 	if (dfu->layout != DFU_RAW_ADDR) {
80*cb383cd2SLukasz Majewski 		str_env = getenv("filesize");
81*cb383cd2SLukasz Majewski 		if (str_env == NULL) {
82*cb383cd2SLukasz Majewski 			puts("dfu: Wrong file size!\n");
83*cb383cd2SLukasz Majewski 			return -1;
84*cb383cd2SLukasz Majewski 		}
85*cb383cd2SLukasz Majewski 		*len = simple_strtoul(str_env, NULL, 16);
86*cb383cd2SLukasz Majewski 	}
87*cb383cd2SLukasz Majewski 
88*cb383cd2SLukasz Majewski 	return ret;
89*cb383cd2SLukasz Majewski }
90*cb383cd2SLukasz Majewski 
91*cb383cd2SLukasz Majewski static inline int mmc_file_write(struct dfu_entity *dfu, void *buf, long *len)
92*cb383cd2SLukasz Majewski {
93*cb383cd2SLukasz Majewski 	return mmc_file_op(DFU_OP_WRITE, dfu, buf, len);
94*cb383cd2SLukasz Majewski }
95*cb383cd2SLukasz Majewski 
96*cb383cd2SLukasz Majewski static inline int mmc_file_read(struct dfu_entity *dfu, void *buf, long *len)
97*cb383cd2SLukasz Majewski {
98*cb383cd2SLukasz Majewski 	return mmc_file_op(DFU_OP_READ, dfu, buf, len);
99*cb383cd2SLukasz Majewski }
100*cb383cd2SLukasz Majewski 
101*cb383cd2SLukasz Majewski int dfu_write_medium_mmc(struct dfu_entity *dfu, void *buf, long *len)
102*cb383cd2SLukasz Majewski {
103*cb383cd2SLukasz Majewski 	int ret = -1;
104*cb383cd2SLukasz Majewski 
105*cb383cd2SLukasz Majewski 	switch (dfu->layout) {
106*cb383cd2SLukasz Majewski 	case DFU_RAW_ADDR:
107*cb383cd2SLukasz Majewski 		ret = mmc_block_write(dfu, buf, len);
108*cb383cd2SLukasz Majewski 		break;
109*cb383cd2SLukasz Majewski 	case DFU_FS_FAT:
110*cb383cd2SLukasz Majewski 		ret = mmc_file_write(dfu, buf, len);
111*cb383cd2SLukasz Majewski 		break;
112*cb383cd2SLukasz Majewski 	default:
113*cb383cd2SLukasz Majewski 		printf("%s: Layout (%s) not (yet) supported!\n", __func__,
114*cb383cd2SLukasz Majewski 		       dfu_get_layout(dfu->layout));
115*cb383cd2SLukasz Majewski 	}
116*cb383cd2SLukasz Majewski 
117*cb383cd2SLukasz Majewski 	return ret;
118*cb383cd2SLukasz Majewski }
119*cb383cd2SLukasz Majewski 
120*cb383cd2SLukasz Majewski int dfu_read_medium_mmc(struct dfu_entity *dfu, void *buf, long *len)
121*cb383cd2SLukasz Majewski {
122*cb383cd2SLukasz Majewski 	int ret = -1;
123*cb383cd2SLukasz Majewski 
124*cb383cd2SLukasz Majewski 	switch (dfu->layout) {
125*cb383cd2SLukasz Majewski 	case DFU_RAW_ADDR:
126*cb383cd2SLukasz Majewski 		ret = mmc_block_read(dfu, buf, len);
127*cb383cd2SLukasz Majewski 		break;
128*cb383cd2SLukasz Majewski 	case DFU_FS_FAT:
129*cb383cd2SLukasz Majewski 		ret = mmc_file_read(dfu, buf, len);
130*cb383cd2SLukasz Majewski 		break;
131*cb383cd2SLukasz Majewski 	default:
132*cb383cd2SLukasz Majewski 		printf("%s: Layout (%s) not (yet) supported!\n", __func__,
133*cb383cd2SLukasz Majewski 		       dfu_get_layout(dfu->layout));
134*cb383cd2SLukasz Majewski 	}
135*cb383cd2SLukasz Majewski 
136*cb383cd2SLukasz Majewski 	return ret;
137*cb383cd2SLukasz Majewski }
138*cb383cd2SLukasz Majewski 
139*cb383cd2SLukasz Majewski int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
140*cb383cd2SLukasz Majewski {
141*cb383cd2SLukasz Majewski 	char *st;
142*cb383cd2SLukasz Majewski 
143*cb383cd2SLukasz Majewski 	dfu->dev_type = DFU_DEV_MMC;
144*cb383cd2SLukasz Majewski 	st = strsep(&s, " ");
145*cb383cd2SLukasz Majewski 	if (!strcmp(st, "mmc")) {
146*cb383cd2SLukasz Majewski 		dfu->layout = DFU_RAW_ADDR;
147*cb383cd2SLukasz Majewski 		dfu->data.mmc.lba_start = simple_strtoul(s, &s, 16);
148*cb383cd2SLukasz Majewski 		dfu->data.mmc.lba_size = simple_strtoul(++s, &s, 16);
149*cb383cd2SLukasz Majewski 		dfu->data.mmc.lba_blk_size = get_mmc_blk_size(dfu->dev_num);
150*cb383cd2SLukasz Majewski 	} else if (!strcmp(st, "fat")) {
151*cb383cd2SLukasz Majewski 		dfu->layout = DFU_FS_FAT;
152*cb383cd2SLukasz Majewski 		dfu->data.mmc.dev = simple_strtoul(s, &s, 10);
153*cb383cd2SLukasz Majewski 		dfu->data.mmc.part = simple_strtoul(++s, &s, 10);
154*cb383cd2SLukasz Majewski 	} else {
155*cb383cd2SLukasz Majewski 		printf("%s: Memory layout (%s) not supported!\n", __func__, st);
156*cb383cd2SLukasz Majewski 	}
157*cb383cd2SLukasz Majewski 
158*cb383cd2SLukasz Majewski 	dfu->read_medium = dfu_read_medium_mmc;
159*cb383cd2SLukasz Majewski 	dfu->write_medium = dfu_write_medium_mmc;
160*cb383cd2SLukasz Majewski 
161*cb383cd2SLukasz Majewski 	return 0;
162*cb383cd2SLukasz Majewski }
163