1616#include <linux/crc8.h>
1717#include <linux/crc32.h>
1818#include <linux/string_helpers.h>
19+ #include <linux/gpio/consumer.h>
1920
2021#include <net/bluetooth/bluetooth.h>
2122#include <net/bluetooth/hci_core.h>
8283#define WAKEUP_METHOD_BREAK 1
8384#define WAKEUP_METHOD_EXT_BREAK 2
8485#define WAKEUP_METHOD_RTS 3
86+ #define WAKEUP_METHOD_GPIO 4
8587#define WAKEUP_METHOD_INVALID 0xff
8688
8789/* power save mode status */
@@ -135,6 +137,7 @@ struct ps_data {
135137 bool driver_sent_cmd ;
136138 u16 h2c_ps_interval ;
137139 u16 c2h_ps_interval ;
140+ struct gpio_desc * h2c_ps_gpio ;
138141 struct hci_dev * hdev ;
139142 struct work_struct work ;
140143 struct timer_list ps_timer ;
@@ -365,14 +368,22 @@ static void ps_control(struct hci_dev *hdev, u8 ps_state)
365368{
366369 struct btnxpuart_dev * nxpdev = hci_get_drvdata (hdev );
367370 struct ps_data * psdata = & nxpdev -> psdata ;
368- int status ;
371+ int status = 0 ;
369372
370373 if (psdata -> ps_state == ps_state ||
371374 !test_bit (BTNXPUART_SERDEV_OPEN , & nxpdev -> tx_state ))
372375 return ;
373376
374377 mutex_lock (& psdata -> ps_lock );
375378 switch (psdata -> cur_h2c_wakeupmode ) {
379+ case WAKEUP_METHOD_GPIO :
380+ if (ps_state == PS_STATE_AWAKE )
381+ gpiod_set_value_cansleep (psdata -> h2c_ps_gpio , 0 );
382+ else
383+ gpiod_set_value_cansleep (psdata -> h2c_ps_gpio , 1 );
384+ bt_dev_dbg (hdev , "Set h2c_ps_gpio: %s" ,
385+ str_high_low (ps_state == PS_STATE_SLEEP ));
386+ break ;
376387 case WAKEUP_METHOD_DTR :
377388 if (ps_state == PS_STATE_AWAKE )
378389 status = serdev_device_set_tiocm (nxpdev -> serdev , TIOCM_DTR , 0 );
@@ -422,15 +433,29 @@ static void ps_timeout_func(struct timer_list *t)
422433 }
423434}
424435
425- static void ps_setup (struct hci_dev * hdev )
436+ static int ps_setup (struct hci_dev * hdev )
426437{
427438 struct btnxpuart_dev * nxpdev = hci_get_drvdata (hdev );
439+ struct serdev_device * serdev = nxpdev -> serdev ;
428440 struct ps_data * psdata = & nxpdev -> psdata ;
429441
442+ psdata -> h2c_ps_gpio = devm_gpiod_get_optional (& serdev -> dev , "device-wakeup" ,
443+ GPIOD_OUT_LOW );
444+ if (IS_ERR (psdata -> h2c_ps_gpio )) {
445+ bt_dev_err (hdev , "Error fetching device-wakeup-gpios: %ld" ,
446+ PTR_ERR (psdata -> h2c_ps_gpio ));
447+ return PTR_ERR (psdata -> h2c_ps_gpio );
448+ }
449+
450+ if (!psdata -> h2c_ps_gpio )
451+ psdata -> h2c_wakeup_gpio = 0xff ;
452+
430453 psdata -> hdev = hdev ;
431454 INIT_WORK (& psdata -> work , ps_work_func );
432455 mutex_init (& psdata -> ps_lock );
433456 timer_setup (& psdata -> ps_timer , ps_timeout_func , 0 );
457+
458+ return 0 ;
434459}
435460
436461static bool ps_wakeup (struct btnxpuart_dev * nxpdev )
@@ -516,6 +541,9 @@ static int send_wakeup_method_cmd(struct hci_dev *hdev, void *data)
516541 pcmd .c2h_wakeupmode = psdata -> c2h_wakeupmode ;
517542 pcmd .c2h_wakeup_gpio = psdata -> c2h_wakeup_gpio ;
518543 switch (psdata -> h2c_wakeupmode ) {
544+ case WAKEUP_METHOD_GPIO :
545+ pcmd .h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_GPIO ;
546+ break ;
519547 case WAKEUP_METHOD_DTR :
520548 pcmd .h2c_wakeupmode = BT_CTRL_WAKEUP_METHOD_DSR ;
521549 break ;
@@ -550,6 +578,7 @@ static void ps_init(struct hci_dev *hdev)
550578{
551579 struct btnxpuart_dev * nxpdev = hci_get_drvdata (hdev );
552580 struct ps_data * psdata = & nxpdev -> psdata ;
581+ u8 default_h2c_wakeup_mode = DEFAULT_H2C_WAKEUP_MODE ;
553582
554583 serdev_device_set_tiocm (nxpdev -> serdev , 0 , TIOCM_RTS );
555584 usleep_range (5000 , 10000 );
@@ -561,8 +590,17 @@ static void ps_init(struct hci_dev *hdev)
561590 psdata -> c2h_wakeup_gpio = 0xff ;
562591
563592 psdata -> cur_h2c_wakeupmode = WAKEUP_METHOD_INVALID ;
593+ if (psdata -> h2c_ps_gpio )
594+ default_h2c_wakeup_mode = WAKEUP_METHOD_GPIO ;
595+
564596 psdata -> h2c_ps_interval = PS_DEFAULT_TIMEOUT_PERIOD_MS ;
565- switch (DEFAULT_H2C_WAKEUP_MODE ) {
597+
598+ switch (default_h2c_wakeup_mode ) {
599+ case WAKEUP_METHOD_GPIO :
600+ psdata -> h2c_wakeupmode = WAKEUP_METHOD_GPIO ;
601+ gpiod_set_value_cansleep (psdata -> h2c_ps_gpio , 0 );
602+ usleep_range (5000 , 10000 );
603+ break ;
566604 case WAKEUP_METHOD_DTR :
567605 psdata -> h2c_wakeupmode = WAKEUP_METHOD_DTR ;
568606 serdev_device_set_tiocm (nxpdev -> serdev , 0 , TIOCM_DTR );
@@ -1279,6 +1317,9 @@ static int nxp_enqueue(struct hci_dev *hdev, struct sk_buff *skb)
12791317 psdata -> c2h_wakeup_gpio = wakeup_parm .c2h_wakeup_gpio ;
12801318 psdata -> h2c_wakeup_gpio = wakeup_parm .h2c_wakeup_gpio ;
12811319 switch (wakeup_parm .h2c_wakeupmode ) {
1320+ case BT_CTRL_WAKEUP_METHOD_GPIO :
1321+ psdata -> h2c_wakeupmode = WAKEUP_METHOD_GPIO ;
1322+ break ;
12821323 case BT_CTRL_WAKEUP_METHOD_DSR :
12831324 psdata -> h2c_wakeupmode = WAKEUP_METHOD_DTR ;
12841325 break ;
@@ -1509,13 +1550,17 @@ static int nxp_serdev_probe(struct serdev_device *serdev)
15091550
15101551 if (hci_register_dev (hdev ) < 0 ) {
15111552 dev_err (& serdev -> dev , "Can't register HCI device\n" );
1512- hci_free_dev (hdev );
1513- return - ENODEV ;
1553+ goto probe_fail ;
15141554 }
15151555
1516- ps_setup (hdev );
1556+ if (ps_setup (hdev ))
1557+ goto probe_fail ;
15171558
15181559 return 0 ;
1560+
1561+ probe_fail :
1562+ hci_free_dev (hdev );
1563+ return - ENODEV ;
15191564}
15201565
15211566static void nxp_serdev_remove (struct serdev_device * serdev )
0 commit comments