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"
25 module_param(no_dma
, bool, 0644);
28 * Some control bits of TIFM appear to conform to Sony's reference design,
29 * so I'm just assuming they all are.
32 #define TIFM_MS_STAT_DRQ 0x04000
33 #define TIFM_MS_STAT_MSINT 0x02000
34 #define TIFM_MS_STAT_RDY 0x01000
35 #define TIFM_MS_STAT_CRC 0x00200
36 #define TIFM_MS_STAT_TOE 0x00100
37 #define TIFM_MS_STAT_EMP 0x00020
38 #define TIFM_MS_STAT_FUL 0x00010
39 #define TIFM_MS_STAT_CED 0x00008
40 #define TIFM_MS_STAT_ERR 0x00004
41 #define TIFM_MS_STAT_BRQ 0x00002
42 #define TIFM_MS_STAT_CNK 0x00001
44 #define TIFM_MS_SYS_DMA 0x10000
45 #define TIFM_MS_SYS_RESET 0x08000
46 #define TIFM_MS_SYS_SRAC 0x04000
47 #define TIFM_MS_SYS_INTEN 0x02000
48 #define TIFM_MS_SYS_NOCRC 0x01000
49 #define TIFM_MS_SYS_INTCLR 0x00800
50 #define TIFM_MS_SYS_MSIEN 0x00400
51 #define TIFM_MS_SYS_FCLR 0x00200
52 #define TIFM_MS_SYS_FDIR 0x00100
53 #define TIFM_MS_SYS_DAM 0x00080
54 #define TIFM_MS_SYS_DRM 0x00040
55 #define TIFM_MS_SYS_DRQSL 0x00020
56 #define TIFM_MS_SYS_REI 0x00010
57 #define TIFM_MS_SYS_REO 0x00008
58 #define TIFM_MS_SYS_BSY_MASK 0x00007
60 #define TIFM_MS_SYS_FIFO (TIFM_MS_SYS_INTEN | TIFM_MS_SYS_MSIEN \
61 | TIFM_MS_SYS_FCLR | TIFM_MS_SYS_BSY_MASK)
72 struct timer_list timer
;
73 struct memstick_request
*req
;
74 unsigned int mode_mask
;
75 unsigned int block_pos
;
76 unsigned long timeout_jiffies
;
77 unsigned char eject
:1,
79 unsigned char cmd_flags
;
84 static unsigned int tifm_ms_read_data(struct tifm_ms
*host
,
85 unsigned char *buf
, unsigned int length
)
87 struct tifm_dev
*sock
= host
->dev
;
90 while (host
->io_pos
&& length
) {
91 buf
[off
++] = host
->io_word
& 0xff;
100 while (!(TIFM_MS_STAT_EMP
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
103 *(unsigned int *)(buf
+ off
) = __raw_readl(sock
->addr
110 && !(TIFM_MS_STAT_EMP
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
111 host
->io_word
= readl(sock
->addr
+ SOCK_MS_DATA
);
112 for (host
->io_pos
= 4; host
->io_pos
; --host
->io_pos
) {
113 buf
[off
++] = host
->io_word
& 0xff;
124 static unsigned int tifm_ms_write_data(struct tifm_ms
*host
,
125 unsigned char *buf
, unsigned int length
)
127 struct tifm_dev
*sock
= host
->dev
;
128 unsigned int off
= 0;
131 while (host
->io_pos
< 4 && length
) {
132 host
->io_word
|= buf
[off
++] << (host
->io_pos
* 8);
138 if (host
->io_pos
== 4
139 && !(TIFM_MS_STAT_FUL
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
140 writel(TIFM_MS_SYS_FDIR
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
141 sock
->addr
+ SOCK_MS_SYSTEM
);
142 writel(host
->io_word
, sock
->addr
+ SOCK_MS_DATA
);
145 } else if (host
->io_pos
) {
152 while (!(TIFM_MS_STAT_FUL
& readl(sock
->addr
+ SOCK_MS_STATUS
))) {
155 writel(TIFM_MS_SYS_FDIR
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
156 sock
->addr
+ SOCK_MS_SYSTEM
);
157 __raw_writel(*(unsigned int *)(buf
+ off
),
158 sock
->addr
+ SOCK_MS_DATA
);
165 host
->io_word
|= buf
[off
+ 2] << 16;
168 host
->io_word
|= buf
[off
+ 1] << 8;
171 host
->io_word
|= buf
[off
];
180 static unsigned int tifm_ms_transfer_data(struct tifm_ms
*host
)
182 struct tifm_dev
*sock
= host
->dev
;
185 unsigned int t_size
, p_off
, p_cnt
;
188 unsigned long flags
= 0;
190 if (host
->req
->long_data
) {
191 length
= host
->req
->sg
.length
- host
->block_pos
;
192 off
= host
->req
->sg
.offset
+ host
->block_pos
;
194 length
= host
->req
->data_len
- host
->block_pos
;
197 dev_dbg(&sock
->dev
, "fifo data transfer, %d, %d\n", length
,
201 if (host
->req
->long_data
) {
202 pg
= nth_page(sg_page(&host
->req
->sg
),
204 p_off
= offset_in_page(off
);
205 p_cnt
= PAGE_SIZE
- p_off
;
206 p_cnt
= min(p_cnt
, length
);
208 local_irq_save(flags
);
209 buf
= kmap_atomic(pg
, KM_BIO_SRC_IRQ
) + p_off
;
211 buf
= host
->req
->data
+ host
->block_pos
;
212 p_cnt
= host
->req
->data_len
- host
->block_pos
;
215 t_size
= host
->req
->data_dir
== WRITE
216 ? tifm_ms_write_data(host
, buf
, p_cnt
)
217 : tifm_ms_read_data(host
, buf
, p_cnt
);
219 if (host
->req
->long_data
) {
220 kunmap_atomic(buf
- p_off
, KM_BIO_SRC_IRQ
);
221 local_irq_restore(flags
);
226 host
->block_pos
+= t_size
;
231 dev_dbg(&sock
->dev
, "fifo data transfer, %d remaining\n", length
);
232 if (!length
&& (host
->req
->data_dir
== WRITE
)) {
234 writel(TIFM_MS_SYS_FDIR
235 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
236 sock
->addr
+ SOCK_MS_SYSTEM
);
237 writel(host
->io_word
, sock
->addr
+ SOCK_MS_DATA
);
239 writel(TIFM_MS_SYS_FDIR
240 | readl(sock
->addr
+ SOCK_MS_SYSTEM
),
241 sock
->addr
+ SOCK_MS_SYSTEM
);
242 writel(0, sock
->addr
+ SOCK_MS_DATA
);
244 readl(sock
->addr
+ SOCK_MS_DATA
);
250 static int tifm_ms_issue_cmd(struct tifm_ms
*host
)
252 struct tifm_dev
*sock
= host
->dev
;
254 unsigned int data_len
, cmd
, sys_param
;
262 data
= host
->req
->data
;
264 host
->use_dma
= !no_dma
;
266 if (host
->req
->long_data
) {
267 data_len
= host
->req
->sg
.length
;
268 if (!is_power_of_2(data_len
))
271 data_len
= host
->req
->data_len
;
275 writel(TIFM_FIFO_INT_SETALL
,
276 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
277 writel(TIFM_FIFO_ENABLE
,
278 sock
->addr
+ SOCK_FIFO_CONTROL
);
281 if (1 != tifm_map_sg(sock
, &host
->req
->sg
, 1,
282 host
->req
->data_dir
== READ
284 : PCI_DMA_TODEVICE
)) {
285 host
->req
->error
= -ENOMEM
;
286 return host
->req
->error
;
288 data_len
= sg_dma_len(&host
->req
->sg
);
290 writel(ilog2(data_len
) - 2,
291 sock
->addr
+ SOCK_FIFO_PAGE_SIZE
);
292 writel(TIFM_FIFO_INTMASK
,
293 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
294 sys_param
= TIFM_DMA_EN
| (1 << 8);
295 if (host
->req
->data_dir
== WRITE
)
296 sys_param
|= TIFM_DMA_TX
;
298 writel(TIFM_FIFO_INTMASK
,
299 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
301 writel(sg_dma_address(&host
->req
->sg
),
302 sock
->addr
+ SOCK_DMA_ADDRESS
);
303 writel(sys_param
, sock
->addr
+ SOCK_DMA_CONTROL
);
305 writel(host
->mode_mask
| TIFM_MS_SYS_FIFO
,
306 sock
->addr
+ SOCK_MS_SYSTEM
);
308 writel(TIFM_FIFO_MORE
,
309 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_SET
);
312 mod_timer(&host
->timer
, jiffies
+ host
->timeout_jiffies
);
313 writel(TIFM_CTRL_LED
| readl(sock
->addr
+ SOCK_CONTROL
),
314 sock
->addr
+ SOCK_CONTROL
);
315 host
->req
->error
= 0;
317 sys_param
= readl(sock
->addr
+ SOCK_MS_SYSTEM
);
318 sys_param
|= TIFM_MS_SYS_INTCLR
;
321 sys_param
|= TIFM_MS_SYS_DMA
;
323 sys_param
&= ~TIFM_MS_SYS_DMA
;
325 writel(sys_param
, sock
->addr
+ SOCK_MS_SYSTEM
);
327 cmd
= (host
->req
->tpc
& 0xf) << 12;
329 writel(cmd
, sock
->addr
+ SOCK_MS_COMMAND
);
331 dev_dbg(&sock
->dev
, "executing TPC %x, %x\n", cmd
, sys_param
);
335 static void tifm_ms_complete_cmd(struct tifm_ms
*host
)
337 struct tifm_dev
*sock
= host
->dev
;
338 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
341 del_timer(&host
->timer
);
344 tifm_unmap_sg(sock
, &host
->req
->sg
, 1,
345 host
->req
->data_dir
== READ
349 writel((~TIFM_CTRL_LED
) & readl(sock
->addr
+ SOCK_CONTROL
),
350 sock
->addr
+ SOCK_CONTROL
);
352 dev_dbg(&sock
->dev
, "TPC complete\n");
354 rc
= memstick_next_req(msh
, &host
->req
);
355 } while (!rc
&& tifm_ms_issue_cmd(host
));
358 static int tifm_ms_check_status(struct tifm_ms
*host
)
360 if (!host
->req
->error
) {
361 if (!(host
->cmd_flags
& CMD_READY
))
363 if (!(host
->cmd_flags
& FIFO_READY
))
365 if (host
->req
->need_card_int
366 && !(host
->cmd_flags
& CARD_INT
))
372 /* Called from interrupt handler */
373 static void tifm_ms_data_event(struct tifm_dev
*sock
)
375 struct tifm_ms
*host
;
376 unsigned int fifo_status
= 0, host_status
= 0;
379 spin_lock(&sock
->lock
);
380 host
= memstick_priv((struct memstick_host
*)tifm_get_drvdata(sock
));
381 fifo_status
= readl(sock
->addr
+ SOCK_DMA_FIFO_STATUS
);
382 host_status
= readl(sock
->addr
+ SOCK_MS_STATUS
);
384 "data event: fifo_status %x, host_status %x, flags %x\n",
385 fifo_status
, host_status
, host
->cmd_flags
);
388 if (host
->use_dma
&& (fifo_status
& 1)) {
389 host
->cmd_flags
|= FIFO_READY
;
390 rc
= tifm_ms_check_status(host
);
392 if (!host
->use_dma
&& (fifo_status
& TIFM_FIFO_MORE
)) {
393 if (!tifm_ms_transfer_data(host
)) {
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_STAT_TOE
)
423 host
->req
->error
= -ETIME
;
424 else if (host_status
& TIFM_MS_STAT_CRC
)
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_STAT_RDY
)
434 host
->cmd_flags
|= CMD_READY
;
436 if (host_status
& TIFM_MS_STAT_MSINT
)
437 host
->cmd_flags
|= CARD_INT
;
439 rc
= tifm_ms_check_status(host
);
443 writel(TIFM_MS_SYS_INTCLR
| readl(sock
->addr
+ SOCK_MS_SYSTEM
),
444 sock
->addr
+ SOCK_MS_SYSTEM
);
447 tifm_ms_complete_cmd(host
);
449 spin_unlock(&sock
->lock
);
453 static void tifm_ms_request(struct memstick_host
*msh
)
455 struct tifm_ms
*host
= memstick_priv(msh
);
456 struct tifm_dev
*sock
= host
->dev
;
460 spin_lock_irqsave(&sock
->lock
, flags
);
462 printk(KERN_ERR
"%s : unfinished request detected\n",
464 spin_unlock_irqrestore(&sock
->lock
, flags
);
465 tifm_eject(host
->dev
);
471 rc
= memstick_next_req(msh
, &host
->req
);
473 host
->req
->error
= -ETIME
;
475 spin_unlock_irqrestore(&sock
->lock
, flags
);
480 rc
= memstick_next_req(msh
, &host
->req
);
481 } while (!rc
&& tifm_ms_issue_cmd(host
));
483 spin_unlock_irqrestore(&sock
->lock
, flags
);
487 static void tifm_ms_set_param(struct memstick_host
*msh
,
488 enum memstick_param param
,
491 struct tifm_ms
*host
= memstick_priv(msh
);
492 struct tifm_dev
*sock
= host
->dev
;
495 spin_lock_irqsave(&sock
->lock
, flags
);
499 /* also affected by media detection mechanism */
500 if (value
== MEMSTICK_POWER_ON
) {
501 host
->mode_mask
= TIFM_MS_SYS_SRAC
| TIFM_MS_SYS_REI
;
502 writel(TIFM_MS_SYS_RESET
, sock
->addr
+ SOCK_MS_SYSTEM
);
503 writel(TIFM_MS_SYS_FCLR
| TIFM_MS_SYS_INTCLR
,
504 sock
->addr
+ SOCK_MS_SYSTEM
);
505 writel(0xffffffff, sock
->addr
+ SOCK_MS_STATUS
);
506 } else if (value
== MEMSTICK_POWER_OFF
) {
507 writel(TIFM_MS_SYS_FCLR
| TIFM_MS_SYS_INTCLR
,
508 sock
->addr
+ SOCK_MS_SYSTEM
);
509 writel(0xffffffff, sock
->addr
+ SOCK_MS_STATUS
);
512 case MEMSTICK_INTERFACE
:
513 if (value
== MEMSTICK_SERIAL
) {
514 host
->mode_mask
= TIFM_MS_SYS_SRAC
| TIFM_MS_SYS_REI
;
515 writel((~TIFM_CTRL_FAST_CLK
)
516 & readl(sock
->addr
+ SOCK_CONTROL
),
517 sock
->addr
+ SOCK_CONTROL
);
518 } else if (value
== MEMSTICK_PAR4
) {
520 writel(TIFM_CTRL_FAST_CLK
521 | readl(sock
->addr
+ SOCK_CONTROL
),
522 sock
->addr
+ SOCK_CONTROL
);
527 spin_unlock_irqrestore(&sock
->lock
, flags
);
530 static void tifm_ms_abort(unsigned long data
)
532 struct tifm_ms
*host
= (struct tifm_ms
*)data
;
534 dev_dbg(&host
->dev
->dev
, "status %x\n",
535 readl(host
->dev
->addr
+ SOCK_MS_STATUS
));
537 "%s : card failed to respond for a long period of time "
539 host
->dev
->dev
.bus_id
, host
->req
? host
->req
->tpc
: 0,
542 tifm_eject(host
->dev
);
545 static int tifm_ms_probe(struct tifm_dev
*sock
)
547 struct memstick_host
*msh
;
548 struct tifm_ms
*host
;
551 if (!(TIFM_SOCK_STATE_OCCUPIED
552 & readl(sock
->addr
+ SOCK_PRESENT_STATE
))) {
553 printk(KERN_WARNING
"%s : card gone, unexpectedly\n",
558 msh
= memstick_alloc_host(sizeof(struct tifm_ms
), &sock
->dev
);
562 host
= memstick_priv(msh
);
563 tifm_set_drvdata(sock
, msh
);
565 host
->timeout_jiffies
= msecs_to_jiffies(1000);
567 setup_timer(&host
->timer
, tifm_ms_abort
, (unsigned long)host
);
569 msh
->request
= tifm_ms_request
;
570 msh
->set_param
= tifm_ms_set_param
;
571 sock
->card_event
= tifm_ms_card_event
;
572 sock
->data_event
= tifm_ms_data_event
;
573 if (tifm_has_ms_pif(sock
))
574 msh
->caps
|= MEMSTICK_CAP_PAR4
;
576 rc
= memstick_add_host(msh
);
580 memstick_free_host(msh
);
584 static void tifm_ms_remove(struct tifm_dev
*sock
)
586 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
587 struct tifm_ms
*host
= memstick_priv(msh
);
591 spin_lock_irqsave(&sock
->lock
, flags
);
594 del_timer(&host
->timer
);
595 writel(TIFM_FIFO_INT_SETALL
,
596 sock
->addr
+ SOCK_DMA_FIFO_INT_ENABLE_CLEAR
);
597 writel(TIFM_DMA_RESET
, sock
->addr
+ SOCK_DMA_CONTROL
);
599 tifm_unmap_sg(sock
, &host
->req
->sg
, 1,
600 host
->req
->data_dir
== READ
602 : PCI_DMA_FROMDEVICE
);
603 host
->req
->error
= -ETIME
;
606 rc
= memstick_next_req(msh
, &host
->req
);
608 host
->req
->error
= -ETIME
;
611 spin_unlock_irqrestore(&sock
->lock
, flags
);
613 memstick_remove_host(msh
);
614 memstick_free_host(msh
);
619 static int tifm_ms_suspend(struct tifm_dev
*sock
, pm_message_t state
)
621 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
623 memstick_suspend_host(msh
);
627 static int tifm_ms_resume(struct tifm_dev
*sock
)
629 struct memstick_host
*msh
= tifm_get_drvdata(sock
);
631 memstick_resume_host(msh
);
637 #define tifm_ms_suspend NULL
638 #define tifm_ms_resume NULL
640 #endif /* CONFIG_PM */
642 static struct tifm_device_id tifm_ms_id_tbl
[] = {
643 { TIFM_TYPE_MS
}, { 0 }
646 static struct tifm_driver tifm_ms_driver
= {
651 .id_table
= tifm_ms_id_tbl
,
652 .probe
= tifm_ms_probe
,
653 .remove
= tifm_ms_remove
,
654 .suspend
= tifm_ms_suspend
,
655 .resume
= tifm_ms_resume
658 static int __init
tifm_ms_init(void)
660 return tifm_register_driver(&tifm_ms_driver
);
663 static void __exit
tifm_ms_exit(void)
665 tifm_unregister_driver(&tifm_ms_driver
);
668 MODULE_AUTHOR("Alex Dubov");
669 MODULE_DESCRIPTION("TI FlashMedia MemoryStick driver");
670 MODULE_LICENSE("GPL");
671 MODULE_DEVICE_TABLE(tifm
, tifm_ms_id_tbl
);
673 module_init(tifm_ms_init
);
674 module_exit(tifm_ms_exit
);