.. | .. |
---|
17 | 17 | #include <linux/firmware.h> |
---|
18 | 18 | #include <linux/file.h> |
---|
19 | 19 | #include <linux/kernel.h> |
---|
| 20 | +#include <linux/input.h> |
---|
20 | 21 | #include <linux/module.h> |
---|
21 | 22 | #include <linux/mfd/syscon.h> |
---|
22 | 23 | #include <linux/of_gpio.h> |
---|
23 | 24 | #include <linux/of_device.h> |
---|
24 | 25 | #include <linux/platform_device.h> |
---|
| 26 | +#include <linux/proc_fs.h> |
---|
25 | 27 | #include <linux/regulator/consumer.h> |
---|
26 | 28 | #include <linux/regmap.h> |
---|
27 | 29 | #include <linux/slab.h> |
---|
.. | .. |
---|
430 | 432 | * 0x5663000x: Marlin3E series |
---|
431 | 433 | * 0: read chipid fail or not unisoc module |
---|
432 | 434 | */ |
---|
| 435 | + |
---|
| 436 | +#ifdef CONFIG_RK_BOARD |
---|
| 437 | +#define PROC_DIR "bluetooth/sleep" |
---|
| 438 | +static struct proc_dir_entry *bluetooth_dir, *sleep_dir; |
---|
| 439 | +static struct input_dev *power_key_dev; |
---|
| 440 | +static unsigned char enable_power_key = 0; |
---|
| 441 | +#endif |
---|
| 442 | + |
---|
433 | 443 | #define WCN_CHIPID_MASK (0xFFFFF000) |
---|
434 | 444 | unsigned int marlin_get_wcn_chipid(void) |
---|
435 | 445 | { |
---|
.. | .. |
---|
1418 | 1428 | disable_irq(marlin_dev->bt_wake_host_int_num); |
---|
1419 | 1429 | } |
---|
1420 | 1430 | |
---|
| 1431 | +#if defined CONFIG_RK_BOARD |
---|
| 1432 | +static int rkbt_power_key_up(void) |
---|
| 1433 | +{ |
---|
| 1434 | + if (!power_key_dev) |
---|
| 1435 | + return -ENODEV; |
---|
| 1436 | + input_report_key(power_key_dev, KEY_POWER, 1); |
---|
| 1437 | + input_sync(power_key_dev); |
---|
| 1438 | + msleep(20); |
---|
| 1439 | + input_report_key(power_key_dev, KEY_POWER, 0); |
---|
| 1440 | + input_sync(power_key_dev); |
---|
| 1441 | + |
---|
| 1442 | + return 0; |
---|
| 1443 | +} |
---|
| 1444 | + |
---|
| 1445 | +static irqreturn_t rkbt_wake_host_irq_thread(int irq, void *dev) |
---|
| 1446 | +{ |
---|
| 1447 | + rkbt_power_key_up(); |
---|
| 1448 | + |
---|
| 1449 | + return IRQ_HANDLED; |
---|
| 1450 | +} |
---|
| 1451 | + |
---|
| 1452 | +static ssize_t bluesleep_read_proc_powerupkey(struct file *file, |
---|
| 1453 | + char __user *buffer, size_t count, |
---|
| 1454 | + loff_t *data) |
---|
| 1455 | +{ |
---|
| 1456 | + char src[2]; |
---|
| 1457 | + |
---|
| 1458 | + if (*data >= 1) |
---|
| 1459 | + return 0; |
---|
| 1460 | + |
---|
| 1461 | + src[0] = enable_power_key ? '1' : '0'; |
---|
| 1462 | + src[1] = '\n'; |
---|
| 1463 | + if (copy_to_user(buffer, src, 2)) |
---|
| 1464 | + return -EFAULT; |
---|
| 1465 | + *data = 1; |
---|
| 1466 | + |
---|
| 1467 | + return 2; |
---|
| 1468 | +} |
---|
| 1469 | + |
---|
| 1470 | +static ssize_t bluesleep_write_proc_powerupkey(struct file *file, |
---|
| 1471 | + const char __user *buffer, |
---|
| 1472 | + size_t count, loff_t *data) |
---|
| 1473 | +{ |
---|
| 1474 | + char b; |
---|
| 1475 | + |
---|
| 1476 | + if (count < 1) |
---|
| 1477 | + return -EINVAL; |
---|
| 1478 | + |
---|
| 1479 | + if (copy_from_user(&b, buffer, 1)) |
---|
| 1480 | + return -EFAULT; |
---|
| 1481 | + |
---|
| 1482 | + if (b != '0') |
---|
| 1483 | + enable_power_key = 1; |
---|
| 1484 | + else |
---|
| 1485 | + enable_power_key = 0; |
---|
| 1486 | + |
---|
| 1487 | + return count; |
---|
| 1488 | +} |
---|
| 1489 | + |
---|
| 1490 | +static const struct file_operations bluesleep_powerupkey = { |
---|
| 1491 | + .owner = THIS_MODULE, |
---|
| 1492 | + .read = bluesleep_read_proc_powerupkey, |
---|
| 1493 | + .write = bluesleep_write_proc_powerupkey, |
---|
| 1494 | +}; |
---|
| 1495 | + |
---|
| 1496 | +static int rkbt_register_power_key(void) |
---|
| 1497 | +{ |
---|
| 1498 | + int ret = 0; |
---|
| 1499 | + |
---|
| 1500 | + /* register input device */ |
---|
| 1501 | + power_key_dev = input_allocate_device(); |
---|
| 1502 | + if (!power_key_dev) { |
---|
| 1503 | + WCN_ERR("ir_dev: not enough memory for input device\n"); |
---|
| 1504 | + return -ENOMEM; |
---|
| 1505 | + } |
---|
| 1506 | + |
---|
| 1507 | + power_key_dev->name = "bt-powerkey"; |
---|
| 1508 | + power_key_dev->id.bustype = BUS_HOST; |
---|
| 1509 | + |
---|
| 1510 | + power_key_dev->evbit[0] = BIT_MASK(EV_KEY); |
---|
| 1511 | + set_bit(KEY_POWER, power_key_dev->keybit); |
---|
| 1512 | + |
---|
| 1513 | + ret = input_register_device(power_key_dev); |
---|
| 1514 | + if (ret) { |
---|
| 1515 | + input_free_device(power_key_dev); |
---|
| 1516 | + WCN_ERR("ir_rx_init: register input device exception, exit\n"); |
---|
| 1517 | + return -EBUSY; |
---|
| 1518 | + } |
---|
| 1519 | + |
---|
| 1520 | + return ret; |
---|
| 1521 | +} |
---|
| 1522 | +#endif |
---|
| 1523 | + |
---|
1421 | 1524 | static irqreturn_t marlin_bt_wake_int_isr(int irq, void *para) |
---|
1422 | 1525 | { |
---|
1423 | 1526 | static int bt_wake_cnt; |
---|
1424 | 1527 | |
---|
1425 | 1528 | bt_wake_cnt++; |
---|
1426 | 1529 | WCN_DEBUG("bt_wake_irq_cnt %d\n", bt_wake_cnt); |
---|
| 1530 | + |
---|
| 1531 | + #if defined CONFIG_RK_BOARD |
---|
| 1532 | + if (enable_power_key) |
---|
| 1533 | + return IRQ_WAKE_THREAD; |
---|
| 1534 | + #endif |
---|
| 1535 | + |
---|
1427 | 1536 | return IRQ_HANDLED; |
---|
1428 | 1537 | } |
---|
1429 | 1538 | |
---|
.. | .. |
---|
1466 | 1575 | return ret; |
---|
1467 | 1576 | } |
---|
1468 | 1577 | |
---|
| 1578 | + #if defined CONFIG_RK_BOARD |
---|
| 1579 | + ret = request_threaded_irq(marlin_dev->bt_wake_host_int_num, |
---|
| 1580 | + marlin_bt_wake_int_isr, |
---|
| 1581 | + rkbt_wake_host_irq_thread, |
---|
| 1582 | + IRQF_ONESHOT | IRQF_TRIGGER_RISING | |
---|
| 1583 | + IRQF_NO_SUSPEND, |
---|
| 1584 | + "bt_wake_isr", |
---|
| 1585 | + NULL); |
---|
| 1586 | + #else |
---|
1469 | 1587 | ret = request_irq(marlin_dev->bt_wake_host_int_num, |
---|
1470 | 1588 | marlin_bt_wake_int_isr, |
---|
1471 | 1589 | IRQF_TRIGGER_RISING | |
---|
1472 | 1590 | IRQF_NO_SUSPEND, |
---|
1473 | 1591 | "bt_wake_isr", |
---|
1474 | 1592 | NULL); |
---|
| 1593 | + #endif |
---|
1475 | 1594 | if (ret != 0) { |
---|
1476 | 1595 | WCN_ERR("req bt_hostwake irq-%d err! ret=%d", |
---|
1477 | 1596 | marlin_dev->bt_wake_host_int_num, ret); |
---|
.. | .. |
---|
3971 | 4090 | static void marlin_reset_notify_init(void); |
---|
3972 | 4091 | static int marlin_probe(struct platform_device *pdev) |
---|
3973 | 4092 | { |
---|
| 4093 | +#if defined CONFIG_RK_BOARD |
---|
| 4094 | + struct proc_dir_entry *ent; |
---|
| 4095 | +#endif |
---|
3974 | 4096 | #ifdef CONFIG_WCN_PMIC |
---|
3975 | 4097 | struct device_node *regmap_np; |
---|
3976 | 4098 | struct platform_device *pdev_regmap = NULL; |
---|
.. | .. |
---|
4074 | 4196 | marlin_dev->marlin_probe_status = 1; |
---|
4075 | 4197 | #endif |
---|
4076 | 4198 | |
---|
4077 | | - WCN_INFO("marlin_probe ok!\n"); |
---|
| 4199 | +#if defined CONFIG_RK_BOARD |
---|
| 4200 | + bluetooth_dir = proc_mkdir("bluetooth", NULL); |
---|
| 4201 | + if (!bluetooth_dir) { |
---|
| 4202 | + WCN_ERR("Unable to create /proc/bluetooth directory"); |
---|
| 4203 | + return -ENOMEM; |
---|
| 4204 | + } |
---|
4078 | 4205 | |
---|
| 4206 | + sleep_dir = proc_mkdir("sleep", bluetooth_dir); |
---|
| 4207 | + if (!sleep_dir) { |
---|
| 4208 | + WCN_ERR("Unable to create /proc/%s directory", PROC_DIR); |
---|
| 4209 | + return -ENOMEM; |
---|
| 4210 | + } |
---|
| 4211 | + |
---|
| 4212 | + /* read/write proc entries */ |
---|
| 4213 | + ent = proc_create("powerupkey", 0, sleep_dir, &bluesleep_powerupkey); |
---|
| 4214 | + if (!ent) { |
---|
| 4215 | + WCN_ERR("Unable to create /proc/%s/powerupkey entry", PROC_DIR); |
---|
| 4216 | + remove_proc_entry("powerupkey", sleep_dir); |
---|
| 4217 | + return -ENOMEM; |
---|
| 4218 | + } |
---|
| 4219 | + |
---|
| 4220 | + if (rkbt_register_power_key() != 0) { |
---|
| 4221 | + WCN_ERR("Unable to register power_key"); |
---|
| 4222 | + return -EBUSY; |
---|
| 4223 | + } |
---|
| 4224 | +#endif |
---|
| 4225 | + |
---|
| 4226 | + WCN_INFO("marlin_probe ok!\n"); |
---|
4079 | 4227 | return 0; |
---|
4080 | 4228 | } |
---|
4081 | 4229 | |
---|
4082 | 4230 | static int marlin_remove(struct platform_device *pdev) |
---|
4083 | 4231 | { |
---|
| 4232 | +#if defined CONFIG_RK_BOARD |
---|
| 4233 | + input_unregister_device(power_key_dev); |
---|
| 4234 | + remove_proc_entry("powerupkey", sleep_dir); |
---|
| 4235 | +#endif |
---|
| 4236 | + |
---|
4084 | 4237 | #if (defined(CONFIG_BT_WAKE_HOST_EN) && defined(CONFIG_AW_BOARD)) \ |
---|
4085 | 4238 | || defined(CONFIG_RK_BOARD) |
---|
4086 | 4239 | marlin_unregistsr_bt_wake(); |
---|