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