aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2012-03-14 05:48:25 -0400
committerGrant Likely <grant.likely@secretlab.ca>2012-03-15 05:41:50 -0400
commitbb9c5687e8cd02d6f8a3aea40c118b439cb09501 (patch)
treec523e187256ddde75cbd55dd5d7a79847c60ca5a /drivers/spi
parent49e599b8595f9d33276860c6a02e05f240c4ceca (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')
-rw-r--r--drivers/spi/spi-sh-hspi.c93
1 files changed, 24 insertions, 69 deletions
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c
index 5784734d257..934138c7b3d 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
89static 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
119static 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 }
246error:
247 202
248 msg->status = ret; 203 msg->status = ret;
249 spi_finalize_current_message(master); 204 spi_finalize_current_message(master);