1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "aos/kernel.h"
10 #include "ulog/ulog.h"
11 #include "aos/vfs.h"
12 #include "sensor_hal.h"
13
14 #define SENSOR_MS_TO_ODR(ms) ((1000/(ms)) + 1)
15
16 extern void sensor_drv_init(void);
17
18 static int sensor_open(inode_t *node, file_t *file);
19 static int sensor_close(file_t *file);
20 static ssize_t sensor_read(file_t *f, void *buf, size_t len);
21 static ssize_t sensor_write(file_t *f, const void *buf, size_t len);
22 static int sensor_ioctl(file_t *f, int cmd, unsigned long arg);
23
24
25 file_ops_t sensor_fops = {
26 .open = sensor_open,
27 .close = sensor_close,
28 .read = sensor_read,
29 .write = sensor_write,
30 .ioctl = sensor_ioctl,
31 };
32
33 static bool g_sensor_init_flag = false;
34 static SENSOR_IRQ_CALLBACK g_sensor_irq_cb = NULL;
35 static sensor_obj_t * g_sensor_obj[SENSOR_MAX_NUM];
36 static char g_sensor_path[SENSOR_MAX_NUM][SENSOR_NAME_LEN];
37 static uint32_t g_sensor_cnt = 0;
38 extern int g_sensor_drv_num;
39 extern SENSOR_INIT_FUN g_sensor_func[];
40
sensor_set_power_mode(dev_power_mode_e power,int index)41 UNUSED static void sensor_set_power_mode(dev_power_mode_e power, int index)
42 {
43 g_sensor_obj[index]->power = power;
44
45 }
46
sensor_set_sensor_service(SENSOR_IRQ_CALLBACK func)47 static int sensor_set_sensor_service(SENSOR_IRQ_CALLBACK func)
48 {
49 if (func == NULL) {
50 return -1;
51 }
52
53 if (g_sensor_irq_cb != NULL) {
54 return 0;
55 }
56
57 g_sensor_irq_cb = func;
58
59 return 0;
60 }
sensor_get_sensor_mode_config(uint32_t index,dev_sensor_config_t * config)61 static int sensor_get_sensor_mode_config(uint32_t index, dev_sensor_config_t *config)
62 {
63 if (index >= g_sensor_cnt) {
64 return -1;
65 }
66 if (config == NULL) {
67 return -1;
68 }
69
70 config->mode = g_sensor_obj[index]->mode;
71 config->data_buf = g_sensor_obj[index]->data_buf;
72 config->data_len = g_sensor_obj[index]->data_len;
73
74 return 0;
75 }
76
sensor_irq_handle(void * arg)77 void sensor_irq_handle(void *arg)
78 {
79 uint32_t index = (uint32_t)arg;
80
81 if (index >= SENSOR_MAX_NUM) {
82 return;
83 }
84
85 if ((g_sensor_obj[index]->mode != DEV_FIFO) &&
86 (g_sensor_obj[index]->mode != DEV_INT) &&
87 (g_sensor_obj[index]->mode != DEV_DATA_READY)) {
88 return;
89 }
90
91 if (NULL != g_sensor_obj[index]->irq_handle) {
92 g_sensor_obj[index]->irq_handle();
93
94 if (NULL != g_sensor_irq_cb) {
95 g_sensor_irq_cb(g_sensor_obj[index]->tag, g_sensor_obj[index]->instance);
96 }
97 }
98 return;
99 }
100
sensor_register_irq(int index)101 static int sensor_register_irq(int index )
102 {
103 int ret = -1;
104
105 if (0 == g_sensor_obj[index]->data_len) {
106 return -1;
107 }
108 #if SENSOR_CONFIG_INT_ENABLE
109 ret =
110 hal_gpio_enable_irq(&(g_sensor_obj[index]->gpio), *(gpio_irq_trigger_t*)(g_sensor_obj[index]->gpio.priv),
111 sensor_irq_handle, (void *)index);
112 if (unlikely(ret)) {
113 return -1;
114 }
115 #endif
116 return ret;
117 }
118
find_selected_sensor(char * path,sensor_tag_e * ptag,uint8_t * pinstance)119 static int find_selected_sensor(char *path, sensor_tag_e* ptag, uint8_t* pinstance)
120 {
121 uint32_t i = 0;
122 if (path == NULL) {
123 return -1;
124 }
125
126 if (ptag == NULL) {
127 return -1;
128 }
129
130 if (pinstance == NULL) {
131 return -1;
132 }
133 for (i = 0; i < g_sensor_cnt; i++) {
134 if(strlen(path) != strlen(g_sensor_path[i])){
135 continue;
136 }
137 if (strncmp(g_sensor_path[i], path, strlen(path)) == 0) {
138 break;
139 }
140 }
141
142 if (i >= g_sensor_cnt){
143 return -1;
144 }
145
146 *ptag = g_sensor_obj[i]->tag;
147 *pinstance = g_sensor_obj[i]->instance;
148
149 return 0;
150 }
151
load_sensor_config(int index)152 UNUSED static int load_sensor_config(int index)
153 {
154 g_sensor_obj[index] = (sensor_obj_t *)aos_malloc(sizeof(sensor_obj_t));
155 if (g_sensor_obj[index] == NULL) {
156 /* plan to add the other bus register here like spi */
157 return -1;
158 }
159 return 0;
160 }
161
sensor_obj_register(int index)162 static int sensor_obj_register(int index )
163 {
164 int ret = 0;
165
166 if ((g_sensor_obj[index]->mode == DEV_INT) ||
167 (g_sensor_obj[index]->mode == DEV_DATA_READY) ||
168 (g_sensor_obj[index]->mode == DEV_FIFO)) {
169 ret = sensor_register_irq(index);
170 if (unlikely(ret)) {
171 return -1;
172 }
173 }
174
175 ret = aos_register_driver(g_sensor_path[index], &sensor_fops, NULL);
176 if (unlikely(ret)) {
177 return -1;
178 }
179 return 0;
180 }
181
sensor_create_obj(sensor_obj_t * sensor)182 int sensor_create_obj(sensor_obj_t* sensor)
183 {
184 int ret = 0;
185 int index;
186 sensor_tag_e tag;
187 uint8_t instance;
188
189 index = g_sensor_cnt;
190 if(index >= SENSOR_MAX_NUM){
191 return -1;
192 }
193
194 g_sensor_obj[index] =
195 (sensor_obj_t *)aos_malloc(sizeof(sensor_obj_t));
196 if (g_sensor_obj[index] == NULL) {
197 return -1;
198 }
199
200 memset(g_sensor_obj[index], 0, sizeof(sensor_obj_t));
201 memset(g_sensor_path[index], 0, SENSOR_NAME_LEN);
202
203 /* install the phy sensor info into the sensor object datebase here */
204 ret = snprintf(g_sensor_path[index], SENSOR_NAME_LEN, "%s/%d", sensor->path, sensor->instance);
205 if(ret < 0){
206 goto error;
207 }
208
209 ret = find_selected_sensor(g_sensor_path[index], &tag, &instance);
210 if(ret == 0){
211 goto error;
212 }
213
214 g_sensor_obj[index]->io_port = sensor->io_port;
215 g_sensor_obj[index]->tag = sensor->tag;
216 g_sensor_obj[index]->instance = sensor->instance;
217 g_sensor_obj[index]->open = sensor->open;
218 g_sensor_obj[index]->close = sensor->close;
219 g_sensor_obj[index]->ioctl = sensor->ioctl;
220 g_sensor_obj[index]->read = sensor->read;
221 g_sensor_obj[index]->write = sensor->write;
222 g_sensor_obj[index]->irq_handle = sensor->irq_handle;
223 g_sensor_obj[index]->mode = sensor->mode;
224 g_sensor_obj[index]->data_buf = 0;
225 g_sensor_obj[index]->data_len = sensor->data_len;
226 g_sensor_obj[index]->power =
227 DEV_POWER_OFF; // will update the status later
228 g_sensor_obj[index]->ref = 0; // count the ref of this sensor
229 g_sensor_obj[index]->drv_index = sensor->drv_index;
230
231 if ((sensor->mode == DEV_INT) || (sensor->mode == DEV_DATA_READY) ||
232 (sensor->mode == DEV_FIFO)) {
233 g_sensor_obj[index]->gpio.port = sensor->gpio.port;
234 g_sensor_obj[index]->gpio.config = sensor->gpio.config;
235 g_sensor_obj[index]->gpio.priv = sensor->gpio.priv;
236 }
237
238 /* register the sensor object into the irq list and vfs */
239 ret = sensor_obj_register(index);
240 if (unlikely(ret)) {
241 goto error;
242 }
243
244 g_sensor_cnt++;
245 return 0;
246
247 error:
248 if(g_sensor_obj[index] != NULL){
249 aos_free(g_sensor_obj[index]);
250 }
251 return -1;
252 }
253
sensor_hal_get_dev_list(void * buf)254 static int sensor_hal_get_dev_list(void* buf)
255 {
256 int index;
257 sensor_list_t *sensor_list = buf;
258 if (buf == NULL)
259 return -1;
260
261 /* load the sensor count and tag list here */
262
263 if (sensor_list->cnt != 0) {
264 return -1;
265 }
266
267 for(index = 0; (index < g_sensor_cnt) && (index < SENSOR_MAX_NUM); index++){
268 sensor_list->list[index].tag = g_sensor_obj[index]->tag;
269 sensor_list->list[index].instance = g_sensor_obj[index]->instance;
270 sensor_list->list[index].io_port = g_sensor_obj[index]->io_port;
271 }
272
273 sensor_list->cnt = g_sensor_cnt;
274
275 return 0;
276 }
277
278
sensor_obj_get(sensor_tag_e tag,uint8_t instance,uint32_t * pindex)279 static int sensor_obj_get(sensor_tag_e tag, uint8_t instance,uint32_t* pindex)
280 {
281 uint32_t i;
282
283 if (tag >= TAG_DEV_SENSOR_NUM_MAX){
284 return -1;
285 }
286
287 if (pindex == NULL){
288 return -1;
289 }
290
291 for (i = 0; i < g_sensor_cnt; i++) {
292 if ((g_sensor_obj[i]->tag == tag) && (g_sensor_obj[i]->instance == instance)){
293 break;
294 }
295 }
296
297 if (i >= g_sensor_cnt){
298 return -1;
299 }
300
301 *pindex = i;
302
303 return 0;
304 }
305
sensor_hal_open(sensor_tag_e tag,uint8_t instance)306 int sensor_hal_open(sensor_tag_e tag, uint8_t instance)
307 {
308 int ret;
309 uint32_t index;
310
311 if (tag >= TAG_DEV_SENSOR_NUM_MAX){
312 return -1;
313 }
314
315 ret = sensor_obj_get(tag, instance, &index);
316 if (unlikely(ret)){
317 return -1;
318 }
319
320 if( g_sensor_obj[index]->open == NULL){
321 return -1;
322 }
323
324 if(g_sensor_obj[index]->ref == 0){
325 ret = g_sensor_obj[index]->open();
326 if (unlikely(ret)){
327 return -1;
328 }
329 }
330 g_sensor_obj[index]->ref++;
331
332 LOGD(SENSOR_STR, "%s successfully \n", __func__);
333 return 0;
334 }
335
sensor_hal_close(sensor_tag_e tag,uint8_t instance)336 int sensor_hal_close(sensor_tag_e tag, uint8_t instance)
337 {
338 int ret;
339 uint32_t index;
340
341 if (tag >= TAG_DEV_SENSOR_NUM_MAX){
342 return -1;
343 }
344
345 ret = sensor_obj_get(tag, instance, &index);
346 if (unlikely(ret)){
347 return -1;
348 }
349
350 if( g_sensor_obj[index]->close == NULL){
351 return -1;
352 }
353 //if the ref counter is less than 2, then close the sensor
354 if(g_sensor_obj[index]->ref < 2){
355 ret = g_sensor_obj[index]->close();
356 if (unlikely(ret)){
357 return -1;
358 }
359 }
360
361 if(g_sensor_obj[index]->ref > 0){
362 g_sensor_obj[index]->ref--;
363 }
364 return 0;
365 }
366
367
sensor_hal_read(sensor_tag_e tag,uint8_t instance,void * buf,size_t len)368 ssize_t sensor_hal_read(sensor_tag_e tag, uint8_t instance, void *buf, size_t len)
369 {
370 int ret;
371 uint32_t index;
372
373 if (tag >= TAG_DEV_SENSOR_NUM_MAX){
374 goto error;
375 }
376
377 ret = sensor_obj_get(tag, instance, &index);
378 if (unlikely(ret)){
379 goto error;
380 }
381
382 #if SENSOR_CONFIG_MODBUS_ENABLE
383 if(g_sensor_obj[index]->io_port == MODBUS_PORT){
384 int* index_data = (int *)buf;
385 *index_data = g_sensor_obj[index]->drv_index;
386 if(*index_data < 0)
387 {
388 goto error;
389 }
390 }
391 #endif
392
393 if ((g_sensor_obj[index]->read == NULL)) {
394 goto error;
395 }
396
397 if (buf == NULL) {
398 goto error;
399 }
400
401 ret = g_sensor_obj[index]->read(buf, len);
402 if (ret < 0) {
403 goto error;
404 }
405
406 return ret;
407
408 error:
409 return -1;
410 }
411
sensor_hal_write(sensor_tag_e tag,uint8_t instance,const void * buf,size_t len)412 ssize_t sensor_hal_write(sensor_tag_e tag, uint8_t instance, const void *buf, size_t len)
413 {
414 /* no need this functionality recently */
415 return 0;
416 }
417
sensor_hal_ioctl(sensor_tag_e tag,uint8_t instance,sensor_cmd_type cmd,unsigned long arg)418 int sensor_hal_ioctl(sensor_tag_e tag, uint8_t instance, sensor_cmd_type cmd, unsigned long arg)
419 {
420 int ret = 0;
421 uint32_t index = 0;
422 unsigned long value = arg;
423 dev_sensor_config_t *config;
424
425 if (tag >= TAG_DEV_SENSOR_NUM_MAX){
426 return -1;
427 }
428
429 ret = sensor_obj_get(tag, instance, &index);
430 if (unlikely(ret)){
431 return -1;
432 }
433
434 switch (cmd){
435 case SENSOR_IOCTL_GET_SENSOR_LIST:
436 return -1;
437
438 case SENSOR_IOCTL_SET_SENSOR_IRQ_CB: {
439 config = (dev_sensor_config_t *)value;
440 if (NULL == config) {
441 return -1;
442 }
443 ret = sensor_set_sensor_service(config->irq_callback);
444 if (unlikely(ret)) {
445 return -1;
446 }
447 return 0;
448 }
449 case SENSOR_IOCTL_GET_SENSOR_MODE: {
450 config = (dev_sensor_config_t *)value;
451 if (NULL == config) {
452 return -1;
453 }
454
455 ret = sensor_get_sensor_mode_config(index, config);
456 if (unlikely(ret)) {
457 return -1;
458 }
459 return 0;
460 }
461 case SENSOR_IOCTL_ODR_SET: {
462 if (0 == value) {
463 return -1;
464 }
465 value = SENSOR_MS_TO_ODR(value);
466 break;
467 }
468
469 default :
470 break;
471
472 }
473
474 if (g_sensor_obj[index]->ioctl) {
475 g_sensor_obj[index]->ioctl(cmd, value);
476 }
477
478 LOGD(SENSOR_STR, "%s successfully \n", __func__);
479 return 0;
480 }
481
482
sensor_hal_init(void)483 int sensor_hal_init(void)
484 {
485 int ret = 0;
486 int i;
487 if(g_sensor_init_flag != false){
488 return 0;
489 }
490
491 g_sensor_cnt = 0;
492
493 sensor_drv_init();
494
495 #if SENSOR_CONFIG_MODBUS_ENABLE
496 modbus_init();
497 #endif
498 g_sensor_init_flag = true;
499
500 return 0;
501 }
502
sensor_open(inode_t * node,file_t * file)503 static int sensor_open(inode_t *node, file_t *file)
504 {
505 int ret;
506 sensor_tag_e tag;
507 uint8_t instance;
508
509 if ((node == NULL) || (file == NULL)) {
510 return -1;
511 }
512
513 /* just open the /dev/sensor node here */
514 if ((strlen(node->i_name) == strlen(sensor_node_path)) && (strncmp(sensor_node_path, node->i_name, strlen(node->i_name)) == 0)){
515 return 0;
516 }
517
518 ret = find_selected_sensor(node->i_name, &tag, &instance);
519 if (unlikely(ret)){
520 return -1;
521 }
522
523 return sensor_hal_open(tag, instance);
524 }
525
sensor_close(file_t * file)526 static int sensor_close(file_t *file)
527 {
528 int ret;
529 sensor_tag_e tag;
530 uint8_t instance;
531
532 if (file == NULL) {
533 return -1;
534 }
535 if (file->node == NULL) {
536 return -1;
537 }
538
539 /* just close the /dev/sensor node here */
540 if ((strlen(file->node->i_name) == strlen(sensor_node_path)) && (strncmp(sensor_node_path, (file->node->i_name), strlen(file->node->i_name)) == 0)){
541 return 0;
542 }
543
544 ret = find_selected_sensor(file->node->i_name, &tag, &instance);
545 if (unlikely(ret)){
546 return -1;
547 }
548
549 return sensor_hal_close(tag, instance);
550 }
551
552
sensor_read(file_t * f,void * buf,size_t len)553 static ssize_t sensor_read(file_t *f, void *buf, size_t len)
554 {
555 int ret;
556 sensor_tag_e tag;
557 uint8_t instance;
558
559 if (f == NULL) {
560 return 0;
561 }
562 if (f->node == NULL) {
563 return 0;
564 }
565
566 if (buf == NULL) {
567 return 0;
568 }
569
570 ret = find_selected_sensor(f->node->i_name, &tag, &instance);
571 if (unlikely(ret)){
572 return 0;
573 }
574
575 return sensor_hal_read(tag, instance,buf, len);
576
577 }
578
sensor_write(file_t * f,const void * buf,size_t len)579 static ssize_t sensor_write(file_t *f, const void *buf, size_t len)
580 {
581 int ret;
582 sensor_tag_e tag;
583 uint8_t instance;
584
585 if (f == NULL) {
586 return 0;
587 }
588 if (f->node == NULL) {
589 return 0;
590 }
591
592 if (buf == NULL) {
593 return 0;
594 }
595 ret = find_selected_sensor(f->node->i_name, &tag, &instance);
596 if (unlikely(ret)){
597 return 0;
598 }
599
600 /* no need this functionality recently */
601 return sensor_hal_write(tag, instance,buf, len);
602 }
603
sensor_ioctl(file_t * f,int cmd,unsigned long arg)604 static int sensor_ioctl(file_t *f, int cmd, unsigned long arg)
605 {
606 int ret = 0;
607 sensor_tag_e tag;
608 uint8_t instance;
609
610 if (f == NULL) {
611 LOGD(SENSOR_STR, "%s fail line: %d\n", __func__, __LINE__);
612 return -1;
613 }
614
615 if (cmd >= SENSOR_IOCTL_MAX) {
616 return -1;
617 }
618
619 if (cmd == SENSOR_IOCTL_GET_SENSOR_LIST) {
620 ret = sensor_hal_get_dev_list((void *)arg);
621 if (unlikely(ret)) {
622 LOGD(SENSOR_STR, "%s fail line: %d\n", __func__, __LINE__);
623 return -1;
624 }
625 return 0;
626 }
627
628 if (f->node == NULL) {
629 LOGD(SENSOR_STR, "%s fail line: %d\n", __func__, __LINE__);
630 return -1;
631 }
632
633 ret = find_selected_sensor(f->node->i_name, &tag, &instance);
634 if (unlikely(ret)){
635 return -1;
636 }
637
638 ret = sensor_hal_ioctl(tag,instance,(sensor_cmd_type)cmd,arg);
639 if (unlikely(ret)){
640 return -1;
641 }
642
643 LOGD(SENSOR_STR, "%s successfully \n", __func__);
644 return 0;
645 }
sensor_hal_register(void)646 static int sensor_hal_register(void)
647 {
648 int ret = 0;
649 ret = aos_register_driver(sensor_node_path, &sensor_fops, NULL);
650 if (unlikely(ret)) {
651 return -1;
652 }
653 return 0;
654 }
655
656
sensor_init(void)657 int sensor_init(void)
658 {
659 int ret = 0;
660
661 ret = sensor_hal_init();
662 if(unlikely(ret)){
663 return -1;
664 }
665
666 ret = sensor_hal_register();
667 if(unlikely(ret)){
668 return -1;
669 }
670
671 LOGD(SENSOR_STR, "%s successfully \n", __func__);
672 return 0;
673 }
674
675