summaryrefslogtreecommitdiff
path: root/src/driver.c
blob: c4022497207d4d486799256c3b6c805b9b6019c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
 * Copyright (c) 2006-2018, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <rtthread.h>
#ifdef RT_USING_FDT
#include <dtb_node.h>
#endif
#if defined(RT_USING_POSIX_DEVIO)
#include <rtdevice.h> /* for wqueue_init */
#endif

/**
 * This function driver device match with id
 *
 * @param drv the pointer of driver structure
 * @param device_id the id of the device
 *
 * @return the error code, RT_EOK on successfully.
 */
rt_err_t rt_driver_match_with_id(const rt_driver_t drv,int device_id)
{
    rt_device_t device;
    int ret;
    if (!drv)
    {
        return -RT_EINVAL;
    }
    device = rt_device_create_since_driver(drv,device_id);
    if(!device)
    {
        return -RT_ERROR;
    }
    ret = rt_device_bind_driver(device,drv,RT_NULL);
    if(ret != 0)
    {
        return -RT_ERROR;
    }
    ret = rt_device_probe_and_init(device);
    if(ret != 0)
    {
        return -RT_ERROR;
    }
    return ret;
}

RTM_EXPORT(rt_driver_match_with_id);

#ifdef RT_USING_FDT
/**
 * This function driver device match with dtb_node
 *
 * @param drv the pointer of driver structure
 * @param from_node dtb node entry 
 * @param max_dev_num the max device support 
 * 
 * @return the error code, RT_EOK on successfully.
 */
rt_err_t rt_driver_match_with_dtb(const rt_driver_t drv,void *from_node,int max_dev_num)
{
    struct dtb_node** node_list; 
    rt_device_t device;
    int ret,i;
    int total_dev_num = 0;
    if ((!drv)||(!drv->dev_match)||(!drv->dev_match->compatible)||(!from_node)||(!drv->device_size))
    {
        return -RT_EINVAL;
    }

    node_list = rt_calloc(max_dev_num,sizeof(void *));
    if(!node_list)
    {
        return -RT_ERROR;
    }

    ret = dtb_node_find_all_compatible_node(from_node,drv->dev_match->compatible,node_list,max_dev_num,&total_dev_num);
    if((ret != 0) || (!total_dev_num))
    {
        return -RT_ERROR;
    }
    
    for(i = 0; i < total_dev_num; i ++)
    {
        if (!dtb_node_device_is_available(node_list[i]))
        {
            continue;
        }
        device = rt_device_create_since_driver(drv,i);
        if(!device)
        {
            continue;
        }
    
        ret = rt_device_bind_driver(device,drv,node_list[i]);
        if(ret != 0)
        {
            continue;
        }
        ret = rt_device_probe_and_init(device);
        if(ret != 0)
        {
            continue;
        }
    }
    rt_free(node_list);
    return ret;
}

RTM_EXPORT(rt_driver_match_with_dtb);
#endif