blob: c02ca552c1a0723620c18cea70f55ad42c483496 [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
Greg Kroah-Hartmanf91121b2014-09-11 08:22:06 -070021#include "kernel_ver.h"
22
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -070023/* Function fields */
24#define greybus_function_attr(field) \
25static ssize_t function_##field##_show(struct device *dev, \
26 struct device_attribute *attr, \
27 char *buf) \
28{ \
29 struct greybus_device *gdev = to_greybus_device(dev); \
30 return sprintf(buf, "%d\n", gdev->function.field); \
31} \
32static DEVICE_ATTR_RO(function_##field)
33
34greybus_function_attr(number);
35greybus_function_attr(cport);
36greybus_function_attr(class);
37greybus_function_attr(subclass);
38greybus_function_attr(protocol);
39
40static struct attribute *function_attrs[] = {
41 &dev_attr_function_number.attr,
42 &dev_attr_function_cport.attr,
43 &dev_attr_function_class.attr,
44 &dev_attr_function_subclass.attr,
45 &dev_attr_function_protocol.attr,
46 NULL,
47};
48
49static umode_t function_attrs_are_visible(struct kobject *kobj,
50 struct attribute *a, int n)
51{
52 struct greybus_device *gdev = to_greybus_device(kobj_to_dev(kobj));
53
54 // FIXME - make this a dynamic structure to "know" if it really is here
55 // or not easier?
56 if (gdev->function.number ||
57 gdev->function.cport ||
58 gdev->function.class ||
59 gdev->function.subclass ||
60 gdev->function.protocol)
61 return a->mode;
62 return 0;
63}
64
65static struct attribute_group function_attr_grp = {
66 .attrs = function_attrs,
67 .is_visible = function_attrs_are_visible,
68};
69
70/* Module fields */
71#define greybus_module_attr(field) \
72static ssize_t module_##field##_show(struct device *dev, \
73 struct device_attribute *attr, \
74 char *buf) \
75{ \
76 struct greybus_device *gdev = to_greybus_device(dev); \
77 return sprintf(buf, "%x\n", gdev->module_id.field); \
78} \
79static DEVICE_ATTR_RO(module_##field)
80
81greybus_module_attr(vendor);
82greybus_module_attr(product);
83greybus_module_attr(version);
84
85static ssize_t module_vendor_string_show(struct device *dev,
86 struct device_attribute *attr,
87 char *buf)
88{
89 struct greybus_device *gdev = to_greybus_device(dev);
Greg Kroah-Hartman3be03d42014-09-01 19:10:06 -070090
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -070091 return sprintf(buf, "%s",
92 greybus_string(gdev, gdev->module_id.vendor_stringid));
93}
94static DEVICE_ATTR_RO(module_vendor_string);
95
96static ssize_t module_product_string_show(struct device *dev,
97 struct device_attribute *attr,
98 char *buf)
99{
100 struct greybus_device *gdev = to_greybus_device(dev);
Greg Kroah-Hartman3be03d42014-09-01 19:10:06 -0700101
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -0700102 return sprintf(buf, "%s",
103 greybus_string(gdev, gdev->module_id.product_stringid));
104}
105static DEVICE_ATTR_RO(module_product_string);
106
107static struct attribute *module_attrs[] = {
108 &dev_attr_module_vendor.attr,
109 &dev_attr_module_product.attr,
110 &dev_attr_module_version.attr,
111 &dev_attr_module_vendor_string.attr,
112 &dev_attr_module_product_string.attr,
113 NULL,
114};
115
116static umode_t module_attrs_are_visible(struct kobject *kobj,
117 struct attribute *a, int n)
118{
119 struct greybus_device *gdev = to_greybus_device(kobj_to_dev(kobj));
120
121 if ((a == &dev_attr_module_vendor_string.attr) &&
122 (gdev->module_id.vendor_stringid))
123 return a->mode;
124 if ((a == &dev_attr_module_product_string.attr) &&
125 (gdev->module_id.product_stringid))
126 return a->mode;
127
128 // FIXME - make this a dynamic structure to "know" if it really is here
129 // or not easier?
130 if (gdev->module_id.vendor ||
131 gdev->module_id.product ||
132 gdev->module_id.version)
133 return a->mode;
134 return 0;
135}
136
137static struct attribute_group module_attr_grp = {
138 .attrs = module_attrs,
139 .is_visible = module_attrs_are_visible,
140};
141
142
143/* Serial Number */
144static ssize_t serial_number_show(struct device *dev,
145 struct device_attribute *attr, char *buf)
146{
147 struct greybus_device *gdev = to_greybus_device(dev);
Greg Kroah-Hartman3be03d42014-09-01 19:10:06 -0700148
Greg Kroah-Hartman06340ef2014-09-01 19:05:54 -0700149 return sprintf(buf, "%llX\n",
150 (unsigned long long)gdev->serial_number.serial_number);
151}
152static DEVICE_ATTR_RO(serial_number);
153
154static struct attribute *serial_number_attrs[] = {
155 &dev_attr_serial_number.attr,
156 NULL,
157};
158
159static struct attribute_group serial_number_attr_grp = {
160 .attrs = serial_number_attrs,
161 .is_visible = function_attrs_are_visible,
162};
163
164
165const struct attribute_group *greybus_module_groups[] = {
166 &function_attr_grp,
167 &module_attr_grp,
168 &serial_number_attr_grp,
169 NULL,
170};
171