1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * Generic framer profider header file
4  *
5  * Copyright 2023 CS GROUP France
6  *
7  * Author: Herve Codina <herve.codina@bootlin.com>
8  */
9 
10 #ifndef __DRIVERS_PROVIDER_FRAMER_H
11 #define __DRIVERS_PROVIDER_FRAMER_H
12 
13 #include <linux/export.h>
14 #include <linux/framer/framer.h>
15 #include <linux/types.h>
16 
17 #define FRAMER_FLAG_POLL_STATUS  BIT(0)
18 
19 /**
20  * struct framer_ops - set of function pointers for performing framer operations
21  * @init: operation to be performed for initializing the framer
22  * @exit: operation to be performed while exiting
23  * @power_on: powering on the framer
24  * @power_off: powering off the framer
25  * @flags: OR-ed flags (FRAMER_FLAG_*) to ask for core functionality
26  *          - @FRAMER_FLAG_POLL_STATUS:
27  *            Ask the core to perform a polling to get the framer status and
28  *            notify consumers on change.
29  *            The framer should call @framer_notify_status_change() when it
30  *            detects a status change. This is usually done using interrupts.
31  *            If the framer cannot detect this change, it can ask the core for
32  *            a status polling. The core will call @get_status() periodically
33  *            and, on change detected, it will notify the consumer.
34  *            the @get_status()
35  * @owner: the module owner containing the ops
36  */
37 struct framer_ops {
38 	int	(*init)(struct framer *framer);
39 	void	(*exit)(struct framer *framer);
40 	int	(*power_on)(struct framer *framer);
41 	int	(*power_off)(struct framer *framer);
42 
43 	/**
44 	 * @get_status:
45 	 *
46 	 * Optional.
47 	 *
48 	 * Used to get the framer status. framer_init() must have
49 	 * been called on the framer.
50 	 *
51 	 * Returns: 0 if successful, an negative error code otherwise
52 	 */
53 	int	(*get_status)(struct framer *framer, struct framer_status *status);
54 
55 	/**
56 	 * @set_config:
57 	 *
58 	 * Optional.
59 	 *
60 	 * Used to set the framer configuration. framer_init() must have
61 	 * been called on the framer.
62 	 *
63 	 * Returns: 0 if successful, an negative error code otherwise
64 	 */
65 	int	(*set_config)(struct framer *framer, const struct framer_config *config);
66 
67 	/**
68 	 * @get_config:
69 	 *
70 	 * Optional.
71 	 *
72 	 * Used to get the framer configuration. framer_init() must have
73 	 * been called on the framer.
74 	 *
75 	 * Returns: 0 if successful, an negative error code otherwise
76 	 */
77 	int	(*get_config)(struct framer *framer, struct framer_config *config);
78 
79 	u32 flags;
80 	struct module *owner;
81 };
82 
83 /**
84  * struct framer_provider - represents the framer provider
85  * @dev: framer provider device
86  * @children: can be used to override the default (dev->of_node) child node
87  * @owner: the module owner having of_xlate
88  * @list: to maintain a linked list of framer providers
89  * @of_xlate: function pointer to obtain framer instance from framer pointer
90  */
91 struct framer_provider {
92 	struct device		*dev;
93 	struct module		*owner;
94 	struct list_head	list;
95 	struct framer * (*of_xlate)(struct device *dev,
96 				    struct of_phandle_args *args);
97 };
98 
framer_set_drvdata(struct framer * framer,void * data)99 static inline void framer_set_drvdata(struct framer *framer, void *data)
100 {
101 	dev_set_drvdata(&framer->dev, data);
102 }
103 
framer_get_drvdata(struct framer * framer)104 static inline void *framer_get_drvdata(struct framer *framer)
105 {
106 	return dev_get_drvdata(&framer->dev);
107 }
108 
109 #if IS_ENABLED(CONFIG_GENERIC_FRAMER)
110 
111 /* Create and destroy a framer */
112 struct framer *framer_create(struct device *dev, struct device_node *node,
113 			     const struct framer_ops *ops);
114 void framer_destroy(struct framer *framer);
115 
116 /* devm version */
117 struct framer *devm_framer_create(struct device *dev, struct device_node *node,
118 				  const struct framer_ops *ops);
119 
120 struct framer *framer_provider_simple_of_xlate(struct device *dev,
121 					       struct of_phandle_args *args);
122 
123 struct framer_provider *
124 __framer_provider_of_register(struct device *dev, struct module *owner,
125 			      struct framer *(*of_xlate)(struct device *dev,
126 							 struct of_phandle_args *args));
127 
128 void framer_provider_of_unregister(struct framer_provider *framer_provider);
129 
130 struct framer_provider *
131 __devm_framer_provider_of_register(struct device *dev, struct module *owner,
132 				   struct framer *(*of_xlate)(struct device *dev,
133 							      struct of_phandle_args *args));
134 
135 void framer_notify_status_change(struct framer *framer);
136 
137 #else /* IS_ENABLED(CONFIG_GENERIC_FRAMER) */
138 
framer_create(struct device * dev,struct device_node * node,const struct framer_ops * ops)139 static inline struct framer *framer_create(struct device *dev, struct device_node *node,
140 					   const struct framer_ops *ops)
141 {
142 	return ERR_PTR(-ENOSYS);
143 }
144 
framer_destroy(struct framer * framer)145 static inline void framer_destroy(struct framer *framer)
146 {
147 }
148 
149 /* devm version */
devm_framer_create(struct device * dev,struct device_node * node,const struct framer_ops * ops)150 static inline struct framer *devm_framer_create(struct device *dev, struct device_node *node,
151 						const struct framer_ops *ops)
152 {
153 	return ERR_PTR(-ENOSYS);
154 }
155 
framer_provider_simple_of_xlate(struct device * dev,struct of_phandle_args * args)156 static inline struct framer *framer_provider_simple_of_xlate(struct device *dev,
157 							     struct of_phandle_args *args)
158 {
159 	return ERR_PTR(-ENOSYS);
160 }
161 
162 static inline struct framer_provider *
__framer_provider_of_register(struct device * dev,struct module * owner,struct framer * (* of_xlate)(struct device * dev,struct of_phandle_args * args))163 __framer_provider_of_register(struct device *dev, struct module *owner,
164 			      struct framer *(*of_xlate)(struct device *dev,
165 							 struct of_phandle_args *args))
166 {
167 	return ERR_PTR(-ENOSYS);
168 }
169 
framer_provider_of_unregister(struct framer_provider * framer_provider)170 void framer_provider_of_unregister(struct framer_provider *framer_provider)
171 {
172 }
173 
174 static inline struct framer_provider *
__devm_framer_provider_of_register(struct device * dev,struct module * owner,struct framer * (* of_xlate)(struct device * dev,struct of_phandle_args * args))175 __devm_framer_provider_of_register(struct device *dev, struct module *owner,
176 				   struct framer *(*of_xlate)(struct device *dev,
177 							      struct of_phandle_args *args))
178 {
179 	return ERR_PTR(-ENOSYS);
180 }
181 
framer_notify_status_change(struct framer * framer)182 void framer_notify_status_change(struct framer *framer)
183 {
184 }
185 
186 #endif /* IS_ENABLED(CONFIG_GENERIC_FRAMER) */
187 
188 #define framer_provider_of_register(dev, xlate)		\
189 	__framer_provider_of_register((dev), THIS_MODULE, (xlate))
190 
191 #define devm_framer_provider_of_register(dev, xlate)	\
192 	__devm_framer_provider_of_register((dev), THIS_MODULE, (xlate))
193 
194 #endif /* __DRIVERS_PROVIDER_FRAMER_H */
195