Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 882c4916 authored by Frank Seidel's avatar Frank Seidel Committed by Pierre Ossman
Browse files

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: default avatarFrank Seidel <fseidel@suse.de>
Signed-off-by: default avatarPierre Ossman <drzeus@drzeus.cx>
parent 6e996ee8
Loading
Loading
Loading
Loading
+80 −21
Original line number Diff line number Diff line
@@ -44,12 +44,35 @@ MODULE_DEVICE_TABLE(pci, pci_ids);
static int ricoh_mmc_disable(struct pci_dev *fw_dev)
{
	u8 write_enable;
	u8 write_target;
	u8 disable;

	if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
		/* via RL5C476 */

		pci_read_config_byte(fw_dev, 0xB7, &disable);
		if (disable & 0x02) {
			printk(KERN_INFO DRIVER_NAME
				": Controller already disabled. " \
				"Nothing to do.\n");
			return -ENODEV;
		}

		pci_read_config_byte(fw_dev, 0x8E, &write_enable);
		pci_write_config_byte(fw_dev, 0x8E, 0xAA);
		pci_read_config_byte(fw_dev, 0x8D, &write_target);
		pci_write_config_byte(fw_dev, 0x8D, 0xB7);
		pci_write_config_byte(fw_dev, 0xB7, disable | 0x02);
		pci_write_config_byte(fw_dev, 0x8E, write_enable);
		pci_write_config_byte(fw_dev, 0x8D, write_target);
	} else {
		/* via R5C832 */

		pci_read_config_byte(fw_dev, 0xCB, &disable);
		if (disable & 0x02) {
			printk(KERN_INFO DRIVER_NAME
		       ": Controller already disabled. Nothing to do.\n");
			       ": Controller already disabled. " \
				"Nothing to do.\n");
			return -ENODEV;
		}

@@ -57,6 +80,7 @@ static int ricoh_mmc_disable(struct pci_dev *fw_dev)
		pci_write_config_byte(fw_dev, 0xCA, 0x57);
		pci_write_config_byte(fw_dev, 0xCB, disable | 0x02);
		pci_write_config_byte(fw_dev, 0xCA, write_enable);
	}

	printk(KERN_INFO DRIVER_NAME
	       ": Controller is now disabled.\n");
@@ -67,13 +91,29 @@ static int ricoh_mmc_disable(struct pci_dev *fw_dev)
static int ricoh_mmc_enable(struct pci_dev *fw_dev)
{
	u8 write_enable;
	u8 write_target;
	u8 disable;

	if (fw_dev->device == PCI_DEVICE_ID_RICOH_RL5C476) {
		/* via RL5C476 */

		pci_read_config_byte(fw_dev, 0x8E, &write_enable);
		pci_write_config_byte(fw_dev, 0x8E, 0xAA);
		pci_read_config_byte(fw_dev, 0x8D, &write_target);
		pci_write_config_byte(fw_dev, 0x8D, 0xB7);
		pci_read_config_byte(fw_dev, 0xB7, &disable);
		pci_write_config_byte(fw_dev, 0xB7, disable & ~0x02);
		pci_write_config_byte(fw_dev, 0x8E, write_enable);
		pci_write_config_byte(fw_dev, 0x8D, write_target);
	} else {
		/* via R5C832 */

		pci_read_config_byte(fw_dev, 0xCA, &write_enable);
		pci_read_config_byte(fw_dev, 0xCB, &disable);
		pci_write_config_byte(fw_dev, 0xCA, 0x57);
		pci_write_config_byte(fw_dev, 0xCB, disable & ~0x02);
		pci_write_config_byte(fw_dev, 0xCA, write_enable);
	}

	printk(KERN_INFO DRIVER_NAME
	       ": Controller is now re-enabled.\n");
@@ -85,6 +125,7 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
				     const struct pci_device_id *ent)
{
	u8 rev;
	u8 ctrlfound = 0;

	struct pci_dev *fw_dev = NULL;

@@ -98,20 +139,38 @@ static int __devinit ricoh_mmc_probe(struct pci_dev *pdev,
		pci_name(pdev), (int)pdev->vendor, (int)pdev->device,
		(int)rev);

	while ((fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
	while ((fw_dev =
		pci_get_device(PCI_VENDOR_ID_RICOH,
			PCI_DEVICE_ID_RICOH_RL5C476, fw_dev))) {
		if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
		    pdev->bus == fw_dev->bus) {
			if (ricoh_mmc_disable(fw_dev) != 0) {
			if (ricoh_mmc_disable(fw_dev) != 0)
				return -ENODEV;
			}

			pci_set_drvdata(pdev, fw_dev);

			++ctrlfound;
			break;
		}
	}

	if (pci_get_drvdata(pdev) == NULL) {
	fw_dev = NULL;

	while (!ctrlfound &&
	    (fw_dev = pci_get_device(PCI_VENDOR_ID_RICOH,
					PCI_DEVICE_ID_RICOH_R5C832, fw_dev))) {
		if (PCI_SLOT(pdev->devfn) == PCI_SLOT(fw_dev->devfn) &&
		    pdev->bus == fw_dev->bus) {
			if (ricoh_mmc_disable(fw_dev) != 0)
				return -ENODEV;

			pci_set_drvdata(pdev, fw_dev);

			++ctrlfound;
		}
	}

	if (!ctrlfound) {
		printk(KERN_WARNING DRIVER_NAME
		       ": Main firewire function not found. Cannot disable controller.\n");
		return -ENODEV;