diff options
Diffstat (limited to 'drivers/rtc')
-rw-r--r-- | drivers/rtc/Kconfig | 4 | ||||
-rw-r--r-- | drivers/rtc/rtc-max77686.c | 47 |
2 files changed, 46 insertions, 5 deletions
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 08df14be7c15..1c8dadc1491f 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -326,10 +326,10 @@ config RTC_DRV_MAX8997 config RTC_DRV_MAX77686 tristate "Maxim MAX77686" - depends on MFD_MAX77686 + depends on MFD_MAX77686 || MFD_MAX77620 help If you say yes here you will get support for the - RTC of Maxim MAX77686 PMIC. + RTC of Maxim MAX77686/MAX77620/MAX77802 PMIC. This driver can also be built as a module. If so, the module will be called rtc-max77686. diff --git a/drivers/rtc/rtc-max77686.c b/drivers/rtc/rtc-max77686.c index 5e924f3cde90..9cd4c4ff8c1b 100644 --- a/drivers/rtc/rtc-max77686.c +++ b/drivers/rtc/rtc-max77686.c @@ -24,8 +24,12 @@ #include <linux/regmap.h> #define MAX77686_I2C_ADDR_RTC (0x0C >> 1) +#define MAX77620_I2C_ADDR_RTC 0x68 #define MAX77686_INVALID_I2C_ADDR (-1) +/* Define non existing register */ +#define MAX77686_INVALID_REG (-1) + /* RTC Control Register */ #define BCD_EN_SHIFT 0 #define BCD_EN_MASK BIT(BCD_EN_SHIFT) @@ -74,6 +78,10 @@ struct max77686_rtc_driver_data { bool alarm_enable_reg; /* I2C address for RTC block */ int rtc_i2c_addr; + /* RTC interrupt via platform resource */ + bool rtc_irq_from_platform; + /* Pending alarm status register */ + int alarm_pending_status_reg; /* RTC IRQ CHIP for regmap */ const struct regmap_irq_chip *rtc_irq_chip; }; @@ -185,10 +193,23 @@ static const struct max77686_rtc_driver_data max77686_drv_data = { .mask = 0x7f, .map = max77686_map, .alarm_enable_reg = false, + .rtc_irq_from_platform = false, + .alarm_pending_status_reg = MAX77686_REG_STATUS2, .rtc_i2c_addr = MAX77686_I2C_ADDR_RTC, .rtc_irq_chip = &max77686_rtc_irq_chip, }; +static const struct max77686_rtc_driver_data max77620_drv_data = { + .delay = 16000, + .mask = 0x7f, + .map = max77686_map, + .alarm_enable_reg = false, + .rtc_irq_from_platform = true, + .alarm_pending_status_reg = MAX77686_INVALID_REG, + .rtc_i2c_addr = MAX77620_I2C_ADDR_RTC, + .rtc_irq_chip = &max77686_rtc_irq_chip, +}; + static const unsigned int max77802_map[REG_RTC_END] = { [REG_RTC_CONTROLM] = MAX77802_RTC_CONTROLM, [REG_RTC_CONTROL] = MAX77802_RTC_CONTROL, @@ -232,6 +253,8 @@ static const struct max77686_rtc_driver_data max77802_drv_data = { .mask = 0xff, .map = max77802_map, .alarm_enable_reg = true, + .rtc_irq_from_platform = false, + .alarm_pending_status_reg = MAX77686_REG_STATUS2, .rtc_i2c_addr = MAX77686_INVALID_I2C_ADDR, .rtc_irq_chip = &max77802_rtc_irq_chip, }; @@ -427,9 +450,15 @@ static int max77686_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) } alrm->pending = 0; - ret = regmap_read(info->regmap, MAX77686_REG_STATUS2, &val); + + if (info->drv_data->alarm_pending_status_reg == MAX77686_INVALID_REG) + goto out; + + ret = regmap_read(info->regmap, + info->drv_data->alarm_pending_status_reg, &val); if (ret < 0) { - dev_err(info->dev, "Fail to read status2 reg(%d)\n", ret); + dev_err(info->dev, + "Fail to read alarm pending status reg(%d)\n", ret); goto out; } @@ -648,7 +677,18 @@ static int max77686_init_rtc_regmap(struct max77686_rtc_info *info) struct i2c_client *parent_i2c = to_i2c_client(parent); int ret; - info->rtc_irq = parent_i2c->irq; + if (info->drv_data->rtc_irq_from_platform) { + struct platform_device *pdev = to_platform_device(info->dev); + + info->rtc_irq = platform_get_irq(pdev, 0); + if (info->rtc_irq < 0) { + dev_err(info->dev, "Failed to get rtc interrupts: %d\n", + info->rtc_irq); + return info->rtc_irq; + } + } else { + info->rtc_irq = parent_i2c->irq; + } info->regmap = dev_get_regmap(parent, NULL); if (!info->regmap) { @@ -802,6 +842,7 @@ static SIMPLE_DEV_PM_OPS(max77686_rtc_pm_ops, static const struct platform_device_id rtc_id[] = { { "max77686-rtc", .driver_data = (kernel_ulong_t)&max77686_drv_data, }, { "max77802-rtc", .driver_data = (kernel_ulong_t)&max77802_drv_data, }, + { "max77620-rtc", .driver_data = (kernel_ulong_t)&max77620_drv_data, }, {}, }; MODULE_DEVICE_TABLE(platform, rtc_id); |