summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/odm_kit/adaptations
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/adaptations
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/adaptations')
-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
95 files changed, 18446 insertions, 0 deletions
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