hc
2024-03-25 edb30157bad0c0001c32b854271ace01d3b9a16a
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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
#include <linux/module.h>
#include <linux/inetdevice.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/platform_device.h>
#include "aic_bsp_driver.h"
#include "rwnx_version_gen.h"
#include "aicwf_txq_prealloc.h"
 
 
#define DRV_DESCRIPTION       "AIC BSP"
#define DRV_COPYRIGHT         "Copyright(c) 2015-2020 AICSemi"
#define DRV_AUTHOR            "AICSemi"
#define DRV_VERS_MOD          "1.0"
 
int aicwf_dbg_level_bsp = LOGERROR|LOGINFO|LOGDEBUG|LOGTRACE;
 
static struct platform_device *aicbsp_pdev;
 
const struct aicbsp_firmware *aicbsp_firmware_list = fw_u02;
 
const struct aicbsp_firmware fw_u02[] = {
   [AICBSP_CPMODE_WORK] = {
       .desc          = "normal work mode(sdio u02)",
       .bt_adid       = "fw_adid.bin",
       .bt_patch      = "fw_patch.bin",
       .bt_table      = "fw_patch_table.bin",
       .wl_fw         = "fmacfw.bin"
   },
   [AICBSP_CPMODE_TEST] = {
       .desc          = "rf test mode(sdio u02)",
       .bt_adid       = "fw_adid.bin",
       .bt_patch      = "fw_patch.bin",
       .bt_table      = "fw_patch_table.bin",
       .wl_fw         = "fmacfw_rf.bin"
   },
};
 
const struct aicbsp_firmware fw_u03[] = {
   [AICBSP_CPMODE_WORK] = {
       .desc          = "normal work mode(sdio u03/u04)",
       .bt_adid       = "fw_adid_u03.bin",
       .bt_patch      = "fw_patch_u03.bin",
       .bt_table      = "fw_patch_table_u03.bin",
       #ifdef CONFIG_MCU_MESSAGE
       .wl_fw         = "fmacfw_8800m_custmsg.bin"
       #else
       .wl_fw         = "fmacfw.bin"
       #endif
   },
 
   [AICBSP_CPMODE_TEST] = {
       .desc          = "rf test mode(sdio u03/u04)",
       .bt_adid       = "fw_adid_u03.bin",
       .bt_patch      = "fw_patch_u03.bin",
       .bt_table      = "fw_patch_table_u03.bin",
       .wl_fw         = "fmacfw_rf.bin"
   },
};
 
const struct aicbsp_firmware fw_8800dc_u01[] = {
   [AICBSP_CPMODE_WORK] = {
       .desc          = "normal work mode(sdio u01)",
       .bt_adid       = "fw_adid_8800dc.bin",
       .bt_patch      = "fw_patch_8800dc.bin",
       .bt_table      = "fw_patch_table_8800dc.bin",
       .wl_fw         = "fmacfw_8800dc.bin"
   },
 
   [AICBSP_CPMODE_TEST] = {
       .desc          = "rf test mode(sdio u01)",
       .bt_adid       = "fw_adid_8800dc.bin",
       .bt_patch      = "fw_patch_8800dc.bin",
       .bt_table      = "fw_patch_table_8800dc.bin",
       .wl_fw         = "fmacfw_rf_8800dc.bin"
   },
};
 
 
const struct aicbsp_firmware fw_8800dc_u02[] = {
   [AICBSP_CPMODE_WORK] = {
       .desc          = "normal work mode(8800dc sdio u02)",
       .bt_adid       = "fw_adid_8800dc_u02.bin",
       .bt_patch      = "fw_patch_8800dc_u02.bin",
       .bt_table      = "fw_patch_table_8800dc_u02.bin",
       .wl_fw         = "fmacfw_patch_8800dc_u02.bin"
   },
 
   [AICBSP_CPMODE_TEST] = {
       .desc          = "rf test mode(8800dc sdio u02)",
       .bt_adid       = "fw_adid_8800dc_u02.bin",
       .bt_patch      = "fw_patch_8800dc_u02.bin",
       .bt_table      = "fw_patch_table_8800dc_u02.bin",
       .wl_fw         = "lmacfw_rf_8800dc.bin" //u01,u02 lmacfw load same bin
   },
};
 
