old mode 100644new mode 100755.. | .. |
---|
5 | 5 | #include <linux/kernel.h> |
---|
6 | 6 | #include <linux/version.h> |
---|
7 | 7 | #include <linux/platform_device.h> |
---|
| 8 | +#include <linux/rfkill.h> |
---|
8 | 9 | #include "aic_bsp_driver.h" |
---|
9 | 10 | |
---|
10 | 11 | #define DRV_DESCRIPTION "AIC BSP" |
---|
.. | .. |
---|
12 | 13 | #define DRV_AUTHOR "AICSemi" |
---|
13 | 14 | #define DRV_VERS_MOD "1.0" |
---|
14 | 15 | |
---|
| 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 | + |
---|
15 | 26 | static struct platform_device *aicbsp_pdev; |
---|
16 | 27 | |
---|
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)", |
---|
20 | 33 | .bt_adid = "fw_adid.bin", |
---|
21 | 34 | .bt_patch = "fw_patch.bin", |
---|
22 | 35 | .bt_table = "fw_patch_table.bin", |
---|
23 | | - .bt_patch_test = NULL, |
---|
24 | 36 | .wl_fw = "fmacfw.bin" |
---|
25 | 37 | }, |
---|
26 | 38 | |
---|
27 | | - [AICBSP_MODE_BT_WIFI_COMBO] = { |
---|
28 | | - .desc = "wifi/bt combo mode", |
---|
| 39 | + [AICBSP_CPMODE_TEST] = { |
---|
| 40 | + .desc = "rf test mode(sdio u02)", |
---|
29 | 41 | .bt_adid = "fw_adid.bin", |
---|
30 | 42 | .bt_patch = "fw_patch.bin", |
---|
31 | 43 | .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", |
---|
60 | 44 | .wl_fw = "fmacfw_rf.bin" |
---|
61 | 45 | }, |
---|
62 | 46 | }; |
---|
63 | 47 | |
---|
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 | + |
---|
65 | 72 | struct mutex aicbsp_power_lock; |
---|
66 | 73 | |
---|
67 | 74 | static struct platform_driver aicbsp_driver = { |
---|
.. | .. |
---|
73 | 80 | //.remove = aicbsp_remove, |
---|
74 | 81 | }; |
---|
75 | 82 | |
---|
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, |
---|
77 | 88 | struct device_attribute *attr, char *buf) |
---|
78 | 89 | { |
---|
79 | 90 | ssize_t count = 0; |
---|
80 | 91 | uint8_t i = 0; |
---|
81 | 92 | |
---|
82 | | - count += sprintf(&buf[count], "Support mode number:\n"); |
---|
| 93 | + count += sprintf(&buf[count], "Support mode value:\n"); |
---|
83 | 94 | |
---|
84 | | - for (i = 0; i < sizeof(aicbsp_firmware_list) / sizeof(aicbsp_firmware_list[0]); i++) { |
---|
| 95 | + for (i = 0; i < AICBSP_CPMODE_MAX; i++) { |
---|
85 | 96 | if (aicbsp_firmware_list[i].desc) |
---|
86 | 97 | count += sprintf(&buf[count], " %2d: %s\n", i, aicbsp_firmware_list[i].desc); |
---|
87 | 98 | } |
---|
88 | 99 | |
---|
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); |
---|
95 | 105 | return count; |
---|
96 | 106 | } |
---|
97 | 107 | |
---|
98 | | -static ssize_t aicbsp_mode_store(struct device *dev, |
---|
| 108 | +static ssize_t cpmode_store(struct device *dev, |
---|
99 | 109 | struct device_attribute *attr, const char *buf, size_t count) |
---|
100 | 110 | { |
---|
101 | 111 | unsigned long val; |
---|
102 | | - uint32_t max; |
---|
103 | 112 | int err = kstrtoul(buf, 0, &val); |
---|
104 | 113 | if (err) |
---|
105 | 114 | return err; |
---|
106 | 115 | |
---|
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); |
---|
110 | 118 | return -EINVAL; |
---|
111 | 119 | } |
---|
112 | 120 | |
---|
113 | | - aicbsp_mode_index = val; |
---|
| 121 | + aicbsp_info.cpmode = val; |
---|
114 | 122 | printk("%s, set mode to: %lu[%s] done\n", __func__, val, aicbsp_firmware_list[val].desc); |
---|
115 | 123 | |
---|
116 | 124 | return count; |
---|
117 | 125 | } |
---|
118 | 126 | |
---|
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); |
---|
121 | 211 | |
---|
122 | 212 | 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, |
---|
124 | 216 | NULL, |
---|
125 | 217 | }; |
---|
126 | 218 | |
---|
127 | 219 | static struct attribute_group aicbsp_attribute_group = { |
---|
128 | | - .name = "driver_mode", |
---|
| 220 | + .name = "aicbsp_info", |
---|
129 | 221 | .attrs = aicbsp_attributes, |
---|
130 | 222 | }; |
---|
| 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 | +} |
---|
131 | 278 | |
---|
132 | 279 | static int __init aicbsp_init(void) |
---|
133 | 280 | { |
---|
134 | 281 | int ret; |
---|
135 | 282 | 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); |
---|
136 | 287 | ret = platform_driver_register(&aicbsp_driver); |
---|
137 | 288 | if (ret) { |
---|
138 | 289 | pr_err("register platform driver failed: %d\n", ret); |
---|
139 | | - return ret; |
---|
| 290 | + goto err0; |
---|
140 | 291 | } |
---|
141 | 292 | |
---|
142 | 293 | aicbsp_pdev = platform_device_alloc("aic-bsp", -1); |
---|
143 | 294 | ret = platform_device_add(aicbsp_pdev); |
---|
144 | 295 | if (ret) { |
---|
145 | 296 | pr_err("register platform device failed: %d\n", ret); |
---|
146 | | - return ret; |
---|
| 297 | + goto err1; |
---|
147 | 298 | } |
---|
148 | 299 | |
---|
149 | 300 | ret = sysfs_create_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group); |
---|
150 | 301 | if (ret) { |
---|
151 | 302 | pr_err("register sysfs create group failed!\n"); |
---|
152 | | - return ret; |
---|
| 303 | + goto err2; |
---|
153 | 304 | } |
---|
154 | 305 | |
---|
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 | + } |
---|
156 | 316 | |
---|
157 | 317 | 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; |
---|
158 | 329 | } |
---|
159 | 330 | |
---|
160 | 331 | static void __exit aicbsp_exit(void) |
---|
161 | 332 | { |
---|
| 333 | + aicbt_rfkill_remove(aicbsp_pdev); |
---|
162 | 334 | sysfs_remove_group(&(aicbsp_pdev->dev.kobj), &aicbsp_attribute_group); |
---|
163 | 335 | platform_device_del(aicbsp_pdev); |
---|
164 | 336 | platform_driver_unregister(&aicbsp_driver); |
---|
165 | 337 | mutex_destroy(&aicbsp_power_lock); |
---|
| 338 | + aicbsp_resv_mem_deinit(); |
---|
166 | 339 | printk("%s\n", __func__); |
---|
167 | 340 | } |
---|
168 | 341 | |
---|