Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  global2_scratch.c  Sprache: unbekannt

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Marvell 88E6xxx Switch Global 2 Scratch & Misc Registers support
 *
 * Copyright (c) 2008 Marvell Semiconductor
 *
 * Copyright (c) 2017 National Instruments
 *      Brandon Streiff <brandon.streiff@ni.com>
 */


#include "chip.h"
#include "global2.h"

/* Offset 0x1A: Scratch and Misc. Register */
static int mv88e6xxx_g2_scratch_read(struct mv88e6xxx_chip *chip, int reg,
         u8 *data)
{
 u16 value;
 int err;

 err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
     reg << 8);
 if (err)
  return err;

 err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, &value);
 if (err)
  return err;

 *data = (value & MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK);

 return 0;
}

static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg,
          u8 data)
{
 u16 value = (reg << 8) | data;

 return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
      MV88E6XXX_G2_SCRATCH_MISC_UPDATE | value);
}

/**
 * mv88e6xxx_g2_scratch_get_bit - get a bit
 * @chip: chip private data
 * @base_reg: base of scratch bits
 * @offset: index of bit within the register
 * @set: is bit set?
 */

static int mv88e6xxx_g2_scratch_get_bit(struct mv88e6xxx_chip *chip,
     int base_reg, unsigned int offset,
     int *set)
{
 int reg = base_reg + (offset / 8);
 u8 mask = (1 << (offset & 0x7));
 u8 val;
 int err;

 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
 if (err)
  return err;

 *set = !!(mask & val);

 return 0;
}

/**
 * mv88e6xxx_g2_scratch_set_bit - set (or clear) a bit
 * @chip: chip private data
 * @base_reg: base of scratch bits
 * @offset: index of bit within the register
 * @set: should this bit be set?
 *
 * Helper function for dealing with the direction and data registers.
 */

static int mv88e6xxx_g2_scratch_set_bit(struct mv88e6xxx_chip *chip,
     int base_reg, unsigned int offset,
     int set)
{
 int reg = base_reg + (offset / 8);
 u8 mask = (1 << (offset & 0x7));
 u8 val;
 int err;

 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
 if (err)
  return err;

 if (set)
  val |= mask;
 else
  val &= ~mask;

 return mv88e6xxx_g2_scratch_write(chip, reg, val);
}

/**
 * mv88e6352_g2_scratch_gpio_get_data - get data on gpio pin
 * @chip: chip private data
 * @pin: gpio index
 *
 * Return: 0 for low, 1 for high, negative error
 */

static int mv88e6352_g2_scratch_gpio_get_data(struct mv88e6xxx_chip *chip,
           unsigned int pin)
{
 int val = 0;
 int err;

 err = mv88e6xxx_g2_scratch_get_bit(chip,
        MV88E6352_G2_SCRATCH_GPIO_DATA0,
        pin, &val);
 if (err)
  return err;

 return val;
}

/**
 * mv88e6352_g2_scratch_gpio_set_data - set data on gpio pin
 * @chip: chip private data
 * @pin: gpio index
 * @value: value to set
 */

static int mv88e6352_g2_scratch_gpio_set_data(struct mv88e6xxx_chip *chip,
           unsigned int pin, int value)
{
 u8 mask = (1 << (pin & 0x7));
 int offset = (pin / 8);
 int reg;

 reg = MV88E6352_G2_SCRATCH_GPIO_DATA0 + offset;

 if (value)
  chip->gpio_data[offset] |= mask;
 else
  chip->gpio_data[offset] &= ~mask;

 return mv88e6xxx_g2_scratch_write(chip, reg, chip->gpio_data[offset]);
}

/**
 * mv88e6352_g2_scratch_gpio_get_dir - get direction of gpio pin
 * @chip: chip private data
 * @pin: gpio index
 *
 * Return: 0 for output, 1 for input.
 */

static int mv88e6352_g2_scratch_gpio_get_dir(struct mv88e6xxx_chip *chip,
          unsigned int pin)
{
 int val = 0;
 int err;

 err = mv88e6xxx_g2_scratch_get_bit(chip,
        MV88E6352_G2_SCRATCH_GPIO_DIR0,
        pin, &val);
 if (err)
  return err;

 return val;
}

/**
 * mv88e6352_g2_scratch_gpio_set_dir - set direction of gpio pin
 * @chip: chip private data
 * @pin: gpio index
 * @input: should the gpio be an input, or an output?
 */

static int mv88e6352_g2_scratch_gpio_set_dir(struct mv88e6xxx_chip *chip,
          unsigned int pin, bool input)
{
 int value = (input ? MV88E6352_G2_SCRATCH_GPIO_DIR_IN :
        MV88E6352_G2_SCRATCH_GPIO_DIR_OUT);

 return mv88e6xxx_g2_scratch_set_bit(chip,
         MV88E6352_G2_SCRATCH_GPIO_DIR0,
         pin, value);
}

/**
 * mv88e6352_g2_scratch_gpio_get_pctl - get pin control setting
 * @chip: chip private data
 * @pin: gpio index
 * @func: function number
 *
 * Note that the function numbers themselves may vary by chipset.
 */

static int mv88e6352_g2_scratch_gpio_get_pctl(struct mv88e6xxx_chip *chip,
           unsigned int pin, int *func)
{
 int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
 int offset = (pin & 0x1) ? 4 : 0;
 u8 mask = (0x7 << offset);
 int err;
 u8 val;

 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
 if (err)
  return err;

 *func = (val & mask) >> offset;

 return 0;
}

/**
 * mv88e6352_g2_scratch_gpio_set_pctl - set pin control setting
 * @chip: chip private data
 * @pin: gpio index
 * @func: function number
 */

static int mv88e6352_g2_scratch_gpio_set_pctl(struct mv88e6xxx_chip *chip,
           unsigned int pin, int func)
{
 int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
 int offset = (pin & 0x1) ? 4 : 0;
 u8 mask = (0x7 << offset);
 int err;
 u8 val;

 err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
 if (err)
  return err;

 val = (val & ~mask) | ((func & mask) << offset);

 return mv88e6xxx_g2_scratch_write(chip, reg, val);
}

const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
 .get_data = mv88e6352_g2_scratch_gpio_get_data,
 .set_data = mv88e6352_g2_scratch_gpio_set_data,
 .get_dir = mv88e6352_g2_scratch_gpio_get_dir,
 .set_dir = mv88e6352_g2_scratch_gpio_set_dir,
 .get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
 .set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
};

/**
 * mv88e6390_g2_scratch_gpio_set_smi - set gpio muxing for external smi
 * @chip: chip private data
 * @external: set mux for external smi, or free for gpio usage
 *
 * Some mv88e6xxx models have GPIO pins that may be configured as
 * an external SMI interface, or they may be made free for other
 * GPIO uses.
 */

int mv88e6390_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
          bool external)
{
 int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
 int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
 int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
 bool no_cpu;
 u8 p0_mode;
 int err;
 u8 val;

 err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
 if (err)
  return err;

 p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;

 if (p0_mode == 0x01 || p0_mode == 0x02)
  return -EBUSY;

 err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
 if (err)
  return err;

 no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);

 err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
 if (err)
  return err;

 /* NO_CPU being 0 inverts the meaning of the bit */
 if (!no_cpu)
  external = !external;

 if (external)
  val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
 else
  val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;

 return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
}

/**
 * mv88e6393x_g2_scratch_gpio_set_smi - set gpio muxing for external smi
 * @chip: chip private data
 * @external: set mux for external smi, or free for gpio usage
 *
 * MV88E6191X/6193X/6393X GPIO pins 9 and 10 can be configured as an
 * external SMI interface or as regular GPIO-s.
 *
 * They however have a different register layout then the existing
 * function.
 */


int mv88e6393x_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
           bool external)
{
 int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
 int err;
 u8 val;

 err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
 if (err)
  return err;

 if (external)
  val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
 else
  val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;

 return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
}

/**
 * mv88e6352_g2_scratch_port_has_serdes - indicate if a port can have a serdes
 * @chip: chip private data
 * @port: port number to check for serdes
 *
 * Indicates whether the port may have a serdes attached according to the
 * pin strapping. Returns negative error number, 0 if the port is not
 * configured to have a serdes, and 1 if the port is configured to have a
 * serdes attached.
 */

int mv88e6352_g2_scratch_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
{
 u8 config3, p;
 int err;

 err = mv88e6xxx_g2_scratch_read(chip, MV88E6352_G2_SCRATCH_CONFIG_DATA3,
     &config3);
 if (err)
  return err;

 if (config3 & MV88E6352_G2_SCRATCH_CONFIG_DATA3_S_SEL)
  p = 5;
 else
  p = 4;

 return port == p;
}

Messung V0.5 in Prozent
C=96 H=100 G=97

[0.9QuellennavigatorsProjekt 2026-09-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126864
#Domains=1897691