root/drivers/misc/ti-st/st_ll.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. send_ll_cmd
  2. ll_device_want_to_sleep
  3. ll_device_want_to_wakeup
  4. st_ll_enable
  5. st_ll_disable
  6. st_ll_wakeup
  7. st_ll_getstate
  8. st_ll_sleep_state
  9. st_ll_init
  10. st_ll_deinit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *  Shared Transport driver
   4  *      HCI-LL module responsible for TI proprietary HCI_LL protocol
   5  *  Copyright (C) 2009-2010 Texas Instruments
   6  *  Author: Pavan Savoy <pavan_savoy@ti.com>
   7  */
   8 
   9 #define pr_fmt(fmt) "(stll) :" fmt
  10 #include <linux/skbuff.h>
  11 #include <linux/module.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/ti_wilink_st.h>
  14 
  15 /**********************************************************************/
  16 /* internal functions */
  17 static void send_ll_cmd(struct st_data_s *st_data,
  18         unsigned char cmd)
  19 {
  20 
  21         pr_debug("%s: writing %x", __func__, cmd);
  22         st_int_write(st_data, &cmd, 1);
  23         return;
  24 }
  25 
  26 static void ll_device_want_to_sleep(struct st_data_s *st_data)
  27 {
  28         struct kim_data_s       *kim_data;
  29         struct ti_st_plat_data  *pdata;
  30 
  31         pr_debug("%s", __func__);
  32         /* sanity check */
  33         if (st_data->ll_state != ST_LL_AWAKE)
  34                 pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND"
  35                           "in state %ld", st_data->ll_state);
  36 
  37         send_ll_cmd(st_data, LL_SLEEP_ACK);
  38         /* update state */
  39         st_data->ll_state = ST_LL_ASLEEP;
  40 
  41         /* communicate to platform about chip asleep */
  42         kim_data = st_data->kim_data;
  43         pdata = kim_data->kim_pdev->dev.platform_data;
  44         if (pdata->chip_asleep)
  45                 pdata->chip_asleep(NULL);
  46 }
  47 
  48 static void ll_device_want_to_wakeup(struct st_data_s *st_data)
  49 {
  50         struct kim_data_s       *kim_data;
  51         struct ti_st_plat_data  *pdata;
  52 
  53         /* diff actions in diff states */
  54         switch (st_data->ll_state) {
  55         case ST_LL_ASLEEP:
  56                 send_ll_cmd(st_data, LL_WAKE_UP_ACK);   /* send wake_ack */
  57                 break;
  58         case ST_LL_ASLEEP_TO_AWAKE:
  59                 /* duplicate wake_ind */
  60                 pr_err("duplicate wake_ind while waiting for Wake ack");
  61                 break;
  62         case ST_LL_AWAKE:
  63                 /* duplicate wake_ind */
  64                 pr_err("duplicate wake_ind already AWAKE");
  65                 break;
  66         case ST_LL_AWAKE_TO_ASLEEP:
  67                 /* duplicate wake_ind */
  68                 pr_err("duplicate wake_ind");
  69                 break;
  70         }
  71         /* update state */
  72         st_data->ll_state = ST_LL_AWAKE;
  73 
  74         /* communicate to platform about chip wakeup */
  75         kim_data = st_data->kim_data;
  76         pdata = kim_data->kim_pdev->dev.platform_data;
  77         if (pdata->chip_awake)
  78                 pdata->chip_awake(NULL);
  79 }
  80 
  81 /**********************************************************************/
  82 /* functions invoked by ST Core */
  83 
  84 /* called when ST Core wants to
  85  * enable ST LL */
  86 void st_ll_enable(struct st_data_s *ll)
  87 {
  88         ll->ll_state = ST_LL_AWAKE;
  89 }
  90 
  91 /* called when ST Core /local module wants to
  92  * disable ST LL */
  93 void st_ll_disable(struct st_data_s *ll)
  94 {
  95         ll->ll_state = ST_LL_INVALID;
  96 }
  97 
  98 /* called when ST Core wants to update the state */
  99 void st_ll_wakeup(struct st_data_s *ll)
 100 {
 101         if (likely(ll->ll_state != ST_LL_AWAKE)) {
 102                 send_ll_cmd(ll, LL_WAKE_UP_IND);        /* WAKE_IND */
 103                 ll->ll_state = ST_LL_ASLEEP_TO_AWAKE;
 104         } else {
 105                 /* don't send the duplicate wake_indication */
 106                 pr_err(" Chip already AWAKE ");
 107         }
 108 }
 109 
 110 /* called when ST Core wants the state */
 111 unsigned long st_ll_getstate(struct st_data_s *ll)
 112 {
 113         pr_debug(" returning state %ld", ll->ll_state);
 114         return ll->ll_state;
 115 }
 116 
 117 /* called from ST Core, when a PM related packet arrives */
 118 unsigned long st_ll_sleep_state(struct st_data_s *st_data,
 119         unsigned char cmd)
 120 {
 121         switch (cmd) {
 122         case LL_SLEEP_IND:      /* sleep ind */
 123                 pr_debug("sleep indication recvd");
 124                 ll_device_want_to_sleep(st_data);
 125                 break;
 126         case LL_SLEEP_ACK:      /* sleep ack */
 127                 pr_err("sleep ack rcvd: host shouldn't");
 128                 break;
 129         case LL_WAKE_UP_IND:    /* wake ind */
 130                 pr_debug("wake indication recvd");
 131                 ll_device_want_to_wakeup(st_data);
 132                 break;
 133         case LL_WAKE_UP_ACK:    /* wake ack */
 134                 pr_debug("wake ack rcvd");
 135                 st_data->ll_state = ST_LL_AWAKE;
 136                 break;
 137         default:
 138                 pr_err(" unknown input/state ");
 139                 return -EINVAL;
 140         }
 141         return 0;
 142 }
 143 
 144 /* Called from ST CORE to initialize ST LL */
 145 long st_ll_init(struct st_data_s *ll)
 146 {
 147         /* set state to invalid */
 148         ll->ll_state = ST_LL_INVALID;
 149         return 0;
 150 }
 151 
 152 /* Called from ST CORE to de-initialize ST LL */
 153 long st_ll_deinit(struct st_data_s *ll)
 154 {
 155         return 0;
 156 }

/* [<][>][^][v][top][bottom][index][help] */