Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 338641
b: refs/heads/master
c: 1c90ee0
h: refs/heads/master
i:
  338639: 46e8c2b
v: v3
  • Loading branch information
Kuninori Morimoto authored and Felipe Balbi committed Nov 8, 2012
1 parent 61e8894 commit 153cdfd
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7b332e5fef480ee14d133d9b83af22d03819368e
refs/heads/master: 1c90ee0b3e30235165180a1a8ee3fb3cbe47d295
4 changes: 4 additions & 0 deletions trunk/drivers/usb/renesas_usbhs/fifo.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,6 +488,8 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done)
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */

usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);

ret = usbhsf_fifo_select(pipe, fifo, 1);
if (ret < 0)
return 0;
Expand Down Expand Up @@ -594,6 +596,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done)
usbhs_pipe_data_sequence(pipe, pkt->sequence);
pkt->sequence = -1; /* -1 sequence will be ignored */

usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length);
usbhs_pipe_enable(pipe);
usbhsf_rx_irq_ctrl(pipe, 1);

Expand Down Expand Up @@ -795,6 +798,7 @@ static void xfer_work(struct work_struct *work)
dev_dbg(dev, " %s %d (%d/ %d)\n",
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);

usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans);
usbhsf_dma_start(pipe, fifo);
dma_async_issue_pending(chan);
}
Expand Down
101 changes: 101 additions & 0 deletions trunk/drivers/usb/renesas_usbhs/pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,82 @@ static void usbhsp_pipe_cfg_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
__usbhsp_pipe_xxx_set(pipe, DCPCFG, PIPECFG, mask, val);
}

/*
* PIPEnTRN/PIPEnTRE functions
*/
static void usbhsp_pipe_trn_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct device *dev = usbhs_priv_to_dev(priv);
int num = usbhs_pipe_number(pipe);
u16 reg;

/*
* It is impossible to calculate address,
* since PIPEnTRN addresses were mapped randomly.
*/
#define CASE_PIPExTRN(a) \
case 0x ## a: \
reg = PIPE ## a ## TRN; \
break;

switch (num) {
CASE_PIPExTRN(1);
CASE_PIPExTRN(2);
CASE_PIPExTRN(3);
CASE_PIPExTRN(4);
CASE_PIPExTRN(5);
CASE_PIPExTRN(B);
CASE_PIPExTRN(C);
CASE_PIPExTRN(D);
CASE_PIPExTRN(E);
CASE_PIPExTRN(F);
CASE_PIPExTRN(9);
CASE_PIPExTRN(A);
default:
dev_err(dev, "unknown pipe (%d)\n", num);
return;
}
__usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
}

static void usbhsp_pipe_tre_set(struct usbhs_pipe *pipe, u16 mask, u16 val)
{
struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
struct device *dev = usbhs_priv_to_dev(priv);
int num = usbhs_pipe_number(pipe);
u16 reg;

/*
* It is impossible to calculate address,
* since PIPEnTRE addresses were mapped randomly.
*/
#define CASE_PIPExTRE(a) \
case 0x ## a: \
reg = PIPE ## a ## TRE; \
break;

switch (num) {
CASE_PIPExTRE(1);
CASE_PIPExTRE(2);
CASE_PIPExTRE(3);
CASE_PIPExTRE(4);
CASE_PIPExTRE(5);
CASE_PIPExTRE(B);
CASE_PIPExTRE(C);
CASE_PIPExTRE(D);
CASE_PIPExTRE(E);
CASE_PIPExTRE(F);
CASE_PIPExTRE(9);
CASE_PIPExTRE(A);
default:
dev_err(dev, "unknown pipe (%d)\n", num);
return;
}

__usbhsp_pipe_xxx_set(pipe, 0, reg, mask, val);
}

/*
* PIPEBUF
*/
Expand Down Expand Up @@ -264,6 +340,31 @@ int usbhs_pipe_is_stall(struct usbhs_pipe *pipe)
return (int)(pid == PID_STALL10 || pid == PID_STALL11);
}

void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len)
{
if (!usbhs_pipe_type_is(pipe, USB_ENDPOINT_XFER_BULK))
return;

/*
* clear and disable transfer counter for IN/OUT pipe
*/
usbhsp_pipe_tre_set(pipe, TRCLR | TRENB, TRCLR);

/*
* Only IN direction bulk pipe can use transfer count.
* Without using this function,
* received data will break if it was large data size.
* see PIPEnTRN/PIPEnTRE for detail
*/
if (usbhs_pipe_is_dir_in(pipe)) {
int maxp = usbhs_pipe_get_maxpacket(pipe);

usbhsp_pipe_trn_set(pipe, 0xffff, DIV_ROUND_UP(len, maxp));
usbhsp_pipe_tre_set(pipe, TRENB, TRENB); /* enable */
}
}


/*
* pipe setup
*/
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/usb/renesas_usbhs/pipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void usbhs_pipe_enable(struct usbhs_pipe *pipe);
void usbhs_pipe_disable(struct usbhs_pipe *pipe);
void usbhs_pipe_stall(struct usbhs_pipe *pipe);
int usbhs_pipe_is_stall(struct usbhs_pipe *pipe);
void usbhs_pipe_set_trans_count_if_bulk(struct usbhs_pipe *pipe, int len);
void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo);
void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel,
u16 epnum, u16 maxp);
Expand Down

0 comments on commit 153cdfd

Please sign in to comment.