root/drivers/staging/comedi/drivers/ni_routes.h

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

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. ni_rtsi_route_requires_mux
  2. route_is_valid
  3. channel_is_pfi
  4. channel_is_rtsi
  5. channel_is_ctr
  6. route_register_is_valid
  7. ni_get_reg_value_roffs
  8. ni_get_reg_value
  9. ni_check_trigger_arg_roffs
  10. ni_check_trigger_arg

   1 /* SPDX-License-Identifier: GPL-2.0+ */
   2 /* vim: set ts=8 sw=8 noet tw=80 nowrap: */
   3 /*
   4  *  comedi/drivers/ni_routes.h
   5  *  Route information for NI boards.
   6  *
   7  *  COMEDI - Linux Control and Measurement Device Interface
   8  *  Copyright (C) 2016 Spencer E. Olson <olsonse@umich.edu>
   9  *
  10  *  This program is free software; you can redistribute it and/or modify
  11  *  it under the terms of the GNU General Public License as published by
  12  *  the Free Software Foundation; either version 2 of the License, or
  13  *  (at your option) any later version.
  14  *
  15  *  This program is distributed in the hope that it will be useful,
  16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18  *  GNU General Public License for more details.
  19  */
  20 
  21 #ifndef _COMEDI_DRIVERS_NI_ROUTES_H
  22 #define _COMEDI_DRIVERS_NI_ROUTES_H
  23 
  24 #include <linux/types.h>
  25 #include <linux/errno.h>
  26 
  27 #ifndef NI_ROUTE_VALUE_EXTERNAL_CONVERSION
  28 #include <linux/bitops.h>
  29 #endif
  30 
  31 #include "../comedi.h"
  32 
  33 /**
  34  * struct ni_route_set - Set of destinations with a common source.
  35  * @dest: Destination of all sources in this route set.
  36  * @n_src: Number of sources for this route set.
  37  * @src: List of sources that all map to the same destination.
  38  */
  39 struct ni_route_set {
  40         int dest;
  41         int n_src;
  42         int *src;
  43 };
  44 
  45 /**
  46  * struct ni_device_routes - List of all src->dest sets for a particular device.
  47  * @device: Name of board/device (e.g. pxi-6733).
  48  * @n_route_sets: Number of route sets that are valid for this device.
  49  * @routes: List of route sets that are valid for this device.
  50  */
  51 struct ni_device_routes {
  52         const char *device;
  53         int n_route_sets;
  54         struct ni_route_set *routes;
  55 };
  56 
  57 /**
  58  * struct ni_route_tables - Register values and valid routes for a device.
  59  * @valid_routes: Pointer to a all valid route sets for a single device.
  60  * @route_values: Pointer to register values for all routes for the family to
  61  *                which the device belongs.
  62  *
  63  * Link to the valid src->dest routes and the register values used to assign
  64  * such routes for that particular device.
  65  */
  66 struct ni_route_tables {
  67         const struct ni_device_routes *valid_routes;
  68         const u8 *route_values;
  69 };
  70 
  71 /*
  72  * ni_assign_device_routes() - Assign the proper lookup table for NI signal
  73  *                             routing to the specified NI device.
  74  *
  75  * Return: -ENODATA if assignment was not successful; 0 if successful.
  76  */
  77 int ni_assign_device_routes(const char *device_family,
  78                             const char *board_name,
  79                             struct ni_route_tables *tables);
  80 
  81 /*
  82  * ni_find_route_set() - Finds the proper route set with the specified
  83  *                       destination.
  84  * @destination: Destination of which to search for the route set.
  85  * @valid_routes: Pointer to device routes within which to search.
  86  *
  87  * Return: NULL if no route_set is found with the specified @destination;
  88  *      otherwise, a pointer to the route_set if found.
  89  */
  90 const struct ni_route_set *
  91 ni_find_route_set(const int destination,
  92                   const struct ni_device_routes *valid_routes);
  93 
  94 /*
  95  * ni_route_set_has_source() - Determines whether the given source is in
  96  *                             included given route_set.
  97  *
  98  * Return: true if found; false otherwise.
  99  */
 100 bool ni_route_set_has_source(const struct ni_route_set *routes, const int src);
 101 
 102 /*
 103  * ni_route_to_register() - Validates and converts the specified signal route
 104  *                          (src-->dest) to the value used at the appropriate
 105  *                          register.
 106  * @src:        global-identifier for route source
 107  * @dest:       global-identifier for route destination
 108  * @tables:     pointer to relevant set of routing tables.
 109  *
 110  * Generally speaking, most routes require the first six bits and a few require
 111  * 7 bits.  Special handling is given for the return value when the route is to
 112  * be handled by the RTSI sub-device.  In this case, the returned register may
 113  * not be sufficient to define the entire route path, but rather may only
 114  * indicate the intermediate route.  For example, if the route must go through
 115  * the RGOUT0 pin, the (src->RGOUT0) register value will be returned.
 116  * Similarly, if the route must go through the NI_RTSI_BRD lines, the BIT(6)
 117  * will be set:
 118  *
 119  * if route does not need RTSI_BRD lines:
 120  *   bits 0:7 : register value
 121  *              for a route that must go through RGOUT0 pin, this will be equal
 122  *              to the (src->RGOUT0) register value.
 123  * else: * route is (src->RTSI_BRD(x), RTSI_BRD(x)->TRIGGER_LINE(i)) *
 124  *   bits 0:5 : zero
 125  *   bits 6   : set to 1
 126  *   bits 7:7 : zero
 127  *
 128  * Return: register value to be used for source at destination with special
 129  *      cases given above; Otherwise, -1 if the specified route is not valid for
 130  *      this particular device.
 131  */
 132 s8 ni_route_to_register(const int src, const int dest,
 133                         const struct ni_route_tables *tables);
 134 
 135 static inline bool ni_rtsi_route_requires_mux(s8 value)
 136 {
 137         return value & BIT(6);
 138 }
 139 
 140 /*
 141  * ni_lookup_route_register() - Look up a register value for a particular route
 142  *                              without checking whether the route is valid for
 143  *                              the particular device.
 144  * @src:        global-identifier for route source
 145  * @dest:       global-identifier for route destination
 146  * @tables:     pointer to relevant set of routing tables.
 147  *
 148  * Return: -EINVAL if the specified route is not valid for this device family.
 149  */
 150 s8 ni_lookup_route_register(int src, int dest,
 151                             const struct ni_route_tables *tables);
 152 
 153 /**
 154  * route_is_valid() - Determines whether the specified signal route (src-->dest)
 155  *                    is valid for the given NI comedi_device.
 156  * @src:        global-identifier for route source
 157  * @dest:       global-identifier for route destination
 158  * @tables:     pointer to relevant set of routing tables.
 159  *
 160  * Return: True if the route is valid, otherwise false.
 161  */
 162 static inline bool route_is_valid(const int src, const int dest,
 163                                   const struct ni_route_tables *tables)
 164 {
 165         return ni_route_to_register(src, dest, tables) >= 0;
 166 }
 167 
 168 /*
 169  * ni_is_cmd_dest() - Determine whether the given destination is only
 170  *                    configurable via a comedi_cmd struct.
 171  * @dest: Destination to test.
 172  */
 173 bool ni_is_cmd_dest(int dest);
 174 
 175 static inline bool channel_is_pfi(int channel)
 176 {
 177         return NI_PFI(0) <= channel && channel <= NI_PFI(-1);
 178 }
 179 
 180 static inline bool channel_is_rtsi(int channel)
 181 {
 182         return TRIGGER_LINE(0) <= channel && channel <= TRIGGER_LINE(-1);
 183 }
 184 
 185 static inline bool channel_is_ctr(int channel)
 186 {
 187         return channel >= NI_COUNTER_NAMES_BASE &&
 188                channel <= NI_COUNTER_NAMES_MAX;
 189 }
 190 
 191 /*
 192  * ni_count_valid_routes() - Count the number of valid routes.
 193  * @tables: Routing tables for which to count all valid routes.
 194  */
 195 unsigned int ni_count_valid_routes(const struct ni_route_tables *tables);
 196 
 197 /*
 198  * ni_get_valid_routes() - Implements INSN_DEVICE_CONFIG_GET_ROUTES.
 199  * @tables:     pointer to relevant set of routing tables.
 200  * @n_pairs:    Number of pairs for which memory is allocated by the user.  If
 201  *              the user specifies '0', only the number of available pairs is
 202  *              returned.
 203  * @pair_data:  Pointer to memory allocated to return pairs back to user.  Each
 204  *              even, odd indexed member of this array will hold source,
 205  *              destination of a route pair respectively.
 206  *
 207  * Return: the number of valid routes if n_pairs == 0; otherwise, the number of
 208  *      valid routes copied.
 209  */
 210 unsigned int ni_get_valid_routes(const struct ni_route_tables *tables,
 211                                  unsigned int n_pairs,
 212                                  unsigned int *pair_data);
 213 
 214 /*
 215  * ni_sort_device_routes() - Sort the list of valid device signal routes in
 216  *                           preparation for use.
 217  * @valid_routes:       pointer to ni_device_routes struct to sort.
 218  */
 219 void ni_sort_device_routes(struct ni_device_routes *valid_routes);
 220 
 221 /*
 222  * ni_find_route_source() - Finds the signal source corresponding to a signal
 223  *                          route (src-->dest) of the specified routing register
 224  *                          value and the specified route destination on the
 225  *                          specified device.
 226  *
 227  * Note that this function does _not_ validate the source based on device
 228  * routes.
 229  *
 230  * Return: The NI signal value (e.g. NI_PFI(0) or PXI_Clk10) if found.
 231  *      If the source was not found (i.e. the register value is not
 232  *      valid for any routes to the destination), -EINVAL is returned.
 233  */
 234 int ni_find_route_source(const u8 src_sel_reg_value, const int dest,
 235                          const struct ni_route_tables *tables);
 236 
 237 /**
 238  * route_register_is_valid() - Determines whether the register value for the
 239  *                             specified route destination on the specified
 240  *                             device is valid.
 241  */
 242 static inline bool route_register_is_valid(const u8 src_sel_reg_value,
 243                                            const int dest,
 244                                            const struct ni_route_tables *tables)
 245 {
 246         return ni_find_route_source(src_sel_reg_value, dest, tables) >= 0;
 247 }
 248 
 249 /**
 250  * ni_get_reg_value_roffs() - Determines the proper register value for a
 251  *                            particular valid NI signal/terminal route.
 252  * @src:        Either a direct register value or one of NI_* signal names.
 253  * @dest:       global-identifier for route destination
 254  * @tables:     pointer to relevant set of routing tables.
 255  * @direct_reg_offset:
 256  *              Compatibility compensation argument.  This argument allows us to
 257  *              arbitrarily apply an offset to src if src is a direct register
 258  *              value reference.  This is necessary to be compatible with
 259  *              definitions of register values as previously exported directly
 260  *              to user space.
 261  *
 262  * Return: the register value (>0) to be used at the destination if the src is
 263  *      valid for the given destination; -1 otherwise.
 264  */
 265 static inline s8 ni_get_reg_value_roffs(int src, const int dest,
 266                                         const struct ni_route_tables *tables,
 267                                         const int direct_reg_offset)
 268 {
 269         if (src < NI_NAMES_BASE) {
 270                 src += direct_reg_offset;
 271                 /*
 272                  * In this case, the src is expected to actually be a register
 273                  * value.
 274                  */
 275                 if (route_register_is_valid(src, dest, tables))
 276                         return src;
 277                 return -1;
 278         }
 279 
 280         /*
 281          * Otherwise, the src is expected to be one of the abstracted NI
 282          * signal/terminal names.
 283          */
 284         return ni_route_to_register(src, dest, tables);
 285 }
 286 
 287 static inline int ni_get_reg_value(const int src, const int dest,
 288                                    const struct ni_route_tables *tables)
 289 {
 290         return ni_get_reg_value_roffs(src, dest, tables, 0);
 291 }
 292 
 293 /**
 294  * ni_check_trigger_arg_roffs() - Checks the trigger argument (*_arg) of an NI
 295  *                                device to ensure that the *_arg value
 296  *                                corresponds to _either_ a valid register value
 297  *                                to define a trigger source, _or_ a valid NI
 298  *                                signal/terminal name that has a valid route to
 299  *                                the destination on the particular device.
 300  * @src:        Either a direct register value or one of NI_* signal names.
 301  * @dest:       global-identifier for route destination
 302  * @tables:     pointer to relevant set of routing tables.
 303  * @direct_reg_offset:
 304  *              Compatibility compensation argument.  This argument allows us to
 305  *              arbitrarily apply an offset to src if src is a direct register
 306  *              value reference.  This is necessary to be compatible with
 307  *              definitions of register values as previously exported directly
 308  *              to user space.
 309  *
 310  * Return: 0 if the src (either register value or NI signal/terminal name) is
 311  *      valid for the destination; -EINVAL otherwise.
 312  */
 313 static inline
 314 int ni_check_trigger_arg_roffs(int src, const int dest,
 315                                const struct ni_route_tables *tables,
 316                                const int direct_reg_offset)
 317 {
 318         if (ni_get_reg_value_roffs(src, dest, tables, direct_reg_offset) < 0)
 319                 return -EINVAL;
 320         return 0;
 321 }
 322 
 323 static inline int ni_check_trigger_arg(const int src, const int dest,
 324                                        const struct ni_route_tables *tables)
 325 {
 326         return ni_check_trigger_arg_roffs(src, dest, tables, 0);
 327 }
 328 
 329 #endif /* _COMEDI_DRIVERS_NI_ROUTES_H */

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