2 * Copyright (c) 2010, Motorola, All Rights Reserved.
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.
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.
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/>.
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>
35 #include <linux/regulator/consumer.h>
36 #include <linux/nct1008.h>
38 #include "board-stingray.h"
39 #include "gpio-names.h"
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
54 extern void tegra_throttling_enable(bool enable);
56 static int stingray_ov5650_power_on(void)
60 gpio_direction_output(OV5650_PWRDN_GPIO, 0);
63 gpio_direction_output(OV5650_RESETN_GPIO, 1);
65 gpio_direction_output(OV5650_RESETN_GPIO, 0);
67 gpio_direction_output(OV5650_RESETN_GPIO, 1);
73 static int stingray_ov5650_power_off(void)
75 gpio_direction_output(OV5650_PWRDN_GPIO, 1);
76 gpio_direction_output(OV5650_RESETN_GPIO, 0);
81 struct ov5650_platform_data stingray_ov5650_data = {
82 .power_on = stingray_ov5650_power_on,
83 .power_off = stingray_ov5650_power_off,
87 static int stingray_ov5650_init(void)
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);
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);
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");
104 pr_info("initialize the ov5650 sensor\n");
109 static int stingray_soc2030_init(void)
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);
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);
121 pr_info("initialize the soc2030 sensor\n");
126 static int stingray_soc2030_power_on(void)
128 gpio_direction_output(SOC2030_PWRDN_GPIO, 0);
131 gpio_direction_output(SOC2030_RESETN_GPIO, 1);
133 gpio_direction_output(SOC2030_RESETN_GPIO, 0);
135 gpio_direction_output(SOC2030_RESETN_GPIO, 1);
141 static int stingray_soc2030_power_off(void)
143 gpio_direction_output(SOC2030_RESETN_GPIO, 0);
144 gpio_direction_output(SOC2030_PWRDN_GPIO, 1);
148 struct soc2030_platform_data stingray_soc2030_data = {
149 .power_on = stingray_soc2030_power_on,
150 .power_off = stingray_soc2030_power_off,
153 static int stingray_bmp085_init(void)
155 /*struct regulator *reg;*/
157 tegra_gpio_enable(BMP085_IRQ_GPIO);
158 gpio_request(BMP085_IRQ_GPIO, "bmp085_irq");
159 gpio_direction_input(BMP085_IRQ_GPIO);
164 struct bmp085_platform_data stingray_barom_pdata = {
165 .poll_interval = 200,
173 static int stingray_kxtf9_gpio_level(void)
175 return gpio_get_value(KXTF9_IRQ_GPIO);
179 struct kxtf9_platform_data stingray_kxtf9_pdata = {
181 .poll_interval = 200,
183 .g_range = KXTF9_G_2G,
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,
209 .gpio = stingray_kxtf9_gpio_level,
212 0x50, 0xFF, 0xB8, 0x32, 0x09, 0x0A, 0xA0,
214 .sensitivity_medium = {
215 0x50, 0xFF, 0x68, 0x32, 0x09, 0x0A, 0xA0,
217 .sensitivity_high = {
218 0x78, 0xB6, 0x1A, 0xA2, 0x24, 0x28, 0xA0,
221 static void stingray_kxtf9_init(void)
223 tegra_gpio_enable(KXTF9_IRQ_GPIO);
224 gpio_request(KXTF9_IRQ_GPIO, "kxtf9_irq");
225 gpio_direction_input(KXTF9_IRQ_GPIO);
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 = {
247 .key_enable_mask = 0x3F,
248 .data_integration = 0x40,
249 .neg_drift_rate = 0x50,
250 .pos_drift_rate = 0x60,
251 .force_detect = 0x75,
257 .drift_hold_time = 0xd0,
263 static void stingray_cap_prox_init(void)
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);
270 struct max9635_platform_data stingray_max9635_pdata = {
272 .threshold_timer = 0x04, /* 400mS interrupt delay */
273 .def_low_threshold = 0xFE,
274 .def_high_threshold = 0xFF,
278 static int stingray_max9635_init(void)
280 tegra_gpio_enable(MAX9635_IRQ_GPIO);
281 gpio_request(MAX9635_IRQ_GPIO, "max9635_irq");
282 gpio_direction_input(MAX9635_IRQ_GPIO);
286 static int stingray_l3g4200d_init(void)
288 tegra_gpio_enable(L3G4200D_DRDY_GPIO);
289 gpio_request(L3G4200D_DRDY_GPIO, "l3g4200d_irq");
290 gpio_direction_input(L3G4200D_DRDY_GPIO);
294 struct l3g4200d_platform_data stingray_gyro_pdata = {
296 .gpio_drdy = L3G4200D_DRDY_GPIO,
298 .ctrl_reg1 = 0x1f, /* ODR100 */
300 .ctrl_reg3 = 0x08, /* Enable DRDY interrupt */
301 .ctrl_reg4 = 0xA0, /* BDU enable, 2000 dps */
304 .fifo_ctrl_reg = 0x00,
312 .int1_duration = 0x00,
315 static int stingray_akm8975_init(void)
317 tegra_gpio_enable(AKM8975_IRQ_GPIO);
318 gpio_request(AKM8975_IRQ_GPIO, "akm8975");
319 gpio_direction_input(AKM8975_IRQ_GPIO);
323 struct lm3559_platform_data stingray_lm3559_data = {
325 .flash_duration_def = 0x04, /* 160ms timeout */
326 .vin_monitor_def = 0xC0,
329 static void stingray_lm3559_init(void)
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);
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);
345 static struct nct1008_platform_data stingray_nct1008_data = {
346 .supported_hwrev = true,
351 .shutdown_ext_limit = 115,
352 .shutdown_local_limit = 120,
353 .throttling_ext_limit = 90,
354 .alarm_fn = tegra_throttling_enable,
357 static int stingray_nct1008_init(void)
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);
364 stingray_nct1008_data.supported_hwrev = false;
369 static struct i2c_board_info __initdata stingray_i2c_bus4_sensor_info[] = {
371 I2C_BOARD_INFO("akm8975", 0x0C),
372 .irq = TEGRA_GPIO_TO_IRQ(AKM8975_IRQ_GPIO),
375 I2C_BOARD_INFO("kxtf9", 0x0F),
376 .platform_data = &stingray_kxtf9_pdata,
377 .irq = TEGRA_GPIO_TO_IRQ(KXTF9_IRQ_GPIO),
380 I2C_BOARD_INFO("nct1008", 0x4C),
381 .platform_data = &stingray_nct1008_data,
382 .irq = TEGRA_GPIO_TO_IRQ(NCT1008_THERM2_GPIO),
385 I2C_BOARD_INFO("cap-prox", 0x12),
386 .platform_data = &stingray_cap_prox_pdata,
387 .irq = TEGRA_GPIO_TO_IRQ(CAP_PROX_IRQ_GPIO),
391 static struct i2c_board_info __initdata stingray_i2c_bus1_sensor_info[] = {
393 I2C_BOARD_INFO(BMP085_NAME, 0x77),
394 .platform_data = &stingray_barom_pdata,
395 .irq = TEGRA_GPIO_TO_IRQ(BMP085_IRQ_GPIO),
398 I2C_BOARD_INFO(MAX9635_NAME, 0x4b),
399 .platform_data = &stingray_max9635_pdata,
400 .irq = TEGRA_GPIO_TO_IRQ(MAX9635_IRQ_GPIO),
404 static struct i2c_board_info __initdata stingray_i2c_bus3_sensor_info[] = {
406 I2C_BOARD_INFO(L3G4200D_NAME, 0x68),
407 .platform_data = &stingray_gyro_pdata,
408 .irq = TEGRA_GPIO_TO_IRQ(L3G4200D_DRDY_GPIO),
412 I2C_BOARD_INFO(LM3559_NAME, 0x53),
413 .platform_data = &stingray_lm3559_data,
417 I2C_BOARD_INFO("ov5650", 0x36),
418 .platform_data = &stingray_ov5650_data,
422 I2C_BOARD_INFO("dw9714l", 0x0C),
426 I2C_BOARD_INFO("soc2030", 0x3c),
427 .platform_data = &stingray_soc2030_data,
431 int __init stingray_sensors_init(void)
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();
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));