Exemplo n.º 1
0
/*
 * Set current time and date in RTC
 */
static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time)
{
	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
	struct wm831x *wm831x = wm831x_rtc->wm831x;
	struct rtc_time new_tm;
	unsigned long new_time;
	int ret;
	int count = 0;

	ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_1,
			       (time >> 16) & 0xffff);
	if (ret < 0) {
		dev_err(dev, "Failed to write TIME_1: %d\n", ret);
		return ret;
	}

	ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_2, time & 0xffff);
	if (ret < 0) {
		dev_err(dev, "Failed to write TIME_2: %d\n", ret);
		return ret;
	}

	/* Wait for the update to complete - should happen first time
	 * round but be conservative.
	 */
	do {
		msleep(1);

		ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL);
		if (ret < 0)
			ret = WM831X_RTC_SYNC_BUSY;
	} while (!(ret & WM831X_RTC_SYNC_BUSY) &&
		 ++count < WM831X_SET_TIME_RETRIES);

	if (ret & WM831X_RTC_SYNC_BUSY) {
		dev_err(dev, "Timed out writing RTC update\n");
		return -EIO;
	}

	/* Check that the update was accepted; security features may
	 * have caused the update to be ignored.
	 */
	ret = wm831x_rtc_readtime(dev, &new_tm);
	if (ret < 0)
		return ret;

	ret = rtc_tm_to_time(&new_tm, &new_time);
	if (ret < 0) {
		dev_err(dev, "Failed to convert time: %d\n", ret);
		return ret;
	}

	/* Allow a second of change in case of tick */
	if (new_time - time > 1) {
		dev_err(dev, "RTC update not permitted by hardware\n");
		return -EPERM;
	}

	return 0;
}
static int wm831x_rtc_set_mmss(struct device *dev, unsigned long time)
{
	struct wm831x_rtc *wm831x_rtc = dev_get_drvdata(dev);
	struct wm831x *wm831x = wm831x_rtc->wm831x;
	struct rtc_time new_tm;
	unsigned long new_time;
	int ret;
	int count = 0;

	ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_1,
			       (time >> 16) & 0xffff);
	if (ret < 0) {
		dev_err(dev, "Failed to write TIME_1: %d\n", ret);
		return ret;
	}

	ret = wm831x_reg_write(wm831x, WM831X_RTC_TIME_2, time & 0xffff);
	if (ret < 0) {
		dev_err(dev, "Failed to write TIME_2: %d\n", ret);
		return ret;
	}

	do {
		msleep(1);

		ret = wm831x_reg_read(wm831x, WM831X_RTC_CONTROL);
		if (ret < 0)
			ret = WM831X_RTC_SYNC_BUSY;
	} while (!(ret & WM831X_RTC_SYNC_BUSY) &&
		 ++count < WM831X_SET_TIME_RETRIES);

	if (ret & WM831X_RTC_SYNC_BUSY) {
		dev_err(dev, "Timed out writing RTC update\n");
		return -EIO;
	}

	ret = wm831x_rtc_readtime(dev, &new_tm);
	if (ret < 0)
		return ret;

	ret = rtc_tm_to_time(&new_tm, &new_time);
	if (ret < 0) {
		dev_err(dev, "Failed to convert time: %d\n", ret);
		return ret;
	}

	
	if (new_time - time > 1) {
		dev_err(dev, "RTC update not permitted by hardware\n");
		return -EPERM;
	}

	return 0;
}