Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[cascardo/linux.git] / drivers / staging / vt6656 / firmware.c
1 /*
2  * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
3  * All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (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  *
16  * File: baseband.c
17  *
18  * Purpose: Implement functions to access baseband
19  *
20  * Author: Yiching Chen
21  *
22  * Date: May 20, 2004
23  *
24  * Functions:
25  *
26  * Revision History:
27  *
28  */
29
30 #include <linux/compiler.h>
31 #include "firmware.h"
32 #include "usbpipe.h"
33
34 #define FIRMWARE_VERSION        0x133           /* version 1.51 */
35 #define FIRMWARE_NAME           "vntwusb.fw"
36
37 #define FIRMWARE_CHUNK_SIZE     0x400
38
39 int vnt_download_firmware(struct vnt_private *priv)
40 {
41         struct device *dev = &priv->usb->dev;
42         const struct firmware *fw;
43         int status;
44         void *buffer = NULL;
45         bool result = false;
46         u16 length;
47         int ii, rc;
48
49         dev_dbg(dev, "---->Download firmware\n");
50
51         rc = request_firmware(&fw, FIRMWARE_NAME, dev);
52         if (rc) {
53                 dev_err(dev, "firmware file %s request failed (%d)\n",
54                         FIRMWARE_NAME, rc);
55                         goto out;
56         }
57
58         buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
59         if (!buffer)
60                 goto free_fw;
61
62         for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
63                 length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
64                 memcpy(buffer, fw->data + ii, length);
65
66                 status = vnt_control_out(priv,
67                                                 0,
68                                                 0x1200+ii,
69                                                 0x0000,
70                                                 length,
71                                                 buffer);
72
73                 dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);
74
75                 if (status != STATUS_SUCCESS)
76                         goto free_fw;
77         }
78
79         result = true;
80 free_fw:
81         release_firmware(fw);
82
83 out:
84         kfree(buffer);
85
86         return result;
87 }
88 MODULE_FIRMWARE(FIRMWARE_NAME);
89
90 int vnt_firmware_branch_to_sram(struct vnt_private *priv)
91 {
92         int status;
93
94         dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");
95
96         status = vnt_control_out(priv,
97                                         1,
98                                         0x1200,
99                                         0x0000,
100                                         0,
101                                         NULL);
102         return status == STATUS_SUCCESS;
103 }
104
105 int vnt_check_firmware_version(struct vnt_private *priv)
106 {
107         int status;
108
109         status = vnt_control_in(priv,
110                                         MESSAGE_TYPE_READ,
111                                         0,
112                                         MESSAGE_REQUEST_VERSION,
113                                         2,
114                                         (u8 *)&priv->firmware_version);
115
116         dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
117                                                 priv->firmware_version);
118
119         if (status != STATUS_SUCCESS) {
120                 dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
121                 return false;
122         }
123         if (priv->firmware_version == 0xFFFF) {
124                 dev_dbg(&priv->usb->dev, "In Loader.\n");
125                 return false;
126         }
127
128         dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
129                                                 priv->firmware_version);
130
131         if (priv->firmware_version < FIRMWARE_VERSION) {
132                 /* branch to loader for download new firmware */
133                 vnt_firmware_branch_to_sram(priv);
134                 return false;
135         }
136         return true;
137 }