diff options
| author | Alex Dubov <oakad@yahoo.com> | 2008-03-19 20:01:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-03-19 21:53:37 -0400 |
| commit | 962ee1b10bff5e99e9ecb2a5f4e6399a0214c9cf (patch) | |
| tree | d04d3463c1f5d4a45faf151c4b7fd1735161edab /drivers/memstick | |
| parent | ead70773608a5d97f81cb492f117d20b5e9f323e (diff) | |
memstick: add support for 8-bit parallel mode
Newer MemoryStick (HG) cards and hosts support 8-bit parallel mode of
operation in addition to original 4-bit and 1-bit modes.
Signed-off-by: Alex Dubov <oakad@yahoo.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/memstick')
| -rw-r--r-- | drivers/memstick/core/mspro_block.c | 81 |
1 files changed, 55 insertions, 26 deletions
diff --git a/drivers/memstick/core/mspro_block.c b/drivers/memstick/core/mspro_block.c index e5356f97d076..557dbbba5cb2 100644 --- a/drivers/memstick/core/mspro_block.c +++ b/drivers/memstick/core/mspro_block.c | |||
| @@ -816,12 +816,13 @@ static int mspro_block_wait_for_ced(struct memstick_dev *card) | |||
| 816 | return card->current_mrq.error; | 816 | return card->current_mrq.error; |
| 817 | } | 817 | } |
| 818 | 818 | ||
| 819 | static int mspro_block_switch_to_parallel(struct memstick_dev *card) | 819 | static int mspro_block_set_interface(struct memstick_dev *card, |
| 820 | unsigned char sys_reg) | ||
| 820 | { | 821 | { |
| 821 | struct memstick_host *host = card->host; | 822 | struct memstick_host *host = card->host; |
| 822 | struct mspro_block_data *msb = memstick_get_drvdata(card); | 823 | struct mspro_block_data *msb = memstick_get_drvdata(card); |
| 823 | struct mspro_param_register param = { | 824 | struct mspro_param_register param = { |
| 824 | .system = MEMSTICK_SYS_PAR4, | 825 | .system = sys_reg, |
| 825 | .data_count = 0, | 826 | .data_count = 0, |
| 826 | .data_address = 0, | 827 | .data_address = 0, |
| 827 | .tpc_param = 0 | 828 | .tpc_param = 0 |
| @@ -833,41 +834,70 @@ static int mspro_block_switch_to_parallel(struct memstick_dev *card) | |||
| 833 | sizeof(param)); | 834 | sizeof(param)); |
| 834 | memstick_new_req(host); | 835 | memstick_new_req(host); |
| 835 | wait_for_completion(&card->mrq_complete); | 836 | wait_for_completion(&card->mrq_complete); |
| 836 | if (card->current_mrq.error) | 837 | return card->current_mrq.error; |
| 837 | return card->current_mrq.error; | 838 | } |
| 839 | |||
| 840 | static int mspro_block_switch_interface(struct memstick_dev *card) | ||
| 841 | { | ||
| 842 | struct memstick_host *host = card->host; | ||
| 843 | struct mspro_block_data *msb = memstick_get_drvdata(card); | ||
| 844 | int rc = 0; | ||
| 845 | |||
| 846 | if (msb->caps & MEMSTICK_CAP_PAR4) | ||
| 847 | rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR4); | ||
| 848 | else | ||
| 849 | return 0; | ||
| 850 | |||
| 851 | if (rc) { | ||
| 852 | printk(KERN_WARNING | ||
| 853 | "%s: could not switch to 4-bit mode, error %d\n", | ||
| 854 | card->dev.bus_id, rc); | ||
| 855 | return 0; | ||
| 856 | } | ||
| 838 | 857 | ||
| 839 | msb->system = MEMSTICK_SYS_PAR4; | 858 | msb->system = MEMSTICK_SYS_PAR4; |
| 840 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4); | 859 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_PAR4); |
| 860 | printk(KERN_INFO "%s: switching to 4-bit parallel mode\n", | ||
| 861 | card->dev.bus_id); | ||
| 862 | |||
| 863 | if (msb->caps & MEMSTICK_CAP_PAR8) { | ||
| 864 | rc = mspro_block_set_interface(card, MEMSTICK_SYS_PAR8); | ||
| 865 | |||
| 866 | if (!rc) { | ||
| 867 | msb->system = MEMSTICK_SYS_PAR8; | ||
| 868 | host->set_param(host, MEMSTICK_INTERFACE, | ||
| 869 | MEMSTICK_PAR8); | ||
| 870 | printk(KERN_INFO | ||
| 871 | "%s: switching to 8-bit parallel mode\n", | ||
| 872 | card->dev.bus_id); | ||
| 873 | } else | ||
| 874 | printk(KERN_WARNING | ||
| 875 | "%s: could not switch to 8-bit mode, error %d\n", | ||
| 876 | card->dev.bus_id, rc); | ||
| 877 | } | ||
| 841 | 878 | ||
| 842 | card->next_request = h_mspro_block_req_init; | 879 | card->next_request = h_mspro_block_req_init; |
| 843 | msb->mrq_handler = h_mspro_block_default; | 880 | msb->mrq_handler = h_mspro_block_default; |
| 844 | memstick_init_req(&card->current_mrq, MS_TPC_GET_INT, NULL, 1); | 881 | memstick_init_req(&card->current_mrq, MS_TPC_GET_INT, NULL, 1); |
| 845 | memstick_new_req(card->host); | 882 | memstick_new_req(card->host); |
| 846 | wait_for_completion(&card->mrq_complete); | 883 | wait_for_completion(&card->mrq_complete); |
| 884 | rc = card->current_mrq.error; | ||
| 847 | 885 | ||
| 848 | if (card->current_mrq.error) { | 886 | if (rc) { |
| 887 | printk(KERN_WARNING | ||
| 888 | "%s: interface error, trying to fall back to serial\n", | ||
| 889 | card->dev.bus_id); | ||
| 849 | msb->system = MEMSTICK_SYS_SERIAL; | 890 | msb->system = MEMSTICK_SYS_SERIAL; |
| 850 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); | 891 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_OFF); |
| 851 | msleep(1000); | 892 | msleep(10); |
| 852 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); | 893 | host->set_param(host, MEMSTICK_POWER, MEMSTICK_POWER_ON); |
| 853 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); | 894 | host->set_param(host, MEMSTICK_INTERFACE, MEMSTICK_SERIAL); |
| 854 | 895 | ||
| 855 | if (memstick_set_rw_addr(card)) | 896 | rc = memstick_set_rw_addr(card); |
| 856 | return card->current_mrq.error; | 897 | if (!rc) |
| 857 | 898 | rc = mspro_block_set_interface(card, msb->system); | |
| 858 | param.system = msb->system; | ||
| 859 | |||
| 860 | card->next_request = h_mspro_block_req_init; | ||
| 861 | msb->mrq_handler = h_mspro_block_default; | ||
| 862 | memstick_init_req(&card->current_mrq, MS_TPC_WRITE_REG, ¶m, | ||
| 863 | sizeof(param)); | ||
| 864 | memstick_new_req(host); | ||
| 865 | wait_for_completion(&card->mrq_complete); | ||
| 866 | |||
| 867 | return -EFAULT; | ||
| 868 | } | 899 | } |
| 869 | 900 | return rc; | |
| 870 | return 0; | ||
| 871 | } | 901 | } |
| 872 | 902 | ||
| 873 | /* Memory allocated for attributes by this function should be freed by | 903 | /* Memory allocated for attributes by this function should be freed by |
| @@ -1053,12 +1083,11 @@ static int mspro_block_init_card(struct memstick_dev *card) | |||
| 1053 | return -EIO; | 1083 | return -EIO; |
| 1054 | 1084 | ||
| 1055 | msb->caps = host->caps; | 1085 | msb->caps = host->caps; |
| 1056 | if (msb->caps & MEMSTICK_CAP_PAR4) { | 1086 | rc = mspro_block_switch_interface(card); |
| 1057 | if (mspro_block_switch_to_parallel(card)) | 1087 | if (rc) |
| 1058 | printk(KERN_WARNING "%s: could not switch to " | 1088 | return rc; |
| 1059 | "parallel interface\n", card->dev.bus_id); | ||
| 1060 | } | ||
| 1061 | 1089 | ||
| 1090 | msleep(200); | ||
| 1062 | rc = mspro_block_wait_for_ced(card); | 1091 | rc = mspro_block_wait_for_ced(card); |
| 1063 | if (rc) | 1092 | if (rc) |
| 1064 | return rc; | 1093 | return rc; |
