/*! * This function sets external RTC * * @param second value in second to be set to external RTC * * @return 0 if successful; non-zero otherwise */ int set_ext_rtc_time(u32 second) { int ret = 0; struct timeval tmp; if (!pmic_rtc_loaded()) { return MXC_EXTERNAL_RTC_NONE; } tmp.tv_sec = second; ret = pmic_rtc_set_time(&tmp); if (0 != ret) ret = MXC_EXTERNAL_RTC_ERR; return ret; }
/*! * This function implements IOCTL controls on a PMIC RTC device. * * @param inode pointer on the node * @param file pointer on the file * @param cmd the command * @param arg the parameter * @return This function returns 0 if successful. */ static int pmic_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct timeval *pmic_time = NULL; if (_IOC_TYPE(cmd) != 'p') return -ENOTTY; if (arg) { pmic_time = kmalloc(sizeof(struct timeval), GFP_KERNEL); if (pmic_time == NULL) return -ENOMEM; /* if (copy_from_user(pmic_time, (struct timeval *)arg, sizeof(struct timeval))) { return -EFAULT; } */ } switch (cmd) { case PMIC_RTC_SET_TIME: if (copy_from_user(pmic_time, (struct timeval *)arg, sizeof(struct timeval))) { return -EFAULT; } pr_debug("SET RTC\n"); CHECK_ERROR(pmic_rtc_set_time(pmic_time)); break; case PMIC_RTC_GET_TIME: if (copy_to_user((struct timeval *)arg, pmic_time, sizeof(struct timeval))) { return -EFAULT; } pr_debug("GET RTC\n"); CHECK_ERROR(pmic_rtc_get_time(pmic_time)); break; case PMIC_RTC_SET_ALARM: if (copy_from_user(pmic_time, (struct timeval *)arg, sizeof(struct timeval))) { return -EFAULT; } pr_debug("SET RTC ALARM\n"); CHECK_ERROR(pmic_rtc_set_time_alarm(pmic_time)); break; case PMIC_RTC_GET_ALARM: if (copy_to_user((struct timeval *)arg, pmic_time, sizeof(struct timeval))) { return -EFAULT; } pr_debug("GET RTC ALARM\n"); CHECK_ERROR(pmic_rtc_get_time_alarm(pmic_time)); break; case PMIC_RTC_WAIT_ALARM: printk(KERN_INFO "WAIT ALARM...\n"); CHECK_ERROR(pmic_rtc_event_sub(RTC_IT_ALARM, callback_test_sub)); CHECK_ERROR(pmic_rtc_wait_alarm()); printk(KERN_INFO "ALARM DONE\n"); CHECK_ERROR(pmic_rtc_event_unsub(RTC_IT_ALARM, callback_test_sub)); break; case PMIC_RTC_ALARM_REGISTER: printk(KERN_INFO "PMIC RTC ALARM REGISTER\n"); alarm_callback.func = callback_alarm_asynchronous; alarm_callback.param = NULL; CHECK_ERROR(pmic_event_subscribe(EVENT_TODAI, alarm_callback)); break; case PMIC_RTC_ALARM_UNREGISTER: printk(KERN_INFO "PMIC RTC ALARM UNREGISTER\n"); alarm_callback.func = callback_alarm_asynchronous; alarm_callback.param = NULL; CHECK_ERROR(pmic_event_unsubscribe (EVENT_TODAI, alarm_callback)); pmic_rtc_done = false; break; default: pr_debug("%d unsupported ioctl command\n", (int)cmd); return -EINVAL; } if (arg) { if (copy_to_user((struct timeval *)arg, pmic_time, sizeof(struct timeval))) { return -EFAULT; } kfree(pmic_time); } return 0; }