const struct aicbsp_firmware fw_8800d80_u01[] = {
   [AICBSP_CPMODE_WORK] = {
       .desc          = "normal work mode(8800d80 sdio u01)",
       .bt_adid       = "fw_adid_8800d80.bin",
       .bt_patch      = "fw_patch_8800d80.bin",
       .bt_table      = "fw_patch_table_8800d80.bin",
       .wl_fw         = "fmacfw_8800d80.bin"
   },
 
   [AICBSP_CPMODE_TEST] = {
       .desc          = "rf test mode(8800d80 sdio u01)",
       .bt_adid       = "fw_adid_8800d80.bin",
       .bt_patch      = "fw_patch_8800d80.bin",
       .bt_table      = "fw_patch_table_8800d80.bin",
       .wl_fw         = "lmacfw_rf_8800d80.bin"
   },
};
 
const struct aicbsp_firmware fw_8800d80_u02[] = {
   [AICBSP_CPMODE_WORK] = {
       .desc          = "normal work mode(8800d80 sdio u02)",
       .bt_adid       = "fw_adid_8800d80_u02.bin",
       .bt_patch      = "fw_patch_8800d80_u02.bin",
       .bt_table      = "fw_patch_table_8800d80_u02.bin",
       .wl_fw         = "fmacfw_8800d80_u02.bin"
   },
 
   [AICBSP_CPMODE_TEST] = {
       .desc          = "rf test mode(8800d80 sdio u02)",
       .bt_adid       = "fw_adid_8800d80_u02.bin",
       .bt_patch      = "fw_patch_8800d80_u02.bin",
       .bt_table      = "fw_patch_table_8800d80_u02.bin",
       .wl_fw         = "lmacfw_rf_8800d80_u02.bin"
   },
};
 
struct aicbsp_info_t aicbsp_info = {
   .hwinfo_r = AICBSP_HWINFO_DEFAULT,
   .hwinfo   = AICBSP_HWINFO_DEFAULT,
   .cpmode   = AICBSP_CPMODE_DEFAULT,
   .fwlog_en = AICBSP_FWLOG_EN_DEFAULT,
   .irqf     = AIC_IRQ_WAKE_FLAG,
};
 
struct mutex aicbsp_power_lock;
 
static struct platform_driver aicbsp_driver = {
   .driver = {
       .owner = THIS_MODULE,
       .name = "aic_bsp",
   },
   //.probe = aicbsp_probe,
   //.remove = aicbsp_remove,
};
 
static ssize_t cpmode_show(struct device *dev,
   struct device_attribute *attr, char *buf)
{
   ssize_t count = 0;
   uint8_t i = 0;
 
   count += sprintf(&buf[count], "Support mode value:\n");
 
   for (i = 0; i < AICBSP_CPMODE_MAX; i++) {
       if (aicbsp_firmware_list[i].desc)
           count += sprintf(&buf[count], " %2d: %s\n", i, aicbsp_firmware_list[i].desc);
   }
 
