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

Quelle  qe_io.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * arch/powerpc/sysdev/qe_lib/qe_io.c
 *
 * QE Parallel I/O ports configuration routines
 *
 * Copyright 2006 Freescale Semiconductor, Inc. All rights reserved.
 *
 * Author: Li Yang <LeoLi@freescale.com>
 * Based on code from Shlomi Gridish <gridish@freescale.com>
 */


#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/ioport.h>

#include <asm/io.h>
#include <soc/fsl/qe/qe.h>

#undef DEBUG

static struct qe_pio_regs __iomem *par_io;
static int num_par_io_ports = 0;

int par_io_init(struct device_node *np)
{
 struct resource res;
 int ret;
 u32 num_ports;

 /* Map Parallel I/O ports registers */
 ret = of_address_to_resource(np, 0, &res);
 if (ret)
  return ret;
 par_io = ioremap(res.start, resource_size(&res));
 if (!par_io)
  return -ENOMEM;

 if (!of_property_read_u32(np, "num-ports", &num_ports))
  num_par_io_ports = num_ports;

 return 0;
}

void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
    int open_drain, int assignment, int has_irq)
{
 u32 pin_mask1bit;
 u32 pin_mask2bits;
 u32 new_mask2bits;
 u32 tmp_val;

 /* calculate pin location for single and 2 bits information */
 pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1)));

 /* Set open drain, if required */
 tmp_val = ioread32be(&par_io->cpodr);
 if (open_drain)
  iowrite32be(pin_mask1bit | tmp_val, &par_io->cpodr);
 else
  iowrite32be(~pin_mask1bit & tmp_val, &par_io->cpodr);

 /* define direction */
 tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
  ioread32be(&par_io->cpdir2) :
  ioread32be(&par_io->cpdir1);

 /* get all bits mask for 2 bit per port */
 pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS -
    (pin % (QE_PIO_PINS / 2) + 1) * 2));

 /* Get the final mask we need for the right definition */
 new_mask2bits = (u32) (dir << (QE_PIO_PINS -
    (pin % (QE_PIO_PINS / 2) + 1) * 2));

 /* clear and set 2 bits mask */
 if (pin > (QE_PIO_PINS / 2) - 1) {
  iowrite32be(~pin_mask2bits & tmp_val, &par_io->cpdir2);
  tmp_val &= ~pin_mask2bits;
  iowrite32be(new_mask2bits | tmp_val, &par_io->cpdir2);
 } else {
  iowrite32be(~pin_mask2bits & tmp_val, &par_io->cpdir1);
  tmp_val &= ~pin_mask2bits;
  iowrite32be(new_mask2bits | tmp_val, &par_io->cpdir1);
 }
 /* define pin assignment */
 tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
  ioread32be(&par_io->cppar2) :
  ioread32be(&par_io->cppar1);

 new_mask2bits = (u32) (assignment << (QE_PIO_PINS -
   (pin % (QE_PIO_PINS / 2) + 1) * 2));
 /* clear and set 2 bits mask */
 if (pin > (QE_PIO_PINS / 2) - 1) {
  iowrite32be(~pin_mask2bits & tmp_val, &par_io->cppar2);
  tmp_val &= ~pin_mask2bits;
  iowrite32be(new_mask2bits | tmp_val, &par_io->cppar2);
 } else {
  iowrite32be(~pin_mask2bits & tmp_val, &par_io->cppar1);
  tmp_val &= ~pin_mask2bits;
  iowrite32be(new_mask2bits | tmp_val, &par_io->cppar1);
 }
}
EXPORT_SYMBOL(__par_io_config_pin);

int par_io_config_pin(u8 port, u8 pin, int dir, int open_drain,
        int assignment, int has_irq)
{
 if (!par_io || port >= num_par_io_ports)
  return -EINVAL;

 __par_io_config_pin(&par_io[port], pin, dir, open_drain, assignment,
       has_irq);
 return 0;
}
EXPORT_SYMBOL(par_io_config_pin);

int par_io_data_set(u8 port, u8 pin, u8 val)
{
 u32 pin_mask, tmp_val;

 if (port >= num_par_io_ports)
  return -EINVAL;
 if (pin >= QE_PIO_PINS)
  return -EINVAL;
 /* calculate pin location */
 pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin));

 tmp_val = ioread32be(&par_io[port].cpdata);

 if (val == 0)  /* clear */
  iowrite32be(~pin_mask & tmp_val, &par_io[port].cpdata);
 else   /* set */
  iowrite32be(pin_mask | tmp_val, &par_io[port].cpdata);

 return 0;
}
EXPORT_SYMBOL(par_io_data_set);

int par_io_of_config(struct device_node *np)
{
 struct device_node *pio;
 int pio_map_len;
 const __be32 *pio_map;

 if (par_io == NULL) {
  printk(KERN_ERR "par_io not initialized\n");
  return -1;
 }

 pio = of_parse_phandle(np, "pio-handle", 0);
 if (pio == NULL) {
  printk(KERN_ERR "pio-handle not available\n");
  return -1;
 }

 pio_map = of_get_property(pio, "pio-map", &pio_map_len);
 if (pio_map == NULL) {
  printk(KERN_ERR "pio-map is not set!\n");
  return -1;
 }
 pio_map_len /= sizeof(unsigned int);
 if ((pio_map_len % 6) != 0) {
  printk(KERN_ERR "pio-map format wrong!\n");
  return -1;
 }

 while (pio_map_len > 0) {
  u8 port        = be32_to_cpu(pio_map[0]);
  u8 pin         = be32_to_cpu(pio_map[1]);
  int dir        = be32_to_cpu(pio_map[2]);
  int open_drain = be32_to_cpu(pio_map[3]);
  int assignment = be32_to_cpu(pio_map[4]);
  int has_irq    = be32_to_cpu(pio_map[5]);

  par_io_config_pin(port, pin, dir, open_drain,
      assignment, has_irq);
  pio_map += 6;
  pio_map_len -= 6;
 }
 of_node_put(pio);
 return 0;
}
EXPORT_SYMBOL(par_io_of_config);

Messung V0.5
C=95 H=95 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.