blob: 8d4c33dea12ef3dc02e2ee69c4f5574d920fa4ed [file] [log] [blame]
Li Jun57677be2014-04-23 15:56:44 +08001/*
2 * otg_fsm.c - ChipIdea USB IP core OTG FSM driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Jun Li
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13/*
14 * This file mainly handles OTG fsm, it includes OTG fsm operations
15 * for HNP and SRP.
Li Jun4dcf7202014-04-23 15:56:50 +080016 *
17 * TODO List
18 * - ADP
19 * - OTG test device
Li Jun57677be2014-04-23 15:56:44 +080020 */
21
22#include <linux/usb/otg.h>
23#include <linux/usb/gadget.h>
24#include <linux/usb/hcd.h>
25#include <linux/usb/chipidea.h>
Li Jun826cfe72014-04-23 15:56:48 +080026#include <linux/regulator/consumer.h>
Li Jun57677be2014-04-23 15:56:44 +080027
28#include "ci.h"
29#include "bits.h"
30#include "otg.h"
31#include "otg_fsm.h"
32
Li June287b672014-04-23 15:56:49 +080033static struct ci_otg_fsm_timer *otg_timer_initializer
34(struct ci_hdrc *ci, void (*function)(void *, unsigned long),
35 unsigned long expires, unsigned long data)
36{
37 struct ci_otg_fsm_timer *timer;
38
39 timer = devm_kzalloc(ci->dev, sizeof(struct ci_otg_fsm_timer),
40 GFP_KERNEL);
41 if (!timer)
42 return NULL;
43 timer->function = function;
44 timer->expires = expires;
45 timer->data = data;
46 return timer;
47}
48
Li Jun15f75de2014-04-23 15:56:51 +080049/* Add for otg: interact with user space app */
50static ssize_t
51get_a_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
52{
53 char *next;
54 unsigned size, t;
55 struct ci_hdrc *ci = dev_get_drvdata(dev);
56
57 next = buf;
58 size = PAGE_SIZE;
59 t = scnprintf(next, size, "%d\n", ci->fsm.a_bus_req);
60 size -= t;
61 next += t;
62
63 return PAGE_SIZE - size;
64}
65
66static ssize_t
67set_a_bus_req(struct device *dev, struct device_attribute *attr,
68 const char *buf, size_t count)
69{
70 struct ci_hdrc *ci = dev_get_drvdata(dev);
71
72 if (count > 2)
73 return -1;
74
75 mutex_lock(&ci->fsm.lock);
76 if (buf[0] == '0') {
77 ci->fsm.a_bus_req = 0;
78 } else if (buf[0] == '1') {
79 /* If a_bus_drop is TRUE, a_bus_req can't be set */
80 if (ci->fsm.a_bus_drop) {
81 mutex_unlock(&ci->fsm.lock);
82 return count;
83 }
84 ci->fsm.a_bus_req = 1;
85 }
86
87 disable_irq_nosync(ci->irq);
88 queue_work(ci->wq, &ci->work);
89 mutex_unlock(&ci->fsm.lock);
90
91 return count;
92}
93static DEVICE_ATTR(a_bus_req, S_IRUGO | S_IWUSR, get_a_bus_req, set_a_bus_req);
94
95static ssize_t
96get_a_bus_drop(struct device *dev, struct device_attribute *attr, char *buf)
97{
98 char *next;
99 unsigned size, t;
100 struct ci_hdrc *ci = dev_get_drvdata(dev);
101
102 next = buf;
103 size = PAGE_SIZE;
104 t = scnprintf(next, size, "%d\n", ci->fsm.a_bus_drop);
105 size -= t;
106 next += t;
107
108 return PAGE_SIZE - size;
109}
110
111static ssize_t
112set_a_bus_drop(struct device *dev, struct device_attribute *attr,
113 const char *buf, size_t count)
114{
115 struct ci_hdrc *ci = dev_get_drvdata(dev);
116
117 if (count > 2)
118 return -1;
119
120 mutex_lock(&ci->fsm.lock);
121 if (buf[0] == '0') {
122 ci->fsm.a_bus_drop = 0;
123 } else if (buf[0] == '1') {
124 ci->fsm.a_bus_drop = 1;
125 ci->fsm.a_bus_req = 0;
126 }
127
128 disable_irq_nosync(ci->irq);
129 queue_work(ci->wq, &ci->work);
130 mutex_unlock(&ci->fsm.lock);
131
132 return count;
133}
134static DEVICE_ATTR(a_bus_drop, S_IRUGO | S_IWUSR, get_a_bus_drop,
135 set_a_bus_drop);
136
137static ssize_t
138get_b_bus_req(struct device *dev, struct device_attribute *attr, char *buf)
139{
140 char *next;
141 unsigned size, t;
142 struct ci_hdrc *ci = dev_get_drvdata(dev);
143
144 next = buf;
145 size = PAGE_SIZE;
146 t = scnprintf(next, size, "%d\n", ci->fsm.b_bus_req);
147 size -= t;
148 next += t;
149
150 return PAGE_SIZE - size;
151}
152
153static ssize_t
154set_b_bus_req(struct device *dev, struct device_attribute *attr,
155 const char *buf, size_t count)
156{
157 struct ci_hdrc *ci = dev_get_drvdata(dev);
158
159 if (count > 2)
160 return -1;
161
162 mutex_lock(&ci->fsm.lock);
163 if (buf[0] == '0')
164 ci->fsm.b_bus_req = 0;
165 else if (buf[0] == '1')
166 ci->fsm.b_bus_req = 1;
167
168 disable_irq_nosync(ci->irq);
169 queue_work(ci->wq, &ci->work);
170 mutex_unlock(&ci->fsm.lock);
171
172 return count;
173}
174static DEVICE_ATTR(b_bus_req, S_IRUGO | S_IWUSR, get_b_bus_req, set_b_bus_req);
175
176static ssize_t
177set_a_clr_err(struct device *dev, struct device_attribute *attr,
178 const char *buf, size_t count)
179{
180 struct ci_hdrc *ci = dev_get_drvdata(dev);
181
182 if (count > 2)
183 return -1;
184
185 mutex_lock(&ci->fsm.lock);
186 if (buf[0] == '1')
187 ci->fsm.a_clr_err = 1;
188
189 disable_irq_nosync(ci->irq);
190 queue_work(ci->wq, &ci->work);
191 mutex_unlock(&ci->fsm.lock);
192
193 return count;
194}
195static DEVICE_ATTR(a_clr_err, S_IWUSR, NULL, set_a_clr_err);
196
197static struct attribute *inputs_attrs[] = {
198 &dev_attr_a_bus_req.attr,
199 &dev_attr_a_bus_drop.attr,
200 &dev_attr_b_bus_req.attr,
201 &dev_attr_a_clr_err.attr,
202 NULL,
203};
204
205static struct attribute_group inputs_attr_group = {
206 .name = "inputs",
207 .attrs = inputs_attrs,
208};
209
Li Jun826cfe72014-04-23 15:56:48 +0800210/*
211 * Add timer to active timer list
212 */
213static void ci_otg_add_timer(struct ci_hdrc *ci, enum ci_otg_fsm_timer_index t)
214{
215 struct ci_otg_fsm_timer *tmp_timer;
216 struct ci_otg_fsm_timer *timer = ci->fsm_timer->timer_list[t];
217 struct list_head *active_timers = &ci->fsm_timer->active_timers;
218
219 if (t >= NUM_CI_OTG_FSM_TIMERS)
220 return;
221
222 /*
223 * Check if the timer is already in the active list,
224 * if so update timer count
225 */
226 list_for_each_entry(tmp_timer, active_timers, list)
227 if (tmp_timer == timer) {
228 timer->count = timer->expires;
229 return;
230 }
231
232 timer->count = timer->expires;
233 list_add_tail(&timer->list, active_timers);
234
235 /* Enable 1ms irq */
236 if (!(hw_read_otgsc(ci, OTGSC_1MSIE)))
237 hw_write_otgsc(ci, OTGSC_1MSIE, OTGSC_1MSIE);
238}
239
240/*
241 * Remove timer from active timer list
242 */
243static void ci_otg_del_timer(struct ci_hdrc *ci, enum ci_otg_fsm_timer_index t)
244{
245 struct ci_otg_fsm_timer *tmp_timer, *del_tmp;
246 struct ci_otg_fsm_timer *timer = ci->fsm_timer->timer_list[t];
247 struct list_head *active_timers = &ci->fsm_timer->active_timers;
248
249 if (t >= NUM_CI_OTG_FSM_TIMERS)
250 return;
251
252 list_for_each_entry_safe(tmp_timer, del_tmp, active_timers, list)
253 if (tmp_timer == timer)
254 list_del(&timer->list);
255
256 /* Disable 1ms irq if there is no any active timer */
257 if (list_empty(active_timers))
258 hw_write_otgsc(ci, OTGSC_1MSIE, 0);
259}
260
Li Jun4dcf7202014-04-23 15:56:50 +0800261/*
262 * Reduce timer count by 1, and find timeout conditions.
263 * Called by otg 1ms timer interrupt
264 */
265static inline int ci_otg_tick_timer(struct ci_hdrc *ci)
266{
267 struct ci_otg_fsm_timer *tmp_timer, *del_tmp;
268 struct list_head *active_timers = &ci->fsm_timer->active_timers;
269 int expired = 0;
270
271 list_for_each_entry_safe(tmp_timer, del_tmp, active_timers, list) {
272 tmp_timer->count--;
273 /* check if timer expires */
274 if (!tmp_timer->count) {
275 list_del(&tmp_timer->list);
276 tmp_timer->function(ci, tmp_timer->data);
277 expired = 1;
278 }
279 }
280
281 /* disable 1ms irq if there is no any timer active */
282 if ((expired == 1) && list_empty(active_timers))
283 hw_write_otgsc(ci, OTGSC_1MSIE, 0);
284
285 return expired;
286}
287
Li June287b672014-04-23 15:56:49 +0800288/* The timeout callback function to set time out bit */
289static void set_tmout(void *ptr, unsigned long indicator)
290{
291 *(int *)indicator = 1;
292}
293
294static void set_tmout_and_fsm(void *ptr, unsigned long indicator)
295{
296 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
297
298 set_tmout(ci, indicator);
299
300 disable_irq_nosync(ci->irq);
301 queue_work(ci->wq, &ci->work);
302}
303
304static void a_wait_vfall_tmout_func(void *ptr, unsigned long indicator)
305{
306 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
307
308 set_tmout(ci, indicator);
309 /* Disable port power */
310 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP, 0);
311 /* Clear exsiting DP irq */
312 hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
313 /* Enable data pulse irq */
314 hw_write_otgsc(ci, OTGSC_DPIE, OTGSC_DPIE);
315 disable_irq_nosync(ci->irq);
316 queue_work(ci->wq, &ci->work);
317}
318
319static void b_ase0_brst_tmout_func(void *ptr, unsigned long indicator)
320{
321 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
322
323 set_tmout(ci, indicator);
324 if (!hw_read_otgsc(ci, OTGSC_BSV))
325 ci->fsm.b_sess_vld = 0;
326
327 disable_irq_nosync(ci->irq);
328 queue_work(ci->wq, &ci->work);
329}
330
331static void b_ssend_srp_tmout_func(void *ptr, unsigned long indicator)
332{
333 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
334
335 set_tmout(ci, indicator);
336
337 /* only vbus fall below B_sess_vld in b_idle state */
338 if (ci->transceiver->state == OTG_STATE_B_IDLE) {
339 disable_irq_nosync(ci->irq);
340 queue_work(ci->wq, &ci->work);
341 }
342}
343
344static void b_sess_vld_tmout_func(void *ptr, unsigned long indicator)
345{
346 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
347
348 /* Check if A detached */
349 if (!(hw_read_otgsc(ci, OTGSC_BSV))) {
350 ci->fsm.b_sess_vld = 0;
351 ci_otg_add_timer(ci, B_SSEND_SRP);
352 disable_irq_nosync(ci->irq);
353 queue_work(ci->wq, &ci->work);
354 }
355}
356
357static void b_data_pulse_end(void *ptr, unsigned long indicator)
358{
359 struct ci_hdrc *ci = (struct ci_hdrc *)ptr;
360
361 ci->fsm.b_srp_done = 1;
362 ci->fsm.b_bus_req = 0;
363 if (ci->fsm.power_up)
364 ci->fsm.power_up = 0;
365
366 hw_write_otgsc(ci, OTGSC_HABA, 0);
367
368 disable_irq_nosync(ci->irq);
369 queue_work(ci->wq, &ci->work);
370}
371
372/* Initialize timers */
373static int ci_otg_init_timers(struct ci_hdrc *ci)
374{
375 struct otg_fsm *fsm = &ci->fsm;
376
377 /* FSM used timers */
378 ci->fsm_timer->timer_list[A_WAIT_VRISE] =
379 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_WAIT_VRISE,
380 (unsigned long)&fsm->a_wait_vrise_tmout);
381 if (ci->fsm_timer->timer_list[A_WAIT_VRISE] == NULL)
382 return -ENOMEM;
383
384 ci->fsm_timer->timer_list[A_WAIT_VFALL] =
385 otg_timer_initializer(ci, &a_wait_vfall_tmout_func,
386 TA_WAIT_VFALL, (unsigned long)&fsm->a_wait_vfall_tmout);
387 if (ci->fsm_timer->timer_list[A_WAIT_VFALL] == NULL)
388 return -ENOMEM;
389
390 ci->fsm_timer->timer_list[A_WAIT_BCON] =
391 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_WAIT_BCON,
392 (unsigned long)&fsm->a_wait_bcon_tmout);
393 if (ci->fsm_timer->timer_list[A_WAIT_BCON] == NULL)
394 return -ENOMEM;
395
396 ci->fsm_timer->timer_list[A_AIDL_BDIS] =
397 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_AIDL_BDIS,
398 (unsigned long)&fsm->a_aidl_bdis_tmout);
399 if (ci->fsm_timer->timer_list[A_AIDL_BDIS] == NULL)
400 return -ENOMEM;
401
402 ci->fsm_timer->timer_list[A_BIDL_ADIS] =
403 otg_timer_initializer(ci, &set_tmout_and_fsm, TA_BIDL_ADIS,
404 (unsigned long)&fsm->a_bidl_adis_tmout);
405 if (ci->fsm_timer->timer_list[A_BIDL_ADIS] == NULL)
406 return -ENOMEM;
407
408 ci->fsm_timer->timer_list[B_ASE0_BRST] =
409 otg_timer_initializer(ci, &b_ase0_brst_tmout_func, TB_ASE0_BRST,
410 (unsigned long)&fsm->b_ase0_brst_tmout);
411 if (ci->fsm_timer->timer_list[B_ASE0_BRST] == NULL)
412 return -ENOMEM;
413
414 ci->fsm_timer->timer_list[B_SE0_SRP] =
415 otg_timer_initializer(ci, &set_tmout_and_fsm, TB_SE0_SRP,
416 (unsigned long)&fsm->b_se0_srp);
417 if (ci->fsm_timer->timer_list[B_SE0_SRP] == NULL)
418 return -ENOMEM;
419
420 ci->fsm_timer->timer_list[B_SSEND_SRP] =
421 otg_timer_initializer(ci, &b_ssend_srp_tmout_func, TB_SSEND_SRP,
422 (unsigned long)&fsm->b_ssend_srp);
423 if (ci->fsm_timer->timer_list[B_SSEND_SRP] == NULL)
424 return -ENOMEM;
425
426 ci->fsm_timer->timer_list[B_SRP_FAIL] =
427 otg_timer_initializer(ci, &set_tmout, TB_SRP_FAIL,
428 (unsigned long)&fsm->b_srp_done);
429 if (ci->fsm_timer->timer_list[B_SRP_FAIL] == NULL)
430 return -ENOMEM;
431
432 ci->fsm_timer->timer_list[B_DATA_PLS] =
433 otg_timer_initializer(ci, &b_data_pulse_end, TB_DATA_PLS, 0);
434 if (ci->fsm_timer->timer_list[B_DATA_PLS] == NULL)
435 return -ENOMEM;
436
437 ci->fsm_timer->timer_list[B_SESS_VLD] = otg_timer_initializer(ci,
438 &b_sess_vld_tmout_func, TB_SESS_VLD, 0);
439 if (ci->fsm_timer->timer_list[B_SESS_VLD] == NULL)
440 return -ENOMEM;
441
442 return 0;
443}
444
Li Jun826cfe72014-04-23 15:56:48 +0800445/* -------------------------------------------------------------*/
446/* Operations that will be called from OTG Finite State Machine */
447/* -------------------------------------------------------------*/
448static void ci_otg_fsm_add_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
449{
450 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
451
452 if (t < NUM_OTG_FSM_TIMERS)
453 ci_otg_add_timer(ci, t);
454 return;
455}
456
457static void ci_otg_fsm_del_timer(struct otg_fsm *fsm, enum otg_fsm_timer t)
458{
459 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
460
461 if (t < NUM_OTG_FSM_TIMERS)
462 ci_otg_del_timer(ci, t);
463 return;
464}
465
466/*
467 * A-device drive vbus: turn on vbus regulator and enable port power
468 * Data pulse irq should be disabled while vbus is on.
469 */
470static void ci_otg_drv_vbus(struct otg_fsm *fsm, int on)
471{
472 int ret;
473 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
474
475 if (on) {
476 /* Enable power power */
477 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_PP,
478 PORTSC_PP);
479 if (ci->platdata->reg_vbus) {
480 ret = regulator_enable(ci->platdata->reg_vbus);
481 if (ret) {
482 dev_err(ci->dev,
483 "Failed to enable vbus regulator, ret=%d\n",
484 ret);
485 return;
486 }
487 }
488 /* Disable data pulse irq */
489 hw_write_otgsc(ci, OTGSC_DPIE, 0);
490
491 fsm->a_srp_det = 0;
492 fsm->power_up = 0;
493 } else {
494 if (ci->platdata->reg_vbus)
495 regulator_disable(ci->platdata->reg_vbus);
496
497 fsm->a_bus_drop = 1;
498 fsm->a_bus_req = 0;
499 }
500}
501
502/*
503 * Control data line by Run Stop bit.
504 */
505static void ci_otg_loc_conn(struct otg_fsm *fsm, int on)
506{
507 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
508
509 if (on)
510 hw_write(ci, OP_USBCMD, USBCMD_RS, USBCMD_RS);
511 else
512 hw_write(ci, OP_USBCMD, USBCMD_RS, 0);
513}
514
515/*
516 * Generate SOF by host.
517 * This is controlled through suspend/resume the port.
518 * In host mode, controller will automatically send SOF.
519 * Suspend will block the data on the port.
520 */
521static void ci_otg_loc_sof(struct otg_fsm *fsm, int on)
522{
523 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
524
525 if (on)
526 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_FPR,
527 PORTSC_FPR);
528 else
529 hw_write(ci, OP_PORTSC, PORTSC_W1C_BITS | PORTSC_SUSP,
530 PORTSC_SUSP);
531}
532
533/*
534 * Start SRP pulsing by data-line pulsing,
535 * no v-bus pulsing followed
536 */
537static void ci_otg_start_pulse(struct otg_fsm *fsm)
538{
539 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
540
541 /* Hardware Assistant Data pulse */
542 hw_write_otgsc(ci, OTGSC_HADP, OTGSC_HADP);
543
544 ci_otg_add_timer(ci, B_DATA_PLS);
545}
546
547static int ci_otg_start_host(struct otg_fsm *fsm, int on)
548{
549 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
550
551 mutex_unlock(&fsm->lock);
552 if (on) {
553 ci_role_stop(ci);
554 ci_role_start(ci, CI_ROLE_HOST);
555 } else {
556 ci_role_stop(ci);
557 hw_device_reset(ci, USBMODE_CM_DC);
558 ci_role_start(ci, CI_ROLE_GADGET);
559 }
560 mutex_lock(&fsm->lock);
561 return 0;
562}
563
564static int ci_otg_start_gadget(struct otg_fsm *fsm, int on)
565{
566 struct ci_hdrc *ci = container_of(fsm, struct ci_hdrc, fsm);
567
568 mutex_unlock(&fsm->lock);
569 if (on)
570 usb_gadget_vbus_connect(&ci->gadget);
571 else
572 usb_gadget_vbus_disconnect(&ci->gadget);
573 mutex_lock(&fsm->lock);
574
575 return 0;
576}
577
578static struct otg_fsm_ops ci_otg_ops = {
579 .drv_vbus = ci_otg_drv_vbus,
580 .loc_conn = ci_otg_loc_conn,
581 .loc_sof = ci_otg_loc_sof,
582 .start_pulse = ci_otg_start_pulse,
583 .add_timer = ci_otg_fsm_add_timer,
584 .del_timer = ci_otg_fsm_del_timer,
585 .start_host = ci_otg_start_host,
586 .start_gadget = ci_otg_start_gadget,
587};
588
Li Jun4dcf7202014-04-23 15:56:50 +0800589int ci_otg_fsm_work(struct ci_hdrc *ci)
590{
591 /*
592 * Don't do fsm transition for B device
593 * when there is no gadget class driver
594 */
595 if (ci->fsm.id && !(ci->driver) &&
596 ci->transceiver->state < OTG_STATE_A_IDLE)
597 return 0;
598
599 if (otg_statemachine(&ci->fsm)) {
600 if (ci->transceiver->state == OTG_STATE_A_IDLE) {
601 /*
602 * Further state change for cases:
603 * a_idle to b_idle; or
604 * a_idle to a_wait_vrise due to ID change(1->0), so
605 * B-dev becomes A-dev can try to start new session
606 * consequently; or
607 * a_idle to a_wait_vrise when power up
608 */
609 if ((ci->fsm.id) || (ci->id_event) ||
610 (ci->fsm.power_up)) {
611 disable_irq_nosync(ci->irq);
612 queue_work(ci->wq, &ci->work);
613 }
614 if (ci->id_event)
615 ci->id_event = false;
616 } else if (ci->transceiver->state == OTG_STATE_B_IDLE) {
617 if (ci->fsm.b_sess_vld) {
618 ci->fsm.power_up = 0;
619 /*
620 * Further transite to b_periphearl state
621 * when register gadget driver with vbus on
622 */
623 disable_irq_nosync(ci->irq);
624 queue_work(ci->wq, &ci->work);
625 }
626 }
627 }
628 return 0;
629}
630
631/*
632 * Update fsm variables in each state if catching expected interrupts,
633 * called by otg fsm isr.
634 */
635static void ci_otg_fsm_event(struct ci_hdrc *ci)
636{
637 u32 intr_sts, otg_bsess_vld, port_conn;
638 struct otg_fsm *fsm = &ci->fsm;
639
640 intr_sts = hw_read_intr_status(ci);
641 otg_bsess_vld = hw_read_otgsc(ci, OTGSC_BSV);
642 port_conn = hw_read(ci, OP_PORTSC, PORTSC_CCS);
643
644 switch (ci->transceiver->state) {
645 case OTG_STATE_A_WAIT_BCON:
646 if (port_conn) {
647 fsm->b_conn = 1;
648 fsm->a_bus_req = 1;
649 disable_irq_nosync(ci->irq);
650 queue_work(ci->wq, &ci->work);
651 }
652 break;
653 case OTG_STATE_B_IDLE:
654 if (otg_bsess_vld && (intr_sts & USBi_PCI) && port_conn) {
655 fsm->b_sess_vld = 1;
656 disable_irq_nosync(ci->irq);
657 queue_work(ci->wq, &ci->work);
658 }
659 break;
660 case OTG_STATE_B_PERIPHERAL:
661 if ((intr_sts & USBi_SLI) && port_conn && otg_bsess_vld) {
662 fsm->a_bus_suspend = 1;
663 disable_irq_nosync(ci->irq);
664 queue_work(ci->wq, &ci->work);
665 } else if (intr_sts & USBi_PCI) {
666 if (fsm->a_bus_suspend == 1)
667 fsm->a_bus_suspend = 0;
668 }
669 break;
670 case OTG_STATE_B_HOST:
671 if ((intr_sts & USBi_PCI) && !port_conn) {
672 fsm->a_conn = 0;
673 fsm->b_bus_req = 0;
674 disable_irq_nosync(ci->irq);
675 queue_work(ci->wq, &ci->work);
676 ci_otg_add_timer(ci, B_SESS_VLD);
677 }
678 break;
679 case OTG_STATE_A_PERIPHERAL:
680 if (intr_sts & USBi_SLI) {
681 fsm->b_bus_suspend = 1;
682 /*
683 * Init a timer to know how long this suspend
684 * will contine, if time out, indicates B no longer
685 * wants to be host role
686 */
687 ci_otg_add_timer(ci, A_BIDL_ADIS);
688 }
689
690 if (intr_sts & USBi_URI)
691 ci_otg_del_timer(ci, A_BIDL_ADIS);
692
693 if (intr_sts & USBi_PCI) {
694 if (fsm->b_bus_suspend == 1) {
695 ci_otg_del_timer(ci, A_BIDL_ADIS);
696 fsm->b_bus_suspend = 0;
697 }
698 }
699 break;
700 case OTG_STATE_A_SUSPEND:
701 if ((intr_sts & USBi_PCI) && !port_conn) {
702 fsm->b_conn = 0;
703
704 /* if gadget driver is binded */
705 if (ci->driver) {
706 /* A device to be peripheral mode */
707 ci->gadget.is_a_peripheral = 1;
708 }
709 disable_irq_nosync(ci->irq);
710 queue_work(ci->wq, &ci->work);
711 }
712 break;
713 case OTG_STATE_A_HOST:
714 if ((intr_sts & USBi_PCI) && !port_conn) {
715 fsm->b_conn = 0;
716 disable_irq_nosync(ci->irq);
717 queue_work(ci->wq, &ci->work);
718 }
719 break;
720 case OTG_STATE_B_WAIT_ACON:
721 if ((intr_sts & USBi_PCI) && port_conn) {
722 fsm->a_conn = 1;
723 disable_irq_nosync(ci->irq);
724 queue_work(ci->wq, &ci->work);
725 }
726 break;
727 default:
728 break;
729 }
730}
731
732/*
733 * ci_otg_irq - otg fsm related irq handling
734 * and also update otg fsm variable by monitoring usb host and udc
735 * state change interrupts.
736 * @ci: ci_hdrc
737 */
738irqreturn_t ci_otg_fsm_irq(struct ci_hdrc *ci)
739{
740 irqreturn_t retval = IRQ_NONE;
741 u32 otgsc, otg_int_src = 0;
742 struct otg_fsm *fsm = &ci->fsm;
743
744 otgsc = hw_read_otgsc(ci, ~0);
745 otg_int_src = otgsc & OTGSC_INT_STATUS_BITS & (otgsc >> 8);
746 fsm->id = (otgsc & OTGSC_ID) ? 1 : 0;
747
748 if (otg_int_src) {
749 if (otg_int_src & OTGSC_1MSIS) {
750 hw_write_otgsc(ci, OTGSC_1MSIS, OTGSC_1MSIS);
751 retval = ci_otg_tick_timer(ci);
752 return IRQ_HANDLED;
753 } else if (otg_int_src & OTGSC_DPIS) {
754 hw_write_otgsc(ci, OTGSC_DPIS, OTGSC_DPIS);
755 fsm->a_srp_det = 1;
756 fsm->a_bus_drop = 0;
757 } else if (otg_int_src & OTGSC_IDIS) {
758 hw_write_otgsc(ci, OTGSC_IDIS, OTGSC_IDIS);
759 if (fsm->id == 0) {
760 fsm->a_bus_drop = 0;
761 fsm->a_bus_req = 1;
762 ci->id_event = true;
763 }
764 } else if (otg_int_src & OTGSC_BSVIS) {
765 hw_write_otgsc(ci, OTGSC_BSVIS, OTGSC_BSVIS);
766 if (otgsc & OTGSC_BSV) {
767 fsm->b_sess_vld = 1;
768 ci_otg_del_timer(ci, B_SSEND_SRP);
769 ci_otg_del_timer(ci, B_SRP_FAIL);
770 fsm->b_ssend_srp = 0;
771 } else {
772 fsm->b_sess_vld = 0;
773 if (fsm->id)
774 ci_otg_add_timer(ci, B_SSEND_SRP);
775 }
776 } else if (otg_int_src & OTGSC_AVVIS) {
777 hw_write_otgsc(ci, OTGSC_AVVIS, OTGSC_AVVIS);
778 if (otgsc & OTGSC_AVV) {
779 fsm->a_vbus_vld = 1;
780 } else {
781 fsm->a_vbus_vld = 0;
782 fsm->b_conn = 0;
783 }
784 }
785 disable_irq_nosync(ci->irq);
786 queue_work(ci->wq, &ci->work);
787 return IRQ_HANDLED;
788 }
789
790 ci_otg_fsm_event(ci);
791
792 return retval;
793}
794
795void ci_hdrc_otg_fsm_start(struct ci_hdrc *ci)
796{
797 disable_irq_nosync(ci->irq);
798 queue_work(ci->wq, &ci->work);
799}
800
Li Jun57677be2014-04-23 15:56:44 +0800801int ci_hdrc_otg_fsm_init(struct ci_hdrc *ci)
802{
Li June287b672014-04-23 15:56:49 +0800803 int retval = 0;
Li Jun57677be2014-04-23 15:56:44 +0800804 struct usb_otg *otg;
805
806 otg = devm_kzalloc(ci->dev,
807 sizeof(struct usb_otg), GFP_KERNEL);
808 if (!otg) {
809 dev_err(ci->dev,
810 "Failed to allocate usb_otg structure for ci hdrc otg!\n");
811 return -ENOMEM;
812 }
813
814 otg->phy = ci->transceiver;
815 otg->gadget = &ci->gadget;
816 ci->fsm.otg = otg;
817 ci->transceiver->otg = ci->fsm.otg;
818 ci->fsm.power_up = 1;
819 ci->fsm.id = hw_read_otgsc(ci, OTGSC_ID) ? 1 : 0;
820 ci->transceiver->state = OTG_STATE_UNDEFINED;
Li Jun826cfe72014-04-23 15:56:48 +0800821 ci->fsm.ops = &ci_otg_ops;
Li Jun57677be2014-04-23 15:56:44 +0800822
823 mutex_init(&ci->fsm.lock);
824
Li June287b672014-04-23 15:56:49 +0800825 ci->fsm_timer = devm_kzalloc(ci->dev,
826 sizeof(struct ci_otg_fsm_timer_list), GFP_KERNEL);
827 if (!ci->fsm_timer) {
828 dev_err(ci->dev,
829 "Failed to allocate timer structure for ci hdrc otg!\n");
830 return -ENOMEM;
831 }
832
833 INIT_LIST_HEAD(&ci->fsm_timer->active_timers);
834 retval = ci_otg_init_timers(ci);
835 if (retval) {
836 dev_err(ci->dev, "Couldn't init OTG timers\n");
837 return retval;
838 }
839
Li Jun15f75de2014-04-23 15:56:51 +0800840 retval = sysfs_create_group(&ci->dev->kobj, &inputs_attr_group);
841 if (retval < 0) {
842 dev_dbg(ci->dev,
843 "Can't register sysfs attr group: %d\n", retval);
844 return retval;
845 }
846
Li Jun57677be2014-04-23 15:56:44 +0800847 /* Enable A vbus valid irq */
848 hw_write_otgsc(ci, OTGSC_AVVIE, OTGSC_AVVIE);
849
850 if (ci->fsm.id) {
851 ci->fsm.b_ssend_srp =
852 hw_read_otgsc(ci, OTGSC_BSV) ? 0 : 1;
853 ci->fsm.b_sess_vld =
854 hw_read_otgsc(ci, OTGSC_BSV) ? 1 : 0;
855 /* Enable BSV irq */
856 hw_write_otgsc(ci, OTGSC_BSVIE, OTGSC_BSVIE);
857 }
858
859 return 0;
860}
Li Jun15f75de2014-04-23 15:56:51 +0800861
862void ci_hdrc_otg_fsm_remove(struct ci_hdrc *ci)
863{
864 sysfs_remove_group(&ci->dev->kobj, &inputs_attr_group);
865}