| /* SPDX-License-Identifier: GPL-2.0-or-later */ | |
| /* | |
| * Generic framer profider header file | |
| * | |
| * Copyright 2023 CS GROUP France | |
| * | |
| * Author: Herve Codina <herve.codina@bootlin.com> | |
| */ | |
| #ifndef __DRIVERS_PROVIDER_FRAMER_H | |
| #define __DRIVERS_PROVIDER_FRAMER_H | |
| #include <linux/export.h> | |
| #include <linux/framer/framer.h> | |
| #include <linux/types.h> | |
| #define FRAMER_FLAG_POLL_STATUS BIT(0) | |
| /** | |
| * struct framer_ops - set of function pointers for performing framer operations | |
| * @init: operation to be performed for initializing the framer | |
| * @exit: operation to be performed while exiting | |
| * @power_on: powering on the framer | |
| * @power_off: powering off the framer | |
| * @flags: OR-ed flags (FRAMER_FLAG_*) to ask for core functionality | |
| * - @FRAMER_FLAG_POLL_STATUS: | |
| * Ask the core to perform a polling to get the framer status and | |
| * notify consumers on change. | |
| * The framer should call @framer_notify_status_change() when it | |
| * detects a status change. This is usually done using interrupts. | |
| * If the framer cannot detect this change, it can ask the core for | |
| * a status polling. The core will call @get_status() periodically | |
| * and, on change detected, it will notify the consumer. | |
| * the @get_status() | |
| * @owner: the module owner containing the ops | |
| */ | |
| struct framer_ops { | |
| int (*init)(struct framer *framer); | |
| void (*exit)(struct framer *framer); | |
| int (*power_on)(struct framer *framer); | |
| int (*power_off)(struct framer *framer); | |
| /** | |
| * @get_status: | |
| * | |
| * Optional. | |
| * | |
| * Used to get the framer status. framer_init() must have | |
| * been called on the framer. | |
| * | |
| * Returns: 0 if successful, an negative error code otherwise | |
| */ | |
| int (*get_status)(struct framer *framer, struct framer_status *status); | |
| /** | |
| * @set_config: | |
| * | |
| * Optional. | |
| * | |
| * Used to set the framer configuration. framer_init() must have | |
| * been called on the framer. | |
| * | |
| * Returns: 0 if successful, an negative error code otherwise | |
| */ | |
| int (*set_config)(struct framer *framer, const struct framer_config *config); | |
| /** | |
| * @get_config: | |
| * | |
| * Optional. | |
| * | |
| * Used to get the framer configuration. framer_init() must have | |
| * been called on the framer. | |
| * | |
| * Returns: 0 if successful, an negative error code otherwise | |
| */ | |
| int (*get_config)(struct framer *framer, struct framer_config *config); | |
| u32 flags; | |
| struct module *owner; | |
| }; | |
| /** | |
| * struct framer_provider - represents the framer provider | |
| * @dev: framer provider device | |
| * @owner: the module owner having of_xlate | |
| * @list: to maintain a linked list of framer providers | |
| * @of_xlate: function pointer to obtain framer instance from framer pointer | |
| */ | |
| struct framer_provider { | |
| struct device *dev; | |
| struct module *owner; | |
| struct list_head list; | |
| struct framer * (*of_xlate)(struct device *dev, | |
| const struct of_phandle_args *args); | |
| }; | |
| static inline void framer_set_drvdata(struct framer *framer, void *data) | |
| { | |
| dev_set_drvdata(&framer->dev, data); | |
| } | |
| static inline void *framer_get_drvdata(struct framer *framer) | |
| { | |
| return dev_get_drvdata(&framer->dev); | |
| } | |
| #if IS_ENABLED(CONFIG_GENERIC_FRAMER) | |
| /* Create and destroy a framer */ | |
| struct framer *framer_create(struct device *dev, struct device_node *node, | |
| const struct framer_ops *ops); | |
| void framer_destroy(struct framer *framer); | |
| /* devm version */ | |
| struct framer *devm_framer_create(struct device *dev, struct device_node *node, | |
| const struct framer_ops *ops); | |
| struct framer *framer_provider_simple_of_xlate(struct device *dev, | |
| const struct of_phandle_args *args); | |
| struct framer_provider * | |
| __framer_provider_of_register(struct device *dev, struct module *owner, | |
| struct framer *(*of_xlate)(struct device *dev, | |
| const struct of_phandle_args *args)); | |
| void framer_provider_of_unregister(struct framer_provider *framer_provider); | |
| struct framer_provider * | |
| __devm_framer_provider_of_register(struct device *dev, struct module *owner, | |
| struct framer *(*of_xlate)(struct device *dev, | |
| const struct of_phandle_args *args)); | |
| void framer_notify_status_change(struct framer *framer); | |
| #else /* IS_ENABLED(CONFIG_GENERIC_FRAMER) */ | |
| static inline struct framer *framer_create(struct device *dev, struct device_node *node, | |
| const struct framer_ops *ops) | |
| { | |
| return ERR_PTR(-ENOSYS); | |
| } | |
| static inline void framer_destroy(struct framer *framer) | |
| { | |
| } | |
| /* devm version */ | |
| static inline struct framer *devm_framer_create(struct device *dev, struct device_node *node, | |
| const struct framer_ops *ops) | |
| { | |
| return ERR_PTR(-ENOSYS); | |
| } | |
| static inline struct framer *framer_provider_simple_of_xlate(struct device *dev, | |
| const struct of_phandle_args *args) | |
| { | |
| return ERR_PTR(-ENOSYS); | |
| } | |
| static inline struct framer_provider * | |
| __framer_provider_of_register(struct device *dev, struct module *owner, | |
| struct framer *(*of_xlate)(struct device *dev, | |
| const struct of_phandle_args *args)) | |
| { | |
| return ERR_PTR(-ENOSYS); | |
| } | |
| void framer_provider_of_unregister(struct framer_provider *framer_provider) | |
| { | |
| } | |
| static inline struct framer_provider * | |
| __devm_framer_provider_of_register(struct device *dev, struct module *owner, | |
| struct framer *(*of_xlate)(struct device *dev, | |
| const struct of_phandle_args *args)) | |
| { | |
| return ERR_PTR(-ENOSYS); | |
| } | |
| void framer_notify_status_change(struct framer *framer) | |
| { | |
| } | |
| #endif /* IS_ENABLED(CONFIG_GENERIC_FRAMER) */ | |
| #define framer_provider_of_register(dev, xlate) \ | |
| __framer_provider_of_register((dev), THIS_MODULE, (xlate)) | |
| #define devm_framer_provider_of_register(dev, xlate) \ | |
| __devm_framer_provider_of_register((dev), THIS_MODULE, (xlate)) | |
| #endif /* __DRIVERS_PROVIDER_FRAMER_H */ |