ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[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 boardinfo_id_attr =
55         __ATTR(boardinfo_id, 0444, nct_item_show, 0);
56 static const struct kobj_attribute gps_id_attr =
57         __ATTR(gps_id, 0444, nct_item_show, 0);
58 static const struct kobj_attribute lcd_id_attr =
59         __ATTR(lcd_id, 0444, nct_item_show, 0);
60 static const struct kobj_attribute accelerometer_id_attr =
61         __ATTR(accelerometer_id, 0444, nct_item_show, 0);
62 static const struct kobj_attribute compass_id_attr =
63         __ATTR(compass_id, 0444, nct_item_show, 0);
64 static const struct kobj_attribute gyroscope_id_attr =
65         __ATTR(gyroscope_id, 0444, nct_item_show, 0);
66 static const struct kobj_attribute light_id_attr =
67         __ATTR(light_id, 0444, nct_item_show, 0);
68 static const struct kobj_attribute charger_id_attr =
69         __ATTR(charger_id, 0444, nct_item_show, 0);
70 static const struct kobj_attribute touch_id_attr =
71         __ATTR(touch_id, 0444, nct_item_show, 0);
72
73 static const struct attribute *nct_item_attrs[] = {
74         &serial_number_attr.attr,
75         &wifi_mac_addr_attr.attr,
76         &bt_addr_attr.attr,
77         &cm_id_attr.attr,
78         &lbh_id_attr.attr,
79         &boardinfo_id_attr.attr,
80         &gps_id_attr.attr,
81         &lcd_id_attr.attr,
82         &accelerometer_id_attr.attr,
83         &compass_id_attr.attr,
84         &gyroscope_id_attr.attr,
85         &light_id_attr.attr,
86         &charger_id_attr.attr,
87         &touch_id_attr.attr,
88         NULL
89 };
90
91 static ssize_t nct_item_show(struct kobject *kobj,
92         struct kobj_attribute *attr, char *buf)
93 {
94         ssize_t rval = 0;
95         union nct_item_type item;
96         int err;
97
98         if (attr == &serial_number_attr) {
99                 err = tegra_nct_read_item(NCT_ID_SERIAL_NUMBER, &item);
100                 if (err < 0)
101                         return 0;
102                 rval = sprintf(buf, "%s\n", item.serial_number.sn);
103         } else if (attr == &wifi_mac_addr_attr) {
104                 err = tegra_nct_read_item(NCT_ID_WIFI_MAC_ADDR, &item);
105                 if (err < 0)
106                         return 0;
107                 rval = sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
108                         item.wifi_mac_addr.addr[0],
109                         item.wifi_mac_addr.addr[1],
110                         item.wifi_mac_addr.addr[2],
111                         item.wifi_mac_addr.addr[3],
112                         item.wifi_mac_addr.addr[4],
113                         item.wifi_mac_addr.addr[5]);
114         } else if (attr == &bt_addr_attr) {
115                 err = tegra_nct_read_item(NCT_ID_BT_ADDR, &item);
116                 if (err < 0)
117                         return 0;
118                 rval = sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
119                         item.bt_addr.addr[0],
120                         item.bt_addr.addr[1],
121                         item.bt_addr.addr[2],
122                         item.bt_addr.addr[3],
123                         item.bt_addr.addr[4],
124                         item.bt_addr.addr[5]);
125         } else if (attr == &cm_id_attr) {
126                 err = tegra_nct_read_item(NCT_ID_CM_ID, &item);
127                 if (err < 0)
128                         return 0;
129                 rval = sprintf(buf, "%04d\n", item.cm_id.id);
130         } else if (attr == &lbh_id_attr) {
131                 err = tegra_nct_read_item(NCT_ID_LBH_ID, &item);
132                 if (err < 0)
133                         return 0;
134                 rval = sprintf(buf, "%04d\n", item.lbh_id.id);
135         } else if (attr == &boardinfo_id_attr) {
136                 err = tegra_nct_read_item(NCT_ID_BOARD_INFO, &item);
137                 if (err < 0)
138                         return 0;
139                 rval = sprintf(buf,
140                         "Proc: %4u (sku: %u, fab: %u)\n"
141                         "PMU : %4u (sku: %u, fab: %u)\n"
142                         "Disp: %4u (sku: %u, fab: %u)\n",
143                         item.board_info.proc_board_id,
144                         item.board_info.proc_sku,
145                         item.board_info.proc_fab,
146                         item.board_info.pmu_board_id,
147                         item.board_info.pmu_sku,
148                         item.board_info.pmu_fab,
149                         item.board_info.display_board_id,
150                         item.board_info.display_sku,
151                         item.board_info.display_fab);
152         } else if (attr == &gps_id_attr) {
153                 err = tegra_nct_read_item(NCT_ID_GPS_ID, &item);
154                 if (err < 0)
155                         return 0;
156                 rval = sprintf(buf, "%04d\n", item.gps_id.id);
157         } else if (attr == &lcd_id_attr) {
158                 err = tegra_nct_read_item(NCT_ID_LCD_ID, &item);
159                 if (err < 0)
160                         return 0;
161                 rval = sprintf(buf, "%04d\n", item.lcd_id.id);
162         } else if (attr == &accelerometer_id_attr) {
163                 err = tegra_nct_read_item(NCT_ID_ACCELEROMETER_ID, &item);
164                 if (err < 0)
165                         return 0;
166                 rval = sprintf(buf, "%04d\n", item.accelerometer_id.id);
167         } else if (attr == &compass_id_attr) {
168                 err = tegra_nct_read_item(NCT_ID_COMPASS_ID, &item);
169                 if (err < 0)
170                         return 0;
171                 rval = sprintf(buf, "%04d\n", item.compass_id.id);
172         } else if (attr == &gyroscope_id_attr) {
173                 err = tegra_nct_read_item(NCT_ID_GYROSCOPE_ID, &item);
174                 if (err < 0)
175                         return 0;
176                 rval = sprintf(buf, "%04d\n", item.gyroscope_id.id);
177         } else if (attr == &light_id_attr) {
178                 err = tegra_nct_read_item(NCT_ID_LIGHT_ID, &item);
179                 if (err < 0)
180                         return 0;
181                 rval = sprintf(buf, "%04d\n", item.light_id.id);
182         } else if (attr == &charger_id_attr) {
183                 err = tegra_nct_read_item(NCT_ID_CHARGER_ID, &item);
184                 if (err < 0)
185                         return 0;
186                 rval = sprintf(buf, "%04d\n", item.charger_id.id);
187         } else if (attr == &touch_id_attr) {
188                 err = tegra_nct_read_item(NCT_ID_TOUCH_ID, &item);
189                 if (err < 0)
190                         return 0;
191                 rval = sprintf(buf, "%04d\n", item.touch_id.id);
192         }
193
194         return rval;
195 }
196
197 static int __init tegra_nct_sysfs_init(void)
198 {
199         if (!tegra_nct_is_init()) {
200                 pr_err("tegra_nct: not initialized\n");
201                 return 0;
202         }
203
204         nct_kobj = kobject_create_and_add("tegra_nct", kernel_kobj);
205         if (!nct_kobj) {
206                 pr_err("tegra_nct: failed to create sysfs nct object\n");
207                 return 0;
208         }
209
210         if (sysfs_create_files(nct_kobj, nct_item_attrs)) {
211                 pr_err("%s: failed to create nct item sysfs files\n", __func__);
212                 kobject_del(nct_kobj);
213                 nct_kobj = 0;
214         }
215
216         return 0;
217 }
218
219 late_initcall(tegra_nct_sysfs_init);