14 #include <linux/pci.h>
19 #include <linux/slab.h>
20 #include <linux/module.h>
22 #define DRIVER_NAME "jmb38x_ms"
75 #define BLOCK_COUNT_MASK 0xffff0000
76 #define BLOCK_SIZE_MASK 0x00000fff
78 #define DMA_CONTROL_ENABLE 0x00000001
80 #define TPC_DATA_SEL 0x00008000
81 #define TPC_DIR 0x00004000
82 #define TPC_WAIT_INT 0x00002000
83 #define TPC_GET_INT 0x00000800
84 #define TPC_CODE_SZ_MASK 0x00000700
85 #define TPC_DATA_SZ_MASK 0x00000007
87 #define HOST_CONTROL_TDELAY_EN 0x00040000
88 #define HOST_CONTROL_HW_OC_P 0x00010000
89 #define HOST_CONTROL_RESET_REQ 0x00008000
90 #define HOST_CONTROL_REI 0x00004000
91 #define HOST_CONTROL_LED 0x00000400
92 #define HOST_CONTROL_FAST_CLK 0x00000200
93 #define HOST_CONTROL_RESET 0x00000100
94 #define HOST_CONTROL_POWER_EN 0x00000080
95 #define HOST_CONTROL_CLOCK_EN 0x00000040
96 #define HOST_CONTROL_REO 0x00000008
97 #define HOST_CONTROL_IF_SHIFT 4
99 #define HOST_CONTROL_IF_SERIAL 0x0
100 #define HOST_CONTROL_IF_PAR4 0x1
101 #define HOST_CONTROL_IF_PAR8 0x3
103 #define STATUS_BUSY 0x00080000
104 #define STATUS_MS_DAT7 0x00040000
105 #define STATUS_MS_DAT6 0x00020000
106 #define STATUS_MS_DAT5 0x00010000
107 #define STATUS_MS_DAT4 0x00008000
108 #define STATUS_MS_DAT3 0x00004000
109 #define STATUS_MS_DAT2 0x00002000
110 #define STATUS_MS_DAT1 0x00001000
111 #define STATUS_MS_DAT0 0x00000800
112 #define STATUS_HAS_MEDIA 0x00000400
113 #define STATUS_FIFO_EMPTY 0x00000200
114 #define STATUS_FIFO_FULL 0x00000100
115 #define STATUS_MS_CED 0x00000080
116 #define STATUS_MS_ERR 0x00000040
117 #define STATUS_MS_BRQ 0x00000020
118 #define STATUS_MS_CNK 0x00000001
120 #define INT_STATUS_TPC_ERR 0x00080000
121 #define INT_STATUS_CRC_ERR 0x00040000
122 #define INT_STATUS_TIMER_TO 0x00020000
123 #define INT_STATUS_HSK_TO 0x00010000
124 #define INT_STATUS_ANY_ERR 0x00008000
125 #define INT_STATUS_FIFO_WRDY 0x00000080
126 #define INT_STATUS_FIFO_RRDY 0x00000040
127 #define INT_STATUS_MEDIA_OUT 0x00000010
128 #define INT_STATUS_MEDIA_IN 0x00000008
129 #define INT_STATUS_DMA_BOUNDARY 0x00000004
130 #define INT_STATUS_EOTRAN 0x00000002
131 #define INT_STATUS_EOTPC 0x00000001
133 #define INT_STATUS_ALL 0x000f801f
135 #define PAD_OUTPUT_ENABLE_MS 0x0F3F
137 #define PAD_PU_PD_OFF 0x7FFF0000
138 #define PAD_PU_PD_ON_MS_SOCK0 0x5f8f0000
139 #define PAD_PU_PD_ON_MS_SOCK1 0x0f0f0000
141 #define CLOCK_CONTROL_BY_MMIO 0x00000008
142 #define CLOCK_CONTROL_40MHZ 0x00000001
143 #define CLOCK_CONTROL_50MHZ 0x00000002
144 #define CLOCK_CONTROL_60MHZ 0x00000010
145 #define CLOCK_CONTROL_62_5MHZ 0x00000004
146 #define CLOCK_CONTROL_OFF 0x00000000
148 #define PCI_CTL_CLOCK_DLY_ADDR 0x000000b0
160 unsigned int off = 0;
162 while (host->
io_pos && length) {
163 buf[off++] = host->
io_word[0] & 0xff;
184 buf[off++] = host->
io_word[0] & 0xff;
195 static unsigned int jmb38x_ms_read_reg_data(
struct jmb38x_ms_host *host,
199 unsigned int off = 0;
201 while (host->
io_pos > 4 && length) {
202 buf[off++] = host->
io_word[0] & 0xff;
211 while (host->
io_pos && length) {
212 buf[off++] = host->
io_word[1] & 0xff;
221 static unsigned int jmb38x_ms_write_data(
struct jmb38x_ms_host *host,
225 unsigned int off = 0;
228 while (host->
io_pos < 4 && length) {
240 }
else if (host->
io_pos) {
259 host->
io_word[0] |= buf[off + 2] << 16;
262 host->
io_word[0] |= buf[off + 1] << 8;
274 static unsigned int jmb38x_ms_write_reg_data(
struct jmb38x_ms_host *host,
278 unsigned int off = 0;
280 while (host->
io_pos < 4 && length) {
290 while (host->
io_pos < 8 && length) {
304 unsigned int t_size, p_cnt;
307 unsigned long flags = 0;
309 if (host->
req->long_data) {
320 if (host->
req->long_data) {
321 pg = nth_page(sg_page(&host->
req->sg),
325 p_cnt =
min(p_cnt, length);
336 ? jmb38x_ms_write_data(host, buf, p_cnt)
337 : jmb38x_ms_write_reg_data(host, buf, p_cnt);
340 ? jmb38x_ms_read_data(host, buf, p_cnt)
341 : jmb38x_ms_read_reg_data(host, buf, p_cnt);
343 if (host->
req->long_data) {
355 if (!length && host->
req->data_dir ==
WRITE) {
359 }
else if (host->
io_pos) {
376 return host->
req->error;
389 cmd = host->
req->tpc << 16;
392 if (host->
req->data_dir ==
READ)
395 if (host->
req->need_card_int) {
402 data = host->
req->data;
407 if (host->
req->long_data) {
408 data_len = host->
req->sg.length;
410 data_len = host->
req->data_len;
417 cmd |= data_len & 0xf;
422 if (1 != pci_map_sg(host->
chip->pdev, &host->
req->sg, 1,
427 return host->
req->error;
441 t_val |= host->
req->data_dir ==
READ
450 cmd |= data_len & 0xf;
453 jmb38x_ms_transfer_data(host);
462 host->
req->error = 0;
465 dev_dbg(&msh->
dev,
"executing TPC %08x, len %x\n", cmd, data_len);
470 static void jmb38x_ms_complete_cmd(
struct memstick_host *msh,
int last)
473 unsigned int t_val = 0;
490 pci_unmap_sg(host->
chip->pdev, &host->
req->sg, 1,
495 if (host->
req->data_dir ==
READ)
510 }
while (!rc && jmb38x_ms_issue_cmd(msh));
524 unsigned int irq_status;
526 spin_lock(&host->
lock);
528 dev_dbg(&host->
chip->pdev->dev,
"irq_status = %08x\n", irq_status);
529 if (irq_status == 0 || irq_status == (~0)) {
530 spin_unlock(&host->
lock);
540 jmb38x_ms_complete_cmd(msh, 0);
550 jmb38x_ms_transfer_data(host);
553 jmb38x_ms_transfer_data(host);
561 if (host->
req->data_dir ==
READ) {
570 jmb38x_ms_transfer_data(host);
579 dev_dbg(&host->
chip->pdev->dev,
"media changed\n");
588 || host->
req->error))
589 jmb38x_ms_complete_cmd(msh, 0);
591 spin_unlock(&host->
lock);
595 static void jmb38x_ms_abort(
unsigned long data)
605 jmb38x_ms_complete_cmd(msh, 0);
607 spin_unlock_irqrestore(&host->
lock, flags);
610 static void jmb38x_ms_req_tasklet(
unsigned long data)
621 dev_dbg(&host->
chip->pdev->dev,
"tasklet req %d\n", rc);
622 }
while (!rc && jmb38x_ms_issue_cmd(msh));
624 spin_unlock_irqrestore(&host->
lock, flags);
627 static void jmb38x_ms_dummy_submit(
struct memstick_host *msh)
636 tasklet_schedule(&host->
notify);
648 for (cnt = 0; cnt < 20; ++
cnt) {
655 dev_dbg(&host->
chip->pdev->dev,
"reset_req timeout\n");
663 for (cnt = 0; cnt < 20; ++
cnt) {
670 dev_dbg(&host->
chip->pdev->dev,
"reset timeout\n");
692 rc = jmb38x_ms_reset(host);
722 "Set Host Interface Mode to %d\n", value);
753 pci_write_config_byte(host->
chip->pdev,
762 #define PCI_PMOS0_CONTROL 0xae
763 #define PMOS0_ENABLE 0x01
764 #define PMOS0_OVERCURRENT_LEVEL_2_4V 0x06
765 #define PMOS0_EN_OVERCURRENT_DEBOUNCE 0x40
766 #define PMOS0_SW_LED_POLARITY_ENABLE 0x80
767 #define PMOS0_ACTIVE_BITS (PMOS0_ENABLE | PMOS0_EN_OVERCURRENT_DEBOUNCE | \
768 PMOS0_OVERCURRENT_LEVEL_2_4V)
769 #define PCI_PMOS1_CONTROL 0xbd
770 #define PMOS1_ACTIVE_BITS 0x4a
771 #define PCI_CLOCK_CTL 0xb9
773 static int jmb38x_ms_pmos(
struct pci_dev *pdev,
int flag)
783 dev_dbg(&pdev->
dev,
"JMB38x: set PMOS0 val 0x%x\n", val);
792 dev_dbg(&pdev->
dev,
"JMB38x: set PMOS1 val 0x%x\n", val);
798 dev_dbg(&pdev->
dev,
"Clock Control by PCI config is disabled!\n");
807 struct jmb38x_ms *jm = pci_get_drvdata(dev);
825 struct jmb38x_ms *jm = pci_get_drvdata(dev);
835 jmb38x_ms_pmos(dev, 1);
849 #define jmb38x_ms_suspend NULL
850 #define jmb38x_ms_resume NULL
854 static int jmb38x_ms_count_slots(
struct pci_dev *
pdev)
880 host = memstick_priv(msh);
895 msh->
request = jmb38x_ms_submit_req;
921 static int jmb38x_ms_probe(
struct pci_dev *pdev,
925 int pci_dev_busy = 0;
944 jmb38x_ms_pmos(pdev, 1);
946 cnt = jmb38x_ms_count_slots(pdev);
962 pci_set_drvdata(pdev, jm);
965 jm->
hosts[
cnt] = jmb38x_ms_alloc_host(jm, cnt);
972 jmb38x_ms_free_host(jm->
hosts[cnt]);
983 pci_set_drvdata(pdev,
NULL);
993 static void jmb38x_ms_remove(
struct pci_dev *dev)
995 struct jmb38x_ms *jm = pci_get_drvdata(dev);
1001 if (!jm->
hosts[cnt])
1004 host = memstick_priv(jm->
hosts[cnt]);
1006 jm->
hosts[
cnt]->request = jmb38x_ms_dummy_submit;
1015 jmb38x_ms_complete_cmd(jm->
hosts[cnt], 1);
1017 spin_unlock_irqrestore(&host->
lock, flags);
1022 jmb38x_ms_free_host(jm->
hosts[cnt]);
1025 jmb38x_ms_pmos(dev, 0);
1027 pci_set_drvdata(dev,
NULL);
1040 static struct pci_driver jmb38x_ms_driver = {
1042 .id_table = jmb38x_ms_id_tbl,
1043 .probe = jmb38x_ms_probe,
1044 .remove = jmb38x_ms_remove,
1049 static int __init jmb38x_ms_init(
void)
1051 return pci_register_driver(&jmb38x_ms_driver);
1054 static void __exit jmb38x_ms_exit(
void)