arm: tegra: fury: add NCT chip id to /sys
[linux-3.10.git] / arch / arm / mach-tegra / nct_sysfs.c
1 /*
2  * arch/arm/mach-tegra/nct_sysfs.c
3  *
4  * Copyright (c) 2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 #include <linux/kernel.h>
22 #include <linux/errno.h>
23 #include <linux/init.h>
24 #include <linux/io.h>
25 #include <linux/module.h>
26 #include <linux/moduleparam.h>
27 #include <linux/slab.h>
28 #include <linux/vmalloc.h>
29 #include <linux/fcntl.h>
30 #include <linux/fs.h>
31 #include <linux/uaccess.h>
32 #include <linux/crc32.h>
33 #include <linux/kobject.h>
34 #include <linux/sysfs.h>
35
36 #include <mach/nct.h>
37 #include "board.h"
38
39 static struct kobject *nct_kobj;
40 static ssize_t nct_item_show(struct kobject *kobj,
41         struct kobj_attribute *attr, char *buf);
42
43
44 static const struct kobj_attribute serial_number_attr =
45         __ATTR(serial_number, 0444, nct_item_show, 0);
46 static const struct kobj_attribute wifi_mac_addr_attr =
47         __ATTR(wifi_mac_addr, 0444, nct_item_show, 0);
48 static const struct kobj_attribute bt_addr_attr =
49         __ATTR(bt_addr, 0444, nct_item_show, 0);
50 static const struct kobj_attribute cm_id_attr =
51         __ATTR(cm_id, 0444, nct_item_show, 0);
52 static const struct kobj_attribute lbh_id_attr =
53         __ATTR(lbh_id, 0444, nct_item_show, 0);
54 static const struct kobj_attribute gps_id_attr =
55         __ATTR(gps_id, 0444, nct_item_show, 0);
56 static const struct kobj_attribute lcd_id_attr =
57         __ATTR(lcd_id, 0444, nct_item_show, 0);
58 static const struct kobj_attribute accelerometer_id_attr =
59         __ATTR(accelerometer_id, 0444, nct_item_show, 0);
60 static const struct kobj_attribute compass_id_attr =
61         __ATTR(compass_id, 0444, nct_item_show, 0);
62 static const struct kobj_attribute gyroscope_id_attr =
63         __ATTR(gyroscope_id, 0444, nct_item_show, 0);
64 static const struct kobj_attribute light_id_attr =
65         __ATTR(light_id, 0444, nct_item_show, 0);
66 static const struct kobj_attribute charger_id_attr =
67         __ATTR(charger_id, 0444, nct_item_show, 0);
68 static const struct kobj_attribute touch_id_attr =
69         __ATTR(touch_id, 0444, nct_item_show, 0);
70
71 static const struct attribute *nct_item_attrs[] = {
72         &serial_number_attr.attr,
73         &wifi_mac_addr_attr.attr,
74         &bt_addr_attr.attr,
75         &cm_id_attr.attr,
76         &lbh_id_attr.attr,
77         &gps_id_attr.attr,
78         &lcd_id_attr.attr,
79         &accelerometer_id_attr.attr,
80         &compass_id_attr.attr,
81         &gyroscope_id_attr.attr,
82         &light_id_attr.attr,
83         &charger_id_attr.attr,
84         &touch_id_attr.attr,
85         NULL
86 };
87
88 static ssize_t nct_item_show(struct kobject *kobj,
89         struct kobj_attribute *attr, char *buf)
90 {
91         ssize_t rval = 0;
92         union nct_item_type item;
93         int err;
94
95         if (attr == &serial_number_attr) {
96                 err = tegra_nct_read_item(NCT_ID_SERIAL_NUMBER, &item);
97                 if (err < 0)
98                         return 0;
99                 rval = sprintf(buf, "%s\n", item.serial_number.sn);
100         } else if (attr == &wifi_mac_addr_attr) {
101                 err = tegra_nct_read_item(NCT_ID_WIFI_MAC_ADDR, &item);
102                 if (err < 0)
103                         return 0;
104                 rval = sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
105                         item.wifi_mac_addr.addr[0],
106                         item.wifi_mac_addr.addr[1],
107                         item.wifi_mac_addr.addr[2],
108                         item.wifi_mac_addr.addr[3],
109                         item.wifi_mac_addr.addr[4],
110                         item.wifi_mac_addr.addr[5]);
111         } else if (attr == &bt_addr_attr) {
112                 err = tegra_nct_read_item(NCT_ID_BT_ADDR, &item);
113                 if (err < 0)
114                         return 0;
115                 rval = sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
116                         item.bt_addr.addr[0],
117                         item.bt_addr.addr[1],
118                         item.bt_addr.addr[2],
119                         item.bt_addr.addr[3],
120                         item.bt_addr.addr[4],
121                         item.bt_addr.addr[5]);
122         } else if (attr == &cm_id_attr) {
123                 err = tegra_nct_read_item(NCT_ID_CM_ID, &item);
124                 if (err < 0)
125                         return 0;
126                 rval = sprintf(buf, "%04d\n", item.cm_id.id);
127         } else if (attr == &lbh_id_attr) {
128                 err = tegra_nct_read_item(NCT_ID_LBH_ID, &item);
129                 if (err < 0)
130                         return 0;
131                 rval = sprintf(buf, "%04d\n", item.lbh_id.id);
132         } else if (attr == &gps_id_attr) {
133                 err = tegra_nct_read_item(NCT_ID_GPS_ID, &item);
134                 if (err < 0)
135                         return 0;
136                 rval = sprintf(buf, "%04d\n", item.gps_id.id);
137         } else if (attr == &lcd_id_attr) {
138                 err = tegra_nct_read_item(NCT_ID_LCD_ID, &item);
139                 if (err < 0)
140                         return 0;
141                 rval = sprintf(buf, "%04d\n", item.lcd_id.id);
142         } else if (attr == &accelerometer_id_attr) {
143                 err = tegra_nct_read_item(NCT_ID_ACCELEROMETER_ID, &item);
144                 if (err < 0)
145                         return 0;
146                 rval = sprintf(buf, "%04d\n", item.accelerometer_id.id);
147         } else if (attr == &compass_id_attr) {
148                 err = tegra_nct_read_item(NCT_ID_COMPASS_ID, &item);
149                 if (err < 0)
150                         return 0;
151                 rval = sprintf(buf, "%04d\n", item.compass_id.id);
152         } else if (attr == &gyroscope_id_attr) {
153                 err = tegra_nct_read_item(NCT_ID_GYROSCOPE_ID, &item);
154                 if (err < 0)
155                         return 0;
156                 rval = sprintf(buf, "%04d\n", item.gyroscope_id.id);
157         } else if (attr == &light_id_attr) {
158                 err = tegra_nct_read_item(NCT_ID_LIGHT_ID, &item);
159                 if (err < 0)
160                         return 0;
161                 rval = sprintf(buf, "%04d\n", item.light_id.id);
162         } else if (attr == &charger_id_attr) {
163                 err = tegra_nct_read_item(NCT_ID_CHARGER_ID, &item);
164                 if (err < 0)
165                         return 0;
166                 rval = sprintf(buf, "%04d\n", item.charger_id.id);
167         } else if (attr == &touch_id_attr) {
168                 err = tegra_nct_read_item(NCT_ID_TOUCH_ID, &item);
169                 if (err < 0)
170                         return 0;
171                 rval = sprintf(buf, "%04d\n", item.touch_id.id);
172         }
173
174         return rval;
175 }
176
177 static int __init tegra_nct_sysfs_init(void)
178 {
179         if (!tegra_nct_is_init()) {
180                 pr_err("tegra_nct: not initialized\n");
181                 return 0;
182         }
183
184         nct_kobj = kobject_create_and_add("tegra_nct", kernel_kobj);
185         if (!nct_kobj) {
186                 pr_err("tegra_nct: failed to create sysfs nct object\n");
187                 return 0;
188         }
189
190         if (sysfs_create_files(nct_kobj, nct_item_attrs)) {
191                 pr_err("%s: failed to create nct item sysfs files\n", __func__);
192                 kobject_del(nct_kobj);
193                 nct_kobj = 0;
194         }
195
196         return 0;
197 }
198
199 late_initcall(tegra_nct_sysfs_init);