rtc-rv3028.c (05909cd9a0c8811731b38697af13075e8954314f) | rtc-rv3028.c (3a905c2d9544a418953d6c18668f0f853fbd9be9) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * RTC driver for the Micro Crystal RV3028 4 * 5 * Copyright (C) 2019 Micro Crystal SA 6 * 7 * Alexandre Belloni <alexandre.belloni@bootlin.com> 8 * --- 57 unchanged lines hidden (view full) --- 66#define RV3028_CTRL2_EIE BIT(2) 67#define RV3028_CTRL2_AIE BIT(3) 68#define RV3028_CTRL2_TIE BIT(4) 69#define RV3028_CTRL2_UIE BIT(5) 70#define RV3028_CTRL2_TSE BIT(7) 71 72#define RV3028_EVT_CTRL_TSR BIT(2) 73 | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * RTC driver for the Micro Crystal RV3028 4 * 5 * Copyright (C) 2019 Micro Crystal SA 6 * 7 * Alexandre Belloni <alexandre.belloni@bootlin.com> 8 * --- 57 unchanged lines hidden (view full) --- 66#define RV3028_CTRL2_EIE BIT(2) 67#define RV3028_CTRL2_AIE BIT(3) 68#define RV3028_CTRL2_TIE BIT(4) 69#define RV3028_CTRL2_UIE BIT(5) 70#define RV3028_CTRL2_TSE BIT(7) 71 72#define RV3028_EVT_CTRL_TSR BIT(2) 73 |
74#define RV3028_EEPROM_CMD_UPDATE 0x11 |
|
74#define RV3028_EEPROM_CMD_WRITE 0x21 75#define RV3028_EEPROM_CMD_READ 0x22 76 77#define RV3028_EEBUSY_POLL 10000 78#define RV3028_EEBUSY_TIMEOUT 100000 79 80#define RV3028_BACKUP_TCE BIT(5) 81#define RV3028_BACKUP_TCR_MASK GENMASK(1,0) --- 8 unchanged lines hidden (view full) --- 90 struct regmap *regmap; 91 struct rtc_device *rtc; 92 enum rv3028_type type; 93#ifdef CONFIG_COMMON_CLK 94 struct clk_hw clkout_hw; 95#endif 96}; 97 | 75#define RV3028_EEPROM_CMD_WRITE 0x21 76#define RV3028_EEPROM_CMD_READ 0x22 77 78#define RV3028_EEBUSY_POLL 10000 79#define RV3028_EEBUSY_TIMEOUT 100000 80 81#define RV3028_BACKUP_TCE BIT(5) 82#define RV3028_BACKUP_TCR_MASK GENMASK(1,0) --- 8 unchanged lines hidden (view full) --- 91 struct regmap *regmap; 92 struct rtc_device *rtc; 93 enum rv3028_type type; 94#ifdef CONFIG_COMMON_CLK 95 struct clk_hw clkout_hw; 96#endif 97}; 98 |
98static u16 rv3028_trickle_resistors[] = {1000, 3000, 6000, 11000}; | 99static u16 rv3028_trickle_resistors[] = {3000, 5000, 9000, 15000}; |
99 100static ssize_t timestamp0_store(struct device *dev, 101 struct device_attribute *attr, 102 const char *buf, size_t count) 103{ 104 struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); 105 106 regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR, --- 59 unchanged lines hidden (view full) --- 166 &dev_attr_timestamp0_count.attr, 167 NULL 168}; 169 170static const struct attribute_group rv3028_attr_group = { 171 .attrs = rv3028_attrs, 172}; 173 | 100 101static ssize_t timestamp0_store(struct device *dev, 102 struct device_attribute *attr, 103 const char *buf, size_t count) 104{ 105 struct rv3028_data *rv3028 = dev_get_drvdata(dev->parent); 106 107 regmap_update_bits(rv3028->regmap, RV3028_EVT_CTRL, RV3028_EVT_CTRL_TSR, --- 59 unchanged lines hidden (view full) --- 167 &dev_attr_timestamp0_count.attr, 168 NULL 169}; 170 171static const struct attribute_group rv3028_attr_group = { 172 .attrs = rv3028_attrs, 173}; 174 |
175static int rv3028_exit_eerd(struct rv3028_data *rv3028, u32 eerd) 176{ 177 if (eerd) 178 return 0; 179 180 return regmap_update_bits(rv3028->regmap, RV3028_CTRL1, RV3028_CTRL1_EERD, 0); 181} 182 183static int rv3028_enter_eerd(struct rv3028_data *rv3028, u32 *eerd) 184{ 185 u32 ctrl1, status; 186 int ret; 187 188 ret = regmap_read(rv3028->regmap, RV3028_CTRL1, &ctrl1); 189 if (ret) 190 return ret; 191 192 *eerd = ctrl1 & RV3028_CTRL1_EERD; 193 if (*eerd) 194 return 0; 195 196 ret = regmap_update_bits(rv3028->regmap, RV3028_CTRL1, 197 RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); 198 if (ret) 199 return ret; 200 201 ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status, 202 !(status & RV3028_STATUS_EEBUSY), 203 RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); 204 if (ret) { 205 rv3028_exit_eerd(rv3028, *eerd); 206 207 return ret; 208 } 209 210 return 0; 211} 212 213static int rv3028_update_eeprom(struct rv3028_data *rv3028, u32 eerd) 214{ 215 u32 status; 216 int ret; 217 218 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0); 219 if (ret) 220 goto exit_eerd; 221 222 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, RV3028_EEPROM_CMD_UPDATE); 223 if (ret) 224 goto exit_eerd; 225 226 usleep_range(63000, RV3028_EEBUSY_TIMEOUT); 227 228 ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status, 229 !(status & RV3028_STATUS_EEBUSY), 230 RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); 231 232exit_eerd: 233 rv3028_exit_eerd(rv3028, eerd); 234 235 return ret; 236} 237 238static int rv3028_update_cfg(struct rv3028_data *rv3028, unsigned int reg, 239 unsigned int mask, unsigned int val) 240{ 241 u32 eerd; 242 int ret; 243 244 ret = rv3028_enter_eerd(rv3028, &eerd); 245 if (ret) 246 return ret; 247 248 ret = regmap_update_bits(rv3028->regmap, reg, mask, val); 249 if (ret) { 250 rv3028_exit_eerd(rv3028, eerd); 251 return ret; 252 } 253 254 return rv3028_update_eeprom(rv3028, eerd); 255} 256 |
|
174static irqreturn_t rv3028_handle_irq(int irq, void *dev_id) 175{ 176 struct rv3028_data *rv3028 = dev_id; 177 unsigned long events = 0; 178 u32 status = 0, ctrl = 0; 179 180 if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 || 181 status == 0) { --- 217 unchanged lines hidden (view full) --- 399 *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); 400 401 return 0; 402} 403 404static int rv3028_set_offset(struct device *dev, long offset) 405{ 406 struct rv3028_data *rv3028 = dev_get_drvdata(dev); | 257static irqreturn_t rv3028_handle_irq(int irq, void *dev_id) 258{ 259 struct rv3028_data *rv3028 = dev_id; 260 unsigned long events = 0; 261 u32 status = 0, ctrl = 0; 262 263 if (regmap_read(rv3028->regmap, RV3028_STATUS, &status) < 0 || 264 status == 0) { --- 217 unchanged lines hidden (view full) --- 482 *offset = DIV_ROUND_CLOSEST(steps * OFFSET_STEP_PPT, 1000); 483 484 return 0; 485} 486 487static int rv3028_set_offset(struct device *dev, long offset) 488{ 489 struct rv3028_data *rv3028 = dev_get_drvdata(dev); |
490 u32 eerd; |
|
407 int ret; 408 409 offset = clamp(offset, -244141L, 243187L) * 1000; 410 offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); 411 | 491 int ret; 492 493 offset = clamp(offset, -244141L, 243187L) * 1000; 494 offset = DIV_ROUND_CLOSEST(offset, OFFSET_STEP_PPT); 495 |
496 ret = rv3028_enter_eerd(rv3028, &eerd); 497 if (ret) 498 return ret; 499 |
|
412 ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1); 413 if (ret < 0) | 500 ret = regmap_write(rv3028->regmap, RV3028_OFFSET, offset >> 1); 501 if (ret < 0) |
414 return ret; | 502 goto exit_eerd; |
415 | 503 |
416 return regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7), 417 offset << 7); | 504 ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, BIT(7), 505 offset << 7); 506 if (ret < 0) 507 goto exit_eerd; 508 509 return rv3028_update_eeprom(rv3028, eerd); 510 511exit_eerd: 512 rv3028_exit_eerd(rv3028, eerd); 513 514 return ret; 515 |
418} 419 420static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 421{ 422 struct rv3028_data *rv3028 = dev_get_drvdata(dev); 423 int status, ret = 0; 424 425 switch (cmd) { --- 20 unchanged lines hidden (view full) --- 446 size_t bytes) 447{ 448 return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes); 449} 450 451static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, 452 size_t bytes) 453{ | 516} 517 518static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) 519{ 520 struct rv3028_data *rv3028 = dev_get_drvdata(dev); 521 int status, ret = 0; 522 523 switch (cmd) { --- 20 unchanged lines hidden (view full) --- 544 size_t bytes) 545{ 546 return regmap_bulk_read(priv, RV3028_RAM1 + offset, val, bytes); 547} 548 549static int rv3028_eeprom_write(void *priv, unsigned int offset, void *val, 550 size_t bytes) 551{ |
454 u32 status, ctrl1; 455 int i, ret, err; | 552 struct rv3028_data *rv3028 = priv; 553 u32 status, eerd; 554 int i, ret; |
456 u8 *buf = val; 457 | 555 u8 *buf = val; 556 |
458 ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); | 557 ret = rv3028_enter_eerd(rv3028, &eerd); |
459 if (ret) 460 return ret; 461 | 558 if (ret) 559 return ret; 560 |
462 if (!(ctrl1 & RV3028_CTRL1_EERD)) { 463 ret = regmap_update_bits(priv, RV3028_CTRL1, 464 RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); 465 if (ret) 466 return ret; 467 468 ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, 469 !(status & RV3028_STATUS_EEBUSY), 470 RV3028_EEBUSY_POLL, 471 RV3028_EEBUSY_TIMEOUT); 472 if (ret) 473 goto restore_eerd; 474 } 475 | |
476 for (i = 0; i < bytes; i++) { | 561 for (i = 0; i < bytes; i++) { |
477 ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); | 562 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i); |
478 if (ret) 479 goto restore_eerd; 480 | 563 if (ret) 564 goto restore_eerd; 565 |
481 ret = regmap_write(priv, RV3028_EEPROM_DATA, buf[i]); | 566 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_DATA, buf[i]); |
482 if (ret) 483 goto restore_eerd; 484 | 567 if (ret) 568 goto restore_eerd; 569 |
485 ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); | 570 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0); |
486 if (ret) 487 goto restore_eerd; 488 | 571 if (ret) 572 goto restore_eerd; 573 |
489 ret = regmap_write(priv, RV3028_EEPROM_CMD, | 574 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, |
490 RV3028_EEPROM_CMD_WRITE); 491 if (ret) 492 goto restore_eerd; 493 494 usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); 495 | 575 RV3028_EEPROM_CMD_WRITE); 576 if (ret) 577 goto restore_eerd; 578 579 usleep_range(RV3028_EEBUSY_POLL, RV3028_EEBUSY_TIMEOUT); 580 |
496 ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, | 581 ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status, |
497 !(status & RV3028_STATUS_EEBUSY), 498 RV3028_EEBUSY_POLL, 499 RV3028_EEBUSY_TIMEOUT); 500 if (ret) 501 goto restore_eerd; 502 } 503 504restore_eerd: | 582 !(status & RV3028_STATUS_EEBUSY), 583 RV3028_EEBUSY_POLL, 584 RV3028_EEBUSY_TIMEOUT); 585 if (ret) 586 goto restore_eerd; 587 } 588 589restore_eerd: |
505 if (!(ctrl1 & RV3028_CTRL1_EERD)) 506 { 507 err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, 508 0); 509 if (err && !ret) 510 ret = err; 511 } | 590 rv3028_exit_eerd(rv3028, eerd); |
512 513 return ret; 514} 515 516static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val, 517 size_t bytes) 518{ | 591 592 return ret; 593} 594 595static int rv3028_eeprom_read(void *priv, unsigned int offset, void *val, 596 size_t bytes) 597{ |
519 u32 status, ctrl1, data; 520 int i, ret, err; | 598 struct rv3028_data *rv3028 = priv; 599 u32 status, eerd, data; 600 int i, ret; |
521 u8 *buf = val; 522 | 601 u8 *buf = val; 602 |
523 ret = regmap_read(priv, RV3028_CTRL1, &ctrl1); | 603 ret = rv3028_enter_eerd(rv3028, &eerd); |
524 if (ret) 525 return ret; 526 | 604 if (ret) 605 return ret; 606 |
527 if (!(ctrl1 & RV3028_CTRL1_EERD)) { 528 ret = regmap_update_bits(priv, RV3028_CTRL1, 529 RV3028_CTRL1_EERD, RV3028_CTRL1_EERD); 530 if (ret) 531 return ret; 532 533 ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, 534 !(status & RV3028_STATUS_EEBUSY), 535 RV3028_EEBUSY_POLL, 536 RV3028_EEBUSY_TIMEOUT); 537 if (ret) 538 goto restore_eerd; 539 } 540 | |
541 for (i = 0; i < bytes; i++) { | 607 for (i = 0; i < bytes; i++) { |
542 ret = regmap_write(priv, RV3028_EEPROM_ADDR, offset + i); | 608 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_ADDR, offset + i); |
543 if (ret) 544 goto restore_eerd; 545 | 609 if (ret) 610 goto restore_eerd; 611 |
546 ret = regmap_write(priv, RV3028_EEPROM_CMD, 0x0); | 612 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, 0x0); |
547 if (ret) 548 goto restore_eerd; 549 | 613 if (ret) 614 goto restore_eerd; 615 |
550 ret = regmap_write(priv, RV3028_EEPROM_CMD, | 616 ret = regmap_write(rv3028->regmap, RV3028_EEPROM_CMD, |
551 RV3028_EEPROM_CMD_READ); 552 if (ret) 553 goto restore_eerd; 554 | 617 RV3028_EEPROM_CMD_READ); 618 if (ret) 619 goto restore_eerd; 620 |
555 ret = regmap_read_poll_timeout(priv, RV3028_STATUS, status, | 621 ret = regmap_read_poll_timeout(rv3028->regmap, RV3028_STATUS, status, |
556 !(status & RV3028_STATUS_EEBUSY), 557 RV3028_EEBUSY_POLL, 558 RV3028_EEBUSY_TIMEOUT); 559 if (ret) 560 goto restore_eerd; 561 | 622 !(status & RV3028_STATUS_EEBUSY), 623 RV3028_EEBUSY_POLL, 624 RV3028_EEBUSY_TIMEOUT); 625 if (ret) 626 goto restore_eerd; 627 |
562 ret = regmap_read(priv, RV3028_EEPROM_DATA, &data); | 628 ret = regmap_read(rv3028->regmap, RV3028_EEPROM_DATA, &data); |
563 if (ret) 564 goto restore_eerd; 565 buf[i] = data; 566 } 567 568restore_eerd: | 629 if (ret) 630 goto restore_eerd; 631 buf[i] = data; 632 } 633 634restore_eerd: |
569 if (!(ctrl1 & RV3028_CTRL1_EERD)) 570 { 571 err = regmap_update_bits(priv, RV3028_CTRL1, RV3028_CTRL1_EERD, 572 0); 573 if (err && !ret) 574 ret = err; 575 } | 635 rv3028_exit_eerd(rv3028, eerd); |
576 577 return ret; 578} 579 580#ifdef CONFIG_COMMON_CLK 581#define clkout_hw_to_rv3028(hw) container_of(hw, struct rv3028_data, clkout_hw) 582 583static int clkout_rates[] = { --- 30 unchanged lines hidden (view full) --- 614 615 return 0; 616} 617 618static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 619 unsigned long parent_rate) 620{ 621 int i, ret; | 636 637 return ret; 638} 639 640#ifdef CONFIG_COMMON_CLK 641#define clkout_hw_to_rv3028(hw) container_of(hw, struct rv3028_data, clkout_hw) 642 643static int clkout_rates[] = { --- 30 unchanged lines hidden (view full) --- 674 675 return 0; 676} 677 678static int rv3028_clkout_set_rate(struct clk_hw *hw, unsigned long rate, 679 unsigned long parent_rate) 680{ 681 int i, ret; |
682 u32 enabled; |
|
622 struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw); 623 | 683 struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw); 684 |
685 ret = regmap_read(rv3028->regmap, RV3028_CLKOUT, &enabled); 686 if (ret < 0) 687 return ret; 688 |
|
624 ret = regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0); 625 if (ret < 0) 626 return ret; 627 | 689 ret = regmap_write(rv3028->regmap, RV3028_CLKOUT, 0x0); 690 if (ret < 0) 691 return ret; 692 |
628 for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) { 629 if (clkout_rates[i] == rate) { 630 ret = regmap_update_bits(rv3028->regmap, 631 RV3028_CLKOUT, 632 RV3028_CLKOUT_FD_MASK, i); 633 if (ret < 0) 634 return ret; | 693 enabled &= RV3028_CLKOUT_CLKOE; |
635 | 694 |
636 return regmap_write(rv3028->regmap, RV3028_CLKOUT, 637 RV3028_CLKOUT_CLKSY | RV3028_CLKOUT_CLKOE); 638 } 639 } | 695 for (i = 0; i < ARRAY_SIZE(clkout_rates); i++) 696 if (clkout_rates[i] == rate) 697 return rv3028_update_cfg(rv3028, RV3028_CLKOUT, 0xff, 698 RV3028_CLKOUT_CLKSY | enabled | i); |
640 641 return -EINVAL; 642} 643 644static int rv3028_clkout_prepare(struct clk_hw *hw) 645{ 646 struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw); 647 --- 158 unchanged lines hidden (view full) --- 806 &ohms)) { 807 int i; 808 809 for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) 810 if (ohms == rv3028_trickle_resistors[i]) 811 break; 812 813 if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { | 699 700 return -EINVAL; 701} 702 703static int rv3028_clkout_prepare(struct clk_hw *hw) 704{ 705 struct rv3028_data *rv3028 = clkout_hw_to_rv3028(hw); 706 --- 158 unchanged lines hidden (view full) --- 865 &ohms)) { 866 int i; 867 868 for (i = 0; i < ARRAY_SIZE(rv3028_trickle_resistors); i++) 869 if (ohms == rv3028_trickle_resistors[i]) 870 break; 871 872 if (i < ARRAY_SIZE(rv3028_trickle_resistors)) { |
814 ret = regmap_update_bits(rv3028->regmap, RV3028_BACKUP, 815 RV3028_BACKUP_TCE | 816 RV3028_BACKUP_TCR_MASK, 817 RV3028_BACKUP_TCE | i); | 873 ret = rv3028_update_cfg(rv3028, RV3028_BACKUP, RV3028_BACKUP_TCE | 874 RV3028_BACKUP_TCR_MASK, RV3028_BACKUP_TCE | i); |
818 if (ret) 819 return ret; 820 } else { 821 dev_warn(&client->dev, "invalid trickle resistor value\n"); 822 } 823 } 824 825 ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); 826 if (ret) 827 return ret; 828 829 rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 830 rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099; 831 rv3028->rtc->ops = &rv3028_rtc_ops; 832 ret = rtc_register_device(rv3028->rtc); 833 if (ret) 834 return ret; 835 836 nvmem_cfg.priv = rv3028->regmap; | 875 if (ret) 876 return ret; 877 } else { 878 dev_warn(&client->dev, "invalid trickle resistor value\n"); 879 } 880 } 881 882 ret = rtc_add_group(rv3028->rtc, &rv3028_attr_group); 883 if (ret) 884 return ret; 885 886 rv3028->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000; 887 rv3028->rtc->range_max = RTC_TIMESTAMP_END_2099; 888 rv3028->rtc->ops = &rv3028_rtc_ops; 889 ret = rtc_register_device(rv3028->rtc); 890 if (ret) 891 return ret; 892 893 nvmem_cfg.priv = rv3028->regmap; |
837 rtc_nvmem_register(rv3028->rtc, &nvmem_cfg); 838 eeprom_cfg.priv = rv3028->regmap; 839 rtc_nvmem_register(rv3028->rtc, &eeprom_cfg); | 894 devm_rtc_nvmem_register(rv3028->rtc, &nvmem_cfg); 895 eeprom_cfg.priv = rv3028; 896 devm_rtc_nvmem_register(rv3028->rtc, &eeprom_cfg); |
840 841 rv3028->rtc->max_user_freq = 1; 842 843#ifdef CONFIG_COMMON_CLK 844 rv3028_clkout_register_clk(rv3028, client); 845#endif 846 return 0; 847} --- 19 unchanged lines hidden --- | 897 898 rv3028->rtc->max_user_freq = 1; 899 900#ifdef CONFIG_COMMON_CLK 901 rv3028_clkout_register_clk(rv3028, client); 902#endif 903 return 0; 904} --- 19 unchanged lines hidden --- |