2 * linux/arch/arm/mach-sc8800s/mfp-sprd.c
4 * Spreadtrum SoC multi-function pin configuration support
6 * The GPIOs on SoC can be configured as one of many alternate
9 * Author: Yingchun Li(yingchun.li@spreadtrum.com)
10 * Created: March 10, 2010
11 * Copyright: Spreadtrum Inc.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
19 //#include <linux/module.h>
20 //#include <linux/kernel.h>
22 //#include <mach/mfp.h>
23 //#include <mach/regs_cpc.h>
24 #include <asm/arch/mfp.h>
25 #include <asm/arch/sc8810_reg_base.h>
26 //#include <asm/arch/sc8810_cpc.h>
31 NOTE: pin to gpio's map, you should check it from your chip's spec
33 in the map table, pin as the index, for mostly we use
34 MFP_PIN_TO_GPIO to get the gpio from the pin
36 const static unsigned long pin_gpio_map[MFP_PIN_MAX] = {
37 [MFP_PIN_MAX - 1] = 0xffff
43 we cann't find a easy way to map pin to gpio, so drop it.
45 unsigned long mfp_to_gpio(int pin)
50 static int __mfp_validate(unsigned long c)
55 static unsigned long __mfp_get_pin_reg(int pin_offset)
57 if (!(pin_offset & A_DIE_PIN)) {
58 return (unsigned long)PIN_CTL_BASE + pin_offset;
60 pin_offset &= ~A_DIE_PIN;
61 return (unsigned long)ANA_PIN_CTL_BASE + pin_offset;
66 #define MFP_DBG(fmt...) pr_debug(fmt)
67 static unsigned long __mfp_get_physical(int pin_offset)
69 if (!(pin_offset & A_DIE_PIN)) {
70 return (unsigned long)SPRD_CPC_PHYS + pin_offset;
72 pin_offset &= ~A_DIE_PIN;
73 return (unsigned long)SPRD_MISC_PHYS + 0x180 + pin_offset;
77 #define MFP_DBG(fmt...)
80 static int __mfp_config_pin(unsigned long c)
83 unsigned long pin_reg;
84 unsigned long pin_cfg;
87 pin_offset = MFP_CFG_TO_REG_OFFS(c);
88 pin_reg = __mfp_get_pin_reg(pin_offset);
90 MFP_DBG("register is :0x%x, old config is %x\r\n",
91 __mfp_get_pin_reg(pin_offset),
92 __raw_readl(pin_reg));
94 //local_irq_save(flags);
95 pin_cfg =__raw_readl(pin_reg);
97 pin_cfg = (pin_cfg & ~MFP_IO_MASK) | (c & MFP_IO_MASK);
100 if (c & MFP_S_PULL_SET) {
101 pin_cfg = (pin_cfg & ~MFP_S_PULL_MASK) | (c & MFP_S_PULL_MASK);
104 if (c & MFP_AF_SET) {
105 pin_cfg = (pin_cfg & ~MFP_AF_MASK) | (c & MFP_AF_MASK);
108 if (c & MFP_F_PULL_SET) {
109 pin_cfg = (pin_cfg & ~MFP_F_PULL_MASK) | (c & MFP_F_PULL_MASK);
112 if (c & MFP_DS_SET) {
113 pin_cfg = (pin_cfg & ~MFP_DS_MASK) | (c & MFP_DS_MASK);
116 __raw_writel(pin_cfg, pin_reg);
117 // local_irq_restore(flags);
119 MFP_DBG("new config is :%x\r\n", (int)pin_cfg);
124 static unsigned long spi_cs1_gpio_cfg = MFP_CFG_X(SPI_CSN0, GPIO, DS1, F_PULL_NONE, S_PULL_DOWN, IO_NONE);
126 void sprd_mfp_config(unsigned long *mfp_cfgs, int num)
133 for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
135 res = __mfp_validate((*c));
139 // local_irq_save(flags);
141 __mfp_config_pin(*c);
143 // local_irq_restore(flags);
146 //EXPORT_SYMBOL_GPL(sprd_mfp_config);