Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/Roqc/test-suite/output/   (Beweissystem des Inria Version 9.1.0©)  Datei vom 15.8.2025 mit Größe 92 B image not shown  

Quelle  max77705.c   Sprache: unbekannt

 
// SPDX-License-Identifier: GPL-2.0+
/*
 * Maxim MAX77705 PMIC core driver
 *
 * Copyright (C) 2025 Dzmitry Sankouski <dsankouski@gmail.com>
 **/

#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77705-private.h>
#include <linux/mfd/max77693-common.h>
#include <linux/pm.h>
#include <linux/power/max17042_battery.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <linux/of.h>

static struct mfd_cell max77705_devs[] = {
 MFD_CELL_OF("max77705-rgb", NULL, NULL, 0, 0, "maxim,max77705-rgb"),
 MFD_CELL_OF("max77705-charger", NULL, NULL, 0, 0, "maxim,max77705-charger"),
 MFD_CELL_OF("max77705-haptic", NULL, NULL, 0, 0, "maxim,max77705-haptic"),
};

static const struct regmap_range max77705_readable_ranges[] = {
 regmap_reg_range(MAX77705_PMIC_REG_PMICID1,  MAX77705_PMIC_REG_BSTOUT_MASK),
 regmap_reg_range(MAX77705_PMIC_REG_INTSRC,  MAX77705_PMIC_REG_RESERVED_29),
 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
 regmap_reg_range(MAX77705_PMIC_REG_MCONFIG,  MAX77705_PMIC_REG_MCONFIG2),
 regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK),
 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2),
 regmap_reg_range(MAX77705_PMIC_REG_SW_RESET,  MAX77705_PMIC_REG_USBC_RESET),
};

static const struct regmap_range max77705_writable_ranges[] = {
 regmap_reg_range(MAX77705_PMIC_REG_MAINCTRL1,  MAX77705_PMIC_REG_BSTOUT_MASK),
 regmap_reg_range(MAX77705_PMIC_REG_INTSRC,  MAX77705_PMIC_REG_RESERVED_29),
 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
 regmap_reg_range(MAX77705_PMIC_REG_MCONFIG,  MAX77705_PMIC_REG_MCONFIG2),
 regmap_reg_range(MAX77705_PMIC_REG_FORCE_EN_MASK, MAX77705_PMIC_REG_FORCE_EN_MASK),
 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL1, MAX77705_PMIC_REG_BOOSTCONTROL1),
 regmap_reg_range(MAX77705_PMIC_REG_BOOSTCONTROL2, MAX77705_PMIC_REG_BOOSTCONTROL2),
 regmap_reg_range(MAX77705_PMIC_REG_SW_RESET,  MAX77705_PMIC_REG_USBC_RESET),
};

static const struct regmap_access_table max77705_readable_table = {
 .yes_ranges = max77705_readable_ranges,
 .n_yes_ranges = ARRAY_SIZE(max77705_readable_ranges),
};

static const struct regmap_access_table max77705_writable_table = {
 .yes_ranges = max77705_writable_ranges,
 .n_yes_ranges = ARRAY_SIZE(max77705_writable_ranges),
};

static const struct regmap_config max77705_regmap_config = {
 .reg_bits = 8,
 .val_bits = 8,
 .rd_table = &max77705_readable_table,
 .wr_table = &max77705_writable_table,
 .max_register = MAX77705_PMIC_REG_USBC_RESET,
};

static const struct regmap_irq max77705_irqs[] = {
 { .mask = MAX77705_SRC_IRQ_CHG, },
 { .mask = MAX77705_SRC_IRQ_TOP, },
 { .mask = MAX77705_SRC_IRQ_FG, },
 { .mask = MAX77705_SRC_IRQ_USBC, },
};

