Skip to content

Commit

Permalink
usb: gadget: renesas_usbhs: add data/status stage handler
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Kuninori Morimoto authored and Felipe Balbi committed Oct 13, 2011
1 parent 89c1d2e commit 9e74d60
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
145 changes: 145 additions & 0 deletions drivers/usb/renesas_usbhs/fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,151 @@ static int usbhsf_fifo_select(struct usbhs_pipe *pipe,
return -EIO;
}

/*
* DCP status stage
*/
static int usbhs_dcp_dir_switch_to_write(struct usbhs_pkt *pkt, int *is_done)
{
struct usbhs_pipe *pipe = pkt->pipe;
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */
struct device *dev = usbhs_priv_to_dev(priv);
int ret;

usbhs_pipe_disable(pipe);

ret = usbhsf_fifo_select(pipe, fifo, 1);
if (ret < 0) {
dev_err(dev, "%s() faile\n", __func__);
return ret;
}

usbhs_pipe_sequence_data1(pipe); /* DATA1 */

usbhsf_fifo_clear(pipe, fifo);
usbhsf_send_terminator(pipe, fifo);

usbhsf_fifo_unselect(pipe, fifo);

usbhsf_tx_irq_ctrl(pipe, 1);
usbhs_pipe_enable(pipe);

return ret;
}

static int usbhs_dcp_dir_switch_to_read(struct usbhs_pkt *pkt, int *is_done)
{
struct usbhs_pipe *pipe = pkt->pipe;
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv); /* CFIFO */
struct device *dev = usbhs_priv_to_dev(priv);
int ret;

usbhs_pipe_disable(pipe);

ret = usbhsf_fifo_select(pipe, fifo, 0);
if (ret < 0) {
dev_err(dev, "%s() fail\n", __func__);
return ret;
}

usbhs_pipe_sequence_data1(pipe); /* DATA1 */
usbhsf_fifo_clear(pipe, fifo);

usbhsf_fifo_unselect(pipe, fifo);

usbhsf_rx_irq_ctrl(pipe, 1);
usbhs_pipe_enable(pipe);

return ret;

}

static int usbhs_dcp_dir_switch_done(struct usbhs_pkt *pkt, int *is_done)
{
struct usbhs_pipe *pipe = pkt->pipe;

if (pkt->handler == &usbhs_dcp_status_stage_in_handler)
usbhsf_tx_irq_ctrl(pipe, 0);
else
usbhsf_rx_irq_ctrl(pipe, 0);

pkt->actual = pkt->length;
*is_done = 1;

return 0;
}

struct usbhs_pkt_handle usbhs_dcp_status_stage_in_handler = {
.prepare = usbhs_dcp_dir_switch_to_write,
.try_run = usbhs_dcp_dir_switch_done,
};

struct usbhs_pkt_handle usbhs_dcp_status_stage_out_handler = {
.prepare = usbhs_dcp_dir_switch_to_read,
.try_run = usbhs_dcp_dir_switch_done,
};

/*
* DCP data stage (push)
*/
static int usbhsf_dcp_data_stage_try_push(struct usbhs_pkt *pkt, int *is_done)
{
struct usbhs_pipe *pipe = pkt->pipe;

usbhs_pipe_sequence_data1(pipe); /* DATA1 */

/*
* change handler to PIO push
*/
pkt->handler = &usbhs_fifo_pio_push_handler;

return pkt->handler->prepare(pkt, is_done);
}

struct usbhs_pkt_handle usbhs_dcp_data_stage_out_handler = {
.prepare = usbhsf_dcp_data_stage_try_push,
};

/*
* DCP data stage (pop)
*/
static int usbhsf_dcp_data_stage_prepare_pop(struct usbhs_pkt *pkt,
int *is_done)
{
struct usbhs_pipe *pipe = pkt->pipe;
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct usbhs_fifo *fifo = usbhsf_get_cfifo(priv);

if (usbhs_pipe_is_busy(pipe))
return 0;

/*
* prepare pop for DCP should
* - change DCP direction,
* - clear fifo
* - DATA1
*/
usbhs_pipe_disable(pipe);

usbhs_pipe_sequence_data1(pipe); /* DATA1 */

usbhsf_fifo_select(pipe, fifo, 0);
usbhsf_fifo_clear(pipe, fifo);
usbhsf_fifo_unselect(pipe, fifo);

/*
* change handler to PIO pop
*/
pkt->handler = &usbhs_fifo_pio_pop_handler;

return pkt->handler->prepare(pkt, is_done);
}

struct usbhs_pkt_handle usbhs_dcp_data_stage_in_handler = {
.prepare = usbhsf_dcp_data_stage_prepare_pop,
};

/*
* PIO push handler
*/
Expand Down
5 changes: 5 additions & 0 deletions drivers/usb/renesas_usbhs/fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ extern struct usbhs_pkt_handle usbhs_ctrl_stage_end_handler;
extern struct usbhs_pkt_handle usbhs_fifo_dma_push_handler;
extern struct usbhs_pkt_handle usbhs_fifo_dma_pop_handler;

extern struct usbhs_pkt_handle usbhs_dcp_status_stage_in_handler;
extern struct usbhs_pkt_handle usbhs_dcp_status_stage_out_handler;

extern struct usbhs_pkt_handle usbhs_dcp_data_stage_in_handler;
extern struct usbhs_pkt_handle usbhs_dcp_data_stage_out_handler;

void usbhs_pkt_init(struct usbhs_pkt *pkt);
void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt,
Expand Down

0 comments on commit 9e74d60

Please sign in to comment.