summaryrefslogtreecommitdiff
path: root/bsp/allwinner/libraries/sunxi-hal/hal/source/usb/manager/usb_msg_center.c
blob: b334b1c6bac18f8bfd3a84aa7e2e31992a0bf448 (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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <rtthread.h>
#include <init.h>
#include <typedef.h>
#include <kapi.h>
#include <log.h>
#include <usb/sunxi_hal_udc.h>
#include <usb/hal_hci.h>
#include "usb_msg_center.h"
#include "usb_manager_common.h"

static struct usb_msg_center_info g_center_info;
enum usb_role get_usb_role(void)
{
    return g_center_info.role;
}
static void set_usb_role(struct usb_msg_center_info *center_info, enum usb_role role)
{
    Usb_Manager_INFO("role:%d \n", role);
    center_info->role = role;
}

static void insmod_host_driver(struct usb_msg_center_info *center_info)
{
    Usb_Manager_INFO("\n");
    set_usb_role(center_info, USB_ROLE_HOST);
    hal_usb_hcd_init(0);
}

static void rmmod_host_driver(struct usb_msg_center_info *center_info)
{
    Usb_Manager_INFO("\n");
    set_usb_role(center_info, USB_ROLE_NULL);
    /*TODO*/
    hal_usb_hcd_deinit(0);
}

static void insmod_device_driver(struct usb_msg_center_info *center_info)
{
#ifdef CONFIG_COMPONENT_ADBD
    extern int adbd_main(void);
#endif
    Usb_Manager_Err(" adbd_main\n");
    set_usb_role(center_info, USB_ROLE_DEVICE);
#ifdef CONFIG_COMPONENT_ADBD
    adbd_main();
#endif
}

static void rmmod_device_driver(struct usb_msg_center_info *center_info)
{
#ifdef CONFIG_COMPONENT_ADBD
    extern int adbd_exit(void);
#endif
    Usb_Manager_Err("\n");
    set_usb_role(center_info, USB_ROLE_NULL);
#ifdef CONFIG_COMPONENT_ADBD
    adbd_exit();
#endif
    Usb_Manager_Err("\n");
}

static void do_usb_role_null(struct usb_msg_center_info *center_info)
{
    if (center_info->msg.hw_insmod_host)
    {
        insmod_host_driver(center_info);
        center_info->msg.hw_insmod_host = 0;

        goto end;
    }

    if (center_info->msg.hw_insmod_device)
    {
        insmod_device_driver(center_info);
        center_info->msg.hw_insmod_device = 0;

        goto end;
    }

end:
    memset(&center_info->msg, 0, sizeof(struct usb_msg));
}

static void do_usb_role_host(struct usb_msg_center_info *center_info)
{
    if (center_info->msg.hw_rmmod_host)
    {
        rmmod_host_driver(center_info);
        center_info->msg.hw_rmmod_host = 0;
        goto end;
    }

end:
    memset(&center_info->msg, 0, sizeof(struct usb_msg));
}

static void do_usb_role_device(struct usb_msg_center_info *center_info)
{
    if (center_info->msg.hw_rmmod_device)
    {
        rmmod_device_driver(center_info);
        center_info->msg.hw_rmmod_device = 0;
        goto end;
    }

end:
    memset(&center_info->msg, 0, sizeof(struct usb_msg));
}
static void modify_msg(struct usb_msg *msg)
{
    if (msg->hw_insmod_host && msg->hw_rmmod_host)
    {
        msg->hw_insmod_host = 0;
        msg->hw_rmmod_host  = 0;
    }

    if (msg->hw_insmod_device && msg->hw_rmmod_device)
    {
        msg->hw_insmod_device = 0;
        msg->hw_rmmod_device  = 0;
    }
}
void usb_msg_center(usb_cfg_t *cfg)
{
    enum usb_role role = USB_ROLE_NULL;
    struct usb_msg_center_info *center_info = &g_center_info;

    center_info->cfg = cfg;

    /* receive massage */
    modify_msg(&center_info->msg);
    /* execute cmd */
    role = get_usb_role();
    Usb_Manager_Debug("role=%d\n", get_usb_role());
    switch (role)
    {
        case USB_ROLE_NULL:
            do_usb_role_null(center_info);
            break;

        case USB_ROLE_HOST:
            do_usb_role_host(center_info);
            break;

        case USB_ROLE_DEVICE:
            do_usb_role_device(center_info);
            break;

        default:
            Usb_Manager_Err("ERR: unknown role(%x)\n", role);
    }
}

int usb_msg_center_init(void)
{
    struct usb_msg_center_info *center_info = &g_center_info;

    memset(center_info, 0, sizeof(struct usb_msg_center_info));
    return 0;
}

int usb_msg_center_exit(void)
{
    struct usb_msg_center_info *center_info = &g_center_info;

    memset(center_info, 0, sizeof(struct usb_msg_center_info));
    return 0;
}

void hw_insmod_usb_host(void)
{
    g_center_info.msg.hw_insmod_host = 1;
}

void hw_rmmod_usb_host(void)
{
    g_center_info.msg.hw_rmmod_host = 1;
}

void hw_insmod_usb_device(void)
{
    g_center_info.msg.hw_insmod_device = 1;
}

void hw_rmmod_usb_device(void)
{
    g_center_info.msg.hw_rmmod_device = 1;
}