@@ -156,14 +156,107 @@ static int rzn1_rtc_set_time(struct device *dev, struct rtc_time *tm)
156156 return 0 ;
157157}
158158
159+ static irqreturn_t rzn1_rtc_alarm_irq (int irq , void * dev_id )
160+ {
161+ struct rzn1_rtc * rtc = dev_id ;
162+
163+ rtc_update_irq (rtc -> rtcdev , 1 , RTC_AF | RTC_IRQF );
164+
165+ return IRQ_HANDLED ;
166+ }
167+
168+ static int rzn1_rtc_alarm_irq_enable (struct device * dev , unsigned int enable )
169+ {
170+ struct rzn1_rtc * rtc = dev_get_drvdata (dev );
171+ u32 ctl1 = readl (rtc -> base + RZN1_RTC_CTL1 );
172+
173+ if (enable )
174+ ctl1 |= RZN1_RTC_CTL1_ALME ;
175+ else
176+ ctl1 &= ~RZN1_RTC_CTL1_ALME ;
177+
178+ writel (ctl1 , rtc -> base + RZN1_RTC_CTL1 );
179+
180+ return 0 ;
181+ }
182+
183+ static int rzn1_rtc_read_alarm (struct device * dev , struct rtc_wkalrm * alrm )
184+ {
185+ struct rzn1_rtc * rtc = dev_get_drvdata (dev );
186+ struct rtc_time * tm = & alrm -> time ;
187+ unsigned int min , hour , wday , delta_days ;
188+ time64_t alarm ;
189+ u32 ctl1 ;
190+ int ret ;
191+
192+ ret = rzn1_rtc_read_time (dev , tm );
193+ if (ret )
194+ return ret ;
195+
196+ min = readl (rtc -> base + RZN1_RTC_ALM );
197+ hour = readl (rtc -> base + RZN1_RTC_ALH );
198+ wday = readl (rtc -> base + RZN1_RTC_ALW );
199+
200+ tm -> tm_sec = 0 ;
201+ tm -> tm_min = bcd2bin (min );
202+ tm -> tm_hour = bcd2bin (hour );
203+ delta_days = ((fls (wday ) - 1 ) - tm -> tm_wday + 7 ) % 7 ;
204+ tm -> tm_wday = fls (wday ) - 1 ;
205+
206+ if (delta_days ) {
207+ alarm = rtc_tm_to_time64 (tm ) + (delta_days * 86400 );
208+ rtc_time64_to_tm (alarm , tm );
209+ }
210+
211+ ctl1 = readl (rtc -> base + RZN1_RTC_CTL1 );
212+ alrm -> enabled = !!(ctl1 & RZN1_RTC_CTL1_ALME );
213+
214+ return 0 ;
215+ }
216+
217+ static int rzn1_rtc_set_alarm (struct device * dev , struct rtc_wkalrm * alrm )
218+ {
219+ struct rzn1_rtc * rtc = dev_get_drvdata (dev );
220+ struct rtc_time * tm = & alrm -> time , tm_now ;
221+ unsigned long alarm , farest ;
222+ unsigned int days_ahead , wday ;
223+ int ret ;
224+
225+ ret = rzn1_rtc_read_time (dev , & tm_now );
226+ if (ret )
227+ return ret ;
228+
229+ /* We cannot set alarms more than one week ahead */
230+ farest = rtc_tm_to_time64 (& tm_now ) + (7 * 86400 );
231+ alarm = rtc_tm_to_time64 (tm );
232+ if (time_after (alarm , farest ))
233+ return - ERANGE ;
234+
235+ /* Convert alarm day into week day */
236+ days_ahead = tm -> tm_mday - tm_now .tm_mday ;
237+ wday = (tm_now .tm_wday + days_ahead ) % 7 ;
238+
239+ writel (bin2bcd (tm -> tm_min ), rtc -> base + RZN1_RTC_ALM );
240+ writel (bin2bcd (tm -> tm_hour ), rtc -> base + RZN1_RTC_ALH );
241+ writel (BIT (wday ), rtc -> base + RZN1_RTC_ALW );
242+
243+ rzn1_rtc_alarm_irq_enable (dev , alrm -> enabled );
244+
245+ return 0 ;
246+ }
247+
159248static const struct rtc_class_ops rzn1_rtc_ops = {
160249 .read_time = rzn1_rtc_read_time ,
161250 .set_time = rzn1_rtc_set_time ,
251+ .read_alarm = rzn1_rtc_read_alarm ,
252+ .set_alarm = rzn1_rtc_set_alarm ,
253+ .alarm_irq_enable = rzn1_rtc_alarm_irq_enable ,
162254};
163255
164256static int rzn1_rtc_probe (struct platform_device * pdev )
165257{
166258 struct rzn1_rtc * rtc ;
259+ int alarm_irq ;
167260 int ret ;
168261
169262 rtc = devm_kzalloc (& pdev -> dev , sizeof (* rtc ), GFP_KERNEL );
@@ -176,14 +269,18 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
176269 if (IS_ERR (rtc -> base ))
177270 return dev_err_probe (& pdev -> dev , PTR_ERR (rtc -> base ), "Missing reg\n" );
178271
272+ alarm_irq = platform_get_irq (pdev , 0 );
273+ if (alarm_irq < 0 )
274+ return alarm_irq ;
275+
179276 rtc -> rtcdev = devm_rtc_allocate_device (& pdev -> dev );
180277 if (IS_ERR (rtc -> rtcdev ))
181278 return PTR_ERR (rtc );
182279
183280 rtc -> rtcdev -> range_min = RTC_TIMESTAMP_BEGIN_2000 ;
184281 rtc -> rtcdev -> range_max = RTC_TIMESTAMP_END_2099 ;
185282 rtc -> rtcdev -> ops = & rzn1_rtc_ops ;
186- clear_bit ( RTC_FEATURE_ALARM , rtc -> rtcdev -> features );
283+ set_bit ( RTC_FEATURE_ALARM_RES_MINUTE , rtc -> rtcdev -> features );
187284 clear_bit (RTC_FEATURE_UPDATE_INTERRUPT , rtc -> rtcdev -> features );
188285
189286 devm_pm_runtime_enable (& pdev -> dev );
@@ -201,6 +298,13 @@ static int rzn1_rtc_probe(struct platform_device *pdev)
201298 /* Disable all interrupts */
202299 writel (0 , rtc -> base + RZN1_RTC_CTL1 );
203300
301+ ret = devm_request_irq (& pdev -> dev , alarm_irq , rzn1_rtc_alarm_irq , 0 ,
302+ dev_name (& pdev -> dev ), rtc );
303+ if (ret ) {
304+ dev_err (& pdev -> dev , "RTC timer interrupt not available\n" );
305+ goto dis_runtime_pm ;
306+ }
307+
204308 ret = devm_rtc_register_device (rtc -> rtcdev );
205309 if (ret )
206310 goto dis_runtime_pm ;
0 commit comments