aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrank Seidel <fseidel@suse.de>2008-02-04 13:25:42 -0500
committerPierre Ossman <drzeus@drzeus.cx>2008-02-08 03:02:47 -0500
commit882c49164d72c45f37d7fa1bb3de7c31cf1a5fab (patch)
tree2db5b00ad700c31999fc5e3eecd5d8a28b84fad4
parent6e996ee8e730a50eef51cdb072b166fe8f80831e (diff)
mmc: extend ricoh_mmc to support Ricoh RL5c476
This patch adds support for the Ricoh RL5c476 chip: with this the mmc adapter that needs this disabler (R5C843) can also be handled correctly when it sits on a RL5c476. Signed-off-by: Frank Seidel <fseidel@suse.de> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
-rw-r--r--drivers/mmc/host/ricoh_mmc.c101
1 files changed, 80 insertions, 21 deletions
diff --git a/drivers/mmc/host/ricoh_mmc.c b/drivers/mmc/host/ricoh_mmc.c
index 898e7991caef..a16d7609e4ee 100644
--- a/drivers/mmc/host/ricoh_mmc.c
+++ b/drivers/mmc/host/ricoh_mmc.c
@@ -44,19 +44,43 @@ MODULE_DEVICE_TABLE(pci, pci_ids);
44static int ricoh_mmc_disable(struct pci_dev *fw_dev) 44static int ricoh_mmc_disable(struct pci_dev *fw_dev)
45{ 45{
46 u8 write_enable; 46 u8 write_enable;
47 u8 write_target;
47 u8 disable; 48 u8 disable;
48 49
49 pci_read_config_byte(fw_dev, 0xCB, &disable); 50 if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
50 if (disable & 0x02) { 51 /* via RL5C476 */
51 printk(KERN_INFO DRIVER_NAME
52 ": Controller already disabled. Nothing to do.\n");
53 return -ENODEV;
54 }
55 52
56 pci_read_config_byte(fw_dev, 0xCA, &write_enable); 53 pci_read_config_byte(fw_dev, 0xB7, &disable);
57 pci_write_config_byte(fw_dev, 0xCA, 0x57); 54 if (disable & 0x02) {
58 pci_write_config_byte(fw_dev, 0xCB, disable | 0x02); 55 printk(KERN_INFO DRIVER_NAME
59 pci_write_config_byte(fw_dev, 0xCA, write_enable); 56 ": Controller already disabled. " \
57 "Nothing to do.\n");
58 return -ENODEV;
59 }
60
61 pci_read_config_byte(fw_dev, 0x8E, &write_enable);
62 pci_write_config_byte(fw_dev, 0x8E, 0xAA);
63 pci_read_config_byte(fw_dev, 0x8D, &write_target);
64 pci_write_config_byte(fw_dev, 0x8D, 0xB7);
65 pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
66 pci_write_config_byte(fw_dev, 0x8E, write_enable);
67 pci_write_config_byte(fw_dev, 0x8D, write_target);
68 } else {
69 /* via R5C832 */
70
71 pci_read_config_byte(fw_dev, 0xCB, &disable);
72 if (disable & 0x02) {
73 printk(KERN_INFO DRIVER_NAME
74 ": Controller already disabled. " \
75 "Nothing to do.\n");
76 return -ENODEV;
77 }
78
79 pci_read_config_byte(fw_dev, 0xCA, &write_enable);
80 pci_write_config_byte(fw_dev, 0xCA, 0x57);
81 pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
82 pci_write_config_byte(fw_dev, 0xCA, write_enable);
83 }
60 84
61 printk(KERN_INFO DRIVER_NAME 85 printk(KERN_INFO DRIVER_NAME
62 ": Controller is now disabled.\n"); 86 ": Controller is now disabled.\n");
@@ -67,13 +91,29 @@ static int ricoh_mmc_disable(struct pci_dev *fw_dev)
67static int ricoh_mmc_enable(struct pci_dev *fw_dev) 91static int ricoh_mmc_enable(struct pci_dev *fw_dev)
68{ 92{
69 u8 write_enable; 93 u8 write_enable;
94 u8 write_target;
70 u8 disable; 95 u8 disable;
71 96
72 pci_read_config_byte(fw_dev, 0xCA, &write_enable); 97 if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
73 pci_read_config_byte(fw_dev, 0xCB, &disable); 98 /* via RL5C476 */
74 pci_write_config_byte(fw_dev, 0xCA, 0x57); 99
75 pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02); 100 pci_read_config_byte(fw_dev, 0x8E, &write_enable);
76 pci_write_config_byte(fw_dev, 0xCA, write_enable); 101 pci_write_config_byte(fw_dev, 0x8E, 0xAA);
102 pci_read_config_byte(fw_dev, 0x8D, &write_target);
103 pci_write_config_byte(fw_dev, 0x8D, 0xB7);
104 pci_read_config_byte(fw_dev, 0xB7, &disable);
105 pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
106 pci_write_config_byte(fw_dev, 0x8E, write_enable);
107 pci_write_config_byte(fw_dev, 0x8D, write_target);
108 } else {
109 /* via R5C832 */
110
111 pci_read_config_byte(fw_dev, 0xCA, &write_enable);
112 pci_read_config_byte(fw_dev, 0xCB, &disable);
113 pci_write_config_byte(fw_dev, 0xCA, 0x57);
114 pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
115 pci_write_config_byte(fw_dev, 0xCA, write_enable);
116 }
77 117
78 printk(KERN_INFO DRIVER_NAME 118 printk(KERN_INFO DRIVER_NAME
79 ": Controller is now re-enabled.\n"); 119 ": Controller is now re-enabled.\n");
@@ -85,6 +125,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
85 const struct pci_device_id *ent) 125 const struct pci_device_id *ent)
86{ 126{
87 u8 rev; 127 u8 rev;
128 u8 ctrlfound = 0;
88 129
89 struct pci_dev *fw_dev = NULL; 130 struct pci_dev *fw_dev = NULL;
90 131
@@ -98,20 +139,38 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
98 pci_name(pdev), (int)pdev->vendor, (int)pdev->device, 139 pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
99 (int)rev); 140 (int)rev);
100 141
101 while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) { 142 while ((fw_dev =
143 pci_get_device(PCI_VENDOR_ID_RICOH,
144 PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {
102 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) && 145 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
103 pdev->bus == fw_dev->bus) { 146 pdev->bus == fw_dev->bus) {
104 if (ricoh_mmc_disable(fw_dev) != 0) { 147 if (ricoh_mmc_disable(fw_dev) != 0)
105 return -ENODEV; 148 return -ENODEV;
106 }
107 149
108 pci_set_drvdata(pdev, fw_dev); 150 pci_set_drvdata(pdev, fw_dev);
109 151
152 ++ctrlfound;
110 break; 153 break;
111 } 154 }
112 } 155 }
113 156
114 if (pci_get_drvdata(pdev) == NULL) { 157 fw_dev = NULL;
158
159 while (!ctrlfound &&
160 (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
161 PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
162 if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
163 pdev->bus == fw_dev->bus) {
164 if (ricoh_mmc_disable(fw_dev) != 0)
165 return -ENODEV;
166
167 pci_set_drvdata(pdev, fw_dev);
168
169 ++ctrlfound;
170 }
171 }
172
173 if (!ctrlfound) {
115 printk(KERN_WARNING DRIVER_NAME 174 printk(KERN_WARNING DRIVER_NAME
116 ": Main firewire function not found. Cannot disable controller.\n"); 175 ": Main firewire function not found. Cannot disable controller.\n");
117 return -ENODEV; 176 return -ENODEV;
@@ -132,7 +191,7 @@ static void __devexit ricoh_mmc_remove(struct pci_dev *pdev)
132 pci_set_drvdata(pdev, NULL); 191 pci_set_drvdata(pdev, NULL);
133} 192}
134 193
135static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state) 194static int ricoh_mmc_suspend(struct pci_dev *pdev, pm_message_t state)
136{ 195{
137 struct pci_dev *fw_dev = NULL; 196 struct pci_dev *fw_dev = NULL;
138 197
@@ -146,7 +205,7 @@ static int ricoh_mmc_suspend (struct pci_dev *pdev, pm_message_t state)
146 return 0; 205 return 0;
147} 206}
148 207
149static int ricoh_mmc_resume (struct pci_dev *pdev) 208static int ricoh_mmc_resume(struct pci_dev *pdev)
150{ 209{
151 struct pci_dev *fw_dev = NULL; 210 struct pci_dev *fw_dev = NULL;
152 211