static const struct regmap_irq_chip max77705_irq_chip = {
 .name  = "max77705",
 .status_base = MAX77705_PMIC_REG_INTSRC,
 .ack_base = MAX77705_PMIC_REG_INTSRC,
 .mask_base = MAX77705_PMIC_REG_INTSRC_MASK,
 .num_regs = 1,
 .irqs  = max77705_irqs,
 .num_irqs = ARRAY_SIZE(max77705_irqs),
};

static int max77705_i2c_probe(struct i2c_client *i2c)
{
 struct device *dev = &i2c->dev;
 struct max77693_dev *max77705;
 struct regmap_irq_chip_data *irq_data;
 struct irq_domain *domain;
 enum max77705_hw_rev pmic_rev;
 unsigned int pmic_rev_value;
 int ret;

 max77705 = devm_kzalloc(dev, sizeof(*max77705), GFP_KERNEL);
 if (!max77705)
  return -ENOMEM;

 max77705->i2c = i2c;
 max77705->type = TYPE_MAX77705;
 i2c_set_clientdata(i2c, max77705);

 max77705->regmap = devm_regmap_init_i2c(i2c, &max77705_regmap_config);
 if (IS_ERR(max77705->regmap))
  return PTR_ERR(max77705->regmap);

 ret = regmap_read(max77705->regmap, MAX77705_PMIC_REG_PMICREV, &pmic_rev_value);
 if (ret < 0)
  return -ENODEV;

 pmic_rev = pmic_rev_value & MAX77705_REVISION_MASK;
 if (pmic_rev != MAX77705_PASS3)
  return dev_err_probe(dev, -ENODEV, "Rev.0x%x is not tested\n", pmic_rev);

 /* Active Discharge Enable */
 regmap_update_bits(max77705->regmap, MAX77705_PMIC_REG_MAINCTRL1, 1, 1);

 ret = devm_regmap_add_irq_chip(dev, max77705->regmap,
     i2c->irq,
     IRQF_ONESHOT, 0,
     &max77705_irq_chip,
     &irq_data);
 if (ret)
  return dev_err_probe(dev, ret, "Failed to add IRQ chip\n");

 domain = regmap_irq_get_domain(irq_data);

 ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
       max77705_devs, ARRAY_SIZE(max77705_devs),
       NULL, 0, domain);
 if (ret)
  return dev_err_probe(dev, ret, "Failed to register child devices\n");

 ret = devm_device_init_wakeup(dev);
 if (ret)
  return dev_err_probe(dev, ret, "Failed to init wakeup\n");

 return 0;
}

static int max77705_suspend(struct device *dev)
{
 struct i2c_client *i2c = to_i2c_client(dev);

 disable_irq(i2c->irq);

 if (device_may_wakeup(dev))
  enable_irq_wake(i2c->irq);

 return 0;
}

static int max77705_resume(struct device *dev)
{
 struct i2c_client *i2c = to_i2c_client(dev);

 if (device_may_wakeup(dev))
  disable_irq_wake(i2c->irq);

 enable_irq(i2c->irq);

 return 0;
}
DEFINE_SIMPLE_DEV_PM_OPS(max77705_pm_ops, max77705_suspend, max77705_resume);

static const struct of_device_id max77705_i2c_of_match[] = {
 { .compatible = "maxim,max77705" },
 { }
};
MODULE_DEVICE_TABLE(of, max77705_i2c_of_match);

static struct i2c_driver max77705_i2c_driver = {
 .driver = {
  .name   = "max77705",
  .of_match_table  = max77705_i2c_of_match,
  .pm   = pm_sleep_ptr(&max77705_pm_ops),
 },
 .probe = max77705_i2c_probe
};
module_i2c_driver(max77705_i2c_driver);

MODULE_DESCRIPTION("Maxim MAX77705 PMIC core driver");
MODULE_AUTHOR("Dzmitry Sankouski ");
MODULE_LICENSE("GPL");

Messung V0.5
C=95 H=96 G=95

[ Dauer der Verarbeitung: 0.2 Sekunden  (vorverarbeitet)  ]