• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/ti-st/
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