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>
30 NOTE: pin to gpio's map, you should check it from your chip's spec
32 in the map table, pin as the index, for mostly we use
33 MFP_PIN_TO_GPIO to get the gpio from the pin
35 const static unsigned long pin_gpio_map[MFP_PIN_MAX] = {
36 [MFP_PIN_MAX - 1] = 0xffff
42 we cann't find a easy way to map pin to gpio, so drop it.
44 unsigned long mfp_to_gpio(int pin)
49 static int __mfp_validate(unsigned long c)
54 static unsigned long __mfp_get_pin_reg(int pin_offset)
56 if (!(pin_offset & A_DIE_PIN)) {
57 return (unsigned long)PIN_CTL_BASE + pin_offset;
59 pin_offset &= ~A_DIE_PIN;
60 return (unsigned long)ANA_PIN_CTL_BASE + pin_offset;
65 #define MFP_DBG(fmt...) pr_debug(fmt)
66 static unsigned long __mfp_get_physical(int pin_offset)
68 if (!(pin_offset & A_DIE_PIN)) {
69 return (unsigned long)SPRD_CPC_PHYS + pin_offset;
71 pin_offset &= ~A_DIE_PIN;
72 return (unsigned long)SPRD_MISC_PHYS + 0x180 + pin_offset;
76 #define MFP_DBG(fmt...)
79 static int __mfp_config_pin(unsigned long c)
82 unsigned long pin_reg;
83 unsigned long pin_cfg;
86 pin_offset = MFP_CFG_TO_REG_OFFS(c);
87 pin_reg = __mfp_get_pin_reg(pin_offset);
89 MFP_DBG("register is :0x%x, old config is %x\r\n",
90 __mfp_get_physical(pin_offset),
91 __raw_readl(pin_reg));
93 //local_irq_save(flags);
94 pin_cfg =__raw_readl(pin_reg);
96 pin_cfg = (pin_cfg & ~MFP_IO_MASK) | (c & MFP_IO_MASK);
99 if (c & MFP_S_PULL_SET) {
100 pin_cfg = (pin_cfg & ~MFP_S_PULL_MASK) | (c & MFP_S_PULL_MASK);
103 if (c & MFP_AF_SET) {
104 pin_cfg = (pin_cfg & ~MFP_AF_MASK) | (c & MFP_AF_MASK);
107 if (c & MFP_F_PULL_SET) {
108 pin_cfg = (pin_cfg & ~MFP_F_PULL_MASK) | (c & MFP_F_PULL_MASK);
111 if (c & MFP_DS_SET) {
112 pin_cfg = (pin_cfg & ~MFP_DS_MASK) | (c & MFP_DS_MASK);
115 __raw_writel(pin_cfg, pin_reg);
116 // local_irq_restore(flags);
118 MFP_DBG("new config is :%x\r\n", (int)pin_cfg);
123 static unsigned long spi_cs1_gpio_cfg = MFP_CFG_X(SPI_CSN0, GPIO, DS1, F_PULL_NONE, S_PULL_DOWN, IO_NONE);
125 void sprd_mfp_config(unsigned long *mfp_cfgs, int num)
132 for (i = 0, c = mfp_cfgs; i < num; i++, c++) {
134 res = __mfp_validate((*c));
138 // local_irq_save(flags);
140 __mfp_config_pin(*c);
142 // local_irq_restore(flags);
145 //EXPORT_SYMBOL_GPL(sprd_mfp_config);