ab3f54e78710190e2d870b7aff222437d0ba445a
[linux-2.6.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 = 10,
54         .throt_tab = {
55                 {      0, 1000 },
56                 { 640000, 1000 },
57                 { 640000, 1000 },
58                 { 640000, 1000 },
59                 { 640000, 1000 },
60                 { 640000, 1000 },
61                 { 760000, 1000 },
62                 { 760000, 1050 },
63                 {1000000, 1050 },
64                 {1000000, 1100 },
65         },
66 };
67
68 static struct nct1008_platform_data roth_nct1008_pdata = {
69         .supported_hwrev = true,
70         .ext_range = true,
71         .conv_rate = 0x08,
72         .offset = 80, /* 4 * 20C. Bug 844025 - 1C for device accuracies */
73         .shutdown_ext_limit = 90, /* C */
74         .shutdown_local_limit = 120, /* C */
75
76         /* Thermal Throttling */
77         .passive = {
78                 .create_cdev = (struct thermal_cooling_device *(*)(void *))
79                                 balanced_throttle_register,
80                 .cdev_data = &tj_throttle,
81                 .trip_temp = 80000,
82                 .tc1 = 0,
83                 .tc2 = 1,
84                 .passive_delay = 2000,
85         }
86 };
87
88 static struct i2c_board_info roth_i2c4_nct1008_board_info[] = {
89         {
90                 I2C_BOARD_INFO("nct1008", 0x4C),
91                 .platform_data = &roth_nct1008_pdata,
92                 .irq = -1,
93         }
94 };
95
96 #define VI_PINMUX(_pingroup, _mux, _pupd, _tri, _io, _lock, _ioreset) \
97         {                                                       \
98                 .pingroup       = TEGRA_PINGROUP_##_pingroup,   \
99                 .func           = TEGRA_MUX_##_mux,             \
100                 .pupd           = TEGRA_PUPD_##_pupd,           \
101                 .tristate       = TEGRA_TRI_##_tri,             \
102                 .io             = TEGRA_PIN_##_io,              \
103                 .lock           = TEGRA_PIN_LOCK_##_lock,       \
104                 .od             = TEGRA_PIN_OD_DEFAULT,         \
105                 .ioreset        = TEGRA_PIN_IO_RESET_##_ioreset \
106         }
107
108 /* MPU board file definition    */
109 static struct mpu_platform_data mpu9150_gyro_data = {
110         .int_config     = 0x10,
111         .level_shifter  = 0,
112         /* Located in board_[platformname].h */
113         .orientation    = MPU_GYRO_ORIENTATION,
114         .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS,
115         .sec_slave_id   = COMPASS_ID_AK8975,
116         .secondary_i2c_addr     = MPU_COMPASS_ADDR,
117         .secondary_read_reg     = 0x06,
118         .secondary_orientation  = MPU_COMPASS_ORIENTATION,
119         .key            = {0x4E, 0xCC, 0x7E, 0xEB, 0xF6, 0x1E, 0x35, 0x22,
120                            0x00, 0x34, 0x0D, 0x65, 0x32, 0xE9, 0x94, 0x89},
121 };
122
123 static struct i2c_board_info roth_i2c_board_info_cm3218[] = {
124         {
125                 I2C_BOARD_INFO("cm3218", 0x48),
126         },
127 };
128
129 static struct i2c_board_info __initdata inv_mpu9150_i2c2_board_info[] = {
130         {
131                 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
132                 .platform_data = &mpu9150_gyro_data,
133         },
134 };
135
136 static void mpuirq_init(void)
137 {
138         int ret = 0;
139         unsigned gyro_irq_gpio = MPU_GYRO_IRQ_GPIO;
140         unsigned gyro_bus_num = MPU_GYRO_BUS_NUM;
141         char *gyro_name = MPU_GYRO_NAME;
142
143         pr_info("*** MPU START *** mpuirq_init...\n");
144
145         ret = gpio_request(gyro_irq_gpio, gyro_name);
146
147         if (ret < 0) {
148                 pr_err("%s: gpio_request failed %d\n", __func__, ret);
149                 return;
150         }
151
152         ret = gpio_direction_input(gyro_irq_gpio);
153         if (ret < 0) {
154                 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
155                 gpio_free(gyro_irq_gpio);
156                 return;
157         }
158         pr_info("*** MPU END *** mpuirq_init...\n");
159
160         inv_mpu9150_i2c2_board_info[0].irq = gpio_to_irq(MPU_GYRO_IRQ_GPIO);
161         i2c_register_board_info(gyro_bus_num, inv_mpu9150_i2c2_board_info,
162                 ARRAY_SIZE(inv_mpu9150_i2c2_board_info));
163 }
164
165 static int roth_nct1008_init(void)
166 {
167         int nct1008_port = -1;
168         int ret = 0;
169
170 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
171         if ((board_info.board_id == BOARD_E1611) ||
172             (board_info.board_id == BOARD_E1612) ||
173             (board_info.board_id == BOARD_E1641) ||
174             (board_info.board_id == BOARD_E1613) ||
175             (board_info.board_id == BOARD_P2454))
176         {
177                 /* per email from Matt 9/10/2012 */
178                 nct1008_port = TEGRA_GPIO_PX6;
179         } else {
180                 nct1008_port = TEGRA_GPIO_PX6;
181                 pr_err("Warning: nct alert_port assumed TEGRA_GPIO_PX6"
182                        " for unknown roth board id E%d\n",
183                        board_info.board_id);
184         }
185 #else
186         /* roth + AP30 interposer has SPI2_CS0 gpio */
187         nct1008_port = TEGRA_GPIO_PX3;
188 #endif
189
190         if (nct1008_port >= 0) {
191 #ifdef CONFIG_TEGRA_EDP_LIMITS
192                 const struct tegra_edp_limits *cpu_edp_limits;
193                 int cpu_edp_limits_size;
194                 int i;
195
196                 /* edp capping */
197                 tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
198
199                 if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
200                         BUG();
201
202                 for (i = 0; i < cpu_edp_limits_size-1; i++) {
203                         roth_nct1008_pdata.active[i].create_cdev =
204                                 (struct thermal_cooling_device *(*)(void *))
205                                         edp_cooling_device_create;
206                         roth_nct1008_pdata.active[i].cdev_data = (void *)i;
207                         roth_nct1008_pdata.active[i].trip_temp =
208                                 cpu_edp_limits[i].temperature * 1000;
209                         roth_nct1008_pdata.active[i].hysteresis = 1000;
210                 }
211                 roth_nct1008_pdata.active[i].create_cdev = NULL;
212 #endif
213
214                 roth_i2c4_nct1008_board_info[0].irq = gpio_to_irq(nct1008_port);
215                 pr_info("%s: roth nct1008 irq %d", __func__, roth_i2c4_nct1008_board_info[0].irq);
216
217                 ret = gpio_request(nct1008_port, "temp_alert");
218                 if (ret < 0)
219                         return ret;
220
221                 ret = gpio_direction_input(nct1008_port);
222                 if (ret < 0) {
223                         pr_info("%s: calling gpio_free(nct1008_port)", __func__);
224                         gpio_free(nct1008_port);
225                 }
226         }
227
228         /* roth has thermal sensor on GEN1-I2C i.e. instance 0 */
229         i2c_register_board_info(0, roth_i2c4_nct1008_board_info,
230                 ARRAY_SIZE(roth_i2c4_nct1008_board_info));
231
232         return ret;
233 }
234
235 static struct i2c_board_info __initdata bq20z45_pdata[] = {
236         {
237                 I2C_BOARD_INFO("sbs-battery", 0x0B),
238         },
239 };
240
241 #ifdef CONFIG_TEGRA_SKIN_THROTTLE
242 static int tegra_skin_match(struct thermal_zone_device *thz, void *data)
243 {
244         return strcmp((char *)data, thz->type) == 0;
245 }
246
247 static int tegra_skin_get_temp(void *data, long *temp)
248 {
249         struct thermal_zone_device *thz;
250
251         thz = thermal_zone_device_find(data, tegra_skin_match);
252
253         if (!thz || thz->ops->get_temp(thz, temp))
254                 *temp = 25000;
255
256         return 0;
257 }
258
259 static struct therm_est_data skin_data = {
260         .toffset = 9793,
261         .polling_period = 1100,
262         .ndevs = 2,
263         .devs = {
264                         {
265                                 .dev_data = "nct_ext",
266                                 .get_temp = tegra_skin_get_temp,
267                                 .coeffs = {
268                                         2, 1, 1, 1,
269                                         1, 1, 1, 1,
270                                         1, 1, 1, 0,
271                                         1, 1, 0, 0,
272                                         0, 0, -1, -7
273                                 },
274                         },
275                         {
276                                 .dev_data = "nct_int",
277                                 .get_temp = tegra_skin_get_temp,
278                                 .coeffs = {
279                                         -11, -7, -5, -3,
280                                         -3, -2, -1, 0,
281                                         0, 0, 1, 1,
282                                         1, 2, 2, 3,
283                                         4, 6, 11, 18
284                                 },
285                         },
286         },
287         .trip_temp = 43000,
288         .tc1 = 1,
289         .tc2 = 15,
290         .passive_delay = 15000,
291 };
292
293 static struct balanced_throttle skin_throttle = {
294         .throt_tab_size = 6,
295         .throt_tab = {
296                 { 640000, 1200 },
297                 { 640000, 1200 },
298                 { 760000, 1200 },
299                 { 760000, 1200 },
300                 {1000000, 1200 },
301                 {1000000, 1200 },
302         },
303 };
304
305 static int __init roth_skin_init(void)
306 {
307         struct thermal_cooling_device *skin_cdev;
308
309         skin_cdev = balanced_throttle_register(&skin_throttle);
310
311         skin_data.cdev = skin_cdev;
312         tegra_skin_therm_est_device.dev.platform_data = &skin_data;
313         platform_device_register(&tegra_skin_therm_est_device);
314
315         return 0;
316 }
317 late_initcall(roth_skin_init);
318 #endif
319
320 int __init roth_sensors_init(void)
321 {
322         int err;
323
324         tegra_get_board_info(&board_info);
325
326         err = roth_nct1008_init();
327         if (err)
328                 return err;
329
330         mpuirq_init();
331
332         i2c_register_board_info(0, roth_i2c_board_info_cm3218,
333                 ARRAY_SIZE(roth_i2c_board_info_cm3218));
334
335         i2c_register_board_info(0, bq20z45_pdata,
336                 ARRAY_SIZE(bq20z45_pdata));
337
338         return 0;
339 }