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