static int jmb38x_ms_set_param()

in host/jmb38x_ms.c [673:753]


static int jmb38x_ms_set_param(struct memstick_host *msh,
			       enum memstick_param param,
			       int value)
{
	struct jmb38x_ms_host *host = memstick_priv(msh);
	unsigned int host_ctl = readl(host->addr + HOST_CONTROL);
	unsigned int clock_ctl = CLOCK_CONTROL_BY_MMIO, clock_delay = 0;
	int rc = 0;

	switch (param) {
	case MEMSTICK_POWER:
		if (value == MEMSTICK_POWER_ON) {
			rc = jmb38x_ms_reset(host);
			if (rc)
				return rc;

			host_ctl = 7;
			host_ctl |= HOST_CONTROL_POWER_EN
				 | HOST_CONTROL_CLOCK_EN;
			writel(host_ctl, host->addr + HOST_CONTROL);

			writel(host->id ? PAD_PU_PD_ON_MS_SOCK1
					: PAD_PU_PD_ON_MS_SOCK0,
			       host->addr + PAD_PU_PD);

			writel(PAD_OUTPUT_ENABLE_MS,
			       host->addr + PAD_OUTPUT_ENABLE);

			msleep(10);
			dev_dbg(&host->chip->pdev->dev, "power on\n");
		} else if (value == MEMSTICK_POWER_OFF) {
			host_ctl &= ~(HOST_CONTROL_POWER_EN
				      | HOST_CONTROL_CLOCK_EN);
			writel(host_ctl, host->addr +  HOST_CONTROL);
			writel(0, host->addr + PAD_OUTPUT_ENABLE);
			writel(PAD_PU_PD_OFF, host->addr + PAD_PU_PD);
			dev_dbg(&host->chip->pdev->dev, "power off\n");
		} else
			return -EINVAL;
		break;
	case MEMSTICK_INTERFACE:
		dev_dbg(&host->chip->pdev->dev,
			"Set Host Interface Mode to %d\n", value);
		host_ctl &= ~(HOST_CONTROL_FAST_CLK | HOST_CONTROL_REI |
			      HOST_CONTROL_REO);
		host_ctl |= HOST_CONTROL_TDELAY_EN | HOST_CONTROL_HW_OC_P;
		host_ctl &= ~(3 << HOST_CONTROL_IF_SHIFT);

		if (value == MEMSTICK_SERIAL) {
			host_ctl |= HOST_CONTROL_IF_SERIAL
				    << HOST_CONTROL_IF_SHIFT;
			host_ctl |= HOST_CONTROL_REI;
			clock_ctl |= CLOCK_CONTROL_40MHZ;
			clock_delay = 0;
		} else if (value == MEMSTICK_PAR4) {
			host_ctl |= HOST_CONTROL_FAST_CLK;
			host_ctl |= HOST_CONTROL_IF_PAR4
				    << HOST_CONTROL_IF_SHIFT;
			host_ctl |= HOST_CONTROL_REO;
			clock_ctl |= CLOCK_CONTROL_40MHZ;
			clock_delay = 4;
		} else if (value == MEMSTICK_PAR8) {
			host_ctl |= HOST_CONTROL_FAST_CLK;
			host_ctl |= HOST_CONTROL_IF_PAR8
				    << HOST_CONTROL_IF_SHIFT;
			clock_ctl |= CLOCK_CONTROL_50MHZ;
			clock_delay = 0;
		} else
			return -EINVAL;

		writel(host_ctl, host->addr + HOST_CONTROL);
		writel(CLOCK_CONTROL_OFF, host->addr + CLOCK_CONTROL);
		writel(clock_ctl, host->addr + CLOCK_CONTROL);
		pci_write_config_byte(host->chip->pdev,
				      PCI_CTL_CLOCK_DLY_ADDR + 1,
				      clock_delay);
		host->ifmode = value;
		break;
	}
	return 0;
}