Date: | 2011-07-05 11:23:02 (12 years 8 months ago) |
---|---|
Author: | Stefan Schmidt |
Commit: | b5f9b7375e424a1f03cb11aaea229801d51e2d52 |
Message: | spi/atben: Start with write Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org> |
Files: |
drivers/spi/atusb.c (9 diffs) |
Change Details
drivers/spi/atusb.c | ||
---|---|---|
134 | 134 | complete(&atusb->urb_completion); |
135 | 135 | } |
136 | 136 | |
137 | static void atusb_read1_cb(struct urb *urb) | |
138 | { | |
139 | struct spi_message *msg; | |
140 | msg = urb->context; | |
141 | ||
142 | if (urb->status) { | |
143 | if (!(urb->status == -ENOENT || | |
144 | urb->status == -ECONNRESET || | |
145 | urb->status == -ESHUTDOWN)) | |
146 | printk("Async USB failed with error %i\n", urb->status); | |
147 | ||
148 | } else { | |
149 | printk("Async USB succeeded with length %i\n", urb->actual_length); | |
150 | } | |
151 | // printk("RX buffer %i\n", msg->transfers->rx_buf); | |
152 | msg->status = 0; | |
153 | msg->complete(msg->context); | |
154 | } | |
137 | 155 | static int atusb_get_static_info(struct atusb_local *atusb) |
138 | 156 | { |
139 | 157 | int retval; |
... | ... | |
238 | 256 | __func__, retval); |
239 | 257 | } |
240 | 258 | } |
241 | /* | |
242 | * host-> ATUSB_SPI_WRITE byte0 byte1 #bytes | |
243 | * ->host ATUSB_SPI_READ1 byte0 - #bytes | |
244 | * ->host ATUSB_SPI_READ2 byte0 byte1 #bytes | |
245 | */ | |
246 | 259 | |
247 | static void atusb_read1(struct atusb_local *atusb, const uint8_t *tx, uint8_t *rx, int len) | |
260 | static void atusb_read1(struct atusb_local *atusb, const uint8_t *tx, uint8_t *rx, int len, struct spi_message *msg) | |
248 | 261 | { |
249 | 262 | int retval; |
250 | 263 | struct usb_ctrlrequest *req; |
251 | dev_info(&atusb->udev->dev, "atusb_read1: tx = %i\n", *tx); | |
252 | #if 0 | |
253 | usb_control_msg(atusb->udev, | |
254 | usb_rcvctrlpipe(atusb->udev, 0), | |
255 | ATUSB_SPI_READ1, | |
256 | ATUSB_FROM_DEV, | |
257 | *tx, | |
258 | 0, | |
259 | (void *) rx, //(void *) &value | |
260 | 1, | |
261 | 1000); | |
262 | printk("USB SPI response: %i\n", *rx); | |
263 | #endif | |
264 | #if 1 | |
265 | INIT_COMPLETION(atusb->urb_completion); | |
264 | ||
265 | dev_info(&atusb->udev->dev, "atusb_read1: tx = 0x%x\n", *tx); | |
266 | 266 | atusb->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); |
267 | 267 | if (!atusb->ctrl_urb) { |
268 | 268 | retval = -ENOMEM; |
269 | 269 | } |
270 | /* ->host ATUSB_SPI_READ1 byte0 - #bytes */ | |
270 | 271 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); |
271 | 272 | req->bRequest = ATUSB_SPI_READ1; |
272 | 273 | req->bRequestType = ATUSB_FROM_DEV; |
273 | 274 | req->wValue = cpu_to_le16(*tx); |
274 | 275 | req->wIndex = cpu_to_le16(0x00); |
275 | req->wLength = cpu_to_le16(ATUSB_BUILD_SIZE+1); | |
276 | req->wLength = cpu_to_le16(0x02); | |
276 | 277 | |
277 | 278 | usb_fill_control_urb(atusb->ctrl_urb, |
278 | 279 | atusb->udev, |
279 | 280 | usb_rcvbulkpipe(atusb->udev, 0), |
280 | 281 | (unsigned char *)req, |
281 | 282 | rx, |
282 | ATUSB_BUILD_SIZE+1, /* ... or size length is wrong */ | |
283 | atusb_usb_cb, | |
284 | atusb); | |
283 | 0x02, /* ... or size length is wrong */ | |
284 | atusb_read1_cb, | |
285 | msg); | |
285 | 286 | |
286 | 287 | retval = usb_submit_urb(atusb->ctrl_urb, GFP_KERNEL); |
287 | 288 | if (retval < 0) { |
... | ... | |
289 | 290 | retval); |
290 | 291 | retval = (retval == -ENOMEM) ? retval : -EIO; |
291 | 292 | } |
292 | wait_for_completion(&atusb->urb_completion); | |
293 | //wait_for_completion_interruptible(&atusb->urb_completion); | |
294 | 293 | usb_free_urb(atusb->ctrl_urb); |
295 | 294 | kfree(req); |
296 | #endif | |
297 | 295 | } |
298 | 296 | |
299 | #if 0 | |
300 | 297 | static void atusb_read2(struct atusb_local *atusb, uint8_t *buf, int len) |
301 | 298 | { |
299 | /* ->host ATUSB_SPI_READ2 byte0 byte1 #bytes */ | |
302 | 300 | } |
303 | 301 | |
304 | static void atusb_write(struct atusb_local *atusb, uint8_t *buf, int len) | |
302 | static void atusb_write(struct atusb_local *atusb, const uint8_t *tx, uint8_t *rx, int len, struct spi_message *msg) | |
305 | 303 | { |
304 | int retval; | |
305 | struct usb_ctrlrequest *req; | |
306 | ||
307 | dev_info(&atusb->udev->dev, "atusb_write: tx = 0x%x\n", *tx); | |
308 | atusb->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL); | |
309 | if (!atusb->ctrl_urb) { | |
310 | retval = -ENOMEM; | |
311 | } | |
312 | /* host-> ATUSB_SPI_WRITE byte0 byte1 #bytes */ | |
313 | req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); | |
314 | req->bRequest = ATUSB_SPI_WRITE; | |
315 | req->bRequestType = ATUSB_FROM_DEV; | |
316 | req->wValue = cpu_to_le16(tx[0]); | |
317 | req->wIndex = cpu_to_le16(tx[1]); | |
318 | req->wLength = cpu_to_le16(0x02); | |
319 | ||
320 | usb_fill_control_urb(atusb->ctrl_urb, | |
321 | atusb->udev, | |
322 | usb_rcvbulkpipe(atusb->udev, 0), | |
323 | (unsigned char *)req, | |
324 | rx, | |
325 | 0x02, /* ... or size length is wrong */ | |
326 | atusb_read1_cb, | |
327 | msg); | |
328 | ||
329 | retval = usb_submit_urb(atusb->ctrl_urb, GFP_KERNEL); | |
330 | if (retval < 0) { | |
331 | dev_info(&atusb->udev->dev, "failed submitting read urb, error %d", | |
332 | retval); | |
333 | retval = (retval == -ENOMEM) ? retval : -EIO; | |
334 | } | |
335 | usb_free_urb(atusb->ctrl_urb); | |
336 | kfree(req); | |
306 | 337 | } |
307 | #endif | |
338 | ||
308 | 339 | static int atusb_transfer(struct spi_device *spi, struct spi_message *msg) |
309 | 340 | { |
310 | 341 | struct atusb_local *atusb = spi_master_get_devdata(spi->master); |
311 | 342 | struct spi_transfer *xfer; |
312 | // struct spi_transfer *x[2]; | |
313 | // int n; | |
343 | struct spi_transfer *x[2]; | |
344 | int n; | |
314 | 345 | const uint8_t *tx; |
315 | 346 | uint8_t *rx; |
316 | 347 | |
317 | dev_info(&atusb->udev->dev, "Entered atusb_transfer\n"); | |
318 | 348 | if (unlikely(list_empty(&msg->transfers))) { |
319 | 349 | dev_err(&atusb->udev->dev, "transfer is empty\n"); |
320 | 350 | return -EINVAL; |
321 | 351 | } |
322 | #if 0 | |
352 | ||
323 | 353 | /* |
324 | * Classify the request. This is just a proof of concept - we don't | |
325 | * need it in this driver. | |
354 | * Classify the request. | |
326 | 355 | */ |
327 | 356 | n = 0; |
328 | 357 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
... | ... | |
331 | 360 | return -EINVAL; |
332 | 361 | } |
333 | 362 | x[n] = xfer; |
334 | dev_info(&atusb->udev->dev, "%s transfer %i\n", __func__, n); | |
363 | //dev_info(&atusb->udev->dev, "%s transfer %i\n", __func__, n); | |
335 | 364 | n++; |
336 | 365 | } |
337 | 366 | |
367 | msg->actual_length = 0; | |
368 | ||
338 | 369 | if (!x[0]->tx_buf || x[0]->len != 2) |
339 | 370 | goto bad_req; |
340 | 371 | if (n == 1) { |
341 | 372 | if (x[0]->rx_buf) { |
342 | 373 | dev_info(&atusb->udev->dev, "read 1\n"); |
374 | tx = x[0]->tx_buf; | |
375 | rx = x[0]->rx_buf; | |
376 | msg->actual_length += x[0]->len; | |
377 | atusb_read1(atusb, tx, rx, x[0]->len, msg); | |
343 | 378 | } else { |
344 | 379 | dev_info(&atusb->udev->dev, "write 2\n"); |
380 | tx = x[0]->tx_buf; | |
381 | rx = x[0]->rx_buf; | |
382 | msg->actual_length += x[0]->len; | |
383 | atusb_write(atusb, tx, rx, x[0]->len, msg); | |
345 | 384 | } |
346 | 385 | } else { |
347 | 386 | if (x[0]->rx_buf) { |
... | ... | |
354 | 393 | dev_info(&atusb->udev->dev, "write 2+n\n"); |
355 | 394 | } |
356 | 395 | } |
357 | #endif | |
396 | #if 0 | |
358 | 397 | msg->actual_length = 0; |
359 | 398 | |
360 | 399 | list_for_each_entry(xfer, &msg->transfers, transfer_list) { |
361 | 400 | tx = xfer->tx_buf; |
362 | 401 | rx = xfer->rx_buf; |
363 | 402 | msg->actual_length += xfer->len; |
364 | #if 0 | |
365 | if (!tx) | |
366 | rx_only(prv, rx, xfer->len); | |
367 | else if (!rx) | |
368 | tx_only(prv, tx, xfer->len); | |
369 | else | |
370 | bidir(prv, tx, rx, xfer->len); | |
371 | #endif | |
372 | atusb_read1(atusb, tx, rx, xfer->len); | |
403 | atusb_read1(atusb, tx, rx, xfer->len, msg); | |
373 | 404 | } |
405 | #endif | |
374 | 406 | #if 0 |
375 | 407 | /* |
376 | 408 | * The AT86RF230 driver sometimes requires a transceiver state |
... | ... | |
389 | 421 | synchronize_irq(atusb->gpio_irq); |
390 | 422 | #endif |
391 | 423 | // dev_info(&atusb->udev->dev, "atusb_transfer: tx = %i, rx = %i\n", *tx, *rx); |
392 | msg->status = 0; | |
393 | msg->complete(msg->context); | |
394 | 424 | |
395 | 425 | return 0; |
396 | #if 0 | |
426 | ||
397 | 427 | bad_req: |
398 | 428 | dev_info(&atusb->udev->dev, "unrecognized request:\n"); |
399 | 429 | list_for_each_entry(xfer, &msg->transfers, transfer_list) |
... | ... | |
401 | 431 | xfer->tx_buf ? "" : "!", xfer->rx_buf ? " " : "!", |
402 | 432 | xfer->len); |
403 | 433 | return -EINVAL; |
404 | #endif | |
405 | 434 | } |
406 | 435 | |
407 | 436 | static int atusb_setup(struct spi_device *spi) |
... | ... | |
502 | 531 | set_irq_chip_and_handler(atusb->slave_irq, &atusb_irq_chip, |
503 | 532 | handle_level_irq); |
504 | 533 | |
505 | /* FIXME preapre USB IRQ */ | |
534 | /* FIXME prepare USB IRQ */ | |
506 | 535 | |
507 | 536 | retval = spi_register_master(master); |
508 | 537 | if (retval < 0) { |
... | ... | |
523 | 552 | } |
524 | 553 | |
525 | 554 | dev_info(&atusb->spi->dev, "ATUSB ready for mischief (IRQ %d)\n", board_info.irq); |
526 | ||
555 | #if 1 | |
527 | 556 | /* |
528 | 557 | * Get the static info from the device and save it ... |
529 | 558 | */ |
Branches:
ben-wpan
ben-wpan-stefan
5396a9238205f20f811ea57898980d3ca82df0b6
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9