s5pc1xx: usb: codes clean up
[kernel/u-boot.git] / cpu / arm_cortexa8 / s5pc1xx / usb_downloader.c
1 /*
2  * Copyright (C) 2009 Samsung Electronics
3  * Minkyu Kang <mk7.kang@samsung.com>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA
19  *
20  */
21
22 #include <common.h>
23 #include "usbd.h"
24 #include "usb-hs-otg.h"
25 #ifdef CONFIG_S5PC1XXFB
26 #include <fbutils.h>
27 #endif
28
29 static char tx_data[8] = "MPL";
30 static long tx_len = 4;
31
32 static char rx_data[64];
33 static long rx_len = 64;
34
35 extern int s5p_receive_done;
36 extern int s5p_usb_connected;
37 extern otg_dev_t otg;
38
39 static int __usb_board_init(void)
40 {
41         return 0;
42 }
43
44 int usb_board_init(void) __attribute__((weak, alias("__usb_board_init")));
45
46 extern int s5p_no_lcd_support(void);
47 extern void s5pc_fimd_lcd_off(unsigned int win_id);
48 extern void s5pc_fimd_window_off(unsigned int win_id);
49
50 /* clear download informations */
51 static void s5p_usb_clear_dnfile_info(void)
52 {
53         otg.dn_addr = 0;
54         otg.dn_filesize = 0;
55         otg.dn_ptr = 0;
56 }
57
58 /* start the usb controller */
59 static void usb_init(void)
60 {
61         if (usb_board_init()) {
62                 printf("Failed to usb_board_init\n");
63                 return;
64         }
65
66 #ifdef CONFIG_S5PC1XXFB
67         if (!s5p_no_lcd_support()) {
68                 init_font();
69                 set_font_color(FONT_WHITE);
70                 fb_printf("Ready to USB Connection\n");
71         }
72 #endif
73
74         s5p_usbctl_init();
75
76         printf("USB Start!! - %s Speed\n",
77                         otg.speed ? "Full" : "High");
78
79         while (!s5p_usb_connected) {
80                 if (s5p_usb_detect_irq()) {
81                         s5p_udc_int_hndlr();
82                         s5p_usb_clear_irq();
83                 }
84         }
85
86         s5p_usb_clear_dnfile_info();
87
88         printf("Connected!!\n");
89
90 #ifdef CONFIG_S5PC1XXFB
91         if (!s5p_no_lcd_support()) {
92                 fb_printf("Download Start\n");
93                 draw_progress(40, 0, FONT_WHITE);
94         }
95 #endif
96 }
97
98 static void usb_stop(void)
99 {
100 #ifdef CONFIG_S5PC1XXFB
101         if (!s5p_no_lcd_support()) {
102                 exit_font();
103
104                 /* it uses fb3 as default window. */
105                 s5pc_fimd_lcd_off(3);
106                 s5pc_fimd_window_off(3);
107         }
108 #endif
109 }
110
111 /*
112  * receive the packet from host PC
113  * return received size
114  */
115 static int usb_receive_packet(void)
116 {
117         while (1) {
118                 if (s5p_usb_detect_irq()) {
119                         s5p_udc_int_hndlr();
120                         s5p_usb_clear_irq();
121                 }
122
123                 if (s5p_receive_done) {
124                         s5p_receive_done = 0;
125                         return otg.dn_filesize;
126                 }
127         }
128 }
129
130 /* setup the download informations */
131 static void recv_setup(char *addr, int len)
132 {
133         s5p_usb_clear_dnfile_info();
134
135         otg.dn_addr = (u32)addr;
136         otg.dn_ptr = (u8 *) addr;
137         otg.dn_filesize = len;
138 }
139
140 #ifdef CONFIG_GENERIC_MMC
141 #include <mmc.h>
142 extern int s5p_no_mmc_support(void);
143
144 static void usbd_set_mmc_dev(struct usbd_ops *usbd)
145 {
146         struct mmc *mmc;
147
148         if (s5p_no_mmc_support())
149                 return;
150
151         usbd->mmc_dev = 0;
152         /* FIXME */
153         usbd->mmc_max = 0x8000;
154
155         mmc = find_mmc_device(usbd->mmc_dev);
156         mmc_init(mmc);
157
158         usbd->mmc_blk = mmc->read_bl_len;
159
160         if (mmc->high_capacity)
161                 usbd->mmc_total = mmc->capacity;
162         else
163                 usbd->mmc_total = mmc->capacity / mmc->read_bl_len;
164 }
165 #endif
166
167 #ifdef CONFIG_S5PC1XXFB
168 static void set_progress(int progress)
169 {
170         draw_progress(40, progress, FONT_WHITE);
171 }
172 #endif
173 /*
174  * This function is interfaced between
175  * USB Device Controller and USB Downloader
176  */
177 struct usbd_ops *usbd_set_interface(struct usbd_ops *usbd)
178 {
179         usbd->usb_init = usb_init;
180         usbd->usb_stop = usb_stop;
181         usbd->send_data = s5p_usb_tx;
182         usbd->recv_data = usb_receive_packet;
183         usbd->recv_setup = recv_setup;
184         usbd->tx_data = tx_data;
185         usbd->rx_data = rx_data;
186         usbd->tx_len = tx_len;
187         usbd->rx_len = rx_len;
188         usbd->ram_addr = CONFIG_SYS_DOWN_ADDR;
189 #ifdef CONFIG_S5PC1XXFB
190         if (!s5p_no_lcd_support())
191                 usbd->set_progress = set_progress;
192 #endif
193 #ifdef CONFIG_GENERIC_MMC
194         usbd_set_mmc_dev(usbd);
195 #endif
196
197         return usbd;
198 }