Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/mfd/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  max77714.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Maxim MAX77714 Core Driver
 *
 * Copyright (C) 2022 Luca Ceresoli
 * Author: Luca Ceresoli <luca.ceresoli@bootlin.com>
 */


#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77714.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/regmap.h>

static const struct mfd_cell max77714_cells[] = {
 { .name = "max77714-watchdog" },
 { .name = "max77714-rtc" },
};

static const struct regmap_range max77714_readable_ranges[] = {
 regmap_reg_range(MAX77714_INT_TOP,     MAX77714_INT_TOP),
 regmap_reg_range(MAX77714_INT_TOPM,    MAX77714_INT_TOPM),
 regmap_reg_range(MAX77714_32K_STATUS,  MAX77714_32K_CONFIG),
 regmap_reg_range(MAX77714_CNFG_GLBL2,  MAX77714_CNFG2_ONOFF),
};

static const struct regmap_range max77714_writable_ranges[] = {
 regmap_reg_range(MAX77714_INT_TOPM,    MAX77714_INT_TOPM),
 regmap_reg_range(MAX77714_32K_CONFIG,  MAX77714_32K_CONFIG),
 regmap_reg_range(MAX77714_CNFG_GLBL2,  MAX77714_CNFG2_ONOFF),
};

static const struct regmap_access_table max77714_readable_table = {
 .yes_ranges = max77714_readable_ranges,
 .n_yes_ranges = ARRAY_SIZE(max77714_readable_ranges),
};

static const struct regmap_access_table max77714_writable_table = {
 .yes_ranges = max77714_writable_ranges,
 .n_yes_ranges = ARRAY_SIZE(max77714_writable_ranges),
};

static const struct regmap_config max77714_regmap_config = {
 .reg_bits = 8,
 .val_bits = 8,
 .max_register = MAX77714_CNFG2_ONOFF,
 .rd_table = &max77714_readable_table,
 .wr_table = &max77714_writable_table,
};

static const struct regmap_irq max77714_top_irqs[] = {
 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_ONOFF,   0, MAX77714_INT_TOP_ONOFF),
 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_RTC,     0, MAX77714_INT_TOP_RTC),
 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GPIO,    0, MAX77714_INT_TOP_GPIO),
 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_LDO,     0, MAX77714_INT_TOP_LDO),
 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_SD,      0, MAX77714_INT_TOP_SD),
 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GLBL,    0, MAX77714_INT_TOP_GLBL),
};

static const struct regmap_irq_chip max77714_irq_chip = {
 .name   = "max77714-pmic",
 .status_base  = MAX77714_INT_TOP,
 .mask_base  = MAX77714_INT_TOPM,
 .num_regs  = 1,
 .irqs   = max77714_top_irqs,
 .num_irqs  = ARRAY_SIZE(max77714_top_irqs),
};

/*
 * MAX77714 initially uses the internal, low precision oscillator. Enable
 * the external oscillator by setting the XOSC_RETRY bit. If the external
 * oscillator is not OK (probably not installed) this has no effect.
 */

static int max77714_setup_xosc(struct device *dev, struct regmap *regmap)
{
 /* Internal Crystal Load Capacitance, indexed by value of 32KLOAD bits */
 static const unsigned int load_cap[4] = {0, 10, 12, 22}; /* pF */
 unsigned int load_cap_idx;
 unsigned int status;
 int err;

 err = regmap_update_bits(regmap, MAX77714_32K_CONFIG,
     MAX77714_32K_CONFIG_XOSC_RETRY,
     MAX77714_32K_CONFIG_XOSC_RETRY);
 if (err)
  return dev_err_probe(dev, err, "Failed to configure the external oscillator\n");

 err = regmap_read(regmap, MAX77714_32K_STATUS, &status);
 if (err)
  return dev_err_probe(dev, err, "Failed to read external oscillator status\n");

 load_cap_idx = (status >> MAX77714_32K_STATUS_32KLOAD_SHF)
  & MAX77714_32K_STATUS_32KLOAD_MSK;

 dev_info(dev, "Using %s oscillator, %d pF load cap\n",
   status & MAX77714_32K_STATUS_32KSOURCE ? "internal" : "external",
   load_cap[load_cap_idx]);

 return 0;
}

static int max77714_probe(struct i2c_client *client)
{
 struct device *dev = &client->dev;
 struct regmap *regmap;
 struct regmap_irq_chip_data *irq_data;
 int err;

 regmap = devm_regmap_init_i2c(client, &max77714_regmap_config);
 if (IS_ERR(regmap))
  return dev_err_probe(dev, PTR_ERR(regmap),
         "Failed to initialise regmap\n");

 err = max77714_setup_xosc(dev, regmap);
 if (err)
  return err;

 err = devm_regmap_add_irq_chip(dev, regmap, client->irq,
           IRQF_ONESHOT | IRQF_SHARED, 0,
           &max77714_irq_chip, &irq_data);
 if (err)
  return dev_err_probe(dev, err, "Failed to add PMIC IRQ chip\n");

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

 return 0;
}

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

static struct i2c_driver max77714_driver = {
 .driver = {
  .name = "max77714",
  .of_match_table = max77714_dt_match,
 },
 .probe = max77714_probe,
};
module_i2c_driver(max77714_driver);

MODULE_DESCRIPTION("Maxim MAX77714 MFD core driver");
MODULE_AUTHOR("Luca Ceresoli ");
MODULE_LICENSE("GPL");

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

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.