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
13enum fieldbus_dev_type {
14	FIELDBUS_DEV_TYPE_UNKNOWN = 0,
15	FIELDBUS_DEV_TYPE_PROFINET,
16};
17
18enum 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 */
46struct 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 **/
77void 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 **/
84int __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 **/
92void 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 **/
99void fieldbus_dev_online_changed(struct fieldbus_dev *fb, bool online);
100
101#else /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */
102
103static inline void fieldbus_dev_unregister(struct fieldbus_dev *fb) {}
104static inline int __must_check fieldbus_dev_register(struct fieldbus_dev *fb)
105{
106	return -ENOTSUPP;
107}
108
109static inline void fieldbus_dev_area_updated(struct fieldbus_dev *fb) {}
110static 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