]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/arm/mach-tegra/board-dalmore-sensors.c
ARM: tegra: dalmore: Fix temperature sensor vdd rail and i2c bus
[linux-2.6.git] / arch / arm / mach-tegra / board-dalmore-sensors.c
1 /*
2  * arch/arm/mach-tegra/board-dalmore-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 <mach/gpio.h>
34 #include "gpio-names.h"
35 #include "board.h"
36 #include <mach/gpio.h>
37 #include <media/imx091.h>
38 #include <media/ov9772.h>
39 #include "board-dalmore.h"
40 #include "cpu-tegra.h"
41 #include <generated/mach-types.h>
42 #include <linux/mpu.h>
43
44 #include <linux/i2c.h>
45 #include <linux/delay.h>
46 #include <linux/regulator/consumer.h>
47 #include <linux/i2c/pca954x.h>
48 #include <linux/i2c/pca953x.h>
49 #include <linux/nct1008.h>
50 #include <linux/gpio.h>
51 #include <linux/therm_est.h>
52
53 #include <mach/fb.h>
54 #include <mach/edp.h>
55 #include <mach/gpio.h>
56 #include <mach/gpio-tegra.h>
57
58 #include "gpio-names.h"
59 #include "board.h"
60 #include "board-dalmore.h"
61 #include "cpu-tegra.h"
62 #include "devices.h"
63 #include "tegra-board-id.h"
64
65 static struct board_info board_info;
66
67 static char *dalmore_cam_reg_name[] = {
68         "vdd_sensor_2v85",      /* 2.85V */
69         "avddio_usb",           /* VDDIO USB CAM */
70         "dvdd_cam",             /* DVDD CAM */
71         "vddio_cam",            /* Tegra CAM_I2C, CAM_MCLK, VDD 1.8V */
72         "avdd_cam1",            /* Analog VDD 2.7V */
73         "avdd_cam2",            /* Analog VDD 2.7V */
74 };
75
76 static struct regulator *dalmore_cam_reg[ARRAY_SIZE(dalmore_cam_reg_name)];
77
78 static struct balanced_throttle tj_throttle = {
79         .throt_tab_size = 10,
80         .throt_tab = {
81                 {      0, 1000 },
82                 { 640000, 1000 },
83                 { 640000, 1000 },
84                 { 640000, 1000 },
85                 { 640000, 1000 },
86                 { 640000, 1000 },
87                 { 760000, 1000 },
88                 { 760000, 1050 },
89                 {1000000, 1050 },
90                 {1000000, 1100 },
91         },
92 };
93
94 static struct nct1008_platform_data dalmore_nct1008_pdata = {
95         .supported_hwrev = true,
96         .ext_range = true,
97         .conv_rate = 0x08,
98         .offset = 80, /* 4 * 20C. Bug 844025 - 1C for device accuracies */
99         .shutdown_ext_limit = 90, /* C */
100         .shutdown_local_limit = 120, /* C */
101
102         /* Thermal Throttling */
103         .passive = {
104                 .create_cdev = (struct thermal_cooling_device *(*)(void *))
105                                 balanced_throttle_register,
106                 .cdev_data = &tj_throttle,
107                 .trip_temp = 80000,
108                 .tc1 = 0,
109                 .tc2 = 1,
110                 .passive_delay = 2000,
111         }
112 };
113
114 static struct i2c_board_info dalmore_i2c4_nct1008_board_info[] = {
115         {
116                 I2C_BOARD_INFO("nct1008", 0x4C),
117                 .platform_data = &dalmore_nct1008_pdata,
118                 .irq = -1,
119         }
120 };
121
122 static int dalmore_imx091_power_on(struct device *dev)
123 {
124         int i;
125         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
126                 if (!dalmore_cam_reg[i]) {
127                         dalmore_cam_reg[i] = regulator_get(dev,
128                                         dalmore_cam_reg_name[i]);
129                         if (WARN_ON(IS_ERR(dalmore_cam_reg[i]))) {
130                                 pr_err("%s: didn't get regulator #%d: %ld\n",
131                                 __func__, i, PTR_ERR(dalmore_cam_reg[i]));
132                                 goto reg_alloc_fail;
133                         }
134                 }
135                 regulator_enable(dalmore_cam_reg[i]);
136         }
137
138         gpio_direction_output(CAM_RSTN, 0);
139         mdelay(10);
140         gpio_direction_output(CAM_AF_PWDN, 1);
141         gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
142         gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
143         gpio_direction_output(CAM_RSTN, 1);
144
145         return 0;
146
147 reg_alloc_fail:
148
149         for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
150                 if (dalmore_cam_reg[i]) {
151                         regulator_put(dalmore_cam_reg[i]);
152                         dalmore_cam_reg[i] = NULL;
153                 }
154         }
155
156         return -ENODEV;
157 }
158
159 static int dalmore_imx091_power_off(struct device *dev)
160 {
161         int i;
162         gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
163
164         for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
165                 if (dalmore_cam_reg[i]) {
166                         regulator_disable(dalmore_cam_reg[i]);
167                         regulator_put(dalmore_cam_reg[i]);
168                         dalmore_cam_reg[i] = NULL;
169                 }
170         }
171
172         return 0;
173 }
174
175 static int dalmore_ov9772_power_on(struct device *dev)
176 {
177         int i;
178         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
179                 if (!dalmore_cam_reg[i]) {
180                         dalmore_cam_reg[i] = regulator_get(dev,
181                                         dalmore_cam_reg_name[i]);
182                         if (WARN_ON(IS_ERR(dalmore_cam_reg[i]))) {
183                                 pr_err("%s: didn't get regulator #%d: %ld\n",
184                                 __func__, i, PTR_ERR(dalmore_cam_reg[i]));
185                                 goto reg_alloc_fail;
186                         }
187                 }
188                 regulator_enable(dalmore_cam_reg[i]);
189         }
190
191         gpio_direction_output(CAM_RSTN, 0);
192         mdelay(10);
193         gpio_direction_output(CAM_AF_PWDN, 1);
194         gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
195         gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
196         gpio_direction_output(CAM_RSTN, 1);
197
198         return 0;
199
200 reg_alloc_fail:
201
202         for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
203                 if (dalmore_cam_reg[i]) {
204                         regulator_put(dalmore_cam_reg[i]);
205                         dalmore_cam_reg[i] = NULL;
206                 }
207         }
208
209         return -ENODEV;
210 }
211
212 static int dalmore_ov9772_power_off(struct device *dev)
213 {
214         int i;
215         gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
216
217         for (i = ARRAY_SIZE(dalmore_cam_reg_name) - 1; i >= 0; i--) {
218                 if (dalmore_cam_reg[i]) {
219                         regulator_disable(dalmore_cam_reg[i]);
220                         regulator_put(dalmore_cam_reg[i]);
221                         dalmore_cam_reg[i] = NULL;
222                 }
223         }
224
225         return 0;
226 }
227
228 static struct nvc_gpio_pdata ov9772_gpio_pdata[] = {
229         { OV9772_GPIO_TYPE_SHTDN, TEGRA_GPIO_PBB5, true, 0, },
230         { OV9772_GPIO_TYPE_PWRDN, TEGRA_GPIO_PBB3, true, 0, },
231 };
232
233 static struct ov9772_platform_data ov9772_pdata = {
234         .num            = 1,
235         .dev_name       = "camera",
236         .gpio_count     = ARRAY_SIZE(ov9772_gpio_pdata),
237         .gpio           = ov9772_gpio_pdata,
238         .power_on       = dalmore_ov9772_power_on,
239         .power_off      = dalmore_ov9772_power_off,
240 };
241
242 struct imx091_platform_data dalmore_imx091_data = {
243         .power_on = dalmore_imx091_power_on,
244         .power_off = dalmore_imx091_power_off,
245 };
246
247 static struct i2c_board_info dalmore_i2c_board_info_e1625[] = {
248         {
249                 I2C_BOARD_INFO("imx091", 0x36),
250                 .platform_data = &dalmore_imx091_data,
251         },
252         {
253                 I2C_BOARD_INFO("ov9772", 0x10),
254                 .platform_data = &ov9772_pdata,
255         },
256 };
257
258 struct dalmore_cam_gpio {
259         int gpio;
260         const char *label;
261         int value;
262 };
263
264 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)                \
265         {                                                       \
266                 .gpio = _gpio,                                  \
267                 .label = _label,                                \
268                 .value = _value,                                \
269         }
270
271 static struct dalmore_cam_gpio dalmore_cam_gpio_data[] = {
272         [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 0),
273         [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 0),
274         [2] = TEGRA_CAMERA_GPIO(CAM_GPIO1, "camera_gpio1", 0),
275         [3] = TEGRA_CAMERA_GPIO(CAM_GPIO2, "camera_gpio2", 0),
276         [4] = TEGRA_CAMERA_GPIO(CAM_RSTN, "camera_rstn", 1),
277         [5] = TEGRA_CAMERA_GPIO(CAM_AF_PWDN, "camera_af_pwdn", 1),
278 };
279
280 static int dalmore_camera_init(void)
281 {
282
283         int ret;
284         int i;
285
286         pr_debug("%s: ++\n", __func__);
287
288         for (i = 0; i < ARRAY_SIZE(dalmore_cam_gpio_data); i++) {
289                 ret = gpio_request(dalmore_cam_gpio_data[i].gpio,
290                                 dalmore_cam_gpio_data[i].label);
291                 if (ret < 0) {
292                         pr_err("%s: gpio_request failed for gpio #%d\n",
293                                 __func__, i);
294                         goto fail_free_gpio;
295                 }
296                 gpio_direction_output(dalmore_cam_gpio_data[i].gpio,
297                                         dalmore_cam_gpio_data[i].value);
298                 gpio_export(dalmore_cam_gpio_data[i].gpio, false);
299         }
300
301         i2c_register_board_info(2, dalmore_i2c_board_info_e1625,
302                 ARRAY_SIZE(dalmore_i2c_board_info_e1625));
303
304 fail_free_gpio:
305
306         while (i--)
307                 gpio_free(dalmore_cam_gpio_data[i].gpio);
308         return ret;
309
310 }
311
312
313 /* MPU board file definition    */
314 static struct mpu_platform_data mpu9150_gyro_data = {
315         .int_config     = 0x10,
316         .level_shifter  = 0,
317         .orientation    = MPU_GYRO_ORIENTATION, /* Located in board_[platformname].h    */
318         .sec_slave_type = SECONDARY_SLAVE_TYPE_COMPASS,
319         .sec_slave_id   = COMPASS_ID_AK8975,
320         .secondary_i2c_addr     = MPU_COMPASS_ADDR,
321         .secondary_read_reg     = 0x06,
322         .secondary_orientation  = MPU_COMPASS_ORIENTATION,
323         .key            = {0x4E, 0xCC, 0x7E, 0xEB, 0xF6, 0x1E, 0x35, 0x22,
324                            0x00, 0x34, 0x0D, 0x65, 0x32, 0xE9, 0x94, 0x89},
325 };
326
327 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)                \
328         {                                                       \
329                 .gpio = _gpio,                                  \
330                 .label = _label,                                \
331                 .value = _value,                                \
332         }
333
334 static struct i2c_board_info dalmore_i2c_board_info_cm3218[] = {
335         {
336                 I2C_BOARD_INFO("cm3218", 0x48),
337         },
338 };
339
340 static struct i2c_board_info __initdata inv_mpu9150_i2c2_board_info[] = {
341         {
342                 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
343                 .platform_data = &mpu9150_gyro_data,
344         },
345 };
346
347 static void mpuirq_init(void)
348 {
349         int ret = 0;
350         unsigned gyro_irq_gpio = MPU_GYRO_IRQ_GPIO;
351         unsigned gyro_bus_num = MPU_GYRO_BUS_NUM;
352         char *gyro_name = MPU_GYRO_NAME;
353
354         pr_info("*** MPU START *** mpuirq_init...\n");
355
356         ret = gpio_request(gyro_irq_gpio, gyro_name);
357
358         if (ret < 0) {
359                 pr_err("%s: gpio_request failed %d\n", __func__, ret);
360                 return;
361         }
362
363         ret = gpio_direction_input(gyro_irq_gpio);
364         if (ret < 0) {
365                 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
366                 gpio_free(gyro_irq_gpio);
367                 return;
368         }
369         pr_info("*** MPU END *** mpuirq_init...\n");
370
371         inv_mpu9150_i2c2_board_info[0].irq = gpio_to_irq(MPU_GYRO_IRQ_GPIO);
372         i2c_register_board_info(gyro_bus_num, inv_mpu9150_i2c2_board_info,
373                 ARRAY_SIZE(inv_mpu9150_i2c2_board_info));
374 }
375
376 static int dalmore_nct1008_init(void)
377 {
378         int nct1008_port = -1;
379         int ret = 0;
380
381 #if defined(CONFIG_ARCH_TEGRA_11x_SOC)
382         if ((board_info.board_id == BOARD_E1611) ||
383             (board_info.board_id == BOARD_E1612) ||
384             (board_info.board_id == BOARD_E1641) ||
385             (board_info.board_id == BOARD_E1613))
386         {
387                 /* per email from Matt 9/10/2012 */
388                 nct1008_port = TEGRA_GPIO_PX6;
389         } else {
390                 nct1008_port = TEGRA_GPIO_PX6;
391                 pr_err("Warning: nct alert_port assumed TEGRA_GPIO_PX6"
392                        " for unknown dalmore board id E%d\n",
393                        board_info.board_id);
394         }
395 #else
396         /* dalmore + AP30 interposer has SPI2_CS0 gpio */
397         nct1008_port = TEGRA_GPIO_PX3;
398 #endif
399
400         if (nct1008_port >= 0) {
401 #ifdef CONFIG_TEGRA_EDP_LIMITS
402                 const struct tegra_edp_limits *cpu_edp_limits;
403                 int cpu_edp_limits_size;
404                 int i;
405
406                 /* edp capping */
407                 tegra_get_cpu_edp_limits(&cpu_edp_limits, &cpu_edp_limits_size);
408
409                 if (cpu_edp_limits_size > MAX_THROT_TABLE_SIZE)
410                         BUG();
411
412                 for (i = 0; i < cpu_edp_limits_size-1; i++) {
413                         dalmore_nct1008_pdata.active[i].create_cdev =
414                                 (struct thermal_cooling_device *(*)(void *))
415                                         edp_cooling_device_create;
416                         dalmore_nct1008_pdata.active[i].cdev_data = (void *)i;
417                         dalmore_nct1008_pdata.active[i].trip_temp =
418                                 cpu_edp_limits[i].temperature * 1000;
419                         dalmore_nct1008_pdata.active[i].hysteresis = 1000;
420                 }
421                 dalmore_nct1008_pdata.active[i].create_cdev = NULL;
422 #endif
423
424                 dalmore_i2c4_nct1008_board_info[0].irq = gpio_to_irq(nct1008_port);
425                 pr_info("%s: dalmore nct1008 irq %d", __func__, dalmore_i2c4_nct1008_board_info[0].irq);
426
427                 ret = gpio_request(nct1008_port, "temp_alert");
428                 if (ret < 0)
429                         return ret;
430
431                 ret = gpio_direction_input(nct1008_port);
432                 if (ret < 0) {
433                         pr_info("%s: calling gpio_free(nct1008_port)", __func__);
434                         gpio_free(nct1008_port);
435                 }
436         }
437
438         /* dalmore has thermal sensor on GEN1-I2C i.e. instance 0 */
439         i2c_register_board_info(0, dalmore_i2c4_nct1008_board_info,
440                 ARRAY_SIZE(dalmore_i2c4_nct1008_board_info));
441
442         return ret;
443 }
444
445 static struct i2c_board_info __initdata bq20z45_pdata[] = {
446         {
447                 I2C_BOARD_INFO("sbs-battery", 0x0B),
448         },
449 };
450
451 #ifdef CONFIG_TEGRA_SKIN_THROTTLE
452 static int tegra_skin_match(struct thermal_zone_device *thz, void *data)
453 {
454         return strcmp((char *)data, thz->type) == 0;
455 }
456
457 static int tegra_skin_get_temp(void *data, long *temp)
458 {
459         struct thermal_zone_device *thz;
460
461         thz = thermal_zone_device_find(data, tegra_skin_match);
462
463         if (!thz || thz->ops->get_temp(thz, temp))
464                 *temp = 25000;
465
466         return 0;
467 }
468
469 static struct therm_est_data skin_data = {
470         .toffset = 9793,
471         .polling_period = 1100,
472         .ndevs = 2,
473         .devs = {
474                         {
475                                 .dev_data = "nct_ext",
476                                 .get_temp = tegra_skin_get_temp,
477                                 .coeffs = {
478                                         2, 1, 1, 1,
479                                         1, 1, 1, 1,
480                                         1, 1, 1, 0,
481                                         1, 1, 0, 0,
482                                         0, 0, -1, -7
483                                 },
484                         },
485                         {
486                                 .dev_data = "nct_int",
487                                 .get_temp = tegra_skin_get_temp,
488                                 .coeffs = {
489                                         -11, -7, -5, -3,
490                                         -3, -2, -1, 0,
491                                         0, 0, 1, 1,
492                                         1, 2, 2, 3,
493                                         4, 6, 11, 18
494                                 },
495                         },
496         },
497         .trip_temp = 43000,
498         .tc1 = 1,
499         .tc2 = 15,
500         .passive_delay = 15000,
501 };
502
503 static struct balanced_throttle skin_throttle = {
504         .throt_tab_size = 6,
505         .throt_tab = {
506                 { 640000, 1200 },
507                 { 640000, 1200 },
508                 { 760000, 1200 },
509                 { 760000, 1200 },
510                 {1000000, 1200 },
511                 {1000000, 1200 },
512         },
513 };
514
515 static int __init dalmore_skin_init(void)
516 {
517         struct thermal_cooling_device *skin_cdev;
518
519         skin_cdev = balanced_throttle_register(&skin_throttle);
520
521         skin_data.cdev = skin_cdev;
522         tegra_skin_therm_est_device.dev.platform_data = &skin_data;
523         platform_device_register(&tegra_skin_therm_est_device);
524
525         return 0;
526 }
527 late_initcall(dalmore_skin_init);
528 #endif
529
530 int __init dalmore_sensors_init(void)
531 {
532         int err;
533
534         tegra_get_board_info(&board_info);
535
536         err = dalmore_nct1008_init();
537         if (err)
538                 return err;
539
540         dalmore_camera_init();
541         mpuirq_init();
542
543         i2c_register_board_info(0, dalmore_i2c_board_info_cm3218,
544                 ARRAY_SIZE(dalmore_i2c_board_info_cm3218));
545
546         i2c_register_board_info(0, bq20z45_pdata,
547                 ARRAY_SIZE(bq20z45_pdata));
548
549         return 0;
550 }