drivers: make tegra-throughput driver always post fps
[linux-2.6.git] / drivers / misc / tegra-baseband / bb-oem1.c
1 /*
2  * drivers/misc/tegra-baseband/bb-oem1.c
3  *
4  * Copyright (c) 2012, NVIDIA Corporation.
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 as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 #include <linux/resource.h>
22 #include <linux/platform_device.h>
23 #include <linux/delay.h>
24 #include <linux/gpio.h>
25 #include <linux/interrupt.h>
26 #include <linux/irq.h>
27 #include <linux/err.h>
28 #include <linux/device.h>
29 #include <linux/usb.h>
30 #include <linux/wakelock.h>
31 #include <linux/suspend.h>
32 #include <linux/platform_data/tegra_usb.h>
33 #include <linux/regulator/consumer.h>
34 #include <asm/mach-types.h>
35 #include <asm/mach/arch.h>
36 #include <mach/tegra-bb-power.h>
37 #include <mach/usb_phy.h>
38 #include "bb-power.h"
39 #include "bb-oem1.h"
40
41 #define WAKE_TIMEOUT_MS 50
42
43 static struct tegra_bb_gpio_data bb_gpios[] = {
44         { { GPIO_INVALID, GPIOF_OUT_INIT_LOW, "MDM4_RST" }, true },
45         { { GPIO_INVALID, GPIOF_OUT_INIT_LOW, "MDM4_ON" }, true },
46         { { GPIO_INVALID, GPIOF_OUT_INIT_LOW, "MDM4_USB_AWR" }, true },
47         { { GPIO_INVALID, GPIOF_IN, "MDM4_USB_CWR" }, true },
48         { { GPIO_INVALID, GPIOF_IN, "MDM4_SPARE" }, true },
49         { { GPIO_INVALID, GPIOF_IN, "MDM4_WDI" }, true },
50         { { GPIO_INVALID, 0, NULL }, false },   /* End of table */
51 };
52
53 static struct sdata bb_sdata;
54 static struct opsdata bb_opdata;
55 static struct locks bb_locks;
56 static struct regulator *hsic_reg;
57 static bool ehci_registered;
58 static int dlevel;
59
60 static int gpio_wait_timeout(int gpio, int value, int timeout_msec)
61 {
62         int count;
63         for (count = 0; count < timeout_msec; ++count) {
64                 if (gpio_get_value(gpio) == value)
65                         return 0;
66                 mdelay(1);
67         }
68         return -1;
69 }
70
71 static void bb_setdata(struct opsdata *data)
72 {
73         unsigned long flags;
74
75         spin_lock_irqsave(&bb_locks.lock, flags);
76         if (data) {
77                 if (data->powerstate != bb_opdata.powerstate)
78                         bb_opdata.powerstate = data->powerstate;
79                 if (data->usbdev != bb_opdata.usbdev)
80                         bb_opdata.usbdev = data->usbdev;
81         }
82         spin_unlock_irqrestore(&bb_locks.lock, flags);
83
84         if (data->powerstate == BBSTATE_UNKNOWN) {
85                 if (!wake_lock_active(&bb_locks.wlock)) {
86                         wake_lock(&bb_locks.wlock);
87                         if (dlevel & DLEVEL_MISC)
88                                 pr_info("%s: Taking wakelock.\n", __func__);
89                 } else
90                         pr_warn("%s: Active wakelock in UNK\n", __func__);
91         } else {
92                 if (wake_lock_active(&bb_locks.wlock)) {
93                         wake_unlock(&bb_locks.wlock);
94                         if (dlevel & DLEVEL_MISC)
95                                 pr_info("%s: Releasing wakelock.\n", __func__);
96                 }
97         }
98 }
99
100 static void bb_getdata(struct opsdata *data)
101 {
102         unsigned long flags;
103
104         spin_lock_irqsave(&bb_locks.lock, flags);
105         if (data) {
106                 data->powerstate = bb_opdata.powerstate;
107                 data->usbdev = bb_opdata.usbdev;
108         }
109         spin_unlock_irqrestore(&bb_locks.lock, flags);
110 }
111
112 static int bb_getpowerstate(void)
113 {
114         struct opsdata data;
115
116         bb_getdata(&data);
117         return data.powerstate;
118 }
119
120 static void bb_setpowerstate(int status)
121 {
122         struct opsdata data;
123
124         bb_getdata(&data);
125         data.powerstate = status;
126         bb_setdata(&data);
127 }
128
129 static bool bb_crashed(void)
130 {
131         bool flag;
132
133         flag = ((gpio_get_value(bb_sdata.gpio_wdi)) ? false : true);
134         return flag;
135 }
136
137 static bool bb_get_cwr(void)
138 {
139         return gpio_get_value(bb_sdata.gpio_cwr);
140 }
141
142 static void bb_set_awr(int value)
143 {
144         gpio_set_value(bb_sdata.gpio_awr, value);
145 }
146
147 static void bb_gpio_stat(void)
148 {
149         pr_info("%s: AWR:%d, CWR:%d, WDI:%d.\n", __func__,
150                 gpio_get_value(bb_sdata.gpio_awr),
151                 gpio_get_value(bb_sdata.gpio_cwr),
152                 gpio_get_value(bb_sdata.gpio_wdi));
153 }
154
155 static int apup_handshake(bool checkresponse)
156 {
157         int retval = 0;
158
159         /* Signal AP ready - Drive USB_AWR high. */
160         bb_set_awr(1);
161
162         if (checkresponse) {
163                 /* Wait for CP ack - by driving USB_CWR high. */
164                 if (gpio_wait_timeout(bb_sdata.gpio_cwr, 1,
165                                         WAKE_TIMEOUT_MS) != 0) {
166                         pr_err("%s: Error: Timeout waiting for modem ack.\n",
167                                                         __func__);
168                         retval = -1;
169                 }
170         }
171         return retval;
172 }
173
174 static void apdown_handshake(void)
175 {
176         /* Signal AP going down to modem - Drive USB_AWR low. */
177         /* No need to wait for a CP response */
178         bb_set_awr(0);
179 }
180
181 static void pre_l2_suspend(void)
182 {
183         bb_setpowerstate(BBSTATE_L02L2);
184 }
185
186 static void l2_suspend(void)
187 {
188         int modemstate = bb_getpowerstate();
189
190         if (dlevel & DLEVEL_PM)
191                 pr_info("%s.\n", __func__);
192
193         if (modemstate != BBSTATE_L02L2) {
194                 pr_err("%s: Error. Unexp modemstate %x. Should be %d.\n",
195                                          __func__, modemstate, BBSTATE_L02L2);
196                 return;
197         }
198         bb_setpowerstate(BBSTATE_L2);
199 }
200
201 static void l2_resume(void)
202 {
203         int modemstate = bb_getpowerstate();
204         bool resumeok = false;
205
206         if (dlevel & DLEVEL_PM)
207                 pr_info("%s.\n", __func__);
208
209         /* Gets called for two cases :
210                 a) L2 resume.
211                 b) bus resume phase of L3 resume. */
212         switch (modemstate) {
213         case BBSTATE_L2:
214                 resumeok = true;
215                 break;
216         case BBSTATE_L3:
217                 if (apup_handshake(true) == 0)
218                         resumeok = true;
219                 else {
220                         bb_gpio_stat();
221                         pr_err("%s: Error. Modem wakeup from L3 failed.\n",
222                                                                  __func__);
223                         /* TBD: Add code to unregister ehci. */
224                 }
225                 break;
226         default:
227                 pr_err("%s: Error. Unexp modemstate %x. Should be %d or %d.\n",
228                                 __func__, modemstate, BBSTATE_L2, BBSTATE_L3);
229                 break;
230         }
231         if (resumeok)
232                 bb_setpowerstate(BBSTATE_L0);
233 }
234
235 static void phy_ready(void)
236 {
237         int modemstate = bb_getpowerstate();
238
239         if (dlevel & DLEVEL_PM)
240                 pr_info("%s.\n", __func__);
241
242         switch (modemstate) {
243         case BBSTATE_UNKNOWN:
244                 /* Wait for CP to indicate ready - by driving USB_CWR high. */
245                 if (gpio_wait_timeout(bb_sdata.gpio_cwr, 1, 10) != 0) {
246                         pr_info("%s: Timeout 4 modem ready. Maybe 1st enum ?\n",
247                                                          __func__);
248                         /* For first enumeration don't drive AWR high */
249                         break;
250                 }
251
252                 /* Signal AP ready - Drive USB_AWR high. */
253                 pr_info("%s : Driving AWR high.\n", __func__);
254                 bb_set_awr(1);
255                 break;
256         default:
257                 pr_err("%s: Error. Unexp modemstate %x. Should be %d.\n",
258                                 __func__, modemstate, BBSTATE_UNKNOWN);
259                 break;
260         }
261 }
262
263 static void pre_phy_off(void)
264 {
265         if (dlevel & DLEVEL_PM)
266                 pr_info("%s.\n", __func__);
267
268         /* Signal AP going down */
269         apdown_handshake();
270
271         /* Gets called for two cases :
272                 a) L3 suspend.
273                 b) EHCI unregister. */
274         if (bb_getpowerstate() == BBSTATE_L2)
275                 bb_setpowerstate(BBSTATE_L3);
276 }
277
278 static int l3_suspend(void)
279 {
280         int pwrstate = bb_getpowerstate();
281         bool wakeup_detected = bb_get_cwr();
282         bool crashed = bb_crashed();
283
284         if (dlevel & DLEVEL_PM)
285                 pr_info("%s.\n", __func__);
286
287         /* If modem state during system suspend is not L3 (crashed)
288                 or modem is initiating a wakeup, abort system suspend. */
289         if ((pwrstate != BBSTATE_L3) || wakeup_detected || crashed) {
290                 if (pwrstate != BBSTATE_L3)
291                         pr_err("%s: Unexp modemstate %x. Should be %d.\n",
292                                  __func__, pwrstate, BBSTATE_L3);
293                 if (wakeup_detected)
294                         pr_info("%s : CWR high.\n", __func__);
295                 if (crashed)
296                         pr_info("%s : WDI low.\n", __func__);
297                 pr_info("%s: Aborting suspend.\n", __func__);
298                 return 1;
299         }
300         return 0;
301 }
302
303 static int l3_suspend_noirq(void)
304 {
305         bool wakeup_detected = bb_get_cwr();
306         bool crashed = bb_crashed();
307
308         /* If modem is initiating a wakeup, or it had crashed
309         abort system suspend. */
310         if (wakeup_detected || crashed) {
311                 pr_info("%s: Aborting suspend.\n", __func__);
312                 return 1;
313         }
314         return 0;
315 }
316
317 static int l3_resume(void)
318 {
319         return 0;
320 }
321
322 static int l3_resume_noirq(void)
323 {
324         return 0;
325 }
326
327 static irqreturn_t bb_wake_irq(int irq, void *dev_id)
328 {
329         struct opsdata data;
330         struct usb_interface *iface;
331         int cwrlevel = bb_get_cwr();
332         bool pwrstate_l2 = false;
333
334         bb_getdata(&data);
335         pwrstate_l2 = ((data.powerstate == BBSTATE_L02L2) ||
336                                 (data.powerstate == BBSTATE_L2));
337         if (cwrlevel && pwrstate_l2) {
338                 if (dlevel & DLEVEL_PM)
339                         pr_info("%s: Modem wakeup request from L2.\n",
340                                                         __func__);
341                 if (data.usbdev) {
342                         usb_lock_device(data.usbdev);
343                         iface = usb_ifnum_to_if(data.usbdev, 0);
344                         if (iface) {
345                                 /* Resume usb host activity. */
346                                 usb_autopm_get_interface(iface);
347                                 usb_autopm_put_interface_no_suspend(iface);
348                         }
349                         usb_unlock_device(data.usbdev);
350                 }
351         }
352
353         if (!cwrlevel && data.powerstate == BBSTATE_UNKNOWN && data.usbdev) {
354                 data.powerstate = BBSTATE_L0;
355                 bb_setdata(&data);
356                 if (dlevel & DLEVEL_PM)
357                         pr_info("%s: Network interface up.\n", __func__);
358         }
359         return IRQ_HANDLED;
360 }
361
362 static int bb_power(int code)
363 {
364         int retval = 0;
365
366         switch (code) {
367         case PWRSTATE_L2L3:
368         retval = l3_suspend();
369         break;
370         case PWRSTATE_L2L3_NOIRQ:
371         retval = l3_suspend_noirq();
372         break;
373         case PWRSTATE_L3L0_NOIRQ:
374         retval = l3_resume_noirq();
375         break;
376         case PWRSTATE_L3L0:
377         retval = l3_resume();
378         break;
379         default:
380         break;
381         }
382         return retval;
383 }
384
385 static int bb_ehci_customize(struct tegra_bb_pdata *pdata)
386 {
387         struct platform_device *pdev;
388         struct tegra_usb_platform_data *usb_pdata;
389         struct tegra_usb_phy_platform_ops *pops;
390
391         if (pdata && pdata->device) {
392                 pdev = pdata->device;
393                 usb_pdata = (struct tegra_usb_platform_data *)
394                         pdev->dev.platform_data;
395                 pops = (struct tegra_usb_phy_platform_ops *)
396                         usb_pdata->ops;
397
398                 /* Register PHY platform callbacks */
399                 pops->pre_suspend = pre_l2_suspend;
400                 pops->post_suspend = l2_suspend;
401                 pops->pre_resume = l2_resume;
402                 pops->port_power = phy_ready;
403                 pops->pre_phy_off = pre_phy_off;
404
405                 /* Override required settings */
406                 usb_pdata->u_data.host.power_off_on_suspend = 0;
407
408         } else {
409                 pr_err("%s: Error. Invalid platform data.\n", __func__);
410                 return 0;
411         }
412         return 1;
413 }
414
415 static int bb_sysfs_load(struct device *dev, int value)
416 {
417         struct tegra_bb_pdata *pdata;
418         static struct platform_device *ehci_device;
419         struct opsdata data;
420
421         if (dlevel & DLEVEL_SYS_CB)
422                 pr_info("%s: Called with value : %d\n", __func__, value);
423
424         if (value > 1 || (!ehci_registered && !value) ||
425                                 (ehci_registered && value)) {
426                 /* Supported values are 0/1. */
427                 pr_err("%s:  Error. Invalid data. Exiting.\n", __func__);
428                 return -1;
429         }
430
431         pdata = (struct tegra_bb_pdata *) dev->platform_data;
432         if (value) {
433                 /* Register ehci controller */
434                 ehci_device = pdata->ehci_register(pdata->device);
435                 if (ehci_device == NULL) {
436                         pr_err("%s: Error. ehci register failed.\n",
437                                                          __func__);
438                         return -1;
439                 }
440                 ehci_registered = true;
441         } else {
442                 /* Mark usb device invalid */
443                 data.usbdev = NULL;
444                 data.powerstate = BBSTATE_UNKNOWN;
445                 bb_setdata(&data);
446                 ehci_registered = false;
447
448                 /* Unregister ehci controller */
449                 if (ehci_device != NULL)
450                         pdata->ehci_unregister(&ehci_device);
451
452                 /* Signal AP going down */
453                 apdown_handshake();
454         }
455         return 0;
456 }
457
458 static int bb_sysfs_dlevel(struct device *dev, int value)
459 {
460         if (dlevel & DLEVEL_SYS_CB)
461                 pr_info("%s: Called with value : %d\n", __func__, value);
462
463         dlevel = value;
464         return 0;
465 }
466
467 static int bb_usbnotify(struct usb_device *udev, bool registered)
468 {
469         struct opsdata data;
470
471         data.powerstate = BBSTATE_UNKNOWN;
472         if (registered) {
473                 data.usbdev = udev;
474                 if (dlevel & DLEVEL_MISC)
475                         pr_info("%s: Modem attached.\n", __func__);
476
477         } else {
478                 data.usbdev = NULL;
479                 if (dlevel & DLEVEL_MISC)
480                         pr_info("%s: Modem detached.\n", __func__);
481         }
482
483         bb_setdata(&data);
484         return 0;
485 }
486
487 #ifdef CONFIG_PM_SLEEP
488 static int bb_pmnotify(unsigned long event)
489 {
490         int pwrstate = bb_getpowerstate();
491         int retval = NOTIFY_OK;
492
493         if (dlevel & DLEVEL_PM)
494                 pr_info("%s: PM notification %ld.\n", __func__, event);
495
496         switch (event) {
497         case PM_SUSPEND_PREPARE:
498         if (pwrstate == BBSTATE_UNKNOWN) {
499                 pr_err("%s: Suspend with pwrstate=%d. Aborting suspend.\n",
500                                                  __func__, pwrstate);
501                 retval = NOTIFY_BAD;
502         }
503         break;
504         case PM_POST_SUSPEND:
505         break;
506         default:
507         retval = NOTIFY_DONE;
508         break;
509         }
510         return retval;
511 }
512 #endif
513
514 static struct tegra_bb_gpio_irqdata bb_gpioirqs[] = {
515         { GPIO_INVALID, "tegra_bb_wake", bb_wake_irq,
516                 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, true, NULL },
517         { GPIO_INVALID, "tegra_bb_wdi", NULL,
518                 IRQF_TRIGGER_NONE, true, NULL },
519         { GPIO_INVALID, NULL, NULL, 0, NULL },  /* End of table */
520 };
521
522 static struct tegra_bb_power_gdata bb_gdata = {
523         .gpio = bb_gpios,
524         .gpioirq = bb_gpioirqs,
525 };
526
527 static struct tegra_bb_power_mdata bb_mdata = {
528         .vid = 0x045B,
529         .pid = 0x020F,
530         .wake_capable = true,
531         .autosuspend_ready = true,
532 };
533
534 static struct tegra_bb_power_data bb_data = {
535         .gpio_data = &bb_gdata,
536         .modem_data = &bb_mdata,
537 };
538
539
540 static void *bb_init(void *pdata)
541 {
542         struct tegra_bb_pdata *platdata = (struct tegra_bb_pdata *) pdata;
543         union tegra_bb_gpio_id *id = platdata->id;
544         struct opsdata data;
545
546         /* Fill the gpio ids allocated by hardware */
547         bb_gpios[0].data.gpio = id->oem1.reset;
548         bb_gpios[1].data.gpio = id->oem1.pwron;
549         bb_gpios[2].data.gpio = id->oem1.awr;
550         bb_gpios[3].data.gpio = id->oem1.cwr;
551         bb_gpios[4].data.gpio = id->oem1.spare;
552         bb_gpios[5].data.gpio = id->oem1.wdi;
553         bb_gpioirqs[0].id = id->oem1.cwr;
554         bb_gpioirqs[1].id = id->oem1.wdi;
555
556         if (!platdata->ehci_register || !platdata->ehci_unregister) {
557                 pr_err("%s - Error: ehci reg/unreg functions missing.\n"
558                                                         , __func__);
559                 return 0;
560         }
561
562         bb_sdata.gpio_awr = bb_gpios[2].data.gpio;
563         bb_sdata.gpio_cwr = bb_gpios[3].data.gpio;
564         bb_sdata.gpio_wdi = bb_gpios[5].data.gpio;
565         if (bb_sdata.gpio_awr == GPIO_INVALID ||
566                 bb_sdata.gpio_cwr == GPIO_INVALID ||
567                 bb_sdata.gpio_wdi == GPIO_INVALID) {
568                 pr_err("%s: Error. Invalid gpio data.\n", __func__);
569                 return 0;
570         }
571
572         /* Customize PHY setup/callbacks */
573         if (!bb_ehci_customize(platdata))
574                 return 0;
575
576         /* Board specific regulator init */
577         if (platdata->regulator) {
578                 hsic_reg = regulator_get(NULL,
579                                         (const char *)platdata->regulator);
580                 if (IS_ERR_OR_NULL(hsic_reg)) {
581                         pr_err("%s: Error. regulator_get failed.\n",
582                                                          __func__);
583                         return 0;
584                 }
585
586                 if (regulator_enable(hsic_reg) < 0) {
587                         pr_err("%s: Error. regulator_enable failed.\n",
588                                                          __func__);
589                         return 0;
590                 }
591         }
592
593         spin_lock_init(&bb_locks.lock);
594         wake_lock_init(&bb_locks.wlock, WAKE_LOCK_SUSPEND,
595                                                 "tegra-bb-lock");
596         dlevel = DLEVEL_INIT;
597         ehci_registered = false;
598         data.usbdev = NULL;
599         data.powerstate = BBSTATE_UNKNOWN;
600         bb_setdata(&data);
601
602         return (void *) &bb_data;
603 }
604
605 static void *bb_deinit(void)
606 {
607         /* destroy wake lock */
608         wake_lock_destroy(&bb_locks.wlock);
609
610         return (void *) &bb_data;
611 }
612
613 static struct tegra_bb_callback bb_callbacks = {
614         .init = bb_init,
615         .deinit = bb_deinit,
616         .load = bb_sysfs_load,
617         .dlevel = bb_sysfs_dlevel,
618         .usbnotify = bb_usbnotify,
619 #ifdef CONFIG_PM
620         .power = bb_power,
621 #endif
622 #ifdef CONFIG_PM_SLEEP
623         .pmnotify = bb_pmnotify,
624 #endif
625 };
626
627 void *bb_oem1_get_cblist(void)
628 {
629         return (void *) &bb_callbacks;
630 }