drm/cma: Cocci spatch "ptr_ret.spatch"
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / bluetooth / sprd_lpm.c
1 #include <linux/module.h>
2 #include <linux/errno.h>
3 #include <linux/init.h>
4 #include <linux/kernel.h>
5 #include <linux/proc_fs.h>
6 #include <linux/uaccess.h>
7 #include <linux/ioport.h>//
8 #include <linux/param.h> //
9 #include <linux/bitops.h>//
10 #include <linux/gpio.h>
11 #include <linux/hrtimer.h>
12 #include <linux/seq_file.h>
13 #include <net/bluetooth/bluetooth.h>
14 #include <linux/wakelock.h>
15
16 #include <linux/export.h>
17
18
19 #define BT_SLEEP_DBG BT_ERR
20
21 #define PROC_DIR        "bluetooth/sleep"
22
23 extern int set_marlin_wakeup(unsigned int chn,unsigned int user_id);
24 extern int set_marlin_sleep(unsigned int chn,unsigned int user_id);
25
26 struct proc_dir_entry *bluetooth_dir, *sleep_dir;
27
28 struct sprd_bt_lpm {
29         struct hrtimer enter_lpm_timer;
30         ktime_t enter_lpm_delay;
31
32         struct uart_port *uport;
33
34         struct wake_lock BT_wakelock;
35         int bt_wake_state;
36 } bt_lpm;
37
38 void bt_wakeup(unsigned int chn,unsigned int user_id)
39 {
40         set_marlin_wakeup(chn,user_id);
41 }
42 void bt_sleep(unsigned int chn,unsigned int user_id)
43 {
44         return;
45 }
46
47 static enum hrtimer_restart enter_lpm(struct hrtimer *timer)
48 {
49         wake_lock_timeout(&bt_lpm.BT_wakelock, HZ/2);
50
51         return HRTIMER_NORESTART;
52 }
53
54 void sprd_bt_lpm_exit_lpm_locked(struct uart_port *uport)
55 {
56         bt_lpm.uport = uport;
57
58         hrtimer_try_to_cancel(&bt_lpm.enter_lpm_timer);
59
60         wake_lock(&bt_lpm.BT_wakelock);
61         bt_wakeup(0xff,0x2);//set_marlin_wakeup(0xff,0x2)
62
63         hrtimer_start(&bt_lpm.enter_lpm_timer, bt_lpm.enter_lpm_delay,
64                 HRTIMER_MODE_REL);
65 }
66 EXPORT_SYMBOL(sprd_bt_lpm_exit_lpm_locked);
67
68 static ssize_t bluesleep_write_proc_btwrite(struct file *file, const char __user *buffer,size_t count, loff_t *pos)
69 {
70         char b;
71         //BT_ERR("bluesleep_write_proc_btwrite");
72
73         if (count < 1)
74                 return -EINVAL;
75
76         if (copy_from_user(&b, buffer, 1))
77                 return -EFAULT;
78         BT_ERR("bluesleep_write_proc_btwrite=%d",b);
79
80         if(b == '1')
81         {
82                 wake_lock(&bt_lpm.BT_wakelock);
83                 bt_wakeup(0xff,0x2);//set_marlin_wakeup(0xff,0x2)
84         }
85         else if(b=='2')
86                 wake_unlock(&bt_lpm.BT_wakelock);
87         else
88                 BT_ERR("bludroid pass a unsupport parameter");
89                 //bt_sleep(0xff,0x2);//set_marlin_sleep(0xff ,0x2)
90         return count;
91 }
92 static int btwrite_proc_show(struct seq_file * m,void * v)
93 {
94         //unsigned int btwrite;
95         BT_ERR("bluesleep_read_proc_lpm\n");
96         seq_printf(m, "unsupported to read\n");
97         return 0;
98 }
99
100 static int bluesleep_open_proc_btwrite(struct inode *inode, struct file *file)
101 {
102         return single_open(file, btwrite_proc_show, PDE_DATA(inode));
103
104 }
105
106
107 static const struct file_operations lpm_proc_btwrite_fops = {
108         .owner = THIS_MODULE,
109         .open = bluesleep_open_proc_btwrite,
110         .read = seq_read,
111         .write = bluesleep_write_proc_btwrite,
112         .release = single_release,
113 };
114
115
116 static int __init bluesleep_init(void)
117 {
118         int retval;
119         struct proc_dir_entry *ent;
120         bluetooth_dir = proc_mkdir("bluetooth", NULL);
121         if (bluetooth_dir == NULL) {
122                 BT_SLEEP_DBG("Unable to create /proc/bluetooth directory");
123                 return -ENOMEM;
124         }
125         sleep_dir = proc_mkdir("sleep", bluetooth_dir);
126         if (sleep_dir == NULL) {
127                 BT_SLEEP_DBG("Unable to create /proc/%s directory", PROC_DIR);
128                 return -ENOMEM;
129         }
130
131         /* Creating read/write  entry */
132         ent=proc_create("btwrite", S_IRUGO | S_IWUSR | S_IWGRP, sleep_dir,&lpm_proc_btwrite_fops); /*read/write */
133         if (ent == NULL) {
134         BT_SLEEP_DBG("Unable to create /proc/%s/btwake entry", PROC_DIR);
135          retval = -ENOMEM;
136          goto fail;
137         }
138         wake_lock_init(&bt_lpm.BT_wakelock, WAKE_LOCK_SUSPEND, "bluetooth_wakelock");
139
140         hrtimer_init(&bt_lpm.enter_lpm_timer, CLOCK_MONOTONIC,
141                         HRTIMER_MODE_REL);
142         bt_lpm.enter_lpm_delay = ktime_set(10, 0);  /* 1 sec */ /*1->3*//*3->4*/
143         bt_lpm.enter_lpm_timer.function = enter_lpm;
144         bt_lpm.uport = NULL;
145
146         return 0;
147 fail:
148         remove_proc_entry("btwrite", sleep_dir);
149         remove_proc_entry("sleep", bluetooth_dir);
150         remove_proc_entry("bluetooth", 0);
151         wake_lock_destroy(&bt_lpm.BT_wakelock);
152         return retval;
153 }
154
155 static void __exit bluesleep_exit(void)
156 {
157         remove_proc_entry("btwrite", sleep_dir);
158         remove_proc_entry("sleep", bluetooth_dir);
159         remove_proc_entry("bluetooth", 0);
160         wake_lock_destroy(&bt_lpm.BT_wakelock);
161
162 }
163
164 module_init(bluesleep_init);
165 module_exit(bluesleep_exit);
166
167 MODULE_DESCRIPTION("Bluetooth Sleep Mode Driver ver %s " VERSION);
168 //#ifdef MODULE_LICENSE
169 MODULE_LICENSE("GPL");
170 //#endif
171