aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/misc/ti-st/st_ll.c
diff options
context:
space:
mode:
authorPavan Savoy <pavan_savoy@ti.com>2010-10-06 12:18:14 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2010-10-06 11:25:06 -0400
commita0cc2f3b51a8649da5262aba7501dc21738e1b8d (patch)
tree01f5a8a5fa8ef079de806fc192a1a400348d17ea /drivers/misc/ti-st/st_ll.c
parentaecac19179180b7d6cda13f598e314c0870aee80 (diff)
staging: ti-st: move TI_ST from staging to misc/
move the 3 source files st_core.c, st_kim.c and st_ll.c from staging to drivers/misc/. Texas Instrument's WiLink 7 chipset packs wireless technologies like Bluetooth, FM, GPS and WLAN into a single die. Among these the Bluetooth, FM Rx/Tx and GPS are interfaced to a apps processor over a single UART. This line discipline driver allows various protocol drivers such as Bluetooth BlueZ driver, FM V4L2 driver and GPS simple character device driver to communicate with its relevant core in the chip. Each protocol or technologies use a logical channel to communicate with chip. Bluetooth uses the HCI-H4 [channels 1-4], FM uses a CH-8 and GPS a CH-9 protocol. The driver also constitutes the TI HCI-LL Power Management protocol which use channels 30-33. Signed-off-by: Pavan Savoy <pavan_savoy@ti.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/misc/ti-st/st_ll.c')
-rw-r--r--drivers/misc/ti-st/st_ll.c150
1 files changed, 150 insertions, 0 deletions
diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c
new file mode 100644
index 000000000000..2bda8dea15b0
--- /dev/null
+++ b/drivers/misc/ti-st/st_ll.c
@@ -0,0 +1,150 @@
1/*
2 * Shared Transport driver
3 * HCI-LL module responsible for TI proprietary HCI_LL protocol
4 * Copyright (C) 2009-2010 Texas Instruments
5 * Author: Pavan Savoy <pavan_savoy@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#define pr_fmt(fmt) "(stll) :" fmt
23#include <linux/skbuff.h>
24#include <linux/module.h>
25#include <linux/ti_wilink_st.h>
26
27/**********************************************************************/
28/* internal functions */
29static void send_ll_cmd(struct st_data_s *st_data,
30 unsigned char cmd)
31{
32
33 pr_info("%s: writing %x", __func__, cmd);
34 st_int_write(st_data, &cmd, 1);
35 return;
36}
37
38static void ll_device_want_to_sleep(struct st_data_s *st_data)
39{
40 pr_debug("%s", __func__);
41 /* sanity check */
42 if (st_data->ll_state != ST_LL_AWAKE)
43 pr_err("ERR hcill: ST_LL_GO_TO_SLEEP_IND"
44 "in state %ld", st_data->ll_state);
45
46 send_ll_cmd(st_data, LL_SLEEP_ACK);
47 /* update state */
48 st_data->ll_state = ST_LL_ASLEEP;
49}
50
51static void ll_device_want_to_wakeup(struct st_data_s *st_data)
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
75/**********************************************************************/
76/* functions invoked by ST Core */
77
78/* called when ST Core wants to
79 * enable ST LL */
80void st_ll_enable(struct st_data_s *ll)
81{
82 ll->ll_state = ST_LL_AWAKE;
83}
84
85/* called when ST Core /local module wants to
86 * disable ST LL */
87void st_ll_disable(struct st_data_s *ll)
88{
89 ll->ll_state = ST_LL_INVALID;
90}
91
92/* called when ST Core wants to update the state */
93void st_ll_wakeup(struct st_data_s *ll)
94{
95 if (likely(ll->ll_state != ST_LL_AWAKE)) {
96 send_ll_cmd(ll, LL_WAKE_UP_IND); /* WAKE_IND */
97 ll->ll_state = ST_LL_ASLEEP_TO_AWAKE;
98 } else {
99 /* don't send the duplicate wake_indication */
100 pr_err(" Chip already AWAKE ");
101 }
102}
103
104/* called when ST Core wants the state */
105unsigned long st_ll_getstate(struct st_data_s *ll)
106{
107 pr_debug(" returning state %ld", ll->ll_state);
108 return ll->ll_state;
109}
110
111/* called from ST Core, when a PM related packet arrives */
112unsigned long st_ll_sleep_state(struct st_data_s *st_data,
113 unsigned char cmd)
114{
115 switch (cmd) {
116 case LL_SLEEP_IND: /* sleep ind */
117 pr_info("sleep indication recvd");
118 ll_device_want_to_sleep(st_data);
119 break;
120 case LL_SLEEP_ACK: /* sleep ack */
121 pr_err("sleep ack rcvd: host shouldn't");
122 break;
123 case LL_WAKE_UP_IND: /* wake ind */
124 pr_info("wake indication recvd");
125 ll_device_want_to_wakeup(st_data);
126 break;
127 case LL_WAKE_UP_ACK: /* wake ack */
128 pr_info("wake ack rcvd");
129 st_data->ll_state = ST_LL_AWAKE;
130 break;
131 default:
132 pr_err(" unknown input/state ");
133 return -1;
134 }
135 return 0;
136}
137
138/* Called from ST CORE to initialize ST LL */
139long st_ll_init(struct st_data_s *ll)
140{
141 /* set state to invalid */
142 ll->ll_state = ST_LL_INVALID;
143 return 0;
144}
145
146/* Called from ST CORE to de-initialize ST LL */
147long st_ll_deinit(struct st_data_s *ll)
148{
149 return 0;
150}