1 /*
2 * Copyright (c) 2020 Amarula Solutions.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT st_stm32_sdmmc
8
9 #include <devicetree.h>
10 #include <drivers/disk.h>
11 #include <drivers/clock_control.h>
12 #include <drivers/clock_control/stm32_clock_control.h>
13 #include <pinmux/pinmux_stm32.h>
14 #include <drivers/gpio.h>
15 #include <logging/log.h>
16 #include <soc.h>
17 #include <stm32_ll_rcc.h>
18
19 LOG_MODULE_REGISTER(stm32_sdmmc, CONFIG_SDMMC_LOG_LEVEL);
20
21 #ifndef MMC_TypeDef
22 #define MMC_TypeDef SDMMC_TypeDef
23 #endif
24
25 struct stm32_sdmmc_priv {
26 SD_HandleTypeDef hsd;
27 int status;
28 struct k_work work;
29 struct gpio_callback cd_cb;
30 struct {
31 const char *name;
32 const struct device *port;
33 int pin;
34 int flags;
35 } cd;
36 struct {
37 const char *name;
38 const struct device *port;
39 int pin;
40 int flags;
41 } pe;
42 struct stm32_pclken pclken;
43 struct {
44 const struct soc_gpio_pinctrl *list;
45 size_t len;
46 } pinctrl;
47 };
48
stm32_sdmmc_clock_enable(struct stm32_sdmmc_priv * priv)49 static int stm32_sdmmc_clock_enable(struct stm32_sdmmc_priv *priv)
50 {
51 const struct device *clock;
52
53 #if CONFIG_SOC_SERIES_STM32L4X
54 LL_RCC_PLLSAI1_Disable();
55 /* Configure PLLSA11 to enable 48M domain */
56 LL_RCC_PLLSAI1_ConfigDomain_48M(LL_RCC_PLLSOURCE_HSI,
57 LL_RCC_PLLM_DIV_1,
58 8, LL_RCC_PLLSAI1Q_DIV_8);
59
60 /* Enable PLLSA1 */
61 LL_RCC_PLLSAI1_Enable();
62
63 /* Enable PLLSAI1 output mapped on 48MHz domain clock */
64 LL_RCC_PLLSAI1_EnableDomain_48M();
65
66 /* Wait for PLLSA1 ready flag */
67 while (LL_RCC_PLLSAI1_IsReady() != 1)
68 ;
69
70 LL_RCC_SetSDMMCClockSource(LL_RCC_SDMMC1_CLKSOURCE_PLLSAI1);
71 #endif
72
73 clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
74
75 /* Enable the APB clock for stm32_sdmmc */
76 return clock_control_on(clock, (clock_control_subsys_t *)&priv->pclken);
77 }
78
stm32_sdmmc_clock_disable(struct stm32_sdmmc_priv * priv)79 static int stm32_sdmmc_clock_disable(struct stm32_sdmmc_priv *priv)
80 {
81 const struct device *clock;
82
83 clock = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
84
85 return clock_control_off(clock,
86 (clock_control_subsys_t *)&priv->pclken);
87 }
88
stm32_sdmmc_access_init(struct disk_info * disk)89 static int stm32_sdmmc_access_init(struct disk_info *disk)
90 {
91 const struct device *dev = disk->dev;
92 struct stm32_sdmmc_priv *priv = dev->data;
93 int err;
94
95 if (priv->status == DISK_STATUS_OK) {
96 return 0;
97 }
98
99 if (priv->status == DISK_STATUS_NOMEDIA) {
100 return -ENODEV;
101 }
102
103 err = stm32_sdmmc_clock_enable(priv);
104 if (err) {
105 LOG_ERR("failed to init clocks");
106 return err;
107 }
108
109 err = HAL_SD_Init(&priv->hsd);
110 if (err != HAL_OK) {
111 LOG_ERR("failed to init stm32_sdmmc");
112 return -EIO;
113 }
114
115 priv->status = DISK_STATUS_OK;
116 return 0;
117 }
118
stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv * priv)119 static void stm32_sdmmc_access_deinit(struct stm32_sdmmc_priv *priv)
120 {
121 HAL_SD_DeInit(&priv->hsd);
122 stm32_sdmmc_clock_disable(priv);
123 }
124
stm32_sdmmc_access_status(struct disk_info * disk)125 static int stm32_sdmmc_access_status(struct disk_info *disk)
126 {
127 const struct device *dev = disk->dev;
128 struct stm32_sdmmc_priv *priv = dev->data;
129
130 return priv->status;
131 }
132
stm32_sdmmc_access_read(struct disk_info * disk,uint8_t * data_buf,uint32_t start_sector,uint32_t num_sector)133 static int stm32_sdmmc_access_read(struct disk_info *disk, uint8_t *data_buf,
134 uint32_t start_sector, uint32_t num_sector)
135 {
136 const struct device *dev = disk->dev;
137 struct stm32_sdmmc_priv *priv = dev->data;
138 int err;
139
140 err = HAL_SD_ReadBlocks(&priv->hsd, data_buf, start_sector,
141 num_sector, 30000);
142 if (err != HAL_OK) {
143 LOG_ERR("sd read block failed %d", err);
144 return -EIO;
145 }
146
147 while (HAL_SD_GetCardState(&priv->hsd) != HAL_SD_CARD_TRANSFER)
148 ;
149
150 return 0;
151 }
152
stm32_sdmmc_access_write(struct disk_info * disk,const uint8_t * data_buf,uint32_t start_sector,uint32_t num_sector)153 static int stm32_sdmmc_access_write(struct disk_info *disk,
154 const uint8_t *data_buf,
155 uint32_t start_sector, uint32_t num_sector)
156 {
157 const struct device *dev = disk->dev;
158 struct stm32_sdmmc_priv *priv = dev->data;
159 int err;
160
161 err = HAL_SD_WriteBlocks(&priv->hsd, (uint8_t *)data_buf, start_sector,
162 num_sector, 30000);
163 if (err != HAL_OK) {
164 LOG_ERR("sd write block failed %d", err);
165 return -EIO;
166 }
167 while (HAL_SD_GetCardState(&priv->hsd) != HAL_SD_CARD_TRANSFER)
168 ;
169
170 return 0;
171 }
172
stm32_sdmmc_access_ioctl(struct disk_info * disk,uint8_t cmd,void * buff)173 static int stm32_sdmmc_access_ioctl(struct disk_info *disk, uint8_t cmd,
174 void *buff)
175 {
176 const struct device *dev = disk->dev;
177 struct stm32_sdmmc_priv *priv = dev->data;
178 HAL_SD_CardInfoTypeDef info;
179 int err;
180
181 switch (cmd) {
182 case DISK_IOCTL_GET_SECTOR_COUNT:
183 err = HAL_SD_GetCardInfo(&priv->hsd, &info);
184 if (err != HAL_OK) {
185 return -EIO;
186 }
187 *(uint32_t *)buff = info.LogBlockNbr;
188 break;
189 case DISK_IOCTL_GET_SECTOR_SIZE:
190 err = HAL_SD_GetCardInfo(&priv->hsd, &info);
191 if (err != HAL_OK) {
192 return -EIO;
193 }
194 *(uint32_t *)buff = info.LogBlockSize;
195 break;
196 case DISK_IOCTL_GET_ERASE_BLOCK_SZ:
197 *(uint32_t *)buff = 1;
198 break;
199 case DISK_IOCTL_CTRL_SYNC:
200 /* we use a blocking API, so nothing to do for sync */
201 break;
202 default:
203 return -EINVAL;
204 }
205 return 0;
206 }
207
208 static const struct disk_operations stm32_sdmmc_ops = {
209 .init = stm32_sdmmc_access_init,
210 .status = stm32_sdmmc_access_status,
211 .read = stm32_sdmmc_access_read,
212 .write = stm32_sdmmc_access_write,
213 .ioctl = stm32_sdmmc_access_ioctl,
214 };
215
216 static struct disk_info stm32_sdmmc_info = {
217 .name = CONFIG_SDMMC_VOLUME_NAME,
218 .ops = &stm32_sdmmc_ops,
219 };
220
221 /*
222 * Check if the card is present or not. If no card detect gpio is set, assume
223 * the card is present. If reading the gpio fails for some reason, assume the
224 * card is there.
225 */
stm32_sdmmc_card_present(struct stm32_sdmmc_priv * priv)226 static bool stm32_sdmmc_card_present(struct stm32_sdmmc_priv *priv)
227 {
228 int err;
229
230 if (!priv->cd.name) {
231 return true;
232 }
233
234 err = gpio_pin_get(priv->cd.port, priv->cd.pin);
235 if (err < 0) {
236 LOG_WRN("reading card detect failed %d", err);
237 return true;
238 }
239 return err;
240 }
241
stm32_sdmmc_cd_handler(struct k_work * item)242 static void stm32_sdmmc_cd_handler(struct k_work *item)
243 {
244 struct stm32_sdmmc_priv *priv = CONTAINER_OF(item,
245 struct stm32_sdmmc_priv,
246 work);
247
248 if (stm32_sdmmc_card_present(priv)) {
249 LOG_DBG("card inserted");
250 priv->status = DISK_STATUS_UNINIT;
251 } else {
252 LOG_DBG("card removed");
253 stm32_sdmmc_access_deinit(priv);
254 priv->status = DISK_STATUS_NOMEDIA;
255 }
256 }
257
stm32_sdmmc_cd_callback(const struct device * gpiodev,struct gpio_callback * cb,uint32_t pin)258 static void stm32_sdmmc_cd_callback(const struct device *gpiodev,
259 struct gpio_callback *cb,
260 uint32_t pin)
261 {
262 struct stm32_sdmmc_priv *priv = CONTAINER_OF(cb,
263 struct stm32_sdmmc_priv,
264 cd_cb);
265
266 k_work_submit(&priv->work);
267 }
268
stm32_sdmmc_card_detect_init(struct stm32_sdmmc_priv * priv)269 static int stm32_sdmmc_card_detect_init(struct stm32_sdmmc_priv *priv)
270 {
271 int err;
272
273 if (!priv->cd.name) {
274 return 0;
275 }
276
277 priv->cd.port = device_get_binding(priv->cd.name);
278 if (!priv->cd.port) {
279 return -ENODEV;
280 }
281
282 gpio_init_callback(&priv->cd_cb, stm32_sdmmc_cd_callback,
283 1 << priv->cd.pin);
284
285 err = gpio_add_callback(priv->cd.port, &priv->cd_cb);
286 if (err) {
287 return err;
288 }
289
290 err = gpio_pin_configure(priv->cd.port, priv->cd.pin,
291 priv->cd.flags | GPIO_INPUT);
292 if (err) {
293 goto remove_callback;
294 }
295
296 err = gpio_pin_interrupt_configure(priv->cd.port, priv->cd.pin,
297 GPIO_INT_EDGE_BOTH);
298 if (err) {
299 goto unconfigure_pin;
300 }
301 return 0;
302
303 unconfigure_pin:
304 gpio_pin_configure(priv->cd.port, priv->cd.pin, GPIO_DISCONNECTED);
305 remove_callback:
306 gpio_remove_callback(priv->cd.port, &priv->cd_cb);
307 return err;
308 }
309
stm32_sdmmc_card_detect_uninit(struct stm32_sdmmc_priv * priv)310 static int stm32_sdmmc_card_detect_uninit(struct stm32_sdmmc_priv *priv)
311 {
312 if (!priv->cd.name) {
313 return 0;
314 }
315
316 gpio_pin_interrupt_configure(priv->cd.port, priv->cd.pin,
317 GPIO_INT_MODE_DISABLED);
318 gpio_pin_configure(priv->cd.port, priv->cd.pin, GPIO_DISCONNECTED);
319 gpio_remove_callback(priv->cd.port, &priv->cd_cb);
320 return 0;
321 }
322
stm32_sdmmc_pwr_init(struct stm32_sdmmc_priv * priv)323 static int stm32_sdmmc_pwr_init(struct stm32_sdmmc_priv *priv)
324 {
325 int err;
326
327 if (!priv->pe.name) {
328 return 0;
329 }
330
331 priv->pe.port = device_get_binding(priv->pe.name);
332 if (!priv->pe.port) {
333 return -ENODEV;
334 }
335
336 err = gpio_pin_configure(priv->pe.port, priv->pe.pin,
337 priv->pe.flags | GPIO_OUTPUT_ACTIVE);
338 if (err) {
339 return err;
340 }
341
342 k_sleep(K_MSEC(50));
343
344 return 0;
345 }
346
stm32_sdmmc_pwr_uninit(struct stm32_sdmmc_priv * priv)347 static int stm32_sdmmc_pwr_uninit(struct stm32_sdmmc_priv *priv)
348 {
349 if (!priv->pe.name) {
350 return 0;
351 }
352
353 gpio_pin_configure(priv->pe.port, priv->pe.pin, GPIO_DISCONNECTED);
354 return 0;
355 }
356
disk_stm32_sdmmc_init(const struct device * dev)357 static int disk_stm32_sdmmc_init(const struct device *dev)
358 {
359 struct stm32_sdmmc_priv *priv = dev->data;
360 int err;
361
362 k_work_init(&priv->work, stm32_sdmmc_cd_handler);
363
364 /* Configure dt provided device signals when available */
365 err = stm32_dt_pinctrl_configure(priv->pinctrl.list,
366 priv->pinctrl.len,
367 (uint32_t)priv->hsd.Instance);
368 if (err < 0) {
369 return err;
370 }
371
372 err = stm32_sdmmc_card_detect_init(priv);
373 if (err) {
374 return err;
375 }
376
377 err = stm32_sdmmc_pwr_init(priv);
378 if (err) {
379 goto err_card_detect;
380 }
381
382 if (stm32_sdmmc_card_present(priv)) {
383 priv->status = DISK_STATUS_UNINIT;
384 } else {
385 priv->status = DISK_STATUS_NOMEDIA;
386 }
387
388 stm32_sdmmc_info.dev = dev;
389 err = disk_access_register(&stm32_sdmmc_info);
390 if (err) {
391 goto err_pwr;
392 }
393 return 0;
394
395 err_pwr:
396 stm32_sdmmc_pwr_uninit(priv);
397 err_card_detect:
398 stm32_sdmmc_card_detect_uninit(priv);
399 return err;
400 }
401
402 #if DT_NODE_HAS_STATUS(DT_DRV_INST(0), okay)
403
404 static const struct soc_gpio_pinctrl sdmmc_pins_1[] =
405 ST_STM32_DT_INST_PINCTRL(0, 0);
406
407 static struct stm32_sdmmc_priv stm32_sdmmc_priv_1 = {
408 .hsd = {
409 .Instance = (MMC_TypeDef *)DT_INST_REG_ADDR(0),
410 },
411 #if DT_INST_NODE_HAS_PROP(0, cd_gpios)
412 .cd = {
413 .name = DT_INST_GPIO_LABEL(0, cd_gpios),
414 .pin = DT_INST_GPIO_PIN(0, cd_gpios),
415 .flags = DT_INST_GPIO_FLAGS(0, cd_gpios),
416 },
417 #endif
418 #if DT_INST_NODE_HAS_PROP(0, pwr_gpios)
419 .pe = {
420 .name = DT_INST_GPIO_LABEL(0, pwr_gpios),
421 .pin = DT_INST_GPIO_PIN(0, pwr_gpios),
422 .flags = DT_INST_GPIO_FLAGS(0, pwr_gpios),
423 },
424 #endif
425 .pclken = {
426 .bus = DT_INST_CLOCKS_CELL(0, bus),
427 .enr = DT_INST_CLOCKS_CELL(0, bits),
428 },
429 .pinctrl = {
430 .list = sdmmc_pins_1,
431 .len = ARRAY_SIZE(sdmmc_pins_1)
432 }
433 };
434
435 DEVICE_DT_INST_DEFINE(0, disk_stm32_sdmmc_init, NULL,
436 &stm32_sdmmc_priv_1, NULL, POST_KERNEL,
437 CONFIG_SDMMC_INIT_PRIORITY,
438 NULL);
439 #endif
440