msm: board-8064-pmic: Add PM8921 Sub-devices
Enable supported sub-devices for PM8921 pmic for
APQ8064 board.
Also, contrary to the information present in the irq
mapping table for 8064, GPIO 77 is _not_ connected to the
PM8821_USR_IRQ_N. For now use TLMM summary irq line to
support PMIC irq.
Signed-off-by: Jay Chokshi <jchokshi@codeaurora.org>
Change-Id: If32729e6e5d147676102a5796c0a509fc8af8440
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 2182079..7b12f97 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -15,15 +15,189 @@
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
+#include <linux/mfd/pm8xxx/pm8921.h>
+#include <linux/leds.h>
+#include <linux/leds-pm8xxx.h>
#include <asm/mach-types.h>
#include <asm/mach/mmc.h>
#include <mach/msm_bus_board.h>
#include <mach/board.h>
#include <mach/gpio.h>
#include <mach/gpiomux.h>
+#include <mach/restart.h>
#include "devices.h"
#include "board-8064.h"
+struct pm8xxx_gpio_init {
+ unsigned gpio;
+ struct pm_gpio config;
+};
+
+struct pm8xxx_mpp_init {
+ unsigned mpp;
+ struct pm8xxx_mpp_config_data config;
+};
+
+#define PM8921_GPIO_INIT(_gpio, _dir, _buf, _val, _pull, _vin, _out_strength, \
+ _func, _inv, _disable) \
+{ \
+ .gpio = PM8921_GPIO_PM_TO_SYS(_gpio), \
+ .config = { \
+ .direction = _dir, \
+ .output_buffer = _buf, \
+ .output_value = _val, \
+ .pull = _pull, \
+ .vin_sel = _vin, \
+ .out_strength = _out_strength, \
+ .function = _func, \
+ .inv_int_pol = _inv, \
+ .disable_pin = _disable, \
+ } \
+}
+
+#define PM8921_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+ .mpp = PM8921_MPP_PM_TO_SYS(_mpp), \
+ .config = { \
+ .type = PM8XXX_MPP_TYPE_##_type, \
+ .level = _level, \
+ .control = PM8XXX_MPP_##_control, \
+ } \
+}
+
+#define PM8821_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+ .mpp = PM8821_MPP_PM_TO_SYS(_mpp), \
+ .config = { \
+ .type = PM8XXX_MPP_TYPE_##_type, \
+ .level = _level, \
+ .control = PM8XXX_MPP_##_control, \
+ } \
+}
+
+#define PM8921_GPIO_DISABLE(_gpio) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, 0, 0, 0, PM_GPIO_VIN_S4, \
+ 0, 0, 0, 1)
+
+#define PM8921_GPIO_OUTPUT(_gpio, _val, _strength) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_##_strength, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8921_GPIO_INPUT(_gpio, _pull) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_IN, PM_GPIO_OUT_BUF_CMOS, 0, \
+ _pull, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_NO, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+#define PM8921_GPIO_OUTPUT_FUNC(_gpio, _val, _func) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, PM_GPIO_VIN_S4, \
+ PM_GPIO_STRENGTH_HIGH, \
+ _func, 0, 0)
+
+#define PM8921_GPIO_OUTPUT_VIN(_gpio, _val, _vin) \
+ PM8921_GPIO_INIT(_gpio, PM_GPIO_DIR_OUT, PM_GPIO_OUT_BUF_CMOS, _val, \
+ PM_GPIO_PULL_NO, _vin, \
+ PM_GPIO_STRENGTH_HIGH, \
+ PM_GPIO_FUNC_NORMAL, 0, 0)
+
+/* Initial PM8921 GPIO configurations */
+static struct pm8xxx_gpio_init pm8921_gpios[] __initdata = {
+};
+
+/* Initial PM8XXX MPP configurations */
+static struct pm8xxx_mpp_init pm8xxx_mpps[] __initdata = {
+};
+
+void __init apq8064_pm8xxx_gpio_mpp_init(void)
+{
+ int i, rc;
+
+ for (i = 0; i < ARRAY_SIZE(pm8921_gpios); i++) {
+ rc = pm8xxx_gpio_config(pm8921_gpios[i].gpio,
+ &pm8921_gpios[i].config);
+ if (rc) {
+ pr_err("%s: pm8xxx_gpio_config: rc=%d\n", __func__, rc);
+ break;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pm8xxx_mpps); i++) {
+ rc = pm8xxx_mpp_config(pm8xxx_mpps[i].mpp,
+ &pm8xxx_mpps[i].config);
+ if (rc) {
+ pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+ break;
+ }
+ }
+}
+
+static struct pm8xxx_pwrkey_platform_data apq8064_pm8921_pwrkey_pdata = {
+ .pull_up = 1,
+ .kpd_trigger_delay_us = 15625,
+ .wakeup = 1,
+};
+
+static struct pm8xxx_misc_platform_data apq8064_pm8921_misc_pdata = {
+ .priority = 0,
+};
+
+#define PM8921_LC_LED_MAX_CURRENT 4 /* I = 4mA */
+#define PM8921_LC_LED_LOW_CURRENT 1 /* I = 1mA */
+#define PM8XXX_LED_PWM_PERIOD 1000
+#define PM8XXX_LED_PWM_DUTY_MS 20
+/**
+ * PM8XXX_PWM_CHANNEL_NONE shall be used when LED shall not be
+ * driven using PWM feature.
+ */
+#define PM8XXX_PWM_CHANNEL_NONE -1
+
+static struct led_info pm8921_led_info[] = {
+ [0] = {
+ .name = "led:red",
+ .default_trigger = "ac-online",
+ },
+};
+
+static struct led_platform_data pm8921_led_core_pdata = {
+ .num_leds = ARRAY_SIZE(pm8921_led_info),
+ .leds = pm8921_led_info,
+};
+
+static int pm8921_led0_pwm_duty_pcts[56] = {
+ 1, 4, 8, 12, 16, 20, 24, 28, 32, 36,
+ 40, 44, 46, 52, 56, 60, 64, 68, 72, 76,
+ 80, 84, 88, 92, 96, 100, 100, 100, 98, 95,
+ 92, 88, 84, 82, 78, 74, 70, 66, 62, 58,
+ 58, 54, 50, 48, 42, 38, 34, 30, 26, 22,
+ 14, 10, 6, 4, 1
+};
+
+static struct pm8xxx_pwm_duty_cycles pm8921_led0_pwm_duty_cycles = {
+ .duty_pcts = (int *)&pm8921_led0_pwm_duty_pcts,
+ .num_duty_pcts = ARRAY_SIZE(pm8921_led0_pwm_duty_pcts),
+ .duty_ms = PM8XXX_LED_PWM_DUTY_MS,
+ .start_idx = 0,
+};
+
+static struct pm8xxx_led_config pm8921_led_configs[] = {
+ [0] = {
+ .id = PM8XXX_ID_LED_0,
+ .mode = PM8XXX_LED_MODE_PWM2,
+ .max_current = PM8921_LC_LED_MAX_CURRENT,
+ .pwm_channel = 5,
+ .pwm_period_us = PM8XXX_LED_PWM_PERIOD,
+ .pwm_duty_cycles = &pm8921_led0_pwm_duty_cycles,
+ },
+};
+
+static struct pm8xxx_led_platform_data apq8064_pm8921_leds_pdata = {
+ .led_core = &pm8921_led_core_pdata,
+ .configs = pm8921_led_configs,
+ .num_configs = ARRAY_SIZE(pm8921_led_configs),
+};
static struct pm8xxx_mpp_platform_data
apq8064_pm8921_mpp_pdata __devinitdata = {
@@ -56,12 +230,15 @@
.gpio_pdata = &apq8064_pm8921_gpio_pdata,
.mpp_pdata = &apq8064_pm8921_mpp_pdata,
.rtc_pdata = &apq8064_pm8921_rtc_pdata,
+ .pwrkey_pdata = &apq8064_pm8921_pwrkey_pdata,
+ .misc_pdata = &apq8064_pm8921_misc_pdata,
+ .leds_pdata = &apq8064_pm8921_leds_pdata,
};
static struct pm8xxx_irq_platform_data
apq8064_pm8821_irq_pdata __devinitdata = {
.irq_base = PM8821_IRQ_BASE,
- .devirq = PM8821_USR_IRQ_N,
+ .devirq = PM8821_SEC_IRQ_N,
.irq_trigger_flag = IRQF_TRIGGER_HIGH,
.dev_id = 1,
};
@@ -95,6 +272,8 @@
void __init apq8064_init_pmic(void)
{
+ pmic_reset_irq = PM8921_IRQ_BASE + PM8921_RESOUT_IRQ;
+
apq8064_device_ssbi_pmic1.dev.platform_data =
&apq8064_ssbi_pm8921_pdata;
apq8064_device_ssbi_pmic2.dev.platform_data =
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index a95d733..4f1adad 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -1183,6 +1183,7 @@
apq8064_device_otg.dev.platform_data = &msm_otg_pdata;
apq8064_init_buses();
platform_add_devices(common_devices, ARRAY_SIZE(common_devices));
+ apq8064_pm8xxx_gpio_mpp_init();
apq8064_init_mmc();
slim_register_board_info(apq8064_slim_devices,
ARRAY_SIZE(apq8064_slim_devices));
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index 4735504..f106b95 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -54,5 +54,6 @@
void apq8064_mdp_writeback(struct memtype_reserve *reserve_table);
void apq8064_init_gpu(void);
+void apq8064_pm8xxx_gpio_mpp_init(void);
#endif