   count += sprintf(&buf[count], "Current: %d, firmware info:\n", aicbsp_info.cpmode);
   count += sprintf(&buf[count], "  BT ADID : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid);
   count += sprintf(&buf[count], "  BT PATCH: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch);
   count += sprintf(&buf[count], "  BT TABLE: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_table);
   count += sprintf(&buf[count], "  WIFI FW : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw);
   return count;
}
 
static ssize_t cpmode_store(struct device *dev,
   struct device_attribute *attr, const char *buf, size_t count)
{
   unsigned long val;
   int err = kstrtoul(buf, 0, &val);
   if (err)
       return err;
 
   if (val >= AICBSP_CPMODE_MAX) {
       pr_err("mode value must less than %d\n", AICBSP_CPMODE_MAX);
       return -EINVAL;
   }
 
   aicbsp_info.cpmode = val;
   printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list[val].desc);
 
   return count;
}
 
static ssize_t hwinfo_show(struct device *dev,
   struct device_attribute *attr, char *buf)
{
   ssize_t count = 0;
 
   count += sprintf(&buf[count], "chip hw rev: ");
   if (aicbsp_info.hwinfo_r < 0)
       count += sprintf(&buf[count], "-1(not avalible)\n");
   else
       count += sprintf(&buf[count], "0x%02X\n", aicbsp_info.chip_rev);
 
   count += sprintf(&buf[count], "hwinfo read: ");
   if (aicbsp_info.hwinfo_r < 0)
       count += sprintf(&buf[count], "%d(not avalible), ", aicbsp_info.hwinfo_r);
   else
       count += sprintf(&buf[count], "0x%02X, ", aicbsp_info.hwinfo_r);
 
   if (aicbsp_info.hwinfo < 0)
       count += sprintf(&buf[count], "set: %d(not avalible)\n", aicbsp_info.hwinfo);
   else
       count += sprintf(&buf[count], "set: 0x%02X\n", aicbsp_info.hwinfo);
 
   return count;
}
 
static ssize_t hwinfo_store(struct device *dev,
   struct device_attribute *attr, const char *buf, size_t count)
{
   long val;
   int err = kstrtol(buf, 0, &val);
 
   if (err) {
       pr_err("invalid input\n");
       return err;
   }
 
   if ((val == -1) || (val >= 0 && val <= 0xFF)) {
       aicbsp_info.hwinfo = val;
   } else {
       pr_err("invalid values\n");
       return -EINVAL;
   }
   return count;
}
 
static ssize_t fwdebug_show(struct device *dev,
   struct device_attribute *attr, char *buf)
{
   ssize_t count = 0;
 
   count += sprintf(&buf[count], "fw log status: %s\n",
           aicbsp_info.fwlog_en ? "on" : "off");
 
   return count;
}
 
static ssize_t fwdebug_store(struct device *dev,
   struct device_attribute *attr, const char *buf, size_t count)
{
   long val;
   int err = kstrtol(buf, 0, &val);
 
   if (err) {
       pr_err("invalid input\n");
       return err;
   }
 
   if (val > 1 || val < 0) {
       pr_err("must be 0 or 1\n");
       return -EINVAL;
   }
 
   aicbsp_info.fwlog_en = val;
   return count;
}
 
static DEVICE_ATTR(cpmode, S_IRUGO | S_IWUSR,
       cpmode_show, cpmode_store);
 
static DEVICE_ATTR(hwinfo, S_IRUGO | S_IWUSR,
       hwinfo_show, hwinfo_store);
 
static DEVICE_ATTR(fwdebug, S_IRUGO | S_IWUSR,
       fwdebug_show, fwdebug_store);
 
static struct attribute *aicbsp_attributes[] = {
   &dev_attr_cpmode.attr,
   &dev_attr_hwinfo.attr,
   &dev_attr_fwdebug.attr,
   NULL,
};
 
static struct attribute_group aicbsp_attribute_group = {
   .name  = "aicbsp_info",
   .attrs = aicbsp_attributes,
};
 
int testmode = AICBSP_CPMODE_DEFAULT;
int adap_test = 0;
module_param(testmode, int, 0660);
module_param(adap_test, int, 0660);
 
 
static int __init aicbsp_init(void)
{
   int ret;
   printk("%s\n", __func__);
   printk("RELEASE_DATE:%s\r\n", RELEASE_DATE);
 
   aicbsp_info.cpmode = testmode;
 
   aicbsp_resv_mem_init();
   ret = platform_driver_register(&aicbsp_driver);
   if (ret) {
       pr_err("register platform driver failed: %d\n", ret);
       return ret;
   }
 
   aicbsp_pdev = platform_device_alloc("aic-bsp", -1);
   ret = platform_device_add(aicbsp_pdev);
   if (ret) {
       pr_err("register platform device failed: %d\n", ret);
       return ret;
   }
 
   ret = sysfs_create_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
   if (ret) {
       pr_err("register sysfs create group failed!\n");
       return ret;
   }
 
   mutex_init(&aicbsp_power_lock);
#ifdef CONFIG_PLATFORM_ROCKCHIP
   aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_ON);
#endif
   return 0;
}
 
void aicbsp_sdio_exit(void);
extern struct aic_sdio_dev *aicbsp_sdiodev;
 
static void __exit aicbsp_exit(void)
{
#ifdef CONFIG_PLATFORM_ROCKCHIP
    if(aicbsp_sdiodev){
        aicbsp_sdio_exit();
    }
#endif
   sysfs_remove_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
   platform_device_del(aicbsp_pdev);
   platform_driver_unregister(&aicbsp_driver);
   mutex_destroy(&aicbsp_power_lock);
   aicbsp_resv_mem_deinit();
#ifdef CONFIG_PREALLOC_TXQ
    aicwf_prealloc_txq_free();
#endif
   printk("%s\n", __func__);
}
 
module_init(aicbsp_init);
module_exit(aicbsp_exit);
 
MODULE_DESCRIPTION(DRV_DESCRIPTION);
MODULE_VERSION(DRV_VERS_MOD);
MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR);
MODULE_LICENSE("GPL");