static int rtsx_usb_ms_set_param()

in host/rtsx_usb_ms.c [551:641]


static int rtsx_usb_ms_set_param(struct memstick_host *msh,
		enum memstick_param param, int value)
{
	struct rtsx_usb_ms *host = memstick_priv(msh);
	struct rtsx_ucr *ucr = host->ucr;
	unsigned int clock = 0;
	u8 ssc_depth = 0;
	int err;

	dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
			__func__, param, value);

	pm_runtime_get_sync(ms_dev(host));
	mutex_lock(&ucr->dev_mutex);

	err = rtsx_usb_card_exclusive_check(ucr, RTSX_USB_MS_CARD);
	if (err)
		goto out;

	switch (param) {
	case MEMSTICK_POWER:
		if (value == host->power_mode)
			break;

		if (value == MEMSTICK_POWER_ON) {
			pm_runtime_get_noresume(ms_dev(host));
			err = ms_power_on(host);
			if (err)
				pm_runtime_put_noidle(ms_dev(host));
		} else if (value == MEMSTICK_POWER_OFF) {
			err = ms_power_off(host);
			if (!err)
				pm_runtime_put_noidle(ms_dev(host));
		} else
			err = -EINVAL;
		if (!err)
			host->power_mode = value;
		break;

	case MEMSTICK_INTERFACE:
		if (value == MEMSTICK_SERIAL) {
			clock = 19000000;
			ssc_depth = SSC_DEPTH_512K;
			err = rtsx_usb_write_register(ucr, MS_CFG, 0x5A,
				       MS_BUS_WIDTH_1 | PUSH_TIME_DEFAULT);
			if (err < 0)
				break;
		} else if (value == MEMSTICK_PAR4) {
			clock = 39000000;
			ssc_depth = SSC_DEPTH_1M;

			err = rtsx_usb_write_register(ucr, MS_CFG, 0x5A,
					MS_BUS_WIDTH_4 | PUSH_TIME_ODD |
					MS_NO_CHECK_INT);
			if (err < 0)
				break;
		} else {
			err = -EINVAL;
			break;
		}

		err = rtsx_usb_switch_clock(ucr, clock,
				ssc_depth, false, true, false);
		if (err < 0) {
			dev_dbg(ms_dev(host), "switch clock failed\n");
			break;
		}

		host->ssc_depth = ssc_depth;
		host->clock = clock;
		host->ifmode = value;
		break;
	default:
		err = -EINVAL;
		break;
	}
out:
	mutex_unlock(&ucr->dev_mutex);
	pm_runtime_put_sync(ms_dev(host));

	/* power-on delay */
	if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON) {
		usleep_range(10000, 12000);

		if (!host->eject)
			schedule_delayed_work(&host->poll_card, 100);
	}

	dev_dbg(ms_dev(host), "%s: return = %d\n", __func__, err);
	return err;
}