1 /*
2 * Copyright (C) 2015-2021 Alibaba Group Holding Limited
3 */
4
5 #include <poll.h>
6
7 #include <aos/hal/spi.h>
8 #include <vfsdev/spi_dev.h>
9 #include <devicevfs/devicevfs.h>
10
11 #ifdef CONFIG_SPI_NUM
12 #define PLATFORM_SPI_NUM CONFIG_SPI_NUM
13 #else
14 #define PLATFORM_SPI_NUM 4
15 #endif
16
17 #if (PLATFORM_SPI_NUM > 0)
18
19 // SPI device node will be named with "/dev/spi<x>", where <x> is spi port id
20 #define SPI_DEV_NAME_FORMAT "spi%d"
21 #define DEFAULT_SPI_FREQ 1000000
22 /* used to notify user on poll events */
23 typedef struct spi_poll_notify {
24 bool flag;
25 struct mutex mutex;
26 poll_notify_t notify;
27 struct pollfd *fd;
28 void *arg;
29 } spi_poll_notify_t;
30
31 static spi_poll_notify_t g_spi_notify[PLATFORM_SPI_NUM];
32
hal_spi_recv_cb_reg(spi_dev_t * spi,spi_rx_cb cb)33 __weak int hal_spi_recv_cb_reg(spi_dev_t *spi, spi_rx_cb cb) {
34 ddkc_dbg("%s, spi:%p, cb:%p\r\n", __func__, spi, cb);
35 return 0;
36 }
37
spi_device_read(file_t * f,void * buffer,size_t size)38 ssize_t spi_device_read (file_t *f, void *buffer, size_t size) {
39
40 spi_dev_t *spi = (spi_dev_t *)f->node->i_arg;
41 spi_poll_notify_t *spi_poll = NULL;
42
43 if (!spi || !buffer || !size) {
44 ddkc_dbg("invalid spi:%p, buffer:%p or size:%d\r\n", spi, buffer, size);
45 return -EINVAL;
46 }
47 spi_poll = &g_spi_notify[spi->port];
48 if (spi_poll->flag) {
49 mutex_lock(&spi_poll->mutex);
50 spi_poll->flag = false;
51 mutex_unlock(&spi_poll->mutex);
52 }
53 return hal_spi_recv(spi, buffer, size, 0);
54 }
55
spi_device_write(file_t * f,const void * buffer,size_t size)56 ssize_t spi_device_write (file_t *f, const void *buffer, size_t size) {
57 spi_dev_t *spi = (spi_dev_t *)f->node->i_arg;
58
59 if (!spi || !buffer || !size) {
60 ddkc_err("invalid spi:%p, buffer:%p or size:%d\r\n", spi, buffer, size);
61 return -EINVAL;
62 }
63 return hal_spi_send(spi, buffer, size, 1000);
64 }
65
_arg_to_role(unsigned long arg)66 static spi_role_e _arg_to_role (unsigned long arg) {
67 spi_role_e role = 0;
68 int control = arg & SPI_SLAVE;
69
70 switch (control) {
71 case SPI_SLAVE:
72 role = SPI_ROLE_SLAVE;
73 break;
74 case SPI_MASTER:
75 role = SPI_ROLE_MASTER;
76 break;
77
78 default:
79 role = SPI_ROLE_MASTER;
80 break;
81 }
82
83 return role;
84 }
85
_arg_to_firstbit(unsigned long arg)86 static spi_firstbit_e _arg_to_firstbit (unsigned long arg) {
87 spi_firstbit_e firstbit = 0;
88 int control = arg & SPI_LSB;
89
90 switch (control) {
91 case SPI_LSB:
92 firstbit = SPI_FIRSTBIT_LSB;
93 break;
94 case SPI_MSB:
95 firstbit = SPI_FIRSTBIT_MSB;
96 break;
97
98 default:
99 firstbit = SPI_FIRSTBIT_MSB;
100 break;
101 }
102
103 return firstbit;
104 }
105
_arg_to_work_mode(unsigned long arg)106 static spi_work_mode_e _arg_to_work_mode (unsigned long arg) {
107 spi_work_mode_e mode = 0;
108 int control = arg & (SPI_CPOL|SPI_CPHA);
109
110 switch (control) {
111 case SPI_MODE_0:
112 mode = SPI_WORK_MODE_0;
113 break;
114 case SPI_MODE_1:
115 mode = SPI_WORK_MODE_1;
116 break;
117 case SPI_MODE_2:
118 mode = SPI_WORK_MODE_2;
119 break;
120 case SPI_MODE_3:
121 mode = SPI_WORK_MODE_3;
122 break;
123 }
124
125 return mode;
126 }
127
_arg_to_tranmode(unsigned long arg)128 static spi_transfer_mode_e _arg_to_tranmode (unsigned long arg) {
129 spi_transfer_mode_e mode = 0;
130 int control = arg & SPI_TRANSFER_MODE_MASK;
131
132 switch (control) {
133 case SPI_TRANSFER_DMA_MODE:
134 mode = (spi_transfer_mode_e)SPI_TRANSFER_DMA;
135 break;
136 case SPI_TRANSFER_NORMAL_MODE:
137 mode = (spi_transfer_mode_e)SPI_TRANSFER_NORMAL;
138 break;
139
140 default:
141 mode = (spi_transfer_mode_e)SPI_TRANSFER_NORMAL;
142 break;
143 }
144
145 return mode;
146 }
147
_arg_to_datasize(unsigned long arg)148 static spi_data_size_e _arg_to_datasize (unsigned long arg) {
149 spi_data_size_e datasize = 0;
150 int control = arg & SPI_DATA_SIZE_MASK;
151
152 switch (control) {
153 case SPI_DATA_4BIT:
154 datasize = SPI_DATA_SIZE_4BIT;
155 break;
156 case SPI_DATA_5BIT:
157 datasize = SPI_DATA_SIZE_5BIT;
158 break;
159 case SPI_DATA_6BIT:
160 datasize = SPI_DATA_SIZE_6BIT;
161 break;
162 case SPI_DATA_7BIT:
163 datasize = SPI_DATA_SIZE_7BIT;
164 break;
165 case SPI_DATA_8BIT:
166 datasize = SPI_DATA_SIZE_8BIT;
167 break;
168 case SPI_DATA_9BIT:
169 datasize = SPI_DATA_SIZE_9BIT;
170 break;
171 case SPI_DATA_10BIT:
172 datasize = SPI_DATA_SIZE_10BIT;
173 break;
174 case SPI_DATA_11BIT:
175 datasize = SPI_DATA_SIZE_11BIT;
176 break;
177 case SPI_DATA_12BIT:
178 datasize = SPI_DATA_SIZE_12BIT;
179 break;
180 case SPI_DATA_13BIT:
181 datasize = SPI_DATA_SIZE_13BIT;
182 break;
183 case SPI_DATA_14BIT:
184 datasize = SPI_DATA_SIZE_14BIT;
185 break;
186 case SPI_DATA_15BIT:
187 datasize = SPI_DATA_SIZE_15BIT;
188 break;
189 case SPI_DATA_16BIT:
190 datasize = SPI_DATA_SIZE_16BIT;
191 break;
192
193 default:
194 datasize = SPI_DATA_SIZE_8BIT;
195 break;
196 }
197
198 return datasize;
199 }
200
_arg_to_cs(int arg)201 static spi_cs_e _arg_to_cs (int arg) {
202 spi_cs_e cs = 0;
203 int control = arg & SPI_NO_CS;
204
205 switch (control) {
206 case SPI_NO_CS:
207 cs = SPI_CS_DIS;
208 break;
209
210 default:
211 cs = SPI_CS_EN;
212 break;
213 }
214
215 return cs;
216 }
217
spi_device_ioctl(file_t * f,int cmd,unsigned long arg)218 int spi_device_ioctl (file_t *f, int cmd, unsigned long arg) {
219 int ret = -1;
220 spi_config_t *config = NULL;
221 spi_dev_t *spi = (spi_dev_t *)f->node->i_arg;
222 ioc_spi_transfer_t *tranptr;
223
224 if (!spi) {
225 ddkc_dbg("spi is NULL,invalid and ignore\r\n");
226 return -EINVAL;
227 }
228
229 config = &spi->config;
230
231 ddkc_dbg("i_name:%s, spi:%p, cmd:%d, arg:0x%lx\r\n", f->node->i_name, spi, cmd, arg);
232
233 switch (cmd) {
234 case IOC_SPI_SET_CFLAG:
235 ret = hal_spi_finalize(spi);
236 if (ret) {
237 ddkc_warn("hal_spi_finalize failed, ret:%d\r\n", ret);
238 break;
239 }
240
241 config->role = _arg_to_role(arg);
242 config->firstbit = _arg_to_firstbit(arg);
243 config->mode = _arg_to_work_mode(arg);
244 config->t_mode = _arg_to_tranmode(arg);
245 config->data_size = _arg_to_datasize(arg);
246 config->cs = _arg_to_cs(arg);
247 ddkc_info("role:%d, firstbit:%d, mode:%d, t_mode:%d, data_size:%d, cs:%d\r\n",
248 config->role, config->firstbit, config->mode, config->t_mode, config->data_size, config->cs);
249
250 ret = hal_spi_init(spi);
251 if (ret) {
252 ddkc_warn("hal_spi_init failed, ret:%d\r\n", ret);
253 }
254 break;
255 case IOC_SPI_SET_FREQ:
256 ret = hal_spi_finalize(spi);
257 if (ret) {
258 ddkc_warn("hal_spi_finalize failed, ret:%d\r\n", ret);
259 break;
260 }
261 config->freq = arg;
262 ret = hal_spi_init(spi);
263 if (ret) {
264 ddkc_warn("hal_spi_init failed, ret:%d\r\n", ret);
265 }
266
267 break;
268 case IOC_SPI_SEND_RECV:
269 tranptr = (ioc_spi_transfer_t *)arg;
270 if(NULL == tranptr){
271 ddkc_warn("tranptr is null, ret:%d\r\n", ret);
272 break;
273 }
274 ret = hal_spi_send_recv(spi,tranptr->tx_buf,tranptr->rx_buf,tranptr->rx_size,0);
275 if (ret) {
276 ddkc_warn("hal_spi_send_recv failed, ret:%d\r\n", ret);
277 }
278
279 break;
280 case IOC_SPI_SEND_AND_RECV:
281 tranptr = (ioc_spi_transfer_t *)arg;
282 if(NULL == tranptr){
283 ddkc_warn("tranptr is null, ret:%d\r\n", ret);
284 break;
285 }
286 ret = hal_spi_send_and_recv(spi,tranptr->tx_buf,tranptr->tx_size,tranptr->rx_buf,tranptr->rx_size,0);
287 if (ret) {
288 ddkc_warn("hal_spi_send_and_recv failed, ret:%d\r\n", ret);
289 }
290
291 break;
292 case IOC_SPI_SEND_AND_SEND:
293 tranptr = (ioc_spi_transfer_t *)arg;
294 if(NULL == tranptr){
295 ddkc_warn("tranptr is null, ret:%d\r\n", ret);
296 break;
297 }
298 ret = hal_spi_send_and_send(spi,tranptr->tx_buf,tranptr->tx_size,tranptr->rx_buf,tranptr->rx_size,0);
299 if (ret) {
300 ddkc_warn("hal_spi_send_and_send failed, ret:%d\r\n", ret);
301 }
302 break;
303
304 case IOC_SPI_SET_SERIAL_LEN:
305 ret = hal_spi_finalize(spi);
306 if (ret) {
307 ddkc_warn("hal_spi_finalize failed, ret:%d\r\n", ret);
308 break;
309 }
310 config->serial_len = arg;
311 ret = hal_spi_init(spi);
312 if (ret) {
313 ddkc_warn("hal_spi_init failed, ret:%d\r\n", ret);
314 }
315
316 break;
317
318 default:
319 break;
320 }
321
322 return ret;
323 }
324
spi_device_open(inode_t * node,file_t * f)325 int spi_device_open (inode_t *node, file_t *f) {
326 int ret = -1;
327 spi_dev_t *spi = (spi_dev_t *)node->i_arg;
328
329 ddkc_dbg("%s - node:%p, i_name:%s, spi:%p\r\n", __func__, node, node->i_name, spi);
330 if (!spi) {
331 ddkc_dbg("spi is NULL,invalid and ignore\r\n");
332 return -EINVAL;
333 }
334
335 //TODO: check whether it is for console, special operation needed for console
336 /* open spi with default parameter */
337 ret = hal_spi_init(spi);
338 if (ret) {
339 ddkc_err("hal_spi_init failed, ret:%d\r\n", ret);
340 return ret;
341 }
342
343 hal_spi_recv_cb_reg(spi, NULL);
344 //spi->priv = f;
345
346 return 0;
347 }
348
spi_device_close(file_t * f)349 int spi_device_close (file_t *f) {
350 int ret = 0;
351
352 ddkc_dbg("%s\r\n", __func__);
353 spi_dev_t *spi = (spi_dev_t *)f->node->i_arg;
354
355 //TODO: check whether it is for console, special operation needed for console
356 if (!spi) {
357 ddkc_dbg("f->node->i_arg is NULL, invalid and ignore\r\n");
358 return -EINVAL;
359 }
360
361 hal_spi_recv_cb_reg(spi, NULL);
362 /* open spi with default parameter */
363 ret = hal_spi_finalize(spi);
364 if (ret) {
365 ddkc_err("hal_spi_finalize failed, ret:%d\r\n", ret);
366 return ret;
367 }
368
369 return 0;
370 }
371
spi_rx_notify(spi_dev_t * spi)372 int spi_rx_notify (spi_dev_t *spi) {
373 struct pollfd *fd = NULL;
374 spi_poll_notify_t *spi_poll = NULL;
375
376 if (!spi) {
377 ddkc_err("spi should not be NULL in %s\r\n", __func__);
378 return -1;
379 }
380 ddkc_dbg("enter %s\r\n", __func__);
381 //fp = (file_t *)spi->priv;
382
383 spi_poll = &g_spi_notify[spi->port];
384
385 if (spi_poll->notify) {
386 mutex_lock(&spi_poll->mutex);
387 spi_poll->flag = true;
388
389 fd = (struct pollfd *)spi_poll->fd;
390 fd->revents |= POLLIN;
391 /* add POLLOUT by default */
392 fd->revents |= POLLOUT;
393
394 (*(spi_poll->notify)) (fd, spi_poll->arg);
395
396 spi_poll->notify = NULL;
397 spi_poll->fd = NULL;
398 spi_poll->arg = NULL;
399
400 hal_spi_recv_cb_reg(spi, NULL);
401
402 mutex_unlock(&spi_poll->mutex);
403
404 } else {
405 ddkc_err("!!!impossible case happened!!! spi_poll->notify is NULL\r\n");
406 }
407
408
409 return 0;
410 }
411
spi_device_poll(file_t * f,int flag,poll_notify_t notify,void * fd,void * arg)412 int spi_device_poll (file_t *f, int flag, poll_notify_t notify, void *fd, void *arg) {
413 spi_poll_notify_t *spi_poll = NULL;
414 spi_dev_t *spi = (spi_dev_t *)f->node->i_arg;
415
416 //TODO: check whether it is for console, special operation needed for console
417 if (!spi) {
418 ddkc_dbg("f->node->i_arg is NULL, invalid and ignore\r\n");
419 return -EINVAL;
420 }
421 ddkc_dbg("enter %s, fd:%p, arg:%p, notify:%p\r\n", __func__, fd, arg, notify);
422
423 spi_poll = &g_spi_notify[spi->port];
424
425 if (!fd) {
426 mutex_lock(&spi_poll->mutex);
427 hal_spi_recv_cb_reg(spi, NULL);
428 spi_poll->notify = NULL;
429 spi_poll->fd = NULL;
430 spi_poll->arg = NULL;
431 mutex_unlock(&spi_poll->mutex);
432 return 0;
433 }
434
435 if (!spi_poll->flag) {
436 mutex_lock(&spi_poll->mutex);
437
438 spi_poll->notify = notify;
439 spi_poll->fd = (struct pollfd *)fd;
440 spi_poll->arg = arg;
441
442 hal_spi_recv_cb_reg(spi, spi_rx_notify);
443 ((struct pollfd *)fd)->revents &= ~POLLIN;
444
445 mutex_unlock(&spi_poll->mutex);
446 } else {
447 ddkc_warn("spi_poll->flag is true, notify user directly\r\n");
448 ((struct pollfd *)fd)->events |= POLLIN;
449 (*notify)(fd, arg);
450 }
451
452 // add POLLOUT to events by default
453 ((struct pollfd *)fd)->events |= POLLOUT;
454
455 return 0;
456 }
457
458 /************************** device ****************************/
459
460
461 subsys_file_ops_t spi_device_fops = {
462 .open = spi_device_open,
463 .close = spi_device_close,
464 .read = spi_device_read,
465 .write = spi_device_write,
466 .ioctl = spi_device_ioctl,
467 .poll = spi_device_poll,
468 .lseek = NULL,
469 };
470
spi_device_init(struct u_platform_device * pdev)471 int spi_device_init (struct u_platform_device *pdev) {
472 // make sure 0 is returned if init operation success
473 // or aos_dev_reg procedure will break and no device node will be registered
474 ddkc_dbg("%s\r\n", __func__);
475 return 0;
476 }
477
spi_device_deinit(struct u_platform_device * pdev)478 int spi_device_deinit (struct u_platform_device *pdev) {
479 ddkc_dbg("%s\r\n", __func__);
480 return 0;
481 }
482
spi_device_pm(struct u_platform_device * pdev,u_pm_ops_t state)483 int spi_device_pm (struct u_platform_device *pdev, u_pm_ops_t state) {
484 ddkc_dbg("%s\r\n", __func__);
485 return 0;
486 }
487
488 struct subsys_drv spi_device_drv = {
489 .drv_name = "spi",
490 .init = spi_device_init,
491 .deinit = spi_device_deinit,
492 .pm = spi_device_pm,
493 };
494
495 struct subsys_dev *g_spi_device_array[PLATFORM_SPI_NUM];
496
497 static spi_dev_t g_def_setting = {
498 .port = 0,
499 .config = {
500 .role = SPI_ROLE_MASTER,
501 .firstbit = SPI_FIRSTBIT_MSB,
502 .mode = SPI_WORK_MODE_0,
503 .t_mode = SPI_TRANSFER_NORMAL,
504 .freq = DEFAULT_SPI_FREQ,
505 .serial_len = DEFAULT_SPI_SERAIL_LEN,
506 .data_size = SPI_DATA_SIZE_8BIT,
507 .cs = SPI_CS_EN,
508 },
509 .priv = NULL,
510 };
511
vfs_spi_drv_init(void)512 int vfs_spi_drv_init (void) {
513 int i = 0;
514 int j = 0;
515 int ret = 0;
516 int node_name_len = 0;
517 struct subsys_dev **ppsdev = NULL;
518
519 ddkc_info("spi vfs driver init starts\r\n");
520
521 node_name_len = strlen(SPI_DEV_NAME_FORMAT) + 1;
522
523 memset(g_spi_notify, 0, sizeof(g_spi_notify));
524 memset(g_spi_device_array, 0, sizeof(g_spi_device_array));
525 ppsdev = g_spi_device_array;
526
527 for (i = 0; i < PLATFORM_SPI_NUM; i++) {
528 spi_dev_t *spi_dev = malloc(sizeof(*spi_dev));
529
530 *ppsdev = malloc(sizeof(struct subsys_dev) + node_name_len);
531
532 if (!spi_dev || !(*ppsdev)) {
533 ddkc_info("malloc for spi_dev:%p or subsys_dev:%p failed, \r\n", spi_dev, *ppsdev);
534 if (spi_dev) {
535 free(spi_dev);
536 }
537 if (*ppsdev) {
538 free(*ppsdev);
539 *ppsdev = NULL;
540 }
541
542 goto err;
543 }
544
545 memset(*ppsdev, 0, sizeof(struct subsys_dev) + node_name_len);
546
547 (*ppsdev)->node_name = (char *)((*ppsdev) + 1);
548 snprintf((*ppsdev)->node_name, node_name_len, SPI_DEV_NAME_FORMAT, i);
549 ddkc_dbg("*ppsdev:%p, node_name:%s, (*ppsdev) + 1:%p, sizeof(struct subsys_dev):%d\r\n",
550 *ppsdev, (*ppsdev)->node_name, (*ppsdev) + 1, sizeof(struct subsys_dev));
551 (*ppsdev)->permission = 0;
552 // please refer to definitions in enum SUBSYS_BUS_TYPE
553 (*ppsdev)->type = BUS_TYPE_PLATFORM;
554 memcpy(spi_dev, &g_def_setting, sizeof(*spi_dev));
555 spi_dev->port = i;
556 // user_data will be passed to open operation via node->i_arg
557 (*ppsdev)->user_data = spi_dev;
558
559 mutex_init(&g_spi_notify[i].mutex);
560 ret = aos_dev_reg(*ppsdev, &spi_device_fops, &spi_device_drv);
561 if (ret) {
562 ddkc_err("aos_dev_reg for pwm%d failed, ret:%d\r\n", i, ret);
563
564 free(spi_dev);
565 free(*ppsdev);
566 *ppsdev = NULL;
567
568 goto err;
569 }
570
571 ppsdev++;
572 }
573
574 ddkc_info("spi vfs driver init finish, ret:%d\r\n", ret);
575
576 return 0;
577
578 err:
579 ppsdev = g_spi_device_array;
580
581 for (j = 0; j < i; j++) {
582 if (*ppsdev) {
583 aos_dev_unreg(*ppsdev);
584
585 ddkc_info("free memory for spi%d\r\n", j);
586
587 if ((*ppsdev)->user_data)
588 free((*ppsdev)->user_data);
589 free(*ppsdev);
590
591 *ppsdev = NULL;
592 }
593 ppsdev++;
594 }
595 ddkc_err("spi vfs driver init failed, ret:%d\r\n", ret);
596
597 return ret;
598 }
599
600 //FIXME: not implement for pangu now.
601 #ifndef CONFIG_CHIP_PANGU
602 VFS_DRIVER_ENTRY(vfs_spi_drv_init)
603 #endif
604
605 #endif
606