dect
/
linux-2.6
Archived
13
0
Fork 0
This repository has been archived on 2022-02-17. You can view files and clone it, but cannot push or open issues or pull requests.
linux-2.6/drivers/dect/vtrx/vtrx-sysfs.c

231 lines
5.5 KiB
C

/*
* DECT virtual transceiver
*
* Copyright (c) 2010 Patrick McHardy <kaber@trash.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/stat.h>
#include <linux/export.h>
#include <net/dect/transceiver.h>
#include "vtrx.h"
static struct class *dect_class;
/*
* Transceivers
*/
#define VTRX_ATTR(_name, _mode, _show, _store) \
struct device_attribute vtrx_attr_##_name = __ATTR(_name, _mode, _show, _store)
#define VTRX_NUMERIC_ATTR(name, field, scale) \
static ssize_t vtrx_show_##name(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct dect_vtrx *vtrx = dev_get_drvdata(dev); \
return sprintf(buf, "%llu\n", \
(unsigned long long)div64_u64(vtrx->field, scale)); \
} \
\
static ssize_t vtrx_store_##name(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct dect_vtrx *vtrx = dev_get_drvdata(dev); \
char *ptr; \
u32 val; \
\
val = simple_strtoul(buf, &ptr, 10); \
if (ptr == buf) \
return -EINVAL; \
vtrx->field = val * scale; \
return count; \
} \
static VTRX_ATTR(name, S_IRUGO | S_IWUSR, vtrx_show_##name, vtrx_store_##name)
VTRX_NUMERIC_ATTR(tx_power, tx_power, DECT_VTRX_POWER_SCALE);
VTRX_NUMERIC_ATTR(pos_x, pos_x, 1000);
VTRX_NUMERIC_ATTR(pos_y, pos_y, 1000);
static ssize_t vtrx_store_remove(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dect_vtrx *vtrx = dev_get_drvdata(dev);
dect_vtrx_free(vtrx);
return count;
}
static VTRX_ATTR(remove, S_IWUSR, NULL, vtrx_store_remove);
static struct attribute *vtrx_attrs[] = {
&vtrx_attr_tx_power.attr,
&vtrx_attr_pos_x.attr,
&vtrx_attr_pos_y.attr,
&vtrx_attr_remove.attr,
NULL
};
static struct attribute_group vtrx_attr_group = {
.attrs = vtrx_attrs,
};
static const struct attribute_group *vtrx_attr_groups[] = {
&vtrx_attr_group,
NULL,
};
static void dect_vtrx_release(struct device *dev)
{
printk("%s\n", __func__);
}
static struct device_type dect_vtrx_group = {
.name = "vtrx",
.groups = vtrx_attr_groups,
.release = dect_vtrx_release,
};
int dect_vtrx_register_sysfs(struct dect_vtrx *vtrx)
{
struct device *dev = &vtrx->dev;
dev->type = &dect_vtrx_group;
dev->class = dect_class;
dev->parent = &vtrx->group->dev;
dev_set_name(dev, "%s", vtrx->trx->name);
dev_set_drvdata(dev, vtrx);
return device_register(dev);
}
void dect_vtrx_unregister_sysfs(struct dect_vtrx *vtrx)
{
device_del(&vtrx->dev);
}
/*
* Groups
*/
#define GROUP_ATTR(_name, _mode, _show, _store) \
struct device_attribute group_attr_##_name = __ATTR(_name, _mode, _show, _store)
#define GROUP_SHOW(name, field, fmt) \
static ssize_t group_show_##name(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct dect_vtrx_group *group = dev_get_drvdata(dev); \
return sprintf(buf, fmt, group->field); \
} \
\
static ssize_t group_store_##name(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct dect_vtrx_group *group = dev_get_drvdata(dev); \
char *ptr; \
u32 val; \
\
val = simple_strtoul(buf, &ptr, 10); \
if (ptr == buf) \
return -EINVAL; \
group->field = val; \
return count; \
} \
static GROUP_ATTR(name, S_IRUGO | S_IWUSR, group_show_##name, group_store_##name)
static ssize_t group_store_new(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct dect_vtrx_group *group = dev_get_drvdata(dev);
int err;
err = dect_vtrx_init(group);
return err ? err : count;
}
static GROUP_ATTR(new_trx, S_IWUSR, NULL, group_store_new);
static struct attribute *group_attrs[] = {
&group_attr_new_trx.attr,
NULL
};
static struct attribute_group group_attr_group = {
.attrs = group_attrs,
};
static const struct attribute_group *group_attr_groups[] = {
&group_attr_group,
NULL,
};
static void dect_vtrx_group_release(struct device *dev)
{
printk("%s\n", __func__);
}
static struct device_type dect_vtrx_group_group = {
.name = "vtrx-group",
.groups = group_attr_groups,
.release = dect_vtrx_group_release,
};
int dect_vtrx_group_register_sysfs(struct dect_vtrx_group *group)
{
struct device *dev = &group->dev;
dev->type = &dect_vtrx_group_group;
dev->class = dect_class;
dev->parent = NULL;
dev_set_name(dev, "%s", group->name);
dev_set_drvdata(dev, group);
return device_register(dev);
}
static ssize_t store_new_group(struct class *dev, struct class_attribute *attr,
const char *buf, size_t count)
{
char name[16];
sscanf(buf, "%16s", name);
if (!dect_vtrx_group_init(name))
return -ENOMEM;
return count;
}
static CLASS_ATTR(new_group, S_IWUSR, NULL, store_new_group);
void dect_vtrx_group_unregister_sysfs(struct dect_vtrx_group *group)
{
device_del(&group->dev);
}
int dect_vtrx_sysfs_init(void)
{
int err;
dect_class = class_create(THIS_MODULE, "dect");
if (dect_class == NULL)
return -ENOMEM;
err = class_create_file(dect_class, &class_attr_new_group);
if (err < 0)
class_destroy(dect_class);
return err;
}
void dect_vtrx_sysfs_exit(void)
{
class_remove_file(dect_class, &class_attr_new_group);
class_destroy(dect_class);
}