diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2012-03-14 05:48:25 -0400 |
---|---|---|
committer | Grant Likely <grant.likely@secretlab.ca> | 2012-03-15 05:41:50 -0400 |
commit | bb9c5687e8cd02d6f8a3aea40c118b439cb09501 (patch) | |
tree | c523e187256ddde75cbd55dd5d7a79847c60ca5a /drivers/spi/spi-sh-hspi.c | |
parent | 49e599b8595f9d33276860c6a02e05f240c4ceca (diff) |
spi: sh-hspi: modify write/read method
Current sh-hspi had wrong write/read method which was not linux standard.
If spi_transfer requests tx[2], rx[2] len=2,
then, driver should run tx[0], rx[0], tx[1], rx[1].
But current sh-hspi runs tx[0], tx[1], rx[0], rx[1].
This patch fixes it up.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
Diffstat (limited to 'drivers/spi/spi-sh-hspi.c')
-rw-r--r-- | drivers/spi/spi-sh-hspi.c | 93 |
1 files changed, 24 insertions, 69 deletions
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index 5784734d257d..934138c7b3d3 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c | |||
@@ -86,66 +86,6 @@ static int hspi_status_check_timeout(struct hspi_priv *hspi, u32 mask, u32 val) | |||
86 | return -ETIMEDOUT; | 86 | return -ETIMEDOUT; |
87 | } | 87 | } |
88 | 88 | ||
89 | static int hspi_push(struct hspi_priv *hspi, struct spi_message *msg, | ||
90 | struct spi_transfer *t) | ||
91 | { | ||
92 | int i, ret; | ||
93 | u8 *data = (u8 *)t->tx_buf; | ||
94 | |||
95 | /* | ||
96 | * FIXME | ||
97 | * very simple, but polling transfer | ||
98 | */ | ||
99 | for (i = 0; i < t->len; i++) { | ||
100 | /* wait remains */ | ||
101 | ret = hspi_status_check_timeout(hspi, 0x1, 0x0); | ||
102 | if (ret < 0) | ||
103 | return ret; | ||
104 | |||
105 | hspi_write(hspi, SPTBR, (u32)data[i]); | ||
106 | |||
107 | /* wait recive */ | ||
108 | ret = hspi_status_check_timeout(hspi, 0x4, 0x4); | ||
109 | if (ret < 0) | ||
110 | return ret; | ||
111 | |||
112 | /* dummy read */ | ||
113 | hspi_read(hspi, SPRBR); | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static int hspi_pop(struct hspi_priv *hspi, struct spi_message *msg, | ||
120 | struct spi_transfer *t) | ||
121 | { | ||
122 | int i, ret; | ||
123 | u8 *data = (u8 *)t->rx_buf; | ||
124 | |||
125 | /* | ||
126 | * FIXME | ||
127 | * very simple, but polling receive | ||
128 | */ | ||
129 | for (i = 0; i < t->len; i++) { | ||
130 | /* wait remains */ | ||
131 | ret = hspi_status_check_timeout(hspi, 0x1, 0); | ||
132 | if (ret < 0) | ||
133 | return ret; | ||
134 | |||
135 | /* dummy write */ | ||
136 | hspi_write(hspi, SPTBR, 0x0); | ||
137 | |||
138 | /* wait recive */ | ||
139 | ret = hspi_status_check_timeout(hspi, 0x4, 0x4); | ||
140 | if (ret < 0) | ||
141 | return ret; | ||
142 | |||
143 | data[i] = (u8)hspi_read(hspi, SPRBR); | ||
144 | } | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* | 89 | /* |
150 | * spi master function | 90 | * spi master function |
151 | */ | 91 | */ |
@@ -223,7 +163,9 @@ static int hspi_transfer_one_message(struct spi_master *master, | |||
223 | { | 163 | { |
224 | struct hspi_priv *hspi = spi_master_get_devdata(master); | 164 | struct hspi_priv *hspi = spi_master_get_devdata(master); |
225 | struct spi_transfer *t; | 165 | struct spi_transfer *t; |
226 | int ret; | 166 | u32 tx; |
167 | u32 rx; | ||
168 | int ret, i; | ||
227 | 169 | ||
228 | dev_dbg(hspi->dev, "%s\n", __func__); | 170 | dev_dbg(hspi->dev, "%s\n", __func__); |
229 | 171 | ||
@@ -231,19 +173,32 @@ static int hspi_transfer_one_message(struct spi_master *master, | |||
231 | list_for_each_entry(t, &msg->transfers, transfer_list) { | 173 | list_for_each_entry(t, &msg->transfers, transfer_list) { |
232 | hspi_hw_setup(hspi, msg, t); | 174 | hspi_hw_setup(hspi, msg, t); |
233 | 175 | ||
234 | if (t->tx_buf) { | 176 | for (i = 0; i < t->len; i++) { |
235 | ret = hspi_push(hspi, msg, t); | 177 | |
178 | /* wait remains */ | ||
179 | ret = hspi_status_check_timeout(hspi, 0x1, 0); | ||
236 | if (ret < 0) | 180 | if (ret < 0) |
237 | goto error; | 181 | break; |
238 | } | 182 | |
239 | if (t->rx_buf) { | 183 | tx = 0; |
240 | ret = hspi_pop(hspi, msg, t); | 184 | if (t->tx_buf) |
185 | tx = (u32)((u8 *)t->tx_buf)[i]; | ||
186 | |||
187 | hspi_write(hspi, SPTBR, tx); | ||
188 | |||
189 | /* wait recive */ | ||
190 | ret = hspi_status_check_timeout(hspi, 0x4, 0x4); | ||
241 | if (ret < 0) | 191 | if (ret < 0) |
242 | goto error; | 192 | break; |
193 | |||
194 | rx = hspi_read(hspi, SPRBR); | ||
195 | if (t->rx_buf) | ||
196 | ((u8 *)t->rx_buf)[i] = (u8)rx; | ||
197 | |||
243 | } | 198 | } |
199 | |||
244 | msg->actual_length += t->len; | 200 | msg->actual_length += t->len; |
245 | } | 201 | } |
246 | error: | ||
247 | 202 | ||
248 | msg->status = ret; | 203 | msg->status = ret; |
249 | spi_finalize_current_message(master); | 204 | spi_finalize_current_message(master); |