blob: 2393a6a0b678c430f351e1a403540693fe65b2bc [file] [log] [blame]
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -07001/*
2 * Greybus sysfs file functions
3 *
4 * Copyright 2014 Google Inc.
5 *
6 * Released under the GPLv2 only.
7 */
8
9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/types.h>
12#include <linux/module.h>
13#include <linux/moduleparam.h>
14#include <linux/kernel.h>
15#include <linux/slab.h>
16#include <linux/kthread.h>
17#include <linux/device.h>
18
19#include "greybus.h"
20
21/* Function fields */
22#define greybus_function_attr(field) \
23static ssize_t function_##field##_show(struct device *dev, \
24 struct device_attribute *attr, \
25 char *buf) \
26{ \
27 struct greybus_device *gdev = to_greybus_device(dev); \
28 return sprintf(buf, "%d\n", gdev->function.field); \
29} \
30static DEVICE_ATTR_RO(function_##field)
31
32greybus_function_attr(number);
33greybus_function_attr(cport);
34greybus_function_attr(class);
35greybus_function_attr(subclass);
36greybus_function_attr(protocol);
37
38static struct attribute *function_attrs[] = {
39 &dev_attr_function_number.attr,
40 &dev_attr_function_cport.attr,
41 &dev_attr_function_class.attr,
42 &dev_attr_function_subclass.attr,
43 &dev_attr_function_protocol.attr,
44 NULL,
45};
46
47static umode_t function_attrs_are_visible(struct kobject *kobj,
48 struct attribute *a, int n)
49{
50 struct greybus_device *gdev = to_greybus_device(kobj_to_dev(kobj));
51
52 // FIXME - make this a dynamic structure to "know" if it really is here
53 // or not easier?
54 if (gdev->function.number ||
55 gdev->function.cport ||
56 gdev->function.class ||
57 gdev->function.subclass ||
58 gdev->function.protocol)
59 return a->mode;
60 return 0;
61}
62
63static struct attribute_group function_attr_grp = {
64 .attrs = function_attrs,
65 .is_visible = function_attrs_are_visible,
66};
67
68/* Module fields */
69#define greybus_module_attr(field) \
70static ssize_t module_##field##_show(struct device *dev, \
71 struct device_attribute *attr, \
72 char *buf) \
73{ \
74 struct greybus_device *gdev = to_greybus_device(dev); \
75 return sprintf(buf, "%x\n", gdev->module_id.field); \
76} \
77static DEVICE_ATTR_RO(module_##field)
78
79greybus_module_attr(vendor);
80greybus_module_attr(product);
81greybus_module_attr(version);
82
83static ssize_t module_vendor_string_show(struct device *dev,
84 struct device_attribute *attr,
85 char *buf)
86{
87 struct greybus_device *gdev = to_greybus_device(dev);
Greg Kroah-Hartman3be03d42014-09-01 19:10:06 -070088
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -070089 return sprintf(buf, "%s",
90 greybus_string(gdev, gdev->module_id.vendor_stringid));
91}
92static DEVICE_ATTR_RO(module_vendor_string);
93
94static ssize_t module_product_string_show(struct device *dev,
95 struct device_attribute *attr,
96 char *buf)
97{
98 struct greybus_device *gdev = to_greybus_device(dev);
Greg Kroah-Hartman3be03d42014-09-01 19:10:06 -070099
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -0700100 return sprintf(buf, "%s",
101 greybus_string(gdev, gdev->module_id.product_stringid));
102}
103static DEVICE_ATTR_RO(module_product_string);
104
105static struct attribute *module_attrs[] = {
106 &dev_attr_module_vendor.attr,
107 &dev_attr_module_product.attr,
108 &dev_attr_module_version.attr,
109 &dev_attr_module_vendor_string.attr,
110 &dev_attr_module_product_string.attr,
111 NULL,
112};
113
114static umode_t module_attrs_are_visible(struct kobject *kobj,
115 struct attribute *a, int n)
116{
117 struct greybus_device *gdev = to_greybus_device(kobj_to_dev(kobj));
118
119 if ((a == &dev_attr_module_vendor_string.attr) &&
120 (gdev->module_id.vendor_stringid))
121 return a->mode;
122 if ((a == &dev_attr_module_product_string.attr) &&
123 (gdev->module_id.product_stringid))
124 return a->mode;
125
126 // FIXME - make this a dynamic structure to "know" if it really is here
127 // or not easier?
128 if (gdev->module_id.vendor ||
129 gdev->module_id.product ||
130 gdev->module_id.version)
131 return a->mode;
132 return 0;
133}
134
135static struct attribute_group module_attr_grp = {
136 .attrs = module_attrs,
137 .is_visible = module_attrs_are_visible,
138};
139
140
141/* Serial Number */
142static ssize_t serial_number_show(struct device *dev,
143 struct device_attribute *attr, char *buf)
144{
145 struct greybus_device *gdev = to_greybus_device(dev);
Greg Kroah-Hartman3be03d42014-09-01 19:10:06 -0700146
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -0700147 return sprintf(buf, "%llX\n",
148 (unsigned long long)gdev->serial_number.serial_number);
149}
150static DEVICE_ATTR_RO(serial_number);
151
152static struct attribute *serial_number_attrs[] = {
153 &dev_attr_serial_number.attr,
154 NULL,
155};
156
157static struct attribute_group serial_number_attr_grp = {
158 .attrs = serial_number_attrs,
159 .is_visible = function_attrs_are_visible,
160};
161
162
163const struct attribute_group *greybus_module_groups[] = {
164 &function_attr_grp,
165 &module_attr_grp,
166 &serial_number_attr_grp,
167 NULL,
168};
169