blob: 44b7d19074889baa1c2f17411047743647808605 [file] [log] [blame]
Yann Gautier9abbd6a2018-10-15 09:36:44 +02001/*
Yann Gautierf30cddc2019-04-16 11:35:19 +02002 * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved.
Yann Gautier9abbd6a2018-10-15 09:36:44 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <assert.h>
Yann Gautier9abbd6a2018-10-15 09:36:44 +02008#include <errno.h>
Yann Gautier9abbd6a2018-10-15 09:36:44 +02009#include <string.h>
10
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000011#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
Yann Gautier9abbd6a2018-10-15 09:36:44 +020018/* SDMMC device functions */
19static int mmc_dev_open(const uintptr_t init_params, io_dev_info_t **dev_info);
20static int mmc_block_open(io_dev_info_t *dev_info, const uintptr_t spec,
21 io_entity_t *entity);
22static int mmc_dev_init(io_dev_info_t *dev_info, const uintptr_t init_params);
Yann Gautierf30cddc2019-04-16 11:35:19 +020023static int mmc_block_seek(io_entity_t *entity, int mode,
24 signed long long offset);
Yann Gautier9abbd6a2018-10-15 09:36:44 +020025static int mmc_block_read(io_entity_t *entity, uintptr_t buffer, size_t length,
26 size_t *length_read);
27static int mmc_block_close(io_entity_t *entity);
28static int mmc_dev_close(io_dev_info_t *dev_info);
29static io_type_t device_type_mmc(void);
30
Yann Gautierf30cddc2019-04-16 11:35:19 +020031static signed long long seek_offset;
Yann Gautier9abbd6a2018-10-15 09:36:44 +020032
33static const io_dev_connector_t mmc_dev_connector = {
34 .dev_open = mmc_dev_open
35};
36
37static 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
49static 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 */
55static io_type_t device_type_mmc(void)
56{
57 return IO_TYPE_MMC;
58}
59
60/* Open a connection to the mmc device */
61static 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
69static 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 */
75static int mmc_dev_close(io_dev_info_t *dev_info)
76{
77 return 0;
78}
79
80/* Open a file on the mmc device */
81static 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 */
Yann Gautierf30cddc2019-04-16 11:35:19 +020089static int mmc_block_seek(io_entity_t *entity, int mode,
90 signed long long offset)
Yann Gautier9abbd6a2018-10-15 09:36:44 +020091{
92 seek_offset = offset;
93 return 0;
94}
95
96/* Read data from a file on the mmc device */
97static 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 */
111static int mmc_block_close(io_entity_t *entity)
112{
113 return 0;
114}
115
116/* Register the mmc driver with the IO abstraction */
117int 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}