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  hi655x-pmic.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Device driver for MFD hi655x PMIC
 *
 * Copyright (c) 2016 HiSilicon Ltd.
 *
 * Authors:
 * Chen Feng <puck.chen@hisilicon.com>
 * Fei  Wang <w.f@huawei.com>
 */


#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/mfd/core.h>
#include <linux/mfd/hi655x-pmic.h>
#include <linux/module.h>
#include <linux/gpio/consumer.h>
#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

static const struct regmap_irq hi655x_irqs[] = {
 { .reg_offset = 0, .mask = OTMP_D1R_INT_MASK },
 { .reg_offset = 0, .mask = VSYS_2P5_R_INT_MASK },
 { .reg_offset = 0, .mask = VSYS_UV_D3R_INT_MASK },
 { .reg_offset = 0, .mask = VSYS_6P0_D200UR_INT_MASK },
 { .reg_offset = 0, .mask = PWRON_D4SR_INT_MASK },
 { .reg_offset = 0, .mask = PWRON_D20F_INT_MASK },
 { .reg_offset = 0, .mask = PWRON_D20R_INT_MASK },
 { .reg_offset = 0, .mask = RESERVE_INT_MASK },
};

static const struct regmap_irq_chip hi655x_irq_chip = {
 .name = "hi655x-pmic",
 .irqs = hi655x_irqs,
 .num_regs = 1,
 .num_irqs = ARRAY_SIZE(hi655x_irqs),
 .status_base = HI655X_IRQ_STAT_BASE,
 .ack_base = HI655X_IRQ_STAT_BASE,
 .mask_base = HI655X_IRQ_MASK_BASE,
};

static const struct regmap_config hi655x_regmap_config = {
 .reg_bits = 32,
 .reg_stride = HI655X_STRIDE,
 .val_bits = 8,
 .max_register = HI655X_BUS_ADDR(0x400) - HI655X_STRIDE,
};

static const struct resource pwrkey_resources[] = {
 {
  .name = "down",
  .start = PWRON_D20R_INT,
  .end = PWRON_D20R_INT,
  .flags = IORESOURCE_IRQ,
 }, {
  .name = "up",
  .start = PWRON_D20F_INT,
  .end = PWRON_D20F_INT,
  .flags = IORESOURCE_IRQ,
 }, {
  .name = "hold 4s",
  .start = PWRON_D4SR_INT,
  .end = PWRON_D4SR_INT,
  .flags = IORESOURCE_IRQ,
 },
};

static const struct mfd_cell hi655x_pmic_devs[] = {
 {
  .name  = "hi65xx-powerkey",
  .num_resources = ARRAY_SIZE(pwrkey_resources),
  .resources = &pwrkey_resources[0],
 },
 { .name  = "hi655x-regulator", },
 { .name  = "hi655x-clk",  },
};

static void hi655x_local_irq_clear(struct regmap *map)
{
 int i;

 regmap_write(map, HI655X_ANA_IRQM_BASE, HI655X_IRQ_CLR);
 for (i = 0; i < HI655X_IRQ_ARRAY; i++) {
  regmap_write(map, HI655X_IRQ_STAT_BASE + i * HI655X_STRIDE,
        HI655X_IRQ_CLR);
 }
}

static int hi655x_pmic_probe(struct platform_device *pdev)
{
 int ret;
 struct hi655x_pmic *pmic;
 struct device *dev = &pdev->dev;
 void __iomem *base;

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

 base = devm_platform_ioremap_resource(pdev, 0);
 if (IS_ERR(base))
  return PTR_ERR(base);

 pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base,
       &hi655x_regmap_config);
 if (IS_ERR(pmic->regmap))
  return PTR_ERR(pmic->regmap);

 regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver);
 if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) {
  dev_warn(dev, "PMU version %d unsupported\n", pmic->ver);
  return -EINVAL;
 }

 hi655x_local_irq_clear(pmic->regmap);

 pmic->gpio = devm_gpiod_get_optional(dev, "pmic", GPIOD_IN);
 if (IS_ERR(pmic->gpio))
  return dev_err_probe(dev, PTR_ERR(pmic->gpio),
    "Failed to request hi655x pmic-gpio");

 ret = regmap_add_irq_chip(pmic->regmap, gpiod_to_irq(pmic->gpio),
      IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, 0,
      &hi655x_irq_chip, &pmic->irq_data);
 if (ret) {
  dev_err(dev, "Failed to obtain 'hi655x_pmic_irq' %d\n", ret);
  return ret;
 }

 platform_set_drvdata(pdev, pmic);

 ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs,
         ARRAY_SIZE(hi655x_pmic_devs), NULL, 0,
         regmap_irq_get_domain(pmic->irq_data));
 if (ret) {
  dev_err(dev, "Failed to register device %d\n", ret);
  regmap_del_irq_chip(gpiod_to_irq(pmic->gpio), pmic->irq_data);
  return ret;
 }

 return 0;
}

static void hi655x_pmic_remove(struct platform_device *pdev)
{
 struct hi655x_pmic *pmic = platform_get_drvdata(pdev);

 regmap_del_irq_chip(gpiod_to_irq(pmic->gpio), pmic->irq_data);
 mfd_remove_devices(&pdev->dev);
}

static const struct of_device_id hi655x_pmic_match[] = {
 { .compatible = "hisilicon,hi655x-pmic", },
 {},
};
MODULE_DEVICE_TABLE(of, hi655x_pmic_match);

static struct platform_driver hi655x_pmic_driver = {
 .driver = {
  .name = "hi655x-pmic",
  .of_match_table = hi655x_pmic_match,
 },
 .probe = hi655x_pmic_probe,
 .remove = hi655x_pmic_remove,
};
module_platform_driver(hi655x_pmic_driver);

MODULE_AUTHOR("Chen Feng ");
MODULE_DESCRIPTION("Hisilicon hi655x PMIC driver");
MODULE_LICENSE("GPL v2");

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

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet)  ¤

*© 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.