Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

rtc: pcf8523: add alarm support

Alarm support requires unconditionally disabling clock out because it is
using the int1 pin.

Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com>
Link: https://lore.kernel.org/r/20210418002023.1000265-2-alexandre.belloni@bootlin.com

+179
+179
drivers/rtc/rtc-pcf8523.c
··· 8 8 #include <linux/module.h> 9 9 #include <linux/rtc.h> 10 10 #include <linux/of.h> 11 + #include <linux/pm_wakeirq.h> 11 12 12 13 #define REG_CONTROL1 0x00 13 14 #define REG_CONTROL1_CAP_SEL BIT(7) 14 15 #define REG_CONTROL1_STOP BIT(5) 16 + #define REG_CONTROL1_AIE BIT(1) 17 + 18 + #define REG_CONTROL2 0x01 19 + #define REG_CONTROL2_AF BIT(3) 15 20 16 21 #define REG_CONTROL3 0x02 17 22 #define REG_CONTROL3_PM_BLD BIT(7) /* battery low detection disabled */ ··· 35 30 #define REG_MONTHS 0x08 36 31 #define REG_YEARS 0x09 37 32 33 + #define REG_MINUTE_ALARM 0x0a 34 + #define REG_HOUR_ALARM 0x0b 35 + #define REG_DAY_ALARM 0x0c 36 + #define REG_WEEKDAY_ALARM 0x0d 37 + #define ALARM_DIS BIT(7) 38 + 38 39 #define REG_OFFSET 0x0e 39 40 #define REG_OFFSET_MODE BIT(7) 41 + 42 + #define REG_TMR_CLKOUT_CTRL 0x0f 43 + 44 + struct pcf8523 { 45 + struct rtc_device *rtc; 46 + struct i2c_client *client; 47 + }; 40 48 41 49 static int pcf8523_read(struct i2c_client *client, u8 reg, u8 *valuep) 42 50 { ··· 154 136 return err; 155 137 156 138 return 0; 139 + } 140 + 141 + static irqreturn_t pcf8523_irq(int irq, void *dev_id) 142 + { 143 + struct pcf8523 *pcf8523 = i2c_get_clientdata(dev_id); 144 + u8 value; 145 + int err; 146 + 147 + err = pcf8523_read(pcf8523->client, REG_CONTROL2, &value); 148 + if (err < 0) 149 + return IRQ_HANDLED; 150 + 151 + if (value & REG_CONTROL2_AF) { 152 + value &= ~REG_CONTROL2_AF; 153 + pcf8523_write(pcf8523->client, REG_CONTROL2, value); 154 + rtc_update_irq(pcf8523->rtc, 1, RTC_IRQF | RTC_AF); 155 + 156 + return IRQ_HANDLED; 157 + } 158 + 159 + return IRQ_NONE; 157 160 } 158 161 159 162 static int pcf8523_stop_rtc(struct i2c_client *client) ··· 296 257 return pcf8523_start_rtc(client); 297 258 } 298 259 260 + static int pcf8523_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm) 261 + { 262 + struct i2c_client *client = to_i2c_client(dev); 263 + u8 start = REG_MINUTE_ALARM, regs[4]; 264 + struct i2c_msg msgs[2]; 265 + u8 value; 266 + int err; 267 + 268 + msgs[0].addr = client->addr; 269 + msgs[0].flags = 0; 270 + msgs[0].len = 1; 271 + msgs[0].buf = &start; 272 + 273 + msgs[1].addr = client->addr; 274 + msgs[1].flags = I2C_M_RD; 275 + msgs[1].len = sizeof(regs); 276 + msgs[1].buf = regs; 277 + 278 + err = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 279 + if (err < 0) 280 + return err; 281 + 282 + tm->time.tm_sec = 0; 283 + tm->time.tm_min = bcd2bin(regs[0] & 0x7F); 284 + tm->time.tm_hour = bcd2bin(regs[1] & 0x3F); 285 + tm->time.tm_mday = bcd2bin(regs[2] & 0x3F); 286 + tm->time.tm_wday = bcd2bin(regs[3] & 0x7); 287 + 288 + err = pcf8523_read(client, REG_CONTROL1, &value); 289 + if (err < 0) 290 + return err; 291 + tm->enabled = !!(value & REG_CONTROL1_AIE); 292 + 293 + err = pcf8523_read(client, REG_CONTROL2, &value); 294 + if (err < 0) 295 + return err; 296 + tm->pending = !!(value & REG_CONTROL2_AF); 297 + 298 + return 0; 299 + } 300 + 301 + static int pcf8523_irq_enable(struct device *dev, unsigned int enabled) 302 + { 303 + struct i2c_client *client = to_i2c_client(dev); 304 + u8 value; 305 + int err; 306 + 307 + err = pcf8523_read(client, REG_CONTROL1, &value); 308 + if (err < 0) 309 + return err; 310 + 311 + value &= REG_CONTROL1_AIE; 312 + 313 + if (enabled) 314 + value |= REG_CONTROL1_AIE; 315 + 316 + err = pcf8523_write(client, REG_CONTROL1, value); 317 + if (err < 0) 318 + return err; 319 + 320 + return 0; 321 + } 322 + 323 + static int pcf8523_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *tm) 324 + { 325 + struct i2c_client *client = to_i2c_client(dev); 326 + struct i2c_msg msg; 327 + u8 regs[5]; 328 + int err; 329 + 330 + err = pcf8523_irq_enable(dev, 0); 331 + if (err) 332 + return err; 333 + 334 + err = pcf8523_write(client, REG_CONTROL2, 0); 335 + if (err < 0) 336 + return err; 337 + 338 + /* The alarm has no seconds, round up to nearest minute */ 339 + if (tm->time.tm_sec) { 340 + time64_t alarm_time = rtc_tm_to_time64(&tm->time); 341 + 342 + alarm_time += 60 - tm->time.tm_sec; 343 + rtc_time64_to_tm(alarm_time, &tm->time); 344 + } 345 + 346 + regs[0] = REG_MINUTE_ALARM; 347 + regs[1] = bin2bcd(tm->time.tm_min); 348 + regs[2] = bin2bcd(tm->time.tm_hour); 349 + regs[3] = bin2bcd(tm->time.tm_mday); 350 + regs[4] = ALARM_DIS; 351 + msg.addr = client->addr; 352 + msg.flags = 0; 353 + msg.len = sizeof(regs); 354 + msg.buf = regs; 355 + err = i2c_transfer(client->adapter, &msg, 1); 356 + if (err < 0) 357 + return err; 358 + 359 + if (tm->enabled) 360 + return pcf8523_irq_enable(dev, tm->enabled); 361 + 362 + return 0; 363 + } 364 + 299 365 #ifdef CONFIG_RTC_INTF_DEV 300 366 static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd, 301 367 unsigned long arg) ··· 464 320 static const struct rtc_class_ops pcf8523_rtc_ops = { 465 321 .read_time = pcf8523_rtc_read_time, 466 322 .set_time = pcf8523_rtc_set_time, 323 + .read_alarm = pcf8523_rtc_read_alarm, 324 + .set_alarm = pcf8523_rtc_set_alarm, 325 + .alarm_irq_enable = pcf8523_irq_enable, 467 326 .ioctl = pcf8523_rtc_ioctl, 468 327 .read_offset = pcf8523_rtc_read_offset, 469 328 .set_offset = pcf8523_rtc_set_offset, ··· 475 328 static int pcf8523_probe(struct i2c_client *client, 476 329 const struct i2c_device_id *id) 477 330 { 331 + struct pcf8523 *pcf8523; 478 332 struct rtc_device *rtc; 333 + bool wakeup_source = false; 479 334 int err; 480 335 481 336 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) 482 337 return -ENODEV; 338 + 339 + pcf8523 = devm_kzalloc(&client->dev, sizeof(struct pcf8523), GFP_KERNEL); 340 + if (!pcf8523) 341 + return -ENOMEM; 342 + 343 + i2c_set_clientdata(client, pcf8523); 344 + pcf8523->client = client; 483 345 484 346 err = pcf8523_load_capacitance(client); 485 347 if (err < 0) ··· 503 347 if (IS_ERR(rtc)) 504 348 return PTR_ERR(rtc); 505 349 350 + pcf8523->rtc = rtc; 506 351 rtc->ops = &pcf8523_rtc_ops; 507 352 rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 508 353 rtc->range_max = RTC_TIMESTAMP_END_2099; 354 + rtc->uie_unsupported = 1; 355 + 356 + if (client->irq > 0) { 357 + err = pcf8523_write(client, REG_TMR_CLKOUT_CTRL, 0x38); 358 + if (err < 0) 359 + return err; 360 + 361 + err = devm_request_threaded_irq(&client->dev, client->irq, 362 + NULL, pcf8523_irq, 363 + IRQF_SHARED | IRQF_ONESHOT | IRQF_TRIGGER_LOW, 364 + dev_name(&rtc->dev), client); 365 + if (err) 366 + return err; 367 + 368 + dev_pm_set_wake_irq(&client->dev, client->irq); 369 + } 370 + 371 + #ifdef CONFIG_OF 372 + wakeup_source = of_property_read_bool(client->dev.of_node, "wakeup-source"); 373 + #endif 374 + if (client->irq > 0 || wakeup_source) 375 + device_init_wakeup(&client->dev, true); 509 376 510 377 return devm_rtc_register_device(rtc); 511 378 }