1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Fieldbus Device Driver Core
4  *
5  */
6 
7 #ifndef __FIELDBUS_DEV_H
8 #define __FIELDBUS_DEV_H
9 
10 #include <linux/cdev.h>
11 #include <linux/wait.h>
12 
13 enum fieldbus_dev_type {
14 	FIELDBUS_DEV_TYPE_UNKNOWN = 0,
15 	FIELDBUS_DEV_TYPE_PROFINET,
16 };
17 
18 enum fieldbus_dev_offl_mode {
19 	FIELDBUS_DEV_OFFL_MODE_CLEAR = 0,
20 	FIELDBUS_DEV_OFFL_MODE_FREEZE,
21 	FIELDBUS_DEV_OFFL_MODE_SET
22 };
23 
24 /**
25  * struct fieldbus_dev - Fieldbus device
26  * @read_area:		[DRIVER] function to read the process data area of the
27  *				 device. same parameters/return values as
28  *				 the read function in struct file_operations
29  * @write_area:		[DRIVER] function to write to the process data area of
30  *				 the device. same parameters/return values as
31  *				 the write function in struct file_operations
32  * @write_area_sz	[DRIVER] size of the writable process data area
33  * @read_area_sz	[DRIVER] size of the readable process data area
34  * @card_name		[DRIVER] name of the card, e.g. "ACME Inc. profinet"
35  * @fieldbus_type	[DRIVER] fieldbus type of this device, e.g.
36  *					FIELDBUS_DEV_TYPE_PROFINET
37  * @enable_get		[DRIVER] function which returns true if the card
38  *				 is enabled, false otherwise
39  * @fieldbus_id_get	[DRIVER] function to retrieve the unique fieldbus id
40  *				 by which this device can be identified;
41  *				 return value follows the snprintf convention
42  * @simple_enable_set	[DRIVER] (optional) function to enable the device
43  *				 according to its default settings
44  * @parent		[DRIVER] (optional) the device's parent device
45  */
46 struct fieldbus_dev {
47 	ssize_t (*read_area)(struct fieldbus_dev *fbdev, char __user *buf,
48 			     size_t size, loff_t *offset);
49 	ssize_t (*write_area)(struct fieldbus_dev *fbdev,
50 			      const char __user *buf, size_t size,
51 			      loff_t *offset);
52 	size_t write_area_sz, read_area_sz;
53 	const char *card_name;
54 	enum fieldbus_dev_type fieldbus_type;
55 	bool (*enable_get)(struct fieldbus_dev *fbdev);
56 	int (*fieldbus_id_get)(struct fieldbus_dev *fbdev, char *buf,
57 			       size_t max_size);
58 	int (*simple_enable_set)(struct fieldbus_dev *fbdev, bool enable);
59 	struct device *parent;
60 
61 	/* private data */
62 	int id;
63 	struct cdev cdev;
64 	struct device *dev;
65 	int dc_event;
66 	wait_queue_head_t dc_wq;
67 	bool online;
68 };
69 
70 #if IS_ENABLED(CONFIG_FIELDBUS_DEV)
71 
72 /**
73  * fieldbus_dev_unregister()
74  *	- unregister a previously registered fieldbus device
75  * @fb:		Device structure previously registered
76  **/
77 void fieldbus_dev_unregister(struct fieldbus_dev *fb);
78 
79 /**
80  * fieldbus_dev_register()
81  *	- register a device with the fieldbus device subsystem
82  * @fb:		Device structure filled by the device driver
83  **/
84 int __must_check fieldbus_dev_register(struct fieldbus_dev *fb);
85 
86 /**
87  * fieldbus_dev_area_updated()
88  *	- notify the subsystem that an external fieldbus controller updated
89  *			the process data area
90  * @fb:		Device structure
91  **/
92 void fieldbus_dev_area_updated(struct fieldbus_dev *fb);
93 
94 /**
95  * fieldbus_dev_online_changed()
96  *	- notify the subsystem that the fieldbus online status changed
97  * @fb:		Device structure
98  **/
99 void fieldbus_dev_online_changed(struct fieldbus_dev *fb, bool online);
100 
101 #else /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */
102 
fieldbus_dev_unregister(struct fieldbus_dev * fb)103 static inline void fieldbus_dev_unregister(struct fieldbus_dev *fb) {}
fieldbus_dev_register(struct fieldbus_dev * fb)104 static inline int __must_check fieldbus_dev_register(struct fieldbus_dev *fb)
105 {
106 	return -ENOTSUPP;
107 }
108 
fieldbus_dev_area_updated(struct fieldbus_dev * fb)109 static inline void fieldbus_dev_area_updated(struct fieldbus_dev *fb) {}
fieldbus_dev_online_changed(struct fieldbus_dev * fb,bool online)110 static inline void fieldbus_dev_online_changed(struct fieldbus_dev *fb,
111 					       bool online) {}
112 
113 #endif /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */
114 #endif /* __FIELDBUS_DEV_H */
115