1 /* 2 * Driver for Epson's RTC module RX-8025 SA/NB 3 * 4 * Copyright (C) 2009 Wolfgang Grandegger <wg@grandegger.com> 5 * 6 * Copyright (C) 2005 by Digi International Inc. 7 * All rights reserved. 8 * 9 * Modified by fengjh at rising.com.cn 10 * <http://lists.lm-sensors.org/mailman/listinfo/lm-sensors> 11 * 2006.11 12 * 13 * Code cleanup by Sergei Poselenov, <sposelenov@emcraft.com> 14 * Converted to new style by Wolfgang Grandegger <wg@grandegger.com> 15 * Alarm and periodic interrupt added by Dmitry Rakhchev <rda@emcraft.com> 16 * 17 * This program is free software; you can redistribute it and/or 18 * modify it under the terms of the GNU General Public License 19 * version 2 as published by the Free Software Foundation. 20 */ 21 #include <linux/kernel.h> 22 #include <linux/module.h> 23 #include <linux/slab.h> 24 #include <linux/init.h> 25 #include <linux/bcd.h> 26 #include <linux/i2c.h> 27 #include <linux/list.h> 28 #include <linux/rtc.h> 29 30 /* Register definitions */ 31 #define RX8025_REG_SEC 0x00 32 #define RX8025_REG_MIN 0x01 33 #define RX8025_REG_HOUR 0x02 34 #define RX8025_REG_WDAY 0x03 35 #define RX8025_REG_MDAY 0x04 36 #define RX8025_REG_MONTH 0x05 37 #define RX8025_REG_YEAR 0x06 38 #define RX8025_REG_DIGOFF 0x07 39 #define RX8025_REG_ALWMIN 0x08 40 #define RX8025_REG_ALWHOUR 0x09 41 #define RX8025_REG_ALWWDAY 0x0a 42 #define RX8025_REG_ALDMIN 0x0b 43 #define RX8025_REG_ALDHOUR 0x0c 44 /* 0x0d is reserved */ 45 #define RX8025_REG_CTRL1 0x0e 46 #define RX8025_REG_CTRL2 0x0f 47 48 #define RX8025_BIT_CTRL1_CT (7 << 0) 49 /* 1 Hz periodic level irq */ 50 #define RX8025_BIT_CTRL1_CT_1HZ 4 51 #define RX8025_BIT_CTRL1_TEST (1 << 3) 52 #define RX8025_BIT_CTRL1_1224 (1 << 5) 53 #define RX8025_BIT_CTRL1_DALE (1 << 6) 54 #define RX8025_BIT_CTRL1_WALE (1 << 7) 55 56 #define RX8025_BIT_CTRL2_DAFG (1 << 0) 57 #define RX8025_BIT_CTRL2_WAFG (1 << 1) 58 #define RX8025_BIT_CTRL2_CTFG (1 << 2) 59 #define RX8025_BIT_CTRL2_PON (1 << 4) 60 #define RX8025_BIT_CTRL2_XST (1 << 5) 61 #define RX8025_BIT_CTRL2_VDET (1 << 6) 62 63 /* Clock precision adjustment */ 64 #define RX8025_ADJ_RESOLUTION 3050 /* in ppb */ 65 #define RX8025_ADJ_DATA_MAX 62 66 #define RX8025_ADJ_DATA_MIN -62 67 68 static const struct i2c_device_id rx8025_id[] = { 69 { "rx8025", 0 }, 70 { } 71 }; 72 MODULE_DEVICE_TABLE(i2c, rx8025_id); 73 74 struct rx8025_data { 75 struct i2c_client *client; 76 struct rtc_device *rtc; 77 struct work_struct work; 78 u8 ctrl1; 79 unsigned exiting:1; 80 }; 81 82 static int rx8025_read_reg(struct i2c_client *client, int number, u8 *value) 83 { 84 int ret = i2c_smbus_read_byte_data(client, (number << 4) | 0x08); 85 86 if (ret < 0) { 87 dev_err(&client->dev, "Unable to read register #%d\n", number); 88 return ret; 89 } 90 91 *value = ret; 92 return 0; 93 } 94 95 static int rx8025_read_regs(struct i2c_client *client, 96 int number, u8 length, u8 *values) 97 { 98 int ret = i2c_smbus_read_i2c_block_data(client, (number << 4) | 0x08, 99 length, values); 100 101 if (ret != length) { 102 dev_err(&client->dev, "Unable to read registers #%d..#%d\n", 103 number, number + length - 1); 104 return ret < 0 ? ret : -EIO; 105 } 106 107 return 0; 108 } 109 110 static int rx8025_write_reg(struct i2c_client *client, int number, u8 value) 111 { 112 int ret = i2c_smbus_write_byte_data(client, number << 4, value); 113 114 if (ret) 115 dev_err(&client->dev, "Unable to write register #%d\n", 116 number); 117 118 return ret; 119 } 120 121 static int rx8025_write_regs(struct i2c_client *client, 122 int number, u8 length, u8 *values) 123 { 124 int ret = i2c_smbus_write_i2c_block_data(client, (number << 4) | 0x08, 125 length, values); 126 127 if (ret) 128 dev_err(&client->dev, "Unable to write registers #%d..#%d\n", 129 number, number + length - 1); 130 131 return ret; 132 } 133 134 static irqreturn_t rx8025_irq(int irq, void *dev_id) 135 { 136 struct i2c_client *client = dev_id; 137 struct rx8025_data *rx8025 = i2c_get_clientdata(client); 138 139 disable_irq_nosync(irq); 140 schedule_work(&rx8025->work); 141 return IRQ_HANDLED; 142 } 143 144 static void rx8025_work(struct work_struct *work) 145 { 146 struct rx8025_data *rx8025 = container_of(work, struct rx8025_data, 147 work); 148 struct i2c_client *client = rx8025->client; 149 struct mutex *lock = &rx8025->rtc->ops_lock; 150 u8 status; 151 152 mutex_lock(lock); 153 154 if (rx8025_read_reg(client, RX8025_REG_CTRL2, &status)) 155 goto out; 156 157 if (!(status & RX8025_BIT_CTRL2_XST)) 158 dev_warn(&client->dev, "Oscillation stop was detected," 159 "you may have to readjust the clock\n"); 160 161 if (status & RX8025_BIT_CTRL2_CTFG) { 162 /* periodic */ 163 status &= ~RX8025_BIT_CTRL2_CTFG; 164 local_irq_disable(); 165 rtc_update_irq(rx8025->rtc, 1, RTC_PF | RTC_IRQF); 166 local_irq_enable(); 167 } 168 169 if (status & RX8025_BIT_CTRL2_DAFG) { 170 /* alarm */ 171 status &= RX8025_BIT_CTRL2_DAFG; 172 if (rx8025_write_reg(client, RX8025_REG_CTRL1, 173 rx8025->ctrl1 & ~RX8025_BIT_CTRL1_DALE)) 174 goto out; 175 local_irq_disable(); 176 rtc_update_irq(rx8025->rtc, 1, RTC_AF | RTC_IRQF); 177 local_irq_enable(); 178 } 179 180 /* acknowledge IRQ */ 181 rx8025_write_reg(client, RX8025_REG_CTRL2, 182 status | RX8025_BIT_CTRL2_XST); 183 184 out: 185 if (!rx8025->exiting) 186 enable_irq(client->irq); 187 188 mutex_unlock(lock); 189 } 190 191 static int rx8025_get_time(struct device *dev, struct rtc_time *dt) 192 { 193 struct rx8025_data *rx8025 = dev_get_drvdata(dev); 194 u8 date[7]; 195 int err; 196 197 err = rx8025_read_regs(rx8025->client, RX8025_REG_SEC, 7, date); 198 if (err) 199 return err; 200 201 dev_dbg(dev, "%s: read 0x%02x 0x%02x " 202 "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", __func__, 203 date[0], date[1], date[2], date[3], date[4], 204 date[5], date[6]); 205 206 dt->tm_sec = bcd2bin(date[RX8025_REG_SEC] & 0x7f); 207 dt->tm_min = bcd2bin(date[RX8025_REG_MIN] & 0x7f); 208 if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) 209 dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x3f); 210 else 211 dt->tm_hour = bcd2bin(date[RX8025_REG_HOUR] & 0x1f) % 12 212 + (date[RX8025_REG_HOUR] & 0x20 ? 12 : 0); 213 214 dt->tm_mday = bcd2bin(date[RX8025_REG_MDAY] & 0x3f); 215 dt->tm_mon = bcd2bin(date[RX8025_REG_MONTH] & 0x1f) - 1; 216 dt->tm_year = bcd2bin(date[RX8025_REG_YEAR]); 217 218 if (dt->tm_year < 70) 219 dt->tm_year += 100; 220 221 dev_dbg(dev, "%s: date %ds %dm %dh %dmd %dm %dy\n", __func__, 222 dt->tm_sec, dt->tm_min, dt->tm_hour, 223 dt->tm_mday, dt->tm_mon, dt->tm_year); 224 225 return rtc_valid_tm(dt); 226 } 227 228 static int rx8025_set_time(struct device *dev, struct rtc_time *dt) 229 { 230 struct rx8025_data *rx8025 = dev_get_drvdata(dev); 231 u8 date[7]; 232 233 /* 234 * BUG: The HW assumes every year that is a multiple of 4 to be a leap 235 * year. Next time this is wrong is 2100, which will not be a leap 236 * year. 237 */ 238 239 /* 240 * Here the read-only bits are written as "0". I'm not sure if that 241 * is sound. 242 */ 243 date[RX8025_REG_SEC] = bin2bcd(dt->tm_sec); 244 date[RX8025_REG_MIN] = bin2bcd(dt->tm_min); 245 if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) 246 date[RX8025_REG_HOUR] = bin2bcd(dt->tm_hour); 247 else 248 date[RX8025_REG_HOUR] = (dt->tm_hour >= 12 ? 0x20 : 0) 249 | bin2bcd((dt->tm_hour + 11) % 12 + 1); 250 251 date[RX8025_REG_WDAY] = bin2bcd(dt->tm_wday); 252 date[RX8025_REG_MDAY] = bin2bcd(dt->tm_mday); 253 date[RX8025_REG_MONTH] = bin2bcd(dt->tm_mon + 1); 254 date[RX8025_REG_YEAR] = bin2bcd(dt->tm_year % 100); 255 256 dev_dbg(dev, 257 "%s: write 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", 258 __func__, 259 date[0], date[1], date[2], date[3], date[4], date[5], date[6]); 260 261 return rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date); 262 } 263 264 static int rx8025_init_client(struct i2c_client *client, int *need_reset) 265 { 266 struct rx8025_data *rx8025 = i2c_get_clientdata(client); 267 u8 ctrl[2], ctrl2; 268 int need_clear = 0; 269 int err; 270 271 err = rx8025_read_regs(rx8025->client, RX8025_REG_CTRL1, 2, ctrl); 272 if (err) 273 goto out; 274 275 /* Keep test bit zero ! */ 276 rx8025->ctrl1 = ctrl[0] & ~RX8025_BIT_CTRL1_TEST; 277 278 if (ctrl[1] & RX8025_BIT_CTRL2_PON) { 279 dev_warn(&client->dev, "power-on reset was detected, " 280 "you may have to readjust the clock\n"); 281 *need_reset = 1; 282 } 283 284 if (ctrl[1] & RX8025_BIT_CTRL2_VDET) { 285 dev_warn(&client->dev, "a power voltage drop was detected, " 286 "you may have to readjust the clock\n"); 287 *need_reset = 1; 288 } 289 290 if (!(ctrl[1] & RX8025_BIT_CTRL2_XST)) { 291 dev_warn(&client->dev, "Oscillation stop was detected," 292 "you may have to readjust the clock\n"); 293 *need_reset = 1; 294 } 295 296 if (ctrl[1] & (RX8025_BIT_CTRL2_DAFG | RX8025_BIT_CTRL2_WAFG)) { 297 dev_warn(&client->dev, "Alarm was detected\n"); 298 need_clear = 1; 299 } 300 301 if (!(ctrl[1] & RX8025_BIT_CTRL2_CTFG)) 302 need_clear = 1; 303 304 if (*need_reset || need_clear) { 305 ctrl2 = ctrl[0]; 306 ctrl2 &= ~(RX8025_BIT_CTRL2_PON | RX8025_BIT_CTRL2_VDET | 307 RX8025_BIT_CTRL2_CTFG | RX8025_BIT_CTRL2_WAFG | 308 RX8025_BIT_CTRL2_DAFG); 309 ctrl2 |= RX8025_BIT_CTRL2_XST; 310 311 err = rx8025_write_reg(client, RX8025_REG_CTRL2, ctrl2); 312 } 313 out: 314 return err; 315 } 316 317 /* Alarm support */ 318 static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t) 319 { 320 struct rx8025_data *rx8025 = dev_get_drvdata(dev); 321 struct i2c_client *client = rx8025->client; 322 u8 ctrl2, ald[2]; 323 int err; 324 325 if (client->irq <= 0) 326 return -EINVAL; 327 328 err = rx8025_read_regs(client, RX8025_REG_ALDMIN, 2, ald); 329 if (err) 330 return err; 331 332 err = rx8025_read_reg(client, RX8025_REG_CTRL2, &ctrl2); 333 if (err) 334 return err; 335 336 dev_dbg(dev, "%s: read alarm 0x%02x 0x%02x ctrl2 %02x\n", 337 __func__, ald[0], ald[1], ctrl2); 338 339 /* Hardware alarms precision is 1 minute! */ 340 t->time.tm_sec = 0; 341 t->time.tm_min = bcd2bin(ald[0] & 0x7f); 342 if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) 343 t->time.tm_hour = bcd2bin(ald[1] & 0x3f); 344 else 345 t->time.tm_hour = bcd2bin(ald[1] & 0x1f) % 12 346 + (ald[1] & 0x20 ? 12 : 0); 347 348 t->time.tm_wday = -1; 349 t->time.tm_mday = -1; 350 t->time.tm_mon = -1; 351 t->time.tm_year = -1; 352 353 dev_dbg(dev, "%s: date: %ds %dm %dh %dmd %dm %dy\n", 354 __func__, 355 t->time.tm_sec, t->time.tm_min, t->time.tm_hour, 356 t->time.tm_mday, t->time.tm_mon, t->time.tm_year); 357 t->enabled = !!(rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE); 358 t->pending = (ctrl2 & RX8025_BIT_CTRL2_DAFG) && t->enabled; 359 360 return err; 361 } 362 363 static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t) 364 { 365 struct i2c_client *client = to_i2c_client(dev); 366 struct rx8025_data *rx8025 = dev_get_drvdata(dev); 367 u8 ald[2]; 368 int err; 369 370 if (client->irq <= 0) 371 return -EINVAL; 372 373 /* Hardware alarm precision is 1 minute! */ 374 ald[0] = bin2bcd(t->time.tm_min); 375 if (rx8025->ctrl1 & RX8025_BIT_CTRL1_1224) 376 ald[1] = bin2bcd(t->time.tm_hour); 377 else 378 ald[1] = (t->time.tm_hour >= 12 ? 0x20 : 0) 379 | bin2bcd((t->time.tm_hour + 11) % 12 + 1); 380 381 dev_dbg(dev, "%s: write 0x%02x 0x%02x\n", __func__, ald[0], ald[1]); 382 383 if (rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE) { 384 rx8025->ctrl1 &= ~RX8025_BIT_CTRL1_DALE; 385 err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1, 386 rx8025->ctrl1); 387 if (err) 388 return err; 389 } 390 err = rx8025_write_regs(rx8025->client, RX8025_REG_ALDMIN, 2, ald); 391 if (err) 392 return err; 393 394 if (t->enabled) { 395 rx8025->ctrl1 |= RX8025_BIT_CTRL1_DALE; 396 err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1, 397 rx8025->ctrl1); 398 if (err) 399 return err; 400 } 401 402 return 0; 403 } 404 405 static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled) 406 { 407 struct rx8025_data *rx8025 = dev_get_drvdata(dev); 408 u8 ctrl1; 409 int err; 410 411 ctrl1 = rx8025->ctrl1; 412 if (enabled) 413 ctrl1 |= RX8025_BIT_CTRL1_DALE; 414 else 415 ctrl1 &= ~RX8025_BIT_CTRL1_DALE; 416 417 if (ctrl1 != rx8025->ctrl1) { 418 rx8025->ctrl1 = ctrl1; 419 err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1, 420 rx8025->ctrl1); 421 if (err) 422 return err; 423 } 424 return 0; 425 } 426 427 static struct rtc_class_ops rx8025_rtc_ops = { 428 .read_time = rx8025_get_time, 429 .set_time = rx8025_set_time, 430 .read_alarm = rx8025_read_alarm, 431 .set_alarm = rx8025_set_alarm, 432 .alarm_irq_enable = rx8025_alarm_irq_enable, 433 }; 434 435 /* 436 * Clock precision adjustment support 437 * 438 * According to the RX8025 SA/NB application manual the frequency and 439 * temperature characteristics can be approximated using the following 440 * equation: 441 * 442 * df = a * (ut - t)**2 443 * 444 * df: Frequency deviation in any temperature 445 * a : Coefficient = (-35 +-5) * 10**-9 446 * ut: Ultimate temperature in degree = +25 +-5 degree 447 * t : Any temperature in degree 448 * 449 * Note that the clock adjustment in ppb must be entered (which is 450 * the negative value of the deviation). 451 */ 452 static int rx8025_get_clock_adjust(struct device *dev, int *adj) 453 { 454 struct i2c_client *client = to_i2c_client(dev); 455 u8 digoff; 456 int err; 457 458 err = rx8025_read_reg(client, RX8025_REG_DIGOFF, &digoff); 459 if (err) 460 return err; 461 462 *adj = digoff >= 64 ? digoff - 128 : digoff; 463 if (*adj > 0) 464 (*adj)--; 465 *adj *= -RX8025_ADJ_RESOLUTION; 466 467 return 0; 468 } 469 470 static int rx8025_set_clock_adjust(struct device *dev, int adj) 471 { 472 struct i2c_client *client = to_i2c_client(dev); 473 u8 digoff; 474 int err; 475 476 adj /= -RX8025_ADJ_RESOLUTION; 477 if (adj > RX8025_ADJ_DATA_MAX) 478 adj = RX8025_ADJ_DATA_MAX; 479 else if (adj < RX8025_ADJ_DATA_MIN) 480 adj = RX8025_ADJ_DATA_MIN; 481 else if (adj > 0) 482 adj++; 483 else if (adj < 0) 484 adj += 128; 485 digoff = adj; 486 487 err = rx8025_write_reg(client, RX8025_REG_DIGOFF, digoff); 488 if (err) 489 return err; 490 491 dev_dbg(dev, "%s: write 0x%02x\n", __func__, digoff); 492 493 return 0; 494 } 495 496 static ssize_t rx8025_sysfs_show_clock_adjust(struct device *dev, 497 struct device_attribute *attr, 498 char *buf) 499 { 500 int err, adj; 501 502 err = rx8025_get_clock_adjust(dev, &adj); 503 if (err) 504 return err; 505 506 return sprintf(buf, "%d\n", adj); 507 } 508 509 static ssize_t rx8025_sysfs_store_clock_adjust(struct device *dev, 510 struct device_attribute *attr, 511 const char *buf, size_t count) 512 { 513 int adj, err; 514 515 if (sscanf(buf, "%i", &adj) != 1) 516 return -EINVAL; 517 518 err = rx8025_set_clock_adjust(dev, adj); 519 520 return err ? err : count; 521 } 522 523 static DEVICE_ATTR(clock_adjust_ppb, S_IRUGO | S_IWUSR, 524 rx8025_sysfs_show_clock_adjust, 525 rx8025_sysfs_store_clock_adjust); 526 527 static int rx8025_sysfs_register(struct device *dev) 528 { 529 return device_create_file(dev, &dev_attr_clock_adjust_ppb); 530 } 531 532 static void rx8025_sysfs_unregister(struct device *dev) 533 { 534 device_remove_file(dev, &dev_attr_clock_adjust_ppb); 535 } 536 537 static int rx8025_probe(struct i2c_client *client, 538 const struct i2c_device_id *id) 539 { 540 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 541 struct rx8025_data *rx8025; 542 int err, need_reset = 0; 543 544 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA 545 | I2C_FUNC_SMBUS_I2C_BLOCK)) { 546 dev_err(&adapter->dev, 547 "doesn't support required functionality\n"); 548 err = -EIO; 549 goto errout; 550 } 551 552 rx8025 = kzalloc(sizeof(*rx8025), GFP_KERNEL); 553 if (!rx8025) { 554 dev_err(&adapter->dev, "failed to alloc memory\n"); 555 err = -ENOMEM; 556 goto errout; 557 } 558 559 rx8025->client = client; 560 i2c_set_clientdata(client, rx8025); 561 INIT_WORK(&rx8025->work, rx8025_work); 562 563 err = rx8025_init_client(client, &need_reset); 564 if (err) 565 goto errout_free; 566 567 if (need_reset) { 568 struct rtc_time tm; 569 dev_info(&client->dev, 570 "bad conditions detected, resetting date\n"); 571 rtc_time_to_tm(0, &tm); /* 1970/1/1 */ 572 rx8025_set_time(&client->dev, &tm); 573 } 574 575 rx8025->rtc = rtc_device_register(client->name, &client->dev, 576 &rx8025_rtc_ops, THIS_MODULE); 577 if (IS_ERR(rx8025->rtc)) { 578 err = PTR_ERR(rx8025->rtc); 579 dev_err(&client->dev, "unable to register the class device\n"); 580 goto errout_free; 581 } 582 583 if (client->irq > 0) { 584 dev_info(&client->dev, "IRQ %d supplied\n", client->irq); 585 err = request_irq(client->irq, rx8025_irq, 586 0, "rx8025", client); 587 if (err) { 588 dev_err(&client->dev, "unable to request IRQ\n"); 589 goto errout_reg; 590 } 591 } 592 593 rx8025->rtc->irq_freq = 1; 594 rx8025->rtc->max_user_freq = 1; 595 596 err = rx8025_sysfs_register(&client->dev); 597 if (err) 598 goto errout_irq; 599 600 return 0; 601 602 errout_irq: 603 if (client->irq > 0) 604 free_irq(client->irq, client); 605 606 errout_reg: 607 rtc_device_unregister(rx8025->rtc); 608 609 errout_free: 610 kfree(rx8025); 611 612 errout: 613 dev_err(&adapter->dev, "probing for rx8025 failed\n"); 614 return err; 615 } 616 617 static int rx8025_remove(struct i2c_client *client) 618 { 619 struct rx8025_data *rx8025 = i2c_get_clientdata(client); 620 struct mutex *lock = &rx8025->rtc->ops_lock; 621 622 if (client->irq > 0) { 623 mutex_lock(lock); 624 rx8025->exiting = 1; 625 mutex_unlock(lock); 626 627 free_irq(client->irq, client); 628 cancel_work_sync(&rx8025->work); 629 } 630 631 rx8025_sysfs_unregister(&client->dev); 632 rtc_device_unregister(rx8025->rtc); 633 kfree(rx8025); 634 return 0; 635 } 636 637 static struct i2c_driver rx8025_driver = { 638 .driver = { 639 .name = "rtc-rx8025", 640 .owner = THIS_MODULE, 641 }, 642 .probe = rx8025_probe, 643 .remove = rx8025_remove, 644 .id_table = rx8025_id, 645 }; 646 647 module_i2c_driver(rx8025_driver); 648 649 MODULE_AUTHOR("Wolfgang Grandegger <wg@grandegger.com>"); 650 MODULE_DESCRIPTION("RX-8025 SA/NB RTC driver"); 651 MODULE_LICENSE("GPL"); 652