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>
20 #include <linux/module.h>
23 #define DRIVER_NAME "tifm_ms"
26 module_param(no_dma
, bool, 0644);
29 * Some control bits of TIFM appear to conform to Sony's reference design,
30 * so I'm just assuming they all are.
33 #define TIFM_MS_STAT_DRQ 0x04000
34 #define TIFM_MS_STAT_MSINT 0x02000
35 #define TIFM_MS_STAT_RDY 0x01000
36 #define TIFM_MS_STAT_CRC 0x00200
37 #define TIFM_MS_STAT_TOE 0x00100
38 #define TIFM_MS_STAT_EMP 0x00020
39 #define TIFM_MS_STAT_FUL 0x00010
40 #define TIFM_MS_STAT_CED 0x00008
41 #define TIFM_MS_STAT_ERR 0x00004
42 #define TIFM_MS_STAT_BRQ 0x00002
43 #define TIFM_MS_STAT_CNK 0x00001
45 #define TIFM_MS_SYS_DMA 0x10000
46 #define TIFM_MS_SYS_RESET 0x08000
47 #define TIFM_MS_SYS_SRAC 0x04000
48 #define TIFM_MS_SYS_INTEN 0x02000
49 #define TIFM_MS_SYS_NOCRC 0x01000
50 #define TIFM_MS_SYS_INTCLR 0x00800
51 #define TIFM_MS_SYS_MSIEN 0x00400
52 #define TIFM_MS_SYS_FCLR 0x00200
53 #define TIFM_MS_SYS_FDIR 0x00100
54 #define TIFM_MS_SYS_DAM 0x00080
55 #define TIFM_MS_SYS_DRM 0x00040
56 #define TIFM_MS_SYS_DRQSL 0x00020
57 #define TIFM_MS_SYS_REI 0x00010
58 #define TIFM_MS_SYS_REO 0x00008
59 #define TIFM_MS_SYS_BSY_MASK 0x00007
61 #define TIFM_MS_SYS_FIFO (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \
62 | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK)
73 struct timer_list timer
;
74 struct memstick_request
*req
;
75 struct tasklet_struct notify
;
76 unsigned int mode_mask
;
77 unsigned int block_pos
;
78 unsigned long timeout_jiffies
;
79 unsigned char eject
:1,
81 unsigned char cmd_flags
;
86 static unsigned int tifm_ms_read_data(struct tifm_ms
*host
,
87 unsigned char *buf
, unsigned int length
)
89 struct tifm_dev
*sock
= host
->dev
;
92 while (host
->io_pos
&& length
) {
93 buf
[off
++] = host
->io_word
& 0xff;
102 while (!(TIFM_MS_STAT_EMP
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
105 *(unsigned int *)(buf
+ off
) = __raw_readl(sock
->addr
112 && !(TIFM_MS_STAT_EMP
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
113 host
->io_word
= readl(sock
->addr
+ SOCK_MS_DATA
);
114 for (host
->io_pos
= 4; host
->io_pos
; --host
->io_pos
) {
115 buf
[off
++] = host
->io_word
& 0xff;
126 static unsigned int tifm_ms_write_data(struct tifm_ms
*host
,
127 unsigned char *buf
, unsigned int length
)
129 struct tifm_dev
*sock
= host
->dev
;
130 unsigned int off
= 0;
133 while (host
->io_pos
< 4 && length
) {
134 host
->io_word
|= buf
[off
++] << (host
->io_pos
* 8);
140 if (host
->io_pos
== 4
141 && !(TIFM_MS_STAT_FUL
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
142 writel(TIFM_MS_SYS_FDIR
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
143 sock
->addr
+ SOCK_MS_SYSTEM
);
144 writel(host
->io_word
, sock
->addr
+ SOCK_MS_DATA
);
147 } else if (host
->io_pos
) {
154 while (!(TIFM_MS_STAT_FUL
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
157 writel(TIFM_MS_SYS_FDIR
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
158 sock
->addr
+ SOCK_MS_SYSTEM
);
159 __raw_writel(*(unsigned int *)(buf
+ off
),
160 sock
->addr
+ SOCK_MS_DATA
);
167 host
->io_word
|= buf
[off
+ 2] << 16;
170 host
->io_word
|= buf
[off
+ 1] << 8;
173 host
->io_word
|= buf
[off
];
182 static unsigned int tifm_ms_transfer_data(struct tifm_ms
*host
)
184 struct tifm_dev
*sock
= host
->dev
;
187 unsigned int t_size
, p_cnt
;
190 unsigned long flags
= 0;
192 if (host
->req
->long_data
) {
193 length
= host
->req
->sg
.length
- host
->block_pos
;
194 off
= host
->req
->sg
.offset
+ host
->block_pos
;
196 length
= host
->req
->data_len
- host
->block_pos
;
199 dev_dbg(&sock
->dev
, "fifo data transfer, %d, %d\n", length
,
203 unsigned int uninitialized_var(p_off
);
205 if (host
->req
->long_data
) {
206 pg
= nth_page(sg_page(&host
->req
->sg
),
208 p_off
= offset_in_page(off
);
209 p_cnt
= PAGE_SIZE
- p_off
;
210 p_cnt
= min(p_cnt
, length
);
212 local_irq_save(flags
);
213 buf
= kmap_atomic(pg
) + p_off
;
215 buf
= host
->req
->data
+ host
->block_pos
;
216 p_cnt
= host
->req
->data_len
- host
->block_pos
;
219 t_size
= host
->req
->data_dir
== WRITE
220 ? tifm_ms_write_data(host
, buf
, p_cnt
)
221 : tifm_ms_read_data(host
, buf
, p_cnt
);
223 if (host
->req
->long_data
) {
224 kunmap_atomic(buf
- p_off
);
225 local_irq_restore(flags
);
230 host
->block_pos
+= t_size
;
235 dev_dbg(&sock
->dev
, "fifo data transfer, %d remaining\n", length
);
236 if (!length
&& (host
->req
->data_dir
== WRITE
)) {
238 writel(TIFM_MS_SYS_FDIR
239 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
240 sock
->addr
+ SOCK_MS_SYSTEM
);
241 writel(host
->io_word
, sock
->addr
+ SOCK_MS_DATA
);
243 writel(TIFM_MS_SYS_FDIR
244 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
245 sock
->addr
+ SOCK_MS_SYSTEM
);
246 writel(0, sock
->addr
+ SOCK_MS_DATA
);
248 readl(sock
->addr
+ SOCK_MS_DATA
);
254 static int tifm_ms_issue_cmd(struct tifm_ms
*host
)
256 struct tifm_dev
*sock
= host
->dev
;
258 unsigned int data_len
, cmd
, sys_param
;
266 data
= host
->req
->data
;
268 host
->use_dma
= !no_dma
;
270 if (host
->req
->long_data
) {
271 data_len
= host
->req
->sg
.length
;
272 if (!is_power_of_2(data_len
))
275 data_len
= host
->req
->data_len
;
279 writel(TIFM_FIFO_INT_SETALL
,
280 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
281 writel(TIFM_FIFO_ENABLE
,
282 sock
->addr
+ SOCK_FIFO_CONTROL
);
285 if (1 != tifm_map_sg(sock
, &host
->req
->sg
, 1,
286 host
->req
->data_dir
== READ
288 : PCI_DMA_TODEVICE
)) {
289 host
->req
->error
= -ENOMEM
;
290 return host
->req
->error
;
292 data_len
= sg_dma_len(&host
->req
->sg
);
294 writel(ilog2(data_len
) - 2,
295 sock
->addr
+ SOCK_FIFO_PAGE_SIZE
);
296 writel(TIFM_FIFO_INTMASK
,
297 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
298 sys_param
= TIFM_DMA_EN
| (1 << 8);
299 if (host
->req
->data_dir
== WRITE
)
300 sys_param
|= TIFM_DMA_TX
;
302 writel(TIFM_FIFO_INTMASK
,
303 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
305 writel(sg_dma_address(&host
->req
->sg
),
306 sock
->addr
+ SOCK_DMA_ADDRESS
);
307 writel(sys_param
, sock
->addr
+ SOCK_DMA_CONTROL
);
309 writel(host
->mode_mask
| TIFM_MS_SYS_FIFO
,
310 sock
->addr
+ SOCK_MS_SYSTEM
);
312 writel(TIFM_FIFO_MORE
,
313 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
316 mod_timer(&host
->timer
, jiffies
+ host
->timeout_jiffies
);
317 writel(TIFM_CTRL_LED
| readl(sock
->addr
+ SOCK_CONTROL
),
318 sock
->addr
+ SOCK_CONTROL
);
319 host
->req
->error
= 0;
321 sys_param
= readl(sock
->addr
+ SOCK_MS_SYSTEM
);
322 sys_param
|= TIFM_MS_SYS_INTCLR
;
325 sys_param
|= TIFM_MS_SYS_DMA
;
327 sys_param
&= ~TIFM_MS_SYS_DMA
;
329 writel(sys_param
, sock
->addr
+ SOCK_MS_SYSTEM
);
331 cmd
= (host
->req
->tpc
& 0xf) << 12;
333 writel(cmd
, sock
->addr
+ SOCK_MS_COMMAND
);
335 dev_dbg(&sock
->dev
, "executing TPC %x, %x\n", cmd
, sys_param
);
339 static void tifm_ms_complete_cmd(struct tifm_ms
*host
)
341 struct tifm_dev
*sock
= host
->dev
;
342 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
345 del_timer(&host
->timer
);
347 host
->req
->int_reg
= readl(sock
->addr
+ SOCK_MS_STATUS
) & 0xff;
348 host
->req
->int_reg
= (host
->req
->int_reg
& 1)
349 | ((host
->req
->int_reg
<< 4) & 0xe0);
351 writel(TIFM_FIFO_INT_SETALL
,
352 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
353 writel(TIFM_DMA_RESET
, sock
->addr
+ SOCK_DMA_CONTROL
);
356 tifm_unmap_sg(sock
, &host
->req
->sg
, 1,
357 host
->req
->data_dir
== READ
362 writel((~TIFM_CTRL_LED
) & readl(sock
->addr
+ SOCK_CONTROL
),
363 sock
->addr
+ SOCK_CONTROL
);
365 dev_dbg(&sock
->dev
, "TPC complete\n");
367 rc
= memstick_next_req(msh
, &host
->req
);
368 } while (!rc
&& tifm_ms_issue_cmd(host
));
371 static int tifm_ms_check_status(struct tifm_ms
*host
)
373 if (!host
->req
->error
) {
374 if (!(host
->cmd_flags
& CMD_READY
))
376 if (!(host
->cmd_flags
& FIFO_READY
))
378 if (host
->req
->need_card_int
379 && !(host
->cmd_flags
& CARD_INT
))
385 /* Called from interrupt handler */
386 static void tifm_ms_data_event(struct tifm_dev
*sock
)
388 struct tifm_ms
*host
;
389 unsigned int fifo_status
= 0, host_status
= 0;
392 spin_lock(&sock
->lock
);
393 host
= memstick_priv((struct memstick_host
*)tifm_get_drvdata(sock
));
394 fifo_status
= readl(sock
->addr
+ SOCK_DMA_FIFO_STATUS
);
395 host_status
= readl(sock
->addr
+ SOCK_MS_STATUS
);
397 "data event: fifo_status %x, host_status %x, flags %x\n",
398 fifo_status
, host_status
, host
->cmd_flags
);
401 if (host
->use_dma
&& (fifo_status
& 1)) {
402 host
->cmd_flags
|= FIFO_READY
;
403 rc
= tifm_ms_check_status(host
);
405 if (!host
->use_dma
&& (fifo_status
& TIFM_FIFO_MORE
)) {
406 if (!tifm_ms_transfer_data(host
)) {
407 host
->cmd_flags
|= FIFO_READY
;
408 rc
= tifm_ms_check_status(host
);
413 writel(fifo_status
, sock
->addr
+ SOCK_DMA_FIFO_STATUS
);
415 tifm_ms_complete_cmd(host
);
417 spin_unlock(&sock
->lock
);
421 /* Called from interrupt handler */
422 static void tifm_ms_card_event(struct tifm_dev
*sock
)
424 struct tifm_ms
*host
;
425 unsigned int host_status
= 0;
428 spin_lock(&sock
->lock
);
429 host
= memstick_priv((struct memstick_host
*)tifm_get_drvdata(sock
));
430 host_status
= readl(sock
->addr
+ SOCK_MS_STATUS
);
431 dev_dbg(&sock
->dev
, "host event: host_status %x, flags %x\n",
432 host_status
, host
->cmd_flags
);
435 if (host_status
& TIFM_MS_STAT_TOE
)
436 host
->req
->error
= -ETIME
;
437 else if (host_status
& TIFM_MS_STAT_CRC
)
438 host
->req
->error
= -EILSEQ
;
440 if (host_status
& TIFM_MS_STAT_RDY
)
441 host
->cmd_flags
|= CMD_READY
;
443 if (host_status
& TIFM_MS_STAT_MSINT
)
444 host
->cmd_flags
|= CARD_INT
;
446 rc
= tifm_ms_check_status(host
);
450 writel(TIFM_MS_SYS_INTCLR
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
451 sock
->addr
+ SOCK_MS_SYSTEM
);
454 tifm_ms_complete_cmd(host
);
456 spin_unlock(&sock
->lock
);
460 static void tifm_ms_req_tasklet(unsigned long data
)
462 struct memstick_host
*msh
= (struct memstick_host
*)data
;
463 struct tifm_ms
*host
= memstick_priv(msh
);
464 struct tifm_dev
*sock
= host
->dev
;
468 spin_lock_irqsave(&sock
->lock
, flags
);
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
);
487 static void tifm_ms_dummy_submit(struct memstick_host
*msh
)
492 static void tifm_ms_submit_req(struct memstick_host
*msh
)
494 struct tifm_ms
*host
= memstick_priv(msh
);
496 tasklet_schedule(&host
->notify
);
499 static int tifm_ms_set_param(struct memstick_host
*msh
,
500 enum memstick_param param
,
503 struct tifm_ms
*host
= memstick_priv(msh
);
504 struct tifm_dev
*sock
= host
->dev
;
508 /* also affected by media detection mechanism */
509 if (value
== MEMSTICK_POWER_ON
) {
510 host
->mode_mask
= TIFM_MS_SYS_SRAC
| TIFM_MS_SYS_REI
;
511 writel(TIFM_MS_SYS_RESET
, sock
->addr
+ SOCK_MS_SYSTEM
);
512 writel(TIFM_MS_SYS_FCLR
| TIFM_MS_SYS_INTCLR
,
513 sock
->addr
+ SOCK_MS_SYSTEM
);
514 writel(0xffffffff, sock
->addr
+ SOCK_MS_STATUS
);
515 } else if (value
== MEMSTICK_POWER_OFF
) {
516 writel(TIFM_MS_SYS_FCLR
| TIFM_MS_SYS_INTCLR
,
517 sock
->addr
+ SOCK_MS_SYSTEM
);
518 writel(0xffffffff, sock
->addr
+ SOCK_MS_STATUS
);
522 case MEMSTICK_INTERFACE
:
523 if (value
== MEMSTICK_SERIAL
) {
524 host
->mode_mask
= TIFM_MS_SYS_SRAC
| TIFM_MS_SYS_REI
;
525 writel((~TIFM_CTRL_FAST_CLK
)
526 & readl(sock
->addr
+ SOCK_CONTROL
),
527 sock
->addr
+ SOCK_CONTROL
);
528 } else if (value
== MEMSTICK_PAR4
) {
530 writel(TIFM_CTRL_FAST_CLK
531 | readl(sock
->addr
+ SOCK_CONTROL
),
532 sock
->addr
+ SOCK_CONTROL
);
541 static void tifm_ms_abort(struct timer_list
*t
)
543 struct tifm_ms
*host
= from_timer(host
, t
, timer
);
545 dev_dbg(&host
->dev
->dev
, "status %x\n",
546 readl(host
->dev
->addr
+ SOCK_MS_STATUS
));
548 "%s : card failed to respond for a long period of time "
550 dev_name(&host
->dev
->dev
), host
->req
? host
->req
->tpc
: 0,
553 tifm_eject(host
->dev
);
556 static int tifm_ms_probe(struct tifm_dev
*sock
)
558 struct memstick_host
*msh
;
559 struct tifm_ms
*host
;
562 if (!(TIFM_SOCK_STATE_OCCUPIED
563 & readl(sock
->addr
+ SOCK_PRESENT_STATE
))) {
564 printk(KERN_WARNING
"%s : card gone, unexpectedly\n",
565 dev_name(&sock
->dev
));
569 msh
= memstick_alloc_host(sizeof(struct tifm_ms
), &sock
->dev
);
573 host
= memstick_priv(msh
);
574 tifm_set_drvdata(sock
, msh
);
576 host
->timeout_jiffies
= msecs_to_jiffies(1000);
578 timer_setup(&host
->timer
, tifm_ms_abort
, 0);
579 tasklet_init(&host
->notify
, tifm_ms_req_tasklet
, (unsigned long)msh
);
581 msh
->request
= tifm_ms_submit_req
;
582 msh
->set_param
= tifm_ms_set_param
;
583 sock
->card_event
= tifm_ms_card_event
;
584 sock
->data_event
= tifm_ms_data_event
;
585 if (tifm_has_ms_pif(sock
))
586 msh
->caps
|= MEMSTICK_CAP_PAR4
;
588 rc
= memstick_add_host(msh
);
592 memstick_free_host(msh
);
596 static void tifm_ms_remove(struct tifm_dev
*sock
)
598 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
599 struct tifm_ms
*host
= memstick_priv(msh
);
603 msh
->request
= tifm_ms_dummy_submit
;
604 tasklet_kill(&host
->notify
);
605 spin_lock_irqsave(&sock
->lock
, flags
);
608 del_timer(&host
->timer
);
609 writel(TIFM_FIFO_INT_SETALL
,
610 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
611 writel(TIFM_DMA_RESET
, sock
->addr
+ SOCK_DMA_CONTROL
);
613 tifm_unmap_sg(sock
, &host
->req
->sg
, 1,
614 host
->req
->data_dir
== READ
616 : PCI_DMA_FROMDEVICE
);
617 host
->req
->error
= -ETIME
;
620 rc
= memstick_next_req(msh
, &host
->req
);
622 host
->req
->error
= -ETIME
;
625 spin_unlock_irqrestore(&sock
->lock
, flags
);
627 memstick_remove_host(msh
);
628 memstick_free_host(msh
);
633 static int tifm_ms_suspend(struct tifm_dev
*sock
, pm_message_t state
)
635 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
637 memstick_suspend_host(msh
);
641 static int tifm_ms_resume(struct tifm_dev
*sock
)
643 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
645 memstick_resume_host(msh
);
651 #define tifm_ms_suspend NULL
652 #define tifm_ms_resume NULL
654 #endif /* CONFIG_PM */
656 static struct tifm_device_id tifm_ms_id_tbl
[] = {
657 { TIFM_TYPE_MS
}, { 0 }
660 static struct tifm_driver tifm_ms_driver
= {
665 .id_table
= tifm_ms_id_tbl
,
666 .probe
= tifm_ms_probe
,
667 .remove
= tifm_ms_remove
,
668 .suspend
= tifm_ms_suspend
,
669 .resume
= tifm_ms_resume
672 static int __init
tifm_ms_init(void)
674 return tifm_register_driver(&tifm_ms_driver
);
677 static void __exit
tifm_ms_exit(void)
679 tifm_unregister_driver(&tifm_ms_driver
);
682 MODULE_AUTHOR("Alex Dubov");
683 MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
684 MODULE_LICENSE("GPL");
685 MODULE_DEVICE_TABLE(tifm
, tifm_ms_id_tbl
);
687 module_init(tifm_ms_init
);
688 module_exit(tifm_ms_exit
);