4 * Copyright (C) 2007 Alex Dubov <oakad@yahoo.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
10 * Special thanks to Carlos Corbacho for providing various MemoryStick cards
11 * that made this driver possible.
15 #include <linux/tifm.h>
16 #include <linux/memstick.h>
17 #include <linux/highmem.h>
18 #include <linux/scatterlist.h>
19 #include <linux/log2.h>
22 #define DRIVER_NAME "tifm_ms"
23 #define DRIVER_VERSION "0.1"
26 module_param(no_dma
, bool, 0644);
28 #define TIFM_MS_TIMEOUT 0x00100
29 #define TIFM_MS_BADCRC 0x00200
30 #define TIFM_MS_EOTPC 0x01000
31 #define TIFM_MS_INT 0x02000
33 /* The meaning of the bit majority in this constant is unknown. */
34 #define TIFM_MS_SERIAL 0x04010
36 #define TIFM_MS_SYS_LATCH 0x00100
37 #define TIFM_MS_SYS_NOT_RDY 0x00800
38 #define TIFM_MS_SYS_DATA 0x10000
50 unsigned short eject
:1,
52 unsigned short cmd_flags
;
53 unsigned int mode_mask
;
54 unsigned int block_pos
;
55 unsigned long timeout_jiffies
;
57 struct timer_list timer
;
58 struct memstick_request
*req
;
62 static void tifm_ms_read_fifo(struct tifm_ms
*host
, unsigned int fifo_offset
,
63 struct page
*pg
, unsigned int page_off
,
66 struct tifm_dev
*sock
= host
->dev
;
67 unsigned int cnt
= 0, off
= 0;
68 unsigned char *buf
= kmap_atomic(pg
, KM_BIO_DST_IRQ
) + page_off
;
70 if (host
->cmd_flags
& DATA_CARRY
) {
71 while ((fifo_offset
& 3) && length
) {
72 buf
[off
++] = host
->io_word
& 0xff;
77 if (!(fifo_offset
& 3))
78 host
->cmd_flags
&= ~DATA_CARRY
;
84 host
->io_word
= readl(sock
->addr
+ SOCK_FIFO_ACCESS
87 while (length
&& cnt
) {
88 buf
[off
++] = (host
->io_word
>> 8) & 0xff;
92 fifo_offset
+= 4 - cnt
;
96 host
->cmd_flags
|= DATA_CARRY
;
98 kunmap_atomic(buf
- page_off
, KM_BIO_DST_IRQ
);
101 static void tifm_ms_write_fifo(struct tifm_ms
*host
, unsigned int fifo_offset
,
102 struct page
*pg
, unsigned int page_off
,
105 struct tifm_dev
*sock
= host
->dev
;
106 unsigned int cnt
= 0, off
= 0;
107 unsigned char *buf
= kmap_atomic(pg
, KM_BIO_SRC_IRQ
) + page_off
;
109 if (host
->cmd_flags
& DATA_CARRY
) {
110 while (fifo_offset
& 3) {
111 host
->io_word
|= buf
[off
++] << (8 * (fifo_offset
& 3));
115 if (!(fifo_offset
& 3)) {
116 writel(host
->io_word
, sock
->addr
+ SOCK_FIFO_ACCESS
119 host
->cmd_flags
&= ~DATA_CARRY
;
128 while (length
&& cnt
) {
129 host
->io_word
|= buf
[off
++] << (4 - cnt
);
133 fifo_offset
+= 4 - cnt
;
135 writel(host
->io_word
, sock
->addr
+ SOCK_FIFO_ACCESS
141 host
->cmd_flags
|= DATA_CARRY
;
143 kunmap_atomic(buf
- page_off
, KM_BIO_SRC_IRQ
);
146 static void tifm_ms_move_block(struct tifm_ms
*host
, unsigned int length
)
149 unsigned int off
= host
->req
->sg
.offset
+ host
->block_pos
;
150 unsigned int p_off
, p_cnt
;
154 dev_dbg(&host
->dev
->dev
, "moving block\n");
155 local_irq_save(flags
);
158 pg
= nth_page(sg_page(&host
->req
->sg
), off
>> PAGE_SHIFT
);
159 p_off
= offset_in_page(off
);
160 p_cnt
= PAGE_SIZE
- p_off
;
161 p_cnt
= min(p_cnt
, t_size
);
163 if (host
->req
->data_dir
== WRITE
)
164 tifm_ms_write_fifo(host
, length
- t_size
,
167 tifm_ms_read_fifo(host
, length
- t_size
,
172 local_irq_restore(flags
);
175 static int tifm_ms_transfer_data(struct tifm_ms
*host
, int skip
)
177 struct tifm_dev
*sock
= host
->dev
;
178 unsigned int length
= host
->req
->sg
.length
- host
->block_pos
;
183 if (length
> TIFM_FIFO_SIZE
)
184 length
= TIFM_FIFO_SIZE
;
187 tifm_ms_move_block(host
, length
);
188 host
->block_pos
+= length
;
191 if ((host
->req
->data_dir
== READ
)
192 && (host
->block_pos
== host
->req
->sg
.length
))
195 writel(ilog2(length
) - 2, sock
->addr
+ SOCK_FIFO_PAGE_SIZE
);
196 if (host
->req
->data_dir
== WRITE
)
197 writel((1 << 8) | TIFM_DMA_TX
, sock
->addr
+ SOCK_DMA_CONTROL
);
199 writel((1 << 8), sock
->addr
+ SOCK_DMA_CONTROL
);
204 static int tifm_ms_issue_cmd(struct tifm_ms
*host
)
206 struct tifm_dev
*sock
= host
->dev
;
208 unsigned int data_len
= 0, cmd
= 0, cmd_mask
= 0, cnt
, tval
= 0;
212 if (host
->req
->io_type
== MEMSTICK_IO_SG
) {
214 if (1 != tifm_map_sg(sock
, &host
->req
->sg
, 1,
215 host
->req
->data_dir
== READ
217 : PCI_DMA_TODEVICE
)) {
218 host
->req
->error
= -ENOMEM
;
219 return host
->req
->error
;
221 data_len
= sg_dma_len(&host
->req
->sg
);
223 data_len
= host
->req
->sg
.length
;
225 writel(TIFM_FIFO_INT_SETALL
,
226 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
227 writel(TIFM_FIFO_ENABLE
,
228 sock
->addr
+ SOCK_FIFO_CONTROL
);
229 writel(TIFM_FIFO_INTMASK
,
230 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
233 writel(ilog2(data_len
) - 2,
234 sock
->addr
+ SOCK_FIFO_PAGE_SIZE
);
235 writel(sg_dma_address(&host
->req
->sg
),
236 sock
->addr
+ SOCK_DMA_ADDRESS
);
237 if (host
->req
->data_dir
== WRITE
)
238 writel((1 << 8) | TIFM_DMA_TX
| TIFM_DMA_EN
,
239 sock
->addr
+ SOCK_DMA_CONTROL
);
241 writel((1 << 8) | TIFM_DMA_EN
,
242 sock
->addr
+ SOCK_DMA_CONTROL
);
244 tifm_ms_transfer_data(host
,
245 host
->req
->data_dir
== READ
);
248 cmd_mask
= readl(sock
->addr
+ SOCK_MS_SYSTEM
);
249 cmd_mask
|= TIFM_MS_SYS_DATA
| TIFM_MS_SYS_NOT_RDY
;
250 writel(cmd_mask
, sock
->addr
+ SOCK_MS_SYSTEM
);
251 } else if (host
->req
->io_type
== MEMSTICK_IO_VAL
) {
252 data
= host
->req
->data
;
253 data_len
= host
->req
->data_len
;
255 cmd_mask
= host
->mode_mask
| 0x2607; /* unknown constant */
257 if (host
->req
->data_dir
== WRITE
) {
258 cmd_mask
|= TIFM_MS_SYS_LATCH
;
259 writel(cmd_mask
, sock
->addr
+ SOCK_MS_SYSTEM
);
260 for (cnt
= 0; (data_len
- cnt
) >= 4; cnt
+= 4) {
261 writel(TIFM_MS_SYS_LATCH
262 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
263 sock
->addr
+ SOCK_MS_SYSTEM
);
264 __raw_writel(*(unsigned int *)(data
+ cnt
),
265 sock
->addr
+ SOCK_MS_DATA
);
266 dev_dbg(&sock
->dev
, "writing %x\n",
267 *(int *)(data
+ cnt
));
269 switch (data_len
- cnt
) {
271 tval
|= data
[cnt
+ 2] << 16;
273 tval
|= data
[cnt
+ 1] << 8;
276 writel(TIFM_MS_SYS_LATCH
277 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
278 sock
->addr
+ SOCK_MS_SYSTEM
);
279 writel(tval
, sock
->addr
+ SOCK_MS_DATA
);
280 dev_dbg(&sock
->dev
, "writing %x\n", tval
);
283 writel(TIFM_MS_SYS_LATCH
284 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
285 sock
->addr
+ SOCK_MS_SYSTEM
);
286 writel(0, sock
->addr
+ SOCK_MS_DATA
);
287 dev_dbg(&sock
->dev
, "writing %x\n", 0);
290 writel(cmd_mask
, sock
->addr
+ SOCK_MS_SYSTEM
);
292 cmd_mask
= readl(sock
->addr
+ SOCK_MS_SYSTEM
);
293 cmd_mask
&= ~TIFM_MS_SYS_DATA
;
294 cmd_mask
|= TIFM_MS_SYS_NOT_RDY
;
295 dev_dbg(&sock
->dev
, "mask %x\n", cmd_mask
);
296 writel(cmd_mask
, sock
->addr
+ SOCK_MS_SYSTEM
);
300 mod_timer(&host
->timer
, jiffies
+ host
->timeout_jiffies
);
301 writel(TIFM_CTRL_LED
| readl(sock
->addr
+ SOCK_CONTROL
),
302 sock
->addr
+ SOCK_CONTROL
);
303 host
->req
->error
= 0;
305 cmd
= (host
->req
->tpc
& 0xf) << 12;
307 writel(cmd
, sock
->addr
+ SOCK_MS_COMMAND
);
309 dev_dbg(&sock
->dev
, "executing TPC %x, %x\n", cmd
, cmd_mask
);
313 static void tifm_ms_complete_cmd(struct tifm_ms
*host
)
315 struct tifm_dev
*sock
= host
->dev
;
316 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
317 unsigned int tval
= 0, data_len
;
321 del_timer(&host
->timer
);
322 if (host
->req
->io_type
== MEMSTICK_IO_SG
) {
324 tifm_unmap_sg(sock
, &host
->req
->sg
, 1,
325 host
->req
->data_dir
== READ
328 } else if (host
->req
->io_type
== MEMSTICK_IO_VAL
) {
329 writel(~TIFM_MS_SYS_DATA
& readl(sock
->addr
+ SOCK_MS_SYSTEM
),
330 sock
->addr
+ SOCK_MS_SYSTEM
);
332 data
= host
->req
->data
;
333 data_len
= host
->req
->data_len
;
335 if (host
->req
->data_dir
== READ
) {
336 for (rc
= 0; (data_len
- rc
) >= 4; rc
+= 4)
338 = __raw_readl(sock
->addr
342 tval
= readl(sock
->addr
+ SOCK_MS_DATA
);
343 switch (data_len
- rc
) {
345 data
[rc
+ 2] = (tval
>> 16) & 0xff;
347 data
[rc
+ 1] = (tval
>> 8) & 0xff;
349 data
[rc
] = tval
& 0xff;
351 readl(sock
->addr
+ SOCK_MS_DATA
);
355 writel((~TIFM_CTRL_LED
) & readl(sock
->addr
+ SOCK_CONTROL
),
356 sock
->addr
+ SOCK_CONTROL
);
359 rc
= memstick_next_req(msh
, &host
->req
);
360 } while (!rc
&& tifm_ms_issue_cmd(host
));
363 static int tifm_ms_check_status(struct tifm_ms
*host
)
365 if (!host
->req
->error
) {
366 if (!(host
->cmd_flags
& CMD_READY
))
368 if ((host
->req
->io_type
== MEMSTICK_IO_SG
)
369 && !(host
->cmd_flags
& FIFO_READY
))
371 if (host
->req
->need_card_int
372 && !(host
->cmd_flags
& CARD_READY
))
378 /* Called from interrupt handler */
379 static void tifm_ms_data_event(struct tifm_dev
*sock
)
381 struct tifm_ms
*host
;
382 unsigned int fifo_status
= 0;
385 spin_lock(&sock
->lock
);
386 host
= memstick_priv((struct memstick_host
*)tifm_get_drvdata(sock
));
387 fifo_status
= readl(sock
->addr
+ SOCK_DMA_FIFO_STATUS
);
388 dev_dbg(&sock
->dev
, "data event: fifo_status %x, flags %x\n",
389 fifo_status
, host
->cmd_flags
);
392 if (fifo_status
& TIFM_FIFO_READY
) {
393 if (!host
->no_dma
|| tifm_ms_transfer_data(host
, 0)) {
394 host
->cmd_flags
|= FIFO_READY
;
395 rc
= tifm_ms_check_status(host
);
400 writel(fifo_status
, sock
->addr
+ SOCK_DMA_FIFO_STATUS
);
402 tifm_ms_complete_cmd(host
);
404 spin_unlock(&sock
->lock
);
408 /* Called from interrupt handler */
409 static void tifm_ms_card_event(struct tifm_dev
*sock
)
411 struct tifm_ms
*host
;
412 unsigned int host_status
= 0;
415 spin_lock(&sock
->lock
);
416 host
= memstick_priv((struct memstick_host
*)tifm_get_drvdata(sock
));
417 host_status
= readl(sock
->addr
+ SOCK_MS_STATUS
);
418 dev_dbg(&sock
->dev
, "host event: host_status %x, flags %x\n",
419 host_status
, host
->cmd_flags
);
422 if (host_status
& TIFM_MS_TIMEOUT
)
423 host
->req
->error
= -ETIME
;
424 else if (host_status
& TIFM_MS_BADCRC
)
425 host
->req
->error
= -EILSEQ
;
427 if (host
->req
->error
) {
428 writel(TIFM_FIFO_INT_SETALL
,
429 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
430 writel(TIFM_DMA_RESET
, sock
->addr
+ SOCK_DMA_CONTROL
);
433 if (host_status
& TIFM_MS_EOTPC
)
434 host
->cmd_flags
|= CMD_READY
;
435 if (host_status
& TIFM_MS_INT
)
436 host
->cmd_flags
|= CARD_READY
;
438 rc
= tifm_ms_check_status(host
);
442 writel(TIFM_MS_SYS_NOT_RDY
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
443 sock
->addr
+ SOCK_MS_SYSTEM
);
444 writel((~TIFM_MS_SYS_DATA
) & readl(sock
->addr
+ SOCK_MS_SYSTEM
),
445 sock
->addr
+ SOCK_MS_SYSTEM
);
448 tifm_ms_complete_cmd(host
);
450 spin_unlock(&sock
->lock
);
454 static void tifm_ms_request(struct memstick_host
*msh
)
456 struct tifm_ms
*host
= memstick_priv(msh
);
457 struct tifm_dev
*sock
= host
->dev
;
461 spin_lock_irqsave(&sock
->lock
, flags
);
463 printk(KERN_ERR
"%s : unfinished request detected\n",
465 spin_unlock_irqrestore(&sock
->lock
, flags
);
466 tifm_eject(host
->dev
);
472 rc
= memstick_next_req(msh
, &host
->req
);
474 host
->req
->error
= -ETIME
;
476 spin_unlock_irqrestore(&sock
->lock
, flags
);
481 rc
= memstick_next_req(msh
, &host
->req
);
482 } while (!rc
&& tifm_ms_issue_cmd(host
));
484 spin_unlock_irqrestore(&sock
->lock
, flags
);
488 static void tifm_ms_set_param(struct memstick_host
*msh
,
489 enum memstick_param param
,
492 struct tifm_ms
*host
= memstick_priv(msh
);
493 struct tifm_dev
*sock
= host
->dev
;
496 spin_lock_irqsave(&sock
->lock
, flags
);
500 /* this is set by card detection mechanism */
502 case MEMSTICK_INTERFACE
:
503 if (value
== MEMSTICK_SERIAL
) {
504 host
->mode_mask
= TIFM_MS_SERIAL
;
505 writel((~TIFM_CTRL_FAST_CLK
)
506 & readl(sock
->addr
+ SOCK_CONTROL
),
507 sock
->addr
+ SOCK_CONTROL
);
508 } else if (value
== MEMSTICK_PARALLEL
) {
510 writel(TIFM_CTRL_FAST_CLK
511 | readl(sock
->addr
+ SOCK_CONTROL
),
512 sock
->addr
+ SOCK_CONTROL
);
517 spin_unlock_irqrestore(&sock
->lock
, flags
);
520 static void tifm_ms_abort(unsigned long data
)
522 struct tifm_ms
*host
= (struct tifm_ms
*)data
;
524 dev_dbg(&host
->dev
->dev
, "status %x\n",
525 readl(host
->dev
->addr
+ SOCK_MS_STATUS
));
527 "%s : card failed to respond for a long period of time "
529 host
->dev
->dev
.bus_id
, host
->req
? host
->req
->tpc
: 0,
532 tifm_eject(host
->dev
);
535 static int tifm_ms_initialize_host(struct tifm_ms
*host
)
537 struct tifm_dev
*sock
= host
->dev
;
538 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
540 host
->mode_mask
= TIFM_MS_SERIAL
;
541 writel(0x8000, sock
->addr
+ SOCK_MS_SYSTEM
);
542 writel(0x0200 | TIFM_MS_SYS_NOT_RDY
, sock
->addr
+ SOCK_MS_SYSTEM
);
543 writel(0xffffffff, sock
->addr
+ SOCK_MS_STATUS
);
544 if (tifm_has_ms_pif(sock
))
545 msh
->caps
|= MEMSTICK_CAP_PARALLEL
;
550 static int tifm_ms_probe(struct tifm_dev
*sock
)
552 struct memstick_host
*msh
;
553 struct tifm_ms
*host
;
556 if (!(TIFM_SOCK_STATE_OCCUPIED
557 & readl(sock
->addr
+ SOCK_PRESENT_STATE
))) {
558 printk(KERN_WARNING
"%s : card gone, unexpectedly\n",
563 msh
= memstick_alloc_host(sizeof(struct tifm_ms
), &sock
->dev
);
567 host
= memstick_priv(msh
);
568 tifm_set_drvdata(sock
, msh
);
570 host
->timeout_jiffies
= msecs_to_jiffies(1000);
571 host
->no_dma
= no_dma
;
573 setup_timer(&host
->timer
, tifm_ms_abort
, (unsigned long)host
);
575 msh
->request
= tifm_ms_request
;
576 msh
->set_param
= tifm_ms_set_param
;
577 sock
->card_event
= tifm_ms_card_event
;
578 sock
->data_event
= tifm_ms_data_event
;
579 rc
= tifm_ms_initialize_host(host
);
582 rc
= memstick_add_host(msh
);
586 memstick_free_host(msh
);
590 static void tifm_ms_remove(struct tifm_dev
*sock
)
592 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
593 struct tifm_ms
*host
= memstick_priv(msh
);
597 spin_lock_irqsave(&sock
->lock
, flags
);
600 del_timer(&host
->timer
);
601 writel(TIFM_FIFO_INT_SETALL
,
602 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
603 writel(TIFM_DMA_RESET
, sock
->addr
+ SOCK_DMA_CONTROL
);
604 if ((host
->req
->io_type
== MEMSTICK_IO_SG
) && !host
->no_dma
)
605 tifm_unmap_sg(sock
, &host
->req
->sg
, 1,
606 host
->req
->data_dir
== READ
608 : PCI_DMA_FROMDEVICE
);
609 host
->req
->error
= -ETIME
;
612 rc
= memstick_next_req(msh
, &host
->req
);
614 host
->req
->error
= -ETIME
;
617 spin_unlock_irqrestore(&sock
->lock
, flags
);
619 memstick_remove_host(msh
);
621 writel(0x0200 | TIFM_MS_SYS_NOT_RDY
, sock
->addr
+ SOCK_MS_SYSTEM
);
622 writel(0xffffffff, sock
->addr
+ SOCK_MS_STATUS
);
624 memstick_free_host(msh
);
629 static int tifm_ms_suspend(struct tifm_dev
*sock
, pm_message_t state
)
634 static int tifm_ms_resume(struct tifm_dev
*sock
)
636 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
637 struct tifm_ms
*host
= memstick_priv(msh
);
639 tifm_ms_initialize_host(host
);
640 memstick_detect_change(msh
);
647 #define tifm_ms_suspend NULL
648 #define tifm_ms_resume NULL
650 #endif /* CONFIG_PM */
652 static struct tifm_device_id tifm_ms_id_tbl
[] = {
653 { TIFM_TYPE_MS
}, { 0 }
656 static struct tifm_driver tifm_ms_driver
= {
661 .id_table
= tifm_ms_id_tbl
,
662 .probe
= tifm_ms_probe
,
663 .remove
= tifm_ms_remove
,
664 .suspend
= tifm_ms_suspend
,
665 .resume
= tifm_ms_resume
668 static int __init
tifm_ms_init(void)
670 return tifm_register_driver(&tifm_ms_driver
);
673 static void __exit
tifm_ms_exit(void)
675 tifm_unregister_driver(&tifm_ms_driver
);
678 MODULE_AUTHOR("Alex Dubov");
679 MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
680 MODULE_LICENSE("GPL");
681 MODULE_DEVICE_TABLE(tifm
, tifm_ms_id_tbl
);
682 MODULE_VERSION(DRIVER_VERSION
);
684 module_init(tifm_ms_init
);
685 module_exit(tifm_ms_exit
);