tzh
2024-08-15 d4a1bd480003f3e1a0590bc46fbcb24f05652ca7
longan/kernel/linux-4.9/drivers/net/wireless/aic8800/aic8800_bsp/aic_bsp_main.c
old mode 100644new mode 100755
....@@ -5,6 +5,7 @@
55 #include <linux/kernel.h>
66 #include <linux/version.h>
77 #include <linux/platform_device.h>
8
+#include <linux/rfkill.h>
89 #include "aic_bsp_driver.h"
910
1011 #define DRV_DESCRIPTION "AIC BSP"
....@@ -12,56 +13,62 @@
1213 #define DRV_AUTHOR "AICSemi"
1314 #define DRV_VERS_MOD "1.0"
1415
16
+#if defined(AICWF_SDIO_SUPPORT)
17
+#define DRV_TYPE_NAME "sdio"
18
+#elif defined(AICWF_USB_SUPPORT)
19
+#define DRV_TYPE_NAME "usb"
20
+#else
21
+#define DRV_TYPE_NAME "unknow"
22
+#endif
23
+
24
+#define DRV_RELEASE_TAG "aic-bsp-" DRV_TYPE_NAME "-20220429-002"
25
+
1526 static struct platform_device *aicbsp_pdev;
1627
17
-const struct aicbsp_firmware aicbsp_firmware_list[] = {
18
- [AICBSP_MODE_BT_ONLY_SW] = {
19
- .desc = "bt only mode with switch",
28
+const struct aicbsp_firmware *aicbsp_firmware_list = fw_u02;
29
+
30
+const struct aicbsp_firmware fw_u02[] = {
31
+ [AICBSP_CPMODE_WORK] = {
32
+ .desc = "normal work mode(sdio u02)",
2033 .bt_adid = "fw_adid.bin",
2134 .bt_patch = "fw_patch.bin",
2235 .bt_table = "fw_patch_table.bin",
23
- .bt_patch_test = NULL,
2436 .wl_fw = "fmacfw.bin"
2537 },
2638
27
- [AICBSP_MODE_BT_WIFI_COMBO] = {
28
- .desc = "wifi/bt combo mode",
39
+ [AICBSP_CPMODE_TEST] = {
40
+ .desc = "rf test mode(sdio u02)",
2941 .bt_adid = "fw_adid.bin",
3042 .bt_patch = "fw_patch.bin",
3143 .bt_table = "fw_patch_table.bin",
32
- .bt_patch_test = NULL,
33
- .wl_fw = "fmacfw.bin"
34
- },
35
-
36
- [AICBSP_MODE_BT_ONLY] = {
37
- .desc = "bt only mode without switch",
38
- .bt_adid = "fw_adid.bin",
39
- .bt_patch = "fw_patch.bin",
40
- .bt_table = "fw_patch_table.bin",
41
- .bt_patch_test = NULL,
42
- .wl_fw = "fmacfw.bin"
43
- },
44
-
45
- [AICBSP_MODE_BT_ONLY_TEST] = {
46
- .desc = "bt only test mode",
47
- .bt_adid = "fw_adid.bin",
48
- .bt_patch = "fw_patch.bin",
49
- .bt_table = "fw_patch_table.bin",
50
- .bt_patch_test = "fw_patch_test.bin",
51
- .wl_fw = "fmacfw_rf.bin"
52
- },
53
-
54
- [AICBSP_MODE_COMBO_TEST] = {
55
- .desc = "wifi/bt combo test mode",
56
- .bt_adid = "fw_adid.bin",
57
- .bt_patch = "fw_patch.bin",
58
- .bt_table = "fw_patch_table.bin",
59
- .bt_patch_test = "fw_patch_test.bin",
6044 .wl_fw = "fmacfw_rf.bin"
6145 },
6246 };
6347
64
-uint32_t aicbsp_mode_index = AICBSP_MODE_DEFAULT;
48
+const struct aicbsp_firmware fw_u03[] = {
49
+ [AICBSP_CPMODE_WORK] = {
50
+ .desc = "normal work mode(sdio u03/u04)",
51
+ .bt_adid = "fw_adid_u03.bin",
52
+ .bt_patch = "fw_patch_u03.bin",
53
+ .bt_table = "fw_patch_table_u03.bin",
54
+ .wl_fw = "fmacfw.bin"
55
+ },
56
+
57
+ [AICBSP_CPMODE_TEST] = {
58
+ .desc = "rf test mode(sdio u03/u04)",
59
+ .bt_adid = "fw_adid_u03.bin",
60
+ .bt_patch = "fw_patch_u03.bin",
61
+ .bt_table = "fw_patch_table_u03.bin",
62
+ .wl_fw = "fmacfw_rf.bin"
63
+ },
64
+};
65
+
66
+struct aicbsp_info_t aicbsp_info = {
67
+ .hwinfo_r = AICBSP_HWINFO_DEFAULT,
68
+ .hwinfo = AICBSP_HWINFO_DEFAULT,
69
+ .cpmode = AICBSP_CPMODE_DEFAULT,
70
+};
71
+
6572 struct mutex aicbsp_power_lock;
6673
6774 static struct platform_driver aicbsp_driver = {
....@@ -73,96 +80,262 @@
7380 //.remove = aicbsp_remove,
7481 };
7582
76
-static ssize_t aicbsp_mode_show(struct device *dev,
83
+static int test_enable = -1;
84
+module_param(test_enable, int, S_IRUGO);
85
+MODULE_PARM_DESC(test_enable, "Set driver to test mode as default");
86
+
87
+static ssize_t cpmode_show(struct device *dev,
7788 struct device_attribute *attr, char *buf)
7889 {
7990 ssize_t count = 0;
8091 uint8_t i = 0;
8192
82
- count += sprintf(&buf[count], "Support mode number:\n");
93
+ count += sprintf(&buf[count], "Support mode value:\n");
8394
84
- for (i = 0; i < sizeof(aicbsp_firmware_list) / sizeof(aicbsp_firmware_list[0]); i++) {
95
+ for (i = 0; i < AICBSP_CPMODE_MAX; i++) {
8596 if (aicbsp_firmware_list[i].desc)
8697 count += sprintf(&buf[count], " %2d: %s\n", i, aicbsp_firmware_list[i].desc);
8798 }
8899
89
- count += sprintf(&buf[count], "Current: %d, firmware info:\n", aicbsp_mode_index);
90
- count += sprintf(&buf[count], " BT ADID : %s\n", aicbsp_firmware_list[aicbsp_mode_index].bt_adid);
91
- count += sprintf(&buf[count], " BT PATCH: %s\n", aicbsp_firmware_list[aicbsp_mode_index].bt_patch);
92
- count += sprintf(&buf[count], " BT TABLE: %s\n", aicbsp_firmware_list[aicbsp_mode_index].bt_table);
93
- count += sprintf(&buf[count], " BT TEST : %s\n", aicbsp_firmware_list[aicbsp_mode_index].bt_patch_test);
94
- count += sprintf(&buf[count], " WIFI FW : %s\n", aicbsp_firmware_list[aicbsp_mode_index].wl_fw);
100
+ count += sprintf(&buf[count], "Current: %d, firmware info:\n", aicbsp_info.cpmode);
101
+ count += sprintf(&buf[count], " BT ADID : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_adid);
102
+ count += sprintf(&buf[count], " BT PATCH: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_patch);
103
+ count += sprintf(&buf[count], " BT TABLE: %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].bt_table);
104
+ count += sprintf(&buf[count], " WIFI FW : %s\n", aicbsp_firmware_list[aicbsp_info.cpmode].wl_fw);
95105 return count;
96106 }
97107
98
-static ssize_t aicbsp_mode_store(struct device *dev,
108
+static ssize_t cpmode_store(struct device *dev,
99109 struct device_attribute *attr, const char *buf, size_t count)
100110 {
101111 unsigned long val;
102
- uint32_t max;
103112 int err = kstrtoul(buf, 0, &val);
104113 if (err)
105114 return err;
106115
107
- max = sizeof(aicbsp_firmware_list) / sizeof(aicbsp_firmware_list[0]);
108
- if (val >= max) {
109
- pr_err("mode value must less than %d\n", max);
116
+ if (val >= AICBSP_CPMODE_MAX) {
117
+ pr_err("mode value must less than %d\n", AICBSP_CPMODE_MAX);
110118 return -EINVAL;
111119 }
112120
113
- aicbsp_mode_index = val;
121
+ aicbsp_info.cpmode = val;
114122 printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list[val].desc);
115123
116124 return count;
117125 }
118126
119
-static DEVICE_ATTR(aicbsp_mode, S_IRUGO | S_IWUSR,
120
- aicbsp_mode_show, aicbsp_mode_store);
127
+static ssize_t hwinfo_show(struct device *dev,
128
+ struct device_attribute *attr, char *buf)
129
+{
130
+ ssize_t count = 0;
131
+
132
+ count += sprintf(&buf[count], "chip hw rev: ");
133
+ if (aicbsp_info.hwinfo_r < 0)
134
+ count += sprintf(&buf[count], "-1(not avalible)\n");
135
+ else
136
+ count += sprintf(&buf[count], "0x%02X\n", aicbsp_info.chip_rev);
137
+
138
+ count += sprintf(&buf[count], "hwinfo read: ");
139
+ if (aicbsp_info.hwinfo_r < 0)
140
+ count += sprintf(&buf[count], "%d(not avalible), ", aicbsp_info.hwinfo_r);
141
+ else
142
+ count += sprintf(&buf[count], "0x%02X, ", aicbsp_info.hwinfo_r);
143
+
144
+ if (aicbsp_info.hwinfo < 0)
145
+ count += sprintf(&buf[count], "set: %d(not avalible)\n", aicbsp_info.hwinfo);
146
+ else
147
+ count += sprintf(&buf[count], "set: 0x%02X\n", aicbsp_info.hwinfo);
148
+
149
+ return count;
150
+}
151
+
152
+static ssize_t hwinfo_store(struct device *dev,
153
+ struct device_attribute *attr, const char *buf, size_t count)
154
+{
155
+ long val;
156
+ int err = kstrtol(buf, 0, &val);
157
+
158
+ if (err) {
159
+ pr_err("invalid input\n");
160
+ return err;
161
+ }
162
+
163
+ if ((val == -1) || (val >= 0 && val <= 0xFF)) {
164
+ aicbsp_info.hwinfo = val;
165
+ } else {
166
+ pr_err("invalid values\n");
167
+ return -EINVAL;
168
+ }
169
+ return count;
170
+}
171
+
172
+static ssize_t fwdebug_show(struct device *dev,
173
+ struct device_attribute *attr, char *buf)
174
+{
175
+ ssize_t count = 0;
176
+
177
+ count += sprintf(&buf[count], "fw log status: %s\n",
178
+ aicbsp_info.fwlog_en ? "on" : "off");
179
+
180
+ return count;
181
+}
182
+
183
+static ssize_t fwdebug_store(struct device *dev,
184
+ struct device_attribute *attr, const char *buf, size_t count)
185
+{
186
+ long val;
187
+ int err = kstrtol(buf, 0, &val);
188
+
189
+ if (err) {
190
+ pr_err("invalid input\n");
191
+ return err;
192
+ }
193
+
194
+ if (val > 1 || val < 0) {
195
+ pr_err("must be 0 or 1\n");
196
+ return -EINVAL;
197
+ }
198
+
199
+ aicbsp_info.fwlog_en = val;
200
+ return count;
201
+}
202
+
203
+static DEVICE_ATTR(cpmode, S_IRUGO | S_IWUSR,
204
+ cpmode_show, cpmode_store);
205
+
206
+static DEVICE_ATTR(hwinfo, S_IRUGO | S_IWUSR,
207
+ hwinfo_show, hwinfo_store);
208
+
209
+static DEVICE_ATTR(fwdebug, S_IRUGO | S_IWUSR,
210
+ fwdebug_show, fwdebug_store);
121211
122212 static struct attribute *aicbsp_attributes[] = {
123
- &dev_attr_aicbsp_mode.attr,
213
+ &dev_attr_cpmode.attr,
214
+ &dev_attr_hwinfo.attr,
215
+ &dev_attr_fwdebug.attr,
124216 NULL,
125217 };
126218
127219 static struct attribute_group aicbsp_attribute_group = {
128
- .name = "driver_mode",
220
+ .name = "aicbsp_info",
129221 .attrs = aicbsp_attributes,
130222 };
223
+
224
+static int aicbt_set_power(void *data, bool blocked)
225
+{
226
+ pr_info("%s: start_block=%d\n", __func__, blocked);
227
+ if (!blocked) {
228
+ aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_ON);
229
+ } else {
230
+ aicbsp_set_subsys(AIC_BLUETOOTH, AIC_PWR_OFF);
231
+ }
232
+
233
+ pr_info("%s: end_block=%d\n", __func__, blocked);
234
+ return 0;
235
+}
236
+
237
+static struct rfkill_ops aicbt_rfkill_ops = {
238
+ .set_block = aicbt_set_power,
239
+};
240
+
241
+static struct rfkill *aicbt_rfk;
242
+
243
+static int aicbt_rfkill_init(struct platform_device *pdev)
244
+{
245
+ int rc = 0;
246
+
247
+ pr_info("-->%s\n", __func__);
248
+ aicbt_rfk = rfkill_alloc("bluetooth", &pdev->dev, RFKILL_TYPE_BLUETOOTH,
249
+ &aicbt_rfkill_ops, NULL);
250
+ if (!aicbt_rfk) {
251
+ rc = -ENOMEM;
252
+ goto err_rfkill_alloc;
253
+ }
254
+ /* userspace cannot take exclusive control */
255
+ rfkill_init_sw_state(aicbt_rfk, true);
256
+ rc = rfkill_register(aicbt_rfk);
257
+ if (rc)
258
+ goto err_rfkill_reg;
259
+
260
+ pr_info("<--%s\n", __func__);
261
+
262
+ return 0;
263
+
264
+err_rfkill_reg:
265
+ rfkill_destroy(aicbt_rfk);
266
+err_rfkill_alloc:
267
+ return rc;
268
+}
269
+
270
+static int aicbt_rfkill_remove(struct platform_device *dev)
271
+{
272
+ pr_info("-->%s\n", __func__);
273
+ rfkill_unregister(aicbt_rfk);
274
+ rfkill_destroy(aicbt_rfk);
275
+ pr_info("<--%s\n", __func__);
276
+ return 0;
277
+}
131278
132279 static int __init aicbsp_init(void)
133280 {
134281 int ret;
135282 printk("%s\n", __func__);
283
+ printk("%s, Driver Release Tag: %s\n", __func__, DRV_RELEASE_TAG);
284
+
285
+ aicbsp_resv_mem_init();
286
+ mutex_init(&aicbsp_power_lock);
136287 ret = platform_driver_register(&aicbsp_driver);
137288 if (ret) {
138289 pr_err("register platform driver failed: %d\n", ret);
139
- return ret;
290
+ goto err0;
140291 }
141292
142293 aicbsp_pdev = platform_device_alloc("aic-bsp", -1);
143294 ret = platform_device_add(aicbsp_pdev);
144295 if (ret) {
145296 pr_err("register platform device failed: %d\n", ret);
146
- return ret;
297
+ goto err1;
147298 }
148299
149300 ret = sysfs_create_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
150301 if (ret) {
151302 pr_err("register sysfs create group failed!\n");
152
- return ret;
303
+ goto err2;
153304 }
154305
155
- mutex_init(&aicbsp_power_lock);
306
+ if (test_enable == 1) {
307
+ aicbsp_info.cpmode = AICBSP_CPMODE_TEST,
308
+ printk("aicbsp: Test mode enable!!!\n");
309
+ }
310
+
311
+ ret = aicbt_rfkill_init(aicbsp_pdev);
312
+ if (ret) {
313
+ pr_err("register rfkill fail\n");
314
+ goto err3;
315
+ }
156316
157317 return 0;
318
+
319
+err3:
320
+ sysfs_remove_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
321
+err2:
322
+ platform_device_del(aicbsp_pdev);
323
+err1:
324
+ platform_driver_unregister(&aicbsp_driver);
325
+err0:
326
+ mutex_destroy(&aicbsp_power_lock);
327
+ aicbsp_resv_mem_deinit();
328
+ return ret;
158329 }
159330
160331 static void __exit aicbsp_exit(void)
161332 {
333
+ aicbt_rfkill_remove(aicbsp_pdev);
162334 sysfs_remove_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group);
163335 platform_device_del(aicbsp_pdev);
164336 platform_driver_unregister(&aicbsp_driver);
165337 mutex_destroy(&aicbsp_power_lock);
338
+ aicbsp_resv_mem_deinit();
166339 printk("%s\n", __func__);
167340 }
168341