Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  sun4i-gpadc.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/* ADC MFD core driver for sunxi platforms
 *
 * Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
 */


#include <linux/interrupt.h>
#include <linux/kernel.h>
#include <linux/mfd/core.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

#include <linux/mfd/sun4i-gpadc.h>

#define ARCH_SUN4I_A10 0
#define ARCH_SUN5I_A13 1
#define ARCH_SUN6I_A31 2

static const struct resource adc_resources[] = {
 DEFINE_RES_IRQ_NAMED(SUN4I_GPADC_IRQ_FIFO_DATA, "FIFO_DATA_PENDING"),
 DEFINE_RES_IRQ_NAMED(SUN4I_GPADC_IRQ_TEMP_DATA, "TEMP_DATA_PENDING"),
};

static const struct regmap_irq sun4i_gpadc_regmap_irq[] = {
 REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_FIFO_DATA, 0,
         SUN4I_GPADC_INT_FIFOC_TP_DATA_IRQ_EN),
 REGMAP_IRQ_REG(SUN4I_GPADC_IRQ_TEMP_DATA, 0,
         SUN4I_GPADC_INT_FIFOC_TEMP_IRQ_EN),
};

static const struct regmap_irq_chip sun4i_gpadc_regmap_irq_chip = {
 .name = "sun4i_gpadc_irq_chip",
 .status_base = SUN4I_GPADC_INT_FIFOS,
 .ack_base = SUN4I_GPADC_INT_FIFOS,
 .unmask_base = SUN4I_GPADC_INT_FIFOC,
 .init_ack_masked = true,
 .irqs = sun4i_gpadc_regmap_irq,
 .num_irqs = ARRAY_SIZE(sun4i_gpadc_regmap_irq),
 .num_regs = 1,
};

static struct mfd_cell sun4i_gpadc_cells[] = {
 {
  .name = "sun4i-a10-gpadc-iio",
  .resources = adc_resources,
  .num_resources = ARRAY_SIZE(adc_resources),
 },
 { .name = "iio_hwmon" }
};

static struct mfd_cell sun5i_gpadc_cells[] = {
 {
  .name = "sun5i-a13-gpadc-iio",
  .resources = adc_resources,
  .num_resources = ARRAY_SIZE(adc_resources),
 },
 { .name = "iio_hwmon" },
};

static struct mfd_cell sun6i_gpadc_cells[] = {
 {
  .name = "sun6i-a31-gpadc-iio",
  .resources = adc_resources,
  .num_resources = ARRAY_SIZE(adc_resources),
 },
 { .name = "iio_hwmon" },
};

static const struct regmap_config sun4i_gpadc_regmap_config = {
 .reg_bits = 32,
 .val_bits = 32,
 .reg_stride = 4,
 .fast_io = true,
};

static const struct of_device_id sun4i_gpadc_of_match[] = {
 {
  .compatible = "allwinner,sun4i-a10-ts",
  .data = (void *)ARCH_SUN4I_A10,
 }, {
  .compatible = "allwinner,sun5i-a13-ts",
  .data = (void *)ARCH_SUN5I_A13,
 }, {
  .compatible = "allwinner,sun6i-a31-ts",
  .data = (void *)ARCH_SUN6I_A31,
 }, { /* sentinel */ }
};

MODULE_DEVICE_TABLE(of, sun4i_gpadc_of_match);

static int sun4i_gpadc_probe(struct platform_device *pdev)
{
 struct sun4i_gpadc_dev *dev;
 const struct of_device_id *of_id;
 const struct mfd_cell *cells;
 unsigned int irq, size;
 int ret;

 of_id = of_match_node(sun4i_gpadc_of_match, pdev->dev.of_node);
 if (!of_id)
  return -EINVAL;

 switch ((long)of_id->data) {
 case ARCH_SUN4I_A10:
  cells = sun4i_gpadc_cells;
  size = ARRAY_SIZE(sun4i_gpadc_cells);
  break;
 case ARCH_SUN5I_A13:
  cells = sun5i_gpadc_cells;
  size = ARRAY_SIZE(sun5i_gpadc_cells);
  break;
 case ARCH_SUN6I_A31:
  cells = sun6i_gpadc_cells;
  size = ARRAY_SIZE(sun6i_gpadc_cells);
  break;
 default:
  return -EINVAL;
 }

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

 dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
 if (IS_ERR(dev->base))
  return PTR_ERR(dev->base);

 dev->dev = &pdev->dev;
 dev_set_drvdata(dev->dev, dev);

 dev->regmap = devm_regmap_init_mmio(dev->dev, dev->base,
         &sun4i_gpadc_regmap_config);
 if (IS_ERR(dev->regmap)) {
  ret = PTR_ERR(dev->regmap);
  dev_err(&pdev->dev, "failed to init regmap: %d\n", ret);
  return ret;
 }

 /* Disable all interrupts */
 regmap_write(dev->regmap, SUN4I_GPADC_INT_FIFOC, 0);

 irq = platform_get_irq(pdev, 0);
 ret = devm_regmap_add_irq_chip(&pdev->dev, dev->regmap, irq,
           IRQF_ONESHOT, 0,
           &sun4i_gpadc_regmap_irq_chip,
           &dev->regmap_irqc);
 if (ret) {
  dev_err(&pdev->dev, "failed to add irq chip: %d\n", ret);
  return ret;
 }

 ret = devm_mfd_add_devices(dev->dev, 0, cells, size, NULL, 0, NULL);
 if (ret) {
  dev_err(&pdev->dev, "failed to add MFD devices: %d\n", ret);
  return ret;
 }

 return 0;
}

static struct platform_driver sun4i_gpadc_driver = {
 .driver = {
  .name = "sun4i-gpadc",
  .of_match_table = sun4i_gpadc_of_match,
 },
 .probe = sun4i_gpadc_probe,
};

module_platform_driver(sun4i_gpadc_driver);

MODULE_DESCRIPTION("Allwinner sunxi platforms' GPADC MFD core driver");
MODULE_AUTHOR("Quentin Schulz ");
MODULE_LICENSE("GPL v2");

Messung V0.5
C=96 H=93 G=94

¤ Dauer der Verarbeitung: 0.13 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.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge