summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/odm_kit
diff options
context:
space:
mode:
authorGary King <gking@nvidia.com>2010-05-14 10:36:33 -0700
committerGary King <gking@nvidia.com>2010-05-14 20:04:06 -0700
commit106de33bf7f410bade659e110a5a7b187b46b8b2 (patch)
tree4d8231dc38fb3c05b6ccb911ff1e3b840d1d444b /arch/arm/mach-tegra/odm_kit
parente0426ba3077eae7e326c56487f34719f9638ddb5 (diff)
[ARM/tegra] add NvRm, ODM services, ODM kit for harmony & whistler
add power rail support to GPIO driver Change-Id: I45d4c1110a635047d68fb14f3e72a28f99acbe1b
Diffstat (limited to 'arch/arm/mach-tegra/odm_kit')
-rw-r--r--arch/arm/mach-tegra/odm_kit/Kconfig16
-rw-r--r--arch/arm/mach-tegra/odm_kit/Makefile3
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/Makefile4
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile12
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c92
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h66
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c54
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h50
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c142
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h58
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile2
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile14
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c70
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c184
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c326
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c138
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c144
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile15
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c145
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c75
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c358
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c138
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c235
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile18
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile22
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c193
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h92
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c123
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h63
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h48
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c2324
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h160
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c101
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h63
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c97
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h71
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c365
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h82
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c172
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h58
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h398
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c260
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h97
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h197
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c119
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h65
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h181
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c190
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h109
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h69
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile21
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c70
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h58
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c119
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h64
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h44
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h144
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c938
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h169
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c196
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h71
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c257
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h158
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c209
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h76
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c167
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h62
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h491
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c155
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h97
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h615
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c148
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c354
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h93
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile18
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c2036
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h103
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c200
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h67
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c109
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h67
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c207
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h74
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c150
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h93
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c193
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h93
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h193
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h200
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile11
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile13
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c934
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h199
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h58
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h203
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c304
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h86
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/Makefile8
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile12
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c1204
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h321
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c622
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h212
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c150
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/battery/Makefile11
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c1896
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h181
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c174
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile12
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c485
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c70
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile10
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c586
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h78
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile12
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c396
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c52
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/Makefile27
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c125
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h78
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c603
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h188
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c861
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h72
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h165
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile10
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c272
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/Makefile3
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/Makefile19
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c869
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c770
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c240
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c100
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h75
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h54
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c255
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c305
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h428
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h453
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h153
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/Makefile18
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h191
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c1490
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c997
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c216
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c88
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h74
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c254
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c482
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h102
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h75
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h270
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h349
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h74
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h75
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h69
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h59
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h57
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h50
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h76
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h67
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h99
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h96
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h55
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h50
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h96
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h82
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h180
168 files changed, 36873 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/odm_kit/Kconfig b/arch/arm/mach-tegra/odm_kit/Kconfig
new file mode 100644
index 000000000000..dbf829f1b79e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/Kconfig
@@ -0,0 +1,16 @@
+if MACH_TEGRA_GENERIC
+
+choice
+ prompt "Select ODM kit target board"
+
+config TEGRA_ODM_HARMONY
+ bool "NVIDIA Harmony development system"
+ depends on ARCH_TEGRA_2x_SOC
+
+config TEGRA_ODM_WHISTLER
+ bool "NVIDIA Whistler development system"
+ depends on ARCH_TEGRA_2x_SOC
+
+endchoice
+
+endif
diff --git a/arch/arm/mach-tegra/odm_kit/Makefile b/arch/arm/mach-tegra/odm_kit/Makefile
new file mode 100644
index 000000000000..a0f0c6670f71
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/Makefile
@@ -0,0 +1,3 @@
+obj-y += adaptations/
+obj-y += platform/
+obj-y += query/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/Makefile
new file mode 100644
index 000000000000..9b0d46744489
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/Makefile
@@ -0,0 +1,4 @@
+obj-y += gpio_ext/
+obj-y += tmon/
+obj-y += pmu/
+obj-y += misc/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile
new file mode 100644
index 000000000000..8500f4a6779a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile
@@ -0,0 +1,12 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-y += gpio_ext_hal.o
+obj-y += gpio_ext_null.o
+obj-y += gpio_pcf50626.o
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c
new file mode 100644
index 000000000000..c53fad2da1cd
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvcommon.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_gpio_ext.h"
+#include "nvodm_services.h"
+#include "gpio_ext_hal.h"
+#include "gpio_ext_null.h"
+#include "gpio_pcf50626.h"
+
+void
+NvOdmExternalGpioWritePins(
+ NvU32 Port,
+ NvU32 Pin,
+ NvU32 PinValue)
+{
+ static NvBool IsInit = NV_FALSE;
+ static NvOdmGpioExtDevice GpioExtDevice;
+
+ if (!IsInit)
+ {
+ NvOdmOsMemset(&GpioExtDevice, 0, sizeof(GpioExtDevice));
+ if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0')))
+ {
+ // fill in HAL function here.
+ GpioExtDevice.pfnWritePins = GPIO_PCF50626_NvOdmExternalGpioWritePins;
+ }
+ else
+ {
+ // NULL implementation
+ GpioExtDevice.pfnWritePins = null_NvOdmExternalGpioWritePins;
+ }
+ IsInit = NV_TRUE;
+ }
+ GpioExtDevice.pfnWritePins(Port, Pin, PinValue);
+}
+
+NvU32
+NvOdmExternalGpioReadPins(
+ NvU32 Port,
+ NvU32 Pin)
+{
+ static NvBool IsInit = NV_FALSE;
+ static NvOdmGpioExtDevice GpioExtDevice;
+
+ if (!IsInit)
+ {
+ NvOdmOsMemset(&GpioExtDevice, 0, sizeof(GpioExtDevice));
+ if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0')))
+ {
+ // fill in HAL function here.
+ GpioExtDevice.pfnReadPins = GPIO_PCF50626_NvOdmExternalGpioReadPins;
+ }
+ else
+ {
+ // NULL implementation
+ GpioExtDevice.pfnReadPins = null_NvOdmExternalGpioReadPins;
+ }
+ IsInit = NV_TRUE;
+ }
+ return GpioExtDevice.pfnReadPins(Port, Pin);
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h
new file mode 100644
index 000000000000..e1ca2c1182f9
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Abstraction layer stub for external gpio
+ * adaptation</b>
+ */
+
+#ifndef INCLUDED_NVODM_GPIO_EXT_ADAPTATION_HAL_H
+#define INCLUDED_NVODM_GPIO_EXT_ADAPTATION_HAL_H
+
+#include "nvodm_gpio_ext.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+// A simple HAL for the External GPIO adaptations.
+typedef void (*pfnExternalGpioWritePins)(NvU32, NvU32, NvU32);
+typedef NvU32 (*pfnExternalGpioReadPins)(NvU32, NvU32);
+
+typedef struct NvOdmGpioExtDeviceRec
+{
+ pfnExternalGpioWritePins pfnWritePins;
+ pfnExternalGpioReadPins pfnReadPins;
+
+} NvOdmGpioExtDevice;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c
new file mode 100644
index 000000000000..4957b099484a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_gpio_ext.h"
+#include "gpio_ext_null.h"
+
+void
+null_NvOdmExternalGpioWritePins(
+ NvU32 Port,
+ NvU32 Pin,
+ NvU32 PinValue)
+{
+ // NULL implementation that does nothing.
+ return;
+}
+
+NvU32
+null_NvOdmExternalGpioReadPins(
+ NvU32 Port,
+ NvU32 Pin)
+{
+ // NULL implementation that does nothing.
+ return 0;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h
new file mode 100644
index 000000000000..6e38bb31f121
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_GPIO_EXT_NULL_H
+#define INCLUDED_GPIO_EXT_NULL_H
+
+#include "gpio_ext_hal.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+void null_NvOdmExternalGpioWritePins(NvU32, NvU32, NvU32);
+NvU32 null_NvOdmExternalGpioReadPins(NvU32, NvU32);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c
new file mode 100644
index 000000000000..5f41b8aee053
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_services.h"
+#include "nvassert.h"
+#include "nvodm_gpio_ext.h"
+#include "gpio_pcf50626.h"
+
+#if NV_DEBUG
+#define ASSERT_SUCCESS( expr ) \
+ do { \
+ NvBool b = (expr); \
+ NV_ASSERT( b == NV_TRUE ); \
+ } while( 0 )
+#else
+#define ASSERT_SUCCESS( expr ) \
+ do { \
+ (void)(expr); \
+ } while( 0 )
+#endif
+
+static NvOdmServicesI2cHandle s_hOdmI2c = NULL;
+
+#define PCF50626_I2C_SPEED_KHZ 400
+#define PCF50626_DEVICE_ADDR 0xE0
+#define PCF50626_GPO2C1_ADDR 0x55
+#define PCF50626_PWM1S_ADDR 0x2D
+#define PCF50626_PWM1D_ADDR 0x2E
+
+static NvBool GPIO_PCF50626_I2cWrite8(NvU8 Addr, NvU8 Data);
+
+void
+GPIO_PCF50626_NvOdmExternalGpioWritePins(
+ NvU32 Port,
+ NvU32 Pin,
+ NvU32 PinValue)
+{
+ NvU8 val;
+ NvBool RetVal = NV_TRUE;
+
+ switch (Port)
+ {
+ case NVODM_GPIO_EXT_PORT_2:
+ if (Pin != 1) // Only Pin 1 is implemented at this time
+ break;
+
+ if (PinValue) // Enable
+ {
+ val = (1UL << 6) // invert polarity
+ | 0x3; // pwm1 output
+ RetVal = GPIO_PCF50626_I2cWrite8(PCF50626_GPO2C1_ADDR, val);
+ }
+ else // Disable
+ {
+ RetVal = GPIO_PCF50626_I2cWrite8(PCF50626_GPO2C1_ADDR, 0x0);
+ }
+ break;
+ }
+
+ if (RetVal == NV_FALSE)
+ {
+ NvOdmOsDebugPrintf("ERROR: GPIO_PCF50626_I2cWrite8() failed.\n");
+ }
+
+ return;
+}
+
+NvU32
+GPIO_PCF50626_NvOdmExternalGpioReadPins(
+ NvU32 Port,
+ NvU32 Pin)
+{
+ // Implement external GPIO port read routine here.
+ return 0;
+}
+
+static NvBool GPIO_PCF50626_I2cWrite8(
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvBool RetVal = NV_TRUE;
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvU32 DeviceAddr = (NvU32)PCF50626_DEVICE_ADDR;
+
+ s_hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0);
+ if (!s_hOdmI2c)
+ {
+ RetVal = NV_FALSE;
+ goto GPIO_PCF50626_I2cWrite8_exit;
+ }
+
+ WriteBuffer[0] = Addr & 0xFF; // PMU offset
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = DeviceAddr;
+ TransactionInfo.Buf = WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(s_hOdmI2c, &TransactionInfo, 1,
+ PCF50626_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ RetVal = NV_TRUE;
+ else
+ RetVal = NV_FALSE;
+
+GPIO_PCF50626_I2cWrite8_exit:
+ NvOdmI2cClose(s_hOdmI2c);
+ s_hOdmI2c = NULL;
+ return RetVal;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h
new file mode 100644
index 000000000000..4f78bff05e3f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_GPIO_PCF50626_H
+#define INCLUDED_GPIO_PCF50626_H
+
+#include "gpio_ext_hal.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+void
+GPIO_PCF50626_NvOdmExternalGpioWritePins(
+ NvU32 Port,
+ NvU32 Pin,
+ NvU32 PinValue);
+
+NvU32
+GPIO_PCF50626_NvOdmExternalGpioReadPins(
+ NvU32 Port,
+ NvU32 Pin);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile
new file mode 100644
index 000000000000..61c287105a48
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += harmony/
+obj-$(CONFIG_TEGRA_ODM_WHISTLER) += whistler/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile
new file mode 100644
index 000000000000..12af02178d7f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile
@@ -0,0 +1,14 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc.o
+obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc_keymapping.o
+obj-y += nvodm_sdio.o
+obj-y += nvodm_uart.o
+obj-y += nvodm_usbulpi.o
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c
new file mode 100644
index 000000000000..3f07a61a66c4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2008-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file Nvodm_Kbc.c
+ * @brief <b>KBC odm implementation</b>
+ *
+ * @Description : Implementation of the odm KBC API
+ */
+#include "nvodm_kbc.h"
+#include "../../../query/harmony/nvodm_query_kbc_qwerty_def.h"
+
+NvU32
+NvOdmKbcFilterKeys(
+ NvU32 *pRows,
+ NvU32 *pCols,
+ NvU32 NumOfKeysPressed)
+{
+ NvBool IsFunctionKeyFound = NV_FALSE;
+ NvU32 KeyIndex;
+
+ for (KeyIndex = 0; KeyIndex < NumOfKeysPressed; ++KeyIndex)
+ {
+ if ((pRows[KeyIndex] == KBC_QWERTY_FUNCTION_KEY_ROW_NUMBER) &&
+ (pCols[KeyIndex] == KBC_QWERTY_FUNCTION_KEY_COLUMN_NUMBER))
+ {
+ IsFunctionKeyFound = NV_TRUE;
+ break;
+ }
+ }
+ if (!IsFunctionKeyFound)
+ return NumOfKeysPressed;
+
+ // Add function row base to treat as special case
+ for (KeyIndex = 0; KeyIndex < NumOfKeysPressed; ++KeyIndex)
+ pRows[KeyIndex] += KBC_QWERTY_FUNCTION_KEY_ROW_BASE;
+
+ return NumOfKeysPressed;
+}
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c
new file mode 100644
index 000000000000..1b316bc511e8
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Keyboard Controller virtual key mapping</b>
+ *
+ * @b Description: Implement the ODM keyboard mapping to the platform
+ * specific.
+ */
+#include "nvodm_kbc_keymapping.h"
+#include <linux/input.h>
+
+
+#define KBC_QWERTY_NORMAL_KEY_CODE_BASE 0x1000
+#define KBC_QWERTY_FUNCTION_KEY_CODE_BASE 0x2000
+
+#define KBC_QWERTY_FUNCTION_KEY_ROW_BASE 0x100
+#define KBC_QWERTY_FUNCTION_KEY_ROW_NUMBER 0
+#define KBC_QWERTY_FUNCTION_KEY_COLUMN_NUMBER 7
+
+/**
+ * @brief Scan Code to Virtual Key mappings.
+ */
+
+
+/* The total number of soc scan codes will be (first - last) */
+#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST KBC_QWERTY_NORMAL_KEY_CODE_BASE
+#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST (KBC_QWERTY_NORMAL_KEY_CODE_BASE +0x7F)
+
+#define NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_FIRST KBC_QWERTY_FUNCTION_KEY_CODE_BASE
+#define NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_LAST (KBC_QWERTY_FUNCTION_KEY_CODE_BASE +0x7F)
+
+/**
+ * @brief This is the actual Scan-code-to-VKey mapping table. For new layouts
+ * this is the only structure which needs to be modified to return the
+ * proper vkey depending on the scan code.
+ */
+
+#define KEY_UNUSED 0
+
+static NvU32 ScanCodeToVKeyTableKbcQwertyNormal[] =
+{
+ // Row 0-> Unused, Unused, 'W', 'S', 'A', 'Z', Unused, Function,
+ // Row 1 ->Unused, Unused, Unused, Unused, Unused, unused, Unused, WIN_SPECIAL
+ // Row 2 ->Unused, Unused, Unused, Unused, Unused, unused, Alt, Alt2
+ // Row 3 ->'5', '4', 'R', 'E', 'F', 'D', 'X', Unused,
+ // Row 4 ->'7', '6', 'T', 'H', 'G', 'V', 'C', SPACEBAR,
+ // Row 5 ->'9', '8', 'U', 'Y', 'J', 'N', 'B', '|\',
+ // Row 6 ->Minus, '0', 'O', 'I', 'L', 'K', '<', M,
+ // Row 7 ->unused, '+', '}]', '#', Unused, Unused, Unused, WinSpecial,
+ // Row 8 ->Unused, Unused, Unused, Unused, SHIFT, SHIFT, UnUsed, Unused ,
+ // Row 9 ->Unused, Unused, Unused, Unused, unused, Ctrl, UnUsed, Control,
+ // Row A ->Unused, Unused, Unused, Unused, unused, unused, UnUsed, Unused,
+ // Row B ->'{[', 'P', '"', ':;', '/?, '>', UnUsed, Unused,
+ // Row C ->'F10', 'F9', 'BckSpc','3', '2', 'Up, Prntscr,Pause
+ // Row D ->INS, DEL, Unused, Pgup, PgDn, right, Down, Left,
+ // Row E ->F11, F12, F8, 'Q', F4, F3, '1', F7,
+ // Row F ->ESC, '~', F5, TAB, F1, F2, CAPLOCK,F6,
+ KEY_UNUSED, KEY_UNUSED, KEY_W, KEY_S,
+ KEY_A, KEY_Z, KEY_UNUSED, KEY_FN,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_MENU,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_LEFTALT, KEY_RIGHTALT,
+ KEY_5, KEY_4, KEY_R, KEY_E,
+ KEY_F, KEY_D, KEY_X, KEY_UNUSED,
+ KEY_7, KEY_6, KEY_T, KEY_H,
+ KEY_G, KEY_V, KEY_C, KEY_SPACE,
+ KEY_9, KEY_8, KEY_U, KEY_Y,
+ KEY_J, KEY_N, KEY_B, KEY_BACKSLASH,
+ KEY_MINUS, KEY_0, KEY_O, KEY_I,
+ KEY_L, KEY_K, KEY_COMMA, KEY_M,
+ KEY_UNUSED, KEY_EQUAL, KEY_RIGHTBRACE, KEY_ENTER,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_MENU,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_LEFTSHIFT, KEY_RIGHTSHIFT, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_LEFTCTRL, KEY_UNUSED, KEY_RIGHTCTRL,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_LEFTBRACE, KEY_P, KEY_APOSTROPHE, KEY_SEMICOLON,
+ KEY_SLASH, KEY_DOT, KEY_UNUSED, KEY_UNUSED,
+ KEY_F10, KEY_F9, KEY_BACKSPACE, KEY_3,
+ KEY_2, KEY_UP, KEY_PRINT, KEY_PAUSE,
+ KEY_INSERT, KEY_DELETE, KEY_UNUSED, KEY_PAGEUP,
+ KEY_PAGEDOWN, KEY_RIGHT, KEY_DOWN, KEY_LEFT,
+ KEY_F11, KEY_F12, KEY_F8, KEY_Q,
+ KEY_F4, KEY_F3, KEY_1, KEY_F7,
+ KEY_ESC, KEY_GRAVE, KEY_F5, KEY_TAB,
+ KEY_F1, KEY_F2, KEY_CAPSLOCK , KEY_F6
+};
+
+static NvU32 ScanCodeToVKeyTableKbcQwertyFunction[] =
+{
+ // Row 0-> Unused, Unused, 'W', 'S', 'A', 'Z', Unused, Function,
+ // Row 1 ->WINSPECIAL, Unused, Unused, Unused, Unused, unused, Unused, Win_special
+ // Row 2 ->Unused, Unused, Unused, Unused, Unused, unused, Alt, Alt2
+ // Row 3 ->'5', '4', 'R', 'E', 'F', 'D', 'X', Unused,
+ // Row 4 ->'7', '6', 'T', 'H', 'G', 'V', 'C', SPACEBAR,
+ // Row 5 ->'9', '8', 'U', 'Y', 'J', 'N', 'B', '|\',
+ // Row 6 ->Minus, '0', 'O', 'I', 'L', 'K', '<', M,
+ // Row 7 ->unused, '+', '}]', '#', Unused, Unused, Unused, WinSpecial,
+ // Row 8 ->Unused, Unused, Unused, Unused, SHIFT, SHIFT, UnUsed, Unused ,
+ // Row 9 ->Unused, Unused, Unused, Unused, unused, Ctrl, UnUsed, Control,
+ // Row A ->Unused, Unused, Unused, Unused, unused, unused, UnUsed, Unused,
+ // Row B ->'{[', 'P', '"', ':;', '/?, '>', UnUsed, Unused,
+ // Row C ->'F10', 'F9', 'BckSpc','3', '2', 'Up, Prntscr,Pause
+ // Row D ->INS, DEL, Unused, Pgup, PgDn, right, Down, Left,
+ // Row E ->F11, F12, F8, 'Q', F4, F3, '1', F7,
+ // Row F ->ESC, '~', F5, TAB, F1, F2, CAPLOCK,F6,
+
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_7, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_9, KEY_8, KEY_4, KEY_UNUSED, KEY_1, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_SLASH, KEY_6, KEY_5, KEY_3, KEY_2, KEY_UNUSED, KEY_0,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_KPASTERISK, KEY_UNUSED, KEY_KPMINUS, KEY_KPPLUS, KEY_DOT, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_VOLUMEUP, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_HOME, KEY_END, KEY_BRIGHTNESSUP, KEY_VOLUMEDOWN, KEY_BRIGHTNESSDOWN,
+ KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_MUTE,KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED,
+ KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_QUESTION,KEY_UNUSED, KEY_UNUSED, KEY_UNUSED
+};
+static struct NvOdmKeyVirtTableDetail s_ScvkQwertyNormalEngUS =
+{
+ NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST, // scan code start
+ NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST, // scan code end
+ ScanCodeToVKeyTableKbcQwertyNormal // Normal Qwerty keyboard
+};
+
+static struct NvOdmKeyVirtTableDetail s_ScvkQwertyFunctionEngUS =
+{
+ NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_FIRST, // scan code start
+ NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_LAST, // scan code end
+ ScanCodeToVKeyTableKbcQwertyFunction // Function Qwerty keyboard
+};
+
+static const struct NvOdmKeyVirtTableDetail *s_pVirtualKeyTables[] =
+ {&s_ScvkQwertyNormalEngUS, &s_ScvkQwertyFunctionEngUS};
+
+
+NvU32
+NvOdmKbcKeyMappingGetVirtualKeyMappingList(
+ const struct NvOdmKeyVirtTableDetail ***pVirtKeyTableList)
+{
+ *pVirtKeyTableList = s_pVirtualKeyTables;
+ return NV_ARRAY_SIZE(s_pVirtualKeyTables);
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c
new file mode 100644
index 000000000000..946f4ab9ecc4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2008-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file Nvodm_Sdio.c
+ * @brief <b>Sdio odm implementation</b>
+ *
+ * @Description : Implementation of the odm sdio API
+ */
+#include "nvodm_sdio.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvodm_pmu.h"
+#include "nvos.h"
+
+#ifdef NV_DRIVER_DEBUG
+ #define NV_DRIVER_TRACE(x) NvOdmOsDebugPrintf x
+#else
+ #define NV_DRIVER_TRACE(x)
+#endif
+
+#define WLAN_GUID NV_ODM_GUID('s','d','i','o','w','l','a','n')
+
+typedef struct NvOdmSdioRec
+{
+ // NvODM PMU device handle
+ NvOdmServicesPmuHandle hPmu;
+ // Gpio Handle
+ NvOdmServicesGpioHandle hGpio;
+ // Pin handle to Wlan Reset Gpio pin
+ NvOdmGpioPinHandle hResetPin;
+ // Pin handle to Wlan PWR GPIO Pin
+ NvOdmGpioPinHandle hPwrPin;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ // Power state
+ NvBool PoweredOn;
+ // Instance
+ NvU32 Instance;
+} NvOdmSdio;
+
+
+
+static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, NvBool IsEnable);
+static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable);
+
+
+static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable)
+{
+ if (IsEnable)
+ {
+ // Wlan Power On Reset Sequence
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x0); //RST -> Low
+ NvOdmOsWaitUS(2000);
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x1); //PWD -> High
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x1); //RST -> High
+ }
+ else
+ {
+ // Power Off sequence
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low
+ }
+
+ return NV_TRUE;
+}
+
+NvOdmSdioHandle NvOdmSdioOpen(NvU32 Instance)
+{
+ static NvOdmSdio *pDevice = NULL;
+ NvOdmServicesGpioHandle hGpioTemp = NULL;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ NvU32 NumOfGuids = 1;
+ NvU64 guid;
+ NvU32 searchVals[2];
+ const NvU32 *pOdmConfigs;
+ NvU32 NumOdmConfigs;
+ NvBool Status = NV_TRUE;
+ const NvOdmPeripheralSearch searchAttrs[] =
+ {
+ NvOdmPeripheralSearch_IoModule,
+ NvOdmPeripheralSearch_Instance,
+ };
+
+ searchVals[0] = NvOdmIoModule_Sdio;
+ searchVals[1] = Instance;
+
+ NvOdmQueryPinMux(NvOdmIoModule_Sdio, &pOdmConfigs, &NumOdmConfigs);
+ if (Instance >= NumOdmConfigs )
+ return NULL;
+ if( pOdmConfigs[Instance] == 0 )
+ return NULL;
+
+ NumOfGuids = NvOdmPeripheralEnumerate(
+ searchAttrs,
+ searchVals,
+ 2,
+ &guid,
+ NumOfGuids);
+
+
+ // Get the peripheral connectivity information
+ pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid);
+ if (pConnectivity == NULL)
+ return NULL;
+
+ pDevice = NvOdmOsAlloc(sizeof(NvOdmSdio));
+ pDevice->hPmu = NULL;
+ if(pDevice == NULL)
+ return (pDevice);
+
+ if (pDevice->hPmu == NULL)
+ {
+ pDevice->hPmu = NvOdmServicesPmuOpen();
+ if(pDevice->hPmu == NULL)
+ {
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ return (NULL);
+ }
+ }
+
+ pDevice->pConnectivity = pConnectivity;
+ NvOdmSetPowerOnSdio(pDevice, NV_TRUE);
+
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Getting the OdmGpio Handle
+ hGpioTemp = NvOdmGpioOpen();
+ if (hGpioTemp == NULL)
+ {
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ return (pDevice);
+ }
+
+ // Search for the Vdd rail and set the proper volage to the rail.
+ if (pConnectivity->AddressList[1].Interface == NvOdmIoModule_Gpio)
+ {
+ // Acquiring Pin Handles for Power Pin
+ pDevice->hPwrPin= NvOdmGpioAcquirePinHandle(hGpioTemp,
+ pConnectivity->AddressList[1].Instance,
+ pConnectivity->AddressList[1].Address);
+ }
+
+ if (pConnectivity->AddressList[2].Interface == NvOdmIoModule_Gpio)
+ {
+ // Acquiring Pin Handles for Reset Pin
+ pDevice->hResetPin= NvOdmGpioAcquirePinHandle(hGpioTemp,
+ pConnectivity->AddressList[2].Instance,
+ pConnectivity->AddressList[2].Address);
+ }
+
+ // Setting the ON/OFF pin to output mode.
+ NvOdmGpioConfig(hGpioTemp, pDevice->hPwrPin, NvOdmGpioPinMode_Output);
+ NvOdmGpioConfig(hGpioTemp, pDevice->hResetPin, NvOdmGpioPinMode_Output);
+
+ // Setting the Output Pin to Low
+ NvOdmGpioSetState(hGpioTemp, pDevice->hPwrPin, 0x0);
+ NvOdmGpioSetState(hGpioTemp, pDevice->hResetPin, 0x0);
+
+ pDevice->hGpio = hGpioTemp;
+
+ Status = SdioOdmWlanSetPowerOn(pDevice, NV_TRUE);
+ if (Status != NV_TRUE)
+ {
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ return (pDevice);
+ }
+ }
+ pDevice->PoweredOn = NV_TRUE;
+ pDevice->Instance = Instance;
+ NV_DRIVER_TRACE(("Open SDIO%d", Instance));
+ return pDevice;
+}
+
+void NvOdmSdioClose(NvOdmSdioHandle hOdmSdio)
+{
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+
+ NV_DRIVER_TRACE(("Close SDIO%d", hOdmSdio->Instance));
+
+ pConnectivity = hOdmSdio->pConnectivity;
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Call Turn off power when close is Called
+ (void)SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE);
+
+ NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hPwrPin);
+ NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hResetPin);
+ NvOdmGpioClose(hOdmSdio->hGpio);
+ }
+ NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE);
+ if (hOdmSdio->hPmu != NULL)
+ {
+ NvOdmServicesPmuClose(hOdmSdio->hPmu);
+ }
+ NvOdmOsFree(hOdmSdio);
+ hOdmSdio = NULL;
+}
+
+static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice,
+ NvBool IsEnable)
+{
+ NvU32 Index = 0;
+ NvOdmServicesPmuVddRailCapabilities RailCaps;
+ NvU32 SettlingTime = 0;
+ const NvOdmPeripheralConnectivity *pConnectivity;
+
+ pConnectivity = pDevice->pConnectivity;
+ if (IsEnable) // Turn on Power
+ {
+ // Search for the Vdd rail and set the proper volage to the rail.
+ for (Index = 0; Index < pConnectivity->NumAddress; ++Index)
+ {
+ if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd)
+ {
+ NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps);
+ NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address,
+ RailCaps.requestMilliVolts, &SettlingTime);
+ if (SettlingTime)
+ {
+ NvOdmOsWaitUS(SettlingTime);
+ }
+ }
+ }
+ }
+ else // Shutdown Power
+ {
+ // Search for the Vdd rail and power Off the module
+ for (Index = 0; Index < pConnectivity->NumAddress; ++Index)
+ {
+ if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd)
+ {
+ NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps);
+ NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address,
+ ODM_VOLTAGE_OFF, &SettlingTime);
+ if (SettlingTime)
+ {
+ NvOdmOsWaitUS(SettlingTime);
+ }
+ }
+ }
+ }
+}
+
+NvBool NvOdmSdioSuspend(NvOdmSdioHandle hOdmSdio)
+{
+
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+ NvBool Status = NV_TRUE;
+
+ if (!hOdmSdio->PoweredOn)
+ {
+ NV_DRIVER_TRACE(("SDIO%d already suspended", hOdmSdio->Instance));
+ return NV_TRUE;
+ }
+
+ NV_DRIVER_TRACE(("Suspend SDIO%d", hOdmSdio->Instance));
+ NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE);
+
+ pConnectivity = hOdmSdio->pConnectivity;
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Turn off power
+ Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE);
+
+ }
+ hOdmSdio->PoweredOn = NV_FALSE;
+ return Status;
+
+}
+
+NvBool NvOdmSdioResume(NvOdmSdioHandle hOdmSdio)
+{
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+ NvBool Status = NV_TRUE;
+
+ if (hOdmSdio->PoweredOn)
+ {
+ NV_DRIVER_TRACE(("SDIO%d already resumed", hOdmSdio->Instance));
+ return NV_TRUE;
+ }
+
+ NvOdmSetPowerOnSdio(hOdmSdio, NV_TRUE);
+
+ pConnectivity = hOdmSdio->pConnectivity;
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Turn on power
+ Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_TRUE);
+ }
+ NV_DRIVER_TRACE(("Resume SDIO%d", hOdmSdio->Instance));
+ hOdmSdio->PoweredOn = NV_TRUE;
+ return Status;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c
new file mode 100644
index 000000000000..a3f09ad89c18
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file nvodm_uart.c
+ * @brief <b>Adaptation for uart </b>
+ *
+ * @Description : Implementation of the uart adaptation.
+ */
+#include "nvodm_uart.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvos.h"
+#include "nvodm_pmu.h"
+
+#ifdef NV_DRIVER_DEBUG
+ #define NV_DRIVER_TRACE NvOsDebugPrintf
+#else
+ #define NV_DRIVER_TRACE (void)
+#endif
+
+typedef struct NvOdmUartRec
+{
+ // NvODM PMU device handle
+ NvOdmServicesPmuHandle hPmu;
+ // Gpio Handle
+ NvOdmServicesGpioHandle hGpio;
+ // Pin handle to Bluetooth Reset Gpio pin
+ NvOdmGpioPinHandle hResetPin;
+ NvOdmPeripheralConnectivity *pConnectivity;
+} NvOdmUart;
+
+NvOdmUartHandle NvOdmUartOpen(NvU32 Instance)
+{
+ NvOdmUart *pDevice = NULL;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ NvU32 NumOfGuids = 1;
+ NvU64 guid;
+ NvU32 searchVals[2];
+ const NvOdmPeripheralSearch searchAttrs[] =
+ {
+ NvOdmPeripheralSearch_IoModule,
+ NvOdmPeripheralSearch_Instance,
+ };
+
+ searchVals[0] = NvOdmIoModule_Uart;
+ searchVals[1] = Instance;
+
+ NumOfGuids = NvOdmPeripheralEnumerate(
+ searchAttrs,
+ searchVals,
+ 2,
+ &guid,
+ NumOfGuids);
+
+ pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid);
+ if (pConnectivity == NULL)
+ goto ExitUartOdm;
+
+ pDevice = NvOdmOsAlloc(sizeof(NvOdmUart));
+ if(pDevice == NULL)
+ goto ExitUartOdm;
+
+ pDevice->hPmu = NvOdmServicesPmuOpen();
+ if(pDevice->hPmu == NULL)
+ {
+ goto ExitUartOdm;
+ }
+
+ // Switch On UART Interface
+
+ pDevice->pConnectivity = pConnectivity;
+
+ return pDevice;
+
+ExitUartOdm:
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+
+ return NULL;
+}
+
+void NvOdmUartClose(NvOdmUartHandle hOdmUart)
+{
+
+ if (hOdmUart)
+ {
+ // Switch OFF UART Interface
+
+ if (hOdmUart->hPmu != NULL)
+ {
+ NvOdmServicesPmuClose(hOdmUart->hPmu);
+ }
+ NvOdmOsFree(hOdmUart);
+ hOdmUart = NULL;
+ }
+}
+
+NvBool NvOdmUartSuspend(NvOdmUartHandle hOdmUart)
+{
+ return NV_FALSE;
+}
+
+NvBool NvOdmUartResume(NvOdmUartHandle hOdmUart)
+{
+ return NV_FALSE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c
new file mode 100644
index 000000000000..63bdf09a14ae
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file nvodm_usbulpi.c
+ * @brief <b>Adaptation for USB ULPI </b>
+ *
+ * @Description : Implementation of the USB ULPI adaptation.
+ */
+#include "nvodm_usbulpi.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvos.h"
+
+#define SMSC3317GUID NV_ODM_GUID('s','m','s','c','3','3','1','7')
+
+#define MAX_CLOCKS 3
+
+#define NVODM_PORT(x) ((x) - 'a')
+#define ULPI_RESET_PORT NVODM_PORT('v')
+#define ULPI_RESET_PIN 1
+
+
+#ifdef NV_DRIVER_DEBUG
+ #define NV_DRIVER_TRACE NvOsDebugPrintf
+#else
+ #define NV_DRIVER_TRACE (void)
+#endif
+
+typedef struct NvOdmUsbUlpiRec
+{
+ NvU64 CurrentGUID;
+} NvOdmUsbUlpi;
+
+static NvOdmServicesGpioHandle s_hGpio = NULL;
+static NvOdmGpioPinHandle s_hResetPin = NULL;
+
+NvOdmUsbUlpiHandle NvOdmUsbUlpiOpen(NvU32 Instance)
+{
+ NvOdmUsbUlpi*pDevice = NULL;
+ NvU32 ClockInstances[MAX_CLOCKS];
+ NvU32 ClockFrequencies[MAX_CLOCKS];
+ NvU32 NumClocks;
+
+ pDevice = NvOdmOsAlloc(sizeof(NvOdmUsbUlpi));
+ if(pDevice == NULL)
+ return NULL;
+
+ if(!NvOdmExternalClockConfig(SMSC3317GUID, NV_FALSE, ClockInstances,
+ ClockFrequencies, &NumClocks))
+ {
+ NV_DRIVER_TRACE (("ERROR NvOdmUsbUlpiOpen: "
+ "NvOdmExternalClockConfig fail\n"));
+ goto ExitUlpiOdm;
+ }
+ NvOdmOsSleepMS(10);
+
+ if (!s_hGpio)
+ s_hGpio = NvOdmGpioOpen();
+ if (!s_hGpio)
+ {
+ NV_DRIVER_TRACE (("ERROR NvOdmUsbUlpiOpen: "
+ "Not able to open gpio handle\n"));
+ goto ExitUlpiOdm;
+ }
+
+ if (!s_hResetPin)
+ s_hResetPin = NvOdmGpioAcquirePinHandle(s_hGpio, ULPI_RESET_PORT,
+ ULPI_RESET_PIN);
+ if (!s_hResetPin)
+ {
+ NvOdmGpioClose(s_hGpio);
+ s_hGpio = NULL;
+ NV_DRIVER_TRACE (("ERROR NvOdmGpioAcquirePinHandle: "
+ "Not able to Acq pinhandle\n"));
+ goto ExitUlpiOdm;
+ }
+
+ // Pull high on RESETB ( 22nd pin of smsc3315)
+ // config as out put pin
+ NvOdmGpioConfig(s_hGpio,s_hResetPin, NvOdmGpioPinMode_Output);
+ // Set low to write high on ULPI_RESETB pin
+ NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x01);
+ NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x0);
+ NvOdmOsSleepMS(5);
+ NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x01);
+
+ pDevice->CurrentGUID = SMSC3317GUID;
+ return pDevice;
+
+ExitUlpiOdm:
+ NvOdmOsFree(pDevice);
+ return NULL;
+}
+
+void NvOdmUsbUlpiClose(NvOdmUsbUlpiHandle hOdmUlpi)
+{
+ if (hOdmUlpi)
+ {
+ NvOdmOsFree(hOdmUlpi);
+ }
+ if (s_hResetPin)
+ {
+ NvOdmGpioReleasePinHandle(s_hGpio, s_hResetPin);
+ s_hResetPin = NULL;
+ }
+ if (s_hGpio)
+ {
+ NvOdmGpioClose(s_hGpio);
+ s_hGpio = NULL;
+ }
+
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile
new file mode 100644
index 000000000000..9f3eb8402b6b
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile
@@ -0,0 +1,15 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc.o
+obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc_keymapping.o
+obj-y += nvodm_sdio.o
+obj-y += nvodm_uart.o
+obj-y += nvodm_usbulpi.o
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c
new file mode 100644
index 000000000000..70b468d9ff51
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2008-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file Nvodm_Kbc.c
+ * @brief <b>KBC odm implementation</b>
+ *
+ * @Description : Implementation of the odm KBC API
+ */
+#include "nvodm_kbc.h"
+
+
+#define KEYPAD_HAS_DIODES 1
+
+NvU32
+NvOdmKbcFilterKeys(
+ NvU32 *pRows,
+ NvU32 *pCols,
+ NvU32 NumOfKeysPressed)
+{
+
+#if KEYPAD_HAS_DIODES
+ return NumOfKeysPressed;
+#else
+ NvU32 i=0;
+ NvU32 j=0;
+ NvU32 k=0;
+ NvU32 FilterKeys[2] = {0};
+ NvBool IsFiltered = NV_FALSE;
+ NvU32 NewKeyPressCount = NumOfKeysPressed;
+
+ if (NumOfKeysPressed <= 3)
+ {
+ for (i=0; i<NumOfKeysPressed; i++)
+ {
+ for (j=(i+1); j<NumOfKeysPressed; j++)
+ {
+ if ((pRows[i]+1==pRows[j])||(pRows[j]+1==pRows[i]))
+ {
+ for (k=j; i<(NumOfKeysPressed - 1); i++)
+ {
+ pRows[k] = pRows[k+1];
+ pCols[k] = pCols[k+1];
+ }
+ NumOfKeysPressed--;
+ }
+ if ((pCols[i]+1==pCols[j])||(pCols[j]+1==pCols[i]))
+ {
+ for (k=j; i<(NumOfKeysPressed - 1); i++)
+ {
+ pRows[k] = pRows[k+1];
+ pCols[k] = pCols[k+1];
+ }
+ NumOfKeysPressed--;
+ }
+ }
+ }
+ return NumOfKeysPressed;
+ }
+
+ for (i=0; i<NumOfKeysPressed; i++)
+ {
+ for (j=(i+1); j<NumOfKeysPressed; j++)
+ {
+ if (pRows[i] == pRows[j])
+ {
+ for (k=0; k<NumOfKeysPressed; k++)
+ {
+ if (k == i)
+ continue;
+
+ if(pCols[i] == pCols[k])
+ {
+ FilterKeys[0] = k;
+ IsFiltered = NV_TRUE;
+ }
+ }
+ for (k=0; k<NumOfKeysPressed; k++)
+ {
+ if (k == j)
+ continue;
+
+ if (pCols[j] == pCols[k])
+ {
+ FilterKeys[1] = k;
+ IsFiltered = NV_TRUE;
+ }
+ }
+ goto end;
+ }
+ }
+ }
+
+ end:
+ if (IsFiltered)
+ {
+ for (i=FilterKeys[0]; i<(NumOfKeysPressed - 1); i++)
+ {
+ pRows[i] = pRows[i+1];
+ pCols[i] = pCols[i+1];
+ }
+ NewKeyPressCount--;
+ for (i=FilterKeys[1]; i<(NumOfKeysPressed - 1); i++)
+ {
+ pRows[i] = pRows[i+1];
+ pCols[i] = pCols[i+1];
+ }
+ NewKeyPressCount--;
+ }
+ NumOfKeysPressed = NewKeyPressCount;
+ return NewKeyPressCount;
+#endif
+
+}
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c
new file mode 100644
index 000000000000..1f2dd7275eae
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Keyboard Controller virtual key mapping</b>
+ *
+ * @b Description: Implement the ODM keyboard mapping to the platform
+ * specific.
+ */
+#include "nvodm_kbc_keymapping.h"
+#include <linux/input.h>
+
+/* The total number of soc scan codes will be (first - last) */
+#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST 0
+#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST 3
+
+static NvU32 KbcLayOutVirtualKey[] =
+{
+ KEY_MENU,
+ 0,
+ KEY_HOME,
+ KEY_BACK
+};
+
+static struct NvOdmKeyVirtTableDetail s_ScvkKeyMap =
+{
+ NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST, // scan code start
+ NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST, // scan code end
+ KbcLayOutVirtualKey // Normal Qwerty keyboard
+};
+
+
+static const struct NvOdmKeyVirtTableDetail *s_pVirtualKeyTables[] =
+ {&s_ScvkKeyMap};
+
+
+NvU32
+NvOdmKbcKeyMappingGetVirtualKeyMappingList(
+ const struct NvOdmKeyVirtTableDetail ***pVirtKeyTableList)
+{
+ *pVirtKeyTableList = s_pVirtualKeyTables;
+ return NV_ARRAY_SIZE(s_pVirtualKeyTables);
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c
new file mode 100644
index 000000000000..d980dfca3b2b
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2008-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file Nvodm_Sdio.c
+ * @brief <b>Sdio odm implementation</b>
+ *
+ * @Description : Implementation of the odm sdio API
+ */
+#include "nvodm_sdio.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvodm_pmu.h"
+
+#ifdef NV_DRIVER_DEBUG
+ #define NV_DRIVER_TRACE(x) NvOdmOsDebugPrintf x
+#else
+ #define NV_DRIVER_TRACE(x)
+#endif
+
+#define WLAN_GUID NV_ODM_GUID('s','d','i','o','w','l','a','n')
+// Device Board definitions
+#define BOARD_ID_E951 (0x0933) /* Decimal 951. => ((9<<8) | 51)*/
+
+
+typedef enum
+{
+ NvOdmSdioDiscoveryAddress_0 = 0,
+ NvOdmSdioDiscoveryAddress_1,
+
+ NvOdmSdioDiscoveryAddress_Force32 = 0x7FFFFFFF,
+
+} NvOdmSdioDiscoveryAddress;
+
+typedef struct NvOdmSdioRec
+{
+ // NvODM PMU device handle
+ NvOdmServicesPmuHandle hPmu;
+ // Gpio Handle
+ NvOdmServicesGpioHandle hGpio;
+ // Pin handle to Wlan Reset Gpio pin
+ NvOdmGpioPinHandle hResetPin;
+ // Pin handle to Wlan PWR GPIO Pin
+ NvOdmGpioPinHandle hPwrPin;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ // Power state
+ NvBool PoweredOn;
+ // Instance
+ NvU32 Instance;
+} NvOdmSdio;
+
+static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, NvBool IsEnable);
+static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable);
+
+
+static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable)
+{
+ if (IsEnable)
+ {
+ // Wlan Power On Reset Sequence
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x0); //RST -> Low
+ NvOdmOsWaitUS(2000);
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x1); //PWD -> High
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x1); //RST -> High
+ }
+ else
+ {
+ // Power Off sequence
+ NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low
+ }
+ return NV_TRUE;
+}
+
+NvOdmSdioHandle NvOdmSdioOpen(NvU32 Instance)
+{
+ static NvOdmSdio *pDevice = NULL;
+ NvOdmServicesGpioHandle hGpioTemp = NULL;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ NvU32 NumOfGuids = 1;
+ NvU64 guid;
+ NvU32 searchVals[4];
+ const NvU32 *pOdmConfigs;
+ NvU32 NumOdmConfigs;
+ NvBool Status = NV_TRUE;
+ const NvOdmPeripheralSearch searchAttrs[] =
+ {
+ NvOdmPeripheralSearch_PeripheralClass,
+ NvOdmPeripheralSearch_IoModule,
+ NvOdmPeripheralSearch_Instance,
+ NvOdmPeripheralSearch_Address,
+ };
+ NvOdmBoardInfo BoardInfo;
+ NvBool status = NV_FALSE;
+
+ searchVals[0] = NvOdmPeripheralClass_Other;
+ searchVals[1] = NvOdmIoModule_Sdio;
+ searchVals[2] = Instance;
+
+ NvOdmQueryPinMux(NvOdmIoModule_Sdio, &pOdmConfigs, &NumOdmConfigs);
+ if ((Instance == 0) && (pOdmConfigs[0] == NvOdmSdioPinMap_Config1))
+ {
+ // sdio is connected to sdio2 slot.
+ searchVals[3] = NvOdmSdioDiscoveryAddress_1;
+ }
+ else
+ {
+ // sdio is connected to wifi module.
+ searchVals[3] = NvOdmSdioDiscoveryAddress_0;
+ }
+
+ NumOfGuids = NvOdmPeripheralEnumerate(searchAttrs,
+ searchVals,
+ 4,
+ &guid,
+ NumOfGuids);
+
+ // Get the peripheral connectivity information
+ pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid);
+ if (pConnectivity == NULL)
+ return NULL;
+
+ pDevice = NvOdmOsAlloc(sizeof(NvOdmSdio));
+ if(pDevice == NULL)
+ return (pDevice);
+
+ pDevice->hPmu = NvOdmServicesPmuOpen();
+ if(pDevice->hPmu == NULL)
+ {
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ return (NULL);
+ }
+
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // WARNING: This function *cannot* be called before RmOpen().
+ status = NvOdmPeripheralGetBoardInfo((BOARD_ID_E951), &BoardInfo);
+ if (NV_TRUE != status)
+ {
+ // whistler should have E951 Module, if it is not presnt return NULL Handle.
+ NvOdmServicesPmuClose(pDevice->hPmu);
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ NvOdmOsDebugPrintf(("No E951 Detected"));
+ return (pDevice);
+ }
+ }
+
+ pDevice->pConnectivity = pConnectivity;
+ NvOdmSetPowerOnSdio(pDevice, NV_TRUE);
+
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Getting the OdmGpio Handle
+ hGpioTemp = NvOdmGpioOpen();
+ if (hGpioTemp == NULL)
+ {
+ NvOdmServicesPmuClose(pDevice->hPmu);
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ return (pDevice);
+ }
+
+ // Search for the Vdd rail and set the proper volage to the rail.
+ if (pConnectivity->AddressList[1].Interface == NvOdmIoModule_Gpio)
+ {
+ // Acquiring Pin Handles for Power Pin
+ pDevice->hPwrPin= NvOdmGpioAcquirePinHandle(hGpioTemp,
+ pConnectivity->AddressList[1].Instance,
+ pConnectivity->AddressList[1].Address);
+ }
+
+ if (pConnectivity->AddressList[2].Interface == NvOdmIoModule_Gpio)
+ {
+ // Acquiring Pin Handles for Reset Pin
+ pDevice->hResetPin= NvOdmGpioAcquirePinHandle(hGpioTemp,
+ pConnectivity->AddressList[2].Instance,
+ pConnectivity->AddressList[2].Address);
+ }
+
+ // Setting the ON/OFF pin to output mode.
+ NvOdmGpioConfig(hGpioTemp, pDevice->hPwrPin, NvOdmGpioPinMode_Output);
+ NvOdmGpioConfig(hGpioTemp, pDevice->hResetPin, NvOdmGpioPinMode_Output);
+
+ // Setting the Output Pin to Low
+ NvOdmGpioSetState(hGpioTemp, pDevice->hPwrPin, 0x0);
+ NvOdmGpioSetState(hGpioTemp, pDevice->hResetPin, 0x0);
+
+ pDevice->hGpio = hGpioTemp;
+
+ Status = SdioOdmWlanSetPowerOn(pDevice, NV_TRUE);
+ if (Status != NV_TRUE)
+ {
+ NvOdmServicesPmuClose(pDevice->hPmu);
+ NvOdmGpioReleasePinHandle(pDevice->hGpio, pDevice->hPwrPin);
+ NvOdmGpioReleasePinHandle(pDevice->hGpio, pDevice->hResetPin);
+ NvOdmGpioClose(pDevice->hGpio);
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+ return (pDevice);
+ }
+ }
+ pDevice->PoweredOn = NV_TRUE;
+ pDevice->Instance = Instance;
+ NV_DRIVER_TRACE(("Open SDIO%d", Instance));
+ return pDevice;
+}
+
+void NvOdmSdioClose(NvOdmSdioHandle hOdmSdio)
+{
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+
+ NV_DRIVER_TRACE(("Close SDIO%d", hOdmSdio->Instance));
+
+ pConnectivity = hOdmSdio->pConnectivity;
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Call Turn off power when close is Called
+ (void)SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE);
+
+ NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hPwrPin);
+ NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hResetPin);
+ NvOdmGpioClose(hOdmSdio->hGpio);
+ }
+ NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE);
+ if (hOdmSdio->hPmu != NULL)
+ {
+ NvOdmServicesPmuClose(hOdmSdio->hPmu);
+ }
+ NvOdmOsFree(hOdmSdio);
+ hOdmSdio = NULL;
+}
+
+static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, NvBool IsEnable)
+{
+ NvU32 Index = 0;
+ NvOdmServicesPmuVddRailCapabilities RailCaps;
+ NvU32 SettlingTime = 0;
+ const NvOdmPeripheralConnectivity *pConnectivity;
+
+ pConnectivity = pDevice->pConnectivity;
+ if (IsEnable) // Turn on Power
+ {
+ // Search for the Vdd rail and set the proper volage to the rail.
+ for (Index = 0; Index < pConnectivity->NumAddress; ++Index)
+ {
+ if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd)
+ {
+ NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps);
+ NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address,
+ RailCaps.requestMilliVolts, &SettlingTime);
+ if (SettlingTime)
+ {
+ NvOdmOsWaitUS(SettlingTime);
+ }
+ }
+ }
+ }
+ else // Shutdown Power
+ {
+ // Search for the Vdd rail and power Off the module
+ for (Index = 0; Index < pConnectivity->NumAddress; ++Index)
+ {
+ if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd)
+ {
+ NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps);
+ NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address,
+ ODM_VOLTAGE_OFF, &SettlingTime);
+ if (SettlingTime)
+ {
+ NvOdmOsWaitUS(SettlingTime);
+ }
+ }
+ }
+ }
+}
+
+NvBool NvOdmSdioSuspend(NvOdmSdioHandle hOdmSdio)
+{
+
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+ NvBool Status = NV_TRUE;
+
+ if (!hOdmSdio->PoweredOn)
+ {
+ NV_DRIVER_TRACE(("SDIO%d already suspended", hOdmSdio->Instance));
+ return NV_TRUE;
+ }
+
+ NV_DRIVER_TRACE(("Suspend SDIO%d", hOdmSdio->Instance));
+ NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE);
+
+ pConnectivity = hOdmSdio->pConnectivity;
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Turn off power
+ Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE);
+
+ }
+ hOdmSdio->PoweredOn = NV_FALSE;
+ return Status;
+
+}
+
+NvBool NvOdmSdioResume(NvOdmSdioHandle hOdmSdio)
+{
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+ NvBool Status = NV_TRUE;
+
+ if (hOdmSdio->PoweredOn)
+ {
+ NV_DRIVER_TRACE(("SDIO%d already resumed", hOdmSdio->Instance));
+ return NV_TRUE;
+ }
+
+ NvOdmSetPowerOnSdio(hOdmSdio, NV_TRUE);
+
+ pConnectivity = hOdmSdio->pConnectivity;
+ if (pConnectivity->Guid == WLAN_GUID)
+ {
+ // Turn on power
+ Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_TRUE);
+ }
+ NV_DRIVER_TRACE(("Resume SDIO%d", hOdmSdio->Instance));
+ hOdmSdio->PoweredOn = NV_TRUE;
+ return Status;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c
new file mode 100644
index 000000000000..a3f09ad89c18
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file nvodm_uart.c
+ * @brief <b>Adaptation for uart </b>
+ *
+ * @Description : Implementation of the uart adaptation.
+ */
+#include "nvodm_uart.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvos.h"
+#include "nvodm_pmu.h"
+
+#ifdef NV_DRIVER_DEBUG
+ #define NV_DRIVER_TRACE NvOsDebugPrintf
+#else
+ #define NV_DRIVER_TRACE (void)
+#endif
+
+typedef struct NvOdmUartRec
+{
+ // NvODM PMU device handle
+ NvOdmServicesPmuHandle hPmu;
+ // Gpio Handle
+ NvOdmServicesGpioHandle hGpio;
+ // Pin handle to Bluetooth Reset Gpio pin
+ NvOdmGpioPinHandle hResetPin;
+ NvOdmPeripheralConnectivity *pConnectivity;
+} NvOdmUart;
+
+NvOdmUartHandle NvOdmUartOpen(NvU32 Instance)
+{
+ NvOdmUart *pDevice = NULL;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ NvU32 NumOfGuids = 1;
+ NvU64 guid;
+ NvU32 searchVals[2];
+ const NvOdmPeripheralSearch searchAttrs[] =
+ {
+ NvOdmPeripheralSearch_IoModule,
+ NvOdmPeripheralSearch_Instance,
+ };
+
+ searchVals[0] = NvOdmIoModule_Uart;
+ searchVals[1] = Instance;
+
+ NumOfGuids = NvOdmPeripheralEnumerate(
+ searchAttrs,
+ searchVals,
+ 2,
+ &guid,
+ NumOfGuids);
+
+ pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid);
+ if (pConnectivity == NULL)
+ goto ExitUartOdm;
+
+ pDevice = NvOdmOsAlloc(sizeof(NvOdmUart));
+ if(pDevice == NULL)
+ goto ExitUartOdm;
+
+ pDevice->hPmu = NvOdmServicesPmuOpen();
+ if(pDevice->hPmu == NULL)
+ {
+ goto ExitUartOdm;
+ }
+
+ // Switch On UART Interface
+
+ pDevice->pConnectivity = pConnectivity;
+
+ return pDevice;
+
+ExitUartOdm:
+ NvOdmOsFree(pDevice);
+ pDevice = NULL;
+
+ return NULL;
+}
+
+void NvOdmUartClose(NvOdmUartHandle hOdmUart)
+{
+
+ if (hOdmUart)
+ {
+ // Switch OFF UART Interface
+
+ if (hOdmUart->hPmu != NULL)
+ {
+ NvOdmServicesPmuClose(hOdmUart->hPmu);
+ }
+ NvOdmOsFree(hOdmUart);
+ hOdmUart = NULL;
+ }
+}
+
+NvBool NvOdmUartSuspend(NvOdmUartHandle hOdmUart)
+{
+ return NV_FALSE;
+}
+
+NvBool NvOdmUartResume(NvOdmUartHandle hOdmUart)
+{
+ return NV_FALSE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c
new file mode 100644
index 000000000000..5bd21b2bd51b
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file nvodm_usbulpi.c
+ * @brief <b>Adaptation for USB ULPI </b>
+ *
+ * @Description : Implementation of the USB ULPI adaptation.
+ */
+#include "nvodm_usbulpi.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvodm_keylist_reserved.h"
+#include "nvrm_drf.h"
+#include "nvos.h"
+
+typedef struct NvOdmUsbUlpiRec {
+ NvU64 CurrentGUID;
+} NvOdmUsbUlpi;
+
+/* ST-Ericsson U3XX modem power control */
+struct ste_u3xx_info {
+ NvU32 ste_u3xx_uart_port;
+ NvU32 ste_u3xx_reset_port;
+ NvU32 ste_u3xx_reset_pin;
+ NvU32 ste_u3xx_power_port;
+ NvU32 ste_u3xx_power_pin;
+ NvU32 ste_u3xx_awr_port;
+ NvU32 ste_u3xx_awr_pin;
+ NvU32 ste_u3xx_cwr_port;
+ NvU32 ste_u3xx_cwr_pin;
+ NvU32 ste_u3xx_spi_int_port;
+ NvU32 ste_u3xx_spi_int_pin;
+ NvU32 ste_u3xx_slave_select_port;
+ NvU32 ste_u3xx_slave_select_pin;
+ NvU32 ste_u3xx_slink_instance;
+};
+
+/* ST-Ericsson U3XX modem control */
+static struct ste_u3xx_info ste_u3xx_info;
+static NvOdmServicesGpioHandle ste_u3xx_gpio;
+static NvOdmGpioPinHandle ste_u3xx_reset_gpio_pin;
+static NvOdmGpioPinHandle ste_u3xx_power_gpio_pin;
+static NvOdmGpioPinHandle ste_u3xx_awr_gpio_pin;
+static NvOdmGpioPinHandle ste_u3xx_cwr_gpio_pin;
+
+static int ste_u3xx_query(struct ste_u3xx_info *info)
+{
+ NvU64 guid = NV_ODM_GUID('e', 'm', 'p', ' ', 'M', '5', '7', '0');
+ NvOdmPeripheralConnectivity *pConnectivity;
+
+ /* query odm kit for modem support */
+ pConnectivity =
+ (NvOdmPeripheralConnectivity *) NvOdmPeripheralGetGuid(guid);
+ if (pConnectivity == NULL)
+ return -1;
+ NV_ASSERT(pConnectivity->NumAddress >= 5);
+
+ /* query for uart port */
+ NV_ASSERT(pConnectivity->AddressList[0].Interface ==
+ NvOdmIoModule_Uart);
+ info->ste_u3xx_uart_port = pConnectivity->AddressList[0].Instance;
+
+ /* query for reset pin */
+ NV_ASSERT(pConnectivity->AddressList[1].Interface ==
+ NvOdmIoModule_Gpio);
+ info->ste_u3xx_reset_port = pConnectivity->AddressList[1].Instance;
+ info->ste_u3xx_reset_pin = pConnectivity->AddressList[1].Address;
+
+ /* query for power pin */
+ NV_ASSERT(pConnectivity->AddressList[2].Interface ==
+ NvOdmIoModule_Gpio);
+ info->ste_u3xx_power_port = pConnectivity->AddressList[2].Instance;
+ info->ste_u3xx_power_pin = pConnectivity->AddressList[2].Address;
+
+ /* query for ACPU wakeup request pin */
+ NV_ASSERT(pConnectivity->AddressList[3].Interface ==
+ NvOdmIoModule_Gpio);
+ info->ste_u3xx_awr_port = pConnectivity->AddressList[3].Instance;
+ info->ste_u3xx_awr_pin = pConnectivity->AddressList[3].Address;
+
+ /* query for CCPU wakeup request pin */
+ NV_ASSERT(pConnectivity->AddressList[4].Interface ==
+ NvOdmIoModule_Gpio);
+ info->ste_u3xx_cwr_port = pConnectivity->AddressList[4].Instance;
+ info->ste_u3xx_cwr_pin = pConnectivity->AddressList[4].Address;
+
+ return 0;
+}
+
+static void ste_u3xx_turn_on_modem(struct ste_u3xx_info *info)
+{
+ /* get odm gpio handle */
+ ste_u3xx_gpio = NvOdmGpioOpen();
+ if (!ste_u3xx_gpio)
+ return;
+
+ /* acquire pin handle for reset pin */
+ ste_u3xx_reset_gpio_pin =
+ NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_reset_port,
+ info->ste_u3xx_reset_pin);
+ if (!ste_u3xx_reset_gpio_pin) {
+ NvOdmGpioClose(ste_u3xx_gpio);
+ return;
+ }
+
+ /* acquire pin handle for power pin */
+ ste_u3xx_power_gpio_pin =
+ NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_power_port,
+ info->ste_u3xx_power_pin);
+ if (!ste_u3xx_power_gpio_pin) {
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio,
+ ste_u3xx_reset_gpio_pin);
+ NvOdmGpioClose(ste_u3xx_gpio);
+ return;
+ }
+
+ /* acquire pin handle for ACPU wakeup request pin */
+ ste_u3xx_awr_gpio_pin =
+ NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_awr_port,
+ info->ste_u3xx_awr_pin);
+ if (!ste_u3xx_awr_gpio_pin) {
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio,
+ ste_u3xx_power_gpio_pin);
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio,
+ ste_u3xx_reset_gpio_pin);
+ NvOdmGpioClose(ste_u3xx_gpio);
+ return;
+ }
+
+ /* acquire pin handle for CCPU wakeup request pin */
+ ste_u3xx_cwr_gpio_pin =
+ NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_cwr_port,
+ info->ste_u3xx_cwr_pin);
+ if (!ste_u3xx_cwr_gpio_pin) {
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_awr_gpio_pin);
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio,
+ ste_u3xx_power_gpio_pin);
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio,
+ ste_u3xx_reset_gpio_pin);
+ NvOdmGpioClose(ste_u3xx_gpio);
+ return;
+ }
+
+ /* set output levels - start with modem power off, reset deasserted */
+ NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, 0);
+ NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin, 0);
+ NvOdmGpioConfig(ste_u3xx_gpio, ste_u3xx_power_gpio_pin,
+ NvOdmGpioPinMode_Output);
+ NvOdmGpioConfig(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin,
+ NvOdmGpioPinMode_Output);
+ NvOdmGpioConfig(ste_u3xx_gpio, ste_u3xx_cwr_gpio_pin,
+ NvOdmGpioPinMode_InputData);
+
+ NvOdmOsSleepMS(300);
+ NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin, 1);
+
+ /* pulse modem power on for 300 ms */
+ NvOdmOsSleepMS(300);
+ NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, 1);
+ NvOdmOsSleepMS(300);
+ NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, 0);
+ NvOdmOsSleepMS(100);
+
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_cwr_gpio_pin);
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_awr_gpio_pin);
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_power_gpio_pin);
+ NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin);
+ NvOdmGpioClose(ste_u3xx_gpio);
+}
+
+NvOdmUsbUlpiHandle NvOdmUsbUlpiOpen(NvU32 Instance)
+{
+ const NvOdmUsbProperty *pUsbProperty =
+ NvOdmQueryGetUsbProperty(NvOdmIoModule_Usb, Instance);
+ NvOdmUsbUlpi *pDevice = NULL;
+
+ pDevice = NvOdmOsAlloc(sizeof(NvOdmUsbUlpi));
+ if (pDevice == NULL)
+ goto ExitUlpiOdm;
+
+ if (pUsbProperty->UsbInterfaceType ==
+ NvOdmUsbInterfaceType_UlpiNullPhy) {
+ /* query the modem control pins */
+ if (ste_u3xx_query(&ste_u3xx_info) < 0)
+ goto ExitUlpiOdm;
+
+ NvOsDebugPrintf("turn modem on\n");
+ ste_u3xx_turn_on_modem(&ste_u3xx_info);
+ }
+ return pDevice;
+
+ExitUlpiOdm:
+ if (pDevice)
+ NvOdmOsFree(pDevice);
+ return NULL;
+}
+
+void NvOdmUsbUlpiClose(NvOdmUsbUlpiHandle hOdmUlpi)
+{
+ if (hOdmUlpi) {
+ NvOdmOsFree(hOdmUlpi);
+ hOdmUlpi = NULL;
+ }
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile
new file mode 100644
index 000000000000..b19449bd3cfa
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile
@@ -0,0 +1,18 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x
+
+obj-y += pmu_hal.o
+obj-y += max8907b/
+obj-y += pcf50626/
+obj-y += tps6586x/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile
new file mode 100644
index 000000000000..321377d9317f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile
@@ -0,0 +1,22 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b
+
+obj-y += ad5258_dpm.o
+obj-y += fan5355_buck_i2c.o
+obj-y += max8907b_adc.o
+obj-y += max8907b_batterycharger.o
+obj-y += max8907b.o
+obj-y += max8907b_i2c.o
+obj-y += max8907b_interrupt.o
+obj-y += max8907b_rtc.o
+obj-y += mic2826_i2c.o
+obj-y += tca6416_expander_i2c.o
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c
new file mode 100644
index 000000000000..7f785f920afc
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+#include "ad5258_dpm.h"
+
+
+static NvBool
+Ad5258I2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvU32 i;
+ NvU8 WriteBuffer[2];
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+
+ for (i = 0; i < AD5258_I2C_RETRY_CNT; i++)
+ {
+ WriteBuffer[0] = Addr & 0xFF; // AD5258 address
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = AD5258_SLAVE_ADDR;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ AD5258_I2C_SPEED_KHZ, AD5258_I2C_TIMEOUT_MS);
+ if (status == NvOdmI2cStatus_Success)
+ return NV_TRUE;
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmDpmI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmDpmI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+static NvBool
+Ad5258I2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data)
+{
+ NvU32 i;
+ NvU8 ReadBuffer = 0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ for (i = 0; i < AD5258_I2C_RETRY_CNT; i++)
+ {
+ // The AD5258 register address
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[0].Address = AD5258_SLAVE_ADDR;
+ TransactionInfo[0].Buf = &ReadBuffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+
+ TransactionInfo[1].Address = (AD5258_SLAVE_ADDR | 0x1);;
+ TransactionInfo[1].Buf = &ReadBuffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ // Read data from PMU at the specified offset
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2,
+ AD5258_I2C_SPEED_KHZ, AD5258_I2C_TIMEOUT_MS);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ *Data = ReadBuffer;
+ return NV_TRUE;
+ }
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmDpmI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmDpmI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+NvBool
+Ad5258I2cSetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 MilliVolts)
+{
+ static NvU32 s_LastMilliVolts = 0;
+
+ NvU8 Data = 0;
+ NvU8 Addr = AD5258_RDAC_ADDR;
+
+ if (s_LastMilliVolts == 0)
+ {
+ if (!Ad5258I2cGetVoltage(hDevice, &s_LastMilliVolts))
+ return NV_FALSE;
+ NV_ASSERT((s_LastMilliVolts >= AD5258_V0) &&
+ (s_LastMilliVolts <= AD5258_VMAX));
+ }
+
+ // Change voltage level one maximum allowed step at a time
+ while (s_LastMilliVolts != MilliVolts)
+ {
+ if (MilliVolts > s_LastMilliVolts + AD5258_MAX_STEP_MV)
+ s_LastMilliVolts += AD5258_MAX_STEP_MV;
+ else if (MilliVolts + AD5258_MAX_STEP_MV < s_LastMilliVolts)
+ s_LastMilliVolts -= AD5258_MAX_STEP_MV;
+ else
+ s_LastMilliVolts = MilliVolts;
+
+ // D(Vout) = (Vout - V0) * M1 / 2^b
+ Data = 0;
+ if (s_LastMilliVolts > AD5258_V0)
+ {
+ Data = (NvU8)(((s_LastMilliVolts - AD5258_V0) * AD5258_M1 +
+ (0x1 << (AD5258_b - 1))) >> AD5258_b);
+ Data++; // account for load
+ }
+ NV_ASSERT(Data <= AD5258_RDAC_MASK);
+ if (!Ad5258I2cWrite8(hDevice, Addr, Data))
+ return NV_FALSE;
+ NvOdmOsWaitUS(AD5258_MAX_STEP_SETTLE_TIME_US);
+ }
+ return NV_TRUE;
+}
+
+NvBool
+Ad5258I2cGetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* pMilliVolts)
+{
+ NvU8 Data = 0;
+ NvU8 Addr = AD5258_RDAC_ADDR;
+
+ if (!Ad5258I2cRead8(hDevice, Addr, &Data))
+ return NV_FALSE;
+
+ // Vout(D) = V0 + (D * M2) / 2^b
+ Data &= AD5258_RDAC_MASK;
+ *pMilliVolts = AD5258_V0 +
+ (((NvU32)Data * AD5258_M2 + (0x1 << (AD5258_b - 1))) >> AD5258_b);
+
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h
new file mode 100644
index 000000000000..8bfd23eecf59
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_AD5258_DPM_I2C_H
+#define INCLUDED_AD5258_DPM_I2C_H
+
+#include "nvodm_pmu.h"
+#include "max8907b.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define AD5258_SLAVE_ADDR (0x9C) // (7'h4E)
+#define AD5258_I2C_SPEED_KHZ (400)
+#define AD5258_I2C_RETRY_CNT (2)
+#define AD5258_I2C_TIMEOUT_MS (1000)
+
+#define AD5258_RDAC_ADDR (0x0)
+#define AD5258_RDAC_MASK (0x3F)
+
+/*
+ * Linear approximation of digital potentiometer (DPM) scaling ladder:
+ * D(Vout) = (Vout - V0) * M1 / 2^b
+ * Vout(D) = V0 + (D * M2) / 2^b
+ * D - DPM setting, Vout - output voltage in mV, b - fixed point calculation
+ * precision, approximation parameters V0, M1, M2 are determined for the
+ * particular schematic combining constant resistors, DPM, and DCDC supply.
+ */
+// On Whistler:
+#define AD5258_V0 (815)
+#define AD5258_M1 (229)
+#define AD5258_M2 (4571)
+#define AD5258_b (10)
+
+#define AD5258_VMAX (AD5258_V0 + ((AD5258_RDAC_MASK * AD5258_M2 + \
+ (0x1 << (AD5258_b - 1))) >> AD5258_b))
+
+// Minimum voltage step is determined by DPM resolution, maximum voltage step
+// is limited to keep dynamic over/under shoot within +/- 50mV
+#define AD5258_MIN_STEP_MV ((AD5258_M2 + (0x1 << AD5258_b) - 1) >> AD5258_b)
+#define AD5258_MAX_STEP_MV (50)
+#define AD5258_MAX_STEP_SETTLE_TIME_US (20)
+#define AD5258_TURN_ON_TIME_US (2000)
+
+NvBool
+Ad5258I2cSetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 MilliVolts);
+
+NvBool
+Ad5258I2cGetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* pMilliVolts);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_AD5258_DPM_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c
new file mode 100644
index 000000000000..bb00b0bbab1f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+#include "fan5355_buck_i2c.h"
+#include "fan5355_buck_reg.h"
+
+// Function declaration
+NvBool Fan5355I2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+
+ WriteBuffer[0] = Addr & 0xFF; // PMU offset
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = FAN5335_SLAVE_ADDR;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ FAN5335_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool Fan5355I2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data)
+{
+ NvU8 ReadBuffer = 0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ // Write the PMU offset
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[0].Address = FAN5335_SLAVE_ADDR;
+ TransactionInfo[0].Buf = &ReadBuffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+
+ TransactionInfo[1].Address = (FAN5335_SLAVE_ADDR | 0x1);;
+ TransactionInfo[1].Buf = &ReadBuffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ // Read data from PMU at the specified offset
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2,
+ FAN5335_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = ReadBuffer;
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h
new file mode 100644
index 000000000000..7df90a192769
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_FAN5355_BUCK_I2C_H
+#define INCLUDED_FAN5355_BUCK_I2C_H
+
+#include "nvodm_pmu.h"
+#include "max8907b.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define FAN5335_SLAVE_ADDR 0x94 // (7'h4A)
+#define FAN5335_I2C_SPEED_KHZ 400
+
+NvBool Fan5355I2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data);
+
+NvBool Fan5355I2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_FAN5355_BUCK_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h
new file mode 100644
index 000000000000..104be89ac462
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_FAN5355_BUCK_REG_HEADER
+#define INCLUDED_FAN5355_BUCK_REG_HEADER
+
+// Registers
+
+/* field defines for register bit ops */
+
+#define FAN5335_VSEL0 0x0
+#define FAN5335_VSEL1 0x1
+#define FAN5335_CONTROL1 0x2
+#define FAN5335_CONTROL2 0x3
+
+#define FAN5335_REG_INVALID 0xFF
+
+#endif //INCLUDED_FAN5355_BUCK_REG_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c
new file mode 100644
index 000000000000..285044034f97
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c
@@ -0,0 +1,2324 @@
+/*
+ * Copyright (c) 2007-2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_query_discovery.h"
+#include "nvodm_query.h"
+#include "nvodm_services.h"
+#include "max8907b.h"
+#include "max8907b_reg.h"
+#include "max8907b_adc.h"
+#include "max8907b_i2c.h"
+#include "max8907b_interrupt.h"
+#include "max8907b_batterycharger.h"
+#include "max8907b_supply_info_table.h"
+#include "fan5355_buck_reg.h"
+#include "fan5355_buck_i2c.h"
+#include "tca6416_expander_reg.h"
+#include "tca6416_expander_i2c.h"
+#include "mic2826_reg.h"
+#include "mic2826_i2c.h"
+#include "ad5258_dpm.h"
+
+// Private PMU context info
+Max8907bPrivData *hMax8907bPmu;
+
+#define PMUGUID NV_ODM_GUID('m','a','x','8','9','0','7','b')
+
+#define MAX_CHARGER_LIMIT_MA 1000
+
+#define ALWAYS_ONLINE (1)
+
+/**
+ * MAX8907B regulators can be enabled/disabled via s/w I2C commands only
+ * when MAX8907B_SEQSEL_I2CEN_LXX (7) is selected as regulator sequencer.
+ * Otherwise, regulator is controlled by h/w sequencers: SEQ1 (SYSEN),
+ * which is always On when PMU is On, or SEQ2 (PWREN) which is always On,
+ * when system is running (it is Off in LPx mode only).
+ */
+#define MAX8907B_OUT_VOLTAGE_CONTROL_MASK \
+ ((MAX8907B_CTL_SEQ_MASK << MAX8907B_CTL_SEQ_SHIFT) | \
+ MAX8907B_OUT_VOLTAGE_ENABLE_BIT)
+
+#define MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE \
+ (MAX8907B_SEQSEL_I2CEN_LXX << MAX8907B_CTL_SEQ_SHIFT)
+
+// MAX8907B revision that requires s/w WAR to connect PWREN input to
+// sequencer 2 because of the bug in the silicon.
+#define MAX8907B_II2RR_PWREN_WAR (0x12)
+
+/**
+* The FAN5355 is used to scale the voltage of an external
+* DC/DC voltage rail (for PCIE). However, voltage scaling is
+* not required for this source, since the 1.05V default
+* voltage when enabled is OK. On some boards, the FAN5355 may
+* not function properly, as an I2C re-work may be required
+* (otherwise, the slave address may not be found). Therefore,
+* this feature is disabled by default.
+*/
+#undef MAX8907B_USE_FAN5355_VOLTAGE_SCALING
+
+/*-- Output Voltage tables --*/
+
+// V1, V2 (millivolts x 10)
+static const NvU32 VoltageTable_SD_A[] = {
+ 6375, 6500, 6625, 6750, 6875, 7000, 7125, 7250,
+ 7375, 7500, 7625, 7750, 7875, 8000, 8125, 8250,
+ 8375, 8500, 8625, 8750, 8875, 9000, 9125, 9250,
+ 9375, 9500, 9625, 9750, 9875, 10000, 10125, 10250,
+ 10375, 10500, 10625, 10750, 10875, 11000, 11125, 11250,
+ 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250,
+ 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250,
+ 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250
+};
+
+// V3, LDO1, LDO4-LDO16, LDO19-20 (millivolts)
+static const NvU32 VoltageTable_SD_B_LDO_B[] = {
+ 750, 800, 850, 900, 950, 1000, 1050, 1100,
+ 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500,
+ 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900,
+ 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300,
+ 2350, 2400, 2450, 2500, 2550, 2600, 2650, 2700,
+ 2750, 2800, 2850, 2900, 2950, 3000, 3050, 3100,
+ 3150, 3200, 3250, 3300, 3350, 3400, 3450, 3500,
+ 3550, 3600, 3650, 3700, 3750, 3800, 3850, 3900
+};
+
+// LDO2, LDO3, LDO17, LDO18 (millivolts)
+static const NvU32 VoltageTable_LDO_A[] = {
+ 650, 675, 700, 725, 750, 775, 800, 825,
+ 850, 875, 900, 925, 950, 975, 1000, 1025,
+ 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1225,
+ 1250, 1275, 1300, 1325, 1350, 1375, 1400, 1425,
+ 1450, 1475, 1500, 1525, 1550, 1575, 1600, 1625,
+ 1650, 1675, 1700, 1725, 1750, 1775, 1800, 1825,
+ 1850, 1875, 1900, 1925, 1950, 1975, 2000, 2025,
+ 2050, 2075, 2100, 2125, 2150, 2175, 2200, 2225
+};
+
+// FAN5355 VOUT_02 (millivolts x 10)
+static const NvU32 VoltageTable_VOUT_02[] = {
+ 7500, 7625, 7750, 7875, 8000, 8125, 8250, 8375,
+ 8500, 8625, 8750, 8875, 9000, 9125, 9250, 9375,
+ 9500, 9625, 9750, 9875, 10000, 10125, 10250, 10375,
+ 10500, 10625, 10750, 10875, 11000, 11125, 11250, 11375,
+ 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375,
+ 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375,
+ 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375,
+};
+
+/*-- Sequencer table --*/
+
+// Timer period, microseconds (us).
+// Specifies the time between each sequencer event.
+
+// Disable temporarily to keep the compiler happy.
+//static const NvU32 SequencerPeriod[] = { 20, 40, 80, 160, 320, 640, 1280, 2560 };
+
+/*-- Voltage translation functions --*/
+
+// OutVoltageIndex is the lower six bits of the output voltage registers, VO[5:0]
+static NvU32 Max8907bPmuVoltageGet_SD_A(const NvU32 OutVoltageIndex);
+static NvU32 Max8907bPmuVoltageGet_SD_B_LDO_B(const NvU32 OutVoltageIndex);
+static NvU32 Max8907bPmuVoltageGet_LDO_A(const NvU32 OutVoltageIndex);
+
+static NvU32 Max8907bPmuVoltageSet_SD_A(const NvU32 OutMilliVolts);
+static NvU32 Max8907bPmuVoltageSet_SD_B_LDO_B(const NvU32 OutMilliVolts);
+static NvU32 Max8907bPmuVoltageSet_LDO_A(const NvU32 OutMilliVolts);
+
+#define MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX 0x3F
+#define FAN5355_MAX_OUTPUT_VOLTAGE_INDEX 0x37
+
+static NvU32 Max8907bPmuVoltageGet_SD_A(const NvU32 OutVoltageIndex)
+{
+ NV_ASSERT(OutVoltageIndex <= MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX);
+ return VoltageTable_SD_A[OutVoltageIndex]/10;
+}
+
+static NvU32 Max8907bPmuVoltageGet_SD_B_LDO_B(const NvU32 OutVoltageIndex)
+{
+ NV_ASSERT(OutVoltageIndex <= MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX);
+ return VoltageTable_SD_B_LDO_B[OutVoltageIndex];
+}
+
+static NvU32 Max8907bPmuVoltageGet_LDO_A(const NvU32 OutVoltageIndex)
+{
+ NV_ASSERT(OutVoltageIndex <= MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX);
+ return VoltageTable_LDO_A[OutVoltageIndex];
+}
+
+// Secondary PMU MIC2826 API
+static NvBool MIC2826ReadVoltageReg(NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail, NvU32* pMilliVolts);
+
+static NvBool MIC2826WriteVoltageReg( NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail, NvU32 MilliVolts, NvU32* pSettleMicroSeconds);
+
+const NvU8 MIC2826_BUCK_Votage_Table[] =
+{
+ MIC2826_BUCK_OUT_VOLTAGE_0800,
+ MIC2826_BUCK_OUT_VOLTAGE_0825,
+ MIC2826_BUCK_OUT_VOLTAGE_0850,
+ MIC2826_BUCK_OUT_VOLTAGE_0875,
+ MIC2826_BUCK_OUT_VOLTAGE_0900,
+ MIC2826_BUCK_OUT_VOLTAGE_0925,
+ MIC2826_BUCK_OUT_VOLTAGE_0950,
+ MIC2826_BUCK_OUT_VOLTAGE_0975,
+ MIC2826_BUCK_OUT_VOLTAGE_1000,
+ MIC2826_BUCK_OUT_VOLTAGE_1025,
+ MIC2826_BUCK_OUT_VOLTAGE_1050,
+ MIC2826_BUCK_OUT_VOLTAGE_1075,
+ MIC2826_BUCK_OUT_VOLTAGE_1100,
+ MIC2826_BUCK_OUT_VOLTAGE_1125,
+ MIC2826_BUCK_OUT_VOLTAGE_1150,
+ MIC2826_BUCK_OUT_VOLTAGE_1175,
+ MIC2826_BUCK_OUT_VOLTAGE_1200,
+ MIC2826_BUCK_OUT_VOLTAGE_1250,
+ MIC2826_BUCK_OUT_VOLTAGE_1300,
+ MIC2826_BUCK_OUT_VOLTAGE_1350,
+ MIC2826_BUCK_OUT_VOLTAGE_1400,
+ MIC2826_BUCK_OUT_VOLTAGE_1450,
+ MIC2826_BUCK_OUT_VOLTAGE_1500,
+ MIC2826_BUCK_OUT_VOLTAGE_1550,
+ MIC2826_BUCK_OUT_VOLTAGE_1600,
+ MIC2826_BUCK_OUT_VOLTAGE_1650,
+ MIC2826_BUCK_OUT_VOLTAGE_1700,
+ MIC2826_BUCK_OUT_VOLTAGE_1750,
+ MIC2826_BUCK_OUT_VOLTAGE_1800
+};
+
+const NvU8 MIC2826_LDO_Votage_Table[] =
+{
+ MIC2826_LDO_OUT_VOLTAGE_0800,
+ MIC2826_LDO_OUT_VOLTAGE_0850,
+ MIC2826_LDO_OUT_VOLTAGE_0900,
+ MIC2826_LDO_OUT_VOLTAGE_0950,
+ MIC2826_LDO_OUT_VOLTAGE_1000,
+ MIC2826_LDO_OUT_VOLTAGE_1050,
+ MIC2826_LDO_OUT_VOLTAGE_1100,
+ MIC2826_LDO_OUT_VOLTAGE_1150,
+ MIC2826_LDO_OUT_VOLTAGE_1200,
+ MIC2826_LDO_OUT_VOLTAGE_1250,
+ MIC2826_LDO_OUT_VOLTAGE_1300,
+ MIC2826_LDO_OUT_VOLTAGE_1350,
+ MIC2826_LDO_OUT_VOLTAGE_1400,
+ MIC2826_LDO_OUT_VOLTAGE_1450,
+ MIC2826_LDO_OUT_VOLTAGE_1500,
+ MIC2826_LDO_OUT_VOLTAGE_1550,
+ MIC2826_LDO_OUT_VOLTAGE_1600,
+ MIC2826_LDO_OUT_VOLTAGE_1650,
+ MIC2826_LDO_OUT_VOLTAGE_1700,
+ MIC2826_LDO_OUT_VOLTAGE_1750,
+ MIC2826_LDO_OUT_VOLTAGE_1800,
+ MIC2826_LDO_OUT_VOLTAGE_1850,
+ MIC2826_LDO_OUT_VOLTAGE_1900,
+ MIC2826_LDO_OUT_VOLTAGE_1950,
+ MIC2826_LDO_OUT_VOLTAGE_2000,
+ MIC2826_LDO_OUT_VOLTAGE_2050,
+ MIC2826_LDO_OUT_VOLTAGE_2100,
+ MIC2826_LDO_OUT_VOLTAGE_2150,
+ MIC2826_LDO_OUT_VOLTAGE_2200,
+ MIC2826_LDO_OUT_VOLTAGE_2250,
+ MIC2826_LDO_OUT_VOLTAGE_2300,
+ MIC2826_LDO_OUT_VOLTAGE_2350,
+ MIC2826_LDO_OUT_VOLTAGE_2400,
+ MIC2826_LDO_OUT_VOLTAGE_2450,
+ MIC2826_LDO_OUT_VOLTAGE_2500,
+ MIC2826_LDO_OUT_VOLTAGE_2550,
+ MIC2826_LDO_OUT_VOLTAGE_2600,
+ MIC2826_LDO_OUT_VOLTAGE_2650,
+ MIC2826_LDO_OUT_VOLTAGE_2700,
+ MIC2826_LDO_OUT_VOLTAGE_2750,
+ MIC2826_LDO_OUT_VOLTAGE_2800,
+ MIC2826_LDO_OUT_VOLTAGE_2850,
+ MIC2826_LDO_OUT_VOLTAGE_2900,
+ MIC2826_LDO_OUT_VOLTAGE_2950,
+ MIC2826_LDO_OUT_VOLTAGE_3000,
+ MIC2826_LDO_OUT_VOLTAGE_3050,
+ MIC2826_LDO_OUT_VOLTAGE_3100,
+ MIC2826_LDO_OUT_VOLTAGE_3150,
+ MIC2826_LDO_OUT_VOLTAGE_3200,
+ MIC2826_LDO_OUT_VOLTAGE_3250,
+ MIC2826_LDO_OUT_VOLTAGE_3300
+};
+
+#define MIC2826_BUCK_Votage_Table_Size NV_ARRAY_SIZE(MIC2826_BUCK_Votage_Table)
+#define MIC2826_LDO_Votage_Table_Size NV_ARRAY_SIZE(MIC2826_LDO_Votage_Table)
+
+#ifndef MIN
+#define MIN(a, b) (a) <= (b) ? (a) : (b)
+#endif
+
+#define MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10 6375 // 637.5 mV
+#define MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B 750 // 750 mV
+#define MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A 650 // 650 mV
+#define FAN5355_MIN_OUTPUT_VOLTAGE_x10 7500 // 750.0 mV
+
+#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10 125 // 12.5 mV
+#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B 50 // 50 mV
+#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A 25 // 25 mV
+#define FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10 125 // 12.5 mV
+
+#define MAX8907B_MAX_OUTPUT_VOLTAGE_SD_A_x10 14250 // 1,425.0 mV
+#define MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B 3900 // 3,900 mV
+#define MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A 2225 // 2,225 mV
+#define FAN5355_MAX_OUTPUT_VOLTAGE_x10 14375 // 1,437.5 mV
+
+#define MAX8907B_MIN_OUTPUT_VOLTAGE_RTC 0 // 0 mV
+#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_RTC 1 // Protected; use dummy, non-zero value
+//#define MAX8907B_MAX_OUTPUT_VOLTAGE_RTC 3300 // 3,300 mV
+// WHISTLER/AP16 - Make this 1.2V for now, since ap15rm_power.c expects it that way.
+#define MAX8907B_MAX_OUTPUT_VOLTAGE_RTC 1200
+
+static NvU32 Max8907bPmuVoltageSet_SD_A(const NvU32 OutMilliVolts)
+{
+ if (OutMilliVolts < MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10/10)
+ return 0;
+ else
+ return MIN( \
+ (OutMilliVolts*10 - MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10) / \
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10, \
+ MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX);
+}
+
+static NvU32 Max8907bPmuVoltageSet_SD_B_LDO_B(const NvU32 OutMilliVolts)
+{
+ if (OutMilliVolts < MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B)
+ return 0;
+ else
+ return MIN( \
+ (OutMilliVolts - MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B) / \
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, \
+ MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX);
+}
+
+static NvU32 Max8907bPmuVoltageSet_LDO_A(const NvU32 OutMilliVolts)
+{
+ if (OutMilliVolts < MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A)
+ return 0;
+ else
+ return MIN( \
+ (OutMilliVolts - MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A) / \
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A, \
+ MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX);
+}
+
+static NvU32 Fan5355PmuVoltageGet_VOUT_02(const NvU32 OutVoltageIndex)
+{
+ NV_ASSERT(OutVoltageIndex <= FAN5355_MAX_OUTPUT_VOLTAGE_INDEX);
+ return VoltageTable_VOUT_02[OutVoltageIndex]/10;
+}
+
+static NvU32 Fan5355PmuVoltageSet_VOUT_02(const NvU32 OutMilliVolts)
+{
+ if (OutMilliVolts < FAN5355_MIN_OUTPUT_VOLTAGE_x10/10)
+ return 0;
+ else
+ return MIN( \
+ (OutMilliVolts*10 - FAN5355_MIN_OUTPUT_VOLTAGE_x10) / \
+ FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10, \
+ FAN5355_MAX_OUTPUT_VOLTAGE_x10);
+}
+
+// This board-specific table is indexed by Max8907bPmuSupply
+const Max8907bPmuSupplyInfo Max8907bSupplyInfoTable[] =
+{
+ {
+ Max8907bPmuSupply_Invalid,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {NV_TRUE, 0, 0, 0, 0},
+ },
+
+ // LX_V1 (V1)
+ {
+ Max8907bPmuSupply_LX_V1,
+ MAX8907B_SDCTL1,
+ MAX8907B_SDSEQCNT1,
+ MAX8907B_SDV1,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_A,
+ Max8907bPmuVoltageSet_SD_A,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10/10,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10/10,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_A_x10/10,
+ MAX8907B_REQUESTVOLTAGE_LX_V1
+ },
+ },
+
+ // LX_V2 (V2)
+ {
+ Max8907bPmuSupply_LX_V2,
+ MAX8907B_SDCTL2,
+ MAX8907B_SDSEQCNT2,
+ MAX8907B_SDV2,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_A,
+ Max8907bPmuVoltageSet_SD_A,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10/10,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10/10,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_A_x10/10,
+ MAX8907B_REQUESTVOLTAGE_LX_V2
+ },
+ },
+
+ // LX_V3 (V3)
+ {
+ Max8907bPmuSupply_LX_V3,
+ MAX8907B_SDCTL3,
+ MAX8907B_SDSEQCNT3,
+ MAX8907B_SDV3,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LX_V3
+ },
+ },
+
+ // VRTC (RTC)
+ {
+ Max8907bPmuSupply_VRTC,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_TRUE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_RTC,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_RTC,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_RTC,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_RTC
+ },
+ },
+
+ // LDO1 (VOUT1)
+ {
+ Max8907bPmuSupply_LDO1,
+ MAX8907B_LDOCTL1,
+ MAX8907B_LDOSEQCNT1,
+ MAX8907B_LDO1VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO1
+ },
+ },
+
+ // LDO2 (VOUT2)
+ {
+ Max8907bPmuSupply_LDO2,
+ MAX8907B_LDOCTL2,
+ MAX8907B_LDOSEQCNT2,
+ MAX8907B_LDO2VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_LDO_A,
+ Max8907bPmuVoltageSet_LDO_A,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_REQUESTVOLTAGE_LDO2
+ },
+ },
+
+ // LDO3 (VOUT3)
+ {
+ Max8907bPmuSupply_LDO3,
+ MAX8907B_LDOCTL3,
+ MAX8907B_LDOSEQCNT3,
+ MAX8907B_LDO3VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_LDO_A,
+ Max8907bPmuVoltageSet_LDO_A,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_REQUESTVOLTAGE_LDO3
+ },
+ },
+
+ // LDO4 (VOUT4)
+ {
+ Max8907bPmuSupply_LDO4,
+ MAX8907B_LDOCTL4,
+ MAX8907B_LDOSEQCNT4,
+ MAX8907B_LDO4VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO4
+ },
+ },
+
+ // LDO5 (VOUT5)
+ {
+ Max8907bPmuSupply_LDO5,
+ MAX8907B_LDOCTL5,
+ MAX8907B_LDOSEQCNT5,
+ MAX8907B_LDO5VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO5
+ },
+ },
+
+ // LDO6 (VOUT6)
+ {
+ Max8907bPmuSupply_LDO6,
+ MAX8907B_LDOCTL6,
+ MAX8907B_LDOSEQCNT6,
+ MAX8907B_LDO6VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO6
+ },
+ },
+
+ // LDO7 (VOUT7)
+ {
+ Max8907bPmuSupply_LDO7,
+ MAX8907B_LDOCTL7,
+ MAX8907B_LDOSEQCNT7,
+ MAX8907B_LDO7VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO7
+ },
+ },
+
+ // LDO8 (VOUT8)
+ {
+ Max8907bPmuSupply_LDO8,
+ MAX8907B_LDOCTL8,
+ MAX8907B_LDOSEQCNT8,
+ MAX8907B_LDO8VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO8
+ },
+ },
+
+ // LDO9 (VOUT9)
+ {
+ Max8907bPmuSupply_LDO9,
+ MAX8907B_LDOCTL9,
+ MAX8907B_LDOSEQCNT9,
+ MAX8907B_LDO9VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO9
+ },
+ },
+
+ // LDO10 (VOUT10)
+ {
+ Max8907bPmuSupply_LDO10,
+ MAX8907B_LDOCTL10,
+ MAX8907B_LDOSEQCNT10,
+ MAX8907B_LDO10VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO10
+ },
+ },
+
+ // LDO11 (VOUT11)
+ {
+ Max8907bPmuSupply_LDO11,
+ MAX8907B_LDOCTL11,
+ MAX8907B_LDOSEQCNT11,
+ MAX8907B_LDO11VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO11
+ },
+ },
+
+ // LDO12 (VOUT12)
+ {
+ Max8907bPmuSupply_LDO12,
+ MAX8907B_LDOCTL12,
+ MAX8907B_LDOSEQCNT12,
+ MAX8907B_LDO12VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO12
+ },
+ },
+
+ // LDO13 (VOUT13)
+ {
+ Max8907bPmuSupply_LDO13,
+ MAX8907B_LDOCTL13,
+ MAX8907B_LDOSEQCNT13,
+ MAX8907B_LDO13VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO13
+ },
+ },
+
+ // LDO14 (VOUT14)
+ {
+ Max8907bPmuSupply_LDO14,
+ MAX8907B_LDOCTL14,
+ MAX8907B_LDOSEQCNT14,
+ MAX8907B_LDO14VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO14
+ },
+ },
+
+ // LDO15 (VOUT15)
+ {
+ Max8907bPmuSupply_LDO15,
+ MAX8907B_LDOCTL15,
+ MAX8907B_LDOSEQCNT15,
+ MAX8907B_LDO15VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO15
+ },
+ },
+
+ // LDO16 (VOUT16)
+ {
+ Max8907bPmuSupply_LDO16,
+ MAX8907B_LDOCTL16,
+ MAX8907B_LDOSEQCNT16,
+ MAX8907B_LDO16VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO16
+ },
+ },
+
+ // LDO17 (VOUT17)
+ {
+ Max8907bPmuSupply_LDO17,
+ MAX8907B_LDOCTL17,
+ MAX8907B_LDOSEQCNT17,
+ MAX8907B_LDO17VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_LDO_A,
+ Max8907bPmuVoltageSet_LDO_A,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_REQUESTVOLTAGE_LDO17
+ },
+ },
+
+ // LDO18 (VOUT18)
+ {
+ Max8907bPmuSupply_LDO18,
+ MAX8907B_LDOCTL18,
+ MAX8907B_LDOSEQCNT18,
+ MAX8907B_LDO18VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_LDO_A,
+ Max8907bPmuVoltageSet_LDO_A,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A,
+ MAX8907B_REQUESTVOLTAGE_LDO18
+ },
+ },
+
+ // LDO19 (VOUT19)
+ {
+ Max8907bPmuSupply_LDO19,
+ MAX8907B_LDOCTL19,
+ MAX8907B_LDOSEQCNT19,
+ MAX8907B_LDO19VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO19
+ },
+ },
+
+ // LDO20 (VOUT20)
+ {
+ Max8907bPmuSupply_LDO20,
+ MAX8907B_LDOCTL20,
+ MAX8907B_LDOSEQCNT20,
+ MAX8907B_LDO20VOUT,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ Max8907bPmuVoltageGet_SD_B_LDO_B,
+ Max8907bPmuVoltageSet_SD_B_LDO_B,
+ {
+ NV_FALSE,
+ MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B,
+ MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B,
+ MAX8907B_REQUESTVOLTAGE_LDO20
+ },
+ },
+
+ // WHITE_LED
+ {
+ Max8907bPmuSupply_WHITE_LED,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {NV_TRUE, 0, 0, 0, 0},
+ },
+
+ // EXT_DC/DC1 (for HDMI, VGA, USB)
+ // By default, this is hard-wired as "always on" (see schematics)
+ {
+ Max8907bPmuSupply_EXT_DCDC_1,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_TRUE,
+ MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1,
+ 0,
+ MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1,
+ MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1
+ },
+ },
+
+ // EXT_DC/DC2 (not connected / reserved)
+ {
+ Max8907bPmuSupply_EXT_DCDC_2,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {NV_TRUE, 0, 0, 0, 0},
+ },
+
+ // EXT_DC/DC3 (PCI Express)
+ {
+ Max8907bPmuSupply_EXT_DCDC_3,
+ TCA6416_CONFIG_PORT_0,
+ MAX8907B_REG_INVALID,
+ FAN5335_VSEL0,
+ TCA6416_PORT_0,
+ TCA6416_PIN_6,
+ Fan5355PmuVoltageGet_VOUT_02,
+ Fan5355PmuVoltageSet_VOUT_02,
+ {
+ NV_FALSE,
+ FAN5355_MIN_OUTPUT_VOLTAGE_x10/10,
+ FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10/10,
+ FAN5355_MAX_OUTPUT_VOLTAGE_x10/10,
+ MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3
+ },
+ },
+
+ // EXT_DC/DC4 (Backlight-1 Intensity Enable)
+ // By default, this is hard-wired as "always enabled" (see schematics)
+ {
+ Max8907bPmuSupply_EXT_DCDC_4,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {NV_TRUE, 0, 0, 0, 0},
+ },
+
+ // EXT_DC/DC5 (Backlight-2 Intensity Enable)
+ // By default, this is hard-wired as "always enabled" (see schematics)
+ {
+ Max8907bPmuSupply_EXT_DCDC_5,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {NV_TRUE, 0, 0, 0, 0},
+ },
+
+ // EXT_DC/DC6 (not connected / reserved)
+ {
+ Max8907bPmuSupply_EXT_DCDC_6,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {NV_TRUE, 0, 0, 0, 0},
+ },
+
+ // USB1 VBUS is wired from with DCDC_3.
+ {
+ Max8907bPmuSupply_EXT_DCDC_3_USB1,
+ TCA6416_CONFIG_PORT_0,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ TCA6416_PORT_0,
+ TCA6416_PIN_0,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ FAN5355_MIN_OUTPUT_VOLTAGE_x10/10,
+ FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10/10,
+ FAN5355_MAX_OUTPUT_VOLTAGE_x10/10,
+ MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3
+ },
+ },
+
+ // USB3 VBUS is wired from with DCDC_3.
+ {
+ Max8907bPmuSupply_EXT_DCDC_3_USB3,
+ TCA6416_CONFIG_PORT_0,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ TCA6416_PORT_0,
+ TCA6416_PIN_1,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ FAN5355_MIN_OUTPUT_VOLTAGE_x10/10,
+ FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10/10,
+ FAN5355_MAX_OUTPUT_VOLTAGE_x10/10,
+ MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3
+ },
+ },
+
+ // MIC2826 BUCK Regulator(BUCK)
+ {
+ MIC2826PmuSupply_BUCK,
+ MIC2826_REG_ADDR_BUCK,
+ MIC2826_REG_INVALID,
+ MIC2826_REG_INVALID,
+ MIC2826_INVALID_PORT,
+ MIC2826_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ MIC2826_BUCK_VOLTAGE_MIN_MV,
+ MIC2826_BUCK_VOLTAGE_STEP_MV,
+ MIC2826_BUCK_VOLTAGE_MAX_MV,
+ MIC2826_BUCK_REQUESTVOLTAGE_MV
+ },
+ },
+ // MIC2826 LDO1
+ {
+ MIC2826PmuSupply_LDO1,
+ MIC2826_REG_ADDR_LD01,
+ MIC2826_REG_INVALID,
+ MIC2826_REG_INVALID,
+ MIC2826_INVALID_PORT,
+ MIC2826_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ MIC2826_LDO_VOLTAGE_MIN_MV,
+ MIC2826_LDO_VOLTAGE_STEP_MV,
+ MIC2826_LDO_VOLTAGE_MAX_MV,
+ MIC2826_LDO1_REQUESTVOLTAGE_MV
+ },
+ },
+
+ // MIC2826 LDO2
+ {
+ MIC2826PmuSupply_LDO2,
+ MIC2826_REG_ADDR_LD02,
+ MIC2826_REG_INVALID,
+ MIC2826_REG_INVALID,
+ MIC2826_INVALID_PORT,
+ MIC2826_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ MIC2826_LDO_VOLTAGE_MIN_MV,
+ MIC2826_LDO_VOLTAGE_STEP_MV,
+ MIC2826_LDO_VOLTAGE_MAX_MV,
+ MIC2826_LDO2_REQUESTVOLTAGE_MV
+ },
+ },
+
+ // LDO3
+ {
+ MIC2826PmuSupply_LDO3,
+ MIC2826_REG_ADDR_LD03,
+ MIC2826_REG_INVALID,
+ MIC2826_REG_INVALID,
+ MIC2826_INVALID_PORT,
+ MIC2826_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ MIC2826_LDO_VOLTAGE_MIN_MV,
+ MIC2826_LDO_VOLTAGE_STEP_MV,
+ MIC2826_LDO_VOLTAGE_MAX_MV,
+ MIC2826_LDO3_REQUESTVOLTAGE_MV
+ },
+ },
+
+ // EXT_DC/DC7 (controlled by LX_V1, scaled by AD5258 DPM)
+ {
+ Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7,
+ AD5258_RDAC_ADDR,
+ MAX8907B_REG_INVALID,
+ MAX8907B_REG_INVALID,
+ TCA6416_INVALID_PORT,
+ TCA6416_INVALID_PORT,
+ NULL,
+ NULL,
+ {
+ NV_FALSE,
+ AD5258_V0,
+ AD5258_MIN_STEP_MV,
+ AD5258_VMAX,
+ MAX8907B_REQUESTVOLTAGE_LX_V1
+ },
+ }
+};
+
+static NvBool
+Max8907bReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+ NvU8 data = 0;
+ NvU32 milliVolts = 0;
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ if (pSupplyInfo->ControlRegAddr != MAX8907B_REG_INVALID)
+ {
+ if (!Max8907bI2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data))
+ return NV_FALSE;
+
+ if ((data & MAX8907B_OUT_VOLTAGE_CONTROL_MASK) ==
+ MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE)
+ {
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] =
+ ODM_VOLTAGE_OFF;
+ *pMilliVolts = ODM_VOLTAGE_OFF;
+ return NV_TRUE;
+ }
+ }
+
+ if (pSupplyInfo->OutputVoltageRegAddr == MAX8907B_REG_INVALID)
+ return NV_FALSE;
+
+ if (!Max8907bI2cRead8(hDevice, pSupplyInfo->OutputVoltageRegAddr, &data))
+ return NV_FALSE;
+
+ data &= MAX8907B_OUT_VOLTAGE_MASK;
+ if (!data) //OFF
+ milliVolts = ODM_VOLTAGE_OFF;
+ else
+ milliVolts = pSupplyInfo->GetVoltage(data);
+
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] = milliVolts;
+ *pMilliVolts = milliVolts;
+ return NV_TRUE;
+}
+
+static NvBool
+Max8907bWriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+ NvU8 data = 0;
+ NvU32 SettleUS = 0;
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ // check if the supply can be turned off
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 1)
+ {
+ // turn off the supply
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE);
+
+ // Disable the output (read-modify-write the control register)
+ Max8907bI2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data);
+ data &= (~MAX8907B_OUT_VOLTAGE_CONTROL_MASK);
+ data |= MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE;
+ if (!Max8907bI2cWrite8(hDevice, pSupplyInfo->ControlRegAddr, data))
+ return NV_FALSE;
+
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] =
+ ODM_VOLTAGE_OFF;
+ SettleUS = MAX8907B_TURN_OFF_TIME_US;
+ }
+
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] != 0)
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] --;
+
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds = SettleUS;
+ else
+ NvOdmOsWaitUS(SettleUS);
+
+ return NV_TRUE;
+ }
+
+ // Set voltage level
+ data = pSupplyInfo->SetVoltage(MilliVolts);
+ if (!Max8907bI2cWrite8(hDevice, pSupplyInfo->OutputVoltageRegAddr, data))
+ return NV_FALSE;
+ if (MilliVolts >
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail])
+ {
+ NvU32 LastMV =
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail];
+ SettleUS = (MilliVolts - LastMV) * 1000 / MAX8907B_SCALE_UP_UV_PER_US;
+ }
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] = MilliVolts;
+
+ // turn on supply
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 0)
+ {
+ // Enable the output (read-modify-write the control register)
+ Max8907bI2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data);
+
+ if ((data & MAX8907B_OUT_VOLTAGE_CONTROL_MASK) ==
+ MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE)
+ {
+ // Voltage on/change (supply was off, so it must be turned on)
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Max8907bPrivData*)(hDevice->pPrivate))->hOdmPmuSevice,
+ pSupplyInfo->supply, NV_TRUE);
+ data |= MAX8907B_OUT_VOLTAGE_ENABLE_BIT;
+ if (!Max8907bI2cWrite8(hDevice, pSupplyInfo->ControlRegAddr, data))
+ return NV_FALSE;
+
+ SettleUS = MAX8907B_TURN_ON_TIME_US;
+ }
+ }
+
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] ++;
+
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds = SettleUS;
+ else
+ NvOdmOsWaitUS(SettleUS);
+
+ return NV_TRUE;
+}
+
+static NvBool
+Max8907bOnOffConfigure(NvOdmPmuDeviceHandle hDevice)
+{
+ NvU8 data = 0;
+
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_SYSENSEL, &data))
+ return NV_FALSE;
+
+ // Enable hard reset - power-off after ONKEY press for 5 seconds
+ // (must be enabled for thermal auto-shutdown)
+ data |= (MAX8907B_SYSENSEL_HRDSTEN_MASK <<
+ MAX8907B_SYSENSEL_HRDSTEN_SHIFT);
+
+ return Max8907bI2cWrite8(hDevice, MAX8907B_SYSENSEL, data);
+}
+
+static NvBool
+Max8907bPwrEnConfigure(NvOdmPmuDeviceHandle hDevice, NvBool Enable)
+{
+ NvU8 data = 0;
+
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_RESET_CNFG, &data))
+ return NV_FALSE;
+
+ // Enable/disable PWREN h/w control mechanism (PWREN signal must be
+ // inactive = high at this time)
+ if (Enable)
+ data |= (MAX8907B_RESET_CNFG_PWREN_EN_MASK <<
+ MAX8907B_RESET_CNFG_PWREN_EN_SHIFT);
+ else
+ data &= (~(MAX8907B_RESET_CNFG_PWREN_EN_MASK <<
+ MAX8907B_RESET_CNFG_PWREN_EN_SHIFT));
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_RESET_CNFG, data))
+ return NV_FALSE;
+
+ // When enabled, connect PWREN to SEQ2 by clearing SEQ2 configuration
+ // settings for silicon revision that requires s/w WAR. On other MAX8907B
+ // revisions PWREN is always connected to SEQ2.
+ if (Enable)
+ {
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_II2RR, &data))
+ return NV_FALSE;
+
+ if (data == MAX8907B_II2RR_PWREN_WAR)
+ {
+ data = 0x00;
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_SEQ2CNFG, data))
+ return NV_FALSE;
+ }
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+Max8907bPwrEnAttach(
+ NvOdmPmuDeviceHandle hDevice,
+ Max8907bPmuSupply Supply,
+ NvBool Attach)
+{
+ NvU8 CtlAddr, CtlData, CntAddr, CntData, SeqSel;
+
+ switch (Supply)
+ {
+ case Max8907bPmuSupply_LX_V1: // CPU
+ // No sequencer delay for CPU rail when it is attached
+ CntData = Attach ? 0x00 : MAX8907B_SEQCNT_DEFAULT_LX_V1;
+ SeqSel = Attach ? MAX8907B_SEQSEL_PWREN_LXX :
+ MAX8907B_SEQSEL_DEFAULT_LX_V1;
+ break;
+
+ case Max8907bPmuSupply_LX_V2: // Core
+ // Change CPU sequencer delay when core is attached to assure
+ // order of Core/CPU rails control; clear CPU delay when core
+ // is detached
+ CntAddr = Max8907bSupplyInfoTable[
+ Max8907bPmuSupply_LX_V1].SequencerCountRegAddr;
+ CntData = Attach ? MAX8907B_SEQCNT_PWREN_LX_V1 : 0x00;
+ if (!Max8907bI2cWrite8(hDevice, CntAddr, CntData))
+ return NV_FALSE;
+
+ CntData = Attach ? MAX8907B_SEQCNT_PWREN_LX_V2 :
+ MAX8907B_SEQCNT_DEFAULT_LX_V2;
+ SeqSel = Attach ? MAX8907B_SEQSEL_PWREN_LXX :
+ MAX8907B_SEQSEL_DEFAULT_LX_V2;
+ break;
+
+ default:
+ NV_ASSERT(!"This supply must not be attached to PWREN");
+ return NV_FALSE;
+ }
+ CtlAddr = Max8907bSupplyInfoTable[Supply].ControlRegAddr;
+ CntAddr = Max8907bSupplyInfoTable[Supply].SequencerCountRegAddr;
+
+ // Read control refgister, and select target sequencer
+ if (!Max8907bI2cRead8(hDevice, CtlAddr, &CtlData))
+ return NV_FALSE;
+ CtlData &= (~(MAX8907B_CTL_SEQ_MASK << MAX8907B_CTL_SEQ_SHIFT ));
+ CtlData |= ((SeqSel & MAX8907B_CTL_SEQ_MASK) << MAX8907B_CTL_SEQ_SHIFT );
+
+ // Attach: set count => set control
+ // Dettach: reset control => reset count
+ if (Attach)
+ {
+ if (!Max8907bI2cWrite8(hDevice, CntAddr, CntData))
+ return NV_FALSE;
+ }
+
+ if (!Max8907bI2cWrite8(hDevice, CtlAddr, CtlData))
+ return NV_FALSE;
+
+ if (!Attach)
+ {
+ if (!Max8907bI2cWrite8(hDevice, CntAddr, CntData))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+Tca6416ConfigPort(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvBool Enable)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+ NvU32 PortNo;
+ NvU32 PinNo;
+
+ // Get port number and pin number
+ PortNo = pSupplyInfo->OutputPort;
+ PinNo = pSupplyInfo->PmuGpio;
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ if (Enable)
+ {
+ // Configure GPIO as output
+ if (!Tca6416ConfigPortPin(hDevice, PortNo, PinNo, GpioPinMode_Output))
+ return NV_FALSE;
+
+ // Set the output port
+ if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_High))
+ return NV_FALSE;
+ }
+ else
+ // check if the supply can be turned off
+ {
+ // turn off the supply
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE);
+
+ // Configure port pin as output
+ if (!Tca6416ConfigPortPin(hDevice, PortNo, PinNo, GpioPinMode_Output))
+ return NV_FALSE;
+
+ // Set the output port (for disable, data = 0)
+ if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_Low))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+
+#if defined(MAX8907B_USE_FAN5355_VOLTAGE_SCALING)
+static NvBool
+Fan5355ReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+ NvU8 data = 0;
+ NvU32 milliVolts = 0;
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ if (pSupplyInfo->OutputVoltageRegAddr == FAN5335_REG_INVALID)
+ return NV_FALSE;
+
+ if (!Fan5355I2cRead8(hDevice, pSupplyInfo->OutputVoltageRegAddr, &data))
+ return NV_FALSE;
+
+ if (!data) //OFF
+ milliVolts = 0;
+ else
+ milliVolts = pSupplyInfo->GetVoltage(data);
+
+ *pMilliVolts = milliVolts;
+ return NV_TRUE;
+}
+#endif
+
+static NvBool
+Fan5355WriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo = NULL;
+ NvU8 data = 0;
+
+ if ((vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB1) ||
+ (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB3))
+ {
+ vddRail = Max8907bPmuSupply_EXT_DCDC_3;
+ }
+
+ pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ // TO DO: Account for reference counting
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ // check if the supply can be turned off
+ {
+ // turn off the supply
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE);
+
+ // Disable the output
+ if (!Tca6416ConfigPort(hDevice, vddRail, NV_FALSE))
+ return NV_FALSE;
+ }
+ }
+ else
+ {
+ // Voltage on/change
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Max8907bPrivData*)(hDevice->pPrivate))->hOdmPmuSevice, pSupplyInfo->supply, NV_TRUE);
+
+ // Set voltage level
+ data = pSupplyInfo->SetVoltage(MilliVolts);
+#if defined(MAX8907B_USE_FAN5355_VOLTAGE_SCALING)
+ if (!Fan5355I2cWrite8(hDevice, pSupplyInfo->OutputVoltageRegAddr, data))
+ return NV_FALSE;
+#endif
+
+ // Enable the output
+ if (!Tca6416ConfigPort(hDevice, vddRail, NV_TRUE))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+Max8907bLxV1Ad5258ReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ const Max8907bPmuSupplyInfo* pSupplyInfo =
+ &Max8907bSupplyInfoTable[vddRail];
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ // Check if DC/DC has been turned Off (controlled by LxV1 main PMU output)
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[
+ pSupplyInfo->supply] == 0)
+ {
+ if (!Max8907bReadVoltageReg(
+ hDevice, Max8907bPmuSupply_LX_V1, pMilliVolts))
+ return NV_FALSE;
+ if (*pMilliVolts == ODM_VOLTAGE_OFF)
+ return NV_TRUE;
+ }
+
+ // DC/DC is On - now get DPM-scaled voltage
+ return Ad5258I2cGetVoltage(hDevice, pMilliVolts);
+}
+
+static NvBool
+Max8907bLxV1Ad5258WriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo =
+ &Max8907bSupplyInfoTable[vddRail];
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ // Check if the supply can be turned off, and if yes - turn off
+ // LxV1 main PMU output, which controls DC/DC
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[
+ pSupplyInfo->supply] == 1)
+ {
+ if (!Max8907bWriteVoltageReg(hDevice, Max8907bPmuSupply_LX_V1,
+ MilliVolts, pSettleMicroSeconds))
+ return NV_FALSE;
+ }
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[
+ pSupplyInfo->supply] != 0)
+ {
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[
+ pSupplyInfo->supply] --;
+ }
+ return NV_TRUE;
+ }
+
+ // Set DPM voltage level (includes DPM and DCDC change level settle time)
+ if (!Ad5258I2cSetVoltage(hDevice, MilliVolts))
+ return NV_FALSE;
+
+ // Turn on control LxV1 supply on main PMU if necessary
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[
+ pSupplyInfo->supply] == 0)
+ {
+ if (!Max8907bWriteVoltageReg(hDevice, Max8907bPmuSupply_LX_V1,
+ MAX8907B_REQUESTVOLTAGE_LX_V1, pSettleMicroSeconds))
+ return NV_FALSE;
+
+ // Add external DCDC turning On settling time
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds += AD5258_TURN_ON_TIME_US;
+ else
+ NvOdmOsWaitUS(AD5258_TURN_ON_TIME_US);
+ }
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[
+ pSupplyInfo->supply] ++;
+
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bSetup(NvOdmPmuDeviceHandle hDevice)
+{
+ NvOdmIoModule I2cModule = NvOdmIoModule_I2c;
+ NvU32 I2cInstance = 0;
+ NvU32 I2cAddress = 0;
+ NvU32 i = 0;
+ const NvOdmPeripheralConnectivity *pConnectivity =
+ NvOdmPeripheralGetGuid(PMUGUID);
+
+ NV_ASSERT(hDevice);
+
+ hMax8907bPmu = (Max8907bPrivData*) NvOdmOsAlloc(sizeof(Max8907bPrivData));
+ if (hMax8907bPmu == NULL)
+ {
+ NVODMPMU_PRINTF(("Error Allocating Max8907bPrivData.\n"));
+ return NV_FALSE;
+ }
+ NvOdmOsMemset(hMax8907bPmu, 0, sizeof(Max8907bPrivData));
+ hDevice->pPrivate = hMax8907bPmu;
+
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable =
+ NvOdmOsAlloc(sizeof(NvU32) * Max8907bPmuSupply_Num);
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable == NULL)
+ {
+ NVODMPMU_PRINTF(("Error Allocating RefCntTable. \n"));
+ goto fail;
+ }
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages =
+ NvOdmOsAlloc(sizeof(NvU32) * Max8907bPmuSupply_Num);
+ if (((Max8907bPrivData*)hDevice->pPrivate)->pVoltages == NULL)
+ {
+ NVODMPMU_PRINTF(("Error Allocating shadow voltages table. \n"));
+ goto fail;
+ }
+
+ // memset
+ for (i = 0; i < Max8907bPmuSupply_Num; i++)
+ {
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[i] = 0;
+ // Setting shadow to 0 would cause spare delay on the 1st scaling of
+ // always On rail; however the alternative reading of initial settings
+ // over I2C is even worse.
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[i] = 0;
+ }
+
+ if (pConnectivity != NULL) // PMU is in database
+ {
+ NvU32 i = 0;
+
+ for (i = 0; i < pConnectivity->NumAddress; i ++)
+ {
+ if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu)
+ {
+ I2cModule = NvOdmIoModule_I2c_Pmu;
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ I2cAddress = pConnectivity->AddressList[i].Address;
+ break;
+ }
+ }
+
+ NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu);
+ NV_ASSERT(I2cAddress != 0);
+
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance);
+ if (!((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C)
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Error Opening I2C device. \n"));
+ NVODMPMU_PRINTF(("[NVODM PMU]Please check PMU device I2C settings. \n"));
+ return NV_FALSE;
+ }
+ ((Max8907bPrivData*)hDevice->pPrivate)->DeviceAddr = I2cAddress;
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice = NvOdmServicesPmuOpen();
+ }
+ else
+ {
+ // if PMU is not present in the database, then the platform is PMU-less.
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: The system did not doscover PMU from the data base.\n"));
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: If this is not intended, please check the peripheral database for PMU settings.\n"));
+ return NV_FALSE;
+ }
+
+ // Configure OnOff options
+ if (!Max8907bOnOffConfigure(hDevice))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bOnOffConfigure() failed. \n"));
+ return NV_FALSE;
+ }
+
+ // Configure PWREN, and attach CPU V1 rail to it.
+ // TODO: h/w events (power cycle, reset, battery low) auto-disables PWREN.
+ // Only soft reset (not supported) requires s/w to disable PWREN explicitly
+ if (!Max8907bPwrEnConfigure(hDevice, NV_TRUE))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bPwrEnConfigure() failed. \n"));
+ return NV_FALSE;
+ }
+ if (!Max8907bPwrEnAttach(hDevice, Max8907bPmuSupply_LX_V1, NV_TRUE))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bPwrEnAttach() failed. \n"));
+ return NV_FALSE;
+ }
+
+ //Check battery presence
+ if (!Max8907bBatteryChargerMainBatt(hDevice,&((Max8907bPrivData*)hDevice->pPrivate)->battPresence))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bBatteryChargerMainBatt() failed. \n"));
+ return NV_FALSE;
+ }
+
+ // Power up Whistler thermal monitor (it is reported "not connected"
+ // if board info ROMs cannot be read when the thermal rail is enabled).
+ // This has to be done as early as possible because of 100ms+ power up
+ // delay before interface level shifters are operational.
+ pConnectivity =
+ NvOdmPeripheralGetGuid(NV_ODM_GUID('a','d','t','7','4','6','1',' '));
+ if (pConnectivity)
+ {
+ for (i = 0; i < pConnectivity->NumAddress; i++)
+ {
+ if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_Vdd)
+ {
+ NvU32 vddRail = pConnectivity->AddressList[i].Address;
+ NvU32 mv =
+ Max8907bSupplyInfoTable[vddRail].cap.requestMilliVolts;
+ if(!Max8907bSetVoltage(hDevice, vddRail, mv, NULL))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup:"
+ " Thermal rail setup failed. \n"));
+ }
+ }
+ }
+ }
+
+ // The interrupt assumes not supported until Max8907bInterruptHandler() is called.
+ ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_FALSE;
+
+ return NV_TRUE;
+
+fail:
+ Max8907bRelease(hDevice);
+ return NV_FALSE;
+}
+
+void
+Max8907bRelease(NvOdmPmuDeviceHandle hDevice)
+{
+ if (hDevice->pPrivate != NULL)
+ {
+ if (((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice != NULL)
+ {
+ NvOdmServicesPmuClose(((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice);
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice = NULL;
+ }
+
+ if (((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C != NULL)
+ {
+ NvOdmI2cClose(((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C);
+ ((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C = NULL;
+ }
+
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable != NULL)
+ {
+ NvOdmOsFree(((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable);
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable = NULL;
+ }
+
+ if (((Max8907bPrivData*)hDevice->pPrivate)->pVoltages != NULL)
+ {
+ NvOdmOsFree(((Max8907bPrivData*)hDevice->pPrivate)->pVoltages);
+ ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages = NULL;
+ }
+
+
+ NvOdmOsFree(hDevice->pPrivate);
+ hDevice->pPrivate = NULL;
+ }
+}
+
+NvBool
+Max8907bGetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pMilliVolts);
+ NV_ASSERT(vddRail < Max8907bPmuSupply_Num);
+
+ // RTC is a special case, since it's "always on"
+ if (vddRail == Max8907bPmuSupply_VRTC)
+ {
+ // Fixed voltage
+ *pMilliVolts = MAX8907B_MAX_OUTPUT_VOLTAGE_RTC;
+ }
+ else if (vddRail == Max8907bPmuSupply_EXT_DCDC_1)
+ {
+ // Fixed voltage
+ *pMilliVolts = MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1;
+ }
+ else if (vddRail == Max8907bPmuSupply_EXT_DCDC_3)
+ {
+#if defined(MAX8907B_USE_FAN5355_VOLTAGE_SCALING)
+ if (!Fan5355ReadVoltageReg(hDevice, vddRail, pMilliVolts))
+ return NV_FALSE;
+#else
+ // Fixed voltage
+ *pMilliVolts = MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3;
+#endif
+ }
+ else if((vddRail == MIC2826PmuSupply_BUCK) ||
+ (vddRail == MIC2826PmuSupply_LDO1) ||
+ (vddRail == MIC2826PmuSupply_LDO2) ||
+ (vddRail == MIC2826PmuSupply_LDO3))
+ {
+ // Secondary PMU Case
+ if(! MIC2826ReadVoltageReg(hDevice, (vddRail), pMilliVolts))
+ return NV_FALSE;
+ }
+ else if (vddRail == Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7)
+ {
+ // External DCDC controlled by LX_V1, and scaled by DPM
+ if (!Max8907bLxV1Ad5258ReadVoltageReg(hDevice, vddRail, pMilliVolts))
+ return NV_FALSE;
+ }
+ else
+ {
+ if (!Max8907bReadVoltageReg(hDevice, vddRail, pMilliVolts))
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+
+static NvBool
+Tca6416UsbVbusControl(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts)
+{
+ const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+ NvU32 PortNo;
+ NvU32 PinNo;
+
+ // Get port number and pin number
+ PortNo = pSupplyInfo->OutputPort;
+ PinNo = pSupplyInfo->PmuGpio;
+
+ // Configure port pin as output
+ if (!Tca6416ConfigPortPin(hDevice, PortNo, PinNo, GpioPinMode_Output))
+ return NV_FALSE;
+
+ if (MilliVolts == ODM_VOLTAGE_OFF) // to disable VBUS
+ {
+ // Set Low on pin
+ if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_Low))
+ return NV_FALSE;
+ }
+ else // to Enable VBUS
+ {
+ // Set high on pin
+ if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_High))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bSetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ NV_ASSERT(hDevice);
+ NV_ASSERT(vddRail < Max8907bPmuSupply_Num);
+
+ if ( Max8907bSupplyInfoTable[vddRail].cap.OdmProtected == NV_TRUE)
+ {
+ NVODMPMU_PRINTF(("The voltage is protected and cannot be set.\n"));
+ return NV_TRUE;
+ }
+
+ if ((MilliVolts == ODM_VOLTAGE_ENABLE_EXT_ONOFF) ||
+ (MilliVolts == ODM_VOLTAGE_DISABLE_EXT_ONOFF))
+ {
+ return Max8907bPwrEnAttach(hDevice, (Max8907bPmuSupply)vddRail,
+ (MilliVolts == ODM_VOLTAGE_ENABLE_EXT_ONOFF));
+ }
+
+ if ((MilliVolts == ODM_VOLTAGE_OFF) ||
+ ((MilliVolts <= Max8907bSupplyInfoTable[vddRail].cap.MaxMilliVolts) &&
+ (MilliVolts >= Max8907bSupplyInfoTable[vddRail].cap.MinMilliVolts)))
+ {
+ if ((vddRail == Max8907bPmuSupply_EXT_DCDC_1) ||
+ (vddRail == Max8907bPmuSupply_EXT_DCDC_3) ||
+ (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB1) ||
+ (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB3))
+ {
+ // Use External DC/DC switcher
+ if (!Fan5355WriteVoltageReg(hDevice, vddRail, MilliVolts))
+ return NV_FALSE;
+ }
+ else if((vddRail == MIC2826PmuSupply_BUCK) ||
+ (vddRail == MIC2826PmuSupply_LDO1) ||
+ (vddRail == MIC2826PmuSupply_LDO2) ||
+ (vddRail == MIC2826PmuSupply_LDO3))
+ {
+ // Secondary PMU Case
+ if (!MIC2826WriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds))
+ return NV_FALSE;
+ }
+ else if (vddRail == Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7)
+ {
+ // External DCDC controlled by LX_V1, and scaled by DPM
+ if (!Max8907bLxV1Ad5258WriteVoltageReg(
+ hDevice, vddRail, MilliVolts, pSettleMicroSeconds))
+ return NV_FALSE;
+ }
+ else
+ {
+ if (!Max8907bWriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds))
+ return NV_FALSE;
+ }
+ }
+ else
+ {
+ NVODMPMU_PRINTF(("The requested voltage is not supported.\n"));
+ return NV_FALSE;
+ }
+
+ // Check whether need to enable VBUS for any of the USB Instance
+ if ((vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB1) ||
+ (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB3))
+ {
+ // Enable VBUS for USB1 or USB3
+ if (!Tca6416UsbVbusControl(hDevice, vddRail, MilliVolts))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+void
+Max8907bGetCapabilities(
+ NvU32 vddRail,
+ NvOdmPmuVddRailCapabilities* pCapabilities)
+{
+ NV_ASSERT(pCapabilities);
+ NV_ASSERT(vddRail < Max8907bPmuSupply_Num);
+
+ *pCapabilities = Max8907bSupplyInfoTable[vddRail].cap;
+}
+
+NvBool
+Max8907bGetAcLineStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuAcLineStatus *pStatus)
+{
+ NvBool acLineStatus = NV_FALSE;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pStatus);
+
+ // check if battery is present
+ if (((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_FALSE)
+ {
+ *pStatus = NvOdmPmuAcLine_Online;
+ return NV_TRUE;
+ }
+
+ if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE )
+ {
+ if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus.mChgPresent == NV_TRUE )
+ {
+ *pStatus = NvOdmPmuAcLine_Online;
+ acLineStatus = NV_TRUE;
+ }
+ else
+ {
+ *pStatus = NvOdmPmuAcLine_Offline;
+ acLineStatus = NV_FALSE;
+ }
+ }
+ else
+ {
+ // battery is present, now check if charger present
+ if (!Max8907bBatteryChargerOK(hDevice, &acLineStatus))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU] Max8907bGetAcLineStatus: Error in checking main charger presence.\n"));
+ return NV_FALSE;
+ }
+
+ if (acLineStatus == NV_TRUE)
+ *pStatus = NvOdmPmuAcLine_Online;
+ else
+ *pStatus = NvOdmPmuAcLine_Offline;
+ }
+
+#if ALWAYS_ONLINE
+ // Currently on Whistler battery is not used, and AC is connected to PMU
+ // battery input, causing false battery presence detection. Voyager battery
+ // management is don't care at the moment. Hence, force OnLine status.
+ *pStatus = NvOdmPmuAcLine_Online;
+#endif
+
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bGetBatteryStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU8 *pStatus)
+{
+ NvU8 status = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pStatus);
+ NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num);
+
+ if (batteryInst == NvOdmPmuBatteryInst_Main)
+ {
+ if ( ((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_TRUE )
+ {
+ NvOdmPmuAcLineStatus stat = NvOdmPmuAcLine_Offline;
+ NvU32 VBatSense = 0;
+ if (!Max8907bGetAcLineStatus(hDevice, &stat))
+ return NV_FALSE;
+
+ if (stat == NvOdmPmuAcLine_Online)
+ {
+ if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE )
+ {
+ if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus.batFull == NV_FALSE )
+ status = NVODM_BATTERY_STATUS_CHARGING;
+ }
+ else
+ {
+ NvBool batFull = NV_FALSE;
+ if (!Max8907bBatteryChargerMainBattFull(hDevice, &batFull))
+ return NV_FALSE;
+ if (batFull == NV_FALSE)
+ status = NVODM_BATTERY_STATUS_CHARGING;
+ }
+ }
+
+ // Get VBatSense
+ if (!Max8907bAdcVBatSenseRead(hDevice, &VBatSense))
+ return NV_FALSE;
+
+ // TO DO: Update status based on VBatSense
+ }
+ else
+ {
+ /* Battery is actually not present */
+ status = NVODM_BATTERY_STATUS_NO_BATTERY;
+ }
+ *pStatus = status;
+ }
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bGetBatteryData(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryData *pData)
+{
+ NvOdmPmuBatteryData batteryData;
+
+ batteryData.batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pData);
+ NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num);
+
+ if (batteryInst == NvOdmPmuBatteryInst_Main)
+ {
+ NvU32 VBatSense = 0;
+ NvU32 VBatTemp = 0;
+
+ if (((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_TRUE)
+ {
+ /* retrieve Battery voltage and temperature */
+
+ // Get VBatSense
+ if (!Max8907bAdcVBatSenseRead(hDevice, &VBatSense))
+ {
+ NVODMPMU_PRINTF(("Error reading VBATSense. \n"));
+ return NV_FALSE;
+ }
+
+ // Get VBatTemp
+ if (!Max8907bAdcVBatTempRead(hDevice, &VBatTemp))
+ {
+ NVODMPMU_PRINTF(("Error reading VBATSense. \n"));
+ return NV_FALSE;
+ }
+
+ batteryData.batteryVoltage = VBatSense;
+ batteryData.batteryTemperature = Max8907bBatteryTemperature(VBatSense, VBatTemp);
+ }
+
+ *pData = batteryData;
+ }
+ else
+ {
+ *pData = batteryData;
+ }
+
+ return NV_TRUE;
+}
+
+void
+Max8907bGetBatteryFullLifeTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU32 *pLifeTime)
+{
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+}
+
+void
+Max8907bGetBatteryChemistry(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryChemistry *pChemistry)
+{
+ *pChemistry = NvOdmPmuBatteryChemistry_LION;
+}
+
+NvBool
+Max8907bSetChargingCurrent(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuChargingPath chargingPath,
+ NvU32 chargingCurrentLimitMa,
+ NvOdmUsbChargerType ChargerType)
+{
+ NvU8 data = 0;
+ NvU8 fchg = 0;
+ NV_ASSERT(hDevice);
+
+ // If no battery is connected, then do nothing.
+ if (((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_FALSE)
+ return NV_TRUE;
+
+ // If requested current is more than supported maximum then limit to supported.
+ if ( chargingCurrentLimitMa > MAX_CHARGER_LIMIT_MA )
+ chargingCurrentLimitMa = MAX_CHARGER_LIMIT_MA;
+
+ // If dedicated charger is connected, request maximum current.
+ if (chargingPath == NvOdmPmuChargingPath_UsbBus)
+ {
+ switch (ChargerType)
+ {
+ case NvOdmUsbChargerType_SJ:
+ case NvOdmUsbChargerType_SK:
+ case NvOdmUsbChargerType_SE1:
+ case NvOdmUsbChargerType_SE0:
+ chargingCurrentLimitMa = MAX_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_UsbHost:
+ default:
+ break;
+ }
+ }
+
+ // Read the current charger setup.
+ if ( !Max8907bI2cRead8(hDevice, MAX8907B_CHG_CNTL1, &data) )
+ return NV_FALSE;
+
+ // Set charging current to the value no larger than requested.
+ // If less than 85mA is requested, set to 85mA.
+ // If larger than 1000mA is requested, set to 1000mA.
+ if (chargingCurrentLimitMa >= 1000)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_1000MA;
+ else if (chargingCurrentLimitMa >= 900)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_900MA;
+ else if (chargingCurrentLimitMa >= 800)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_800MA;
+ else if (chargingCurrentLimitMa >= 700)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_700MA;
+ else if (chargingCurrentLimitMa >= 600)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_600MA;
+ else if (chargingCurrentLimitMa >= 460)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_460MA;
+ else if (chargingCurrentLimitMa >= 300)
+ fchg = MAX8907B_CHG_CNTL1_FCHG_300MA;
+ else
+ fchg = MAX8907B_CHG_CNTL1_FCHG_85MA;
+
+ data &= ~(MAX8907B_CHG_CNTL1_FCHG_MASK <<
+ MAX8907B_CHG_CNTL1_FCHG_SHIFT);
+ data |= fchg << MAX8907B_CHG_CNTL1_FCHG_SHIFT;
+
+ // Turn off the charger path if the requested current limit is 0mA.
+ // Turn on the path otherwise.
+ if ( chargingCurrentLimitMa == 0 )
+ {
+ // off
+ data |= (MAX8907B_CHG_CNTL1_NOT_CHGEN_MASK <<
+ MAX8907B_CHG_CNTL1_NOT_CHGEN_SHIFT);
+ }
+ else
+ {
+ // on
+ data &= ~(MAX8907B_CHG_CNTL1_NOT_CHGEN_MASK <<
+ MAX8907B_CHG_CNTL1_NOT_CHGEN_SHIFT);
+ }
+
+ // Update the current charger setup.
+ if ( !Max8907bI2cWrite8(hDevice, MAX8907B_CHG_CNTL1, data) )
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+void Max8907bInterruptHandler( NvOdmPmuDeviceHandle hDevice)
+{
+ // If the interrupt handle is called, the interrupt is supported.
+ ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_TRUE;
+
+ Max8907bInterruptHandler_int(hDevice, &((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus);
+}
+
+/**************** Secondary PMU MIC2826 Programming */
+static NvBool
+MIC2826ReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ NvU32 milliVolts = 0;
+ NvU32 index = 0;
+ NvU8 data = 0;
+ const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ if(! MIC2826I2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data))
+ return NV_FALSE;
+
+ // convert Data to MilliVolts
+ if (!data) //OFF
+ milliVolts = 0;
+ else
+ {
+ // set voltage
+ if(vddRail == MIC2826PmuSupply_BUCK)
+ {
+ for(index=0;index<MIC2826_BUCK_Votage_Table_Size;index++)
+ {
+ if(data == MIC2826_BUCK_Votage_Table[index])
+ break;
+ }
+ if(index < 0x10)
+ {
+ milliVolts = index * MIC2826_BUCK_VOLTAGE_STEP_25MV + MIC2826_BUCK_VOLTAGE_OFFSET ;
+ }else
+ {
+ milliVolts = 1200 + ((index - 0x10) * MIC2826_BUCK_VOLTAGE_STEP_50MV) ;
+ }
+ }
+ else if ( (vddRail == MIC2826PmuSupply_LDO1) ||
+ (vddRail == MIC2826PmuSupply_LDO2) ||
+ (vddRail == MIC2826PmuSupply_LDO3))
+ {
+ for(index=0;index<MIC2826_LDO_Votage_Table_Size;index++)
+ {
+ if(data == MIC2826_BUCK_Votage_Table[index])
+ break;
+ }
+ milliVolts = (index * pSupplyInfo->cap.StepMilliVolts) + MIC2826_LDO_VOLTAGE_OFFSET;
+ }
+ }
+
+ *pMilliVolts = milliVolts;
+
+ return NV_TRUE;
+}
+
+
+static NvBool
+MIC2826WriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ NvU8 data = 0;
+ NvU32 index = 0;
+ NvU32 settleTime = 0;
+ const Max8907bPmuSupplyInfo* pSupplyInfo = &Max8907bSupplyInfoTable[vddRail];
+
+ NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail);
+
+ // Require to turn off the supply
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ // check if the supply can be turned off
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 1)
+ {
+
+ // Read the current supply info
+ if(! MIC2826I2cRead8(hDevice, MIC2826_REG_ADDR_ENABLE, &data))
+ return NV_FALSE;
+
+ // turn off the supply of particular rail
+ if(vddRail == MIC2826PmuSupply_BUCK)
+ data &= MIC2826_REG_DISABLE_BK;
+ else if(vddRail == MIC2826PmuSupply_LDO1)
+ data &= MIC2826_REG_DISABLE_LDO1;
+ else if(vddRail == MIC2826PmuSupply_LDO2)
+ data &= MIC2826_REG_DISABLE_LDO2;
+ else if(vddRail == MIC2826PmuSupply_LDO3)
+ data &= MIC2826_REG_DISABLE_LDO3;
+
+ if (!MIC2826I2cWrite8(hDevice, MIC2826_REG_ADDR_ENABLE, data))
+ return NV_FALSE;
+ }
+
+ //TODO: check if the supply input can be turned off
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] != 0)
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] --;
+
+ if (pSettleMicroSeconds != NULL)
+ *pSettleMicroSeconds = settleTime;
+ else
+ NvOdmOsWaitUS(settleTime);
+
+ return NV_TRUE;
+ }
+
+ // turn on supply
+ if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 0)
+ {
+ {
+ // Read the current supply info
+ if(! MIC2826I2cRead8(hDevice, MIC2826_REG_ADDR_ENABLE, &data))
+ return NV_FALSE;
+
+ // turn on the supply of particular rail
+ if(vddRail == MIC2826PmuSupply_BUCK)
+ data |= MIC2826_REG_ENABLE_BK;
+ else if(vddRail == MIC2826PmuSupply_LDO1)
+ data |= MIC2826_REG_ENABLE_LDO1;
+ else if(vddRail == MIC2826PmuSupply_LDO2)
+ data |= MIC2826_REG_ENABLE_LDO2;
+ else if(vddRail == MIC2826PmuSupply_LDO3)
+ data |= MIC2826_REG_ENABLE_LDO3;
+
+ if (!MIC2826I2cWrite8(hDevice, MIC2826_REG_ADDR_ENABLE, data))
+ return NV_FALSE;
+ }
+ }
+
+ // set voltage
+ if(vddRail == MIC2826PmuSupply_BUCK)
+ {
+ if(MilliVolts < 1200)
+ {
+ index = (MilliVolts - MIC2826_BUCK_VOLTAGE_OFFSET) / MIC2826_BUCK_VOLTAGE_STEP_25MV ;
+ }else
+ {
+ index = 0x10 + ((MilliVolts - 1200) / MIC2826_BUCK_VOLTAGE_STEP_50MV) ;
+ }
+ data = MIC2826_BUCK_Votage_Table[index];
+ }
+ else if ( (vddRail == MIC2826PmuSupply_LDO1) ||
+ (vddRail == MIC2826PmuSupply_LDO2) ||
+ (vddRail == MIC2826PmuSupply_LDO3))
+ {
+ index = (MilliVolts - MIC2826_LDO_VOLTAGE_OFFSET) / pSupplyInfo->cap.StepMilliVolts;
+ data = MIC2826_LDO_Votage_Table[index];
+ }
+
+ // Program the Rail Voltage
+ if(! MIC2826I2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data))
+ return NV_FALSE;
+
+ ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] ++;
+
+ // TODO: turn on supply input if necessary
+ if (pSettleMicroSeconds != NULL)
+ *pSettleMicroSeconds = settleTime;
+ else
+ NvOdmOsWaitUS(settleTime);
+
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h
new file mode 100644
index 000000000000..ce66a64c9716
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_PMU_MAX8907B_H
+#define INCLUDED_PMU_MAX8907B_H
+
+#include "nvodm_pmu.h"
+#include"pmu_hal.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if (NV_DEBUG)
+#define NVODMPMU_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODMPMU_PRINTF(x)
+#endif
+
+typedef struct Max8907bStatusRec
+{
+ /* Low Battery voltage detected by BVM */
+ NvBool lowBatt;
+
+ /* PMU high temperature */
+ NvBool highTemp;
+
+ /* Main charger Present */
+ NvBool mChgPresent;
+
+ /* battery Full */
+ NvBool batFull;
+
+} Max8907bStatus;
+
+typedef struct
+{
+ /* The handle to the I2C */
+ NvOdmServicesI2cHandle hOdmI2C;
+
+ /* The odm pmu service handle */
+ NvOdmServicesPmuHandle hOdmPmuSevice;
+
+ /* the PMU I2C device Address */
+ NvU32 DeviceAddr;
+
+ /* the PMU status */
+ Max8907bStatus pmuStatus;
+
+ /* battery presence */
+ NvBool battPresence;
+
+ /* PMU interrupt support enabled */
+ NvBool pmuInterruptSupported;
+
+ /* The ref cnt table of the power supplies */
+ NvU32 *supplyRefCntTable;
+
+ /* The pointer to supply voltages shadow */
+ NvU32 *pVoltages;
+
+} Max8907bPrivData;
+
+NvBool
+Max8907bSetup(NvOdmPmuDeviceHandle hDevice);
+
+void
+Max8907bRelease(NvOdmPmuDeviceHandle hDevice);
+
+NvBool
+Max8907bGetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts);
+
+NvBool
+Max8907bSetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds);
+
+void
+Max8907bGetCapabilities(
+ NvU32 vddRail,
+ NvOdmPmuVddRailCapabilities* pCapabilities);
+
+NvBool
+Max8907bGetAcLineStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuAcLineStatus *pStatus);
+
+NvBool
+Max8907bGetBatteryStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU8 *pStatus);
+
+NvBool
+Max8907bGetBatteryData(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryData *pData);
+
+void
+Max8907bGetBatteryFullLifeTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU32 *pLifeTime);
+
+void
+Max8907bGetBatteryChemistry(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryChemistry *pChemistry);
+
+NvBool
+Max8907bSetChargingCurrent(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuChargingPath chargingPath,
+ NvU32 chargingCurrentLimitMa,
+ NvOdmUsbChargerType ChargerType);
+
+void Max8907bInterruptHandler( NvOdmPmuDeviceHandle hDevice);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_PMU_MAX8907B_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c
new file mode 100644
index 000000000000..14d2c0d87a1a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "max8907b.h"
+#include "max8907b_adc.h"
+#include "max8907b_i2c.h"
+#include "max8907b_reg.h"
+
+NvBool
+Max8907bAdcVBatSenseRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt)
+{
+#if 0
+ NvU32 timeout = 0;
+ NvU8 dataS1 = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(volt);
+
+ // Configure ADC (conversion cycle, resolution, etc...)
+
+ // Start conversion
+
+ // Wait for conversion
+
+ // Make sure conversion is complete (or timeout or error)
+
+ // Get result
+ *volt = << compute >>;
+
+#endif
+ *volt = 0;
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bAdcVBatTempRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt)
+{
+#if 0
+ NvU32 timeout = 0;
+ NvU8 dataS1 = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(volt);
+
+ // Setup ADC (resolution, etc..)
+
+ // Start conversion
+
+ // Wait for conversion
+
+ // Make sure conversion is complete (or timeout or error)
+
+ // Get result
+ *volt = << compute >>;
+
+#endif
+ *volt = 0;
+ return NV_TRUE;
+}
+
+NvU32
+Max8907bBatteryTemperature(
+ NvU32 VBatSense,
+ NvU32 VBatTemp)
+{
+ return 0;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h
new file mode 100644
index 000000000000..5c3fb34fbf22
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_MAX8907B_ADC_HEADER
+#define INCLUDED_MAX8907B_ADC_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* read voltage from ... */
+NvBool
+Max8907bAdcVBatSenseRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt);
+
+/* read bat temperature voltage from ADC */
+NvBool
+Max8907bAdcVBatTempRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt);
+
+/* Calculate the battery temperature */
+NvU32
+Max8907bBatteryTemperature(
+ NvU32 VBatSense,
+ NvU32 VBatTemp);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_MAX8907B_ADC_HEADER
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c
new file mode 100644
index 000000000000..00096508b05a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "max8907b.h"
+#include "max8907b_batterycharger.h"
+#include "max8907b_reg.h"
+#include "max8907b_i2c.h"
+
+NvBool
+Max8907bBatteryChargerMainBatt(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data))
+ return NV_FALSE;
+
+ data = (data >> MAX8907B_CHG_STAT_MBDET_SHIFT) & MAX8907B_CHG_STAT_MBDET_MASK;
+ *status = (data == 0 ? NV_TRUE : NV_FALSE ); // MBDET low (0) = present
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bBatteryChargerOK(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data))
+ return NV_FALSE;
+
+ data = (data >> MAX8907B_CHG_STAT_VCHG_OK_SHIFT) & MAX8907B_CHG_STAT_VCHG_OK_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bBatteryChargerEnabled(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data))
+ return NV_FALSE;
+
+ data = (data >> MAX8907B_CHG_STAT_CHG_EN_STAT_SHIFT) & MAX8907B_CHG_STAT_CHG_EN_STAT_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bBatteryChargerMainBattFull(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data))
+ return NV_FALSE;
+
+ data = (data >> MAX8907B_CHG_STAT_MBATTLOW_SHIFT) & MAX8907B_CHG_STAT_MBATTLOW_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h
new file mode 100644
index 000000000000..ab7d1212a44f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_MAX8907B_BATTERYCHARGER_HEADER
+#define INCLUDED_MAX8907B_BATTERYCHARGER_HEADER
+
+/* the battery charger functions */
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* check main battery presence */
+NvBool
+Max8907bBatteryChargerMainBatt(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check charger input voltage */
+NvBool
+Max8907bBatteryChargerOK(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check charger enable status */
+NvBool
+Max8907bBatteryChargerEnabled(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check main battery voltage status */
+NvBool
+Max8907bBatteryChargerMainBattFull(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_MAX8907B_BATTERYCHARGER_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c
new file mode 100644
index 000000000000..0f7a09446876
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "max8907b.h"
+#include "max8907b_i2c.h"
+#include "max8907b_reg.h"
+
+#define MAX8907B_I2C_SPEED_KHZ 400
+#define MAX8907B_I2C_RETRY_CNT 2
+
+// Maximum i2c transaction count
+#define MAX_TRANSACTION_COUNT 5
+
+NvBool Max8907bI2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvU32 i;
+ NvU8 WriteBuffer[2];
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+
+ for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++)
+ {
+ WriteBuffer[0] = Addr & 0xFF; // PMU offset
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = hPmu->DeviceAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (status == NvOdmI2cStatus_Success)
+ return NV_TRUE;
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+NvBool Max8907bI2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data)
+{
+ NvU32 i;
+ NvU8 ReadBuffer = 0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++)
+ {
+ NvU32 TransactionCount = 0;
+ // Write the PMU offset
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[TransactionCount].Address = hPmu->DeviceAddr;
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer;
+ TransactionInfo[TransactionCount].Flags =
+ NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ TransactionInfo[TransactionCount].Address = (hPmu->DeviceAddr | 0x1);
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer;
+ TransactionInfo[TransactionCount].Flags = 0;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ // Read data from PMU at the specified offset
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0],
+ TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (status == NvOdmI2cStatus_Success)
+ {
+ *Data = ReadBuffer;
+ return NV_TRUE;
+ }
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+NvBool Max8907bI2cWrite32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 Data)
+{
+ NvU32 i;
+ NvU8 WriteBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++)
+ {
+ WriteBuffer[0] = (NvU8)(Addr & 0xFF);
+ WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF);
+ WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF);
+ WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF);
+ WriteBuffer[4] = (NvU8)(Data & 0xFF);
+
+ TransactionInfo.Address = hPmu->DeviceAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 5;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (status == NvOdmI2cStatus_Success)
+ return NV_TRUE;
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+NvBool Max8907bI2cRead32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 *Data)
+{
+ NvU32 i;
+ NvU8 ReadBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++)
+ {
+ NvU32 TransactionCount = 0;
+ ReadBuffer[0] = Addr & 0xFF;
+
+ TransactionInfo[TransactionCount].Address = hPmu->DeviceAddr;
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[0];
+ TransactionInfo[TransactionCount].Flags =
+ NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ TransactionInfo[TransactionCount].Address = (hPmu->DeviceAddr | 0x1);
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[0];
+ TransactionInfo[TransactionCount].Flags = 0;
+ TransactionInfo[TransactionCount++].NumBytes = 4;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0],
+ TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (status == NvOdmI2cStatus_Success)
+ {
+ *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) |
+ (ReadBuffer[2] << 8) | ReadBuffer[3];
+
+ return NV_TRUE;
+ }
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+NvBool Max8907bRtcI2cWriteTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 Data)
+{
+ NvU32 i;
+ NvU8 WriteBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ NVODMPMU_PRINTF(("\n RTC I2C write: Addr=0x%x, Data=0x%x ", Addr, Data));
+ for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++)
+ {
+ WriteBuffer[0] = (NvU8)(Addr & 0xFF);
+ WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF);
+ WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF);
+ WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF);
+ WriteBuffer[4] = (NvU8)(Data & 0xFF);
+
+ TransactionInfo.Address = MAX8907B_RTC_SLAVE_ADDR;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 5;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (status == NvOdmI2cStatus_Success)
+ return NV_TRUE;
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("Max8907bRtcI2cWrite32 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("Max8907bRtcI2cWrite32 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
+NvBool Max8907bRtcI2cReadTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 *Data)
+{
+ NvU32 i;
+ NvU8 ReadBuffer[4];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[MAX_TRANSACTION_COUNT];
+
+ NVODMPMU_PRINTF(("\n RTC I2C read: Addr=0x%x ", Addr));
+ for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++)
+ {
+ NvU32 TransactionCount = 0;
+ ReadBuffer[0] = Addr & 0xFF;
+
+ TransactionInfo[TransactionCount].Address = MAX8907B_RTC_SLAVE_ADDR;
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[0];
+ TransactionInfo[TransactionCount].Flags =
+ NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ // Seconds / day
+ if (TransactionCount >= MAX_TRANSACTION_COUNT)
+ return NV_FALSE;
+ TransactionInfo[TransactionCount].Address =
+ (MAX8907B_RTC_SLAVE_ADDR | 0x1);
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[0];
+ TransactionInfo[TransactionCount].Flags = 0;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ // Minutes / month
+ if (TransactionCount >= MAX_TRANSACTION_COUNT)
+ return NV_FALSE;
+ TransactionInfo[TransactionCount].Address =
+ (MAX8907B_RTC_SLAVE_ADDR | 0x1);
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[1];
+ TransactionInfo[TransactionCount].Flags = 0;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ // Hours / YY1
+ if (TransactionCount >= MAX_TRANSACTION_COUNT)
+ return NV_FALSE;
+ TransactionInfo[TransactionCount].Address =
+ (MAX8907B_RTC_SLAVE_ADDR | 0x1);
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[2];
+ TransactionInfo[TransactionCount].Flags = 0;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ // Weekday / YY2
+ if (TransactionCount >= MAX_TRANSACTION_COUNT)
+ return NV_FALSE;
+ TransactionInfo[TransactionCount].Address =
+ (MAX8907B_RTC_SLAVE_ADDR | 0x1);
+ TransactionInfo[TransactionCount].Buf = &ReadBuffer[3];
+ TransactionInfo[TransactionCount].Flags = 0;
+ TransactionInfo[TransactionCount++].NumBytes = 1;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0],
+ TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) |
+ (ReadBuffer[2] << 8) | ReadBuffer[3];
+
+ return NV_TRUE;
+ }
+ }
+
+ // Transaction Error
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("Max8907bRtcI2cRead32 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("Max8907bRtcI2cRead32 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h
new file mode 100644
index 000000000000..c4b5c634c4fa
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_PMU_MAX8907B_I2C_H
+#define INCLUDED_NVODM_PMU_MAX8907B_I2C_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// Constant definition
+// #define PMU_MAX8907B_DEVADDR TBD
+#define PMU_MAX8907B_I2C_SPEED_KHZ 400
+
+// Function declaration
+NvBool Max8907bI2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data);
+
+NvBool Max8907bI2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data);
+
+NvBool Max8907bI2cWrite32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 Data);
+
+NvBool Max8907bI2cRead32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 *Data);
+
+NvBool Max8907bRtcI2cWriteTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 Data);
+
+NvBool Max8907bRtcI2cReadTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 *Data);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_PMU_MAX8907B_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c
new file mode 100644
index 000000000000..38110f83c5a0
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "max8907b.h"
+#include "max8907b_interrupt.h"
+#include "max8907b_i2c.h"
+#include "max8907b_reg.h"
+#include "max8907b_batterycharger.h"
+#include "nvodm_services.h"
+
+NvBool
+Max8907bSetupInterrupt(
+ NvOdmPmuDeviceHandle hDevice,
+ Max8907bStatus *pmuStatus)
+{
+ NvBool status = NV_FALSE;
+ NvU8 data = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pmuStatus);
+
+ /* Init Pmu Status */
+ pmuStatus->lowBatt = NV_FALSE;
+ pmuStatus->highTemp = NV_FALSE;
+
+ if (!Max8907bBatteryChargerMainBatt(hDevice, &status))
+ return NV_FALSE;
+ pmuStatus->mChgPresent = status;
+
+ /* Set up Interrupt Mask */
+
+ // CHG_IRQ1
+ data = 0;
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_CHG_IRQ1, data))
+ return NV_FALSE;
+
+ // CHG_IRQ2
+ data = MAX8907B_CHG_IRQ2_CHG_DONE_MASK |
+ MAX8907B_CHG_IRQ2_MBATTLOW_F_SHIFT |
+ MAX8907B_CHG_IRQ2_THM_OK_F_MASK |
+ MAX8907B_CHG_IRQ2_THM_OK_R_MASK ;
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_CHG_IRQ2, data))
+ return NV_FALSE;
+
+ // ON_OFF_IRQ1
+ data = 0;
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_ON_OFF_IRQ1, data))
+ return NV_FALSE;
+
+ // ON_OFF_IRQ2
+ data = 0;
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_ON_OFF_IRQ2, data))
+ return NV_FALSE;
+
+ // RTC_IRQ
+ data = 0;
+ if (!Max8907bI2cWrite8(hDevice, MAX8907B_RTC_IRQ, data))
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+void
+Max8907bInterruptHandler_int(
+ NvOdmPmuDeviceHandle hDevice,
+ Max8907bStatus *pmuStatus)
+{
+ NvU8 data = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pmuStatus);
+
+ /* Check which interrupt... */
+
+ // CHG_IRQ1
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_CHG_IRQ1, &data))
+ {
+ return;
+ }
+
+ if (data)
+ {
+ // VBUS connect interrupt
+ if (data &
+ (MAX8907B_CHG_IRQ1_VCHG_R_MASK << MAX8907B_CHG_IRQ1_VCHG_R_SHIFT))
+ {
+ NvOdmEnableOtgCircuitry(NV_TRUE);
+ }
+ // VBUS dis-connect interrupt
+ else if (data &
+ (MAX8907B_CHG_IRQ1_VCHG_F_MASK << MAX8907B_CHG_IRQ1_VCHG_F_SHIFT))
+ {
+ NvOdmEnableOtgCircuitry(NV_FALSE);
+ }
+ }
+
+ // CHG_IRQ2
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_CHG_IRQ2, &data))
+ {
+ return;
+ }
+ if (data)
+ {
+ if (data & MAX8907B_CHG_IRQ2_CHG_DONE_MASK)
+ {
+ pmuStatus->mChgPresent = NV_TRUE;
+ pmuStatus->batFull = NV_TRUE;
+ }
+ if (data & MAX8907B_CHG_IRQ2_MBATTLOW_F_SHIFT)
+ {
+ pmuStatus->batFull = NV_FALSE;
+ }
+ if (data & MAX8907B_CHG_IRQ2_THM_OK_F_MASK)
+ {
+ pmuStatus->highTemp = NV_TRUE;
+ }
+ if (data & MAX8907B_CHG_IRQ2_THM_OK_R_MASK)
+ {
+ pmuStatus->highTemp = NV_FALSE;
+ }
+ }
+
+ // ON_OFF_IRQ1
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_ON_OFF_IRQ1, &data))
+ {
+ return;
+ }
+
+ // ON_OFF_IRQ2
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_ON_OFF_IRQ2, &data))
+ {
+ return;
+ }
+
+ // RTC_IRQ
+ if (!Max8907bI2cRead8(hDevice, MAX8907B_RTC_IRQ, &data))
+ {
+ return;
+ }
+
+ return;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h
new file mode 100644
index 000000000000..a00cabc17039
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_MAX8907B_INTERRUPT_HEADER
+#define INCLUDED_MAX8907B_INTERRUPT_HEADER
+
+#include "max8907b.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+NvBool
+Max8907bSetupInterrupt(
+ NvOdmPmuDeviceHandle hDevice,
+ Max8907bStatus *pmuStatus);
+
+void
+Max8907bInterruptHandler_int(
+ NvOdmPmuDeviceHandle hDevice,
+ Max8907bStatus *pmuStatus);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_MAX8907B_INTERRUPT_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h
new file mode 100644
index 000000000000..513e2f6a1812
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2009-2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_MAX8907B_REG_HEADER
+#define INCLUDED_MAX8907B_REG_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// -- MAX8907B Addresses (See Table 71 of data sheet) --
+
+/* MAX8907B Slave Addresses */
+
+#define MAX8907B_PMU_SLAVE_ADDR 0x78
+#define MAX8907B_RTC_SLAVE_ADDR 0xD0
+#define MAX8907B_ADC_SLAVE_ADDR 0x8E
+
+/* MAX8907B Register Addresses */
+
+// Main-Battery Charger
+#define MAX8907B_CHG_CNTL1 0x7C
+#define MAX8907B_CHG_CNTL2 0x7D
+#define MAX8907B_CHG_IRQ1 0x7E
+#define MAX8907B_CHG_IRQ2 0x7F
+#define MAX8907B_CHG_IRQ1_MASK 0x80
+#define MAX8907B_CHG_IRQ2_MASK 0x81
+#define MAX8907B_CHG_STAT 0x82
+
+// Backup-Battery Charger
+#define MAX8907B_BBATT_CNFG 0x78
+#define MAX8907B_SDBYSEQCNT 0x13
+
+// V1 Step Down Regulator
+#define MAX8907B_SDCTL1 0x04
+#define MAX8907B_SDSEQCNT1 0x05
+#define MAX8907B_SDV1 0x06
+
+// V2 Step Down Regulator
+#define MAX8907B_SDCTL2 0x07
+#define MAX8907B_SDSEQCNT2 0x08
+#define MAX8907B_SDV2 0x09
+
+// V3 Step Down Regulator
+#define MAX8907B_SDCTL3 0x0A
+#define MAX8907B_SDSEQCNT3 0x0B
+#define MAX8907B_SDV3 0x0C
+
+// LDO1 Regulator
+#define MAX8907B_LDOCTL1 0x18
+#define MAX8907B_LDOSEQCNT1 0x19
+#define MAX8907B_LDO1VOUT 0x1A
+
+// LDO2 Regulator
+#define MAX8907B_LDOCTL2 0x1C
+#define MAX8907B_LDOSEQCNT2 0x1D
+#define MAX8907B_LDO2VOUT 0x1E
+
+// LDO3 Regulator
+#define MAX8907B_LDOCTL3 0x20
+#define MAX8907B_LDOSEQCNT3 0x21
+#define MAX8907B_LDO3VOUT 0x22
+
+// LDO4 Regulator
+#define MAX8907B_LDOCTL4 0x24
+#define MAX8907B_LDOSEQCNT4 0x25
+#define MAX8907B_LDO4VOUT 0x26
+
+// LDO5 Regulator
+#define MAX8907B_LDOCTL5 0x28
+#define MAX8907B_LDOSEQCNT5 0x29
+#define MAX8907B_LDO5VOUT 0x2A
+
+// LDO6 Regulator
+#define MAX8907B_LDOCTL6 0x2C
+#define MAX8907B_LDOSEQCNT6 0x2D
+#define MAX8907B_LDO6VOUT 0x2E
+
+// LDO7 Regulator
+#define MAX8907B_LDOCTL7 0x30
+#define MAX8907B_LDOSEQCNT7 0x31
+#define MAX8907B_LDO7VOUT 0x32
+
+// LDO8 Regulator
+#define MAX8907B_LDOCTL8 0x34
+#define MAX8907B_LDOSEQCNT8 0X35
+#define MAX8907B_LDO8VOUT 0x36
+
+// LDO9 Regulator
+#define MAX8907B_LDOCTL9 0x38
+#define MAX8907B_LDOSEQCNT9 0x39
+#define MAX8907B_LDO9VOUT 0x3A
+
+// LDO10 Regulator
+#define MAX8907B_LDOCTL10 0x3C
+#define MAX8907B_LDOSEQCNT10 0x3D
+#define MAX8907B_LDO10VOUT 0x3E
+
+// LDO11 Regulator
+#define MAX8907B_LDOCTL11 0x40
+#define MAX8907B_LDOSEQCNT11 0x41
+#define MAX8907B_LDO11VOUT 0x42
+
+// LDO12 Regulator
+#define MAX8907B_LDOCTL12 0x44
+#define MAX8907B_LDOSEQCNT12 0x45
+#define MAX8907B_LDO12VOUT 0x46
+
+// LDO13 Regulator
+#define MAX8907B_LDOCTL13 0x48
+#define MAX8907B_LDOSEQCNT13 0x49
+#define MAX8907B_LDO13VOUT 0x4A
+
+// LDO14 Regulator
+#define MAX8907B_LDOCTL14 0x4C
+#define MAX8907B_LDOSEQCNT14 0x4D
+#define MAX8907B_LDO14VOUT 0x4E
+
+// LDO15 Regulator
+#define MAX8907B_LDOCTL15 0x50
+#define MAX8907B_LDOSEQCNT15 0x51
+#define MAX8907B_LDO15VOUT 0x52
+
+// LDO16 Regulator
+#define MAX8907B_LDOCTL16 0x10
+#define MAX8907B_LDOSEQCNT16 0x11
+#define MAX8907B_LDO16VOUT 0x12
+
+// LDO17 Regulator
+#define MAX8907B_LDOCTL17 0x14
+#define MAX8907B_LDOSEQCNT17 0x15
+#define MAX8907B_LDO17VOUT 0x16
+
+// LDO18 Regulator
+#define MAX8907B_LDOCTL18 0x72
+#define MAX8907B_LDOSEQCNT18 0x73
+#define MAX8907B_LDO18VOUT 0x74
+
+// LDO19 Regulator
+#define MAX8907B_LDOCTL19 0x5C
+#define MAX8907B_LDOSEQCNT19 0x5D
+#define MAX8907B_LDO19VOUT 0x5E
+
+// LDO20 Regulator
+#define MAX8907B_LDOCTL20 0x9C
+#define MAX8907B_LDOSEQCNT20 0x9D
+#define MAX8907B_LDO20VOUT 0x9E
+
+// OUT5V Regulator
+#define MAX8907B_OUT5VEN 0x54
+#define MAX8907B_OUT5VSEQ 0x55
+
+// OUT3.3V Regulator
+#define MAX8907B_OUT_3_3VEN 0x58
+#define MAX8907B_OUT_3_3VSEQ 0x59
+
+// Main Bias Register
+#define MAX8907B_LBCNFG 0x60
+
+// ON/OFF Controller
+#define MAX8907B_SYSENSEL 0x00
+#define MAX8907B_ON_OFF_IRQ1 0x01
+#define MAX8907B_ON_OFF_IRQ1_MASK 0x02
+#define MAX8907B_ON_OFF_STAT 0x03
+#define MAX8907B_ON_OFF_IRQ2 0x0D
+#define MAX8907B_ON_OFF_IRQ2_MASK 0x0E
+#define MAX8907B_RESET_CNFG 0x0F
+
+// Flexible Power Sequencer
+#define MAX8907B_SEQ1CNFG 0x64
+#define MAX8907B_SEQ2CNFG 0x65
+#define MAX8907B_SEQ3CNFG 0x66
+#define MAX8907B_SEQ4CNFG 0x67
+#define MAX8907B_SEQ5CNFG 0x68
+#define MAX8907B_SEQ6CNFG 0x69
+#define MAX8907B_SEQ7CNFG 0x6A
+
+// RTC Registers
+#define MAX8907B_RTC_SEC 0x00
+#define MAX8907B_RTC_MIN 0x01
+#define MAX8907B_RTC_HOURS 0x02
+#define MAX8907B_RTC_WEEKDAY 0x03
+#define MAX8907B_RTC_DATE 0x04
+#define MAX8907B_RTC_MONTH 0x05
+#define MAX8907B_RTC_YEAR1 0x06
+#define MAX8907B_RTC_YEAR2 0x07
+#define MAX8907B_ALARM0_SEC 0x08
+#define MAX8907B_ALARM0_MIN 0x09
+#define MAX8907B_ALARM0_HOURS 0x0A
+#define MAX8907B_ALARM0_WEEKDAY 0x0B
+#define MAX8907B_ALARM0_DATE 0x0C
+#define MAX8907B_ALARM0_MONTH 0x0D
+#define MAX8907B_ALARM0_YEAR1 0x0E
+#define MAX8907B_ALARM0_YEAR2 0x0F
+#define MAX8907B_ALARM1_SEC 0x10
+#define MAX8907B_ALARM1_MIN 0x11
+#define MAX8907B_ALARM1_HOURS 0x12
+#define MAX8907B_ALARM1_WEEKDAY 0x13
+#define MAX8907B_ALARM1_DATE 0x14
+#define MAX8907B_ALARM1_MONTH 0x15
+#define MAX8907B_ALARM1_YEAR1 0x16
+#define MAX8907B_ALARM1_YEAR2 0x17
+#define MAX8907B_ALARM0_CNTL 0x18
+#define MAX8907B_ALARM1_CNTL 0x19
+#define MAX8907B_RTC_STATUS 0x1A
+#define MAX8907B_RTC_CNTL 0x1B
+#define MAX8907B_RTC_IRQ 0x1C
+#define MAX8907B_RTC_IRQ_MASK 0x1D
+#define MAX8907B_MPL_CNTL 0x1E
+
+// ADC and Touch Screen Controller
+#define MAX8907B_TSC_STA_INT 0x00
+#define MAX8907B_TSC_INT_MASK 0x01
+#define MAX8907B_TSC_CNFG1 0x02
+#define MAX8907B_TSC_CNFG2 0x03
+#define MAX8907B_TSC_CNFG3 0x04
+#define MAX8907B_ADC_RES_CNFG1 0x06
+#define MAX8907B_ADC_AVG_CNFG1 0x07
+#define MAX8907B_ADC_ACQ_CNFG1 0x08
+#define MAX8907B_ADC_ACQ_CNFG2 0x09
+#define MAX8907B_ADC_SCHED 0x10
+#define MAX8907B_X_MSB 0x50
+#define MAX8907B_X_LSB 0x51
+#define MAX8907B_Y_MSB 0x52
+#define MAX8907B_Y_LSB 0x53
+#define MAX8907B_Z1_MSB 0x54
+#define MAX8907B_Z1_LSB 0x55
+#define MAX8907B_Z2_MSB 0x56
+#define MAX8907B_Z2_LSB 0x57
+#define MAX8907B_AUX1_MSB 0x60
+#define MAX8907B_AUX1_LSB 0x61
+#define MAX8907B_AUX2_MSB 0x62
+#define MAX8907B_AUX2_LSB 0x63
+#define MAX8907B_VCHG_MSB 0x64
+#define MAX8907B_VCHG_LSB 0x65
+#define MAX8907B_VBBATT_MSB 0x66
+#define MAX8907B_VBBATT_LSB 0x67
+#define MAX8907B_VMBATT_MSB 0x68
+#define MAX8907B_VMBATT_LSB 0x69
+#define MAX8907B_ISNS_MSB 0x6A
+#define MAX8907B_ISNS_LSB 0x6B
+#define MAX8907B_THM_MSB 0x6C
+#define MAX8907B_THM_LSB 0x6D
+#define MAX8907B_TDIE_MSB 0x6E
+#define MAX8907B_TDIE_LSB 0x6F
+
+// WLED Driver
+#define MAX8907B_WLED_MODE_CNTL 0x84
+#define MAX8907B_ILED_CNTL 0x85
+
+// Chip Identification
+#define MAX8907B_II1RR 0x8E
+#define MAX8907B_II2RR 0x8F
+
+#define MAX8907B_REG_INVALID 0xFF
+
+/* field defines for register bit ops */
+#define MAX8907B_OUT_VOLTAGE_MASK 0x3F
+#define MAX8907B_OUT_VOLTAGE_ENABLE_BIT 0x01
+#define MAX8907B_OUT_VOLTAGE_DISABLE_MASK 0x3E
+
+#define MAX8907B_CTL_SEQ_SHIFT 0x02
+#define MAX8907B_CTL_SEQ_MASK 0x07
+
+// CHG_CNTL_1
+#define MAX8907B_CHG_CNTL1_NOT_CHGEN_SHIFT 0x7
+#define MAX8907B_CHG_CNTL1_NOT_CHGEN_MASK 0x1
+#define MAX8907B_CHG_CNTL1_CHG_TOPOFF_SHIFT 0x5
+#define MAX8907B_CHG_CNTL1_CHG_TOPOFF_MASK 0x3
+#define MAX8907B_CHG_CNTL1_CHG_RST_HYS_SHIFT 0x3
+#define MAX8907B_CHG_CNTL1_CHG_RST_HYS_MASK 0x3
+#define MAX8907B_CHG_CNTL1_FCHG_SHIFT 0x0
+#define MAX8907B_CHG_CNTL1_FCHG_MASK 0x7
+
+#define MAX8907B_CHG_CNTL1_FCHG_85MA 0
+#define MAX8907B_CHG_CNTL1_FCHG_300MA 1
+#define MAX8907B_CHG_CNTL1_FCHG_460MA 2
+#define MAX8907B_CHG_CNTL1_FCHG_600MA 3
+#define MAX8907B_CHG_CNTL1_FCHG_700MA 4
+#define MAX8907B_CHG_CNTL1_FCHG_800MA 5
+#define MAX8907B_CHG_CNTL1_FCHG_900MA 6
+#define MAX8907B_CHG_CNTL1_FCHG_1000MA 7
+
+// CHG_CNTL_1
+#define MAX8907B_CHG_CNTL2_FCHG_TMR_SHIFT 0x4
+#define MAX8907B_CHG_CNTL2_FCHG_TMR_MASK 0x3
+#define MAX8907B_CHG_CNTL2_MBAT_REG_TH_SHIFT 0x3
+#define MAX8907B_CHG_CNTL2_MBAT_REG_TH_MASK 0x1
+#define MAX8907B_CHG_CNTL2_TDIE_THERM_REG_SHIFT 0x0
+#define MAX8907B_CHG_CNTL2_TDIE_THERM_REG_MASK 0x3
+
+// Interrupts
+#define MAX8907B_CHG_STAT_VCHG_OK_SHIFT 0x7
+#define MAX8907B_CHG_STAT_VCHG_OK_MASK 0x1
+#define MAX8907B_CHG_STAT_CHG_TMR_FLT_SHIFT 0x5
+#define MAX8907B_CHG_STAT_CHG_TMR_FLT_MASK 0x1
+#define MAX8907B_CHG_STAT_CHG_EN_STAT_SHIFT 0x4
+#define MAX8907B_CHG_STAT_CHG_EN_STAT_MASK 0x1
+#define MAX8907B_CHG_STAT_CHG_MODE_SHIFT 0x2
+#define MAX8907B_CHG_STAT_CHG_MODE_MASK 0x3
+#define MAX8907B_CHG_STAT_MBDET_SHIFT 0x1
+#define MAX8907B_CHG_STAT_MBDET_MASK 0x1
+#define MAX8907B_CHG_STAT_MBATTLOW_SHIFT 0x0
+#define MAX8907B_CHG_STAT_MBATTLOW_MASK 0x1
+
+#define MAX8907B_CHG_IRQ1_VCHG_R_SHIFT 0x2
+#define MAX8907B_CHG_IRQ1_VCHG_R_MASK 0x1
+#define MAX8907B_CHG_IRQ1_VCHG_F_SHIFT 0x1
+#define MAX8907B_CHG_IRQ1_VCHG_F_MASK 0x1
+#define MAX8907B_CHG_IRQ1_VCHG_OVP_SHIFT 0x0
+#define MAX8907B_CHG_IRQ1_VCHG_OVP_MASK 0x1
+
+#define MAX8907B_CHG_IRQ2_CHG_TMR_FAULT_SHIFT 0x7
+#define MAX8907B_CHG_IRQ2_CHG_TMR_FAULT_MASK 0x1
+#define MAX8907B_CHG_IRQ2_CHG_TOPOFF_SHIFT 0x6
+#define MAX8907B_CHG_IRQ2_CHG_TOPOFF_MASK 0x1
+#define MAX8907B_CHG_IRQ2_CHG_DONE_SHIFT 0x5
+#define MAX8907B_CHG_IRQ2_CHG_DONE_MASK 0x1
+#define MAX8907B_CHG_IRQ2_CHG_RST_SHIFT 0x4
+#define MAX8907B_CHG_IRQ2_CHG_RST_MASK 0x1
+#define MAX8907B_CHG_IRQ2_MBATTLOW_R_SHIFT 0x3
+#define MAX8907B_CHG_IRQ2_MBATTLOW_R_MASK 0x1
+#define MAX8907B_CHG_IRQ2_MBATTLOW_F_SHIFT 0x2
+#define MAX8907B_CHG_IRQ2_MBATTLOW_F_MASK 0x1
+#define MAX8907B_CHG_IRQ2_THM_OK_F_SHIFT 0x1
+#define MAX8907B_CHG_IRQ2_THM_OK_F_MASK 0x1
+#define MAX8907B_CHG_IRQ2_THM_OK_R_SHIFT 0x0
+#define MAX8907B_CHG_IRQ2_THM_OK_R_MASK 0x1
+
+#define MAX8907B_ON_OFF_IRQ1_SW_R_SHIFT 0x7
+#define MAX8907B_ON_OFF_IRQ1_SW_R_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_SW_F_SHIFT 0x6
+#define MAX8907B_ON_OFF_IRQ1_SW_F_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_SW_1SEC_SHIFT 0x5
+#define MAX8907B_ON_OFF_IRQ1_SW_1SEC_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_EXTON_R_SHIFT 0x4
+#define MAX8907B_ON_OFF_IRQ1_EXTON_R_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_EXTON_F_SHIFT 0x3
+#define MAX8907B_ON_OFF_IRQ1_EXTON_F_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_SW_3SEC_SHIFT 0x2
+#define MAX8907B_ON_OFF_IRQ1_SW_3SEC_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_MPL_EVENT_SHIFT 0x1
+#define MAX8907B_ON_OFF_IRQ1_MPL_EVENT_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ1_RSTIN_F_SHIFT 0x0
+#define MAX8907B_ON_OFF_IRQ1_RSTIN_F_MASK 0x1
+
+#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_R_SHIFT 0x1
+#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_R_MASK 0x1
+#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_F_SHIFT 0x0
+#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_F_MASK 0x1
+
+#define MAX8907B_RTC_IRQ_ALARM0_R_SHIFT 0x3
+#define MAX8907B_RTC_IRQ_ALARM0_R_MASK 0x1
+#define MAX8907B_RTC_IRQ_ALARM1_R_SHIFT 0x2
+#define MAX8907B_RTC_IRQ_ALARM1_R_MASK 0x1
+
+// ON/OFF controller
+#define MAX8907B_SYSENSEL_HRDSTEN_SHIFT 0x7
+#define MAX8907B_SYSENSEL_HRDSTEN_MASK 0x1
+
+#define MAX8907B_RESET_CNFG_PWREN_EN_SHIFT 0x7
+#define MAX8907B_RESET_CNFG_PWREN_EN_MASK 0x1
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //INCLUDED_MAX8907B_REG_HEADER
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c
new file mode 100644
index 000000000000..1c4d61a01a98
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/time.h>
+#include <linux/rtc.h>
+#include "max8907b.h"
+#include "max8907b_rtc.h"
+#include "max8907b_i2c.h"
+#include "max8907b_reg.h"
+
+/**
+* The Maxim 8907B does not have an RTC that simply counts
+* seconds from some time t0 (as defined by the OS API).
+* Instead, this RTC contains several BCD (Binary Coded Decimal)
+* registers, including: seconds, minutes, hours, days, day of
+* week, date, etc... These registers account for leap year and
+* the various days of the month as well.
+*
+* Since the OS interpretation of seconds to a particular
+* date/time from some OS-defined t0 is unknown at this level of
+* the implementation, it is not possible to translate the given
+* seconds into these registers (at least, not without a
+* dependency on some OS-specific information).
+*
+*/
+
+#define MAX8907B_SECONDS_PER_DAY (60*60*24)
+#define MAX8907B_SECONDS_PER_HOUR (60*60)
+#define MAX8907B_SECONDS_PER_MINUTE (60)
+
+#define LINUX_RTC_BASE_YEAR 1900
+
+/* Macro for conversion of BCD number to decimal format */
+#define BCD_TO_DECIMAL(BCD) \
+ ((((BCD) & 0xF0) >> 4) * 10 + ((BCD) & 0xF))
+/* Macro for conversion of decimal number to BCD format */
+#define DECIMAL_TO_BCD(DEC) \
+ ((((DEC) / 10) << 4) | ((DEC) % 10))
+
+static NvBool bRtcNotInitialized = NV_TRUE;
+
+NvBool
+Max8907bRtcCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count)
+{
+ NvU32 data = 0;
+ NvU32 BcdHours, BcdMinutes, BcdSeconds;
+ NvU32 Hours, Minutes, Seconds;
+ NvU32 BcdDD, BcdMM, BcdYY1, BcdYY2;
+ NvU32 DD, MM, YY1, YY2, YYYY;
+#if NV_DEBUG
+ struct rtc_time tm;
+#endif
+
+ *Count = 0;
+ // Read seconds, minute, hour and weekday data from RTC registers
+ if (Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_SEC, &data))
+ {
+ NVODMPMU_PRINTF(("\n Read time data-sec=0x%x ", data));
+ // Extract seconds, minute and hour data from RTC registers read
+ BcdHours = (data >> 8) & 0xFF;
+ BcdMinutes = (data >> 16) & 0xFF;
+ BcdSeconds = (data >> 24) & 0xFF;
+
+ // Convert BCD time into decimal values
+ Hours = BCD_TO_DECIMAL(BcdHours);
+ Minutes = BCD_TO_DECIMAL(BcdMinutes);
+ Seconds = BCD_TO_DECIMAL(BcdSeconds);
+
+ // Read day, month, yy1 and yy2 data from RTC registers
+ if (Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_DATE, &data))
+ {
+ NVODMPMU_PRINTF(("\n Read time data-year=0x%x ", data));
+ // Extract day, month, yy1 and yy2 data from RTC registers read
+ BcdYY2 = (data & 0xFF);
+ BcdYY1 = (data >> 8) & 0xFF;
+ BcdMM = (data >> 16) & 0xFF;
+ BcdDD = (data >> 24) & 0xFF;
+ // convert bcd day/month/year data to decimal values
+ YY2 = BCD_TO_DECIMAL(BcdYY2);
+ YY1 = BCD_TO_DECIMAL(BcdYY1);
+ YYYY = (YY2 * 100 + YY1) & 0xFFFF;
+ MM = BCD_TO_DECIMAL(BcdMM);
+ DD = BCD_TO_DECIMAL(BcdDD);
+ // get seconds since reference time value given
+ // year, month, day, hour, minutes and seconds
+ // NOTE: Using linux specific API mktime for conversion
+ *Count = mktime(YYYY, (MM + 1), DD, Hours, Minutes, Seconds);
+ NVODMPMU_PRINTF(("\n Rtc read count=0x%x ", *Count));
+ NVODMPMU_PRINTF(("\n mktime: YYYY=%d MM=%d DD=%d Hr=%d Min=%d "
+ "Sec=%d, *Count=0x%x ", YYYY, (MM + 1), DD, Hours, Minutes,
+ Seconds, *Count));
+#if NV_DEBUG
+ // Call to verify that reverse conversion of seconds matches date
+ rtc_time_to_tm(*Count, &tm);
+ // Check if Local_rtc_time_to_tm can return values sent to mktime
+ NVODMPMU_PRINTF(("\n rtc_time_to_tm: YYYY=%d MM=%d DD=%d Hr=%d "
+ "Min=%d Sec=%d, *Count=0x%x ", (tm.tm_year +
+ LINUX_RTC_BASE_YEAR), tm.tm_mon, tm.tm_mday, tm.tm_hour,
+ tm.tm_min, tm.tm_sec, *Count));
+#endif
+ }
+ else
+ {
+ NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. "));
+ return NV_FALSE;
+ }
+ }
+ else
+ {
+ NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. "));
+ return NV_FALSE;
+ }
+ NVODMPMU_PRINTF(("\n *Count=0x%x ", *Count));
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bRtcAlarmCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count)
+{
+ return NV_FALSE;
+}
+
+NvBool
+Max8907bRtcCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ NvU32 BcdHours, BcdMinutes, BcdSeconds;
+ NvU32 data = 0;
+ NvU8 BcdDD, BcdMM, BcdYY1, BcdYY2;
+ NvU16 YYYY;
+ struct rtc_time tm;
+#if NV_DEBUG
+ NvU32 data1;
+#endif
+
+ NVODMPMU_PRINTF(("\n Rtc write count=0x%x ", Count));
+ // convert seconds since reference time into date
+ // NOTE: using linux specific convert function rtc_time_to_tm
+ rtc_time_to_tm(Count, &tm);
+ NVODMPMU_PRINTF(("\n rtc_time_to_tm: YYYY=%d MM=%d DD=%d Hr=%d Min=%d "
+ "Sec=%d, *Count=0x%x ", (tm.tm_year + LINUX_RTC_BASE_YEAR),
+ (tm.tm_mon + 1), tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec, Count));
+
+ // Convert time to bcd format
+ BcdHours = DECIMAL_TO_BCD(tm.tm_hour);
+ BcdMinutes = DECIMAL_TO_BCD(tm.tm_min);
+ BcdSeconds = DECIMAL_TO_BCD(tm.tm_sec);
+
+ data = (BcdSeconds << 24) | (BcdMinutes << 16) | (BcdHours << 8);
+ // write time - seconds, minutes and hours in a day to RTC registers
+ if (Max8907bRtcI2cWriteTime(hDevice, MAX8907B_RTC_SEC, data))
+ {
+ // set the day, month, year
+ // Assuming we get the days since 1 Jan 1970
+
+ // convert date to bcd format
+ BcdDD = DECIMAL_TO_BCD((NvU8)tm.tm_mday);
+ BcdMM = DECIMAL_TO_BCD((NvU8)tm.tm_mon);
+ YYYY = (NvU16)tm.tm_year + LINUX_RTC_BASE_YEAR;
+ BcdYY1 = DECIMAL_TO_BCD((NvU8)(YYYY % 100));
+ BcdYY2 = DECIMAL_TO_BCD((NvU8)(YYYY / 100));
+ data = (NvU32)((BcdDD << 24) | (BcdMM << 16) | (BcdYY1 << 8) | BcdYY2);
+ // write date - day, month, and year to RTC registers
+ if (!(Max8907bRtcI2cWriteTime(hDevice, MAX8907B_RTC_DATE, data)))
+ {
+ NVODMPMU_PRINTF(("\n Max8907bRtcCountWrite() error. "));
+ return NV_FALSE;
+ }
+#if NV_DEBUG
+ // verify that read back values from RTC matches written values
+ if (!(Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_DATE, &data1)))
+ {
+ NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. "));
+ return NV_FALSE;
+ }
+ if (data1 == data)
+ {
+ NVODMPMU_PRINTF(("\n Write read Success. "));
+ return NV_TRUE;
+ }
+ else
+ {
+ // return error when read data does not match written data
+ NVODMPMU_PRINTF(("\n Error: write data=0x%x, rd data=0x%x. ", data, data1));
+ return NV_FALSE;
+ }
+#endif
+ }
+ else
+ {
+ NVODMPMU_PRINTF(("\n Max8907bRtcCountWrite() error. "));
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool
+Max8907bRtcAlarmCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ return NV_FALSE;
+}
+
+NvBool
+Max8907bRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice)
+{
+ return NV_FALSE;
+}
+
+NvBool
+Max8907bRtcAlarmIntEnable(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool Enable)
+{
+ return NV_FALSE;
+}
+
+NvBool
+Max8907bIsRtcInitialized(NvOdmPmuDeviceHandle hDevice)
+{
+ return (!bRtcNotInitialized);
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h
new file mode 100644
index 000000000000..0baa0de55339
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_MAX8907B_RTC_HEADER
+#define INCLUDED_MAX8907B_RTC_HEADER
+
+#include "pmu_hal.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* Read RTC count register */
+
+NvBool
+Max8907bRtcCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count);
+
+/* Read RTC alarm count register */
+
+NvBool
+Max8907bRtcAlarmCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count);
+
+/* Write RTC count register */
+
+NvBool
+Max8907bRtcCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count);
+
+/* Write RTC alarm count register */
+
+NvBool
+Max8907bRtcAlarmCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count);
+
+/* Reads RTC alarm interrupt mask status */
+
+NvBool
+Max8907bRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice);
+
+/* Enables / Disables the RTC alarm interrupt */
+
+NvBool
+Max8907bRtcAlarmIntEnable(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool Enable);
+
+/* Checks if boot was from nopower / powered state */
+
+NvBool
+Max8907bRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice);
+
+NvBool
+Max8907bIsRtcInitialized(NvOdmPmuDeviceHandle hDevice);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_MAX8907B_RTC_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h
new file mode 100644
index 000000000000..1b362aac43f4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_MAX8907B_SUPPLY_INFO_HEADER
+#define INCLUDED_MAX8907B_SUPPLY_INFO_HEADER
+
+#include "nvodm_pmu.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// Defines for the requested voltage for each supply (mV).
+// This is board specific and ODM should change this based on device.
+#define MAX8907B_REQUESTVOLTAGE_LX_V1 1000
+#define MAX8907B_REQUESTVOLTAGE_LX_V2 1200
+#define MAX8907B_REQUESTVOLTAGE_LX_V3 1800
+
+#define MAX8907B_REQUESTVOLTAGE_LDO1 3300
+#define MAX8907B_REQUESTVOLTAGE_LDO2 1100
+#define MAX8907B_REQUESTVOLTAGE_LDO3 1800
+#define MAX8907B_REQUESTVOLTAGE_LDO4 3300
+#define MAX8907B_REQUESTVOLTAGE_LDO5 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO6 1800
+#define MAX8907B_REQUESTVOLTAGE_LDO7 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO8 3000
+#define MAX8907B_REQUESTVOLTAGE_LDO9 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO10 3000
+#define MAX8907B_REQUESTVOLTAGE_LDO11 3300
+#define MAX8907B_REQUESTVOLTAGE_LDO12 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO13 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO14 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO15 3300
+#define MAX8907B_REQUESTVOLTAGE_LDO16 1300
+#define MAX8907B_REQUESTVOLTAGE_LDO17 1200
+#define MAX8907B_REQUESTVOLTAGE_LDO18 1800
+#define MAX8907B_REQUESTVOLTAGE_LDO19 2800
+#define MAX8907B_REQUESTVOLTAGE_LDO20 1200
+
+#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1 5000 // Fixed
+#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_2 0 // Reserved
+#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3 1050 // Fixed (unless FAN5355 is enabled)
+#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_4 0 // VBL1, controlled by display adaptation
+#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_5 0 // VBL2, controlled by display adaptation
+#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_6 0 // Reserved
+
+#define MAX8907B_REQUESTVOLTAGE_SDBY 1100
+
+// Defines default sequencer selection
+#define MAX8907B_SEQSEL_DEFAULT_LX_V1 0 /* SEQ1 (SYSEN) */
+#define MAX8907B_SEQSEL_DEFAULT_LX_V2 0 /* SEQ1 (SYSEN) */
+
+// Defines common for all supplies PWREN sequencer selection
+#define MAX8907B_SEQSEL_PWREN_LXX 1 /* SEQ2 (PWREN) */
+
+// Defines common for all supplies I2C (s/w) sequencer selection
+#define MAX8907B_SEQSEL_I2CEN_LXX 7 /* I2CEN (s/w) */
+
+// Defines sequencer count default values
+#define MAX8907B_SEQCNT_DEFAULT_LX_V1 0x1C
+#define MAX8907B_SEQCNT_DEFAULT_LX_V2 0x1C
+
+// Defines sequencer count PWREN control values (these settings applied
+// togeteher, when both CPU/V1 and CORE/V2 rails are attached to PWREN;
+// in case when only CPU/V1 rail is attached no delay is specified)
+// B[7:4] - power up delay in 20us taps
+// B[3:0] - power down delay in 20us taps
+#define MAX8907B_SEQCNT_PWREN_LX_V1 0xC0 /* 240us up delay */
+#define MAX8907B_SEQCNT_PWREN_LX_V2 0x00 /* no delay */
+
+// Defines PMU output timing parameters. Scaling up time is dynamically
+// calculated based on the slew rate maintained by MAX8907B. Turn On delay
+// is fixed at max. Turn Off time is "just in case" placeholder - no need
+// for s/w to track when output capacitors are discharged.
+#define MAX8907B_SCALE_UP_UV_PER_US (2500)
+#define MAX8907B_TURN_ON_TIME_US (3000)
+#define MAX8907B_TURN_OFF_TIME_US (20)
+
+// Output voltages supplied by PMU
+typedef enum
+{
+ Max8907bPmuSupply_Invalid = 0x0,
+
+ /*-- Step-Down DC Regulators --*/
+ Max8907bPmuSupply_LX_V1, // LX_V1 (V1), step-down DC regulator
+ Max8907bPmuSupply_LX_V2, // LX_V2 (V2), step-down DC regulator
+ Max8907bPmuSupply_LX_V3, // LX_V3 (V3), step-down DC regulator
+
+ /*-- Standby LDO --*/
+ Max8907bPmuSupply_VRTC, // VRTC (RTC), always-on supply for RTC
+
+ /*-- Linear Regulator Outputs --*/
+ Max8907bPmuSupply_LDO1, // LDO1 (VOUT1), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO2, // LDO2 (VOUT2), linear regulator output (default = 1.2V)
+ Max8907bPmuSupply_LDO3, // LDO3 (VOUT3), linear regulator output (default = 1.2V)
+ Max8907bPmuSupply_LDO4, // LDO4 (VOUT4), linear regulator output (default = 3.3V)
+ Max8907bPmuSupply_LDO5, // LDO5 (VOUT5), linear regulator output (default = 1.8V)
+ Max8907bPmuSupply_LDO6, // LDO6 (VOUT6), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO7, // LDO7 (VOUT7), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO8, // LDO8 (VOUT8), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO9, // LDO9 (VOUT9), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO10, // LDO10 (VOUT10), linear regulator output (default = 1.8V)
+ Max8907bPmuSupply_LDO11, // LDO11 (VOUT11), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO12, // LDO12 (VOUT12), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO13, // LDO13 (VOUT13), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO14, // LDO14 (VOUT14), linear regulator output (default = 3.3V)
+ Max8907bPmuSupply_LDO15, // LDO15 (VOUT15), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO16, // LDO16 (VOUT16), linear regulator output (default = 2.8V)
+ Max8907bPmuSupply_LDO17, // LDO17 (VOUT17), linear regulator output (default = 1.2V)
+ Max8907bPmuSupply_LDO18, // LDO18 (VOUT18), linear regulator output (default = 1.2V)
+ Max8907bPmuSupply_LDO19, // LDO19 (VOUT19), linear regulator output (default = 3.3V)
+ Max8907bPmuSupply_LDO20, // LDO20 (VOUT20), linear regulator output (default = 1.2V)
+
+ /*-- White LED --*/
+ Max8907bPmuSupply_WHITE_LED, // (Boost WLED)
+
+ /*-- External DC/DC switcher --*/
+ Max8907bPmuSupply_EXT_DCDC_1, // EXT_DC/DC1
+ Max8907bPmuSupply_EXT_DCDC_2, // EXT_DC/DC2
+ Max8907bPmuSupply_EXT_DCDC_3, // EXT_DC/DC3
+ Max8907bPmuSupply_EXT_DCDC_4, // EXT_DC/DC4
+ Max8907bPmuSupply_EXT_DCDC_5, // EXT_DC/DC5
+ Max8907bPmuSupply_EXT_DCDC_6, // EXT_DC/DC6
+
+ /** USB1 & USB3 VBus's are getting 5V from DCDC_3 **/
+ Max8907bPmuSupply_EXT_DCDC_3_USB1, //USB1 VBUS
+ Max8907bPmuSupply_EXT_DCDC_3_USB3, // USB3 VBUS
+
+ /** Secondary PMU MIC2826 Rails **/
+ MIC2826PmuSupply_BUCK,
+ MIC2826PmuSupply_LDO1,
+ MIC2826PmuSupply_LDO2,
+ MIC2826PmuSupply_LDO3,
+
+ // External DCDC controlled by LX_V1, and scaled by digital
+ // potentiometer (DPM) AD5258
+ Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7,
+
+ Max8907bPmuSupply_Num,
+ Max8907bPmuSupply_Force32 = 0x7FFFFFFF
+} Max8907bPmuSupply;
+
+typedef NvU32 (*Max8907bPmuVoltageFunc)(const NvU32 data);
+
+typedef struct Max8907bPmuSupplyInfoRec
+{
+ Max8907bPmuSupply supply;
+
+ // I2C Registers
+ NvU8 ControlRegAddr;
+ NvU8 SequencerCountRegAddr;
+ NvU8 OutputVoltageRegAddr;
+ NvU8 OutputPort;
+ NvU8 PmuGpio;
+
+ Max8907bPmuVoltageFunc GetVoltage; // Function to convert register bits to real voltage
+ Max8907bPmuVoltageFunc SetVoltage; // Function to convert real voltage to register bits
+
+ NvOdmPmuVddRailCapabilities cap;
+} Max8907bPmuSupplyInfo;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //INCLUDED_MAX8907B_SUPPLY_INFO_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c
new file mode 100644
index 000000000000..097f0510d581
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+#include "mic2826_i2c.h"
+#include "mic2826_reg.h"
+
+NvBool MIC2826I2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ WriteBuffer[0] = Addr & 0xFF;
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = MIC2826_SLAVE_ADDR;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ MIC2826_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool MIC2826I2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data)
+{
+ NvU8 ReadBuffer = 0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[0].Address = MIC2826_SLAVE_ADDR;
+ TransactionInfo[0].Buf = &ReadBuffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+ TransactionInfo[1].Address = (MIC2826_SLAVE_ADDR | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2,
+ MIC2826_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = ReadBuffer;
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h
new file mode 100644
index 000000000000..850ab9907b11
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_PMU_MIC2826_I2C_H
+#define INCLUDED_NVODM_PMU_MIC2826_I2C_H
+
+#include "nvodm_pmu.h"
+#include "max8907b.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// Constant definition
+#define MIC2826_SLAVE_ADDR 0xB4
+#define MIC2826_I2C_SPEED_KHZ 400
+
+// Function declaration
+NvBool MIC2826I2cWrite8(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU8 Addr,
+ NvU8 Data);
+
+NvBool MIC2826I2cRead8(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU8 Addr,
+ NvU8 *Data);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_PMU_MIC2826_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h
new file mode 100644
index 000000000000..24b31cfa8824
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef MIC2826_REG_HEADER
+#define MIC2826_REG_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define MIC2826_REG_INVALID ~0x0
+#define MIC2826_REG_ADDR_ENABLE 0x00
+#define MIC2826_REG_ADDR_STATUS 0x01
+#define MIC2826_REG_ADDR_BUCK 0x02
+#define MIC2826_REG_ADDR_LD01 0x03
+#define MIC2826_REG_ADDR_LD02 0x04
+#define MIC2826_REG_ADDR_LD03 0x05
+
+#define MIC2826_REG_ENABLE_BK 0x1
+#define MIC2826_REG_ENABLE_LDO1 0x2
+#define MIC2826_REG_ENABLE_LDO2 0x4
+#define MIC2826_REG_ENABLE_LDO3 0x8
+#define MIC2826_REG_ENABLE_SEQCNT ~0x10
+#define MIC2826_REG_ENABLE_POAF ~0x20
+
+#define MIC2826_REG_DISABLE_BK ~0x1
+#define MIC2826_REG_DISABLE_LDO1 ~0x2
+#define MIC2826_REG_DISABLE_LDO2 ~0x4
+#define MIC2826_REG_DISABLE_LDO3 ~0x8
+#define MIC2826_REG_DISABLE_SEQCNT 0x10
+#define MIC2826_REG_DISABLE_POAF 0x20
+
+#define MIC2826_REG_STATUS_BK 0x1
+#define MIC2826_REG_STATUS_LDO1 0x2
+#define MIC2826_REG_STATUS_LDO2 0x4
+#define MIC2826_REG_STATUS_LDO3 0x8
+#define MIC2826_TSD_STATUS_TSD 0x10
+#define MIC2826_REG_STATUS_UVLO 0x20
+#define MIC2826_REG_STATUS_TSD_NORMAL ~0x10
+#define MIC2826_REG_STATUS_UVLO_NORMAL ~0x20
+
+#define MIC2826_REG_STATUS_INT_EN 0x40
+#define MIC2826_REG_STATUS_INT_DIS ~0x40
+
+#define MIC2826_BUCK_OUT_VOLTAGE_0800 0x00 //0.800 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0825 0x01 //0.825 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0850 0x02 //0.850 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0875 0x03 //0.875 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0900 0x04 //0.900 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0925 0x05 //0.925 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0950 0x06 //0.950 V
+#define MIC2826_BUCK_OUT_VOLTAGE_0975 0x07 //0.975 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1000 0x08 //1.000 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1025 0x09 //1.025 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1050 0x0A //1.050 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1075 0x0B //1.075 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1100 0x0C //1.100 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1125 0x0D //1.125 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1150 0x0E //1.150 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1175 0x0F //1.175 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1200 0x10 //1.200 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1250 0x11 //1.250 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1300 0x12 //1.300 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1350 0x13 //1.350 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1400 0x14 //1.400 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1450 0x15 //1.450 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1500 0x16 //1.500 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1550 0x17 //1.550 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1600 0x18 //1.600 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1650 0x19 //1.650 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1700 0x1A //1.700 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1750 0x1B //1.750 V
+#define MIC2826_BUCK_OUT_VOLTAGE_1800 0x1C //1.800 V
+
+#define MIC2826_LDO_OUT_VOLTAGE_0800 0x00 //0.800 V
+#define MIC2826_LDO_OUT_VOLTAGE_0850 0x0B //0.850 V
+#define MIC2826_LDO_OUT_VOLTAGE_0900 0x14 //0.900 V
+#define MIC2826_LDO_OUT_VOLTAGE_0950 0x1D //0.950 V
+#define MIC2826_LDO_OUT_VOLTAGE_1000 0x25 //1.000 V
+#define MIC2826_LDO_OUT_VOLTAGE_1050 0x2E //1.050 V
+#define MIC2826_LDO_OUT_VOLTAGE_1100 0x37 //1.100 V
+#define MIC2826_LDO_OUT_VOLTAGE_1150 0x3E //1.150 V
+#define MIC2826_LDO_OUT_VOLTAGE_1200 0x45 //1.200 V
+#define MIC2826_LDO_OUT_VOLTAGE_1250 0x4B //1.250 V
+#define MIC2826_LDO_OUT_VOLTAGE_1300 0x51 //1.300 V
+#define MIC2826_LDO_OUT_VOLTAGE_1350 0x57 //1.350 V
+#define MIC2826_LDO_OUT_VOLTAGE_1400 0x5C //1.400 V
+#define MIC2826_LDO_OUT_VOLTAGE_1450 0x60 //1.450 V
+#define MIC2826_LDO_OUT_VOLTAGE_1500 0x65 //1.500 V
+#define MIC2826_LDO_OUT_VOLTAGE_1550 0x69 //1.550 V
+#define MIC2826_LDO_OUT_VOLTAGE_1600 0x6D //1.600 V
+#define MIC2826_LDO_OUT_VOLTAGE_1650 0x72 //1.650 V
+#define MIC2826_LDO_OUT_VOLTAGE_1700 0x78 //1.700 V
+#define MIC2826_LDO_OUT_VOLTAGE_1750 0x75 //1.750 V
+#define MIC2826_LDO_OUT_VOLTAGE_1800 0x85 //1.800 V
+#define MIC2826_LDO_OUT_VOLTAGE_1850 0x8B //1.850 V
+#define MIC2826_LDO_OUT_VOLTAGE_1900 0x90 //1.900 V
+#define MIC2826_LDO_OUT_VOLTAGE_1950 0x95 //1.950 V
+#define MIC2826_LDO_OUT_VOLTAGE_2000 0x9A //2.000 V
+#define MIC2826_LDO_OUT_VOLTAGE_2050 0x9F //2.050 V
+#define MIC2826_LDO_OUT_VOLTAGE_2100 0xA3 //2.100 V
+#define MIC2826_LDO_OUT_VOLTAGE_2150 0xA7 //2.150 V
+#define MIC2826_LDO_OUT_VOLTAGE_2200 0xAB //2.200 V
+#define MIC2826_LDO_OUT_VOLTAGE_2250 0xA0 //2.250 V
+#define MIC2826_LDO_OUT_VOLTAGE_2300 0xB3 //2.300 V
+#define MIC2826_LDO_OUT_VOLTAGE_2350 0xB7 //2.350 V
+#define MIC2826_LDO_OUT_VOLTAGE_2400 0xBA //2.400 V
+#define MIC2826_LDO_OUT_VOLTAGE_2450 0xBD //2.450 V
+#define MIC2826_LDO_OUT_VOLTAGE_2500 0xC1 //2.500 V
+#define MIC2826_LDO_OUT_VOLTAGE_2550 0xC3 //2.550 V
+#define MIC2826_LDO_OUT_VOLTAGE_2600 0xC6 //2.600 V
+#define MIC2826_LDO_OUT_VOLTAGE_2650 0xC9 //2.650 V
+#define MIC2826_LDO_OUT_VOLTAGE_2700 0xCB //2.700 V
+#define MIC2826_LDO_OUT_VOLTAGE_2750 0xCE //2.750 V
+#define MIC2826_LDO_OUT_VOLTAGE_2800 0xD1 //2.800 V
+#define MIC2826_LDO_OUT_VOLTAGE_2850 0xD3 //2.850 V
+#define MIC2826_LDO_OUT_VOLTAGE_2900 0xD5 //2.900 V
+#define MIC2826_LDO_OUT_VOLTAGE_2950 0xD8 //2.950 V
+#define MIC2826_LDO_OUT_VOLTAGE_3000 0xDA //3.000 V
+#define MIC2826_LDO_OUT_VOLTAGE_3050 0xDC //3.050 V
+#define MIC2826_LDO_OUT_VOLTAGE_3100 0xDE //3.100 V
+#define MIC2826_LDO_OUT_VOLTAGE_3150 0xE0 //3.150 V
+#define MIC2826_LDO_OUT_VOLTAGE_3200 0xE3 //3.200 V
+#define MIC2826_LDO_OUT_VOLTAGE_3250 0xE6 //3.250 V
+#define MIC2826_LDO_OUT_VOLTAGE_3300 0xE8 //3.300 V
+
+#define MIC2826_BUCK_VOLTAGE_OFFSET 800
+#define MIC2826_BUCK_VOLTAGE_MIN_MV 800
+#define MIC2826_BUCK_VOLTAGE_STEP_MV 25
+#define MIC2826_BUCK_VOLTAGE_STEP_25MV 25
+#define MIC2826_BUCK_VOLTAGE_STEP_50MV 50
+#define MIC2826_BUCK_VOLTAGE_MAX_MV 1800
+#define MIC2826_BUCK_REQUESTVOLTAGE_MV 1800
+
+#define MIC2826_LDO_VOLTAGE_OFFSET 800
+#define MIC2826_LDO_VOLTAGE_MIN_MV 800
+#define MIC2826_LDO_VOLTAGE_STEP_MV 50
+#define MIC2826_LDO_VOLTAGE_MAX_MV 3300
+#define MIC2826_LDO1_REQUESTVOLTAGE_MV 1800
+#define MIC2826_LDO2_REQUESTVOLTAGE_MV 1800
+#define MIC2826_LDO3_REQUESTVOLTAGE_MV 1200
+
+#define MIC2826_INVALID_PORT 0xFF
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c
new file mode 100644
index 000000000000..4ca397b9951b
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+#include "tca6416_expander_i2c.h"
+#include "tca6416_expander_reg.h"
+
+
+
+#define TCA6416_SLAVE_ADDR 0x40 // (7'h20)
+#define TCA6416_I2C_SPEED_KHZ 400
+
+
+NvBool
+Tca6416ConfigPortPin(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 PortNo,
+ NvU32 PinNo,
+ GpioPinMode Mode)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus Error;
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+
+ NvOdmI2cTransactionInfo TransactionInfo;
+ static NvU8 ConfigPort1Val = 0xFF; // set to default value
+ static NvU8 ConfigPort2Val = 0xFF; // set to default value
+
+ if (PortNo == TCA6416_PORT_0)
+ {
+ WriteBuffer[0] = TCA6416_CONFIG_PORT_0 & 0xFF;
+
+ if (Mode == GpioPinMode_Output)
+ {
+ WriteBuffer[1] = ((ConfigPort1Val & (0xFF & (~(1 << PinNo)))) | (0x0 << PinNo));
+ } else if (Mode == GpioPinMode_InputData)
+ {
+ WriteBuffer[1] = ((ConfigPort1Val & (0xFF & (~(1 << PinNo)))) | (0x1 << PinNo));
+ }
+ ConfigPort1Val = WriteBuffer[1];
+ }else if (PortNo == TCA6416_PORT_1)
+ {
+ WriteBuffer[0] = TCA6416_CONFIG_PORT_1 & 0xFF;
+
+ if (Mode == GpioPinMode_Output)
+ {
+ WriteBuffer[1] = (ConfigPort2Val & (0xFF & (~(1 << PinNo))));
+ } else if (Mode == GpioPinMode_InputData)
+ {
+ WriteBuffer[1] = ((ConfigPort2Val & (0xFF & (~(1 << PinNo)))) | (0x1 << PinNo));
+ }
+ ConfigPort2Val = WriteBuffer[1];
+ }
+
+ TransactionInfo.Address = TCA6416_SLAVE_ADDR;
+ TransactionInfo.Buf = WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ // write the pmu Offset (from where data gpio need to be set)
+ Error = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ TCA6416_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (Error == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (Error)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("Tca6416ConfigPortPin Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("Tca6416ConfigPortPin Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+
+NvBool
+Tca6416WritePortPin(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 PortNo,
+ NvU32 PinNo,
+ GpioPinState data)
+{
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvOdmI2cStatus Error;
+ NvU8 WriteBuffer[2];
+ Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate;
+
+ static NvU8 OutPut1Val = 0xFF; // set to default value
+ static NvU8 OutPut2Val = 0xFF; // set to default value
+
+
+ /* set the command byte */
+ if (PortNo == TCA6416_PORT_0)
+ {
+ WriteBuffer[0] = TCA6416_OUTPUT_PORT_0 & 0xFF;
+ // Set the data
+ WriteBuffer[1] = ((OutPut1Val & (0xFF & (~(1 << PinNo)))) | (data << PinNo));
+
+ OutPut1Val = WriteBuffer[1];
+
+ } else if (PortNo == TCA6416_PORT_1)
+ {
+ WriteBuffer[0] = TCA6416_OUTPUT_PORT_1 & 0xFF;
+ // Set the data
+ WriteBuffer[1] = ((OutPut2Val & (0xFF & (~(1 << PinNo)))) | (data << PinNo));
+
+ OutPut2Val = WriteBuffer[1];
+ }
+
+ TransactionInfo.Address = TCA6416_SLAVE_ADDR;
+ TransactionInfo.Buf = WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ Error = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ TCA6416_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+
+ if (Error == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (Error)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("Tca6416I2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("Tca6416I2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool
+Tca6416ReadPortPin(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 PortNo,
+ NvU32 PinNo,
+ GpioPinState*State)
+{
+
+ // Need to implement
+ return NV_TRUE;
+}
+
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h
new file mode 100644
index 000000000000..ce14b79df090
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_TCA6416_EXPANDER_I2C_H
+#define INCLUDED_TCA6416_EXPANDER_I2C_H
+
+#include "nvodm_pmu.h"
+#include "max8907b.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+
+/**
+ * @brief Defines the possible modes.
+ */
+
+typedef enum
+{
+
+ /**
+ * Specifies the gpio pin as not in use.
+ */
+ GpioPinMode_Inactive = 0,
+
+ /// Specifies the gpio pin mode as input.
+ GpioPinMode_InputData,
+
+ /// Specifies the gpio pin mode as output.
+ GpioPinMode_Output,
+
+ GpioPinMode_Num,
+ GpioPinMode_Force32 = 0x7FFFFFFF
+} GpioPinMode;
+
+
+/**
+ * @brief Defines the pin state
+ */
+
+typedef enum
+{
+ // Pin state high
+ GpioPinState_Low = 0,
+ // Pin is high
+ GpioPinState_High,
+ GpioPinState_Num,
+ GpioPinState_Force32 = 0x7FFFFFFF
+} GpioPinState;
+
+
+NvBool Tca6416ConfigPortPin(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 portNo,
+ NvU32 pinNo,
+ GpioPinMode Mode);
+
+NvBool Tca6416WritePortPin(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 portNo,
+ NvU32 pinNo,
+ GpioPinState data);
+
+NvBool Tca6416ReadPortPin(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 portNo,
+ NvU32 pinNo,
+ GpioPinState*State);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_TCA6416_EXPANDER_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h
new file mode 100644
index 000000000000..588335a804c8
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#ifndef INCLUDED_TCA6416_EXPANDER_REG_HEADER
+#define INCLUDED_TCA6416_EXPANDER_REG_HEADER
+
+
+// Ports evailable on TCA6416. it is having 2 ports
+#define TCA6416_PORT_0 0
+#define TCA6416_PORT_1 1
+
+
+// Each port is having 8 pins
+#define TCA6416_PIN_0 0
+#define TCA6416_PIN_1 1
+#define TCA6416_PIN_2 2
+#define TCA6416_PIN_3 3
+#define TCA6416_PIN_4 4
+#define TCA6416_PIN_5 5
+#define TCA6416_PIN_6 6
+#define TCA6416_PIN_7 7
+
+
+// Registers
+#define TCA6416_INPUT_PORT_0 0x00 // For ports 00 to 07
+#define TCA6416_INPUT_PORT_1 0x01 // For ports 10 to 17
+#define TCA6416_OUTPUT_PORT_0 0x02 // For ports 00 to 07
+#define TCA6416_OUTPUT_PORT_1 0x03 // For ports 10 to 17
+#define TCA6416_POLARITY_INV_PORT_0 0x04 // For ports 00 to 07
+#define TCA6416_POLARITY_INV_PORT_1 0x05 // For ports 10 to 17
+#define TCA6416_CONFIG_PORT_0 0x06 // For ports 00 to 07
+#define TCA6416_CONFIG_PORT_1 0x07 // For ports 10 to 17
+
+
+
+#define TCA6416_INVALID_PORT 0xFF
+
+#endif //INCLUDED_TCA6416_EXPANDER_REG_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile
new file mode 100644
index 000000000000..9e7fe0bcdb16
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile
@@ -0,0 +1,21 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626
+
+obj-y += ds2482_bridge.o
+obj-y += ds2482_i2c.o
+obj-y += pcf50626_adc.o
+obj-y += pcf50626_batterycharger.o
+obj-y += pcf50626.o
+obj-y += pcf50626_i2c.o
+obj-y += pcf50626_interrupt.o
+obj-y += pcf50626_rtc.o
+obj-y += platform.o
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c
new file mode 100644
index 000000000000..ecc09f8e6775
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "ds2482_bridge.h"
+#include "pcf50626_i2c.h"
+#include "ds2482_i2c.h"
+#include "pcf50626_reg.h"
+#include "ds2482_reg.h"
+
+NvBool
+Ds2482Setup(NvOdmPmuDeviceHandle hDevice)
+{
+ NvU8 data = 0;
+
+ // One wire I2C bridge
+ //Device Reset Status
+ if (!Ds2482OWI2cRead8(hDevice, DS2482_DEVICE_RESET, &data))
+ return NV_FALSE;
+ //NVODMPMU_PRINTF(("Device Reset reg 0x%02x = 0x%02x\n", DS2482_DEVICE_RESET, data));
+
+ //1-Wire Reset Status
+ if (!Ds2482OWI2cRead8(hDevice, DS2482_1WIRE_RESET, &data))
+ return NV_FALSE;
+ //NVODMPMU_PRINTF(("1-Wire Reset reg 0x%02x = 0x%02x\n", DS2482_1WIRE_RESET, data));
+
+ while(1)
+ {
+ if (!Ds2482OWI2cWrite8(hDevice, DS2482_READ_DATA_REG_ADDR, DS2482_DEVICE_RESET))
+ return NV_FALSE;
+
+ if (!Ds2482OWI2cRead8(hDevice, DS2482_READ_DATA_REG_ADDR, &data))
+ return NV_FALSE;
+
+ if (!(data & 0x01))
+ break;
+ }
+
+
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h
new file mode 100644
index 000000000000..84111f8a7876
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_DS2482_BRIDGE_H
+#define INCLUDED_DS2482_BRIDGE_H
+
+#include "nvodm_pmu.h"
+#include "pcf50626.h"
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+NvBool
+Ds2482Setup(NvOdmPmuDeviceHandle hDevice);
+
+NvBool
+Ds2482BatteryPresented(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *BattPresence);
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif // INCLUDED_DS2482_BRIDGE_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c
new file mode 100644
index 000000000000..09f1194e2a30
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "ds2482_i2c.h"
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+#include "ds2482_reg.h"
+
+NvBool Ds2482OWI2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ WriteBuffer[0] = Addr & 0xFF;
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = DS2482_SLAVE_ADDR;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ DS2482_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool Ds2482OWI2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data)
+{
+ NvU8 ReadBuffer = 0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[0].Address = DS2482_SLAVE_ADDR;
+ TransactionInfo[0].Buf = &ReadBuffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+ TransactionInfo[1].Address = (DS2482_SLAVE_ADDR | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2,
+ DS2482_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = ReadBuffer;
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h
new file mode 100644
index 000000000000..af6ea8c9330e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_PMU_DS2482_I2C_H
+#define INCLUDED_NVODM_PMU_DS2482_I2C_H
+
+#include "pcf50626.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// Constant definition
+#define DS2482_SLAVE_ADDR 0x32
+#define DS2482_I2C_SPEED_KHZ 400
+
+// Function declaration
+NvBool Ds2482OWI2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data);
+
+NvBool Ds2482OWI2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data);
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_PMU_DS2482_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h
new file mode 100644
index 000000000000..6ce603046918
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef DS2482_REG_HEADER
+#define DS2482_REG_HEADER
+
+#define DS2482_DEVICE_RESET 0xF0
+#define DS2482_1WIRE_RESET 0xB4
+#define DS2482_STATUS_REG_ADDR 0xF0
+#define DS2482_READ_DATA_REG_ADDR 0xE1
+#define DS2482_CONFIGURATION_REG_ADDR 0xC3
+
+
+#endif //DS2482_REG_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h
new file mode 100644
index 000000000000..bf46e600401f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef PCF50626_SUPPLY_INFO_HEADER
+#define PCF50626_SUPPLY_INFO_HEADER
+
+#include "pcf50626.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+ typedef enum
+{
+ PCF50626PmuSupply_Invalid = 0x0,
+
+ //DCD1
+ PCF50626PmuSupply_DCD1,
+
+ //DCD2
+ PCF50626PmuSupply_DCD2,
+
+ //DCUD
+ PCF50626PmuSupply_DCUD,
+
+ //DCULED
+ PCF50626PmuSupply_DCULED,
+
+ //RF1REG
+ PCF50626PmuSupply_RF1REG,
+
+ //RF2REG
+ PCF50626PmuSupply_RF2REG,
+
+ //RF3REG
+ PCF50626PmuSupply_RF3REG,
+
+ //RF4REG
+ PCF50626PmuSupply_RF4REG,
+
+ //D1REG
+ PCF50626PmuSupply_D1REG,
+
+ //D2REG
+ PCF50626PmuSupply_D2REG,
+
+ //D3REG
+ PCF50626PmuSupply_D3REG,
+
+ //D4REG
+ PCF50626PmuSupply_D4REG,
+
+ //D5REG
+ PCF50626PmuSupply_D5REG,
+
+ //D6REG
+ PCF50626PmuSupply_D6REG,
+
+ //D7REG
+ PCF50626PmuSupply_D7REG,
+
+ //D8REG
+ PCF50626PmuSupply_D8REG,
+
+ //HCREG
+ PCF50626PmuSupply_HCREG,
+
+ //IOREG
+ PCF50626PmuSupply_IOREG,
+
+ //USIMREG
+ PCF50626PmuSupply_USIMREG,
+
+ //USBREG
+ PCF50626PmuSupply_USBREG,
+
+ //LCREG
+ PCF50626PmuSupply_LCREG,
+
+ //VBAT
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626PmuSupply_Num,
+ PCF50626PmuSupply_Force32 = 0x7FFFFFFF
+} PCF50626PmuSupply;
+
+
+typedef struct PCF50626PmuSupplyInfoRec
+{
+ PCF50626PmuSupply supply;
+ PCF50626PmuSupply supplyInput;
+ NvU8 control1Addr;
+ NvU8 control2Addr;
+ NvU8 control3Addr;
+ NvU8 control4Addr;
+
+ NvU8 dvm1Addr;
+ NvU8 dvm2Addr;
+ NvU8 dvm3Addr;
+ NvU8 dvmTimAddr;
+
+ NvOdmPmuVddRailCapabilities cap;
+ NvU32 offsetVoltage;
+ NvU32 turnOnTimeMicroSec;
+ NvU32 switchTimeMicroSec;
+} PCF50626PmuSupplyInfo;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //PCF50626_VOLTAGE_INFO_TABLE_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c
new file mode 100644
index 000000000000..9272dbdddbc5
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c
@@ -0,0 +1,938 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_query_discovery.h"
+#include "nvodm_query.h"
+#include "nvodm_services.h"
+#include "pcf50626_i2c.h"
+#include "pcf50626.h"
+#include "pcf50626_batterycharger.h"
+#include "pcf50626_adc.h"
+#include "pcf50626_interrupt.h"
+#include "pcf50626_supply_info_table.h"
+
+#ifndef PMU_MAX
+#define PMU_MAX(a,b) ((a)<(b)?(b):(a))
+#endif
+
+#define BATTEMP_CONTROL (0)
+
+// Board IDs
+#define NVODM_PMU_BOARD_ID_E924 0x0918
+#define NVODM_PMU_BOARD_ID_E934 0x0922
+
+// SKUs
+#define NVODM_PMU_BOARD_SAMSUNG_26_MHZ_OSC 0x0A00
+#define NVODM_PMU_BOARD_HYNIX_12_MHZ_XTAL 0x0A01
+
+// h/w configuration
+#define CHARGER_CONSTANT_CURRENT_SET_MA (NvU32)(125000/127)
+#define MAX_CHARGER_LIMIT_MA 850
+
+// This PMU does not have differnet charger programming
+// So setting all types of charger limit to the default charger limit
+#define SE0_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA
+#define SE1_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA
+#define SJ_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA
+#define SK_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA
+
+
+// threshold for battery status. need to fine tune based on battery/system characterisation
+#define NVODM_BATTERY_FULL_VOLTAGE_MV 4150
+#define NVODM_BATTERY_HIGH_VOLTAGE_MV 3900
+#define NVODM_BATTERY_LOW_VOLTAGE_MV 3300
+#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 3100
+
+#define NVODM_BATTERY_OVERHEAT_THRESHOLD 70
+
+
+Pcf50626PrivData *pPrivData;
+//Concorde WAR for the USB Host mode
+NvBool UsbHostMode;
+
+#define PMUGUID NV_ODM_GUID('p','c','f','_','p','m','u','0')
+
+
+// Calulate the battery life percentage according to the battery voltage.
+static NvU32
+Pcf50626CalulateBatteryLifePercent_int(NvU32 vBatSense);
+
+#if BATTEMP_CONTROL
+// switch off the chargeer if the battery temperature is too high
+static NvBool
+Pcf50626BatteryTemperatureControl_int(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 batTemp);
+#endif
+
+// Read the voltage setting from PCF50626 registers
+static NvBool
+Pcf50626ReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts);
+
+// Write the voltage setting from PCF50626 registers
+static NvBool
+Pcf50626WriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds);
+
+
+void
+Pcf50626GetCapabilities(
+ NvU32 vddRail,
+ NvOdmPmuVddRailCapabilities* pCapabilities)
+{
+ NvOdmBoardInfo BoardInfo;
+ NvBool Status = NV_FALSE;
+
+ NV_ASSERT(pCapabilities);
+ NV_ASSERT(vddRail < PCF50626PmuSupply_Num);
+
+ *pCapabilities = pcf50626SupplyInfoTable[vddRail].cap;
+
+ if (vddRail == PCF50626PmuSupply_DCD2)
+ {
+ Status = NvOdmPeripheralGetBoardInfo(NVODM_PMU_BOARD_ID_E924, &BoardInfo);
+ if (Status == NV_TRUE)
+ {
+ if ((BoardInfo.SKU == NVODM_PMU_BOARD_SAMSUNG_26_MHZ_OSC) ||
+ (BoardInfo.SKU == NVODM_PMU_BOARD_HYNIX_12_MHZ_XTAL))
+ {
+ // Use 1.8v DDR (TO DO: Don't use a magic number here; define this.)
+ pCapabilities->requestMilliVolts = 1800;
+ }
+ }
+ else
+ {
+ Status = NvOdmPeripheralGetBoardInfo(NVODM_PMU_BOARD_ID_E934, &BoardInfo);
+ if (Status == NV_TRUE)
+ {
+ if (BoardInfo.SKU == NVODM_PMU_BOARD_HYNIX_12_MHZ_XTAL)
+ {
+ // Use 1.8v DDR (TO DO: Don't use a magic number here; define this.)
+ pCapabilities->requestMilliVolts = 1800;
+ }
+ }
+ else
+ {
+ // Use default DDR voltage (1.925v)
+ ;
+ }
+ }
+ }
+}
+
+
+NvBool Pcf50626Setup(NvOdmPmuDeviceHandle hDevice)
+{
+ NvOdmIoModule I2cModule = NvOdmIoModule_I2c;
+ NvU32 I2cInstance = 0;
+ NvU32 I2cAddress = 0;
+ NvU32 i = 0;
+ NvBool status = NV_FALSE;
+
+ const NvOdmPeripheralConnectivity *pConnectivity =
+ NvOdmPeripheralGetGuid(PMUGUID);
+
+ NV_ASSERT(hDevice);
+
+
+ pPrivData = (Pcf50626PrivData*) NvOdmOsAlloc(sizeof(Pcf50626PrivData));
+ if (pPrivData == NULL)
+ {
+ NVODMPMU_PRINTF(("Error Allocating Pcf50626PrivData. \n"));
+ return NV_FALSE;
+ }
+ NvOdmOsMemset(pPrivData, 0, sizeof(Pcf50626PrivData));
+ hDevice->pPrivate = pPrivData;
+
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable = NvOdmOsAlloc(sizeof(NvU32) * PCF50626PmuSupply_Num);
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable == NULL)
+ {
+ NVODMPMU_PRINTF(("Error Allocating RefCntTable. \n"));
+ goto fail;
+ }
+
+ // memset
+ for (i = 0; i < PCF50626PmuSupply_Num; i++)
+ {
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[i] = 0;
+ }
+
+
+ if (pConnectivity != NULL) // PMU is in database
+ {
+ for (i = 0; i < pConnectivity->NumAddress; i ++)
+ {
+ if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu)
+ {
+ I2cModule = NvOdmIoModule_I2c_Pmu;
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ I2cAddress = pConnectivity->AddressList[i].Address;
+ break;
+ }
+ }
+
+ NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu);
+ NV_ASSERT(I2cAddress != 0);
+
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance);
+ if (!((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C)
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Error Open I2C device. \n"));
+ NVODMPMU_PRINTF(("[NVODM PMU]Please check PMU device I2C settings. \n"));
+ goto fail;
+ }
+
+ ((Pcf50626PrivData*)hDevice->pPrivate)->DeviceAddr = I2cAddress;
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice = NvOdmServicesPmuOpen();
+ if (!((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice)
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Error Open PMU Odm service. \n"));
+ goto fail;
+ }
+ }
+ else
+ {
+ // if PMU is not presented in the database, then the platform is PMU-less.
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: The system did not doscover PMU fromthe data base. \n"));
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: If this is not intended, please check the peripheral database for PMU settings. \n"));
+ goto fail;
+ }
+
+ if (!Pcf50626BatteryChargerSetup(hDevice))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626BatteryChargerSetup() failed. \n"));
+ goto fail;
+ }
+
+ //Check battery presence
+ if (!Pcf50626BatteryChargerCBCMainBatt(hDevice,&((Pcf50626PrivData*)hDevice->pPrivate)->battPresence))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626BatteryChargerCBCMainBatt() failed. \n"));
+ goto fail;
+ }
+
+ // The interrupt assumes not supported until pcf50626InterruptHandler() is called.
+ ((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_FALSE;
+
+ // setup the interrupt any way.
+ if (!Pcf50626SetupInterrupt(hDevice, &((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626SetupInterrupt() failed. \n"));
+ goto fail;
+ }
+
+ // Check battery Fullness
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_TRUE)
+ {
+ if (!Pcf50626BatteryChargerCBCBattFul(hDevice,&status))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626BatteryChargerCBCBattFul() failed. \n"));
+ goto fail;
+ }
+
+ ((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.batFull = status;
+ }
+ else
+ {
+ ((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.batFull = NV_FALSE;
+ }
+
+ return NV_TRUE;
+
+fail:
+ Pcf50626Release(hDevice);
+ return NV_FALSE;
+
+
+}
+
+void Pcf50626Release(NvOdmPmuDeviceHandle hDevice)
+{
+ if (hDevice->pPrivate != NULL)
+ {
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice != NULL)
+ {
+ NvOdmServicesPmuClose(((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice);
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice = NULL;
+ }
+
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C != NULL)
+ {
+ NvOdmI2cClose(((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C);
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C = NULL;
+ }
+
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable != NULL)
+ {
+ NvOdmOsFree(((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable);
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable = NULL;
+ }
+
+ NvOdmOsFree(hDevice->pPrivate);
+ hDevice->pPrivate = NULL;
+ }
+}
+
+
+NvBool
+Pcf50626GetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pMilliVolts);
+ NV_ASSERT(vddRail < PCF50626PmuSupply_Num);
+
+ if(! Pcf50626ReadVoltageReg(hDevice, vddRail,pMilliVolts))
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+
+NvBool
+Pcf50626SetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ NvU8 data = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(vddRail < PCF50626PmuSupply_Num);
+
+ if (pcf50626SupplyInfoTable[vddRail].cap.OdmProtected == NV_TRUE)
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626SetVoltage Warning: The voltage is protected and can not be set: %d.\n", vddRail));
+ return NV_TRUE;
+ }
+
+ if ((MilliVolts == ODM_VOLTAGE_OFF) ||
+ ((MilliVolts <= pcf50626SupplyInfoTable[vddRail].cap.MaxMilliVolts)
+ && (MilliVolts >= pcf50626SupplyInfoTable[vddRail].cap.MinMilliVolts)))
+ {
+ if (! Pcf50626WriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds))
+ return NV_FALSE;
+ }
+ else
+ {
+ NVODMPMU_PRINTF(("[NVODM OPMU] Pcf50626SetVoltage Error: The required voltage is not supported..\n"));
+ return NV_FALSE;
+ }
+
+ if (vddRail == PCF50626PmuSupply_DCUD)
+ {
+ // VBUs rail is enabled bydefault, so no need to enable set voltage.
+ // "Millivolts" field is used as Enable or disable VBUS GPIO
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ data = 0x7; // all bits to low fixed 0
+ }
+ else
+ {
+ data = 0x0; // default reset value high impedence state
+ }
+ if (!Pcf50626I2cWrite8(hDevice,PCF50626_GPIO5C1_ADDR, data))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+Pcf50626ReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ NvU32 milliVolts = 0;
+ NvU8 data = 0;
+ const PCF50626PmuSupplyInfo *pSupplyInfo = &pcf50626SupplyInfoTable[vddRail];
+
+ NV_ASSERT(pSupplyInfo->supply == (PCF50626PmuSupply)vddRail);
+
+ if(! Pcf50626I2cRead8(hDevice, pSupplyInfo->control2Addr, &data))
+ return NV_FALSE;
+
+ data >>= PCF50626_C2_OPMOD_SHIFT;
+ if (!data) //OFF
+ milliVolts = 0;
+ else
+ {
+ if (!Pcf50626I2cRead8(hDevice, pSupplyInfo->control1Addr, &data))
+ return NV_FALSE;
+
+ if ( (vddRail == PCF50626PmuSupply_DCD1)
+ |(vddRail == PCF50626PmuSupply_DCD2)
+ |(vddRail == PCF50626PmuSupply_DCUD))
+ {
+ milliVolts = pSupplyInfo->offsetVoltage + pSupplyInfo->cap.StepMilliVolts * ((NvU32)(data & 0x7F));
+ }
+ else if (vddRail == PCF50626PmuSupply_LCREG)
+ {
+ milliVolts = pSupplyInfo->offsetVoltage + pSupplyInfo->cap.StepMilliVolts * ((NvU32)(data & 0x7F) >> 1);
+ }
+ else
+ {
+ milliVolts = pSupplyInfo->offsetVoltage + pSupplyInfo->cap.StepMilliVolts * ((NvU32)(data & 0x7F) >> 2);
+ }
+ }
+
+ *pMilliVolts = milliVolts;
+ return NV_TRUE;
+}
+
+
+static NvBool
+Pcf50626WriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ NvU8 data = 0;
+ NvU8 reg = 0;
+ NvU32 settleTime = 0;
+
+ const PCF50626PmuSupplyInfo* pSupplyInfo = &pcf50626SupplyInfoTable[vddRail];
+ const PCF50626PmuSupplyInfo* pSupplyInputInfo = &pcf50626SupplyInfoTable[pSupplyInfo->supplyInput];
+
+ NV_ASSERT(pSupplyInfo->supply == (PCF50626PmuSupply)vddRail);
+
+ // Require to turn off the supply
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ // check if the supply can be turned off
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 1)
+ {
+ // turn off the supply
+ data = PCF50626_C2_OPMOD_OFF;
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE);
+ if (!Pcf50626I2cWrite8(hDevice, pSupplyInfo->control2Addr, data))
+ return NV_FALSE;
+ }
+
+ //check if the supply input can be turned off
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] == 1)
+ {
+ // turn off the supply input
+ data = PCF50626_C2_OPMOD_OFF;
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInputInfo->supply, NV_FALSE);
+ if(! Pcf50626I2cWrite8(hDevice, pSupplyInputInfo->control2Addr, data))
+ return NV_FALSE;
+ }
+
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] != 0)
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] --;
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] != 0)
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] --;
+
+ settleTime = PMU_MAX (pSupplyInfo->switchTimeMicroSec, pSupplyInputInfo->switchTimeMicroSec);
+
+ if (pSettleMicroSeconds != NULL)
+ *pSettleMicroSeconds = settleTime;
+ else
+ NvOdmOsWaitUS(settleTime);
+ return NV_TRUE;
+ }
+
+ // set voltage
+ if ( (vddRail == PCF50626PmuSupply_HCREG) ||
+ ((vddRail == PCF50626PmuSupply_LCREG) &&
+ (MilliVolts > PCF50626_LCREGOUT_VOLTAGE_RESCHANGE_MV)))
+ {
+ data = (NvU8)((MilliVolts - pSupplyInfo->offsetVoltage) / pSupplyInfo->cap.StepMilliVolts);
+ if (data % 2)
+ data --;
+ }
+ else
+ {
+ data = (NvU8)((MilliVolts - pSupplyInfo->offsetVoltage) / pSupplyInfo->cap.StepMilliVolts);
+ }
+
+ reg = 0;
+ reg &= ~PCF50626_C1_OUTPUT_MASK;
+ if ( (pSupplyInfo->supply == PCF50626PmuSupply_DCD1)
+ |(pSupplyInfo->supply == PCF50626PmuSupply_DCD2)
+ |(pSupplyInfo->supply == PCF50626PmuSupply_DCUD))
+ {
+ reg |= data;
+ }
+ else if (pSupplyInfo->supply == PCF50626PmuSupply_LCREG)
+ {
+ reg |= (data << 1);
+ }
+ else
+ {
+ reg |= (data << 2);
+ }
+
+ if(! Pcf50626I2cWrite8(hDevice, pSupplyInfo->control1Addr, reg))
+ return NV_FALSE;
+
+ settleTime = pSupplyInfo->switchTimeMicroSec;
+
+ // turn on supply
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 0)
+ {
+ if (! Pcf50626I2cRead8(hDevice, pSupplyInfo->control2Addr, &data))
+ return NV_FALSE;
+ data >>= PCF50626_C2_OPMOD_SHIFT;
+ if (!data)
+ {
+ // Require to turn on the supply
+ data = PCF50626_C2_OPMOD_ON;
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_TRUE);
+ if(! Pcf50626I2cWrite8(hDevice, pSupplyInfo->control2Addr, data))
+ return NV_FALSE;
+
+ settleTime += pSupplyInfo->turnOnTimeMicroSec;
+ }
+ }
+
+ // turn on supply input if necessary
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] == 0)
+ {
+ if(! Pcf50626I2cRead8(hDevice, pSupplyInputInfo->control2Addr, &data))
+ return NV_FALSE;
+
+ data >>= PCF50626_C2_OPMOD_SHIFT;
+ if (!data)
+ {
+ // Require to turn on the supply input
+ data = PCF50626_C2_OPMOD_ON;
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInputInfo->supply, NV_TRUE);
+ if(! Pcf50626I2cWrite8(hDevice,pSupplyInputInfo->control2Addr, data))
+ return NV_FALSE;
+
+ settleTime += pSupplyInputInfo->turnOnTimeMicroSec;
+ }
+ }
+
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] ++;
+ ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] ++;
+
+
+ if (pSettleMicroSeconds != NULL)
+ *pSettleMicroSeconds = settleTime;
+ else
+ NvOdmOsWaitUS(settleTime);
+
+ return NV_TRUE;
+}
+
+NvBool
+Pcf50626GetAcLineStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuAcLineStatus *pStatus)
+{
+ NvBool acLineStatus = NV_FALSE;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pStatus);
+
+ // check if charger presents
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_FALSE)
+ {
+ *pStatus = NvOdmPmuAcLine_Online;
+ return NV_TRUE;
+ }
+
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE)
+ {
+ if (( ((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.mChgPresent == NV_TRUE ) &&
+ (UsbHostMode == NV_FALSE))
+ {
+ *pStatus = NvOdmPmuAcLine_Online;
+ acLineStatus = NV_TRUE;
+ }
+ else
+ {
+ *pStatus = NvOdmPmuAcLine_Offline;
+ acLineStatus = NV_FALSE;
+ }
+ }
+ else
+ {
+ // battery is present, now check if charger presents
+ if (!Pcf50626BatteryChargerMainChgPresent(hDevice, &acLineStatus))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetAcLineStatus: Error in checking main charger presence.\n"));
+ return NV_FALSE;
+ }
+
+ if ((acLineStatus == NV_TRUE) && (UsbHostMode == NV_FALSE))
+ *pStatus = NvOdmPmuAcLine_Online;
+ else
+ *pStatus = NvOdmPmuAcLine_Offline;
+ }
+ return NV_TRUE;
+}
+
+
+NvBool
+Pcf50626GetBatteryStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU8 *pStatus)
+{
+ NvU8 status = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pStatus);
+ NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num);
+
+ if (batteryInst == NvOdmPmuBatteryInst_Main)
+ {
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_TRUE)
+ {
+ NvOdmPmuAcLineStatus stat = NvOdmPmuAcLine_Offline;
+ NvU32 VBatSense = 0;
+ if (!Pcf50626GetAcLineStatus(hDevice, &stat))
+ return NV_FALSE;
+
+ if (stat == NvOdmPmuAcLine_Online)
+ {
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE)
+ {
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.batFull == NV_FALSE)
+ status = NVODM_BATTERY_STATUS_CHARGING;
+ }
+ else
+ {
+ NvBool batFull = NV_FALSE;
+ if (!Pcf50626BatteryChargerCBCBattFul(hDevice, &batFull))
+ return NV_FALSE;
+ if (batFull == NV_FALSE)
+ status = NVODM_BATTERY_STATUS_CHARGING;
+ }
+ }
+
+ // Get VBatSense
+ if (!Pcf50626AdcVBatSenseRead(hDevice, &VBatSense))
+ return NV_FALSE;
+
+ if (VBatSense > NVODM_BATTERY_HIGH_VOLTAGE_MV)
+ status |= NVODM_BATTERY_STATUS_HIGH;
+ else if ((VBatSense < NVODM_BATTERY_LOW_VOLTAGE_MV)&&
+ (VBatSense > NVODM_BATTERY_CRITICAL_VOLTAGE_MV))
+ status |= NVODM_BATTERY_STATUS_LOW;
+ else if (VBatSense <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV)
+ status |= NVODM_BATTERY_STATUS_CRITICAL;
+
+ }
+ else
+ {
+ /* Battery is actually not present */
+ status = NVODM_BATTERY_STATUS_NO_BATTERY;
+ }
+
+ *pStatus = status;
+ }
+
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool
+Pcf50626GetBatteryData(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryData *pData)
+{
+ NvOdmPmuBatteryData batteryData;
+ batteryData.batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pData);
+ NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num);
+
+
+ if (batteryInst == NvOdmPmuBatteryInst_Main)
+ {
+ NvU32 VBatSense = 0;
+ NvU32 VBatTemp = 0;
+
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_TRUE)
+ {
+ /* retrieve Battery voltage and temperature */
+
+ // Get VBatSense
+ if (!Pcf50626AdcVBatSenseRead(hDevice, &VBatSense))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetBatteryData: Error reading VBATSense. \n"));
+ return NV_FALSE;
+ }
+
+ // Get VBatTemp
+ if (!Pcf50626AdcVBatTempRead(hDevice, &VBatTemp))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetBatteryData: Error reading VBATSense. \n"));
+ return NV_FALSE;
+ }
+
+ batteryData.batteryLifePercent =
+ Pcf50626CalulateBatteryLifePercent_int(VBatSense);
+
+#if BATTEMP_CONTROL
+ if (!Pcf50626BatteryTemperatureControl_int(hDevice, VBatTemp))
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetBatteryData: Error in battery ctemperature controls. \n"));
+ return NV_FALSE;
+ }
+#endif
+
+ batteryData.batteryVoltage = VBatSense;
+ batteryData.batteryTemperature = Pcf50626BatteryTemperature(VBatSense,
+ VBatTemp);
+ }
+
+ *pData = batteryData;
+ }
+ else
+ {
+ *pData = batteryData;
+ }
+
+ return NV_TRUE;
+}
+
+void
+Pcf50626GetBatteryFullLifeTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU32 *pLifeTime)
+{
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+}
+
+void
+Pcf50626GetBatteryChemistry(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryChemistry *pChemistry)
+{
+ //return fixed data for now.
+ *pChemistry = NvOdmPmuBatteryChemistry_LION;
+}
+
+NvBool
+Pcf50626SetChargingCurrent(
+NvOdmPmuDeviceHandle hDevice,
+NvOdmPmuChargingPath chargingPath,
+NvU32 chargingCurrentLimitMa,
+NvOdmUsbChargerType chargerType)
+{
+ NvU8 data = 0;
+ NV_ASSERT(hDevice);
+
+ // if no battery, then do nothing
+ if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_FALSE)
+ return NV_TRUE;
+ //Concorde s/w WAR for USB Host mode
+ if (chargingCurrentLimitMa == NVODM_USB_HOST_MODE_LIMIT)
+ {
+ chargingCurrentLimitMa = 0; // turn off the charging path
+ UsbHostMode = NV_TRUE;
+ }
+ else
+ {
+ UsbHostMode = NV_FALSE;
+ }
+
+ // if requested current is more than max supported current then limit to supported
+ if ( chargingCurrentLimitMa > MAX_CHARGER_LIMIT_MA )
+ chargingCurrentLimitMa = MAX_CHARGER_LIMIT_MA;
+
+ if (chargingPath == NvOdmPmuChargingPath_UsbBus)
+ {
+ switch (chargerType)
+ {
+ case NvOdmUsbChargerType_SJ:
+ chargingCurrentLimitMa = SJ_TYPE_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_SK:
+ chargingCurrentLimitMa = SK_TYPE_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_SE1:
+ chargingCurrentLimitMa = SE1_TYPE_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_SE0:
+ chargingCurrentLimitMa = SE0_TYPE_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_UsbHost:
+ default:
+ // USB Host based charging, nothing to do. Just pass current limit to PMU.
+ break;
+ }
+ }
+
+ data = (NvU8)((( chargingCurrentLimitMa << 8 ) - chargingCurrentLimitMa )
+ / CHARGER_CONSTANT_CURRENT_SET_MA );
+
+ if (!Pcf50626I2cWrite8(hDevice, PCF50626_CBCC3_ADDR, data))
+ return NV_FALSE;
+
+ // turn off the charger path if the requested current limit is 0mA. Turn on the path otherwise.
+ data = 0;
+ if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data) )
+ return NV_FALSE;
+
+ if ( chargingCurrentLimitMa == 0 )
+ data &= ~(PCF50626_CBCC1_CHGENA_MASK); //off
+ else
+ data |= PCF50626_CBCC1_CHGENA_MASK; //on
+
+ if ( !Pcf50626I2cWrite8(hDevice, PCF50626_CBCC1_ADDR, data) )
+ return NV_FALSE;
+
+
+ data = 0;
+ if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC2_ADDR, &data) )
+ return NV_FALSE;
+ if ( chargingCurrentLimitMa == 0 )
+ {
+ //enable USB suspend mode regardless of the SCUSB pin state
+ data |= (PCF50626_CBCC2_SUSPENA_MASK << PCF50626_CBCC2_SUSPENA_SHIFT);
+ }
+ else
+ {
+ //disable USB suspend mode regardless of the SCUSB pin state
+ data &= ~(PCF50626_CBCC2_SUSPENA_MASK << PCF50626_CBCC2_SUSPENA_SHIFT);
+ }
+ if ( !Pcf50626I2cWrite8(hDevice, PCF50626_CBCC2_ADDR, data) )
+ return NV_FALSE;
+
+ //Dump the register value for debug purpose, can be commented out is undesired..
+ NVODMPMU_PRINTF(("NvOdmPmuSetChargingCurrent: \n"));
+ NVODMPMU_PRINTF((" chargingCurrentLimitMa:%d\n", chargingCurrentLimitMa));
+
+ if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data) )
+ return NV_FALSE;
+ NVODMPMU_PRINTF((" CBCC1:0x%02x\n", data));
+
+ if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC2_ADDR, &data) )
+ return NV_FALSE;
+ NVODMPMU_PRINTF((" CBCC2:0x%02x\n", data));
+
+ if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC3_ADDR, &data) )
+ return NV_FALSE;
+ NVODMPMU_PRINTF((" CBCC3:0x%02x\n", data));
+
+ return NV_TRUE;
+}
+
+void Pcf50626InterruptHandler( NvOdmPmuDeviceHandle hDevice)
+{
+ // If the interrupt handle is called, the interrupt is supported.
+ ((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_TRUE;
+
+ Pcf50626InterruptHandler_int(hDevice, &((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus);
+}
+
+
+static NvU32 Pcf50626CalulateBatteryLifePercent_int(NvU32 vBatSense)
+{
+ NvU32 lifePerc = 0;
+ NvU32 vbat = vBatSense;
+
+ if (vbat < NVODM_BATTERY_CRITICAL_VOLTAGE_MV)
+ vbat = NVODM_BATTERY_CRITICAL_VOLTAGE_MV;
+
+ // using the linear mapping between the battery voltage and the life percentage.
+ lifePerc = ( ( vbat - NVODM_BATTERY_CRITICAL_VOLTAGE_MV ) * 50
+ / ( NVODM_BATTERY_FULL_VOLTAGE_MV - NVODM_BATTERY_CRITICAL_VOLTAGE_MV ) ) << 1;
+
+ if (lifePerc > 100)
+ lifePerc = 100;
+
+ return lifePerc;
+}
+
+
+#if BATTEMP_CONTROL
+static NvBool Pcf50626BatteryTemperatureControl_int(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 batTemp)
+{
+ NvU8 data = 0;
+
+ //turn off the charger if the battery is overheating.
+ if ( batTemp > NVODM_BATTERY_OVERHEAT_THRESHOLD )
+ {
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data))
+ return NV_FALSE;
+
+ data &= 0xFE;
+ if (!Pcf50626I2cWrite8(hDevice, PCF50626_CBCC1_ADDR, data))
+ return NV_FALSE;
+ }
+ // turn it on otherwise
+ else
+ {
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data))
+ return NV_FALSE;
+
+ data |= 0x01;
+ if (!Pcf50626I2cWrite8(hDevice, PCF50626_CBCC1_ADDR, data))
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+#endif
+
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h
new file mode 100644
index 000000000000..2325fb75a9d2
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_PMU_PCF50626_H
+#define INCLUDED_PMU_PCF50626_H
+
+#include "nvodm_pmu.h"
+#include"pmu_hal.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+#if (NV_DEBUG)
+#define NVODMPMU_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODMPMU_PRINTF(x)
+#endif
+
+
+typedef struct Pcf50626StatusRec
+{
+ /* Low Battery voltage detected by BVM */
+ NvBool lowBatt;
+
+ /* PMU high temperature */
+ NvBool highTemp;
+
+ /* charger switch from CC mode to CV mode */
+ NvBool chgCcToCv;
+
+ /* Main charger Presents */
+ NvBool mChgPresent;
+
+ /* battery Full */
+ NvBool batFull;
+
+} Pcf50626Status;
+
+
+
+typedef struct
+{
+ /* The handle to the I2C */
+ NvOdmServicesI2cHandle hOdmI2C;
+
+ /* The odm pmu service handle */
+ NvOdmServicesPmuHandle hOdmPmuSevice;
+
+ /* the PMU I2C device Address */
+ NvU32 DeviceAddr;
+
+ /* the PMU status */
+ Pcf50626Status pmuStatus;
+
+ /* battery presence */
+ NvBool battPresence;
+
+ /* PMU interrupt support enabled */
+ NvBool pmuInterruptSupported;
+
+
+ /* The ref cnt table of the power supplies */
+ NvU32 *supplyRefCntTable;
+
+}Pcf50626PrivData;
+
+
+NvBool
+Pcf50626Setup(NvOdmPmuDeviceHandle hDevice);
+
+void
+Pcf50626Release(NvOdmPmuDeviceHandle hDevice);
+
+NvBool
+Pcf50626GetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts);
+
+NvBool
+Pcf50626SetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds);
+
+void
+Pcf50626GetCapabilities(
+ NvU32 vddRail,
+ NvOdmPmuVddRailCapabilities* pCapabilities);
+
+
+NvBool
+Pcf50626GetAcLineStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuAcLineStatus *pStatus);
+
+
+NvBool
+Pcf50626GetBatteryStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU8 *pStatus);
+
+NvBool
+Pcf50626GetBatteryData(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryData *pData);
+
+void
+Pcf50626GetBatteryFullLifeTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU32 *pLifeTime);
+
+void
+Pcf50626GetBatteryChemistry(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryChemistry *pChemistry);
+
+NvBool
+Pcf50626SetChargingCurrent(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuChargingPath chargingPath,
+ NvU32 chargingCurrentLimitMa,
+ NvOdmUsbChargerType ChargerType);
+
+void Pcf50626InterruptHandler( NvOdmPmuDeviceHandle hDevice);
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif // INCLUDED_PMU_PCF50626_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c
new file mode 100644
index 000000000000..95347fa42cd7
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "pcf50626_adc.h"
+#include "pcf50626_i2c.h"
+#include "pcf50626_reg.h"
+//#include "pcf50626_supply_info.h"
+
+#define ADC_CONVERSION_DELAY_USEC 70
+#define ADC_CONVERSION_TIMEOUT_USEC 500
+#define ADC_CONVERSION_VOLTAGE_RANGE 2000
+#define ADC_CONVERSION_DIVIDOR 3
+#define ADC_CONVERSION_PRECISION 10
+#define ADC_CONVERSION_SUB_OFFSET 2250
+
+
+static NvBool
+Pcf50626AdcIn1Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt);
+
+static NvBool
+Pcf50626AdcIn2Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt);
+
+
+/* read voltage from VBATSENSE */
+NvBool
+Pcf50626AdcVBatSenseRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt)
+{
+ return Pcf50626AdcIn1Read(hDevice, volt);
+}
+
+static NvBool
+Pcf50626AdcIn1Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt)
+{
+
+ NvU32 timeout = 0;
+ NvU8 dataS1 = 0;
+ NvU8 dataS3 = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(volt);
+
+ // Turn off GPIO7
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_GPIO7C1_ADDR, 0x0))
+ return NV_FALSE;
+
+
+ //ADCC3 - Division sel
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC3_ADDR, PCF50626_ADCC3_RESET))
+ return NV_FALSE;
+
+
+ //ADCC1 - Resolustion, Mux Sel, Avg sel
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x0C))
+ return NV_FALSE;
+
+ // Start Converstion
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x0D))
+ return NV_FALSE;
+
+ // Wait for conversion
+ NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+
+ // make sure the conversion is completed, or timeout.
+ while (timeout < ADC_CONVERSION_TIMEOUT_USEC)
+ {
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_ADCS3_ADDR, &dataS3))
+ return NV_FALSE;
+
+ if (dataS3 & 0x80)
+ break;
+
+ NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+ timeout += ADC_CONVERSION_DELAY_USEC;
+ }
+
+ if (timeout >= ADC_CONVERSION_TIMEOUT_USEC)
+ {
+ NVODMPMU_PRINTF(("ADC conversion timeout.\n"));
+ return NV_FALSE;
+ }
+
+ // read the conversion result
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_ADCS1_ADDR, &dataS1))
+ return NV_FALSE;
+
+ // Get result
+ *volt = (((NvU32)((dataS1 << 2) | (dataS3 & 0x03))) *
+ ADC_CONVERSION_VOLTAGE_RANGE * ADC_CONVERSION_DIVIDOR)
+ >> ADC_CONVERSION_PRECISION;
+
+ return NV_TRUE;
+}
+
+
+
+/* read bat temperature voltage from ADC2 */
+NvBool
+Pcf50626AdcVBatTempRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt)
+{
+ return Pcf50626AdcIn2Read(hDevice, volt);
+}
+
+static NvBool
+Pcf50626AdcIn2Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt)
+{
+ NvU32 timeout = 0;
+ NvU8 dataS1 = 0;
+ NvU8 dataS3 = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(volt);
+
+ // Turn off GPIO7
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_GPIO7C1_ADDR, 0x0))
+ return NV_FALSE;
+
+
+ //ADCC3 - Division sel
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC3_ADDR, PCF50626_ADCC3_RESET))
+ return NV_FALSE;
+
+
+ //ADCC1 - Resolustion, Mux Sel, Avg sel
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x2C))
+ return NV_FALSE;
+
+ // Start Converstion
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x2D))
+ return NV_FALSE;
+
+ // Wait for conversion
+ NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+
+ // make sure the conversion is completed, or timeout.
+ while (timeout < ADC_CONVERSION_TIMEOUT_USEC)
+ {
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_ADCS3_ADDR, &dataS3))
+ return NV_FALSE;
+
+ if (dataS3 & 0x80)
+ break;
+
+ NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+ timeout += ADC_CONVERSION_DELAY_USEC;
+ }
+
+ if (timeout >= ADC_CONVERSION_TIMEOUT_USEC)
+ {
+ NVODMPMU_PRINTF(("ADC conversion timeout.\n"));
+ return NV_FALSE;
+ }
+
+ // read the conversion result
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_ADCS1_ADDR, &dataS1))
+ return NV_FALSE;
+
+ // Get result
+ *volt = (((NvU32)((dataS1 << 2) | (dataS3 & 0x03))) *
+ ADC_CONVERSION_VOLTAGE_RANGE * ADC_CONVERSION_DIVIDOR)
+ >> ADC_CONVERSION_PRECISION;
+
+ return NV_TRUE;
+}
+
+
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h
new file mode 100644
index 000000000000..e5022c449289
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_PCF50626_ADC_HEADER
+#define INCLUDED_PCF50626_ADC_HEADER
+
+
+/* the ADC is used for battery voltage conversion */
+#include "pcf50626.h"
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* read voltage from VBATSENSE */
+
+NvBool
+Pcf50626AdcVBatSenseRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt);
+
+
+/* read bat temperature voltage from ADC2 */
+NvBool
+Pcf50626AdcVBatTempRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt);
+
+/* Calculate the battery temperature */
+NvU32 Pcf50626BatteryTemperature(
+ NvU32 VBatSense,
+ NvU32 VBatTemp);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_PCF50626_ADC_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c
new file mode 100644
index 000000000000..814d12319dd5
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "pcf50626_batterycharger.h"
+#include "pcf50626_adc.h"
+#include "pcf50626_i2c.h"
+#include "pcf50626_reg.h"
+
+
+/* Get battery Voltage */
+NvBool
+Pcf50626BatteryChargerGetVoltage(NvOdmPmuDeviceHandle hDevice, NvU32 *res)
+{
+ NvU32 volt = 0;
+ ///TODO: check on HW to see the relation between adc output and the voltage. for now, assume they are the same.
+ if(! Pcf50626AdcVBatSenseRead(hDevice,&volt))
+ return NV_FALSE;
+
+ *res = volt;
+ return NV_TRUE;
+}
+
+
+
+/* check OnKey Level */
+NvBool
+Pcf50626BatteryChargerOnKeyStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data))
+ return NV_FALSE
+ ;
+ data = (data >> PCF50626_OOCS_ONKEY_SHIFT) & PCF50626_OOCS_ONKEY_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+
+ return NV_TRUE;
+}
+
+/* check OnKey Level */
+NvBool
+Pcf50626BatteryChargerRec1Status(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data))
+ return NV_FALSE;
+ data = (data >> PCF50626_OOCS_REC1_SHIFT) & PCF50626_OOCS_REC1_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+
+ return NV_TRUE;
+}
+
+/* check battery status */
+NvBool
+Pcf50626BatteryChargerBattStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data))
+ return NV_FALSE;
+ data = (data >> PCF50626_OOCS_BATOK_SHIFT) & PCF50626_OOCS_BATOK_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+
+ return NV_TRUE;
+}
+
+/* check main charger status */
+NvBool
+Pcf50626BatteryChargerMainChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_OOCS_MCHGOK_SHIFT) & PCF50626_OOCS_MCHGOK_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+
+/* check USB charger status */
+NvBool
+Pcf50626BatteryChargerUsbChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_OOCS_UCHGOK_SHIFT) & PCF50626_OOCS_UCHGOK_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+
+/* check temparature status */
+NvBool
+Pcf50626BatteryChargerTempStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_OOCS_TEMPOK_SHIFT) & PCF50626_OOCS_TEMPOK_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+/* check CBC batt_ful status */
+NvBool
+Pcf50626BatteryChargerCBCBattFul(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS1_BATTFUL_SHIFT) & PCF50626_CBCS1_BATTFUL_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+
+/* check CBC thermal limit activation status */
+NvBool
+Pcf50626BatteryChargerCBCTlimStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS1_TLIMIT_SHIFT) & PCF50626_CBCS1_TLIMIT_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+/* check CBC batt_ful status */
+NvBool
+Pcf50626BatteryChargerCBCWdExpired(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS1_WDEXP_SHIFT) & PCF50626_CBCS1_WDEXP_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+
+/* check CBC charger current status */
+NvBool
+Pcf50626BatteryChargerCBCChgCurStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS1_ILIMIT_SHIFT) & PCF50626_CBCS1_ILIMIT_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+/* check CBC charger voltage status */
+NvBool
+Pcf50626BatteryChargerCBCChgVoltStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS1_VLIMIT_SHIFT) & PCF50626_CBCS1_VLIMIT_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+/* check CBC charger resume status */
+NvBool
+Pcf50626BatteryChargerCBCChgResStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS1_RESSTAT_SHIFT) & PCF50626_CBCS1_RESSTAT_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+
+/* check USB suspend status */
+NvBool
+Pcf50626BatteryChargerCBCUsbSuspStat(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS2_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS2_USBSUSPSTAT_SHIFT) & PCF50626_CBCS2_USBSUSPSTAT_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+/* check charger over-voltage protection status */
+NvBool
+Pcf50626BatteryChargerCBCChgOvpStat(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU8 data = 0;
+
+ if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS2_ADDR, &data))
+ return NV_FALSE;
+
+ data = (data >> PCF50626_CBCS2_CHGOVP_SHIFT) & PCF50626_CBCS2_CHGOVP_MASK;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+ return NV_TRUE;
+}
+
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h
new file mode 100644
index 000000000000..ad5ebbc9f344
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_PCF50626_BATTERYCHARGER_HEADER
+#define INCLUDED_PCF50626_BATTERYCHARGER_HEADER
+
+
+
+#include "pcf50626.h"
+
+/* the battery charger functions */
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* Initliase all registers that related to battery charger */
+NvBool
+Pcf50626BatteryChargerSetup(NvOdmPmuDeviceHandle hDevice);
+
+/* Get battery Voltage */
+NvBool
+Pcf50626BatteryChargerGetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *res);
+
+
+/* check OnKey level */
+NvBool
+Pcf50626BatteryChargerOnKeyStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check rec1 level */
+NvBool
+Pcf50626BatteryChargerRec1Status(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check battery status */
+NvBool
+Pcf50626BatteryChargerBattStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check main charger status */
+NvBool
+Pcf50626BatteryChargerMainChgPresent(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check USB charger status */
+NvBool
+Pcf50626BatteryChargerUsbChgPresent(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check temparature status */
+NvBool
+Pcf50626BatteryChargerTempStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+
+/* check CBC batt_ful status */
+NvBool
+Pcf50626BatteryChargerCBCBattFul(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+
+
+/* check CBC thermal limit activation status */
+NvBool
+Pcf50626BatteryChargerCBCTlimStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check CBC batt_ful status */
+NvBool
+Pcf50626BatteryChargerCBCWdExpired(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+
+/* check CBC charger current status */
+NvBool
+Pcf50626BatteryChargerCBCChgCurStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check CBC charger voltage status */
+NvBool
+Pcf50626BatteryChargerCBCChgVoltStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check CBC charger resume status */
+NvBool
+Pcf50626BatteryChargerCBCChgResStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check CBC main batt presence */
+NvBool
+Pcf50626BatteryChargerCBCMainBatt(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check USB suspend status */
+NvBool
+Pcf50626BatteryChargerCBCUsbSuspStat(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+/* check charger over-voltage protection status */
+NvBool
+Pcf50626BatteryChargerCBCChgOvpStat(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool *status);
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_PCF50626_BATTERYCHARGER_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c
new file mode 100644
index 000000000000..38990b3ffada
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "pcf50626_i2c.h"
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+
+
+NvBool Pcf50626I2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate;
+
+ WriteBuffer[0] = Addr & 0xFF; // PMU offset
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = hPmu->DeviceAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool Pcf50626I2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data)
+{
+ NvU8 ReadBuffer = 0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ // Write the PMU offset
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[0].Address = hPmu->DeviceAddr;
+ TransactionInfo[0].Buf = &ReadBuffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+ TransactionInfo[1].Address = (hPmu->DeviceAddr | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ // Read data from PMU at the specified offset
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2,
+ PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = ReadBuffer;
+ return NV_TRUE;
+}
+
+NvBool Pcf50626I2cWrite32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 Data)
+{
+ NvU8 WriteBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ WriteBuffer[0] = (NvU8)(Addr & 0xFF);
+ WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF);
+ WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF);
+ WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF);
+ WriteBuffer[4] = (NvU8)(Data & 0xFF);
+
+ TransactionInfo.Address = hPmu->DeviceAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 5;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1,
+ PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool Pcf50626I2cRead32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 *Data)
+{
+ NvU8 ReadBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+
+ ReadBuffer[0] = Addr & 0xFF;
+
+ TransactionInfo[0].Address = hPmu->DeviceAddr;
+ TransactionInfo[0].Buf = &ReadBuffer[0];
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+
+ TransactionInfo[1].Address = (hPmu->DeviceAddr | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer[0];
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 4;
+
+ status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2,
+ PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) |
+ (ReadBuffer[2] << 8) | ReadBuffer[3];
+
+ return NV_TRUE;
+}
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h
new file mode 100644
index 000000000000..bc4b5aead9c8
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_PMU_PCF50626_I2C_H
+#define INCLUDED_NVODM_PMU_PCF50626_I2C_H
+
+#include "pcf50626.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// Constant definition
+#define PMU_PCF50626_DEVADDR 0xE0
+#define PCF506226_I2C_SPEED_KHZ 400
+
+// Function declaration
+NvBool Pcf50626I2cWrite8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 Data);
+
+NvBool Pcf50626I2cRead8(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU8 *Data);
+
+NvBool Pcf50626I2cWrite32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 Data);
+
+NvBool Pcf50626I2cRead32(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU8 Addr,
+ NvU32 *Data);
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_PMU_PCF50626_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c
new file mode 100644
index 000000000000..da9c4b605976
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include "pcf50626_interrupt.h"
+#include "pcf50626_batterycharger.h"
+#include "pcf50626_i2c.h"
+#include "pcf50626_reg.h"
+#include "nvodm_services.h"
+
+NvBool Pcf50626SetupInterrupt(NvOdmPmuDeviceHandle hDevice,
+ Pcf50626Status *pmuStatus)
+{
+ NvBool status = NV_FALSE;
+ NvU8 data = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pmuStatus);
+
+ /* Init Pmu Status */
+ pmuStatus->lowBatt = NV_FALSE;
+ pmuStatus->highTemp = NV_FALSE;
+ pmuStatus->chgCcToCv = NV_FALSE;
+
+ if (!Pcf50626BatteryChargerMainChgPresent(hDevice,&status))
+ return NV_FALSE;
+ pmuStatus->mChgPresent = status;
+
+
+ /* Set up Interrupt Mask */
+ data = (NvU8) ~(PCF50626_INT1_LOWBATT | PCF50626_INT1_HIGHTEMP);
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT1M_ADDR, data ))
+ return NV_FALSE;
+
+ data = 0;
+ data = (NvU8) ~PCF50626_INT2_VMAX;
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT2M_ADDR, data ))
+ return NV_FALSE;
+
+ data = 0;
+ data = (NvU8) ~(PCF50626_INT3_MCHGINS | PCF50626_INT3_MCHGRM);
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT3M_ADDR, data ))
+ return NV_FALSE;
+
+ data = 0;
+ data = (NvU8) ~(PCF50626_INT4_BATFUL | PCF50626_INT4_CHGRES);
+ if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT4M_ADDR, data ))
+ return NV_FALSE;
+
+ //if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT5M_ADDR, 0xff))
+ // return NV_FALSE;
+
+ //if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT6M_ADDR, 0xff))
+ // return NV_FALSE;
+
+ //if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT7M_ADDR, 0xff))
+ // return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+void Pcf50626InterruptHandler_int(NvOdmPmuDeviceHandle hDevice,
+ Pcf50626Status *pmuStatus)
+{
+
+ NvU8 data = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pmuStatus);
+
+ // INT1
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_INT1_ADDR, &data))
+ {
+ NVODMPMU_PRINTF(("Error reading INT1"));
+ return;
+ }
+ if (data != 0)
+ {
+ if (data & PCF50626_INT1_HIGHTEMP)
+ pmuStatus->highTemp = NV_TRUE;
+ else
+ pmuStatus->highTemp = NV_FALSE;
+ if (data & PCF50626_INT1_LOWBATT)
+ pmuStatus->lowBatt = NV_TRUE;
+ else
+ pmuStatus->lowBatt = NV_FALSE;
+ }
+
+ // INT2
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_INT2_ADDR, &data))
+ {
+ NVODMPMU_PRINTF(("Error reading INT2"));
+ return;
+ }
+ if (data != 0)
+ {
+ if (data & PCF50626_INT2_VMAX)
+ pmuStatus->chgCcToCv = NV_TRUE;
+ else
+ pmuStatus->chgCcToCv = NV_FALSE;
+ }
+
+ // INT3
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_INT3_ADDR, &data))
+ {
+ NVODMPMU_PRINTF(("Error reading INT3"));
+ return;
+ }
+ if (data != 0)
+ {
+ if (data & PCF50626_INT3_MCHGRM)
+ pmuStatus->mChgPresent = NV_FALSE;
+
+ if (data & PCF50626_INT3_MCHGINS)
+ {
+ pmuStatus->mChgPresent = NV_TRUE;
+ NvOdmEnableOtgCircuitry(NV_TRUE);
+ }
+ }
+
+ // INT4
+ if (!Pcf50626I2cRead8(hDevice, PCF50626_INT4_ADDR, &data))
+ {
+ NVODMPMU_PRINTF(("Error reading INT4"));
+ return;
+ }
+ if (data != 0)
+ {
+ if (data & PCF50626_INT4_CHGRES)
+ pmuStatus->batFull = NV_FALSE;
+
+ if (data & PCF50626_INT4_BATFUL)
+ pmuStatus->batFull = NV_TRUE;
+ }
+
+}
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h
new file mode 100644
index 000000000000..2cf1b404bc8c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_PCF50626_INTERRUPT_HEADER
+#define INCLUDED_PCF50626_INTERRUPT_HEADER
+
+#include "pcf50626.h"
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+NvBool
+Pcf50626SetupInterrupt(
+ NvOdmPmuDeviceHandle hDevice,
+ Pcf50626Status *pmuStatus);
+
+
+
+void
+Pcf50626InterruptHandler_int(
+ NvOdmPmuDeviceHandle hDevice,
+ Pcf50626Status *pmuStatus);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_PCF50626_INTERRUPT_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h
new file mode 100644
index 000000000000..2454487149e8
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h
@@ -0,0 +1,491 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef PCF50626_REG_HEADER
+#define PCF50626_REG_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+// The following are the OTP reset values
+#define PCF50626_ID_DEFAULT 0x31 // TBD, may change
+#define PCF50626_BVMC_RESET 0x18
+
+#define PCF50626_D1REGC1_RESET 0x6C
+#define PCF50626_D1REGC2_RESET 0x01
+#define PCF50626_D1REGC3_RESET 0x00
+
+#define PCF50626_D2REGC1_RESET 0x6C
+#define PCF50626_D2REGC2_RESET 0xE1
+#define PCF50626_D2REGC3_RESET 0x00
+
+#define PCF50626_D3REGC1_RESET 0x18
+#define PCF50626_D3REGC2_RESET 0xE1
+#define PCF50626_D3REGC3_RESET 0x80
+
+#define PCF50626_D7REGC2_RESET 0x01
+#define PCF50626_D7REGC3_RESET 0x00
+
+#define PCF50626_D8REGC2_RESET 0xE1
+#define PCF50626_D8REGC3_RESET 0x40
+
+#define PCF50626_RF1REGC1_RESET 0x58
+#define PCF50626_RF1REGC2_RESET 0x01
+#define PCF50626_RF1REGC3_RESET 0x40
+
+#define PCF50626_RF2REGC1_RESET 0x58
+#define PCF50626_RF2REGC2_RESET 0x01
+#define PCF50626_RF2REGC3_RESET 0x40
+
+#define PCF50626_IOREGC1_RESET 0x30
+#define PCF50626_IOREGC2_RESET 0xE1
+#define PCF50626_IOREGC3_RESET 0x40
+
+#define PCF50626_USBREGC1_RESET 0x58
+#define PCF50626_USBREGC2_RESET 0xE1
+#define PCF50626_USBREGC3_RESET 0x40
+
+#define PCF50626_LCREGC1_RESET 0x18
+#define PCF50626_LCREGC2_RESET 0xE1
+#define PCF50626_LCREGC3_RESET 0x00
+
+#define PCF50626_DCD1C1_RESET 0x18
+#define PCF50626_DCD1C2_RESET 0xE1
+#define PCF50626_DCD1C3_RESET 0x00
+#define PCF50626_DCD1C4_RESET 0x0F
+
+#define PCF50626_DCD2C1_RESET 0x30
+#define PCF50626_DCD2C2_RESET 0xE1
+#define PCF50626_DCD2C3_RESET 0x80
+#define PCF50626_DCD2C4_RESET 0x0F
+
+#define PCF50626_DCUDC2_RESET 0xE1
+#define PCF50626_DCUDC3_RESET 0xC0
+
+#define PCF50626_ALMCAL_RESET 0x11
+#define PCF50626_ALMCRV1_RESET 0x01
+#define PCF50626_ALMCRV2_RESET 0x28
+#define PCF50626_ALMCRV3_RESET 0x50
+#define PCF50626_ALMCRV4_RESET 0x78
+#define PCF50626_LED1C_RESET 0x4D
+#define PCF50626_LEDCC_RESET 0x01
+
+#define PCF50626_ADCC1_RESET 0x02
+#define PCF50626_ADCC2_RESET 0x00
+#define PCF50626_ADCC3_RESET 0x00
+#define PCF50626_ADCC4_RESET 0x00
+
+#define PCF50626_DCULEDC1_RESET 0x08
+#define PCF50626_DCULEDC2_RESET 0x01
+#define PCF50626_DCULEDC3_RESET 0x00
+#define PCF50626_DCULEDDIMMAN_RESET 0x3F
+
+#define PCF50626_CBCC1_RESET 0x2B
+#define PCF50626_CBCC2_RESET 0x5A
+#define PCF50626_CBCC3_RESET 0x12
+#define PCF50626_CBCC4_RESET 0x12
+#define PCF50626_CBCC5_RESET 0x0B
+#define PCF50626_CBCC6_RESET 0x02
+
+#define PCF50626_BBCC1_RESET 0x00
+
+
+//Table. 168
+#define PCF50626_ID_ADDR 0x00
+#define PCF50626_INT1_ADDR 0x01
+#define PCF50626_INT2_ADDR 0x02
+#define PCF50626_INT3_ADDR 0x03
+#define PCF50626_INT4_ADDR 0x04
+#define PCF50626_INT5_ADDR 0x05
+#define PCF50626_INT6_ADDR 0x06
+#define PCF50626_INT7_ADDR 0x09
+
+#define PCF50626_INT1M_ADDR 0x0A
+#define PCF50626_INT2M_ADDR 0x0B
+#define PCF50626_INT3M_ADDR 0x0C
+#define PCF50626_INT4M_ADDR 0x0D
+#define PCF50626_INT5M_ADDR 0x0E
+#define PCF50626_INT6M_ADDR 0x0F
+#define PCF50626_INT7M_ADDR 0x12
+
+#define PCF50626_ERROR_ADDR 0x13
+
+#define PCF50626_OOCC1_ADDR 0x14
+#define PCF50626_OOCC2_ADDR 0x15
+#define PCF50626_OOCPH_ADDR 0x16
+#define PCF50626_OOCS_ADDR 0x17
+
+#define PCF50626_BVMC_ADDR 0x18
+
+#define PCF50626_RECC1_ADDR 0x19
+#define PCF50626_RECC2_ADDR 0x1A
+#define PCF50626_RECS_ADDR 0x1B
+
+#define PCF50626_RTC1_ADDR 0x1C
+#define PCF50626_RTC2_ADDR 0x1D
+#define PCF50626_RTC3_ADDR 0x1E
+#define PCF50626_RTC4_ADDR 0x1F
+
+#define PCF50626_RTC1A_ADDR 0x20
+#define PCF50626_RTC2A_ADDR 0x21
+#define PCF50626_RTC3A_ADDR 0x22
+#define PCF50626_RTC4A_ADDR 0x23
+
+#define PCF50626_CBCC1_ADDR 0x24
+#define PCF50626_CBCC2_ADDR 0x25
+#define PCF50626_CBCC3_ADDR 0x26
+#define PCF50626_CBCC4_ADDR 0x27
+#define PCF50626_CBCC5_ADDR 0x28
+#define PCF50626_CBCC6_ADDR 0x29
+
+#define PCF50626_CBCS1_ADDR 0x2A
+#define PCF50626_CBCS2_ADDR 0x2B
+#define PCF50626_BBCC1_ADDR 0x2C
+#define PCF50626_PWM1S_ADDR 0x2D
+#define PCF50626_PWM1D_ADDR 0x2E
+#define PCF50626_PWM2S_ADDR 0x2F
+#define PCF50626_PWM2D_ADDR 0x30
+
+#define PCF50626_LED1C_ADDR 0x31
+#define PCF50626_LED2C_ADDR 0x32
+#define PCF50626_LEDCC_ADDR 0x33
+
+#define PCF50626_ADCC2_ADDR 0x34
+#define PCF50626_ADCC3_ADDR 0x35
+#define PCF50626_ADCC4_ADDR 0x36
+#define PCF50626_ADCC1_ADDR 0x37
+#define PCF50626_ADCS1_ADDR 0x38
+#define PCF50626_ADCS2_ADDR 0x39
+#define PCF50626_ADCS3_ADDR 0x3A
+
+#define PCF50626_TSIC2_ADDR 0x3B
+#define PCF50626_TSIC1_ADDR 0x3C
+#define PCF50626_TSIDAT1_ADDR 0x3D
+#define PCF50626_TSIDAT2_ADDR 0x3E
+#define PCF50626_TSIDAT3_ADDR 0x3F
+
+#define PCF50626_GPIO1C1_ADDR 0x40
+#define PCF50626_E1REGC2_ADDR 0x41
+#define PCF50626_E1REGC3_ADDR 0x42
+#define PCF50626_GPIO2C1_ADDR 0x43
+#define PCF50626_E2REGC2_ADDR 0x44
+#define PCF50626_E2REGC3_ADDR 0x45
+#define PCF50626_GPIO3C1_ADDR 0x46
+#define PCF50626_E3REGC2_ADDR 0x47
+#define PCF50626_E3REGC3_ADDR 0x48
+#define PCF50626_GPIO4C1_ADDR 0x49
+#define PCF50626_E4REGC2_ADDR 0x4A
+#define PCF50626_E4REGC3_ADDR 0x4B
+#define PCF50626_GPIO5C1_ADDR 0x4C
+#define PCF50626_E5REGC2_ADDR 0x4D
+#define PCF50626_E5REGC3_ADDR 0x4E
+#define PCF50626_GPIO6C1_ADDR 0x4F
+#define PCF50626_E6REGC2_ADDR 0x50
+#define PCF50626_E6REGC3_ADDR 0x51
+
+#define PCF50626_GPO1C1_ADDR 0x52
+#define PCF50626_EO1REGC2_ADDR 0x53
+#define PCF50626_EO1REGC3_ADDR 0x54
+#define PCF50626_GPO2C1_ADDR 0x55
+#define PCF50626_EO2REGC2_ADDR 0x56
+#define PCF50626_EO2REGC3_ADDR 0x57
+#define PCF50626_GPO3C1_ADDR 0x58
+#define PCF50626_EO3REGC2_ADDR 0x59
+#define PCF50626_EO3REGC3_ADDR 0x5A
+#define PCF50626_GPO4C1_ADDR 0x5B
+#define PCF50626_EO4REGC2_ADDR 0x5C
+#define PCF50626_EO4REGC3_ADDR 0x5D
+
+#define PCF50626_D1REGC1_ADDR 0x5E
+#define PCF50626_D1REGC2_ADDR 0x5F
+#define PCF50626_D1REGC3_ADDR 0x60
+
+#define PCF50626_D2REGC1_ADDR 0x61
+#define PCF50626_D2REGC2_ADDR 0x62
+#define PCF50626_D2REGC3_ADDR 0x63
+
+#define PCF50626_D3REGC1_ADDR 0x64
+#define PCF50626_D3REGC2_ADDR 0x65
+#define PCF50626_D3REGC3_ADDR 0x66
+
+#define PCF50626_D4REGC1_ADDR 0x67
+#define PCF50626_D4REGC2_ADDR 0x68
+#define PCF50626_D4REGC3_ADDR 0x69
+
+#define PCF50626_D5REGC1_ADDR 0x6A
+#define PCF50626_D5REGC2_ADDR 0x6B
+#define PCF50626_D5REGC3_ADDR 0x6C
+
+#define PCF50626_D6REGC1_ADDR 0x6D
+#define PCF50626_D6REGC2_ADDR 0x6E
+#define PCF50626_D6REGC3_ADDR 0x6F
+
+#define PCF50626_D7REGC1_ADDR 0x70
+#define PCF50626_D7REGC2_ADDR 0x71
+#define PCF50626_D7REGC3_ADDR 0x72
+
+#define PCF50626_D8REGC1_ADDR 0x73
+#define PCF50626_D8REGC2_ADDR 0x74
+#define PCF50626_D8REGC3_ADDR 0x75
+
+#define PCF50626_RF1REGC1_ADDR 0x76
+#define PCF50626_RF1REGC2_ADDR 0x77
+#define PCF50626_RF1REGC3_ADDR 0x78
+
+#define PCF50626_RF2REGC1_ADDR 0x79
+#define PCF50626_RF2REGC2_ADDR 0x7A
+#define PCF50626_RF2REGC3_ADDR 0x7B
+
+#define PCF50626_RF3REGC1_ADDR 0x7C
+#define PCF50626_RF3REGC2_ADDR 0x7D
+#define PCF50626_RF3REGC3_ADDR 0x7E
+
+#define PCF50626_RF4REGC1_ADDR 0x7F
+#define PCF50626_RF4REGC2_ADDR 0x80
+#define PCF50626_RF4REGC3_ADDR 0x81
+
+#define PCF50626_IOREGC1_ADDR 0x82
+#define PCF50626_IOREGC2_ADDR 0x83
+#define PCF50626_IOREGC3_ADDR 0x84
+
+#define PCF50626_USBREGC1_ADDR 0x85
+#define PCF50626_USBREGC2_ADDR 0x86
+#define PCF50626_USBREGC3_ADDR 0x87
+
+#define PCF50626_USIMREGC1_ADDR 0x88
+#define PCF50626_USIMREGC2_ADDR 0x89
+#define PCF50626_USIMREGC3_ADDR 0x8A
+
+#define PCF50626_LCREGC1_ADDR 0x8B
+#define PCF50626_LCREGC2_ADDR 0x8C
+#define PCF50626_LCREGC3_ADDR 0x8D
+
+#define PCF50626_HCREGC1_ADDR 0x8E
+#define PCF50626_HCREGC2_ADDR 0x8F
+#define PCF50626_HCREGC3_ADDR 0x90
+
+#define PCF50626_DCD1C1_ADDR 0x91
+#define PCF50626_DCD1C2_ADDR 0x92
+#define PCF50626_DCD1C3_ADDR 0x93
+#define PCF50626_DCD1C4_ADDR 0x94
+
+#define PCF50626_DCD1DVM1_ADDR 0x95
+#define PCF50626_DCD1DVM2_ADDR 0x96
+#define PCF50626_DCD1DVM3_ADDR 0x97
+#define PCF50626_DCD1DVMTIM_ADDR 0x98
+
+#define PCF50626_DCD2C1_ADDR 0x99
+#define PCF50626_DCD2C2_ADDR 0x9A
+#define PCF50626_DCD2C3_ADDR 0x9B
+#define PCF50626_DCD2C4_ADDR 0x9C
+
+#define PCF50626_DCD2DVM1_ADDR 0x9D
+#define PCF50626_DCD2DVM2_ADDR 0x9E
+#define PCF50626_DCD2DVM3_ADDR 0x9F
+#define PCF50626_DCD2DVMTIM_ADDR 0xA0
+
+#define PCF50626_DCUDC1_ADDR 0xA1
+#define PCF50626_DCUDC2_ADDR 0xA2
+#define PCF50626_DCUDC3_ADDR 0xA3
+#define PCF50626_DCUDC4_ADDR 0xA4
+#define PCF50626_DCUDDVMTIM_ADDR 0xA5
+
+#define PCF50626_DCULEDC1_ADDR 0xA6
+#define PCF50626_DCULEDC2_ADDR 0xA7
+#define PCF50626_DCULEDC3_ADDR 0xA8
+#define PCF50626_DCULED_DIMMAN_ADDR 0xA9
+
+#define PCF50626_ALMCAL_ADDR 0xAA
+#define PCF50626_ALMCALMEA_ADDR 0xAB
+#define PCF50626_ALMCRV1_ADDR 0xAC
+#define PCF50626_ALMCRV2_ADDR 0xAD
+#define PCF50626_ALMCRV3_ADDR 0xAE
+#define PCF50626_ALMCRV4_ADDR 0xAF
+
+#define PCF50626_GPIOS_ADDR 0xB0
+#define PCF50626_DREGS1_ADDR 0xB1
+#define PCF50626_DREGS2_ADDR 0xB2
+#define PCF50626_RFREGS_ADDR 0xB3
+#define PCF50626_GREGS_ADDR 0xB4
+
+#define PCF50626_GPIO7C1_ADDR 0xB5
+#define PCF50626_GPIO8C1_ADDR 0xB6
+
+#define PCF50626_USIMDETC_ADDR 0xB7
+
+#define PCF50626_TSINOI_ADDR 0xFE
+#define PCF50626_TSIDAT4_ADDR 0xFF
+
+
+/* field defines for register bit ops */
+#define PCF50626_C2_OPMOD_SHIFT 0x05
+#define PCF50626_C2_OPMOD_ON 0xE1
+#define PCF50626_C2_OPMOD_OFF 0x01
+#define PCF50626_C1_OUTPUT_MASK 0x7F
+
+#define PCF50626_OOCS_ONKEY_SHIFT 0x00
+#define PCF50626_OOCS_ONKEY_MASK 0x01
+#define PCF50626_OOCS_REC1_SHIFT 0x01
+#define PCF50626_OOCS_REC1_MASK 0x01
+#define PCF50626_OOCS_BATOK_SHIFT 0x02
+#define PCF50626_OOCS_BATOK_MASK 0x01
+#define PCF50626_OOCS_MCHGOK_SHIFT 0x04
+#define PCF50626_OOCS_MCHGOK_MASK 0x01
+#define PCF50626_OOCS_UCHGOK_SHIFT 0x05
+#define PCF50626_OOCS_UCHGOK_MASK 0x01
+#define PCF50626_OOCS_TEMPOK_SHIFT 0x06
+#define PCF50626_OOCS_TEMPOK_MASK 0x01
+
+#define PCF50626_CBCS1_BATTFUL_SHIFT 0x00
+#define PCF50626_CBCS1_BATTFUL_MASK 0x01
+#define PCF50626_CBCS1_TLIMIT_SHIFT 0x01
+#define PCF50626_CBCS1_TLIMIT_MASK 0x01
+#define PCF50626_CBCS1_WDEXP_SHIFT 0x02
+#define PCF50626_CBCS1_WDEXP_MASK 0x01
+#define PCF50626_CBCS1_ILIMIT_SHIFT 0x03
+#define PCF50626_CBCS1_ILIMIT_MASK 0x01
+#define PCF50626_CBCS1_VLIMIT_SHIFT 0x04
+#define PCF50626_CBCS1_VLIMIT_MASK 0x01
+#define PCF50626_CBCS1_RESSTAT_SHIFT 0x07
+#define PCF50626_CBCS1_RESSTAT_MASK 0x01
+#define PCF50626_CBCS2_NOBAT_SHIFT 0x00
+#define PCF50626_CBCS2_NOBAT_MASK 0x01
+#define PCF50626_CBCS2_USBSUSPSTAT_SHIFT 0x02
+#define PCF50626_CBCS2_USBSUSPSTAT_MASK 0x01
+#define PCF50626_CBCS2_CHGOVP_SHIFT 0x03
+#define PCF50626_CBCS2_CHGOVP_MASK 0x01
+
+#define PCF50626_ADCC1_STARTCMD_SHIFT 0x00
+#define PCF50626_ADCC1_STARTCMD_MASK 0x01
+#define PCF50626_ADCC1_STARTCMD_START 0x01
+#define PCF50626_ADCC1_STARTCMD_STOP 0x00
+
+#define PCF50626_ADCS3_ADCRDY_SHIFT 0x07
+#define PCF50626_ADCS3_ADCRDY_MASK 0x01
+#define PCF50626_ADCS3_ADCRDY_READY 0x01
+
+#define PCF50626_DCULED_DIMMAN_LEDMAN_MASK 0x3F
+#define PCF50626_DCULED_DIMMAN_LEDMAN_SHIFT 0x00
+
+#define PCF50626_DCULED_DIMMAN_ALMSEL_MASK 0x01
+#define PCF50626_DCULED_DIMMAN_ALMSEL_SHIFT 0x06
+#define PCF50626_DCULED_DIMMAN_ALMSEL_ALM 0x01
+#define PCF50626_DCULED_DIMMAN_ALMSEL_MAN 0x00
+
+#define PCF50626_INT1_LOWBATT 0x01
+#define PCF50626_INT1_HIGHTEMP 0x80
+#define PCF50626_INT2_VMAX 0x40
+#define PCF50626_INT3_MCHGINS 0x40
+#define PCF50626_INT3_MCHGRM 0x80
+#define PCF50626_INT4_CHGRES 0x01
+#define PCF50626_INT4_BATFUL 0x08
+
+#define PCF50626_CBCC1_CHGENA_SHIFT 0x00
+#define PCF50626_CBCC1_CHGENA_MASK 0x01
+#define PCF50626_CBCC2_SUSPENA_SHIFT 0x02
+#define PCF50626_CBCC2_SUSPENA_MASK 0x01
+
+//rail specs
+#define PCF50626_DCDXOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_DCDXOUT_VOLTAGE_MIN_MV 625
+#define PCF50626_DCDXOUT_VOLTAGE_STEP_MV 25
+#define PCF50626_DCDXOUT_VOLTAGE_MAX_MV 2700
+#define PCF50626_DCDXOUT_TURNON_TIME_MICROSEC 365
+#define PCF50626_DCDXOUT_SWITCH_TIME_MICROSEC 20
+
+#define PCF50626_DCUDOUT_MODE1_VOLTAGE_OFFSET_MV 2675
+#define PCF50626_DCUDOUT_MODE1_VOLTAGE_MIN_MV 3100
+#define PCF50626_DCUDOUT_MODE1_VOLTAGE_STEP_MV 25
+#define PCF50626_DCUDOUT_MODE1_VOLTAGE_MAX_MV 4975
+#define PCF50626_DCUDOUT_TURNON_TIME_MICROSEC 65
+#define PCF50626_DCUDOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_DXREGOUT_VOLTAGE_MIN_MV 1200
+#define PCF50626_DXREGOUT_VOLTAGE_STEP_MV 100
+#define PCF50626_DXREGOUT_VOLTAGE_MAX_MV 3300
+#define PCF50626_DXREGOUT_TURNON_TIME_MICROSEC 85
+#define PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_RFXREGOUT_VOLTAGE_MIN_MV 1200
+#define PCF50626_RFXREGOUT_VOLTAGE_STEP_MV 100
+#define PCF50626_RFXREGOUT_VOLTAGE_MAX_MV 3000
+#define PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC 285
+#define PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_HCREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_HCREGOUT_VOLTAGE_MIN_MV 1800
+#define PCF50626_HCREGOUT_VOLTAGE_STEP_MV 100
+#define PCF50626_HCREGOUT_VOLTAGE_MAX_MV 3000
+#define PCF50626_HCREGOUT_TURNON_TIME_MICROSEC 85
+#define PCF50626_HCREGOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_IOREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_IOREGOUT_VOLTAGE_MIN_MV 1200
+#define PCF50626_IOREGOUT_VOLTAGE_STEP_MV 100
+#define PCF50626_IOREGOUT_VOLTAGE_MAX_MV 3300
+#define PCF50626_IOREGOUT_TURNON_TIME_MICROSEC 85
+#define PCF50626_IOREGOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_USBREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_USBREGOUT_VOLTAGE_MIN_MV 1200
+#define PCF50626_USBREGOUT_VOLTAGE_STEP_MV 100
+#define PCF50626_USBREGOUT_VOLTAGE_MAX_MV 3300
+#define PCF50626_USBREGOUT_TURNON_TIME_MICROSEC 85
+#define PCF50626_USBREGOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_USIMREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_USIMREGOUT_VOLTAGE_MIN_MV 1800
+#define PCF50626_USIMREGOUT_VOLTAGE_STEP_MV 100
+#define PCF50626_USIMREGOUT_VOLTAGE_MAX_MV 3000
+#define PCF50626_USIMREGOUT_TURNON_TIME_MICROSEC 105
+#define PCF50626_USIMREGOUT_SWITCH_TIME_MICROSEC 0
+
+#define PCF50626_LCREGOUT_VOLTAGE_OFFSET_MV 600
+#define PCF50626_LCREGOUT_VOLTAGE_MIN_MV 600
+#define PCF50626_LCREGOUT_VOLTAGE_STEP_MV 50
+#define PCF50626_LCREGOUT_VOLTAGE_MAX_MV 2900
+#define PCF50626_LCREGOUT_VOLTAGE_RESCHANGE_MV 1400
+#define PCF50626_LCREGOUT_TURNON_TIME_MICROSEC 125
+#define PCF50626_LCREGOUT_SWITCH_TIME_MICROSEC 0
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif //PCF50626_VOLTAGE_INFO_TABLE_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c
new file mode 100644
index 000000000000..ca35bab03b2d
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "pcf50626_rtc.h"
+#include "pcf50626_i2c.h"
+#include "pcf50626_reg.h"
+
+/* Read RTC count register */
+
+static NvBool bRtcNotInitialized = NV_TRUE;
+
+NvBool
+Pcf50626RtcCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count)
+{
+ if (Pcf50626RtcWasStartUpFromNoPower(hDevice) && bRtcNotInitialized)
+ {
+ if (!Pcf50626I2cWrite32 (hDevice, PCF50626_RTC1_ADDR, 0))
+ {
+ return NV_FALSE;
+ }
+ bRtcNotInitialized = NV_FALSE;
+ *Count = 0;
+ return NV_TRUE;
+ } else
+ {
+ return ( Pcf50626I2cRead32 (hDevice, PCF50626_RTC1_ADDR, Count) );
+ }
+}
+
+/* Write RTC count register */
+
+NvBool
+Pcf50626RtcCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ NvBool ret;
+
+ ret = Pcf50626I2cWrite32 (hDevice, PCF50626_RTC1_ADDR, Count);
+
+ if (ret && bRtcNotInitialized)
+ bRtcNotInitialized = NV_FALSE;
+
+ return ret;
+}
+
+/* Read RTC alarm count register */
+
+NvBool
+Pcf50626RtcAlarmCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count)
+{
+ return ( Pcf50626I2cRead32 (hDevice, PCF50626_RTC1A_ADDR, Count) );
+}
+
+/* Write RTC alarm count register */
+
+NvBool
+Pcf50626RtcAlarmCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ return ( Pcf50626I2cWrite32 (hDevice, PCF50626_RTC1A_ADDR, Count) );
+}
+
+/* Reads RTC alarm interrupt mask status */
+
+NvBool
+Pcf50626RtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice)
+{
+ NvU8 Mask;
+
+ if(Pcf50626I2cRead8 (hDevice, PCF50626_INT1M_ADDR, &Mask))
+ {
+ return ((Mask & 0x8)? NV_FALSE:NV_TRUE);
+ }
+
+ return NV_FALSE;
+}
+
+/* Enables / Disables the RTC alarm interrupt */
+
+NvBool
+Pcf50626RtcAlarmIntEnable(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool Enable)
+{
+ NvBool Status = NV_FALSE;
+ NvU8 Mask;
+
+ if ((Status = Pcf50626I2cRead8(hDevice, PCF50626_INT1M_ADDR, &Mask)) == NV_TRUE)
+ {
+ (Mask = Enable? (Mask & ~0x8):(Mask|0x8));
+ Status = Pcf50626I2cWrite8 (hDevice, PCF50626_INT1M_ADDR, Mask);
+ }
+
+ return Status;
+}
+
+/* Checks if boot was from nopower / powered state */
+
+NvBool
+Pcf50626RtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice)
+{
+ NvU8 Data;
+
+ // Check "nopower" bit of the ERROR status register.
+ // Make sure the backup battery charger is enabled (bbce and vsaveen bits). This is done by
+ // the bootloader. If this is not done, the "nopower" bit will remain stuck at 0x1.
+ if ((Pcf50626I2cRead8(hDevice, PCF50626_ERROR_ADDR, &Data)) == NV_TRUE)
+ {
+ return ((Data & 0x20)? NV_TRUE : NV_FALSE);
+ }
+
+ return NV_FALSE;
+}
+
+NvBool
+Pcf50626IsRtcInitialized(NvOdmPmuDeviceHandle hDevice)
+{
+ return ((Pcf50626RtcWasStartUpFromNoPower(hDevice))? NV_FALSE : NV_TRUE);
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h
new file mode 100644
index 000000000000..f5979cf5e52d
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_PCF50626_RTC_HEADER
+#define INCLUDED_PCF50626_RTC_HEADER
+
+#include "pmu_hal.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* Read RTC count register */
+
+NvBool
+Pcf50626RtcCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count);
+
+/* Read RTC alarm count register */
+
+NvBool
+Pcf50626RtcAlarmCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count);
+
+/* Write RTC count register */
+
+NvBool
+Pcf50626RtcCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count);
+
+/* Write RTC alarm count register */
+
+NvBool
+Pcf50626RtcAlarmCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count);
+
+/* Reads RTC alarm interrupt mask status */
+
+NvBool
+Pcf50626RtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice);
+
+/* Enables / Disables the RTC alarm interrupt */
+
+NvBool
+Pcf50626RtcAlarmIntEnable(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool Enable);
+
+/* Checks if boot was from nopower / powered state */
+
+NvBool
+Pcf50626RtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice);
+
+NvBool
+Pcf50626IsRtcInitialized(NvOdmPmuDeviceHandle hDevice);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_PCF50626_RTC_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h
new file mode 100644
index 000000000000..7064cf6e68c7
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h
@@ -0,0 +1,615 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef PCF50626_SUPPLY_INFO_TABLE_HEADER
+#define PCF50626_SUPPLY_INFO_TABLE_HEADER
+
+#include "nvodm_pmu_pcf50626_supply_info.h"
+#include "pcf50626_reg.h"
+
+
+// defines for the request Voltage. This is board specific and ODM should change this based on
+// device.
+#define PCF50626_REQUESTVOLTAGE_DCD1_MV 1200
+#define PCF50626_REQUESTVOLTAGE_DCD2_MV 1925
+#define PCF50626_REQUESTVOLTAGE_DCUD_MV 4975
+#define PCF50626_REQUESTVOLTAGE_RF1REG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_RF2REG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_RF3REG_MV 1800
+#define PCF50626_REQUESTVOLTAGE_RF4REG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_D1REG_MV 3300
+#define PCF50626_REQUESTVOLTAGE_D2REG_MV 3300
+#define PCF50626_REQUESTVOLTAGE_D3REG_MV 1200
+#define PCF50626_REQUESTVOLTAGE_D4REG_MV 1200
+#define PCF50626_REQUESTVOLTAGE_D5REG_MV 1800
+#define PCF50626_REQUESTVOLTAGE_D6REG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_D7REG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_D8REG_MV 3100
+#define PCF50626_REQUESTVOLTAGE_HCREG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_IOREG_MV 1800
+#define PCF50626_REQUESTVOLTAGE_USIMREG_MV 3000
+#define PCF50626_REQUESTVOLTAGE_USBREG_MV 2800
+#define PCF50626_REQUESTVOLTAGE_LCREG_MV 1200
+
+// defines for the additional load-dependent TurnOn delays. This is board
+// specific and ODM should change this based on device.
+#define PCF50626_TURNON_DELAY_DCD1_US 0
+#define PCF50626_TURNON_DELAY_DCD2_US 0
+#define PCF50626_TURNON_DELAY_DCUD_US 0
+#define PCF50626_TURNON_DELAY_RF1REG_US 0
+#define PCF50626_TURNON_DELAY_RF2REG_US 0
+#define PCF50626_TURNON_DELAY_RF3REG_US 0
+#define PCF50626_TURNON_DELAY_RF4REG_US 0
+#define PCF50626_TURNON_DELAY_D1REG_US 0
+#define PCF50626_TURNON_DELAY_D2REG_US 0
+#define PCF50626_TURNON_DELAY_D3REG_US 0
+#define PCF50626_TURNON_DELAY_D4REG_US 0
+#define PCF50626_TURNON_DELAY_D5REG_US 2000
+#define PCF50626_TURNON_DELAY_D6REG_US 500
+#define PCF50626_TURNON_DELAY_D7REG_US 0
+#define PCF50626_TURNON_DELAY_D8REG_US 0
+#define PCF50626_TURNON_DELAY_HCREG_US 0
+#define PCF50626_TURNON_DELAY_IOREG_US 0
+#define PCF50626_TURNON_DELAY_USIMREG_US 0
+#define PCF50626_TURNON_DELAY_USBREG_US 0
+#define PCF50626_TURNON_DELAY_LCREG_US 0
+
+
+const PCF50626PmuSupplyInfo pcf50626SupplyInfoTable[] =
+{
+ {
+ PCF50626PmuSupply_Invalid,
+ PCF50626PmuSupply_Invalid,
+ 0,0,0,0,
+ 0,0,0,0,
+ {NV_TRUE,0,0,0,0},
+ 0,0,0
+ },
+
+ // DCD1
+ {
+ PCF50626PmuSupply_DCD1,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_DCD1C1_ADDR,
+ PCF50626_DCD1C2_ADDR,
+ PCF50626_DCD1C3_ADDR,
+ PCF50626_DCD1C4_ADDR,
+
+ PCF50626_DCD1DVM1_ADDR,
+ PCF50626_DCD1DVM2_ADDR,
+ PCF50626_DCD1DVM3_ADDR,
+ PCF50626_DCD1DVMTIM_ADDR,
+
+ {
+ NV_FALSE,
+ PCF50626_DCDXOUT_VOLTAGE_MIN_MV,
+ PCF50626_DCDXOUT_VOLTAGE_STEP_MV,
+ PCF50626_DCDXOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_DCD1_MV
+ },
+
+ PCF50626_DCDXOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DCDXOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_DCD1_US,
+ PCF50626_DCDXOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //DCD2
+ {
+ PCF50626PmuSupply_DCD2,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_DCD2C1_ADDR,
+ PCF50626_DCD2C2_ADDR,
+ PCF50626_DCD2C3_ADDR,
+ PCF50626_DCD2C4_ADDR,
+
+ PCF50626_DCD2DVM1_ADDR,
+ PCF50626_DCD2DVM2_ADDR,
+ PCF50626_DCD2DVM3_ADDR,
+ PCF50626_DCD2DVMTIM_ADDR,
+
+ {
+ NV_FALSE,
+ PCF50626_DCDXOUT_VOLTAGE_MIN_MV,
+ PCF50626_DCDXOUT_VOLTAGE_STEP_MV,
+ PCF50626_DCDXOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_DCD2_MV
+ },
+
+ PCF50626_DCDXOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DCDXOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_DCD2_US,
+ PCF50626_DCDXOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //DCUD
+ {
+ PCF50626PmuSupply_DCUD,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_DCUDC1_ADDR,
+ PCF50626_DCUDC2_ADDR,
+ PCF50626_DCUDC3_ADDR,
+ PCF50626_DCUDC4_ADDR,
+ 0,0,0,
+ PCF50626_DCUDDVMTIM_ADDR,
+
+ {
+ NV_FALSE,
+ PCF50626_DCUDOUT_MODE1_VOLTAGE_MIN_MV,
+ PCF50626_DCUDOUT_MODE1_VOLTAGE_STEP_MV,
+ PCF50626_DCUDOUT_MODE1_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_DCUD_MV
+ },
+
+ PCF50626_DCUDOUT_MODE1_VOLTAGE_OFFSET_MV,
+ PCF50626_DCUDOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_DCUD_US,
+ PCF50626_DCUDOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //DCULED
+ {
+ PCF50626PmuSupply_DCULED,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_DCULEDC1_ADDR,
+ PCF50626_DCULEDC2_ADDR,
+ PCF50626_DCULEDC3_ADDR,
+ PCF50626_DCULED_DIMMAN_ADDR,
+ 0,0,0,0,
+ {NV_TRUE, 0,0,0, 0},
+ 0,87,0
+ },
+
+ //RF1
+ {
+ PCF50626PmuSupply_RF1REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_RF1REGC1_ADDR,
+ PCF50626_RF1REGC2_ADDR,
+ PCF50626_RF1REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+ {
+ NV_FALSE,
+ PCF50626_RFXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_RF1REG_MV
+ },
+
+ PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF1REG_US,
+ PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //RF2
+ {
+ PCF50626PmuSupply_RF2REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_RF2REGC1_ADDR,
+ PCF50626_RF2REGC2_ADDR,
+ PCF50626_RF2REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_RFXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_RF2REG_MV
+ },
+
+ PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF2REG_US,
+ PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //RF3
+ {
+ PCF50626PmuSupply_RF3REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_RF3REGC1_ADDR,
+ PCF50626_RF3REGC2_ADDR,
+ PCF50626_RF3REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_RFXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_RF3REG_MV
+ },
+
+ PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF3REG_US,
+ PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //RF4
+ {
+ PCF50626PmuSupply_RF4REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_RF4REGC1_ADDR,
+ PCF50626_RF4REGC2_ADDR,
+ PCF50626_RF4REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_RFXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_RFXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_RF4REG_MV
+ },
+
+ PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF4REG_US,
+ PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D1
+ {
+ PCF50626PmuSupply_D1REG,
+ PCF50626PmuSupply_DCUD,
+
+ PCF50626_D1REGC1_ADDR,
+ PCF50626_D1REGC2_ADDR,
+ PCF50626_D1REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D1REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D1REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D2
+ {
+ PCF50626PmuSupply_D2REG,
+ PCF50626PmuSupply_DCUD,
+ PCF50626_D2REGC1_ADDR,
+ PCF50626_D2REGC2_ADDR,
+ PCF50626_D2REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D2REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D2REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D3
+ {
+ PCF50626PmuSupply_D3REG,
+ PCF50626PmuSupply_DCD2,
+
+ PCF50626_D3REGC1_ADDR,
+ PCF50626_D3REGC2_ADDR,
+ PCF50626_D3REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D3REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D3REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D4
+ {
+ PCF50626PmuSupply_D4REG,
+ PCF50626PmuSupply_DCD2,
+
+ PCF50626_D4REGC1_ADDR,
+ PCF50626_D4REGC2_ADDR,
+ PCF50626_D4REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D4REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D4REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D5
+ {
+ PCF50626PmuSupply_D5REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_D5REGC1_ADDR,
+ PCF50626_D5REGC2_ADDR,
+ PCF50626_D5REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D5REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D5REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D6
+ {
+ PCF50626PmuSupply_D6REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_D6REGC1_ADDR,
+ PCF50626_D6REGC2_ADDR,
+ PCF50626_D6REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D6REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D6REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D7
+ {
+ PCF50626PmuSupply_D7REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_D7REGC1_ADDR,
+ PCF50626_D7REGC2_ADDR,
+ PCF50626_D7REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D7REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D7REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //D8
+ {
+ PCF50626PmuSupply_D8REG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_D8REGC1_ADDR,
+ PCF50626_D8REGC2_ADDR,
+ PCF50626_D8REGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_DXREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_DXREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_DXREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_D8REG_MV
+ },
+
+ PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D8REG_US,
+ PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //HCREG
+ {
+ PCF50626PmuSupply_HCREG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_HCREGC1_ADDR,
+ PCF50626_HCREGC2_ADDR,
+ PCF50626_HCREGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_HCREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_HCREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_HCREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_HCREG_MV
+ },
+
+ PCF50626_HCREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_HCREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_HCREG_US,
+ PCF50626_HCREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //IO
+ {
+ PCF50626PmuSupply_IOREG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_IOREGC1_ADDR,
+ PCF50626_IOREGC2_ADDR,
+ PCF50626_IOREGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_IOREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_IOREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_IOREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_IOREG_MV
+ },
+
+ PCF50626_IOREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_IOREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_IOREG_US,
+ PCF50626_IOREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //USIM
+ {
+ PCF50626PmuSupply_USIMREG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_USIMREGC1_ADDR,
+ PCF50626_USIMREGC2_ADDR,
+ PCF50626_USIMREGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_USIMREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_USIMREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_USIMREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_USIMREG_MV
+ },
+
+ PCF50626_USIMREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_USIMREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_USIMREG_US,
+ PCF50626_USIMREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //USB
+ {
+ PCF50626PmuSupply_USBREG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_USBREGC1_ADDR,
+ PCF50626_USBREGC2_ADDR,
+ PCF50626_USBREGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_USBREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_USBREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_USBREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_USBREG_MV
+ },
+
+ PCF50626_USBREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_USBREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_USBREG_US,
+ PCF50626_USBREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //LC
+ {
+ PCF50626PmuSupply_LCREG,
+ PCF50626PmuSupply_VBAT,
+
+ PCF50626_LCREGC1_ADDR,
+ PCF50626_LCREGC2_ADDR,
+ PCF50626_LCREGC3_ADDR,
+ 0,
+ 0,0,0,0,
+
+ {
+ NV_FALSE,
+ PCF50626_LCREGOUT_VOLTAGE_MIN_MV,
+ PCF50626_LCREGOUT_VOLTAGE_STEP_MV,
+ PCF50626_LCREGOUT_VOLTAGE_MAX_MV,
+ PCF50626_REQUESTVOLTAGE_LCREG_MV
+ },
+
+ PCF50626_LCREGOUT_VOLTAGE_OFFSET_MV,
+ PCF50626_LCREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_LCREG_US,
+ PCF50626_LCREGOUT_SWITCH_TIME_MICROSEC
+ },
+
+ //VBAT
+ {
+ PCF50626PmuSupply_VBAT,
+ PCF50626PmuSupply_Invalid,
+
+ 0,0,0,0,
+ 0,0,0,0,
+
+ {NV_TRUE,0,0,0,0},
+ 0,0,0
+ }
+};
+
+#define PCF50626SUPPLYINFOTABLESIZE NV_ARRAY_SIZE(pcf50626SupplyInfoTable)
+
+#endif //PCF50626_VOLTAGE_INFO_TABLE_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c
new file mode 100644
index 000000000000..dee9641eef7c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "pcf50626_batterycharger.h"
+#include "pcf50626_adc.h"
+#include "pcf50626_i2c.h"
+#include "pcf50626_reg.h"
+#include "ds2482_bridge.h"
+#include "ds2482_i2c.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_query.h"
+
+// implementations of platform related functions.
+
+#define OWI2CGUID NV_ODM_GUID('o','w','i','2','c','_','d','s')
+#define BATTERYGUID NV_ODM_GUID('b','a','t','t','_','m','o','t')
+
+static NvBool ds2482Presented = NV_FALSE;
+
+/* Initliase all registers that related to battery charger */
+NvBool
+Pcf50626BatteryChargerSetup(NvOdmPmuDeviceHandle hDevice)
+{
+
+ NvOdmIoModule I2cModule = NvOdmIoModule_I2c;
+ NvU32 I2cInstance = 0;
+ NvU32 I2cAddress = 0;
+ const NvOdmPeripheralConnectivity *pConnectivity =
+ NvOdmPeripheralGetGuid(OWI2CGUID);
+ NV_ASSERT(hDevice);
+
+ if (pConnectivity != NULL) // OwI2c device is in database
+ {
+ NvU32 i = 0;
+ for (i = 0; i < pConnectivity->NumAddress; i ++)
+ {
+ if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu)
+ {
+ I2cModule = NvOdmIoModule_I2c_Pmu;
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ I2cAddress = pConnectivity->AddressList[i].Address;
+ break;
+ }
+ }
+ ds2482Presented = NV_TRUE;
+ }
+ else
+ {
+ ds2482Presented = NV_FALSE;
+ }
+
+ if (ds2482Presented == NV_TRUE)
+ {
+ // init GPIO8
+ if (!Pcf50626I2cWrite8(hDevice, PCF50626_GPIO8C1_ADDR, 0x0))
+ return NV_FALSE;
+
+ NvOdmOsWaitUS(50000);
+
+ if (!Ds2482Setup(hDevice))
+ return NV_FALSE;
+
+ return NV_TRUE;
+ }
+
+ //TODO: add battery charger setup implementation here, base on HW.
+ // by default, simply return TRUE if nothing needed.
+ return NV_TRUE;
+}
+
+
+/* check CBC main batt presence */
+NvBool
+Pcf50626BatteryChargerCBCMainBatt(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ const NvOdmPeripheralConnectivity *pConnectivity =
+ NvOdmPeripheralGetGuid(BATTERYGUID);
+
+ NV_ASSERT(hDevice);
+
+ if (pConnectivity != NULL) // battery is in database
+ {
+ ///TODO: retrieve data from the database;
+ //Nothing needed on Concorde for now
+ }
+
+ if (ds2482Presented == NV_TRUE)
+ {
+ if (!Ds2482BatteryPresented(hDevice, status))
+ return NV_FALSE;
+ }
+ else
+ {
+ //TODO: add battery detection impelentation here. by default always return TRUE.
+ *status = NV_TRUE;
+ }
+
+ return NV_TRUE;
+}
+
+/* Calculate the battery temperature */
+NvU32 Pcf50626BatteryTemperature(NvU32 VBatSense, NvU32 VBatTemp)
+{
+ //TODO: implement the temperature algorithm based on the reading of Vbat sense and VBat temp.
+ // Pending approval.
+ return 0;
+}
+
+
+NvBool
+Ds2482BatteryPresented(NvOdmPmuDeviceHandle hDevice, NvBool *BattPresence)
+{
+ ///TODO: detect battery via ds2482 based on the battery spec.
+ ///Pending approval
+ return NV_TRUE;
+}
+
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c
new file mode 100644
index 000000000000..ec62ac6c4c17
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvcommon.h"
+#include "nvodm_pmu.h"
+#include "nvodm_query_discovery.h"
+#include "pmu_hal.h"
+#include "nvodm_services.h"
+#include "tps6586x/nvodm_pmu_tps6586x.h"
+#include "max8907b/max8907b.h"
+#include "max8907b/max8907b_rtc.h"
+#include "pcf50626/pcf50626.h"
+#include "pcf50626/pcf50626_rtc.h"
+
+static NvOdmPmuDevice*
+GetPmuInstance(NvOdmPmuDeviceHandle hDevice)
+{
+ static NvOdmPmuDevice Pmu;
+ static NvBool first = NV_TRUE;
+
+ if (first)
+ {
+ NvOdmOsMemset(&Pmu, 0, sizeof(Pmu));
+ first = NV_FALSE;
+
+ if (NvOdmPeripheralGetGuid(NV_ODM_GUID('t','p','s','6','5','8','6','x')))
+ {
+ // fill in HAL functions here.
+ Pmu.Hal = NV_TRUE;
+ Pmu.pfnSetup = Tps6586xSetup;
+ Pmu.pfnRelease = Tps6586xRelease;
+ Pmu.pfnGetCaps = Tps6586xGetCapabilities;
+ Pmu.pfnGetVoltage = Tps6586xGetVoltage;
+ Pmu.pfnSetVoltage = Tps6586xSetVoltage;
+ Pmu.pfnGetAcLineStatus = Tps6586xGetAcLineStatus;
+ Pmu.pfnGetBatteryStatus = Tps6586xGetBatteryStatus;
+ Pmu.pfnGetBatteryData = Tps6586xGetBatteryData;
+ Pmu.pfnGetBatteryFullLifeTime = Tps6586xGetBatteryFullLifeTime;
+ Pmu.pfnGetBatteryChemistry = Tps6586xGetBatteryChemistry;
+ Pmu.pfnSetChargingCurrent = Tps6586xSetChargingCurrent;
+ Pmu.pfnInterruptHandler = Tps6586xInterruptHandler;
+ Pmu.pfnReadRtc = Tps6586xReadRtc;
+ Pmu.pfnWriteRtc = Tps6586xWriteRtc;
+ Pmu.pfnIsRtcInitialized = Tps6586xIsRtcInitialized;
+ }
+ else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0')))
+ {
+
+ Pmu.pfnSetup = Pcf50626Setup;
+ Pmu.pfnRelease = Pcf50626Release;
+ Pmu.pfnGetCaps = Pcf50626GetCapabilities;
+ Pmu.pfnGetVoltage = Pcf50626GetVoltage;
+ Pmu.pfnSetVoltage = Pcf50626SetVoltage;
+ Pmu.pfnGetAcLineStatus = Pcf50626GetAcLineStatus;
+ Pmu.pfnGetBatteryStatus = Pcf50626GetBatteryStatus;
+ Pmu.pfnGetBatteryData = Pcf50626GetBatteryData;
+ Pmu.pfnGetBatteryFullLifeTime = Pcf50626GetBatteryFullLifeTime;
+ Pmu.pfnGetBatteryChemistry = Pcf50626GetBatteryChemistry;
+ Pmu.pfnSetChargingCurrent = Pcf50626SetChargingCurrent;
+ Pmu.pfnInterruptHandler = Pcf50626InterruptHandler;
+ Pmu.pfnReadRtc = Pcf50626RtcCountRead;
+ Pmu.pfnWriteRtc = Pcf50626RtcCountWrite;
+ Pmu.pfnIsRtcInitialized = Pcf50626IsRtcInitialized;
+ Pmu.pPrivate = NULL;
+ Pmu.Hal = NV_TRUE;
+ Pmu.Init = NV_FALSE;
+ }
+ else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('m','a','x','8','9','0','7','b')))
+ {
+
+ Pmu.pfnSetup = Max8907bSetup;
+ Pmu.pfnRelease = Max8907bRelease;
+ Pmu.pfnGetCaps = Max8907bGetCapabilities;
+ Pmu.pfnGetVoltage = Max8907bGetVoltage;
+ Pmu.pfnSetVoltage = Max8907bSetVoltage;
+ Pmu.pfnGetAcLineStatus = Max8907bGetAcLineStatus;
+ Pmu.pfnGetBatteryStatus = Max8907bGetBatteryStatus;
+ Pmu.pfnGetBatteryData = Max8907bGetBatteryData;
+ Pmu.pfnGetBatteryFullLifeTime = Max8907bGetBatteryFullLifeTime;
+ Pmu.pfnGetBatteryChemistry = Max8907bGetBatteryChemistry;
+ Pmu.pfnSetChargingCurrent = Max8907bSetChargingCurrent;
+ Pmu.pfnInterruptHandler = Max8907bInterruptHandler;
+ Pmu.pfnReadRtc = Max8907bRtcCountRead;
+ Pmu.pfnWriteRtc = Max8907bRtcCountWrite;
+ Pmu.pfnIsRtcInitialized = Max8907bIsRtcInitialized;
+ Pmu.pPrivate = NULL;
+ Pmu.Hal = NV_TRUE;
+ Pmu.Init = NV_FALSE;
+ }
+ }
+
+ if (hDevice && Pmu.Hal)
+ return &Pmu;
+
+ return NULL;
+}
+
+NvBool
+NvOdmPmuDeviceOpen(NvOdmPmuDeviceHandle *hDevice)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance((NvOdmPmuDeviceHandle)1);
+
+ *hDevice = (NvOdmPmuDeviceHandle)0;
+
+ if (!pmu || !pmu->pfnSetup)
+ return NV_FALSE;
+
+ if (pmu->Init)
+ {
+ *hDevice = (NvOdmPmuDeviceHandle)1;
+ return NV_TRUE;
+ }
+
+ if (pmu->pfnSetup(pmu))
+ {
+ *hDevice = (NvOdmPmuDeviceHandle)1;
+ pmu->Init = NV_TRUE;
+ return NV_TRUE;
+ }
+
+ return NV_FALSE;
+}
+
+void NvOdmPmuDeviceClose(NvOdmPmuDeviceHandle hDevice)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (!pmu)
+ return;
+
+ if (pmu->pfnRelease)
+ pmu->pfnRelease(pmu);
+
+ pmu->Init = NV_FALSE;
+}
+
+void
+NvOdmPmuGetCapabilities(NvU32 vddId,
+ NvOdmPmuVddRailCapabilities* pCapabilities)
+{
+ // use a manual handle, since this function doesn't takea handle
+ NvOdmPmuDevice* pmu = GetPmuInstance((NvOdmPmuDeviceHandle)1);
+
+ if (pmu && pmu->pfnGetCaps)
+ pmu->pfnGetCaps(vddId, pCapabilities);
+ else if (pCapabilities)
+ {
+ NvOdmOsMemset(pCapabilities, 0, sizeof(NvOdmPmuVddRailCapabilities));
+ pCapabilities->OdmProtected = NV_TRUE;
+ }
+}
+
+
+NvBool
+NvOdmPmuGetVoltage(NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddId,
+ NvU32* pMilliVolts)
+{
+ NvOdmPmuDevice* pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnGetVoltage)
+ return pmu->pfnGetVoltage(pmu, vddId, pMilliVolts);
+
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmPmuSetVoltage(NvOdmPmuDeviceHandle hDevice,
+ NvU32 VddId,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnSetVoltage)
+ {
+ return pmu->pfnSetVoltage(pmu, VddId, MilliVolts, pSettleMicroSeconds);
+ }
+
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds = 0;
+ return NV_TRUE;
+}
+
+
+NvBool
+NvOdmPmuGetAcLineStatus(NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuAcLineStatus *pStatus)
+{
+ NvOdmPmuDevice* pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnGetAcLineStatus)
+ return pmu->pfnGetAcLineStatus(pmu, pStatus);
+
+ return NV_TRUE;
+}
+
+
+NvBool
+NvOdmPmuGetBatteryStatus(NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance BatteryInst,
+ NvU8 *pStatus)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnGetBatteryStatus)
+ return pmu->pfnGetBatteryStatus(pmu, BatteryInst, pStatus);
+
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmPmuGetBatteryData(NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance BatteryInst,
+ NvOdmPmuBatteryData *pData)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnGetBatteryData)
+ return pmu->pfnGetBatteryData(pmu, BatteryInst, pData);
+
+ pData->batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN;
+ pData->batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN;
+
+ return NV_TRUE;
+}
+
+
+void
+NvOdmPmuGetBatteryFullLifeTime(NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance BatteryInst,
+ NvU32 *pLifeTime)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnGetBatteryFullLifeTime)
+ pmu->pfnGetBatteryFullLifeTime(pmu, BatteryInst, pLifeTime);
+
+ else
+ {
+ if (pLifeTime)
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ }
+}
+
+
+void
+NvOdmPmuGetBatteryChemistry(NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance BatteryInst,
+ NvOdmPmuBatteryChemistry *pChemistry)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnGetBatteryChemistry)
+ pmu->pfnGetBatteryChemistry(pmu, BatteryInst, pChemistry);
+ else
+ {
+ if (pChemistry)
+ *pChemistry = NVODM_BATTERY_DATA_UNKNOWN;
+ }
+}
+
+NvBool
+NvOdmPmuSetChargingCurrent(NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuChargingPath ChargingPath,
+ NvU32 ChargingCurrentLimitMa,
+ NvOdmUsbChargerType ChargerType)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnSetChargingCurrent)
+ return pmu->pfnSetChargingCurrent(pmu, ChargingPath, ChargingCurrentLimitMa, ChargerType);
+
+ return NV_TRUE;
+}
+
+
+void NvOdmPmuInterruptHandler(NvOdmPmuDeviceHandle hDevice)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnInterruptHandler)
+ pmu->pfnInterruptHandler(pmu);
+}
+
+NvBool NvOdmPmuReadRtc(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *Count)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnReadRtc)
+ return pmu->pfnReadRtc(pmu, Count);
+ return NV_FALSE;
+}
+
+
+NvBool NvOdmPmuWriteRtc(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnWriteRtc)
+ return pmu->pfnWriteRtc(pmu, Count);
+ return NV_FALSE;
+}
+
+NvBool
+NvOdmPmuIsRtcInitialized(NvOdmPmuDeviceHandle hDevice)
+{
+ NvOdmPmuDevice *pmu = GetPmuInstance(hDevice);
+
+ if (pmu && pmu->pfnIsRtcInitialized)
+ return pmu->pfnIsRtcInitialized(pmu);
+
+ return NV_FALSE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h
new file mode 100644
index 000000000000..05cdea828a20
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Abstraction layer stub for audio codec adaptations</b>
+ */
+
+#ifndef INCLUDED_NVODM_PMU_ADAPTATION_HAL_H
+#define INCLUDED_NVODM_PMU_ADAPTATION_HAL_H
+
+#include "nvcommon.h"
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef NvBool (*pfnPmuSetup)(NvOdmPmuDeviceHandle);
+typedef void (*pfnPmuRelease)(NvOdmPmuDeviceHandle);
+typedef void (*pfnPmuGetCaps)(NvU32, NvOdmPmuVddRailCapabilities*);
+typedef NvBool (*pfnPmuGetVoltage)(NvOdmPmuDeviceHandle, NvU32, NvU32*);
+typedef NvBool (*pfnPmuSetVoltage)(NvOdmPmuDeviceHandle, NvU32, NvU32, NvU32*);
+typedef NvBool (*pfnPmuGetAcLineStatus)(NvOdmPmuDeviceHandle, NvOdmPmuAcLineStatus*);
+typedef NvBool (*pfnPmuGetBatteryStatus)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvU8*);
+typedef NvBool (*pfnPmuGetBatteryData)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvOdmPmuBatteryData*);
+typedef void (*pfnPmuGetBatteryFullLifeTime)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvU32*);
+typedef void (*pfnPmuGetBatteryChemistry)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvOdmPmuBatteryChemistry*);
+typedef NvBool (*pfnPmuSetChargingCurrent)(NvOdmPmuDeviceHandle, NvOdmPmuChargingPath, NvU32, NvOdmUsbChargerType);
+typedef void (*pfnPmuInterruptHandler)(NvOdmPmuDeviceHandle);
+typedef NvBool (*pfnPmuReadRtc)(NvOdmPmuDeviceHandle, NvU32*);
+typedef NvBool (*pfnPmuWriteRtc)(NvOdmPmuDeviceHandle, NvU32);
+typedef NvBool (*pfnPmuIsRtcInitialized)(NvOdmPmuDeviceHandle);
+
+typedef struct NvOdmPmuDeviceRec
+{
+ pfnPmuSetup pfnSetup;
+ pfnPmuRelease pfnRelease;
+ pfnPmuGetCaps pfnGetCaps;
+ pfnPmuGetVoltage pfnGetVoltage;
+ pfnPmuSetVoltage pfnSetVoltage;
+ pfnPmuGetAcLineStatus pfnGetAcLineStatus;
+ pfnPmuGetBatteryStatus pfnGetBatteryStatus;
+ pfnPmuGetBatteryData pfnGetBatteryData;
+ pfnPmuGetBatteryFullLifeTime pfnGetBatteryFullLifeTime;
+ pfnPmuGetBatteryChemistry pfnGetBatteryChemistry;
+ pfnPmuSetChargingCurrent pfnSetChargingCurrent;
+ pfnPmuInterruptHandler pfnInterruptHandler;
+ pfnPmuReadRtc pfnReadRtc;
+ pfnPmuWriteRtc pfnWriteRtc;
+ pfnPmuIsRtcInitialized pfnIsRtcInitialized;
+ void *pPrivate;
+ NvBool Hal;
+ NvBool Init;
+} NvOdmPmuDevice;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile
new file mode 100644
index 000000000000..3b4770addf96
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile
@@ -0,0 +1,18 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x
+
+obj-y += nvodm_pmu_tps6586x.o
+obj-y += nvodm_pmu_tps6586x_adc.o
+obj-y += nvodm_pmu_tps6586x_batterycharger.o
+obj-y += nvodm_pmu_tps6586x_i2c.o
+obj-y += nvodm_pmu_tps6586x_interrupt.o
+obj-y += nvodm_pmu_tps6586x_rtc.o
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c
new file mode 100644
index 000000000000..197a2c227e1d
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c
@@ -0,0 +1,2036 @@
+
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_query_discovery.h"
+#include "nvodm_query.h"
+#include "nvodm_query_gpio.h"
+#include "nvodm_pmu_tps6586x_i2c.h"
+#include "nvodm_pmu_tps6586x_interrupt.h"
+#include "nvodm_pmu_tps6586x_batterycharger.h"
+#include "nvodm_pmu_tps6586x_adc.h"
+#include "nvodm_pmu_tps6586x_rtc.h"
+#include "pmu_hal.h"
+
+/**************************************************************************
+ * NOTE:
+ * + Please search "FIXME" and then change the code according to your tps6586x fuse
+ * * each LDO's voltage range and default value
+ * * each SM's voltage range and default value
+ * * Interrupt Masks
+ * + Battery settings
+ **************************************************************************/
+
+/**************************************************************************
+ * TPS6586x has two sets of power supliers:
+ * + 3 DC/DC converters: DCD0/1/2
+ * + 11 Regulators: LDO0-9 and RTC_OUT
+ * Besides that, TPS6586x has
+ * + 2 sets drivers for LED or other open drain outputs
+ * + 1 dedicated driver for keyboard backlight LED
+ * + 1 dedicated driver for external vibrator motor
+ * + 1 dedicated driver for white LED(SM3)
+ **************************************************************************/
+
+NvBool pmuPresented;
+NvBool battPresence;
+NvBool pmuInterruptSupported;
+TPS6586xStatus pmuStatus;
+NvOdmPmuDeviceTPS *hPmu;
+
+
+// threshold for battery status. need to fine tune based on battery/system characterisation
+#define NVODM_BATTERY_FULL_VOLTAGE_MV 4200
+#define NVODM_BATTERY_HIGH_VOLTAGE_MV 3900
+#define NVODM_BATTERY_LOW_VOLTAGE_MV 3300
+#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 3100
+
+#define DUMB_CHARGER_LIMIT_MA 250
+#define DEDICATED_CHARGER_LIMIT_MA 1000 // 1000mA for dedicated charger
+
+#define T_START_TIME 210
+#define K_RAMP 7
+
+/*
+ Only 4 options for charger current; Page36
+ According to TPS658x spec, the charge current = scaling factor / R_ISET.
+ From the schematic, R_ISET shows "1K". So the charge current = scaling factor.
+ Because the min value of the scaling factor is 0.25 and the R_ISET is fixed,
+ the min charging current = 0.25 / 1 = 0.25 A = 250 mA.
+ Thus, it will only support 1000mA, 750mA, 500mA, 250mA.
+ TODO: In future, we need to change to the actual R_IST value
+*/
+#define R_IST 1000
+#define MAX_CHARGING_CURRENT 1000000/R_IST
+#define L1_CHARGING_CURRENT 750
+#define L2_CHARGING_CURRENT 500
+#define L3_CHARGING_CURRENT 250
+
+/* Valtage tables for LDOs */
+/* FIXME: Modify those tables according to your fuse */
+static const NvU32 VLDOx[] = {1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300};
+static const NvU32 VLDO2[] = { 725, 750, 775, 800, 825, 850, 875, 900,
+ 925, 950, 975, 1000, 1025, 1050, 1075, 1100,
+ 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300,
+ 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500};
+/* FIXME tps65860 only */
+static const NvU32 VLDO4[] = {1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875,
+ 1900, 1925, 1950, 1975, 2000, 2000, 2000, 2000,
+ 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000,
+ 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000};
+
+typedef NvU32 (*TPS6586xPmuVoltageFunc)(const NvU32 bits);
+typedef NvBool (*TPS6586xPmuRailCtrlFunc)(const NvU32 rail, NvBool enable);
+
+typedef struct {
+ NvU8 addr;
+ NvU8 start;
+ NvU8 bits;
+ NvU8 flag; /*!< see each settings */
+} TPS6586xPmuRegisterInfo;
+
+typedef struct TPS6586xPmuSupplyInfoRec
+{
+ TPS6586xPmuSupply supply;
+
+ TPS6586xPmuRegisterInfo supplyRegInfo; /*!< Register info to set/get supply voltage */
+ TPS6586xPmuRegisterInfo ctrlRegInfo; /*!< Register info to enable/disable supply, flag indicates another addr */
+ TPS6586xPmuVoltageFunc getVoltage; /*!< Func to convert register bits to real voltage */
+ TPS6586xPmuVoltageFunc setVoltage; /*!< Func to convert real voltage to register bits */
+ TPS6586xPmuRailCtrlFunc railControl; /*!< Func to enable/disable output for each rail */
+ NvU8 Gpio; /*!< GPIO pin used to enable/disable external supplies */
+
+ NvOdmPmuVddRailCapabilities cap;
+
+
+} TPS6586xPmuSupplyInfo;
+
+static NvU32 TPS6586xPmuVoltageGetSM0(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageGetSM1(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageGetSM2(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageGetVLDOx(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageGetVLDO1(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageGetVLDO2(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageGetVLDO4(const NvU32 bits);
+
+static NvU32 TPS6586xPmuVoltageSetSM0(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageSetSM1(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageSetSM2(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageSetVLDOx(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageSetVLDO1(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageSetVLDO2(const NvU32 bits);
+static NvU32 TPS6586xPmuVoltageSetVLDO4(const NvU32 bits);
+
+/* FIXME: Change getVoltage/setVoltage according to your fuse */
+static const TPS6586xPmuSupplyInfo tps6586xSupplyInfoTable[] =
+{
+ {
+ TPS6586xPmuSupply_Invalid,
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_TRUE,0,0,0,0},
+ },
+
+ //DCD0
+ {
+ TPS6586xPmuSupply_DCD0,
+
+ {TPS6586x_R26_SM0V1, 0, 5, 0},
+ {TPS6586x_R10_SUPPLYENA, 1, 1, TPS6586x_R11_SUPPLYENB},
+ TPS6586xPmuVoltageGetSM0,
+ TPS6586xPmuVoltageSetSM0,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 625, 25, 2700, 1200
+#else
+ 900, 25, 1200, 1200
+#endif
+ },
+ },
+
+ //DCD1
+ {
+ TPS6586xPmuSupply_DCD1,
+
+ {TPS6586x_R23_SM1V1, 0, 5, 0},
+ {TPS6586x_R10_SUPPLYENA, 0, 1, TPS6586x_R11_SUPPLYENB},
+ TPS6586xPmuVoltageGetSM1,
+ TPS6586xPmuVoltageSetSM1,
+ NULL,
+ TPS6586x_RFF_INVALID,
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 625, 25, 2700, 1000
+#else
+ 1800, 0, 1800, 1800
+#endif
+ },
+ },
+
+ //DCD2
+ {
+ TPS6586xPmuSupply_DCD2,
+
+ {TPS6586x_R42_SUPPLYV2, 0, 5, 0},
+ {TPS6586x_R12_SUPPLYENC, 7, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetSM2,
+ TPS6586xPmuVoltageSetSM2,
+ NULL,
+ TPS6586x_RFF_INVALID,
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 3000, 50, 4550, 3700
+#else
+ 3000, 50, 4550, 3250 // fixme
+#endif
+ },
+ },
+
+ // LD00
+ {
+ TPS6586xPmuSupply_LDO0,
+
+ {TPS6586x_R41_SUPPLYV1, 5, 3, 0},
+ {TPS6586x_R12_SUPPLYENC, 0, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 3300
+#else
+ 2800, 0, 2800, 2800
+#endif
+ },
+ },
+
+ // LD01 - V-1V2
+ {
+ TPS6586xPmuSupply_LDO1,
+
+ {TPS6586x_R41_SUPPLYV1, 0, 5, 0},
+ {TPS6586x_R12_SUPPLYENC, 1, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDO1,
+ TPS6586xPmuVoltageSetVLDO1,
+ NULL,
+ TPS6586x_RFF_INVALID,
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 725, 25, 1500, 1100
+#else
+ 1200, 0, 1200, 1200
+#endif
+ },
+ },
+
+ //LD02 - V-RTC
+ {
+ TPS6586xPmuSupply_LDO2,
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ {TPS6586x_R2F_LDO2BV1, 0, 5, 0},
+#else
+ {TPS6586x_R29_LDO2AV1, 0, 5, 0},
+#endif
+ {TPS6586x_R10_SUPPLYENA, 2, 2, TPS6586x_R11_SUPPLYENB},
+ TPS6586xPmuVoltageGetVLDO2,
+ TPS6586xPmuVoltageSetVLDO2,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 725, 25, 1500, 1200
+#else
+ 900, 25, 1200, 1200
+#endif
+ },
+ },
+
+ //LDO3
+ {
+ TPS6586xPmuSupply_LDO3,
+
+ {TPS6586x_R44_SUPPLYV4, 0, 3, 0},
+ {TPS6586x_R12_SUPPLYENC, 2, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 3300
+#else
+ 1800, 0, 1800, 1800
+#endif
+ },
+ },
+
+ //LDO4
+ {
+ TPS6586xPmuSupply_LDO4,
+
+ {TPS6586x_R32_LDO4V1, 0, 5, 0},
+ {TPS6586x_R12_SUPPLYENC, 3, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDO4,
+ TPS6586xPmuVoltageSetVLDO4,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1700, 25, 2000, 1800
+#else
+ 1800, 0, 1800, 1800
+#endif
+ },
+ },
+
+ //LDO5
+ {
+ TPS6586xPmuSupply_LDO5,
+
+ {TPS6586x_R46_SUPPLYV6, 0, 3, 0},
+ {TPS6586x_R14_SUPPLYENE, 6, 1, TPS6586x_RFF_INVALID},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 2850
+#else
+ 2800, 0, 2800, 2800
+#endif
+ },
+ },
+
+ //LDO6 - V-3V3 USB
+ {
+ TPS6586xPmuSupply_LDO6,
+
+ {TPS6586x_R43_SUPPLYV3, 0, 3, 0},
+ {TPS6586x_R12_SUPPLYENC, 4, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 2850
+#else
+ 3300, 0, 3300, 3300
+#endif
+ },
+ },
+
+ //LDO7 - V-SDIO
+ {
+ TPS6586xPmuSupply_LDO7,
+
+ {TPS6586x_R43_SUPPLYV3, 3, 3, 0},
+ {TPS6586x_R12_SUPPLYENC, 5, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 3300
+#else
+ 2800, 0, 2800, 2800
+#endif
+ },
+ },
+
+ //LDO8 - V-2V8
+ {
+ TPS6586xPmuSupply_LDO8,
+
+ {TPS6586x_R42_SUPPLYV2, 5, 3, 0},
+ {TPS6586x_R12_SUPPLYENC, 6, 1, TPS6586x_R13_SUPPLYEND},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 1800
+#else
+ 2800, 0, 2800, 2800
+#endif
+ },
+ },
+
+ //LDO9
+ {
+ TPS6586xPmuSupply_LDO9,
+
+ {TPS6586x_R46_SUPPLYV6, 3, 3, 0},
+ {TPS6586x_R14_SUPPLYENE, 7, 1, TPS6586x_RFF_INVALID},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 2850
+#else
+ 2500, 0, 2500, 2500,
+#endif
+ },
+ },
+
+ //RTC_OUT
+ {
+ TPS6586xPmuSupply_RTC_OUT,
+
+ {TPS6586x_R44_SUPPLYV4, 3, 3, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, TPS6586x_RFF_INVALID},
+ TPS6586xPmuVoltageGetVLDOx,
+ TPS6586xPmuVoltageSetVLDOx,
+ NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ 1250, 25, 3350, 3300
+#else
+ 2500, 0, 2500, 2500
+#endif
+ },
+ },
+
+
+ //RED1
+ {
+ TPS6586xPmuSupply_RED1,
+
+ {TPS6586x_R51_RGB1RED, 0, 5, 0},
+ {TPS6586x_R52_RGB1GREEN, 7, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 0, 1, 0x1f, 0
+ },
+ },
+
+ //GREEN1
+ {
+ TPS6586xPmuSupply_GREEN1,
+
+ {TPS6586x_R52_RGB1GREEN, 0, 5, 0},
+ {TPS6586x_R52_RGB1GREEN, 7, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 0, 1, 0x1f, 0
+ },
+ },
+
+ //BLUE1
+ {
+ TPS6586xPmuSupply_BLUE1,
+
+ {TPS6586x_R53_RGB1BLUE, 0, 5, 0},
+ {TPS6586x_R52_RGB1GREEN, 7, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 0, 1, 0x1f, 0
+ },
+ },
+
+ //RED2
+ {
+ TPS6586xPmuSupply_RED2,
+
+ {TPS6586x_R54_RGB2RED, 0, 5, 0},
+ {TPS6586x_R55_RGB2GREEN, 7, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 0, 1, 0x1f, 0
+ },
+ },
+
+ //GREEN2
+ {
+ TPS6586xPmuSupply_GREEN2,
+
+ {TPS6586x_R55_RGB2GREEN, 0, 5, 0},
+ {TPS6586x_R55_RGB2GREEN, 7, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 0, 1, 0x1f, 0
+ },
+ },
+
+ //BLUE2
+ {
+ TPS6586xPmuSupply_BLUE2,
+
+ {TPS6586x_R56_RGB2BLUE, 0, 5, 0},
+ {TPS6586x_R55_RGB2GREEN, 7, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 0, 1, 0x1f, 0
+ },
+ },
+
+ //LED_PWM
+ {
+ TPS6586xPmuSupply_LED_PWM,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0}, /* FIXME: how to get the output */
+ {TPS6586x_RFF_INVALID, 0, 0, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_TRUE,
+ 0, 0, 0, 0
+ },
+ },
+
+ //PWM
+ {
+ TPS6586xPmuSupply_PWM,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0}, /* FIXME: how to get the output */
+ {TPS6586x_RFF_INVALID, 0, 0, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_TRUE,
+ 0, 0, 0, 0
+ },
+ },
+
+ //White LED(SM3)
+ {
+ TPS6586xPmuSupply_WHITE_LED,
+
+ {TPS6586x_R58_SM3_SET1, 0, 3, 0},
+ {TPS6586x_R57_SM3_SET0, 0, 8, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+
+ {
+ NV_FALSE,
+ 25000, 0, 25000, 0
+ },
+ },
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ {
+ TPS6586xPmuSupply_SoC,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_R14_SUPPLYENE, 3, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_FALSE,0,0,0,0},
+ },
+ // External Supplies
+
+ {
+ Ext_TPS62290PmuSupply_BUCK,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ 3,
+ {NV_FALSE,0,1050,1050,1050},
+ },
+
+ {
+ Ext_TPS72012PmuSupply_LDO,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ 2,
+ {NV_FALSE,0,1200,1200,1200},
+ },
+
+ {
+ Ext_TPS74201PmuSupply_LDO,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ 1,
+ {NV_FALSE,0,1500,1500,1500},
+ },
+ {
+ Ext_TPS2051BPmuSupply_VDDIO_VID,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_FALSE,0,5000,5000,5000},
+ },
+
+ {
+ Ext_SWITCHPmuSupply_VDDIO_SD,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_FALSE,0,3300,3300,3300},
+ },
+
+ {
+ Ext_SWITCHPmuSupply_VDDIO_SDMMC,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_FALSE,0,3300,3300,3300},
+ },
+ {
+ Ext_SWITCHPmuSupply_VDD_BL,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_FALSE,0,11100,11100,11100},
+ },
+
+ {
+ Ext_SWITCHPmuSupply_VDD_PNL,
+
+ {TPS6586x_RFF_INVALID, 0, 0, 0},
+ {TPS6586x_R14_SUPPLYENE, 3, 1, TPS6586x_RFF_INVALID},
+ NULL, NULL, NULL,
+ TPS6586x_RFF_INVALID,
+ {NV_FALSE,0,3300,3300,3300},
+ }
+#endif
+};
+
+static NvU32 TPS6586xPmuVoltageGetSM0(const NvU32 bits)
+{
+ NV_ASSERT(bits <= 0x1F);
+
+ return (725 + bits * 25);
+}
+
+static NvU32 TPS6586xPmuVoltageGetSM1(const NvU32 bits)
+{
+ NV_ASSERT(bits <= 0x1F);
+
+#if defined (CONFIG_TEGRA_ODM_HARMONY)
+ return (725 + bits * 25);
+#else
+ return (1450 + bits * 50);
+#endif
+}
+
+static NvU32 TPS6586xPmuVoltageGetSM2(const NvU32 bits)
+{
+ NV_ASSERT(bits <= 0x1F);
+
+ return (3000 + bits * 25);
+}
+
+static NvU32 TPS6586xPmuVoltageGetVLDOx(const NvU32 bits)
+{
+ NV_ASSERT(bits <= 0x7);
+
+ return VLDOx[bits];
+}
+
+static NvU32 TPS6586xPmuVoltageGetVLDO1(const NvU32 bits)
+{
+ /* VLDO1 and VLDO2 use the same table.
+ * See pp. 64 - 66 of TPS658621 data sheet.
+ */
+ NV_ASSERT(bits <= 0x1F);
+
+ return VLDO2[bits];
+}
+
+static NvU32 TPS6586xPmuVoltageGetVLDO2(const NvU32 bits)
+{
+ NV_ASSERT(bits <= 0x1F);
+ return VLDO2[bits];
+}
+static NvU32 TPS6586xPmuVoltageGetVLDO4(const NvU32 bits)
+{
+ NV_ASSERT(bits <= 0x1F);
+ return VLDO4[bits];
+}
+
+#ifndef MIN
+#define MIN(a, b) (a) <= (b) ? (a) : (b)
+#endif
+
+static NvU32 TPS6586xPmuVoltageSetSM0(const NvU32 millivolts)
+{
+ if (millivolts < 725)
+ return 0;
+ else
+ return MIN((millivolts - 725) / 25, 0x1f);
+}
+
+static NvU32 TPS6586xPmuVoltageSetSM1(const NvU32 millivolts)
+{
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if (millivolts < 725)
+ return 0;
+ else
+ return MIN((millivolts - 725) / 25, 0x1f);
+#else
+ if (millivolts < 1450)
+ return 0;
+ else
+ return MIN((millivolts - 1450) / 50, 0x1f);
+#endif
+}
+
+static NvU32 TPS6586xPmuVoltageSetSM2(const NvU32 millivolts)
+{
+ if (millivolts < 3000)
+ return 0;
+ else
+ return MIN((millivolts - 3000) / 25, 0x1f);
+}
+
+#define VOLTAGE_SEARCH(mv, vtbl) \
+ const int cnt = sizeof(vtbl)/sizeof(NvU32); \
+ int i; \
+ for (i=0; i<cnt; i++) \
+ { \
+ if (mv <= (vtbl)[i]) \
+ break; \
+ } \
+ return MIN(i, cnt-1)
+
+
+static NvU32 TPS6586xPmuVoltageSetVLDOx(const NvU32 millivolts)
+{
+ VOLTAGE_SEARCH(millivolts, VLDOx);
+}
+
+static NvU32 TPS6586xPmuVoltageSetVLDO1(const NvU32 millivolts)
+{
+ /* VLDO1 and VLDO2 use the same table.
+ * See pp. 64 - 66 of TPS658621 data sheet.
+ */
+ VOLTAGE_SEARCH(millivolts, VLDO2);
+}
+
+static NvU32 TPS6586xPmuVoltageSetVLDO2(const NvU32 millivolts)
+{
+ VOLTAGE_SEARCH(millivolts, VLDO2);
+}
+static NvU32 TPS6586xPmuVoltageSetVLDO4(const NvU32 millivolts)
+{
+ VOLTAGE_SEARCH(millivolts, VLDO4);
+}
+
+
+void
+Tps6586xGetCapabilities(
+ NvU32 vddRail,
+ NvOdmPmuVddRailCapabilities* pCapabilities)
+{
+ NV_ASSERT(pCapabilities);
+ NV_ASSERT(vddRail < TPS6586xPmuSupply_Num);
+
+ *pCapabilities = tps6586xSupplyInfoTable[vddRail].cap;
+}
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+static NvBool g_ExternalSupplyEnabled[TPS6586x_EXTERNAL_SUPPLY_NUM] = { 0 };
+
+static NvBool
+Tps6586xGetExternalSupply(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ if (g_ExternalSupplyEnabled[vddRail - (NvU32)(Ext_TPS62290PmuSupply_BUCK)] == NV_TRUE)
+ *pMilliVolts = tps6586xSupplyInfoTable[vddRail].cap.requestMilliVolts;
+ else
+ *pMilliVolts = 0;
+
+ return NV_TRUE;
+}
+#endif
+
+static NvBool
+Tps6586xReadVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ const TPS6586xPmuSupplyInfo *pSupplyInfo = &tps6586xSupplyInfoTable[vddRail];
+ NvU32 data = 0;
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ // External supplies are fixed.
+ if ((vddRail == Ext_TPS62290PmuSupply_BUCK) ||
+ (vddRail == Ext_TPS72012PmuSupply_LDO) ||
+ (vddRail == Ext_TPS74201PmuSupply_LDO) ||
+ (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDDIO_SD) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDDIO_SDMMC) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDD_BL) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDD_PNL))
+ {
+ if (!Tps6586xGetExternalSupply(hDevice, vddRail, pMilliVolts))
+ return NV_FALSE;
+ else
+ return NV_TRUE;
+ }
+#endif
+
+ if (pSupplyInfo->supplyRegInfo.addr == TPS6586x_RFF_INVALID)
+ {
+ return NV_FALSE;
+ }
+
+ if (! Tps6586xI2cRead8(hDevice, pSupplyInfo->supplyRegInfo.addr, &data))
+ return NV_FALSE;
+
+ if (pSupplyInfo->getVoltage)
+ *pMilliVolts = pSupplyInfo->getVoltage((data >> pSupplyInfo->supplyRegInfo.start) & ((1<<pSupplyInfo->supplyRegInfo.bits)-1));
+ else
+ *pMilliVolts = data;
+
+ Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.addr, &data);
+ data &= (((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start);
+ if (data == 0)
+ {
+ //since Voltage table is {1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300}
+ //need to fill 0 voltage if needed
+ *pMilliVolts = data;
+ }
+
+
+ return NV_TRUE;
+}
+
+#if 0
+static NvBool
+Tps6586xSupplyCtrl(
+ const NvU32 vddRail,
+ NvBool ctrl)
+{
+ return NV_TRUE;
+}
+#endif
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+#define NVODM_PORT(x) ((x) - 'a')
+
+static NvBool
+Tps6586xSetExternalSupply(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvBool Enable)
+{
+ const TPS6586xPmuSupplyInfo* pSupplyInfo = &tps6586xSupplyInfoTable[vddRail];
+ NvU32 data = 0;
+ NvU8 Gpio;
+ NvU32 GpioPort;
+ NvU32 GpioPin;
+
+ NV_ASSERT((vddRail > TPS6586xPmuSupply_Invalid) && (vddRail < TPS6586xPmuSupply_Num));
+
+ // FIXME: Clean this up! This includes embedding more of these settings in
+ // the supply info table to simplify the code.
+
+ // Switched by PMU GPIO
+ if ((vddRail == Ext_TPS62290PmuSupply_BUCK)||
+ (vddRail == Ext_TPS72012PmuSupply_LDO) ||
+ (vddRail == Ext_TPS74201PmuSupply_LDO))
+ {
+ // Set output mode (TEST: FOR GPIO1 only)
+
+ Gpio = pSupplyInfo->Gpio;
+ switch (Gpio)
+ {
+ case 1:
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5D_GPIOSET1, &data))
+ return NV_FALSE;
+
+ // Reset mode field
+ data &= ~(TPS6586x_R5D_GPIOSET1_GPIO1_MODE_MASK <<
+ TPS6586x_R5D_GPIOSET1_GPIO1_MODE_SHIFT);
+ // Apply new mode setting (output)
+ data |= (TPS6586x_R5D_GPIO_MODE_OUTPUT <<
+ TPS6586x_R5D_GPIOSET1_GPIO1_MODE_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data))
+ return NV_FALSE;
+
+ if (Enable)
+ {
+ // Enable output
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data))
+ return NV_FALSE;
+
+ data |= (TPS6586x_R5E_GPIOSET2_GPIO1_OUT_MASK <<
+ TPS6586x_R5E_GPIOSET2_GPIO1_OUT_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+ }
+ else
+ {
+ // Disable output
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data))
+ return NV_FALSE;
+
+ data &= ~(TPS6586x_R5E_GPIOSET2_GPIO1_OUT_MASK <<
+ TPS6586x_R5E_GPIOSET2_GPIO1_OUT_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+ }
+ break;
+
+ case 2:
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5D_GPIOSET1, &data))
+ return NV_FALSE;
+
+ // Reset mode field
+ data &= ~(TPS6586x_R5D_GPIOSET1_GPIO2_MODE_MASK <<
+ TPS6586x_R5D_GPIOSET1_GPIO2_MODE_SHIFT);
+ // Apply new mode setting (output)
+ data |= (TPS6586x_R5D_GPIO_MODE_OUTPUT <<
+ TPS6586x_R5D_GPIOSET1_GPIO2_MODE_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data))
+ return NV_FALSE;
+
+ if (Enable)
+ {
+ // Enable output
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data))
+ return NV_FALSE;
+
+ data |= (TPS6586x_R5E_GPIOSET2_GPIO2_OUT_MASK <<
+ TPS6586x_R5E_GPIOSET2_GPIO2_OUT_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+ }
+ else
+ {
+ // Disable output
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data))
+ return NV_FALSE;
+
+ data &= ~(TPS6586x_R5E_GPIOSET2_GPIO2_OUT_MASK <<
+ TPS6586x_R5E_GPIOSET2_GPIO2_OUT_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+ }
+ break;
+
+ case 3:
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5D_GPIOSET1, &data))
+ return NV_FALSE;
+ // Reset mode field
+ data &= ~(TPS6586x_R5D_GPIOSET1_GPIO3_MODE_MASK <<
+ TPS6586x_R5D_GPIOSET1_GPIO3_MODE_SHIFT);
+ // Apply new mode setting (output)
+ data |= (TPS6586x_R5D_GPIO_MODE_OUTPUT <<
+ TPS6586x_R5D_GPIOSET1_GPIO3_MODE_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data))
+ return NV_FALSE;
+
+ if (Enable)
+ {
+ // Enable output
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data))
+ return NV_FALSE;
+
+ data |= (TPS6586x_R5E_GPIOSET2_GPIO3_OUT_MASK <<
+ TPS6586x_R5E_GPIOSET2_GPIO3_OUT_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+ }
+ else
+ {
+ // Disable output
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data))
+ return NV_FALSE;
+
+ data &= ~(TPS6586x_R5E_GPIOSET2_GPIO3_OUT_MASK <<
+ TPS6586x_R5E_GPIOSET2_GPIO3_OUT_SHIFT);
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+ }
+ break;
+
+ default:
+ return NV_FALSE; // bad parameter
+ }
+ }
+ // Switched by AP GPIO
+ else
+ {
+ // Open GPIO
+ if (!hPmu->hGpio)
+ {
+ hPmu->hGpio = NvOdmGpioOpen();
+
+ if (!hPmu->hGpio)
+ return NV_FALSE;
+ }
+
+ // Get AP GPIO pin assigned to the respective voltage rail
+ // FIXME: This should be driven by supply info table.
+ switch (vddRail)
+ {
+ case Ext_TPS2051BPmuSupply_VDDIO_VID:
+ GpioPort = NVODM_PORT('t');
+ GpioPin = 2;
+ break;
+
+ case Ext_SWITCHPmuSupply_VDDIO_SD:
+ GpioPort = NVODM_PORT('t');
+ GpioPin = 3;
+ break;
+
+ case Ext_SWITCHPmuSupply_VDDIO_SDMMC:
+ GpioPort = NVODM_PORT('i');
+ GpioPin = 6;
+ break;
+
+ case Ext_SWITCHPmuSupply_VDD_BL:
+ GpioPort = NVODM_PORT('w');
+ GpioPin = 0;
+ break;
+
+ case Ext_SWITCHPmuSupply_VDD_PNL:
+ GpioPort = NVODM_PORT('c');
+ GpioPin = 6;
+ break;
+
+ default:
+ return NV_FALSE;
+ }
+
+ NV_ASSERT((NVODM_EXT_AP_GPIO_RAIL(vddRail) >= 0) &&
+ (NVODM_EXT_AP_GPIO_RAIL(vddRail) < TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM));
+
+ // Acquire Pin Handle
+ if (!hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)])
+ {
+ hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)] =
+ NvOdmGpioAcquirePinHandle(hPmu->hGpio, GpioPort, GpioPin);
+
+ if (!hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)])
+ return NV_FALSE;
+ }
+
+ if (Enable)
+ {
+ if (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID)
+ {
+ NvOdmGpioConfig(hPmu->hGpio,
+ hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)],
+ NvOdmGpioPinMode_Tristate);
+ }
+ else
+ {
+ NvOdmGpioSetState(hPmu->hGpio,
+ hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)],
+ NvOdmGpioPinActiveState_High);
+
+ NvOdmGpioConfig(hPmu->hGpio,
+ hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)],
+ NvOdmGpioPinMode_Output);
+ }
+ }
+ else
+ {
+ if (vddRail != Ext_TPS2051BPmuSupply_VDDIO_VID)
+ {
+ NvOdmGpioSetState(hPmu->hGpio,
+ hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)],
+ NvOdmGpioPinActiveState_Low);
+ NvOdmGpioConfig(hPmu->hGpio,
+ hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)],
+ NvOdmGpioPinMode_Output);
+ }
+ }
+ }
+
+ // This isn't thread safe, but it's highly unlikely that will be an issue for these rails.
+ if (Enable)
+ {
+ g_ExternalSupplyEnabled[vddRail - (NvU32)(Ext_TPS62290PmuSupply_BUCK)] = NV_TRUE;
+ }
+ else
+ {
+ g_ExternalSupplyEnabled[vddRail - (NvU32)(Ext_TPS62290PmuSupply_BUCK)] = NV_FALSE;
+ }
+ return NV_TRUE;
+}
+#endif
+
+static NvBool
+Tps6586xWriteVoltageReg(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ const TPS6586xPmuSupplyInfo* pSupplyInfo = &tps6586xSupplyInfoTable[vddRail];
+ //const TPS6586xPmuSupplyInfo* pSupplyInputInfo = &tps6586xSupplyInfoTable[pSupplyInfo->supplyInput];
+ NvBool status = NV_FALSE;
+ NvU32 settleTime = 0;
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ NvU32 volChange = 0;
+#endif
+
+ NV_ASSERT(pSupplyInfo->supply == (TPS6586xPmuSupply)vddRail);
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if ((vddRail != Ext_TPS62290PmuSupply_BUCK) &&
+ (vddRail != Ext_TPS72012PmuSupply_LDO) &&
+ (vddRail != Ext_TPS74201PmuSupply_LDO) &&
+ (vddRail != Ext_TPS2051BPmuSupply_VDDIO_VID) &&
+ (vddRail != Ext_SWITCHPmuSupply_VDDIO_SD) &&
+ (vddRail != Ext_SWITCHPmuSupply_VDDIO_SDMMC) &&
+ (vddRail != Ext_SWITCHPmuSupply_VDD_BL) &&
+ (vddRail != Ext_SWITCHPmuSupply_VDD_PNL))
+#endif
+ {
+ if (pSupplyInfo->ctrlRegInfo.addr == TPS6586x_RFF_INVALID)
+ {
+ NVODMPMU_PRINTF(("TPS:The required ctrl register address is INVALID...\n"));
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ return NV_TRUE;
+ //return NV_FALSE;
+#else
+ return NV_FALSE;
+#endif
+ }
+ }
+
+ if (MilliVolts == ODM_VOLTAGE_OFF)
+ {
+ NvU32 data = 0;
+
+ // check if the supply can be turned off
+ //NV_ASSERT(hDevice->supplyRefCntTable[vddRail]);
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ // Disable external supplies
+ if ((vddRail == Ext_TPS62290PmuSupply_BUCK) ||
+ (vddRail == Ext_TPS72012PmuSupply_LDO) ||
+ (vddRail == Ext_TPS74201PmuSupply_LDO) ||
+ (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDDIO_SD) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDDIO_SDMMC) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDD_BL) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDD_PNL))
+ {
+ status = Tps6586xSetExternalSupply(hDevice, vddRail, NV_FALSE);
+ }
+ else
+#endif
+ if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail] == 1)
+ {
+ /* Disable */
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE);
+ Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.addr, &data);
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if (vddRail == TPS6586xPmuSupply_SoC)
+ {
+ // SOC Super power rail don't hold the sleep bit
+ data |= (((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start);
+ }
+ else
+#endif
+ {
+ data &= ~(((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start);
+ }
+ status = Tps6586xI2cWrite8(hDevice, pSupplyInfo->ctrlRegInfo.addr, data);
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if (vddRail == TPS6586xPmuSupply_SoC)
+ {
+ // Wait 10 secs for PMU to shutdown
+ NvOdmOsWaitUS(100000000);
+ }
+#endif
+
+ if (status && (pSupplyInfo->ctrlRegInfo.flag != TPS6586x_RFF_INVALID))
+ {
+ status = Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.flag, &data);
+ if (status)
+ {
+ data &= ~(((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start);
+ status = Tps6586xI2cWrite8(hDevice, pSupplyInfo->ctrlRegInfo.flag, data);
+ }
+ }
+
+ /* Reset to voltage to 0th */
+ MilliVolts = 0;
+
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ // Calcuate this voltage change
+ volChange = ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail];
+
+ ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] = 0;
+
+ // DCD0/DCD1/DCD2
+ if ((vddRail == TPS6586xPmuSupply_DCD0) ||
+ (vddRail == TPS6586xPmuSupply_DCD1) ||
+ (vddRail == TPS6586xPmuSupply_DCD2))
+ {
+ // delay = Tstart(210) + Voltage change/Kramp
+ settleTime = T_START_TIME + volChange/K_RAMP;
+ }
+ else if ((vddRail == TPS6586xPmuSupply_LDO2) ||
+ (vddRail == TPS6586xPmuSupply_LDO4))
+ {
+ // Voltage change/Kramp
+ settleTime = volChange/K_RAMP;
+ }
+ else
+ {
+ settleTime = 0;
+ }
+#endif
+ }
+
+ if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail] != 0)
+ {
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if(--((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail] != 0)
+ {
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds = 0;
+ return NV_TRUE;
+ }
+#else
+ --((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail];
+#endif
+ }
+
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ if (pSettleMicroSeconds != NULL)
+ *pSettleMicroSeconds = settleTime;
+ else
+ NvOdmOsWaitUS(settleTime);
+
+ return NV_TRUE;
+#endif
+ }
+ else
+ {
+ NvU32 data = 0;
+
+ if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail]++ == 0)
+ {
+ // Enable external supplies
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ if ((vddRail == Ext_TPS62290PmuSupply_BUCK) ||
+ (vddRail == Ext_TPS72012PmuSupply_LDO) ||
+ (vddRail == Ext_TPS74201PmuSupply_LDO) ||
+ (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDDIO_SD) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDDIO_SDMMC) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDD_BL) ||
+ (vddRail == Ext_SWITCHPmuSupply_VDD_PNL))
+ {
+ status = Tps6586xSetExternalSupply(hDevice, vddRail, NV_TRUE);
+ }
+ else
+#endif
+ {
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->hOdmPmuSevice, pSupplyInfo->supply, NV_TRUE);
+#endif
+ status = Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.addr, &data);
+ if (status && ((data >> pSupplyInfo->ctrlRegInfo.start) & 0x1) == 0)
+ {
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ /* Enable */
+ NvOdmServicesPmuSetSocRailPowerState(
+ ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->hOdmPmuSevice,
+ pSupplyInfo->supply, NV_TRUE);
+#endif
+ data |= (((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start);
+ if (NV_FALSE == Tps6586xI2cWrite8(hDevice, pSupplyInfo->ctrlRegInfo.addr, data))
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ return NV_TRUE;
+#else
+ return NV_FALSE;
+#endif
+ }
+ }
+ }
+
+ /* Disable Flash mode
+ * FIXME: please check whether you need to disable flash */
+ /*
+ if (vddRail == TPS6586xPmuSupply_RED1 ||
+ vddRail == TPS6586xPmuSupply_GREEN1 ||
+ vddRail == TPS6586xPmuSupply_BLUE1)
+ {
+ if (NV_FALSE == Tps6586xI2cWrite8(hDevice, TPS6586x_R50_RGB1FLASH, 0xFF))
+ return NV_FALSE;
+ }
+ */
+ }
+
+ if (pSupplyInfo->supplyRegInfo.addr == TPS6586x_RFF_INVALID)
+ {
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ return NV_TRUE;
+#else
+ return NV_FALSE;
+#endif
+ }
+ else
+ {
+ const int bits = pSupplyInfo->setVoltage ? pSupplyInfo->setVoltage(MilliVolts) : MilliVolts;
+ NvU32 data = 0;
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ status = Tps6586xI2cRead8(hDevice, pSupplyInfo->supplyRegInfo.addr, &data);
+ if (NV_FALSE == status)
+ NVODMPMU_PRINTF(("TPS:Writing to PMU I2C fails 1... supplyaddress: %d\n", pSupplyInfo->supplyRegInfo.addr));
+#else
+ if ((vddRail == TPS6586xPmuSupply_DCD0) ||
+ (vddRail == TPS6586xPmuSupply_DCD1) ||
+ (vddRail == TPS6586xPmuSupply_LDO4) ||
+ (vddRail == TPS6586xPmuSupply_LDO2))
+ {
+ status = NV_TRUE;
+ }
+ else
+ {
+ status = Tps6586xI2cRead8(hDevice, pSupplyInfo->supplyRegInfo.addr, &data);
+ }
+#endif
+
+ if (status)
+ {
+ data &= ~(((1<<pSupplyInfo->supplyRegInfo.bits)-1)<<pSupplyInfo->supplyRegInfo.start);
+ data |= (bits << pSupplyInfo->supplyRegInfo.start);
+ status = Tps6586xI2cWrite8(hDevice, pSupplyInfo->supplyRegInfo.addr, data);
+
+ /* Trigger a voltage change for SM0/SM1/LDO2/LDO4 */
+ if ((vddRail == TPS6586xPmuSupply_DCD0) ||
+ (vddRail == TPS6586xPmuSupply_DCD1) ||
+ (vddRail == TPS6586xPmuSupply_LDO4) ||
+ (vddRail == TPS6586xPmuSupply_LDO2))
+ {
+ data = 0;
+ switch (vddRail)
+ {
+ case TPS6586xPmuSupply_LDO2:
+ data |= (1<<4);
+ data &= ~(1<<5);
+ break;
+
+ case TPS6586xPmuSupply_LDO4:
+ data |= (1<<6);
+ data &= ~(1<<7);
+ break;
+
+ case TPS6586xPmuSupply_DCD0:
+ data |= (1<<2);
+ data &= ~(1<<3);
+ break;
+
+ case TPS6586xPmuSupply_DCD1:
+ data |= (1<<0);
+ data &= ~(1<<1);
+ break;
+ }
+ status = Tps6586xI2cWrite8(hDevice, TPS6586x_R20_VCC1, data);
+ }
+
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ // Calcuate this voltage change
+ if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] < MilliVolts)
+ volChange = MilliVolts - ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail];
+ else
+ volChange = ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] - MilliVolts;
+
+ ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] = MilliVolts;
+
+ // DCD0/DCD1/DCD2
+ if ((vddRail == TPS6586xPmuSupply_DCD0) ||
+ (vddRail == TPS6586xPmuSupply_DCD1) ||
+ (vddRail == TPS6586xPmuSupply_DCD2))
+ {
+ // delay = Tstart(210) + Voltage change/Kramp
+ settleTime = T_START_TIME + volChange/K_RAMP;
+ }
+ else if ((vddRail == TPS6586xPmuSupply_LDO2) ||
+ (vddRail == TPS6586xPmuSupply_LDO4))
+ {
+ // Voltage change/Kramp
+ settleTime = volChange/K_RAMP;
+ }
+ else
+ {
+ settleTime = 0;
+ }
+#else
+ settleTime = 250;
+#endif
+
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds = settleTime;
+ else
+ NvOdmOsWaitUS(settleTime);
+ return status;
+ }
+ }
+
+ if (pSupplyInfo->supplyRegInfo.addr == TPS6586x_RFF_INVALID)
+ {
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ return NV_TRUE;
+#else
+ return NV_FALSE;
+#endif
+ }
+
+ if (pSettleMicroSeconds)
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ *pSettleMicroSeconds = 250;
+ else
+ NvOdmOsWaitUS(250);
+#else
+ *pSettleMicroSeconds = 0;
+#endif
+
+ return NV_TRUE;
+}
+
+NvBool
+Tps6586xGetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32* pMilliVolts)
+{
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pMilliVolts);
+ NV_ASSERT(vddRail < TPS6586xPmuSupply_Num);
+
+ if(! Tps6586xReadVoltageReg(hDevice, vddRail,pMilliVolts))
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+NvBool
+Tps6586xSetVoltage(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 vddRail,
+ NvU32 MilliVolts,
+ NvU32* pSettleMicroSeconds)
+{
+ NV_ASSERT(hDevice);
+ NV_ASSERT(vddRail < TPS6586xPmuSupply_Num);
+
+ if (pSettleMicroSeconds)
+ *pSettleMicroSeconds = 0;
+
+ if (tps6586xSupplyInfoTable[vddRail].cap.OdmProtected == NV_TRUE)
+ {
+ NVODMPMU_PRINTF(("The voltage is protected and can not be set.\n"));
+ return NV_TRUE;
+ }
+
+ if ((MilliVolts == ODM_VOLTAGE_OFF) ||
+ ((MilliVolts <= tps6586xSupplyInfoTable[vddRail].cap.MaxMilliVolts) &&
+ (MilliVolts >= tps6586xSupplyInfoTable[vddRail].cap.MinMilliVolts)))
+ {
+ if (! Tps6586xWriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds))
+ return NV_FALSE;
+ }
+ else
+ {
+ NVODMPMU_PRINTF(("The required voltage is not supported..\n"));
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ return NV_TRUE;
+ //return NV_FALSE;
+#else
+ return NV_FALSE;
+#endif
+ }
+
+ return NV_TRUE;
+}
+
+#if 0
+void DumpTps6586x(NvOdmPmuDeviceHandle hDevice)
+{
+ int i;
+ NvU32 data;
+ for (i=0; i<0xFF; i++)
+ {
+ data = 0;
+ Tps6586xI2cRead8(hDevice, i, &data);
+ NVODMPMU_PRINTF(("Register 0x%x = 0x%x\n", i, data));
+ }
+}
+#endif
+
+NvBool Tps6586xSetup(NvOdmPmuDeviceHandle hDevice)
+{
+ NvOdmIoModule I2cModule = NvOdmIoModule_I2c;
+ NvU32 I2cInstance = 0;
+ NvU32 I2cAddress = 0;
+ NvBool status = NV_FALSE;
+ NvU32 data = 0;
+// static TPS6586xDevice s_tps6586x = {0};
+
+ const NvOdmPeripheralConnectivity *pConnectivity =
+ NvOdmPeripheralGetGuid(PMUGUID);
+
+ NV_ASSERT(hDevice);
+
+ hPmu = (NvOdmPmuDeviceTPS *)NvOdmOsAlloc(sizeof(NvOdmPmuDeviceTPS));
+ if (hPmu == NULL)
+ {
+ NVODMPMU_PRINTF(("Error Allocating NvOdmPmuDeviceTPS. \n"));
+ return NV_FALSE;
+ }
+ NvOdmOsMemset(hPmu, 0, sizeof(NvOdmPmuDeviceTPS));
+
+ hDevice->pPrivate = hPmu;
+
+ if (pConnectivity != NULL) // PMU is in database
+ {
+ NvU32 i = 0;
+ pmuPresented = NV_TRUE;
+
+ for (i = 0; i < pConnectivity->NumAddress; i ++)
+ {
+ if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu)
+ {
+ I2cModule = NvOdmIoModule_I2c_Pmu;
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ I2cAddress = pConnectivity->AddressList[i].Address;
+ break;
+ }
+ }
+
+ NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu);
+ NV_ASSERT(I2cAddress != 0);
+
+ hPmu->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance);
+ if (!hPmu->hOdmI2C)
+ {
+ NVODMPMU_PRINTF(("[NVODM PMU]Tps6586xSetup: Error Open I2C device. \n"));
+ NVODMPMU_PRINTF(("[NVODM PMU]Please check PMU device I2C settings. \n"));
+ goto OPEN_FAILED;
+ }
+ hPmu->DeviceAddr = I2cAddress;
+ hPmu->hOdmPmuSevice = NvOdmServicesPmuOpen();
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ //if (NV_FALSE == Tps6586xWriteVoltageReg(hDevice, TPS6586xPmuSupply_LDO5, 3300, NULL))
+ if (NV_FALSE == Tps6586xWriteVoltageReg(hDevice, TPS6586xPmuSupply_LDO5, 2850, NULL))
+ NVODMPMU_PRINTF(("TPS: Fail to set the NVDDIO_NAND to 2.85V\n"));
+ else
+ NVODMPMU_PRINTF(("TPS: set the NVDDIO_NAND to 2.85V\n"));
+#endif
+ }
+ else
+ {
+ // if PMU is not presented in the database, then the platform is PMU-less.
+ NVODMPMU_PRINTF(("[NVODM PMU]Tps6586xSetup: The system did not doscover PMU fromthe data base. \n"));
+ NVODMPMU_PRINTF(("[NVODM PMU]Tps6586xSetup: If this is not intended, please check the peripheral database for PMU settings. \n"));
+
+ //uncomment below line if you really need to run pmu adaptation on pmu-less system.
+ // the system will run in pmu-less mode.
+ //pmuPresented = NV_FALSE;
+
+ goto OPEN_FAILED;
+ }
+
+ //hDevice->priv = &s_tps6586x;
+
+ /* Check Chip Device ID to verify it */
+#if 0
+ I2cInstance = 0;
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RCD_VERSIONID, &I2cInstance) || I2cInstance != 0x60)
+ {
+ NV_ASSERT(!"did not find TSP6586x");
+ goto OPEN_FAILED;
+ }
+#endif
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ /* Initialize the refcont of the rails which are ON by default */
+ hPmu->supplyRefCntTable[TPS6586xPmuSupply_SoC] = 1;
+#endif
+
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ // If your project doesn't use this GPIO, please delete them!
+ // Enable GPIO3 to HIGH
+ // Set GPIO Configure to output
+ data = 0x10;
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data))
+ return NV_FALSE;
+
+ // Set GPIO to HI, NON-Inverting
+ data = 0x04;
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data))
+ return NV_FALSE;
+#endif
+
+ //NvOdmOsMemset(&s_tps6586x, 0, sizeof(s_tps6586x));
+ //s_tps6586x.pmuPresented = NV_TRUE;
+ pmuPresented = NV_TRUE;
+
+#if NV_DEBUG
+ //DumpTps6586x(hDevice);
+#endif
+
+ if (!Tps6586xBatteryChargerSetup(hDevice))
+ return NV_FALSE;
+
+ // The interrupt assumes not supported until tps6586xInterruptHandler() is called.
+ pmuInterruptSupported = NV_FALSE;
+
+ // setup the interrupt any way.
+ if (!Tps6586xSetupInterrupt(hDevice, &pmuStatus))
+ return NV_FALSE;
+
+ //Check battery presence
+ if (!Tps6586xBatteryChargerCBCMainBatt(hDevice, &battPresence))
+ return NV_FALSE;
+
+ // Check battery Fullness
+ if (battPresence == NV_TRUE)
+ {
+ if (!Tps6586xBatteryChargerCBCBattFul(hDevice, &status))
+ return NV_FALSE;
+ pmuStatus.batFull = status;
+ }
+ else
+ {
+ pmuStatus.batFull = NV_FALSE;
+ }
+
+ return NV_TRUE;
+
+OPEN_FAILED:
+ Tps6586xRelease(hDevice);
+ return NV_FALSE;
+}
+
+void Tps6586xRelease(NvOdmPmuDeviceHandle hDevice)
+{
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ NvU32 i;
+#endif
+ if (hDevice != NULL && hPmu->hOdmI2C)
+ {
+ NvOdmServicesPmuClose(hPmu->hOdmPmuSevice);
+ hPmu->hOdmPmuSevice = NULL;
+ NvOdmI2cClose(hPmu->hOdmI2C);
+ hPmu->hOdmI2C = NULL;
+ NvOdmOsFree(hPmu);
+ hPmu = NULL;
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+
+ // Release & Close the GPIOs
+ for (i=0; i<(TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM); i++)
+ {
+ NvOdmGpioReleasePinHandle(hPmu->hGpio, hPmu->hPin[i]);
+ }
+ NvOdmGpioClose(hPmu->hGpio);
+#endif
+ }
+}
+
+NvBool
+Tps6586xGetAcLineStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuAcLineStatus *pStatus)
+{
+ NvBool acLineStatus = NV_FALSE;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pStatus);
+
+ // check if charger presents
+ if (battPresence == NV_FALSE)
+ {
+ *pStatus = NvOdmPmuAcLine_Online;
+ return NV_TRUE;
+ }
+
+ if (pmuInterruptSupported == NV_TRUE)
+ {
+ if ( pmuStatus.mChgPresent == NV_TRUE )
+ {
+ *pStatus = NvOdmPmuAcLine_Online;
+ acLineStatus = NV_TRUE;
+ }
+ else
+ {
+ *pStatus = NvOdmPmuAcLine_Offline;
+ acLineStatus = NV_FALSE;
+ }
+ }
+ else
+ {
+ // battery is present, now check if charger presents
+ if (!Tps6586xBatteryChargerMainChgPresent(hDevice, &acLineStatus))
+ {
+ NVODMPMU_PRINTF(("Error in checking main charger presence.\n"));
+ return NV_FALSE;
+ }
+
+ if (acLineStatus == NV_TRUE)
+ *pStatus = NvOdmPmuAcLine_Online;
+ else
+ *pStatus = NvOdmPmuAcLine_Offline;
+ }
+ return NV_TRUE;
+}
+
+NvBool
+Tps6586xGetBatteryStatus(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU8 *pStatus)
+{
+ NvU8 status = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pStatus);
+ NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num);
+
+ if (batteryInst == NvOdmPmuBatteryInst_Main)
+ {
+ if (battPresence == NV_TRUE)
+ {
+ NvOdmPmuAcLineStatus stat = NvOdmPmuAcLine_Offline;
+ NvU32 VBatSense = 0;
+ if (!Tps6586xGetAcLineStatus(hDevice, &stat))
+ return NV_FALSE;
+
+ if (stat == NvOdmPmuAcLine_Online)
+ {
+ if (pmuInterruptSupported == NV_TRUE)
+ {
+ if (pmuStatus.batFull == NV_FALSE)
+ status = NVODM_BATTERY_STATUS_CHARGING;
+ }
+ else
+ {
+ NvBool batFull = NV_FALSE;
+ if (!Tps6586xBatteryChargerCBCBattFul(hDevice, &batFull))
+ return NV_FALSE;
+ if (batFull == NV_FALSE)
+ status = NVODM_BATTERY_STATUS_CHARGING;
+ }
+ }
+
+ // Get VBatSense
+ if (!Tps6586xAdcVBatSenseRead(hDevice, &VBatSense))
+ return NV_FALSE;
+
+ if (VBatSense > NVODM_BATTERY_HIGH_VOLTAGE_MV) // maybe modify these parameters
+ status |= NVODM_BATTERY_STATUS_HIGH;
+ else if ((VBatSense < NVODM_BATTERY_LOW_VOLTAGE_MV)&&
+ (VBatSense > NVODM_BATTERY_CRITICAL_VOLTAGE_MV))
+ status |= NVODM_BATTERY_STATUS_LOW;
+ else if (VBatSense <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV)
+ status |= NVODM_BATTERY_STATUS_CRITICAL;
+
+ }
+ else
+ {
+ /* Battery is actually not present */
+ status = NVODM_BATTERY_STATUS_NO_BATTERY;
+ }
+
+ *pStatus = status;
+ }
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool
+Tps6586xGetBatteryData(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryData *pData)
+{
+ NvOdmPmuBatteryData batteryData;
+
+ batteryData.batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN;
+ batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pData);
+ NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num);
+
+ if (batteryInst == NvOdmPmuBatteryInst_Main)
+ {
+ NvU32 VBatSense = 0;
+ NvU32 VBatTemp = 0;
+
+ if (battPresence == NV_TRUE)
+ {
+ /* retrieve Battery voltage and temperature */
+
+ // Get VBatSense
+ if (!Tps6586xAdcVBatSenseRead(hDevice, &VBatSense))
+ {
+ NVODMPMU_PRINTF(("Error reading VBATSense. \n"));
+ return NV_FALSE;
+ }
+
+ // Get VBatTemp
+ if (!Tps6586xAdcVBatTempRead(hDevice, &VBatTemp))
+ {
+ NVODMPMU_PRINTF(("Error reading VBATSense. \n"));
+ return NV_FALSE;
+ }
+
+ batteryData.batteryVoltage = VBatSense;
+ batteryData.batteryTemperature = Tps6586xBatteryTemperature(VBatSense, VBatTemp);
+ }
+
+ *pData = batteryData;
+ }
+ else
+ {
+ *pData = batteryData;
+ }
+
+ return NV_TRUE;
+}
+
+void
+Tps6586xGetBatteryFullLifeTime(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvU32 *pLifeTime)
+{
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+}
+
+void
+Tps6586xGetBatteryChemistry(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuBatteryInstance batteryInst,
+ NvOdmPmuBatteryChemistry *pChemistry)
+{
+ *pChemistry = NvOdmPmuBatteryChemistry_LION;
+}
+
+
+NvBool
+Tps6586xSetChargingCurrent(
+ NvOdmPmuDeviceHandle hDevice,
+ NvOdmPmuChargingPath chargingPath,
+ NvU32 chargingCurrentLimitMa,
+ NvOdmUsbChargerType ChargerType)
+{
+ NvU32 data = 0;
+ NV_ASSERT(hDevice);
+
+ // if no battery, then do nothing
+ if (battPresence == NV_FALSE)
+ return NV_TRUE;
+
+ if (chargingCurrentLimitMa > DEDICATED_CHARGER_LIMIT_MA)
+ chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA;
+
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R49_CHG1, &data))
+ return NV_FALSE;
+
+ if (chargingPath == NvOdmPmuChargingPath_UsbBus)
+ {
+ switch (ChargerType)
+ {
+ case NvOdmUsbChargerType_SJ:
+ chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_SK:
+ chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_SE1:
+ chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_SE0:
+ chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_Dummy:
+ chargingCurrentLimitMa = DUMB_CHARGER_LIMIT_MA;
+ break;
+ case NvOdmUsbChargerType_UsbHost:
+ default:
+ // USB Host based charging, nothing to do. Just pass current limit to PMU.
+ break;
+ }
+ }
+
+ if (chargingCurrentLimitMa >= MAX_CHARGING_CURRENT)
+ {
+ data = data & 0xf3;
+ data = data | 0xC;
+ }
+ else if (chargingCurrentLimitMa >= L2_CHARGING_CURRENT)
+ {
+ data = data & 0xf3;
+ data = data | 0x4;
+ }
+ else if (chargingCurrentLimitMa >= L3_CHARGING_CURRENT)
+ {
+ data = data & 0xf3;
+ data = data | 0x0;
+ }
+ // 0 mA
+ else
+ {
+ chargingCurrentLimitMa = 0;
+ }
+
+ //data = (NvU8)((( chargingCurrentLimitMa << 8 ) - chargingCurrentLimitMa )
+ // / CHARGER_CONSTANT_CURRENT_SET_MA );
+
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R49_CHG1, data))
+ return NV_FALSE;
+
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R4A_CHG2, &data))
+ return NV_FALSE;
+
+ if (chargingCurrentLimitMa == 0)
+ {
+ data = data & 0xfd; // Disable charging!
+ }
+ else
+ {
+ data = data | 0x02; // Enable Charging!
+ }
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4A_CHG2, data))
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+void Tps6586xInterruptHandler( NvOdmPmuDeviceHandle hDevice)
+{
+ //TPS6586xHandle tps6586x = hDevice->priv;
+ //tps6586x->pmuStatus.batFull = NV_FALSE;
+
+ // If the interrupt handle is called, the interrupt is supported.
+ pmuInterruptSupported = NV_TRUE;
+
+ Tps6586xInterruptHandler_int(hDevice, &pmuStatus);
+}
+
+NvBool Tps6586xReadRtc( NvOdmPmuDeviceHandle hDevice, NvU32 *Count)
+{
+ *Count = 0;
+ return (Tps6586xRtcCountRead(hDevice, Count));
+}
+
+NvBool Tps6586xWriteRtc( NvOdmPmuDeviceHandle hDevice, NvU32 Count)
+{
+ return (Tps6586xRtcCountWrite(hDevice, Count));
+}
+
+NvBool Tps6586xIsRtcInitialized( NvOdmPmuDeviceHandle hDevice)
+{
+ return ((Tps6586xRtcWasStartUpFromNoPower(hDevice))? NV_FALSE: NV_TRUE);
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h
new file mode 100644
index 000000000000..0c1f4fb2b9af
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NVODM_PMU_TPS6586X_H_HH
+#define NVODM_PMU_TPS6586X_H_HH
+
+#include "nvodm_pmu.h"
+#include "nvodm_services.h"
+#include "nvodm_pmu_tps6586x_supply_info_table.h"
+#include "tps6586x_reg.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#if (NV_DEBUG)
+#define NVODMPMU_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODMPMU_PRINTF(x)
+#endif
+
+typedef struct NvOdmPmuDeviceTPSRec
+{
+ /* The handle to the I2C */
+ NvOdmServicesI2cHandle hOdmI2C;
+
+ /* The odm pmu service handle */
+ NvOdmServicesPmuHandle hOdmPmuSevice;
+ /* the PMU I2C device Address */
+ NvU32 DeviceAddr;
+
+ /* Device's private data */
+ void *priv;
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ /* Gpio Handles (for external supplies) */
+ NvOdmServicesGpioHandle hGpio;
+ NvOdmGpioPinHandle hPin[TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM];
+#else
+ /* The current voltage */
+ NvU32 curVoltageTable[VRAILCOUNT];
+#endif
+
+ /* The ref cnt table of the power supplies */
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ NvU32 supplyRefCntTable[TPS6586xPmuSupply_Num];
+#else
+ NvU32 supplyRefCntTable[VRAILCOUNT];
+#endif
+
+} NvOdmPmuDeviceTPS;
+
+void Tps6586xGetCapabilities( NvU32 vddRail, NvOdmPmuVddRailCapabilities* pCapabilities);
+NvBool Tps6586xGetVoltage( NvOdmPmuDeviceHandle hDevice, NvU32 vddRail, NvU32* pMilliVolts);
+NvBool Tps6586xSetVoltage( NvOdmPmuDeviceHandle hDevice, NvU32 vddRail, NvU32 MilliVolts, NvU32* pSettleMicroSeconds);
+NvBool Tps6586xSetup(NvOdmPmuDeviceHandle hDevice);
+void Tps6586xRelease(NvOdmPmuDeviceHandle hDevice);
+NvBool Tps6586xGetAcLineStatus( NvOdmPmuDeviceHandle hDevice, NvOdmPmuAcLineStatus *pStatus);
+NvBool Tps6586xGetBatteryStatus( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvU8 *pStatus);
+NvBool Tps6586xGetBatteryData( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvOdmPmuBatteryData *pData);
+void Tps6586xGetBatteryFullLifeTime( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvU32 *pLifeTime);
+void Tps6586xGetBatteryChemistry( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvOdmPmuBatteryChemistry *pChemistry);
+NvBool Tps6586xSetChargingCurrent( NvOdmPmuDeviceHandle hDevice, NvOdmPmuChargingPath chargingPath, NvU32 chargingCurrentLimitMa, NvOdmUsbChargerType ChargerType);
+void Tps6586xInterruptHandler( NvOdmPmuDeviceHandle hDevice);
+NvBool Tps6586xReadRtc( NvOdmPmuDeviceHandle hDevice, NvU32 *Count);
+NvBool Tps6586xWriteRtc( NvOdmPmuDeviceHandle hDevice, NvU32 Count);
+NvBool Tps6586xIsRtcInitialized( NvOdmPmuDeviceHandle hDevice);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* NVODM_PMU_TPS6586X_H_HH */
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c
new file mode 100644
index 000000000000..7f2fcb0dd54c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu_tps6586x_adc.h"
+#include "nvodm_pmu_tps6586x_i2c.h"
+#include "tps6586x_reg.h"
+#include "nvodm_pmu_tps6586x_supply_info_table.h"
+
+#define ADC_CONVERSION_DELAY_USEC 70
+#define ADC_CONVERSION_TIMEOUT_USEC 500
+#define ADC_CONVERSION_VOLTAGE_RANGE 2000
+#define ADC_CONVERSION_DIVIDOR 3
+#define ADC_CONVERSION_PRECISION 10
+#define ADC_CONVERSION_SUB_OFFSET 2250
+#define ADC_FULL_SCALE_READING_MV_BAT 4622
+#define ADC_FULL_SCALE_READING_MV_TS 2600
+#define ADC_CONVERSION_PREWAIT_MS 26
+
+/* read voltage from ADC CH10(battery) */
+NvBool
+Tps6586xAdcVBatSenseRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt)
+{
+ NvU32 timeout = 0;
+ NvU32 dataS1 = 0;
+ NvU32 dataH = 0;
+ NvU32 dataL = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(volt);
+
+ *volt = 0; // Default is 0mV.
+ // Configuring the adc conversion cycle
+ // ADC0_WAIT register(0x62)
+ // Reset all ADC engines and return them to the idle state; ADC0_RESET: 1
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x80))
+ return NV_FALSE;
+
+ // ADC0_SET register(0x61)
+ // ADC0_EN: 0(Don't start conversion); Number of Readings: 16; CHANNEL: CH10(battery)
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x19))
+ return NV_FALSE;
+
+ // ADC0_WAIT register(0x62)
+ // REF_EN: 0; AUTO_REF: 1; Wait time: 0.062ms
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x21))
+ return NV_FALSE;
+
+ // Start conversion!!
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x99))
+ return NV_FALSE;
+
+ // Wait for conversion
+ //NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+ NvOdmOsSleepMS(ADC_CONVERSION_PREWAIT_MS);
+
+ // Make sure the conversion is completed - check for ADC error.
+ while (1)
+ {
+ // Read ADC status register
+ if(! Tps6586xI2cRead8(hDevice, TPS6586x_R9A_ADC0_INT, &dataS1))
+ return NV_FALSE;
+
+ // Conversion is done!
+ if (dataS1 & 0x80)
+ break;
+
+ // ADC error!
+ if (dataS1 & 0x40)
+ {
+ NVODMPMU_PRINTF(("ADC conversion error.\n"));
+ return NV_FALSE;
+ }
+
+ NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+ timeout += ADC_CONVERSION_DELAY_USEC;
+ if (timeout >= ADC_CONVERSION_TIMEOUT_USEC)
+ return NV_FALSE;
+ }
+
+ // Read the ADC conversion Average (SUM).
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R94_ADC0_SUM2, &dataH))
+ return NV_FALSE;
+
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R95_ADC0_SUM1, &dataL))
+ return NV_FALSE;
+
+ // Get a result value with mV.
+ *volt = (((dataH << 8) | dataL) * ADC_FULL_SCALE_READING_MV_BAT) / 1023 / 16;
+
+ return NV_TRUE;
+}
+
+/* read voltage from ADC CH5(temperature) */
+NvBool
+Tps6586xAdcVBatTempRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt)
+{
+ NvU32 timeout = 0;
+ NvU32 dataS1 = 0;
+ NvU32 dataH = 0;
+ NvU32 dataL = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(volt);
+
+ *volt = 0; // Default is 0'C.
+
+ // Configuring the adc conversion cycle
+ // ADC0_WAIT register(0x62)
+ // Reset all ADC engines and return them to the idle state; ADC0_RESET: 1
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x80))
+ return NV_FALSE;
+ // ADC0_SET register(0x61)
+ // ADC0_EN: 0(Don't start conversion); Number of Readings: 16; CHANNEL: CH5(temperature)
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x14))
+ return NV_FALSE;
+
+ // ADC0_WAIT register(0x62)
+ // REF_EN: 0; AUTO_REF: 1; Wait time: 0.062ms
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x21))
+ return NV_FALSE;
+
+ // Start conversion!!
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x94))
+ return NV_FALSE;
+
+ // Wait for conversion
+ // NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+ NvOdmOsSleepMS(ADC_CONVERSION_PREWAIT_MS);
+
+ // make sure the conversion is completed, or adc error.
+ while (1)
+ {
+ // Read ADC status register
+ if(! Tps6586xI2cRead8(hDevice, TPS6586x_R9A_ADC0_INT, &dataS1))
+ return NV_FALSE;
+
+ // Conversion is done!
+ if (dataS1 & 0x80)
+ break;
+
+ // ADC error!
+ if (dataS1 & 0x40)
+ {
+ NVODMPMU_PRINTF(("ADC conversion error.\n"));
+ return NV_FALSE;
+ }
+
+ NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC);
+ timeout += ADC_CONVERSION_DELAY_USEC;
+ if (timeout >= ADC_CONVERSION_TIMEOUT_USEC)
+ return NV_FALSE;
+ }
+
+ // Read the ADC conversion Average (SUM).
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R94_ADC0_SUM2, &dataH))
+ return NV_FALSE;
+
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_R95_ADC0_SUM1, &dataL))
+ return NV_FALSE;
+
+ // Get a result value with mV.
+ *volt = (((dataH << 8) | dataL) * ADC_FULL_SCALE_READING_MV_TS) / 1023 / 16;
+
+ return NV_TRUE;
+}
+
+/* Calculate the battery temperature */
+NvU32 Tps6586xBatteryTemperature(NvU32 VBatSense, NvU32 VBatTemp)
+{
+ return 0;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h
new file mode 100644
index 000000000000..803a62856a9b
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_TPS6586X_ADC_HEADER
+#define INCLUDED_TPS6586X_ADC_HEADER
+
+/* the ADC is used for battery voltage conversion */
+#include "nvodm_pmu_tps6586x.h"
+
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* read voltage from adc */
+NvBool
+Tps6586xAdcVBatSenseRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt);
+
+/* read bat temperature voltage from ADC */
+NvBool
+Tps6586xAdcVBatTempRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 *volt);
+
+/* Calculate the battery temperature */
+NvU32
+Tps6586xBatteryTemperature(
+ NvU32 VBatSense,
+ NvU32 VBatTemp);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_TPS6586X_ADC_HEADER
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c
new file mode 100644
index 000000000000..8a4573922adf
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu_tps6586x_i2c.h"
+#include "nvodm_pmu_tps6586x_batterycharger.h"
+
+NvBool Tps6586xBatteryChargerSetup(NvOdmPmuDeviceHandle hDevice)
+{
+ NvU32 data = 0;
+ // Configure CHARGER RAM registers
+ // CHG1: Charge safety timer value is 4 Hrs; Charge current scaling facotr: 1.0;
+ data = 0x0c;
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R49_CHG1, data))
+ return NV_FALSE;
+
+ // CHG2: CHARGE SAFETY TIMER: ON; CHARGE VOLTAGE: 4.2V; CHARGER: ON;
+ data = 0x1a;
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4A_CHG2, data))
+ return NV_FALSE;
+
+ // CHG3:
+ data = 0x0;
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4B_CHG3, data))
+ return NV_FALSE;
+
+ // RAM Control BITS: CHARGE VOLTAGE RANGE: 3.95 - 4.2; USB Input current limit: 500mA;
+ // Auto mode enabled; AC input current limit: 2A
+ data = 0x05;
+ if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4C_PPATH2, data))
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+/* check CBC main batt presence */
+NvBool
+Tps6586xBatteryChargerCBCMainBatt(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU32 data = 0;
+
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB9_STAT1, &data))
+ return NV_FALSE;
+
+ // bit 0 show if battery exists or not
+ data = data & 0x01;
+
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+
+ return NV_TRUE;
+}
+
+/* check batt_ful status */
+NvBool
+Tps6586xBatteryChargerCBCBattFul(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU32 data = 0;
+
+ if(! Tps6586xI2cRead8(hDevice, TPS6586x_RBA_STAT2, &data))
+ return NV_FALSE;
+
+ data = data & 0x2;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+
+ return NV_TRUE;
+}
+
+/* check main charger status */
+NvBool
+Tps6586xBatteryChargerMainChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status)
+{
+ NvU32 data = 0;
+
+ if(! Tps6586xI2cRead8(hDevice, TPS6586x_RBB_STAT3, &data))
+ return NV_FALSE;
+
+ data = data & 0xc;
+ *status = (data == 0 ? NV_FALSE : NV_TRUE );
+
+ return NV_TRUE;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h
new file mode 100644
index 000000000000..83b538792334
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_TPS6586X_BATTERYCHARGER_HEADER
+#define INCLUDED_TPS6586X_BATTERYCHARGER_HEADER
+
+
+
+#include "nvodm_pmu_tps6586x.h"
+
+/* the battery charger functions */
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* Initliase all registers that related to battery charger */
+NvBool
+Tps6586xBatteryChargerSetup(NvOdmPmuDeviceHandle hDevice);
+
+/* check CBC main batt presence */
+NvBool
+Tps6586xBatteryChargerCBCMainBatt(NvOdmPmuDeviceHandle hDevice, NvBool *status);
+
+/* check batt_ful status */
+NvBool
+Tps6586xBatteryChargerCBCBattFul(NvOdmPmuDeviceHandle hDevice, NvBool *status);
+
+/* check main charger status */
+NvBool
+Tps6586xBatteryChargerMainChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_TPS6586X_BATTERYCHARGER_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c
new file mode 100644
index 000000000000..94e806101b10
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_pmu_tps6586x_i2c.h"
+#include "nvodm_pmu_tps6586x.h"
+#include "pmu_hal.h"
+
+NvBool
+Tps6586xI2cWrite8(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 Data)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo = {0};
+
+ WriteBuffer[0] = Addr & 0xFF; // PMU offset
+ WriteBuffer[1] = Data & 0xFF; // written data
+
+ TransactionInfo.Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo, 1,
+ TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool
+Tps6586xI2cRead8(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 *Data)
+{
+ NvU8 ReadBuffer=0;
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ // Write the PMU offset
+ ReadBuffer = Addr & 0xFF;
+
+ TransactionInfo[0].Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr;
+ TransactionInfo[0].Buf = &ReadBuffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+ TransactionInfo[1].Address = (((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ // Read data from PMU at the specified offset
+ status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo[0], 2,
+ TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = ReadBuffer;
+ return NV_TRUE;
+}
+
+NvBool Tps6586xI2cWrite32(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 Data)
+{
+ NvU8 WriteBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo = {0};
+
+ WriteBuffer[0] = (NvU8)(Addr & 0xFF);
+ WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF);
+ WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF);
+ WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF);
+ WriteBuffer[4] = (NvU8)(Data & 0xFF);
+
+ TransactionInfo.Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 5;
+
+ status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo, 1,
+ TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status == NvOdmI2cStatus_Success)
+ {
+ return NV_TRUE;
+ }
+ else
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+}
+
+NvBool Tps6586xI2cRead32(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 *Data)
+{
+ NvU8 ReadBuffer[5];
+ NvOdmI2cStatus status = NvOdmI2cStatus_Success;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ // Write the PMU offset
+ ReadBuffer[0] = Addr & 0xFF;
+
+ TransactionInfo[0].Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr;
+ TransactionInfo[0].Buf = &ReadBuffer[0];
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+
+ TransactionInfo[1].Address = (((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr | 0x1);
+ TransactionInfo[1].Buf = &ReadBuffer[0];
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 4;
+
+ // Read data from PMU at the specified offset
+ status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo[0], 2,
+ TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE);
+ if (status != NvOdmI2cStatus_Success)
+ {
+ switch (status)
+ {
+ case NvOdmI2cStatus_Timeout:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n"));
+ break;
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n"));
+ break;
+ }
+ return NV_FALSE;
+ }
+
+ *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) |
+ (ReadBuffer[2] << 8) | ReadBuffer[3];
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h
new file mode 100644
index 000000000000..df17ff6c2cf0
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_PMU_TPS6856X_I2C_H
+#define INCLUDED_NVODM_PMU_TPS6856X_I2C_H
+
+#include "nvodm_pmu_tps6586x.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// Constant definition
+#define TPS6586x_I2C_SPEED_KHZ 100
+
+// Function declaration
+NvBool Tps6586xI2cWrite8(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 Data);
+
+NvBool Tps6586xI2cRead8(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 *Data);
+
+NvBool Tps6586xI2cWrite32(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 Data);
+
+NvBool Tps6586xI2cRead32(
+ NvOdmPmuDeviceHandle hPmu,
+ NvU32 Addr,
+ NvU32 *Data);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_PMU_TPS6856X_I2C_H
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c
new file mode 100644
index 000000000000..b3ac0b954a4e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include "nvodm_pmu_tps6586x_interrupt.h"
+#include "nvodm_pmu_tps6586x_i2c.h"
+#include "nvodm_pmu_tps6586x_supply_info_table.h"
+#include "nvodm_services.h"
+#include "nvodm_pmu_tps6586x_batterycharger.h"
+
+#define TPS6586X_INT_BATT_INST 0x01
+#define TPS6586X_INT_PACK_COLD_DET 0x02
+#define TPS6586X_INT_PACK_HOT_DET 0x04
+
+#define TPS6586X_INT_USB_DETECTION 0x04
+#define TPS6586X_INT_AC_DETECTION 0x08
+#define TPS6586X_INT_LOWSYS_DETECTION 0x40
+
+NvBool Tps6586xSetupInterrupt(NvOdmPmuDeviceHandle hDevice,
+ TPS6586xStatus *pmuStatus)
+{
+ NvBool status = NV_FALSE;
+ NvU32 data = 0;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pmuStatus);
+
+ /* Init Pmu Status */
+ pmuStatus->lowBatt = NV_FALSE;
+ pmuStatus->highTemp = NV_FALSE;
+
+ if (!Tps6586xBatteryChargerMainChgPresent(hDevice,&status))
+ return NV_FALSE;
+ pmuStatus->mChgPresent = status;
+
+ /* Set up Interrupt Mask */
+ /* Mask1 */
+ data = 0xFF;
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB0_INT_MASK1, data ))
+ return NV_FALSE;
+
+ /* Mask2 */
+ data = 0xFF;
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB1_INT_MASK2, data ))
+ return NV_FALSE;
+
+ /* Mask3: Battery detction, etc */
+ data = 0;
+ data = (NvU32)~(TPS6586X_INT_BATT_INST|TPS6586X_INT_PACK_COLD_DET|TPS6586X_INT_PACK_HOT_DET);
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB2_INT_MASK3, data ))
+ return NV_FALSE;
+
+ /* Mask4 */
+ data = 0xFF;
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB3_INT_MASK4, data ))
+ return NV_FALSE;
+
+ /* Mask5: USB Detection; AC Detection; Low System detection; */
+ data = 0;
+ data = (NvU32) ~(TPS6586X_INT_USB_DETECTION|TPS6586X_INT_AC_DETECTION|TPS6586X_INT_LOWSYS_DETECTION);
+ if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB4_INT_MASK5, data ))
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+void Tps6586xInterruptHandler_int(NvOdmPmuDeviceHandle hDevice,
+ TPS6586xStatus *pmuStatus)
+{
+ NvU32 data = 0;
+
+ /* INT_ACK1 */
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB5_INT_ACK1, &data))
+ {
+ return;
+ }
+ pmuStatus->powerGood = (data & 0xFF);
+
+
+ /* INT_ACK2 */
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB6_INT_ACK2, &data))
+ {
+ return;
+ }
+ pmuStatus->powerGood |= ((data & 0xFF)<<8);
+
+ /* INT_ACK3 */
+ /* LOW SYS */
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB7_INT_ACK3, &data))
+ {
+ return;
+ }
+ if (data != 0)
+ {
+ if (data&0x40)
+ {
+ pmuStatus->highTemp = NV_TRUE;
+ }
+ if (data&0xc0)
+ {
+ pmuStatus->mChgPresent = NV_TRUE;
+#if !defined(CONFIG_TEGRA_ODM_HARMONY)
+ NvOdmEnableOtgCircuitry(NV_TRUE);
+#endif
+ }
+ }
+
+ /* INT_ACK4 */
+ /* CHG TEMP */
+ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB8_INT_ACK4, &data))
+ {
+ return;
+ }
+ if (data != 0)
+ {
+ if (data&0x02)
+ {
+ pmuStatus->lowBatt = NV_TRUE;
+ }
+ }
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h
new file mode 100644
index 000000000000..8e9ff0464135
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_TPS6586X_INTERRUPT_HEADER
+#define INCLUDED_TPS6586X_INTERRUPT_HEADER
+
+#include "nvodm_pmu_tps6586x.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct TPS6586xStatusRef
+{
+ /* Low Battery voltage detected by BVM */
+ NvBool lowBatt;
+
+ /* PMU high temperature */
+ NvBool highTemp;
+
+ /* Main charger Presents */
+ NvBool mChgPresent;
+
+ /* battery Full */
+ NvBool batFull;
+
+ /* Porwer In type*/
+ NvU32 powerType; /* Bit meanings:
+ 0: AC_DET,
+ 1: USB_DET,
+ 2: BAT_DET */
+ NvU32 powerGood; /* Bit meanings:
+ 0-7: LDO0 to LDO7
+ 10-11: LDO8 and LDO9,
+ 12-15: SMO0 to SM11 */
+}TPS6586xStatus;
+
+#if 0
+typedef struct {
+ NvBool pmuInterruptSupported;
+ NvBool pmuPresented;
+ NvBool battPresence;
+ TPS6586xStatus pmuStatus;
+} TPS6586xDevice, *TPS6586xHandle;
+#endif
+
+NvBool
+Tps6586xSetupInterrupt(
+ NvOdmPmuDeviceHandle hDevice,
+ TPS6586xStatus *pmuStatus);
+
+
+
+void
+Tps6586xInterruptHandler_int(
+ NvOdmPmuDeviceHandle hDevice,
+ TPS6586xStatus *pmuStatus);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_TPS6586X_INTERRUPT_HEADER
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c
new file mode 100644
index 000000000000..889cf2bbc6ff
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <linux/time.h>
+#include "nvodm_pmu_tps6586x_rtc.h"
+#include "nvodm_pmu_tps6586x_i2c.h"
+#include "tps6586x_reg.h"
+
+// macro OFFSET_BASE_YEAR if 1, uses epoch as reference year instead of 1970
+// This is because RTC in PMU TPS6586x can store duration of 34 years,
+// else we cannot retain date beyond 2004
+#define OFFSET_BASE_YEAR 1
+#if OFFSET_BASE_YEAR
+static unsigned long epoch = 2009;
+static unsigned long epoch_sec = 0;
+#endif
+
+static NvBool bRtcNotInitialized = NV_TRUE;
+
+/* Read RTC count register */
+NvBool
+Tps6586xRtcCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count)
+{
+ NvU32 ReadBuffer[2];
+
+ // 1) The I2C address pointer must not be left pointing in the range 0xC6 to 0xCA
+ // 2) The maximum time for the address pointer to be in this range is 1ms
+ // 3) Always read RTC_ALARM2 in the following order to prevent the address pointer
+ // from stopping at 0xC6: RTC_ALARM2_LO, then RTC_ALARM2_HI
+
+ if (Tps6586xRtcWasStartUpFromNoPower(hDevice) && bRtcNotInitialized)
+ {
+ Tps6586xRtcCountWrite(hDevice, 0);
+ *Count = 0;
+ }
+ else
+ {
+ // The unit of the RTC count is second!!! 1024 tick = 1s.
+ // Read all 40 bit and right move 10 = Read the hightest 32bit and right move 2
+ Tps6586xI2cRead32(hDevice, TPS6586x_RC6_RTC_COUNT4, &ReadBuffer[0]);
+
+ Tps6586xI2cRead8(hDevice, TPS6586x_RCA_RTC_COUNT0, &ReadBuffer[1]);
+
+ Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer[1]);
+
+ // return second
+ *Count = ReadBuffer[0]>>2;
+ }
+#if OFFSET_BASE_YEAR
+ // calculate epoch_sec once
+ if (!epoch_sec)
+ epoch_sec = mktime(epoch,1,1,0,0,0);
+ *Count += epoch_sec;
+#endif
+
+ return NV_TRUE;
+}
+
+/* Write RTC count register */
+
+NvBool
+Tps6586xRtcCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ NvU32 ReadBuffer = 0;
+#if OFFSET_BASE_YEAR
+ // calculate epoch_sec once
+ if (!epoch_sec)
+ epoch_sec = mktime(epoch,1,1,0,0,0);
+ if (Count < (NvU32)epoch_sec)
+ {
+ // prevent setting date earlier than 'epoch'
+ pr_warning("\n Date being set cannot be earlier than least "
+ "year=%d. Setting as least year. ", (int)epoch);
+ // base year seconds count is 0
+ Count = 0;
+ }
+ else
+ Count -= (NvU32)epoch_sec;
+#endif
+
+ // Switch to 32KHz crystal oscillator
+ // POR_SRC_SEL=1 and OSC_SRC_SEL=1
+ Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer);
+ ReadBuffer = ReadBuffer | 0xC0;
+ Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer);
+
+ // To enable incrementing of the RTC_COUNT[39:0] from an initial value set by the host,
+ // the RTC_ENABLE bit should be written to 1 only after the RTC_OUT voltage reaches
+ // the operating range
+
+ // Clear RTC_ENABLE before writing RTC_COUNT
+ Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer);
+ ReadBuffer = ReadBuffer & 0xDF;
+ Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer);
+
+ Tps6586xI2cWrite32(hDevice, TPS6586x_RC6_RTC_COUNT4, (Count<<2));
+ Tps6586xI2cWrite8(hDevice, TPS6586x_RCA_RTC_COUNT0, 0);
+
+ // Set RTC_ENABLE after writing RTC_COUNT
+ Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer);
+ ReadBuffer = ReadBuffer | 0x20;
+ Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer);
+
+ if (bRtcNotInitialized)
+ bRtcNotInitialized = NV_FALSE;
+
+ return NV_TRUE;
+}
+
+/* Read RTC alarm count register */
+
+NvBool
+Tps6586xRtcAlarmCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count)
+{
+ return NV_FALSE;
+}
+
+/* Write RTC alarm count register */
+
+NvBool
+Tps6586xRtcAlarmCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count)
+{
+ return NV_FALSE;
+}
+
+/* Reads RTC alarm interrupt mask status */
+
+NvBool
+Tps6586xRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice)
+{
+ return NV_FALSE;
+}
+
+/* Enables / Disables the RTC alarm interrupt */
+
+NvBool
+Tps6586xRtcAlarmIntEnable(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool Enable)
+{
+ return NV_FALSE;
+}
+
+/* Checks if boot was from nopower / powered state */
+
+NvBool
+Tps6586xRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice)
+{
+ NvU32 Data = 0;
+
+ if ((Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &Data)) == NV_TRUE)
+ {
+ return ((Data & 0x20)? NV_FALSE : NV_TRUE);
+ }
+ return NV_FALSE;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h
new file mode 100644
index 000000000000..8137c95e1702
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_TPS6586X_RTC_HEADER
+#define INCLUDED_TPS6586X_RTC_HEADER
+
+#include "nvodm_pmu_tps6586x.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/* Read RTC count register */
+
+NvBool
+Tps6586xRtcCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count);
+
+/* Read RTC alarm count register */
+
+NvBool
+Tps6586xRtcAlarmCountRead(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32* Count);
+
+/* Write RTC count register */
+
+NvBool
+Tps6586xRtcCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count);
+
+/* Write RTC alarm count register */
+
+NvBool
+Tps6586xRtcAlarmCountWrite(
+ NvOdmPmuDeviceHandle hDevice,
+ NvU32 Count);
+
+/* Reads RTC alarm interrupt mask status */
+
+NvBool
+Tps6586xRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice);
+
+/* Enables / Disables the RTC alarm interrupt */
+
+NvBool
+Tps6586xRtcAlarmIntEnable(
+ NvOdmPmuDeviceHandle hDevice,
+ NvBool Enable);
+
+/* Checks if boot was from nopower / powered state */
+
+NvBool
+Tps6586xRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_TPS6586X_RTC_HEADER
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h
new file mode 100644
index 000000000000..fe34d3a02ca1
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TPS6586x_SUPPLY_INFO_TABLE_H_
+#define TPS6586x_SUPPLY_INFO_TABLE_H_
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+#define PMUGUID NV_ODM_GUID('t','p','s','6','5','8','6','x')
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+
+/// The total number of external supplies (which use both AP and PMU GPIOs)
+#define TPS6586x_EXTERNAL_SUPPLY_NUM \
+ (NvU32)(TPS6586xPmuSupply_Num - Ext_TPS62290PmuSupply_BUCK)
+
+/// Macro for converting a vddRail to AP GPIO pin index.
+#define NVODM_EXT_AP_GPIO_RAIL(x) ((x) - Ext_TPS2051BPmuSupply_VDDIO_VID)
+
+/// The total number of external supplies which use AP GPIO pins for enable
+#define TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM \
+ (NvU32)NVODM_EXT_AP_GPIO_RAIL(TPS6586xPmuSupply_Num)
+
+#else
+
+/* FIXME: modify this table according to your schematics */
+#define V_CORE TPS6586xPmuSupply_DCD0
+#define V_1V8 TPS6586xPmuSupply_DCD1
+#define LCD_2V8 TPS6586xPmuSupply_LDO0
+#define V_1V2 TPS6586xPmuSupply_LDO1
+#define V_RTC TPS6586xPmuSupply_LDO2
+#define V_CAM_1V8 TPS6586xPmuSupply_LDO3
+#define V_CODEC_1V8 TPS6586xPmuSupply_LDO4
+#define V_CAM_2V8 TPS6586xPmuSupply_LDO5
+#define V_3V3 TPS6586xPmuSupply_LDO6
+#define V_SDIO TPS6586xPmuSupply_LDO7
+#define V_2V8 TPS6586xPmuSupply_LDO8
+#define V_2V5 TPS6586xPmuSupply_LDO9
+#define V_25V TPS6586xPmuSupply_WHITE_LED
+#define V_CHARGE TPS6586xPmuSupply_DCD2
+#define V_MODEM V_1V8 /* Alias for V_1V8 */
+#define V_GND TPS6586xPmuSupply_Invalid
+#define V_INVALID TPS6586xPmuSupply_Invalid
+#define VRAILCOUNT TPS6586xPmuSupply_Num
+#endif
+
+typedef enum
+{
+ TPS6586xPmuSupply_Invalid = 0x0,
+
+ //DCD0
+ TPS6586xPmuSupply_DCD0,
+
+ //DCD1
+ TPS6586xPmuSupply_DCD1,
+
+ //DCD2
+ TPS6586xPmuSupply_DCD2,
+
+
+ //LDO0
+ TPS6586xPmuSupply_LDO0,
+
+ //LDO1
+ TPS6586xPmuSupply_LDO1,
+
+ //LDO2
+ TPS6586xPmuSupply_LDO2,
+
+ //LDO3
+ TPS6586xPmuSupply_LDO3,
+
+ //LDO4
+ TPS6586xPmuSupply_LDO4,
+
+ //LDO5
+ TPS6586xPmuSupply_LDO5,
+
+ //LDO6
+ TPS6586xPmuSupply_LDO6,
+
+ //LDO7
+ TPS6586xPmuSupply_LDO7,
+
+ //LDO8
+ TPS6586xPmuSupply_LDO8,
+
+ //LDO9
+ TPS6586xPmuSupply_LDO9,
+
+ //RTC_OUT
+ TPS6586xPmuSupply_RTC_OUT,
+
+ //RED1
+ TPS6586xPmuSupply_RED1,
+
+ //GREEN1
+ TPS6586xPmuSupply_GREEN1,
+
+ //BLUE1
+ TPS6586xPmuSupply_BLUE1,
+
+ //RED2
+ TPS6586xPmuSupply_RED2,
+
+ //GREEN2
+ TPS6586xPmuSupply_GREEN2,
+
+ //BLUE2
+ TPS6586xPmuSupply_BLUE2,
+
+ //LED_PWM
+ TPS6586xPmuSupply_LED_PWM,
+
+ //PWM
+ TPS6586xPmuSupply_PWM,
+
+ //White LED(SW3)
+ TPS6586xPmuSupply_WHITE_LED,
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+ //SOC
+ TPS6586xPmuSupply_SoC,
+
+ /*--- Secondary/External PMU Rails ---*/
+
+ // PMU GPIO-3: VDD_1V05
+ Ext_TPS62290PmuSupply_BUCK,
+
+ // PMU GPIO-2: VDD_1V2
+ Ext_TPS72012PmuSupply_LDO,
+
+ // PMU GPIO-1: VDD_1V5
+ Ext_TPS74201PmuSupply_LDO,
+
+ // AP GPIO(T,2): VDDIO_HDMI, VDDIO_VGA (5V @ 500ma)
+ Ext_TPS2051BPmuSupply_VDDIO_VID,
+
+ // AP GPIO(T,3): VDDIO_SD
+ Ext_SWITCHPmuSupply_VDDIO_SD,
+
+ // AP GPIO(I,6): VDDIO_SDMMC
+ Ext_SWITCHPmuSupply_VDDIO_SDMMC,
+
+ // AP GPIO(W,0): VDD_BL
+ // FIXME: This is already supplied by nvodm_query_gpio in the display GPIO settings.
+ Ext_SWITCHPmuSupply_VDD_BL,
+
+ // AP GPIO(C,6): VDD_PNL
+ // FIXME: This is already supplied by nvodm_query_gpio in the display GPIO settings.
+ Ext_SWITCHPmuSupply_VDD_PNL,
+#endif
+
+ TPS6586xPmuSupply_Num,
+ TPS6586xPmuSupply_Force32 = 0x7FFFFFFF
+} TPS6586xPmuSupply;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* TPS6586x_SUPPLY_INFO_TABLE_H_ */
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h
new file mode 100644
index 000000000000..c22cc43854ae
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TPS6586X_REG_HEADER
+#define TPS6586X_REG_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+
+/* TPS6586x registers */
+
+/* Supply Control and Voltage Settings */
+#define TPS6586x_R10_SUPPLYENA 0x10
+#define TPS6586x_R11_SUPPLYENB 0x11
+#define TPS6586x_R12_SUPPLYENC 0x12
+#define TPS6586x_R13_SUPPLYEND 0x13
+#define TPS6586x_R14_SUPPLYENE 0x14
+#define TPS6586x_R20_VCC1 0x20
+#define TPS6586x_R21_VCC2 0x21
+#define TPS6586x_R23_SM1V1 0x23
+#define TPS6586x_R24_SM1V2 0x24
+#define TPS6586x_R25_SM1SL 0x25
+#define TPS6586x_R26_SM0V1 0x26
+#define TPS6586x_R27_SM0V2 0x27
+#define TPS6586x_R28_SM0SL 0x28
+#define TPS6586x_R29_LDO2AV1 0x29
+#define TPS6586x_R2A_LDO2AV2 0x2A
+#define TPS6586x_R2F_LDO2BV1 0x2F
+#define TPS6586x_R30_LDO2BV2 0x30
+#define TPS6586x_R32_LDO4V1 0x32
+#define TPS6586x_R33_LDO4V2 0x33
+
+/* Converter Settings */
+#define TPS6586x_R41_SUPPLYV1 0x41
+#define TPS6586x_R42_SUPPLYV2 0x42
+#define TPS6586x_R43_SUPPLYV3 0x43
+#define TPS6586x_R44_SUPPLYV4 0x44
+#define TPS6586x_R45_SUPPLYV5 0x45
+#define TPS6586x_R46_SUPPLYV6 0x46
+#define TPS6586x_R47_SMODE1 0x47
+#define TPS6586x_R48_SMODE2 0x48
+
+/* Charger Setup */
+#define TPS6586x_R49_CHG1 0x49
+#define TPS6586x_R4A_CHG2 0x4A
+#define TPS6586x_R4B_CHG3 0x4B
+
+/* Power Path Setup */
+#define TPS6586x_R4C_PPATH2 0x4C
+
+/* Sequencing */
+#define TPS6586x_R4D_PGFLTMSK1 0x4D
+#define TPS6586x_R4E_PGFLTMSK2 0x4E
+
+/* Peripheral Control */
+#define TPS6586x_R50_RGB1FLASH 0x50
+#define TPS6586x_R51_RGB1RED 0x51
+#define TPS6586x_R52_RGB1GREEN 0x52
+#define TPS6586x_R53_RGB1BLUE 0x53
+#define TPS6586x_R54_RGB2RED 0x54
+#define TPS6586x_R55_RGB2GREEN 0x55
+#define TPS6586x_R56_RGB2BLUE 0x56
+#define TPS6586x_R57_SM3_SET0 0x57
+#define TPS6586x_R58_SM3_SET1 0x58
+#define TPS6586x_R59_LED_PWM 0x59
+#define TPS6586x_R5A_DIG_PWM 0x5A
+#define TPS6586x_R5B_PWM 0x5B
+#define TPS6586x_R5C_DIG_PWM1 0x5C
+#define TPS6586x_R5D_GPIOSET1 0x5D
+#define TPS6586x_R5E_GPIOSET2 0x5E
+
+#if defined(CONFIG_TEGRA_ODM_HARMONY)
+/*-- GPIO Register Bit Shifts/Masks --*/
+// GPIO1
+#define TPS6586x_R5D_GPIOSET1_GPIO1_MODE_SHIFT 0x0
+#define TPS6586x_R5D_GPIOSET1_GPIO1_MODE_MASK 0x3
+#define TPS6586x_R5E_GPIOSET2_GPIO1_OUT_SHIFT 0x0
+#define TPS6586x_R5E_GPIOSET2_GPIO1_OUT_MASK 0x1
+#define TPS6586x_R5E_GPIOSET2_GPIO1_INV_SHIFT 0x4
+#define TPS6586x_R5E_GPIOSET2_GPIO1_INV_MASK 0x1
+
+// GPIO2
+#define TPS6586x_R5D_GPIOSET1_GPIO2_MODE_SHIFT 0x2
+#define TPS6586x_R5D_GPIOSET1_GPIO2_MODE_MASK 0x3
+#define TPS6586x_R5E_GPIOSET2_GPIO2_OUT_SHIFT 0x1
+#define TPS6586x_R5E_GPIOSET2_GPIO2_OUT_MASK 0x1
+#define TPS6586x_R5E_GPIOSET2_GPIO2_INV_SHIFT 0x5
+#define TPS6586x_R5E_GPIOSET2_GPIO2_INV_MASK 0x1
+
+// GPIO3
+#define TPS6586x_R5D_GPIOSET1_GPIO3_MODE_SHIFT 0x4
+#define TPS6586x_R5D_GPIOSET1_GPIO3_MODE_MASK 0x3
+#define TPS6586x_R5E_GPIOSET2_GPIO3_OUT_SHIFT 0x2
+#define TPS6586x_R5E_GPIOSET2_GPIO3_OUT_MASK 0x1
+#define TPS6586x_R5E_GPIOSET2_GPIO3_INV_SHIFT 0x6
+#define TPS6586x_R5E_GPIOSET2_GPIO3_INV_MASK 0x1
+
+// GPIO4
+#define TPS6586x_R5D_GPIOSET1_GPIO4_MODE_SHIFT 0x6
+#define TPS6586x_R5D_GPIOSET1_GPIO4_MODE_MASK 0x3
+#define TPS6586x_R5E_GPIOSET2_GPIO4_OUT_SHIFT 0x3
+#define TPS6586x_R5E_GPIOSET2_GPIO4_OUT_MASK 0x1
+#define TPS6586x_R5E_GPIOSET2_GPIO4_INV_SHIFT 0x7
+#define TPS6586x_R5E_GPIOSET2_GPIO4_INV_MASK 0x1
+
+#define TPS6586x_R5D_GPIO_MODE_NOT_CONFIG 0x0
+#define TPS6586x_R5D_GPIO_MODE_OUTPUT 0x1
+#define TPS6586x_R5D_GPIO_MODE_INPUT_ADC 0x2
+#define TPS6586x_R5D_GPIO_MODE_INPUT_LDO 0x3
+#endif
+
+/* ADC0 Engine Setup */
+#define TPS6586x_R60_ADCANLG 0x60
+ /* Not finish yet */
+
+/* ADC0 Engine Data */
+#define TPS6586x_R61_ADC0_SET 0x61
+#define TPS6586x_R62_ADC0_WAIT 0x62
+#define TPS6586x_R94_ADC0_SUM2 0x94
+#define TPS6586x_R95_ADC0_SUM1 0x95
+#define TPS6586x_R9A_ADC0_INT 0x9A
+
+/* Interrupt Control */
+#define TPS6586x_RB0_INT_MASK1 0xB0
+#define TPS6586x_RB1_INT_MASK2 0xB1
+#define TPS6586x_RB2_INT_MASK3 0xB2
+#define TPS6586x_RB3_INT_MASK4 0xB3
+#define TPS6586x_RB4_INT_MASK5 0xB4
+#define TPS6586x_RB5_INT_ACK1 0xB5
+#define TPS6586x_RB6_INT_ACK2 0xB6
+#define TPS6586x_RB7_INT_ACK3 0xB7
+#define TPS6586x_RB8_INT_ACK4 0xB8
+
+/* System Status */
+#define TPS6586x_RB9_STAT1 0xB9
+#define TPS6586x_RBA_STAT2 0xBA
+#define TPS6586x_RBB_STAT3 0xBB
+#define TPS6586x_RBC_STAT4 0xBC
+
+/* RTC */
+#define TPS6586x_RC0_RTC_CTRL 0xC0
+#define TPS6586x_RC1_RTC_ALARM1_HI 0xC1
+#define TPS6586x_RC2_RTC_ALARM1_MID 0xC2
+#define TPS6586x_RC3_RTC_ALARM1_LO 0xC3
+#define TPS6586x_RC4_RTC_ALARM2_HI 0xC4
+#define TPS6586x_RC5_RTC_ALARM2_LO 0xC5
+#define TPS6586x_RC6_RTC_COUNT4 0xC6
+#define TPS6586x_RC7_RTC_COUNT3 0xC7
+#define TPS6586x_RC8_RTC_COUNT2 0xC8
+#define TPS6586x_RC9_RTC_COUNT1 0xC9
+#define TPS6586x_RCA_RTC_COUNT0 0xCA
+
+/* Device ID */
+#define TPS6586x_RCD_VERSIONID 0xCD
+
+#define TPS6586x_RFF_INVALID 0xFF
+
+/* RTC */
+ /* Not finish yet */
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif //TPS6586X_REG_HEADER
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile
new file mode 100644
index 000000000000..d2245a6505fa
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile
@@ -0,0 +1,11 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-y += tmon_hal.o
+obj-y += adt7461/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile
new file mode 100644
index 000000000000..03f222cbeee4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile
@@ -0,0 +1,13 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/tmon
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461
+
+obj-y += nvodm_tmon_adt7461.o
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c
new file mode 100644
index 000000000000..dc76869f6dec
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c
@@ -0,0 +1,934 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+#include "nvodm_tmon_adt7461.h"
+#include "tmon_hal.h"
+
+// TODO: Always Disable before check-in
+// Always debug module: 0=disable, 1=enable
+#define NV_ADT7461_DEBUG (0)
+
+#if (NV_DEBUG || NV_ADT7461_DEBUG)
+#define NVODM_ADT7461_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODM_ADT7461_PRINTF(x)
+#endif
+
+#define ADT7461_ALERT_DEBOUNCE (1)
+
+// ADT7461 Descrriptor
+static const ADT7461Info s_Adt7461Info =
+{
+ // TMON device conversion channels
+ {
+ // Invalid channel
+ {0},
+
+ // Local channel
+ {
+ ADT7461ChannelID_Local,
+ {
+ ADT7461_ODM_LOCAL_RATE_PROTECTED,
+ ADT7461_ODM_LOCAL_INTR_LIMITS_PROTECTED,
+ ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_PROTECTED
+ },
+ {
+ ADT7461_LOCAL_INTR_LIMIT_HIGH_RD_ADDR,
+ ADT7461_LOCAL_INTR_LIMIT_HIGH_WR_ADDR,
+ },
+ {
+ ADT7461_LOCAL_INTR_LIMIT_LOW_RD_ADDR,
+ ADT7461_LOCAL_INTR_LIMIT_LOW_WR_ADDR,
+ },
+ {
+ ADT7461_LOCAL_COMPARATOR_LIMIT_ADDR,
+ ADT7461_LOCAL_COMPARATOR_LIMIT_ADDR,
+ },
+ {
+ ADT7461_INVALID_ADDR, // Local offset does not exist
+ ADT7461_INVALID_ADDR,
+ },
+ {
+ ADT7461_LOCAL_TDATA_RD_ADDR,
+ ADT7461_INVALID_ADDR,
+ },
+ },
+
+ // Remote channel
+ {
+ ADT7461ChannelID_Remote,
+ {
+ ADT7461_ODM_REMOTE_RATE_PROTECTED,
+ ADT7461_ODM_REMOTE_INTR_LIMITS_PROTECTED,
+ ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_PROTECTED
+ },
+ {
+ ADT7461_REMOTE_INTR_LIMIT_HIGH_RD_ADDR,
+ ADT7461_REMOTE_INTR_LIMIT_HIGH_WR_ADDR,
+ },
+ {
+ ADT7461_REMOTE_INTR_LIMIT_LOW_RD_ADDR,
+ ADT7461_REMOTE_INTR_LIMIT_LOW_WR_ADDR,
+ },
+ {
+ ADT7461_REMOTE_COMPARATOR_LIMIT_ADDR,
+ ADT7461_REMOTE_COMPARATOR_LIMIT_ADDR,
+ },
+ {
+ ADT7461_REMOTE_TOFFSET_ADDR,
+ ADT7461_REMOTE_TOFFSET_ADDR,
+ },
+ {
+ ADT7461_REMOTE_TDATA_RD_ADDR,
+ ADT7461_INVALID_ADDR,
+ },
+ }
+ },
+
+ // TMON device common status/control registers
+ {
+ ADT7461_STATUS_RD_ADDR,
+ ADT7461_INVALID_ADDR,
+ },
+ {
+ ADT7461_CONFIG_RD_ADDR,
+ ADT7461_CONFIG_WR_ADDR,
+ },
+ {
+ ADT7461_RATE_RD_ADDR,
+ ADT7461_RATE_WR_ADDR,
+ },
+ {
+ ADT7461_INVALID_ADDR,
+ ADT7461_ONE_SHOT_WR_ADDR,
+ },
+ {
+ ADT7461_COMPARATOR_HYSTERESIS_ADDR,
+ ADT7461_COMPARATOR_HYSTERESIS_ADDR,
+ },
+ {
+ ADT7461_INTR_CNT_DELAY_ADDR,
+ ADT7461_INTR_CNT_DELAY_ADDR,
+ },
+};
+
+// ADT7461 sample intervals
+static const NvS32 s_Adt7461SampleIntervalsMS[] =
+{
+ ADT7461_SAMPLE_INTERVALS_MS
+};
+
+// ADT7461 converison times
+static const NvS32 s_Adt7461ConversionTimesMS[] =
+{
+ ADT7461_CONVERSION_TIME_MS
+};
+
+NV_CT_ASSERT(NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS) ==
+ NV_ARRAY_SIZE(s_Adt7461ConversionTimesMS));
+
+/*****************************************************************************/
+
+#define ADT7461_T_DATA_TO_VALUE(ExtRange, data) \
+ ( (ExtRange) ? \
+ ((NvS32)((NvU32)(data) - ADT7461_RANGE_EXTENDED_DATA_OFFSET)) : \
+ ((NvS32)((NvS8)data)) \
+ )
+
+#define ADT7461_T_VALUE_TO_DATA(ExtRange, val) \
+ ( (ExtRange) ? \
+ ((NvU8)((NvU32)(val) + ADT7461_RANGE_EXTENDED_DATA_OFFSET)) : \
+ ((NvU8)(val)) \
+ )
+
+#define ADT7461_T_RANGE_LIMIT_HIGH(ExtRange) \
+ ( (ExtRange) ? \
+ ADT7461_RANGE_EXTENDED_LIMIT_HIGH : \
+ ADT7461_RANGE_STANDARD_LIMIT_HIGH \
+ )
+
+#define ADT7461_T_RANGE_LIMIT_LOW(ExtRange) \
+ ( (ExtRange) ? \
+ ADT7461_RANGE_EXTENDED_LIMIT_LOW : \
+ ADT7461_RANGE_STANDARD_LIMIT_LOW \
+ )
+
+/*****************************************************************************/
+
+static NvBool
+Adt7461WriteReg(
+ ADT7461PrivData* pPrivData,
+ const ADT7461RegisterInfo* pReg,
+ NvU8 Data)
+{
+ NvU32 i;
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus status;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ NV_ASSERT(pPrivData && pReg);
+ NV_ASSERT(pReg->WrAddr != ADT7461_INVALID_ADDR);
+
+ for (i = 0; i < ADT7461_I2C_RETRY_CNT; i++)
+ {
+ WriteBuffer[0] = pReg->WrAddr;
+ WriteBuffer[1] = Data;
+
+ TransactionInfo.Address = pPrivData->DeviceI2cAddr;
+ TransactionInfo.Buf = &WriteBuffer[0];
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ status = NvOdmI2cTransaction(pPrivData->hOdmI2C, &TransactionInfo, 1,
+ ADT7461_I2C_SPEED_KHZ, ADT7461_I2C_TIMEOUT_MS);
+ if (status == NvOdmI2cStatus_Success)
+ break;
+ }
+
+ switch (status)
+ {
+ case NvOdmI2cStatus_Success:
+ pPrivData->ShadowRegPtr = pReg->WrAddr;
+ return NV_TRUE;
+
+ case NvOdmI2cStatus_Timeout:
+ NVODM_ADT7461_PRINTF(("ADT7461: WriteReg Timeout\n"));
+ return NV_FALSE;
+
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODM_ADT7461_PRINTF(("ADT7461: WriteReg SlaveNotFound\n"));
+ return NV_FALSE;
+ }
+}
+
+static NvBool
+Adt7461ReadReg(
+ ADT7461PrivData* pPrivData,
+ const ADT7461RegisterInfo* pReg,
+ NvU8* pData)
+{
+ NvU32 i;
+ NvU8 Buffer = 0;
+ NvOdmI2cStatus status;
+ NvOdmI2cTransactionInfo TransactionInfo[2];
+
+ NV_ASSERT(pPrivData && pReg && pData);
+ NV_ASSERT(pReg->RdAddr != ADT7461_INVALID_ADDR);
+
+ // TODO: possible optimization - is shadow pointer matches register
+ // address, just send one read transaction (can be done only if Read/Wr
+ // Reg routines are serialized).
+
+ for (i = 0; i < ADT7461_I2C_RETRY_CNT; i++)
+ {
+ Buffer = pReg->RdAddr;
+
+ TransactionInfo[0].Address = pPrivData->DeviceI2cAddr;
+ TransactionInfo[0].Buf = &Buffer;
+ TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[0].NumBytes = 1;
+
+ TransactionInfo[1].Address = (pPrivData->DeviceI2cAddr | 0x1);
+ TransactionInfo[1].Buf = &Buffer;
+ TransactionInfo[1].Flags = 0;
+ TransactionInfo[1].NumBytes = 1;
+
+ status = NvOdmI2cTransaction(pPrivData->hOdmI2C, &TransactionInfo[0], 2,
+ ADT7461_I2C_SPEED_KHZ, ADT7461_I2C_TIMEOUT_MS);
+ if (status == NvOdmI2cStatus_Success)
+ break;
+ }
+
+ switch (status)
+ {
+ case NvOdmI2cStatus_Success:
+ pPrivData->ShadowRegPtr = pReg->RdAddr;
+ *pData = Buffer;
+ return NV_TRUE;
+
+ case NvOdmI2cStatus_Timeout:
+ NVODM_ADT7461_PRINTF(("ADT7461: ReadReg Timeout\n"));
+ return NV_FALSE;
+
+ case NvOdmI2cStatus_SlaveNotFound:
+ default:
+ NVODM_ADT7461_PRINTF(("ADT7461: ReadReg SlaveNotFound\n"));
+ return NV_FALSE;
+ }
+}
+
+static void Adt7461ReadAra(ADT7461PrivData* pPrivData)
+{
+ NvU32 i;
+ NvU8 Buffer = 0;
+ NvOdmI2cStatus status;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ NV_ASSERT(pPrivData);
+
+ for (i = 0; i < ADT7461_ARA_RETRY_CNT; i++)
+ {
+ TransactionInfo.Address = (ADT7461_ARA | 0x1);
+ TransactionInfo.Buf = &Buffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = 1;
+
+ status = NvOdmI2cTransaction(pPrivData->hOdmI2C, &TransactionInfo, 1,
+ ADT7461_I2C_SPEED_KHZ, ADT7461_I2C_TIMEOUT_MS);
+ if ((status == NvOdmI2cStatus_SlaveNotFound) || // False alarm
+ ((status == NvOdmI2cStatus_Success) &&
+ ((Buffer & 0xFE) == (NvU8)pPrivData->DeviceI2cAddr)) // Cleared ARA
+ )
+ break;
+ }
+}
+
+static NvBool
+Adt7461ConfigureSampleInterval(
+ ADT7461PrivData* pPrivData,
+ NvBool OdmProtected,
+ NvS32* pTargetMs)
+{
+ NvU8 i;
+ NvS32 Delta;
+ const ADT7461RegisterInfo* pReg = &pPrivData->pDeviceInfo->Rate;
+
+ if (OdmProtected ||
+ ((*pTargetMs) == ODM_TMON_PARAMETER_UNSPECIFIED))
+ {
+ // Read ADT7461 rate register (fail the call if returned data
+ // does not make sense)
+ if(!Adt7461ReadReg(pPrivData, pReg, &i))
+ return NV_FALSE;
+ if (i >= NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS))
+ return NV_FALSE;
+ }
+ else
+ {
+ // Find and set the best floor approximation of the target sample
+ // interval. Note the descending order of sample intervals array.
+ for (i = 0; i < NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS); i++)
+ {
+ Delta = (*pTargetMs) - s_Adt7461SampleIntervalsMS[i];
+ if(Delta >= 0)
+ break;
+ }
+ if (i == NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS))
+ i--; // min interval is the best we can do
+
+ if(!Adt7461WriteReg(pPrivData, pReg, i))
+ return NV_FALSE;
+ pPrivData->ShadowRate = i;
+ }
+ *pTargetMs = s_Adt7461SampleIntervalsMS[i];
+ return NV_TRUE;
+}
+
+/*****************************************************************************/
+
+static void Adt7461Isr(void* arg)
+{
+ NvU8 Data;
+ ADT7461PrivData* pPrivData = (ADT7461PrivData*)arg;
+ NvOdmInterruptHandler volatile Callback = pPrivData->Callback;
+ void* volatile CallbackArg = pPrivData->CallbackArg;
+ const ADT7461RegisterInfo* pReg = NULL;
+
+ if (Callback && CallbackArg)
+ {
+ Callback(CallbackArg);
+ }
+#if ADT7461_ALERT_DEBOUNCE
+ // New range limits set by callback are not guaranteed to take effect
+ // before the next temperature conversion is completed, and interrupt
+ // can not be cleared until then. Hence, the debounce delay below.
+ NvOdmOsSleepMS(s_Adt7461SampleIntervalsMS[pPrivData->ShadowRate] +
+ s_Adt7461ConversionTimesMS[pPrivData->ShadowRate] + 1);
+#endif
+ // Read status and ARA to finish clearing interrupt after callback
+ pReg = &pPrivData->pDeviceInfo->Status;
+ (void)Adt7461ReadReg(pPrivData, pReg, &Data);
+ Adt7461ReadAra(pPrivData);
+
+ // Re-enable interrupt
+ if (pPrivData->hGpioIntr)
+ NvOdmGpioInterruptDone(pPrivData->hGpioIntr);
+}
+
+static void Adt7461FreePrivData(ADT7461PrivData* pPrivData)
+{
+ if (pPrivData)
+ {
+ if (pPrivData->hGpioIntr)
+ {
+ NvOdmGpioInterruptUnregister(
+ pPrivData->hGpio, pPrivData->hGpioPin, pPrivData->hGpioIntr);
+ }
+ NvOdmI2cClose(pPrivData->hOdmI2C);
+ NvOdmGpioReleasePinHandle(pPrivData->hGpio, pPrivData->hGpioPin);
+ NvOdmGpioClose(pPrivData->hGpio);
+ NvOdmServicesPmuClose(pPrivData->hOdmPmuSevice);
+ NvOdmOsFree(pPrivData);
+ }
+}
+
+/*****************************************************************************/
+
+NvBool Adt7461Init(NvOdmTmonDeviceHandle hTmon)
+{
+ NvU8 Data;
+ NvBool ExtRange;
+ NvU32 i = 0;
+ NvU32 I2cInstance = 0;
+ NvOdmIoModule I2cModule = NvOdmIoModule_Num; // Inavlid module
+ const ADT7461RegisterInfo* pReg = NULL;
+ ADT7461PrivData* pPrivData = NULL;
+
+ NV_ASSERT(hTmon && hTmon->pConn && hTmon->pConn->AddressList);
+
+ // Allocate and clear priavte data
+ pPrivData = (ADT7461PrivData*) NvOdmOsAlloc(sizeof(ADT7461PrivData));
+ if (pPrivData == NULL)
+ {
+ NVODM_ADT7461_PRINTF(("ADT7461: Error Allocating PrivData. \n"));
+ return NV_FALSE;
+ }
+ NvOdmOsMemset(pPrivData, 0, sizeof(ADT7461PrivData));
+ hTmon->pPrivate = pPrivData;
+
+ // Register for PMU services
+ pPrivData->hOdmPmuSevice = NvOdmServicesPmuOpen();
+ if (pPrivData->hOdmPmuSevice == NULL)
+ {
+ NVODM_ADT7461_PRINTF(("ADT7461: Error Open PMU service. \n"));
+ goto fail;
+ }
+
+ // Register for GPIO services
+ pPrivData->hGpio = NvOdmGpioOpen();
+ if (pPrivData->hOdmPmuSevice == NULL)
+ {
+ NVODM_ADT7461_PRINTF(("ADT7461: Error Open GPIO service. \n"));
+ goto fail;
+ }
+
+ /*
+ * Parse connectivity data: turn On power to the device, acquire I2C
+ * interface and GPIO interrupt (optional); map device channels to
+ * thermal zones
+ */
+ for (i = 0; i < hTmon->pConn->NumAddress; i ++)
+ {
+ const NvOdmIoAddress* pIoAddress = &hTmon->pConn->AddressList[i];
+ if (pIoAddress->Interface == NvOdmIoModule_I2c_Pmu)
+ {
+ I2cModule = NvOdmIoModule_I2c_Pmu;
+ I2cInstance = pIoAddress->Instance;
+ NV_ASSERT(pIoAddress->Address != 0);
+ pPrivData->DeviceI2cAddr = pIoAddress->Address;
+ }
+ else if (pIoAddress->Interface == NvOdmIoModule_Tsense)
+ {
+ NV_ASSERT(pIoAddress->Instance < NvOdmTmonZoneID_Num);
+ NV_ASSERT(pIoAddress->Address < ADT7461ChannelID_Num);
+ pPrivData->ConnectivityMap[pIoAddress->Instance] =
+ pIoAddress->Address;
+ }
+ else if (pIoAddress->Interface == NvOdmIoModule_Vdd)
+ {
+ NvU32 usec = 0;
+ NvU32 RailAddress = pIoAddress->Address;
+ NvOdmServicesPmuVddRailCapabilities RailCapabilities = {0};
+ NvOdmServicesPmuGetCapabilities(
+ pPrivData->hOdmPmuSevice, RailAddress, &RailCapabilities);
+ NvOdmServicesPmuSetVoltage(pPrivData->hOdmPmuSevice, RailAddress,
+ RailCapabilities.requestMilliVolts, &usec);
+ NvOdmOsWaitUS(usec + (ADT7461_POWERUP_DELAY_MS * 1000));
+ }
+ else if (pIoAddress->Interface == NvOdmIoModule_Gpio)
+ {
+ NvU32 port = pIoAddress->Instance;
+ NvU32 pin = pIoAddress->Address;
+ pPrivData->hGpioPin = NvOdmGpioAcquirePinHandle(
+ pPrivData->hGpio, port, pin);
+ }
+
+ }
+ NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu);
+ pPrivData->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance);
+ if (pPrivData->hOdmI2C == NULL)
+ {
+ NVODM_ADT7461_PRINTF(("ADT7461: Error Open I2C device. \n"));
+ goto fail;
+ }
+
+ /*
+ * Initialize device info and configuration. Force standby mode to avoid
+ * glitch on shutdown comparator output when temperature range and/or
+ * comparator limit is changing during initialization. The Adt7461Run()
+ * call from the hal that follows initialization will switch device to
+ * run mode and re-start temperature monitoring (note that out of limit
+ * interrupt is always masked during and after initialization)
+ */
+ pPrivData->pDeviceInfo = &s_Adt7461Info;
+ pPrivData->ShadowRegPtr = ADT7461_INVALID_ADDR;
+
+ pReg = &pPrivData->pDeviceInfo->Config;
+ if (!Adt7461ReadReg(pPrivData, pReg, &Data))
+ goto fail;
+ if ((Data & ADT7461ConfigBits_ExtendedRange) !=
+ (ADT7461_INITIAL_CONFIG & ADT7461ConfigBits_ExtendedRange))
+ {
+ // Only switch from standard to extended range is supported
+ NV_ASSERT((Data & ADT7461ConfigBits_ExtendedRange) == 0);
+ Data |= ADT7461ConfigBits_Standby;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+ }
+ Data = ADT7461_INITIAL_CONFIG | ADT7461ConfigBits_Standby;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+ pPrivData->ShadowConfig = Data;
+ ExtRange = ((Data & ADT7461ConfigBits_ExtendedRange) != 0);
+
+ // Program shutdown comparators settings
+ Data = ADT7461_T_VALUE_TO_DATA(
+ ExtRange, ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_VALUE);
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Local].ComparatorLimit;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+
+ Data = ADT7461_T_VALUE_TO_DATA(
+ ExtRange, ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_VALUE);
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Remote].ComparatorLimit;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+
+ // Set interrupt limits to the range boundaries to prevent out of limit
+ // interrupt
+ Data = ADT7461_T_VALUE_TO_DATA(
+ ExtRange, ADT7461_T_RANGE_LIMIT_HIGH(ExtRange));
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Local].IntrLimitHigh;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Remote].IntrLimitHigh;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+
+ Data = ADT7461_T_VALUE_TO_DATA(
+ ExtRange, ADT7461_T_RANGE_LIMIT_LOW(ExtRange));
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Local].IntrLimitLow;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Remote].IntrLimitLow;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+
+ // Set initial rate
+ Data = ADT7461_INITIAL_RATE_SETTING;
+ pReg = &pPrivData->pDeviceInfo->Rate;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+ pPrivData->ShadowRate = Data;
+
+ // Set remote channel offset (8-bit 2's complement value for any range)
+ Data = ((NvU8)ADT7461_ODM_REMOTE_OFFSET_VALUE);
+ pReg = &pPrivData->pDeviceInfo->Channels[
+ ADT7461ChannelID_Remote].Toffset;
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ goto fail;
+
+ // Read ADT7461 status and ARA (clear pending Alert interrupt, if any)
+ pReg = &pPrivData->pDeviceInfo->Status;
+ if (!Adt7461ReadReg(pPrivData, pReg, &Data))
+ goto fail;
+ // TODO: check open remote circuit error
+
+ Adt7461ReadAra(pPrivData);
+ return NV_TRUE;
+
+fail:
+ Adt7461FreePrivData(pPrivData);
+ hTmon->pPrivate = NULL;
+ return NV_FALSE;
+}
+
+void Adt7461Deinit(NvOdmTmonDeviceHandle hTmon)
+{
+ if (hTmon && hTmon->pPrivate)
+ {
+ ADT7461PrivData* pPrivData = hTmon->pPrivate;
+ (void)Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config,
+ ADT7461_INITIAL_CONFIG); //leave device in default configuration
+ // with power rail ON (forever)
+ Adt7461FreePrivData(pPrivData);
+ hTmon->pPrivate = NULL;
+ }
+}
+
+/*****************************************************************************/
+
+NvBool Adt7461Run(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId)
+{
+ NvU8 Data;
+ NvBool IsRunning;
+ ADT7461PrivData* pPrivData;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate);
+ pPrivData = hTmon->pPrivate;
+ IsRunning = (pPrivData->ShadowConfig & ADT7461ConfigBits_Standby) == 0;
+
+ if (!IsRunning)
+ {
+ Data = pPrivData->ShadowConfig & (~ADT7461ConfigBits_Standby);
+ if(!Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data))
+ return NV_FALSE;
+ pPrivData->ShadowConfig = Data;
+ }
+ pPrivData->RunRefCount++;
+ return NV_TRUE;
+}
+
+NvBool Adt7461Stop(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId)
+{
+ NvU8 Data;
+ NvBool IsRunning;
+ ADT7461PrivData* pPrivData;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate);
+ pPrivData = hTmon->pPrivate;
+ IsRunning = (pPrivData->ShadowConfig & ADT7461ConfigBits_Standby) == 0;
+
+ if (ADT7461_ODM_STANDBY_ENABLED &&
+ IsRunning && (pPrivData->RunRefCount == 1))
+ {
+ Data = pPrivData->ShadowConfig | ADT7461ConfigBits_Standby;
+ if(!Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data))
+ return NV_FALSE;
+ pPrivData->ShadowConfig = Data;
+ }
+ if (pPrivData->RunRefCount != 0)
+ {
+ pPrivData->RunRefCount--;
+ return NV_TRUE;
+ }
+ NV_ASSERT(!"RunRefCount balance failed");
+ NVODM_ADT7461_PRINTF(("ADT7461: RunRefCount balance failed. \n"));
+ return NV_FALSE;
+}
+
+/*****************************************************************************/
+// ADT7461 aborts and restarts conversion cycle when temperature is read
+// (actually on any I2C access for that matter, but other accesses are rare).
+// TODO: add time stamps and implement refresh policy to make sure that
+// frequent temperature reads would not stall the conversion forever.
+
+NvBool
+Adt7461TemperatureGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvS32* pDegreesC)
+{
+ NvU8 Data;
+ NvBool ExtRange;
+ ADT7461ChannelID ChannelId;
+ ADT7461PrivData* pPrivData;
+ const ADT7461RegisterInfo* pReg;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate && pDegreesC);
+ pPrivData = hTmon->pPrivate;
+ ExtRange = ((pPrivData->ShadowConfig &
+ ADT7461ConfigBits_ExtendedRange) != 0);
+ ChannelId = pPrivData->ConnectivityMap[ZoneId];
+ pReg = &pPrivData->pDeviceInfo->Channels[ChannelId].Tdata;
+
+ if(!Adt7461ReadReg(pPrivData, pReg, &Data))
+ return NV_FALSE;
+
+ *pDegreesC = ADT7461_T_DATA_TO_VALUE(ExtRange, Data);
+ return NV_TRUE;
+}
+
+/*****************************************************************************/
+
+void
+Adt7461CapabilitiesGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonCapabilities* pCaps)
+{
+ NvBool ExtRange;
+ ADT7461PrivData* pPrivData;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate && pCaps);
+ pPrivData = hTmon->pPrivate;
+ ExtRange = ((pPrivData->ShadowConfig &
+ ADT7461ConfigBits_ExtendedRange) != 0);
+
+ pCaps->Tmax = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange);
+ pCaps->Tmin = ADT7461_T_RANGE_LIMIT_LOW(ExtRange);
+ pCaps->IntrSupported = NV_TRUE;
+ pCaps->HwCriticalSupported = NV_TRUE;
+ pCaps->HwCoolingSupported = NV_FALSE;
+}
+
+void
+Adt7461ParameterCapsGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonConfigParam ParamId,
+ NvOdmTmonParameterCaps* pCaps)
+{
+ NvBool ExtRange;
+ ADT7461PrivData* pPrivData;
+ const ADT7461ChannelInfo* pChannel;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate && pCaps);
+ pPrivData = hTmon->pPrivate;
+ ExtRange = ((pPrivData->ShadowConfig &
+ ADT7461ConfigBits_ExtendedRange) != 0);
+ pChannel = &pPrivData->pDeviceInfo->Channels[(
+ pPrivData->ConnectivityMap[ZoneId])];
+
+ switch (ParamId)
+ {
+ case NvOdmTmonConfigParam_IntrLimitHigh:
+ case NvOdmTmonConfigParam_IntrLimitLow:
+ pCaps->OdmProtected =
+ pChannel->ChannelPolicy.IntrLimitsOdmProtected;
+ break;
+
+ case NvOdmTmonConfigParam_HwLimitCrit:
+ pCaps->OdmProtected =
+ pChannel->ChannelPolicy.HwLimitCritOdmProtected;
+ break;
+
+ case NvOdmTmonConfigParam_SampleMs:
+ // smaple intervals in descending order
+ pCaps->MaxValue = s_Adt7461SampleIntervalsMS[0];
+ pCaps->MinValue = s_Adt7461SampleIntervalsMS[(
+ NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS) - 1)];
+ pCaps->OdmProtected = pChannel->ChannelPolicy.RateOdmProtected;
+ return;
+
+ default: // unsupported parameter
+ pCaps->MaxValue = ODM_TMON_PARAMETER_UNSPECIFIED;
+ pCaps->MinValue = ODM_TMON_PARAMETER_UNSPECIFIED;
+ pCaps->OdmProtected = NV_TRUE;
+ return;
+ }
+
+ // Common range for limits
+ pCaps->MaxValue = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange);
+ pCaps->MinValue = ADT7461_T_RANGE_LIMIT_LOW(ExtRange);
+}
+
+NvBool
+Adt7461ParameterConfig(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonConfigParam ParamId,
+ NvS32* pSetting)
+{
+ NvU8 Data;
+ NvBool ExtRange, OdmProtected;
+ ADT7461PrivData* pPrivData;
+ const ADT7461RegisterInfo* pReg;
+ const ADT7461ChannelInfo* pChannel;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate && pSetting);
+ pPrivData = hTmon->pPrivate;
+ ExtRange = ((pPrivData->ShadowConfig &
+ ADT7461ConfigBits_ExtendedRange) != 0);
+ pChannel = &pPrivData->pDeviceInfo->Channels[(
+ pPrivData->ConnectivityMap[ZoneId])];
+
+ switch (ParamId)
+ {
+ case NvOdmTmonConfigParam_IntrLimitHigh:
+ pReg = &pChannel->IntrLimitHigh;
+ OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected;
+ break;
+
+ case NvOdmTmonConfigParam_IntrLimitLow:
+ pReg = &pChannel->IntrLimitLow;
+ OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected;
+ break;
+
+ case NvOdmTmonConfigParam_HwLimitCrit:
+ pReg = &pChannel->ComparatorLimit;
+ OdmProtected = pChannel->ChannelPolicy.HwLimitCritOdmProtected;
+ break;
+
+ case NvOdmTmonConfigParam_SampleMs:
+ OdmProtected = pChannel->ChannelPolicy.RateOdmProtected;
+ return Adt7461ConfigureSampleInterval(
+ pPrivData, OdmProtected, pSetting);
+
+ default: // unsupported parameter
+ *pSetting = ODM_TMON_PARAMETER_UNSPECIFIED;
+ return NV_TRUE;
+ }
+
+ // Common processing for temperature limits configuration
+ if ((OdmProtected) ||
+ ((*pSetting) == ODM_TMON_PARAMETER_UNSPECIFIED))
+ {
+ // Read ADT7461 register and convert data to current parameter value
+ if(!Adt7461ReadReg(pPrivData, pReg, &Data))
+ return NV_FALSE;
+
+ *pSetting = ADT7461_T_DATA_TO_VALUE(ExtRange, Data);
+ }
+ else
+ {
+ // Clip target setting to temperature range
+ if ((*pSetting) > ADT7461_T_RANGE_LIMIT_HIGH(ExtRange))
+ *pSetting = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange);
+ else if ((*pSetting) < ADT7461_T_RANGE_LIMIT_LOW(ExtRange))
+ *pSetting = ADT7461_T_RANGE_LIMIT_LOW(ExtRange);
+
+ // Convert new configuration setting and write to ADT7461 register
+ Data = ADT7461_T_VALUE_TO_DATA(ExtRange, *pSetting);
+ if(!Adt7461WriteReg(pPrivData, pReg, Data))
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+/*****************************************************************************/
+
+NvOdmTmonIntrHandle
+Adt7461IntrRegister(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmInterruptHandler Callback,
+ void* CallbackArg)
+{
+ NvU8 Data;
+ ADT7461PrivData* pPrivData;
+ const ADT7461ChannelInfo* pChannel;
+ NvOdmServicesGpioIntrHandle hGpioIntr = NULL;
+
+ NV_ASSERT(hTmon && hTmon->pPrivate && Callback && CallbackArg);
+ pPrivData = hTmon->pPrivate;
+
+ // No registration, if no GPIO pin available or interrupt already registred
+ if (!pPrivData->hGpioPin || pPrivData->hGpioIntr)
+ return NULL;
+
+ // No registration for other than remote channel
+ pChannel = &pPrivData->pDeviceInfo->Channels[(
+ pPrivData->ConnectivityMap[ZoneId])];
+ if (pChannel->ChannelId != ADT7461ChannelID_Remote)
+ return NULL;
+
+ // Register GPIO interrupt (will be enabled at SoC IC, but still disabled
+ // at ADT7461 device)
+ pPrivData->Callback = Callback;
+ pPrivData->CallbackArg = CallbackArg;
+ if (!NvOdmGpioInterruptRegister(
+ pPrivData->hGpio, &hGpioIntr, pPrivData->hGpioPin,
+ ADT7461_ODM_INTR_POLARITY, Adt7461Isr, (void *)pPrivData, 0))
+ {
+ pPrivData->Callback = NULL;
+ pPrivData->CallbackArg = NULL;
+ return NULL;
+ }
+ NV_ASSERT(hGpioIntr);
+ pPrivData->hGpioIntr = hGpioIntr;
+
+ // Finally enable ADT7461 device interrupt output (interrupt may or may
+ // not be generated depending on temperature and limt settings).
+ Data = pPrivData->ShadowConfig & (~ADT7461ConfigBits_IntrDisabled);
+ if(!Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data))
+ {
+ NvOdmGpioInterruptUnregister(
+ pPrivData->hGpio, pPrivData->hGpioPin, hGpioIntr);
+ pPrivData->Callback = NULL;
+ pPrivData->CallbackArg = NULL;
+ pPrivData->hGpioIntr = NULL;
+ return NULL;
+ }
+ pPrivData->ShadowConfig = Data;
+
+ return (NvOdmTmonIntrHandle)hGpioIntr;
+}
+
+void
+Adt7461IntrUnregister(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonIntrHandle hIntr)
+{
+ NvU8 Data;
+ ADT7461PrivData* pPrivData;
+ const ADT7461ChannelInfo* pChannel;
+
+ // Ignore invalid handles
+ if(!hIntr || !hTmon || !hTmon->pPrivate)
+ return;
+
+ pPrivData = hTmon->pPrivate;
+ if (hIntr != ((NvOdmTmonIntrHandle)pPrivData->hGpioIntr))
+ return;
+
+ // Ignore any channel other than remote
+ pChannel = &pPrivData->pDeviceInfo->Channels[(
+ pPrivData->ConnectivityMap[ZoneId])];
+ if (pChannel->ChannelId != ADT7461ChannelID_Remote)
+ return;
+
+ // Disable ADT7461 interrupt output
+ Data = pPrivData->ShadowConfig | ADT7461ConfigBits_IntrDisabled;
+ if(Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data))
+ pPrivData->ShadowConfig = Data;
+
+ // Unregister GPIO interrupt, clear callbacks and handle
+ NvOdmGpioInterruptUnregister(
+ pPrivData->hGpio, pPrivData->hGpioPin, pPrivData->hGpioIntr);
+
+ pPrivData->Callback = NULL;
+ pPrivData->CallbackArg = NULL;
+ pPrivData->hGpioIntr = NULL;
+}
+
+/*****************************************************************************/
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h
new file mode 100644
index 000000000000..ffe4bf15dbec
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_TMON_ADT7461_H
+#define INCLUDED_NVODM_TMON_ADT7461_H
+
+#include "nvodm_tmon.h"
+#include "nvodm_tmon_adt7461_reg.h"
+#include "nvodm_tmon_adt7461_channel.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct ADT7461RegisterInfoRec
+{
+ NvU8 RdAddr; // Invalid if WO
+ NvU8 WrAddr; // Invalid if RO
+} ADT7461RegisterInfo;
+
+typedef struct ADT7461ChannelOdmPolicyRec
+{
+ NvBool RateOdmProtected;
+ NvBool IntrLimitsOdmProtected;
+ NvBool HwLimitCritOdmProtected;
+} ADT7461ChannelOdmPolicy;
+
+typedef struct ADT7461ChannelInfoRec
+{
+ // TMON device conversion channel ID
+ ADT7461ChannelID ChannelId;
+
+ // ODM channel policy
+ ADT7461ChannelOdmPolicy ChannelPolicy;
+
+ // Alert Interrupt limits registers
+ ADT7461RegisterInfo IntrLimitHigh;
+ ADT7461RegisterInfo IntrLimitLow;
+
+ // Thermal comparator limit register
+ ADT7461RegisterInfo ComparatorLimit;
+
+ // Temperature measurement offset
+ ADT7461RegisterInfo Toffset;
+
+ // Temperature Data register
+ ADT7461RegisterInfo Tdata;
+} ADT7461ChannelInfo;
+
+typedef struct ADT7461InfoRec
+{
+ // TMON device conversion channels
+ ADT7461ChannelInfo Channels[ADT7461ChannelID_Num];
+
+ // Chip status register
+ ADT7461RegisterInfo Status;
+
+ // Common configration controls
+ ADT7461RegisterInfo Config;
+
+ // Common conversion rate
+ ADT7461RegisterInfo Rate;
+
+ // One-shot trigger register
+ ADT7461RegisterInfo OneShot;
+
+ // Common comparator hysteresis
+ ADT7461RegisterInfo ComparatorHysteresis;
+
+ // Number of consecutive limit violation before
+ // interrupt is generated
+ ADT7461RegisterInfo IntrCntDelay;
+} ADT7461Info;
+
+typedef struct ADT7461PrivDataRec
+{
+ // ADT7461 device registers descriptors
+ const ADT7461Info* pDeviceInfo;
+
+ // ADT7461 I2C device Address
+ NvU32 DeviceI2cAddr;
+
+ // The handle to the I2C controller
+ NvOdmServicesI2cHandle hOdmI2C;
+
+ // The odm pmu service handle
+ NvOdmServicesPmuHandle hOdmPmuSevice;
+
+ // Zone => Channel map
+ ADT7461ChannelID ConnectivityMap[NvOdmTmonZoneID_Num];
+
+ // ADR7461 run mode reference count
+ NvU32 RunRefCount;
+
+ // Shadow of ADT7461 internal configuration register
+ NvU8 ShadowConfig;
+
+ // Shadow of ADT7461 internal rate settings
+ NvU8 ShadowRate;
+
+ // Shadow of ADT7461 internal address pointer
+ NvU8 ShadowRegPtr;
+
+ // The odm GPIO service handle
+ NvOdmServicesGpioHandle hGpio;
+
+ // SoC GPIO dedicated for ADT7461 out of limit interrupt
+ NvOdmGpioPinHandle hGpioPin;
+
+ // The ADT7461 interrupt handle
+ NvOdmServicesGpioIntrHandle hGpioIntr;
+
+ // The ADT7461 interrupt callback
+ NvOdmInterruptHandler Callback;
+
+ // The ADT7461 interrupt callback context
+ void* CallbackArg;
+} ADT7461PrivData;
+
+NvBool Adt7461Init(NvOdmTmonDeviceHandle hTmon);
+void Adt7461Deinit(NvOdmTmonDeviceHandle hTmon);
+NvBool Adt7461Run(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId);
+NvBool Adt7461Stop(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId);
+
+NvBool
+Adt7461TemperatureGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvS32* pDegreesC);
+
+void
+Adt7461CapabilitiesGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonCapabilities* pCaps);
+
+void
+Adt7461ParameterCapsGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonConfigParam ParamId,
+ NvOdmTmonParameterCaps* pCaps);
+
+NvBool
+Adt7461ParameterConfig(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonConfigParam ParamId,
+ NvS32* pSetting);
+
+NvOdmTmonIntrHandle
+Adt7461IntrRegister(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmInterruptHandler Callback,
+ void* arg);
+
+void
+Adt7461IntrUnregister(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonZoneID ZoneId,
+ NvOdmTmonIntrHandle hIntr);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //INCLUDED_NVODM_TMON_ADT7461_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h
new file mode 100644
index 000000000000..8d9f9bb22d95
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_TMON_ADT7461_CHANNEL_H
+#define INCLUDED_NVODM_TMON_ADT7461_CHANNEL_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ // Local sensor
+ ADT7461ChannelID_Local = 1,
+
+ // Remote sensor
+ ADT7461ChannelID_Remote,
+
+ ADT7461ChannelID_Num,
+ ADT7461ChannelID_Force32 = 0x7FFFFFFFUL
+} ADT7461ChannelID;
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //INCLUDED_NVODM_TMON_ADT7461_CHANNEL_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h
new file mode 100644
index 000000000000..e0e930e79fe7
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_TMON_ADT7461_REG_H
+#define INCLUDED_NVODM_TMON_ADT7461_REG_H
+
+#include "nvodm_tmon_adt7461.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+// ODM policy: use ADT7461 extended=1 (standard=0) range
+#define ADT7461_ODM_EXTENDED_RANGE (1)
+
+// ODM policy: enable=1 (disable=0) ADT7461 standby mode
+#define ADT7461_ODM_STANDBY_ENABLED (0)
+
+// ODM policy: protect=1 (not=0) thermal limits from being overwritten by API
+#define ADT7461_ODM_LOCAL_INTR_LIMITS_PROTECTED (1)
+#define ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_PROTECTED (1)
+
+#define ADT7461_ODM_REMOTE_INTR_LIMITS_PROTECTED (0)
+#define ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_PROTECTED (1)
+
+// ODM policy: protect=1 (not=0) sample rate from being overwritten by API
+#define ADT7461_ODM_LOCAL_RATE_PROTECTED (1)
+#define ADT7461_ODM_REMOTE_RATE_PROTECTED (0)
+
+// ODM policy: comparator limit values for critical shutdown (in degrees C)
+#define ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_VALUE (120L)
+#define ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_VALUE (115L)
+
+// ODM ADT7461 remote channel measurement offset
+#define ADT7461_ODM_REMOTE_OFFSET_VALUE (6L)
+
+// ODM ADT7461 interrupt polarity
+#define ADT7461_ODM_INTR_POLARITY (NvOdmGpioPinMode_InputInterruptLow)
+
+// ADT7461 Register POR settings
+#define ADT7461_LOCAL_TDATA_POR (0x00)
+#define ADT7461_REMOTE_TDATA_POR (0x00)
+// #define ADT7461_STATUS_POR unknown
+#define ADT7461_CONFIG_POR (0x00)
+#define ADT7461_RATE_POR (0x08)
+#define ADT7461_LOCAL_INTR_LIMIT_HIGH_POR (0x55)
+#define ADT7461_LOCAL_INTR_LIMIT_LOW_POR (0x00)
+#define ADT7461_REMOTE_INTR_LIMIT_HIGH_POR (0x55)
+#define ADT7461_REMOTE_INTR_LIMIT_LOW_POR (0x00)
+// #define ADT7461_ONE_SHOT_POR unknown
+#define ADT7461_REMOTE_TDATA_FRACTION_POR (0x00)
+#define ADT7461_REMOTE_TOFFSET_POR (0x00)
+#define ADT7461_REMOTE_TOFFSET_FRACTION_POR (0x00)
+#define ADT7461_REMOTE_INTR_LIMIT_HIGH_FRACTION_POR (0x00)
+#define ADT7461_REMOTE_INTR_LIMIT_LOW_FRACTION_POR (0x00)
+#define ADT7461_REMOTE_COMPARATOR_LIMIT_POR (0x55)
+#define ADT7461_LOCAL_COMPARATOR_LIMIT_POR (0x55)
+#define ADT7461_COMPARATOR_HYSTERESIS_POR (0x0A)
+#define ADT7461_INTR_CNT_DELAY_POR (0x01)
+#define ADT7461_CHIP_ID_POR (0x41)
+#define ADT7461_CHIP_REV_POR (0x51)
+
+
+// ADT7461 Register Addresses
+#define ADT7461_LOCAL_TDATA_RD_ADDR (0x00)
+#define ADT7461_REMOTE_TDATA_RD_ADDR (0x01)
+
+#define ADT7461_STATUS_RD_ADDR (0x02)
+#define ADT7461_CONFIG_RD_ADDR (0x03)
+#define ADT7461_CONFIG_WR_ADDR (0x09)
+#define ADT7461_RATE_RD_ADDR (0x04)
+#define ADT7461_RATE_WR_ADDR (0x0A)
+
+#define ADT7461_LOCAL_INTR_LIMIT_HIGH_RD_ADDR (0x05)
+#define ADT7461_LOCAL_INTR_LIMIT_HIGH_WR_ADDR (0x0B)
+#define ADT7461_LOCAL_INTR_LIMIT_LOW_RD_ADDR (0x06)
+#define ADT7461_LOCAL_INTR_LIMIT_LOW_WR_ADDR (0x0C)
+
+#define ADT7461_REMOTE_INTR_LIMIT_HIGH_RD_ADDR (0x07)
+#define ADT7461_REMOTE_INTR_LIMIT_HIGH_WR_ADDR (0x0D)
+#define ADT7461_REMOTE_INTR_LIMIT_LOW_RD_ADDR (0x08)
+#define ADT7461_REMOTE_INTR_LIMIT_LOW_WR_ADDR (0x0E)
+
+#define ADT7461_ONE_SHOT_WR_ADDR (0x0F)
+
+#define ADT7461_REMOTE_TDATA_FRACTION_RD_ADDR (0x10)
+#define ADT7461_REMOTE_TOFFSET_ADDR (0x11)
+#define ADT7461_REMOTE_TOFFSET_FRACTION_ADDR (0x12)
+#define ADT7461_REMOTE_INTR_LIMIT_HIGH_FRACTION_ADDR (0x13)
+#define ADT7461_REMOTE_INTR_LIMIT_LOW_FRACTION_ADDR (0x14)
+
+#define ADT7461_REMOTE_COMPARATOR_LIMIT_ADDR (0x19)
+#define ADT7461_LOCAL_COMPARATOR_LIMIT_ADDR (0x20)
+#define ADT7461_COMPARATOR_HYSTERESIS_ADDR (0x21)
+
+#define ADT7461_INTR_CNT_DELAY_ADDR (0x22)
+#define ADT7461_CHIP_ID_RD_ADDR (0xFE)
+#define ADT7461_CHIP_REV_RD_ADDR (0xFF)
+
+#define ADT7461_INVALID_ADDR (0xF0)
+
+
+// ADT7461 conversion range (signed values)
+#define ADT7461_RANGE_STANDARD_LIMIT_HIGH (127L)
+#define ADT7461_RANGE_STANDARD_LIMIT_LOW (0L)
+#define ADT7461_RANGE_EXTENDED_LIMIT_HIGH (150L)
+#define ADT7461_RANGE_EXTENDED_LIMIT_LOW (-64L)
+
+// ADT7461 data reading offsets (unsigned data)
+#define ADT7461_RANGE_STANDARD_DATA_OFFSET (0UL)
+#define ADT7461_RANGE_EXTENDED_DATA_OFFSET (64UL)
+
+
+// ADT7461 Configuration Register bitfields
+typedef enum
+{
+ // If set - extended temperature range (-55C to 150C); data offset 64C
+ // If cleared - stnadard temperature range (0C to 127C); data offset 0
+ ADT7461ConfigBits_ExtendedRange = (0x1 << 2),
+
+ // If set - interrupt output works as second auto cleared comparator
+ // If cleared - interrupt output works as level out of limit interrupt,
+ // cleared by (a) reading status and (b) alert response protocol over I2C
+ ADT7461ConfigBits_IntrAutoClear = (0x1 << 5),
+
+ // If set - put device in stanby mode
+ // If cleared - put device in running mode
+ ADT7461ConfigBits_Standby = (0x1 << 6),
+
+ // If set - interrupt from device is disabled
+ // If cleared - interrupt from device is enabled
+ ADT7461ConfigBits_IntrDisabled = (0x1 << 7),
+} ADT7461ConfigBits;
+
+// ADT7461 initial configuration set by adaptation:
+// ADT7461 THERM1 output is dedicated for critical h/w shutdown, and ADT7461
+// ALERT/THERM2 output is always configured as out of limit ALERT interrupt.
+// Monitor is in running mode, in the range selected per ODM policy.
+#define ADT7461_INITIAL_CONFIG \
+ ((ADT7461ConfigBits_IntrDisabled) | \
+ (ADT7461_ODM_EXTENDED_RANGE ? ADT7461ConfigBits_ExtendedRange : 0))
+
+
+// ADT7461 sample intervals and conversion time limits rounded to the nearest
+// milliseconds, in descending order indexed by rate register DATA settings
+
+// RATE: 1/16 1/8 1/4 1/2 1 2 4 8 16 32 64 (1/s)
+// DATA: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A
+#define ADT7461_SAMPLE_INTERVALS_MS \
+ 16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 31, 16
+#define ADT7461_CONVERSION_TIME_MS \
+ 115, 115, 115, 115, 115, 115, 115, 115, 13, 13, 13
+
+#define ADT7461_INITIAL_RATE_SETTING (0x0A)
+
+
+// ADT7461 I2C (SMBus) clock speed, bus timeout, retries, and fixed
+// Alert Response Address (ARA).
+#define ADT7461_I2C_SPEED_KHZ (400)
+#define ADT7461_I2C_TIMEOUT_MS (500)
+#define ADT7461_I2C_RETRY_CNT (2)
+#define ADT7461_ARA_RETRY_CNT (4)
+#define ADT7461_ARA (0x18)
+
+// ADT7461 power up delay (TODO: get spec for delay from vendor)
+#define ADT7461_POWERUP_DELAY_MS (5)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif //INCLUDED_NVODM_TMON_ADT7461_REG_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c
new file mode 100644
index 000000000000..acabf8492c35
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c
@@ -0,0 +1,304 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "tmon_hal.h"
+#include "adt7461/nvodm_tmon_adt7461.h"
+
+/*
+ * TMON adaptation is a singleton linked directly with NVRM only.
+ * Thread safety for TMON APIs is provided by NVRM as well.
+ */
+
+
+// Temperature Monitors suported under hal
+#define TMON_ADT7461_ID (NV_ODM_GUID('a','d','t','7','4','6','1',' '))
+
+#define TMON_ZONE_PSEUDOHANDLE(h, z) \
+ ( (NvOdmTmonDeviceHandle)((((NvU32)(h)) << 16) | (z)) )
+#define TMON_PSEUDOHANDLE_ZONE(h) ( ((NvU32)(h)) & 0xFFFF )
+
+/*****************************************************************************/
+
+static NvOdmTmonDevice*
+TmonGetInstance(NvOdmTmonZoneID ZoneId)
+{
+ static NvOdmTmonDevice s_TmonArray[NvOdmTmonZoneID_Num];
+ static NvOdmTmonDevice* s_TmonMap[NvOdmTmonZoneID_Num];
+ static NvBool s_Initialized = NV_FALSE;
+
+ NvU32 i, j;
+ NvOdmTmonDevice* pTmon = NULL;
+ const NvOdmPeripheralConnectivity* pConn = NULL;
+
+ // Check for invalid zone
+ if (ZoneId == 0)
+ return NULL;
+
+ if (!s_Initialized)
+ {
+ NvOdmOsMemset(s_TmonArray, 0, sizeof(s_TmonArray));
+ NvOdmOsMemset(s_TmonMap, 0, sizeof(s_TmonMap));
+ s_Initialized = NV_TRUE;
+ i = 0; // allocation index
+
+ pConn = NvOdmPeripheralGetGuid(TMON_ADT7461_ID);
+ if (pConn)
+ {
+ pTmon = &s_TmonArray[i++];
+ pTmon->pfnInit = Adt7461Init;
+ pTmon->pfnDeinit = Adt7461Deinit;
+ pTmon->pfnTemperatureGet = Adt7461TemperatureGet;
+ pTmon->pfnCapabilitiesGet = Adt7461CapabilitiesGet;
+ pTmon->pfnParameterCapsGet = Adt7461ParameterCapsGet;
+ pTmon->pfnParameterConfig = Adt7461ParameterConfig;
+ pTmon->pfnRun = Adt7461Run;
+ pTmon->pfnStop = Adt7461Stop;
+ pTmon->pfnIntrRegister = Adt7461IntrRegister;
+ pTmon->pfnIntrUnregister = Adt7461IntrUnregister;
+ pTmon->pConn = pConn;
+ pTmon->RefCount = 0;
+ pTmon->pPrivate = NULL;
+
+ // Fill in Zones => TMON devices map
+ NV_ASSERT(pConn->AddressList);
+ for (j = 0; j < pConn->NumAddress; j++)
+ {
+ if (pConn->AddressList[j].Interface == NvOdmIoModule_Tsense)
+ s_TmonMap[pConn->AddressList[j].Instance] = pTmon;
+ }
+ }
+ }
+ // Find TMON instance for the given zone
+ if(ZoneId < NvOdmTmonZoneID_Num)
+ {
+ pTmon = s_TmonMap[ZoneId];
+ if (pTmon && pTmon->pConn)
+ return pTmon;
+ }
+ return NULL;
+}
+
+/*****************************************************************************/
+
+NvOdmTmonDeviceHandle
+NvOdmTmonDeviceOpen(NvOdmTmonZoneID ZoneId)
+{
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon)
+ {
+ NV_ASSERT(pTmon->pfnInit && pTmon->pfnRun);
+ // Init TMON device on the 1st open
+ if (pTmon->RefCount == 0)
+ {
+ if (!pTmon->pfnInit(pTmon))
+ return NULL;
+ }
+ // Make sure targeted zone is monitored
+ if (pTmon->pfnRun(pTmon, ZoneId))
+ {
+ pTmon->RefCount++;
+ return TMON_ZONE_PSEUDOHANDLE(pTmon, ZoneId);
+ }
+ }
+ return NULL;
+}
+
+void NvOdmTmonDeviceClose(NvOdmTmonDeviceHandle hTmon)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon)
+ {
+ NV_ASSERT(pTmon->pfnDeinit && pTmon->pfnStop);
+ (void)pTmon->pfnStop(pTmon, ZoneId);
+ if (pTmon->RefCount == 1)
+ pTmon->pfnDeinit(pTmon);
+
+ if (pTmon->RefCount)
+ {
+ pTmon->RefCount--;
+ return;
+ }
+ NV_ASSERT(!"RefCount balance failed");
+ }
+}
+
+NvBool NvOdmTmonSuspend(NvOdmTmonDeviceHandle hTmon)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnStop);
+ if (pTmon->pfnStop(pTmon, ZoneId))
+ return NV_TRUE;
+ }
+ return NV_FALSE;
+}
+
+NvBool NvOdmTmonResume(NvOdmTmonDeviceHandle hTmon)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnRun);
+ if (pTmon->pfnRun(pTmon, ZoneId))
+ return NV_TRUE;
+ }
+ return NV_FALSE;
+}
+
+/*****************************************************************************/
+
+NvBool
+NvOdmTmonTemperatureGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvS32* pDegreesC)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnTemperatureGet);
+ if (pTmon->pfnTemperatureGet(pTmon, ZoneId, pDegreesC))
+ return NV_TRUE;
+ }
+ return NV_FALSE;
+}
+
+/*****************************************************************************/
+
+void
+NvOdmTmonCapabilitiesGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonCapabilities* pCaps)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnCapabilitiesGet);
+ pTmon->pfnCapabilitiesGet(pTmon, ZoneId, pCaps);
+ }
+ else if (pCaps)
+ {
+ NvOdmOsMemset(pCaps, 0, sizeof(NvOdmTmonCapabilities));
+ pCaps->Tmax = ODM_TMON_PARAMETER_UNSPECIFIED;
+ pCaps->Tmin = ODM_TMON_PARAMETER_UNSPECIFIED;
+ }
+}
+
+void
+NvOdmTmonParameterCapsGet(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonConfigParam ParamId,
+ NvOdmTmonParameterCaps* pCaps)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnParameterCapsGet);
+ pTmon->pfnParameterCapsGet(pTmon, ZoneId, ParamId, pCaps);
+ }
+ else if (pCaps)
+ {
+ NvOdmOsMemset(pCaps, 0, sizeof(NvOdmTmonParameterCaps));
+ pCaps->MaxValue = ODM_TMON_PARAMETER_UNSPECIFIED;
+ pCaps->MinValue = ODM_TMON_PARAMETER_UNSPECIFIED;
+ pCaps->OdmProtected = NV_TRUE;
+ }
+}
+
+NvBool
+NvOdmTmonParameterConfig(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonConfigParam ParamId,
+ NvS32* pSetting)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnParameterConfig);
+ if (pTmon->pfnParameterConfig(pTmon, ZoneId, ParamId, pSetting))
+ return NV_TRUE;
+ }
+ return NV_FALSE;
+}
+
+/*****************************************************************************/
+
+NvOdmTmonIntrHandle
+NvOdmTmonIntrRegister(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmInterruptHandler Callback,
+ void* CallbackArg)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ NvOdmTmonIntrHandle hIntr = NULL;
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnIntrRegister);
+ hIntr = pTmon->pfnIntrRegister(
+ pTmon, ZoneId, Callback, CallbackArg);
+ }
+ return hIntr;
+}
+
+void
+NvOdmTmonIntrUnregister(
+ NvOdmTmonDeviceHandle hTmon,
+ NvOdmTmonIntrHandle hIntr)
+{
+ NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon);
+ NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId);
+
+ if (pTmon && pTmon->RefCount)
+ {
+ NV_ASSERT(pTmon->pfnIntrUnregister);
+ pTmon->pfnIntrUnregister(pTmon, ZoneId, hIntr);
+ }
+}
+
+/*****************************************************************************/
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h
new file mode 100644
index 000000000000..5e5e1141c584
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Abstraction layer stub for Temperature Monitor adaptations</b>
+ */
+
+#ifndef INCLUDED_NVODM_TMON_ADAPTATION_HAL_H
+#define INCLUDED_NVODM_TMON_ADAPTATION_HAL_H
+
+#include "nvcommon.h"
+#include "nvodm_tmon.h"
+#include "nvodm_query_discovery.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef NvBool (*pfnTmonInit)(NvOdmTmonDeviceHandle);
+typedef void (*pfnTmonDeinit)(NvOdmTmonDeviceHandle);
+typedef NvBool (*pfnTmonTemperatureGet)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvS32*);
+typedef void (*pfnTmonCapabilitiesGet)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonCapabilities*);
+typedef void (*pfnTmonParameterCapsGet)
+ (NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonConfigParam, NvOdmTmonParameterCaps*);
+typedef NvBool (*pfnTmonParameterConfig)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonConfigParam, NvS32*);
+typedef NvBool (*pfnTmonRun)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID);
+typedef NvBool (*pfnTmonStop)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID);
+typedef NvOdmTmonIntrHandle
+ (*pfnTmonIntrRegister)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmInterruptHandler, void*);
+typedef void (*pfnTmonIntrUnregister)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonIntrHandle);
+
+typedef struct NvOdmTmonDeviceRec
+{
+ pfnTmonInit pfnInit;
+ pfnTmonDeinit pfnDeinit;
+ pfnTmonTemperatureGet pfnTemperatureGet;
+ pfnTmonCapabilitiesGet pfnCapabilitiesGet;
+ pfnTmonParameterCapsGet pfnParameterCapsGet;
+ pfnTmonParameterConfig pfnParameterConfig;
+ pfnTmonRun pfnRun;
+ pfnTmonStop pfnStop;
+ pfnTmonIntrRegister pfnIntrRegister;
+ pfnTmonIntrUnregister pfnIntrUnregister;
+
+ const NvOdmPeripheralConnectivity* pConn;
+ NvU32 RefCount;
+ void *pPrivate;
+} NvOdmTmonDevice;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //INCLUDED_NVODM_TMON_ADAPTATION_HAL_H
diff --git a/arch/arm/mach-tegra/odm_kit/platform/Makefile b/arch/arm/mach-tegra/odm_kit/platform/Makefile
new file mode 100644
index 000000000000..8cf34fa4b7f6
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/Makefile
@@ -0,0 +1,8 @@
+obj-$(CONFIG_INPUT_TEGRA_ODM_ACCEL) += accelerometer/
+obj-$(CONFIG_INPUT_TEGRA_ODM_SCROLL) += scrollwheel/
+obj-$(CONFIG_KEYBOARD_TEGRA_NVEC) += keyboard/
+obj-$(CONFIG_TOUCHSCREEN_TEGRA_ODM) += touch/
+obj-$(CONFIG_TEGRA_ODM_VIBRATE) += vibrate/
+obj-$(CONFIG_MOUSE_TEGRA_NVEC) += mouse/
+obj-$(CONFIG_TEGRA_BATTERY_NVEC) += battery/
+obj-$(CONFIG_BATTERY_TEGRA_ODM) += battery/
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile
new file mode 100644
index 000000000000..0ec8a6b4ea03
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile
@@ -0,0 +1,12 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_accelerometer_adi340.o
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_accelerometer_bma150.o
+obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_accelerometer_adi340.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c
new file mode 100644
index 000000000000..9a6ae96a3b52
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c
@@ -0,0 +1,1204 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the
+ * WinCE Accelerometer Driver
+ */
+
+
+#include "nvodm_accelerometer_adi340.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvos.h"
+
+#define NV_ACCELEROMETER_REGISTER_RANGE 8
+// When acc is put in horizontal, the max value from acc.
+#define NV_ADI340_ACCELEROMETER_NORMAL_THRESHOLD 30
+#define NV_ADI340_ACCELEROMETER_TAP_THRESHOLD 40
+#define NV_ADI340_LOW_POWER_SAMPLERATE 3
+#define NV_ADI340_FULL_RUN_SAMPLERATE 100
+#define NV_ADI340_FORCE_FACTOR 1000
+#define NV_ADI340_MAX_FORCE_IN_REG 128 // It indicates force register length.
+#define NV_DEBOUNCE_TIME_MS 0
+//static NvU32 g_thresholdG_shadow = 70;
+
+// For interrupt handle, set GPIO when an interrupt happens.
+static void GpioInterruptHandler(void *arg);
+NvBool NvAccelerometerI2COpen(NvOdmServicesI2cHandle* hI2CDevice, NvU32 id);
+void NvAccelerometerI2CClose(NvOdmServicesI2cHandle hI2CDevice);
+NvBool NvAccelerometerI2CSetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len);
+NvBool NvAccelerometerI2CGetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len);
+NvBool NvAccelerometerConnectSemaphore(NvOdmAccelHandle hDevice);
+void NvAccelerometerSetPowerRail(NvOdmServicesPmuHandle hPMUDevice, NvU32 Id, NvBool IsEnable);
+void NvAccelerometerGetInterruptSouce(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType *IntType,
+ NvOdmAccelAxisType *IntMotionAxis,
+ NvOdmAccelAxisType *IntTapAxis);
+
+/*
+ * Set accelerometer registers.
+ * [in] attrib: The register flag.
+ * [out] info: The value to be set into the register of accelerometer.
+ * Returns NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmAccelerometerSetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32 info)
+{
+ // Because there are only 8 bits for one accelerometer register.
+ NvU8 LocalInfo = 0;
+ LocalInfo = (NvU8)(info);
+ // Due to the register length, we only accept the lowest 8 bits.
+ NvOdmOsMemcpy(&LocalInfo, &info, sizeof(NvU8));
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerSetParameter +++\n");
+ switch (attrib)
+ {
+ case XLR_CTL:
+ //NvOdmOsDebugPrintf("set XLR_CTL = 0x%x\n", LocalInfo);
+ hDevice->RegsWrite( hDevice, XLR_CTL, &LocalInfo, 1);
+ break;
+ case XLR_INTCONTROL:
+ //NvOdmOsDebugPrintf("set XLR_INTCONTROL = 0x%x\n", LocalInfo);
+ hDevice->RegsWrite( hDevice, XLR_INTCONTROL, &LocalInfo, 1);
+ break;
+ case XLR_INTCONTROL2:
+ //NvOdmOsDebugPrintf("set XLR_INTCONTROL2 = 0x%x\n", LocalInfo);
+ hDevice->RegsWrite( hDevice, XLR_INTCONTROL2, &LocalInfo, 1);
+ break;
+ case XLR_THRESHG:
+ //NVODMACCELEROMETER_PRINTF("set XLR_THRESHG = 0x%x\n", LocalInfo);
+ hDevice->RegsWrite( hDevice, XLR_THRESHG, &LocalInfo, 1);
+ break;
+ case XLR_THRESHC:
+ hDevice->RegsWrite( hDevice, XLR_THRESHC, &LocalInfo, 1);
+ break;
+ case XLR_OFSX:
+ hDevice->RegsWrite( hDevice, XLR_OFSX, &LocalInfo, 1);
+ break;
+ case XLR_OFSY:
+ hDevice->RegsWrite( hDevice, XLR_OFSY, &LocalInfo, 1);
+ break;
+ case XLR_OFSZ:
+ hDevice->RegsWrite( hDevice, XLR_OFSZ, &LocalInfo, 1);
+ break;
+ case XLR_DUR:
+ hDevice->RegsWrite( hDevice, XLR_DUR, &LocalInfo, 1);
+ break;
+ case XLR_LATENT:
+ hDevice->RegsWrite( hDevice, XLR_LATENT, &LocalInfo, 1);
+ break;
+ case XLR_INTVL:
+ hDevice->RegsWrite( hDevice, XLR_INTVL, &LocalInfo, 1);
+ break;
+ default:
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerSetParameter DONT SUPPORT SUCH ATTRIBUTE ---\n");
+ return NV_FALSE;
+ }
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerSetParameter ---\n");
+ return NV_TRUE;
+}
+
+
+
+/*
+ * Get acceleromter registers.
+ * [in] attrib: The regsiter flag.
+ * [out] info: The value from register of accelerometer.
+ * Returns NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmAccelerometerGetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32* info)
+{
+ NvU8 LocalInfo = 0;
+ NvS32 temp;
+
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter +++\n");
+ switch (attrib)
+ {
+ case XLR_DEVID:
+ hDevice->RegsRead( hDevice, XLR_DEVID, &LocalInfo, 1);
+ break;
+ case XLR_WHOAMI:
+ hDevice->RegsRead( hDevice, XLR_WHOAMI, &LocalInfo, 1);
+ break;
+ case XLR_STATUS:
+ hDevice->RegsRead( hDevice, XLR_STATUS, &LocalInfo, 1);
+ break;
+ case XLR_INTSOURCE:
+ hDevice->RegsRead( hDevice, XLR_INTSOURCE, &LocalInfo, 1);
+ break;
+ case XLR_CTL:
+ hDevice->RegsRead( hDevice, XLR_CTL, &LocalInfo, 1);
+ break;
+ case XLR_INTCONTROL:
+ hDevice->RegsRead( hDevice, XLR_INTCONTROL, &LocalInfo, 1);
+ break;
+ case XLR_INTCONTROL2:
+ hDevice->RegsRead( hDevice, XLR_INTCONTROL2, &LocalInfo, 1);
+ break;
+ case XLR_DATAX:
+ // Because it is a signed char.
+ hDevice->RegsRead( hDevice, XLR_DATAX, &LocalInfo, 1);
+ temp = (LocalInfo<128)?LocalInfo:(LocalInfo-256);
+ NvOdmOsMemcpy(info, &temp, sizeof(NvU32));
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n");
+ return NV_TRUE;
+ case XLR_DATAY:
+ // Because it is a signed char.
+ hDevice->RegsRead( hDevice, XLR_DATAY, &LocalInfo, 1);
+ temp = (LocalInfo<128)?LocalInfo:(LocalInfo-256);
+ NvOdmOsMemcpy(info, &temp, sizeof(NvU32));
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n");
+ return NV_TRUE;
+ case XLR_DATAZ:
+ // Because it is a signed char.
+ hDevice->RegsRead( hDevice, XLR_DATAZ, &LocalInfo, 1);
+ temp = (LocalInfo<128)?LocalInfo:(LocalInfo-256);
+ NvOdmOsMemcpy(info, &temp, sizeof(NvU32));
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n");
+ return NV_TRUE;
+ case XLR_MOREINFO:
+ hDevice->RegsRead( hDevice, XLR_MOREINFO, &LocalInfo, 1);
+ break;
+ case XLR_THRESHG:
+ hDevice->RegsRead( hDevice, XLR_THRESHG, &LocalInfo, 1);
+ break;
+ case XLR_THRESHC:
+ hDevice->RegsRead( hDevice, XLR_THRESHC, &LocalInfo, 1);
+ break;
+ case XLR_OFSX:
+ hDevice->RegsRead( hDevice, XLR_OFSX, &LocalInfo, 1);
+ break;
+ case XLR_OFSY:
+ hDevice->RegsRead( hDevice, XLR_OFSY, &LocalInfo, 1);
+ break;
+ case XLR_OFSZ:
+ hDevice->RegsRead( hDevice, XLR_OFSZ, &LocalInfo, 1);
+ break;
+ case XLR_DUR:
+ hDevice->RegsRead( hDevice, XLR_DUR, &LocalInfo, 1);
+ break;
+ case XLR_LATENT:
+ hDevice->RegsRead( hDevice, XLR_LATENT, &LocalInfo, 1);
+ break;
+ case XLR_INTVL:
+ hDevice->RegsRead( hDevice, XLR_INTVL, &LocalInfo, 1);
+ break;
+ case XLR_SCALE:
+ hDevice->RegsRead( hDevice, XLR_CTL, &LocalInfo, 1);
+ if ((LocalInfo&(0x01)) == 0)
+ {
+ LocalInfo = 2;
+ }
+ else
+ {
+ LocalInfo = 8;
+ }
+ break;
+ case XLR_ROTATE:
+ *info = 1;
+ break;
+ case XLR_GYRO:
+ *info = 0;
+ break;
+ default:
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter DONT SUPPORT SUCH ATTRIBUTE ---\n");
+ return NV_FALSE;
+ }
+ *info = LocalInfo;
+ //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n");
+ return NV_TRUE;
+}
+
+void NvAccelerometerSetPowerRail(NvOdmServicesPmuHandle hPMUDevice, NvU32 Id, NvBool IsEnable)
+{
+ NvOdmServicesPmuVddRailCapabilities vddrailcap;
+ NvU32 settletime;
+
+ if (hPMUDevice)
+ {
+ NvOdmServicesPmuGetCapabilities(hPMUDevice, Id, &vddrailcap);
+ if (IsEnable)
+ {
+ NvOdmServicesPmuSetVoltage(hPMUDevice, Id, vddrailcap.requestMilliVolts, &settletime);
+ }
+ else
+ {
+ NvOdmServicesPmuSetVoltage(hPMUDevice, Id, vddrailcap.MinMilliVolts, &settletime);
+ }
+ NvOdmOsWaitUS(settletime); // wait to settle power
+ }
+}
+
+
+/*
+ * Get interrupt type and source.
+ */
+void NvAccelerometerGetInterruptSouce(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType *IntType,
+ NvOdmAccelAxisType *IntMotionAxis,
+ NvOdmAccelAxisType *IntTapAxis)
+{
+ NvU32 reg_val;
+
+ NV_ASSERT(hDevice != 0);
+ NV_ASSERT(IntType != 0);
+ NV_ASSERT(IntMotionAxis != 0);
+ NV_ASSERT(IntTapAxis != 0);
+
+ *IntType = NvOdmAccelInt_None;
+ *IntMotionAxis = NvOdmAccelAxis_None;
+ *IntTapAxis = NvOdmAccelAxis_None;
+
+ if(NULL != hDevice)
+ {
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTSOURCE, &reg_val);
+ if(reg_val & XLR_INTSOURCE_X_COM_MASK)
+ {
+ *IntType |= NvOdmAccelInt_MotionThreshold;
+ *IntMotionAxis |= NvOdmAccelAxis_X;
+ }
+ if(reg_val & XLR_INTSOURCE_Y_COM_MASK)
+ {
+ *IntType |= NvOdmAccelInt_MotionThreshold;
+ *IntMotionAxis |= NvOdmAccelAxis_Y;
+ }
+ if(reg_val & XLR_INTSOURCE_Z_COM_MASK)
+ {
+ *IntType |= NvOdmAccelInt_MotionThreshold;
+ *IntMotionAxis |= NvOdmAccelAxis_Z;
+ }
+ if(reg_val & XLR_INTSOURCE_X_TAP_MASK)
+ {
+ *IntType |= NvOdmAccelInt_TapThreshold;
+ *IntTapAxis |= NvOdmAccelAxis_X;
+ }
+ if(reg_val & XLR_INTSOURCE_Y_TAP_MASK)
+ {
+ *IntType |= NvOdmAccelInt_TapThreshold;
+ *IntTapAxis |= NvOdmAccelAxis_Y;
+ }
+ if(reg_val & XLR_INTSOURCE_Z_TAP_MASK)
+ {
+ *IntType |= NvOdmAccelInt_TapThreshold;
+ *IntTapAxis |= NvOdmAccelAxis_Z;
+ }
+ }
+ //NvOdmOsDebugPrintf("IntType =%d, IntAxis = %d\n", *IntType, *IntAxis);
+}
+
+
+static void
+GpioInterruptHandler(void *arg)
+{
+ NvOdmGpioPinMode mode;
+
+ NvU32 pinValue;
+ NvOdmAccelHandle hDevice = (NvOdmAccelHandle)arg;
+ //NvOdmOsSemaphoreHandle s = (NvOdmOsSemaphoreHandle)arg;
+
+ NvOdmGpioGetState(hDevice->hGpioINT, hDevice->hPinINT, &pinValue);
+ if (pinValue == 1)
+ {
+ mode = NvOdmGpioPinMode_InputInterruptLow;
+ }
+ else
+ {
+ mode = NvOdmGpioPinMode_InputInterruptHigh;
+ }
+
+ NvOdmGpioConfig(hDevice->hGpioINT, hDevice->hPinINT, mode);
+
+ if (pinValue == 1)
+ {
+ NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT);
+ }
+ NvOdmGpioInterruptDone(hDevice->hGpioInterrupt);
+ return;
+}
+
+/*
+ * Connect semaphore with interrupt pins according to your configuration.
+ */
+NvBool NvAccelerometerConnectSemaphore(NvOdmAccelHandle hDevice)
+{
+ NvOdmGpioPinMode mode;
+ NvOdmInterruptHandler callback = (NvOdmInterruptHandler)GpioInterruptHandler;
+
+ hDevice->hGpioINT = (NvOdmServicesGpioHandle)NvOdmGpioOpen();
+ if(!(hDevice->hGpioINT))
+ {
+ //NVODMACCELEROMETER_PRINTF("NvOdm Accelerometer : NvOdmGpioOpen Error \n");
+ return NV_FALSE;
+ }
+
+ hDevice->hPinINT = NvOdmGpioAcquirePinHandle(hDevice->hGpioINT,
+ hDevice->GPIOPortINT,
+ hDevice->GPIOPinINT);
+
+ hDevice->SemaphoreForINT = NvOdmOsSemaphoreCreate(0);
+
+ if(!(hDevice->SemaphoreForINT))
+ {
+ //NVODMACCELEROMETER_PRINTF("NvOdm Accelerometer : NvOdmOsSemaphoreCreate Error \n");
+ NvOdmGpioClose(hDevice->hGpioINT);
+ return NV_FALSE;
+ }
+
+ mode = NvOdmGpioPinMode_InputInterruptHigh;
+
+ if (NvOdmGpioInterruptRegister(hDevice->hGpioINT, &hDevice->hGpioInterrupt,
+ hDevice->hPinINT, mode, callback, hDevice, NV_DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ return NV_FALSE;
+ }
+
+ if(!(hDevice->hGpioInterrupt))
+ {
+ //NVODMACCELEROMETER_PRINTF("NvOdm Accelerometer : NvOdmGpioInterruptRegister Error \n");
+ NvOdmGpioClose(hDevice->hGpioINT);
+ NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT);
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+/*
+ * Initialize I2C for accelerometer.
+ */
+NvBool NvAccelerometerI2COpen(NvOdmServicesI2cHandle* hI2CDevice, NvU32 id)
+{
+ // Open I2C handle.
+ *hI2CDevice = NvOdmI2cOpen(NvOdmIoModule_I2c, id);
+ if (*hI2CDevice == NULL)
+ {
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+
+/*
+ * De-initialize I2C for accelerometer.
+ */
+void NvAccelerometerI2CClose(NvOdmServicesI2cHandle hI2CDevice)
+{
+ // Close I2C handle.
+ if(NULL != hI2CDevice)
+ {
+ NvOdmI2cClose(hI2CDevice);
+ }
+}
+
+
+/*
+ * Write I2C register function.
+ * offset[Input]: I2C register offset of accelerometer.
+ * value[Input]: register value you will write.
+ * len[Input]: requested bytes.
+ * Returns NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvAccelerometerI2CSetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len)
+{
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ if( (NULL == hDevice) || (NULL == value) || (len > I2C_ACCELRATOR_PACKET_SIZE-1 ))
+ {
+ //NVODMACCELEROMETER_PRINTF("NvOdmI2c Set Regs Failed, max size is %d bytes\n", I2C_ACCELRATOR_PACKET_SIZE-1);
+ return NV_FALSE;
+ }
+
+ NvOdmOsMemset(s_WriteBuffer, 0, sizeof(s_WriteBuffer));
+ s_WriteBuffer[0] = offset;
+ NvOdmOsMemcpy(&s_WriteBuffer[1], value, len);
+
+ TransactionInfo.Address = hDevice->nDevAddr;
+ TransactionInfo.Buf = s_WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = len+1;
+
+ // Write the accelerator offset (from where data is to be read).
+ if(NvOdmI2cStatus_Success != NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, I2C_ACCELRATOR_TRANSACTION_TIMEOUT))
+ {
+ return NV_FALSE;
+ };
+
+ return NV_TRUE;
+}
+
+/*
+ * Read I2C register function.
+ * offset[Input]: I2C register offset of accelerometer.
+ * value[Output]: Fegister value you get.
+ * len[Input]: Requested bytes.
+ * Returns NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+
+NvBool NvAccelerometerI2CGetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len)
+{
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ if( (NULL == hDevice) || (NULL == value) || (len > I2C_ACCELRATOR_PACKET_SIZE-1 ))
+ {
+ //NVODMACCELEROMETER_PRINTF("NvOdmI2c Get Regs Failed, max size is %d bytes\n", I2C_ACCELRATOR_PACKET_SIZE-1);
+ return NV_FALSE;
+ }
+
+ NvOdmOsMemset(s_WriteBuffer, 0, sizeof(s_WriteBuffer));
+ s_WriteBuffer[0] = offset;
+
+ TransactionInfo.Address = hDevice->nDevAddr;
+ TransactionInfo.Buf = s_WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 1;
+
+ // Write the accelerometor offset (from where data is to be read).
+ if(NvOdmI2cStatus_Success != NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, I2C_ACCELRATOR_TRANSACTION_TIMEOUT))
+ {
+ return NV_FALSE;
+ };
+
+ NvOdmOsMemset(s_ReadBuffer, 0, sizeof(s_ReadBuffer));
+ s_ReadBuffer[0] = 0;
+
+ TransactionInfo.Address = (hDevice->nDevAddr| 0x1);
+ TransactionInfo.Buf = s_ReadBuffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = len;
+
+ //Read the data from the eeprom at the specified offset
+ if(NvOdmI2cStatus_Success != NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, I2C_ACCELRATOR_TRANSACTION_TIMEOUT))
+ {
+ return NV_FALSE;
+ };
+
+ NvOdmOsMemcpy(value, &s_ReadBuffer[0], len);
+
+ return NV_TRUE;
+}
+
+//-----------------------------------------------------------------
+//--------------------------------New API--------------------------
+//-----------------------------------------------------------------
+NvBool
+NvOdmAccelOpen(NvOdmAccelHandle* hDevice)
+{
+ NvU32 test_val;
+ NvU32 i;
+ NvBool foundGpio = NV_FALSE, foundI2cModule = NV_FALSE;
+ const NvOdmPeripheralConnectivity *pConnectivity;
+ NvOdmAccelHandle hAccel;
+
+ hAccel = NvOdmOsAlloc(sizeof(NvOdmAccel));
+ if (hAccel == NULL)
+ {
+ //NVODMACCELEROMETER_PRINTF("Error Allocating NvOdmAccel. \n");
+ return NV_FALSE;
+ }
+ NvOdmOsMemset(hAccel, 0, sizeof(NvOdmAccel));
+
+ hAccel->hPmu = NULL;
+ hAccel->hOdmI2C = NULL;
+ hAccel->nBusType = NV_ACCELEROMETER_BUS_I2C;
+
+ // Chip init cfg info here, here just a sample for common interrupt now!
+ // This part will move to a configuration table later.
+ // Start here.
+ // Only enable common interrupt
+ // Enable common and single tap at the same time.
+ hAccel->CtrlRegsList[0].RegAddr = XLR_CTL; //0x12
+ hAccel->CtrlRegsList[0].RegValue = 0x20;
+ hAccel->CtrlRegsList[1].RegAddr = XLR_INTCONTROL; //0x13
+ hAccel->CtrlRegsList[1].RegValue = 0xF3; // modify so that sw is compatible
+ hAccel->CtrlRegsList[2].RegAddr = XLR_INTCONTROL2; //0x14
+ hAccel->CtrlRegsList[2].RegValue = 0xe0;
+ hAccel->CtrlRegsList[3].RegAddr = XLR_THRESHG; //0x1C
+ hAccel->CtrlRegsList[3].RegValue = NV_ADI340_ACCELEROMETER_NORMAL_THRESHOLD;
+ hAccel->CtrlRegsList[4].RegAddr = XLR_OFSX; //0x1E
+ hAccel->CtrlRegsList[4].RegValue = 0;
+ hAccel->CtrlRegsList[5].RegAddr = XLR_OFSY; //0x1F
+ hAccel->CtrlRegsList[5].RegValue = 0;
+ hAccel->CtrlRegsList[6].RegAddr = XLR_OFSZ; //0x20
+ hAccel->CtrlRegsList[6].RegValue = 0;
+ hAccel->CtrlRegsList[7].RegAddr = XLR_THRESHC; //0x1D
+ hAccel->CtrlRegsList[7].RegValue = NV_ADI340_ACCELEROMETER_TAP_THRESHOLD;
+ hAccel->CtrlRegsList[8].RegAddr = XLR_DUR; //0x21
+ hAccel->CtrlRegsList[8].RegValue = 0x40;
+ hAccel->CtrlRegsList[9].RegAddr = XLR_LATENT; //0x22
+ hAccel->CtrlRegsList[9].RegValue = 0xff;
+ hAccel->CtrlRegsList[10].RegAddr = XLR_INTVL; //0x23
+ hAccel->CtrlRegsList[10].RegValue = 0;
+ hAccel->CtrlRegsList[11].RegAddr = XLR_INTCONTROL2; //0x14
+ hAccel->CtrlRegsList[11].RegValue = 0xe1;
+ hAccel->CtrlRegsList[12].RegAddr = XLR_INTCONTROL2; //0x14
+ hAccel->CtrlRegsList[12].RegValue = 0xe0;
+ hAccel->nLength = 13;
+ // Stop here.
+ // Info of accelerometer with current setting.
+ hAccel->Caption.MaxForceInGs = 2000;
+ hAccel->Caption.MaxTapTimeDeltaInUs = 255;
+ hAccel->Caption.NumMotionThresholds = 1;
+ hAccel->Caption.SupportsFreefallInt = 0;
+ hAccel->Caption.MaxSampleRate = 100;
+ hAccel->Caption.MinSampleRate = 3;
+ hAccel->PowerState = NvOdmAccelPower_Fullrun;
+ hAccel->AxisXMapping = NvOdmAccelAxis_X;
+ hAccel->AxisXDirection = 1;
+ hAccel->AxisYMapping = NvOdmAccelAxis_Y;
+ hAccel->AxisYDirection = 1;
+ hAccel->AxisZMapping = NvOdmAccelAxis_Z;
+ hAccel->AxisZDirection = -1;
+
+ hAccel->hPmu = NvOdmServicesPmuOpen();
+ if (!hAccel->hPmu)
+ {
+ //NVODMACCELEROMETER_PRINTF("NvOdmServicesPmuOpen Error \n");
+ goto error;
+ }
+
+ pConnectivity = (NvOdmPeripheralConnectivity*)NvOdmPeripheralGetGuid(NV_ODM_GUID('a','c','c','e','l','e','r','o'));
+ if (!pConnectivity)
+ {
+ NvOdmOsDebugPrintf("NvOdmPeripheralGetGuid doesn't detect accelerometer device\n");
+ goto error;
+ }
+
+ if(pConnectivity->Class != NvOdmPeripheralClass_Other)
+ {
+ goto error;
+ }
+
+ for( i = 0; i < pConnectivity->NumAddress; i++)
+ {
+ switch(pConnectivity->AddressList[i].Interface)
+ {
+ case NvOdmIoModule_I2c:
+ hAccel->I2CChannelId = pConnectivity->AddressList[i].Instance;
+ hAccel->nDevAddr = (NvU8)pConnectivity->AddressList[i].Address;
+ foundI2cModule = NV_TRUE;
+ break;
+ case NvOdmIoModule_Gpio:
+ hAccel->GPIOPortINT = pConnectivity->AddressList[i].Instance;
+ hAccel->GPIOPinINT = pConnectivity->AddressList[i].Address;
+ foundGpio = NV_TRUE;
+ break;
+ case NvOdmIoModule_Vdd:
+ hAccel->VddId = pConnectivity->AddressList[i].Address;
+ // Power on accelerometer according to Vddid
+ NvAccelerometerSetPowerRail(hAccel->hPmu, hAccel->VddId, NV_TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(foundGpio != NV_TRUE || foundI2cModule != NV_TRUE)
+ {
+ //NVODMACCELEROMETER_PRINTF("Accelerometer : didn't find any periperal in discovery query for touch device Error \n");
+ goto error;
+ }
+
+
+ // Set up I2C bus.
+ if(NV_FALSE == NvAccelerometerI2COpen(&hAccel->hOdmI2C, hAccel->I2CChannelId))
+ {
+ goto error;
+ };
+ hAccel->RegsRead = NvAccelerometerI2CGetRegs;
+ hAccel->RegsWrite = NvAccelerometerI2CSetRegs;
+
+ NvOdmAccelerometerGetParameter(hAccel, XLR_WHOAMI, &test_val);
+ if(XLR_IDNUM != test_val)
+ {
+ goto error;
+ }
+
+ NvOdmAccelerometerGetParameter(hAccel, XLR_DEVID, &test_val);
+ if (test_val == XLR_NEWCHIPID)
+ {
+ // This chip is ADXL345
+ //NvOdmOsDebugPrintf("This chip is ADXL345!!!\n");
+ hAccel->CtrlRegsList[4].RegValue = 0x0A; // offset X
+ hAccel->CtrlRegsList[5].RegValue = 0x0B; // offset Y
+ hAccel->CtrlRegsList[6].RegValue = 0x14; // offset Z
+ }
+ //NVODMACCELEROMETER_PRINTF("ID is 0x%x\n", test_val);
+
+ /* We don't know the reset state of the accelerometer. So, program the
+ * accelerometer to disable generation of interrupts.
+ *
+ * Write to INTCONTROL register to disable genetration of the interrupts.
+ * Write to INTCONTROL2 to clear the already latched interrupts.
+ */
+ NvOdmAccelerometerSetParameter(hAccel, XLR_ATTR_INTCONTROL, 0x0);
+ NvOdmAccelerometerSetParameter(hAccel, XLR_ATTR_INTCONTROL2, 0x1);
+ if(NV_FALSE == NvAccelerometerConnectSemaphore(hAccel))
+ {
+ goto error;
+ }
+
+ //init accelerometer
+ for(i=0; i<hAccel->nLength; i++)
+ {
+ NvOdmAccelerometerSetParameter(hAccel,
+ hAccel->CtrlRegsList[i].RegAddr,
+ hAccel->CtrlRegsList[i].RegValue);
+ }
+ // Set up event.
+
+ //NvOdmAccelerometerGetParameter(XLR_SCALE, hAccel);
+ *hDevice = hAccel;
+ return NV_TRUE;
+ error:
+ // Release all of resources requested.
+ if(NULL != hAccel)
+ {
+ NvAccelerometerSetPowerRail(hAccel->hPmu, hAccel->VddId, NV_FALSE);
+ NvOdmServicesPmuClose(hAccel->hPmu);
+ hAccel->hPmu = NULL;
+ NvAccelerometerI2CClose(hAccel->hOdmI2C);
+ hAccel->hOdmI2C = NULL;
+ NvOdmOsFree(hAccel);
+ *hDevice = NULL;
+ }
+ return NV_FALSE;
+}
+
+void
+NvOdmAccelClose(NvOdmAccelHandle hDevice)
+{
+ if(NULL != hDevice)
+ {
+ if(NULL != hDevice->SemaphoreForINT &&
+ NULL != hDevice->hGpioINT &&
+ NULL != hDevice->hPinINT &&
+ NULL != hDevice->hGpioInterrupt)
+ {
+ NvOdmGpioInterruptUnregister(hDevice->hGpioINT,
+ hDevice->hPinINT,
+ hDevice->hGpioInterrupt);
+ NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT);
+ NvOdmGpioReleasePinHandle(hDevice->hGpioINT, hDevice->hPinINT);
+ NvOdmGpioClose(hDevice->hGpioINT);
+ }
+ NvAccelerometerI2CClose(hDevice->hOdmI2C);
+
+ // Power off accelermeter
+ NvAccelerometerSetPowerRail(hDevice->hPmu, hDevice->VddId, NV_FALSE);
+ if (hDevice->hPmu)
+ {
+ //NvAccelerometerSetPowerOn(0);
+ NvOdmServicesPmuClose(hDevice->hPmu);
+ }
+
+ return;
+ }
+}
+
+/*
+ * After setting the force threshold, we should remove all of interrupt flag
+ * that may be left from the last threshold.
+ */
+NvBool
+NvOdmAccelSetIntForceThreshold(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvU32 IntNum,
+ NvU32 Threshold)
+{
+ // At first, we need to translate the threshold to register value for acc.
+ // The first step is get current work range.
+ NvU32 uMaxThreshold;
+ NvU32 uThresholdToRegister;
+ NvU32 temp;
+
+
+ NV_ASSERT(NULL != hDevice);
+ uMaxThreshold = hDevice->Caption.MaxForceInGs;
+ if(Threshold > uMaxThreshold)
+ {
+ //NVODMACCELEROMETER_PRINTF("Current accelerometer supprt max threshold is %d g\n", uMaxThreshold);
+ Threshold = uMaxThreshold;
+ }
+
+ uThresholdToRegister = (NvU8)(Threshold*((1<<(NV_ACCELEROMETER_REGISTER_RANGE-1))-1)/uMaxThreshold);
+
+ // ADI345 can't receive interrupt while threshold = 0
+ if (uThresholdToRegister == 0)
+ uThresholdToRegister = 1;
+
+ // We only enable 2 interrupt pins, INT2 for Motion, INT1 for single tap.
+ switch(IntType)
+ {
+ case NvOdmAccelInt_MotionThreshold:
+ //NvOdmOsDebugPrintf("Current motion setting threshold is %d \n", uThresholdToRegister);
+ //NvOdmOsDebugPrintf("the motion threshold program into reg is %d \n", uThresholdToRegister);
+ NvOdmAccelerometerSetParameter(hDevice, XLR_THRESHG, uThresholdToRegister);
+ break;
+ case NvOdmAccelInt_TapThreshold:
+ //NvOdmOsDebugPrintf("Current tap setting threshold is %d \n", uThresholdToRegister);
+ //NvOdmOsDebugPrintf("the tap threshold program into reg is %d \n", uThresholdToRegister);
+ NvOdmAccelerometerSetParameter(hDevice, XLR_THRESHC, uThresholdToRegister);
+ break;
+ default:
+ //NVODMACCELEROMETER_PRINTF("Do not support such Interrupt!\n");
+ return NV_FALSE;
+ }
+
+ // Clear interrupt flag.
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &temp);
+ temp |= XLR_INTCONTROL2_CLR_INT;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp);
+ temp &= XLR_INTCONTROL2_CLR_INT_MASK;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp);
+ return NV_TRUE;
+}
+
+/*
+ * After setting the time threshold, we should remove all of interrupt flag
+ * that may be left from the last threshold.
+ */
+NvBool
+NvOdmAccelSetIntTimeThreshold(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvU32 IntNum,
+ NvU32 Threshold)
+{
+ NvU32 temp;
+ NV_ASSERT(NULL != hDevice);
+ //its due adi340 limitation.
+ if(Threshold > 0xff)
+ {
+ //NVODMACCELEROMETER_PRINTF("The max threshold support is 255 ms for adi340\n");
+ return NV_FALSE;
+ }
+ //NvOdmOsDebugPrintf("The threshold is %d\n", Threshold);
+ switch(IntType)
+ {
+ case NvOdmAccelInt_TapThreshold:
+ NvOdmAccelerometerSetParameter(hDevice, XLR_DUR, Threshold);
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTVL, 0);
+ NvOdmAccelerometerSetParameter(hDevice, XLR_LATENT, 0);
+ break;
+ default:
+ //NVODMACCELEROMETER_PRINTF("Do not need set time threshold for such Interrupt!\n");
+ return NV_FALSE;
+ }
+
+ // Clear interrupt flag.
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &temp);
+ temp |= XLR_INTCONTROL2_CLR_INT;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp);
+ temp &= XLR_INTCONTROL2_CLR_INT_MASK;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp);
+ return NV_TRUE;
+}
+
+/*
+ * After enable/disable threshold, we should remove all of interrupt flag
+ * that may be left from that last threshold.
+ */
+NvBool
+NvOdmAccelSetIntEnable(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvOdmAccelAxisType IntAxis,
+ NvU32 IntNum,
+ NvBool Toggle)
+{
+ NvU32 uTemp = 0;
+ NV_ASSERT(NULL != hDevice);
+
+ switch(IntType)
+ {
+ case NvOdmAccelInt_MotionThreshold:
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL, &uTemp);
+ //NvOdmOsDebugPrintf("INTCONTROL is 0x%x g\n", uTemp);
+ uTemp |= XLR_INTCONTROL_COM_INT_ENABLE;
+ switch(IntAxis)
+ {
+ case NvOdmAccelAxis_X:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL_COM_SRC_X;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL_COM_SRC_X_MASK;
+ }
+ break;
+ }
+ case NvOdmAccelAxis_Y:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL_COM_SRC_Y;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL_COM_SRC_Y_MASK;
+ }
+ break;
+ }
+ case NvOdmAccelAxis_Z:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL_COM_SRC_Z;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL_COM_SRC_Z_MASK;
+ }
+ break;
+ }
+ case NvOdmAccelAxis_All:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL_COM_SRC_X;
+ uTemp |= XLR_INTCONTROL_COM_SRC_Y;
+ uTemp |= XLR_INTCONTROL_COM_SRC_Z;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL_COM_SRC_X_MASK;
+ uTemp &= XLR_INTCONTROL_COM_SRC_Y_MASK;
+ uTemp &= XLR_INTCONTROL_COM_SRC_Z_MASK;
+ }
+ break;
+ }
+ default:
+ return NV_FALSE;
+ }
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL, uTemp);
+ break;
+ case NvOdmAccelInt_TapThreshold:
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL, &uTemp);
+ //NvOdmOsDebugPrintf("INTCONTROL is 0x%x \n", uTemp);
+ uTemp |= XLR_INTCONTROL_TAP_INT_ENABLE;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL, uTemp);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &uTemp);
+ //NvOdmOsDebugPrintf("INTCONTROL2 is 0x%x \n", uTemp);
+ switch(IntAxis)
+ {
+ case NvOdmAccelAxis_X:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL2_TAP_SRC_X;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL2_TAP_SRC_X_MASK;
+ }
+ break;
+ }
+ case NvOdmAccelAxis_Y:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL2_TAP_SRC_Y;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL2_TAP_SRC_Y_MASK;
+ }
+ break;
+ }
+ case NvOdmAccelAxis_Z:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL2_TAP_SRC_Z;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL2_TAP_SRC_Z_MASK;
+ }
+ break;
+ }
+ case NvOdmAccelAxis_All:
+ {
+ if(Toggle == NV_TRUE)
+ {
+ uTemp |= XLR_INTCONTROL2_TAP_SRC_X;
+ uTemp |= XLR_INTCONTROL2_TAP_SRC_Y;
+ uTemp |= XLR_INTCONTROL2_TAP_SRC_Z;
+ }
+ else
+ {
+ uTemp &= XLR_INTCONTROL2_TAP_SRC_X_MASK;
+ uTemp &= XLR_INTCONTROL2_TAP_SRC_Y_MASK;
+ uTemp &= XLR_INTCONTROL2_TAP_SRC_Z_MASK;
+ }
+ break;
+ }
+ default:
+ return NV_FALSE;
+ }
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, uTemp);
+ break;
+ default:
+ //NVODMACCELEROMETER_PRINTF("Do not support such Interrupt!\n");
+ return NV_FALSE;
+ }
+
+ // Clear interrupt flag.
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &uTemp);
+ uTemp |= XLR_INTCONTROL2_CLR_INT;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, uTemp);
+ uTemp &= XLR_INTCONTROL2_CLR_INT_MASK;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, uTemp);
+ return NV_TRUE;
+}
+
+
+void
+NvOdmAccelWaitInt(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType *IntType,
+ NvOdmAccelAxisType *IntMotionAxis,
+ NvOdmAccelAxisType *IntTapAxis)
+{
+ NvU32 temp;
+ NV_ASSERT(NULL != hDevice);
+ NV_ASSERT(NULL != IntType);
+ NV_ASSERT(NULL != IntMotionAxis);
+ NV_ASSERT(NULL != IntTapAxis);
+
+ NvOdmOsSemaphoreWait( hDevice->SemaphoreForINT);
+
+ NvAccelerometerGetInterruptSouce( hDevice , IntType, IntMotionAxis, IntTapAxis);
+ //NvOdmOsDebugPrintf("Captured interrupt!!!\n");
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &temp);
+ temp |= XLR_INTCONTROL2_CLR_INT;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp);
+ temp &= XLR_INTCONTROL2_CLR_INT_MASK;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp);
+
+ //This is a WAR for ADI340 to prevent I2C register from unstable state
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL, &temp);
+ //NvOdmOsDebugPrintf("XLR_INTCONTROL is 0x%x\n", temp);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_THRESHG, &temp);
+ //NvOdmOsDebugPrintf("XLR_THRESHG is 0x%x\n", temp);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_INTSOURCE, &temp);
+ //NvOdmOsDebugPrintf("XLR_INTSOURCE is 0x%x\n", temp);
+ return ;
+}
+
+
+void NvOdmAccelSignal(NvOdmAccelHandle hDevice)
+{
+ NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT);
+}
+
+NvBool
+NvOdmAccelGetAcceleration(NvOdmAccelHandle hDevice,
+ NvS32 *AccelX,
+ NvS32 *AccelY,
+ NvS32 *AccelZ)
+{
+ NvS32 data = 0;
+ NV_ASSERT(NULL != hDevice);
+ NV_ASSERT(NULL != AccelX);
+ NV_ASSERT(NULL != AccelY);
+ NV_ASSERT(NULL != AccelZ);
+
+ //fix error for adi340 i2c bug. XLR_OFSZ will be set to 0xA0 randomly.
+ NvOdmAccelerometerSetParameter(hDevice, XLR_OFSZ, 0);
+
+ NvOdmAccelerometerGetParameter(hDevice, XLR_DATAX, (NvU32*)&data);
+ //NvOdmOsDebugPrintf("DATAX is %d , after normalization is ", data);
+ data = (((NvS32)(hDevice->Caption.MaxForceInGs))*data+(NvS32)(NV_ADI340_MAX_FORCE_IN_REG/2))/
+ (NvS32)NV_ADI340_MAX_FORCE_IN_REG;
+ switch(hDevice->AxisXMapping)
+ {
+ case NvOdmAccelAxis_X:
+ *AccelX = data*hDevice->AxisXDirection;
+ break;
+ case NvOdmAccelAxis_Y:
+ *AccelY = data*hDevice->AxisYDirection;
+ break;
+ case NvOdmAccelAxis_Z:
+ *AccelZ = data*hDevice->AxisZDirection;
+ break;
+ default:
+ return NV_FALSE;
+ }
+ //NvOdmOsDebugPrintf("%d \n", data);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_DATAY, (NvU32*)&data);
+ //NvOdmOsDebugPrintf("DATAY is %d , after normalization is ", data);
+ data = (((NvS32)(hDevice->Caption.MaxForceInGs))*data+(NvS32)(NV_ADI340_MAX_FORCE_IN_REG/2))/
+ (NvS32)NV_ADI340_MAX_FORCE_IN_REG;
+ switch(hDevice->AxisYMapping)
+ {
+ case NvOdmAccelAxis_X:
+ *AccelX = data*hDevice->AxisXDirection;
+ break;
+ case NvOdmAccelAxis_Y:
+ *AccelY = data*hDevice->AxisYDirection;
+ break;
+ case NvOdmAccelAxis_Z:
+ *AccelZ = data*hDevice->AxisZDirection;
+ break;
+ default:
+ return NV_FALSE;
+ }
+ //NvOdmOsDebugPrintf("%d \n", data);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_DATAZ, (NvU32*)&data);
+ //NvOdmOsDebugPrintf("DATAZ is %d , after normalization is ", data);
+ data = (((NvS32)(hDevice->Caption.MaxForceInGs))*data+(NvS32)(NV_ADI340_MAX_FORCE_IN_REG/2))/
+ (NvS32)NV_ADI340_MAX_FORCE_IN_REG;
+ switch(hDevice->AxisZMapping)
+ {
+ case NvOdmAccelAxis_X:
+ *AccelX = data*hDevice->AxisXDirection;
+ break;
+ case NvOdmAccelAxis_Y:
+ *AccelY = data*hDevice->AxisYDirection;
+ break;
+ case NvOdmAccelAxis_Z:
+ *AccelZ = data*hDevice->AxisZDirection;
+ break;
+ default:
+ return NV_FALSE;
+ }
+ //NvOdmOsDebugPrintf("%d \n", data);
+ return NV_TRUE;
+}
+
+NvOdmAccelerometerCaps
+NvOdmAccelGetCaps(NvOdmAccelHandle hDevice)
+{
+ NV_ASSERT(NULL != hDevice);
+
+ return hDevice->Caption;
+}
+
+NvBool
+NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate)
+{
+ NvU32 PowerFlag = 0;
+ NV_ASSERT(NULL != hDevice);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_CTL, &PowerFlag);
+ if(SampleRate > NV_ADI340_LOW_POWER_SAMPLERATE)////3 is the info get from datasheet
+ {
+ //if(NvOdmAccelPower_Fullrun != hDevice->PowerState)
+ {
+ PowerFlag &= XLR_CTL_POWER_MASK;
+ PowerFlag |= XLR_CTL_FULL_RUN;
+ PowerFlag &= XLR_CTL_MODE_MASK;
+ PowerFlag |= XLR_CTL_MEASURE_MODE;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag);
+ hDevice->PowerState = NvOdmAccelPower_Fullrun;
+ }
+ }
+ else
+ {
+ //if(NvOdmAccelPower_Low != hDevice->PowerState)
+ {
+ PowerFlag &= XLR_CTL_POWER_MASK;
+ PowerFlag |= XLR_CTL_LOW_POWER;
+ PowerFlag &= XLR_CTL_MODE_MASK;
+ PowerFlag |= XLR_CTL_MEASURE_MODE;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag);
+ hDevice->PowerState = NvOdmAccelPower_Low;
+ }
+ }
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate)
+{
+ NvU32 SampleFlag = 0;
+ NV_ASSERT(NULL != hDevice);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_CTL, &SampleFlag);
+
+ if((SampleFlag&XLR_CTL_LOW_POWER))
+ {
+ *pSampleRate = NV_ADI340_LOW_POWER_SAMPLERATE;
+ }
+ else
+ {
+ *pSampleRate = NV_ADI340_FULL_RUN_SAMPLERATE;
+ }
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmAccelSetPowerState(NvOdmAccelHandle hDevice, NvOdmAccelPowerType PowerState)
+{
+ NvU32 PowerFlag = 0;
+ NV_ASSERT(NULL != hDevice);
+ NvOdmAccelerometerGetParameter(hDevice, XLR_CTL, &PowerFlag);
+ switch(PowerState)
+ {
+ case NvOdmAccelPower_Fullrun:
+ if(NvOdmAccelPower_Fullrun != hDevice->PowerState)
+ {
+ PowerFlag &= XLR_CTL_POWER_MASK;
+ PowerFlag |= XLR_CTL_FULL_RUN;
+ PowerFlag &= XLR_CTL_MODE_MASK;
+ PowerFlag |= XLR_CTL_MEASURE_MODE;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag);
+ hDevice->PowerState = NvOdmAccelPower_Fullrun;
+ }
+ break;
+ case NvOdmAccelPower_Low:
+ if(NvOdmAccelPower_Low != hDevice->PowerState)
+ {
+ PowerFlag &= XLR_CTL_POWER_MASK;
+ PowerFlag |= XLR_CTL_LOW_POWER;
+ PowerFlag &= XLR_CTL_MODE_MASK;
+ PowerFlag |= XLR_CTL_MEASURE_MODE;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag);
+ hDevice->PowerState = NvOdmAccelPower_Low;
+ }
+ break;
+ case NvOdmAccelPower_Standby:
+ if(NvOdmAccelPower_Standby != hDevice->PowerState)
+ {
+ PowerFlag &= XLR_CTL_MODE_MASK;
+ PowerFlag |= XLR_CTL_STANDBY_MODE;
+ NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag);
+ hDevice->PowerState = NvOdmAccelPower_Standby;
+ }
+ break;
+ case NvOdmAccelPower_Off:
+ //the implementation should consider real board connection
+ //sometimes we need use acc's interrupt to resum the whole
+ //system, so the power are alway supplied.
+ return NV_FALSE;
+ default:
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h
new file mode 100644
index 000000000000..3febae3b1f40
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the
+ * WinCE Accelerometer Driver
+ */
+
+#ifndef INCLUDED_NVODM_ACCELEROMETER_ADI340_H
+#define INCLUDED_NVODM_ACCELEROMETER_ADI340_H
+
+#if defined(_cplusplus)
+extern "C"
+{
+#endif
+
+#include "nvodm_services.h"
+#include "nvodm_accelerometer.h"
+
+ /* Will keep some attributes from customer in the future */
+ #define XLR_ATTR_CTL 0
+ #define XLR_ATTR_INTCONTROL 1
+ #define XLR_ATTR_INTCONTROL2 2
+ #define XLR_ATTR_THRESHG 3
+ #define XLR_ATTR_THRESHC 4
+ #define XLR_ATTR_OFSX 5
+ #define XLR_ATTR_OFSY 6
+ #define XLR_ATTR_OFSZ 7
+ #define XLR_ATTR_DUR 8
+ #define XLR_ATTR_LATENT 9
+ #define XLR_ATTR_INTVL 10
+ #define XLR_ATTR_WHOAMI 11
+ #define XLR_ATTR_STATUS 12
+ #define XLR_ATTR_INTSOURCE 13
+ #define XLR_ATTR_DATAX 14
+ #define XLR_ATTR_DATAY 15
+ #define XLR_ATTR_DATAZ 16
+ #define XLR_ATTR_MOREINFO 17
+ #define XLR_ATTR_SCALE 18
+ #define XLR_ATTR_ROTATE 19
+ #define XLR_ATTR_GYRO 20
+
+// AD22345 register definitions
+#define XLR_DEVID 0x00
+
+// AD22340 register definitions
+#define XLR_WHOAMI 0x0f // RO - device identification
+#define XLR_STATUS 0x10 // RO - device status bits
+#define XLR_STATUS_DATA_READY 0x80 //0b10000000 indicate that data in XLR_DATAX,Y,Z can be read.
+#define XLR_STATUS_DATA_OVERRUN 0x02 //0b00000010 indicate that the old data in XLR_DATAX,Y,Z have not be read
+#define XLR_STATUS_INTRRUPT_PENDING 0x01 //0b00000001 indicate that interrupt is active.
+
+#define XLR_INTSOURCE 0x11 // RO - interrupt source
+#define XLR_INTSOURCE_X_TAP_MASK 0x80 //0b10000000 tap interrupt is from x-axis
+#define XLR_INTSOURCE_Y_TAP_MASK 0x40 //0b01000000 tap interrupt is from y-axis
+#define XLR_INTSOURCE_Z_TAP_MASK 0x20 //0b00100000 tap interrupt is from z-axis
+#define XLR_INTSOURCE_X_COM_MASK 0x10 //0b00010000 comm interrupt is from x-axis
+#define XLR_INTSOURCE_Y_COM_MASK 0x8 //0b00001000 comm interrupt is from y-axis
+#define XLR_INTSOURCE_Z_COM_MASK 0x4 //0b00000100 comm interrupt is from z-axis
+#define XLR_INTSOURCE_SINGLE_TAP_MASK 0x2 //0b00000010 single tap mask
+#define XLR_INTSOURCE_DOUBLE_TAP_MASK 0x1 //0b00000001 double tap mask
+
+#define XLR_CTL 0x12 // RW - device control reg
+#define XLR_CTL_POWER_MASK 0xbf //0b10111111
+#define XLR_CTL_LOW_POWER 0x40 //0b01000000 low power mode
+#define XLR_CTL_FULL_RUN 0x00 //0b00000000 full run mode
+#define XLR_CTL_MODE_MASK 0xdf //0b11011111
+#define XLR_CTL_STANDBY_MODE 0x0 //0b00000000 standby mode
+#define XLR_CTL_MEASURE_MODE 0x20 //0b00100000 measure mode
+#define XLR_CTL_SPI_3_BUS 0x0 //0b00000000 3 wires SPI mode
+#define XLR_CTL_SPI_4_BUS 0x10 //0b00010000 4 wires SPI mode
+#define XLR_CTL_SELF_TEST_MODE 0x4 //0b00000100 self test mode
+#define XLR_CTL_INT1_FUNC_MASK 0xfd //0b11111101 range mask
+#define XLR_CTL_INT1_DATA_READY_MODE 0x2 //0b00000010 INT1 pin is data ready flag
+#define XLR_CTL_INT1_INTRUPT_MODE 0x0 //0b00000000 INT1 pin is interrupt flag
+#define XLR_CTL_RANGE_MASK 0xfe //0b11111110 range mask
+#define XLR_CTL_8G_RANGE 0x1 //0b00000001 range is 8g
+#define XLR_CTL_2G_RANGE 0x0 //0b00000000 range is 2g
+
+#define XLR_INTCONTROL 0x13 // RW - interrupt control/config reg
+#define XLR_INTCONTROL_COM_SRC_X_MASK 0x7f //0b01111111
+#define XLR_INTCONTROL_COM_SRC_X 0x80 //0b10000000 x participate common interrupt
+#define XLR_INTCONTROL_COM_SRC_Y_MASK 0xbf //0b10111111
+#define XLR_INTCONTROL_COM_SRC_Y 0x40 //0b01000000 y participate common interrupt
+#define XLR_INTCONTROL_COM_SRC_Z_MASK 0xdf //0b11011111
+#define XLR_INTCONTROL_COM_SRC_Z 0x20 //0b00100000 z participate common interrupt
+#define XLR_INTCONTROL_SINGLE_DOUBLE_MASK 0xef //0b11101111
+#define XLR_INTCONTROL_SINGLE_TAP 0x10 //0b00010000 detect single tap
+#define XLR_INTCONTROL_DOUBLE_TAP 0x0 //0b00000000 detect double tap
+#define XLR_INTCONTROL_INTERRUPT_MAP_MASK 0xfb //0b11111011
+#define XLR_INTCONTROL_INTERRUPT_MAP1 0x4 //0b00000100 common interrupt map to INT2, tap interrupt map to INT1
+#define XLR_INTCONTROL_INTERRUPT_MAP2 0x0 //0b00000000 common interrupt map to INT1, tap interrupt map to INT2
+#define XLR_INTCONTROL_TAP_INT_MASK 0xfd //0b11111101
+#define XLR_INTCONTROL_TAP_INT_ENABLE 0x2 //0b00000010 enable the tap interrupt.
+#define XLR_INTCONTROL_COM_INT_MASK 0xfe //0b11111110
+#define XLR_INTCONTROL_COM_INT_ENABLE 0x1 //0b00000001 enable the common interrupt.
+
+#define XLR_INTCONTROL2 0x14 // RW - interrupt control/config reg 2
+#define XLR_INTCONTROL2_TAP_SRC_X_MASK 0x7f //0b01111111
+#define XLR_INTCONTROL2_TAP_SRC_X 0x80 //0b10000000 x participate tap interrupt
+#define XLR_INTCONTROL2_TAP_SRC_Y_MASK 0xbf //0b10111111
+#define XLR_INTCONTROL2_TAP_SRC_Y 0x40 //0b01000000 y participate tap interrupt
+#define XLR_INTCONTROL2_TAP_SRC_Z_MASK 0xdf //0b11011111
+#define XLR_INTCONTROL2_TAP_SRC_Z 0x20 //0b00100000 z participate tap interrupt
+#define XLR_INTCONTROL2_CLR_INT_MASK 0xfe //0b11111110
+#define XLR_INTCONTROL2_CLR_INT 0x1 //0b00000001 clear interrupt bit and pin
+
+#define XLR_DATAX 0x15 // RO - data from X axis
+#define XLR_DATAY 0x16 // RO - data from Y axis
+#define XLR_DATAZ 0x17 // RO - data from Z axis
+#define XLR_MOREINFO 0x1b // RO - additional device info
+
+#define XLR_THRESHG 0x1c // RW - common interrupt threshold reg
+#define XLR_THRESHC 0x1d // RW - click threshold reg
+
+#define XLR_OFSX 0x1e // RW - x axis offset reg
+#define XLR_OFSY 0x1f // RW - y axis offset reg
+#define XLR_OFSZ 0x20 // RW - z axis offset reg
+#define XLR_DUR 0x21 // RW - click duration reg
+#define XLR_LATENT 0x22 // RW - click latency reg
+#define XLR_INTVL 0x23 // RW - click interval reg
+
+//virtual register which should translated in driver.
+#define XLR_SCALE 0x24
+#define XLR_ROTATE 0x25
+#define XLR_GYRO 0x26
+
+/*
+ * Defines the threshold source for the accelerometer.
+ */
+typedef enum
+{
+ /// Indicates the accelerometer generated interrupt by exceeding the x threshold.
+ NvOdmAccelerometerThresholdSource_X = 0,
+
+ /// Indicates the accelerometer generated interrupt by exceeding the y threshold.
+ NvOdmAccelerometerThresholdSource_Y,
+
+ /// Indicates the accelerometer generated interrupt by exceeding the z threshold.
+ NvOdmAccelerometerThresholdSource_Z,
+
+ NvOdmAccelerometerThresholdSource_Force32 = 0x7FFFFFFF
+} NvOdmAccelerometerThresholdSource;
+
+// I2C device address from accelerator.
+enum { I2C_ACCELRATOR_ADDRESS = 0x3A};
+// Timeout for I2C transaction.
+enum { I2C_ACCELRATOR_TRANSACTION_TIMEOUT = 1000 };
+// Maximum number of packetsize supported by the I2C controller.
+enum { I2C_ACCELRATOR_PACKET_SIZE = 8};
+static NvU8 s_ReadBuffer[I2C_ACCELRATOR_PACKET_SIZE];
+static NvU8 s_WriteBuffer[I2C_ACCELRATOR_PACKET_SIZE];
+
+// Fixed device identification code.
+#define XLR_IDNUM 0x4A
+
+#define XLR_NEWCHIPID 0xE5
+
+#define INT_EVENT_TIMEOUT 100
+#define NV_ACCELEROMETER_BUS_I2C 0
+#define NV_ACCELEROMETER_BUS_SPI_3 1
+#define NV_ACCELEROMETER_BUS_SPI_4 2
+/*
+// All of interrupt pins from accelerometer are connected to one interrupt pin of ap15.
+#define NV_ACCELEROMETER_INTERRUPT_GPIO_PORT 'C'-'A'
+#define NV_ACCELEROMETER_INTERRUPT_GPIO_PIN 7
+// only work for ap10 hw connection
+#define NV_ACCELEROMETER_INTERRUPT1_GPIO_PORT 'C'-'A'
+#define NV_ACCELEROMETER_INTERRUPT1_GPIO_PIN 7
+#define NV_ACCELEROMETER_INTERRUPT2_GPIO_PORT 'C'-'A'
+#define NV_ACCELEROMETER_INTERRUPT2_GPIO_PIN 1
+*/
+/*g value under 8g*/
+#define NVODM_ACCELEROMETER_G_UNDER_8G 16
+/*g value under 2g*/
+#define NVODM_ACCELEROMETER_G_UNDER_2G 64
+
+// Module debug: 0=disable, 1=enable
+#define NVODMACCELEROMETER_ENABLE_PRINTF (0)
+
+#if NVODMACCELEROMETER_ENABLE_PRINTF
+ #define NVODMACCELEROMETER_PRINTF NvOdmOsDebugPrintf
+#else
+ #define NVODMACCELEROMETER_PRINTF (void)
+#endif
+/*
+ * Defines the way to read accelerometer registers.
+ */
+typedef NvBool (*AccelerometerRegsRead)(NvOdmAccelHandle hDevice, NvU8 nRegOffset, NvU8* nData, NvU32 nLen);
+/*
+ * Defines the way to write accelerometer registers.
+ */
+typedef NvBool (*AccelerometerRegsWrite)(NvOdmAccelHandle hDevice, NvU8 nRegOffset, NvU8* nData, NvU32 nLen);
+/*
+ * Holds register address and value pairs.
+ */
+typedef struct NvDevCtrlRegRec {
+ /// Holds the register offset.
+ NvU8 RegAddr;
+ /// Holds the value programmed into the upper address.
+ NvU8 RegValue;
+} NvDevCtrlReg;
+/*
+ * Max accelerometer registers number.
+ */
+#define ACCELEROMETER_CONTROL_REGS_MAX_LENGHT 100
+/*
+ * Max accelerometer callback functions number.
+ */
+#define ACCELEROMETER_CALLBACK_ARRAY_LENGTH 5
+
+/*
+ * Gets parameters relating to the accelerometer.
+ * attrib: Specifies the attributes to get.
+ * - XLR_ATTR_DATAX--gets data from x-axis.
+ * - XLR_ATTR_DATAY--gets data from y-axis.
+ * - XLR_ATTR_DATAZ--gets data from z-axis.
+ * - XLR_ATTR_OFSX--gets the x-axis offset.
+ * - XLR_ATTR_OFSY--gets the y-axis offset.
+ * - XLR_ATTR_OFSZ--gets the z-axis offset.
+ *
+ * info: A pointer to the returned parameters.
+ * Returns NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool
+NvOdmAccelerometerGetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32* info);
+
+/*
+ * Sets parameters relating to the accelerometer,
+ * according to the caller's requirements.
+ * attrib: Specifies the attributes to set.
+ * - XLR_ATTR_OFSX--sets the x-axis offset.
+ * - XLR_ATTR_OFSY--sets the y-axis offset.
+ * - XLR_ATTR_OFSZ--sets the z-axis offset.
+ * info: Specifies the parameter information to set.
+ * Returns NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+
+NvBool
+NvOdmAccelerometerSetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32 info);
+
+//-----------------------------------------------------------------
+//--------------------------New API--------------------------------
+//-----------------------------------------------------------------
+
+typedef struct NvOdmAccelRec
+{
+ // Specifies use I2C or SPI to configure accelerometer registers.
+ NvU8 nBusType;
+ // Specifies accelerometer device address, for example, I2C write address.
+ NvU8 nDevAddr;
+ // Specifies the initial value that make accelerometer work, ACCELEROMETER_CONTROL_REGS_MAX_LENGHT is always 100.
+ NvDevCtrlReg CtrlRegsList[ACCELEROMETER_CONTROL_REGS_MAX_LENGHT];
+ // Specifies the initial CtrlRegsList length.
+ NvU8 nLength;
+ // Specifies accelerometer chip ID.
+ NvU8 nChipID;
+ // Specifies the way to get accelerometer register information.
+ AccelerometerRegsRead RegsRead;
+ // Specifies the way to set accelerometer register information.
+ AccelerometerRegsWrite RegsWrite;
+ // Specifies I2C handle from the system.
+ NvOdmServicesI2cHandle hOdmI2C;
+ // Interrupt pin to ap15.
+ NvOdmServicesGpioHandle hGpioINT;
+ NvOdmGpioPinHandle hPinINT;
+ NvU32 GPIOPortINT;
+ NvU32 GPIOPinINT;
+ NvOdmOsSemaphoreHandle SemaphoreForINT;
+ NvOdmServicesGpioIntrHandle hGpioInterrupt;
+ NvOdmAccelIntType Data;
+ NvOdmServicesPmuHandle hPmu;
+ NvU32 VddId;
+ NvU32 I2CChannelId;
+ NvOdmAccelerometerCaps Caption;
+ NvOdmAccelPowerType PowerState;
+ // In real case, when the board put in frontispiece, the value from z axis
+ // should be g, but due to physical connect on different board, the axis
+ // should be remapped to the correct one.
+ NvOdmAccelAxisType AxisXMapping;
+ // If the physical direct is the same with our expection, the value
+ // should be set to 1, or else the value should be -1.
+ NvS32 AxisXDirection;
+ NvOdmAccelAxisType AxisYMapping;
+ NvS32 AxisYDirection;
+ NvOdmAccelAxisType AxisZMapping;
+ NvS32 AxisZDirection;
+} NvOdmAccel;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c
new file mode 100644
index 000000000000..aedf87c837a9
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the
+ * WinCE Accelerometer Driver
+ */
+
+#include "nvodm_accelerometer_bma150.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvos.h"
+
+#define NVODMACCELEROMETER_ENABLE_PRINTF 0
+
+#if NVODMACCELEROMETER_ENABLE_PRINTF
+ #define NVODMACCELEROMETER_PRINTF(x) \
+ do { \
+ NvOdmOsPrintf x; \
+ } while (0)
+#else
+ #define NVODMACCELEROMETER_PRINTF(x)
+#endif
+
+#define NV_BMA150_MAX_FORCE_IN_REG 512 // It indicates force register length.
+#define NV_DEBOUNCE_TIME_MS 0
+
+#define ENABLE_XYZ_POLLING 0
+
+//FIXME: protect this variable using spinlock.
+static volatile int g_WaitCounter = 0;
+static void BMA150_ResetInterrupt(NvOdmAccelHandle hDevice);
+
+static void
+SetPowerRail(
+ NvOdmServicesPmuHandle hPMUDevice,
+ NvU32 Id,
+ NvBool IsEnable)
+{
+ NvOdmServicesPmuVddRailCapabilities vddrailcap;
+ NvU32 settletime;
+
+ if (hPMUDevice && Id)
+ {
+ NvOdmServicesPmuGetCapabilities(hPMUDevice, Id, &vddrailcap);
+ if (IsEnable)
+ {
+ NvOdmServicesPmuSetVoltage(hPMUDevice, Id,
+ vddrailcap.requestMilliVolts, &settletime);
+ }
+ else
+ {
+ NvOdmServicesPmuSetVoltage(hPMUDevice, Id,
+ vddrailcap.MinMilliVolts, &settletime);
+ }
+ NvOdmOsWaitUS(settletime);
+ }
+}
+
+static void GpioInterruptHandler(void *arg)
+{
+ NvU32 pinValue;
+ NvOdmAccelHandle hDevice = (NvOdmAccelHandle)arg;
+
+ NvOdmGpioGetState(hDevice->hGpioINT, hDevice->hPinINT, &pinValue);
+ if (pinValue == 1)
+ {
+ NVODMACCELEROMETER_PRINTF(("\r\nBMA150 Interrupt"));
+ g_WaitCounter = 10;
+ BMA150_ResetInterrupt(hDevice);
+ } else
+ NVODMACCELEROMETER_PRINTF(("\r\nBMA150 non-Interrupt"));
+
+ if (pinValue == 1)
+ {
+ NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT);
+ }
+ NvOdmGpioInterruptDone(hDevice->hGpioInterrupt);
+ return;
+}
+
+static NvBool ConnectSemaphore(NvOdmAccelHandle hDevice)
+{
+ NvOdmGpioPinMode mode;
+ NvOdmInterruptHandler callback =
+ (NvOdmInterruptHandler)GpioInterruptHandler;
+
+ hDevice->hGpioINT = (NvOdmServicesGpioHandle)NvOdmGpioOpen();
+ if (!(hDevice->hGpioINT))
+ {
+ NVODMACCELEROMETER_PRINTF((
+ "NvOdm Accelerometer : NvOdmGpioOpen Error \n"));
+ return NV_FALSE;
+ }
+
+ hDevice->hPinINT = NvOdmGpioAcquirePinHandle(hDevice->hGpioINT,
+ hDevice->GPIOPortINT,
+ hDevice->GPIOPinINT);
+ hDevice->SemaphoreForINT = NvOdmOsSemaphoreCreate(0);
+
+ if (!(hDevice->SemaphoreForINT))
+ {
+ NVODMACCELEROMETER_PRINTF((
+ "NvOdm Accelerometer : NvOdmOsSemaphoreCreate Error \n"));
+ NvOdmGpioClose(hDevice->hGpioINT);
+ return NV_FALSE;
+ }
+
+ mode = NvOdmGpioPinMode_InputInterruptHigh;
+ if (NvOdmGpioInterruptRegister(hDevice->hGpioINT,
+ &hDevice->hGpioInterrupt, hDevice->hPinINT, mode, callback,
+ hDevice, NV_DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ return NV_FALSE;
+ }
+
+ if (!(hDevice->hGpioInterrupt))
+ {
+ NVODMACCELEROMETER_PRINTF((
+ "NvOdm Accelerometer : NvOdmGpioInterruptRegister Error \n"));
+ NvOdmGpioClose(hDevice->hGpioINT);
+ NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT);
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+WriteReg(
+ NvOdmAccelHandle hDevice,
+ NvU8 RegAddr,
+ NvU8* value,
+ NvU32 len)
+{
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ if ( (NULL == hDevice) || (NULL == value) ||
+ (len > I2C_ACCELRATOR_PACKET_SIZE-1 ) )
+ {
+ NVODMACCELEROMETER_PRINTF((
+ "NvOdmI2c Set Regs Failed, max size is %d bytes\n",
+ I2C_ACCELRATOR_PACKET_SIZE-1));
+ return NV_FALSE;
+ }
+
+ s_WriteBuffer[0] = RegAddr;
+ NvOdmOsMemcpy(&s_WriteBuffer[1], value, len);
+
+ TransactionInfo.Address = hDevice->nDevAddr;
+ TransactionInfo.Buf = s_WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = len+1;
+
+ // Write the accelerator RegAddr (from where data is to be read).
+ if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400,
+ I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success)
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+static NvBool
+ReadReg(
+ NvOdmAccelHandle hDevice,
+ NvU8 RegAddr,
+ NvU8* value,
+ NvU32 len)
+{
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ if ( (NULL == hDevice) || (NULL == value) ||
+ (len > I2C_ACCELRATOR_PACKET_SIZE-1 ) )
+ {
+ NVODMACCELEROMETER_PRINTF((
+ "NvOdmI2c Get Regs Failed, max size is %d bytes\n",
+ I2C_ACCELRATOR_PACKET_SIZE-1));
+ return NV_FALSE;
+ }
+
+ s_WriteBuffer[0] = RegAddr;
+ TransactionInfo.Address = hDevice->nDevAddr;
+ TransactionInfo.Buf = s_WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 1;
+
+ // Write the accelerometor RegAddr (from where data is to be read).
+ if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400,
+ I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success)
+ return NV_FALSE;
+
+ s_ReadBuffer[0] = 0;
+ TransactionInfo.Address = (hDevice->nDevAddr| 0x1);
+ TransactionInfo.Buf = s_ReadBuffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = len;
+
+ //Read the data from the eeprom at the specified RegAddr
+ if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400,
+ I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success)
+ return NV_FALSE;
+
+ NvOdmOsMemcpy(value, &s_ReadBuffer[0], len);
+ return NV_TRUE;
+}
+
+static NvBool BMA150_Init(NvOdmAccelHandle hAccel)
+{
+ NvU8 TestVal;
+
+ ReadReg(hAccel, CHIP_ID_REG, &TestVal, 1);
+ if (TestVal != BMA150_CHIP_ID)
+ {
+ NVODMACCELEROMETER_PRINTF(("Unknown BMA150 ID = 0x%x\n", TestVal));
+ goto error;
+ }
+ NVODMACCELEROMETER_PRINTF(("BMA150 ID is 0x%x\n", TestVal));
+
+ // Init Hw
+ if (!ReadReg(hAccel, RANGE_BWIDTH_REG, &TestVal, 1))
+ goto error;
+ TestVal &= 0xE0;
+ TestVal |= 0x04; //Set bandwidth to 375hz
+ if (!WriteReg(hAccel, RANGE_BWIDTH_REG, &TestVal, 1))
+ goto error;
+
+ if (!ReadReg(hAccel, SMB150_CONF2_REG, &TestVal, 1))
+ goto error;
+ // Enable Advanced interrupt(6), latch int(4)
+ TestVal |= (0 << 3) | (1 << 6) | (1 << 4);
+ if (!WriteReg(hAccel, SMB150_CONF2_REG, &TestVal, 1))
+ goto error;
+ // Init Hw end
+ // Set mode
+ if (!ReadReg(hAccel, SMB150_CTRL_REG, &TestVal, 1))
+ goto error;
+ TestVal &= 0xFE;
+ if (!WriteReg(hAccel, SMB150_CTRL_REG, &TestVal, 1))
+ goto error;
+ // Set mode end
+
+ // Set motion thres
+ if (!ReadReg(hAccel, MOTION_THRS_REG, &TestVal, 1))
+ goto error;
+ TestVal = 0x0A;
+ if (!WriteReg(hAccel, MOTION_THRS_REG, &TestVal, 1))
+ goto error;
+ // Set motion thres end
+
+ // Set any motion int
+ if (!ReadReg(hAccel, SMB150_CONF1_REG, &TestVal, 1))
+ goto error;
+ TestVal &= 0xFC;
+ TestVal |= (1 << 6) | (1 << 1) | (1 << 0);
+ if (!WriteReg(hAccel, SMB150_CONF1_REG, &TestVal, 1))
+ goto error;
+ // Set any motion int end
+ NVODMACCELEROMETER_PRINTF(("\n BMA150_Init passed"));
+ return NV_TRUE;
+error:
+ NVODMACCELEROMETER_PRINTF(("\n BMA150_Init failed"));
+ return NV_FALSE;
+}
+
+static NvBool
+BMA150_ReadXYZ(
+ NvOdmAccelHandle hDevice,
+ NvS32* X,
+ NvS32* Y,
+ NvS32* Z)
+{
+ NvU8 Data[6];
+ NvBool NewData = 0;
+
+ if (!ReadReg(hDevice, X_AXIS_LSB_REG, &Data[0], 6))
+ return NV_FALSE;
+ NewData = ( (Data[0] & 0x1) || (Data[2] & 0x1) || (Data[4] & 0x1) ) ? 1 : 0;
+
+ *X = ((Data[1] << 2) | (Data[0] >> 6));
+ *Y = ((Data[3] << 2) | (Data[2] >> 6));
+ *Z = ((Data[5] << 2) | (Data[4] >> 6));
+
+ // Preserve sign bits.
+ *X = *X << ((sizeof(*X)*8) - 10);
+ *X = *X >> ((sizeof(*X)*8) - 10);
+ *Y = *Y << ((sizeof(*Y)*8) - 10);
+ *Y = *Y >> ((sizeof(*Y)*8) - 10);
+ *Z = *Z << ((sizeof(*Z)*8) - 10);
+ *Z = *Z >> ((sizeof(*Z)*8) - 10);
+ return NewData;
+}
+
+static void BMA150_ResetInterrupt(NvOdmAccelHandle hDevice)
+{
+ NvU8 Data = (1 << 6);
+
+ WriteReg(hDevice, SMB150_CTRL_REG, &Data, 1);
+}
+
+NvBool NvOdmAccelOpen(NvOdmAccelHandle* hDevice)
+{
+ NvU32 i;
+ NvOdmAccelHandle hAccel;
+ NvOdmIoModule IoModule = NvOdmIoModule_I2c;
+ const NvOdmPeripheralConnectivity *pConnectivity;
+ NvBool FoundGpio = NV_FALSE, FoundI2cModule = NV_FALSE;
+
+ hAccel = NvOdmOsAlloc(sizeof(NvOdmAccel));
+ if (hAccel == NULL)
+ {
+ NVODMACCELEROMETER_PRINTF(("Error Allocating NvOdmAccel. \n"));
+ return NV_FALSE;
+ }
+ NvOdmOsMemset(hAccel, 0, sizeof(NvOdmAccel));
+ hAccel->nBusType = NV_ACCELEROMETER_BUS_I2C;
+
+ // Info of accelerometer with current setting.
+ hAccel->Caption.MaxForceInGs = 2000;
+ hAccel->Caption.MaxTapTimeDeltaInUs = 255;
+ hAccel->Caption.NumMotionThresholds = 1;
+ hAccel->Caption.SupportsFreefallInt = 0;
+ hAccel->Caption.MaxSampleRate = 100;
+ hAccel->Caption.MinSampleRate = 3;
+ hAccel->PowerState = NvOdmAccelPower_Fullrun;
+ hAccel->AxisXMapping = NvOdmAccelAxis_Y;
+ hAccel->AxisXDirection = -1;
+ hAccel->AxisYMapping = NvOdmAccelAxis_X;
+ hAccel->AxisYDirection = 1;
+ hAccel->AxisZMapping = NvOdmAccelAxis_Z;
+ hAccel->AxisZDirection = -1;
+
+ hAccel->hPmu = NvOdmServicesPmuOpen();
+ if (!hAccel->hPmu)
+ {
+ NVODMACCELEROMETER_PRINTF(("NvOdmServicesPmuOpen Error \n"));
+ goto error;
+ }
+
+ pConnectivity = (NvOdmPeripheralConnectivity*)NvOdmPeripheralGetGuid(
+ NV_ODM_GUID('b','m','a','1','5','0','a','c'));
+ if (!pConnectivity)
+ {
+ NvOdmOsDebugPrintf(("NvOdmPeripheralGetGuid doesn't detect\
+ BMA150 accelerometer device\n"));
+ goto error;
+ }
+
+ if (pConnectivity->Class != NvOdmPeripheralClass_Other)
+ goto error;
+
+ for( i = 0; i < pConnectivity->NumAddress; i++)
+ {
+ switch(pConnectivity->AddressList[i].Interface)
+ {
+ case NvOdmIoModule_I2c:
+ case NvOdmIoModule_I2c_Pmu:
+ hAccel->I2CChannelId = pConnectivity->AddressList[i].Instance;
+ hAccel->nDevAddr = (NvU8)pConnectivity->AddressList[i].Address;
+ FoundI2cModule = NV_TRUE;
+ IoModule = pConnectivity->AddressList[i].Interface;
+ break;
+ case NvOdmIoModule_Gpio:
+ hAccel->GPIOPortINT = pConnectivity->AddressList[i].Instance;
+ hAccel->GPIOPinINT = pConnectivity->AddressList[i].Address;
+ FoundGpio = NV_TRUE;
+ break;
+ case NvOdmIoModule_Vdd:
+ hAccel->VddId = pConnectivity->AddressList[i].Address;
+ // Power on accelerometer according to Vddid
+ SetPowerRail(hAccel->hPmu, hAccel->VddId, NV_TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (!FoundGpio || !FoundI2cModule)
+ {
+ NVODMACCELEROMETER_PRINTF(("Accelerometer : didn't find any periperal\
+ in discovery query for touch device Error \n"));
+ goto error;
+ }
+
+ // Open I2C handle.
+ hAccel->hOdmI2C = NvOdmI2cOpen(IoModule, hAccel->I2CChannelId);
+ if (!hAccel->hOdmI2C)
+ goto error;
+
+ hAccel->RegsRead = ReadReg;
+ hAccel->RegsWrite = WriteReg;
+
+ if (!BMA150_Init(hAccel))
+ goto error;
+ if (!ConnectSemaphore(hAccel))
+ goto error;
+
+ *hDevice = hAccel;
+ return NV_TRUE;
+ error:
+ NVODMACCELEROMETER_PRINTF(("Error during BMA150 NvOdmAccelOpen\n"));
+ // Release all of resources requested.
+ if (hAccel)
+ {
+ SetPowerRail(hAccel->hPmu, hAccel->VddId, NV_FALSE);
+ NvOdmServicesPmuClose(hAccel->hPmu);
+ hAccel->hPmu = NULL;
+ NvOdmI2cClose(hAccel->hOdmI2C);
+ hAccel->hOdmI2C = NULL;
+ NvOdmOsFree(hAccel);
+ *hDevice = NULL;
+ }
+ return NV_FALSE;
+}
+
+void NvOdmAccelClose(NvOdmAccelHandle hDevice)
+{
+ if (hDevice)
+ {
+ if (hDevice->SemaphoreForINT && hDevice->hGpioINT &&
+ hDevice->hPinINT && hDevice->hGpioInterrupt)
+ {
+ NvOdmGpioInterruptUnregister(hDevice->hGpioINT,
+ hDevice->hPinINT, hDevice->hGpioInterrupt);
+ NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT);
+ NvOdmGpioReleasePinHandle(hDevice->hGpioINT, hDevice->hPinINT);
+ NvOdmGpioClose(hDevice->hGpioINT);
+ }
+ NvOdmI2cClose(hDevice->hOdmI2C);
+
+ // Power off accelermeter
+ SetPowerRail(hDevice->hPmu, hDevice->VddId, NV_FALSE);
+ if (hDevice->hPmu)
+ {
+ //NvAccelerometerSetPowerOn(0);
+ NvOdmServicesPmuClose(hDevice->hPmu);
+ }
+ }
+}
+
+NvBool
+NvOdmAccelSetIntForceThreshold(
+ NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvU32 IntNum,
+ NvU32 Threshold)
+{
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmAccelSetIntTimeThreshold(
+ NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvU32 IntNum,
+ NvU32 Threshold)
+{
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmAccelSetIntEnable(
+ NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvOdmAccelAxisType IntAxis,
+ NvU32 IntNum,
+ NvBool Toggle)
+{
+ return NV_TRUE;
+}
+
+void
+NvOdmAccelWaitInt(
+ NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType *IntType,
+ NvOdmAccelAxisType *IntMotionAxis,
+ NvOdmAccelAxisType *IntTapAxis)
+{
+ NV_ASSERT(hDevice);
+ NV_ASSERT(IntType);
+ NV_ASSERT(IntMotionAxis);
+ NV_ASSERT(IntTapAxis);
+
+ if ((g_WaitCounter > 0) || ENABLE_XYZ_POLLING)
+ {
+ NvOdmOsSemaphoreWaitTimeout( hDevice->SemaphoreForINT, 300);
+ g_WaitCounter--;
+ }
+ else
+ NvOdmOsSemaphoreWait( hDevice->SemaphoreForINT);
+}
+
+void NvOdmAccelSignal(NvOdmAccelHandle hDevice)
+{
+ NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT);
+}
+
+NvBool
+NvOdmAccelGetAcceleration(
+ NvOdmAccelHandle hDevice,
+ NvS32 *AccelX,
+ NvS32 *AccelY,
+ NvS32 *AccelZ)
+{
+ NvS32 data;
+ NvBool NewData = 0;
+ NvS32 TempAccelX = 0;
+ NvS32 TempAccelY = 0;
+ NvS32 TempAccelZ = 0;
+
+ NV_ASSERT(NULL != hDevice);
+ NV_ASSERT(NULL != AccelX);
+ NV_ASSERT(NULL != AccelY);
+ NV_ASSERT(NULL != AccelZ);
+ NewData = BMA150_ReadXYZ(hDevice, &TempAccelX, &TempAccelY, &TempAccelZ);
+
+ data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelX+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/
+ (NvS32)NV_BMA150_MAX_FORCE_IN_REG;
+ switch(hDevice->AxisXMapping)
+ {
+ case NvOdmAccelAxis_X:
+ *AccelX = data*hDevice->AxisXDirection;
+ break;
+ case NvOdmAccelAxis_Y:
+ *AccelY = data*hDevice->AxisYDirection;
+ break;
+ case NvOdmAccelAxis_Z:
+ *AccelZ = data*hDevice->AxisZDirection;
+ break;
+ default:
+ return NV_FALSE;
+ }
+
+ data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelY+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/
+ (NvS32)NV_BMA150_MAX_FORCE_IN_REG;
+ switch(hDevice->AxisYMapping)
+ {
+ case NvOdmAccelAxis_X:
+ *AccelX = data*hDevice->AxisXDirection;
+ break;
+ case NvOdmAccelAxis_Y:
+ *AccelY = data*hDevice->AxisYDirection;
+ break;
+ case NvOdmAccelAxis_Z:
+ *AccelZ = data*hDevice->AxisZDirection;
+ break;
+ default:
+ return NV_FALSE;
+ }
+
+ data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelZ+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/
+ (NvS32)NV_BMA150_MAX_FORCE_IN_REG;
+ switch(hDevice->AxisZMapping)
+ {
+ case NvOdmAccelAxis_X:
+ *AccelX = data*hDevice->AxisXDirection;
+ break;
+ case NvOdmAccelAxis_Y:
+ *AccelY = data*hDevice->AxisYDirection;
+ break;
+ case NvOdmAccelAxis_Z:
+ *AccelZ = data*hDevice->AxisZDirection;
+ break;
+ default:
+ return NV_FALSE;
+ }
+
+ NVODMACCELEROMETER_PRINTF(("\naccel output, x=%d,y=%d,z=%d, NewData=%d",
+ *AccelX, *AccelY, *AccelZ, NewData));
+ return NewData;
+}
+
+NvOdmAccelerometerCaps NvOdmAccelGetCaps(NvOdmAccelHandle hDevice)
+{
+ NV_ASSERT(NULL != hDevice);
+ return hDevice->Caption;
+}
+
+NvBool NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate)
+{
+ return NV_TRUE;
+}
+
+NvBool NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate)
+{
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmAccelSetPowerState(
+ NvOdmAccelHandle hDevice,
+ NvOdmAccelPowerType PowerState)
+{
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h
new file mode 100644
index 000000000000..1b8efb12ad0c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the
+ * WinCE Accelerometer Driver
+ */
+
+#ifndef INCLUDED_NVODM_ACCELEROMETER_BMA150_H
+#define INCLUDED_NVODM_ACCELEROMETER_BMA150_H
+
+#if defined(_cplusplus)
+extern "C"
+{
+#endif
+
+#include "nvodm_services.h"
+#include "nvodm_accelerometer.h"
+
+/* BMA150 register address */
+#define CHIP_ID_REG 0x00
+#define VERSION_REG 0x01
+#define X_AXIS_LSB_REG 0x02
+#define X_AXIS_MSB_REG 0x03
+#define Y_AXIS_LSB_REG 0x04
+#define Y_AXIS_MSB_REG 0x05
+#define Z_AXIS_LSB_REG 0x06
+#define Z_AXIS_MSB_REG 0x07
+#define TEMP_RD_REG 0x08
+#define SMB150_STATUS_REG 0x09
+#define SMB150_CTRL_REG 0x0a
+#define SMB150_CONF1_REG 0x0b
+#define LG_THRESHOLD_REG 0x0c
+#define LG_DURATION_REG 0x0d
+#define HG_THRESHOLD_REG 0x0e
+#define HG_DURATION_REG 0x0f
+#define MOTION_THRS_REG 0x10
+#define HYSTERESIS_REG 0x11
+#define CUSTOMER1_REG 0x12
+#define CUSTOMER2_REG 0x13
+#define RANGE_BWIDTH_REG 0x14
+#define SMB150_CONF2_REG 0x15
+
+#define OFFS_GAIN_X_REG 0x16
+#define OFFS_GAIN_Y_REG 0x17
+#define OFFS_GAIN_Z_REG 0x18
+#define OFFS_GAIN_T_REG 0x19
+#define OFFSET_X_REG 0x1a
+#define OFFSET_Y_REG 0x1b
+#define OFFSET_Z_REG 0x1c
+#define OFFSET_T_REG 0x1d
+
+/* range and bandwidth */
+#define BMA_RANGE_2G 0
+#define BMA_RANGE_4G 1
+#define BMA_RANGE_8G 2
+
+#define BMA_BW_25HZ 0
+#define BMA_BW_50HZ 1
+#define BMA_BW_100HZ 2
+#define BMA_BW_190HZ 3
+#define BMA_BW_375HZ 4
+#define BMA_BW_750HZ 5
+#define BMA_BW_1500HZ 6
+
+/* mode settings */
+#define BMA_MODE_NORMAL 0
+#define BMA_MODE_SLEEP 1
+
+#define BMA150_CHIP_ID 0x02 // RO - device identification
+/*
+ * Defines the threshold source for the accelerometer.
+ */
+typedef enum
+{
+ /// Indicates the accelerometer generated interrupt by exceeding the x threshold.
+ NvOdmAccelerometerThresholdSource_X = 0,
+
+ /// Indicates the accelerometer generated interrupt by exceeding the y threshold.
+ NvOdmAccelerometerThresholdSource_Y,
+
+ /// Indicates the accelerometer generated interrupt by exceeding the z threshold.
+ NvOdmAccelerometerThresholdSource_Z,
+
+ NvOdmAccelerometerThresholdSource_Force32 = 0x7FFFFFFF
+} NvOdmAccelerometerThresholdSource;
+
+// Timeout for I2C transaction.
+enum { I2C_ACCELRATOR_TRANSACTION_TIMEOUT = 1000 };
+// Maximum number of packetsize supported by the I2C controller.
+enum { I2C_ACCELRATOR_PACKET_SIZE = 8};
+static NvU8 s_ReadBuffer[I2C_ACCELRATOR_PACKET_SIZE];
+static NvU8 s_WriteBuffer[I2C_ACCELRATOR_PACKET_SIZE];
+
+#define INT_EVENT_TIMEOUT 100
+#define NV_ACCELEROMETER_BUS_I2C 0
+#define NV_ACCELEROMETER_BUS_SPI_3 1
+#define NV_ACCELEROMETER_BUS_SPI_4 2
+
+/*
+ * Defines the way to read accelerometer registers.
+ */
+typedef NvBool
+(*AccelerometerRegsRead)(
+ NvOdmAccelHandle hDevice,
+ NvU8 nRegOffset,
+ NvU8* nData,
+ NvU32 nLen);
+/*
+ * Defines the way to write accelerometer registers.
+ */
+typedef NvBool
+(*AccelerometerRegsWrite)(
+ NvOdmAccelHandle hDevice,
+ NvU8 nRegOffset,
+ NvU8* nData,
+ NvU32 nLen);
+/*
+ * Holds register address and value pairs.
+ */
+typedef struct NvDevCtrlRegRec {
+ /// Holds the register offset.
+ NvU8 RegAddr;
+ /// Holds the value programmed into the upper address.
+ NvU8 RegValue;
+} NvDevCtrlReg;
+/*
+ * Max accelerometer registers number.
+ */
+#define ACCELEROMETER_CONTROL_REGS_MAX_LENGHT 100
+/*
+ * Max accelerometer callback functions number.
+ */
+#define ACCELEROMETER_CALLBACK_ARRAY_LENGTH 5
+
+typedef struct NvOdmAccelRec
+{
+ // Specifies use I2C or SPI to configure accelerometer registers.
+ NvU8 nBusType;
+ // Specifies accelerometer device address, for example, I2C write address.
+ NvU8 nDevAddr;
+ // Specifies the initial value that make accelerometer work,
+ // ACCELEROMETER_CONTROL_REGS_MAX_LENGHT is always 100.
+ NvDevCtrlReg CtrlRegsList[ACCELEROMETER_CONTROL_REGS_MAX_LENGHT];
+ // Specifies the initial CtrlRegsList length.
+ NvU8 nLength;
+ // Specifies accelerometer chip ID.
+ NvU8 nChipID;
+ // Specifies the way to get accelerometer register information.
+ AccelerometerRegsRead RegsRead;
+ // Specifies the way to set accelerometer register information.
+ AccelerometerRegsWrite RegsWrite;
+ // Specifies I2C handle from the system.
+ NvOdmServicesI2cHandle hOdmI2C;
+ // Interrupt pin to ap15.
+ NvOdmServicesGpioHandle hGpioINT;
+ NvOdmGpioPinHandle hPinINT;
+ NvU32 GPIOPortINT;
+ NvU32 GPIOPinINT;
+ NvOdmOsSemaphoreHandle SemaphoreForINT;
+ NvOdmServicesGpioIntrHandle hGpioInterrupt;
+ NvOdmAccelIntType Data;
+ NvOdmServicesPmuHandle hPmu;
+ NvU32 VddId;
+ NvU32 I2CChannelId;
+ NvOdmAccelerometerCaps Caption;
+ NvOdmAccelPowerType PowerState;
+ // In real case, when the board put in frontispiece, the value from z axis
+ // should be g, but due to physical connect on different board, the axis
+ // should be remapped to the correct one.
+ NvOdmAccelAxisType AxisXMapping;
+ // If the physical direct is the same with our expection, the value
+ // should be set to 1, or else the value should be -1.
+ NvS32 AxisXDirection;
+ NvOdmAccelAxisType AxisYMapping;
+ NvS32 AxisYDirection;
+ NvOdmAccelAxisType AxisZMapping;
+ NvS32 AxisZDirection;
+} NvOdmAccel;
+
+#if defined(__cplusplus)
+}
+#endif
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c
new file mode 100644
index 000000000000..b10e15f84754
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file NvAccelerometer.c
+ * @brief <b>Device Driver for Accelerometer</b>
+ *
+ * @Description : Implementation of the WinCE Accelerometer driver
+ */
+
+#include "nvodm_accelerometer.h"
+
+
+NvBool
+NvOdmAccelOpen(NvOdmAccelHandle* hDevice)
+{
+ *hDevice = NULL;
+ return NV_FALSE;
+}
+
+
+void
+NvOdmAccelClose(NvOdmAccelHandle hDevice)
+{
+}
+
+
+/**
+ * After setting the force threshold, we should remove all of interrupt flag
+ * Which may be left from last threshold
+ */
+NvBool
+NvOdmAccelSetIntForceThreshold(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvU32 IntNum,
+ NvU32 Threshold)
+{
+ return NV_FALSE;
+}
+
+/**
+ * After setting the time threshold, we should remove all of interrupt flag
+ * Which may be left from last threshold
+ */
+NvBool
+NvOdmAccelSetIntTimeThreshold(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvU32 IntNum,
+ NvU32 Threshold)
+{
+ return NV_FALSE;
+}
+
+
+/**
+ * After enable/disable threshold, we should remove all of interrupt flag
+ * Which may be left from last threshold
+ */
+NvBool
+NvOdmAccelSetIntEnable(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType IntType,
+ NvOdmAccelAxisType IntAxis,
+ NvU32 IntNum,
+ NvBool Toggle)
+{
+ return NV_FALSE;
+}
+
+
+void
+NvOdmAccelWaitInt(NvOdmAccelHandle hDevice,
+ NvOdmAccelIntType *IntType,
+ NvOdmAccelAxisType *IntMotionAxis,
+ NvOdmAccelAxisType *IntTapAxis)
+{
+}
+
+
+void NvOdmAccelSignal(NvOdmAccelHandle hDevice)
+{
+}
+
+NvBool
+NvOdmAccelGetAcceleration(NvOdmAccelHandle hDevice,
+ NvS32 *AccelX,
+ NvS32 *AccelY,
+ NvS32 *AccelZ)
+{
+ return NV_FALSE;
+}
+
+
+NvOdmAccelerometerCaps
+NvOdmAccelGetCaps(NvOdmAccelHandle hDevice)
+{
+ NvOdmAccelerometerCaps caps;
+ NvOdmOsMemset(&caps, 0, sizeof(NvOdmAccelerometerCaps));
+
+ return caps;
+}
+
+
+NvBool
+NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate)
+{
+ return NV_FALSE;
+}
+
+
+NvBool
+NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate)
+{
+ return NV_FALSE;
+}
+
+NvBool
+NvOdmAccelSetPowerState(NvOdmAccelHandle hDevice, NvOdmAccelPowerType PowerState)
+{
+ return NV_FALSE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/Makefile b/arch/arm/mach-tegra/odm_kit/platform/battery/Makefile
new file mode 100644
index 000000000000..9c1a4b43b4ab
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/battery/Makefile
@@ -0,0 +1,11 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_battery.o
+obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_battery_stub.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c
new file mode 100644
index 000000000000..9a3d775f5308
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c
@@ -0,0 +1,1896 @@
+/*
+ * Copyright (c) 2009-2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvodm_battery_int.h"
+#include "nvodm_battery.h"
+#include "nvec.h"
+
+NvBool NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(
+ NvOdmBatteryDevice *pBattContext,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *BatterySlotStatus,
+ NvU8 *BatteryCapacityGuage);
+
+NvBool NvOdmBatteryPrivGetLifeTime(
+ NvOdmBatteryDevice *pBattContext,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *BatteryLifeTime);
+
+NvBool NvOdmPrivBattGetBatteryVoltage(
+ NvOdmBatteryDevice *pBattContext,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *BatteryVoltage);
+
+NvBool NvOdmBatteryPrivGetCurrent(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvS32 *pCurrent);
+
+NvBool NvOdmBatteryPrivGetAverageCurrent(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvS32 *pAverageCurrent);
+
+NvBool NvOdmBatteryPrivGetAverageTimeInterval(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pAverageTimeInterval);
+
+NvBool NvOdmBatteryPrivGetTemperature(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pBatteryTemp);
+
+NvBool NvOdmBatteryPrivGetRemainingCapacity(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pRemCapacity);
+
+NvBool NvOdmBatteryPrivGetLastFullChargeCapacity(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pLastFullChargeCapacity);
+
+NvBool NvOdmBatteryPrivGetCriticalCapacity(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pCriticalCapacity);
+
+NvBool NvOdmBatterySetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 RemCapAlarm);
+
+#if BATTERY_EXTRA_INFO
+NvBool NvOdmBatteryGetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 *RemCapAlarm);
+
+NvBool NvOdmBatterySetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 Configuration);
+
+NvBool NvOdmBatteryGetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *Configuration);
+#endif
+
+#if NVODM_LOWBATTERY_GPIO_INT
+/*
+ * GPIO interrupt handle for battery events
+ */
+static void
+NvOdmBatteryGpioInterruptHandler(void *args)
+{
+ NvOdmBatteryDevice *pBattContext = args;
+
+ NVODMBATTERY_PRINTF(("NvOdmBatteryGpioInterruptHandler:\n"));
+
+ if (pBattContext)
+ {
+ pBattContext->BatteryEvent = NvOdmBatteryEventType_RemainingCapacityAlarm;
+
+ if (pBattContext->hClientBattEventSem)
+ NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem);
+ }
+
+ NvRmGpioInterruptDone(pBattContext->GpioIntrHandle);
+}
+#endif
+
+/*
+ * Gets the EC Firmware version number
+ */
+static NvError NvOdmBatteryPrivEcGetFirmwareVersion(
+ NvOdmBatteryDevice *pBattContext,
+ NvS32 *MajorVersion,
+ NvS32 *MinorVersion)
+{
+ NvEcControlGetFirmwareVersionResponsePayload FirmwareVersion;
+ NvError RetVal = NvSuccess;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvS32 Version = 0;
+
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Control;
+ EcRequest.RequestSubtype = (NvEcRequestResponseSubtype)
+ NvEcControlSubtype_GetFirmwareVersion;
+ EcRequest.NumPayloadBytes = 0;
+ RetVal = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (RetVal != NvSuccess)
+ return RetVal;
+
+ if (EcResponse.Status != NvEcStatus_Success)
+ return NvError_BadValue;
+
+ NvOdmOsMemcpy(&FirmwareVersion, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+
+ Version = (FirmwareVersion.VersionMajor[1] << 24) |
+ (FirmwareVersion.VersionMajor[0] << 16) |
+ (FirmwareVersion.VersionMinor[1] << 8) |
+ (FirmwareVersion.VersionMinor[0] << 0);
+
+ *MajorVersion = Version & 0xFF00;
+ *MinorVersion = Version & 0xFF;
+ return NvSuccess;
+}
+
+static void NvOdmBatteryEventHandler(void *args)
+{
+ NvOdmBatteryDevice *pBattContext = args;
+ NvError NvStatus = NvError_Success;
+ NvEcEvent EcEvent = {0};
+ NvU8 BattEvent = 0, ChargingState = 0;
+
+ for (;;)
+ {
+ NvOdmOsSemaphoreWait(pBattContext->hBattEventSem);
+
+ if (pBattContext->ExitThread == NV_TRUE)
+ break;
+
+ NVODMBATTERY_PRINTF(("NvOdmBatteryEventHandler:hBattEventSem signaled\n"));
+
+ if (pBattContext->hEcEventReg)
+ {
+ NvStatus = NvEcGetEvent(pBattContext->hEcEventReg,
+ &EcEvent, sizeof(NvEcEvent));
+ if (NvStatus != NvError_Success)
+ {
+ NV_ASSERT(!"Could not receive EC event\n");
+ continue;
+ }
+
+ if (EcEvent.NumPayloadBytes == 0)
+ {
+ NV_ASSERT(!"Received Battery event with no data\n");
+ continue;
+ }
+
+ /* EcEvent.Payload[0] is Slot number */
+
+ /* EcEvent.Payload[1] has 4 lsb bits for battery events */
+ BattEvent = EcEvent.Payload[1] & NVODM_BATTERY_EVENT_MASK;
+
+ pBattContext->BatteryEvent = 0;
+ /* Read the Battery Slot status to set the proper event */
+ if (BattEvent & NVODM_BATTERY_PRESENT_IN_SLOT)
+ pBattContext->BatteryEvent |= NvOdmBatteryEventType_Present;
+
+ ChargingState = BattEvent >> NVODM_BATTERY_CHARGING_STATE_SHIFT;
+ ChargingState &= NVODM_BATTERY_CHARGING_STATE_MASK;
+ if (ChargingState == NVODM_BATTERY_CHARGING_STATE_IDLE)
+ pBattContext->BatteryEvent |= NvOdmBatteryEventType_Idle;
+ else if (ChargingState == NVODM_BATTERY_CHARGING_STATE_CHARGING)
+ pBattContext->BatteryEvent |= NvOdmBatteryEventType_Charging;
+ else if (ChargingState == NVODM_BATTERY_CHARGING_STATE_DISCHARGING)
+ pBattContext->BatteryEvent |= NvOdmBatteryEventType_Disharging;
+
+ ChargingState = BattEvent >> NVODM_BATTERY_REM_CAP_ALARM_SHIFT;
+ if (ChargingState == NVODM_BATTERY_REM_CAP_ALARM_IS_SET)
+ pBattContext->BatteryEvent |= NvOdmBatteryEventType_RemainingCapacityAlarm;
+
+ /* Signal the Battery Client for arrival of the valid event */
+ if ((pBattContext->hClientBattEventSem != 0) &&
+ (pBattContext->BatteryEvent != 0))
+ NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem);
+ }
+ }
+}
+
+/**
+ * Gets the battery event.
+ *
+ * @param hDevice A handle to the EC.
+ * @param pBatteryEvent Battery events
+ *
+ */
+void NvOdmBatteryGetEvent(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvU8 *pBatteryEvent)
+{
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetEvent.\n"));
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ *pBatteryEvent = pBattContext->BatteryEvent;
+}
+
+/**
+ * Sets the battery remaining capacity alarm threshold.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param RemCapAlarm [IN] Capacity Units
+ */
+NvBool NvOdmBatterySetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 RemCapAlarm)
+{
+#if NVEC_BATTERY_DISABLED
+ ;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatterySetRemCapacityAlarm.\n"));
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_SetRemainingCapacityAlarm;
+ EcRequest.NumPayloadBytes = 2;
+ EcRequest.Payload[0] = (RemCapAlarm & 0x00FF);
+ EcRequest.Payload[1] = (RemCapAlarm & 0xFF00) >> 8;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatterySetRemCapacityAlarm\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NVODMBATTERY_PRINTF(("EcResponse.Status failed for NvOdmBatterySetRemCapacityAlarm\n"));
+ return NV_FALSE;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatterySetRemCapacityAlarm.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+#if BATTERY_EXTRA_INFO
+/**
+ * Gets the battery remaining capacity alarm threshold.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param RemCapAlarm [OUT] Capacity Units
+ */
+NvBool NvOdmBatteryGetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 *RemCapAlarm)
+{
+#if NVEC_BATTERY_DISABLED
+ *RemCapAlarm = 0;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetRemCapacityAlarm.\n"));
+ *RemCapAlarm = 0;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetRemainingCapacityAlarm;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatteryGetRemCapacityAlarm\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ *RemCapAlarm = EcResponse.Payload[0];
+ *RemCapAlarm |= EcResponse.Payload[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetRemCapacityAlarm.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Sets the battery capacity unit configuration (mAh or 10mWh)
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param Configuration [IN] Capacity Unit
+ */
+NvBool NvOdmBatterySetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 Configuration)
+{
+#if NVEC_BATTERY_DISABLED
+ ;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatterySetConfiguration.\n"));
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_SetConfiguration;
+ EcRequest.NumPayloadBytes = 1;
+ EcRequest.Payload[0] = Configuration;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatterySetConfiguration\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NVODMBATTERY_PRINTF(("EcResponse.Status failed for NvOdmBatterySetConfiguration\n"));
+ return NV_FALSE;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatterySetConfiguration.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the battery capacity unit configuration (mAh or 10mWh).
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param Configuration [OUT] Capacity Unit
+ */
+NvBool NvOdmBatteryGetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *Configuration)
+{
+#if NVEC_BATTERY_DISABLED
+ *Configuration = 0;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetConfiguration.\n"));
+ *Configuration = 0;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetConfiguration;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatteryGetConfiguration\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ *Configuration = EcResponse.Payload[0];
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetConfiguration.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+#endif
+
+/**
+ * Gets the battery Current.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pCurrent [OUT] A pointer to the battery current
+ */
+NvBool NvOdmBatteryPrivGetCurrent(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvS32 *pCurrent)
+{
+#if NVEC_BATTERY_DISABLED
+ *pCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetCurrentResponsePayload BatteryCurrent;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetCurrent.\n"));
+ *pCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetCurrent;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetCurrent\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryCurrent, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pCurrent = BatteryCurrent.PresentCurrent[0];
+ *pCurrent |= BatteryCurrent.PresentCurrent[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetCurrent.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery Average Current.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pAverageCurrent [OUT] A pointer to the battery average current
+ */
+NvBool NvOdmBatteryPrivGetAverageCurrent(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvS32 *pAverageCurrent)
+{
+#if NVEC_BATTERY_DISABLED
+ *pAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetAverageCurrentResponsePayload BatteryAverageCurrent;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetAverageCurrent.\n"));
+ *pAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetAverageCurrent;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetAverageCurrent\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryAverageCurrent, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pAverageCurrent = BatteryAverageCurrent.AverageCurrent[0];
+ *pAverageCurrent |= BatteryAverageCurrent.AverageCurrent[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetAverageCurrent.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery Average time interval.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pAverageTimeInterval [OUT] A pointer to the battery average
+ * time interval
+ */
+NvBool NvOdmBatteryPrivGetAverageTimeInterval(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pAverageTimeInterval)
+{
+#if NVEC_BATTERY_DISABLED
+ *pAverageTimeInterval = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetAveragingTimeIntervalResponsePayload \
+ BatteryAverageTimeInterval;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetAverageTimeInterval.\n"));
+ *pAverageTimeInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetAveragingTimeInterval;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetAverageTimeInterval\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryAverageTimeInterval, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pAverageTimeInterval = BatteryAverageTimeInterval.TimeInterval[0];
+ *pAverageTimeInterval |= \
+ BatteryAverageTimeInterval.TimeInterval[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetAverageTimeInterval.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery Temperature.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pBatteryTemp [OUT] A pointer to the battery Temperature
+ */
+NvBool NvOdmBatteryPrivGetTemperature(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pBatteryTemp)
+{
+#if NVEC_BATTERY_DISABLED
+ *pBatteryTemp = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetTemperatureResponsePayload BatteryTemperature;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetTemperature.\n"));
+ *pBatteryTemp = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetTemperature;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetTemperature\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryTemperature, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pBatteryTemp = BatteryTemperature.Temperature[0];
+ *pBatteryTemp |= BatteryTemperature.Temperature[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetTemperature.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery Manufacturer.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pBatteryManufacturer [OUT] A pointer to the battery Manufacturer
+ */
+NvBool NvOdmBatteryGetManufacturer(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *pBatteryManufacturer)
+{
+#if NVEC_BATTERY_DISABLED
+ *pBatteryManufacturer = '\0';
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetManufacturerResponsePayload BatteryManufacturer;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetManufacturer.\n"));
+ *pBatteryManufacturer = '\0';
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetManufacturer;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryGetManufacturer\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryManufacturer, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ NvOdmOsMemcpy(pBatteryManufacturer, BatteryManufacturer.Manufacturer,
+ EcResponse.NumPayloadBytes);
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetManufacturer.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery Model.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pBatteryModel [OUT] A pointer to the battery model
+ */
+NvBool NvOdmBatteryGetModel(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *pBatteryModel)
+{
+#if NVEC_BATTERY_DISABLED
+ *pBatteryModel = '\0';
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetModelResponsePayload BatteryModel;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetModel.\n"));
+ *pBatteryModel = '\0';
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetModel;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryGetModel\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryModel, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ NvOdmOsMemcpy(pBatteryModel, BatteryModel.Model,
+ EcResponse.NumPayloadBytes);
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetModel.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+/**
+ * Gets the Battery Remaining Capacity.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pRemCapacity [OUT] A pointer to the battery remaining capacity
+ */
+NvBool NvOdmBatteryPrivGetRemainingCapacity(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pRemCapacity)
+{
+#if NVEC_BATTERY_DISABLED
+ *pRemCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetCapacityRemainingResponsePayload BatteryRemCap;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetRemainingCapacity.\n"));
+ *pRemCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetCapacityRemaining;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetRemainingCapacity\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryRemCap, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pRemCapacity = BatteryRemCap.CapacityRemaining[0];
+ *pRemCapacity |= BatteryRemCap.CapacityRemaining[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetRemainingCapacity.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery Last FullCharge Capacity
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pLastFullChargeCapacity [OUT] A pointer to the battery
+ * last fullcharge capacity
+ */
+NvBool NvOdmBatteryPrivGetLastFullChargeCapacity(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pLastFullChargeCapacity)
+{
+#if NVEC_BATTERY_DISABLED
+ *pLastFullChargeCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetLastFullChargeCapacityResponsePayload \
+ BatteryLastFullChargeCap;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("+NvOdmBatteryPrivGetLastFullChargeCapacity.\n"));
+ *pLastFullChargeCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetLastFullChargeCapacity;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetLastFullChargeCapacity\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryLastFullChargeCap, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pLastFullChargeCapacity = \
+ BatteryLastFullChargeCap.LastFullChargeCapacity[0];
+ *pLastFullChargeCapacity |= \
+ BatteryLastFullChargeCap.LastFullChargeCapacity[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("-NvOdmBatteryPrivGetLastFullChargeCapacity.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the Battery critical capacity
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pCriticalCapacity [OUT] A pointer to the battery critical capacity
+ */
+NvBool NvOdmBatteryPrivGetCriticalCapacity(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pCriticalCapacity)
+{
+#if NVEC_BATTERY_DISABLED
+ *pCriticalCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetCriticalCapacityResponsePayload BatteryCriticalCap;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetCriticalCapacity.\n"));
+ *pCriticalCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetCriticalCapacity;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetCriticalCapacity\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryCriticalCap, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pCriticalCapacity = BatteryCriticalCap.CriticalCapacity[0];
+ *pCriticalCapacity |= BatteryCriticalCap.CriticalCapacity[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetCriticalCapacity.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets Battery Slot status and Capacity Guage.
+ *
+ * @param pBattContext [IN] Handle to the Battery Context.
+ * @param BatteryInst [IN] battery type.
+ * @param BatterySlotStatus [OUT] gives battery presence and charging status
+ * @param BatteryCapacityGuage [OUT] Battery's relative remaining capacity in %
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool
+NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(NvOdmBatteryDevice *pBattContext,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *BatterySlotStatus,
+ NvU8 *BatteryCapacityGuage)
+{
+#if NVEC_BATTERY_DISABLED
+ return NV_FALSE;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+
+ NVODMBATTERY_PRINTF(("NvOdmBatteryPrivGetSlotStatusAndCapacityGuage:Enter"));
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetSlotStatus;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetSlotStatusAndCapacityGuage\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ *BatterySlotStatus = \
+ EcResponse.Payload[NVODM_BATTERY_SLOT_STATUS_DATA];
+ *BatteryCapacityGuage = \
+ EcResponse.Payload[NVODM_BATTERY_CAPACITY_GUAGE_DATA];
+ }
+ else
+ {
+ *BatterySlotStatus = 0;
+ *BatteryCapacityGuage = 0;
+ /*
+ * if the response status is unavailable (0x03) that means
+ * HW is unavailable
+ * in that case return TRUE to tell that Battery is not present.
+ */
+ if (EcResponse.Status == NvEcStatus_Unavailable)
+ return NV_TRUE;
+
+ return NV_FALSE;
+ }
+
+ NVODMBATTERY_PRINTF(("NvOdmBatteryPrivGetSlotStatusAndCapacityGuage:Exit"));
+ return NV_TRUE;
+#endif /* end of NVEC_BATTERY_DISABLED */
+}
+
+/**
+ * Gets Battery's Life time
+ *
+ * @param pBattContext [IN] Handle to the Battery Context.
+ * @param BatteryInst [IN] battery type.
+ * @param BatteryLifeTime [OUT] Estimated remaining time to empty
+ * for discharging.
+ * battery at present rate (in [min])
+ * Report 0FFFFh if battery is not discharging
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryPrivGetLifeTime(NvOdmBatteryDevice *pBattContext,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *BatteryLifeTime)
+{
+#if NVEC_BATTERY_DISABLED
+ return NV_FALSE;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetTimeRemainingResponsePayload BattTimeRemain;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetTimeRemaining;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryPrivGetLifeTime\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BattTimeRemain, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *BatteryLifeTime = BattTimeRemain.TimeRemaining[0];
+ *BatteryLifeTime |= BattTimeRemain.TimeRemaining[1] << 8;
+ }
+ else
+ {
+ NVODMBATTERY_PRINTF(("EcResponse.Status failed for \
+ NvOdmBatteryPrivGetLifeTime\n"));
+ *BatteryLifeTime = 0;
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+#endif /* end of NVEC_BATTERY_DISABLED */
+}
+
+/**
+ * Gets Battery's Present voltage
+ *
+ * @param pBattContext [IN] Handle to the Battery Context.
+ * @param BatteryInst [IN] battery type.
+ * @param BatteryVoltage [OUT] Battery's present voltage
+ * (16-bit unsigned value, in [mV])
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmPrivBattGetBatteryVoltage(NvOdmBatteryDevice *pBattContext,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *BatteryVoltage)
+{
+#if NVEC_BATTERY_DISABLED
+ return NV_FALSE;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetVoltageResponsePayload BattVoltage;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetVoltage;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed \
+ NvOdmPrivBattGetBatteryVoltage\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BattVoltage, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ NvOdmOsMemcpy(BatteryVoltage, BattVoltage.PresentVoltage,
+ sizeof(BattVoltage.PresentVoltage));
+ }
+ else
+ {
+ NVODMBATTERY_PRINTF(("EcResponse.Status failed in \
+ NvOdmPrivBattGetBatteryVoltage\n"));
+ *BatteryVoltage = 0;
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+#endif /* end of NVEC_BATTERY_DISABLED */
+}
+
+/**
+ * Openes the battery device handle
+ *
+ * @param hDevice [OUT] handle to Battery Device.
+ *
+ * @return NV_TRUE on success.
+ */
+NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
+ NvOdmOsSemaphoreHandle *hOdmSemaphore)
+{
+ NvOdmBatteryDevice *pBattContext = NULL;
+ NvError NvStatus = NvError_Success;
+ NvEcEventType EventTypes[] = {NvEcEventType_Battery};
+ NvS32 MajorVersion = 0, MinorVersion = 0;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+#if NVODM_LOWBATTERY_GPIO_INT
+ NvOsInterruptHandler IntrHandler = {NULL};
+#endif
+ NvU32 BatteryDesignCap = 0;
+ NvU16 RemCapAlarm = 0;
+
+ NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryDeviceOpen. \n"));
+
+ /* Allocate the context */
+ pBattContext = NvOdmOsAlloc(sizeof(NvOdmBatteryDevice));
+ if (!pBattContext)
+ {
+ NVODMBATTERY_PRINTF(("NvOdmOsAlloc failed to allocate pBattContext."));
+ return NV_FALSE;
+ }
+
+ NvOdmOsMemset(pBattContext, 0, sizeof(NvOdmBatteryDevice));
+
+ /* Get nvec handle */
+ NvStatus = NvEcOpen(&pBattContext->hEc, 0 /* instance */);
+ if (NvStatus != NvError_Success)
+ {
+ NVODMBATTERY_PRINTF(("NvEcOpen failed for NvOdmBatteryDeviceOpen.\n"));
+ goto Cleanup;
+ }
+
+ /* Get the EC Firmware version */
+ NvStatus = NvOdmBatteryPrivEcGetFirmwareVersion(pBattContext,
+ &MajorVersion,
+ &MinorVersion);
+ if (NvStatus != NvError_Success)
+ {
+ goto Cleanup;
+ }
+
+ pBattContext->ECVersion = MinorVersion;
+ NVODMBATTERY_PRINTF(("EC Firmware Version = 0x%x\n", MinorVersion));
+
+ if (hOdmSemaphore != NULL && *hOdmSemaphore != NULL)
+ {
+ pBattContext->hClientBattEventSem = *hOdmSemaphore;
+
+ /* Semaphore to receive Battery events from EC */
+ pBattContext->hBattEventSem = NvOdmOsSemaphoreCreate(0);
+ if (!pBattContext->hBattEventSem)
+ {
+ goto Cleanup;
+ }
+
+ /* Thread to handle Battery events */
+ pBattContext->hBattEventThread = NvOdmOsThreadCreate(
+ (NvOdmOsThreadFunction)NvOdmBatteryEventHandler,
+ (void *)pBattContext);
+ if (!pBattContext->hBattEventThread)
+ {
+ goto Cleanup;
+ }
+
+ if (pBattContext->ECVersion >= NVODM_BATTERY_EC_FIRMWARE_VER_R04)
+ {
+#if NVODM_WAKEUP_FROM_BATTERY_EVENT
+ /* Configure the Batter present event as a wakeup */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = (NvEcRequestResponseSubtype)
+ NvEcBatterySubtype_ConfigureWake;
+ EcRequest.NumPayloadBytes = 2;
+ EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE;
+ EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT
+#if NVODM_BATTERY_LOW_CAPACITY_ALARM
+ | NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT
+#endif
+ ;
+
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvStatus != NvSuccess)
+ goto Cleanup;
+
+ if (EcResponse.Status != NvEcStatus_Success)
+ goto Cleanup;
+#endif
+
+#if NVODM_WAKEUP_FROM_AC_EVENT
+ /* Configure the AC present event as a wakeup */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_System;
+ EcRequest.RequestSubtype = (NvEcRequestResponseSubtype)
+ NvEcSystemSubtype_ConfigureWake;
+ EcRequest.NumPayloadBytes = 2;
+ EcRequest.Payload[0] = NVEC_SYSTEM_REPORT_ENABLE_0_ACTION_ENABLE;
+ EcRequest.Payload[1] = NVEC_SYSTEM_STATE1_0_AC_PRESENT;
+
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvStatus != NvSuccess)
+ goto Cleanup;
+
+ if (EcResponse.Status != NvEcStatus_Success)
+ goto Cleanup;
+#endif
+ /* Configure the Battery events */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = (NvEcRequestResponseSubtype)
+ NvEcBatterySubtype_ConfigureEventReporting;
+ EcRequest.NumPayloadBytes = 2;
+ EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE;
+ /* Bit 0 = Present State event */
+ /* Bit 1 = Charging State event */
+ /* Bit 2 = Remaining Capacity Alaram event */
+ EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT |
+ NVODM_BATTERY_SET_CHARGING_EVENT|
+ NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT;
+
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvStatus != NvSuccess)
+ goto Cleanup;
+
+ if (EcResponse.Status != NvEcStatus_Success)
+ goto Cleanup;
+
+ /* Get the design capacity */
+ NvOdmBatteryGetBatteryFullLifeTime(pBattContext, NvOdmBatteryInst_Main,
+ &BatteryDesignCap);
+ /* Set the remaining capacity alarm for 10% of the design capacity */
+ RemCapAlarm = (BatteryDesignCap * 10)/100;
+ NvOdmBatterySetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, RemCapAlarm);
+ }
+
+ /* Register for Battery events */
+ NvStatus = NvEcRegisterForEvents(
+ pBattContext->hEc,
+ &pBattContext->hEcEventReg,
+ (NvOsSemaphoreHandle)pBattContext->hBattEventSem,
+ sizeof(EventTypes)/sizeof(NvEcEventType),
+ EventTypes,
+ 1,
+ sizeof(NvEcEvent));
+ if (NvStatus != NvError_Success)
+ {
+ goto Cleanup;
+ }
+
+#if NVODM_LOWBATTERY_GPIO_INT
+ NvStatus = NvRmOpen(&pBattContext->hRm, 0);
+ if (NvStatus != NvError_Success)
+ goto Cleanup;
+
+ NvStatus = NvRmGpioOpen(pBattContext->hRm, &pBattContext->hGpio);
+ if (NvStatus != NvError_Success)
+ goto Cleanup;
+
+ pBattContext->pGpioPinInfo = NvOdmQueryGpioPinMap(
+ NvOdmGpioPinGroup_Battery,
+ 0,
+ &pBattContext->PinCount);
+ if (pBattContext->pGpioPinInfo != NULL)
+ {
+
+ IntrHandler = (NvOsInterruptHandler)NvOdmBatteryGpioInterruptHandler;
+
+ if (pBattContext->pGpioPinInfo[0].Port != 0 &&
+ pBattContext->pGpioPinInfo[0].Pin != 0)
+ {
+
+ NvRmGpioAcquirePinHandle(
+ pBattContext->hGpio,
+ pBattContext->pGpioPinInfo[0].Port,
+ pBattContext->pGpioPinInfo[0].Pin,
+ &pBattContext->hPin);
+ if (!pBattContext->hPin)
+ {
+ goto Cleanup;
+ }
+
+ /* Register to receive GPIO events */
+ NvStatus = NvRmGpioInterruptRegister(
+ pBattContext->hGpio,
+ pBattContext->hRm,
+ pBattContext->hPin,
+ IntrHandler,
+ NvRmGpioPinMode_InputInterruptAny,
+ pBattContext,
+ &pBattContext->GpioIntrHandle,
+ 0);
+ if (NvStatus != NvError_Success)
+ {
+ goto Cleanup;
+ }
+
+ NvStatus = NvRmGpioInterruptEnable(pBattContext->GpioIntrHandle);
+ if (NvStatus != NvError_Success)
+ {
+ goto Cleanup;
+ }
+ }
+ }
+#endif
+ }
+
+ *hDevice = pBattContext;
+ NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryDeviceOpen.\n"));
+ return NV_TRUE;
+
+Cleanup:
+ NvOdmBatteryDeviceClose(pBattContext);
+
+ return NV_FALSE;
+}
+
+/**
+ * Closes the battery device
+ *
+ * @param hDevice [IN] handle to Battery Device.
+ *
+ * @return void.
+ */
+void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice)
+{
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+#if NVODM_LOWBATTERY_GPIO_INT
+ if (pBattContext->hGpio)
+ {
+ if (pBattContext->GpioIntrHandle)
+ {
+ NvRmGpioInterruptUnregister(pBattContext->hGpio, pBattContext->hRm,
+ pBattContext->GpioIntrHandle);
+ pBattContext->GpioIntrHandle = NULL;
+ }
+
+ NvRmGpioReleasePinHandles(pBattContext->hGpio, &pBattContext->hPin,
+ pBattContext->PinCount);
+ NvRmGpioClose(pBattContext->hGpio);
+ }
+
+ if (pBattContext->hRm)
+ {
+ NvRmClose(pBattContext->hRm);
+ pBattContext->hRm = NULL;
+ }
+#endif
+
+ if (pBattContext->hBattEventSem)
+ {
+ pBattContext->ExitThread = NV_TRUE;
+ NvOdmOsSemaphoreSignal(pBattContext->hBattEventSem);
+ NvOdmOsSemaphoreDestroy(pBattContext->hBattEventSem);
+ pBattContext->hBattEventSem = NULL;
+ }
+
+ if (pBattContext->hBattEventThread)
+ {
+ NvOdmOsThreadJoin(pBattContext->hBattEventThread);
+ pBattContext->hBattEventThread = NULL;
+ }
+
+ if (pBattContext->hEc)
+ {
+ if (pBattContext->hEcEventReg)
+ {
+ NvEcUnregisterForEvents(pBattContext->hEcEventReg);
+ pBattContext->hEcEventReg = NULL;
+ }
+
+ NvEcClose(pBattContext->hEc);
+ pBattContext->hEc = NULL;
+ }
+
+ if (pBattContext)
+ NvOdmOsFree(pBattContext);
+}
+
+/**
+ * Gets the AC line status.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param pStatus [OUT] A pointer to the AC line
+ * status returned by the ODM.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryGetAcLineStatus(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryAcLineStatus *pStatus)
+{
+#if NVEC_BATTERY_DISABLED
+ *pStatus = NvOdmBatteryAcLine_Online;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvU8 ACStatus = 0;
+ NvEcSystemGetStateResponsePayload SysQueryState;
+
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetAcLineStatus.\n"));
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* For R01 EC Firware report AC is online as it has not support for this */
+ if (pBattContext->ECVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01)
+ {
+ *pStatus = NvOdmBatteryAcLine_Online;
+ return NV_TRUE;
+ }
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_System;
+ EcRequest.RequestSubtype = NvEcSystemSubtype_GetStatus;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryGetAcLineStatus\n"));
+ *pStatus = NvOdmBatteryAcLine_Num;
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&SysQueryState, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+
+ ACStatus = SysQueryState.State[NVODM_BATTERY_SYSTEM_STATE_DATA1];
+
+ /* AC is present or not */
+ if (ACStatus & NVODM_BATTERY_SYSTEM_STATE_AC_PRESENT)
+ {
+ *pStatus = NvOdmBatteryAcLine_Online;
+ }
+ else
+ {
+ *pStatus = NvOdmBatteryAcLine_Offline;
+ }
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetAcLineStatus.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the battery status.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pStatus [OUT] A pointer to the battery
+ * status returned by the ODM.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryGetBatteryStatus(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *pStatus)
+{
+#if NVEC_BATTERY_DISABLED
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+#else
+ NvU8 BatterySlotStatus = 0, BatteryCapacityGuage = 0,
+ BattPresentState = 0, BattChargingState = 0;
+ NvU32 BatteryVoltage = 0; /* in mV */
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetBatteryStatus.\n"));
+
+ *pStatus = 0;
+
+ /*
+ * For R01 firmware Battery support is not present.
+ */
+ if (pBattContext->ECVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01)
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ NVODMBATTERY_PRINTF(("NvOdmBatteryGetBatteryStatus:EC Firmware R01"));
+ return NV_TRUE;
+ }
+
+ if (BatteryInst == NvOdmBatteryInst_Main)
+ {
+ if(NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(pBattContext,
+ NvOdmBatteryInst_Main,
+ &BatterySlotStatus,
+ &BatteryCapacityGuage))
+ {
+ BattPresentState = BatterySlotStatus & NVODM_BATTERY_PRESENT_IN_SLOT;
+ if (BattPresentState == NVODM_BATTERY_PRESENT_IN_SLOT)
+ {
+ BattChargingState = BatterySlotStatus >> NVODM_BATTERY_CHARGING_STATE_SHIFT;
+ BattChargingState &= NVODM_BATTERY_CHARGING_STATE_MASK;
+ if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_CHARGING)
+ *pStatus |= NVODM_BATTERY_STATUS_CHARGING;
+ else if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_DISCHARGING)
+ *pStatus |= NVODM_BATTERY_STATUS_DISCHARGING;
+ else if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_IDLE)
+ *pStatus |= NVODM_BATTERY_STATUS_IDLE;
+ }
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_NO_BATTERY;
+ return NV_TRUE;
+ }
+ }
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ return NV_TRUE;
+ }
+
+ /* Get the battery voltage to detetmine the Battery Flag */
+ if (NvOdmPrivBattGetBatteryVoltage(pBattContext, NvOdmBatteryInst_Main,
+ &BatteryVoltage))
+ {
+ if (BatteryVoltage >= NVODM_BATTERY_HIGH_VOLTAGE_MV)
+ *pStatus |= NVODM_BATTERY_STATUS_HIGH;
+ else if (BatteryVoltage >= NVODM_BATTERY_LOW_VOLTAGE_MV)
+ *pStatus |= NVODM_BATTERY_STATUS_LOW;
+ else
+ {
+ *pStatus |= NVODM_BATTERY_STATUS_CRITICAL;
+ /*
+ * Additional flag which tells battery is very critical
+ * and needs system shutdown.
+ */
+ if (BatteryVoltage <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV)
+ *pStatus |= NVODM_BATTERY_STATUS_VERY_CRITICAL;
+ }
+ }
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ return NV_TRUE;
+ }
+ }
+ else
+ {
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetBatteryStatus.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the battery data.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pData [OUT] A pointer to the battery
+ * data returned by the ODM.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryGetBatteryData(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvOdmBatteryData *pData)
+{
+ NvOdmBatteryData BatteryData;
+ NvU32 BatteryVoltage = 0, BatteryLifeTime = 0;
+ NvS32 BatteryCurrent = 0, BatteryAvgCurrent = 0;
+ NvU32 BatteryAvgTimeInterval = 0;
+ NvU32 BatteryTemp = 0;
+ NvU32 BattRemCap = 0, BattLastChargeFullCap = 0, BattCriticalCap = 0;
+#if BATTERY_EXTRA_INFO
+ NvU16 RemCapAlarm = 0;
+ NvU8 ConfigurationUnit = NVEC_BATTERY_CONFIGURATION_0_CAPACITY_UNITS_MAH;
+ NvU8 BattManufact[NVEC_MAX_RESPONSE_STRING_SIZE] = {0},
+ BattModel[NVEC_MAX_RESPONSE_STRING_SIZE] = {0};
+#endif
+ NvOdmBatteryDevice *pBattContext = NULL;
+ NvU8 BatterySlotStatus = 0, BatteryCapacityGuage = 0;
+
+ NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetBatteryData.\n"));
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ BatteryData.BatteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryTemperature = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryRemainingCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryLastChargeFullCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryCriticalCapacity = NVODM_BATTERY_DATA_UNKNOWN;
+
+ NV_ASSERT(hDevice);
+ NV_ASSERT(pData);
+ NV_ASSERT(BatteryInst <= NvOdmBatteryInst_Num);
+
+ if (BatteryInst == NvOdmBatteryInst_Main)
+ {
+ if (NvOdmPrivBattGetBatteryVoltage(pBattContext, NvOdmBatteryInst_Main,
+ &BatteryVoltage))
+ {
+ BatteryData.BatteryVoltage = BatteryVoltage;
+ }
+
+ if(NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(pBattContext,
+ NvOdmBatteryInst_Main, &BatterySlotStatus, &BatteryCapacityGuage))
+ {
+ BatteryData.BatteryLifePercent = BatteryCapacityGuage;
+ }
+
+#if BATTERY_EXTRA_INFO
+ /* ConfigurationUnit = NVEC_BATTERY_CONFIGURATION_0_CAPACITY_UNITS_10MWH; */
+ NvOdmBatterySetConfiguration(pBattContext, NvOdmBatteryInst_Main, ConfigurationUnit);
+ NvOdmBatteryGetConfiguration(pBattContext, NvOdmBatteryInst_Main, &ConfigurationUnit);
+#endif
+
+ if(NvOdmBatteryPrivGetLifeTime(pBattContext, NvOdmBatteryInst_Main, &BatteryLifeTime))
+ {
+ BatteryData.BatteryLifeTime = BatteryLifeTime;
+ }
+
+ if(NvOdmBatteryPrivGetCurrent(pBattContext, NvOdmBatteryInst_Main,
+ &BatteryCurrent))
+ {
+ BatteryData.BatteryCurrent = BatteryCurrent;
+ }
+
+ if(NvOdmBatteryPrivGetAverageCurrent(pBattContext,
+ NvOdmBatteryInst_Main, &BatteryAvgCurrent))
+ {
+ BatteryData.BatteryAverageCurrent = BatteryAvgCurrent;
+ }
+
+ if(NvOdmBatteryPrivGetAverageTimeInterval(pBattContext,
+ NvOdmBatteryInst_Main, &BatteryAvgTimeInterval))
+ {
+ BatteryData.BatteryAverageInterval = BatteryAvgTimeInterval;
+ }
+
+ if(NvOdmBatteryPrivGetTemperature(pBattContext, NvOdmBatteryInst_Main,
+ &BatteryTemp))
+ {
+ BatteryData.BatteryTemperature = BatteryTemp;
+ }
+
+ if(NvOdmBatteryPrivGetRemainingCapacity(pBattContext,
+ NvOdmBatteryInst_Main, &BattRemCap))
+ {
+ BatteryData.BatteryRemainingCapacity = BattRemCap;
+ }
+
+ if(NvOdmBatteryPrivGetLastFullChargeCapacity(pBattContext,
+ NvOdmBatteryInst_Main, &BattLastChargeFullCap))
+ {
+ BatteryData.BatteryLastChargeFullCapacity = BattLastChargeFullCap;
+ }
+
+ if(NvOdmBatteryPrivGetCriticalCapacity(pBattContext,
+ NvOdmBatteryInst_Main, &BattCriticalCap))
+ {
+ BatteryData.BatteryCriticalCapacity = BattCriticalCap;
+ }
+
+#if BATTERY_EXTRA_INFO
+ /* RemCapAlarm = 0x0101;*/ /* Some random value */
+ NvOdmBatterySetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, RemCapAlarm);
+ RemCapAlarm = 0;
+ NvOdmBatteryGetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, &RemCapAlarm);
+
+ NvOdmBatteryGetManufacturer(pBattContext, NvOdmBatteryInst_Main, BattManufact);
+ NvOdmBatteryGetModel(pBattContext, NvOdmBatteryInst_Main, BattModel);
+#endif
+
+ *pData = BatteryData;
+ }
+ else
+ {
+ *pData = BatteryData;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetBatteryData.\n"));
+#if NVEC_BATTERY_DISABLED
+ *pData = BatteryData;
+#endif
+ return NV_TRUE;
+}
+
+/**
+ * Gets the battery full life time.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pLifeTime [OUT] A pointer to the battery
+ * full life time returned by the ODM.
+ *
+ */
+void NvOdmBatteryGetBatteryFullLifeTime(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU32 *pLifeTime)
+{
+#if NVEC_BATTERY_DISABLED
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetDesignCapacityResponsePayload BatteryCapacity;
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetBatteryFullLifeTime.\n"));
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetDesignCapacity;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryGetBatteryFullLifeTime\n"));
+ }
+ else
+ {
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryCapacity, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+ *pLifeTime = BatteryCapacity.DesignCapacity[0];
+ *pLifeTime |= BatteryCapacity.DesignCapacity[1] << 8;
+ }
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetBatteryFullLifeTime.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+}
+
+
+/**
+ * Gets the battery chemistry.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param pChemistry [OUT] A pointer to the battery
+ * chemistry returned by the ODM.
+ *
+ */
+void NvOdmBatteryGetBatteryChemistry(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvOdmBatteryChemistry *pChemistry)
+{
+#if NVEC_BATTERY_DISABLED
+ *pChemistry = NVODM_BATTERY_DATA_UNKNOWN;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvEcBatteryGetTypeResponsePayload BatteryType;
+
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetBatteryChemistry.\n"));
+ *pChemistry = NVODM_BATTERY_DATA_UNKNOWN;
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetType;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \
+ NvOdmBatteryGetBatteryChemistry\n"));
+}
+ else
+ {
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NvOdmOsMemcpy(&BatteryType, EcResponse.Payload,
+ EcResponse.NumPayloadBytes);
+
+ if(!NvOsStrncmp(BatteryType.Type, "LION",
+ EcResponse.NumPayloadBytes))
+ *pChemistry = NvOdmBatteryChemistry_LION;
+ else if(!NvOsStrncmp(BatteryType.Type, "Alkaline",
+ EcResponse.NumPayloadBytes))
+ *pChemistry = NvOdmBatteryChemistry_Alkaline;
+ else if(!NvOsStrncmp(BatteryType.Type, "NICD",
+ EcResponse.NumPayloadBytes))
+ *pChemistry = NvOdmBatteryChemistry_NICD;
+ else if(!NvOsStrncmp(BatteryType.Type, "NIMH",
+ EcResponse.NumPayloadBytes))
+ *pChemistry = NvOdmBatteryChemistry_NIMH;
+ else if(!NvOsStrncmp(BatteryType.Type, "LIPOLY",
+ EcResponse.NumPayloadBytes))
+ *pChemistry = NvOdmBatteryChemistry_LIPOLY;
+ else if(!NvOsStrncmp(BatteryType.Type, "XINCAIR",
+ EcResponse.NumPayloadBytes))
+ *pChemistry = NvOdmBatteryChemistry_XINCAIR;
+ }
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetBatteryChemistry.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+}
diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h
new file mode 100644
index 000000000000..3ec7313a0bd4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2009-2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_BATTERY_INT_H
+#define INCLUDED_NVODM_BATTERY_INT_H
+
+#include "nvodm_query_gpio.h"
+#include "nvrm_gpio.h"
+#include "nvodm_services.h"
+#include "nvec.h"
+
+/* Module debug msg: 0=disable, 1=enable */
+#define NVODMBATTERY_ENABLE_PRINTF (0)
+
+#if (NVODMBATTERY_ENABLE_PRINTF)
+#define NVODMBATTERY_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODMBATTERY_PRINTF(x)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+/****************************************************************************/
+/*
+ * Macro to disable EC calls for battery operations
+ * until EC firware supports it
+ */
+#define NVEC_BATTERY_DISABLED 0
+/*
+ * Some extra battery info added which is not yet part of the
+ * BatteryData struct.
+ * Enable it to verify the these extra info with the EC firware
+ */
+#define BATTERY_EXTRA_INFO 0
+
+/* Enable to wakeup the AP from suspend */
+#define NVODM_WAKEUP_FROM_BATTERY_EVENT 1
+#define NVODM_WAKEUP_FROM_AC_EVENT 1
+
+/* Enable the Low Battery GPIO Interrupt */
+#define NVODM_LOWBATTERY_GPIO_INT 1
+
+/* Enable low capacity alarm wakeup */
+#define NVODM_BATTERY_LOW_CAPACITY_ALARM 1
+/****************************************************************************/
+
+#define NVODM_BATTERY_NUM_BATTERY_SLOTS_MASK 0x0F
+
+/* Battery Slot Status and Capacity Gauge Report */
+/* Data Byte 3 : Battery Slot Status */
+#define NVODM_BATTERY_SLOT_STATUS_DATA 0
+/*
+ * Data Byte 4 : Battery Capacity Gauge :
+ * Battery's relative remaining capacity in %
+ */
+#define NVODM_BATTERY_CAPACITY_GUAGE_DATA 1
+
+/*
+ * Battery Slot Status :
+ * Bit 0 = Present State:
+ * 1 = Battery is present in the respective slot
+ */
+#define NVODM_BATTERY_PRESENT_IN_SLOT 0x01
+
+#define NVODM_BATTERY_CHARGING_STATE_SHIFT 1
+#define NVODM_BATTERY_CHARGING_STATE_MASK 0x03
+
+/* Battery Slot Status : Bits 1-2 = Charging state */
+#define NVODM_BATTERY_CHARGING_STATE_IDLE 0x00
+#define NVODM_BATTERY_CHARGING_STATE_CHARGING 0x01
+#define NVODM_BATTERY_CHARGING_STATE_DISCHARGING 0x02
+#define NVODM_BATTERY_CHARGING_STATE_RESERVED 0x03
+
+/* Remaining capacity alarm bit is 3rd in slot status */
+#define NVODM_BATTERY_REM_CAP_ALARM_SHIFT 3
+#define NVODM_BATTERY_REM_CAP_ALARM_IS_SET 1
+
+/* Response System Status : Data Byte 3 System State Bits 7-0 */
+#define NVODM_BATTERY_SYSTEM_STATE_DATA1 0
+/* Response System Status : Data Byte 4 System State Bits 15-8 */
+#define NVODM_BATTERY_SYSTEM_STATE_DATA2 1
+/* System State Flags : AC Present : System State Bit 0 */
+#define NVODM_BATTERY_SYSTEM_STATE_AC_PRESENT 0x01
+
+#define NVODM_BATTERY_CHARGING_RATE_DATA_BYTES 3
+#define NVODM_BATTERY_CHARGING_RATE_UNIT 3
+
+/* Threshold for battery status.*/
+#define NVODM_BATTERY_FULL_VOLTAGE_MV 12600
+#define NVODM_BATTERY_HIGH_VOLTAGE_MV 10200
+#define NVODM_BATTERY_LOW_VOLTAGE_MV 10000
+#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 9500
+
+#define NVODM_BATTERY_EC_FIRMWARE_VER_R01 2
+#define NVODM_BATTERY_EC_FIRMWARE_VER_R04 8
+
+/* Bit 0 = Present State event */
+/* Bit 1 = Charging State event */
+/* Bit 2 = Remaining Capacity Alaram event */
+#define NVODM_BATTERY_SET_PRESENT_EVENT 0x01
+#define NVODM_BATTERY_SET_CHARGING_EVENT 0x02
+#define NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT 0x04
+
+/*
+ * Bit 0 => 0=Not Present, 1=Present
+ * Bit 1:2 => 00=Idle, 01=Charging,10=Discharging, 11=Reserved
+ * Bit 3 => 1=Remaining Capacity Alaram set
+ */
+#define NVODM_BATTERY_EVENT_MASK 0x0F
+
+typedef enum
+{
+ NvOdmBattCharingUnit_mW, /* Milli Watt */
+ NvOdmBattCharingUnit_mA, /* Milli Amps */
+ NvOdmBattCharingUnit_10mW, /* Milli Watt * 10 */
+
+ NvOdmBattCharingUnit_Num,
+ NvOdmBattCharingUnit_Max = 0x7fffffff
+
+} NvOdmBattCharingUnit;
+
+typedef struct NvOdmBatteryDeviceRec
+{
+ NvEcHandle hEc;
+ NvEcEventRegistrationHandle hEcEventReg;
+ NvOdmOsSemaphoreHandle hBattEventSem;
+ NvOdmOsSemaphoreHandle hClientBattEventSem;
+ NvOdmOsThreadHandle hBattEventThread;
+#if NVODM_LOWBATTERY_GPIO_INT
+ const NvOdmGpioPinInfo *pGpioPinInfo;
+ NvRmGpioPinHandle hPin;
+ NvRmGpioInterruptHandle GpioIntrHandle;
+ NvU32 PinCount;
+ NvRmDeviceHandle hRm;
+ NvRmGpioHandle hGpio;
+#endif
+ NvU8 BatteryEvent;
+ NvU8 ECVersion;
+ NvBool ExitThread;
+} NvOdmBatteryDevice;
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif /* INCLUDED_NVODM_BATTERY_INT_H */
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c
new file mode 100644
index 000000000000..63f51d9bdbd2
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvcommon.h"
+#include "nvodm_battery.h"
+
+typedef struct NvOdmBatteryDeviceRec
+{
+ NvBool bBattPresent;
+ NvBool bBattFull;
+} NvOdmBatteryDevice;
+
+/**
+ * Gets the battery event.
+ *
+ * @param hDevice A handle to the EC.
+ * @param pBatteryEvent Battery events
+ *
+ */
+void NvOdmBatteryGetEvent(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvU8 *pBatteryEvent)
+{
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ *pBatteryEvent = 0;
+}
+
+NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
+ NvOdmOsSemaphoreHandle *hOdmSemaphore)
+{
+ *hDevice = NULL;
+ return NV_FALSE;
+}
+
+void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice)
+{
+}
+
+/**
+ * Gets the AC line status.
+ *
+ * @param hDevice A handle to the EC.
+ * @param pStatus A pointer to the AC line
+ * status returned by the ODM.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryGetAcLineStatus(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryAcLineStatus *pStatus)
+{
+ *pStatus = NvOdmBatteryAcLine_Offline;
+ return NV_FALSE;
+}
+
+
+/**
+ * Gets the battery status.
+ *
+ * @param hDevice A handle to the EC.
+ * @param batteryInst The battery type.
+ * @param pStatus A pointer to the battery
+ * status returned by the ODM.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryGetBatteryStatus(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance batteryInst,
+ NvU8 *pStatus)
+{
+ *pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ return NV_FALSE;
+}
+
+/**
+ * Gets the battery data.
+ *
+ * @param hDevice A handle to the EC.
+ * @param batteryInst The battery type.
+ * @param pData A pointer to the battery
+ * data returned by the ODM.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool NvOdmBatteryGetBatteryData(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance batteryInst,
+ NvOdmBatteryData *pData)
+{
+ NvOdmBatteryData BatteryData;
+
+ BatteryData.BatteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryCurrent = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryTemperature = NVODM_BATTERY_DATA_UNKNOWN;
+ BatteryData.BatteryVoltage = NVODM_BATTERY_DATA_UNKNOWN;
+
+ *pData = BatteryData;
+ return NV_FALSE;
+}
+
+/**
+ * Gets the battery full life time.
+ *
+ * @param hDevice A handle to the EC.
+ * @param batteryInst The battery type.
+ * @param pLifeTime A pointer to the battery
+ * full life time returned by the ODM.
+ *
+ */
+void NvOdmBatteryGetBatteryFullLifeTime(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance batteryInst,
+ NvU32 *pLifeTime)
+{
+ *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN;
+}
+
+
+/**
+ * Gets the battery chemistry.
+ *
+ * @param hDevice A handle to the EC.
+ * @param batteryInst The battery type.
+ * @param pChemistry A pointer to the battery
+ * chemistry returned by the ODM.
+ *
+ */
+void NvOdmBatteryGetBatteryChemistry(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance batteryInst,
+ NvOdmBatteryChemistry *pChemistry)
+{
+ *pChemistry = NVODM_BATTERY_DATA_UNKNOWN;
+}
+
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile b/arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile
new file mode 100644
index 000000000000..8f6e46d214c6
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile
@@ -0,0 +1,12 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_keyboard.o
+obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_keyboard_stub.o
+obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_keyboard_stub.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c
new file mode 100644
index 000000000000..86ba9cbc6083
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c
@@ -0,0 +1,485 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "mach/nvrm_linux.h" // for s_hRmGlobal
+#include "nvodm_keyboard.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_services.h"
+#include "nvodm_query_gpio.h"
+#include "nvrm_gpio.h"
+#include "nvec.h"
+
+// Module debug: 0=disable, 1=enable
+#define NVODM_ENABLE_PRINTF 0
+
+#if NVODM_ENABLE_PRINTF
+#define NVODM_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODM_PRINTF(x)
+#endif
+
+// wake from keyboard disabled for now
+#define WAKE_FROM_KEYBOARD 1
+
+/* command main category */
+#define EC_KBC_COMMAND 0x5
+
+/* number of LEDS on the keyboard */
+enum {NUM_OF_LEDS = 3};
+
+/* Keyboard specific sub-commands */
+#define KBD_RESET_COMMAND 0xFF
+
+/* Special Scan Code set 1 codes */
+#define SC1_LSHIFT (0x2A)
+#define SC1_RSHIFT (0x36)
+#define SC1_SCROLL (0x46)
+#define SC1_PREFIX_E0 (0xE0)
+#define SC1_PREFIX_E1 (0xE1)
+
+/* Scan Code Set 1 break mask */
+#define SC1_BREAK_MASK (0x80)
+
+static NvEcHandle s_NvEcHandle = NULL; // nvec handle
+NvEcEventType EventTypes[] = {NvEcEventType_Keyboard}; // get only keyboard events from EC
+NvEcEvent KbdEvent = {0};
+static NvOdmOsSemaphoreHandle s_hKbcKeyScanRecvSema = NULL;
+static NvEcEventRegistrationHandle s_hEcEventRegistration = NULL;
+static NvBool s_KeyboardDeinit = NV_FALSE;
+
+#if WAKE_FROM_KEYBOARD
+extern NvRmGpioHandle s_hGpioGlobal;
+#define DEBOUNCE_TIME_MS 5 /* GPIO debounce time in ms */
+typedef struct NvOdmKbdContextRec
+{
+ const NvOdmGpioPinInfo *GpioPinInfo;
+ NvRmGpioPinHandle hPin;
+ NvRmGpioInterruptHandle GpioIntrHandle;
+ NvU32 PinCount;
+} NvOdmKbdContext;
+NvOdmKbdContext *hOdm;
+
+static void GpioInterruptHandler(void *args)
+{
+ NvOdmKbdContext *Odm = (NvOdmKbdContext *)args;
+
+ if (Odm)
+ {
+ NvRmGpioInterruptDone(Odm->GpioIntrHandle);
+ }
+}
+
+#endif
+
+// Shadow LED state
+NvU8 s_LedState = 0;
+
+NvBool NvOdmKeyboardInit(void)
+{
+ NvError NvStatus = NvError_Success;
+ NvEcRequest Request = {0};
+ NvEcResponse Response = {0};
+
+ /* get nvec handle */
+ NvStatus = NvEcOpen(&s_NvEcHandle, 0 /* instance */);
+ if (NvStatus != NvError_Success)
+ {
+ goto fail;
+ }
+
+ /* reset the EC to start the keyboard scanning */
+ Request.PacketType = NvEcPacketType_Request;
+ Request.RequestType = NvEcRequestResponseType_Keyboard;
+ Request.RequestSubtype = (NvEcRequestResponseSubtype) NvEcKeyboardSubtype_Enable;
+ Request.NumPayloadBytes = 0;
+
+ NvStatus = NvEcSendRequest(s_NvEcHandle, &Request, &Response, sizeof(Request), sizeof(Response));
+ if (NvStatus != NvError_Success)
+ {
+ goto cleanup;
+ }
+
+ /* check if command passed */
+ if (Response.Status != NvEcStatus_Success)
+ {
+ goto cleanup;
+ }
+
+#if WAKE_FROM_KEYBOARD
+ hOdm = NvOdmOsAlloc(sizeof(NvOdmKbdContext));
+ if (!hOdm) {
+ goto cleanup;
+ }
+
+ /* Check the supported GPIOs */
+ hOdm->GpioPinInfo = NvOdmQueryGpioPinMap(NvOdmGpioPinGroup_WakeFromECKeyboard,
+ 0,
+ &hOdm->PinCount);
+
+ NvRmGpioAcquirePinHandle(s_hGpioGlobal,
+ hOdm->GpioPinInfo->Port,
+ hOdm->GpioPinInfo->Pin,
+ &hOdm->hPin);
+ if (!hOdm->hPin) {
+ goto cleanup;
+ }
+
+ /* register to receive GPIO events */
+ NvStatus = NvRmGpioInterruptRegister(s_hGpioGlobal,
+ s_hRmGlobal,
+ hOdm->hPin,
+ (NvOsInterruptHandler)GpioInterruptHandler,
+ NvRmGpioPinMode_InputData,
+ hOdm,
+ &hOdm->GpioIntrHandle,
+ DEBOUNCE_TIME_MS);
+ if (NvStatus != NvError_Success) {
+ goto cleanup;
+ }
+
+ NvStatus = NvRmGpioInterruptEnable(hOdm->GpioIntrHandle);
+ if (NvStatus != NvError_Success) {
+ goto cleanup;
+ }
+
+ /* enable keyboard as wake up source */
+ Request.PacketType = NvEcPacketType_Request;
+ Request.RequestType = NvEcRequestResponseType_Keyboard;
+ Request.RequestSubtype = (NvEcRequestResponseSubtype)
+ NvEcKeyboardSubtype_ConfigureWake;
+ Request.NumPayloadBytes = 2;
+ Request.Payload[0] = NVEC_KEYBOARD_WAKE_ENABLE_0_ACTION_ENABLE;
+ Request.Payload[1] = NVEC_KEYBOARD_EVENT_TYPE_0_ANY_KEY_PRESS_ENABLE;
+
+ NvStatus = NvEcSendRequest(s_NvEcHandle,
+ &Request,
+ &Response,
+ sizeof(Request),
+ sizeof(Response));
+ if (NvStatus != NvError_Success) {
+ goto cleanup;
+ }
+
+ if (Response.Status != NvEcStatus_Success) {
+ goto cleanup;
+ }
+
+ /* enable key reporting on wake up */
+ Request.PacketType = NvEcPacketType_Request;
+ Request.RequestType = NvEcRequestResponseType_Keyboard;
+ Request.RequestSubtype = (NvEcRequestResponseSubtype)
+ NvEcKeyboardSubtype_ConfigureWakeKeyReport;
+ Request.NumPayloadBytes = 1;
+ Request.Payload[0] = NVEC_KEYBOARD_REPORT_WAKE_KEY_0_ACTION_ENABLE;
+
+ NvStatus = NvEcSendRequest(s_NvEcHandle,
+ &Request,
+ &Response,
+ sizeof(Request),
+ sizeof(Response));
+ if (NvStatus != NvError_Success) {
+ goto cleanup;
+ }
+
+ if (Response.Status != NvEcStatus_Success) {
+ goto cleanup;
+ }
+#endif
+
+ /* create semaphore which can be used to send scan codes to the clients */
+ s_hKbcKeyScanRecvSema = NvOdmOsSemaphoreCreate(0);
+ if (!s_hKbcKeyScanRecvSema)
+ {
+ goto cleanup;
+ }
+
+ /* register for keyboard events */
+ NvStatus = NvEcRegisterForEvents(
+ s_NvEcHandle, // nvec handle
+ &s_hEcEventRegistration,
+ (NvOsSemaphoreHandle)s_hKbcKeyScanRecvSema,
+ sizeof(EventTypes)/sizeof(NvEcEventType),
+ EventTypes, // receive keyboard scan codes
+ 1, // currently buffer only 1 packet from ECI at a time
+ sizeof(NvEcEvent));
+ if (NvStatus != NvError_Success)
+ {
+ goto cleanup;
+ }
+
+ /* success */
+ return NV_TRUE;
+
+cleanup:
+#if WAKE_FROM_KEYBOARD
+ NvRmGpioInterruptUnregister(s_hGpioGlobal, s_hRmGlobal, hOdm->GpioIntrHandle);
+ hOdm->GpioIntrHandle = NULL;
+ NvRmGpioReleasePinHandles(s_hGpioGlobal, &hOdm->hPin, hOdm->PinCount);
+ NvOdmOsFree(hOdm);
+ hOdm = NULL;
+#endif
+ (void)NvEcUnregisterForEvents(s_hEcEventRegistration);
+ s_hEcEventRegistration = NULL;
+
+ NvOdmOsSemaphoreDestroy(s_hKbcKeyScanRecvSema);
+ s_hKbcKeyScanRecvSema = NULL;
+
+ NvEcClose(s_NvEcHandle);
+fail:
+ s_NvEcHandle = NULL;
+
+ return NV_FALSE;
+}
+
+void NvOdmKeyboardDeInit(void)
+{
+#if WAKE_FROM_KEYBOARD
+ NvRmGpioInterruptUnregister(s_hGpioGlobal, s_hRmGlobal, hOdm->GpioIntrHandle);
+ hOdm->GpioIntrHandle = NULL;
+ NvRmGpioReleasePinHandles(s_hGpioGlobal, &hOdm->hPin, hOdm->PinCount);
+ hOdm->PinCount = 0;
+ NvOdmOsFree(hOdm);
+ hOdm = NULL;
+#endif
+
+ (void)NvEcUnregisterForEvents(s_hEcEventRegistration);
+ s_hEcEventRegistration = NULL;
+
+ s_KeyboardDeinit = NV_TRUE;
+ NvOdmOsSemaphoreSignal(s_hKbcKeyScanRecvSema);
+ NvOdmOsSemaphoreDestroy(s_hKbcKeyScanRecvSema);
+ s_hKbcKeyScanRecvSema = NULL;
+
+ NvEcClose(s_NvEcHandle);
+ s_NvEcHandle = NULL;
+}
+
+/* Gets the actual scan code for a key press */
+NvBool NvOdmKeyboardGetKeyData(NvU32 *pKeyScanCode, NvU8 *pScanCodeFlags, NvU32 Timeout)
+{
+ NvError NvStatus = NvError_Success;
+ NvU32 OutCode, OutCodeBytes, i;
+ NvU8 ScanCodeFlags;
+
+ if (!pKeyScanCode || !pScanCodeFlags || s_KeyboardDeinit)
+ {
+ return NV_FALSE;
+ }
+
+ if (Timeout != 0)
+ {
+ /* Use the timeout value */
+ if (!NvOdmOsSemaphoreWaitTimeout(s_hKbcKeyScanRecvSema, Timeout))
+ return NV_FALSE; // timed out
+ }
+ else
+ {
+ /* wait till we receive a scan code from the EC */
+ NvOdmOsSemaphoreWait(s_hKbcKeyScanRecvSema);
+ }
+
+ // stop scanning
+ if (s_KeyboardDeinit)
+ return NV_FALSE;
+
+ if (s_hEcEventRegistration)
+ {
+ NvStatus = NvEcGetEvent(s_hEcEventRegistration, &KbdEvent, sizeof(NvEcEvent));
+ if (NvStatus != NvError_Success)
+ {
+ NV_ASSERT(!"Could not receive scan code");
+ return NV_FALSE;
+ }
+ if (KbdEvent.NumPayloadBytes == 0)
+ {
+ NV_ASSERT(!"Received keyboard event with no scan codes");
+ return NV_FALSE;
+ }
+
+ // Pack scan code bytes from payload buffer into 32-bit dword
+ OutCode = (NvU32)KbdEvent.Payload[0];
+ OutCodeBytes = 1;
+ ScanCodeFlags = 0;
+
+ if (KbdEvent.NumPayloadBytes == 1)
+ NVODM_PRINTF(("EC Payload = 0x%x", KbdEvent.Payload[0]));
+ else
+ {
+ for (i = 0; i < KbdEvent.NumPayloadBytes; i++)
+ NVODM_PRINTF(("EC Payload = 0x%x", KbdEvent.Payload[i]));
+ }
+
+ for (i = 1; i < KbdEvent.NumPayloadBytes; i++)
+ {
+ if (KbdEvent.Payload[i-1] == SC1_PREFIX_E0)
+ {
+ // Temporary clear break flag just to check for extended shifts.
+ // If detected, remove the entire extended shift sequence, as
+ // it has no effect on SC1-to-VK translation
+ NvU8 sc = KbdEvent.Payload[i] & (~SC1_BREAK_MASK);
+ if ((sc == SC1_LSHIFT) || (sc == SC1_RSHIFT))
+ {
+ OutCode = OutCode >> 8;
+ OutCodeBytes--;
+ continue;
+ }
+ else if (KbdEvent.Payload[i] == SC1_SCROLL)
+ {
+ // If extended ScrollLock = Ctrl+Break, detected store it,
+ // set both make/break flags, and abort buffer packing, as
+ // the following bytes are just the break part of sequence
+ OutCode = (OutCode << 8) | ((NvU32)KbdEvent.Payload[i]);
+ OutCodeBytes++;
+ ScanCodeFlags = NV_ODM_SCAN_CODE_FLAG_MAKE |
+ NV_ODM_SCAN_CODE_FLAG_BREAK;
+ break;
+ }
+ }
+ if (KbdEvent.Payload[i] == SC1_PREFIX_E1)
+ {
+ // If 2nd half of Pause key is detected, set both make/break
+ // flags, and abort buffer packing, as the following bytes
+ // are just the break part of sequence
+ ScanCodeFlags = NV_ODM_SCAN_CODE_FLAG_MAKE |
+ NV_ODM_SCAN_CODE_FLAG_BREAK;
+ break;
+ }
+ // If not intercepted by special cases, pack scan code byte into
+ // the output dword
+ OutCode = (OutCode << 8) | ((NvU32)KbdEvent.Payload[i]);
+ OutCodeBytes++;
+ }
+
+ // After above packing all SC1 sequences are shrinked to 1-3 byte
+ // scan codes; 3-byte scan code always has both make/break flags
+ // already set; 2- and 1- byte scan code have break flag in low byte
+ // of low word
+ if (!ScanCodeFlags)
+ {
+ switch (OutCodeBytes)
+ {
+ case 2:
+ case 1:
+ ScanCodeFlags = (OutCode & ((NvU32)SC1_BREAK_MASK)) ?
+ NV_ODM_SCAN_CODE_FLAG_BREAK :
+ NV_ODM_SCAN_CODE_FLAG_MAKE;
+ OutCode &= ~((NvU32)SC1_BREAK_MASK);
+ break;
+
+ case 0:
+ // Dummy sequence, no actual keystrokes (FIXME - assert ?)
+ return NV_FALSE;
+
+ default:
+ NV_ASSERT(!"Not an SC1 payload - failed to pack");
+ return NV_FALSE;
+ }
+ }
+ *pScanCodeFlags = ScanCodeFlags;
+ *pKeyScanCode = OutCode;
+ return NV_TRUE;
+ }
+
+ return NV_FALSE;
+}
+
+NvBool NvOdmKeyboardToggleLights(NvU32 LedId)
+{
+ NvError NvStatus = NvError_Success;
+ NvEcRequest Request = {0};
+ NvEcResponse Response = {0};
+ NvU8 NewLedState[NUM_OF_LEDS] = {0}, i = 0;
+
+ /* return if EC handle is not available */
+ if (!s_NvEcHandle)
+ return NV_FALSE;
+
+ /* get the current state for each LED and toggle it */
+ for (i = 0; i < NUM_OF_LEDS; i++)
+ {
+ NewLedState[i] = s_LedState & (LedId & (1 << i));
+
+ if (LedId & (1 << i))
+ {
+ NewLedState[i] = (~NewLedState[i]) & 0x1;
+ }
+ }
+
+ /* update the new LED states to be programmed */
+ s_LedState = 0;
+ for (i = 0; i < NUM_OF_LEDS; i++)
+ {
+ s_LedState |= (NewLedState[i] << i);
+ }
+
+ NVODM_PRINTF(("NvOdmKeyboardToggleLights: LED State = 0x%x", s_LedState));
+
+ /* issue the Set LED command */
+ Request.PacketType = NvEcPacketType_Request;
+ Request.RequestType = NvEcRequestResponseType_Keyboard;
+ Request.RequestSubtype = (NvEcRequestResponseSubtype) NvEcKeyboardSubtype_SetLeds;
+ Request.NumPayloadBytes = 1;
+ Request.Payload[0] = (NvU8)s_LedState;
+
+ NvStatus = NvEcSendRequest(s_NvEcHandle, &Request, &Response, sizeof(Request), sizeof(Response));
+ if (NvStatus != NvError_Success)
+ {
+ NVODM_PRINTF(("NvOdmKeyboardToggleLights: NvEcSendRequest time out"));
+ return NV_FALSE;
+ }
+
+ /* check if command passed */
+ if (Response.Status != NvEcStatus_Success)
+ {
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool NvOdmKeyboardPowerHandler(NvBool PowerDown)
+{
+ return NV_TRUE;
+}
+
+/* -----------Stub Implemetation for Hold Switch Adaptation, since we do not need these-------*/
+
+NvBool NvOdmHoldSwitchInit(void)
+{
+ // firefly should not concerned about the "hold" key
+ return NV_FALSE;
+}
+
+void NvOdmHoldSwitchDeInit(void)
+{
+ // do nothing
+}
diff --git a/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c
new file mode 100644
index 000000000000..7779766c97ba
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_keyboard.h"
+
+
+NvBool NvOdmKeyboardInit(void)
+{
+ return NV_FALSE;
+}
+
+void NvOdmKeyboardDeInit(void)
+{
+}
+
+NvBool NvOdmKeyboardGetKeyData(NvU32 *KeyScanCode, NvBool *IsKeyUp, NvU32 Timeout)
+{
+ return NV_FALSE;
+}
+
+NvBool NvOdmKeyboardToggleLights(NvU32 LedId)
+{
+ return NV_FALSE;
+}
+
+NvBool NvOdmKeyboardPowerHandler(NvBool PowerDown)
+{
+ return NV_FALSE;
+}
+
+/* -----------Implemetation for Hold Switch Adaptation starts here-------*/
+
+NvBool NvOdmHoldSwitchInit(void)
+{
+ return NV_FALSE;
+}
+
+void NvOdmHoldSwitchDeInit(void)
+{
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile b/arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile
new file mode 100644
index 000000000000..a8897024bf2c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile
@@ -0,0 +1,10 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_mouse.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c
new file mode 100644
index 000000000000..a527ea540d55
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nvodm_mouse.h"
+#include "nvodm_mouse_int.h"
+#include "nvrm_drf.h"
+
+// Module debug: 0=disable, 1=enable
+#define NVODM_ENABLE_PRINTF 0
+
+#if NVODM_ENABLE_PRINTF
+#define NVODM_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODM_PRINTF(x)
+#endif
+
+// wake from mouse disabled for now
+#define WAKE_FROM_MOUSE 1
+
+/**
+ * streaming data from mouse can be compressed if (uncompressed) packet size is
+ * 3 bytes (as it is for all legacy ps2 mice). Compression works by not sending
+ * the first byte of the packet when it hasn't change.
+ */
+
+#define ENABLE_COMPRESSION 1
+
+#define ECI_MOUSE_DISABLE_SUPPORTED 1
+
+#define MAX_PAYLOAD_BYTES 32
+
+/**
+ * specify the ps2 port where the mouse is connected
+ */
+#define MOUSE_PS2_PORT_ID_0 NVEC_SUBTYPE_0_AUX_PORT_ID_0
+#define MOUSE_PS2_PORT_ID_1 NVEC_SUBTYPE_0_AUX_PORT_ID_1
+
+/** Implementation for the NvOdm Mouse */
+
+NvBool
+NvOdmMouseDeviceOpen(
+ NvOdmMouseDeviceHandle *hDevice)
+{
+ NvOdmMouseDevice *hMouseDev = NULL;
+ NvBool ret = NV_FALSE;
+ NvU32 InstanceId = 0, count = 0, MousePort = 0, i = 0;
+#if WAKE_FROM_MOUSE
+ NvError err = NvError_Success;
+ NvEcRequest Request = {0};
+ NvEcResponse Response = {0};
+#endif
+
+ // Allocate memory for request type structure
+ hMouseDev = (NvOdmMouseDevice *)NvOdmOsAlloc(sizeof(NvOdmMouseDevice));
+ if (!hMouseDev)
+ {
+ ret = NV_FALSE;
+ NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate hMouseDev!!"));
+ goto fail_safe;
+ }
+ NvOdmOsMemset(hMouseDev, 0, sizeof(NvOdmMouseDevice));
+
+ // open channel to the EC
+ if ((NvEcOpen(&hMouseDev->hEc, InstanceId)) != NvSuccess)
+ {
+ ret = NV_FALSE;
+ NVODMMOUSE_PRINTF(("NvEcOpen failed !!"));
+ goto fail_safe;
+ }
+
+ hMouseDev->pRequest = NULL;
+ hMouseDev->pResponse = NULL;
+ hMouseDev->pEvent = NULL;
+ hMouseDev->CompressionEnabled = NV_FALSE;
+ hMouseDev->CompressionState = 0x0;
+
+ do
+ {
+ hMouseDev->ValidMousePorts[count] = INVALID_MOUSE_PORT_ID;
+ count++;
+ } while (count <= MAX_NUM_MOUSE_PORTS);
+
+ // Allocate memory for request type structure
+ hMouseDev->pRequest = NvOdmOsAlloc(sizeof(NvEcRequest));
+ if (!hMouseDev->pRequest)
+ {
+ ret = NV_FALSE;
+ NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate pRequest!!"));
+ goto fail_safe;
+ }
+ NvOdmOsMemset(hMouseDev->pRequest, 0, sizeof(NvEcRequest));
+
+ // Allocate memory for response type structure
+ hMouseDev->pResponse = NvOdmOsAlloc(sizeof(NvEcResponse));
+ if (!hMouseDev->pResponse)
+ {
+ ret = NV_FALSE;
+ NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate pResponse!!"));
+ goto fail_safe;
+ }
+ NvOdmOsMemset(hMouseDev->pResponse, 0, sizeof(NvEcResponse));
+
+ // Allocate memory for event type structure
+ hMouseDev->pEvent = NvOdmOsAlloc(sizeof(NvEcEvent));
+ if (!hMouseDev->pEvent)
+ {
+ ret = NV_FALSE;
+ NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate pEvent!!"));
+ goto fail_safe;
+ }
+ NvOdmOsMemset(hMouseDev->pEvent, 0, sizeof(NvEcEvent));
+
+ MousePort = MOUSE_PS2_PORT_ID_0;
+ count = CMD_MAX_RETRIES + 1; i = 0;
+ while (count--)
+ {
+ // fill up request structure
+ Request.PacketType = NvEcPacketType_Request;
+ Request.RequestType = NvEcRequestResponseType_AuxDevice;
+ Request.RequestSubtype =
+ ((NvEcRequestResponseSubtype)
+ (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,MousePort))) |
+ ((NvEcRequestResponseSubtype)
+ NvEcAuxDeviceSubtype_SendCommand);
+ Request.NumPayloadBytes = 2;
+ Request.Payload[0] = 0xFF; // set the reset command
+ Request.Payload[1] = 3;
+
+ // Request to EC
+ err = NvEcSendRequest(hMouseDev->hEc, &Request, &Response, sizeof(Request),
+ sizeof(Response));
+
+ if (NvSuccess != err)
+ {
+ NVODMMOUSE_PRINTF(("NvEcSendRequest failed !!"));
+ break;
+ }
+
+ // mouse not found
+ if (NvEcStatus_Success != Response.Status)
+ {
+ NVODMMOUSE_PRINTF(("EC response failed !!"));
+ if (MousePort != MOUSE_PS2_PORT_ID_1)
+ {
+ count = CMD_MAX_RETRIES + 1;
+ MousePort = MOUSE_PS2_PORT_ID_1;
+ continue;
+ }
+ break;
+ }
+
+ if (Response.NumPayloadBytes != 3)
+ continue;
+
+ // success
+ if (Response.Payload[0] == 0xFA)
+ {
+ hMouseDev->ValidMousePorts[i] = MousePort;
+ if (MousePort != MOUSE_PS2_PORT_ID_1)
+ {
+ count = CMD_MAX_RETRIES + 1;
+ MousePort = MOUSE_PS2_PORT_ID_1;
+ i++;
+ continue;
+ }
+ break;
+ }
+ }
+
+#if WAKE_FROM_MOUSE
+ i = 0;
+ do
+ {
+ /* enable mouse as wake up source */
+ Request.PacketType = NvEcPacketType_Request;
+ Request.RequestType = NvEcRequestResponseType_AuxDevice;
+ Request.RequestSubtype = ((NvEcRequestResponseSubtype)
+ (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hMouseDev->ValidMousePorts[i]))) |
+ (NvEcRequestResponseSubtype)
+ NvEcAuxDeviceSubtype_ConfigureWake;
+ Request.NumPayloadBytes = 2;
+ Request.Payload[0] = NVEC_AUX_DEVICE_WAKE_ENABLE_0_ACTION_ENABLE;
+ Request.Payload[1] = NVEC_AUX_DEVICE_EVENT_TYPE_0_ANY_EVENT_ENABLE;
+
+ err = NvEcSendRequest(
+ hMouseDev->hEc,
+ &Request,
+ &Response,
+ sizeof(Request),
+ sizeof(Response));
+ if (err != NvError_Success)
+ {
+ ret = NV_FALSE;
+ goto fail_safe;
+ }
+
+ if (Response.Status != NvEcStatus_Success)
+ {
+ ret = NV_FALSE;
+ goto fail_safe;
+ }
+ } while (hMouseDev->ValidMousePorts[++i] != INVALID_MOUSE_PORT_ID);
+#endif
+
+ *hDevice = (NvOdmMouseDeviceHandle)hMouseDev;
+ ret = NV_TRUE;
+ return ret;
+
+fail_safe:
+ NvOdmMouseDeviceClose((NvOdmMouseDeviceHandle)hMouseDev);
+ hMouseDev = NULL;
+ return ret;
+}
+
+void
+NvOdmMouseDeviceClose(
+ NvOdmMouseDeviceHandle hDevice)
+{
+ if (hDevice)
+ {
+ // close channel to the EC
+ NvEcClose(hDevice->hEc);
+ hDevice->hEc = NULL;
+ // Free the request/response structure objects
+ NvOdmOsFree(hDevice->pRequest);
+ hDevice->pRequest = NULL;
+ NvOdmOsFree(hDevice->pResponse);
+ hDevice->pResponse = NULL;
+ NvOdmOsFree(hDevice->pEvent);
+ hDevice->pEvent = NULL;
+ NvOdmOsFree(hDevice);
+ hDevice = NULL;
+ }
+}
+
+NvBool NvOdmMouseEnableInterrupt(
+ NvOdmMouseDeviceHandle hDevice,
+ NvOdmOsSemaphoreHandle hInterruptSemaphore)
+{
+ NvError Status = NvSuccess;
+ NvEcEventType EventTypes[] = {
+ (NvEcEventType) (NvEcEventType_AuxDevice0 + MOUSE_PS2_PORT_ID_0),
+ (NvEcEventType) (NvEcEventType_AuxDevice0 + MOUSE_PS2_PORT_ID_1)
+ };
+
+ Status = NvEcRegisterForEvents(
+ hDevice->hEc,
+ &hDevice->hEcEventRegister,
+ (NvOsSemaphoreHandle)hInterruptSemaphore,
+ NV_ARRAY_SIZE(EventTypes), // number of EventType's
+ EventTypes, // Auxillary 0 event
+ 1, // One event packet is expected
+ // event packet size = packet overhead + size of the mouse sample;
+ // max sample size is 4 bytes (for an Intellimouse 5-button mouse)
+ NVEC_MIN_EVENT_SIZE+4);
+
+ if (Status != NvSuccess)
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmMouseDisableInterrupt(
+ NvOdmMouseDeviceHandle hDevice)
+{
+ NvError Status = NvSuccess;
+
+ // Un-register the events
+ Status = NvEcUnregisterForEvents(hDevice->hEcEventRegister);
+ if (Status != NvSuccess)
+ return NV_FALSE;
+
+ return NV_TRUE;
+}
+
+NvBool NvOdmMouseGetEventInfo(
+ NvOdmMouseDeviceHandle hDevice,
+ NvU32 *NumPayLoad,
+ NvU8 *PayLoadBuf)
+{
+ NvError Status = NvSuccess;
+
+ // Retrive the event info
+ Status = NvEcGetEvent(hDevice->hEcEventRegister,
+ hDevice->pEvent,
+ sizeof(NvEcEvent));
+
+ if (Status != NvSuccess)
+ return NV_FALSE;
+
+ /**
+ * if compression is enabled, latch the first data byte whenever a full-size
+ * packet is received; then insert the latched data whenever a compressed
+ * packet is seen.
+ */
+ if (hDevice->CompressionEnabled && hDevice->pEvent->NumPayloadBytes == 3)
+ {
+ hDevice->CompressionState = hDevice->pEvent->Payload[0];
+ }
+
+ /**
+ * fill in the payload and number of bytes
+ */
+ if (hDevice->CompressionEnabled && hDevice->pEvent->NumPayloadBytes == 2)
+ {
+ // compressed packet, so insert latched data at beginning
+ *NumPayLoad = 3;
+ PayLoadBuf[0] = hDevice->CompressionState;
+ PayLoadBuf[1] = hDevice->pEvent->Payload[0];
+ PayLoadBuf[2] = hDevice->pEvent->Payload[1];
+ }
+ else
+ {
+ *NumPayLoad = hDevice->pEvent->NumPayloadBytes;
+ NvOdmOsMemcpy(PayLoadBuf, hDevice->pEvent->Payload, *NumPayLoad);
+ }
+
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmMouseSendRequest(
+ NvOdmMouseDeviceHandle hDevice,
+ NvU32 cmd,
+ NvU32 ExpectedResponseSize,
+ NvU32 *NumPayLoad,
+ NvU8 *PayLoadBuf)
+{
+ NvError e;
+ NvEcRequest *pRequest = hDevice->pRequest;
+ NvEcResponse *pResponse = hDevice->pResponse;
+ NvU32 Index = 0;
+
+ do
+ {
+ // fill up request structure
+ pRequest->PacketType = NvEcPacketType_Request;
+ pRequest->RequestType = NvEcRequestResponseType_AuxDevice;
+ pRequest->RequestSubtype =
+ ((NvEcRequestResponseSubtype)
+ (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) |
+ ((NvEcRequestResponseSubtype)
+ NvEcAuxDeviceSubtype_SendCommand);
+ pRequest->NumPayloadBytes = 2;
+ pRequest->Payload[0] = cmd; // set the command
+ pRequest->Payload[1] = ExpectedResponseSize;
+
+ // Request to EC
+ e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest),
+ sizeof(*pResponse));
+
+ if (NvSuccess != e)
+ {
+ NVODMMOUSE_PRINTF(("NvEcSendRequest failed !!"));
+ return NV_FALSE;
+ }
+
+ if (NvEcStatus_Success != pResponse->Status)
+ {
+ NVODMMOUSE_PRINTF(("EC response failed !!"));
+ return NV_FALSE;
+ }
+
+ // store/process the Mouse response and return to the client driver
+ *NumPayLoad = pResponse->NumPayloadBytes;
+ NvOdmOsMemcpy(PayLoadBuf, &pResponse->Payload, *NumPayLoad);
+ } while (hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID);
+
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmMouseStartStreaming(
+ NvOdmMouseDeviceHandle hDevice,
+ NvU32 NumBytesPerSample)
+{
+ NvError e;
+ NvEcRequest *pRequest = hDevice->pRequest;
+ NvEcResponse *pResponse = hDevice->pResponse;
+ NvU32 Index = 0;
+
+ if (!hDevice)
+ return NV_FALSE;
+
+ hDevice->NumBytesPerSample = NumBytesPerSample;
+
+#if ENABLE_COMPRESSION
+ /**
+ * automatically enable compression if sample size is 3 bytes
+ *
+ * compression is supported only for 3-byte data packets (which is the
+ * common case for ps/2 mice and mouses
+ *
+ * compression reduces communication bandwidth by eliminating the first data
+ * byte of the packet when it hasn't changed relative to the previous
+ * packet. Whenever a full-sized packet is sent, the first payload byte is
+ * latched so that it can be inserted into an n y following compressed packets.
+ */
+
+ if (NumBytesPerSample == 3)
+ {
+ do
+ {
+ // prepare Aux Device request for Set Compression
+ pRequest->PacketType = NvEcPacketType_Request;
+ pRequest->RequestType = NvEcRequestResponseType_AuxDevice;
+ pRequest->RequestSubtype =
+ ((NvEcRequestResponseSubtype)
+ (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) |
+ ((NvEcRequestResponseSubtype)
+ NvEcAuxDeviceSubtype_SetCompression);
+ pRequest->NumPayloadBytes = 1;
+ pRequest->Payload[0] = 1; // enable compression
+
+ // send request to EC
+ e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest),
+ sizeof(*pResponse));
+
+ if (NvSuccess != e)
+ {
+ NVODMMOUSE_PRINTF(("NvEcSendRequest (compression) failed !!"));
+ return NV_FALSE;
+ }
+
+ // check status reported by EC
+ if (NvEcStatus_Success != pResponse->Status)
+ {
+ NVODMMOUSE_PRINTF(("EC response (compression) failed !!"));
+ return NV_FALSE;
+ }
+ } while(hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID);
+
+ hDevice->CompressionEnabled = NV_TRUE;
+ hDevice->CompressionState = 0x0;
+ }
+ else
+ {
+ // compression not supported due to packet size (!= 3 bytes)
+ hDevice->CompressionEnabled = NV_FALSE;
+ }
+#else // ENABLE_COMPRESSION
+ // disable compression
+ hDevice->CompressionEnabled = NV_FALSE;
+#endif // ENABLE_COMPRESSION
+
+ // prepare Aux Device request for Auto-Receive N Bytes
+ Index = 0;
+ do
+ {
+ pRequest->PacketType = NvEcPacketType_Request;
+ pRequest->RequestType = NvEcRequestResponseType_AuxDevice;
+ pRequest->RequestSubtype =
+ ((NvEcRequestResponseSubtype)
+ (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) |
+ ((NvEcRequestResponseSubtype)
+ NvEcAuxDeviceSubtype_AutoReceiveBytes);
+ pRequest->NumPayloadBytes = 1;
+ pRequest->Payload[0] = NumBytesPerSample;
+
+ // send request to EC
+ e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest),
+ sizeof(*pResponse));
+
+ if (NvSuccess != e)
+ {
+ NVODMMOUSE_PRINTF(("NvEcSendRequest (auto-receive) failed !!"));
+ return NV_FALSE;
+ }
+
+ // check status reported by EC
+ if (NvEcStatus_Success != pResponse->Status)
+ {
+ NVODMMOUSE_PRINTF(("EC response (auto-receive) failed !!"));
+ return NV_FALSE;
+ }
+ } while(hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID);
+
+ return NV_TRUE;
+}
+
+/**
+ * Power suspend for mouse.
+ *
+ */
+NvBool NvOdmMousePowerSuspend(NvOdmMouseDeviceHandle hDevice)
+{
+#if ECI_MOUSE_DISABLE_SUPPORTED
+ NvError e;
+ NvEcRequest *pRequest = hDevice->pRequest;
+ NvEcResponse *pResponse = hDevice->pResponse;
+ NvU32 Index = 0;
+
+ if (!hDevice || !pRequest || !pResponse)
+ return NV_FALSE;
+
+ NV_ASSERT(hDevice->hEc);
+ NV_ASSERT(hDevice->pRequest);
+ NV_ASSERT(hDevice->pResponse);
+
+ // cancel auto-receive (disables event reporting)
+
+ NVODM_PRINTF(("NvOdmMousePowerSuspend: Cancel Auto Receive\n"));
+
+ do
+ {
+ // fill up request structure
+ pRequest->PacketType = NvEcPacketType_Request;
+ pRequest->RequestType = NvEcRequestResponseType_AuxDevice;
+ pRequest->RequestSubtype =
+ ((NvEcRequestResponseSubtype)
+ (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) |
+ ((NvEcRequestResponseSubtype)
+ NvEcAuxDeviceSubtype_CancelAutoReceive);
+ pRequest->NumPayloadBytes = 0;
+
+ // Request to EC
+ e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest),
+ sizeof(*pResponse));
+
+ if (NvSuccess != e)
+ {
+ NVODMMOUSE_PRINTF(("NvOdmMousePowerSuspend: NvEcSendRequest failed !!"));
+ return NV_FALSE;
+ }
+
+ if (NvEcStatus_Success != pResponse->Status)
+ {
+ NVODMMOUSE_PRINTF(("NvOdmMousePowerSuspend: EC response failed !!"));
+ return NV_FALSE;
+ }
+ } while(hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID);
+#endif
+ NVODM_PRINTF(("NvOdmMousePowerSuspend: Exit success\n"));
+
+ return NV_TRUE;
+}
+
+/**
+ * Power resume for mouse.
+ *
+ */
+NvBool NvOdmMousePowerResume(NvOdmMouseDeviceHandle hDevice)
+{
+#if ECI_MOUSE_DISABLE_SUPPORTED
+ if (!hDevice)
+ return NV_FALSE;
+
+ NVODM_PRINTF(("NvOdmMousePowerResume: Start Streaming\n"));
+
+ if (!NvOdmMouseStartStreaming(hDevice, hDevice->NumBytesPerSample))
+ return NV_FALSE;
+#endif
+ NVODM_PRINTF(("NvOdmMousePowerResume: Exit success\n"));
+
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h
new file mode 100644
index 000000000000..2e3a6cc8b71a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_MOUSE_INT_H
+#define INCLUDED_NVODM_MOUSE_INT_H
+
+#include "nvodm_services.h"
+#include "nvodm_touch.h"
+#include "nvec.h"
+
+// Module debug: 0=disable, 1=enable
+#define NVODMMOUSE_ENABLE_PRINTF (0)
+
+#define MAX_NUM_MOUSE_PORTS 4
+#define INVALID_MOUSE_PORT_ID 0xF
+#define CMD_MAX_RETRIES 3
+
+#if (NVODMMOUSE_ENABLE_PRINTF)
+#define NVODMMOUSE_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODMMOUSE_PRINTF(x)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct NvOdmMouseDeviceRec
+{
+ NvEcHandle hEc;
+ NvEcRequest *pRequest;
+ NvEcResponse *pResponse;
+ NvEcEvent *pEvent;
+ NvEcEventRegistrationHandle hEcEventRegister;
+ NvBool CompressionEnabled;
+ NvU8 CompressionState;
+ NvU32 NumBytesPerSample;
+ NvU32 ValidMousePorts[MAX_NUM_MOUSE_PORTS + 1];
+} NvOdmMouseDevice;
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_MOUSE_INT_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile
new file mode 100644
index 000000000000..071c1f60cc28
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile
@@ -0,0 +1,12 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_scrollwheel_stub.o
+obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_scrollwheel.o
+obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_scrollwheel.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c
new file mode 100644
index 000000000000..392ff053ae1f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2006-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_scrollwheel.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_query.h"
+
+#define SCROLL_WHEEL_GUID NV_ODM_GUID('s', 'c', 'r', 'o', 'l', 'w', 'h', 'l')
+#define DEBOUNCE_TIME_MS 0
+
+typedef struct NvOdmScrollWheelRec
+{
+ // Gpio Handle
+ NvOdmServicesGpioHandle hGpio;
+ // Pin handles to all the 4 Gpio pins
+ NvOdmGpioPinHandle hInputPin1;
+ NvOdmGpioPinHandle hInputPin2;
+ NvOdmGpioPinHandle hSelectPin;
+ NvOdmGpioPinHandle hOnOffPin;
+ // Stores the key events the client had registered for.
+ NvOdmScrollWheelEvent RegisterEvents;
+ NvOdmOsSemaphoreHandle EventSema;
+ NvOdmServicesGpioIntrHandle IntrHandle[2];
+ NvOdmScrollWheelEvent Event;
+ NvU32 LastPin1Val;
+ NvOdmOsMutexHandle hKeyEventMutex;
+ NvOdmOsThreadHandle hDebounceRotThread;
+ NvOdmOsSemaphoreHandle hDebounceRotSema;
+ NvOdmOsSemaphoreHandle hDummySema;
+ volatile NvU32 shutdown;
+ volatile NvBool Debouncing;
+} NvOdmScrollWheel;
+
+static NvU32
+GetReliablePinValue(NvOdmServicesGpioHandle hGpio,
+ NvOdmGpioPinHandle hPin)
+{
+ NvU32 data = (NvU32)-1;
+ const int sampleCount = 10;
+ int i = 0;
+
+ while (i < sampleCount)
+ {
+ NvU32 currData;
+ NvOdmGpioGetState(hGpio, hPin, &currData);
+ if (currData == data)
+ {
+ i++;
+ }
+ else
+ {
+ data = currData;
+ i = 0;
+ }
+ }
+
+ return data;
+}
+
+static void
+ScrollWheelDebounceRotThread(void *arg)
+{
+ NvOdmScrollWheelHandle hOdmScrollWheel = (NvOdmScrollWheelHandle)arg;
+ const NvU32 debounceTimeMS = 2;
+
+ while (!hOdmScrollWheel->shutdown)
+ {
+ // If a scroll wheel event is detected, wait <debounceTime> milliseconds
+ // and then read the Terminal 1 pin to determine the current level
+ NvOdmOsSemaphoreWait(hOdmScrollWheel->hDebounceRotSema);
+ // The dummy semaphore never gets signalled so it will always timeout
+ NvOdmOsSemaphoreWaitTimeout(hOdmScrollWheel->hDummySema, debounceTimeMS);
+ //NvOdmGpioGetState(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin1, &hOdmScrollWheel->LastPin1Val);
+ hOdmScrollWheel->LastPin1Val = GetReliablePinValue(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin1);
+ NvOdmGpioConfig(hOdmScrollWheel->hGpio,
+ hOdmScrollWheel->hInputPin1,
+ hOdmScrollWheel->LastPin1Val ?
+ NvOdmGpioPinMode_InputInterruptFallingEdge :
+ NvOdmGpioPinMode_InputInterruptRisingEdge);
+ hOdmScrollWheel->Debouncing = NV_FALSE;
+ }
+}
+
+static void RotGpioInterruptHandler(void *arg)
+{
+ NvOdmScrollWheelHandle hOdmScrollWheel = (NvOdmScrollWheelHandle)arg;
+ NvU32 InPinValue2;
+ NvOdmScrollWheelEvent Event = NvOdmScrollWheelEvent_None;
+
+ /* if still debouncing, ignore interrupt */
+ if (hOdmScrollWheel->Debouncing)
+ {
+ NvOdmGpioInterruptDone(hOdmScrollWheel->IntrHandle[1]);
+ return;
+ }
+ NvOdmGpioGetState(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin2, &InPinValue2);
+
+ if (InPinValue2 == hOdmScrollWheel->LastPin1Val)
+ {
+ Event = NvOdmScrollWheelEvent_RotateAntiClockWise;
+ }
+ else
+ {
+ Event = NvOdmScrollWheelEvent_RotateClockWise;
+ }
+
+ Event &= hOdmScrollWheel->RegisterEvents;
+ if (Event)
+ {
+ NvOdmOsMutexLock(hOdmScrollWheel->hKeyEventMutex);
+ hOdmScrollWheel->Event &= ~(NvOdmScrollWheelEvent_RotateClockWise |
+ NvOdmScrollWheelEvent_RotateAntiClockWise);
+ hOdmScrollWheel->Event |= Event;
+ NvOdmOsMutexUnlock(hOdmScrollWheel->hKeyEventMutex);
+ NvOdmOsSemaphoreSignal(hOdmScrollWheel->EventSema);
+ }
+ /* start debounce */
+ hOdmScrollWheel->Debouncing = NV_TRUE;
+ NvOdmOsSemaphoreSignal(hOdmScrollWheel->hDebounceRotSema);
+
+ NvOdmGpioInterruptDone(hOdmScrollWheel->IntrHandle[1]);
+}
+
+static void SelectGpioInterruptHandler(void *arg)
+{
+ NvOdmScrollWheelHandle hOdmScrollWheel = (NvOdmScrollWheelHandle)arg;
+ NvU32 CurrSelectPinState;
+ NvOdmScrollWheelEvent Event = NvOdmScrollWheelEvent_None;
+
+ NvOdmGpioGetState(hOdmScrollWheel->hGpio, hOdmScrollWheel->hSelectPin, &CurrSelectPinState);
+ Event = (CurrSelectPinState) ? NvOdmScrollWheelEvent_Release : NvOdmScrollWheelEvent_Press;
+ Event &= hOdmScrollWheel->RegisterEvents;
+
+ if (Event)
+ {
+ NvOdmOsMutexLock(hOdmScrollWheel->hKeyEventMutex);
+ hOdmScrollWheel->Event &= ~(NvOdmScrollWheelEvent_Press | NvOdmScrollWheelEvent_Release);
+ hOdmScrollWheel->Event |= Event;
+ NvOdmOsMutexUnlock(hOdmScrollWheel->hKeyEventMutex);
+ NvOdmOsSemaphoreSignal(hOdmScrollWheel->EventSema);
+ }
+
+ NvOdmGpioInterruptDone(hOdmScrollWheel->IntrHandle[0]);
+}
+
+NvOdmScrollWheelHandle
+NvOdmScrollWheelOpen(
+ NvOdmOsSemaphoreHandle hNotifySema,
+ NvOdmScrollWheelEvent RegisterEvents)
+{
+ NvOdmScrollWheelHandle hOdmScroll = NULL;
+ NvOdmPeripheralConnectivity *pConnectivity;
+ NvU32 i;
+ NvOdmInterruptHandler RotIntrHandler = (NvOdmInterruptHandler)RotGpioInterruptHandler;
+ NvOdmInterruptHandler SelectIntrHandler = (NvOdmInterruptHandler)SelectGpioInterruptHandler;
+ NvU32 GpioInstance[4];
+ NvU32 GpioPin[4];
+ NvU32 GpioIndex;
+
+ pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(SCROLL_WHEEL_GUID);
+
+ if (pConnectivity == NULL)
+ return NULL;
+
+ // Should be IO class device
+ if (pConnectivity->Class != NvOdmPeripheralClass_HCI)
+ return NULL;
+
+ // Minimum 4 entry for the 4 line of GPIO
+ if (pConnectivity->NumAddress < 4)
+ return NULL;
+
+ GpioIndex = 0;
+ for (i=0; i<pConnectivity->NumAddress; i++)
+ {
+ if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_Gpio)
+ {
+ GpioInstance[GpioIndex] = pConnectivity->AddressList[i].Instance;
+ GpioPin[GpioIndex++] = pConnectivity->AddressList[i].Address;
+ }
+ }
+
+ // 4 GPIO entry for the scroll wheel
+ if (GpioIndex != 4)
+ return NULL;
+
+ hOdmScroll = NvOdmOsAlloc(sizeof(NvOdmScrollWheel));
+
+ if(!hOdmScroll)
+ {
+ return NULL;
+ }
+
+ NvOdmOsMemset(hOdmScroll, 0, sizeof(NvOdmScrollWheel));
+
+ hOdmScroll->EventSema = hNotifySema;
+ hOdmScroll->RegisterEvents = RegisterEvents;
+ hOdmScroll->Event = NvOdmScrollWheelEvent_None;
+
+ hOdmScroll->hKeyEventMutex = NvOdmOsMutexCreate();
+ hOdmScroll->hDebounceRotSema = NvOdmOsSemaphoreCreate(0);
+ hOdmScroll->hDummySema = NvOdmOsSemaphoreCreate(0);
+
+ if (!hOdmScroll->hKeyEventMutex ||
+ !hOdmScroll->hDebounceRotSema ||
+ !hOdmScroll->hDummySema)
+ {
+ goto ErrorExit;
+ }
+
+ // Getting the OdmGpio Handle
+ hOdmScroll->hGpio = NvOdmGpioOpen();
+ if (!hOdmScroll->hGpio)
+ {
+ goto ErrorExit;
+ }
+
+ hOdmScroll->hDebounceRotThread =
+ NvOdmOsThreadCreate((NvOdmOsThreadFunction)ScrollWheelDebounceRotThread,
+ (void*)hOdmScroll);
+ if (!hOdmScroll->hDebounceRotThread)
+ {
+ goto ErrorExit;
+ }
+
+ // Acquiring Pin Handles for all the four Gpio Pins
+ // First entry is Input GPIO1
+ // Second entry should be Input GPIO2
+ // Third entry should be Select
+ // 4 th entry should be OnOff pin
+ hOdmScroll->hInputPin1= NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio,
+ GpioInstance[3], GpioPin[3]);
+
+ hOdmScroll->hInputPin2 = NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio,
+ GpioInstance[0], GpioPin[0]);
+
+ hOdmScroll->hSelectPin= NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio,
+ GpioInstance[2], GpioPin[2]);
+
+ hOdmScroll->hOnOffPin= NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio,
+ GpioInstance[1], GpioPin[1]);
+
+ if (!hOdmScroll->hInputPin1 || !hOdmScroll->hInputPin2 ||
+ !hOdmScroll->hSelectPin || !hOdmScroll->hOnOffPin)
+ {
+ goto ErrorExit;
+ }
+
+ // Setting the ON/OFF pin to output mode and setting to Low.
+ NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hOnOffPin, NvOdmGpioPinMode_Output);
+ NvOdmGpioSetState(hOdmScroll->hGpio, hOdmScroll->hOnOffPin, 0);
+
+ // Configuring the other pins as input
+ // NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hSelectPin, NvOdmGpioPinMode_InputData);
+ NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hInputPin1, NvOdmGpioPinMode_InputData);
+ NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hInputPin2, NvOdmGpioPinMode_InputData);
+
+ if (NvOdmGpioInterruptRegister(hOdmScroll->hGpio, &hOdmScroll->IntrHandle[0],
+ hOdmScroll->hSelectPin, NvOdmGpioPinMode_InputInterruptAny,
+ SelectIntrHandler, (void *)(hOdmScroll), DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ goto ErrorExit;
+ }
+
+ hOdmScroll->LastPin1Val = GetReliablePinValue(hOdmScroll->hGpio, hOdmScroll->hInputPin1);
+
+ if (NvOdmGpioInterruptRegister(hOdmScroll->hGpio, &hOdmScroll->IntrHandle[1],
+ hOdmScroll->hInputPin1, hOdmScroll->LastPin1Val ?
+ NvOdmGpioPinMode_InputInterruptFallingEdge :
+ NvOdmGpioPinMode_InputInterruptRisingEdge,
+ RotIntrHandler, (void *)(hOdmScroll), DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ goto ErrorExit;
+ }
+
+ if (!hOdmScroll->IntrHandle[0] || !hOdmScroll->IntrHandle[1])
+ {
+ goto ErrorExit;
+ }
+
+ hOdmScroll->Debouncing = NV_FALSE;
+
+ return hOdmScroll;
+
+ ErrorExit:
+ NvOdmScrollWheelClose(hOdmScroll);
+ return NULL;
+}
+
+void NvOdmScrollWheelClose(NvOdmScrollWheelHandle hOdmScrollWheel)
+{
+ if (hOdmScrollWheel)
+ {
+ hOdmScrollWheel->shutdown = 1;
+
+ if (hOdmScrollWheel->hDebounceRotThread)
+ {
+ if (hOdmScrollWheel->hDebounceRotSema)
+ NvOdmOsSemaphoreSignal(hOdmScrollWheel->hDebounceRotSema);
+ NvOdmOsThreadJoin(hOdmScrollWheel->hDebounceRotThread);
+ }
+
+ if (hOdmScrollWheel->hGpio)
+ {
+ if (hOdmScrollWheel->IntrHandle[0])
+ {
+ NvOdmGpioInterruptUnregister(hOdmScrollWheel->hGpio,
+ hOdmScrollWheel->hSelectPin,
+ hOdmScrollWheel->IntrHandle[0]);
+ }
+ if (hOdmScrollWheel->IntrHandle[1])
+ {
+ NvOdmGpioInterruptUnregister(hOdmScrollWheel->hGpio,
+ hOdmScrollWheel->hInputPin1,
+ hOdmScrollWheel->IntrHandle[1]);
+ }
+
+ if (hOdmScrollWheel->hOnOffPin)
+ {
+ NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hOnOffPin);
+ }
+
+ if (hOdmScrollWheel->hInputPin1)
+ {
+ NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin1);
+ }
+ if (hOdmScrollWheel->hInputPin2)
+ {
+ NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin2);
+ }
+
+ if (hOdmScrollWheel->hSelectPin)
+ {
+ NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hSelectPin);
+ }
+
+ NvOdmGpioClose(hOdmScrollWheel->hGpio);
+ }
+
+ if (hOdmScrollWheel->hDummySema)
+ {
+ NvOdmOsSemaphoreDestroy(hOdmScrollWheel->hDummySema);
+ }
+ if (hOdmScrollWheel->hDebounceRotSema)
+ {
+ NvOdmOsSemaphoreDestroy(hOdmScrollWheel->hDebounceRotSema);
+ }
+ if (hOdmScrollWheel->hKeyEventMutex)
+ {
+ NvOdmOsMutexDestroy(hOdmScrollWheel->hKeyEventMutex);
+ }
+
+ NvOdmOsFree(hOdmScrollWheel);
+ }
+}
+
+NvOdmScrollWheelEvent NvOdmScrollWheelGetEvent(NvOdmScrollWheelHandle hOdmScrollWheel)
+{
+ NvOdmScrollWheelEvent Event;
+ NvOdmOsMutexLock(hOdmScrollWheel->hKeyEventMutex);
+ Event = hOdmScrollWheel->Event;
+ hOdmScrollWheel->Event = NvOdmScrollWheelEvent_None;
+ NvOdmOsMutexUnlock(hOdmScrollWheel->hKeyEventMutex);
+ return Event;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c
new file mode 100644
index 000000000000..cba93b0b9d2d
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_scrollwheel.h"
+
+
+NvOdmScrollWheelHandle
+NvOdmScrollWheelOpen(
+ NvOdmOsSemaphoreHandle hNotifySema,
+ NvOdmScrollWheelEvent RegisterEvents)
+{
+ return NULL;
+}
+
+void NvOdmScrollWheelClose(NvOdmScrollWheelHandle hOdmScrollWheel)
+{
+}
+
+NvOdmScrollWheelEvent NvOdmScrollWheelGetEvent(NvOdmScrollWheelHandle hOdmScrollWheel)
+{
+ return NvOdmScrollWheelEvent_None;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/Makefile b/arch/arm/mach-tegra/odm_kit/platform/touch/Makefile
new file mode 100644
index 000000000000..457bacd20c8c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/Makefile
@@ -0,0 +1,27 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ifeq ($(CONFIG_TEGRA_ODM_CONCORDE),y)
+ is_tpk_touch := y
+endif
+
+ifeq ($(CONFIG_TEGRA_ODM_WHISTLER),y)
+ is_tpk_touch := y
+endif
+
+ifeq ($(CONFIG_TEGRA_ODM_HARMONY),y)
+ is_panjit_touch := y
+endif
+
+ccflags-$(is_tpk_touch) += -DNV_TOUCH_TPK
+ccflags-$(is_panjit_touch) += -DNV_TOUCH_PANJIT
+
+obj-y += nvodm_touch.o
+obj-$(is_tpk_touch) += nvodm_touch_tpk.o
+obj-$(is_panjit_touch) += nvodm_touch_panjit.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c
new file mode 100644
index 000000000000..bf7d3eaa3049
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2006-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_touch.h"
+#include "nvodm_touch_int.h"
+
+#if defined(NV_TOUCH_TPK)
+#include "nvodm_touch_tpk.h"
+#endif
+#if defined(NV_TOUCH_PANJIT)
+#include "nvodm_touch_panjit.h"
+#endif
+
+/** Implementation for the NvOdm TouchPad */
+
+NvBool
+NvOdmTouchDeviceOpen( NvOdmTouchDeviceHandle *hDevice )
+{
+ NvBool ret = NV_TRUE;
+
+#if defined(NV_TOUCH_TPK)
+ ret = TPK_Open(hDevice);
+#endif
+#if defined(NV_TOUCH_PANJIT)
+ ret = PANJIT_Open(hDevice);
+#endif
+
+ return ret;
+}
+
+
+void
+NvOdmTouchDeviceGetCapabilities(NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities)
+{
+ hDevice->GetCapabilities(hDevice, pCapabilities);
+}
+
+
+NvBool
+NvOdmTouchReadCoordinate( NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo *coord)
+{
+ return hDevice->ReadCoordinate(hDevice, coord);
+}
+
+NvBool
+NvOdmTouchGetSampleRate(NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate)
+{
+ return hDevice->GetSampleRate(hDevice, pTouchSampleRate);
+}
+
+void NvOdmTouchDeviceClose(NvOdmTouchDeviceHandle hDevice)
+{
+ hDevice->Close(hDevice);
+}
+
+NvBool NvOdmTouchEnableInterrupt(NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hInterruptSemaphore)
+{
+ return hDevice->EnableInterrupt(hDevice, hInterruptSemaphore);
+}
+
+NvBool NvOdmTouchHandleInterrupt(NvOdmTouchDeviceHandle hDevice)
+{
+ return hDevice->HandleInterrupt(hDevice);
+}
+
+NvBool
+NvOdmTouchSetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 SampleRate)
+{
+ return hDevice->SetSampleRate(hDevice, SampleRate);
+}
+
+
+NvBool
+NvOdmTouchPowerControl(NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode)
+{
+ return hDevice->PowerControl(hDevice, mode);
+}
+
+void
+NvOdmTouchPowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff)
+{
+ hDevice->PowerOnOff(hDevice, OnOff);
+}
+
+
+NvBool
+NvOdmTouchOutputDebugMessage(NvOdmTouchDeviceHandle hDevice)
+{
+ return hDevice->OutputDebugMessage;
+}
+
+NvBool
+NvOdmTouchGetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer)
+{
+ return hDevice->GetCalibrationData(hDevice, NumOfCalibrationData, pRawCoordBuffer);
+}
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h
new file mode 100644
index 000000000000..d980c99b5c3e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_TOUCH_INT_H
+#define INCLUDED_NVODM_TOUCH_INT_H
+
+#include "nvodm_services.h"
+#include "nvodm_touch.h"
+
+
+// Module debug: 0=disable, 1=enable
+#define NVODMTOUCH_ENABLE_PRINTF (0)
+
+#if (NV_DEBUG && NVODMTOUCH_ENABLE_PRINTF)
+#define NVODMTOUCH_PRINTF(x) NvOdmOsDebugPrintf x
+#else
+#define NVODMTOUCH_PRINTF(x)
+#endif
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct NvOdmTouchDeviceRec{
+ NvBool (*ReadCoordinate) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo *coord);
+ NvBool (*EnableInterrupt) (NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hInterruptSemaphore);
+ NvBool (*HandleInterrupt) (NvOdmTouchDeviceHandle hDevice);
+ NvBool (*GetSampleRate) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate);
+ NvBool (*SetSampleRate) (NvOdmTouchDeviceHandle hDevice, NvU32 rate);
+ NvBool (*PowerControl) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode);
+ NvBool (*PowerOnOff) (NvOdmTouchDeviceHandle hDevice, NvBool OnOff);
+ void (*GetCapabilities) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities);
+ NvBool (*GetCalibrationData)(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer);
+ void (*Close) (NvOdmTouchDeviceHandle hDevice);
+ NvU16 CurrentSampleRate;
+ NvBool OutputDebugMessage;
+} NvOdmTouchDevice;
+
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+/** @} */
+
+#endif // INCLUDED_NVODM_TOUCH_INT_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c
new file mode 100644
index 000000000000..6516ccbce839
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_touch_panjit.h"
+#include "nvodm_query_discovery.h"
+#include "nvos.h"
+
+#define PANJIT_BENCHMARK_SAMPLE 0
+#define PANJIT_TOUCH_DEVICE_GUID NV_ODM_GUID('p','a','n','j','i','t','_','0')
+#define PANJIT_READ(dev, reg, buffer, len) \
+ PANJIT_ReadRegister(dev, reg, buffer, len)
+#define PANJIT_I2C_SPEED_KHZ 400
+#define SAMPLES_PER_SECOND 80
+
+#define SLEEP_MODE_NORMAL 0x00
+#define SLEEP_MODE_SENSOR_SLEEP 0x01
+
+#define X_MIN 0x00
+#define Y_MIN 0x00
+#define X_MAX 4095
+#define Y_MAX 4095
+#define PANJIT_I2C_TIMEOUT 1000
+#define PANJIT_DEBOUNCE_TIME_MS 1
+#define TP_DATA_LENGTH 12
+#define TP_TOUCH_STATE_BYTE 0
+#define TP_FINGER_ONE_MASK 0x01
+#define TP_FINGER_TWO_MASK 0x02
+#define TP_SPECIAL_FUNCTION_BYTE 9
+
+static const
+NvOdmTouchCapabilities PANJIT_Capabilities =
+{
+ 1, // IsMultiTouchSupported
+ 2, // MaxNumberOfFingerCoordReported;
+ 0, // IsRelativeDataSupported
+ 0, // MaxNumberOfRelativeCoordReported
+ 0, // MaxNumberOfWidthReported
+ 0, // MaxNumberOfPressureReported
+ (NvU32)NvOdmTouchGesture_Not_Supported, // Gesture
+ 0, // IsWidthSupported
+ 0, // IsPressureSupported
+ 1, // IsFingersSupported
+ X_MIN, // XMinPosition
+ Y_MIN, // YMinPosition
+ X_MAX, // XMaxPosition
+ Y_MAX, // YMaxPosition
+ 0
+};
+
+#define INT_PIN_ACTIVE_STATE 0
+
+static NvBool
+PANJIT_ReadRegister(
+ PANJIT_TouchDevice* hTouch,
+ NvU8 reg,
+ NvU8* buffer,
+ NvU32 len)
+{
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ TransactionInfo.Address = (hTouch->DeviceAddr | 0x1);
+ TransactionInfo.Buf = buffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = len;
+
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ &TransactionInfo,
+ 1,
+ hTouch->I2cClockSpeedKHz,
+ PANJIT_I2C_TIMEOUT);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ NVODMTOUCH_PRINTF(("I2C Read Failure = %d (addr=0x%x, reg=0x%x)\r\n", Error,
+ hTouch->DeviceAddr, reg));
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+static NvBool
+PANJIT_WriteRegister(
+ PANJIT_TouchDevice* hTouch,
+ NvU8 reg,
+ NvU8* buffer,
+ NvU32 len)
+{
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ TransactionInfo.Address = hTouch->DeviceAddr;
+ TransactionInfo.Buf = buffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = len;
+
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ &TransactionInfo,
+ 1,
+ hTouch->I2cClockSpeedKHz,
+ PANJIT_I2C_TIMEOUT);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ NVODMTOUCH_PRINTF(("I2C Write Failure = %d (addr=0x%x, reg=0x%x)\r\n",
+ Error, hTouch->DeviceAddr, reg));
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static void PANJIT_EnableScanMode(PANJIT_TouchDevice* hTouch)
+{
+ NvU8 buff[4];
+
+ // Enable Scan Mode.
+ buff[0] = 0;
+ buff[1] = 8;
+ PANJIT_WriteRegister(hTouch, 0, buff, 2);
+}
+
+static void PANJIT_ClearInterrupt(PANJIT_TouchDevice* hTouch)
+{
+ NvU8 buff[4];
+
+ // Clear Interrupt.
+ buff[0] = 1;
+ buff[1] = 0;
+ PANJIT_WriteRegister(hTouch, 0, buff, 2);
+}
+
+static NvBool PANJIT_Configure(PANJIT_TouchDevice* hTouch)
+{
+
+ NVODMTOUCH_PRINTF(("PANJIT_Configure\r\n"));
+
+ hTouch->SleepMode = SLEEP_MODE_NORMAL;
+ hTouch->SampleRate = SAMPLES_PER_SECOND;
+
+ // Enable Scan Mode.
+ PANJIT_EnableScanMode(hTouch);
+ // Clear Interrupt.
+ PANJIT_ClearInterrupt(hTouch);
+ return NV_TRUE;
+}
+
+static NvBool
+PANJIT_GetSample(
+ PANJIT_TouchDevice* hTouch,
+ NvOdmTouchCoordinateInfo* coord)
+{
+ NvU8 TouchData[TP_DATA_LENGTH] = {0};
+
+ NVODMTOUCH_PRINTF(("PANJIT_GetSample+\r\n"));
+
+ if (!hTouch || !coord)
+ return NV_FALSE;
+
+ if (!PANJIT_READ(hTouch, 0, &TouchData[0], TP_DATA_LENGTH))
+ return NV_FALSE;
+
+ NVODMTOUCH_PRINTF(("TouchData=0x%x %x %x %x %x %x %x %x %x %x %x %x\r\n",
+ TouchData[0], TouchData[1], TouchData[2], TouchData[3], TouchData[4],
+ TouchData[5], TouchData[6], TouchData[7],TouchData[8], TouchData[9],
+ TouchData[10], TouchData[11]));
+
+ /* Ignore No finger */
+ coord->fingerstate = (TouchData[10] & (TP_FINGER_ONE_MASK | TP_FINGER_TWO_MASK)) ?
+ NvOdmTouchSampleValidFlag : NvOdmTouchSampleIgnore;
+
+ if (coord->fingerstate == NvOdmTouchSampleIgnore)
+ {
+ if (hTouch->PrevFingers == 0)
+ {
+ NVODMTOUCH_PRINTF(("NvOdmTouchSampleIgnore\r\n"));
+ return NV_TRUE;
+ }
+ coord->fingerstate = NvOdmTouchSampleValidFlag;
+ }
+
+ // get the finger count
+ coord->additionalInfo.Fingers = TouchData[10];
+ if (coord->additionalInfo.Fingers > hTouch->Caps.MaxNumberOfFingerCoordReported)
+ coord->additionalInfo.Fingers = hTouch->Caps.MaxNumberOfFingerCoordReported;
+
+ NVODMTOUCH_PRINTF(("coord->additionalInfo.Fingers = %d\r\n",
+ coord->additionalInfo.Fingers));
+
+ if (coord->additionalInfo.Fingers)
+ {
+ coord->fingerstate |= NvOdmTouchSampleDownFlag;
+ coord->xcoord = TouchData[2];
+ coord->xcoord = ((coord->xcoord<<8)|(TouchData[3]));
+ coord->ycoord = TouchData[4];
+ coord->ycoord = ((coord->ycoord<<8)|(TouchData[5]));
+ coord->additionalInfo.multi_XYCoords[0][0] = coord->xcoord;
+ coord->additionalInfo.multi_XYCoords[0][1] = coord->ycoord;
+ coord->additionalInfo.multi_XYCoords[1][0] = (TouchData[6]<<8) | (TouchData[7]);
+ coord->additionalInfo.multi_XYCoords[1][1] = (TouchData[8]<<8) | (TouchData[9]);
+ }
+ hTouch->PrevFingers = coord->additionalInfo.Fingers;
+ NVODMTOUCH_PRINTF(("(%d,%d)\r\n", coord->xcoord, coord->ycoord));
+ return NV_TRUE;
+}
+
+static void PANJIT_GpioIsr(void *arg)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)arg;
+
+ /* Signal the touch thread to read the sample. After it is done reading the
+ * sample it should re-enable the interrupt. */
+ NvOdmOsSemaphoreSignal(hTouch->hIntSema);
+}
+
+NvBool
+PANJIT_ReadCoordinate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCoordinateInfo* coord)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+ NvBool status = NV_FALSE;
+ static NvU32 prevSamleTime;
+ NvU32 CurrentSampleTime;
+#if PANJIT_BENCHMARK_SAMPLE
+ NvU32 time;
+#endif
+ NvU32 pinValue;
+
+ NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &pinValue);
+ if (pinValue != INT_PIN_ACTIVE_STATE)
+ return NV_FALSE;
+
+ CurrentSampleTime = NvOdmOsGetTimeMS();
+ if (prevSamleTime)
+ {
+ if ((1000/hTouch->SampleRate) > (CurrentSampleTime - prevSamleTime))
+ {
+ NvOsSleepMS((1000/hTouch->SampleRate) - (CurrentSampleTime - prevSamleTime));
+ }
+ }
+ prevSamleTime = CurrentSampleTime;
+
+#if PANJIT_BENCHMARK_SAMPLE
+ time = CurrentSampleTime;
+#endif
+
+ status = PANJIT_GetSample(hTouch, coord);
+
+#if PANJIT_BENCHMARK_SAMPLE
+ NvOdmOsDebugPrintf("Touch sample time %d\r\n", NvOdmOsGetTimeMS() - time);
+#endif
+ return status;
+}
+
+void
+PANJIT_GetCapabilities(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCapabilities* pCapabilities)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ if (hTouch && pCapabilities)
+ *pCapabilities = hTouch->Caps;
+}
+
+void PANJIT_Close (NvOdmTouchDeviceHandle hDevice)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ if (hTouch)
+ {
+ if (hTouch->hGpio)
+ {
+ if (hTouch->hGpioIntr)
+ {
+ NvOdmGpioInterruptUnregister(hTouch->hGpio,
+ hTouch->hPin, hTouch->hGpioIntr);
+ hTouch->hGpioIntr = NULL;
+ }
+
+ if (hTouch->hPin)
+ {
+ NvOdmGpioReleasePinHandle(hTouch->hGpio, hTouch->hPin);
+ hTouch->hPin = NULL;
+ }
+
+ NvOdmGpioClose(hTouch->hGpio);
+ hTouch->hGpio = NULL;
+ }
+
+ if (hTouch->hOdmI2c)
+ {
+ NvOdmI2cClose(hTouch->hOdmI2c);
+ hTouch->hOdmI2c = NULL;
+ }
+
+ NvOdmOsFree(hTouch);
+ hTouch = NULL;
+ }
+}
+
+static void InitOdmTouch (NvOdmTouchDevice *pDev)
+{
+ if (pDev)
+ {
+ pDev->Close = PANJIT_Close;
+ pDev->GetCapabilities = PANJIT_GetCapabilities;
+ pDev->ReadCoordinate = PANJIT_ReadCoordinate;
+ pDev->EnableInterrupt = PANJIT_EnableInterrupt;
+ pDev->HandleInterrupt = PANJIT_HandleInterrupt;
+ pDev->GetSampleRate = PANJIT_GetSampleRate;
+ pDev->SetSampleRate = PANJIT_SetSampleRate;
+ pDev->PowerControl = PANJIT_PowerControl;
+ pDev->PowerOnOff = PANJIT_PowerOnOff;
+ pDev->GetCalibrationData = PANJIT_GetCalibrationData;
+ pDev->OutputDebugMessage = NV_TRUE;
+ }
+}
+
+NvBool PANJIT_Open(NvOdmTouchDeviceHandle *hDevice)
+{
+ PANJIT_TouchDevice *hTouch = NULL;
+ NvU32 i = 0;
+ NvU32 found = 0;
+ NvU32 GpioPort = 0;
+ NvU32 GpioPin = 0;
+ NvU32 I2cInstance = 0;
+ NvOdmIoModule IoModule = NvOdmIoModule_I2c;
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+
+ NVODMTOUCH_PRINTF(("NvOdm Touch : PANJIT_Open() \r\n"));
+
+ // allocate memory to be used for the handle
+ hTouch = NvOdmOsAlloc(sizeof(PANJIT_TouchDevice));
+ if (!hTouch)
+ return NV_FALSE;
+
+ NvOdmOsMemset(hTouch, 0, sizeof(PANJIT_TouchDevice));
+
+ /* set function pointers */
+ InitOdmTouch(&hTouch->OdmTouch);
+
+ // read the query database
+ pConnectivity = NvOdmPeripheralGetGuid(PANJIT_TOUCH_DEVICE_GUID);
+ if (!pConnectivity)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : pConnectivity is NULL Error \r\n"));
+ goto fail;
+ }
+
+ if (pConnectivity->Class != NvOdmPeripheralClass_HCI)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : didn't find any periperal\
+ in discovery query for touch device Error \r\n"));
+ goto fail;
+ }
+
+ for (i = 0; i < pConnectivity->NumAddress; i++)
+ {
+ switch (pConnectivity->AddressList[i].Interface)
+ {
+ case NvOdmIoModule_I2c:
+ case NvOdmIoModule_I2c_Pmu:
+ hTouch->DeviceAddr = pConnectivity->AddressList[i].Address;
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ found |= 1;
+ IoModule = pConnectivity->AddressList[i].Interface;
+ break;
+
+ case NvOdmIoModule_Gpio:
+ GpioPort = pConnectivity->AddressList[i].Instance;
+ GpioPin = pConnectivity->AddressList[i].Address;
+ found |= 2;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // see if we found the bus and GPIO used by the hardware
+ if ((found & 3) != 3)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch:peripheral connectivity problem \r\n"));
+ goto fail;
+ }
+
+ // allocate I2C instance
+ hTouch->hOdmI2c = NvOdmI2cOpen(IoModule, I2cInstance);
+ if (!hTouch->hOdmI2c)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmI2cOpen Error \r\n"));
+ goto fail;
+ }
+
+ // get the handle to the pin used as pen down interrupt
+ hTouch->hGpio = (NvOdmServicesGpioHandle)NvOdmGpioOpen();
+ if (!hTouch->hGpio)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmGpioOpen Error \r\n"));
+ goto fail;
+ }
+
+ hTouch->hPin = NvOdmGpioAcquirePinHandle(hTouch->hGpio, GpioPort, GpioPin);
+ if (!hTouch->hPin)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : Couldn't get GPIO pin \r\n"));
+ goto fail;
+ }
+
+ NvOdmGpioConfig(hTouch->hGpio, hTouch->hPin, NvOdmGpioPinMode_InputData);
+
+ /* set default capabilities */
+ NvOdmOsMemcpy(&hTouch->Caps, &PANJIT_Capabilities,
+ sizeof(NvOdmTouchCapabilities));
+
+ /* set default I2C speed */
+ hTouch->I2cClockSpeedKHz = PANJIT_I2C_SPEED_KHZ;
+
+ /* set max positions */
+ hTouch->Caps.XMaxPosition = X_MAX;
+ hTouch->Caps.YMaxPosition = Y_MAX;
+
+ PANJIT_Configure(hTouch);
+
+ *hDevice = (NvOdmTouchDeviceHandle)hTouch;
+ return NV_TRUE;
+
+ fail:
+ PANJIT_Close((NvOdmTouchDeviceHandle)hTouch);
+ hTouch = NULL;
+ return NV_FALSE;
+}
+
+NvBool
+PANJIT_EnableInterrupt(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmOsSemaphoreHandle hIntSema)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ NV_ASSERT(hIntSema);
+
+ /* can only be initialized once */
+ if (hTouch->hGpioIntr || hTouch->hIntSema)
+ return NV_FALSE;
+
+ hTouch->hIntSema = hIntSema;
+
+ if (NvOdmGpioInterruptRegister(
+ hTouch->hGpio,
+ &hTouch->hGpioIntr,
+ hTouch->hPin,
+ NvOdmGpioPinMode_InputInterruptLow,
+ PANJIT_GpioIsr,
+ (void*)hTouch,
+ PANJIT_DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ return NV_FALSE;
+ }
+
+ if (!hTouch->hGpioIntr)
+ return NV_FALSE;
+ return NV_TRUE;
+}
+
+NvBool PANJIT_HandleInterrupt(NvOdmTouchDeviceHandle hDevice)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+ NvU32 pinValue;
+
+ if (hTouch)
+ {
+ NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &pinValue);
+ if (pinValue == INT_PIN_ACTIVE_STATE)
+ {
+ // Clear Interrupt.
+ PANJIT_ClearInterrupt(hTouch);
+ NvOdmGpioInterruptDone(hTouch->hGpioIntr);
+ return NV_TRUE;
+ }
+ }
+ return NV_FALSE;
+}
+
+NvBool
+PANJIT_GetSampleRate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchSampleRate* pTouchSampleRate)
+{
+ if (pTouchSampleRate)
+ {
+ pTouchSampleRate->NvOdmTouchSampleRateHigh = SAMPLES_PER_SECOND;
+ pTouchSampleRate->NvOdmTouchSampleRateLow = SAMPLES_PER_SECOND;
+ pTouchSampleRate->NvOdmTouchCurrentSampleRate = 0; // 0 = low , 1 = high
+ }
+ return NV_TRUE;
+}
+
+NvBool PANJIT_SetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 rate)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ if (hTouch)
+ {
+ if (rate > SAMPLES_PER_SECOND)
+ hTouch->SampleRate = SAMPLES_PER_SECOND;
+ else
+ hTouch->SampleRate = rate;
+ }
+ return NV_TRUE;
+}
+
+NvBool
+PANJIT_PowerControl(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchPowerModeType mode)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+ NvU8 SleepMode;
+
+ switch(mode)
+ {
+ case NvOdmTouch_PowerMode_0:
+ SleepMode = SLEEP_MODE_NORMAL;
+ break;
+ case NvOdmTouch_PowerMode_1:
+ case NvOdmTouch_PowerMode_2:
+ case NvOdmTouch_PowerMode_3:
+ SleepMode = SLEEP_MODE_SENSOR_SLEEP;
+ break;
+ default:
+ return NV_FALSE;
+ }
+
+ if (hTouch->SleepMode == SleepMode)
+ return NV_TRUE;
+ hTouch->SleepMode = SleepMode;
+ return NV_TRUE;
+}
+
+NvBool
+PANJIT_GetCalibrationData(
+ NvOdmTouchDeviceHandle hDevice,
+ NvU32 NumOfCalibrationData,
+ NvS32* pRawCoordBuffer)
+{
+ static NvS32 RawCoordBuffer[] = {2048,2048,840,840,840,3330,3280,3330,3280,840};
+
+ if (!pRawCoordBuffer)
+ return NV_FALSE;
+
+ if (NumOfCalibrationData * 2 != (sizeof(RawCoordBuffer) / sizeof(NvS32)))
+ {
+ NVODMTOUCH_PRINTF(("WARNING: number of calibration data isn't matched\r\n"));
+ return NV_FALSE;
+ }
+
+ NvOdmOsMemcpy(pRawCoordBuffer, RawCoordBuffer, sizeof(RawCoordBuffer));
+ return NV_TRUE;
+}
+
+NvBool PANJIT_PowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff)
+{
+ if (!hDevice)
+ return NV_FALSE;
+
+ if (OnOff)
+ return PANJIT_PowerControl(hDevice, NvOdmTouch_PowerMode_0); // power ON
+ else
+ return PANJIT_PowerControl(hDevice, NvOdmTouch_PowerMode_3); // power OFF
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h
new file mode 100644
index 000000000000..bfff86fe21ce
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_TOUCH_PANJIT_H
+#define INCLUDED_NVODM_TOUCH_PANJIT_H
+
+#include "nvodm_touch_int.h"
+#include "nvodm_services.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct PANJIT_TouchDevice_Rec
+{
+ NvOdmTouchDevice OdmTouch;
+ NvOdmTouchCapabilities Caps;
+ NvOdmServicesI2cHandle hOdmI2c;
+ NvOdmServicesGpioHandle hGpio;
+ NvOdmServicesPmuHandle hPmu;
+ NvOdmGpioPinHandle hPin;
+ NvOdmServicesGpioIntrHandle hGpioIntr;
+ NvOdmOsSemaphoreHandle hIntSema;
+ NvU32 PrevFingers;
+ NvU32 DeviceAddr;
+ NvU32 SampleRate;
+ NvU32 SleepMode;
+ NvBool PowerOn;
+ NvU32 I2cClockSpeedKHz;
+} PANJIT_TouchDevice;
+
+/**
+ * Gets a handle to the touch pad in the system.
+ *
+ * @param hDevice A pointer to the handle of the touch pad.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool PANJIT_Open(NvOdmTouchDeviceHandle *hDevice);
+
+/**
+ * Releases the touch pad handle.
+ *
+ * @param hDevice The touch pad handle to be released. If
+ * NULL, this API has no effect.
+ */
+void PANJIT_Close(NvOdmTouchDeviceHandle hDevice);
+
+/**
+ * Gets capabilities for the specified touch device.
+ *
+ * @param hDevice The handle of the touch pad.
+ * @param pCapabilities A pointer to the targeted
+ * capabilities returned by the ODM.
+ */
+void
+PANJIT_GetCapabilities(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCapabilities* pCapabilities);
+
+/**
+ * Gets coordinate info from the touch device.
+ *
+ * @param hDevice The handle to the touch pad.
+ * @param coord A pointer to the structure holding coordinate info.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool
+PANJIT_ReadCoordinate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCoordinateInfo *pCoord);
+
+/**
+ * Hooks up the interrupt handle to the GPIO interrupt and enables the interrupt.
+ *
+ * @param hDevice The handle to the touch pad.
+ * @param hInterruptSemaphore A handle to hook up the interrupt.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool
+PANJIT_EnableInterrupt(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmOsSemaphoreHandle hInterruptSemaphore);
+
+/**
+ * Prepares the next interrupt to get notified from the touch device.
+ *
+ * @param hDevice A handle to the touch pad.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool PANJIT_HandleInterrupt(NvOdmTouchDeviceHandle hDevice);
+
+/**
+ * Gets the touch ADC sample rate.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param pTouchSampleRate A pointer to the NvOdmTouchSampleRate stucture.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+*/
+NvBool
+PANJIT_GetSampleRate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchSampleRate* pTouchSampleRate);
+
+/**
+ * Sets the touch ADC sample rate.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param SampleRate 1 indicates high frequency, 0 indicates low frequency.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+*/
+NvBool PANJIT_SetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 rate);
+
+/**
+ * Sets the touch panel power mode.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param mode The mode, ranging from full power to power off.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+*/
+NvBool
+PANJIT_PowerControl(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchPowerModeType mode);
+
+/**
+ * Gets the touch panel calibration data.
+ * This is optional as calibration may perform after the OS is up.
+ * This is not required to bring up the touch panel.
+ *
+ * @param hDevice A handle to the touch panel.
+ * @param NumOfCalibrationData Indicates the number of calibration points.
+ * @param pRawCoordBuffer The collection of X/Y coordinate data.
+ *
+ * @return NV_TRUE if preset calibration data is required, or NV_FALSE otherwise.
+ */
+NvBool
+PANJIT_GetCalibrationData(
+ NvOdmTouchDeviceHandle hDevice,
+ NvU32 NumOfCalibrationData,
+ NvS32* pRawCoordBuffer);
+
+/**
+ * Powers the touch device on or off.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param OnOff Specify 1 to power ON, 0 to power OFF.
+*/
+NvBool PANJIT_PowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_NVODM_TOUCH_PANJIT_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c
new file mode 100644
index 000000000000..c57663299cc8
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c
@@ -0,0 +1,861 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_touch_int.h"
+#include "nvodm_services.h"
+#include "nvodm_touch_tpk.h"
+#include "nvodm_query_discovery.h"
+#include "tpk_reg.h"
+
+#define TPK_I2C_SPEED_KHZ 40
+#define TPK_I2C_TIMEOUT 500
+#define TPK_LOW_SAMPLE_RATE 0 //40 reports per-second
+#define TPK_HIGH_SAMPLE_RATE 1 //80 reports per-second
+#define TPK_MAX_READ_BYTES 16
+#define TPK_MAX_PACKET_SIZE 8
+#define TPK_CHECK_ERRORS 0
+#define TPK_BENCHMARK_SAMPLE 0
+#define TPK_REPORT_WAR_SUCCESS 0
+#define TPK_REPORT_2ND_FINGER_DATA 0
+#define TPK_DUMP_REGISTER 0
+#define TPK_SCREEN_ANGLE 0 //0=Landscape, 1=Portrait
+#define TPK_QUERY_SENSOR_RESOLUTION 0 //units per millimeter
+#define TPK_SET_MAX_POSITION 0
+#define TPK_PAGE_CHANGE_DELAY 0 //This should be unnecessary
+#define TPK_POR_DELAY 100 //Dealy after Power-On Reset
+ //500ms(Max) is suggested
+ //by RMI Interface Guide
+ //(511-000099-01 Rev.B)
+
+#define TPK_ADL340_WAR 0
+/* WAR for spurious zero reports from panel: verify zero
+ fingers sample data by waiting one refresh interval and
+ retrying reading data */
+#define TPK_SPURIOUS_ZERO_WAR 1
+
+#define TPK_TOUCH_DEVICE_GUID NV_ODM_GUID('t','p','k','t','o','u','c','h')
+
+#define TPK_WRITE(dev, reg, byte) TPK_WriteRegister(dev, reg, byte)
+#define TPK_READ(dev, reg, buffer, len) TPK_ReadRegisterSafe(dev, reg, buffer, len)
+#define TPK_DEBOUNCE_TIME_MS 0
+
+typedef struct TPK_TouchDeviceRec
+{
+ NvOdmTouchDevice OdmTouch;
+ NvOdmTouchCapabilities Caps;
+ NvOdmServicesI2cHandle hOdmI2c;
+ NvOdmServicesGpioHandle hGpio;
+ NvOdmServicesPmuHandle hPmu;
+ NvOdmGpioPinHandle hPin;
+ NvOdmServicesGpioIntrHandle hGpioIntr;
+ NvOdmOsSemaphoreHandle hIntSema;
+ NvBool PrevFingers;
+ NvU32 DeviceAddr;
+ NvU32 SampleRate;
+ NvU32 SleepMode;
+ NvBool PowerOn;
+ NvU32 VddId;
+ NvU32 ChipRevisionId; //Id=0x01:TPK chip on Concorde1
+ //id=0x02:TPK chip with updated firmware on Concorde2
+ NvU32 I2cClockSpeedKHz;
+} TPK_TouchDevice;
+
+
+static const NvOdmTouchCapabilities TPK_Capabilities =
+{
+ 1, //IsMultiTouchSupported
+ 2, //MaxNumberOfFingerCoordReported;
+ 0, //IsRelativeDataSupported
+ 1, //MaxNumberOfRelativeCoordReported
+ 15, //MaxNumberOfWidthReported
+ 255, //MaxNumberOfPressureReported
+ (NvU32)NvOdmTouchGesture_Not_Supported, //Gesture
+ 1, //IsWidthSupported
+ 1, //IsPressureSupported
+ 1, //IsFingersSupported
+ 0, //XMinPosition
+ 0, //YMinPosition
+ 0, //XMaxPosition
+ 0, //YMaxPosition
+#if TPK_SCREEN_ANGLE
+ (NvU32)NvOdmTouchOrientation_H_FLIP // Orientation 4 inch tpk panel
+#else
+ (NvU32)(NvOdmTouchOrientation_XY_SWAP | NvOdmTouchOrientation_H_FLIP | NvOdmTouchOrientation_V_FLIP)
+#endif
+};
+
+#if TPK_ADL340_WAR
+// Dummy write accelerometer in order to workaround a HW bug of ADL340
+// Will Remove it once we use new accelerometer
+static NvBool NvAccDummyI2CSetRegs(TPK_TouchDevice* hTouch)
+{
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvU8 arr[2];
+ NvOdmI2cStatus Error;
+
+ arr[0] = 0x0;
+ arr[1] = 0x0;
+
+ TransactionInfo.Address = 0x3A;
+ TransactionInfo.Buf = arr;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ // Write dummy data to accelerometer
+
+ do
+ {
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ &TransactionInfo,
+ 1,
+ hTouch->I2cClockSpeedKHz,
+ TPK_I2C_TIMEOUT);
+ } while (Error == NvOdmI2cStatus_Timeout);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ //NvOdmOsDebugPrintf("error!\r\n");
+ return NV_FALSE;
+ }
+ //NvOdmOsDebugPrintf("dummy!\r\n");
+ return NV_TRUE;
+}
+#endif
+
+static NvBool TPK_WriteRegister (TPK_TouchDevice* hTouch, NvU8 reg, NvU8 val)
+{
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvU8 arr[2];
+#if TPK_ADL340_WAR
+ // dummy write
+ Error = NvAccDummyI2CSetRegs(hTouch);
+#endif
+ arr[0] = reg;
+ arr[1] = val;
+
+ TransactionInfo.Address = hTouch->DeviceAddr;
+ TransactionInfo.Buf = arr;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ do
+ {
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ &TransactionInfo,
+ 1,
+ hTouch->I2cClockSpeedKHz,
+ TPK_I2C_TIMEOUT);
+ } while (Error == NvOdmI2cStatus_Timeout);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ NVODMTOUCH_PRINTF(("I2C Write Failure = %d (addr=0x%x, reg=0x%x, val=0x%0x)\n", Error,
+ hTouch->DeviceAddr, reg, val));
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+#define TPK_MAX_READS (((TPK_MAX_READ_BYTES+(TPK_MAX_PACKET_SIZE-1))/TPK_MAX_PACKET_SIZE))
+
+static NvBool TPK_ReadRegisterOnce (TPK_TouchDevice* hTouch, NvU8 reg, NvU8* buffer, NvU32 len)
+{
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo[2 * TPK_MAX_READS];
+ int reads = (len+(TPK_MAX_PACKET_SIZE-1))/TPK_MAX_PACKET_SIZE;
+ int left = len;
+ int i;
+
+ NV_ASSERT(len <= TPK_MAX_READ_BYTES);
+#if TPK_ADL340_WAR
+ // dummy write
+ Error = NvAccDummyI2CSetRegs(hTouch);
+#endif
+ ////////////////////////////////////////////////////////////////////////////
+ // For multi-byte reads, the TPK panel supports just sending the first
+ // address and then keep reading registers (non-standard SMBus operation).
+ // The limit for I2C packets is 8 bytes, so we read up to 8 bytes per
+ // multi-byte read transaction.
+ ////////////////////////////////////////////////////////////////////////////
+
+ for (i = 0; i < reads; i++)
+ {
+ int ind = i*2;
+
+ TransactionInfo[ind].Address = hTouch->DeviceAddr;
+ TransactionInfo[ind].Buf = &reg;
+ TransactionInfo[ind].Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo[ind].NumBytes = 1;
+
+ ind++;
+
+ TransactionInfo[ind].Address = hTouch->DeviceAddr | 0x1;
+ TransactionInfo[ind].Buf = buffer + i*TPK_MAX_PACKET_SIZE;
+ TransactionInfo[ind].Flags = 0;
+ TransactionInfo[ind].NumBytes =
+ left > TPK_MAX_PACKET_SIZE ? TPK_MAX_PACKET_SIZE : left;
+
+ left -= TPK_MAX_PACKET_SIZE;
+ }
+
+ do
+ {
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ TransactionInfo,
+ reads * 2,
+ hTouch->I2cClockSpeedKHz,
+ TPK_I2C_TIMEOUT);
+ } while (Error == NvOdmI2cStatus_Timeout);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ NVODMTOUCH_PRINTF(("I2C Read Failure = %d (addr=0x%x, reg=0x%x)\n", Error,
+ hTouch->DeviceAddr, reg));
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+static NvBool TPK_ReadRegisterSafe (TPK_TouchDevice* hTouch, NvU8 reg, NvU8* buffer, NvU32 len)
+{
+
+ if (!TPK_ReadRegisterOnce(hTouch, reg, buffer, len))
+ return NV_FALSE;
+
+
+ return NV_TRUE;
+}
+
+static NvBool TPK_SetPage (TPK_TouchDevice* hTouch, NvU8 page)
+{
+#if TPK_PAGE_CHANGE_DELAY
+ NvU32 SetPageDelayMs = 100; //Wait for 100 millisecond after change page
+#endif
+
+ if (!TPK_WRITE(hTouch, TPK_PAGE_SELECT, page)) return NV_FALSE;
+
+#if TPK_PAGE_CHANGE_DELAY
+ NvOdmOsSleepMS(SetPageDelayMs);
+#endif
+
+ return NV_TRUE;
+}
+
+#if TPK_CHECK_ERRORS
+static void TPK_CheckError (TPK_TouchDevice* hTouch)
+{
+ NvU8 status;
+ TPK_READ(hTouch, TPK_DEVICE_STATUS, &status, 1);
+ if (status & 0x80)
+ {
+ NvU8 error;
+ TPK_READ(hTouch, TPK_ERROR_STATUE, &error, 1);
+ NvOdmOsDebugPrintf("Panel error %x %x\n", status, error);
+ }
+#if TPK_DUMP_REGISTER
+ TPK_READ(hTouch, TPK_DEVICE_STATUS, &status, 1);
+ NvOdmOsDebugPrintf("DeviceStatus(0x%x)=0x%x\n", TPK_DEVICE_STATUS, status);
+
+ TPK_READ(hTouch, TPK_DEVICE_CONTROL, &status, 1);
+ NvOdmOsDebugPrintf("DeviceControl(0x%x)=0x%x\n", TPK_DEVICE_CONTROL, status);
+
+ TPK_READ(hTouch, TPK_INTR_ENABLE, &status, 1);
+ NvOdmOsDebugPrintf("InterruptEnable(0x%x)=0x%x\n", TPK_INTR_ENABLE, status);
+
+ TPK_READ(hTouch, TPK_ERROR_STATUE, &status, 1);
+ NvOdmOsDebugPrintf("TPK_ERROR_STATUE(0x%x)=0x%x\n", TPK_ERROR_STATUE, status);
+
+ TPK_READ(hTouch, TPK_INTR_STATUS, &status, 1);
+ NvOdmOsDebugPrintf("InterruptStatus(0x%x)=0x%x\n", TPK_INTR_STATUS, status);
+
+ TPK_READ(hTouch, TPK_DEVICE_COMMAND, &status, 1);
+ NvOdmOsDebugPrintf("DeviceCommand(0x%x)=0x%x\n", TPK_DEVICE_COMMAND, status);
+#endif
+}
+#endif
+
+static NvBool TPK_Configure (TPK_TouchDevice* hTouch)
+{
+ hTouch->SleepMode = 0x0;
+ hTouch->SampleRate = 0; /* this forces register write */
+ return TPK_SetSampleRate(&hTouch->OdmTouch, TPK_HIGH_SAMPLE_RATE);
+}
+
+static NvBool TPK_GetSample (TPK_TouchDevice* hTouch, NvOdmTouchCoordinateInfo* coord)
+{
+ NvU8 Finger0[6] = {0};
+ NvU8 Finger1[6] = {0};
+ NvU8 Relative[2] = {0};
+ int status = 0;
+
+ NVODMTOUCH_PRINTF(("TPK_GetSample+\n"));
+ coord->fingerstate = NvOdmTouchSampleIgnore;
+
+ if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0, Finger0, 6))
+ return NV_FALSE;
+ else
+ status = (Finger0[0] & 0x7);
+
+ if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0+6, Finger1, 6))
+ return NV_FALSE;
+
+ if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0+12, Relative, 2))
+ return NV_FALSE;
+
+ /* tell windows to ignore transitional finger count samples */
+ coord->fingerstate = (status > 2) ? NvOdmTouchSampleIgnore : NvOdmTouchSampleValidFlag;
+ coord->additionalInfo.Fingers = status;
+
+ if (Finger0[0] & 0x8)
+ // Bit 3 of status indicates a tap. Driver still doesn't expose
+ // gesture capabilities. This is added more for testing of the support
+ // in the hardware for gesture support.
+ {
+ coord->additionalInfo.Gesture = NvOdmTouchGesture_Tap;
+ // NvOdmOsDebugPrintf("Detected the Tap gesture\n");
+ }
+
+ if (status)
+ {
+ /* always read first finger data, even if transitional */
+ coord->fingerstate |= NvOdmTouchSampleDownFlag;
+
+ coord->xcoord =
+ coord->additionalInfo.multi_XYCoords[0][0] =
+ (((NvU16)Finger0[2] & 0x1f) << 8) | (NvU16)Finger0[3];
+
+ coord->ycoord =
+ coord->additionalInfo.multi_XYCoords[0][1] =
+ (((NvU16)Finger0[4] & 0x1f) << 8) | (NvU16)Finger0[5];
+
+ coord->additionalInfo.width[0] = Finger0[0] >> 4;
+ coord->additionalInfo.Pressure[0] = Finger0[1];
+
+ /* only read second finger data if reported */
+ if (status == 2)
+ {
+ coord->additionalInfo.multi_XYCoords[1][0] =
+ (((NvU16)Finger1[2] & 0x1f) << 8) | (NvU16)Finger1[3];
+
+ coord->additionalInfo.multi_XYCoords[1][1] =
+ (((NvU16)Finger1[4] & 0x1f) << 8) | (NvU16)Finger1[5];
+
+ /* these are not supported, zero out just in case */
+ coord->additionalInfo.width[1] = 0;
+ coord->additionalInfo.Pressure[1] = 0;
+ if ( coord->additionalInfo.multi_XYCoords[1][0] <= 0 ||
+ coord->additionalInfo.multi_XYCoords[1][0] >= hTouch->Caps.XMaxPosition ||
+ coord->additionalInfo.multi_XYCoords[1][1] <= 0 ||
+ coord->additionalInfo.multi_XYCoords[1][1] >= hTouch->Caps.YMaxPosition)
+ coord->fingerstate = NvOdmTouchSampleIgnore;
+#if TPK_REPORT_2ND_FINGER_DATA
+ else
+ NvOdmOsDebugPrintf("catch 2 fingers width=0x%x, X=%d, Y=%d, DeltaX=%d, DeltaY=%d\n",
+ coord->additionalInfo.width[0],
+ coord->additionalInfo.multi_XYCoords[1][0],
+ coord->additionalInfo.multi_XYCoords[1][1],
+ Relative[0], Relative[1]);
+#endif
+ }
+ }
+ else if (!hTouch->PrevFingers)
+ {
+ /* two successive 0 finger samples */
+ coord->fingerstate = NvOdmTouchSampleIgnore;
+ }
+
+ hTouch->PrevFingers = status;
+
+ NVODMTOUCH_PRINTF(("TPK_GetSample-\n"));
+ return NV_TRUE;
+}
+
+static void InitOdmTouch (NvOdmTouchDevice* Dev)
+{
+ Dev->Close = TPK_Close;
+ Dev->GetCapabilities = TPK_GetCapabilities;
+ Dev->ReadCoordinate = TPK_ReadCoordinate;
+ Dev->EnableInterrupt = TPK_EnableInterrupt;
+ Dev->HandleInterrupt = TPK_HandleInterrupt;
+ Dev->GetSampleRate = TPK_GetSampleRate;
+ Dev->SetSampleRate = TPK_SetSampleRate;
+ Dev->PowerControl = TPK_PowerControl;
+ Dev->PowerOnOff = TPK_PowerOnOff;
+ Dev->GetCalibrationData = TPK_GetCalibrationData;
+ Dev->OutputDebugMessage = NV_FALSE;
+}
+
+static void TPK_GpioIsr(void *arg)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)arg;
+
+ /* Signal the touch thread to read the sample. After it is done reading the
+ * sample it should re-enable the interrupt. */
+ NvOdmOsSemaphoreSignal(hTouch->hIntSema);
+}
+
+NvBool TPK_ReadCoordinate (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo* coord)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+
+#if TPK_BENCHMARK_SAMPLE
+ NvU32 time = NvOdmOsGetTimeMS();
+#endif
+ NVODMTOUCH_PRINTF(("GpioIst+\n"));
+
+#if TPK_CHECK_ERRORS
+ TPK_CheckError(hTouch);
+#endif
+
+ for (;;)
+ {
+ if (TPK_GetSample(hTouch, coord))
+ {
+ break;
+ }
+
+ /* If reading the data failed, the panel may be resetting itself.
+ Poll device status register to find when panel is back up
+ and reconfigure */
+ for (;;)
+ {
+ NvU8 status;
+
+ while (!TPK_READ(hTouch, TPK_DEVICE_STATUS, &status, 1))
+ {
+ NvOdmOsSleepMS(10);
+ }
+
+ /* if we have a panel error, force reset and wait for status again */
+ if (status & 0x80)
+ {
+ TPK_WRITE(hTouch, TPK_DEVICE_COMMAND, 0x1);
+ continue;
+ }
+
+ /* reconfigure panel, if failed start again */
+ if (!TPK_Configure(hTouch))
+ continue;
+
+ /* re-enable interrupts for absolute data only */
+ if (!TPK_WRITE(hTouch, TPK_INTR_ENABLE, 0x3))
+ continue;
+
+ break;
+ }
+ }
+
+#if TPK_BENCHMARK_SAMPLE
+ NvOdmOsDebugPrintf("Touch sample time %d\n", NvOdmOsGetTimeMS() - time);
+#endif
+
+ return NV_TRUE;
+}
+
+void TPK_GetCapabilities (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+ *pCapabilities = hTouch->Caps;
+}
+
+NvBool TPK_PowerOnOff (NvOdmTouchDeviceHandle hDevice, NvBool OnOff)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+
+ hTouch->hPmu = NvOdmServicesPmuOpen();
+
+ if (!hTouch->hPmu)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmServicesPmuOpen Error \n"));
+ return NV_FALSE;
+ }
+
+ if (OnOff != hTouch->PowerOn)
+ {
+ NvOdmServicesPmuVddRailCapabilities vddrailcap;
+ NvU32 settletime;
+
+ NvOdmServicesPmuGetCapabilities( hTouch->hPmu, hTouch->VddId, &vddrailcap);
+
+ if(OnOff)
+ NvOdmServicesPmuSetVoltage( hTouch->hPmu, hTouch->VddId, vddrailcap.requestMilliVolts, &settletime);
+ else
+ NvOdmServicesPmuSetVoltage( hTouch->hPmu, hTouch->VddId, NVODM_VOLTAGE_OFF, &settletime);
+
+ if (settletime)
+ NvOdmOsWaitUS(settletime); // wait to settle power
+
+ hTouch->PowerOn = OnOff;
+
+ if(OnOff)
+ NvOdmOsSleepMS(TPK_POR_DELAY);
+ }
+
+ NvOdmServicesPmuClose(hTouch->hPmu);
+
+ return NV_TRUE;
+}
+
+NvBool TPK_Open (NvOdmTouchDeviceHandle* hDevice)
+{
+ TPK_TouchDevice* hTouch;
+ NvU32 i;
+ NvU32 found = 0;
+ NvU32 GpioPort = 0;
+ NvU32 GpioPin = 0;
+ NvU32 I2cInstance = 0;
+ NvU8 Buf[4];
+#if TPK_QUERY_SENSOR_RESOLUTION
+ NvU8 sensorresolution = 0; //units per millimeter
+#endif
+#if TPK_SET_MAX_POSITION
+ NvU32 SET_MAX_POSITION = 8191; //Max Position range from 0x0002 to 0x1fff
+ NvU32 SENSOR_MAX_POSITION = 0;
+#endif
+ NvU8 TPKChipRevID;
+
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+
+ hTouch = NvOdmOsAlloc(sizeof(TPK_TouchDevice));
+ if (!hTouch) return NV_FALSE;
+
+ NvOdmOsMemset(hTouch, 0, sizeof(TPK_TouchDevice));
+
+ /* set function pointers */
+ InitOdmTouch(&hTouch->OdmTouch);
+
+ pConnectivity = NvOdmPeripheralGetGuid(TPK_TOUCH_DEVICE_GUID);
+ if (!pConnectivity)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : pConnectivity is NULL Error \n"));
+ goto fail;
+ }
+
+ if (pConnectivity->Class != NvOdmPeripheralClass_HCI)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : didn't find any periperal in discovery query for touch device Error \n"));
+ goto fail;
+ }
+
+ for (i = 0; i < pConnectivity->NumAddress; i++)
+ {
+ switch (pConnectivity->AddressList[i].Interface)
+ {
+ case NvOdmIoModule_I2c:
+ hTouch->DeviceAddr = (pConnectivity->AddressList[i].Address << 1);
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ found |= 1;
+ break;
+ case NvOdmIoModule_Gpio:
+ GpioPort = pConnectivity->AddressList[i].Instance;
+ GpioPin = pConnectivity->AddressList[i].Address;
+ found |= 2;
+ break;
+ case NvOdmIoModule_Vdd:
+ hTouch->VddId = pConnectivity->AddressList[i].Address;
+ found |= 4;
+ break;
+ default:
+ break;
+ }
+ }
+
+ if ((found & 3) != 3)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : peripheral connectivity problem \n"));
+ goto fail;
+ }
+
+ if ((found & 4) != 0)
+ {
+ if (NV_FALSE == TPK_PowerOnOff(&hTouch->OdmTouch, 1))
+ goto fail;
+ }
+ else
+ {
+ hTouch->VddId = 0xFF;
+ }
+
+ hTouch->hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c, I2cInstance);
+ if (!hTouch->hOdmI2c)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmI2cOpen Error \n"));
+ goto fail;
+ }
+
+ hTouch->hGpio = NvOdmGpioOpen();
+
+ if (!hTouch->hGpio)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmGpioOpen Error \n"));
+ goto fail;
+ }
+
+ hTouch->hPin = NvOdmGpioAcquirePinHandle(hTouch->hGpio, GpioPort, GpioPin);
+ if (!hTouch->hPin)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : Couldn't get GPIO pin \n"));
+ goto fail;
+ }
+
+ NvOdmGpioConfig(hTouch->hGpio,
+ hTouch->hPin,
+ NvOdmGpioPinMode_InputData);
+
+ /* set default capabilities */
+ NvOdmOsMemcpy(&hTouch->Caps, &TPK_Capabilities, sizeof(NvOdmTouchCapabilities));
+
+ /* set default I2C speed */
+ hTouch->I2cClockSpeedKHz = TPK_I2C_SPEED_KHZ;
+
+ /* disable interrupts */
+ if (!TPK_WRITE(hTouch, TPK_INTR_ENABLE, 0))
+ goto fail;
+
+#if TPK_SET_MAX_POSITION
+ if (!TPK_READ(hTouch, TPK_SENSOR_MAXPOSITION_0, Buf, 2)) goto fail;
+ SENSOR_MAX_POSITION = ((NvU32)Buf[0] << 8) | (NvU32)Buf[1];
+ NVODMTOUCH_PRINTF(("Touch Max Postion = %d\n", SENSOR_MAX_POSITION));
+
+ if (!TPK_WRITE(hTouch, TPK_SENSOR_MAXPOSITION_0, (NvU8)((SET_MAX_POSITION & 0x1fff) >> 8))) goto fail;
+ if (!TPK_WRITE(hTouch, TPK_SENSOR_MAXPOSITION_1, (NvU8)(SET_MAX_POSITION & 0xff))) goto fail;
+
+ if (!TPK_READ(hTouch, TPK_SENSOR_MAXPOSITION_0, Buf, 2)) goto fail;
+ SENSOR_MAX_POSITION = ((NvU32)Buf[0] << 8) | (NvU32)Buf[1];
+ NVODMTOUCH_PRINTF(("Touch Max Postion = %d\n", SENSOR_MAX_POSITION));
+#endif
+
+ /* get max positions */
+ /* There is no SMBus Aliased Address to query max position, change page to 0x10 */
+ if (!TPK_SetPage(hTouch, ((TPK_RMI_SENSOR_X_MAX_POSITION_0 >> 8) & 0xFF))) goto fail;
+
+ if (!TPK_READ(hTouch, 0x04, Buf, 4)) goto fail;
+
+ hTouch->Caps.XMaxPosition = ((NvU32)Buf[0] << 8) | (NvU32)Buf[1];
+ hTouch->Caps.YMaxPosition = ((NvU32)Buf[2] << 8) | (NvU32)Buf[3];
+
+#if TPK_QUERY_SENSOR_RESOLUTION
+ /* get sensor resulution */
+ /* There is no SMBus Aliased Address to query sensor resolution, change page to 0x10 */
+ if (!TPK_SetPage(hTouch, ((TPK_RMI_SENSOR_RESOLUTION >> 8) & 0xFF))) goto fail;
+
+ if (!TPK_READ(hTouch, TPK_RMI_SENSOR_RESOLUTION, &sensorresolution, 1)) goto fail;
+ NVODMTOUCH_PRINTF(("Touch Sensor Resolution = %d\n", sensorresolution));
+#endif
+ /* change page back to 0x04 */
+ if (!TPK_SetPage(hTouch, ((TPK_RMI_DATA_0 >> 8) & 0xFF))) goto fail;
+
+ /* get chip revision id */
+ if (!TPK_READ(hTouch, TPK_PRODUCT_INFO_QUERY_1, &TPKChipRevID, 1)) goto fail;
+
+ hTouch->ChipRevisionId = (NvU32)TPKChipRevID;
+ NVODMTOUCH_PRINTF(("Touch controller Revision ID = %d\n", hTouch->ChipRevisionId));
+
+ /* boost I2c spped to 100Khz when it is new tpk chip */
+ if (hTouch->ChipRevisionId == 0x02)
+ hTouch->I2cClockSpeedKHz = 100;
+
+ /* configure panel */
+ if (!TPK_Configure(hTouch)) goto fail;
+
+ *hDevice = &hTouch->OdmTouch;
+ return NV_TRUE;
+
+ fail:
+ TPK_Close(&hTouch->OdmTouch);
+ return NV_FALSE;
+}
+
+NvBool TPK_EnableInterrupt (NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hIntSema)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+ NvOdmTouchCoordinateInfo coord;
+
+ NV_ASSERT(hIntSema);
+
+ /* can only be initialized once */
+ if (hTouch->hGpioIntr || hTouch->hIntSema)
+ return NV_FALSE;
+
+ /* zero intr status */
+ (void)TPK_GetSample(hTouch, &coord);
+
+ hTouch->hIntSema = hIntSema;
+
+ if (NvOdmGpioInterruptRegister(hTouch->hGpio, &hTouch->hGpioIntr,
+ hTouch->hPin, NvOdmGpioPinMode_InputInterruptLow, TPK_GpioIsr,
+ (void*)hTouch, TPK_DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ return NV_FALSE;
+ }
+
+ if (!hTouch->hGpioIntr)
+ return NV_FALSE;
+
+ /* enable interrupts -- only for absolute data */
+ if (!TPK_WRITE(hTouch, TPK_INTR_ENABLE, 0x3))
+ {
+ NvOdmGpioInterruptUnregister(hTouch->hGpio, hTouch->hPin, hTouch->hGpioIntr);
+ hTouch->hGpioIntr = NULL;
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+NvBool TPK_HandleInterrupt(NvOdmTouchDeviceHandle hDevice)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+ NvU32 pinValue;
+
+ NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &pinValue);
+ if (!pinValue)
+ {
+ //interrupt pin is still LOW, read data until interrupt pin is released.
+ return NV_FALSE;
+ }
+ else
+ NvOdmGpioInterruptDone(hTouch->hGpioIntr);
+
+ return NV_TRUE;
+}
+
+NvBool TPK_GetSampleRate (NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+ pTouchSampleRate->NvOdmTouchSampleRateHigh = 80;
+ pTouchSampleRate->NvOdmTouchSampleRateLow = 40;
+ pTouchSampleRate->NvOdmTouchCurrentSampleRate = (hTouch->SampleRate >> 1);
+ return NV_TRUE;
+}
+
+NvBool TPK_SetSampleRate (NvOdmTouchDeviceHandle hDevice, NvU32 rate)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+
+ if (rate != 0 && rate != 1)
+ return NV_FALSE;
+
+ rate = 1 << rate;
+
+ if (hTouch->SampleRate == rate)
+ return NV_TRUE;
+
+ if (!TPK_WRITE(hTouch, TPK_DEVICE_CONTROL, (NvU8)((rate << 6) | hTouch->SleepMode)))
+ return NV_FALSE;
+
+ hTouch->SampleRate = rate;
+ return NV_TRUE;
+}
+
+
+NvBool TPK_PowerControl (NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+ NvU32 SleepMode;
+
+ NV_ASSERT(hTouch->VddId != 0xFF);
+
+ switch(mode)
+ {
+ case NvOdmTouch_PowerMode_0:
+ SleepMode = 0x0;
+ break;
+ case NvOdmTouch_PowerMode_1:
+ case NvOdmTouch_PowerMode_2:
+ case NvOdmTouch_PowerMode_3:
+ SleepMode = 0x03;
+ break;
+ default:
+ return NV_FALSE;
+ }
+
+ if (hTouch->SleepMode == SleepMode)
+ return NV_TRUE;
+
+ if (!TPK_WRITE(hTouch, TPK_DEVICE_CONTROL, (NvU8)((hTouch->SampleRate << 6) | SleepMode)))
+ return NV_FALSE;
+
+ hTouch->SleepMode = SleepMode;
+ return NV_TRUE;
+}
+
+NvBool TPK_GetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer)
+{
+#if TPK_SCREEN_ANGLE
+ //Portrait
+ static const NvS32 RawCoordBuffer[] = {2054, 3624, 3937, 809, 3832, 6546, 453, 6528, 231, 890};
+#else
+ //Landscape
+ static NvS32 RawCoordBuffer[] = {2054, 3624, 3832, 6546, 453, 6528, 231, 890, 3937, 809};
+#endif
+
+ if (NumOfCalibrationData*2 != (sizeof(RawCoordBuffer)/sizeof(NvS32)))
+ {
+ NVODMTOUCH_PRINTF(("WARNING: number of calibration data isn't matched\n"));
+ return NV_FALSE;
+ }
+
+ NvOdmOsMemcpy(pRawCoordBuffer, RawCoordBuffer, sizeof(RawCoordBuffer));
+
+ return NV_TRUE;
+}
+
+
+void TPK_Close (NvOdmTouchDeviceHandle hDevice)
+{
+ TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice;
+
+ if (!hTouch) return;
+
+ if (hTouch->hGpio)
+ {
+ if (hTouch->hPin)
+ {
+ if (hTouch->hGpioIntr)
+ NvOdmGpioInterruptUnregister(hTouch->hGpio, hTouch->hPin, hTouch->hGpioIntr);
+
+ NvOdmGpioReleasePinHandle(hTouch->hGpio, hTouch->hPin);
+ }
+
+ NvOdmGpioClose(hTouch->hGpio);
+ }
+
+ if (hTouch->hOdmI2c)
+ NvOdmI2cClose(hTouch->hOdmI2c);
+
+ NvOdmOsFree(hTouch);
+}
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h
new file mode 100644
index 000000000000..6cab3eb66ed1
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef INCLUDED_NVODM_TOUCH_TPK_H
+#define INCLUDED_NVODM_TOUCH_TPK_H
+
+#include "nvodm_touch_int.h"
+#include "nvodm_services.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+NvBool TPK_Open( NvOdmTouchDeviceHandle *hDevice);
+
+void TPK_GetCapabilities(NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities);
+
+NvBool TPK_ReadCoordinate( NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo *coord);
+
+NvBool TPK_EnableInterrupt(NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hInterruptSemaphore);
+
+NvBool TPK_HandleInterrupt(NvOdmTouchDeviceHandle hDevice);
+
+NvBool TPK_GetSampleRate(NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate);
+
+NvBool TPK_SetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 rate);
+
+NvBool TPK_PowerControl(NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode);
+
+NvBool TPK_GetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer);
+
+NvBool TPK_PowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff);
+
+void TPK_Close( NvOdmTouchDeviceHandle hDevice);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif // INCLUDED_NVODM_TOUCH_TPK_H
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h b/arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h
new file mode 100644
index 000000000000..141a522bb944
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TPK_REG_HEADER
+#define TPK_REG_HEADER
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+
+// SMBus Aliased Address
+/* To make most efficient use of the SMBus paged addressing scheme, Synaptics
+ * RMI-on-SMBus devices define that for all commonly used RMI device registers,
+ * there will be a duplicate aliased register located at a new RMI address.
+ * The entire set of aliased register addresses are grouped into a single page
+ * of the RMI address space. This will enable user software to access all commonly
+ * used RMI registers without ever having to rewrite the Page Select register.
+ *
+ * The aliased addresses occupy page $04xx in the general RMI address map. At reset,
+ * all RMI-on-SMBus devices initialize their Page Select register to the value $04.
+ * This means that by default, all SMBus register accesses will access the RMI
+ * Aliased Address space.
+ *
+ * ----------------------------------------------------------------------------
+ * | Aliased Address | General RMI Address | Register Group |
+ * ----------------------------------------------------------------------------
+ * | $0400-$041F | $0400-$041F | RMI Data Register and |
+ * | | | Device Status Reg |
+ * ----------------------------------------------------------------------------
+ * | $04E0-$04E7 | $0200-$0207 | RMI Product ID queries |
+ * ----------------------------------------------------------------------------
+ * | $04F0-$04F4 | $0000-$0004 | RMI control, command, and |
+ * | | | general status registers |
+ * ----------------------------------------------------------------------------
+ * | $04FF | $xxFF | Page Select Register |
+ * ----------------------------------------------------------------------------
+
+*/
+#define TPK_DATA_0 0x00 //Data Reg 0 - Finger #0
+#define TPK_DATA_1 0x01 //Data Reg 1 - Finger #0
+#define TPK_DATA_2 0x02 //Data Reg 2 - Finger #0
+#define TPK_DATA_3 0x03 //Data Reg 3 - Finger #0
+#define TPK_DATA_4 0x04 //Data Reg 4 - Finger #0
+#define TPK_DATA_5 0x05 //Data Reg 5 - Finger #0
+#define TPK_DATA_6 0x06 //Data Reg 6 - Finger #1
+#define TPK_DATA_7 0x07 //Data Reg 7 - Finger #1
+#define TPK_DATA_8 0x08 //Data Reg 8 - Finger #1
+#define TPK_DATA_9 0x09 //Data Reg 9 - Finger #1
+#define TPK_DATA_A 0x0A //Data Reg 10 - Finger #1
+#define TPK_DATA_B 0x0B //Data Reg 11 - Finger #1
+#define TPK_RELATIVE_DATA_X 0x0C //Relative Horizontal Motion - Finger #0
+#define TPK_RELATIVE_DATA_Y 0x0D //Relative Vertical Motion - Finger #0
+#define TPK_DEVICE_STATUS 0x0E //Device Status Register
+#define TPK_2D_CONTROL 0x21 //Func10: General 2D Control Reg
+#define TPK_2D_RELATIVE_SPEED 0x22 //Func10: General 2D Relative Speed Reg
+#define TPK_2D_ACCLELERATION 0x23 //Func10: General 2D Relative Acceleration Reg
+#define TPK_SENSOR_SENSITIVITY 0x24 //Func10: Sensor Sensitivity
+#define TPK_SENSOR_MAXPOSITION_0 0x26 //Func10: Sensor Max Position (bit 12:8)
+#define TPK_SENSOR_MAXPOSITION_1 0x27 //Func10: Sensor Max Position (bit 7:0)
+#define TPK_RMI_PROTOCOL_VERSION 0xE0 //RMI Protocol Version
+#define TPK_MANUFACTURER_ID 0xE1 //Manufacturer ID
+#define TPK_PHYSICAL_INTERFACE_VERSION 0xE2 //Physical Interface Version
+#define TPK_PRODUCT_QUERY 0xE3 //Product Property
+#define TPK_PRODUCT_INFO_QUERY_0 0xE4 //Product Info 0
+#define TPK_PRODUCT_INFO_QUERY_1 0xE5 //Product Info 1 (REVISION_ID)
+#define TPK_PRODUCT_INFO_QUERY_2 0xE6 //Product Info 2
+#define TPK_PRODUCT_INFO_QUERY_3 0xE7 //Product Info 3
+#define TPK_DEVICE_CONTROL 0xF0 //Device Control Register
+#define TPK_INTR_ENABLE 0xF1 //Interrupt Enable Register
+#define TPK_ERROR_STATUE 0xF2 //Error Status Register
+#define TPK_INTR_STATUS 0xF3 //Interrupt Request Status Register
+#define TPK_DEVICE_COMMAND 0xF4 //Device Command Register
+#define TPK_PAGE_SELECT 0xFF //Page Select Register
+
+// RMI Address Space
+// Data registers
+#define TPK_RMI_DATA_0 0x0400 //Data Reg 0 - Finger #0
+#define TPK_RMI_DATA_1 0x0401 //Data Reg 1 - Finger #0
+#define TPK_RMI_DATA_2 0x0402 //Data Reg 2 - Finger #0
+#define TPK_RMI_DATA_3 0x0403 //Data Reg 3 - Finger #0
+#define TPK_RMI_DATA_4 0x0404 //Data Reg 4 - Finger #0
+#define TPK_RMI_DATA_5 0x0405 //Data Reg 5 - Finger #0
+#define TPK_RMI_DATA_6 0x0406 //Data Reg 6 - Finger #1
+#define TPK_RMI_DATA_7 0x0407 //Data Reg 7 - Finger #1
+#define TPK_RMI_DATA_8 0x0408 //Data Reg 8 - Finger #1
+#define TPK_RMI_DATA_9 0x0409 //Data Reg 9 - Finger #1
+#define TPK_RMI_DATA_A 0x040A //Data Reg 10 - Finger #1
+#define TPK_RMI_DATA_B 0x040B //Data Reg 11 - Finger #1
+#define TPK_RMI_RELATIVE_DATA_X 0x040C //Relative Horizontal Motion - Finger #0
+#define TPK_RMI_RELATIVE_DATA_Y 0x040D //Relative Vertical Motion - Finger #0
+#define TPK_RMI_DEVICE_STATUS 0x040E //Device Status Register
+
+// Function $10 register pages
+#define TPK_RMI_FUNCTION_VERSION 0x1000 //Func10: Function Version query
+#define TPK_RMI_2D_PROPERTIES 0x1001 //Func10: General 2D Properties query
+#define TPK_RMI_SENSOR_PROPERTIES_0 0x1002 //Func10: Sensor Properties
+#define TPK_RMI_SENSOR_PROPERTIES_1 0x1003 //Func10: Sensor Properties
+#define TPK_RMI_SENSOR_X_MAX_POSITION_0 0x1004 //Func10: Sensor X Max Position (bits 12:8)
+#define TPK_RMI_SENSOR_X_MAX_POSITION_1 0x1005 //Func10: Sensor X Max Position (bits 7:0)
+#define TPK_RMI_SENSOR_Y_MAX_POSITION_0 0x1006 //Func10: Sensor Y Max Position (bits 12:8)
+#define TPK_RMI_SENSOR_Y_MAX_POSITION_1 0x1007 //Func10: Sensor Y Max Position (bits 7:0)
+#define TPK_RMI_SENSOR_RESOLUTION 0x1008 //Func10: Sensor Resolution
+#define TPK_RMI_2D_CONTROL 0x1041 //Func10: General 2D Control Reg
+#define TPK_RMI_2D_RELATIVE_SPEED 0x1042 //Func10: General 2D Relative Speed Reg
+#define TPK_RMI_2D_ACCLELERATION 0x1043 //Func10: General 2D Relative Acceleration Reg
+#define TPK_RMI_SENSOR_SENSITIVITY 0x1044 //Func10: Sensor Sensitivity
+#define TPK_RMI_SENSOR_MAXPOSITION_0 0x1046 //Func10: Sensor Max Position (bit 12:8)
+#define TPK_RMI_SENSOR_MAXPOSITION_1 0x1047 //Func10: Sensor Max Position (bit 7:0)
+
+// General product information and version queries
+#define TPK_RMI_RMI_PROTOCOL_VERSION 0x2000 //RMI Protocol Version
+#define TPK_RMI_MANUFACTURER_ID 0x2001 //Manufacturer ID
+#define TPK_RMI_PHYSICAL_INTERFACE_VERSION 0x2002 //Physical Interface Version
+#define TPK_RMI_PRODUCT_QUERY 0x2003 //Product Property
+#define TPK_RMI_PRODUCT_INFO_QUERY_0 0x2004 //Product Info 0
+#define TPK_RMI_PRODUCT_INFO_QUERY_1 0x2005 //Product Info 1 (REVISION_ID)
+#define TPK_RMI_PRODUCT_INFO_QUERY_2 0x2006 //Product Info 2
+#define TPK_RMI_PRODUCT_INFO_QUERY_3 0x2007 //Product Info 3
+
+// Standard RMI control, command, and status registers
+#define TPK_RMI_DEVICE_CONTROL 0x0000 //Device Control Register
+#define TPK_RMI_INTR_ENABLE 0x0001 //Interrupt Enable Register
+#define TPK_RMI_ERROR_STATUE 0x0002 //Error Status Register
+#define TPK_RMI_INTR_STATUS 0x0003 //Interrupt Request Status Register
+#define TPK_RMI_DEVICE_COMMAND 0x0004 //Device Command Register
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif //TPK_REG_HEADER
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile b/arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile
new file mode 100644
index 000000000000..d8807f63e73a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile
@@ -0,0 +1,10 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+obj-y += nvodm_vibrate.o
diff --git a/arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c b/arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c
new file mode 100644
index 000000000000..43cc3cbf5ee4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2006-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Vibrate Interface</b>
+ *
+ * @b Description: Defines the ODM interface for Vibrate devices.
+ *
+ */
+
+#include "nvodm_vibrate.h"
+#include "nvos.h"
+#include "nvassert.h"
+#include "nvodm_services.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_pmu.h"
+
+#define VIBRATE_DEVICE_GUID NV_ODM_GUID('v','i','b','r','a','t','o','r')
+
+/**
+ * @brief Used to enable/disable debug print messages.
+ */
+#define NV_ODM_DEBUG 0
+
+#if NV_ODM_DEBUG
+ #define NV_ODM_TRACE NvOdmOsDebugPrintf
+#else
+ #define NV_ODM_TRACE (void)
+#endif
+
+typedef struct NvOdmVibDeviceRec
+{
+ /* The handle to the Pmu device */
+ NvOdmServicesPmuHandle hOdmServicePmuDevice;
+
+ /*Pmu Vdd Rail capabilities*/
+ NvOdmServicesPmuVddRailCapabilities RailCaps;
+
+ /* Pmu Rail ID*/
+ NvU32 VddId;
+
+} NvOdmVibDevice;
+
+
+/**
+ * @brief Allocates a handle to the device. Configures the PWM
+ * control to the Vibro motor with default values. To change
+ * the amplitude and frequency use NvOdmVibrateSetParameter API.
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @return NV_TRUE on success and NV_FALSE on error
+ */
+NvBool
+NvOdmVibOpen(NvOdmVibDeviceHandle *hOdmVibrate)
+{
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+ NvU32 Index = 0;
+
+ NV_ASSERT(hOdmVibrate);
+
+ /* Allocate the handle */
+ (*hOdmVibrate) = (NvOdmVibDeviceHandle)NvOdmOsAlloc(sizeof(NvOdmVibDevice));
+ if (*hOdmVibrate == NULL)
+ {
+ NV_ODM_TRACE(("Error Allocating NvOdmPmuDevice. \n"));
+ return NV_FALSE;
+ }
+ NvOsMemset((*hOdmVibrate), 0, sizeof(NvOdmVibDevice));
+
+ /* Get the PMU handle */
+ (*hOdmVibrate)->hOdmServicePmuDevice = NvOdmServicesPmuOpen();
+ if (!(*hOdmVibrate)->hOdmServicePmuDevice)
+ {
+ NV_ODM_TRACE(("Error Opening Pmu device. \n"));
+ NvOdmOsFree(*hOdmVibrate);
+ *hOdmVibrate = NULL;
+ return NV_FALSE;
+ }
+
+ // Get the peripheral connectivity information
+ pConnectivity = NvOdmPeripheralGetGuid(VIBRATE_DEVICE_GUID);
+ if (pConnectivity == NULL)
+ return NV_FALSE;
+
+ // Search for the Vdd rail and set the proper volage to the rail.
+ for (Index = 0; Index < pConnectivity->NumAddress; ++Index)
+ {
+ if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd)
+ {
+ (*hOdmVibrate)->VddId = pConnectivity->AddressList[Index].Address;
+ NvOdmServicesPmuGetCapabilities((*hOdmVibrate)->hOdmServicePmuDevice, (*hOdmVibrate)->VddId, &((*hOdmVibrate)->RailCaps));
+ break;
+ }
+ }
+
+ return NV_TRUE;
+}
+
+/**
+ * @brief Closes the ODM device and destroys all allocated resources.
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @return None.
+ */
+void NvOdmVibClose(NvOdmVibDeviceHandle hOdmVibrate)
+{
+ if (hOdmVibrate != NULL)
+ {
+ NvOdmServicesPmuClose(hOdmVibrate->hOdmServicePmuDevice);
+ hOdmVibrate->hOdmServicePmuDevice = NULL;
+
+ hOdmVibrate->VddId = 0;
+
+ NvOsMemset(&hOdmVibrate->RailCaps, 0, sizeof(NvOdmServicesPmuVddRailCapabilities));
+
+ NvOdmOsFree(hOdmVibrate);
+ hOdmVibrate = NULL;
+ }
+}
+
+
+/**
+ * @brief Gets capabilities of the Vibrate device.
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @param RequestedCaps [IN] Specifies the capability to get.
+ * @param pCapsValue [OUT] A pointer to the returned value.
+ * @return NV_TRUE on success and NV_FALSE on error
+ */
+NvBool
+NvOdmVibGetCaps(
+ NvOdmVibDeviceHandle hOdmVibrate,
+ NvOdmVibCaps RequestedCaps,
+ NvU32 *pCapsValue)
+{
+ NV_ASSERT(hOdmVibrate);
+ NV_ASSERT(pCapsValue);
+
+ if (!hOdmVibrate || !pCapsValue)
+ {
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+/**
+ * @brief The frequency to the Vibro motor can be set
+ * using this function. A frequency less than zero will be
+ * clamped to zero and a frequency value beyond the max supported value
+ * will be clamped to the max supported value.
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @param Freq [IN] Frequency in Hz
+ * @return NV_TRUE on success and NV_FALSE on error
+ */
+NvBool
+NvOdmVibSetFrequency(NvOdmVibDeviceHandle hOdmVibrate, NvS32 Freq)
+{
+ //AP20 Vibrator does'nt support setting Frequency
+ return NV_TRUE;
+}
+
+/**
+ * @brief The dutycycle of the PWM driving the Vibro motor can be set
+ * using this function. A dutycycle less than zero will be
+ * clamped to zero and value beyond the max supported value
+ * will be clamped to the max supported value.
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @param DCycle [IN] Duty Cycle value in percentage (0%-100%)
+ * @return NV_TRUE on success and NV_FALSE on error
+ */
+NvBool
+NvOdmVibSetDutyCycle(NvOdmVibDeviceHandle hOdmVibrate, NvS32 DCycle)
+{
+ //AP20 Vibrator does'nt support setting DutyCycle
+ return NV_TRUE;
+}
+
+/**
+ * @brief Starts the Vibro with the frequency and duty-cycle set using the
+ * Set API.
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @return NV_TRUE on success and NV_FALSE on error
+ */
+NvBool
+NvOdmVibStart(NvOdmVibDeviceHandle hOdmVibrate)
+{
+ NvU32 SettlingTime = 0;
+
+ NV_ASSERT(hOdmVibrate);
+
+ if (!hOdmVibrate)
+ {
+ return NV_FALSE;
+ }
+
+ if (hOdmVibrate->hOdmServicePmuDevice != NULL)
+ {
+ // Search for the Vdd rail and power Off the module
+ if (hOdmVibrate->VddId)
+ {
+ NvOdmServicesPmuSetVoltage(hOdmVibrate->hOdmServicePmuDevice,
+ hOdmVibrate->VddId, hOdmVibrate->RailCaps.requestMilliVolts, &SettlingTime);
+
+ if (SettlingTime)
+ NvOdmOsWaitUS(SettlingTime);
+ }
+ }
+
+ return NV_TRUE;
+}
+
+/**
+ * @brief Stops the Vibro motor
+ * @param hOdmVibrate [IN] Opaque handle to the device.
+ * @return NV_TRUE on success and NV_FALSE on error
+ */
+NvBool
+NvOdmVibStop(NvOdmVibDeviceHandle hOdmVibrate)
+{
+ NvU32 SettlingTime;
+
+ NV_ASSERT(hOdmVibrate);
+
+ if (!hOdmVibrate)
+ {
+ return NV_FALSE;
+ }
+
+ if (hOdmVibrate->hOdmServicePmuDevice != NULL)
+ {
+ // Search for the Vdd rail and power Off the module
+ if (hOdmVibrate->VddId)
+ {
+ NvOdmServicesPmuSetVoltage(hOdmVibrate->hOdmServicePmuDevice,
+ hOdmVibrate->VddId, NVODM_VOLTAGE_OFF, &SettlingTime);
+
+ if (SettlingTime)
+ NvOdmOsWaitUS(SettlingTime);
+ }
+ }
+
+ return NV_TRUE;
+}
diff --git a/arch/arm/mach-tegra/odm_kit/query/Makefile b/arch/arm/mach-tegra/odm_kit/query/Makefile
new file mode 100644
index 000000000000..ef54c3faed47
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_TEGRA_ODM_HARMONY) += harmony/
+obj-$(CONFIG_TEGRA_ODM_WHISTLER) += whistler/
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/Makefile b/arch/arm/mach-tegra/odm_kit/query/harmony/Makefile
new file mode 100644
index 000000000000..bdc7cbfee77f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/Makefile
@@ -0,0 +1,19 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations
+
+obj-y += nvodm_query.o
+obj-y += nvodm_query_discovery.o
+obj-y += nvodm_query_nand.o
+obj-y += nvodm_query_gpio.o
+obj-y += nvodm_query_pinmux.o
+obj-y += nvodm_query_kbc.o
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
new file mode 100644
index 000000000000..62243eded55d
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit:
+ * Implementation of the ODM Query API</b>
+ *
+ * @b Description: Implements the query functions for ODMs that may be
+ * accessed at boot-time, runtime, or anywhere in between.
+ */
+
+#include "nvodm_query.h"
+#include "nvodm_query_gpio.h"
+#include "nvodm_query_memc.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_query_pins.h"
+#include "nvodm_query_pins_ap20.h"
+#include "tegra_devkit_custopt.h"
+#include "nvodm_keylist_reserved.h"
+#include "nvrm_drf.h"
+
+#if !defined(NV_OAL)
+#define NV_OAL (0)
+#endif
+
+#define BOARD_ID_HARMONY 0x0B3E
+#define HARMONY_HYS5C1GB_SKU 0x3829
+
+#define NVODM_ENABLE_EMC_DVFS (1)
+
+// Although AP16 Concorde2 and AP16 Vail boards can support PMU
+// interrupt, keep it disabled for now because of PMU VBUS input
+// latch problem
+#define NVODM_PMU_INT_ENABLED (0)
+
+static const NvU8
+s_NvOdmQueryDeviceNamePrefixValue[] = {'T','e','g','r','a',0};
+
+static const NvU8
+s_NvOdmQueryManufacturerSetting[] = {'N','V','I','D','I','A',0};
+
+static const NvU8
+s_NvOdmQueryModelSetting[] = {'A','P','2','0',0};
+
+static const NvU8
+s_NvOdmQueryPlatformSetting[] = {'H','a','r','m','o','n','y',0};
+
+static const NvU8
+s_NvOdmQueryProjectNameSetting[] = {'O','D','M',' ','K','i','t',0};
+
+static const NvOdmDownloadTransport
+s_NvOdmQueryDownloadTransportSetting = NvOdmDownloadTransport_None;
+
+static const NvOdmQuerySdioInterfaceProperty s_NvOdmQuerySdioInterfaceProperty[4] =
+{
+ { NV_FALSE, 10, NV_TRUE, 0x8, NvOdmQuerySdioSlotUsage_wlan },
+ { NV_TRUE, 0, NV_FALSE, 0x5, NvOdmQuerySdioSlotUsage_Media },
+ { NV_TRUE, 0, NV_FALSE, 0x6, NvOdmQuerySdioSlotUsage_unused },
+ { NV_TRUE, 0, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Media }
+};
+
+static const NvOdmQuerySpiDeviceInfo s_NvOdmQuerySpiDeviceInfoTable [] =
+{
+ {NvOdmQuerySpiSignalMode_0, NV_TRUE} // Spi1_Devices_0 (chip sel 0)
+};
+
+// Spi idle signal state
+static const NvOdmQuerySpiIdleSignalState s_NvOdmQuerySpiIdleSignalStateLevel[] =
+{
+ {NV_FALSE, NvOdmQuerySpiSignalMode_0, NV_FALSE} // Spi 1
+};
+// We can have two I2s Instances
+static const NvOdmQueryI2sInterfaceProperty s_NvOdmQueryI2sInterfacePropertySetting[] =
+{
+ {
+ NvOdmQueryI2sMode_Master, // Mode
+ NvOdmQueryI2sLRLineControl_LeftOnLow, // I2sLRLineControl
+ NvOdmQueryI2sDataCommFormat_I2S, // I2sDataCommunicationFormat
+ NV_FALSE, // IsFixedMCLK
+ 0 // FixedMCLKFrequency
+ },
+ {
+ NvOdmQueryI2sMode_Master, // Mode
+ NvOdmQueryI2sLRLineControl_LeftOnLow, // I2sLRLineControl
+ NvOdmQueryI2sDataCommFormat_I2S, // I2sDataCommunicationFormat
+ NV_FALSE, // IsFixedMCLK
+ 0 // FixedMCLKFrequency
+ }
+};
+
+
+static const NvOdmQuerySpdifInterfaceProperty s_NvOdmQuerySpdifInterfacePropertySetting =
+{
+ NvOdmQuerySpdifDataCaptureControl_FromLeft
+};
+
+static const NvOdmQueryAc97InterfaceProperty s_NvOdmQueryAc97InterfacePropertySetting =
+{
+ NV_FALSE,
+ NV_FALSE,
+ NV_FALSE,
+ NV_FALSE,
+ NV_TRUE
+};
+
+// Add support for the Codec Formats
+// It must the order (dapIndex) how the codec is connected to the Dap port
+static const NvOdmQueryI2sACodecInterfaceProp s_NvOdmQueryI2sACodecInterfacePropSetting[] =
+{
+ {
+ NV_FALSE, // IsCodecMaster
+ 0, // DapPortIndex
+ 0x36, // DevAddress
+ NV_FALSE, // IsUsbmode
+ NvOdmQueryI2sLRLineControl_LeftOnLow, // I2sCodecLRLineControl
+ NvOdmQueryI2sDataCommFormat_I2S // I2sCodecDataCommFormat
+ }
+};
+
+static const NvOdmQueryDapPortConnection s_NvOdmQueryDapPortConnectionTable[] =
+{
+ // the Default Music Path
+ { NvOdmDapConnectionIndex_Music_Path, 2,
+ { {NvOdmDapPort_I2s1, NvOdmDapPort_Dap1, NV_TRUE},
+ {NvOdmDapPort_Dap1, NvOdmDapPort_I2s1, NV_FALSE}
+ }},
+
+ // Bluetooth to Codec
+ { NvOdmDapConnectionIndex_BlueTooth_Codec, 3,
+ { {NvOdmDapPort_Dap4, NvOdmDapPort_I2s1, NV_TRUE},
+ {NvOdmDapPort_I2s1, NvOdmDapPort_Dap4, NV_FALSE},
+ {NvOdmDapPort_I2s2, NvOdmDapPort_Dap1, NV_FALSE}
+ }}
+};
+
+
+// Ap20 support 5 dap ports
+// For port is connected to DAC(I2s) then PortMode is not valid- as Dac would be driving it
+static const NvOdmQueryDapPortProperty s_NvOdmQueryDapPortInfoTable[] =
+{
+ {NvOdmDapPort_None, NvOdmDapPort_None , {0, 0, 0, 0} }, // Reserved
+ // I2S1 (DAC1) <-> DAP1 <-> HIFICODEC
+ {NvOdmDapPort_I2s1, NvOdmDapPort_HifiCodecType,
+ {2, 16, 44100, NvOdmQueryI2sDataCommFormat_I2S}}, // Dap1
+ {NvOdmDapPort_None, NvOdmDapPort_None , {0, 0, 0, 0} }, // Dap2
+ {NvOdmDapPort_None, NvOdmDapPort_None , {0, 0, 0, 0} }, // Dap3
+ // I2S2 (DAC2) <-> DAP4 <-> BLUETOOTH
+ {NvOdmDapPort_I2s2, NvOdmDapPort_BlueTooth,
+ {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S}} // Dap4
+};
+
+static const NvOdmSdramControllerConfigAdv s_NvOdmHyS5c1GbEmcConfigTable[] =
+{
+ {
+ 0x20, /* Rev 2.0 */
+ 166500, /* SDRAM frquency */
+ 950, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x0000000A, /* RC */
+ 0x00000016, /* RFC */
+ 0x00000008, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000C, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000D, /* RDV */
+ 0x000004DF, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000A, /* RW2PDEN */
+ 0x000000C8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000006, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xE03B0323, /* CFG_DIG_DLL */
+ 0x007FC010, /* DLL_XFORM_DQS */
+ 0x00008010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000000, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 333000, /* SDRAM frquency */
+ 1200, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000014, /* RC */
+ 0x0000002B, /* RFC */
+ 0x0000000F, /* RAS */
+ 0x00000005, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000C, /* W2P */
+ 0x00000005, /* RD_RCD */
+ 0x00000005, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000004, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000D, /* RDV */
+ 0x000009FF, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000005, /* PCHG2PDEN */
+ 0x00000005, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000F, /* RW2PDEN */
+ 0x000000C8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000C, /* TFAW */
+ 0x00000006, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0xF0320303, /* CFG_DIG_DLL */
+ 0x007FC010, /* DLL_XFORM_DQS */
+ 0x00008010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000000, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ }
+};
+
+// Wake Events
+static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] =
+{
+ {NV_FALSE, 0, NvOdmWakeupPadPolarity_Low}, // Wake Event 0 - ulpi_data4 (UART_RI)
+ {NV_FALSE, 1, NvOdmWakeupPadPolarity_High}, // Wake Event 1 - gp3_pv[3] (BB_MOD, MODEM_RESET_OUT)
+ {NV_FALSE, 2, NvOdmWakeupPadPolarity_High}, // Wake Event 2 - dvi_d3
+ {NV_FALSE, 3, NvOdmWakeupPadPolarity_Low}, // Wake Event 3 - sdio3_dat1
+ {NV_FALSE, 4, NvOdmWakeupPadPolarity_High}, // Wake Event 4 - hdmi_int (HDMI_HPD)
+ {NV_TRUE, 5, NvOdmWakeupPadPolarity_Low}, // Wake Event 5 - vgp[6] (VI_GP6, Flash_EN2)
+ {NV_FALSE, 6, NvOdmWakeupPadPolarity_High}, // Wake Event 6 - gp3_pu[5] (GPS_ON_OFF, GPS_IRQ)
+ {NV_FALSE, 7, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 7 - gp3_pu[6] (GPS_INT, BT_IRQ)
+ {NV_FALSE, 8, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 8 - gmi_wp_n (MICRO SD_CD)
+ {NV_FALSE, 9, NvOdmWakeupPadPolarity_High}, // Wake Event 9 - gp3_ps[2] (KB_COL10)
+ {NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP)
+ {NV_TRUE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ, LOW_BAT#)
+ {NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used)
+ {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1
+ {NV_FALSE, 14, NvOdmWakeupPadPolarity_High}, // Wake Event 14 - gp3_pv[6] (WLAN_INT)
+ {NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1)
+ {NV_TRUE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq
+#ifdef CONFIG_KEYBOARD_TEGRA
+ {NV_TRUE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt
+#else
+ {NV_FALSE, 17, NvOdmWakeupPadPolarity_High},
+#endif
+ {NV_FALSE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT)
+ {NV_FALSE, 19, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 19 - usb_vbus_wakeup[0]
+ {NV_FALSE, 20, NvOdmWakeupPadPolarity_High}, // Wake Event 20 - usb_vbus_wakeup[1]
+ {NV_FALSE, 21, NvOdmWakeupPadPolarity_Low}, // Wake Event 21 - usb_iddig[0]
+ {NV_FALSE, 22, NvOdmWakeupPadPolarity_Low}, // Wake Event 22 - usb_iddig[1]
+ {NV_TRUE, 23, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 23 - gmi_iordy (HSMMC_CLK)
+ {NV_FALSE, 24, NvOdmWakeupPadPolarity_High}, // Wake Event 24 - gp3_pv[2] (BB_MOD, MODEM WAKEUP_AP15, SPI-SS)
+ {NV_FALSE, 25, NvOdmWakeupPadPolarity_High}, // Wake Event 25 - gp3_ps[4] (KB_COL12)
+ {NV_FALSE, 26, NvOdmWakeupPadPolarity_High}, // Wake Event 26 - gp3_ps[5] (KB_COL10)
+ {NV_FALSE, 27, NvOdmWakeupPadPolarity_High}, // Wake Event 27 - gp3_ps[0] (KB_COL8)
+ {NV_FALSE, 28, NvOdmWakeupPadPolarity_Low}, // Wake Event 28 - gp3_pq[6] (KB_ROW6)
+ {NV_FALSE, 29, NvOdmWakeupPadPolarity_Low}, // Wake Event 29 - gp3_pq[7] (KB_ROW6)
+ {NV_FALSE, 30, NvOdmWakeupPadPolarity_High} // Wake Event 30 - dap1_dout (DAP1_DOUT)
+};
+
+/* --- Function Implementations ---*/
+static NvU32
+GetBctKeyValue(void)
+{
+ NvOdmServicesKeyListHandle hKeyList = NULL;
+ NvU32 BctCustOpt = 0;
+
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ BctCustOpt =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ }
+
+ return BctCustOpt;
+}
+
+NvOdmDebugConsole
+NvOdmQueryDebugConsole(void)
+{
+ NvU32 CustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC:
+ return NvOdmDebugConsole_Dcc;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE:
+ return NvOdmDebugConsole_None;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART:
+ return NvOdmDebugConsole_UartA +
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE_OPTION, CustOpt);
+ default:
+ return NvOdmDebugConsole_None;
+ }
+}
+
+NvOdmDownloadTransport
+NvOdmQueryDownloadTransport(void)
+{
+ NvU32 CustOpt = GetBctKeyValue();
+
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, TRANSPORT, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE:
+ return NvOdmDownloadTransport_None;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB:
+ return NvOdmDownloadTransport_Usb;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET:
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, ETHERNET_OPTION, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT:
+ default:
+ return NvOdmDownloadTransport_SpiEthernet;
+ }
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART:
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, UART_OPTION, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B:
+ return NvOdmDownloadTransport_UartB;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C:
+ return NvOdmDownloadTransport_UartC;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A:
+ default:
+ return NvOdmDownloadTransport_UartA;
+ }
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT:
+ default:
+ return s_NvOdmQueryDownloadTransportSetting;
+ }
+}
+
+const NvU8*
+NvOdmQueryDeviceNamePrefix(void)
+{
+ return s_NvOdmQueryDeviceNamePrefixValue;
+}
+
+const NvOdmQuerySpiDeviceInfo *
+NvOdmQuerySpiGetDeviceInfo(
+ NvOdmIoModule OdmIoModule,
+ NvU32 ControllerId,
+ NvU32 ChipSelect)
+{
+ if (OdmIoModule == NvOdmIoModule_Spi)
+ {
+ switch (ControllerId)
+ {
+ case 0:
+ if (ChipSelect == 0)
+ return &s_NvOdmQuerySpiDeviceInfoTable[0];
+ break;
+
+ default:
+ break;
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+const NvOdmQuerySpiIdleSignalState *
+NvOdmQuerySpiGetIdleSignalState(
+ NvOdmIoModule OdmIoModule,
+ NvU32 ControllerId)
+{
+ if (OdmIoModule == NvOdmIoModule_Spi)
+ {
+ if (ControllerId == 0)
+ return &s_NvOdmQuerySpiIdleSignalStateLevel[0];
+ }
+ return NULL;
+}
+
+const NvOdmQueryI2sInterfaceProperty *
+NvOdmQueryI2sGetInterfaceProperty(
+ NvU32 I2sInstanceId)
+{
+ if ((I2sInstanceId == 0) || (I2sInstanceId == 1))
+ return &s_NvOdmQueryI2sInterfacePropertySetting[I2sInstanceId];
+
+ return NULL;
+}
+
+const NvOdmQueryDapPortProperty *
+NvOdmQueryDapPortGetProperty(
+ NvU32 DapPortId)
+{
+ if (DapPortId > 0 && DapPortId < NV_ARRAY_SIZE(s_NvOdmQueryDapPortInfoTable) )
+ return &s_NvOdmQueryDapPortInfoTable[DapPortId];
+
+ return NULL;
+}
+
+const NvOdmQueryDapPortConnection*
+NvOdmQueryDapPortGetConnectionTable(
+ NvU32 ConnectionIndex)
+{
+ NvU32 TableIndex = 0;
+ for( TableIndex = 0;
+ TableIndex < NV_ARRAY_SIZE(s_NvOdmQueryDapPortConnectionTable);
+ TableIndex++)
+ {
+ if (s_NvOdmQueryDapPortConnectionTable[TableIndex].UseIndex
+ == ConnectionIndex)
+ return &s_NvOdmQueryDapPortConnectionTable[TableIndex];
+ }
+ return NULL;
+}
+
+const NvOdmQuerySpdifInterfaceProperty *
+NvOdmQuerySpdifGetInterfaceProperty(
+ NvU32 SpdifInstanceId)
+{
+ if (SpdifInstanceId == 0)
+ return &s_NvOdmQuerySpdifInterfacePropertySetting;
+
+ return NULL;
+}
+
+const NvOdmQueryAc97InterfaceProperty *
+NvOdmQueryAc97GetInterfaceProperty(
+ NvU32 Ac97InstanceId)
+{
+ if (Ac97InstanceId == 0)
+ return &s_NvOdmQueryAc97InterfacePropertySetting;
+
+ return NULL;
+}
+
+const NvOdmQueryI2sACodecInterfaceProp *
+NvOdmQueryGetI2sACodecInterfaceProperty(
+ NvU32 AudioCodecId)
+{
+ NvU32 NumInstance = sizeof(s_NvOdmQueryI2sACodecInterfacePropSetting)/
+ sizeof(s_NvOdmQueryI2sACodecInterfacePropSetting[0]);
+ if (AudioCodecId < NumInstance)
+ return &s_NvOdmQueryI2sACodecInterfacePropSetting[AudioCodecId];
+
+ return NULL;
+}
+
+/**
+ * This function is called from early boot process.
+ * Therefore, it cannot use global variables.
+ */
+NvBool NvOdmQueryAsynchMemConfig(
+ NvU32 ChipSelect,
+ NvOdmAsynchMemConfig *pMemConfig)
+{
+ return NV_FALSE;
+}
+
+const void*
+NvOdmQuerySdramControllerConfigGet(NvU32 *pEntries, NvU32 *pRevision)
+{
+#if NVODM_ENABLE_EMC_DVFS
+ NvOdmBoardInfo BoardInfo;
+
+ if (NvOdmPeripheralGetBoardInfo(BOARD_ID_HARMONY, &BoardInfo))
+ {
+ if (BoardInfo.SKU == HARMONY_HYS5C1GB_SKU)
+ {
+ if (pRevision)
+ *pRevision = s_NvOdmHyS5c1GbEmcConfigTable[0].Revision;
+ if (pEntries)
+ *pEntries = NV_ARRAY_SIZE(s_NvOdmHyS5c1GbEmcConfigTable);
+ return (const void*)s_NvOdmHyS5c1GbEmcConfigTable;
+ }
+ }
+#endif
+ if (pEntries)
+ *pEntries = 0;
+ return NULL;
+}
+
+NvOdmQueryOscillator NvOdmQueryGetOscillatorSource(void)
+{
+ return NvOdmQueryOscillator_Xtal;
+}
+
+NvU32 NvOdmQueryGetOscillatorDriveStrength(void)
+{
+ /// Oscillator drive strength range is 0 to 0x3F
+ return 0x04;
+}
+
+const NvOdmWakeupPadInfo *NvOdmQueryGetWakeupPadTable(NvU32 *pSize)
+{
+ if (pSize)
+ *pSize = NV_ARRAY_SIZE(s_NvOdmWakeupPadInfo);
+
+ return (const NvOdmWakeupPadInfo *) s_NvOdmWakeupPadInfo;
+}
+
+const NvU8* NvOdmQueryManufacturer(void)
+{
+ return s_NvOdmQueryManufacturerSetting;
+}
+
+const NvU8* NvOdmQueryModel(void)
+{
+ return s_NvOdmQueryModelSetting;
+}
+
+const NvU8* NvOdmQueryPlatform(void)
+{
+ return s_NvOdmQueryPlatformSetting;
+}
+
+const NvU8* NvOdmQueryProjectName(void)
+{
+ return s_NvOdmQueryProjectNameSetting;
+}
+
+#define EXT 0 // external pull-up/down resistor
+#define INT_PU 1 // internal pull-up
+#define INT_PD 2 // internal pull-down
+
+#define HIGHSPEED 1
+#define SCHMITT 1
+#define VREF 1
+#define OHM_50 3
+#define OHM_100 2
+#define OHM_200 1
+#define OHM_400 0
+
+ // Pin attributes
+static const NvOdmPinAttrib pin_config[] = {
+ // Pull ups for the kbc pins
+ { NvOdmPinRegister_Ap20_PullUpDown_B,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_B(0x0, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) },
+
+ // Pull ups for the kbc pins
+ { NvOdmPinRegister_Ap20_PullUpDown_E,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_E(0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x2, 0x2) },
+
+ // Set pad control for the sdio2 - - AOCFG1 and AOCFG2 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_AOCFG1PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_AOCFG2PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for the sdio3 - SDIO2 and SDIO3 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_SDIO2CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_SDIO3CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for I2C1 pins
+ { NvOdmPinRegister_Ap20_PadCtrl_DBGCFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_VICFG1PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_VICFG2PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for I2C2 (DDC) pins
+ { NvOdmPinRegister_Ap20_PadCtrl_DDCCFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for the sdio1 - SDIO1 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_SDIO1CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // WiFi Pins (DTA, DTD) need to be pulled up
+ { NvOdmPinRegister_Ap20_PullUpDown_A,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_A(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0) },
+
+ // Set pad control for the sdio4- ATCCFG1 and ATCCFG2 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_ATCFG1PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_ATCFG2PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }
+};
+
+NvU32
+NvOdmQueryPinAttributes(const NvOdmPinAttrib** pPinAttributes)
+{
+ if (pPinAttributes)
+ {
+ *pPinAttributes = &pin_config[0];
+ return NV_ARRAY_SIZE(pin_config);
+ }
+ return 0;
+}
+
+NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty)
+{
+ pPmuProperty->IrqConnected = NV_FALSE;
+ pPmuProperty->PowerGoodCount = 0x7E;
+ pPmuProperty->IrqPolarity = NvOdmInterruptPolarity_Low;
+ pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_Low;
+ pPmuProperty->SysClockReqPolarity = NvOdmSysClockReqPolarity_High;
+ pPmuProperty->CombinedPowerReq = NV_FALSE;
+ pPmuProperty->CpuPowerGoodUs = 2000;
+ pPmuProperty->AccuracyPercent = 3;
+ pPmuProperty->VCpuOTPOnWakeup = NV_FALSE;
+ return NV_TRUE;
+}
+
+/**
+ * Gets the lowest soc power state supported by the hardware
+ *
+ * @returns information about the SocPowerState
+ */
+const NvOdmSocPowerStateInfo* NvOdmQueryLowestSocPowerState(void)
+{
+
+ static NvOdmSocPowerStateInfo PowerStateInfo;
+ const static NvOdmSocPowerStateInfo* pPowerStateInfo = NULL;
+ NvOdmServicesKeyListHandle hKeyList;
+ NvU32 LPStateSelection = 0;
+ if (pPowerStateInfo == NULL)
+ {
+
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ LPStateSelection = NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ LPStateSelection = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, LPSTATE, LPStateSelection);
+ }
+ // Lowest power state controlled by the flashed custom option.
+ PowerStateInfo.LowestPowerState = ((LPStateSelection != TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1)?
+ NvOdmSocPowerState_Suspend : NvOdmSocPowerState_DeepSleep);
+ pPowerStateInfo = (const NvOdmSocPowerStateInfo*) &PowerStateInfo;
+ }
+ return (pPowerStateInfo);
+}
+
+const NvOdmUsbProperty*
+NvOdmQueryGetUsbProperty(NvOdmIoModule OdmIoModule,
+ NvU32 Instance)
+{
+ static const NvOdmUsbProperty Usb1Property =
+ {
+ NvOdmUsbInterfaceType_Utmi,
+ (NvOdmUsbChargerType_SE0 | NvOdmUsbChargerType_SE1 | NvOdmUsbChargerType_SK),
+ 20,
+ NV_TRUE,
+ NvOdmUsbModeType_Device,
+ NvOdmUsbIdPinType_CableId,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_TRUE
+ };
+
+ static const NvOdmUsbProperty Usb2Property =
+ {
+ NvOdmUsbInterfaceType_UlpiExternalPhy,
+ NvOdmUsbChargerType_UsbHost,
+ 20,
+ NV_TRUE,
+ NvOdmUsbModeType_Host,
+ NvOdmUsbIdPinType_None,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_TRUE
+ };
+
+ static const NvOdmUsbProperty Usb3Property =
+ {
+ NvOdmUsbInterfaceType_Utmi,
+ NvOdmUsbChargerType_UsbHost,
+ 20,
+ NV_TRUE,
+ NvOdmUsbModeType_Host,
+ NvOdmUsbIdPinType_None,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_TRUE
+ };
+
+ if (OdmIoModule == NvOdmIoModule_Usb && Instance == 0)
+ return &(Usb1Property);
+
+ if (OdmIoModule == NvOdmIoModule_Usb && Instance == 1)
+ return &(Usb2Property);
+
+ if (OdmIoModule == NvOdmIoModule_Usb && Instance == 2)
+ return &(Usb3Property);
+
+ return (const NvOdmUsbProperty *)NULL;
+}
+
+const NvOdmQuerySdioInterfaceProperty* NvOdmQueryGetSdioInterfaceProperty(NvU32 Instance)
+{
+ return &s_NvOdmQuerySdioInterfaceProperty[Instance];
+}
+
+const NvOdmQueryHsmmcInterfaceProperty* NvOdmQueryGetHsmmcInterfaceProperty(NvU32 Instance)
+{
+ return NULL;
+}
+
+NvU32
+NvOdmQueryGetBlockDeviceSectorSize(NvOdmIoModule OdmIoModule)
+{
+ return 0;
+}
+
+const NvOdmQueryOwrDeviceInfo* NvOdmQueryGetOwrDeviceInfo(NvU32 Instance)
+{
+ return NULL;
+}
+
+const NvOdmGpioWakeupSource *NvOdmQueryGetWakeupSources(NvU32 *pCount)
+{
+ *pCount = 0;
+ return NULL;
+}
+
+/**
+ * This function is called from early boot process.
+ * Therefore, it cannot use global variables.
+ */
+NvU32 NvOdmQueryMemSize(NvOdmMemoryType MemType)
+{
+ NvOdmOsOsInfo Info;
+ NvU32 MemBctCustOpt = GetBctKeyValue();
+
+ switch (MemType)
+ {
+ // NOTE:
+ // For Windows CE/WM operating systems the total size of SDRAM may
+ // need to be reduced due to limitations in the virtual address map.
+ // Under the legacy physical memory manager, Windows OSs have a
+ // maximum 512MB statically mapped virtual address space. Under the
+ // new physical memory manager, Windows OSs have a maximum 1GB
+ // statically mapped virtual address space. Out of that virtual
+ // address space, the upper 32 or 36 MB (depending upon the SOC)
+ // of the virtual address space is reserved for SOC register
+ // apertures.
+ //
+ // Refer to virtual_tables_apxx.arm for the reserved aperture list.
+ // If the cumulative size of the reserved apertures changes, the
+ // maximum size of SDRAM will also change.
+ case NvOdmMemoryType_Sdram:
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_SYSTEM, MEMORY, MemBctCustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_256:
+ if ( NvOdmOsGetOsInformation(&Info) &&
+ ((Info.OsType!=NvOdmOsOs_Windows) ||
+ (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) )
+ return 0x10000000;
+ else
+ return 0x0DD00000; // Legacy Physical Memory Manager: 256 MB - 35 MB
+
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1024:
+ if ( NvOdmOsGetOsInformation(&Info) &&
+ ((Info.OsType!=NvOdmOsOs_Windows) ||
+ (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) )
+ return 0x40000000;
+ else
+ // Earlier versions of WinCE only support 512MB max memory size
+ return 0x1E000000; // Legacy Physical Memory Manager: 512 MB - 32 MB
+
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_512:
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT:
+ default:
+ if ( NvOdmOsGetOsInformation(&Info) &&
+ ((Info.OsType!=NvOdmOsOs_Windows) ||
+ (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) )
+ return 0x20000000;
+ else
+ return 0x1E000000; // Legacy Physical Memory Manager: 512 MB - 32 MB
+ }
+
+ case NvOdmMemoryType_Nor:
+ return 0x00400000; // 4 MB
+
+ case NvOdmMemoryType_Nand:
+ case NvOdmMemoryType_I2CEeprom:
+ case NvOdmMemoryType_Hsmmc:
+ case NvOdmMemoryType_Mio:
+ default:
+ return 0;
+ }
+}
+
+NvU32 NvOdmQueryCarveoutSize(void)
+{
+ return 0x04000000; // 64 MB
+}
+
+NvU32 NvOdmQuerySecureRegionSize(void)
+{
+ return 0x00800000;// 8 MB
+}
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c
new file mode 100644
index 000000000000..6b0b896d0cf3
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c
@@ -0,0 +1,770 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: The peripheral connectivity database implementation.
+ */
+
+#include "nvcommon.h"
+#include "nvodm_query_gpio.h"
+#include "nvodm_modules.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_keylist_reserved.h"
+#include "tegra_devkit_custopt.h"
+#include "nvodm_query.h"
+#include "nvrm_drf.h"
+
+#include "subboards/nvodm_query_discovery_e1162_addresses.h"
+
+static NvOdmPeripheralConnectivity s_Peripherals_Default[] =
+{
+#include "subboards/nvodm_query_discovery_e1162_peripherals.h"
+};
+
+#define NVODM_QUERY_BOARD_ID_UNKNOWN 0xFFFF
+
+#define NVODM_QUERY_MAX_PERIPHERALS 0x400
+#define NVODM_QUERY_MAX_IO_ADDRESSES 0x400
+
+#define NVODM_QUERY_MAX_EEPROMS 8 // Maximum number of EEPROMs per bus segment
+
+#define NVODM_QUERY_ERASED_EEPROM_VALUE 0xFF
+
+#define PROCESSOR_BOARD_ID_I2C_ADDRESS ((0x56)<<1)
+#define PROCESSOR_BOARD_ID_I2C_SEGMENT (0x00)
+
+// The following are used to store entries read from EEPROMs at runtime.
+static NvOdmPeripheralConnectivity s_Peripherals[NVODM_QUERY_MAX_PERIPHERALS];
+static NvOdmIoAddress s_Peripheral_IoAddresses[NVODM_QUERY_MAX_IO_ADDRESSES];
+static NvOdmBoardInfo s_BoardModuleTable[NVODM_QUERY_MAX_EEPROMS];
+
+#define NVODM_QUERY_I2C_CLOCK_SPEED 100 // kHz
+
+#define NVODM_QUERY_ENTRY_HEADER_SIZE 0x30 // Size of EERPOM "Entry Header"
+#define NVODM_QUERY_BOARD_HEADER_START 0x04 // Offset to Part Number in EERPOM
+
+#define NVODM_QUERY_I2C_EEPROM_ADDRESS 0xA0 // I2C device base address for EEPROM (7'h50)
+
+#define NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED 10 // See EEPROM_format.txt
+#define NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED 2 // See EEPROM_format.txt
+
+
+static NvOdmI2cStatus
+NvOdmPeripheralI2cRead8(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 I2cAddr,
+ NvU8 Offset,
+ NvU8 *pData)
+{
+ NvU8 ReadBuffer[1];
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ ReadBuffer[0] = Offset;
+
+ TransactionInfo.Address = I2cAddr;
+ TransactionInfo.Buf = ReadBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 1;
+
+ Error = NvOdmI2cTransaction(
+ hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return Error;
+ }
+
+ NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer));
+
+ TransactionInfo.Address = (I2cAddr | 0x1);
+ TransactionInfo.Buf = ReadBuffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = 1;
+
+ // Read data from ROM at the specified offset
+ Error = NvOdmI2cTransaction(
+ hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return Error;
+ }
+ *pData = ReadBuffer[0];
+ return Error;
+}
+
+static NvBool
+NvOdmPeripheralReadNumPeripherals(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvU8 *pNumModulePeripherals)
+{
+ NvOdmI2cStatus Error;
+ NvU8 I2cAddr, Offset;
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ /**
+ * Offset to numPeripherals in NvOdmPeripheralConnectivity Structure.
+ * It's the first parameter after the "Entry Header."
+ */
+ Offset = NVODM_QUERY_ENTRY_HEADER_SIZE;
+
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, Offset, pNumModulePeripherals);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadPeripheral(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvU8 Peripheral,
+ NvU64 *pGuid,
+ NvU8 *pEepromAddressListOffset,
+ NvU32 *pNumAddress,
+ NvOdmPeripheralClass *pClass)
+{
+ NvOdmI2cStatus Error;
+ NvU32 i;
+ NvU8 ConnMemberIndex=0; // Offset to members in NvOdmPeripheralConnectivity
+ NvU8 I2cAddr, Offset;
+ NvU8 ReadBuffer[NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED];
+ NvU8 NumAddrAndClass;
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ /**
+ * Calculate offset to pGuid in NvOdmPeripheralConnectivity Structure
+ *
+ * Offset = sizeof(eeprom Entry Header) +
+ * sizeof(NvOdmPeripheralConnectivity)*peripheral +
+ * pGuid offset <-- First field, so this is 0
+ */
+ Offset = NVODM_QUERY_ENTRY_HEADER_SIZE +
+ sizeof(NvOdmPeripheralConnectivity)*Peripheral;
+
+ for (i=0; i<NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED; i++)
+ {
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, Offset, (NvU8 *)&ReadBuffer[i]);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ }
+ // Save pGuid entry
+ NvOdmOsMemcpy(pGuid, &ReadBuffer[0], sizeof(NvU64));
+
+ // Save EEPROM offset
+ ConnMemberIndex += sizeof(NvU64); // Increment to next member
+ *pEepromAddressListOffset = ReadBuffer[ConnMemberIndex];
+
+ // Save pNumAddress & Class
+ ConnMemberIndex += sizeof(NvU8); // Increment to next member
+ NumAddrAndClass = ReadBuffer[ConnMemberIndex];
+ *pNumAddress = (NvU32)((NumAddrAndClass >> 3) & 0x0000001F);
+ *pClass = (NvOdmPeripheralClass)(NumAddrAndClass & 0x00000007);
+
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadIoAddressData(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvU8 EepromAddressListOffset,
+ NvOdmIoAddress *pIoAddressEntry)
+{
+ NvOdmI2cStatus Error;
+ NvU32 i;
+ NvU8 I2cAddr;
+ NvU8 ReadBuffer[NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED];
+ NvU16 CompressedIoAddressEntry;
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ for (i=0; i<NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED; i++)
+ {
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, EepromAddressListOffset, (NvU8 *)&ReadBuffer[i]);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ }
+ // Save pIoAddressEntry: interface, instance, address
+ CompressedIoAddressEntry = ((((NvU16)ReadBuffer[1]) << 8) & 0xFF00) | ReadBuffer[0];
+
+ pIoAddressEntry->Interface = (NvOdmIoModule)((CompressedIoAddressEntry >> 11) & 0x1F);
+
+ if (pIoAddressEntry->Interface != NvOdmIoModule_Gpio)
+ {
+ pIoAddressEntry->Instance = (NvU32)((CompressedIoAddressEntry >> 7) & 0xF);
+ pIoAddressEntry->Address = (NvU32)(CompressedIoAddressEntry & 0x7F);
+ }
+ else
+ {
+ pIoAddressEntry->Address = (NvU32)((CompressedIoAddressEntry >> 6) & 0x3F);
+ pIoAddressEntry->Instance = (NvU32)(CompressedIoAddressEntry & 0x3F);
+ }
+
+ return NV_TRUE;
+}
+
+static NvBool NvOdmPeripheralGetEntries(NvU32 *pNum)
+{
+ NvBool RetVal;
+ NvBool IsMatch = NV_FALSE;
+ NvOdmServicesI2cHandle hOdmI2c = NULL;
+ NvU8 EepromInst;
+
+ // Peripheral counters
+ NvU8 NumPeripherals = 0;
+ NvU8 CurrentPeripheral = 0;
+ NvU32 TotalPeripherals = 0;
+ NvU32 StaticPeripherals;
+
+ NvU32 CurrentIoAddressNum = 0;
+ NvU32 TotalIoAddressEntries = 0;
+
+ NvU32 i,j;
+ NvU8 EepromAddressListOffset;
+
+ if (!pNum) {
+ return NV_FALSE;
+ }
+
+ // Auto-detect -- Read I2C-EEPROMs on each sub-board
+
+ hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0);
+ if (!hOdmI2c)
+ return NV_FALSE;
+
+ for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++)
+ {
+ RetVal = NvOdmPeripheralReadNumPeripherals(
+ hOdmI2c, EepromInst, &NumPeripherals);
+
+ if ( (RetVal == NV_TRUE) &&
+ (NumPeripherals != NVODM_QUERY_ERASED_EEPROM_VALUE) )
+ {
+ if (NumPeripherals > 0)
+ {
+ if ((NumPeripherals + TotalPeripherals) > NVODM_QUERY_MAX_PERIPHERALS)
+ {
+ NV_ASSERT( !"ERROR: s_Peripherals[] is too small to accommodate entries!" );
+
+ // Break out of loop and use static/default configuration
+ break;
+ }
+
+ for (CurrentPeripheral=0; \
+ CurrentPeripheral < NumPeripherals; \
+ CurrentPeripheral++)
+ {
+ RetVal = NvOdmPeripheralReadPeripheral(
+ hOdmI2c,
+ EepromInst,
+ CurrentPeripheral,
+ &s_Peripherals[TotalPeripherals+CurrentPeripheral].Guid,
+ &EepromAddressListOffset,
+ &s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress,
+ &s_Peripherals[TotalPeripherals+CurrentPeripheral].Class);
+
+ if (RetVal == NV_FALSE)
+ {
+ NV_ASSERT(!"Unable to read EEPROM peripheral entry!");
+ break; // Go to next EEPROM
+ }
+ else // Process peripheral entry
+ {
+ /**
+ * Process NvOdmIoAddress arrays --
+ *
+ * These are separate data structures. The addressList value
+ * read from the EEPROM (EepromAddressListOffset) represents
+ * an offset address within the I2C-EEPROM. This offset value
+ * identifies where to find the first instance of the
+ * NvOdmIoAddress data.
+ *
+ * The total number of NvOdmIoAddress entries is identified
+ * by the numAddress variable following the addressList entry
+ * in EEPROM.
+ *
+ * Once the offset and number of entries are determined (from
+ * above NvOdmPeripheralReadPeripheral function call), a loop
+ * fills in entries within the fixed storage area
+ * (e.g., s_Peripheral_IoAddresses) and the actual
+ * addressList pointer is assigned a value that corresponds
+ * to the first entry of the current class within this array.
+ * In other words, there might be prior entries in the
+ * s_Peripheral_IoAddresses array, but the first entry
+ * corresponding to the current class might be the third
+ * element in this array. Therefore, the actual addressList
+ * pointer for the current NvOdmPeripheralConnectivity.addressList
+ * parameter would be the address of the third entry, which is
+ * &s_Peripheral_IoAddresses[2] in this example.
+ */
+
+ // Read all of the entries and save them in s_Peripheral_IoAddresses
+ for (CurrentIoAddressNum=0; \
+ CurrentIoAddressNum < s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress; \
+ CurrentIoAddressNum++)
+ {
+ if (TotalIoAddressEntries > NVODM_QUERY_MAX_IO_ADDRESSES)
+ {
+ NV_ASSERT( !"ERROR: s_Peripheral_IoAddresses[] is too small to accommodate entries!" );
+
+ // Cannot recover from this error.
+ NvOdmI2cClose(hOdmI2c);
+ return NV_FALSE;
+ }
+
+ RetVal = NvOdmPeripheralReadIoAddressData(
+ hOdmI2c,
+ EepromInst,
+ EepromAddressListOffset,
+ &s_Peripheral_IoAddresses[TotalIoAddressEntries+CurrentIoAddressNum]);
+
+ if (RetVal == NV_FALSE)
+ {
+ NV_ASSERT(!"Unable to read EEPROM (IoAddresses)!");
+
+ // Cannot recover from this error.
+ NvOdmI2cClose(hOdmI2c);
+ return NV_FALSE;
+ }
+ else // Process IoAddresses entry
+ {
+ /**
+ * Save the addressList pointer. This points to the first
+ * IoAddresses entry of this class. Then update the overall
+ * IoAddresses array counter (TotalIoAddressEntries).
+ */
+ s_Peripherals[TotalPeripherals+CurrentPeripheral].AddressList =
+ &s_Peripheral_IoAddresses[TotalIoAddressEntries];
+
+ TotalIoAddressEntries += CurrentIoAddressNum;
+
+ // >-- End of NvOdmIoAddress array processing --<
+ }
+ }
+ }
+ }
+ }
+ TotalPeripherals += NumPeripherals;
+ }
+ }
+
+ // Done reading I2C-EEPROM; close it.
+ NvOdmI2cClose(hOdmI2c);
+
+ /**
+ * Append static peripheral entries (if any) to dynamic list
+ * read from EEPROMs (this list may also be empty), except for
+ * duplicate GUIDs. The dynamic list takes precedence when
+ * duplicate entries are found in the static list.
+ */
+ StaticPeripherals = NV_ARRAY_SIZE(s_Peripherals_Default);
+ for (i=0; i<StaticPeripherals; i++)
+ {
+ for (j=0; j<TotalPeripherals; j++)
+ {
+ if (s_Peripherals_Default[i].Guid == s_Peripherals[j].Guid)
+ {
+ IsMatch = NV_TRUE;
+ break; // Ignore duplicate entry from static list.
+ }
+ }
+ if (IsMatch != NV_TRUE)
+ {
+ // Append unique entry to dynamic list
+
+ s_Peripherals[TotalPeripherals].Guid =
+ s_Peripherals_Default[i].Guid;
+
+ s_Peripherals[TotalPeripherals].AddressList =
+ s_Peripherals_Default[i].AddressList;
+
+ s_Peripherals[TotalPeripherals].NumAddress =
+ s_Peripherals_Default[i].NumAddress;
+
+ s_Peripherals[TotalPeripherals].Class =
+ s_Peripherals_Default[i].Class;
+
+ TotalPeripherals++;
+ }
+ }
+ *pNum = TotalPeripherals;
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadPartNumber(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvOdmBoardInfo *pBoardInfo)
+{
+ NvOdmI2cStatus Error;
+ NvU32 i;
+ NvU8 I2cAddr, Offset;
+ NvU8 ReadBuffer[sizeof(NvOdmBoardInfo)];
+
+ NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer));
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ /**
+ * Offset to the board number entry in EEPROM.
+ */
+ Offset = NVODM_QUERY_BOARD_HEADER_START;
+
+ for (i=0; i<sizeof(NvOdmBoardInfo); i++)
+ {
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, Offset+i, (NvU8 *)&ReadBuffer[i]);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ }
+ NvOdmOsMemcpy(pBoardInfo, &ReadBuffer[0], sizeof(NvOdmBoardInfo));
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmPeripheralGetBoardInfo(
+ NvU16 BoardId,
+ NvOdmBoardInfo *pBoardInfo)
+{
+ NvBool RetVal = NV_FALSE;
+ NvOdmServicesI2cHandle hOdmI2c = NULL;
+ NvU8 EepromInst, CurrentBoard;
+ static NvU8 NumBoards = 0;
+ static NvBool s_ReadBoardInfoDone = NV_FALSE;
+
+ if (!s_ReadBoardInfoDone)
+ {
+ s_ReadBoardInfoDone = NV_TRUE;
+ hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0);
+ if (!hOdmI2c)
+ {
+ // Exit
+ pBoardInfo = NULL;
+ return NV_FALSE;
+ }
+
+ for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++)
+ {
+ RetVal = NvOdmPeripheralReadPartNumber(
+ hOdmI2c, EepromInst, &s_BoardModuleTable[NumBoards]);
+ if (RetVal == NV_TRUE)
+ NumBoards++;
+ }
+ NvOdmI2cClose(hOdmI2c);
+ }
+
+ if (NumBoards)
+ {
+ // Linear search for given BoardId; if found, return entry
+ for (CurrentBoard=0; CurrentBoard < NumBoards; CurrentBoard++)
+ {
+ if (s_BoardModuleTable[CurrentBoard].BoardID == BoardId)
+ {
+ // Match found
+ pBoardInfo->BoardID = s_BoardModuleTable[CurrentBoard].BoardID;
+ pBoardInfo->SKU = s_BoardModuleTable[CurrentBoard].SKU;
+ pBoardInfo->Fab = s_BoardModuleTable[CurrentBoard].Fab;
+ pBoardInfo->Revision = s_BoardModuleTable[CurrentBoard].Revision;
+ pBoardInfo->MinorRevision = s_BoardModuleTable[CurrentBoard].MinorRevision;
+ return NV_TRUE;
+ }
+ }
+ }
+
+ // Match not found
+ pBoardInfo = NULL;
+ return NV_FALSE;
+}
+
+// This will compare the peripheral GUID against a list of known-bad GUIDs
+// for certain development kit personalities, and return NV_TRUE if it is
+// known to be unsupported (filtered) on the current configuration
+static NvBool
+NvIsFilteredPeripheral(const NvOdmPeripheralConnectivity* pConnectivity)
+{
+ NvOdmServicesKeyListHandle hKeyList;
+ NvU32 Personality = 0;
+ NvU32 opt = 0;
+ NvOdmIoModule OdmModule;
+ const NvU32 *OdmConfigs=NULL;
+ NvU32 NumOdmConfigs = 0;
+ const NvOdmPeripheralConnectivity* pFilteredPeriph = pConnectivity;
+
+ if((!pConnectivity) || (!pConnectivity->NumAddress))
+ return NV_TRUE;
+
+ hKeyList = NvOdmServicesKeyListOpen();
+
+ if (hKeyList)
+ {
+ Personality =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ Personality =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, Personality);
+ opt =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, DISPLAY_OPTION, opt);
+ }
+
+ if (!Personality)
+ Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY;
+
+ OdmModule = pFilteredPeriph->AddressList[0].Interface;
+
+ if(OdmModule != NvOdmIoModule_Gpio)
+ NvOdmQueryPinMux(OdmModule, &OdmConfigs, &NumOdmConfigs);
+
+ switch (OdmModule)
+ {
+ case NvOdmIoModule_Gpio:
+ // Filter scroll wheel when trace is enabled
+ if ( (pConnectivity->Guid == NV_ODM_GUID('s','c','r','o','l','w','h','l')) &&
+ ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) )
+ return NV_TRUE;
+ else
+ return NV_FALSE;
+
+ default:
+ return NV_FALSE;
+ }
+}
+
+static const NvOdmPeripheralConnectivity*
+NvApGetAllPeripherals (NvU32 *pNum)
+{
+ static NvBool s_AutoDetectDone = NV_FALSE;
+ NvBool RetVal = NV_TRUE;
+ static NvU32 s_TotalPeripherals;
+ NvOdmBoardInfo BoardInfo;
+
+ if (!pNum)
+ return NULL;
+
+ if (!s_AutoDetectDone)
+ {
+ /**
+ * Read & cache the board ID info from the I2C-EEPROMs. This
+ * is necessary because once Whistler's thermal power rail is
+ * enabled, the ID ROMs cannot be read. NvApGetAllPeripherals()
+ * is called before that rail is enabled.
+ */
+ NvOdmPeripheralGetBoardInfo(NVODM_QUERY_BOARD_ID_UNKNOWN, &BoardInfo);
+
+ RetVal = NvOdmPeripheralGetEntries(&s_TotalPeripherals);
+ if (RetVal == NV_FALSE)
+ {
+ *pNum = 0;
+ return NULL;
+ }
+ s_AutoDetectDone = NV_TRUE;
+ }
+
+ *pNum = s_TotalPeripherals;
+ return (const NvOdmPeripheralConnectivity *)s_Peripherals;
+}
+
+// This implements a simple linear search across the entire set of currently-
+// connected peripherals to find the set of GUIDs that Match the search
+// criteria. More clever implementations are possible, but given the
+// relatively small search space (max dozens of peripherals) and the relative
+// infrequency of enumerating peripherals, this is the easiest implementation.
+const NvOdmPeripheralConnectivity *
+NvOdmPeripheralGetGuid(NvU64 SearchGuid)
+{
+ const NvOdmPeripheralConnectivity *pAllPeripherals;
+ NvU32 NumPeripherals;
+ NvU32 i;
+
+ pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals);
+
+ if (!pAllPeripherals || !NumPeripherals)
+ return NULL;
+
+ for (i=0; i<NumPeripherals; i++)
+ {
+ if (SearchGuid == pAllPeripherals[i].Guid)
+ {
+ if (NvIsFilteredPeripheral(&pAllPeripherals[i]))
+ return NULL;
+ return &pAllPeripherals[i];
+ }
+ }
+
+ return NULL;
+}
+
+static NvBool
+IsBusMatch(
+ const NvOdmPeripheralConnectivity *pPeriph,
+ const NvOdmPeripheralSearch *pSearchAttrs,
+ const NvU32 *pSearchVals,
+ NvU32 offset,
+ NvU32 NumAttrs)
+{
+ NvU32 i, j;
+ NvBool IsMatch = NV_FALSE;
+
+ for (i=0; i<pPeriph->NumAddress; i++)
+ {
+ j = offset;
+ do
+ {
+ switch (pSearchAttrs[j])
+ {
+ case NvOdmPeripheralSearch_IoModule:
+ IsMatch = (pSearchVals[j] ==
+ (NvU32)(pPeriph->AddressList[i].Interface));
+ break;
+ case NvOdmPeripheralSearch_Address:
+ IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Address);
+ break;
+ case NvOdmPeripheralSearch_Instance:
+ IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Instance);
+ break;
+ case NvOdmPeripheralSearch_PeripheralClass:
+ default:
+ NV_ASSERT(!"Bad Query!");
+ break;
+ }
+ j++;
+ } while (IsMatch && j<NumAttrs &&
+ pSearchAttrs[j]!=NvOdmPeripheralSearch_IoModule);
+
+ if (IsMatch)
+ {
+ return NV_TRUE;
+ }
+ }
+ return NV_FALSE;
+}
+
+static NvBool
+IsPeripheralMatch(
+ const NvOdmPeripheralConnectivity *pPeriph,
+ const NvOdmPeripheralSearch *pSearchAttrs,
+ const NvU32 *pSearchVals,
+ NvU32 NumAttrs)
+{
+ NvU32 i;
+ NvBool IsMatch = NV_TRUE;
+
+ for (i=0; i<NumAttrs && IsMatch; i++)
+ {
+ switch (pSearchAttrs[i])
+ {
+ case NvOdmPeripheralSearch_PeripheralClass:
+ IsMatch = (pSearchVals[i] == (NvU32)(pPeriph->Class));
+ break;
+ case NvOdmPeripheralSearch_IoModule:
+ IsMatch = IsBusMatch(pPeriph, pSearchAttrs, pSearchVals, i, NumAttrs);
+ break;
+ case NvOdmPeripheralSearch_Address:
+ case NvOdmPeripheralSearch_Instance:
+ // In correctly-formed searches, these parameters will be parsed by
+ // IsBusMatch, so we ignore them here.
+ break;
+ default:
+ NV_ASSERT(!"Bad search attribute!");
+ break;
+ }
+ }
+ return IsMatch;
+}
+
+NvU32
+NvOdmPeripheralEnumerate(
+ const NvOdmPeripheralSearch *pSearchAttrs,
+ const NvU32 *pSearchVals,
+ NvU32 NumAttrs,
+ NvU64 *pGuidList,
+ NvU32 NumGuids)
+{
+ const NvOdmPeripheralConnectivity *pAllPeripherals;
+ NvU32 NumPeripherals;
+ NvU32 Matches;
+ NvU32 i;
+
+ pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals);
+
+ if (!pAllPeripherals || !NumPeripherals)
+ {
+ return 0;
+ }
+
+ if (!pSearchAttrs || !pSearchVals)
+ {
+ NumAttrs = 0;
+ }
+ for (i=0, Matches=0; i<NumPeripherals &&
+ (Matches < NumGuids || !pGuidList); i++)
+ {
+ if ( !NumAttrs || IsPeripheralMatch(&pAllPeripherals[i],
+ pSearchAttrs, pSearchVals,
+ NumAttrs) )
+ {
+ if (NvIsFilteredPeripheral(&pAllPeripherals[i]))
+ continue;
+
+ if (pGuidList)
+ pGuidList[Matches] = pAllPeripherals[i].Guid;
+ Matches++;
+ }
+ }
+ return Matches;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
new file mode 100644
index 000000000000..8d384db176ee
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_query_gpio.h"
+#include "nvodm_services.h"
+#include "nvrm_drf.h"
+
+#define NVODM_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define NVODM_PORT(x) ((x) - 'a')
+
+static const NvOdmGpioPinInfo s_vi[] = {
+ {NVODM_PORT('t'), 3, NvOdmGpioPinActiveState_High}, // EN_VDDIO_SD
+};
+
+static const NvOdmGpioPinInfo s_display[] = {
+
+ // TO DO: Verify these settings for harmony.
+
+ /* Panel 0 -- sony vga */
+ { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('j'), 3, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('j'), 4, NvOdmGpioPinActiveState_Low },
+ // this pin is not needed for ap15
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+
+ /* Panel 1 -- samtek */
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+
+ /* Panel 2 -- sharp wvga */
+ { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low },
+
+ /* Panel 3 -- sharp qvga */
+ { NVODM_PORT('n'), 6, NvOdmGpioPinActiveState_High }, // LCD_DC0
+ { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low }, // LCD_CS0
+ { NVODM_PORT('b'), 3, NvOdmGpioPinActiveState_Low }, // LCD_PCLK
+ { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low }, // LCD_PWR0
+ { NVODM_PORT('e'), 0, NvOdmGpioPinActiveState_High }, // LCD_D0
+ { NVODM_PORT('e'), 1, NvOdmGpioPinActiveState_High }, // LCD_D1
+ { NVODM_PORT('e'), 2, NvOdmGpioPinActiveState_High }, // LCD_D2
+ { NVODM_PORT('e'), 3, NvOdmGpioPinActiveState_High }, // LCD_D3
+ { NVODM_PORT('e'), 4, NvOdmGpioPinActiveState_High }, // LCD_D4
+ { NVODM_PORT('e'), 5, NvOdmGpioPinActiveState_High }, // LCD_D5
+ { NVODM_PORT('e'), 6, NvOdmGpioPinActiveState_High }, // LCD_D6
+ { NVODM_PORT('e'), 7, NvOdmGpioPinActiveState_High }, // LCD_D7
+ { NVODM_PORT('f'), 0, NvOdmGpioPinActiveState_High }, // LCD_D8
+ { NVODM_PORT('f'), 1, NvOdmGpioPinActiveState_High }, // LCD_D9
+ { NVODM_PORT('f'), 2, NvOdmGpioPinActiveState_High }, // LCD_D10
+ { NVODM_PORT('f'), 3, NvOdmGpioPinActiveState_High }, // LCD_D11
+ { NVODM_PORT('f'), 4, NvOdmGpioPinActiveState_High }, // LCD_D12
+ { NVODM_PORT('f'), 5, NvOdmGpioPinActiveState_High }, // LCD_D13
+ { NVODM_PORT('f'), 6, NvOdmGpioPinActiveState_High }, // LCD_D14
+ { NVODM_PORT('f'), 7, NvOdmGpioPinActiveState_High }, // LCD_D15
+ { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_High }, // LCD_D19
+
+ /* Panel 4 -- auo */
+ { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low },
+
+ /* Panel 5 -- firefly p1138 lvds interface */
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, NvOdmGpioPinActiveState_Low},
+ { NVODM_PORT('b'), 4, NvOdmGpioPinActiveState_High }, // LCD_BL_PWM
+ { NVODM_PORT('b'), 5, NvOdmGpioPinActiveState_High }, // LCD_BL_EN
+ { NVODM_PORT('c'), 6, NvOdmGpioPinActiveState_High }, // EN_VDD_PNL
+};
+
+static const NvOdmGpioPinInfo s_hdmi[] =
+{
+ /* hdmi hot-plug interrupt pin */
+ { NVODM_PORT('n'), 7, NvOdmGpioPinActiveState_High }, // HDMI HPD
+};
+
+static const NvOdmGpioPinInfo s_crt[] =
+{
+ /* crt hot-plug interrupt pin */
+ { NVODM_PORT('x'), 2, NvOdmGpioPinActiveState_Low }, // VGA_DET#
+};
+
+static const NvOdmGpioPinInfo s_sdio[] = {
+ {NVODM_PORT('i'), 5, NvOdmGpioPinActiveState_Low}, // Card Detect for SDIO instance 2
+ /* High for WP and low for read/write */
+ {NVODM_PORT('h'), 1, NvOdmGpioPinActiveState_High}, // Write Protect for SDIO instance 2
+};
+
+static const NvOdmGpioPinInfo s_sdio3[] = {
+ {NVODM_PORT('h'), 2, NvOdmGpioPinActiveState_Low}, // Card Detect for SDIO instance 3
+ /* High for WP and low for read/write */
+ {NVODM_PORT('h'), 3, NvOdmGpioPinActiveState_High}, // Write Protect for SDIO instance 3
+};
+
+static const NvOdmGpioPinInfo s_NandFlash[] = {
+ {NVODM_PORT('c'), 7, NvOdmGpioPinActiveState_High}, // Raw NAND WP_N
+};
+
+static const NvOdmGpioPinInfo s_spi_ethernet[] = {
+ {NVODM_PORT('c'), 1, NvOdmGpioPinActiveState_Low} // DBG_IRQ
+};
+
+static const NvOdmGpioPinInfo s_Bluetooth[] = {
+ {NVODM_PORT('u'), 0, NvOdmGpioPinActiveState_Low} // BT_RST#
+};
+
+static const NvOdmGpioPinInfo s_Wlan[] = {
+ {NVODM_PORT('k'), 5, NvOdmGpioPinActiveState_Low}, // WF_PWDN#
+ {NVODM_PORT('k'), 6, NvOdmGpioPinActiveState_Low} // WF_RST#
+};
+
+static const NvOdmGpioPinInfo s_Power[] = {
+ // lid open/close, High = Lid Closed
+ {NVODM_PORT('u'), 5, NvOdmGpioPinActiveState_High},
+ // power button
+ {NVODM_PORT('v'), 2, NvOdmGpioPinActiveState_Low}
+};
+
+static const NvOdmGpioPinInfo s_WakeFromKeyBoard[] = {
+ {NVODM_PORT('a'), 0, NvOdmGpioPinActiveState_Low} // EC Keyboard Wakeup
+};
+
+static const NvOdmGpioPinInfo s_Battery[] = {
+ // Low Battery
+ {NVODM_PORT('w'), 3, NvOdmGpioPinActiveState_Low},
+};
+
+const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
+ NvU32 Instance, NvU32 *pCount)
+{
+ switch (Group)
+ {
+ case NvOdmGpioPinGroup_Display:
+ *pCount = NVODM_ARRAY_SIZE(s_display);
+ return s_display;
+
+ case NvOdmGpioPinGroup_Hdmi:
+ *pCount = NVODM_ARRAY_SIZE(s_hdmi);
+ return s_hdmi;
+
+ case NvOdmGpioPinGroup_Crt:
+ *pCount = NVODM_ARRAY_SIZE(s_crt);
+ return s_crt;
+
+ case NvOdmGpioPinGroup_Sdio:
+ if (Instance == 1)
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_sdio);
+ return s_sdio;
+ }
+ else if (Instance == 3)
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_sdio3);
+ return s_sdio3;
+ }
+ else
+ {
+ *pCount = 0;
+ return NULL;
+ }
+
+ case NvOdmGpioPinGroup_NandFlash:
+ *pCount = NVODM_ARRAY_SIZE(s_NandFlash);
+ return s_NandFlash;
+
+ case NvOdmGpioPinGroup_Bluetooth:
+ *pCount = NVODM_ARRAY_SIZE(s_Bluetooth);
+ return s_Bluetooth;
+
+ case NvOdmGpioPinGroup_Wlan:
+ *pCount = NVODM_ARRAY_SIZE(s_Wlan);
+ return s_Wlan;
+
+ case NvOdmGpioPinGroup_SpiEthernet:
+ if (NvOdmQueryDownloadTransport() ==
+ NvOdmDownloadTransport_SpiEthernet)
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_spi_ethernet);
+ return s_spi_ethernet;
+ }
+ else
+ {
+ *pCount = 0;
+ return NULL;
+ }
+
+ case NvOdmGpioPinGroup_Vi:
+ *pCount = NVODM_ARRAY_SIZE(s_vi);
+ return s_vi;
+
+ case NvOdmGpioPinGroup_Power:
+ *pCount = NVODM_ARRAY_SIZE(s_Power);
+ return s_Power;
+
+ case NvOdmGpioPinGroup_WakeFromECKeyboard:
+ *pCount = NVODM_ARRAY_SIZE(s_WakeFromKeyBoard);
+ return s_WakeFromKeyBoard;
+
+ case NvOdmGpioPinGroup_Battery:
+ *pCount = NVODM_ARRAY_SIZE(s_Battery);
+ return s_Battery;
+
+ default:
+ *pCount = 0;
+ return NULL;
+ }
+}
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c
new file mode 100644
index 000000000000..951fc9730f41
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>NVIDIA Driver Development Kit:
+ * ODM Kbc interface</b>
+ *
+ */
+
+#include "nvodm_query_kbc.h"
+#include "nvodm_query_kbc_gpio_def.h"
+#include "nvodm_query_kbc_qwerty_def.h"
+
+static NvU32 RowNumbers[] = {1, 15};
+static NvU32 ColNumbers[] = {7, 0};
+
+void
+NvOdmKbcGetParameter(
+ NvOdmKbcParameter Param,
+ NvU32 SizeOfValue,
+ void * pValue)
+{
+ NvU32 *pTempVar;
+ switch (Param)
+ {
+ case NvOdmKbcParameter_DebounceTime:
+ pTempVar = (NvU32 *)pValue;
+ *pTempVar = 2;
+ break;
+ case NvOdmKbcParameter_RepeatCycleTime:
+ pTempVar = (NvU32 *)pValue;
+ *pTempVar = 5;
+ break;
+ default:
+ break;
+ }
+}
+
+NvU32
+NvOdmKbcGetKeyCode(
+ NvU32 Row,
+ NvU32 Column,
+ NvU32 RowCount,
+ NvU32 ColumnCount)
+{
+ NvU32 CodeData;
+ if (Row < KBC_QWERTY_FUNCTION_KEY_ROW_BASE)
+ {
+ CodeData = KBC_QWERTY_NORMAL_KEY_CODE_BASE + ((Row * ColumnCount) + Column);
+ }
+ else
+ {
+ CodeData = KBC_QWERTY_FUNCTION_KEY_CODE_BASE +
+ (((Row - KBC_QWERTY_FUNCTION_KEY_ROW_BASE) * ColumnCount) + Column);
+ }
+ return CodeData;
+}
+
+NvBool
+NvOdmKbcIsSelectKeysWkUpEnabled(
+ NvU32 **pRowNumber,
+ NvU32 **pColNumber,
+ NvU32 *NumOfKeys)
+{
+ *pRowNumber = &RowNumbers[0];
+ *pColNumber = &ColNumbers[0];
+ *NumOfKeys = 2;
+ return NV_TRUE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h
new file mode 100644
index 000000000000..2e625eb6217d
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * The KBC GPIO pin definitions</b>
+ *
+ * @b Description: Define the KBC GPIO pins in row and column numbers.
+ */
+
+#ifndef NVODM_QUERY_KBC_GPIO_DEF_H
+#define NVODM_QUERY_KBC_GPIO_DEF_H
+
+typedef enum
+{
+ NvOdmKbcGpioPin_KBRow0 = 0,
+ NvOdmKbcGpioPin_KBRow1,
+ NvOdmKbcGpioPin_KBRow2,
+ NvOdmKbcGpioPin_KBRow3,
+ NvOdmKbcGpioPin_KBRow4,
+ NvOdmKbcGpioPin_KBRow5,
+ NvOdmKbcGpioPin_KBRow6,
+ NvOdmKbcGpioPin_KBRow7,
+ NvOdmKbcGpioPin_KBRow8,
+ NvOdmKbcGpioPin_KBRow9,
+ NvOdmKbcGpioPin_KBRow10,
+ NvOdmKbcGpioPin_KBRow11,
+ NvOdmKbcGpioPin_KBRow12,
+ NvOdmKbcGpioPin_KBRow13,
+ NvOdmKbcGpioPin_KBRow14,
+ NvOdmKbcGpioPin_KBRow15,
+ NvOdmKbcGpioPin_KBCol0,
+ NvOdmKbcGpioPin_KBCol1,
+ NvOdmKbcGpioPin_KBCol2,
+ NvOdmKbcGpioPin_KBCol3,
+ NvOdmKbcGpioPin_KBCol4,
+ NvOdmKbcGpioPin_KBCol5,
+ NvOdmKbcGpioPin_KBCol6,
+ NvOdmKbcGpioPin_KBCol7,
+ NvOdmKbcGpioPin_Num,
+ NvOdmKbcGpioPin_Force32 = 0x7FFFFFFF
+}NvOdmKbcGpioPin;
+
+#endif // NVODM_QUERY_KBC_GPIO_DEF_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h
new file mode 100644
index 000000000000..c5c82bb5df35
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * The KBC qwerty property definitions</b>
+ *
+ * @b Description: Define the qwerty keyboard support definitions which is used
+ * by multiple functions.
+ */
+
+#ifndef NVODM_QUERY_KBC_QWERTY_DEF_H
+#define NVODM_QUERY_KBC_QWERTY_DEF_H
+
+#define KBC_QWERTY_NORMAL_KEY_CODE_BASE 0x1000
+#define KBC_QWERTY_FUNCTION_KEY_CODE_BASE 0x2000
+
+#define KBC_QWERTY_FUNCTION_KEY_ROW_BASE 0x100
+#define KBC_QWERTY_FUNCTION_KEY_ROW_NUMBER 0
+#define KBC_QWERTY_FUNCTION_KEY_COLUMN_NUMBER 7
+
+
+#endif // NVODM_QUERY_KBC_QWERTY_DEF_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c
new file mode 100644
index 000000000000..18a2c903cbb4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>NVIDIA Driver Development Kit:
+ * ODM Uart interface</b>
+ *
+ * @b Description: Implements the ODM for the Uart communication.
+ *
+ */
+
+#include "nvodm_query_nand.h"
+#include "nvcommon.h"
+
+// fill params for all required nand flashes here.
+// this list will end when vendor id and chipd id will be zero.
+// hence, all supported chips should be listed before that.
+NvOdmNandFlashParams g_Params[] =
+{
+ /*
+ {
+ VendorId, DeviceId, NandType, IsCopyBackCommandSupported, IsCacheWriteSupported, CapacityInMB, ZonesPerDevice,
+ BlocksPerZone, OperationSuccessStatus, InterleaveCapability, EccAlgorithm,
+ ErrorsCorrectable, SkippedSpareBytes,
+ TRP, TRH (TREH), TWP, TWH, TCS, TWHR, TWB, TREA, TADL,
+ TCLS, TCLH, TCH, TALS, TALH, TRC, TWC, TCR(TCLR), TAR, TRR, NandDeviceType, ReadIdFourthByte
+ }
+ Note :
+ TADL values for flashes K9F1G08Q0M, K9F1G08U0M, TH58NVG4D4CTG00,
+ TH58NVG3D4BTG00, TH58NVG2S3BFT00 is not available from their data sheets.
+ Hence TADL is computed as
+ tADL = (tALH + tALS + tWP).
+ */
+ // filling odm parameter structure for Samsung K9K8G08U0M
+ {
+ 0xEC, 0xD3, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 1024, 4,
+ 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 20, 60, 100, 26, 70,
+ 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x95
+ },
+ // filling odm parameter structure for Samsung K9GAG08U0D
+ {
+ 0xEC, 0xD5, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 2048, 2,
+ 2048, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Eight, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 20, 60, 100, 20, 100,
+ 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type2, 0x29
+ },
+ // filling odm parameter structure for Samsung K9W8G08U1M
+ {
+ 0xEC, 0xDC, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 1024, 2,
+ 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 15, 60, 100, 18, 100,
+ 10, 5, 5, 10, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // filling odm parameter structure for Samsung K9F1G08Q0M
+ {
+ 0xEC, 0xA1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1,
+ 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 60, 20, 60, 20, 0, 60, 100, 60, 70,
+ 0, 10, 10, 0, 10, 80, 80, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // filling odm parameter structure for Samsung K9F1G08U0M
+ {
+ 0xEC, 0xF1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 15, 25, 15, 0, 60, 100, 30, 35,
+ 0, 10, 10, 0, 10, 50, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // filling odm parameter structure for Samsung K9L8G08U0M
+ {
+ 0xEC, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 1024, 4,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 20, 60, 100, 20, 35,
+ 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Samsung K9G4G08U0M
+ {
+ 0xEC, 0xDC, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 512, 2,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 15, 15, 60, 100, 18, 50,
+ 10, 5, 5, 10, 5, 30, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Samsung K5E2G1GACM
+ {
+ 0xEC, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 2,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 21, 15, 21, 15, 31, 60, 100, 30, 100,
+ 21, 5, 5, 21, 5, 42, 42, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+/*
+ // filling odm parameter structure for Toshiba TH58NVG4D4CTG00
+ {
+ 0x98, 0xD5, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 2048, 1,
+ 8192, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 41, 15, 15, 10, 0, 30, 20, 200, 41, 21,
+ 0, 6, 6, 0, 6, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Toshiba TH58NVG3D4BTG00
+ {
+ 0x98, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_TRUE, 1024, 1,
+ 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 41, 15, 15, 10, 0, 30, 20, 200, 41, 35,
+ 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Toshiba TH58NVG2S3BFT00
+ {
+ 0x98, 0xDC, NvOdmNandFlashType_Slc, NV_FALSE, NV_FALSE, 512, 1,
+ 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 41, 15, 15, 10, 0, 30, 20, 200, 41, 35,
+ 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25
+ },
+*/
+ // filling odm parameter structure for Samsung K9LBG08U0M
+ {
+ 0xEC, 0xD7, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 4096, 4, 2048,
+ 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Six, NvOdmNandSkipSpareBytes_4,
+ 12, 10, 12, 10, 20, 60, 100, 20, 100,
+ 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0xB6
+ },
+ //Hynix H8BES0UQ0MCP
+ {
+ 0xAD, 0xBC, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 512, 2, 2048,
+ 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 10, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x55
+ },
+ //Hynix H8BCS0SJ0MCP
+ {
+ 0xAD, 0xBA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048,
+ 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 15, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x55
+ },
+
+ //Hynix H8BCS0RJ0MCP
+ {
+ 0xAD, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048,
+ 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 10, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15
+ },
+ /*Numonyx MCP - NAND02GR3B2D*/
+ {
+ 0x20, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1,
+ 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 15, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // Hynix HY27UF084G2B (readid 4th byte 0x95)
+ {
+ 0xAD, 0xDC, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 512, 2,
+ 2048, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 12, 10, 12, 10, 20, 80, 100, 20, 70,
+ 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x95
+ },
+ /* "This is the end of device list please do not modify this. To add support for more flash parts,
+ add device category for those parts before this element"*/
+ {
+ 0, 0, NvOdmNandFlashType_UnKnown, NV_FALSE, NV_FALSE, 0, 0,
+ 0, 0, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NvOdmNandDeviceType_Type1, 0
+ }
+};
+
+NvOdmNandFlashParams *NvOdmNandGetFlashInfo (NvU32 ReadID)
+{
+ NvU8 TempValue;
+ NvU8 VendorId = 0;
+ NvU8 DeviceId = 0;
+ NvU8 ReadIdFourthByte = 0;
+ NvOdmNandFlashType NandType;
+ NvU8 i = 0;
+ // To extract Vendor Id
+ VendorId = (NvU8) (ReadID & 0xFF);
+ // To extract Device Id
+ DeviceId = (NvU8) ((ReadID >> DEVICE_SHIFT) & 0xFF);
+ // To extract Fourth ID byte of Read ID - for checking if the flash is 42nm.
+ ReadIdFourthByte = (NvU8) ((ReadID >> FOURTH_ID_SHIFT) & 0xFF);
+ // To extract device Type Mask
+ TempValue = (NvU8) ((ReadID >> FLASH_TYPE_SHIFT) & 0xC);
+ if (TempValue)
+ {
+ NandType = NvOdmNandFlashType_Mlc;
+ }
+ else
+ {
+ NandType = NvOdmNandFlashType_Slc;
+ }
+ // following ORing is done to check if we reached the end of the list.
+ while ((g_Params[i].VendorId) | (g_Params[i].DeviceId))
+ {
+ if ((g_Params[i].VendorId == VendorId) &&
+ (g_Params[i].DeviceId == DeviceId) &&
+ (g_Params[i].ReadIdFourthByte == ReadIdFourthByte) &&
+ (g_Params[i].NandType == NandType))
+ {
+ return &g_Params[i];
+ }
+ else
+ i++;
+ }
+ // This condition will be reached if "g_Params" is not having Parameters of the flash used.
+ // Hence add the parameters required in the table.
+ return NULL;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c
new file mode 100644
index 000000000000..e8ec4b70b3dc
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * This file implements the pin-mux configuration tables for each I/O module.
+ */
+
+// THESE SETTINGS ARE PLATFORM-SPECIFIC (not SOC-specific).
+// PLATFORM = Harmony
+
+#include "nvodm_query_pinmux.h"
+#include "nvassert.h"
+#include "nvodm_query.h"
+#include "nvodm_services.h"
+
+#define NVODM_PINMUX_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+static const NvU32 s_NvOdmPinMuxConfig_Uart[] = {
+ NvOdmUartPinMap_Config4, // UART1, 2 lines
+ NvOdmUartPinMap_Config2, // UART2, 2 lines
+ NvOdmUartPinMap_Config1, // UART3, 4 lines
+ NvOdmUartPinMap_Config2, // UART4, 4 lines
+ 0 // UART5
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Spi[] = {
+ NvOdmSpiPinMap_Config4,
+ 0,
+ 0,
+ 0,
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Twc[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_I2c[] = {
+ NvOdmI2cPinMap_Config1,
+ NvOdmI2cPinMap_Config1,
+ NvOdmI2cPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_I2cPmu[] = {
+ NvOdmI2cPmuPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Ulpi[] = {
+ NvOdmUlpiPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Sdio[] = {
+ NvOdmSdioPinMap_Config1,
+ NvOdmSdioPinMap_Config5,
+ 0,
+ NvOdmSdioPinMap_Config2
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Spdif[] = {
+ NvOdmSpdifPinMap_Config2
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Hsi[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Hdcp[] = {
+ NvOdmHdcpPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Hdmi[] = {
+ NvOdmHdmiPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Pwm[] = {
+ NvOdmPwmPinMap_Config6
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Ata[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Nand[] = {
+ NvOdmNandPinMap_Config4,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Dap[] = {
+ NvOdmDapPinMap_Config1,
+ NvOdmDapPinMap_Config1,
+ 0,
+ NvOdmDapPinMap_Config1,
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Kbd[] = {
+ NvOdmKbdPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_SyncNor[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Mio[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_ExternalClock[] = {
+ NvOdmExternalClockPinMap_Config2,
+ NvOdmExternalClockPinMap_Config3,
+ NvOdmExternalClockPinMap_Config1
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_VideoInput[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Display[] = {
+ NvOdmDisplayPinMap_Config1,
+ 0 // Only 1 display is connected to the LCD pins
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_BacklightPwm[] = {
+ 0,
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Crt[] = {
+ NvOdmCrtPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Tvo[] = {
+ NvOdmTvoPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_OneWire[] = {
+ 0
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_PciExpress[] = {
+ NvOdmPciExpressPinMap_Config1,
+};
+
+void
+NvOdmQueryPinMux(
+ NvOdmIoModule IoModule,
+ const NvU32 **pPinMuxConfigTable,
+ NvU32 *pCount)
+{
+ switch (IoModule)
+ {
+ case NvOdmIoModule_Display:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Display;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Display);
+ break;
+
+ case NvOdmIoModule_Dap:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Dap;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Dap);
+ break;
+
+ case NvOdmIoModule_Hdcp:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdcp;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdcp);
+ break;
+
+ case NvOdmIoModule_Hdmi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdmi;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdmi);
+ break;
+
+ case NvOdmIoModule_I2c:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2c;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2c);
+ break;
+
+ case NvOdmIoModule_I2c_Pmu:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2cPmu;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2cPmu);
+ break;
+
+ case NvOdmIoModule_Nand:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Nand;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Nand);
+ break;
+
+ case NvOdmIoModule_Sdio:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Sdio;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Sdio);
+ break;
+
+ case NvOdmIoModule_Spi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spi;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spi);
+ break;
+
+ case NvOdmIoModule_Uart:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Uart;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Uart);
+ break;
+
+ case NvOdmIoModule_ExternalClock:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_ExternalClock;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_ExternalClock);
+ break;
+
+ case NvOdmIoModule_Crt:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Crt;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Crt);
+ break;
+
+ case NvOdmIoModule_PciExpress:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_PciExpress;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_PciExpress);
+ break;
+
+ case NvOdmIoModule_Tvo:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Tvo;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Tvo);
+ break;
+ case NvOdmIoModule_BacklightPwm:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_BacklightPwm;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_BacklightPwm);
+ break;
+
+ case NvOdmIoModule_Pwm:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Pwm;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Pwm);
+ break;
+
+ case NvOdmIoModule_Ulpi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ulpi;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ulpi);
+ break;
+
+ case NvOdmIoModule_Spdif:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spdif;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spdif);
+ break;
+
+ case NvOdmIoModule_Kbd:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Kbd;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Kbd);
+ break;
+
+ case NvOdmIoModule_Twc:
+ case NvOdmIoModule_Hsi:
+ case NvOdmIoModule_Ata:
+ case NvOdmIoModule_SyncNor:
+ case NvOdmIoModule_Mio:
+ case NvOdmIoModule_VideoInput:
+ case NvOdmIoModule_OneWire:
+ *pPinMuxConfigTable = NULL;
+ *pCount = 0;
+ break;
+
+ default:
+ *pCount = 0;
+ break;
+ }
+}
+
+void
+NvOdmQueryClockLimits(
+ NvOdmIoModule IoModule,
+ const NvU32 **pClockSpeedLimits,
+ NvU32 *pCount)
+{
+ switch (IoModule)
+ {
+ default:
+ *pClockSpeedLimits = NULL;
+ *pCount = 0;
+ break;
+ }
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h
new file mode 100644
index 000000000000..000fd861577e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity database NvOdmIoAddress entries
+ * for the peripherals on E1162 module.
+ */
+
+#include "pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h"
+#include "tmon/adt7461/nvodm_tmon_adt7461_channel.h"
+#include "nvodm_tmon.h"
+#include "../nvodm_query_kbc_gpio_def.h"
+
+
+// RTC voltage rail
+static const NvOdmIoAddress s_RtcAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO2 } /* VDD_RTC -> LD02 */
+};
+
+// Core voltage rail
+static const NvOdmIoAddress s_CoreAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_DCD0 } /* VDD_CORE -> SM0 */
+};
+
+// CPU voltage rail
+static const NvOdmIoAddress s_ffaCpuAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_DCD1 } /* VDD_CPU -> SM1 */
+};
+
+// PLLA voltage rail
+static const NvOdmIoAddress s_PllAAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */
+};
+
+// PLLM voltage rail
+static const NvOdmIoAddress s_PllMAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */
+};
+
+// PLLP voltage rail
+static const NvOdmIoAddress s_PllPAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */
+};
+
+// PLLC voltage rail
+static const NvOdmIoAddress s_PllCAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */
+};
+
+// PLLE voltage rail
+static const NvOdmIoAddress s_PllEAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS62290PmuSupply_BUCK } /* AVDD_PLLE -> VDD_1V05 */
+};
+
+// PLLU voltage rail
+static const NvOdmIoAddress s_PllUAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDD_PLLU -> LDO1 */
+};
+
+// PLLU1 voltage rail
+static const NvOdmIoAddress s_ffaPllU1Addresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDD_PLLU -> LDO1 */
+};
+
+// PLLS voltage rail
+static const NvOdmIoAddress s_PllSAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* PLL_S -> LDO1 */
+};
+
+// PLLHD voltage rail
+static const NvOdmIoAddress s_PllHdmiAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO8 } /* AVDD_HDMI_PLL -> LDO8 */
+};
+
+// OSC voltage rail
+static const NvOdmIoAddress s_VddOscAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* AVDD_OSC -> LDO4 */
+};
+
+// PLLX voltage rail
+static const NvOdmIoAddress s_PllXAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX -> LDO1 */
+};
+
+// PLL_USB voltage rail
+static const NvOdmIoAddress s_PllUsbAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* AVDD_USB_PLL -> derived from LDO3 (VDD_3V3) */
+};
+
+// SYS IO voltage rail
+static const NvOdmIoAddress s_VddSysAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_SYS -> LDO4 */
+};
+
+// USB voltage rail
+static const NvOdmIoAddress s_VddUsbAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* AVDD_USB -> derived from LDO3 (VDD_3V3) */
+};
+
+// HDMI voltage rail
+static const NvOdmIoAddress s_VddHdmiAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO7 } /* AVDD_HDMI -> LDO7 */
+};
+
+// MIPI voltage rail (DSI_CSI)
+static const NvOdmIoAddress s_VddMipiAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS72012PmuSupply_LDO } /* AVDD_DSI_CSI -> VDD_1V2 */
+};
+
+// LCD voltage rail
+static const NvOdmIoAddress s_VddLcdAddresses[] =
+{
+ // This is in the AON domain
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_LCD -> (LDO4PG) */
+};
+
+// Audio voltage rail
+static const NvOdmIoAddress s_VddAudAddresses[] =
+{
+ // This is in the AON domain
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_AUDIO -> (LDO4PG) */
+};
+
+// DDR voltage rail
+static const NvOdmIoAddress s_VddDdrAddresses[] =
+{
+ // This is in the AON domain
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_DDR -> (LDO4PG) */
+};
+
+// DDR_RX voltage rail
+static const NvOdmIoAddress s_VddDdrRxAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO9 } /* VDDIO_RX_DDR(2.7-3.3) -> LDO9 */
+};
+
+// NAND voltage rail
+static const NvOdmIoAddress s_VddNandAddresses[] =
+{
+ // This is in the AON domain
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_NAND_3V3 -> derived from LDO3 (VDD_3V3) */
+};
+
+// UART voltage rail
+static const NvOdmIoAddress s_VddUartAddresses[] =
+{
+ // This is in the AON domain
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_UART -> (LDO4PG) */
+};
+
+// SDIO voltage rail
+static const NvOdmIoAddress s_VddSdioAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_SDIO -> derived from LDO3 (VDD_3V3) */
+};
+
+// VDAC voltage rail
+static const NvOdmIoAddress s_VddVdacAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO6 } /* AVDD_VDAC -> LDO6 */
+};
+
+// VI voltage rail
+static const NvOdmIoAddress s_VddViAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_VI -> derived from LDO3 (VDD_3V3) */
+};
+
+// BB voltage rail
+static const NvOdmIoAddress s_VddBbAddresses[] =
+{
+ // This is in the AON domain
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_BB -> (LDO4PG) */
+};
+
+// Super power voltage rail for the SOC
+static const NvOdmIoAddress s_VddSocAddresses[]=
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_SoC } /* VDD SOC */
+};
+
+// PEX_CLK voltage rail
+static const NvOdmIoAddress s_VddPexClkAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO0 }, /* VDDIO_PEX_CLK -> LDO0 */
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS62290PmuSupply_BUCK }, /* AVDD_PLLE -> VDD_1V05 */
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS74201PmuSupply_LDO }, /* PMU_GPIO-1 -> VDD_1V5 */
+};
+
+// PMU0
+static const NvOdmIoAddress s_Pmu0Addresses[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x68 },
+};
+
+// SPI1 for Spi Ethernet Kitl only
+static const NvOdmIoAddress s_SpiEthernetAddresses[] =
+{
+ { NvOdmIoModule_Spi, 0, 0 },
+ { NvOdmIoModule_Gpio, (NvU32)'c'-'a', 1 }, // DBQ_IRQ, Port C, Pin 1
+};
+
+// P1160 ULPI USB
+static const NvOdmIoAddress s_UlpiUsbAddresses[] =
+{
+ { NvOdmIoModule_ExternalClock, 1, 0 }, /* ULPI PHY Clock -> DAP_MCLK2 */
+};
+
+// LVDS LCD Display
+static const NvOdmIoAddress s_LvdsDisplayAddresses[] =
+{
+ { NvOdmIoModule_Display, 0, 0 },
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4}, /* VDDIO_LCD (AON:VDD_1V8) */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 }, /* VDD_LVDS (VDD_3V3) */
+};
+
+// HDMI addresses based on Concorde 2 design
+static const NvOdmIoAddress s_HdmiAddresses[] =
+{
+ { NvOdmIoModule_Hdmi, 0, 0 },
+
+ // Display Data Channel (DDC) for Extended Display Identification
+ // Data (EDID)
+ { NvOdmIoModule_I2c, 0x01, 0xA0 },
+
+ // HDCP ROM
+ { NvOdmIoModule_I2c, 0x01, 0x74 },
+
+ /* AVDD_HDMI */
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS2051BPmuSupply_VDDIO_VID }, // VDDIO_HDMI
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO8 }, // AVDD_HDMI_PLL
+
+ /* lcd i/o rail (for hot plug pin) */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 }, // VDDIO_LCD (VDD_1V8)
+};
+
+// CRT address based on Concorde 2 design
+static const NvOdmIoAddress s_CrtAddresses[] =
+{
+ { NvOdmIoModule_Crt, 0, 0 },
+
+ // Display Data Channel (DDC) for Extended Display Identification
+ // Data (EDID)
+ // FIXME: Disable this for now since it causes some TV not display.
+ { NvOdmIoModule_I2c, 0x01, 0xA0 },
+
+ /* tvdac rail */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO6 }, // VDDIO_VDAC
+
+ /* lcd rail (required for crt out) */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 }, // VDDIO_LCD (VDD_1V8)
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS2051BPmuSupply_VDDIO_VID }, // VDDIO_VGA
+};
+
+static const NvOdmIoAddress s_ffaVideoDacAddresses[] =
+{
+ { NvOdmIoModule_Tvo, 0x00, 0x00 },
+ /* tvdac rail */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO6 }, // AVDD_VDAC
+};
+
+// Sdio
+static const NvOdmIoAddress s_SdioAddresses[] =
+{
+ { NvOdmIoModule_Sdio, 0x1, 0x0 }, /* SD Memory on SD Bus */
+ { NvOdmIoModule_Sdio, 0x3, 0x0 }, /* SD Memory on SD Bus */
+ { NvOdmIoModule_Vdd, 0x00, Ext_SWITCHPmuSupply_VDDIO_SD }, /* EN_VDDIO_SD */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_SDIO -> derived from LDO3 (VDD_3V3) */
+};
+
+static const NvOdmIoAddress s_I2cSmbusAddresses[] =
+{
+ { NvOdmIoModule_I2c, 2, 0x8A },
+ { NvOdmIoModule_Gpio, 27, 1} //Port BB:01 is used on harmony.
+};
+
+static const NvOdmIoAddress s_UsbMuxAddress[] =
+{
+ {NvOdmIoModule_Usb, 1, 0}
+};
+
+static const NvOdmIoAddress s_QwertyKeyPad16x8Addresses[] =
+{
+ // instance = 1 indicates Column info.
+ // instance = 0 indicates Row info.
+ // address holds KBC pin number used for row/column.
+
+ // All Row info has to be defined contiguously from 0 to max.
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow0}, // Row 0
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow1}, // Row 1
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow2}, // Row 2
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow3}, // Row 3
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow4}, // Row 4
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow5}, // Row 5
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow6}, // Row 6
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow7}, // Row 7
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow8}, // Row 8
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow9}, // Row 9
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow10}, // Row 10
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow11}, // Row 11
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow12}, // Row 12
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow13}, // Row 13
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow14}, // Row 14
+ { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow15}, // Row 15
+
+ // All Column info has to be defined contiguously from 0 to max.
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol0}, // Column 0
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol1}, // Column 1
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol2}, // Column 2
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol3}, // Column 3
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol4}, // Column 4
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol5}, // Column 5
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol6}, // Column 6
+ { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol7}, // Column 7
+};
+
+
+static const NvOdmIoAddress s_Tmon0Addresses[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x98 }, /* I2C bus */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 }, /* TMON pwer rail -> LDO3 (VDD_3V3) */
+ { NvOdmIoModule_Gpio, (NvU32)'n'-'a', 6 }, /* GPIO Port N and Pin 6 */
+
+ /* Temperature zone mapping */
+ { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Core, ADT7461ChannelID_Remote }, /* TSENSOR */
+ { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Ambient, ADT7461ChannelID_Local }, /* TSENSOR */
+};
+
+// Bluetooth
+static const NvOdmIoAddress s_p1162BluetoothAddresses[] =
+{
+ { NvOdmIoModule_Uart, 0x2, 0x0 }, // FIXME: Is this used?
+ { NvOdmIoModule_Gpio, (NvU32)'u'-'a', 0 }, /* BT_RST#: GPIO Port U and Pin 0 */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDHOSTIF_BT -> LDO4 (AON:VDD_1V8) */
+};
+
+// Wlan
+static const NvOdmIoAddress s_WlanAddresses[] =
+{
+ { NvOdmIoModule_Sdio, 0x0, 0x0 }, /* WLAN is on SD Bus */
+ { NvOdmIoModule_Gpio, 0xa, 0x5 }, /* GPIO Port K and Pin 5 - WIFI_PWR*/
+ { NvOdmIoModule_Gpio, 0xa, 0x6 }, /* GPIO Port K and Pin 6 - WIFI_RST */
+ { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 }, /* VDDIO_WLAN (AON:VDD_1V8) */
+ { NvOdmIoModule_Vdd, 0x00, Ext_TPS72012PmuSupply_LDO } /* VCORE_WIFI (VDD_1V2) */
+};
+
+// Audio Codec
+static const NvOdmIoAddress s_AudioCodecAddresses[] =
+{
+ { NvOdmIoModule_ExternalClock, 0, 0 }, /* Codec MCLK -> APxx DAP_MCLK1 */
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x34 }, /* Codec I2C -> APxx PMU I2C, segment 0 */
+ /* Codec I2C address is 0x34 */
+};
+
+// Audio Codec on GEN1_I2C (I2C_1)
+static const NvOdmIoAddress s_AudioCodecAddressesI2C_1[] =
+{
+ { NvOdmIoModule_ExternalClock, 0, 0 }, /* Codec MCLK -> APxx DAP_MCLK1 */
+ { NvOdmIoModule_I2c, 0x00, 0x34 }, /* Codec I2C -> APxx PMU I2C, segment 0 */
+ /* Codec I2C address is 0x34 */
+};
+
+// TouchPanel
+static const NvOdmIoAddress s_TouchPanelAddresses[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x06 }, /* I2C address (7-bit) 0x03<<1=0x06(8-bit) */
+ { NvOdmIoModule_Gpio, (NvU32)'d'-'a', 0x02 }, /* GPIO Port D and Pin 2 */
+};
+
+static const NvOdmIoAddress s_AcceleroAddresses[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x70 }, /* I2C address (7-bit) 0x38<<1 = 0x70(8-bit) */
+ { NvOdmIoModule_Gpio, (NvU32)'c'-'a', 0x03 }, /* Gpio port C and Pin 3 */
+};
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h
new file mode 100644
index 000000000000..df91cc1e6d22
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h
@@ -0,0 +1,453 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity database Peripheral entries
+ * for the peripherals on P1162 module.
+ */
+// AP20 doesn't have PLL_D rail.
+// PLLD (NV reserved) / Use PLL_U
+{
+ NV_VDD_PLLD_ODM_ID,
+ s_PllUAddresses,
+ NV_ARRAY_SIZE(s_PllUAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// RTC (NV reserved)
+{
+ NV_VDD_RTC_ODM_ID,
+ s_RtcAddresses,
+ NV_ARRAY_SIZE(s_RtcAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// CORE (NV reserved)
+{
+ NV_VDD_CORE_ODM_ID,
+ s_CoreAddresses,
+ NV_ARRAY_SIZE(s_CoreAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// CPU (NV reserved)
+{
+ NV_VDD_CPU_ODM_ID,
+ s_ffaCpuAddresses,
+ NV_ARRAY_SIZE(s_ffaCpuAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLA (NV reserved)
+{
+ NV_VDD_PLLA_ODM_ID,
+ s_PllAAddresses,
+ NV_ARRAY_SIZE(s_PllAAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLM (NV reserved)
+{
+ NV_VDD_PLLM_ODM_ID,
+ s_PllMAddresses,
+ NV_ARRAY_SIZE(s_PllMAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLP (NV reserved)
+{
+ NV_VDD_PLLP_ODM_ID,
+ s_PllPAddresses,
+ NV_ARRAY_SIZE(s_PllPAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLC (NV reserved)
+{
+ NV_VDD_PLLC_ODM_ID,
+ s_PllCAddresses,
+ NV_ARRAY_SIZE(s_PllCAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLE (NV reserved)
+{
+ NV_VDD_PLLE_ODM_ID,
+ s_PllEAddresses,
+ NV_ARRAY_SIZE(s_PllEAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLU (NV reserved)
+{
+ NV_VDD_PLLU_ODM_ID,
+ s_PllUAddresses,
+ NV_ARRAY_SIZE(s_PllUAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLU1 (NV reserved)
+{
+ NV_VDD_PLLU1_ODM_ID,
+ s_ffaPllU1Addresses,
+ NV_ARRAY_SIZE(s_ffaPllU1Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLS (NV reserved)
+{
+ NV_VDD_PLLS_ODM_ID,
+ s_PllSAddresses,
+ NV_ARRAY_SIZE(s_PllSAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// HDMI PLL (NV reserved)
+{
+ NV_VDD_PLLHDMI_ODM_ID,
+ s_PllHdmiAddresses,
+ NV_ARRAY_SIZE(s_PllHdmiAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// OSC VDD (NV reserved)
+{
+ NV_VDD_OSC_ODM_ID,
+ s_VddOscAddresses,
+ NV_ARRAY_SIZE(s_VddOscAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLX (NV reserved)
+{
+ NV_VDD_PLLX_ODM_ID,
+ s_PllXAddresses,
+ NV_ARRAY_SIZE(s_PllXAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLL_USB (NV reserved)
+{
+ NV_VDD_PLL_USB_ODM_ID,
+ s_PllUsbAddresses,
+ NV_ARRAY_SIZE(s_PllUsbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// System IO VDD (NV reserved)
+{
+ NV_VDD_SYS_ODM_ID,
+ s_VddSysAddresses,
+ NV_ARRAY_SIZE(s_VddSysAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// USB VDD (NV reserved)
+{
+ NV_VDD_USB_ODM_ID,
+ s_VddUsbAddresses,
+ NV_ARRAY_SIZE(s_VddUsbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// HDMI VDD (NV reserved)
+{
+ NV_VDD_HDMI_ODM_ID,
+ s_VddHdmiAddresses,
+ NV_ARRAY_SIZE(s_VddHdmiAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// MIPI VDD (NV reserved) / AVDD_DSI_CSI
+{
+ NV_VDD_MIPI_ODM_ID,
+ s_VddMipiAddresses,
+ NV_ARRAY_SIZE(s_VddMipiAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// LCD VDD (NV reserved)
+{
+ NV_VDD_LCD_ODM_ID,
+ s_VddLcdAddresses,
+ NV_ARRAY_SIZE(s_VddLcdAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// AUDIO VDD (NV reserved)
+{
+ NV_VDD_AUD_ODM_ID,
+ s_VddAudAddresses,
+ NV_ARRAY_SIZE(s_VddAudAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// DDR VDD (NV reserved)
+{
+ NV_VDD_DDR_ODM_ID,
+ s_VddDdrAddresses,
+ NV_ARRAY_SIZE(s_VddDdrAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// DDR_RX (NV reserved)
+{
+ NV_VDD_DDR_RX_ODM_ID,
+ s_VddDdrRxAddresses,
+ NV_ARRAY_SIZE(s_VddDdrRxAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// NAND VDD (NV reserved)
+{
+ NV_VDD_NAND_ODM_ID,
+ s_VddNandAddresses,
+ NV_ARRAY_SIZE(s_VddNandAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// UART VDD (NV reserved)
+{
+ NV_VDD_UART_ODM_ID,
+ s_VddUartAddresses,
+ NV_ARRAY_SIZE(s_VddUartAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// SDIO VDD (NV reserved)
+{
+ NV_VDD_SDIO_ODM_ID,
+ s_VddSdioAddresses,
+ NV_ARRAY_SIZE(s_VddSdioAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// VDAC VDD (NV reserved)
+{
+ NV_VDD_VDAC_ODM_ID,
+ s_VddVdacAddresses,
+ NV_ARRAY_SIZE(s_VddVdacAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// VI VDD (NV reserved)
+{
+ NV_VDD_VI_ODM_ID,
+ s_VddViAddresses,
+ NV_ARRAY_SIZE(s_VddViAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// BB VDD (NV reserved)
+{
+ NV_VDD_BB_ODM_ID,
+ s_VddBbAddresses,
+ NV_ARRAY_SIZE(s_VddBbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PEX_CLK (NV reserved)
+{
+ NV_VDD_PEX_CLK_ODM_ID,
+ s_VddPexClkAddresses,
+ NV_ARRAY_SIZE(s_VddPexClkAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+#if 0
+// VBUS
+{
+ NV_VDD_VBUS_ODM_ID,
+ s_VddVBusAddresses,
+ NV_ARRAY_SIZE(s_VddVBusAddresses),
+ NvOdmPeripheralClass_Other
+},
+#endif
+
+//SOC
+{
+ NV_VDD_SoC_ODM_ID,
+ s_VddSocAddresses,
+ NV_ARRAY_SIZE(s_VddSocAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PMU0
+{
+ NV_ODM_GUID('t','p','s','6','5','8','6','x'),
+ s_Pmu0Addresses,
+ NV_ARRAY_SIZE(s_Pmu0Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// ENC28J60 SPI Ethernet module
+{
+ NV_ODM_GUID('e','n','c','2','8','j','6','0'),
+ s_SpiEthernetAddresses,
+ NV_ARRAY_SIZE(s_SpiEthernetAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// SMSC3317 ULPI USB PHY
+{
+ NV_ODM_GUID('s','m','s','c','3','3','1','7'),
+ s_UlpiUsbAddresses,
+ NV_ARRAY_SIZE(s_UlpiUsbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// LVDS LCD Display
+{
+ NV_ODM_GUID('L','V','D','S','W','S','V','G'), // LVDS WSVGA panel
+ s_LvdsDisplayAddresses,
+ NV_ARRAY_SIZE(s_LvdsDisplayAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// HDMI (based on Concorde 2 design)
+{
+ NV_ODM_GUID('f','f','a','2','h','d','m','i'),
+ s_HdmiAddresses,
+ NV_ARRAY_SIZE(s_HdmiAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// CRT (based on Concorde 2 design)
+{
+ NV_ODM_GUID('f','f','a','_','_','c','r','t'),
+ s_CrtAddresses,
+ NV_ARRAY_SIZE(s_CrtAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// TV Out Video Dac
+{
+ NV_ODM_GUID('f','f','a','t','v','o','u','t'),
+ s_ffaVideoDacAddresses,
+ NV_ARRAY_SIZE(s_ffaVideoDacAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// Sdio
+{
+ NV_ODM_GUID('s','d','i','o','_','m','e','m'),
+ s_SdioAddresses,
+ NV_ARRAY_SIZE(s_SdioAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// I2c SmBus transport.
+{
+ NV_ODM_GUID('I','2','c','S','m','B','u','s'),
+ s_I2cSmbusAddresses,
+ NV_ARRAY_SIZE(s_I2cSmbusAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// USB Mux J7A1 and J6A1
+{
+ NV_ODM_GUID('u','s','b','m','x','J','7','6'),
+ s_UsbMuxAddress,
+ NV_ARRAY_SIZE(s_UsbMuxAddress),
+ NvOdmPeripheralClass_Other
+
+},
+
+// Qwerty key baord for 16x8
+{
+ NV_ODM_GUID('q','w','e','r','t','y',' ',' '),
+ s_QwertyKeyPad16x8Addresses,
+ NV_ARRAY_SIZE(s_QwertyKeyPad16x8Addresses),
+ NvOdmPeripheralClass_HCI
+},
+
+// Temperature Monitor (TMON)
+{
+ NV_ODM_GUID('a','d','t','7','4','6','1',' '),
+ s_Tmon0Addresses,
+ NV_ARRAY_SIZE(s_Tmon0Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// Bluetooth
+{
+ NV_ODM_GUID('b','l','u','t','o','o','t','h'),
+ s_p1162BluetoothAddresses,
+ NV_ARRAY_SIZE(s_p1162BluetoothAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// Sdio wlan on COMMs Module
+{
+ NV_ODM_GUID('s','d','i','o','w','l','a','n'),
+ s_WlanAddresses,
+ NV_ARRAY_SIZE(s_WlanAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// Audio codec (I2C_PMU edition)
+{
+ NV_ODM_GUID('w','o','l','f','8','9','0','3'),
+ s_AudioCodecAddresses,
+ NV_ARRAY_SIZE(s_AudioCodecAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// Audio codec (I2C_1 edition)
+{
+ NV_ODM_GUID('w','o','8','9','0','3','_','1'),
+ s_AudioCodecAddressesI2C_1,
+ NV_ARRAY_SIZE(s_AudioCodecAddressesI2C_1),
+ NvOdmPeripheralClass_Other
+},
+
+// Touch panel
+{
+ NV_ODM_GUID('p','a','n','j','i','t','_','0'),
+ s_TouchPanelAddresses,
+ NV_ARRAY_SIZE(s_TouchPanelAddresses),
+ NvOdmPeripheralClass_HCI
+},
+
+// Accelerometer Module
+{
+ NV_ODM_GUID('b','m','a','1','5','0','a','c'),
+ s_AcceleroAddresses,
+ NV_ARRAY_SIZE(s_AcceleroAddresses),
+ NvOdmPeripheralClass_Other,
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h b/arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h
new file mode 100644
index 000000000000..1ec701091145
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Definition of bitfields inside the BCT customer option</b>
+ *
+ * @b Description: Defines the board-specific bitfields of the
+ * BCT customer option parameter, for NVIDIA
+ * Tegra development platforms.
+ *
+ * This file pertains to Whistler and Voyager.
+ */
+
+#ifndef NVIDIA_TEGRA_DEVKIT_CUSTOPT_H
+#define NVIDIA_TEGRA_DEVKIT_CUSTOPT_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+//---------- BOARD PERSONALITIES (BEGIN) ----------//
+// On the Whistler boards, be sure to match the following
+// switches with the personality setting you choose.
+//
+// SW2 = bits 3:0 (low nibble)
+// SW3 = bits 7:4 (high nibble)
+
+#define TEGRA_DEVKIT_DEFAULT_PERSONALITY \
+ TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_RANGE 7:0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_DEFAULT 0x0UL
+
+// VOYAGER, eMMC, NO TRACE (10x8 keypad)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_01 0x01UL // ULPI = baseband
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05 0x05UL // ULPI = UART1
+
+// VOYAGER, eMMC, with TRACE (7x1 keypad)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11 0x11UL // ULPI = baseband
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15 0x15UL // ULPI = UART1
+
+// VOYAGER, NAND, NO TRACE (10x8 keypad)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 0x75UL // Voyager, NAND
+
+// WHISTLER, stand-alone
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1 0xC1UL // KB = 13x1, TRACE, GMI = A/D NOR
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C3 0xC3UL // KB = 16x8, NO TRACE, GMI = NAND
+
+// VOYAGER, USB2-ULPI (No UART1)
+// Personality 71 is similar to the 75, except ULPI is enabled instead of UART1.
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_71 0x71UL
+
+
+//---------- BOARD PERSONALITIES (END) ----------//
+
+/// Download transport
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_RANGE 10:8
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE 0x1UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART 0x2UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB 0x3UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET 0x4UL
+
+/// Transport option (bus selector), for UART and Ethernet transport
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_RANGE 12:11
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A 0x1UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B 0x2UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C 0x3UL
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_RANGE 12:11
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI 0x1UL
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_RANGE 17:15
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_DEFAULT 0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTA 0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTB 1
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTC 2
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTD 3
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTE 4
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_RANGE 19:18
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT 0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE 1
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC 2
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART 3
+
+// display options
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_RANGE 22:20
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_DEFAULT 0x0UL
+// embedded panel (lvds, dsi, etc)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_EMBEDDED 0x0UL
+// no panels (external or embedded)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_NULL 0x1UL
+// use hdmi as the primary
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_HDMI 0x2UL
+// use crt as the primary
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_CRT 0x3UL
+
+// Enable DHCP
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_RANGE 23:23
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_ENABLE 0x1UL
+
+/// Total RAM
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_RANGE 30:28
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT 0x0UL // 512 MB
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_256 0x1UL // 256 MB
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_512 0x2UL // 512 MB
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1024 0x3UL // 1024 MB (1 GB)
+
+/// Soc low power state
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_RANGE 31:31
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP0 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1 0x1UL
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/Makefile b/arch/arm/mach-tegra/odm_kit/query/whistler/Makefile
new file mode 100644
index 000000000000..cd3c24b7f540
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/Makefile
@@ -0,0 +1,18 @@
+ccflags-y += -DNV_IS_AVP=0
+ccflags-y += -DNV_OAL=0
+ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0
+ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y)
+ccflags-y += -DNV_DEBUG=1
+else
+ccflags-y += -DNV_DEBUG=0
+endif
+
+ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations
+
+obj-y += nvodm_query.o
+obj-y += nvodm_query_discovery.o
+obj-y += nvodm_query_nand.o
+obj-y += nvodm_query_gpio.o
+obj-y += nvodm_query_pinmux.o
+obj-y += nvodm_query_kbc.o
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h b/arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h
new file mode 100644
index 000000000000..869aedf1eb67
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NVODM_IMAGER_GUIDS_H
+#define NVODM_IMAGER_GUIDS_H
+
+#include "nvodm_query_discovery.h"
+
+// E912-A02 and Concorde2 Sensors
+#define OV5630_GUID NV_ODM_GUID('s','_','O','V','5','6','3','0')
+
+// E911 Sensors
+#define MI5130_GUID NV_ODM_GUID('s','_','M','I','5','1','3','0')
+#define SEMCOVGA_GUID NV_ODM_GUID('S','E','M','C','O','V','G','A')
+
+// E911 Focusers
+// focuser for MI5130
+#define DW9710_GUID NV_ODM_GUID('f','_','D','W','9','7','1','0')
+
+/// focuser for OV5630
+#define AD5820_GUID NV_ODM_GUID('f','_','A','D','5','8','2','0')
+
+// E911 Flash
+#define LTC3216_GUID NV_ODM_GUID('l','_','L','T','3','2','1','6')
+
+// io addresses common to all imagers (clock)
+#define COMMONIMAGER_GUID NV_ODM_GUID('s', '_', 'c', 'o', 'm', 'm', 'o', 'n')
+
+// Pin Use Codes:
+// VI/CSI Parallel and Serial Pins and GPIO Pins
+
+// More than one device may be retrieved thru the query
+#define NVODM_CAMERA_DEVICE_IS_DEFAULT (1)
+
+// The imager devices can connect to the parallel bus or the serial bus
+// Parallel connections use pins VD0 thru VD9.
+// Serial connections use the mipi pins (ex: CSI_D1AN/CSI_D1AP)
+#define NVODM_CAMERA_DATA_PIN_SHIFT (1)
+#define NVODM_CAMERA_DATA_PIN_MASK 0x0F
+#define NVODM_CAMERA_PARALLEL_VD0_TO_VD9 (1 << NVODM_CAMERA_DATA_PIN_SHIFT)
+#define NVODM_CAMERA_PARALLEL_VD0_TO_VD7 (2 << NVODM_CAMERA_DATA_PIN_SHIFT)
+#define NVODM_CAMERA_SERIAL_CSI_D1A (4 << NVODM_CAMERA_DATA_PIN_SHIFT)
+#define NVODM_CAMERA_SERIAL_CSI_D2A (5 << NVODM_CAMERA_DATA_PIN_SHIFT)
+#define NVODM_CAMERA_SERIAL_CSI_D1A_D2A (6 << NVODM_CAMERA_DATA_PIN_SHIFT)
+#define NVODM_CAMERA_SERIAL_CSI_D1B (7 << NVODM_CAMERA_DATA_PIN_SHIFT)
+
+// Switching the encoding from the VideoInput module address to use with
+// each GPIO module address.
+// NVODM_IMAGER_GPIO will tell the nvodm imager how to use each gpio
+// A gpio can be used for powerdown (lo, hi) or !powerdown (hi, lo)
+// used for reset (hi, lo, hi) or for !reset (lo, hi, lo)
+// Or, for mclk or pwm (unimplemented yet)
+// We have moved the flash to its own, so it is not needed here
+#define NVODM_IMAGER_GPIO_PIN_SHIFT (24)
+#define NVODM_IMAGER_UNUSED (0x0)
+#define NVODM_IMAGER_RESET (0x1 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+#define NVODM_IMAGER_RESET_AL (0x2 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+#define NVODM_IMAGER_POWERDOWN (0x3 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+#define NVODM_IMAGER_POWERDOWN_AL (0x4 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+// only on VGP0
+#define NVODM_IMAGER_MCLK (0x8 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+// only on VGP6
+#define NVODM_IMAGER_PWM (0x9 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+// If flash code wants the gpio's labelled
+// use for any purpose, or not at all
+#define NVODM_IMAGER_FLASH0 (0x5 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+#define NVODM_IMAGER_FLASH1 (0x6 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+#define NVODM_IMAGER_FLASH2 (0x7 << NVODM_IMAGER_GPIO_PIN_SHIFT)
+// Shutter control
+#define NVOSM_IMAGER_SHUTTER (0xA << NVODM_IMAGER_GPIO_PIN_SHIFT)
+//
+
+#define NVODM_IMAGER_MASK (0xF << NVODM_IMAGER_GPIO_PIN_SHIFT)
+#define NVODM_IMAGER_CLEAR(_s) ((_s) & ~(NVODM_IMAGER_MASK))
+#define NVODM_IMAGER_IS_SET(_s) (((_s) & (NVODM_IMAGER_MASK)) != 0)
+#define NVODM_IMAGER_FIELD(_s) ((_s) >> NVODM_IMAGER_GPIO_PIN_SHIFT)
+
+// The imager devices can connect to the vi gpio (VGP) pins
+// for various reasons: flash, powerdown, reset, pwm, mclk.
+// Only certain pins can be used for certain activities.
+// These flags should be OR'd together to form the proper 'address'
+// in the NvOdmIoAddress for VideoInput.
+// VGP1 & VGP2 are used for i2c
+// _AL means 'active low', otherwise active high is assumed
+
+#define NVODM_CAMERA_GPIO_PIN_SHIFT (8)
+#define NVODM_CAMERA_GPIO_PIN_MASK (0x7)
+#define NVODM_CAMERA_GPIO_PIN_WIDTH 3
+#define NVODM_CAMERA_GPIO_PIN_COUNT 7
+
+#define NVODM_CAMERA_UNUSED (0x0)
+#define NVODM_CAMERA_RESET(_s) (0x1 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+#define NVODM_CAMERA_RESET_AL(_s) (0x2 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+#define NVODM_CAMERA_POWERDOWN(_s) (0x3 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+#define NVODM_CAMERA_POWERDOWN_AL(_s) (0x4 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+#define NVODM_CAMERA_FLASH_LOW(_s) (0x5 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+#define NVODM_CAMERA_FLASH_HIGH(_s) (0x6 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+// only on VGP0
+#define NVODM_CAMERA_MCLK(_s) (0x7 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+// only on VGP6
+#define NVODM_CAMERA_PWM(_s) (0x7 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT))
+
+#define NVODM_VGP0_SHIFT 0
+#define NVODM_VD10_SHIFT (1*NVODM_CAMERA_GPIO_PIN_WIDTH)
+#define NVODM_VD11_SHIFT (2*NVODM_CAMERA_GPIO_PIN_WIDTH)
+#define NVODM_VGP3_SHIFT (3*NVODM_CAMERA_GPIO_PIN_WIDTH)
+#define NVODM_VGP4_SHIFT (4*NVODM_CAMERA_GPIO_PIN_WIDTH)
+#define NVODM_VGP5_SHIFT (5*NVODM_CAMERA_GPIO_PIN_WIDTH)
+#define NVODM_VGP6_SHIFT (6*NVODM_CAMERA_GPIO_PIN_WIDTH)
+
+// VGP0
+#define NVODM_CAMERA_VGP0_RESET NVODM_CAMERA_RESET(NVODM_VGP0_SHIFT)
+#define NVODM_CAMERA_VGP0_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP0_SHIFT)
+#define NVODM_CAMERA_VGP0_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP0_SHIFT)
+#define NVODM_CAMERA_VGP0_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP0_SHIFT)
+#define NVODM_CAMERA_VGP0_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP0_SHIFT)
+#define NVODM_CAMERA_VGP0_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP0_SHIFT)
+#define NVODM_CAMERA_VGP0_MCLK NVODM_CAMERA_MCLK(NVODM_VGP0_SHIFT)
+// VD10
+#define NVODM_CAMERA_VD10_RESET NVODM_CAMERA_RESET(NVODM_VD10_SHIFT)
+#define NVODM_CAMERA_VD10_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VD10_SHIFT)
+#define NVODM_CAMERA_VD10_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VD10_SHIFT)
+#define NVODM_CAMERA_VD10_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VD10_SHIFT)
+#define NVODM_CAMERA_VD10_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VD10_SHIFT)
+#define NVODM_CAMERA_VD10_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VD10_SHIFT)
+// VD11
+#define NVODM_CAMERA_VD11_RESET NVODM_CAMERA_RESET(NVODM_VD11_SHIFT)
+#define NVODM_CAMERA_VD11_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VD11_SHIFT)
+#define NVODM_CAMERA_VD11_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VD11_SHIFT)
+#define NVODM_CAMERA_VD11_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VD11_SHIFT)
+#define NVODM_CAMERA_VD11_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VD11_SHIFT)
+#define NVODM_CAMERA_VD11_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VD11_SHIFT)
+// VGP3
+#define NVODM_CAMERA_VGP3_RESET NVODM_CAMERA_RESET(NVODM_VGP3_SHIFT)
+#define NVODM_CAMERA_VGP3_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP3_SHIFT)
+#define NVODM_CAMERA_VGP3_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP3_SHIFT)
+#define NVODM_CAMERA_VGP3_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP3_SHIFT)
+#define NVODM_CAMERA_VGP3_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP3_SHIFT)
+#define NVODM_CAMERA_VGP3_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP3_SHIFT)
+// VGP4
+#define NVODM_CAMERA_VGP4_RESET NVODM_CAMERA_RESET(NVODM_VGP4_SHIFT)
+#define NVODM_CAMERA_VGP4_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP4_SHIFT)
+#define NVODM_CAMERA_VGP4_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP4_SHIFT)
+#define NVODM_CAMERA_VGP4_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP4_SHIFT)
+#define NVODM_CAMERA_VGP4_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP4_SHIFT)
+#define NVODM_CAMERA_VGP4_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP4_SHIFT)
+// VGP5
+#define NVODM_CAMERA_VGP5_RESET NVODM_CAMERA_RESET(NVODM_VGP5_SHIFT)
+#define NVODM_CAMERA_VGP5_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP5_SHIFT)
+#define NVODM_CAMERA_VGP5_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP5_SHIFT)
+#define NVODM_CAMERA_VGP5_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP5_SHIFT)
+#define NVODM_CAMERA_VGP5_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP5_SHIFT)
+#define NVODM_CAMERA_VGP5_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP5_SHIFT)
+// VGP6
+#define NVODM_CAMERA_VGP6_RESET NVODM_CAMERA_RESET(NVODM_VGP6_SHIFT)
+#define NVODM_CAMERA_VGP6_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP6_SHIFT)
+#define NVODM_CAMERA_VGP6_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP6_SHIFT)
+#define NVODM_CAMERA_VGP6_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP6_SHIFT)
+#define NVODM_CAMERA_VGP6_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP6_SHIFT)
+#define NVODM_CAMERA_VGP6_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP6_SHIFT)
+#define NVODM_CAMERA_VGP6_PWM NVODM_CAMERA_PWM(NVODM_VGP6_SHIFT)
+
+#endif
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
new file mode 100644
index 000000000000..d17f12b59559
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c
@@ -0,0 +1,1490 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit:
+ * Implementation of the ODM Query API</b>
+ *
+ * @b Description: Implements the query functions for ODMs that may be
+ * accessed at boot-time, runtime, or anywhere in between.
+ */
+
+#include "nvodm_query.h"
+#include "nvodm_query_gpio.h"
+#include "nvodm_query_memc.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_query_pins.h"
+#include "nvodm_query_pins_ap20.h"
+#include "tegra_devkit_custopt.h"
+#include "nvodm_keylist_reserved.h"
+#include "nvrm_drf.h"
+
+#define BOARD_ID_WHISTLER_E1108 0x0B08
+#define BOARD_ID_WHISTLER_E1109 0x0B09
+#define BOARD_ID_WHISTLER_PMU_E1116 0x0B10
+#define BOARD_ID_WHISTLER_MOTHERBOARD_E1120 0xB14
+#define BOARD_ID_VOYAGER_MAINBOARD_E1215 0xC0F
+#define BOARD_REV_ALL ((NvU8)0xFF)
+
+#define NVODM_ENABLE_EMC_DVFS (1)
+
+// Function to auto-detect boards with external CPU power supply
+NvBool NvOdmIsCpuExtSupply(void);
+
+static const NvU8
+s_NvOdmQueryDeviceNamePrefixValue[] = { 'T','e','g','r','a',0};
+
+static const NvU8
+s_NvOdmQueryManufacturerSetting[] = {'N','V','I','D','I','A',0};
+
+static const NvU8
+s_NvOdmQueryModelSetting[] = {'A','P','2','0',0};
+
+static const NvU8
+s_NvOdmQueryPlatformSetting[] = {'W','h','i','s','t','l','e','r',0};
+
+static const NvU8
+s_NvOdmQueryProjectNameSetting[] = {'O','D','M',' ','K','i','t',0};
+
+static const NvOdmDownloadTransport
+s_NvOdmQueryDownloadTransportSetting = NvOdmDownloadTransport_None;
+
+static NvOdmQuerySdioInterfaceProperty s_NvOdmQuerySdioInterfaceProperty_Whistler[4] =
+{
+ { NV_FALSE, 10, NV_FALSE, 0x6, NvOdmQuerySdioSlotUsage_unused },
+ { NV_TRUE, 10, NV_TRUE, 0xF, NvOdmQuerySdioSlotUsage_wlan },
+ { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Media },
+ { NV_TRUE, 10, NV_TRUE, 0x6, NvOdmQuerySdioSlotUsage_Boot },
+};
+
+static NvOdmQuerySdioInterfaceProperty s_NvOdmQuerySdioInterfaceProperty_Voyager[4] =
+{
+ { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_unused },
+ { NV_TRUE, 10, NV_TRUE, 0x4, NvOdmQuerySdioSlotUsage_wlan },
+ { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Media },
+ { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Boot },
+};
+
+static const NvOdmQueryOwrDeviceInfo s_NvOdmQueryOwrInfo = {
+ NV_FALSE,
+ 0x1, /* Tsu */
+ 0xF, /* TRelease */
+ 0xF, /* TRdv */
+ 0X3C, /* TLow0 */
+ 0x1, /* TLow1 */
+ 0x77, /* TSlot */
+
+ 0x78, /* TPdl */
+ 0x1E, /* TPdh */
+ 0x1DF, /* TRstl */
+ 0x1DF, /* TRsth */
+
+ 0x1E0, /* Tpp */
+ 0x5, /* Tfp */
+ 0x5, /* Trp */
+ 0x5, /* Tdv */
+ 0x5, /* Tpd */
+
+ 0x7, /* Read data sample clk */
+ 0x50, /* Presence sample clk */
+ 2, /* Memory address size */
+ 0x80 /* Memory size*/
+};
+
+static const NvOdmSdramControllerConfigAdv s_NvOdmE1109EmcConfigTable[] =
+{
+ {
+ 0x20, /* Rev 2.0 */
+ 166500, /* SDRAM frquency */
+ 1000, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x0000000A, /* RC */
+ 0x00000016, /* RFC */
+ 0x00000008, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000F, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000005, /* WDV */
+ 0x00000006, /* QUSE */
+ 0x00000005, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000E, /* RDV */
+ 0x000004DF, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000004, /* PDEX2WR */
+ 0x00000004, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000B, /* RW2PDEN */
+ 0x000000C8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000008, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x0000000B, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0x00400006, /* CFG_DIG_DLL */
+ 0x007FD010, /* DLL_XFORM_DQS */
+ 0x00001010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000000, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 333000, /* SDRAM frquency */
+ 1200, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000014, /* RC */
+ 0x0000002B, /* RFC */
+ 0x0000000F, /* RAS */
+ 0x00000005, /* RP */
+ 0x00000004, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000F, /* W2P */
+ 0x00000005, /* RD_RCD */
+ 0x00000005, /* WR_RCD */
+ 0x00000004, /* RRD */
+ 0x00000001, /* REXT */
+ 0x00000005, /* WDV */
+ 0x00000006, /* QUSE */
+ 0x00000005, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000E, /* RDV */
+ 0x000009FF, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000004, /* PDEX2WR */
+ 0x00000004, /* PDEX2RD */
+ 0x00000005, /* PCHG2PDEN */
+ 0x00000005, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x00000010, /* RW2PDEN */
+ 0x000000C8, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000F, /* TFAW */
+ 0x00000006, /* TRPAB */
+ 0x0000000B, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000000, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000083, /* FBIO_CFG5 */
+ 0x002C0006, /* CFG_DIG_DLL */
+ 0x007FD010, /* DLL_XFORM_DQS */
+ 0x00001010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000000, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ }
+};
+
+static const NvOdmSdramControllerConfigAdv s_NvOdmE1108HynixEmcConfigTable[] =
+{
+ {
+ 0x20, /* Rev 2.0 */
+ 18000, /* SDRAM frquency */
+ 950, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000002, /* RC */
+ 0x00000006, /* RFC */
+ 0x00000003, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000006, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000B, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000002, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000008, /* QSAFE */
+ 0x0000000C, /* RDV */
+ 0x00000070, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000B, /* RW2PDEN */
+ 0x00000003, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000008, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x0000004B, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000082, /* FBIO_CFG5 */
+ 0x00780006, /* CFG_DIG_DLL */
+ 0x00000010, /* DLL_XFORM_DQS */
+ 0x00000008, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000002, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 27000, /* SDRAM frquency */
+ 950, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000002, /* RC */
+ 0x00000006, /* RFC */
+ 0x00000003, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000006, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000B, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000002, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000005, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000008, /* QSAFE */
+ 0x0000000C, /* RDV */
+ 0x000000A8, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000B, /* RW2PDEN */
+ 0x00000004, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000008, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000071, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000003, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000082, /* FBIO_CFG5 */
+ 0x00780006, /* CFG_DIG_DLL */
+ 0x00000010, /* DLL_XFORM_DQS */
+ 0x00000008, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000003, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 54000, /* SDRAM frquency */
+ 1000, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000004, /* RC */
+ 0x00000008, /* RFC */
+ 0x00000003, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000006, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000B, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000002, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000006, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000008, /* QSAFE */
+ 0x0000000C, /* RDV */
+ 0x0000017F, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000B, /* RW2PDEN */
+ 0x00000008, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000008, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x000000E1, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000000, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000082, /* FBIO_CFG5 */
+ 0x00780006, /* CFG_DIG_DLL */
+ 0x00000010, /* DLL_XFORM_DQS */
+ 0x00000008, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x00000005, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 108000, /* SDRAM frquency */
+ 1000, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000007, /* RC */
+ 0x0000000F, /* RFC */
+ 0x00000005, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000006, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000B, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000002, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000006, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000008, /* QSAFE */
+ 0x0000000C, /* RDV */
+ 0x0000031F, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000B, /* RW2PDEN */
+ 0x00000010, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000008, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x000001C2, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000000, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000082, /* FBIO_CFG5 */
+ 0xD0780323, /* CFG_DIG_DLL */
+ 0x007FD010, /* DLL_XFORM_DQS */
+ 0x00000010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x0000000A, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 150000, /* SDRAM frquency */
+ 1000, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000009, /* RC */
+ 0x00000014, /* RFC */
+ 0x00000007, /* RAS */
+ 0x00000003, /* RP */
+ 0x00000006, /* R2W */
+ 0x00000004, /* W2R */
+ 0x00000002, /* R2P */
+ 0x0000000B, /* W2P */
+ 0x00000003, /* RD_RCD */
+ 0x00000003, /* WR_RCD */
+ 0x00000002, /* RRD */
+ 0x00000002, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000006, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000008, /* QSAFE */
+ 0x0000000C, /* RDV */
+ 0x0000045F, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000003, /* PDEX2WR */
+ 0x00000003, /* PDEX2RD */
+ 0x00000003, /* PCHG2PDEN */
+ 0x00000003, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000B, /* RW2PDEN */
+ 0x00000015, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x00000008, /* TFAW */
+ 0x00000004, /* TRPAB */
+ 0x00000008, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x00000270, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000001, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000082, /* FBIO_CFG5 */
+ 0xD05E0323, /* CFG_DIG_DLL */
+ 0x007FD010, /* DLL_XFORM_DQS */
+ 0x00000010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x0000000E, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ },
+ {
+ 0x20, /* Rev 2.0 */
+ 300000, /* SDRAM frquency */
+ 1100, /* EMC core voltage */
+ 46, /* Number of EMC parameters below */
+ {
+ 0x00000012, /* RC */
+ 0x00000027, /* RFC */
+ 0x0000000D, /* RAS */
+ 0x00000006, /* RP */
+ 0x00000007, /* R2W */
+ 0x00000005, /* W2R */
+ 0x00000003, /* R2P */
+ 0x0000000B, /* W2P */
+ 0x00000006, /* RD_RCD */
+ 0x00000006, /* WR_RCD */
+ 0x00000003, /* RRD */
+ 0x00000003, /* REXT */
+ 0x00000003, /* WDV */
+ 0x00000006, /* QUSE */
+ 0x00000004, /* QRST */
+ 0x00000009, /* QSAFE */
+ 0x0000000D, /* RDV */
+ 0x000008FF, /* REFRESH */
+ 0x00000000, /* BURST_REFRESH_NUM */
+ 0x00000004, /* PDEX2WR */
+ 0x00000004, /* PDEX2RD */
+ 0x00000006, /* PCHG2PDEN */
+ 0x00000006, /* ACT2PDEN */
+ 0x00000001, /* AR2PDEN */
+ 0x0000000F, /* RW2PDEN */
+ 0x0000002A, /* TXSR */
+ 0x00000003, /* TCKE */
+ 0x0000000F, /* TFAW */
+ 0x00000007, /* TRPAB */
+ 0x00000007, /* TCLKSTABLE */
+ 0x00000002, /* TCLKSTOP */
+ 0x000004E0, /* TREFBW */
+ 0x00000000, /* QUSE_EXTRA */
+ 0x00000002, /* FBIO_CFG6 */
+ 0x00000000, /* ODT_WRITE */
+ 0x00000000, /* ODT_READ */
+ 0x00000282, /* FBIO_CFG5 */
+ 0xE03A0303, /* CFG_DIG_DLL */
+ 0x007FD010, /* DLL_XFORM_DQS */
+ 0x00000010, /* DLL_XFORM_QUSE */
+ 0x00000000, /* ZCAL_REF_CNT */
+ 0x0000001B, /* ZCAL_WAIT_CNT */
+ 0x00000000, /* AUTO_CAL_INTERVAL */
+ 0x00000000, /* CFG_CLKTRIM_0 */
+ 0x00000000, /* CFG_CLKTRIM_1 */
+ 0x00000000, /* CFG_CLKTRIM_2 */
+ }
+ }
+};
+
+
+// Wake Events
+static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] =
+{
+ {NV_FALSE, 0, NvOdmWakeupPadPolarity_Low}, // Wake Event 0 - ulpi_data4 (UART_RI)
+ {NV_FALSE, 1, NvOdmWakeupPadPolarity_High}, // Wake Event 1 - gp3_pv[3] (BB_MOD, MODEM_RESET_OUT)
+ {NV_FALSE, 2, NvOdmWakeupPadPolarity_High}, // Wake Event 2 - dvi_d3
+ {NV_FALSE, 3, NvOdmWakeupPadPolarity_Low}, // Wake Event 3 - sdio3_dat1
+ {NV_FALSE, 4, NvOdmWakeupPadPolarity_High}, // Wake Event 4 - hdmi_int (HDMI_HPD)
+ {NV_FALSE, 5, NvOdmWakeupPadPolarity_High}, // Wake Event 5 - vgp[6] (VI_GP6, Flash_EN2)
+ {NV_FALSE, 6, NvOdmWakeupPadPolarity_High}, // Wake Event 6 - gp3_pu[5] (GPS_ON_OFF, GPS_IRQ)
+ {NV_FALSE, 7, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 7 - gp3_pu[6] (GPS_INT, BT_IRQ)
+ {NV_FALSE, 8, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 8 - gmi_wp_n (MICRO SD_CD)
+ {NV_FALSE, 9, NvOdmWakeupPadPolarity_High}, // Wake Event 9 - gp3_ps[2] (KB_COL10)
+ {NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP)
+ {NV_FALSE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ)
+ {NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used)
+ {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1
+ {NV_FALSE, 14, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 14 - gp3_pv[6] (WLAN_INT)
+ {NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1)
+ {NV_FALSE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq
+ {NV_TRUE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt
+ {NV_FALSE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT)
+ {NV_FALSE, 19, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 19 - usb_vbus_wakeup[0]
+ {NV_FALSE, 20, NvOdmWakeupPadPolarity_High}, // Wake Event 20 - usb_vbus_wakeup[1]
+ {NV_FALSE, 21, NvOdmWakeupPadPolarity_Low}, // Wake Event 21 - usb_iddig[0]
+ {NV_FALSE, 22, NvOdmWakeupPadPolarity_Low}, // Wake Event 22 - usb_iddig[1]
+ {NV_FALSE, 23, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 23 - gmi_iordy (HSMMC_CLK)
+ {NV_FALSE, 24, NvOdmWakeupPadPolarity_High}, // Wake Event 24 - gp3_pv[2] (BB_MOD, MODEM WAKEUP_AP15, SPI-SS)
+ {NV_FALSE, 25, NvOdmWakeupPadPolarity_High}, // Wake Event 25 - gp3_ps[4] (KB_COL12)
+ {NV_FALSE, 26, NvOdmWakeupPadPolarity_High}, // Wake Event 26 - gp3_ps[5] (KB_COL10)
+ {NV_FALSE, 27, NvOdmWakeupPadPolarity_High}, // Wake Event 27 - gp3_ps[0] (KB_COL8)
+ {NV_FALSE, 28, NvOdmWakeupPadPolarity_Low}, // Wake Event 28 - gp3_pq[6] (KB_ROW6)
+ {NV_FALSE, 29, NvOdmWakeupPadPolarity_Low}, // Wake Event 29 - gp3_pq[7] (KB_ROW6)
+ {NV_FALSE, 30, NvOdmWakeupPadPolarity_High} // Wake Event 30 - dap1_dout (DAP1_DOUT)
+};
+
+/* --- Function Implementations ---*/
+
+static NvBool
+NvOdmIsBoardPresent(
+ const NvOdmBoardInfo* pBoardList,
+ NvU32 ListSize)
+{
+ NvU32 i;
+ NvOdmBoardInfo BoardInfo;
+
+ // Scan for presence of any board in the list
+ // ID/SKU/FAB fields must match, revision may be masked
+ if (pBoardList)
+ {
+ for (i=0; i < ListSize; i++)
+ {
+ if (NvOdmPeripheralGetBoardInfo(
+ pBoardList[i].BoardID, &BoardInfo))
+ {
+ if ((pBoardList[i].Fab == BoardInfo.Fab) &&
+ (pBoardList[i].SKU == BoardInfo.SKU) &&
+ ((pBoardList[i].Revision == BOARD_REV_ALL) ||
+ (pBoardList[i].Revision == BoardInfo.Revision)) &&
+ ((pBoardList[i].MinorRevision == BOARD_REV_ALL) ||
+ (pBoardList[i].MinorRevision == BoardInfo.MinorRevision)))
+ {
+ return NV_TRUE; // Board found
+ }
+ }
+ }
+ }
+ return NV_FALSE;
+}
+
+#if NVODM_ENABLE_EMC_DVFS
+static NvBool NvOdmIsE1108Hynix(void)
+{
+ // A list of Whistler E1108 processor boards with Hynix LPDDR2
+ // charcterized by s_NvOdmE1108HynixEmcConfigTable (fill in
+ // ID/SKU/FAB fields, revision fields are ignored)
+ static const NvOdmBoardInfo s_WhistlerE1108Hynix[] =
+ {
+ // ID SKU FAB Rev Minor Rev
+ { BOARD_ID_WHISTLER_E1108, 0x0A14, 0x01, BOARD_REV_ALL, BOARD_REV_ALL},
+ { BOARD_ID_WHISTLER_E1108, 0x0A1E, 0x01, BOARD_REV_ALL, BOARD_REV_ALL},
+ { BOARD_ID_WHISTLER_E1108, 0x0A00, 0x02, BOARD_REV_ALL, BOARD_REV_ALL},
+ { BOARD_ID_WHISTLER_E1108, 0x0A0A, 0x02, BOARD_REV_ALL, BOARD_REV_ALL}
+ };
+ return NvOdmIsBoardPresent(s_WhistlerE1108Hynix,
+ NV_ARRAY_SIZE(s_WhistlerE1108Hynix));
+}
+#endif
+
+static NvBool NvOdmIsCpuRailPreserved(void)
+{
+ // A list of Whistler PMU boards that preserves CPU voltage across LP2/LP1
+ static const NvOdmBoardInfo s_WhistlerCpuPreservedBoards[] =
+ {
+ // ID SKU FAB Rev Minor Rev
+ { BOARD_ID_WHISTLER_PMU_E1116, 0x0A0A, 0x01, BOARD_REV_ALL, BOARD_REV_ALL},
+ };
+ return NvOdmIsBoardPresent(s_WhistlerCpuPreservedBoards,
+ NV_ARRAY_SIZE(s_WhistlerCpuPreservedBoards));
+}
+
+NvBool NvOdmIsCpuExtSupply(void)
+{
+ // A list of Whistler processor boards that use external DCDC as CPU
+ // power supply (fill in ID/SKU/FAB fields, revision fields are ignored)
+ static const NvOdmBoardInfo s_WhistlerCpuExtSupplyBoards[] =
+ {
+ // ID SKU FAB Rev Minor Rev
+ { BOARD_ID_WHISTLER_E1108, 0x0A14, 0x01, BOARD_REV_ALL, BOARD_REV_ALL},
+ { BOARD_ID_WHISTLER_E1108, 0x0A00, 0x02, BOARD_REV_ALL, BOARD_REV_ALL}
+ };
+ return NvOdmIsBoardPresent(s_WhistlerCpuExtSupplyBoards,
+ NV_ARRAY_SIZE(s_WhistlerCpuExtSupplyBoards));
+}
+
+static NvU32
+GetBctKeyValue(void)
+{
+ NvOdmServicesKeyListHandle hKeyList = NULL;
+ NvU32 BctCustOpt = 0;
+
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ BctCustOpt =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ }
+
+ return BctCustOpt;
+}
+
+NvOdmDebugConsole
+NvOdmQueryDebugConsole(void)
+{
+ NvU32 CustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC:
+ return NvOdmDebugConsole_Dcc;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE:
+ return NvOdmDebugConsole_None;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART:
+ return NvOdmDebugConsole_UartA +
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE_OPTION, CustOpt);
+ default:
+ return NvOdmDebugConsole_None;
+ }
+}
+
+NvOdmDownloadTransport
+NvOdmQueryDownloadTransport(void)
+{
+ NvU32 CustOpt = GetBctKeyValue();
+
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, TRANSPORT, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE:
+ return NvOdmDownloadTransport_None;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB:
+ return NvOdmDownloadTransport_Usb;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET:
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, ETHERNET_OPTION, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT:
+ default:
+ return NvOdmDownloadTransport_SpiEthernet;
+ }
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART:
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, UART_OPTION, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B:
+ return NvOdmDownloadTransport_UartB;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C:
+ return NvOdmDownloadTransport_UartC;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A:
+ default:
+ return NvOdmDownloadTransport_UartA;
+ }
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT:
+ default:
+ return s_NvOdmQueryDownloadTransportSetting;
+ }
+}
+
+const NvU8*
+NvOdmQueryDeviceNamePrefix(void)
+{
+ return s_NvOdmQueryDeviceNamePrefixValue;
+}
+
+static const NvOdmQuerySpdifInterfaceProperty s_NvOdmQuerySpdifInterfacePropertySetting =
+{
+ NvOdmQuerySpdifDataCaptureControl_FromLeft
+};
+
+const NvOdmQuerySpiDeviceInfo *
+
+NvOdmQuerySpiGetDeviceInfo(
+ NvOdmIoModule OdmIoModule,
+ NvU32 ControllerId,
+ NvU32 ChipSelect)
+{
+ static const NvOdmQuerySpiDeviceInfo s_Spi1Cs0Info_EmpRil =
+ {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_TRUE};
+
+ static const NvOdmQuerySpiDeviceInfo s_Spi1Cs0Info_IfxRil =
+ {NvOdmQuerySpiSignalMode_1, NV_TRUE, NV_FALSE};
+
+ static const NvOdmQuerySpiDeviceInfo s_Spi1Cs0Info =
+ {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_FALSE};
+
+ static const NvOdmQuerySpiDeviceInfo s_Spi2Cs1Info =
+ {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_FALSE};
+
+ static const NvOdmQuerySpiDeviceInfo s_Spi3Cs1Info =
+ {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_FALSE};
+
+ NvU32 CustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW:
+ if ((OdmIoModule == NvOdmIoModule_Spi) &&
+ (ControllerId == 0 ) && (ChipSelect == 0))
+ return &s_Spi1Cs0Info_EmpRil;
+ break;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX:
+ if ((OdmIoModule == NvOdmIoModule_Spi) &&
+ (ControllerId == 0 ) && (ChipSelect == 0))
+ return &s_Spi1Cs0Info_IfxRil;
+ break;
+ }
+
+ if ((OdmIoModule == NvOdmIoModule_Spi) &&
+ (ControllerId == 1 || ControllerId == 0) && (ChipSelect == 0))
+ return &s_Spi1Cs0Info;
+
+ if ((OdmIoModule == NvOdmIoModule_Spi) &&
+ (ControllerId == 1 ) && ((ChipSelect == 1)|| (ChipSelect == 3)))
+ return &s_Spi2Cs1Info;
+
+ if ((OdmIoModule == NvOdmIoModule_Spi) &&
+ (ControllerId == 2 ) && (ChipSelect == 1))
+ return &s_Spi3Cs1Info;
+
+ if ((OdmIoModule == NvOdmIoModule_Spi) &&
+ (ControllerId == 2 ) && (ChipSelect == 2))
+ return &s_Spi3Cs1Info;
+
+ return NULL;
+}
+
+
+const NvOdmQuerySpiIdleSignalState *
+NvOdmQuerySpiGetIdleSignalState(
+ NvOdmIoModule OdmIoModule,
+ NvU32 ControllerId)
+{
+ return NULL;
+}
+
+const NvOdmQueryI2sInterfaceProperty *
+NvOdmQueryI2sGetInterfaceProperty(
+ NvU32 I2sInstanceId)
+{
+ static const NvOdmQueryI2sInterfaceProperty s_Property =
+ {
+ NvOdmQueryI2sMode_Slave,
+ NvOdmQueryI2sLRLineControl_LeftOnLow,
+ NvOdmQueryI2sDataCommFormat_I2S,
+ NV_FALSE,
+ 0
+ };
+
+ if ((!I2sInstanceId) || (I2sInstanceId == 1))
+ return &s_Property;
+
+ return NULL;
+}
+
+const NvOdmQueryDapPortProperty *
+NvOdmQueryDapPortGetProperty(
+ NvU32 DapPortId)
+{
+ static const NvOdmQueryDapPortProperty s_Property[] =
+ {
+ { NvOdmDapPort_None, NvOdmDapPort_None, { 0, 0, 0, 0 } },
+ // I2S1 (DAC1) <-> DAP1 <-> HIFICODEC
+ { NvOdmDapPort_I2s1, NvOdmDapPort_HifiCodecType,
+ { 2, 16, 44100, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap1
+ // I2S2 (DAC2) <-> DAP2 <-> VOICECODEC
+ {NvOdmDapPort_I2s2, NvOdmDapPort_VoiceCodecType,
+ {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap2
+ };
+ static const NvOdmQueryDapPortProperty s_Property_Ril_Emp_Rainbow[] =
+ {
+ { NvOdmDapPort_None, NvOdmDapPort_None, { 0, 0, 0, 0 } },
+ // I2S1 (DAC1) <-> DAP1 <-> HIFICODEC
+ { NvOdmDapPort_I2s1, NvOdmDapPort_HifiCodecType,
+ { 2, 16, 44100, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap1
+ // I2S2 (DAC2) <-> DAP2 <-> VOICECODEC
+ {NvOdmDapPort_I2s2, NvOdmDapPort_VoiceCodecType,
+ {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap2
+ // I2S2 (DAC2) <-> DAP3 <-> BASEBAND
+ {NvOdmDapPort_I2s2, NvOdmDapPort_BaseBand,
+ {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap3
+ // I2S2 (DAC2) <-> DAP4 <-> BLUETOOTH
+ {NvOdmDapPort_I2s2, NvOdmDapPort_BlueTooth,
+ {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap4
+ };
+ NvU32 CustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX:
+ if (DapPortId && DapPortId<NV_ARRAY_SIZE(s_Property_Ril_Emp_Rainbow))
+ return &s_Property_Ril_Emp_Rainbow[DapPortId];
+ break;
+ default:
+ if (DapPortId && DapPortId<NV_ARRAY_SIZE(s_Property))
+ return &s_Property[DapPortId];
+ break;
+ }
+ return NULL;
+}
+
+const NvOdmQueryDapPortConnection*
+NvOdmQueryDapPortGetConnectionTable(
+ NvU32 ConnectionIndex)
+{
+ static const NvOdmQueryDapPortConnection s_Property[] =
+ {
+ { NvOdmDapConnectionIndex_Music_Path,
+ 2, { {NvOdmDapPort_I2s1, NvOdmDapPort_Dap1, NV_FALSE},
+ {NvOdmDapPort_Dap1, NvOdmDapPort_I2s1, NV_TRUE} } },
+ };
+ static const NvOdmQueryDapPortConnection s_Property_Ril_Emp_Rainbow[] =
+ {
+ { NvOdmDapConnectionIndex_Music_Path,
+ 2, { {NvOdmDapPort_I2s1, NvOdmDapPort_Dap1, NV_FALSE},
+ {NvOdmDapPort_Dap1, NvOdmDapPort_I2s1, NV_TRUE} } },
+
+ // Voicecall without Bluetooth
+ { NvOdmDapConnectionIndex_VoiceCall_NoBlueTooth,
+ 3, { {NvOdmDapPort_Dap3, NvOdmDapPort_Dap2, NV_FALSE},
+ {NvOdmDapPort_Dap2, NvOdmDapPort_Dap3, NV_TRUE},
+ {NvOdmDapPort_Dap2, NvOdmDapPort_I2s2, NV_TRUE} } },
+
+ // Voicecall with Bluetooth
+ { NvOdmDapConnectionIndex_VoiceCall_WithBlueTooth,
+ 2, { {NvOdmDapPort_Dap4, NvOdmDapPort_Dap3, NV_TRUE},
+ {NvOdmDapPort_Dap3, NvOdmDapPort_Dap4, NV_FALSE}
+ }},
+
+ };
+ NvU32 TableIndex = 0;
+ NvU32 CustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW:
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX:
+ {
+ for( TableIndex = 0;
+ TableIndex < NV_ARRAY_SIZE(s_Property_Ril_Emp_Rainbow); TableIndex++)
+ {
+ if (s_Property_Ril_Emp_Rainbow[TableIndex].UseIndex == ConnectionIndex)
+ return &s_Property_Ril_Emp_Rainbow[TableIndex];
+ }
+ }
+ break;
+ default:
+ {
+ for( TableIndex = 0; TableIndex < NV_ARRAY_SIZE(s_Property); TableIndex++)
+ {
+ if (s_Property[TableIndex].UseIndex == ConnectionIndex)
+ return &s_Property[TableIndex];
+ }
+ }
+ break;
+ }
+ return NULL;
+}
+
+const NvOdmQuerySpdifInterfaceProperty *
+NvOdmQuerySpdifGetInterfaceProperty(
+ NvU32 SpdifInstanceId)
+{
+ if (SpdifInstanceId == 0)
+ return &s_NvOdmQuerySpdifInterfacePropertySetting;
+
+ return NULL;
+}
+
+const NvOdmQueryAc97InterfaceProperty *
+NvOdmQueryAc97GetInterfaceProperty(
+ NvU32 Ac97InstanceId)
+{
+ return NULL;
+}
+
+const NvOdmQueryI2sACodecInterfaceProp *
+NvOdmQueryGetI2sACodecInterfaceProperty(
+ NvU32 AudioCodecId)
+{
+ static const NvOdmQueryI2sACodecInterfaceProp s_Property =
+ {
+ NV_TRUE,
+ 0,
+ 0x34,
+ NV_FALSE,
+ NvOdmQueryI2sLRLineControl_LeftOnLow,
+ NvOdmQueryI2sDataCommFormat_I2S
+ };
+ if (!AudioCodecId)
+ return &s_Property;
+ return NULL;
+}
+
+NvBool NvOdmQueryAsynchMemConfig(
+ NvU32 ChipSelect,
+ NvOdmAsynchMemConfig *pMemConfig)
+{
+ return NV_FALSE;
+}
+
+const void*
+NvOdmQuerySdramControllerConfigGet(NvU32 *pEntries, NvU32 *pRevision)
+{
+#if NVODM_ENABLE_EMC_DVFS
+ NvOdmBoardInfo BoardInfo;
+
+ if (NvOdmPeripheralGetBoardInfo(BOARD_ID_WHISTLER_E1109, &BoardInfo))
+ {
+ if (pRevision)
+ *pRevision = s_NvOdmE1109EmcConfigTable[0].Revision;
+ if (pEntries)
+ *pEntries = NV_ARRAY_SIZE(s_NvOdmE1109EmcConfigTable);
+ return (const void*)s_NvOdmE1109EmcConfigTable;
+ }
+ else if (NvOdmIsE1108Hynix())
+ {
+ if (pRevision)
+ *pRevision = s_NvOdmE1108HynixEmcConfigTable[0].Revision;
+ if (pEntries)
+ *pEntries = NV_ARRAY_SIZE(s_NvOdmE1108HynixEmcConfigTable);
+ return (const void*)s_NvOdmE1108HynixEmcConfigTable;
+ }
+#endif
+ if (pEntries)
+ *pEntries = 0;
+ return NULL;
+}
+
+NvOdmQueryOscillator NvOdmQueryGetOscillatorSource(void)
+{
+ return NvOdmQueryOscillator_Xtal;
+}
+
+NvU32 NvOdmQueryGetOscillatorDriveStrength(void)
+{
+ return 0x04;
+}
+
+const NvOdmWakeupPadInfo *NvOdmQueryGetWakeupPadTable(NvU32 *pSize)
+{
+ NvU32 CustOpt;
+ if (pSize)
+ *pSize = NV_ARRAY_SIZE(s_NvOdmWakeupPadInfo);
+
+ CustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW:
+ s_NvOdmWakeupPadInfo[24].enable = NV_TRUE;
+ break;
+ case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX:
+ s_NvOdmWakeupPadInfo[13].enable = NV_TRUE;
+ break;
+ default:
+ break;
+ }
+
+ return (const NvOdmWakeupPadInfo *) s_NvOdmWakeupPadInfo;
+}
+
+
+const NvU8* NvOdmQueryManufacturer(void)
+{
+ return s_NvOdmQueryManufacturerSetting;
+}
+
+const NvU8* NvOdmQueryModel(void)
+{
+ return s_NvOdmQueryModelSetting;
+}
+
+const NvU8* NvOdmQueryPlatform(void)
+{
+ return s_NvOdmQueryPlatformSetting;
+}
+
+const NvU8* NvOdmQueryProjectName(void)
+{
+ return s_NvOdmQueryProjectNameSetting;
+}
+
+
+#define EXT 0 // external pull-up/down resistor
+#define INT_PU 1 // internal pull-up
+#define INT_PD 2 // internal pull-down
+
+#define HIGHSPEED 1
+#define SCHMITT 1
+#define VREF 1
+#define OHM_50 3
+#define OHM_100 2
+#define OHM_200 1
+#define OHM_400 0
+
+ // Pin attributes
+ static const NvOdmPinAttrib s_pin_config_attributes[] = {
+
+ { NvOdmPinRegister_Ap20_PullUpDown_A,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_A(0x2, 0x2, 0x2, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0) },
+ // Pull ups for the kbc pins
+ { NvOdmPinRegister_Ap20_PullUpDown_B,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_B(0x0, 0x0, 0x2, 0x0, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) },
+
+ { NvOdmPinRegister_Ap20_PullUpDown_C,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_C(0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0) },
+
+ // Pull ups for the kbc pins
+ { NvOdmPinRegister_Ap20_PullUpDown_E,
+ NVODM_QUERY_PIN_AP20_PULLUPDOWN_E(0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x2) },
+
+ // Set pad control for the sdio2 - - AOCFG1 and AOCFG2 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_AOCFG1PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_AOCFG2PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for the sdio1 - SDIO1 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_SDIO1CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for the sdio3 - SDIO2 and SDIO3 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_SDIO2CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_SDIO3CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for the sdio4- ATCCFG1 and ATCCFG2 pad control register
+ { NvOdmPinRegister_Ap20_PadCtrl_ATCFG1PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_ATCFG2PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for I2C1 pins
+ { NvOdmPinRegister_Ap20_PadCtrl_DBGCFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_VICFG1PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_VICFG2PADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for I2C2 (DDC) pins
+ { NvOdmPinRegister_Ap20_PadCtrl_DDCCFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) },
+
+ // Set pad control for Dap pins 1 - 4
+ { NvOdmPinRegister_Ap20_PadCtrl_DAP1CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_DAP2CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_DAP3CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) },
+
+ { NvOdmPinRegister_Ap20_PadCtrl_DAP3CFGPADCTRL,
+ NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) },
+ };
+
+
+NvU32
+NvOdmQueryPinAttributes(const NvOdmPinAttrib** pPinAttributes)
+{
+ *pPinAttributes = &s_pin_config_attributes[0];
+ return NV_ARRAY_SIZE(s_pin_config_attributes);
+}
+
+NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty)
+{
+#ifdef CONFIG_TEGRA_USB_VBUS_DETECT_BY_PMU
+ pPmuProperty->IrqConnected = NV_TRUE;
+#else
+ pPmuProperty->IrqConnected = NV_FALSE;
+#endif
+ pPmuProperty->PowerGoodCount = 0x7E;
+ pPmuProperty->IrqPolarity = NvOdmInterruptPolarity_Low;
+
+ // Not there yet, add it later ...
+ //pPmuProperty->CpuPowerReqPolarity = ;
+
+ pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_High;
+ pPmuProperty->SysClockReqPolarity = NvOdmSysClockReqPolarity_High;
+ pPmuProperty->CombinedPowerReq = NV_TRUE;
+ pPmuProperty->CpuPowerGoodUs = 2000;
+ pPmuProperty->AccuracyPercent = 3;
+
+ if (NvOdmIsCpuExtSupply() ||
+ NvOdmIsCpuRailPreserved())
+ pPmuProperty->VCpuOTPOnWakeup = NV_FALSE;
+ else
+ pPmuProperty->VCpuOTPOnWakeup = NV_TRUE;
+
+ return NV_TRUE;
+}
+
+/**
+ * Gets the lowest soc power state supported by the hardware
+ *
+ * @returns information about the SocPowerState
+ */
+const NvOdmSocPowerStateInfo* NvOdmQueryLowestSocPowerState(void)
+{
+
+ static NvOdmSocPowerStateInfo PowerStateInfo;
+ const static NvOdmSocPowerStateInfo* pPowerStateInfo = NULL;
+ NvOdmServicesKeyListHandle hKeyList;
+ NvU32 LPStateSelection = 0;
+ if (pPowerStateInfo == NULL)
+ {
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ LPStateSelection = NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ LPStateSelection = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, LPSTATE, LPStateSelection);
+ }
+ // Lowest power state controlled by the flashed custom option.
+ PowerStateInfo.LowestPowerState = ((LPStateSelection != TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1)?
+ NvOdmSocPowerState_Suspend : NvOdmSocPowerState_DeepSleep);
+ pPowerStateInfo = (const NvOdmSocPowerStateInfo*) &PowerStateInfo;
+ }
+ return (pPowerStateInfo);
+}
+
+const NvOdmUsbProperty*
+NvOdmQueryGetUsbProperty(NvOdmIoModule OdmIoModule,
+ NvU32 Instance)
+{
+#ifdef CONFIG_TEGRA_USB_VBUS_DETECT_BY_PMU
+#define NVODM_USE_INTERNAL_PHY_VBUS_DETECTION NV_FALSE
+#else
+#define NVODM_USE_INTERNAL_PHY_VBUS_DETECTION NV_TRUE
+#endif
+ static const NvOdmUsbProperty Usb1Property =
+ {
+ NvOdmUsbInterfaceType_Utmi,
+ (NvOdmUsbChargerType_SE0 | NvOdmUsbChargerType_SE1 | NvOdmUsbChargerType_SK),
+ 20,
+ NVODM_USE_INTERNAL_PHY_VBUS_DETECTION,
+#ifdef CONFIG_USB_TEGRA_OTG
+ NvOdmUsbModeType_OTG,
+#else
+ NvOdmUsbModeType_Device,
+#endif
+ NvOdmUsbIdPinType_CableId,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_FALSE
+ };
+
+ static const NvOdmUsbProperty Usb2Property =
+ {
+ NvOdmUsbInterfaceType_UlpiExternalPhy,
+ NvOdmUsbChargerType_UsbHost,
+ 20,
+ NVODM_USE_INTERNAL_PHY_VBUS_DETECTION,
+ NvOdmUsbModeType_None,
+ NvOdmUsbIdPinType_None,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_FALSE
+ };
+
+ static const NvOdmUsbProperty Usb2NullPhyProperty =
+ {
+ NvOdmUsbInterfaceType_UlpiNullPhy,
+ NvOdmUsbChargerType_UsbHost,
+ 20,
+ NVODM_USE_INTERNAL_PHY_VBUS_DETECTION,
+ NvOdmUsbModeType_Host,
+ NvOdmUsbIdPinType_None,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_FALSE,
+ {10, 1, 1, 1}
+ };
+
+ static const NvOdmUsbProperty Usb3Property =
+ {
+ NvOdmUsbInterfaceType_Utmi,
+ NvOdmUsbChargerType_UsbHost,
+ 20,
+ NVODM_USE_INTERNAL_PHY_VBUS_DETECTION,
+ NvOdmUsbModeType_Host,
+ NvOdmUsbIdPinType_CableId,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_FALSE
+ };
+
+ /* E1108 has no ID pin for USB3, so disable USB3 Host */
+ static const NvOdmUsbProperty Usb3Property_E1108 =
+ {
+ NvOdmUsbInterfaceType_Utmi,
+ NvOdmUsbChargerType_UsbHost,
+ 20,
+ NVODM_USE_INTERNAL_PHY_VBUS_DETECTION,
+ NvOdmUsbModeType_None,
+ NvOdmUsbIdPinType_None,
+ NvOdmUsbConnectorsMuxType_None,
+ NV_FALSE
+ };
+
+ if (OdmIoModule == NvOdmIoModule_Usb && Instance == 0)
+ return &(Usb1Property);
+
+ if (OdmIoModule == NvOdmIoModule_Usb && Instance == 1)
+ {
+ NvU32 CustOpt = GetBctKeyValue();
+
+ if (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt) ==
+ TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI)
+ return &(Usb2NullPhyProperty);
+ else
+ return &(Usb2Property);
+ }
+
+ if (OdmIoModule == NvOdmIoModule_Usb && Instance == 2)
+ {
+ NvOdmBoardInfo BoardInfo;
+ if (NvOdmPeripheralGetBoardInfo(BOARD_ID_WHISTLER_E1108, &BoardInfo))
+ {
+ return &(Usb3Property_E1108);
+ }
+ else
+ {
+ return &(Usb3Property);
+ }
+ }
+
+ return (const NvOdmUsbProperty *)NULL;
+}
+
+const NvOdmQuerySdioInterfaceProperty* NvOdmQueryGetSdioInterfaceProperty(NvU32 Instance)
+{
+ NvU32 CustomerOption = 0;
+ NvU32 Personality = 0;
+ NvOdmServicesKeyListHandle hKeyList;
+ static NvBool s_IsVoyagerBoard = NV_FALSE;
+ NvOdmBoardInfo BoardInfo;
+ static NvBool s_IsBoardInfoDone = NV_FALSE;
+
+ // Detect whether the board is voyager or not
+ if (!s_IsBoardInfoDone)
+ {
+ s_IsVoyagerBoard = NvOdmPeripheralGetBoardInfo(
+ BOARD_ID_VOYAGER_MAINBOARD_E1215, &BoardInfo);
+ s_IsBoardInfoDone = NV_TRUE;
+ }
+
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ CustomerOption =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ Personality =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustomerOption);
+ }
+
+ if (!Personality)
+ Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY;
+
+ if (s_IsVoyagerBoard)
+ return &s_NvOdmQuerySdioInterfaceProperty_Voyager[Instance];
+
+ if (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 ||
+ Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15 ||
+ Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05 ||
+ Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C3)
+ s_NvOdmQuerySdioInterfaceProperty_Whistler[2].IsCardRemovable = NV_TRUE;
+
+ return &s_NvOdmQuerySdioInterfaceProperty_Whistler[Instance];
+}
+
+const NvOdmQueryHsmmcInterfaceProperty* NvOdmQueryGetHsmmcInterfaceProperty(NvU32 Instance)
+{
+ return NULL;
+}
+
+NvU32
+NvOdmQueryGetBlockDeviceSectorSize(NvOdmIoModule OdmIoModule)
+{
+ return 0;
+}
+
+const NvOdmQueryOwrDeviceInfo* NvOdmQueryGetOwrDeviceInfo(NvU32 Instance)
+{
+ return &s_NvOdmQueryOwrInfo;
+}
+
+const NvOdmGpioWakeupSource *NvOdmQueryGetWakeupSources(NvU32 *pCount)
+{
+ *pCount = 0;
+ return NULL;
+}
+
+/**
+ * This function is called from early boot process.
+ * Therefore, it cannot use global variables.
+ */
+NvU32 NvOdmQueryMemSize(NvOdmMemoryType MemType)
+{
+ NvOdmOsOsInfo Info;
+ NvU32 SdramSize;
+ NvU32 SdramBctCustOpt;
+
+ switch (MemType)
+ {
+ // NOTE:
+ // For Windows CE/WM operating systems the total size of SDRAM may
+ // need to be reduced due to limitations in the virtual address map.
+ // Under the legacy physical memory manager, Windows OSs have a
+ // maximum 512MB statically mapped virtual address space. Under the
+ // new physical memory manager, Windows OSs have a maximum 1GB
+ // statically mapped virtual address space. Out of that virtual
+ // address space, the upper 32 or 36 MB (depending upon the SOC)
+ // of the virtual address space is reserved for SOC register
+ // apertures.
+ //
+ // Refer to virtual_tables_apxx.arm for the reserved aperture list.
+ // If the cumulative size of the reserved apertures changes, the
+ // maximum size of SDRAM will also change.
+ case NvOdmMemoryType_Sdram:
+ {
+ SdramBctCustOpt = GetBctKeyValue();
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_SYSTEM, MEMORY, SdramBctCustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1:
+ SdramSize = 0x10000000; //256 MB
+ break;
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_3:
+ SdramSize = 0x40000000; //1GB
+ break;
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_2:
+ case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT:
+ default:
+ SdramSize = 0x20000000; //512 MB
+ break;
+ }
+
+ if ( NvOdmOsGetOsInformation(&Info) &&
+ ((Info.OsType!=NvOdmOsOs_Windows) ||
+ (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) )
+ return SdramSize;
+
+ // Legacy Physical Memory Manager: SdramSize MB - Carveout MB
+ return (SdramSize - NvOdmQueryCarveoutSize());
+ }
+
+ case NvOdmMemoryType_Nor:
+ return 0x00400000; // 4 MB
+
+ case NvOdmMemoryType_Nand:
+ case NvOdmMemoryType_I2CEeprom:
+ case NvOdmMemoryType_Hsmmc:
+ case NvOdmMemoryType_Mio:
+ default:
+ return 0;
+ }
+}
+
+NvU32 NvOdmQueryCarveoutSize(void)
+{
+ NvU32 CarveBctCustOpt = GetBctKeyValue();
+
+ switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CARVEOUT, MEMORY, CarveBctCustOpt))
+ {
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_1:
+ return 0x00400000;// 4MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_2:
+ return 0x00800000;// 8MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_3:
+ return 0x00C00000;// 12MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_4:
+ return 0x01000000;// 16MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_5:
+ return 0x01400000;// 20MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_6:
+ return 0x01800000;// 24MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_7:
+ return 0x01C00000;// 28MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_8:
+ return 0x02000000; // 32 MB
+ case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_DEFAULT:
+ default:
+ return 0x04000000; // 64 MB
+ }
+}
+
+NvU32 NvOdmQuerySecureRegionSize(void)
+{
+ return 0x00800000;// 8 MB
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c
new file mode 100644
index 000000000000..9cf5ddf199a2
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c
@@ -0,0 +1,997 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: The peripheral connectivity database implementation.
+ */
+
+#include "nvcommon.h"
+#include "nvodm_query_gpio.h"
+#include "nvodm_modules.h"
+#include "nvodm_query_discovery.h"
+#include "nvodm_keylist_reserved.h"
+#include "tegra_devkit_custopt.h"
+#include "nvodm_query.h"
+#include "nvrm_drf.h"
+
+#include "subboards/nvodm_query_discovery_e888_addresses.h"
+#include "subboards/nvodm_query_discovery_e906_addresses.h"
+#include "subboards/nvodm_query_discovery_e911_addresses.h"
+#include "subboards/nvodm_query_discovery_e936_addresses.h"
+#include "subboards/nvodm_query_discovery_e951_addresses.h"
+#include "subboards/nvodm_query_discovery_e1109_addresses.h"
+#include "subboards/nvodm_query_discovery_e1116_addresses.h"
+#include "subboards/nvodm_query_discovery_e1120_addresses.h"
+#include "subboards/nvodm_query_discovery_e1129_addresses.h"
+//#include "subboards/nvodm_query_discovery_e1215_addresses.h" // enable with accelerometer bring-up (Voyager)
+
+static NvOdmPeripheralConnectivity s_Peripherals_Default[] =
+{
+#include "subboards/nvodm_query_discovery_e888_peripherals.h"
+#include "subboards/nvodm_query_discovery_e906_peripherals.h"
+#include "subboards/nvodm_query_discovery_e911_peripherals.h"
+#include "subboards/nvodm_query_discovery_e936_peripherals.h"
+#include "subboards/nvodm_query_discovery_e951_peripherals.h"
+#include "subboards/nvodm_query_discovery_e1109_peripherals.h"
+#include "subboards/nvodm_query_discovery_e1116_peripherals.h"
+#include "subboards/nvodm_query_discovery_e1120_peripherals.h"
+#include "subboards/nvodm_query_discovery_e1129_peripherals.h"
+//#include "subboards/nvodm_query_discovery_e1215_peripherals.h" // enable with accelerometer bring-up (Voyager)
+};
+
+// Function to auto-detect boards with external CPU power supply
+// defined in nvodm_query.c
+extern NvBool NvOdmIsCpuExtSupply(void);
+
+#define NVODM_QUERY_BOARD_ID_UNKNOWN 0xFFFF
+
+#define NVODM_QUERY_MAX_PERIPHERALS 0x400
+#define NVODM_QUERY_MAX_IO_ADDRESSES 0x400
+
+#define NVODM_QUERY_MAX_BUS_SEGMENTS 4 // # of Bus Segments defined by I2C extender
+#define NVODM_QUERY_MAX_EEPROMS 8 // Maximum number of EEPROMs per bus segment
+
+#define NVODM_QUERY_ERASED_EEPROM_VALUE 0xFF
+
+#define PROCESSOR_BOARD_ID_I2C_ADDRESS ((0x56)<<1)
+#define PROCESSOR_BOARD_ID_I2C_SEGMENT (0x00)
+
+// The following are used to store entries read from EEPROMs at runtime.
+static NvOdmPeripheralConnectivity s_Peripherals[NVODM_QUERY_MAX_PERIPHERALS];
+static NvOdmIoAddress s_Peripheral_IoAddresses[NVODM_QUERY_MAX_IO_ADDRESSES];
+static NvOdmBoardInfo s_BoardModuleTable[NVODM_QUERY_MAX_BUS_SEGMENTS * NVODM_QUERY_MAX_EEPROMS];
+
+#define NVODM_QUERY_I2C_CLOCK_SPEED 100 // kHz
+
+#define NVODM_QUERY_ENTRY_HEADER_SIZE 0x30 // Size of EERPOM "Entry Header"
+#define NVODM_QUERY_BOARD_HEADER_START 0x04 // Offset to Part Number in EERPOM
+
+#define NVODM_QUERY_I2C_EEPROM_ADDRESS 0xA0 // I2C device base address for EEPROM (7'h50)
+#define NVODM_QUERY_I2C_EXTENDER_ADDRESS 0x42 // I2C bus extender address (7'h21)
+
+#define NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED 10 // See EEPROM_format.txt
+#define NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED 2 // See EEPROM_format.txt
+
+// The following board IDs are used to auto-configure the thermal rail (VOUT15)
+#define BOARD_ID_E1107 0x0B07
+#define BOARD_ID_E1108 0x0B08
+#define BOARD_ID_E1109 0x0B09
+#define BOARD_ID_E1117 0x0B11
+#define BOARD_ID_E951 0x0933
+
+#define PROCESSOR_MODULE_REV_A 0
+
+// A list of the Whistler processor boards
+static NvU32 gs_WhistlerProcessorBoards[] = {
+ BOARD_ID_E1107,
+ BOARD_ID_E1108,
+ BOARD_ID_E1109
+};
+
+// A list of Whistler DDR2 processor boards
+static NvU32 s_WhistlerDDR2Boards[] = {
+ BOARD_ID_E1107,
+ BOARD_ID_E1109,
+ BOARD_ID_E1117
+};
+
+
+static NvOdmI2cStatus
+NvOdmPeripheralI2cRead8(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 I2cAddr,
+ NvU8 Offset,
+ NvU8 *pData)
+{
+ NvU8 ReadBuffer[1];
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ ReadBuffer[0] = Offset;
+
+ TransactionInfo.Address = I2cAddr;
+ TransactionInfo.Buf = ReadBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 1;
+
+ Error = NvOdmI2cTransaction(
+ hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return Error;
+ }
+
+ NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer));
+
+ TransactionInfo.Address = (I2cAddr | 0x1);
+ TransactionInfo.Buf = ReadBuffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = 1;
+
+ // Read data from ROM at the specified offset
+ Error = NvOdmI2cTransaction(
+ hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return Error;
+ }
+ *pData = ReadBuffer[0];
+ return Error;
+}
+
+static NvBool
+NvOdmPeripheralSetBusSegment(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU16 BusSegment)
+{
+ NvU8 WriteBuffer[2];
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+ NvU8 Data;
+
+ Data = (NvU8)(BusSegment & 0xF);
+
+ WriteBuffer[0] = 0x03; // Register (0x03)
+ WriteBuffer[1] = 0x00; // Data
+
+ TransactionInfo.Address = NVODM_QUERY_I2C_EXTENDER_ADDRESS;
+ TransactionInfo.Buf = WriteBuffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = 2;
+
+ Error = NvOdmI2cTransaction(
+ hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+
+ WriteBuffer[0] = 0x01; // Register (0x01)
+ WriteBuffer[1] = Data; // Data (bus segment 0 thru 3)
+
+ Error = NvOdmI2cTransaction(
+ hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadNumPeripherals(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvU8 *pNumModulePeripherals)
+{
+ NvOdmI2cStatus Error;
+ NvU8 I2cAddr, Offset;
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ /**
+ * Offset to numPeripherals in NvOdmPeripheralConnectivity Structure.
+ * It's the first parameter after the "Entry Header."
+ */
+ Offset = NVODM_QUERY_ENTRY_HEADER_SIZE;
+
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, Offset, pNumModulePeripherals);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadPeripheral(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvU8 Peripheral,
+ NvU64 *pGuid,
+ NvU8 *pEepromAddressListOffset,
+ NvU32 *pNumAddress,
+ NvOdmPeripheralClass *pClass)
+{
+ NvOdmI2cStatus Error;
+ NvU32 i;
+ NvU8 ConnMemberIndex=0; // Offset to members in NvOdmPeripheralConnectivity
+ NvU8 I2cAddr, Offset;
+ NvU8 ReadBuffer[NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED];
+ NvU8 NumAddrAndClass;
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ /**
+ * Calculate offset to pGuid in NvOdmPeripheralConnectivity Structure
+ *
+ * Offset = sizeof(eeprom Entry Header) +
+ * sizeof(NvOdmPeripheralConnectivity)*peripheral +
+ * pGuid offset <-- First field, so this is 0
+ */
+ Offset = NVODM_QUERY_ENTRY_HEADER_SIZE +
+ sizeof(NvOdmPeripheralConnectivity)*Peripheral;
+
+ for (i=0; i<NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED; i++)
+ {
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, Offset, (NvU8 *)&ReadBuffer[i]);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ }
+ // Save pGuid entry
+ NvOdmOsMemcpy(pGuid, &ReadBuffer[0], sizeof(NvU64));
+
+ // Save EEPROM offset
+ ConnMemberIndex += sizeof(NvU64); // Increment to next member
+ *pEepromAddressListOffset = ReadBuffer[ConnMemberIndex];
+
+ // Save pNumAddress & Class
+ ConnMemberIndex += sizeof(NvU8); // Increment to next member
+ NumAddrAndClass = ReadBuffer[ConnMemberIndex];
+ *pNumAddress = (NvU32)((NumAddrAndClass >> 3) & 0x0000001F);
+ *pClass = (NvOdmPeripheralClass)(NumAddrAndClass & 0x00000007);
+
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadIoAddressData(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvU8 EepromAddressListOffset,
+ NvOdmIoAddress *pIoAddressEntry)
+{
+ NvOdmI2cStatus Error;
+ NvU32 i;
+ NvU8 I2cAddr;
+ NvU8 ReadBuffer[NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED];
+ NvU16 CompressedIoAddressEntry;
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ for (i=0; i<NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED; i++)
+ {
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, EepromAddressListOffset, (NvU8 *)&ReadBuffer[i]);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ }
+ // Save pIoAddressEntry: interface, instance, address
+ CompressedIoAddressEntry = ((((NvU16)ReadBuffer[1]) << 8) & 0xFF00) | ReadBuffer[0];
+
+ pIoAddressEntry->Interface = (NvOdmIoModule)((CompressedIoAddressEntry >> 11) & 0x1F);
+
+ if (pIoAddressEntry->Interface != NvOdmIoModule_Gpio)
+ {
+ pIoAddressEntry->Instance = (NvU32)((CompressedIoAddressEntry >> 7) & 0xF);
+ pIoAddressEntry->Address = (NvU32)(CompressedIoAddressEntry & 0x7F);
+ }
+ else
+ {
+ pIoAddressEntry->Address = (NvU32)((CompressedIoAddressEntry >> 6) & 0x3F);
+ pIoAddressEntry->Instance = (NvU32)(CompressedIoAddressEntry & 0x3F);
+ }
+
+ return NV_TRUE;
+}
+
+static NvBool NvOdmPeripheralGetEntries(NvU32 *pNum)
+{
+ NvBool RetVal;
+ NvBool IsMatch = NV_FALSE;
+ NvOdmServicesI2cHandle hOdmI2c = NULL;
+ NvU8 BusSegment, EepromInst;
+
+ // Peripheral counters
+ NvU8 NumPeripherals = 0;
+ NvU8 CurrentPeripheral = 0;
+ NvU32 TotalPeripherals = 0;
+ NvU32 StaticPeripherals;
+
+ NvU32 CurrentIoAddressNum = 0;
+ NvU32 TotalIoAddressEntries = 0;
+
+ NvU32 i,j;
+ NvU8 EepromAddressListOffset;
+
+ if (!pNum) {
+ return NV_FALSE;
+ }
+
+ // Auto-detect -- Read I2C-EEPROMs on each sub-board
+
+ hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0);
+ if (!hOdmI2c)
+ return NV_FALSE;
+
+ for (BusSegment=0; BusSegment < NVODM_QUERY_MAX_BUS_SEGMENTS; BusSegment++)
+ {
+ RetVal = NvOdmPeripheralSetBusSegment(hOdmI2c, BusSegment);
+ if (RetVal == NV_FALSE)
+ {
+ /**
+ * Bus segment not found. Set BusSegment to MAX and try reading
+ * any ID EEPROMS which might be available without the bus
+ * expander.
+ */
+ BusSegment = NVODM_QUERY_MAX_BUS_SEGMENTS;
+ }
+
+ for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++)
+ {
+ RetVal = NvOdmPeripheralReadNumPeripherals(
+ hOdmI2c, EepromInst, &NumPeripherals);
+
+ if ( (RetVal == NV_TRUE) &&
+ (NumPeripherals != NVODM_QUERY_ERASED_EEPROM_VALUE) )
+ {
+ if (NumPeripherals > 0)
+ {
+ if ((NumPeripherals + TotalPeripherals) > NVODM_QUERY_MAX_PERIPHERALS)
+ {
+ NV_ASSERT( !"ERROR: s_Peripherals[] is too small to accommodate entries!" );
+
+ // Break out of loop and use static/default configuration
+ break;
+ }
+
+ for (CurrentPeripheral=0; \
+ CurrentPeripheral < NumPeripherals; \
+ CurrentPeripheral++)
+ {
+ RetVal = NvOdmPeripheralReadPeripheral(
+ hOdmI2c,
+ EepromInst,
+ CurrentPeripheral,
+ &s_Peripherals[TotalPeripherals+CurrentPeripheral].Guid,
+ &EepromAddressListOffset,
+ &s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress,
+ &s_Peripherals[TotalPeripherals+CurrentPeripheral].Class);
+
+ if (RetVal == NV_FALSE)
+ {
+ NV_ASSERT(!"Unable to read EEPROM peripheral entry!");
+ break; // Go to next EEPROM
+ }
+ else // Process peripheral entry
+ {
+ /**
+ * Process NvOdmIoAddress arrays --
+ *
+ * These are separate data structures. The addressList value
+ * read from the EEPROM (EepromAddressListOffset) represents
+ * an offset address within the I2C-EEPROM. This offset value
+ * identifies where to find the first instance of the
+ * NvOdmIoAddress data.
+ *
+ * The total number of NvOdmIoAddress entries is identified
+ * by the numAddress variable following the addressList entry
+ * in EEPROM.
+ *
+ * Once the offset and number of entries are determined (from
+ * above NvOdmPeripheralReadPeripheral function call), a loop
+ * fills in entries within the fixed storage area
+ * (e.g., s_Peripheral_IoAddresses) and the actual
+ * addressList pointer is assigned a value that corresponds
+ * to the first entry of the current class within this array.
+ * In other words, there might be prior entries in the
+ * s_Peripheral_IoAddresses array, but the first entry
+ * corresponding to the current class might be the third
+ * element in this array. Therefore, the actual addressList
+ * pointer for the current NvOdmPeripheralConnectivity.addressList
+ * parameter would be the address of the third entry, which is
+ * &s_Peripheral_IoAddresses[2] in this example.
+ */
+
+ // Read all of the entries and save them in s_Peripheral_IoAddresses
+ for (CurrentIoAddressNum=0; \
+ CurrentIoAddressNum < s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress; \
+ CurrentIoAddressNum++)
+ {
+ if (TotalIoAddressEntries > NVODM_QUERY_MAX_IO_ADDRESSES)
+ {
+ NV_ASSERT( !"ERROR: s_Peripheral_IoAddresses[] is too small to accommodate entries!" );
+
+ // Cannot recover from this error.
+ NvOdmI2cClose(hOdmI2c);
+ return NV_FALSE;
+ }
+
+ RetVal = NvOdmPeripheralReadIoAddressData(
+ hOdmI2c,
+ EepromInst,
+ EepromAddressListOffset,
+ &s_Peripheral_IoAddresses[TotalIoAddressEntries+CurrentIoAddressNum]);
+
+ if (RetVal == NV_FALSE)
+ {
+ NV_ASSERT(!"Unable to read EEPROM (IoAddresses)!");
+
+ // Cannot recover from this error.
+ NvOdmI2cClose(hOdmI2c);
+ return NV_FALSE;
+ }
+ else // Process IoAddresses entry
+ {
+ /**
+ * Save the addressList pointer. This points to the first
+ * IoAddresses entry of this class. Then update the overall
+ * IoAddresses array counter (TotalIoAddressEntries).
+ */
+ s_Peripherals[TotalPeripherals+CurrentPeripheral].AddressList =
+ &s_Peripheral_IoAddresses[TotalIoAddressEntries];
+
+ TotalIoAddressEntries += CurrentIoAddressNum;
+
+ // >-- End of NvOdmIoAddress array processing --<
+ }
+ }
+ }
+ }
+ }
+ TotalPeripherals += NumPeripherals;
+ }
+ }
+ }
+
+ // Done reading I2C-EEPROM; close it.
+ NvOdmI2cClose(hOdmI2c);
+
+ /**
+ * Append static peripheral entries (if any) to dynamic list
+ * read from EEPROMs (this list may also be empty), except for
+ * duplicate GUIDs. The dynamic list takes precedence when
+ * duplicate entries are found in the static list.
+ */
+ StaticPeripherals = NV_ARRAY_SIZE(s_Peripherals_Default);
+ for (i=0; i<StaticPeripherals; i++)
+ {
+ for (j=0; j<TotalPeripherals; j++)
+ {
+ if (s_Peripherals_Default[i].Guid == s_Peripherals[j].Guid)
+ {
+ IsMatch = NV_TRUE;
+ break; // Ignore duplicate entry from static list.
+ }
+ }
+ if (IsMatch != NV_TRUE)
+ {
+ // Append unique entry to dynamic list
+
+ s_Peripherals[TotalPeripherals].Guid =
+ s_Peripherals_Default[i].Guid;
+
+ s_Peripherals[TotalPeripherals].AddressList =
+ s_Peripherals_Default[i].AddressList;
+
+ s_Peripherals[TotalPeripherals].NumAddress =
+ s_Peripherals_Default[i].NumAddress;
+
+ s_Peripherals[TotalPeripherals].Class =
+ s_Peripherals_Default[i].Class;
+
+ // Overwrite DDR IO rail address list for DDR2 board
+ if (s_Peripherals_Default[i].Guid == NV_VDD_DDR_ODM_ID)
+ {
+ NvU32 k;
+ NvOdmBoardInfo BoardInfo;
+ for (k = 0; k < NV_ARRAY_SIZE(s_WhistlerDDR2Boards); k++)
+ {
+ if (NvOdmPeripheralGetBoardInfo(
+ s_WhistlerDDR2Boards[k], &BoardInfo))
+ {
+ s_Peripherals[TotalPeripherals].AddressList =
+ s_ffaVddDdr2Addresses;
+ break;
+ }
+ }
+ }
+
+ // Overwrite CPU rail address list for board with external DCDC
+ if (s_Peripherals_Default[i].Guid == NV_VDD_CPU_ODM_ID)
+ {
+ if (NvOdmIsCpuExtSupply())
+ {
+ s_Peripherals[TotalPeripherals].AddressList =
+ s_ffaCpuExtSupplyAddresses;
+ NV_ASSERT(s_Peripherals[TotalPeripherals].NumAddress ==
+ NV_ARRAY_SIZE(s_ffaCpuExtSupplyAddresses));
+ }
+ }
+ TotalPeripherals++;
+ }
+ }
+ *pNum = TotalPeripherals;
+ return NV_TRUE;
+}
+
+static NvBool
+NvOdmPeripheralReadPartNumber(
+ NvOdmServicesI2cHandle hOdmI2c,
+ NvU8 EepromInst,
+ NvOdmBoardInfo *pBoardInfo)
+{
+ NvOdmI2cStatus Error;
+ NvU32 i;
+ NvU8 I2cAddr, Offset;
+ NvU8 ReadBuffer[sizeof(NvOdmBoardInfo)];
+
+ NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer));
+
+ // EepromInst*2, since 7-bit addressing
+ I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1);
+
+ /**
+ * Offset to the board number entry in EEPROM.
+ */
+ Offset = NVODM_QUERY_BOARD_HEADER_START;
+
+ for (i=0; i<sizeof(NvOdmBoardInfo); i++)
+ {
+ Error = NvOdmPeripheralI2cRead8(
+ hOdmI2c, I2cAddr, Offset+i, (NvU8 *)&ReadBuffer[i]);
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ return NV_FALSE;
+ }
+ }
+ NvOdmOsMemcpy(pBoardInfo, &ReadBuffer[0], sizeof(NvOdmBoardInfo));
+ return NV_TRUE;
+}
+
+NvBool
+NvOdmPeripheralGetBoardInfo(
+ NvU16 BoardId,
+ NvOdmBoardInfo *pBoardInfo)
+{
+ NvBool RetVal = NV_FALSE;
+ NvOdmServicesI2cHandle hOdmI2c = NULL;
+ NvU8 BusSegment, EepromInst, CurrentBoard;
+ static NvU8 NumBoards = 0;
+ static NvBool s_ReadBoardInfoDone = NV_FALSE;
+
+ if (!s_ReadBoardInfoDone)
+ {
+ s_ReadBoardInfoDone = NV_TRUE;
+ hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0);
+ if (!hOdmI2c)
+ {
+ // Exit
+ pBoardInfo = NULL;
+ return NV_FALSE;
+ }
+
+ for (BusSegment=0; BusSegment < NVODM_QUERY_MAX_BUS_SEGMENTS; BusSegment++)
+ {
+ RetVal = NvOdmPeripheralSetBusSegment(hOdmI2c, BusSegment);
+ if (RetVal == NV_FALSE)
+ {
+ /**
+ * Bus segment not found. Set BusSegment to MAX and try reading
+ * any ID EEPROMS which might be available without the bus
+ * expander.
+ */
+ BusSegment = NVODM_QUERY_MAX_BUS_SEGMENTS;
+ }
+
+ for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++)
+ {
+ RetVal = NvOdmPeripheralReadPartNumber(
+ hOdmI2c, EepromInst, &s_BoardModuleTable[NumBoards]);
+ if (RetVal == NV_TRUE)
+ NumBoards++;
+ }
+ }
+ NvOdmI2cClose(hOdmI2c);
+ }
+
+ if (NumBoards)
+ {
+ // Linear search for given BoardId; if found, return entry
+ for (CurrentBoard=0; CurrentBoard < NumBoards; CurrentBoard++)
+ {
+ if (s_BoardModuleTable[CurrentBoard].BoardID == BoardId)
+ {
+ // Match found
+ pBoardInfo->BoardID = s_BoardModuleTable[CurrentBoard].BoardID;
+ pBoardInfo->SKU = s_BoardModuleTable[CurrentBoard].SKU;
+ pBoardInfo->Fab = s_BoardModuleTable[CurrentBoard].Fab;
+ pBoardInfo->Revision = s_BoardModuleTable[CurrentBoard].Revision;
+ return NV_TRUE;
+ }
+ }
+ }
+
+ // Match not found
+ pBoardInfo = NULL;
+ return NV_FALSE;
+}
+
+// This will compare the peripheral GUID against a list of known-bad GUIDs
+// for certain development kit personalities, and return NV_TRUE if it is
+// known to be unsupported (filtered) on the current configuration
+static NvBool
+NvIsFilteredPeripheral(const NvOdmPeripheralConnectivity* pConnectivity)
+{
+ NvOdmServicesKeyListHandle hKeyList;
+ NvU32 CustOpt = 0;
+ NvU32 Personality = 0;
+ NvU32 opt = 0;
+ NvU32 ril = 0;
+ NvOdmIoModule OdmModule;
+ const NvU32 *OdmConfigs=NULL;
+ NvU32 NumOdmConfigs = 0;
+ const NvOdmPeripheralConnectivity* pFilteredPeriph = pConnectivity;
+ NvOdmBoardInfo BoardInfo;
+ NvU32 i, TotalBoards;
+ NvBool status = NV_FALSE;
+
+ if((!pConnectivity) || (!pConnectivity->NumAddress))
+ return NV_TRUE;
+
+ if (pConnectivity->Guid == NV_ODM_GUID('a','d','t','7','4','6','1',' '))
+ {
+ /**
+ * The following board detection is used to keep thermal rail
+ * (VOUT15) disabled for certain board SKUs where the board ID
+ * ROMs cannot be read when the thermal rail is enabled.
+ */
+ TotalBoards = NV_ARRAY_SIZE(gs_WhistlerProcessorBoards);
+
+ // Scan for processor boards
+ for (i=0; i<TotalBoards; i++)
+ {
+ if ( NvOdmPeripheralGetBoardInfo(gs_WhistlerProcessorBoards[i], &BoardInfo) )
+ {
+ // Found the processor module
+ if (BoardInfo.Fab == PROCESSOR_MODULE_REV_A)
+ {
+ // Filter out this peripheral for REV_A processor modules
+ return NV_TRUE;
+ }
+ }
+ }
+ }
+
+ if (pConnectivity->Guid == NV_ODM_GUID('b','l','u','t','o','o','t','h'))
+ {
+ /**
+ * The following board detection is used to detect presence of Bluetooth Chip.
+ * In case of whistler only ossibility is having E951 board.
+ */
+ status = NvOdmPeripheralGetBoardInfo((BOARD_ID_E951), &BoardInfo);
+ if(NV_TRUE == status)
+ {
+ return NV_FALSE; // BT module found; don't filter it.
+ }else
+ {
+ return NV_TRUE; // BT module not found; filter the BT peripheral.
+ }
+ }
+
+ hKeyList = NvOdmServicesKeyListOpen();
+
+ if (hKeyList)
+ {
+ CustOpt =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ Personality =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustOpt);
+ opt =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, DISPLAY_OPTION, CustOpt);
+ ril =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt);
+ }
+
+ if (pConnectivity->Guid == NV_ODM_GUID('e','m','p',' ','_','m','d','m'))
+ {
+ if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW)
+ {
+ return NV_FALSE; // EMP RAINBOW supported - don't filter it
+ }
+ else
+ {
+ return NV_TRUE; // EMP RAINBOW not supported - filter it
+ }
+ }
+
+ if (pConnectivity->Guid == NV_ODM_GUID('e','m','p',' ','M','5','7','0'))
+ {
+ if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI)
+ {
+ return NV_FALSE; // EMP RAINBOW ULPI supported - don't filter it
+ }
+ else
+ {
+ return NV_TRUE; // EMP RAINBOW ULPI not supported - filter it
+ }
+ }
+
+ if (pConnectivity->Guid == NV_ODM_GUID('s','p','i',' ','_','i','p','c'))
+ {
+ if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX)
+ {
+ return NV_FALSE; // IFX supported - don't filter it
+ }
+ else
+ {
+ return NV_TRUE; // IFX not supported - filter it
+ }
+ }
+
+
+ if (!Personality)
+ Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY;
+
+ OdmModule = pFilteredPeriph->AddressList[0].Interface;
+
+ if(OdmModule != NvOdmIoModule_Gpio)
+ NvOdmQueryPinMux(OdmModule, &OdmConfigs, &NumOdmConfigs);
+
+ switch (OdmModule)
+ {
+ case NvOdmIoModule_Gpio:
+ // Filter scroll wheel when trace is enabled
+ if ( (pConnectivity->Guid == NV_ODM_GUID('s','c','r','o','l','w','h','l')) &&
+ ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) )
+ return NV_TRUE;
+ else
+ return NV_FALSE;
+
+ default:
+ return NV_FALSE;
+ }
+}
+
+static const NvOdmPeripheralConnectivity*
+NvApGetAllPeripherals (NvU32 *pNum)
+{
+ static NvBool s_AutoDetectDone = NV_FALSE;
+ NvBool RetVal = NV_TRUE;
+ static NvU32 s_TotalPeripherals;
+ NvOdmBoardInfo BoardInfo;
+
+ if (!pNum)
+ return NULL;
+
+ if (!s_AutoDetectDone)
+ {
+ /**
+ * Read & cache the board ID info from the I2C-EEPROMs. This
+ * is necessary because once Whistler's thermal power rail is
+ * enabled, the ID ROMs cannot be read. NvApGetAllPeripherals()
+ * is called before that rail is enabled.
+ */
+ NvOdmPeripheralGetBoardInfo(NVODM_QUERY_BOARD_ID_UNKNOWN, &BoardInfo);
+
+ RetVal = NvOdmPeripheralGetEntries(&s_TotalPeripherals);
+ if (RetVal == NV_FALSE)
+ {
+ *pNum = 0;
+ return NULL;
+ }
+ s_AutoDetectDone = NV_TRUE;
+ }
+
+ *pNum = s_TotalPeripherals;
+ return (const NvOdmPeripheralConnectivity *)s_Peripherals;
+}
+
+// This implements a simple linear search across the entire set of currently-
+// connected peripherals to find the set of GUIDs that Match the search
+// criteria. More clever implementations are possible, but given the
+// relatively small search space (max dozens of peripherals) and the relative
+// infrequency of enumerating peripherals, this is the easiest implementation.
+const NvOdmPeripheralConnectivity *
+NvOdmPeripheralGetGuid(NvU64 SearchGuid)
+{
+ const NvOdmPeripheralConnectivity *pAllPeripherals;
+ NvU32 NumPeripherals;
+ NvU32 i;
+
+ pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals);
+
+ if (!pAllPeripherals || !NumPeripherals)
+ return NULL;
+
+ for (i=0; i<NumPeripherals; i++)
+ {
+ if (SearchGuid == pAllPeripherals[i].Guid)
+ {
+ if (NvIsFilteredPeripheral(&pAllPeripherals[i]))
+ return NULL;
+ return &pAllPeripherals[i];
+ }
+ }
+
+ return NULL;
+}
+
+static NvBool
+IsBusMatch(
+ const NvOdmPeripheralConnectivity *pPeriph,
+ const NvOdmPeripheralSearch *pSearchAttrs,
+ const NvU32 *pSearchVals,
+ NvU32 offset,
+ NvU32 NumAttrs)
+{
+ NvU32 i, j;
+ NvBool IsMatch = NV_FALSE;
+
+ for (i=0; i<pPeriph->NumAddress; i++)
+ {
+ j = offset;
+ do
+ {
+ switch (pSearchAttrs[j])
+ {
+ case NvOdmPeripheralSearch_IoModule:
+ IsMatch = (pSearchVals[j] ==
+ (NvU32)(pPeriph->AddressList[i].Interface));
+ break;
+ case NvOdmPeripheralSearch_Address:
+ IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Address);
+ break;
+ case NvOdmPeripheralSearch_Instance:
+ IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Instance);
+ break;
+ case NvOdmPeripheralSearch_PeripheralClass:
+ default:
+ NV_ASSERT(!"Bad Query!");
+ break;
+ }
+ j++;
+ } while (IsMatch && j<NumAttrs &&
+ pSearchAttrs[j]!=NvOdmPeripheralSearch_IoModule);
+
+ if (IsMatch)
+ {
+ return NV_TRUE;
+ }
+ }
+ return NV_FALSE;
+}
+
+static NvBool
+IsPeripheralMatch(
+ const NvOdmPeripheralConnectivity *pPeriph,
+ const NvOdmPeripheralSearch *pSearchAttrs,
+ const NvU32 *pSearchVals,
+ NvU32 NumAttrs)
+{
+ NvU32 i;
+ NvBool IsMatch = NV_TRUE;
+
+ for (i=0; i<NumAttrs && IsMatch; i++)
+ {
+ switch (pSearchAttrs[i])
+ {
+ case NvOdmPeripheralSearch_PeripheralClass:
+ IsMatch = (pSearchVals[i] == (NvU32)(pPeriph->Class));
+ break;
+ case NvOdmPeripheralSearch_IoModule:
+ IsMatch = IsBusMatch(pPeriph, pSearchAttrs, pSearchVals, i, NumAttrs);
+ break;
+ case NvOdmPeripheralSearch_Address:
+ case NvOdmPeripheralSearch_Instance:
+ // In correctly-formed searches, these parameters will be parsed by
+ // IsBusMatch, so we ignore them here.
+ break;
+ default:
+ NV_ASSERT(!"Bad search attribute!");
+ break;
+ }
+ }
+ return IsMatch;
+}
+
+NvU32
+NvOdmPeripheralEnumerate(
+ const NvOdmPeripheralSearch *pSearchAttrs,
+ const NvU32 *pSearchVals,
+ NvU32 NumAttrs,
+ NvU64 *pGuidList,
+ NvU32 NumGuids)
+{
+ const NvOdmPeripheralConnectivity *pAllPeripherals;
+ NvU32 NumPeripherals;
+ NvU32 Matches;
+ NvU32 i;
+
+ pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals);
+
+ if (!pAllPeripherals || !NumPeripherals)
+ {
+ return 0;
+ }
+
+ if (!pSearchAttrs || !pSearchVals)
+ {
+ NumAttrs = 0;
+ }
+
+ for (i=0, Matches=0; i<NumPeripherals &&
+ (Matches < NumGuids || !pGuidList); i++)
+ {
+ if ( !NumAttrs || IsPeripheralMatch(&pAllPeripherals[i],
+ pSearchAttrs, pSearchVals,
+ NumAttrs) )
+ {
+ if (NvIsFilteredPeripheral(&pAllPeripherals[i]))
+ continue;
+
+ if (pGuidList)
+ pGuidList[Matches] = pAllPeripherals[i].Guid;
+ Matches++;
+ }
+ }
+ return Matches;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c
new file mode 100644
index 000000000000..eea1843af763
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nvodm_query_gpio.h"
+#include "nvodm_services.h"
+#include "tegra_devkit_custopt.h"
+#include "nvodm_keylist_reserved.h"
+#include "nvrm_drf.h"
+
+#define NVODM_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define NVODM_PORT(x) ((x) - 'a')
+
+static const NvOdmGpioPinInfo s_vi[] = {
+ {NVODM_PORT('t'), 3, NvOdmGpioPinActiveState_High},
+};
+
+static const NvOdmGpioPinInfo s_display[] = {
+ /* Panel 0 -- sony vga */
+ { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('j'), 3, NvOdmGpioPinActiveState_Low },
+ { NVODM_PORT('j'), 4, NvOdmGpioPinActiveState_Low },
+ // this pin is not needed for ap15
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+
+ /* Panel 1 -- samtek */
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+ {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN,
+ NvOdmGpioPinActiveState_Low},
+
+ /* Panel 2 -- sharp wvga */
+ { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low },
+
+ /* Panel 3 -- sharp qvga */
+ { NVODM_PORT('n'), 6, NvOdmGpioPinActiveState_High }, // LCD_DC0
+ { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low }, // LCD_CS0
+ { NVODM_PORT('b'), 3, NvOdmGpioPinActiveState_Low }, // LCD_PCLK
+ { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low }, // LCD_PWR0
+ { NVODM_PORT('e'), 0, NvOdmGpioPinActiveState_High }, // LCD_D0
+ { NVODM_PORT('e'), 1, NvOdmGpioPinActiveState_High }, // LCD_D1
+ { NVODM_PORT('e'), 2, NvOdmGpioPinActiveState_High }, // LCD_D2
+ { NVODM_PORT('e'), 3, NvOdmGpioPinActiveState_High }, // LCD_D3
+ { NVODM_PORT('e'), 4, NvOdmGpioPinActiveState_High }, // LCD_D4
+ { NVODM_PORT('e'), 5, NvOdmGpioPinActiveState_High }, // LCD_D5
+ { NVODM_PORT('e'), 6, NvOdmGpioPinActiveState_High }, // LCD_D6
+ { NVODM_PORT('e'), 7, NvOdmGpioPinActiveState_High }, // LCD_D7
+ { NVODM_PORT('f'), 0, NvOdmGpioPinActiveState_High }, // LCD_D8
+ { NVODM_PORT('f'), 1, NvOdmGpioPinActiveState_High }, // LCD_D9
+ { NVODM_PORT('f'), 2, NvOdmGpioPinActiveState_High }, // LCD_D10
+ { NVODM_PORT('f'), 3, NvOdmGpioPinActiveState_High }, // LCD_D11
+ { NVODM_PORT('f'), 4, NvOdmGpioPinActiveState_High }, // LCD_D12
+ { NVODM_PORT('f'), 5, NvOdmGpioPinActiveState_High }, // LCD_D13
+ { NVODM_PORT('f'), 6, NvOdmGpioPinActiveState_High }, // LCD_D14
+ { NVODM_PORT('f'), 7, NvOdmGpioPinActiveState_High }, // LCD_D15
+ { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_High }, // LCD_D19
+
+ /* Panel 4 -- auo */
+ { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low },
+};
+
+static const NvOdmGpioPinInfo s_Sdio2[] = {
+ {NVODM_PORT('i'), 5, NvOdmGpioPinActiveState_Low}, // Card Detect for SDIO instance 2
+ /* High for WP and low for read/write */
+ {NVODM_PORT('v'), 5, NvOdmGpioPinActiveState_High}, // Write Protect for SDIO instance 2
+};
+
+static const NvOdmGpioPinInfo s_NandFlash[] = {
+ {NVODM_PORT('c'), 7, NvOdmGpioPinActiveState_High}, // MICRO SD_CD#
+};
+
+static const NvOdmGpioPinInfo s_spi_ethernet[] = {
+ {NVODM_PORT('c'), 1, NvOdmGpioPinActiveState_Low} // SPI_ENET_IRQ (EMC_INT)
+};
+
+static const NvOdmGpioPinInfo s_ScrollWheel[] = {
+ {NVODM_PORT('q'), 4, NvOdmGpioPinActiveState_Low}, // Scroll wheel -QP1 (terminal 1)
+ {NVODM_PORT('r'), 3, NvOdmGpioPinActiveState_Low}, // Scroll wheel_ONOFF
+ {NVODM_PORT('q'), 5, NvOdmGpioPinActiveState_Low}, // Scroll wheel -SELECT (terminal 3)
+ {NVODM_PORT('q'), 3, NvOdmGpioPinActiveState_Low}, // Scroll wheel -QP2 (terminal 4)
+};
+
+static const NvOdmGpioPinInfo s_ScrollWheel_TraceMode[] = {
+ {NVODM_PORT('r'), 3, NvOdmGpioPinActiveState_Low}, // Scroll wheel_ONOFF
+};
+
+static const NvOdmGpioPinInfo s_Bluetooth[] = {
+ {NVODM_PORT('u'), 0, NvOdmGpioPinActiveState_Low}, // Bluetooth Controls: BT_RST
+};
+
+static const NvOdmGpioPinInfo s_Wlan[] = {
+ {NVODM_PORT('k'), 5, NvOdmGpioPinActiveState_Low}, // WLAN-OFF
+ {NVODM_PORT('k'), 6, NvOdmGpioPinActiveState_Low}, // WLAN-RESET
+};
+
+static const NvOdmGpioPinInfo s_hdmi[] =
+{
+ /* hdmi hot-plug interrupt pin */
+ { NVODM_PORT('n'), 7, NvOdmGpioPinActiveState_High},
+};
+
+const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
+ NvU32 Instance, NvU32 *pCount)
+{
+ NvU32 CustomerOption = 0;
+ NvU32 Personality = 0;
+ NvOdmServicesKeyListHandle hKeyList;
+
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ CustomerOption =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ Personality =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustomerOption);
+ }
+
+ if (!Personality)
+ Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY;
+
+ switch (Group)
+ {
+ case NvOdmGpioPinGroup_Display:
+ *pCount = NVODM_ARRAY_SIZE(s_display);
+ return s_display;
+
+ case NvOdmGpioPinGroup_Sdio:
+ if (Instance == 2)
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_Sdio2);
+ return s_Sdio2;
+ }
+ else
+ {
+ *pCount = 0;
+ return NULL;
+ }
+
+ case NvOdmGpioPinGroup_ScrollWheel:
+ if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1))
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_ScrollWheel_TraceMode);
+ return s_ScrollWheel_TraceMode;
+ }
+ else
+ {
+ *pCount = NVODM_ARRAY_SIZE(s_ScrollWheel);
+ return s_ScrollWheel;
+ }
+
+ case NvOdmGpioPinGroup_NandFlash:
+ *pCount = NVODM_ARRAY_SIZE(s_NandFlash);
+ return s_NandFlash;
+
+ case NvOdmGpioPinGroup_Bluetooth:
+ *pCount = NVODM_ARRAY_SIZE(s_Bluetooth);
+ return s_Bluetooth;
+
+ case NvOdmGpioPinGroup_Wlan:
+ *pCount = NVODM_ARRAY_SIZE(s_Wlan);
+ return s_Wlan;
+
+ case NvOdmGpioPinGroup_SpiEthernet:
+ *pCount = NVODM_ARRAY_SIZE(s_spi_ethernet);
+ return s_spi_ethernet;
+ case NvOdmGpioPinGroup_Vi:
+ *pCount = NVODM_ARRAY_SIZE(s_vi);
+ return s_vi;
+ case NvOdmGpioPinGroup_Hdmi:
+ *pCount = NVODM_ARRAY_SIZE(s_hdmi);
+ return s_hdmi;
+
+ default:
+ *pCount = 0;
+ return NULL;
+ }
+}
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c
new file mode 100644
index 000000000000..1781b6f0ed99
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>NVIDIA Driver Development Kit:
+ * ODM Kbc interface</b>
+ *
+ */
+
+#include "nvodm_query_kbc.h"
+
+static NvU32 *RowNumbers = NULL;
+static NvU32 *ColNumbers = NULL;
+
+void
+NvOdmKbcGetParameter(
+ NvOdmKbcParameter Param,
+ NvU32 SizeOfValue,
+ void * pValue)
+{
+ NvU32 *pTempVar;
+ switch (Param)
+ {
+ case NvOdmKbcParameter_DebounceTime:
+ pTempVar = (NvU32 *)pValue;
+ *pTempVar = 10;
+ break;
+ case NvOdmKbcParameter_RepeatCycleTime:
+ pTempVar = (NvU32 *)pValue;
+ *pTempVar = 32;
+ break;
+ default:
+ break;
+ }
+}
+
+NvU32
+NvOdmKbcGetKeyCode(
+ NvU32 Row,
+ NvU32 Column,
+ NvU32 RowCount,
+ NvU32 ColumnCount)
+{
+ return ((Row * ColumnCount) + Column);
+}
+
+NvBool
+NvOdmKbcIsSelectKeysWkUpEnabled(
+ NvU32 **pRowNumber,
+ NvU32 **pColNumber,
+ NvU32 *NumOfKeys)
+{
+ *pRowNumber = RowNumbers;
+ *pColNumber = ColNumbers;
+ *NumOfKeys = 0;
+ return NV_FALSE;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h
new file mode 100644
index 000000000000..40b0664eeee1
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2007-2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * The KBC GPIO pin definitions</b>
+ *
+ * @b Description: Define the KBC GPIO pins in row and column numbers.
+ */
+
+#ifndef NVODM_QUERY_KBC_GPIO_DEF_H
+#define NVODM_QUERY_KBC_GPIO_DEF_H
+
+typedef enum
+{
+ NvOdmKbcGpioPin_KBRow0 = 0,
+ NvOdmKbcGpioPin_KBRow1,
+ NvOdmKbcGpioPin_KBRow2,
+ NvOdmKbcGpioPin_KBRow3,
+ NvOdmKbcGpioPin_KBRow4,
+ NvOdmKbcGpioPin_KBRow5,
+ NvOdmKbcGpioPin_KBRow6,
+ NvOdmKbcGpioPin_KBRow7,
+ NvOdmKbcGpioPin_KBRow8,
+ NvOdmKbcGpioPin_KBRow9,
+ NvOdmKbcGpioPin_KBRow10,
+ NvOdmKbcGpioPin_KBRow11,
+ NvOdmKbcGpioPin_KBRow12,
+ NvOdmKbcGpioPin_KBRow13,
+ NvOdmKbcGpioPin_KBRow14,
+ NvOdmKbcGpioPin_KBRow15,
+ NvOdmKbcGpioPin_KBCol0,
+ NvOdmKbcGpioPin_KBCol1,
+ NvOdmKbcGpioPin_KBCol2,
+ NvOdmKbcGpioPin_KBCol3,
+ NvOdmKbcGpioPin_KBCol4,
+ NvOdmKbcGpioPin_KBCol5,
+ NvOdmKbcGpioPin_KBCol6,
+ NvOdmKbcGpioPin_KBCol7,
+ NvOdmKbcGpioPin_Num,
+ NvOdmKbcGpioPin_Force32 = 0x7FFFFFFF
+}NvOdmKbcGpioPin;
+
+#endif // NVODM_QUERY_KBC_GPIO_DEF_H
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c
new file mode 100644
index 000000000000..1b7519c77434
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * @brief <b>NVIDIA Driver Development Kit:
+ * ODM Uart interface</b>
+ *
+ * @b Description: Implements the ODM for the Uart communication.
+ *
+ */
+
+#include "nvodm_query_nand.h"
+#include "nvcommon.h"
+
+// fill params for all required nand flashes here.
+// this list will end when vendor id and chipd id will be zero.
+// hence, all supported chips should be listed before that.
+NvOdmNandFlashParams g_Params[] =
+{
+ /*
+ {
+ VendorId, DeviceId, NandType, IsCopyBackCommandSupported, IsCacheWriteSupported, CapacityInMB, ZonesPerDevice,
+ BlocksPerZone, OperationSuccessStatus, InterleaveCapability, EccAlgorithm,
+ ErrorsCorrectable, SkippedSpareBytes,
+ TRP, TRH (TREH), TWP, TWH, TCS, TWHR, TWB, TREA, TADL,
+ TCLS, TCLH, TCH, TALS, TALH, TRC, TWC, TCR(TCLR), TAR, TRR, NandDeviceType, ReadIdFourthByte
+ }
+ Note :
+ TADL values for flashes K9F1G08Q0M, K9F1G08U0M, TH58NVG4D4CTG00,
+ TH58NVG3D4BTG00, TH58NVG2S3BFT00 is not available from their data sheets.
+ Hence TADL is computed as
+ tADL = (tALH + tALS + tWP).
+ */
+ // filling odm parameter structure for Samsung K9K8G08U0M
+ {
+ 0xEC, 0xD3, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 1024, 4,
+ 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 20, 60, 100, 26, 70,
+ 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x95
+ },
+ // filling odm parameter structure for Samsung K9W8G08U1M
+ {
+ 0xEC, 0xDC, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 1024, 2,
+ 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 15, 60, 100, 18, 100,
+ 10, 5, 5, 10, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // filling odm parameter structure for Samsung K9F1G08Q0M
+ {
+ 0xEC, 0xA1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1,
+ 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 60, 20, 60, 20, 0, 60, 100, 60, 70,
+ 0, 10, 10, 0, 10, 80, 80, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // filling odm parameter structure for Samsung K9F1G08U0M
+ {
+ 0xEC, 0xF1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 15, 25, 15, 0, 60, 100, 30, 35,
+ 0, 10, 10, 0, 10, 50, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // filling odm parameter structure for Samsung K9L8G08U0M
+ {
+ 0xEC, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 1024, 4,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 20, 60, 100, 20, 35,
+ 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Samsung K9G4G08U0M
+ {
+ 0xEC, 0xDC, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 512, 2,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 15, 15, 60, 100, 18, 50,
+ 10, 5, 5, 10, 5, 30, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Samsung K5E2G1GACM
+ {
+ 0xEC, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 2,
+ 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 21, 15, 21, 15, 31, 60, 100, 30, 100,
+ 21, 5, 5, 21, 5, 42, 42, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15
+ },
+/*
+ // filling odm parameter structure for Toshiba TH58NVG4D4CTG00
+ {
+ 0x98, 0xD5, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 2048, 1,
+ 8192, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 41, 15, 15, 10, 0, 30, 20, 200, 41, 21,
+ 0, 6, 6, 0, 6, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Toshiba TH58NVG3D4BTG00
+ {
+ 0x98, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_TRUE, 1024, 1,
+ 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 41, 15, 15, 10, 0, 30, 20, 200, 41, 35,
+ 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25
+ },
+ // filling odm parameter structure for Toshiba TH58NVG2S3BFT00
+ {
+ 0x98, 0xDC, NvOdmNandFlashType_Slc, NV_FALSE, NV_FALSE, 512, 1,
+ 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 41, 15, 15, 10, 0, 30, 20, 200, 41, 35,
+ 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25
+ },
+*/
+ // filling odm parameter structure for Samsung K9LBG08U0M
+ {
+ 0xEC, 0xD7, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 4096, 4, 2048,
+ 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 12, 10, 12, 10, 20, 60, 100, 20, 100,
+ 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0xB6
+ },
+ // filling odm parameter structure for Samsung K9LBG08U0D - 42 nm Nand
+ {
+ 0xEC, 0xD7, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 4096, 4, 2048,
+ 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Eight, NvOdmNandSkipSpareBytes_4,
+ 15, 10, 15, 10, 20, 60, 100, 20, 100,
+ 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type2, 0x29
+ },
+ //Hynix H8BES0UQ0MCR
+ {
+ 0xAD, 0xBC, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 512, 2, 2048,
+ 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 10, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x55
+ },
+ //Hynix H8BCS0SJ0MCP
+ {
+ 0xAD, 0xBA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048,
+ 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 15, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x55
+ },
+ //Hynix H8BCS0RJ0MCP
+ {
+ 0xAD, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048,
+ 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 10, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15
+ },
+ /*Numonyx MCP - NAND02GR3B2D*/
+ {
+ 0x20, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1,
+ 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 25, 15, 25, 15, 35, 60, 100, 30, 100,
+ 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15
+ },
+ // Micron ONFI 16 Bit Nand MT29F2G16ABD
+ {
+ 0x2C, 0xBA, NvOdmNandFlashType_Slc, NV_FALSE, NV_FALSE, 256, 1, 2048,
+ 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 12, 10, 17, 15, 24, 60, 100, 20, 100,
+ 15, 5, 4, 15, 4, 25, 35, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x55
+ },
+ /* "This is the end of device list please do not modify this. To add support for more flash parts,
+ add device category for those parts before this element"*/
+ {
+ 0, 0, NvOdmNandFlashType_UnKnown, NV_FALSE, NV_FALSE, 0, 0,
+ 0, 0, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon,
+ NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NvOdmNandDeviceType_Type1, 0
+ }
+};
+
+NvOdmNandFlashParams *NvOdmNandGetFlashInfo (NvU32 ReadID)
+{
+ NvU8 TempValue;
+ NvU8 VendorId = 0;
+ NvU8 DeviceId = 0;
+ NvU8 ReadIdFourthByte = 0;
+ NvOdmNandFlashType NandType;
+ NvU8 i = 0;
+ // To extract Vendor Id
+ VendorId = (NvU8) (ReadID & 0xFF);
+ // To extract Device Id
+ DeviceId = (NvU8) ((ReadID >> DEVICE_SHIFT) & 0xFF);
+ // To extract Fourth ID byte of Read ID - for checking if the flash is 42nm.
+ ReadIdFourthByte = (NvU8) ((ReadID >> FOURTH_ID_SHIFT) & 0xFF);
+ // To extract device Type Mask
+ TempValue = (NvU8) ((ReadID >> FLASH_TYPE_SHIFT) & 0xC);
+ if (TempValue)
+ {
+ NandType = NvOdmNandFlashType_Mlc;
+ }
+ else
+ {
+ NandType = NvOdmNandFlashType_Slc;
+ }
+ // following ORing is done to check if we reached the end of the list.
+ while ((g_Params[i].VendorId) | (g_Params[i].DeviceId))
+ {
+ if ((g_Params[i].VendorId == VendorId) &&
+ (g_Params[i].DeviceId == DeviceId) &&
+ (g_Params[i].ReadIdFourthByte == ReadIdFourthByte) &&
+ (g_Params[i].NandType == NandType))
+ {
+ return &g_Params[i];
+ }
+ else
+ i++;
+ }
+ // This condition will be reached if "g_Params" is not having Parameters of the flash used.
+ // Hence add the parameters required in the table.
+ return NULL;
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c
new file mode 100644
index 000000000000..1e9aeef4e584
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ * This file implements the pin-mux configuration tables for each I/O module.
+ */
+
+// THESE SETTINGS ARE PLATFORM-SPECIFIC (not SOC-specific).
+// PLATFORM = AP20 Whistler/Voyager
+
+#include "nvodm_query_pinmux.h"
+#include "nvassert.h"
+#include "nvodm_services.h"
+#include "tegra_devkit_custopt.h"
+#include "nvodm_keylist_reserved.h"
+#include "nvrm_drf.h"
+
+#define NVODM_PINMUX_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
+
+static const NvU32 s_NvOdmPinMuxConfig_Uart_Hsi_Ulpi[] = {
+ NvOdmUartPinMap_Config7, // Instance 0: UART-A is mapped to SDIO1 pins when ULPI is used
+ NvOdmUartPinMap_Config1, // Instance 1: UART-B
+ NvOdmUartPinMap_Config1, // Instance 2: UART-C
+ 0, // UART-D function disabled: pins used by BB (SPI1)
+ 0, // UART-E function disabled: pins used by WiFi (SDIO1)
+};
+
+
+static const NvU32 s_NvOdmPinMuxConfig_Uart[] = {
+ NvOdmUartPinMap_Config1,
+ NvOdmUartPinMap_Config1,
+ NvOdmUartPinMap_Config1,
+ 0, // UART-D function disabled: pins used by BB (SPI1)
+ 0, // UART-E function disabled: pins used by WiFi (SDIO1)
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Spi[] = {
+ NvOdmSpiPinMap_Config1,
+ NvOdmSpiPinMap_Config3,
+ NvOdmSpiPinMap_Multiplexed,
+ 0,
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Twc[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_I2c[] = {
+ NvOdmI2cPinMap_Config1,
+ NvOdmI2cPinMap_Config1,
+ NvOdmI2cPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_I2c_Pmu[] = {
+ NvOdmI2cPmuPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Ulpi[] = {
+ NvOdmUlpiPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Sdio[] = {
+ 0,
+ NvOdmSdioPinMap_Config1, /* Wifi */
+ NvOdmSdioPinMap_Config1,
+ NvOdmSdioPinMap_Config2, // NAND enabled
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Sdio_05[] = {
+ 0,
+ NvOdmSdioPinMap_Config1, /* Wifi */
+ NvOdmSdioPinMap_Config1,
+ NvOdmSdioPinMap_Config1, // Personality 5 uses SDIO (disables NAND)
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Spdif[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Hsi[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Hdmi[] = {
+ NvOdmHdmiPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Pwm[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Ata[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Nand[] = {
+ NvOdmNandPinMap_Config2, // disable sdio4 pinmux for enabling nand
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Nand_05[] = {
+ 0, // Personality 5 disables NAND
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Dsi[] = {
+ NvOdmDapPinMap_Config1, // fake one, otherwise, ddk display will assert.
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Dap[] = {
+ NvOdmDapPinMap_Config1,
+ NvOdmDapPinMap_Config1,
+ NvOdmDapPinMap_Config1,
+ NvOdmDapPinMap_Config1,
+ NvOdmDapPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Kbd[] = {
+ NvOdmKbdPinMap_Config4,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Hdcp[] = {
+ NvOdmHdcpPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_SyncNor[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Mio[] = {
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_ExternalClock[] = {
+ NvOdmExternalClockPinMap_Config2,
+ NvOdmExternalClockPinMap_Config2,
+ NvOdmExternalClockPinMap_Config1, // CSUS -> VI_Sensor_CLK
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_VideoInput[] = {
+ NvOdmVideoInputPinMap_Config2,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Display[] = {
+ NvOdmDisplayPinMap_Config1,
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_BacklightPwm[] = {
+ 0,
+ NvOdmBacklightPwmPinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Crt[] = {
+ NvOdmDisplayPinMap_Config1,
+ 0,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Tvo[] = {
+ NvOdmTvoPinMap_Config1, // FIXME: is this the correct config?
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_OneWire[] = {
+ NvOdmOneWirePinMap_Config1,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_PciExpress[] = {
+ 0, // To enable Pcie, set pinmux config for SDIO3 to 0
+};
+
+static const NvU32 s_NvOdmClockLimit_Sdio[] = {
+ 50000,
+ 32000,
+ 50000,
+ 50000,
+};
+
+static const NvU32 s_NvOdmPinMuxConfig_Ptm[] = {
+ NvOdmPtmPinMap_Config1,
+};
+
+void
+NvOdmQueryPinMux(
+ NvOdmIoModule IoModule,
+ const NvU32 **pPinMuxConfigTable,
+ NvU32 *pCount)
+{
+ NvU32 CustomerOption = 0;
+ NvU32 Personality = 0;
+ NvU32 Ril = 0;
+ NvOdmServicesKeyListHandle hKeyList;
+
+ hKeyList = NvOdmServicesKeyListOpen();
+ if (hKeyList)
+ {
+ CustomerOption =
+ NvOdmServicesGetKeyValue(hKeyList,
+ NvOdmKeyListId_ReservedBctCustomerOption);
+ NvOdmServicesKeyListClose(hKeyList);
+ Personality =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustomerOption);
+ Ril =
+ NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustomerOption);
+ }
+
+ if (!Personality)
+ Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY;
+
+ if (!Ril)
+ Ril = TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_DEFAULT;
+
+ switch (IoModule)
+ {
+ case NvOdmIoModule_Display:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Display;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Display);
+ break;
+
+ case NvOdmIoModule_Dap:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Dap;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Dap);
+ break;
+
+ case NvOdmIoModule_Hdcp:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdcp;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdcp);
+ break;
+
+ case NvOdmIoModule_Hdmi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdmi;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdmi);
+ break;
+
+ case NvOdmIoModule_I2c:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2c;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2c);
+ break;
+
+ case NvOdmIoModule_I2c_Pmu:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2c_Pmu;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2c_Pmu);
+ break;
+
+ case NvOdmIoModule_Kbd:
+ if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1))
+ {
+ // Disable KBD pin-mux when PTM trace enabled (shares kbcc pin-group)
+ *pPinMuxConfigTable = NULL;
+ *pCount = 0;
+ }
+ else
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Kbd;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Kbd);
+ }
+ break;
+
+ case NvOdmIoModule_Mio:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Mio;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Mio);
+ break;
+
+ case NvOdmIoModule_Nand:
+ if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15))
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Nand_05;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Nand_05);
+ }
+ else
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Nand;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Nand);
+ }
+ break;
+
+ case NvOdmIoModule_Sdio:
+ if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C4))
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Sdio_05;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Sdio_05);
+ }
+ else
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Sdio;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Sdio);
+ }
+ break;
+
+ case NvOdmIoModule_Spdif:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spdif;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spdif);
+ break;
+
+ case NvOdmIoModule_Spi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spi;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spi);
+ break;
+
+ case NvOdmIoModule_Uart:
+ if (Ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI)
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Uart_Hsi_Ulpi;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Uart_Hsi_Ulpi);
+ }
+ else
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Uart;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Uart);
+ }
+ break;
+
+ case NvOdmIoModule_ExternalClock:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_ExternalClock;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_ExternalClock);
+ break;
+
+ case NvOdmIoModule_VideoInput:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_VideoInput;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_VideoInput);
+ break;
+
+ case NvOdmIoModule_Crt:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Crt;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Crt);
+ break;
+
+ case NvOdmIoModule_Tvo:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Tvo;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Tvo);
+ break;
+
+ case NvOdmIoModule_Ata:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ata;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ata);
+ break;
+
+ case NvOdmIoModule_Pwm:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Pwm;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Pwm);
+ break;
+
+ case NvOdmIoModule_Dsi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Dsi;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Dsi);
+ break;
+
+ case NvOdmIoModule_Hsi:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hsi;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hsi);
+ break;
+
+ case NvOdmIoModule_Twc:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Twc;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Twc);
+ break;
+
+ case NvOdmIoModule_Ulpi:
+ if (Ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI)
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ulpi;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ulpi);
+ }
+ else
+ {
+ *pPinMuxConfigTable = NULL;
+ *pCount = 0;
+ }
+ break;
+
+ case NvOdmIoModule_OneWire:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_OneWire;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_OneWire);
+ break;
+
+ case NvOdmIoModule_SyncNor:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_SyncNor;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_SyncNor);
+ break;
+
+ case NvOdmIoModule_PciExpress:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_PciExpress;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_PciExpress);
+ break;
+
+ case NvOdmIoModule_Trace:
+ if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) ||
+ (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1))
+ {
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ptm;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ptm);
+ }
+ else
+ {
+ *pCount = 0;
+ }
+ break;
+
+ case NvOdmIoModule_BacklightPwm:
+ *pPinMuxConfigTable = s_NvOdmPinMuxConfig_BacklightPwm;
+ *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_BacklightPwm);
+ break;
+
+ case NvOdmIoModule_Hsmmc:
+ case NvOdmIoModule_Csi:
+ case NvOdmIoModule_Sflash:
+ case NvOdmIoModule_Slink:
+ case NvOdmIoModule_Gpio:
+ case NvOdmIoModule_I2s:
+ case NvOdmIoModule_Usb:
+ case NvOdmIoModule_Vdd:
+ case NvOdmIoModule_Xio:
+ case NvOdmIoModule_Tsense:
+ *pCount = 0;
+ break;
+
+ default:
+ NV_ASSERT(!"Bad Parameter!");
+ *pCount = 0;
+ break;
+ }
+}
+
+void
+NvOdmQueryClockLimits(
+ NvOdmIoModule IoModule,
+ const NvU32 **pClockSpeedLimits,
+ NvU32 *pCount)
+{
+ switch (IoModule)
+ {
+ case NvOdmIoModule_Hsmmc:
+ *pCount = 0;
+ break;
+
+ case NvOdmIoModule_Sdio:
+ *pClockSpeedLimits = s_NvOdmClockLimit_Sdio;
+ *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmClockLimit_Sdio);
+ break;
+
+
+ default:
+ *pClockSpeedLimits = NULL;
+ *pCount = 0;
+ break;
+ }
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h
new file mode 100644
index 000000000000..4752fca7b93e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E1109
+ * Processor Module.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+#include "tmon/adt7461/nvodm_tmon_adt7461_channel.h"
+#include "nvodm_tmon.h"
+
+static const NvOdmIoAddress s_ffaHdmiAddresses[] =
+{
+ { NvOdmIoModule_Hdmi, 0, 0 },
+
+ /* Display Data Channel (DDC) for Extended Display Identification
+ * Data (EDID)
+ */
+ { NvOdmIoModule_I2c, 0x01, 0xA0 },
+
+ /* HDCP downstream */
+ { NvOdmIoModule_I2c, 0x01, 0x74 },
+
+ /* AVDD_HDMI -> D1REG */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 },
+
+ /* MIPI PLL */
+ { NvOdmIoModule_Vdd, 0, Max8907bPmuSupply_LDO6 },
+
+ /* lcd i/o rail (for hot plug pin) */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 },
+};
+
+static const NvOdmIoAddress s_ffaCrtAddresses[] =
+{
+ { NvOdmIoModule_Crt, 0, 0 },
+
+ /* Display Data Channel (DDC) for Extended Display Identification
+ * Data (EDID)
+ */
+ { NvOdmIoModule_I2c, 0x01, 0xA0 },
+
+ /* tvdac rail (required) */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO14 },
+
+ /* lcd i/o rail (for hot plug pin) */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 },
+};
+
+static const NvOdmIoAddress s_ffaVideoDacAddresses[] =
+{
+ { NvOdmIoModule_Tvo, 0x00, 0x00 },
+ /* tvdac rail */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO14 },
+};
+
+static const NvOdmIoAddress s_Tmon0Addresses[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x98 }, /* I2C bus */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO15 }, /* TMON pwer rail -> D4REG */
+ { NvOdmIoModule_Gpio, 0x08, 0x02 }, /* GPIO Port I and Pin 2 */
+
+ /* Temperature zone mapping */
+ { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Core, ADT7461ChannelID_Remote }, /* TSENSOR */
+ { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Ambient, ADT7461ChannelID_Local }, /* TSENSOR */
+};
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h
new file mode 100644
index 000000000000..9f213e0c35ab
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database Peripheral entries for the E91109
+ * Processor Module.
+ */
+
+// HDMI
+{
+ NV_ODM_GUID('f','f','a','_','h','d','m','i'),
+ s_ffaHdmiAddresses,
+ NV_ARRAY_SIZE(s_ffaHdmiAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// CRT
+{
+ NV_ODM_GUID('f','f','a','_','-','c','r','t'),
+ s_ffaCrtAddresses,
+ NV_ARRAY_SIZE(s_ffaCrtAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// TV Out Video Dac
+{
+ NV_ODM_GUID('f','f','a','t','v','o','u','t'),
+ s_ffaVideoDacAddresses,
+ NV_ARRAY_SIZE(s_ffaVideoDacAddresses),
+ NvOdmPeripheralClass_Display
+},
+
+// Temperature Monitor (TMON)
+{
+ NV_ODM_GUID('a','d','t','7','4','6','1',' '),
+ s_Tmon0Addresses,
+ NV_ARRAY_SIZE(s_Tmon0Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h
new file mode 100644
index 000000000000..2b5ca7f8bacd
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h
@@ -0,0 +1,270 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E1116
+ * Power module.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+
+// Persistent voltage rail (ie, for RTC, Standby, etc...)
+static const NvOdmIoAddress s_ffaRtcAddresses[] =
+{
+ // On Maxim 8907B, the standby rail automatically follows V2
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V2 } /* VDD_RTC -> RTC */
+};
+
+// Core voltage rail
+static const NvOdmIoAddress s_ffaCoreAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V2 } /* VDD_CORE -> V2 */
+};
+
+// PMU CPU voltage rail
+static const NvOdmIoAddress s_ffaCpuAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V1 } /* VDD_CPU_PMU -> V1 */
+};
+
+// External CPU DCDC voltage rail
+static const NvOdmIoAddress s_ffaCpuExtSupplyAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7 } /* VDD_CPU_PMU -> DCDC7 */
+};
+
+// PLLA voltage rail
+static const NvOdmIoAddress s_ffaPllAAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */
+};
+
+// PLLM voltage rail
+static const NvOdmIoAddress s_ffaPllMAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLM -> VOUT2 */
+};
+
+// PLLP voltage rail
+static const NvOdmIoAddress s_ffaPllPAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */
+};
+
+// PLLC voltage rail
+static const NvOdmIoAddress s_ffaPllCAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */
+};
+
+// PLLE voltage rail
+static const NvOdmIoAddress s_ffaPllEAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLL_E -> VOUT2 */
+};
+
+// PLLU1 voltage rail
+static const NvOdmIoAddress s_ffaPllU1Addresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLU -> VOUT2 */
+};
+
+// PLLS voltage rail
+static const NvOdmIoAddress s_ffaPllSAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */
+};
+
+// PLLHD voltage rail
+static const NvOdmIoAddress s_ffaPllHdmiAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO6 } /* AVDD_HDMI_PLL -> VOUT6 */
+};
+
+// OSC voltage rail
+static const NvOdmIoAddress s_ffaVddOscAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* AVDD_OSC -> V3 */
+};
+
+// PLLX voltage rail
+static const NvOdmIoAddress s_ffaPllXAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLX -> VOUT2 */
+};
+
+// PLL_USB voltage rail
+static const NvOdmIoAddress s_ffaPllUsbAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO4 } /* AVDD_USB_PLL -> VOUT4 */
+};
+
+// SYS IO voltage rail
+static const NvOdmIoAddress s_ffaVddSysAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_SYS -> V3 */
+};
+
+// USB voltage rail
+static const NvOdmIoAddress s_ffaVddUsbAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO4 } /* AVDD_USB -> VOUT4 */
+};
+
+// HDMI voltage rail
+static const NvOdmIoAddress s_ffaVddHdmiAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 } /* AVDD_HDMI -> VOUT11 */
+};
+
+// MIPI voltage rail
+static const NvOdmIoAddress s_ffaVddMipiAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO17 } /* VDDIO_MIPI -> VOUT17 */
+};
+
+// LCD voltage rail
+static const NvOdmIoAddress s_ffaVddLcdAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_LCD_PMU -> V3 */
+};
+
+// Audio voltage rail
+static const NvOdmIoAddress s_ffaVddAudAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_AUDIO -> V3 */
+};
+
+// LPDDR2 voltage rail (default)
+static const NvOdmIoAddress s_ffaVddDdrAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO20 } /* VDDIO_DDR_1V2 -> VOUT20 */
+};
+
+// DDR2 voltage rail (on E1109 board ext 1.8V DCDC is controlled by LDO5)
+static const NvOdmIoAddress s_ffaVddDdr2Addresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 } /* VDDIO_DDR_1V8 -> VOUT05 */
+};
+
+// DDR_RX voltage rail
+static const NvOdmIoAddress s_ffaVddDdrRxAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO1 } /* VDDIO_RX_DDR(2.7-3.3) -> VOUT1 */
+};
+
+// NAND voltage rail
+static const NvOdmIoAddress s_ffaVddNandAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_NAND_PMU -> V3 */
+};
+
+// UART voltage rail
+static const NvOdmIoAddress s_ffaVddUartAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_UART -> V3 */
+};
+
+// SDIO voltage rail
+static const NvOdmIoAddress s_ffaVddSdioAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO12 } /* VDDIO_SDIO -> VOUT12 */
+};
+
+// VDAC voltage rail
+static const NvOdmIoAddress s_ffaVddVdacAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO14 } /* AVDD_VDAC -> VOUT14 */
+};
+
+// VI voltage rail
+static const NvOdmIoAddress s_ffaVddViAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18 } /* VDDIO_VI -> VOUT18 */
+};
+
+// BB voltage rail
+static const NvOdmIoAddress s_ffaVddBbAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_BB -> V3 */
+};
+
+// HSIC voltage rail
+static const NvOdmIoAddress s_ffaVddHsicAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO20 } /* VDDIO_HSIC -> VOUT20 */
+};
+
+// USB_IC voltage rail
+static const NvOdmIoAddress s_ffaVddUsbIcAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* AVDD_USB_IC -> V3 */
+};
+
+// PEX_CLK voltage rail
+static const NvOdmIoAddress s_ffaVddPexClkAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 }, /* VDDIO_PEX_CLK -> VOUT11 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO12 }, /* VDDIO_PEX_CLK -> VOUT12 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_EXT_DCDC_3 }
+};
+
+// PMU0
+static const NvOdmIoAddress s_Pmu0Addresses[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x78 },
+};
+
+// I2C IO Expander
+static const NvOdmIoAddress s_I2cioexpanderAddress[] =
+{
+ { NvOdmIoModule_I2c_Pmu, 0x00, 0x40 },
+};
+
+// USB1 VBus voltage rail
+static const NvOdmIoAddress s_ffaVddUsb1VBusAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_EXT_DCDC_3_USB1 },
+};
+
+// USB3 VBus voltage rail
+static const NvOdmIoAddress s_ffaVddUsb3VBusAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_EXT_DCDC_3_USB3 },
+};
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h
new file mode 100644
index 000000000000..5145bf5b0711
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h
@@ -0,0 +1,349 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database Peripheral entries for the E1116
+ * power module.
+ */
+
+/* All of the reserved values, for SOC voltage domains.
+ */
+
+// WHISTLER_AP16_ONLY - AP20 doesn't have PLL_D rail.
+// PLLD (NV reserved) / Use PLL_U
+{
+ NV_VDD_PLLD_ODM_ID,
+ s_ffaPllU1Addresses,
+ NV_ARRAY_SIZE(s_ffaPllU1Addresses),
+ NvOdmPeripheralClass_Other
+},
+// -------- END WHISTLER_AP16_ONLY --------
+
+
+// RTC (NV reserved)
+{
+ NV_VDD_RTC_ODM_ID,
+ s_ffaRtcAddresses,
+ NV_ARRAY_SIZE(s_ffaRtcAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// CORE (NV reserved)
+{
+ NV_VDD_CORE_ODM_ID,
+ s_ffaCoreAddresses,
+ NV_ARRAY_SIZE(s_ffaCoreAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// CPU (NV reserved)
+{
+ NV_VDD_CPU_ODM_ID,
+ s_ffaCpuAddresses,
+ NV_ARRAY_SIZE(s_ffaCpuAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLA (NV reserved)
+{
+ NV_VDD_PLLA_ODM_ID,
+ s_ffaPllAAddresses,
+ NV_ARRAY_SIZE(s_ffaPllAAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLM (NV reserved)
+{
+ NV_VDD_PLLM_ODM_ID,
+ s_ffaPllMAddresses,
+ NV_ARRAY_SIZE(s_ffaPllMAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLP (NV reserved)
+{
+ NV_VDD_PLLP_ODM_ID,
+ s_ffaPllPAddresses,
+ NV_ARRAY_SIZE(s_ffaPllPAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLC (NV reserved)
+{
+ NV_VDD_PLLC_ODM_ID,
+ s_ffaPllCAddresses,
+ NV_ARRAY_SIZE(s_ffaPllCAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLE (NV reserved)
+{
+ NV_VDD_PLLE_ODM_ID,
+ s_ffaPllEAddresses,
+ NV_ARRAY_SIZE(s_ffaPllEAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLU (NV reserved)
+{
+ NV_VDD_PLLU_ODM_ID,
+ s_ffaPllUsbAddresses,
+ NV_ARRAY_SIZE(s_ffaPllUsbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLU1 (NV reserved)
+{
+ NV_VDD_PLLU1_ODM_ID,
+ s_ffaPllU1Addresses,
+ NV_ARRAY_SIZE(s_ffaPllU1Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLS (NV reserved)
+{
+ NV_VDD_PLLS_ODM_ID,
+ s_ffaPllSAddresses,
+ NV_ARRAY_SIZE(s_ffaPllSAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// HDMI PLL (NV reserved)
+{
+ NV_VDD_PLLHDMI_ODM_ID,
+ s_ffaPllHdmiAddresses,
+ NV_ARRAY_SIZE(s_ffaPllHdmiAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// OSC VDD (NV reserved)
+{
+ NV_VDD_OSC_ODM_ID,
+ s_ffaVddOscAddresses,
+ NV_ARRAY_SIZE(s_ffaVddOscAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLLX (NV reserved)
+{
+ NV_VDD_PLLX_ODM_ID,
+ s_ffaPllXAddresses,
+ NV_ARRAY_SIZE(s_ffaPllXAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PLL_USB (NV reserved)
+{
+ NV_VDD_PLL_USB_ODM_ID,
+ s_ffaPllUsbAddresses,
+ NV_ARRAY_SIZE(s_ffaPllUsbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// (TBD) PLL_PEX (NV reserved)
+
+// System IO VDD (NV reserved)
+{
+ NV_VDD_SYS_ODM_ID,
+ s_ffaVddSysAddresses,
+ NV_ARRAY_SIZE(s_ffaVddSysAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// USB VDD (NV reserved)
+{
+ NV_VDD_USB_ODM_ID,
+ s_ffaVddUsbAddresses,
+ NV_ARRAY_SIZE(s_ffaVddUsbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// VBUS for USB1
+{
+ NV_VDD_VBUS_ODM_ID,
+ s_ffaVddUsb1VBusAddresses,
+ NV_ARRAY_SIZE(s_ffaVddUsb1VBusAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// VBUS for USB3
+{
+ NV_VDD_USB3_VBUS_ODM_ID,
+ s_ffaVddUsb3VBusAddresses,
+ NV_ARRAY_SIZE(s_ffaVddUsb3VBusAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+
+// HDMI VDD (NV reserved)
+{
+ NV_VDD_HDMI_ODM_ID,
+ s_ffaVddHdmiAddresses,
+ NV_ARRAY_SIZE(s_ffaVddHdmiAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// MIPI VDD (NV reserved)
+{
+ NV_VDD_MIPI_ODM_ID,
+ s_ffaVddMipiAddresses,
+ NV_ARRAY_SIZE(s_ffaVddMipiAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// LCD VDD (NV reserved)
+{
+ NV_VDD_LCD_ODM_ID,
+ s_ffaVddLcdAddresses,
+ NV_ARRAY_SIZE(s_ffaVddLcdAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// AUDIO VDD (NV reserved)
+{
+ NV_VDD_AUD_ODM_ID,
+ s_ffaVddAudAddresses,
+ NV_ARRAY_SIZE(s_ffaVddAudAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// DDR VDD (NV reserved)
+{
+ NV_VDD_DDR_ODM_ID,
+ s_ffaVddDdrAddresses,
+ NV_ARRAY_SIZE(s_ffaVddDdrAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// DDR_RX (NV reserved)
+{
+ NV_VDD_DDR_RX_ODM_ID,
+ s_ffaVddDdrRxAddresses,
+ NV_ARRAY_SIZE(s_ffaVddDdrRxAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// NAND VDD (NV reserved)
+{
+ NV_VDD_NAND_ODM_ID,
+ s_ffaVddNandAddresses,
+ NV_ARRAY_SIZE(s_ffaVddNandAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// UART VDD (NV reserved)
+{
+ NV_VDD_UART_ODM_ID,
+ s_ffaVddUartAddresses,
+ NV_ARRAY_SIZE(s_ffaVddUartAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// SDIO VDD (NV reserved)
+{
+ NV_VDD_SDIO_ODM_ID,
+ s_ffaVddSdioAddresses,
+ NV_ARRAY_SIZE(s_ffaVddSdioAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// VDAC VDD (NV reserved)
+{
+ NV_VDD_VDAC_ODM_ID,
+ s_ffaVddVdacAddresses,
+ NV_ARRAY_SIZE(s_ffaVddVdacAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// VI VDD (NV reserved)
+{
+ NV_VDD_VI_ODM_ID,
+ s_ffaVddViAddresses,
+ NV_ARRAY_SIZE(s_ffaVddViAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// BB VDD (NV reserved)
+{
+ NV_VDD_BB_ODM_ID,
+ s_ffaVddBbAddresses,
+ NV_ARRAY_SIZE(s_ffaVddBbAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// HSIC (NV reserved)
+{
+ NV_VDD_HSIC_ODM_ID,
+ s_ffaVddHsicAddresses,
+ NV_ARRAY_SIZE(s_ffaVddHsicAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// USB_IC (NV reserved)
+{
+ NV_VDD_USB_IC_ODM_ID,
+ s_ffaVddUsbIcAddresses,
+ NV_ARRAY_SIZE(s_ffaVddUsbIcAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// (TBD) PEX (NV reserved)
+
+// PEX_CLK (NV reserved)
+{
+ NV_VDD_PEX_CLK_ODM_ID,
+ s_ffaVddPexClkAddresses,
+ NV_ARRAY_SIZE(s_ffaVddPexClkAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// PMU0
+{
+ NV_ODM_GUID('m','a','x','8','9','0','7','b'),
+ s_Pmu0Addresses,
+ NV_ARRAY_SIZE(s_Pmu0Addresses),
+ NvOdmPeripheralClass_Other
+},
+// I2C IO expander
+{
+ NV_ODM_GUID('t','c','a','_','6','4','1','6'),
+ s_I2cioexpanderAddress,
+ NV_ARRAY_SIZE(s_I2cioexpanderAddress),
+ NvOdmPeripheralClass_Other
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h
new file mode 100644
index 000000000000..7085868e5374
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h
@@ -0,0 +1,74 @@
+
+
+/*
+ * Copyright (c) 2010 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E1120
+ * AP20 Development System Motherboard.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+
+static const NvOdmIoAddress s_enc28j60EthernetAddresses[] =
+{
+ { NvOdmIoModule_Spi, 1, 1 },
+ { NvOdmIoModule_Gpio, (NvU32)'c'-'a', 1 }
+};
+
+static const NvOdmIoAddress s_SdioAddresses[] =
+{
+ { NvOdmIoModule_Sdio, 0x0, 0x0 },
+ { NvOdmIoModule_Sdio, 0x2, 0x0 },
+ { NvOdmIoModule_Sdio, 0x3, 0x0 },
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO12 }, /* VDDIO_SDIO -> VOUT12 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 } /* VCORE_MMC -> VOUT05 */
+};
+
+static const NvOdmIoAddress s_VibAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x0, Max8907bPmuSupply_LDO16},
+};
+
+static const NvOdmIoAddress s_AcceleroAddresses[] =
+{
+ { NvOdmIoModule_I2c, 0x0, 0x3A }, /* I2C address (7-bit) 0x1D < 1 = 0x3A (8-bit) */
+ { NvOdmIoModule_Gpio, 0x1A, 0x1 }, /* Gpio port AA[1] = (A=0, Z=25) thus AA = 26 = 0x1A */
+ { NvOdmIoModule_Vdd, 0x0, Max8907bPmuSupply_LX_V3 }, /* VDDIO_UART = V3 */
+ { NvOdmIoModule_Vdd, 0x0, Max8907bPmuSupply_LDO1 }, /* VCORE_ACC = VOUT1 = 2.8v */
+};
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h
new file mode 100644
index 000000000000..90d038ba2ab2
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity database Peripheral
+ * entries for the E1120 AP20 Development System
+ * Motherboard.
+ */
+
+// Ethernet module
+{
+ NV_ODM_GUID('e','n','c','2','8','j','6','0'),
+ s_enc28j60EthernetAddresses,
+ NV_ARRAY_SIZE(s_enc28j60EthernetAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// Sdio module
+{
+ NV_ODM_GUID('s','d','i','o','_','m','e','m'),
+ s_SdioAddresses,
+ NV_ARRAY_SIZE(s_SdioAddresses),
+ NvOdmPeripheralClass_Other,
+},
+
+//..Vibrate Module
+{
+ NV_ODM_GUID('v','i','b','r','a','t','o','r'),
+ s_VibAddresses,
+ NV_ARRAY_SIZE(s_VibAddresses),
+ NvOdmPeripheralClass_Other,
+},
+
+// Accelerometer Module
+{
+ NV_ODM_GUID('a','c','c','e','l','e','r','o'),
+ s_AcceleroAddresses,
+ NV_ARRAY_SIZE(s_AcceleroAddresses),
+ NvOdmPeripheralClass_Other,
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h
new file mode 100644
index 000000000000..bedebff4a8e4
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E1129
+ * keypad module.
+ */
+#include "../nvodm_query_kbc_gpio_def.h"
+
+// Key Pad
+static const NvOdmIoAddress s_KeyPadAddresses[] =
+{
+ // instance = 1 indicates Column info.
+ // instance = 0 indicates Row info.
+ // address holds KBC pin number used for row/column.
+
+ // All Row info has to be defined contiguously from 0 to max.
+ { NvOdmIoModule_Kbd,0x00, NvOdmKbcGpioPin_KBRow0}, // Row 0
+ { NvOdmIoModule_Kbd,0x00, NvOdmKbcGpioPin_KBRow1}, // Row 1
+ { NvOdmIoModule_Kbd,0x00 ,NvOdmKbcGpioPin_KBRow2}, // Row 2
+
+ // All Column info has to be defined contiguously from 0 to max.
+ { NvOdmIoModule_Kbd,0x01, NvOdmKbcGpioPin_KBCol0}, // Column 0
+ { NvOdmIoModule_Kbd,0x01, NvOdmKbcGpioPin_KBCol1}, // Column 1
+};
+
+// s_ffa ScrollWheel... only supported for personality 1
+static const NvOdmIoAddress s_ffaScrollWheelAddresses[] =
+{
+ { NvOdmIoModule_Gpio, 0x10, 0x3 }, // GPIO Port q - Pin3
+ { NvOdmIoModule_Gpio, 0x11, 0x3 }, // GpIO Port r - Pin 3
+ { NvOdmIoModule_Gpio, 0x10, 0x5 }, // GPIO Port q - Pin 5
+ { NvOdmIoModule_Gpio, 0x10, 0x4 }, // GPIO Port q - Pin 4
+};
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h
new file mode 100644
index 000000000000..3df1481a6894
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database Peripheral entries for the E1129
+ * keypad module.
+ */
+
+// Key Pad
+{
+ NV_ODM_GUID('k','e','y','b','o','a','r','d'),
+ s_KeyPadAddresses,
+ NV_ARRAY_SIZE(s_KeyPadAddresses),
+ NvOdmPeripheralClass_HCI
+},
+
+// Scroll Wheel
+{
+ NV_ODM_GUID('s','c','r','o','l','w','h','l'),
+ s_ffaScrollWheelAddresses,
+ NV_ARRAY_SIZE(s_ffaScrollWheelAddresses),
+ NvOdmPeripheralClass_HCI
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h
new file mode 100644
index 000000000000..8946a5cb3056
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E888
+ * audio module.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+
+// Audio Codec
+static const NvOdmIoAddress s_AudioCodecAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO7}, /* AUDIO_PLL etc -> DCD2 */
+ { NvOdmIoModule_ExternalClock, 0, 0 }, // connected to CDEV1
+#if 1
+ { NvOdmIoModule_Spi, 2, 1 }, /* FFA Audio codec on SP3- CS1*/
+#else
+ { NvOdmIoModule_I2c_Pmu, 0, 0x34}, /* FFA Audio codec on DVC*/
+
+#endif
+ { NvOdmIoModule_Dap, 0, 0 }, /* Dap port Index 0 is used for codec*/
+};
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h
new file mode 100644
index 000000000000..939ae49f8175
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database Peripheral entries for the E888
+ * audio module.
+ */
+
+// audio codec
+{
+ NV_ODM_GUID('w','o','l','f','8','7','5','3'),
+ s_AudioCodecAddresses,
+ NV_ARRAY_SIZE(s_AudioCodecAddresses),
+ NvOdmPeripheralClass_Other
+},
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h
new file mode 100644
index 000000000000..09f3197447ea
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E906
+ * LCD Module.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+
+// Main LCD
+static const NvOdmIoAddress s_ffaMainDisplayAddresses[] =
+{
+ { NvOdmIoModule_Display, 0, 0 },
+ { NvOdmIoModule_Spi, 0x2, 0x2 }, // TBD (this is a guess)
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, /* VDDIO_LCD -> V3 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 }, /* AVDD_LCD_1 -> VOUT5 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO19 }, /* AVDD_LCD_2 -> VOUT19 */
+};
+
+// DSI LCD
+// WARNING: Whistler's board personality needs to be set to 077 for the
+// reset gpio pin to work
+static const NvOdmIoAddress s_DsiAddresses[] =
+{
+ { NvOdmIoModule_Display, 0, 0 },
+
+ { NvOdmIoModule_Gpio, (NvU32)('c' - 'a'), 1 },
+
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, /* VDDIO_LCD -> V3 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 }, /* AVDD_LCD_1 -> VOUT5 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO19 }, /* AVDD_LCD_2 -> VOUT19 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO17 }, /* MIPI DSI 1.2V */
+};
+
+// TouchPanel
+static const NvOdmIoAddress s_ffaTouchPanelAddresses[] =
+{
+ { NvOdmIoModule_I2c, 0x00, 0x20 },/* I2C device address is 0x20 */
+ { NvOdmIoModule_Gpio, 'c' - 'a', 6}, /* GPIO Port V and Pin 3 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO19 }
+};
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h
new file mode 100644
index 000000000000..44f7a967ff40
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database Peripheral entries for the E906 LCD
+ * Module.
+ */
+
+// LCD module
+{
+ NV_ODM_GUID('S','H','P','_','A','P','2','0'), // Sharp WVGA panel with AP20 backlight control
+ s_ffaMainDisplayAddresses,
+ NV_ARRAY_SIZE(s_ffaMainDisplayAddresses),
+ NvOdmPeripheralClass_Display,
+},
+
+// DSI module
+{
+ NV_ODM_GUID('s','h','a','r','p','d','s','i'),
+ s_DsiAddresses,
+ NV_ARRAY_SIZE(s_DsiAddresses),
+ NvOdmPeripheralClass_Display,
+},
+
+// Touch Panel
+{
+ NV_ODM_GUID('t','p','k','t','o','u','c','h'),
+ s_ffaTouchPanelAddresses,
+ NV_ARRAY_SIZE(s_ffaTouchPanelAddresses),
+ NvOdmPeripheralClass_HCI
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h
new file mode 100644
index 000000000000..fe193db73d5e
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity database NvOdmIoAddress entries
+ * for the E911 5MP + 1.3MP + VGA VI Camera module.
+ */
+#include "nvodm_query_gpio.h"
+#include "../include/nvodm_imager_guids.h"
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+
+#define NVODM_PORT(x) ((x) - 'a')
+/* VGP5 is apparently inverted on some boards.
+ * For E912- A01, you may need to change the VGP5_RESET_AL line to:
+ * NVODM_CAMERA_VGP5_RESET
+ * If you find other boards for which it needs to be inverted, please
+ * add your information to this comment.
+ */
+#define OV5630_PINS (NVODM_CAMERA_SERIAL_CSI_D1A | \
+ NVODM_CAMERA_DEVICE_IS_DEFAULT)
+static const NvOdmIoAddress s_ffaImagerOV5630Addresses[] =
+{
+ { NvOdmIoModule_I2c, 0x02, 0x6C },
+ { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 5 | NVODM_IMAGER_RESET_AL },
+ { NvOdmIoModule_Gpio, NVODM_PORT('t'), 3 | NVODM_IMAGER_POWERDOWN },
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18 }, //VDDIO_VI
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO9 }, //AVDD_CAM1
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO13 }, //VDDIO_AF
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO17 }, //VDDIO_MIPI
+ { NvOdmIoModule_VideoInput, 0x00, OV5630_PINS },
+ { NvOdmIoModule_ExternalClock, 2, 0 } // CSUS
+};
+
+// OV5630 focuser
+static const NvOdmIoAddress s_ffaImagerAD5820Addresses[] =
+{
+ { NvOdmIoModule_I2c, 0x02, 0x18 }, // focuser i2c
+};
+
+// OV5630 flash
+static const NvOdmIoAddress s_ffaFlashLTC3216Addresses[] =
+{
+ { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 3 | NVODM_IMAGER_FLASH0 }, // Flash 200mA
+ { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 6 | NVODM_IMAGER_FLASH1 } // Flash 600mA
+};
+
+// For SEMCO VGA
+#define SOC380_PINS (NVODM_CAMERA_PARALLEL_VD0_TO_VD7)
+static const NvOdmIoAddress s_ffaImagerSOC380Addresses[] =
+{
+ { NvOdmIoModule_I2c, 0x02, 0x78 },
+ { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 4 | NVODM_IMAGER_POWERDOWN_AL },
+ { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 0 | NVODM_IMAGER_RESET_AL },
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18}, //VDDIO_VI
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO9 }, //AVDD_CAM2
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO13}, //VDDIO_AF
+ { NvOdmIoModule_VideoInput, 0x00, SOC380_PINS },
+ { NvOdmIoModule_ExternalClock, 2, 0 } // CSUS
+};
+
+static const NvOdmIoAddress s_CommonImagerAddresses[] =
+{
+ { NvOdmIoModule_ExternalClock, 2, 0 } // CSUS
+};
+
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h
new file mode 100644
index 000000000000..c6fc1fb9f564
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity database Peripheral entries
+ * for the E911 5MP + 1.3MP + VGA VI Camera module.
+ */
+#include "../include/nvodm_imager_guids.h"
+
+// !!! DON'T MOVE THINGS AROUND !!!
+// Position 0 is used as default primary for E912
+// Position 1 is used as default secondary for E912 and E911
+// Position 2 is used as default primary for E911
+
+// Imager - Primary
+// E912 A01 and Whistler Imager
+{
+ OV5630_GUID,
+ s_ffaImagerOV5630Addresses,
+ NV_ARRAY_SIZE(s_ffaImagerOV5630Addresses),
+ NvOdmPeripheralClass_Imager
+},
+// Imager - Secondary
+// sensor for SEMCO VGA
+{
+ // Aptina (Micron) SOC380
+ SEMCOVGA_GUID,
+ s_ffaImagerSOC380Addresses,
+ NV_ARRAY_SIZE(s_ffaImagerSOC380Addresses),
+ NvOdmPeripheralClass_Imager
+},
+
+// Dummy Entry for Whistler
+{
+ MI5130_GUID,
+ s_ffaImagerOV5630Addresses,
+ NV_ARRAY_SIZE(s_ffaImagerOV5630Addresses),
+ NvOdmPeripheralClass_Imager
+},
+
+// focuser for OV5630 module
+{
+ // VCM driver IC AD5820 Analog Devices
+ AD5820_GUID,
+ s_ffaImagerAD5820Addresses,
+ NV_ARRAY_SIZE(s_ffaImagerAD5820Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// flash device
+{
+ LTC3216_GUID,
+ s_ffaFlashLTC3216Addresses,
+ NV_ARRAY_SIZE(s_ffaFlashLTC3216Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+{
+ COMMONIMAGER_GUID,
+ s_CommonImagerAddresses,
+ NV_ARRAY_SIZE(s_CommonImagerAddresses),
+ NvOdmPeripheralClass_Other
+},
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h
new file mode 100644
index 000000000000..327edf62901a
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E936
+ * ISDB-T module.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+
+// VIP raw bitstream addresses
+static const NvOdmIoAddress s_ffaVIPBitstreamAddresses[] =
+{
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 },
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO9 },
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18 },
+ // Reset. vgp0 and vgp5:
+ { NvOdmIoModule_Gpio, 27, 1 }, // vgp[0] - Port BB(27), Pin 1
+ { NvOdmIoModule_Gpio, 'd'-'a', 2 }, // vgp[5] - Port D, Pin 2
+};
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h
new file mode 100644
index 000000000000..c2733b11531c
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity database Peripheral
+ * entries for the E936 ISDB-T module.
+ */
+
+// Murata tuner source
+{
+ NV_ODM_GUID('m','u','r','a','t','a','5','7'),
+ s_ffaVIPBitstreamAddresses,
+ NV_ARRAY_SIZE(s_ffaVIPBitstreamAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h
new file mode 100644
index 000000000000..70f20af74044
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database NvOdmIoAddress entries for the E951
+ * COMMS module.
+ */
+
+#include "pmu/max8907b/max8907b_supply_info_table.h"
+// Bluetooth
+static const NvOdmIoAddress ffaBluetoothAddresses[] =
+{
+ { NvOdmIoModule_Uart, 0x2, 0x0 },
+ { NvOdmIoModule_Gpio, 0x14, 0x0 }, /* GPIO Port U and Pin 0 */
+ { NvOdmIoModule_Vdd, 0x00, MIC2826PmuSupply_LDO3 } /* VDD -> MIC2826 LDO3 */
+};
+
+
+// Wlan
+static const NvOdmIoAddress s_ffaWlanAddresses[] =
+{
+ { NvOdmIoModule_Sdio, 0x01, 0x0 }, /* WLAN is on SD Bus */
+ { NvOdmIoModule_Gpio, 0x0a, 0x5 }, /* GPIO Port K and Pin 5 */
+ { NvOdmIoModule_Gpio, 0x0a, 0x6 }, /* GPIO Port K and Pin 6 */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO8 }, /* VDD -> LDO8 (VOUT8) */
+ { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 }, /* VDD -> LDO11 (VOUT11) */
+ { NvOdmIoModule_Vdd, 0x00, MIC2826PmuSupply_LDO3 } /* VDD -> MIC2826 LDO3 */
+};
+
+// EMP Rainbow module
+static const NvOdmIoAddress s_ffaEmpAddresses[] =
+{
+ { NvOdmIoModule_Uart, 0x0, 0x0 }, /* UART 0 */
+ { NvOdmIoModule_Gpio, 0x15, 0x0 }, /* GPIO Port V and Pin 0 Reset */
+ { NvOdmIoModule_Gpio, 0x15, 0x1 }, /* GPIO Port V and Pin 1 Power */
+ { NvOdmIoModule_Gpio, 0x19, 0x0 }, /* GPIO Port Z and Pin 0 AWR */
+ { NvOdmIoModule_Gpio, 0x18, 0x6 }, /* GPIO Port Y and Pin 6 CWR */
+ { NvOdmIoModule_Gpio, 0x0e, 0x6 }, /* GPIO Port O and Pin 6 SpiInt */
+ { NvOdmIoModule_Gpio, 0x15, 0x2 }, /* GPIO Port V and Pin 2 SpiSlaveSelect */
+ { NvOdmIoModule_Slink, 0x0, 0x0 } /* Slink 0 */
+};
+
+// EMP M570 module
+static const NvOdmIoAddress s_ffaEmpM570Addresses[] =
+{
+ { NvOdmIoModule_Uart, 0x0, 0x0 }, /* UART 0 */
+ { NvOdmIoModule_Gpio, 0x15, 0x0 }, /* GPIO Port V and Pin 0 Reset */
+ { NvOdmIoModule_Gpio, 0x15, 0x1 }, /* GPIO Port V and Pin 1 Power */
+ { NvOdmIoModule_Gpio, 0x19, 0x0 }, /* GPIO Port Z and Pin 0 AWR */
+ { NvOdmIoModule_Gpio, 0x18, 0x6 }, /* GPIO Port Y and Pin 6 CWR */
+};
+
+// IFX Modem module
+static const NvOdmIoAddress s_ffaInfnAddresses[] =
+{
+ { NvOdmIoModule_Spi, 0x0, 0x0 }, /* Spi Controller 0 and Chip Select 0 */
+ { NvOdmIoModule_Gpio, 0x18, 0x6 }, /* GPIO Port Y and Pin 6 SRDY */
+ { NvOdmIoModule_Gpio, 0x19, 0x0 }, /* GPIO Port Z and Pin 0 MRDY */
+ { NvOdmIoModule_Gpio, 0x15, 0x0 }, /* GPIO Port V and Pin 0 Reset */
+ { NvOdmIoModule_Gpio, 0x15, 0x1 } /* GPIO Port V and Pin 1 Power */
+};
+
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h
new file mode 100644
index 000000000000..69b364f11689
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA APX ODM Kit::
+ * Implementation of the ODM Peripheral Discovery API</b>
+ *
+ * @b Description: Specifies the peripheral connectivity
+ * database Peripheral entries for the E951
+ * COMMS module.
+ */
+// Bluetooth on COMMs Module
+{
+ NV_ODM_GUID('b','l','u','t','o','o','t','h'),
+ ffaBluetoothAddresses,
+ NV_ARRAY_SIZE(ffaBluetoothAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// Sdio wlan on COMMs Module
+{
+ NV_ODM_GUID('s','d','i','o','w','l','a','n'),
+ s_ffaWlanAddresses,
+ NV_ARRAY_SIZE(s_ffaWlanAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// EMP Modem on COMMs Module
+{
+ NV_ODM_GUID('e','m','p',' ','_','m','d','m'),
+ s_ffaEmpAddresses,
+ NV_ARRAY_SIZE(s_ffaEmpAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// EMP M570 Modem on COMMs Module
+{
+ NV_ODM_GUID('e','m','p',' ','M','5','7','0'),
+ s_ffaEmpM570Addresses,
+ NV_ARRAY_SIZE(s_ffaEmpM570Addresses),
+ NvOdmPeripheralClass_Other
+},
+
+// IFX Modem on COMMs Module
+{
+ NV_ODM_GUID('s','p','i',' ','_','i','p','c'),
+ s_ffaInfnAddresses,
+ NV_ARRAY_SIZE(s_ffaInfnAddresses),
+ NvOdmPeripheralClass_Other
+},
+
+// NOTE: This list *must* end with a trailing comma.
diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h b/arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h
new file mode 100644
index 000000000000..bfbedb35945f
--- /dev/null
+++ b/arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (c) 2009 NVIDIA Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * Neither the name of the NVIDIA Corporation nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/**
+ * @file
+ * <b>NVIDIA Tegra ODM Kit:
+ * Definition of bitfields inside the BCT customer option</b>
+ *
+ * @b Description: Defines the board-specific bitfields of the
+ * BCT customer option parameter, for NVIDIA
+ * Tegra development platforms.
+ *
+ * This file pertains to Whistler and Voyager.
+ */
+
+#ifndef NVIDIA_TEGRA_DEVKIT_CUSTOPT_H
+#define NVIDIA_TEGRA_DEVKIT_CUSTOPT_H
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+//---------- BOARD PERSONALITIES (BEGIN) ----------//
+// On the Whistler boards, be sure to match the following
+// switches with the personality setting you choose.
+//
+// SW2 = bits 3:0 (low nibble)
+// SW3 = bits 7:4 (high nibble)
+
+#define TEGRA_DEVKIT_DEFAULT_PERSONALITY \
+ TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_RANGE 7:0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_DEFAULT 0x0UL
+
+// VOYAGER, eMMC, NO TRACE (10x8 keypad)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_01 0x01UL // ULPI = baseband
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05 0x05UL // ULPI = UART1
+
+// VOYAGER, eMMC, with TRACE (7x1 keypad)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11 0x11UL // ULPI = baseband
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15 0x15UL // ULPI = UART1
+
+// VOYAGER, NAND, NO TRACE (10x8 keypad)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 0x75UL // Voyager, NAND
+
+// WHISTLER, stand-alone
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1 0xC1UL // KB = 13x1, TRACE, GMI = A/D NOR
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C3 0xC3UL // KB = 16x8, NO TRACE, GMI = NAND
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C4 0xC4UL
+
+
+// VOYAGER, USB2-ULPI (No UART1)
+// Personality 71 is similar to the 75, except ULPI is enabled instead of UART1.
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_71 0x71UL
+
+
+//---------- BOARD PERSONALITIES (END) ----------//
+
+/// Download transport
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_RANGE 10:8
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE 0x1UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART 0x2UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB 0x3UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET 0x4UL
+
+/// Transport option (bus selector), for UART and Ethernet transport
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_RANGE 12:11
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A 0x1UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B 0x2UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C 0x3UL
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_RANGE 12:11
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI 0x1UL
+
+/// RIL selection
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_RANGE 14:13
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW 0x1UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI 0x2UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX 0x3UL
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_RANGE 17:15
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_DEFAULT 0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTA 0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTB 1
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTC 2
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTD 3
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTE 4
+
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_RANGE 19:18
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT 0
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE 1
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC 2
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART 3
+
+// display options
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_RANGE 22:20
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_DEFAULT 0x0UL
+// embedded panel (lvds, dsi, etc)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_EMBEDDED 0x0UL
+// no panels (external or embedded)
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_NULL 0x1UL
+// use hdmi as the primary
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_HDMI 0x2UL
+// use crt as the primary
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_CRT 0x3UL
+
+
+// Enable DHCP
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_RANGE 23:23
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_ENABLE 0x1UL
+
+/// Carveout RAM
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_RANGE 27:24
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_1 0x1UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_2 0x2UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_3 0x3UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_4 0x4UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_5 0x5UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_6 0x6UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_7 0x7UL
+#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_8 0x8UL //32 MB
+
+
+/// Total RAM
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_RANGE 30:28
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT 0x0UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1 0x1UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_2 0x2UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_3 0x3UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_4 0x4UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_5 0x5UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_6 0x6UL
+#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_7 0x7UL
+/// Soc low power state
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_RANGE 31:31
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP0 0x0UL
+#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1 0x1UL
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif