From 61598093bbdd283a7edc367d900f223070ead8d2 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 10 May 2024 07:43:03 +0000 Subject: [PATCH] add ax88772C AX88772C_eeprom_tools --- kernel/drivers/rtc/rtc-max77686.c | 71 ++++++++++++++++++++++------------- 1 files changed, 44 insertions(+), 27 deletions(-) diff --git a/kernel/drivers/rtc/rtc-max77686.c b/kernel/drivers/rtc/rtc-max77686.c index 8e09450..eae7cb9 100644 --- a/kernel/drivers/rtc/rtc-max77686.c +++ b/kernel/drivers/rtc/rtc-max77686.c @@ -78,6 +78,8 @@ int alarm_pending_status_reg; /* RTC IRQ CHIP for regmap */ const struct regmap_irq_chip *rtc_irq_chip; + /* regmap configuration for the chip */ + const struct regmap_config *regmap_config; }; struct max77686_rtc_info { @@ -182,6 +184,11 @@ .num_irqs = ARRAY_SIZE(max77686_rtc_irqs), }; +static const struct regmap_config max77686_rtc_regmap_config = { + .reg_bits = 8, + .val_bits = 8, +}; + static const struct max77686_rtc_driver_data max77686_drv_data = { .delay = 16000, .mask = 0x7f, @@ -191,6 +198,13 @@ .alarm_pending_status_reg = MAX77686_REG_STATUS2, .rtc_i2c_addr = MAX77686_I2C_ADDR_RTC, .rtc_irq_chip = &max77686_rtc_irq_chip, + .regmap_config = &max77686_rtc_regmap_config, +}; + +static const struct regmap_config max77620_rtc_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .use_single_write = true, }; static const struct max77686_rtc_driver_data max77620_drv_data = { @@ -202,6 +216,7 @@ .alarm_pending_status_reg = MAX77686_INVALID_REG, .rtc_i2c_addr = MAX77620_I2C_ADDR_RTC, .rtc_irq_chip = &max77686_rtc_irq_chip, + .regmap_config = &max77620_rtc_regmap_config, }; static const unsigned int max77802_map[REG_RTC_END] = { @@ -658,11 +673,6 @@ return ret; } -static const struct regmap_config max77686_rtc_regmap_config = { - .reg_bits = 8, - .val_bits = 8, -}; - static int max77686_init_rtc_regmap(struct max77686_rtc_info *info) { struct device *parent = info->dev->parent; @@ -673,11 +683,8 @@ 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); + if (info->rtc_irq < 0) return info->rtc_irq; - } } else { info->rtc_irq = parent_i2c->irq; } @@ -693,19 +700,19 @@ goto add_rtc_irq; } - info->rtc = i2c_new_dummy(parent_i2c->adapter, - info->drv_data->rtc_i2c_addr); - if (!info->rtc) { + info->rtc = devm_i2c_new_dummy_device(info->dev, parent_i2c->adapter, + info->drv_data->rtc_i2c_addr); + if (IS_ERR(info->rtc)) { dev_err(info->dev, "Failed to allocate I2C device for RTC\n"); - return -ENODEV; + return PTR_ERR(info->rtc); } info->rtc_regmap = devm_regmap_init_i2c(info->rtc, - &max77686_rtc_regmap_config); + info->drv_data->regmap_config); if (IS_ERR(info->rtc_regmap)) { ret = PTR_ERR(info->rtc_regmap); dev_err(info->dev, "Failed to allocate RTC regmap: %d\n", ret); - goto err_unregister_i2c; + return ret; } add_rtc_irq: @@ -715,15 +722,10 @@ &info->rtc_irq_data); if (ret < 0) { dev_err(info->dev, "Failed to add RTC irq chip: %d\n", ret); - goto err_unregister_i2c; + return ret; } return 0; - -err_unregister_i2c: - if (info->rtc) - i2c_unregister_device(info->rtc); - return ret; } static int max77686_rtc_probe(struct platform_device *pdev) @@ -786,8 +788,6 @@ err_rtc: regmap_del_irq_chip(info->rtc_irq, info->rtc_irq_data); - if (info->rtc) - i2c_unregister_device(info->rtc); return ret; } @@ -798,8 +798,6 @@ free_irq(info->virq, info); regmap_del_irq_chip(info->rtc_irq, info->rtc_irq_data); - if (info->rtc) - i2c_unregister_device(info->rtc); return 0; } @@ -807,17 +805,36 @@ #ifdef CONFIG_PM_SLEEP static int max77686_rtc_suspend(struct device *dev) { + struct max77686_rtc_info *info = dev_get_drvdata(dev); + int ret = 0; + if (device_may_wakeup(dev)) { struct max77686_rtc_info *info = dev_get_drvdata(dev); - return enable_irq_wake(info->virq); + ret = enable_irq_wake(info->virq); } - return 0; + /* + * If the main IRQ (not virtual) is the parent IRQ, then it must be + * disabled during suspend because if it happens while suspended it + * will be handled before resuming I2C. + * + * Since Main IRQ is shared, all its users should disable it to be sure + * it won't fire while one of them is still suspended. + */ + if (!info->drv_data->rtc_irq_from_platform) + disable_irq(info->rtc_irq); + + return ret; } static int max77686_rtc_resume(struct device *dev) { + struct max77686_rtc_info *info = dev_get_drvdata(dev); + + if (!info->drv_data->rtc_irq_from_platform) + enable_irq(info->rtc_irq); + if (device_may_wakeup(dev)) { struct max77686_rtc_info *info = dev_get_drvdata(dev); -- Gitblit v1.6.2