• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <errno.h>
9 #include <string.h>
10 
11 #include <common/debug.h>
12 #include <drivers/io/io_driver.h>
13 #include <drivers/io/io_storage.h>
14 #include <drivers/mmc.h>
15 #include <drivers/st/io_mmc.h>
16 #include <drivers/st/stm32_sdmmc2.h>
17 
18 /* SDMMC device functions */
19 static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info);
20 static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
21 			  io_entity_t *entity);
22 static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
23 static int mmc_block_seek(io_entity_t *entity, int mode,
24 			  signed long long offset);
25 static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
26 			  size_t *length_read);
27 static int mmc_block_close(io_entity_t *entity);
28 static int mmc_dev_close(io_dev_info_t *dev_info);
29 static io_type_t device_type_mmc(void);
30 
31 static signed long long seek_offset;
32 
33 static const io_dev_connector_t mmc_dev_connector = {
34 	.dev_open = mmc_dev_open
35 };
36 
37 static const io_dev_funcs_t mmc_dev_funcs = {
38 	.type = device_type_mmc,
39 	.open = mmc_block_open,
40 	.seek = mmc_block_seek,
41 	.size = NULL,
42 	.read = mmc_block_read,
43 	.write = NULL,
44 	.close = mmc_block_close,
45 	.dev_init = mmc_dev_init,
46 	.dev_close = mmc_dev_close,
47 };
48 
49 static const io_dev_info_t mmc_dev_info = {
50 	.funcs = &mmc_dev_funcs,
51 	.info = 0,
52 };
53 
54 /* Identify the device type as mmc device */
device_type_mmc(void)55 static io_type_t device_type_mmc(void)
56 {
57 	return IO_TYPE_MMC;
58 }
59 
60 /* Open a connection to the mmc device */
mmc_dev_open(const uintptr_t init_params,io_dev_info_t ** dev_info)61 static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info)
62 {
63 	assert(dev_info != NULL);
64 	*dev_info = (io_dev_info_t *)&mmc_dev_info;
65 
66 	return 0;
67 }
68 
mmc_dev_init(io_dev_info_t * dev_info,const uintptr_t init_params)69 static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params)
70 {
71 	return 0;
72 }
73 
74 /* Close a connection to the mmc device */
mmc_dev_close(io_dev_info_t * dev_info)75 static int mmc_dev_close(io_dev_info_t *dev_info)
76 {
77 	return 0;
78 }
79 
80 /* Open a file on the mmc device */
mmc_block_open(io_dev_info_t * dev_info,const uintptr_t spec,io_entity_t * entity)81 static int mmc_block_open(io_dev_info_t *dev_info, const  uintptr_t spec,
82 			  io_entity_t *entity)
83 {
84 	seek_offset = 0;
85 	return 0;
86 }
87 
88 /* Seek to a particular file offset on the mmc device */
mmc_block_seek(io_entity_t * entity,int mode,signed long long offset)89 static int mmc_block_seek(io_entity_t *entity, int mode,
90 			  signed long long offset)
91 {
92 	seek_offset = offset;
93 	return 0;
94 }
95 
96 /* Read data from a file on the mmc device */
mmc_block_read(io_entity_t * entity,uintptr_t buffer,size_t length,size_t * length_read)97 static int mmc_block_read(io_entity_t *entity, uintptr_t buffer,
98 			  size_t length, size_t *length_read)
99 {
100 	*length_read = mmc_read_blocks(seek_offset / MMC_BLOCK_SIZE,
101 				       buffer, length);
102 
103 	if (*length_read != length) {
104 		return -EIO;
105 	}
106 
107 	return 0;
108 }
109 
110 /* Close a file on the mmc device */
mmc_block_close(io_entity_t * entity)111 static int mmc_block_close(io_entity_t *entity)
112 {
113 	return 0;
114 }
115 
116 /* Register the mmc driver with the IO abstraction */
register_io_dev_mmc(const io_dev_connector_t ** dev_con)117 int register_io_dev_mmc(const io_dev_connector_t **dev_con)
118 {
119 	int result;
120 
121 	assert(dev_con != NULL);
122 
123 	result = io_register_device(&mmc_dev_info);
124 	if (result == 0) {
125 		*dev_con = &mmc_dev_connector;
126 	}
127 
128 	return result;
129 }
130