1/* 2 * Shared Transport driver 3 * HCI-LL module responsible for TI proprietary HCI_LL protocol 4 * Copyright (C) 2009 Texas Instruments 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 */ 20 21#define pr_fmt(fmt) "(stll) :" fmt 22#include "st_ll.h" 23 24/**********************************************************************/ 25/* internal functions */ 26static void send_ll_cmd(struct st_data_s *st_data, 27 unsigned char cmd) 28{ 29 30 pr_info("%s: writing %x", __func__, cmd); 31 st_int_write(st_data, &cmd, 1); 32 return; 33} 34 35static void ll_device_want_to_sleep(struct st_data_s *st_data) 36{ 37 pr_debug("%s", __func__); 38 /* sanity check */ 39 if (st_data->ll_state != ST_LL_AWAKE) 40 pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND" 41 "in state %ld", st_data->ll_state); 42 43 send_ll_cmd(st_data, LL_SLEEP_ACK); 44 /* update state */ 45 st_data->ll_state = ST_LL_ASLEEP; 46} 47 48static void ll_device_want_to_wakeup(struct st_data_s *st_data) 49{ 50 /* diff actions in diff states */ 51 switch (st_data->ll_state) { 52 case ST_LL_ASLEEP: 53 send_ll_cmd(st_data, LL_WAKE_UP_ACK); /* send wake_ack */ 54 break; 55 case ST_LL_ASLEEP_TO_AWAKE: 56 /* duplicate wake_ind */ 57 pr_err("duplicate wake_ind while waiting for Wake ack"); 58 break; 59 case ST_LL_AWAKE: 60 /* duplicate wake_ind */ 61 pr_err("duplicate wake_ind already AWAKE"); 62 break; 63 case ST_LL_AWAKE_TO_ASLEEP: 64 /* duplicate wake_ind */ 65 pr_err("duplicate wake_ind"); 66 break; 67 } 68 /* update state */ 69 st_data->ll_state = ST_LL_AWAKE; 70} 71 72/**********************************************************************/ 73/* functions invoked by ST Core */ 74 75/* called when ST Core wants to 76 * enable ST LL */ 77void st_ll_enable(struct st_data_s *ll) 78{ 79 ll->ll_state = ST_LL_AWAKE; 80} 81 82/* called when ST Core /local module wants to 83 * disable ST LL */ 84void st_ll_disable(struct st_data_s *ll) 85{ 86 ll->ll_state = ST_LL_INVALID; 87} 88 89/* called when ST Core wants to update the state */ 90void st_ll_wakeup(struct st_data_s *ll) 91{ 92 if (likely(ll->ll_state != ST_LL_AWAKE)) { 93 send_ll_cmd(ll, LL_WAKE_UP_IND); /* WAKE_IND */ 94 ll->ll_state = ST_LL_ASLEEP_TO_AWAKE; 95 } else { 96 /* don't send the duplicate wake_indication */ 97 pr_err(" Chip already AWAKE "); 98 } 99} 100 101/* called when ST Core wants the state */ 102unsigned long st_ll_getstate(struct st_data_s *ll) 103{ 104 pr_debug(" returning state %ld", ll->ll_state); 105 return ll->ll_state; 106} 107 108/* called from ST Core, when a PM related packet arrives */ 109unsigned long st_ll_sleep_state(struct st_data_s *st_data, 110 unsigned char cmd) 111{ 112 switch (cmd) { 113 case LL_SLEEP_IND: /* sleep ind */ 114 pr_info("sleep indication recvd"); 115 ll_device_want_to_sleep(st_data); 116 break; 117 case LL_SLEEP_ACK: /* sleep ack */ 118 pr_err("sleep ack rcvd: host shouldn't"); 119 break; 120 case LL_WAKE_UP_IND: /* wake ind */ 121 pr_info("wake indication recvd"); 122 ll_device_want_to_wakeup(st_data); 123 break; 124 case LL_WAKE_UP_ACK: /* wake ack */ 125 pr_info("wake ack rcvd"); 126 st_data->ll_state = ST_LL_AWAKE; 127 break; 128 default: 129 pr_err(" unknown input/state "); 130 return -1; 131 } 132 return 0; 133} 134 135/* Called from ST CORE to initialize ST LL */ 136long st_ll_init(struct st_data_s *ll) 137{ 138 /* set state to invalid */ 139 ll->ll_state = ST_LL_INVALID; 140 return 0; 141} 142 143/* Called from ST CORE to de-initialize ST LL */ 144long st_ll_deinit(struct st_data_s *ll) 145{ 146 return 0; 147} 148