aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memstick/core
diff options
context:
space:
mode:
authorAlex Dubov <oakad@yahoo.com>2008-03-19 20:01:07 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-19 21:53:37 -0400
commit962ee1b10bff5e99e9ecb2a5f4e6399a0214c9cf (patch)
treed04d3463c1f5d4a45faf151c4b7fd1735161edab /drivers/memstick/core
parentead70773608a5d97f81cb492f117d20b5e9f323e (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/core')
-rw-r--r--drivers/memstick/core/mspro_block.c81
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
819static int mspro_block_switch_to_parallel(struct memstick_dev *card) 819static 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
840static 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, &param,
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;