pm8921: Add pwm driver for pmic.
Change-Id: I7846754945b21399c77ae58d6c09843ca8aa07f2
diff --git a/dev/pmic/pm8921/include/dev/pm8921_pwm.h b/dev/pmic/pm8921/include/dev/pm8921_pwm.h
new file mode 100755
index 0000000..8f2f34d
--- /dev/null
+++ b/dev/pmic/pm8921/include/dev/pm8921_pwm.h
@@ -0,0 +1,166 @@
+/*
+ * * Copyright (c) 2011, Code Aurora Forum. 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 Code Aurora Forum, Inc. 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 __PMIC_PWM_H
+#define __PMIC_PWM_H
+
+/* PMIC 8921 LPG defines */
+
+#define PM8921_LPG_CTL_BASE (0x13C)
+
+#define PM8921_LPG_CTL(n) (PM8921_LPG_CTL_BASE + (n))
+#define PM8921_LPG_BANK_SEL (0x143)
+#define PM8921_LPG_BANK_ENABLE (0x144)
+
+#define USEC_PER_SEC 1000000L
+#define NSEC_PER_SEC 1000000000L
+#define NSEC_PER_USEC 1000
+
+#define PWM_FREQ_HZ 300
+#define PWM_LEVEL 15
+
+#define NUM_CLOCKS 3
+#define NUM_PRE_DIVIDE 4
+
+#define NUM_LPG_CTL_REGS 7
+
+#define PRE_DIVIDE_0 2
+#define PRE_DIVIDE_1 3
+#define PRE_DIVIDE_2 5
+#define PRE_DIVIDE_3 6
+
+#define PRE_DIVIDE_MIN PRE_DIVIDE_0
+#define PRE_DIVIDE_MAX PRE_DIVIDE_3
+
+#define PM_PWM_M_MIN 0
+#define PM_PWM_M_MAX 7
+
+#define NSEC_1000HZ (NSEC_PER_SEC / 1000)
+#define NSEC_32768HZ (NSEC_PER_SEC / 32768)
+#define NSEC_19P2MHZ (NSEC_PER_SEC / 19200000)
+
+#define CLK_PERIOD_MIN NSEC_19P2MHZ
+#define CLK_PERIOD_MAX NSEC_1000HZ
+
+#define MIN_MPT ((PRE_DIVIDE_MIN * CLK_PERIOD_MIN) << PM_PWM_M_MIN)
+#define MAX_MPT ((PRE_DIVIDE_MAX * CLK_PERIOD_MAX) << PM_PWM_M_MAX)
+
+/* The MAX value is computation limit. Hardware limit is 393 seconds. */
+#define PM_PWM_PERIOD_MAX (274 * USEC_PER_SEC)
+/* The MIN value is hardware limit. */
+#define PM_PWM_PERIOD_MIN 7 /* micro seconds */
+
+#define PWM_PERIOD_USEC (USEC_PER_SEC / PWM_FREQ_HZ)
+#define PWM_DUTY_LEVEL (PWM_PERIOD_USEC / PWM_LEVEL)
+
+/* Control 0 */
+#define PM_PWM_1KHZ_COUNT_MASK 0xF0
+#define PM_PWM_1KHZ_COUNT_SHIFT 4
+
+#define PM_PWM_1KHZ_COUNT_MAX 15
+
+#define PM_PWM_OUTPUT_EN 0x08
+#define PM_PWM_PWM_EN 0x04
+#define PM_PWM_RAMP_GEN_EN 0x02
+#define PM_PWM_RAMP_START 0x01
+
+#define PM_PWM_PWM_START (PM_PWM_OUTPUT_EN | PM_PWM_PWM_EN)
+#define PM_PWM_RAMP_GEN_START (PM_PWM_RAMP_GEN_EN | PM_PWM_RAMP_START)
+
+/* Control 1 */
+#define PM_PWM_REVERSE_EN 0x80
+#define PM_PWM_BYPASS_LUT 0x40
+#define PM_PWM_HIGH_INDEX_MASK 0x3F
+
+/* Control 2 */
+#define PM_PWM_LOOP_EN 0x80
+#define PM_PWM_RAMP_UP 0x40
+#define PM_PWM_LOW_INDEX_MASK 0x3F
+
+/* Control 3 */
+#define PM_PWM_VALUE_BIT7_0 0xFF
+#define PM_PWM_VALUE_BIT5_0 0x3F
+
+/* Control 4 */
+#define PM_PWM_VALUE_BIT8 0x80
+
+#define PM_PWM_CLK_SEL_MASK 0x60
+#define PM_PWM_CLK_SEL_SHIFT 5
+
+#define PM_PWM_CLK_SEL_NO 0
+#define PM_PWM_CLK_SEL_1KHZ 1
+#define PM_PWM_CLK_SEL_32KHZ 2
+#define PM_PWM_CLK_SEL_19P2MHZ 3
+
+#define PM_PWM_PREDIVIDE_MASK 0x18
+#define PM_PWM_PREDIVIDE_SHIFT 3
+
+#define PM_PWM_PREDIVIDE_2 0
+#define PM_PWM_PREDIVIDE_3 1
+#define PM_PWM_PREDIVIDE_5 2
+#define PM_PWM_PREDIVIDE_6 3
+
+#define PM_PWM_M_MASK 0x07
+#define PM_PWM_M_MIN 0
+#define PM_PWM_M_MAX 7
+
+/* Control 5 */
+#define PM_PWM_PAUSE_COUNT_HI_MASK 0xFC
+#define PM_PWM_PAUSE_COUNT_HI_SHIFT 2
+
+#define PM_PWM_PAUSE_ENABLE_HIGH 0x02
+#define PM_PWM_SIZE_9_BIT 0x01
+
+/* Control 6 */
+#define PM_PWM_PAUSE_COUNT_LO_MASK 0xFC
+#define PM_PWM_PAUSE_COUNT_LO_SHIFT 2
+
+#define PM_PWM_PAUSE_ENABLE_LOW 0x02
+#define PM_PWM_RESERVED 0x01
+
+#define PM_PWM_PAUSE_COUNT_MAX 56 /* < 2^6 = 64*/
+
+struct pm_pwm_config {
+ uint8_t pwm_size; /* round up to 6 or 9 for 6/9-bit PWM SIZE */
+ uint8_t clk;
+ uint8_t pre_div;
+ uint8_t pre_div_exp;
+ uint8_t pwm_value;
+ uint8_t bypass_lut;
+ uint8_t pwm_ctl[NUM_LPG_CTL_REGS];
+};
+
+/* External PWM functions */
+int pm8921_pwm_enable(uint8_t pwm_id, pm8921_dev_t *dev);
+int pm8921_pwm_config(uint8_t pwm_id,
+ uint32_t duty_us,
+ uint32_t period_us,
+ pm8921_dev_t *dev);
+
+#endif