blob: 301dca3b8d71a72cd4bd3e47bd036187124b3866 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Fieldbus Device Driver Core
*
*/
#ifndef __FIELDBUS_DEV_H
#define __FIELDBUS_DEV_H
#include <linux/cdev.h>
#include <linux/wait.h>
enum fieldbus_dev_type {
FIELDBUS_DEV_TYPE_UNKNOWN = 0,
FIELDBUS_DEV_TYPE_PROFINET,
};
enum fieldbus_dev_offl_mode {
FIELDBUS_DEV_OFFL_MODE_CLEAR = 0,
FIELDBUS_DEV_OFFL_MODE_FREEZE,
FIELDBUS_DEV_OFFL_MODE_SET
};
/**
* struct fieldbus_dev - Fieldbus device
* @read_area: [DRIVER] function to read the process data area of the
* device. same parameters/return values as
* the read function in struct file_operations
* @write_area: [DRIVER] function to write to the process data area of
* the device. same parameters/return values as
* the write function in struct file_operations
* @write_area_sz [DRIVER] size of the writable process data area
* @read_area_sz [DRIVER] size of the readable process data area
* @card_name [DRIVER] name of the card, e.g. "ACME Inc. profinet"
* @fieldbus_type [DRIVER] fieldbus type of this device, e.g.
* FIELDBUS_DEV_TYPE_PROFINET
* @enable_get [DRIVER] function which returns true if the card
* is enabled, false otherwise
* @fieldbus_id_get [DRIVER] function to retrieve the unique fieldbus id
* by which this device can be identified;
* return value follows the snprintf convention
* @simple_enable_set [DRIVER] (optional) function to enable the device
* according to its default settings
* @parent [DRIVER] (optional) the device's parent device
*/
struct fieldbus_dev {
ssize_t (*read_area)(struct fieldbus_dev *fbdev, char __user *buf,
size_t size, loff_t *offset);
ssize_t (*write_area)(struct fieldbus_dev *fbdev,
const char __user *buf, size_t size,
loff_t *offset);
size_t write_area_sz, read_area_sz;
const char *card_name;
enum fieldbus_dev_type fieldbus_type;
bool (*enable_get)(struct fieldbus_dev *fbdev);
int (*fieldbus_id_get)(struct fieldbus_dev *fbdev, char *buf,
size_t max_size);
int (*simple_enable_set)(struct fieldbus_dev *fbdev, bool enable);
struct device *parent;
/* private data */
int id;
struct cdev cdev;
struct device *dev;
int dc_event;
wait_queue_head_t dc_wq;
bool online;
};
#if IS_ENABLED(CONFIG_FIELDBUS_DEV)
/**
* fieldbus_dev_unregister()
* - unregister a previously registered fieldbus device
* @fb: Device structure previously registered
**/
void fieldbus_dev_unregister(struct fieldbus_dev *fb);
/**
* fieldbus_dev_register()
* - register a device with the fieldbus device subsystem
* @fb: Device structure filled by the device driver
**/
int __must_check fieldbus_dev_register(struct fieldbus_dev *fb);
/**
* fieldbus_dev_area_updated()
* - notify the subsystem that an external fieldbus controller updated
* the process data area
* @fb: Device structure
**/
void fieldbus_dev_area_updated(struct fieldbus_dev *fb);
/**
* fieldbus_dev_online_changed()
* - notify the subsystem that the fieldbus online status changed
* @fb: Device structure
**/
void fieldbus_dev_online_changed(struct fieldbus_dev *fb, bool online);
#else /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */
static inline void fieldbus_dev_unregister(struct fieldbus_dev *fb) {}
static inline int __must_check fieldbus_dev_register(struct fieldbus_dev *fb)
{
return -ENOTSUPP;
}
static inline void fieldbus_dev_area_updated(struct fieldbus_dev *fb) {}
static inline void fieldbus_dev_online_changed(struct fieldbus_dev *fb,
bool online) {}
#endif /* IS_ENABLED(CONFIG_FIELDBUS_DEV) */
#endif /* __FIELDBUS_DEV_H */