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

Quelle  gpio-i8255.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
/*
 * Intel 8255 Programmable Peripheral Interface
 * Copyright (C) 2022 William Breathitt Gray
 */

#include <linux/bits.h>
#include <linux/device.h>
#include <linux/err.h>
#include <linux/export.h>
#include <linux/gpio/regmap.h>
#include <linux/module.h>
#include <linux/regmap.h>

#include "gpio-i8255.h"

#define I8255_NGPIO 24
#define I8255_NGPIO_PER_REG 8
#define I8255_CONTROL_PORTC_LOWER_DIRECTION BIT(0)
#define I8255_CONTROL_PORTB_DIRECTION BIT(1)
#define I8255_CONTROL_PORTC_UPPER_DIRECTION BIT(3)
#define I8255_CONTROL_PORTA_DIRECTION BIT(4)
#define I8255_CONTROL_MODE_SET BIT(7)
#define I8255_PORTA 0x0
#define I8255_PORTB 0x1
#define I8255_PORTC 0x2
#define I8255_CONTROL 0x3
#define I8255_REG_DAT_BASE I8255_PORTA
#define I8255_REG_DIR_IN_BASE I8255_CONTROL

static int i8255_direction_mask(const unsigned int offset)
{
 const unsigned int stride = offset / I8255_NGPIO_PER_REG;
 const unsigned int line = offset % I8255_NGPIO_PER_REG;

 switch (stride) {
 case I8255_PORTA:
  return I8255_CONTROL_PORTA_DIRECTION;
 case I8255_PORTB:
  return I8255_CONTROL_PORTB_DIRECTION;
 case I8255_PORTC:
  /* Port C can be configured by nibble */
  if (line >= 4)
   return I8255_CONTROL_PORTC_UPPER_DIRECTION;
  return I8255_CONTROL_PORTC_LOWER_DIRECTION;
 default:
  /* Should never reach this path */
  return 0;
 }
}

static int i8255_ppi_init(struct regmap *const map, const unsigned int base)
{
 int err;

 /* Configure all ports to MODE 0 output mode */
 err = regmap_write(map, base + I8255_CONTROL, I8255_CONTROL_MODE_SET);
 if (err)
  return err;

 /* Initialize all GPIO to output 0 */
 err = regmap_write(map, base + I8255_PORTA, 0x00);
 if (err)
  return err;
 err = regmap_write(map, base + I8255_PORTB, 0x00);
 if (err)
  return err;
 return regmap_write(map, base + I8255_PORTC, 0x00);
}

static int i8255_reg_mask_xlate(struct gpio_regmap *gpio, unsigned int base,
    unsigned int offset, unsigned int *reg,
    unsigned int *mask)
{
 const unsigned int ppi = offset / I8255_NGPIO;
 const unsigned int ppi_offset = offset % I8255_NGPIO;
 const unsigned int stride = ppi_offset / I8255_NGPIO_PER_REG;
 const unsigned int line = ppi_offset % I8255_NGPIO_PER_REG;

 switch (base) {
 case I8255_REG_DAT_BASE:
  *reg = base + stride + ppi * 4;
  *mask = BIT(line);
  return 0;
 case I8255_REG_DIR_IN_BASE:
  *reg = base + ppi * 4;
  *mask = i8255_direction_mask(ppi_offset);
  return 0;
 default:
  /* Should never reach this path */
  return -EINVAL;
 }
}

/**
 * devm_i8255_regmap_register - Register an i8255 GPIO controller
 * @dev: device that is registering this i8255 GPIO device
 * @config: configuration for i8255_regmap_config
 *
 * Registers an Intel 8255 Programmable Peripheral Interface GPIO controller.
 * Returns 0 on success and negative error number on failure.
 */

int devm_i8255_regmap_register(struct device *const dev,
          const struct i8255_regmap_config *const config)
{
 struct gpio_regmap_config gpio_config = {0};
 unsigned long i;
 int err;

 if (!config->parent)
  return -EINVAL;

 if (!config->map)
  return -EINVAL;

 if (!config->num_ppi)
  return -EINVAL;

 for (i = 0; i < config->num_ppi; i++) {
  err = i8255_ppi_init(config->map, i * 4);
  if (err)
   return err;
 }

 gpio_config.parent = config->parent;
 gpio_config.regmap = config->map;
 gpio_config.ngpio = I8255_NGPIO * config->num_ppi;
 gpio_config.names = config->names;
 gpio_config.reg_dat_base = GPIO_REGMAP_ADDR(I8255_REG_DAT_BASE);
 gpio_config.reg_set_base = GPIO_REGMAP_ADDR(I8255_REG_DAT_BASE);
 gpio_config.reg_dir_in_base = GPIO_REGMAP_ADDR(I8255_REG_DIR_IN_BASE);
 gpio_config.ngpio_per_reg = I8255_NGPIO_PER_REG;
 gpio_config.irq_domain = config->domain;
 gpio_config.reg_mask_xlate = i8255_reg_mask_xlate;

 return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &gpio_config));
}
EXPORT_SYMBOL_NS_GPL(devm_i8255_regmap_register, "I8255");

MODULE_AUTHOR("William Breathitt Gray");
MODULE_DESCRIPTION("Intel 8255 Programmable Peripheral Interface");
MODULE_LICENSE("GPL");

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

¤ 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.