831-v6.7-rtc-rtc7301-Support-byte-addressed-IO.patch 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. From edd25a77e69b7c546c28077e5dffe72c54c0afe8 Mon Sep 17 00:00:00 2001
  2. From: Linus Walleij <[email protected]>
  3. Date: Thu, 21 Sep 2023 22:18:12 +0200
  4. Subject: [PATCH 2/4] rtc: rtc7301: Support byte-addressed IO
  5. The old RTC7301 driver in OpenWrt used byte access, but the
  6. current mainline Linux driver uses 32bit word access.
  7. Make this configurable using device properties using the
  8. standard property "reg-io-width" in e.g. device tree.
  9. This is needed for the USRobotics USR8200 which has the
  10. chip connected using byte accesses.
  11. Debugging and testing by Howard Harte.
  12. Signed-off-by: Linus Walleij <[email protected]>
  13. ---
  14. drivers/rtc/rtc-r7301.c | 35 +++++++++++++++++++++++++++++++++--
  15. 1 file changed, 33 insertions(+), 2 deletions(-)
  16. --- a/drivers/rtc/rtc-r7301.c
  17. +++ b/drivers/rtc/rtc-r7301.c
  18. @@ -14,6 +14,7 @@
  19. #include <linux/module.h>
  20. #include <linux/mod_devicetable.h>
  21. #include <linux/delay.h>
  22. +#include <linux/property.h>
  23. #include <linux/regmap.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/rtc.h>
  26. @@ -55,12 +56,23 @@ struct rtc7301_priv {
  27. u8 bank;
  28. };
  29. -static const struct regmap_config rtc7301_regmap_config = {
  30. +/*
  31. + * When the device is memory-mapped, some platforms pack the registers into
  32. + * 32-bit access using the lower 8 bits at each 4-byte stride, while others
  33. + * expose them as simply consecutive bytes.
  34. + */
  35. +static const struct regmap_config rtc7301_regmap_32_config = {
  36. .reg_bits = 32,
  37. .val_bits = 8,
  38. .reg_stride = 4,
  39. };
  40. +static const struct regmap_config rtc7301_regmap_8_config = {
  41. + .reg_bits = 8,
  42. + .val_bits = 8,
  43. + .reg_stride = 1,
  44. +};
  45. +
  46. static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
  47. {
  48. int reg_stride = regmap_get_reg_stride(priv->regmap);
  49. @@ -356,7 +368,9 @@ static int __init rtc7301_rtc_probe(stru
  50. void __iomem *regs;
  51. struct rtc7301_priv *priv;
  52. struct rtc_device *rtc;
  53. + static const struct regmap_config *mapconf;
  54. int ret;
  55. + u32 val;
  56. priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
  57. if (!priv)
  58. @@ -366,8 +380,25 @@ static int __init rtc7301_rtc_probe(stru
  59. if (IS_ERR(regs))
  60. return PTR_ERR(regs);
  61. + ret = device_property_read_u32(&dev->dev, "reg-io-width", &val);
  62. + if (ret)
  63. + /* Default to 32bit accesses */
  64. + val = 4;
  65. +
  66. + switch (val) {
  67. + case 1:
  68. + mapconf = &rtc7301_regmap_8_config;
  69. + break;
  70. + case 4:
  71. + mapconf = &rtc7301_regmap_32_config;
  72. + break;
  73. + default:
  74. + dev_err(&dev->dev, "invalid reg-io-width %d\n", val);
  75. + return -EINVAL;
  76. + }
  77. +
  78. priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,
  79. - &rtc7301_regmap_config);
  80. + mapconf);
  81. if (IS_ERR(priv->regmap))
  82. return PTR_ERR(priv->regmap);