diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-10-11 01:07:08 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2011-10-13 13:41:51 -0400 |
commit | 9e74d601de8adb0fe96e100e459ac52f2ddd47f3 (patch) | |
tree | 85fb10664987f1cebf3b13b76bb6e1422a7c320f /drivers/usb | |
parent | 89c1d2e7b5993db33805b42e3675289920812f6f (diff) |
usb: gadget: renesas_usbhs: add data/status stage handler
mod_host needs data/status stage handler
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Felipe Balbi <balbi@ti.com>
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 145 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.h | 5 |
2 files changed, 150 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 1a345c20105f..16b12b09110a 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -321,6 +321,151 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe, | |||
321 | } | 321 | } |
322 | 322 | ||
323 | /* | 323 | /* |
324 | * DCP status stage | ||
325 | */ | ||
326 | static int usbhs_dcp_dir_switch_to_write(struct usbhs_pkt *pkt, int *is_done) | ||
327 | { | ||
328 | struct usbhs_pipe *pipe = pkt->pipe; | ||
329 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
330 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ | ||
331 | struct device *dev = usbhs_priv_to_dev(priv); | ||
332 | int ret; | ||
333 | |||
334 | usbhs_pipe_disable(pipe); | ||
335 | |||
336 | ret = usbhsf_fifo_select(pipe, fifo, 1); | ||
337 | if (ret < 0) { | ||
338 | dev_err(dev, "%s() faile\n", __func__); | ||
339 | return ret; | ||
340 | } | ||
341 | |||
342 | usbhs_pipe_sequence_data1(pipe); /* DATA1 */ | ||
343 | |||
344 | usbhsf_fifo_clear(pipe, fifo); | ||
345 | usbhsf_send_terminator(pipe, fifo); | ||
346 | |||
347 | usbhsf_fifo_unselect(pipe, fifo); | ||
348 | |||
349 | usbhsf_tx_irq_ctrl(pipe, 1); | ||
350 | usbhs_pipe_enable(pipe); | ||
351 | |||
352 | return ret; | ||
353 | } | ||
354 | |||
355 | static int usbhs_dcp_dir_switch_to_read(struct usbhs_pkt *pkt, int *is_done) | ||
356 | { | ||
357 | struct usbhs_pipe *pipe = pkt->pipe; | ||
358 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
359 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */ | ||
360 | struct device *dev = usbhs_priv_to_dev(priv); | ||
361 | int ret; | ||
362 | |||
363 | usbhs_pipe_disable(pipe); | ||
364 | |||
365 | ret = usbhsf_fifo_select(pipe, fifo, 0); | ||
366 | if (ret < 0) { | ||
367 | dev_err(dev, "%s() fail\n", __func__); | ||
368 | return ret; | ||
369 | } | ||
370 | |||
371 | usbhs_pipe_sequence_data1(pipe); /* DATA1 */ | ||
372 | usbhsf_fifo_clear(pipe, fifo); | ||
373 | |||
374 | usbhsf_fifo_unselect(pipe, fifo); | ||
375 | |||
376 | usbhsf_rx_irq_ctrl(pipe, 1); | ||
377 | usbhs_pipe_enable(pipe); | ||
378 | |||
379 | return ret; | ||
380 | |||
381 | } | ||
382 | |||
383 | static int usbhs_dcp_dir_switch_done(struct usbhs_pkt *pkt, int *is_done) | ||
384 | { | ||
385 | struct usbhs_pipe *pipe = pkt->pipe; | ||
386 | |||
387 | if (pkt->handler == &usbhs_dcp_status_stage_in_handler) | ||
388 | usbhsf_tx_irq_ctrl(pipe, 0); | ||
389 | else | ||
390 | usbhsf_rx_irq_ctrl(pipe, 0); | ||
391 | |||
392 | pkt->actual = pkt->length; | ||
393 | *is_done = 1; | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | struct usbhs_pkt_handle usbhs_dcp_status_stage_in_handler = { | ||
399 | .prepare = usbhs_dcp_dir_switch_to_write, | ||
400 | .try_run = usbhs_dcp_dir_switch_done, | ||
401 | }; | ||
402 | |||
403 | struct usbhs_pkt_handle usbhs_dcp_status_stage_out_handler = { | ||
404 | .prepare = usbhs_dcp_dir_switch_to_read, | ||
405 | .try_run = usbhs_dcp_dir_switch_done, | ||
406 | }; | ||
407 | |||
408 | /* | ||
409 | * DCP data stage (push) | ||
410 | */ | ||
411 | static int usbhsf_dcp_data_stage_try_push(struct usbhs_pkt *pkt, int *is_done) | ||
412 | { | ||
413 | struct usbhs_pipe *pipe = pkt->pipe; | ||
414 | |||
415 | usbhs_pipe_sequence_data1(pipe); /* DATA1 */ | ||
416 | |||
417 | /* | ||
418 | * change handler to PIO push | ||
419 | */ | ||
420 | pkt->handler = &usbhs_fifo_pio_push_handler; | ||
421 | |||
422 | return pkt->handler->prepare(pkt, is_done); | ||
423 | } | ||
424 | |||
425 | struct usbhs_pkt_handle usbhs_dcp_data_stage_out_handler = { | ||
426 | .prepare = usbhsf_dcp_data_stage_try_push, | ||
427 | }; | ||
428 | |||
429 | /* | ||
430 | * DCP data stage (pop) | ||
431 | */ | ||
432 | static int usbhsf_dcp_data_stage_prepare_pop(struct usbhs_pkt *pkt, | ||
433 | int *is_done) | ||
434 | { | ||
435 | struct usbhs_pipe *pipe = pkt->pipe; | ||
436 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | ||
437 | struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); | ||
438 | |||
439 | if (usbhs_pipe_is_busy(pipe)) | ||
440 | return 0; | ||
441 | |||
442 | /* | ||
443 | * prepare pop for DCP should | ||
444 | * - change DCP direction, | ||
445 | * - clear fifo | ||
446 | * - DATA1 | ||
447 | */ | ||
448 | usbhs_pipe_disable(pipe); | ||
449 | |||
450 | usbhs_pipe_sequence_data1(pipe); /* DATA1 */ | ||
451 | |||
452 | usbhsf_fifo_select(pipe, fifo, 0); | ||
453 | usbhsf_fifo_clear(pipe, fifo); | ||
454 | usbhsf_fifo_unselect(pipe, fifo); | ||
455 | |||
456 | /* | ||
457 | * change handler to PIO pop | ||
458 | */ | ||
459 | pkt->handler = &usbhs_fifo_pio_pop_handler; | ||
460 | |||
461 | return pkt->handler->prepare(pkt, is_done); | ||
462 | } | ||
463 | |||
464 | struct usbhs_pkt_handle usbhs_dcp_data_stage_in_handler = { | ||
465 | .prepare = usbhsf_dcp_data_stage_prepare_pop, | ||
466 | }; | ||
467 | |||
468 | /* | ||
324 | * PIO push handler | 469 | * PIO push handler |
325 | */ | 470 | */ |
326 | static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) | 471 | static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) |
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index 0e82d67a0257..32a7b246b28d 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -85,6 +85,11 @@ extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler; | |||
85 | extern struct usbhs_pkt_handle usbhs_fifo_dma_push_handler; | 85 | extern struct usbhs_pkt_handle usbhs_fifo_dma_push_handler; |
86 | extern struct usbhs_pkt_handle usbhs_fifo_dma_pop_handler; | 86 | extern struct usbhs_pkt_handle usbhs_fifo_dma_pop_handler; |
87 | 87 | ||
88 | extern struct usbhs_pkt_handle usbhs_dcp_status_stage_in_handler; | ||
89 | extern struct usbhs_pkt_handle usbhs_dcp_status_stage_out_handler; | ||
90 | |||
91 | extern struct usbhs_pkt_handle usbhs_dcp_data_stage_in_handler; | ||
92 | extern struct usbhs_pkt_handle usbhs_dcp_data_stage_out_handler; | ||
88 | 93 | ||
89 | void usbhs_pkt_init(struct usbhs_pkt *pkt); | 94 | void usbhs_pkt_init(struct usbhs_pkt *pkt); |
90 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 95 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |