root/drivers/net/dsa/mv88e6xxx/global2_scratch.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mv88e6xxx_g2_scratch_read
  2. mv88e6xxx_g2_scratch_write
  3. mv88e6xxx_g2_scratch_get_bit
  4. mv88e6xxx_g2_scratch_set_bit
  5. mv88e6352_g2_scratch_gpio_get_data
  6. mv88e6352_g2_scratch_gpio_set_data
  7. mv88e6352_g2_scratch_gpio_get_dir
  8. mv88e6352_g2_scratch_gpio_set_dir
  9. mv88e6352_g2_scratch_gpio_get_pctl
  10. mv88e6352_g2_scratch_gpio_set_pctl
  11. mv88e6xxx_g2_scratch_gpio_set_smi

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Marvell 88E6xxx Switch Global 2 Scratch & Misc Registers support
   4  *
   5  * Copyright (c) 2008 Marvell Semiconductor
   6  *
   7  * Copyright (c) 2017 National Instruments
   8  *      Brandon Streiff <brandon.streiff@ni.com>
   9  */
  10 
  11 #include "chip.h"
  12 #include "global2.h"
  13 
  14 /* Offset 0x1A: Scratch and Misc. Register */
  15 static int mv88e6xxx_g2_scratch_read(struct mv88e6xxx_chip *chip, int reg,
  16                                      u8 *data)
  17 {
  18         u16 value;
  19         int err;
  20 
  21         err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
  22                                  reg << 8);
  23         if (err)
  24                 return err;
  25 
  26         err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, &value);
  27         if (err)
  28                 return err;
  29 
  30         *data = (value & MV88E6XXX_G2_SCRATCH_MISC_DATA_MASK);
  31 
  32         return 0;
  33 }
  34 
  35 static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg,
  36                                       u8 data)
  37 {
  38         u16 value = (reg << 8) | data;
  39 
  40         return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
  41                                   MV88E6XXX_G2_SCRATCH_MISC_UPDATE | value);
  42 }
  43 
  44 /**
  45  * mv88e6xxx_g2_scratch_gpio_get_bit - get a bit
  46  * @chip: chip private data
  47  * @nr: bit index
  48  * @set: is bit set?
  49  */
  50 static int mv88e6xxx_g2_scratch_get_bit(struct mv88e6xxx_chip *chip,
  51                                         int base_reg, unsigned int offset,
  52                                         int *set)
  53 {
  54         int reg = base_reg + (offset / 8);
  55         u8 mask = (1 << (offset & 0x7));
  56         u8 val;
  57         int err;
  58 
  59         err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
  60         if (err)
  61                 return err;
  62 
  63         *set = !!(mask & val);
  64 
  65         return 0;
  66 }
  67 
  68 /**
  69  * mv88e6xxx_g2_scratch_gpio_set_bit - set (or clear) a bit
  70  * @chip: chip private data
  71  * @nr: bit index
  72  * @set: set if true, clear if false
  73  *
  74  * Helper function for dealing with the direction and data registers.
  75  */
  76 static int mv88e6xxx_g2_scratch_set_bit(struct mv88e6xxx_chip *chip,
  77                                         int base_reg, unsigned int offset,
  78                                         int set)
  79 {
  80         int reg = base_reg + (offset / 8);
  81         u8 mask = (1 << (offset & 0x7));
  82         u8 val;
  83         int err;
  84 
  85         err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
  86         if (err)
  87                 return err;
  88 
  89         if (set)
  90                 val |= mask;
  91         else
  92                 val &= ~mask;
  93 
  94         return mv88e6xxx_g2_scratch_write(chip, reg, val);
  95 }
  96 
  97 /**
  98  * mv88e6352_g2_scratch_gpio_get_data - get data on gpio pin
  99  * @chip: chip private data
 100  * @pin: gpio index
 101  *
 102  * Return: 0 for low, 1 for high, negative error
 103  */
 104 static int mv88e6352_g2_scratch_gpio_get_data(struct mv88e6xxx_chip *chip,
 105                                               unsigned int pin)
 106 {
 107         int val = 0;
 108         int err;
 109 
 110         err = mv88e6xxx_g2_scratch_get_bit(chip,
 111                                            MV88E6352_G2_SCRATCH_GPIO_DATA0,
 112                                            pin, &val);
 113         if (err)
 114                 return err;
 115 
 116         return val;
 117 }
 118 
 119 /**
 120  * mv88e6352_g2_scratch_gpio_set_data - set data on gpio pin
 121  * @chip: chip private data
 122  * @pin: gpio index
 123  * @value: value to set
 124  */
 125 static int mv88e6352_g2_scratch_gpio_set_data(struct mv88e6xxx_chip *chip,
 126                                               unsigned int pin, int value)
 127 {
 128         u8 mask = (1 << (pin & 0x7));
 129         int offset = (pin / 8);
 130         int reg;
 131 
 132         reg = MV88E6352_G2_SCRATCH_GPIO_DATA0 + offset;
 133 
 134         if (value)
 135                 chip->gpio_data[offset] |= mask;
 136         else
 137                 chip->gpio_data[offset] &= ~mask;
 138 
 139         return mv88e6xxx_g2_scratch_write(chip, reg, chip->gpio_data[offset]);
 140 }
 141 
 142 /**
 143  * mv88e6352_g2_scratch_gpio_get_dir - get direction of gpio pin
 144  * @chip: chip private data
 145  * @pin: gpio index
 146  *
 147  * Return: 0 for output, 1 for input (same as GPIOF_DIR_XXX).
 148  */
 149 static int mv88e6352_g2_scratch_gpio_get_dir(struct mv88e6xxx_chip *chip,
 150                                              unsigned int pin)
 151 {
 152         int val = 0;
 153         int err;
 154 
 155         err = mv88e6xxx_g2_scratch_get_bit(chip,
 156                                            MV88E6352_G2_SCRATCH_GPIO_DIR0,
 157                                            pin, &val);
 158         if (err)
 159                 return err;
 160 
 161         return val;
 162 }
 163 
 164 /**
 165  * mv88e6352_g2_scratch_gpio_set_dir - set direction of gpio pin
 166  * @chip: chip private data
 167  * @pin: gpio index
 168  */
 169 static int mv88e6352_g2_scratch_gpio_set_dir(struct mv88e6xxx_chip *chip,
 170                                              unsigned int pin, bool input)
 171 {
 172         int value = (input ? MV88E6352_G2_SCRATCH_GPIO_DIR_IN :
 173                              MV88E6352_G2_SCRATCH_GPIO_DIR_OUT);
 174 
 175         return mv88e6xxx_g2_scratch_set_bit(chip,
 176                                             MV88E6352_G2_SCRATCH_GPIO_DIR0,
 177                                             pin, value);
 178 }
 179 
 180 /**
 181  * mv88e6352_g2_scratch_gpio_get_pctl - get pin control setting
 182  * @chip: chip private data
 183  * @pin: gpio index
 184  * @func: function number
 185  *
 186  * Note that the function numbers themselves may vary by chipset.
 187  */
 188 static int mv88e6352_g2_scratch_gpio_get_pctl(struct mv88e6xxx_chip *chip,
 189                                               unsigned int pin, int *func)
 190 {
 191         int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
 192         int offset = (pin & 0x1) ? 4 : 0;
 193         u8 mask = (0x7 << offset);
 194         int err;
 195         u8 val;
 196 
 197         err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
 198         if (err)
 199                 return err;
 200 
 201         *func = (val & mask) >> offset;
 202 
 203         return 0;
 204 }
 205 
 206 /**
 207  * mv88e6352_g2_scratch_gpio_set_pctl - set pin control setting
 208  * @chip: chip private data
 209  * @pin: gpio index
 210  * @func: function number
 211  */
 212 static int mv88e6352_g2_scratch_gpio_set_pctl(struct mv88e6xxx_chip *chip,
 213                                               unsigned int pin, int func)
 214 {
 215         int reg = MV88E6352_G2_SCRATCH_GPIO_PCTL0 + (pin / 2);
 216         int offset = (pin & 0x1) ? 4 : 0;
 217         u8 mask = (0x7 << offset);
 218         int err;
 219         u8 val;
 220 
 221         err = mv88e6xxx_g2_scratch_read(chip, reg, &val);
 222         if (err)
 223                 return err;
 224 
 225         val = (val & ~mask) | ((func & mask) << offset);
 226 
 227         return mv88e6xxx_g2_scratch_write(chip, reg, val);
 228 }
 229 
 230 const struct mv88e6xxx_gpio_ops mv88e6352_gpio_ops = {
 231         .get_data = mv88e6352_g2_scratch_gpio_get_data,
 232         .set_data = mv88e6352_g2_scratch_gpio_set_data,
 233         .get_dir = mv88e6352_g2_scratch_gpio_get_dir,
 234         .set_dir = mv88e6352_g2_scratch_gpio_set_dir,
 235         .get_pctl = mv88e6352_g2_scratch_gpio_get_pctl,
 236         .set_pctl = mv88e6352_g2_scratch_gpio_set_pctl,
 237 };
 238 
 239 /**
 240  * mv88e6xxx_g2_gpio_set_smi - set gpio muxing for external smi
 241  * @chip: chip private data
 242  * @external: set mux for external smi, or free for gpio usage
 243  *
 244  * Some mv88e6xxx models have GPIO pins that may be configured as
 245  * an external SMI interface, or they may be made free for other
 246  * GPIO uses.
 247  */
 248 int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
 249                                       bool external)
 250 {
 251         int misc_cfg = MV88E6352_G2_SCRATCH_MISC_CFG;
 252         int config_data1 = MV88E6352_G2_SCRATCH_CONFIG_DATA1;
 253         int config_data2 = MV88E6352_G2_SCRATCH_CONFIG_DATA2;
 254         bool no_cpu;
 255         u8 p0_mode;
 256         int err;
 257         u8 val;
 258 
 259         err = mv88e6xxx_g2_scratch_read(chip, config_data2, &val);
 260         if (err)
 261                 return err;
 262 
 263         p0_mode = val & MV88E6352_G2_SCRATCH_CONFIG_DATA2_P0_MODE_MASK;
 264 
 265         if (p0_mode == 0x01 || p0_mode == 0x02)
 266                 return -EBUSY;
 267 
 268         err = mv88e6xxx_g2_scratch_read(chip, config_data1, &val);
 269         if (err)
 270                 return err;
 271 
 272         no_cpu = !!(val & MV88E6352_G2_SCRATCH_CONFIG_DATA1_NO_CPU);
 273 
 274         err = mv88e6xxx_g2_scratch_read(chip, misc_cfg, &val);
 275         if (err)
 276                 return err;
 277 
 278         /* NO_CPU being 0 inverts the meaning of the bit */
 279         if (!no_cpu)
 280                 external = !external;
 281 
 282         if (external)
 283                 val |= MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
 284         else
 285                 val &= ~MV88E6352_G2_SCRATCH_MISC_CFG_NORMALSMI;
 286 
 287         return mv88e6xxx_g2_scratch_write(chip, misc_cfg, val);
 288 }

/* [<][>][^][v][top][bottom][index][help] */