ARM: tegra: Use new nct interface for cdev bind
[linux-3.10.git] / arch / arm / mach-tegra / board-roth-sensors.c
1 /*
2  * arch/arm/mach-tegra/board-roth-sensors.c
3  *
4  * Copyright (c) 2012 NVIDIA CORPORATION, All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *
10  * Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  *
17  * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18  * may be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  * This software is licensed under the terms of the GNU General Public
22  * License version 2, as published by the Free Software Foundation, and
23  * may be copied, distributed, and modified under those terms.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU General Public License for more details.
29  */
30
31 #include <linux/i2c.h>
32 #include <linux/delay.h>
33 #include <linux/mpu.h>
34 #include <linux/gpio.h>
35 #include <linux/therm_est.h>
36 #include <linux/nct1008.h>
37 #include <mach/edp.h>
38 #include <mach/gpio-tegra.h>
39 #include <mach/pinmux-t11.h>
40 #include <mach/pinmux.h>
41 #include <generated/mach-types.h>
42
43 #include "gpio-names.h"
44 #include "board.h"
45 #include "board-roth.h"
46 #include "cpu-tegra.h"
47 #include "devices.h"
48 #include "tegra-board-id.h"
49
50 static struct board_info board_info;
51
52 static struct balanced_throttle tj_throttle = {
53         .throt_tab_size = 19,
54         .throt_tab = {
55                 {      0, 1000 },
56                 {  51000, 1000 },
57                 { 102000, 1000 },
58                 { 204000, 1000 },
59                 { 252000, 1000 },
60                 { 288000, 1000 },
61                 { 372000, 1000 },
62                 { 468000, 1000 },
63                 { 510000, 1000 },
64                 { 612000, 1000 },
65                 { 714000, 1050 },
66                 { 816000, 1050 },
67                 { 918000, 1050 },
68                 {1020000, 1100 },
69                 {1122000, 1100 },
70                 {1224000, 1100 },
71                 {1326000, 1100 },
72                 {1428000, 1100 },
73                 {1530000, 1100 },
74         },
75 };
76
77 static int __init roth_throttle_init(void)
78 {
79         if (machine_is_roth())
80                 balanced_throttle_register(&tj_throttle, "roth-nct");
81         return 0;
82 }
83 module_init(roth_throttle_init);
84
85 static struct nct1008_platform_data roth_nct1008_pdata = {
86         .supported_hwrev = true,
87         .ext_range = true,
88         .conv_rate = 0x08,
89         .offset = 80, /* 4 * 20C. Bug 844025 - 1C for device accuracies */
90         .shutdown_ext_limit = 90, /* C */
91         .shutdown_local_limit = 120, /* C */
92
93         /* Thermal Throttling */
94         .passive = {
95                 .enable = true,
96                 .type = "roth-nct",
97                 .trip_temp = 80000,
98                 .tc1 = 0,
99                 .tc2 = 1,
100                 .passive_delay = 2000,
101         }
102 };
103
104 static struct nct1008_platform_data roth_nct1008_lr_pdata = {
105         .supported_hwrev = true,
106         .ext_range = true,
107         .conv_rate = 0x08,
108         .offset = 0,
109         .shutdown_ext_limit = 90, /* C */
110         .shutdown_local_limit = 120, /* C */
111 };
112
113 static struct i2c_board_info roth_i2c4_nct1008_board_info[] = {
114         {
115                 I2C_BOARD_INFO("nct1008", 0x4C),
116                 .platform_data = &roth_nct1008_pdata,
117                 .irq = -1,
118         }
119 };
120
121 static struct i2c_board_info roth_i2c4_nct1008_lr_board_info[] = {
122         {
123                 I2C_BOARD_INFO("nct1008", 0x4C),
124                 .platform_data = &roth_nct1008_lr_pdata,
125                 .irq = -1,
126         },
127         {
128                 I2C_BOARD_INFO("nct1008", 0x4D),
129                 .platform_data = &roth_nct1008_lr_pdata,
130                 .irq = -1,
131         }
132 };
133
134 #define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
135         {                                                       \
136                 .pingroup       = TEGRA_PINGROUP_##_pingroup,   \
137                 .func           = TEGRA_MUX_##_mux,             \
138                 .pupd           = TEGRA_PUPD_##_pupd,           \
139                 .tristate       = TEGRA_TRI_##_tri,             \
140                 .io             = TEGRA_PIN_##_io,              \
141                 .lock           = TEGRA_PIN_LOCK_##_lock,       \
142                 .od             = TEGRA_PIN_OD_DEFAULT,         \
143                 .ioreset        = TEGRA_PIN_IO_RESET_##_ioreset \
144         }
145
146 /* MPU board file definition    */
147 static struct mpu_platform_data mpu6050_gyro_data = {
148         .int_config     = 0x10,
149         .level_shifter  = 0,
150         /* Located in board_[platformname].h */
151         .orientation    = MPU_GYRO_ORIENTATION,
152         .sec_slave_type = SECONDARY_SLAVE_TYPE_NONE,
153         .key            = {0x4E, 0xCC, 0x7E, 0xEB, 0xF6, 0x1E, 0x35, 0x22,
154                            0x00, 0x34, 0x0D, 0x65, 0x32, 0xE9, 0x94, 0x89},
155 };
156
157 static struct i2c_board_info __initdata inv_mpu6050_i2c2_board_info[] = {
158         {
159                 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
160                 .platform_data = &mpu6050_gyro_data,
161         },
162 };
163
164 static void mpuirq_init(void)
165 {
166         int ret = 0;
167         unsigned gyro_irq_gpio = MPU_GYRO_IRQ_GPIO;
168         unsigned gyro_bus_num = MPU_GYRO_BUS_NUM;
169         char *gyro_name = MPU_GYRO_NAME;
170
171         pr_info("*** MPU START *** mpuirq_init...\n");
172
173         ret = gpio_request(gyro_irq_gpio, gyro_name);
174
175         if (ret < 0) {
176                 pr_err("%s: gpio_request failed %d\n", __func__, ret);
177                 return;
178         }
179
180         ret = gpio_direction_input(gyro_irq_gpio);
181         if (ret < 0) {
182                 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
183                 gpio_free(gyro_irq_gpio);
184                 return;
185         }
186         pr_info("*** MPU END *** mpuirq_init...\n");
187
188         inv_mpu6050_i2c2_board_info[0].irq = gpio_to_irq(MPU_GYRO_IRQ_GPIO);
189         i2c_register_board_info(gyro_bus_num, inv_mpu6050_i2c2_board_info,
190                 ARRAY_SIZE(inv_mpu6050_i2c2_board_info));
191 }
192
193 static int roth_nct1008_init(void)
194 {
195         int nct1008_port = TEGRA_GPIO_PX6;
196         int ret = 0;
197
198 #ifdef CONFIG_TEGRA_EDP_LIMITS
199                 const struct tegra_edp_limits *cpu_edp_limits;
200                 struct nct1008_cdev *active_cdev;
201                 int cpu_edp_limits_size;
202                 int i;
203
204                 /* edp capping */
205                 tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
206
207                 if ((cpu_edp_limits_size > MAX_THROT_TABLE_SIZE) ||
208                         (cpu_edp_limits_size > MAX_ACTIVE_TEMP_STATE))
209                         BUG();
210
211                 active_cdev = &roth_nct1008_pdata.active;
212                 active_cdev->enable = true;
213                 active_cdev->type = "edp";
214                 active_cdev->hysteresis = 1000;
215
216                 for (i = 0; i < cpu_edp_limits_size-1; i++) {
217                         active_cdev->states[i].trip_temp =
218                                 cpu_edp_limits[i].temperature * 1000;
219                         active_cdev->states[i].state = i + 1;
220                 }
221 #endif
222
223         roth_i2c4_nct1008_board_info[0].irq = gpio_to_irq(nct1008_port);
224         pr_info("%s: roth nct1008 irq %d", __func__, \
225                                 roth_i2c4_nct1008_board_info[0].irq);
226
227         ret = gpio_request(nct1008_port, "temp_alert");
228         if (ret < 0)
229                 return ret;
230
231         ret = gpio_direction_input(nct1008_port);
232         if (ret < 0) {
233                 pr_info("%s: calling gpio_free(nct1008_port)", __func__);
234                 gpio_free(nct1008_port);
235         }
236
237         /* roth has thermal sensor on GEN1-I2C i.e. instance 0 */
238         i2c_register_board_info(0, roth_i2c4_nct1008_board_info,
239                 ARRAY_SIZE(roth_i2c4_nct1008_board_info));
240
241         i2c_register_board_info(1, roth_i2c4_nct1008_lr_board_info,
242                 ARRAY_SIZE(roth_i2c4_nct1008_lr_board_info));
243         return ret;
244 }
245
246 static struct i2c_board_info __initdata bq20z45_pdata[] = {
247         {
248                 I2C_BOARD_INFO("sbs-battery", 0x0B),
249         },
250 };
251
252 #ifdef CONFIG_TEGRA_SKIN_THROTTLE
253 static int tegra_skin_match(struct thermal_zone_device *thz, void *data)
254 {
255         return strcmp((char *)data, thz->type) == 0;
256 }
257
258 static int tegra_skin_get_temp(void *data, long *temp)
259 {
260         struct thermal_zone_device *thz;
261
262         thz = thermal_zone_device_find(data, tegra_skin_match);
263
264         if (!thz || thz->ops->get_temp(thz, temp))
265                 *temp = 25000;
266
267         return 0;
268 }
269
270 static struct therm_est_data skin_data = {
271         .toffset = 9793,
272         .polling_period = 1100,
273         .ndevs = 2,
274         .devs = {
275                         {
276                                 .dev_data = "nct_ext",
277                                 .get_temp = tegra_skin_get_temp,
278                                 .coeffs = {
279                                         2, 1, 1, 1,
280                                         1, 1, 1, 1,
281                                         1, 1, 1, 0,
282                                         1, 1, 0, 0,
283                                         0, 0, -1, -7
284                                 },
285                         },
286                         {
287                                 .dev_data = "nct_int",
288                                 .get_temp = tegra_skin_get_temp,
289                                 .coeffs = {
290                                         -11, -7, -5, -3,
291                                         -3, -2, -1, 0,
292                                         0, 0, 1, 1,
293                                         1, 2, 2, 3,
294                                         4, 6, 11, 18
295                                 },
296                         },
297         },
298         .trip_temp = 43000,
299         .tc1 = 1,
300         .tc2 = 15,
301         .passive_delay = 15000,
302 };
303
304 static struct balanced_throttle skin_throttle = {
305         .throt_tab_size = 6,
306         .throt_tab = {
307                 { 640000, 1200 },
308                 { 640000, 1200 },
309                 { 760000, 1200 },
310                 { 760000, 1200 },
311                 {1000000, 1200 },
312                 {1000000, 1200 },
313         },
314 };
315
316 static int __init roth_skin_init(void)
317 {
318         struct thermal_cooling_device *skin_cdev;
319
320         skin_cdev = balanced_throttle_register(&skin_throttle, "roth-skin");
321
322         skin_data.cdev = skin_cdev;
323         tegra_skin_therm_est_device.dev.platform_data = &skin_data;
324         platform_device_register(&tegra_skin_therm_est_device);
325
326         return 0;
327 }
328 late_initcall(roth_skin_init);
329 #endif
330
331 int __init roth_sensors_init(void)
332 {
333         int err;
334
335         tegra_get_board_info(&board_info);
336
337         err = roth_nct1008_init();
338         if (err)
339                 return err;
340
341         mpuirq_init();
342
343         if (0)
344                 i2c_register_board_info(0, bq20z45_pdata,
345                         ARRAY_SIZE(bq20z45_pdata));
346
347         return 0;
348 }