st_ll.c (3881B)
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 */ 17static 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 26static 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 48static 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 */ 86void 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 */ 93void 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 */ 99void 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 */ 111unsigned 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 */ 118unsigned 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 */ 145long 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 */ 153long st_ll_deinit(struct st_data_s *ll) 154{ 155 return 0; 156}