Skip to content

Commit 8c767e9

Browse files
linuswalexandrebelloni
authored andcommitted
rtc: rtc7301: Support byte-addressed IO
The old RTC7301 driver in OpenWrt used byte access, but the current mainline Linux driver uses 32bit word access. Make this configurable using device properties using the standard property "reg-io-width" in e.g. device tree. This is needed for the USRobotics USR8200 which has the chip connected using byte accesses. Debugging and testing by Howard Harte. Signed-off-by: Linus Walleij <[email protected]> Reviewed-by: Akinobu Mita <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Belloni <[email protected]>
1 parent 5ded578 commit 8c767e9

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

drivers/rtc/rtc-r7301.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/module.h>
1515
#include <linux/mod_devicetable.h>
1616
#include <linux/delay.h>
17+
#include <linux/property.h>
1718
#include <linux/regmap.h>
1819
#include <linux/platform_device.h>
1920
#include <linux/rtc.h>
@@ -55,12 +56,23 @@ struct rtc7301_priv {
5556
u8 bank;
5657
};
5758

58-
static const struct regmap_config rtc7301_regmap_config = {
59+
/*
60+
* When the device is memory-mapped, some platforms pack the registers into
61+
* 32-bit access using the lower 8 bits at each 4-byte stride, while others
62+
* expose them as simply consecutive bytes.
63+
*/
64+
static const struct regmap_config rtc7301_regmap_32_config = {
5965
.reg_bits = 32,
6066
.val_bits = 8,
6167
.reg_stride = 4,
6268
};
6369

70+
static const struct regmap_config rtc7301_regmap_8_config = {
71+
.reg_bits = 8,
72+
.val_bits = 8,
73+
.reg_stride = 1,
74+
};
75+
6476
static u8 rtc7301_read(struct rtc7301_priv *priv, unsigned int reg)
6577
{
6678
int reg_stride = regmap_get_reg_stride(priv->regmap);
@@ -356,7 +368,9 @@ static int __init rtc7301_rtc_probe(struct platform_device *dev)
356368
void __iomem *regs;
357369
struct rtc7301_priv *priv;
358370
struct rtc_device *rtc;
371+
static const struct regmap_config *mapconf;
359372
int ret;
373+
u32 val;
360374

361375
priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
362376
if (!priv)
@@ -366,8 +380,25 @@ static int __init rtc7301_rtc_probe(struct platform_device *dev)
366380
if (IS_ERR(regs))
367381
return PTR_ERR(regs);
368382

383+
ret = device_property_read_u32(&dev->dev, "reg-io-width", &val);
384+
if (ret)
385+
/* Default to 32bit accesses */
386+
val = 4;
387+
388+
switch (val) {
389+
case 1:
390+
mapconf = &rtc7301_regmap_8_config;
391+
break;
392+
case 4:
393+
mapconf = &rtc7301_regmap_32_config;
394+
break;
395+
default:
396+
dev_err(&dev->dev, "invalid reg-io-width %d\n", val);
397+
return -EINVAL;
398+
}
399+
369400
priv->regmap = devm_regmap_init_mmio(&dev->dev, regs,
370-
&rtc7301_regmap_config);
401+
mapconf);
371402
if (IS_ERR(priv->regmap))
372403
return PTR_ERR(priv->regmap);
373404

0 commit comments

Comments
 (0)