1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Counter interface 4 * Copyright (C) 2018 William Breathitt Gray 5 */ 6 #ifndef _COUNTER_H_ 7 #define _COUNTER_H_ 8 9 #include <linux/device.h> 10 #include <linux/kernel.h> 11 #include <linux/types.h> 12 13 struct counter_device; 14 struct counter_count; 15 struct counter_synapse; 16 struct counter_signal; 17 18 enum counter_comp_type { 19 COUNTER_COMP_U8, 20 COUNTER_COMP_U64, 21 COUNTER_COMP_BOOL, 22 COUNTER_COMP_SIGNAL_LEVEL, 23 COUNTER_COMP_FUNCTION, 24 COUNTER_COMP_SYNAPSE_ACTION, 25 COUNTER_COMP_ENUM, 26 COUNTER_COMP_COUNT_DIRECTION, 27 COUNTER_COMP_COUNT_MODE, 28 }; 29 30 enum counter_scope { 31 COUNTER_SCOPE_DEVICE, 32 COUNTER_SCOPE_SIGNAL, 33 COUNTER_SCOPE_COUNT, 34 }; 35 36 enum counter_count_direction { 37 COUNTER_COUNT_DIRECTION_FORWARD, 38 COUNTER_COUNT_DIRECTION_BACKWARD, 39 }; 40 41 enum counter_count_mode { 42 COUNTER_COUNT_MODE_NORMAL, 43 COUNTER_COUNT_MODE_RANGE_LIMIT, 44 COUNTER_COUNT_MODE_NON_RECYCLE, 45 COUNTER_COUNT_MODE_MODULO_N, 46 }; 47 48 enum counter_function { 49 COUNTER_FUNCTION_INCREASE, 50 COUNTER_FUNCTION_DECREASE, 51 COUNTER_FUNCTION_PULSE_DIRECTION, 52 COUNTER_FUNCTION_QUADRATURE_X1_A, 53 COUNTER_FUNCTION_QUADRATURE_X1_B, 54 COUNTER_FUNCTION_QUADRATURE_X2_A, 55 COUNTER_FUNCTION_QUADRATURE_X2_B, 56 COUNTER_FUNCTION_QUADRATURE_X4, 57 }; 58 59 enum counter_signal_level { 60 COUNTER_SIGNAL_LEVEL_LOW, 61 COUNTER_SIGNAL_LEVEL_HIGH, 62 }; 63 64 enum counter_synapse_action { 65 COUNTER_SYNAPSE_ACTION_NONE, 66 COUNTER_SYNAPSE_ACTION_RISING_EDGE, 67 COUNTER_SYNAPSE_ACTION_FALLING_EDGE, 68 COUNTER_SYNAPSE_ACTION_BOTH_EDGES, 69 }; 70 71 /** 72 * struct counter_comp - Counter component node 73 * @type: Counter component data type 74 * @name: device-specific component name 75 * @priv: component-relevant data 76 * @action_read: Synapse action mode read callback. The read value of the 77 * respective Synapse action mode should be passed back via 78 * the action parameter. 79 * @device_u8_read: Device u8 component read callback. The read value of the 80 * respective Device u8 component should be passed back via 81 * the val parameter. 82 * @count_u8_read: Count u8 component read callback. The read value of the 83 * respective Count u8 component should be passed back via 84 * the val parameter. 85 * @signal_u8_read: Signal u8 component read callback. The read value of the 86 * respective Signal u8 component should be passed back via 87 * the val parameter. 88 * @device_u32_read: Device u32 component read callback. The read value of 89 * the respective Device u32 component should be passed 90 * back via the val parameter. 91 * @count_u32_read: Count u32 component read callback. The read value of the 92 * respective Count u32 component should be passed back via 93 * the val parameter. 94 * @signal_u32_read: Signal u32 component read callback. The read value of 95 * the respective Signal u32 component should be passed 96 * back via the val parameter. 97 * @device_u64_read: Device u64 component read callback. The read value of 98 * the respective Device u64 component should be passed 99 * back via the val parameter. 100 * @count_u64_read: Count u64 component read callback. The read value of the 101 * respective Count u64 component should be passed back via 102 * the val parameter. 103 * @signal_u64_read: Signal u64 component read callback. The read value of 104 * the respective Signal u64 component should be passed 105 * back via the val parameter. 106 * @action_write: Synapse action mode write callback. The write value of 107 * the respective Synapse action mode is passed via the 108 * action parameter. 109 * @device_u8_write: Device u8 component write callback. The write value of 110 * the respective Device u8 component is passed via the val 111 * parameter. 112 * @count_u8_write: Count u8 component write callback. The write value of 113 * the respective Count u8 component is passed via the val 114 * parameter. 115 * @signal_u8_write: Signal u8 component write callback. The write value of 116 * the respective Signal u8 component is passed via the val 117 * parameter. 118 * @device_u32_write: Device u32 component write callback. The write value of 119 * the respective Device u32 component is passed via the 120 * val parameter. 121 * @count_u32_write: Count u32 component write callback. The write value of 122 * the respective Count u32 component is passed via the val 123 * parameter. 124 * @signal_u32_write: Signal u32 component write callback. The write value of 125 * the respective Signal u32 component is passed via the 126 * val parameter. 127 * @device_u64_write: Device u64 component write callback. The write value of 128 * the respective Device u64 component is passed via the 129 * val parameter. 130 * @count_u64_write: Count u64 component write callback. The write value of 131 * the respective Count u64 component is passed via the val 132 * parameter. 133 * @signal_u64_write: Signal u64 component write callback. The write value of 134 * the respective Signal u64 component is passed via the 135 * val parameter. 136 */ 137 struct counter_comp { 138 enum counter_comp_type type; 139 const char *name; 140 void *priv; 141 union { 142 int (*action_read)(struct counter_device *counter, 143 struct counter_count *count, 144 struct counter_synapse *synapse, 145 enum counter_synapse_action *action); 146 int (*device_u8_read)(struct counter_device *counter, u8 *val); 147 int (*count_u8_read)(struct counter_device *counter, 148 struct counter_count *count, u8 *val); 149 int (*signal_u8_read)(struct counter_device *counter, 150 struct counter_signal *signal, u8 *val); 151 int (*device_u32_read)(struct counter_device *counter, 152 u32 *val); 153 int (*count_u32_read)(struct counter_device *counter, 154 struct counter_count *count, u32 *val); 155 int (*signal_u32_read)(struct counter_device *counter, 156 struct counter_signal *signal, u32 *val); 157 int (*device_u64_read)(struct counter_device *counter, 158 u64 *val); 159 int (*count_u64_read)(struct counter_device *counter, 160 struct counter_count *count, u64 *val); 161 int (*signal_u64_read)(struct counter_device *counter, 162 struct counter_signal *signal, u64 *val); 163 }; 164 union { 165 int (*action_write)(struct counter_device *counter, 166 struct counter_count *count, 167 struct counter_synapse *synapse, 168 enum counter_synapse_action action); 169 int (*device_u8_write)(struct counter_device *counter, u8 val); 170 int (*count_u8_write)(struct counter_device *counter, 171 struct counter_count *count, u8 val); 172 int (*signal_u8_write)(struct counter_device *counter, 173 struct counter_signal *signal, u8 val); 174 int (*device_u32_write)(struct counter_device *counter, 175 u32 val); 176 int (*count_u32_write)(struct counter_device *counter, 177 struct counter_count *count, u32 val); 178 int (*signal_u32_write)(struct counter_device *counter, 179 struct counter_signal *signal, u32 val); 180 int (*device_u64_write)(struct counter_device *counter, 181 u64 val); 182 int (*count_u64_write)(struct counter_device *counter, 183 struct counter_count *count, u64 val); 184 int (*signal_u64_write)(struct counter_device *counter, 185 struct counter_signal *signal, u64 val); 186 }; 187 }; 188 189 /** 190 * struct counter_signal - Counter Signal node 191 * @id: unique ID used to identify signal 192 * @name: device-specific Signal name; ideally, this should match the name 193 * as it appears in the datasheet documentation 194 * @ext: optional array of Counter Signal extensions 195 * @num_ext: number of Counter Signal extensions specified in @ext 196 */ 197 struct counter_signal { 198 int id; 199 const char *name; 200 201 struct counter_comp *ext; 202 size_t num_ext; 203 }; 204 205 /** 206 * struct counter_synapse - Counter Synapse node 207 * @actions_list: array of available action modes 208 * @num_actions: number of action modes specified in @actions_list 209 * @signal: pointer to associated signal 210 */ 211 struct counter_synapse { 212 const enum counter_synapse_action *actions_list; 213 size_t num_actions; 214 215 struct counter_signal *signal; 216 }; 217 218 /** 219 * struct counter_count - Counter Count node 220 * @id: unique ID used to identify Count 221 * @name: device-specific Count name; ideally, this should match 222 * the name as it appears in the datasheet documentation 223 * @functions_list: array available function modes 224 * @num_functions: number of function modes specified in @functions_list 225 * @synapses: array of synapses for initialization 226 * @num_synapses: number of synapses specified in @synapses 227 * @ext: optional array of Counter Count extensions 228 * @num_ext: number of Counter Count extensions specified in @ext 229 */ 230 struct counter_count { 231 int id; 232 const char *name; 233 234 const enum counter_function *functions_list; 235 size_t num_functions; 236 237 struct counter_synapse *synapses; 238 size_t num_synapses; 239 240 struct counter_comp *ext; 241 size_t num_ext; 242 }; 243 244 /** 245 * struct counter_ops - Callbacks from driver 246 * @signal_read: optional read callback for Signal attribute. The read 247 * level of the respective Signal should be passed back via 248 * the level parameter. 249 * @count_read: optional read callback for Count attribute. The read 250 * value of the respective Count should be passed back via 251 * the val parameter. 252 * @count_write: optional write callback for Count attribute. The write 253 * value for the respective Count is passed in via the val 254 * parameter. 255 * @function_read: read callback the Count function modes. The read 256 * function mode of the respective Count should be passed 257 * back via the function parameter. 258 * @function_write: write callback for Count function modes. The function 259 * mode to write for the respective Count is passed in via 260 * the function parameter. 261 * @action_read: read callback the Synapse action modes. The read action 262 * mode of the respective Synapse should be passed back via 263 * the action parameter. 264 * @action_write: write callback for Synapse action modes. The action mode 265 * to write for the respective Synapse is passed in via the 266 * action parameter. 267 */ 268 struct counter_ops { 269 int (*signal_read)(struct counter_device *counter, 270 struct counter_signal *signal, 271 enum counter_signal_level *level); 272 int (*count_read)(struct counter_device *counter, 273 struct counter_count *count, u64 *value); 274 int (*count_write)(struct counter_device *counter, 275 struct counter_count *count, u64 value); 276 int (*function_read)(struct counter_device *counter, 277 struct counter_count *count, 278 enum counter_function *function); 279 int (*function_write)(struct counter_device *counter, 280 struct counter_count *count, 281 enum counter_function function); 282 int (*action_read)(struct counter_device *counter, 283 struct counter_count *count, 284 struct counter_synapse *synapse, 285 enum counter_synapse_action *action); 286 int (*action_write)(struct counter_device *counter, 287 struct counter_count *count, 288 struct counter_synapse *synapse, 289 enum counter_synapse_action action); 290 }; 291 292 /** 293 * struct counter_device - Counter data structure 294 * @name: name of the device as it appears in the datasheet 295 * @parent: optional parent device providing the counters 296 * @ops: callbacks from driver 297 * @signals: array of Signals 298 * @num_signals: number of Signals specified in @signals 299 * @counts: array of Counts 300 * @num_counts: number of Counts specified in @counts 301 * @ext: optional array of Counter device extensions 302 * @num_ext: number of Counter device extensions specified in @ext 303 * @priv: optional private data supplied by driver 304 * @dev: internal device structure 305 */ 306 struct counter_device { 307 const char *name; 308 struct device *parent; 309 310 const struct counter_ops *ops; 311 312 struct counter_signal *signals; 313 size_t num_signals; 314 struct counter_count *counts; 315 size_t num_counts; 316 317 struct counter_comp *ext; 318 size_t num_ext; 319 320 void *priv; 321 322 struct device dev; 323 }; 324 325 int counter_register(struct counter_device *const counter); 326 void counter_unregister(struct counter_device *const counter); 327 int devm_counter_register(struct device *dev, 328 struct counter_device *const counter); 329 330 #define COUNTER_COMP_DEVICE_U8(_name, _read, _write) \ 331 { \ 332 .type = COUNTER_COMP_U8, \ 333 .name = (_name), \ 334 .device_u8_read = (_read), \ 335 .device_u8_write = (_write), \ 336 } 337 #define COUNTER_COMP_COUNT_U8(_name, _read, _write) \ 338 { \ 339 .type = COUNTER_COMP_U8, \ 340 .name = (_name), \ 341 .count_u8_read = (_read), \ 342 .count_u8_write = (_write), \ 343 } 344 #define COUNTER_COMP_SIGNAL_U8(_name, _read, _write) \ 345 { \ 346 .type = COUNTER_COMP_U8, \ 347 .name = (_name), \ 348 .signal_u8_read = (_read), \ 349 .signal_u8_write = (_write), \ 350 } 351 352 #define COUNTER_COMP_DEVICE_U64(_name, _read, _write) \ 353 { \ 354 .type = COUNTER_COMP_U64, \ 355 .name = (_name), \ 356 .device_u64_read = (_read), \ 357 .device_u64_write = (_write), \ 358 } 359 #define COUNTER_COMP_COUNT_U64(_name, _read, _write) \ 360 { \ 361 .type = COUNTER_COMP_U64, \ 362 .name = (_name), \ 363 .count_u64_read = (_read), \ 364 .count_u64_write = (_write), \ 365 } 366 #define COUNTER_COMP_SIGNAL_U64(_name, _read, _write) \ 367 { \ 368 .type = COUNTER_COMP_U64, \ 369 .name = (_name), \ 370 .signal_u64_read = (_read), \ 371 .signal_u64_write = (_write), \ 372 } 373 374 #define COUNTER_COMP_DEVICE_BOOL(_name, _read, _write) \ 375 { \ 376 .type = COUNTER_COMP_BOOL, \ 377 .name = (_name), \ 378 .device_u8_read = (_read), \ 379 .device_u8_write = (_write), \ 380 } 381 #define COUNTER_COMP_COUNT_BOOL(_name, _read, _write) \ 382 { \ 383 .type = COUNTER_COMP_BOOL, \ 384 .name = (_name), \ 385 .count_u8_read = (_read), \ 386 .count_u8_write = (_write), \ 387 } 388 #define COUNTER_COMP_SIGNAL_BOOL(_name, _read, _write) \ 389 { \ 390 .type = COUNTER_COMP_BOOL, \ 391 .name = (_name), \ 392 .signal_u8_read = (_read), \ 393 .signal_u8_write = (_write), \ 394 } 395 396 struct counter_available { 397 union { 398 const u32 *enums; 399 const char *const *strs; 400 }; 401 size_t num_items; 402 }; 403 404 #define DEFINE_COUNTER_AVAILABLE(_name, _enums) \ 405 struct counter_available _name = { \ 406 .enums = (_enums), \ 407 .num_items = ARRAY_SIZE(_enums), \ 408 } 409 410 #define DEFINE_COUNTER_ENUM(_name, _strs) \ 411 struct counter_available _name = { \ 412 .strs = (_strs), \ 413 .num_items = ARRAY_SIZE(_strs), \ 414 } 415 416 #define COUNTER_COMP_DEVICE_ENUM(_name, _get, _set, _available) \ 417 { \ 418 .type = COUNTER_COMP_ENUM, \ 419 .name = (_name), \ 420 .device_u32_read = (_get), \ 421 .device_u32_write = (_set), \ 422 .priv = &(_available), \ 423 } 424 #define COUNTER_COMP_COUNT_ENUM(_name, _get, _set, _available) \ 425 { \ 426 .type = COUNTER_COMP_ENUM, \ 427 .name = (_name), \ 428 .count_u32_read = (_get), \ 429 .count_u32_write = (_set), \ 430 .priv = &(_available), \ 431 } 432 #define COUNTER_COMP_SIGNAL_ENUM(_name, _get, _set, _available) \ 433 { \ 434 .type = COUNTER_COMP_ENUM, \ 435 .name = (_name), \ 436 .signal_u32_read = (_get), \ 437 .signal_u32_write = (_set), \ 438 .priv = &(_available), \ 439 } 440 441 #define COUNTER_COMP_CEILING(_read, _write) \ 442 COUNTER_COMP_COUNT_U64("ceiling", _read, _write) 443 444 #define COUNTER_COMP_COUNT_MODE(_read, _write, _available) \ 445 { \ 446 .type = COUNTER_COMP_COUNT_MODE, \ 447 .name = "count_mode", \ 448 .count_u32_read = (_read), \ 449 .count_u32_write = (_write), \ 450 .priv = &(_available), \ 451 } 452 453 #define COUNTER_COMP_DIRECTION(_read) \ 454 { \ 455 .type = COUNTER_COMP_COUNT_DIRECTION, \ 456 .name = "direction", \ 457 .count_u32_read = (_read), \ 458 } 459 460 #define COUNTER_COMP_ENABLE(_read, _write) \ 461 COUNTER_COMP_COUNT_BOOL("enable", _read, _write) 462 463 #define COUNTER_COMP_FLOOR(_read, _write) \ 464 COUNTER_COMP_COUNT_U64("floor", _read, _write) 465 466 #define COUNTER_COMP_PRESET(_read, _write) \ 467 COUNTER_COMP_COUNT_U64("preset", _read, _write) 468 469 #define COUNTER_COMP_PRESET_ENABLE(_read, _write) \ 470 COUNTER_COMP_COUNT_BOOL("preset_enable", _read, _write) 471 472 #endif /* _COUNTER_H_ */ 473