temp revert rk change
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-tegra / board-stingray-sensors.c
1 /*
2  * Copyright (c) 2010, Motorola, All Rights Reserved.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include <linux/delay.h>
20 #include <linux/i2c.h>
21 #include <linux/init.h>
22 #include <linux/input.h>
23 #include <linux/kernel.h>
24 #include <linux/kxtf9.h>
25 #include <linux/l3g4200d.h>
26 #include <linux/led-lm3559.h>
27 #include <linux/max9635.h>
28 #include <linux/moto_bmp085.h>
29 #include <linux/cap_prox.h>
30 #include <media/ov5650.h>
31 #include <media/soc2030.h>
32 #include <linux/platform_device.h>
33 #include <linux/gpio.h>
34
35 #include <linux/regulator/consumer.h>
36 #include <linux/nct1008.h>
37
38 #include "board-stingray.h"
39 #include "gpio-names.h"
40
41 #define KXTF9_IRQ_GPIO          TEGRA_GPIO_PV3
42 #define MAX9635_IRQ_GPIO        TEGRA_GPIO_PV1
43 #define BMP085_IRQ_GPIO         TEGRA_GPIO_PW0
44 #define L3G4200D_DRDY_GPIO      TEGRA_GPIO_PH3
45 #define AKM8975_IRQ_GPIO        TEGRA_GPIO_PQ2
46 #define LM3559_RESETN_GPIO      TEGRA_GPIO_PT4
47 #define OV5650_RESETN_GPIO      TEGRA_GPIO_PD2
48 #define OV5650_PWRDN_GPIO       TEGRA_GPIO_PBB1
49 #define SOC2030_RESETN_GPIO     TEGRA_GPIO_PD5
50 #define SOC2030_PWRDN_GPIO      TEGRA_GPIO_PBB5
51 #define CAP_PROX_IRQ_GPIO       TEGRA_GPIO_PZ3
52 #define NCT1008_THERM2_GPIO     TEGRA_GPIO_PQ7
53
54 extern void tegra_throttling_enable(bool enable);
55
56 static int stingray_ov5650_power_on(void)
57 {
58         msleep(20);
59
60         gpio_direction_output(OV5650_PWRDN_GPIO, 0);
61         msleep(10);
62
63         gpio_direction_output(OV5650_RESETN_GPIO, 1);
64         msleep(5);
65         gpio_direction_output(OV5650_RESETN_GPIO, 0);
66         msleep(5);
67         gpio_direction_output(OV5650_RESETN_GPIO, 1);
68         msleep(5);
69
70         return 0;
71 }
72
73 static int stingray_ov5650_power_off(void)
74 {
75         gpio_direction_output(OV5650_PWRDN_GPIO, 1);
76         gpio_direction_output(OV5650_RESETN_GPIO, 0);
77
78         return 0;
79 }
80
81 struct ov5650_platform_data stingray_ov5650_data = {
82         .power_on = stingray_ov5650_power_on,
83         .power_off = stingray_ov5650_power_off,
84         .ignore_otp = false
85 };
86
87 static int stingray_ov5650_init(void)
88 {
89         tegra_gpio_enable(OV5650_RESETN_GPIO);
90         gpio_request(OV5650_RESETN_GPIO, "ov5650_reset");
91         gpio_direction_output(OV5650_RESETN_GPIO, 0);
92         gpio_export(OV5650_RESETN_GPIO, false);
93
94         tegra_gpio_enable(OV5650_PWRDN_GPIO);
95         gpio_request(OV5650_PWRDN_GPIO, "ov5650_pwrdn");
96         gpio_direction_output(OV5650_PWRDN_GPIO, 1);
97         gpio_export(OV5650_PWRDN_GPIO, false);
98
99         if (stingray_revision() <= STINGRAY_REVISION_P1) {
100                 stingray_ov5650_data.ignore_otp = true;
101                 pr_info("running on old hardware, ignoring OTP data\n");
102         }
103
104         pr_info("initialize the ov5650 sensor\n");
105
106         return 0;
107 }
108
109 static int stingray_soc2030_init(void)
110 {
111         tegra_gpio_enable(SOC2030_RESETN_GPIO);
112         gpio_request(SOC2030_RESETN_GPIO, "soc2030_reset");
113         gpio_direction_output(SOC2030_RESETN_GPIO, 0);
114         gpio_export(SOC2030_RESETN_GPIO, false);
115
116         tegra_gpio_enable(SOC2030_PWRDN_GPIO);
117         gpio_request(SOC2030_PWRDN_GPIO, "soc2030_pwrdn");
118         gpio_direction_output(SOC2030_PWRDN_GPIO, 1);
119         gpio_export(SOC2030_PWRDN_GPIO, false);
120
121         pr_info("initialize the soc2030 sensor\n");
122
123         return 0;
124 }
125
126 static int stingray_soc2030_power_on(void)
127 {
128         gpio_direction_output(SOC2030_PWRDN_GPIO, 0);
129         msleep(10);
130
131         gpio_direction_output(SOC2030_RESETN_GPIO, 1);
132         msleep(5);
133         gpio_direction_output(SOC2030_RESETN_GPIO, 0);
134         msleep(5);
135         gpio_direction_output(SOC2030_RESETN_GPIO, 1);
136         msleep(5);
137
138         return 0;
139 }
140
141 static int stingray_soc2030_power_off(void)
142 {
143         gpio_direction_output(SOC2030_RESETN_GPIO, 0);
144         gpio_direction_output(SOC2030_PWRDN_GPIO, 1);
145         return 0;
146 }
147
148 struct soc2030_platform_data stingray_soc2030_data = {
149         .power_on = stingray_soc2030_power_on,
150         .power_off = stingray_soc2030_power_off,
151 };
152
153 static int stingray_bmp085_init(void)
154 {
155         /*struct regulator *reg;*/
156
157         tegra_gpio_enable(BMP085_IRQ_GPIO);
158         gpio_request(BMP085_IRQ_GPIO, "bmp085_irq");
159         gpio_direction_input(BMP085_IRQ_GPIO);
160
161         return 0;
162 }
163
164 struct bmp085_platform_data stingray_barom_pdata = {
165         .poll_interval = 200,
166         .min_interval = 20,
167         .min_p = 95000,
168         .max_p = 125000,
169         .fuzz = 5,
170         .flat = 5,
171 };
172
173 static int stingray_kxtf9_gpio_level(void)
174 {
175         return gpio_get_value(KXTF9_IRQ_GPIO);
176 }
177
178
179 struct kxtf9_platform_data stingray_kxtf9_pdata = {
180         .min_interval   = 2,
181         .poll_interval  = 200,
182
183         .g_range        = KXTF9_G_2G,
184
185         .axis_map_x     = 0,
186         .axis_map_y     = 1,
187         .axis_map_z     = 2,
188
189         .negate_x       = 0,
190         .negate_y       = 0,
191         .negate_z       = 0,
192
193
194         .data_odr_init          = ODR100,
195         .ctrl_reg1_init         = RES_12BIT | KXTF9_G_2G | WUFE,
196         .int_ctrl_init          = IEA | IEN,
197         .tilt_timer_init        = 0x03,
198         .engine_odr_init        = OTP12_5 | OWUF50 | OTDT400,
199         .wuf_timer_init         = 0x0A,
200         .wuf_thresh_init        = 0x20,
201         .tdt_timer_init         = 0x78,
202         .tdt_h_thresh_init      = 0xB6,
203         .tdt_l_thresh_init      = 0x1A,
204         .tdt_tap_timer_init     = 0xA2,
205         .tdt_total_timer_init   = 0x24,
206         .tdt_latency_timer_init = 0x28,
207         .tdt_window_timer_init  = 0xA0,
208
209         .gpio = stingray_kxtf9_gpio_level,
210         .gesture = 0,
211         .sensitivity_low = {
212                   0x50, 0xFF, 0xB8, 0x32, 0x09, 0x0A, 0xA0,
213         },
214         .sensitivity_medium = {
215                   0x50, 0xFF, 0x68, 0x32, 0x09, 0x0A, 0xA0,
216         },
217         .sensitivity_high = {
218                   0x78, 0xB6, 0x1A, 0xA2, 0x24, 0x28, 0xA0,
219         },
220 };
221 static void stingray_kxtf9_init(void)
222 {
223         tegra_gpio_enable(KXTF9_IRQ_GPIO);
224         gpio_request(KXTF9_IRQ_GPIO, "kxtf9_irq");
225         gpio_direction_input(KXTF9_IRQ_GPIO);
226 }
227
228 struct cap_prox_platform_data stingray_cap_prox_pdata = {
229         .poll_interval                  = 10000,
230         .min_poll_interval              = 200,
231         .key1_ref_drift_thres_l         = 5,
232         .key3_ref_drift_thres_l         = 5,
233         .key1_ref_drift_thres_h         = 30,
234         .key3_ref_drift_thres_h         = 30,
235         .ref_drift_diff_thres           = 9,
236         .key1_save_drift_thres          = 125,
237         .key3_save_drift_thres          = 165,
238         .save_drift_diff_thres          = 90,
239         .key1_failsafe_thres            = 170,
240         .key3_failsafe_thres            = 100,
241         .key2_signal_thres              = 1700,
242         .key4_signal_thres              = 2200,
243         .plat_cap_prox_cfg = {
244                 .lp_mode                = 0x00,
245                 .address_ptr            = 0x10,
246                 .reset                  = 0x20,
247                 .key_enable_mask        = 0x3F,
248                 .data_integration       = 0x40,
249                 .neg_drift_rate         = 0x50,
250                 .pos_drift_rate         = 0x60,
251                 .force_detect           = 0x75,
252                 .calibrate              = 0x80,
253                 .thres_key1             = 0x92,
254                 .ref_backup             = 0xaa,
255                 .thres_key2             = 0xb2,
256                 .reserved12             = 0xc0,
257                 .drift_hold_time        = 0xd0,
258                 .reserved14             = 0xe0,
259                 .reserved15             = 0xf0,
260         },
261 };
262
263 static void stingray_cap_prox_init(void)
264 {
265         tegra_gpio_enable(CAP_PROX_IRQ_GPIO);
266         gpio_request(CAP_PROX_IRQ_GPIO, "cap_prox_irq");
267         gpio_direction_input(CAP_PROX_IRQ_GPIO);
268 }
269
270 struct max9635_platform_data stingray_max9635_pdata = {
271         .configure = 0x80,
272         .threshold_timer = 0x04,        /* 400mS interrupt delay */
273         .def_low_threshold = 0xFE,
274         .def_high_threshold = 0xFF,
275         .lens_coeff = 20,
276 };
277
278 static int stingray_max9635_init(void)
279 {
280         tegra_gpio_enable(MAX9635_IRQ_GPIO);
281         gpio_request(MAX9635_IRQ_GPIO, "max9635_irq");
282         gpio_direction_input(MAX9635_IRQ_GPIO);
283         return 0;
284 }
285
286 static int stingray_l3g4200d_init(void)
287 {
288         tegra_gpio_enable(L3G4200D_DRDY_GPIO);
289         gpio_request(L3G4200D_DRDY_GPIO, "l3g4200d_irq");
290         gpio_direction_input(L3G4200D_DRDY_GPIO);
291         return 0;
292 }
293
294 struct l3g4200d_platform_data stingray_gyro_pdata = {
295         .poll_interval = 10,
296         .gpio_drdy = L3G4200D_DRDY_GPIO,
297
298         .ctrl_reg1 = 0x1f,      /* ODR100 */
299         .ctrl_reg2 = 0x00,
300         .ctrl_reg3 = 0x08,      /* Enable DRDY interrupt */
301         .ctrl_reg4 = 0xA0,      /* BDU enable, 2000 dps */
302         .ctrl_reg5 = 0x00,
303         .reference = 0x00,
304         .fifo_ctrl_reg = 0x00,
305         .int1_cfg = 0x00,
306         .int1_tsh_xh = 0x00,
307         .int1_tsh_xl = 0x00,
308         .int1_tsh_yh = 0x00,
309         .int1_tsh_yl = 0x00,
310         .int1_tsh_zh = 0x00,
311         .int1_tsh_zl = 0x00,
312         .int1_duration = 0x00,
313 };
314
315 static int stingray_akm8975_init(void)
316 {
317         tegra_gpio_enable(AKM8975_IRQ_GPIO);
318         gpio_request(AKM8975_IRQ_GPIO, "akm8975");
319         gpio_direction_input(AKM8975_IRQ_GPIO);
320         return 0;
321 }
322
323 struct lm3559_platform_data stingray_lm3559_data = {
324         .flags = 0,
325         .flash_duration_def = 0x04, /* 160ms timeout */
326         .vin_monitor_def = 0xC0,
327 };
328
329 static void stingray_lm3559_init(void)
330 {
331         tegra_gpio_enable(LM3559_RESETN_GPIO);
332         gpio_request(LM3559_RESETN_GPIO, "lm3559_hwenable");
333         gpio_direction_output(LM3559_RESETN_GPIO, 1);
334         gpio_export(LM3559_RESETN_GPIO, false);
335
336         /* define LM3559_STROBE_GPIO for debug, usually controlled by VGP3 */
337         #ifdef LM3559_STROBE_GPIO
338         tegra_gpio_enable(LM3559_STROBE_GPIO);
339         gpio_request(LM3559_STROBE_GPIO, "lm3559_strobe");
340         gpio_direction_output(LM3559_STROBE_GPIO, 0);
341         gpio_export(LM3559_STROBE_GPIO, false);
342         #endif
343 }
344
345 static struct nct1008_platform_data stingray_nct1008_data = {
346         .supported_hwrev = true,
347         .ext_range = true,
348         .conv_rate = 0x08,
349         .offset = 6,
350         .hysteresis = 5,
351         .shutdown_ext_limit = 115,
352         .shutdown_local_limit = 120,
353         .throttling_ext_limit = 90,
354         .alarm_fn = tegra_throttling_enable,
355 };
356
357 static int stingray_nct1008_init(void)
358 {
359         if (stingray_revision() >= STINGRAY_REVISION_P2) {
360                 tegra_gpio_enable(NCT1008_THERM2_GPIO);
361                 gpio_request(NCT1008_THERM2_GPIO, "nct1008_therm2");
362                 gpio_direction_input(NCT1008_THERM2_GPIO);
363         } else {
364                 stingray_nct1008_data.supported_hwrev = false;
365         }
366         return 0;
367 }
368
369 static struct i2c_board_info __initdata stingray_i2c_bus4_sensor_info[] = {
370         {
371                 I2C_BOARD_INFO("akm8975", 0x0C),
372                 .irq = TEGRA_GPIO_TO_IRQ(AKM8975_IRQ_GPIO),
373         },
374         {
375                 I2C_BOARD_INFO("kxtf9", 0x0F),
376                 .platform_data = &stingray_kxtf9_pdata,
377                 .irq = TEGRA_GPIO_TO_IRQ(KXTF9_IRQ_GPIO),
378         },
379         {
380                 I2C_BOARD_INFO("nct1008", 0x4C),
381                 .platform_data = &stingray_nct1008_data,
382                 .irq = TEGRA_GPIO_TO_IRQ(NCT1008_THERM2_GPIO),
383         },
384         {
385                 I2C_BOARD_INFO("cap-prox", 0x12),
386                 .platform_data = &stingray_cap_prox_pdata,
387                 .irq = TEGRA_GPIO_TO_IRQ(CAP_PROX_IRQ_GPIO),
388         },
389 };
390
391 static struct i2c_board_info __initdata stingray_i2c_bus1_sensor_info[] = {
392         {
393                 I2C_BOARD_INFO(BMP085_NAME, 0x77),
394                 .platform_data = &stingray_barom_pdata,
395                 .irq = TEGRA_GPIO_TO_IRQ(BMP085_IRQ_GPIO),
396          },
397         {
398                  I2C_BOARD_INFO(MAX9635_NAME, 0x4b),
399                 .platform_data = &stingray_max9635_pdata,
400                 .irq = TEGRA_GPIO_TO_IRQ(MAX9635_IRQ_GPIO),
401          },
402 };
403
404 static struct i2c_board_info __initdata stingray_i2c_bus3_sensor_info[] = {
405          {
406                 I2C_BOARD_INFO(L3G4200D_NAME, 0x68),
407                 .platform_data = &stingray_gyro_pdata,
408                 .irq = TEGRA_GPIO_TO_IRQ(L3G4200D_DRDY_GPIO),
409          },
410
411          {
412                 I2C_BOARD_INFO(LM3559_NAME, 0x53),
413                 .platform_data = &stingray_lm3559_data,
414          },
415
416          {
417                  I2C_BOARD_INFO("ov5650", 0x36),
418                  .platform_data = &stingray_ov5650_data,
419          },
420
421          {
422                  I2C_BOARD_INFO("dw9714l", 0x0C),
423          },
424
425          {
426                  I2C_BOARD_INFO("soc2030", 0x3c),
427                  .platform_data = &stingray_soc2030_data,
428          },
429 };
430
431 int __init stingray_sensors_init(void)
432 {
433         stingray_bmp085_init();
434         stingray_kxtf9_init();
435         stingray_max9635_init();
436         stingray_l3g4200d_init();
437         stingray_akm8975_init();
438         stingray_lm3559_init();
439         stingray_ov5650_init();
440         stingray_soc2030_init();
441         stingray_cap_prox_init();
442         stingray_nct1008_init();
443
444         i2c_register_board_info(3, stingray_i2c_bus4_sensor_info,
445                 ARRAY_SIZE(stingray_i2c_bus4_sensor_info));
446         i2c_register_board_info(2, stingray_i2c_bus3_sensor_info,
447                 ARRAY_SIZE(stingray_i2c_bus3_sensor_info));
448         return i2c_register_board_info(0, stingray_i2c_bus1_sensor_info,
449                 ARRAY_SIZE(stingray_i2c_bus1_sensor_info));
450 }