static ssize_t rp5c01_nvram_write(struct file *filp, struct kobject *kobj, struct bin_attribute *bin_attr, char *buf, loff_t pos, size_t size) { struct device *dev = container_of(kobj, struct device, kobj); struct rp5c01_priv *priv = dev_get_drvdata(dev); ssize_t count; spin_lock_irq(&priv->lock); for (count = 0; size > 0 && pos < RP5C01_MODE; count++, size--) { u8 data = *buf++; rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_RAM_BLOCK10, RP5C01_MODE); rp5c01_write(priv, data >> 4, pos); rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_RAM_BLOCK11, RP5C01_MODE); rp5c01_write(priv, data & 0xf, pos++); rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01, RP5C01_MODE); } spin_unlock_irq(&priv->lock); return count; }
static int rp5c01_nvram_write(void *_priv, unsigned int pos, void *val, size_t bytes) { struct rp5c01_priv *priv = _priv; u8 *buf = val; spin_lock_irq(&priv->lock); for (; bytes; bytes--) { u8 data = *buf++; rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_RAM_BLOCK10, RP5C01_MODE); rp5c01_write(priv, data >> 4, pos); rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_RAM_BLOCK11, RP5C01_MODE); rp5c01_write(priv, data & 0xf, pos++); rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01, RP5C01_MODE); } spin_unlock_irq(&priv->lock); return 0; }
static void rp5c01_unlock(struct rp5c01_priv *priv) { rp5c01_write(priv, RP5C01_MODE_TIMER_EN | RP5C01_MODE_MODE01, RP5C01_MODE); }
static void rp5c01_lock(struct rp5c01_priv *priv) { rp5c01_write(priv, RP5C01_MODE_MODE00, RP5C01_MODE); }
static int rp5c01_set_time(struct device *dev, struct rtc_time *tm) { struct rp5c01_priv *priv = dev_get_drvdata(dev); spin_lock_irq(&priv->lock); rp5c01_lock(priv); rp5c01_write(priv, tm->tm_sec / 10, RP5C01_10_SECOND); rp5c01_write(priv, tm->tm_sec % 10, RP5C01_1_SECOND); rp5c01_write(priv, tm->tm_min / 10, RP5C01_10_MINUTE); rp5c01_write(priv, tm->tm_min % 10, RP5C01_1_MINUTE); rp5c01_write(priv, tm->tm_hour / 10, RP5C01_10_HOUR); rp5c01_write(priv, tm->tm_hour % 10, RP5C01_1_HOUR); rp5c01_write(priv, tm->tm_mday / 10, RP5C01_10_DAY); rp5c01_write(priv, tm->tm_mday % 10, RP5C01_1_DAY); if (tm->tm_wday != -1) rp5c01_write(priv, tm->tm_wday, RP5C01_DAY_OF_WEEK); rp5c01_write(priv, (tm->tm_mon + 1) / 10, RP5C01_10_MONTH); rp5c01_write(priv, (tm->tm_mon + 1) % 10, RP5C01_1_MONTH); if (tm->tm_year >= 100) tm->tm_year -= 100; rp5c01_write(priv, tm->tm_year / 10, RP5C01_10_YEAR); rp5c01_write(priv, tm->tm_year % 10, RP5C01_1_YEAR); rp5c01_unlock(priv); spin_unlock_irq(&priv->lock); return 0; }