[PATCH 3.4 0/8] Add support for Olinuxino A13_Micro + A10s

431 views
Skip to first unread message

Hans de Goede

unread,
Jan 24, 2013, 6:00:45 PM1/24/13
to linux...@googlegroups.com
Some work of my own as well as some work from hehopmajieh (Thanks!) note
that the A10s support is still very much WIP!

Regards,

Hans

Hans de Goede

unread,
Jan 24, 2013, 6:00:46 PM1/24/13
to linux...@googlegroups.com, Hans de Goede
It looks like the 3.4 branch has been broken for compiling for sun5i
for a while, this fixes it.

Signed-off-by : Hans de Goede <hdeg...@redhat.com>
---
drivers/video/sunxi/disp/OSAL_Pin.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/sunxi/disp/OSAL_Pin.c b/drivers/video/sunxi/disp/OSAL_Pin.c
index df76f58..d4c0fca 100644
--- a/drivers/video/sunxi/disp/OSAL_Pin.c
+++ b/drivers/video/sunxi/disp/OSAL_Pin.c
@@ -21,7 +21,7 @@
#include "OSAL_Pin.h"

#ifdef CONFIG_ARCH_SUN5I
-#include "../../../../power/axp_power/axp-gpio.h"
+#include "../../../power/axp_power/axp-gpio.h"
#endif

__hdle OSAL_GPIO_Request(user_gpio_set_t *gpio_list, __u32 group_count_max)
--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:47 PM1/24/13
to linux...@googlegroups.com, Hans de Goede
I wrote this patch while working on A10s support, then when I tried to
get my Olinuxino A13_Micro running using commits from
https://github.com/hehopmajieh/linux-sunxi/

I noticed a similar patch there:
https://github.com/hehopmajieh/linux-sunxi/commit/e7c1fc23a723bdf799c0aef02920b55650c06e12

But I believe this fix is better because:
1) It properly checks for CONFIG_AXP rather then CONFIG_POWER, as the former
can still be unset when the latter is set
2) Rather then just ignoring axp gpio calls when not build with axp support
it complains loudly when other code tries to use axp gpio-s when built without

Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
drivers/video/sunxi/disp/OSAL_Pin.c | 34 ++++++++++++++++++++++++++++++----
1 file changed, 30 insertions(+), 4 deletions(-)

diff --git a/drivers/video/sunxi/disp/OSAL_Pin.c b/drivers/video/sunxi/disp/OSAL_Pin.c
index d4c0fca..de62f1f 100644
--- a/drivers/video/sunxi/disp/OSAL_Pin.c
+++ b/drivers/video/sunxi/disp/OSAL_Pin.c
@@ -21,7 +21,13 @@
#include "OSAL_Pin.h"

#ifdef CONFIG_ARCH_SUN5I
+#if defined(CONFIG_AW_AXP) || \
+ (defined(CONFIG_FB_SUNXI_MODULE) && defined(CONFIG_AW_AXP_MODULE))
#include "../../../power/axp_power/axp-gpio.h"
+#define SUNXI_USE_AXP_GPIO
+#else
+#warning "Building sunxi-fb without axp gpio support"
+#endif
#endif

__hdle OSAL_GPIO_Request(user_gpio_set_t *gpio_list, __u32 group_count_max)
@@ -34,11 +40,16 @@ __hdle OSAL_GPIO_Request(user_gpio_set_t *gpio_list, __u32 group_count_max)
#ifdef CONFIG_ARCH_SUN5I
if (gpio_list->port == 0xffff) {
if (gpio_list->mul_sel == 0 || gpio_list->mul_sel == 1) {
+#ifdef SUNXI_USE_AXP_GPIO
axp_gpio_set_io(gpio_list->port_num,
gpio_list->mul_sel);
axp_gpio_set_value(gpio_list->port_num,
gpio_list->data);
return 100 + gpio_list->port_num;
+#else
+ WARN_ON_ONCE("axp gpio used without AXP");
+ return 0;
+#endif
} else
return 0;
} else
@@ -101,10 +112,15 @@ __s32 OSAL_GPIO_DevSetONEPIN_IO_STATUS(u32 p_handler,
const char *gpio_name)
{
#ifdef CONFIG_ARCH_SUN5I
- if (p_handler < 200 && p_handler >= 100)
+ if (p_handler < 200 && p_handler >= 100) {
+#ifdef SUNXI_USE_AXP_GPIO
return axp_gpio_set_io(p_handler - 100,
if_set_to_output_status);
- else
+#else
+ WARN_ON_ONCE("axp gpio used without AXP");
+ return 0;
+#endif
+ } else
#endif
return gpio_set_one_pin_io_status(p_handler,
if_set_to_output_status,
@@ -121,10 +137,15 @@ __s32 OSAL_GPIO_DevREAD_ONEPIN_DATA(u32 p_handler, const char *gpio_name)
{
#ifdef CONFIG_ARCH_SUN5I
if (p_handler < 200 && p_handler >= 100) {
+#ifdef SUNXI_USE_AXP_GPIO
int value;

axp_gpio_get_value(p_handler - 100, &value);
return value;
+#else
+ WARN_ON_ONCE("axp gpio used without AXP");
+ return 0;
+#endif
} else
#endif
return gpio_read_one_pin_value(p_handler, gpio_name);
@@ -134,9 +155,14 @@ __s32 OSAL_GPIO_DevWRITE_ONEPIN_DATA(u32 p_handler, __u32 value_to_gpio,
const char *gpio_name)
{
#ifdef CONFIG_ARCH_SUN5I
- if ((p_handler < 200) && (p_handler >= 100))
+ if ((p_handler < 200) && (p_handler >= 100)) {
+#ifdef SUNXI_USE_AXP_GPIO
return axp_gpio_set_value(p_handler - 100, value_to_gpio);
- else
+#else
+ WARN_ON_ONCE("axp gpio used without AXP");
+ return 0;
+#endif
+ } else
#endif
return gpio_write_one_pin_value(p_handler, value_to_gpio,
gpio_name);
--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:48 PM1/24/13
to linux...@googlegroups.com, Hans de Goede
I was (wrongly) trying to set screen0_output_type to vga for the
Olinuxino A13_Micro (the Olinuxino A13 * uses LCD output + some external
logic for VGA-out).

This leads to a NULL ref due to the sunxi-disp-vga code containing some
special handling for composite out which tries to set up dac parameters
on the 2nd tv-encoder. *But* the sun5i only has 1 tv-encoder.

Even though this was mainly caused by a wrong fex file I'm still submitting
this patch, because the A10s does have a fully functional display block,
which likely does support VGA out.

Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
drivers/video/sunxi/disp/disp_vga.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/video/sunxi/disp/disp_vga.c b/drivers/video/sunxi/disp/disp_vga.c
index 1d3c05f..97dc5c5 100644
--- a/drivers/video/sunxi/disp/disp_vga.c
+++ b/drivers/video/sunxi/disp/disp_vga.c
@@ -45,7 +45,9 @@ __s32 BSP_disp_vga_open(__u32 sel)
{
if (!(gdisp.screen[sel].status & VGA_ON)) {
__disp_vga_mode_t vga_mode;
+#ifdef CONFIG_ARCH_SUN4I
__u32 i = 0;
+#endif

vga_mode = gdisp.screen[sel].vga_mode;

@@ -76,6 +78,7 @@ __s32 BSP_disp_vga_open(__u32 sel)
Disp_TVEC_Open(sel);
TCON1_open(sel);

+#ifdef CONFIG_ARCH_SUN4I
for (i = 0; i < 4; i++) {
if (gdisp.screen[sel].dac_source[i] ==
DISP_TV_DAC_SRC_COMPOSITE) {
@@ -84,6 +87,7 @@ __s32 BSP_disp_vga_open(__u32 sel)
TVE_dac_sel(1 - sel, i, i);
}
}
+#endif

Disp_Switch_Dram_Mode(DISP_OUTPUT_TYPE_VGA, vga_mode);

--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:49 PM1/24/13
to linux...@googlegroups.com, hehopmajieh, Hans de Goede
From: hehopmajieh <gami...@gmail.com>

The Olinuxino A13_Micro needs a special config with a bunch of options
which cause memory to be reserved disabled, because it only has 256M

Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
arch/arm/configs/a13om_defconfig | 1906 ++++++++++++++++++++++++++++++++++++++
1 file changed, 1906 insertions(+)
create mode 100644 arch/arm/configs/a13om_defconfig

diff --git a/arch/arm/configs/a13om_defconfig b/arch/arm/configs/a13om_defconfig
new file mode 100644
index 0000000..89e54de
--- /dev/null
+++ b/arch/arm/configs/a13om_defconfig
@@ -0,0 +1,1906 @@
+#
+# Automatically generated make config: don't edit
+# Linux/arm 3.0.52 Kernel Configuration
+#
+CONFIG_ARM=y
+CONFIG_CHIP_ID=1125
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_KTIME_SCALAR=y
+CONFIG_HAVE_PROC_CPU=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_ARCH_HAS_CPUFREQ=y
+CONFIG_ARCH_HAS_CPU_IDLE_WAIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_NEED_DMA_MAP_STATE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_HAVE_IRQ_WORK=y
+CONFIG_IRQ_WORK=y
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZMA=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="A13Micro"
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_FHANDLE is not set
+CONFIG_TASKSTATS=y
+CONFIG_TASK_DELAY_ACCT=y
+CONFIG_TASK_XACCT=y
+CONFIG_TASK_IO_ACCOUNTING=y
+CONFIG_AUDIT=y
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HAVE_SPARSE_IRQ=y
+CONFIG_GENERIC_IRQ_SHOW=y
+CONFIG_SPARSE_IRQ=y
+
+#
+# RCU Subsystem
+#
+# CONFIG_TREE_PREEMPT_RCU is not set
+CONFIG_TINY_RCU=y
+# CONFIG_TINY_PREEMPT_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=19
+CONFIG_CGROUPS=y
+# CONFIG_CGROUP_DEBUG is not set
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CPUSETS=y
+CONFIG_PROC_PID_CPUSET=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+# CONFIG_CGROUP_MEM_RES_CTLR is not set
+# CONFIG_CGROUP_PERF is not set
+CONFIG_BLK_CGROUP=y
+# CONFIG_DEBUG_BLK_CGROUP is not set
+CONFIG_NAMESPACES=y
+CONFIG_UTS_NS=y
+CONFIG_IPC_NS=y
+CONFIG_PID_NS=y
+CONFIG_NET_NS=y
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_RD_XZ=y
+CONFIG_RD_LZO=y
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_PANIC_TIMEOUT=0
+# CONFIG_EXPERT is not set
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_ASHMEM=y
+CONFIG_AIO=y
+# CONFIG_EMBEDDED is not set
+CONFIG_HAVE_PERF_EVENTS=y
+CONFIG_PERF_USE_VMALLOC=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_PERF_EVENTS=y
+CONFIG_PERF_COUNTERS=y
+# CONFIG_DEBUG_PERF_USE_VMALLOC is not set
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
+CONFIG_HAVE_CLK=y
+CONFIG_HAVE_DMA_API_DEBUG=y
+CONFIG_HAVE_HW_BREAKPOINT=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+CONFIG_BLK_DEV_INTEGRITY=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_SPIN_UNLOCK is not set
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_READ_UNLOCK is not set
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQ is not set
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+# CONFIG_INLINE_WRITE_UNLOCK is not set
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_VEXPRESS is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CNS3XXX is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_MXC is not set
+# CONFIG_ARCH_MXS is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_LPC32XX is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_NUC93X is not set
+# CONFIG_ARCH_TEGRA is not set
+# CONFIG_ARCH_SUN3I is not set
+# CONFIG_ARCH_SUN4I is not set
+CONFIG_ARCH_SUN5I=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_SHMOBILE is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5P64X0 is not set
+# CONFIG_ARCH_S5PC100 is not set
+# CONFIG_ARCH_S5PV210 is not set
+# CONFIG_ARCH_EXYNOS4 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_TCC_926 is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_U8500 is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
+
+#
+# System MMU
+#
+CONFIG_SW_DEBUG_UART=1
+# CONFIG_SUNXI_IGNORE_ATAG_MEM is not set
+CONFIG_MACH_SUN5I=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+CONFIG_SWP_EMULATE=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_ARM_L1_CACHE_SHIFT_6=y
+CONFIG_ARM_L1_CACHE_SHIFT=6
+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
+CONFIG_CPU_HAS_PMU=y
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+# CONFIG_ARM_ERRATA_743622 is not set
+# CONFIG_ARM_ERRATA_754322 is not set
+# CONFIG_ARM_ERRATA_775420 is not set
+# CONFIG_FIQ_DEBUGGER is not set
+
+#
+# Bus support
+#
+CONFIG_ARM_AMBA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
+CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
+CONFIG_HW_PERF_EVENTS=y
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_HAVE_MEMBLOCK=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+CONFIG_KSM=y
+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+CONFIG_NEED_PER_CPU_KM=y
+# CONFIG_CLEANCACHE is not set
+CONFIG_FORCE_MAX_ZONEORDER=11
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_SECCOMP is not set
+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
+# CONFIG_ARM_FLUSH_CONSOLE_ON_RESTART is not set
+
+#
+# Boot options
+#
+# CONFIG_USE_OF is not set
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="mem=448M@0x40000000 console=ttyS0,115200"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
+# CONFIG_CMDLINE_FORCE is not set
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_AUTO_ZRELADDR is not set
+
+#
+# CPU Power Management
+#
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=y
+
+#
+# Power management options
+#
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+CONFIG_HAS_WAKELOCK=y
+CONFIG_HAS_EARLYSUSPEND=y
+CONFIG_WAKELOCK=y
+CONFIG_WAKELOCK_STAT=y
+CONFIG_USER_WAKELOCK=y
+CONFIG_EARLYSUSPEND=y
+# CONFIG_NO_USER_SPACE_SCREEN_ACCESS_CONTROL is not set
+# CONFIG_CONSOLE_EARLYSUSPEND is not set
+CONFIG_FB_EARLYSUSPEND=y
+CONFIG_PM_SLEEP=y
+# CONFIG_PM_RUNTIME is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+# CONFIG_APM_EMULATION is not set
+# CONFIG_SUSPEND_TIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_IPCOMP=y
+CONFIG_NET_KEY=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+CONFIG_NET_IPIP=y
+# CONFIG_NET_IPGRE_DEMUX is not set
+CONFIG_IP_MROUTE=y
+CONFIG_IP_PIMSM_V1=y
+CONFIG_IP_PIMSM_V2=y
+# CONFIG_ARPD is not set
+CONFIG_SYN_COOKIES=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_INET_XFRM_TUNNEL=y
+CONFIG_INET_TUNNEL=y
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+CONFIG_INET_LRO=y
+# CONFIG_INET_DIAG is not set
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_IPV6 is not set
+# CONFIG_ANDROID_PARANOID_NETWORK is not set
+CONFIG_NET_ACTIVITY_STATS=y
+CONFIG_NETWORK_SECMARK=y
+# CONFIG_NETFILTER is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP is not set
+CONFIG_STP=y
+CONFIG_GARP=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_IGMP_SNOOPING=y
+CONFIG_VLAN_8021Q=y
+CONFIG_VLAN_8021Q_GVRP=y
+# CONFIG_DECNET is not set
+CONFIG_LLC=y
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_PHONET is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV is not set
+
+#
+# Network testing
+#
+CONFIG_NET_PKTGEN=m
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+CONFIG_WIRELESS=y
+CONFIG_WIRELESS_EXT=y
+CONFIG_WEXT_CORE=y
+CONFIG_WEXT_PROC=y
+CONFIG_WEXT_PRIV=y
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
+CONFIG_WIRELESS_EXT_SYSFS=y
+# CONFIG_LIB80211 is not set
+# CONFIG_CFG80211_ALLOW_RECONNECT is not set
+CONFIG_MAC80211=y
+CONFIG_MAC80211_HAS_RC=y
+CONFIG_MAC80211_RC_MINSTREL=y
+CONFIG_MAC80211_RC_MINSTREL_HT=y
+CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y
+CONFIG_MAC80211_RC_DEFAULT="minstrel_ht"
+# CONFIG_MAC80211_DEBUGFS is not set
+# CONFIG_MAC80211_DEBUG_MENU is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_RFKILL_REGULATOR is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_FIRMWARE_IN_KERNEL is not set
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_SYNC is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_CRYPTOLOOP=y
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_UB=y
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=4
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_SUN5I_NANDFLASH=y
+CONFIG_SUNXI_NAND=y
+# CONFIG_SUNXI_NAND_TEST is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_AD525X_DPOT is not set
+CONFIG_SUN4I_GPIO_UGLY=y
+# CONFIG_SUNXI_DBGREG is not set
+# CONFIG_INTEL_MID_PTI is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_APDS9802ALS is not set
+# CONFIG_ISL29003 is not set
+# CONFIG_ISL29020 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_SENSORS_BH1780 is not set
+# CONFIG_SENSORS_BH1770 is not set
+# CONFIG_SENSORS_APDS990X is not set
+# CONFIG_HMC6352 is not set
+# CONFIG_SENSORS_AK8975 is not set
+# CONFIG_TI_DAC7512 is not set
+# CONFIG_UID_STAT is not set
+# CONFIG_BMP085 is not set
+# CONFIG_APANIC is not set
+
+#
+# EEPROM support
+#
+# CONFIG_EEPROM_AT24 is not set
+# CONFIG_EEPROM_AT25 is not set
+# CONFIG_EEPROM_LEGACY is not set
+# CONFIG_EEPROM_93CX6 is not set
+
+#
+# Texas Instruments shared transport line discipline
+#
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+CONFIG_BLK_DEV_SR_VENDOR=y
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_ISCSI_BOOT_SYSFS is not set
+# CONFIG_LIBFC is not set
+# CONFIG_LIBFCOE is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+# CONFIG_ATA is not set
+CONFIG_MD=y
+CONFIG_BLK_DEV_MD=y
+CONFIG_MD_AUTODETECT=y
+CONFIG_MD_LINEAR=y
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID10 is not set
+# CONFIG_MD_RAID456 is not set
+CONFIG_MD_MULTIPATH=y
+CONFIG_MD_FAULTY=y
+CONFIG_BLK_DEV_DM=y
+# CONFIG_DM_DEBUG is not set
+CONFIG_DM_CRYPT=y
+CONFIG_DM_SNAPSHOT=y
+CONFIG_DM_MIRROR=y
+CONFIG_DM_ZERO=y
+CONFIG_DM_MULTIPATH=y
+CONFIG_DM_MULTIPATH_QL=y
+CONFIG_DM_MULTIPATH_ST=y
+# CONFIG_TARGET_CORE is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_MII=y
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+# CONFIG_MARVELL_PHY is not set
+# CONFIG_DAVICOM_PHY is not set
+# CONFIG_QSEMI_PHY is not set
+# CONFIG_LXT_PHY is not set
+# CONFIG_CICADA_PHY is not set
+# CONFIG_VITESSE_PHY is not set
+# CONFIG_SMSC_PHY is not set
+# CONFIG_BROADCOM_PHY is not set
+# CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
+# CONFIG_NATIONAL_PHY is not set
+# CONFIG_STE10XP is not set
+# CONFIG_LSI_ET1011C_PHY is not set
+# CONFIG_MICREL_PHY is not set
+# CONFIG_FIXED_PHY is not set
+# CONFIG_MDIO_BITBANG is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8851 is not set
+# CONFIG_KS8851_MLL is not set
+# CONFIG_FTMAC100 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+CONFIG_WLAN=y
+# CONFIG_LIBERTAS_THINFIRM is not set
+# CONFIG_AT76C50X_USB is not set
+# CONFIG_USB_ZD1201 is not set
+# CONFIG_RTL8187 is not set
+# CONFIG_MAC80211_HWSIM is not set
+# CONFIG_WIFI_CONTROL_FUNC is not set
+# CONFIG_ATH_COMMON is not set
+# CONFIG_B43 is not set
+# CONFIG_B43LEGACY is not set
+# CONFIG_BCM4329 is not set
+CONFIG_BCM4330=m
+# CONFIG_BCMDHD is not set
+# CONFIG_HOSTAP is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_RT2X00 is not set
+# CONFIG_MWIFIEX is not set
+CONFIG_RTL8192CU_SW=m
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_USB_IPHETH is not set
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_WEMAC_SUN4I is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=y
+CONFIG_INPUT_POLLDEV=y
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+# CONFIG_INPUT_KEYRESET is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_TCA6416 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_KEYBOARD_SUN4IKEYPAD=m
+CONFIG_KEYBOARD_SUN4I_KEYBOARD=m
+CONFIG_KEYBOARD_HV2605_KEYBOARD=m
+# CONFIG_IR_SUN5I is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_AD7877 is not set
+# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
+# CONFIG_TOUCHSCREEN_BU21013 is not set
+# CONFIG_TOUCHSCREEN_DYNAPRO is not set
+# CONFIG_TOUCHSCREEN_HAMPSHIRE is not set
+# CONFIG_TOUCHSCREEN_EETI is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MAX11801 is not set
+# CONFIG_TOUCHSCREEN_MCS5000 is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_INEXIO is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2005 is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_TOUCHSCREEN_W90X900 is not set
+# CONFIG_TOUCHSCREEN_ST1232 is not set
+# CONFIG_TOUCHSCREEN_TPS6507X is not set
+CONFIG_TOUCHSCREEN_GT801=m
+CONFIG_TOUCHSCREEN_GT811=m
+CONFIG_TOUCHSCREEN_GT818=m
+CONFIG_TOUCHSCREEN_SUN4I_TS=m
+CONFIG_TOUCHSCREEN_FT5X_TS=m
+CONFIG_TOUCHSCREEN_ZT8031=m
+# CONFIG_TOUCHSCREEN_COASIA is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=y
+# CONFIG_SERIO_AMBAKMI is not set
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_SERIO_PS2MULT is not set
+# CONFIG_GAMEPORT is not set
+# CONFIG_GSENSOR is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_DEVPTS_MULTIPLE_INSTANCES=y
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_NONSTANDARD=y
+# CONFIG_N_HDLC is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVMEM=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_STALDRV is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_SUNXI=y
+CONFIG_SERIAL_8250_NR_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_AMBA_PL010 is not set
+# CONFIG_SERIAL_AMBA_PL011 is not set
+# CONFIG_SERIAL_MAX3100 is not set
+# CONFIG_SERIAL_MAX3107 is not set
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_SERIAL_XILINX_PS_UART is not set
+# CONFIG_HVC_DCC is not set
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_DCC_TTY is not set
+# CONFIG_RAMOOPS is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_COMPAT=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_HELPER_AUTO=y
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI is not set
+# CONFIG_I2C_SIMTEC is not set
+CONFIG_I2C_SUN5I=y
+# CONFIG_SUNXI_IIC_PRINT_TRANSFER_INFO is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_DIOLAN_U2C is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TINY_USB is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+CONFIG_SPI=y
+# CONFIG_SPI_DEBUG is not set
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+# CONFIG_SPI_ALTERA is not set
+# CONFIG_SPI_BITBANG is not set
+# CONFIG_SPI_PL022 is not set
+# CONFIG_SPI_PXA2XX_PCI is not set
+CONFIG_SPI_SUN5I=y
+CONFIG_SUN5I_SPI_NDMA=y
+# CONFIG_SPI_DESIGNWARE is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_TLE62X0 is not set
+
+#
+# PPS support
+#
+
+#
+# PPS generators support
+#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
+# CONFIG_MFD_SUPPORT is not set
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+# CONFIG_REGULATOR_DUMMY is not set
+# CONFIG_REGULATOR_FIXED_VOLTAGE is not set
+# CONFIG_REGULATOR_VIRTUAL_CONSUMER is not set
+# CONFIG_REGULATOR_USERSPACE_CONSUMER is not set
+# CONFIG_REGULATOR_BQ24022 is not set
+# CONFIG_REGULATOR_MAX1586 is not set
+# CONFIG_REGULATOR_MAX8649 is not set
+# CONFIG_REGULATOR_MAX8660 is not set
+# CONFIG_REGULATOR_MAX8952 is not set
+# CONFIG_REGULATOR_LP3971 is not set
+# CONFIG_REGULATOR_LP3972 is not set
+# CONFIG_REGULATOR_TPS65023 is not set
+# CONFIG_REGULATOR_TPS6507X is not set
+# CONFIG_REGULATOR_ISL6271A is not set
+# CONFIG_REGULATOR_AD5398 is not set
+# CONFIG_REGULATOR_TPS6524X is not set
+CONFIG_MEDIA_SUPPORT=y
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+CONFIG_RC_CORE=y
+CONFIG_LIRC=y
+CONFIG_RC_MAP=y
+CONFIG_IR_NEC_DECODER=y
+CONFIG_IR_RC5_DECODER=y
+CONFIG_IR_RC6_DECODER=y
+CONFIG_IR_JVC_DECODER=y
+CONFIG_IR_SONY_DECODER=y
+CONFIG_IR_RC5_SZ_DECODER=y
+CONFIG_IR_LIRC_CODEC=y
+# CONFIG_IR_IMON is not set
+# CONFIG_IR_MCEUSB is not set
+# CONFIG_IR_REDRAT3 is not set
+# CONFIG_IR_STREAMZAP is not set
+# CONFIG_RC_LOOPBACK is not set
+# CONFIG_VIDEO_AVS_COUNTER is not set
+CONFIG_VIDEO_SUN5I_CEDAR=y
+CONFIG_VIDEO_DECODER_SUN5I=y
+# CONFIG_AUDIO_ENGINE is not set
+CONFIG_PA_CONTROL=y
+CONFIG_PA_CONFIG=y
+
+#
+# Graphics support
+#
+# CONFIG_DRM is not set
+# CONFIG_ION is not set
+# CONFIG_MALI is not set
+# CONFIG_MALI400 is not set
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+# CONFIG_FB_BOOT_VESA_SUPPORT is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_WMT_GE_ROPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+
+#
+# Display options for sun4i/sun5i
+#
+CONFIG_LYCHEE_FB_SUN5I=y
+CONFIG_FB_SUNXI=y
+CONFIG_FB_SUNXI_RESERVED_MEM=n
+CONFIG_LYCHEE_LCD_SUN5I=y
+CONFIG_FB_SUNXI_LCD=y
+# CONFIG_LYCHEE_HDMI_SUN5I is not set
+# CONFIG_FB_ARMCLCD is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_UDL is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FB_METRONOME is not set
+# CONFIG_FB_BROADSHEET is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+# CONFIG_LOGO is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_OSS_CORE is not set
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+CONFIG_SND_JACK=y
+# CONFIG_SND_SEQUENCER is not set
+# CONFIG_SND_MIXER_OSS is not set
+# CONFIG_SND_PCM_OSS is not set
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+# CONFIG_SND_RAWMIDI_SEQ is not set
+# CONFIG_SND_OPL3_LIB_SEQ is not set
+# CONFIG_SND_OPL4_LIB_SEQ is not set
+# CONFIG_SND_SBAWE_SEQ is not set
+# CONFIG_SND_EMU10K1_SEQ is not set
+CONFIG_SND_DRIVERS=y
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_ALOOP is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+CONFIG_SND_ARM=y
+# CONFIG_SND_ARMAACI is not set
+CONFIG_SND_SPI=y
+CONFIG_SND_USB=y
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_UA101 is not set
+# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
+CONFIG_SND_SOC=y
+# CONFIG_SND_SOC_CACHE_LZO is not set
+CONFIG_SOUND_SUN5I=y
+CONFIG_SND_SUN5I_SOC_CODEC=y
+# CONFIG_SND_SUN5I_SOC_HDMIAUDIO is not set
+CONFIG_SND_SUN5I_SOC_SPDIF=m
+CONFIG_SND_SUN5I_SOC_I2S_INTERFACE=m
+CONFIG_SND_SOC_I2C_AND_SPI=y
+# CONFIG_SND_SOC_ALL_CODECS is not set
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HIDRAW is not set
+# CONFIG_UHID is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=y
+# CONFIG_HID_PID is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_A4TECH=y
+# CONFIG_HID_ACRUX is not set
+CONFIG_HID_APPLE=y
+CONFIG_HID_BELKIN=y
+CONFIG_HID_CHERRY=y
+CONFIG_HID_CHICONY=y
+# CONFIG_HID_PRODIKEYS is not set
+CONFIG_HID_CYPRESS=y
+# CONFIG_HID_DRAGONRISE is not set
+# CONFIG_HID_EMS_FF is not set
+CONFIG_HID_EZKEY=y
+# CONFIG_HID_KEYTOUCH is not set
+CONFIG_HID_KYE=y
+# CONFIG_HID_UCLOGIC is not set
+# CONFIG_HID_WALTOP is not set
+# CONFIG_HID_GYRATION is not set
+# CONFIG_HID_TWINHAN is not set
+CONFIG_HID_KENSINGTON=y
+# CONFIG_HID_LCPOWER is not set
+CONFIG_HID_LOGITECH=y
+# CONFIG_LOGITECH_FF is not set
+# CONFIG_LOGIRUMBLEPAD2_FF is not set
+# CONFIG_LOGIG940_FF is not set
+# CONFIG_LOGIWII_FF is not set
+CONFIG_HID_MICROSOFT=y
+CONFIG_HID_MONTEREY=y
+# CONFIG_HID_MULTITOUCH is not set
+# CONFIG_HID_NTRIG is not set
+# CONFIG_HID_ORTEK is not set
+# CONFIG_HID_PANTHERLORD is not set
+# CONFIG_HID_PETALYNX is not set
+# CONFIG_HID_PICOLCD is not set
+# CONFIG_HID_QUANTA is not set
+# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
+# CONFIG_HID_ROCCAT_KONE is not set
+# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
+# CONFIG_HID_ROCCAT_PYRA is not set
+# CONFIG_HID_SAMSUNG is not set
+# CONFIG_HID_SONY is not set
+# CONFIG_HID_SUNPLUS is not set
+# CONFIG_HID_GREENASIA is not set
+# CONFIG_HID_SMARTJOYPLUS is not set
+# CONFIG_HID_TOPSEED is not set
+# CONFIG_HID_THRUSTMASTER is not set
+# CONFIG_HID_ZEROPLUS is not set
+# CONFIG_HID_ZYDACRON is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_MON is not set
+# CONFIG_USB_WUSB_CBAF is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+# CONFIG_USB_OXU210HP_HCD is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1362_HCD is not set
+CONFIG_USB_OHCI_HCD=y
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+CONFIG_USB_SW_SUN5I_HCD=y
+CONFIG_USB_SW_SUN5I_HCD0=y
+CONFIG_USB_SW_SUN5I_HCI=y
+CONFIG_USB_SW_SUN5I_EHCI0=y
+CONFIG_USB_SW_SUN5I_OHCI0=y
+# CONFIG_USB_MUSB_HDRC is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+# CONFIG_USB_TMC is not set
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
+#
+
+#
+# also be needed; see USB_STORAGE Help for more info
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+CONFIG_USB_STORAGE_REALTEK=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_STORAGE_ENE_UB6250=y
+# CONFIG_USB_UAS is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_SEVSEG is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_LED is not set
+CONFIG_USB_CYPRESS_CY7C63=m
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+# CONFIG_USB_YUREX is not set
+CONFIG_USB_GADGET=y
+# CONFIG_USB_GADGET_DEBUG is not set
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+# CONFIG_USB_GADGET_DEBUG_FS is not set
+CONFIG_USB_GADGET_VBUS_DRAW=2
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_FUSB300 is not set
+# CONFIG_USB_GADGET_R8A66597 is not set
+# CONFIG_USB_GADGET_PXA_U2O is not set
+# CONFIG_USB_GADGET_M66592 is not set
+CONFIG_USB_SW_SUN5I_UDC0=y
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_G_NCM is not set
+# CONFIG_USB_FILE_STORAGE is not set
+# CONFIG_USB_MASS_STORAGE is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_USB_G_ANDROID=y
+# CONFIG_USB_CDC_COMPOSITE is not set
+# CONFIG_USB_G_MULTI is not set
+# CONFIG_USB_G_HID is not set
+# CONFIG_USB_G_DBGP is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_USB_OTG_WAKELOCK is not set
+# CONFIG_USB_ULPI is not set
+# CONFIG_NOP_USB_XCEIV is not set
+CONFIG_USB_SW_SUN5I_USB=y
+CONFIG_USB_SW_SUN5I_USB_MANAGER=y
+# CONFIG_USB_SW_SUN5I_USB0_NULL is not set
+# CONFIG_USB_SW_SUN5I_USB0_DEVICE_ONLY is not set
+# CONFIG_USB_SW_SUN5I_USB0_HOST_ONLY is not set
+CONFIG_USB_SW_SUN5I_USB0_OTG=y
+CONFIG_USB_SW_SUN5I_USB_DEBUG=y
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+CONFIG_MMC_UNSAFE_RESUME=y
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_MINORS=8
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+# CONFIG_MMC_BLOCK_DEFERRED_RESUME is not set
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Card Power Management Drivers
+#
+CONFIG_MMC_SUNXI_POWER_CONTROL=y
+
+#
+# SUNXI MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SUNXI=y
+CONFIG_MMC_SUNXI_DBG=y
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_NFC_DEVICES is not set
+CONFIG_SWITCH=y
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+CONFIG_RTC_INTF_ALARM=y
+CONFIG_RTC_INTF_ALARM_DEV=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_DS3232 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_ISL12022 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+CONFIG_RTC_DRV_SUN5I=y
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_M41T93 is not set
+# CONFIG_RTC_DRV_M41T94 is not set
+# CONFIG_RTC_DRV_DS1305 is not set
+# CONFIG_RTC_DRV_DS1390 is not set
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+# CONFIG_RTC_DRV_DS3234 is not set
+# CONFIG_RTC_DRV_PCF2123 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_DRV_PL030 is not set
+# CONFIG_RTC_DRV_PL031 is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+CONFIG_STAGING=y
+# CONFIG_RISCOM8 is not set
+# CONFIG_SPECIALIX is not set
+# CONFIG_PRISM2_USB is not set
+# CONFIG_ECHO is not set
+# CONFIG_BRCMUTIL is not set
+# CONFIG_ASUS_OLED is not set
+# CONFIG_R8712U is not set
+# CONFIG_TRANZPORT is not set
+
+#
+# Android
+#
+# CONFIG_ANDROID is not set
+# CONFIG_POHMELFS is not set
+# CONFIG_LINE6_USB is not set
+# CONFIG_VT6656 is not set
+# CONFIG_IIO is not set
+CONFIG_XVMALLOC=y
+CONFIG_ZRAM=m
+# CONFIG_ZRAM_DEBUG is not set
+# CONFIG_FB_SM7XX is not set
+# CONFIG_LIRC_STAGING is not set
+CONFIG_MACH_NO_WESTBRIDGE=y
+# CONFIG_ATH6K_LEGACY is not set
+# CONFIG_USB_ENESTORAGE is not set
+# CONFIG_FT1000 is not set
+
+#
+# Speakup console speech
+#
+# CONFIG_SPEAKUP is not set
+# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set
+
+#
+# Altera FPGA firmware download module
+#
+# CONFIG_ALTERA_STAPL is not set
+CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS_XATTR=y
+# CONFIG_EXT3_FS_POSIX_ACL is not set
+# CONFIG_EXT3_FS_SECURITY is not set
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+# CONFIG_EXT4_FS_POSIX_ACL is not set
+# CONFIG_EXT4_FS_SECURITY is not set
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_FS_POSIX_ACL=y
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QUOTA_DEBUG is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+# CONFIG_AUTOFS4_FS is not set
+CONFIG_FUSE_FS=y
+CONFIG_CUSE=y
+CONFIG_GENERIC_ACL=y
+
+#
+# Caches
+#
+CONFIG_FSCACHE=y
+CONFIG_FSCACHE_STATS=y
+# CONFIG_FSCACHE_HISTOGRAM is not set
+# CONFIG_FSCACHE_DEBUG is not set
+# CONFIG_FSCACHE_OBJECT_LIST is not set
+CONFIG_CACHEFILES=y
+# CONFIG_CACHEFILES_DEBUG is not set
+# CONFIG_CACHEFILES_HISTOGRAM is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+CONFIG_NTFS_FS=y
+# CONFIG_NTFS_DEBUG is not set
+CONFIG_NTFS_RW=y
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+CONFIG_TMPFS_XATTR=y
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_FSCACHE is not set
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_CIFS=y
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+CONFIG_OSF_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+CONFIG_BSD_DISKLABEL=y
+CONFIG_MINIX_SUBPARTITION=y
+CONFIG_SOLARIS_X86_PARTITION=y
+CONFIG_UNIXWARE_DISKLABEL=y
+# CONFIG_LDM_PARTITION is not set
+CONFIG_SGI_PARTITION=y
+# CONFIG_ULTRIX_PARTITION is not set
+CONFIG_SUN_PARTITION=y
+CONFIG_KARMA_PARTITION=y
+CONFIG_EFI_PARTITION=y
+# CONFIG_SYSV68_PARTITION is not set
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="utf8"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+CONFIG_NLS_CODEPAGE_936=y
+CONFIG_NLS_CODEPAGE_950=y
+CONFIG_NLS_CODEPAGE_932=y
+CONFIG_NLS_CODEPAGE_949=y
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+
+#
+# Kernel hacking
+#
+CONFIG_PRINTK_TIME=y
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_STRIP_ASM_SYMS=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_LOCKUP_DETECTOR is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEFAULT_HUNG_TASK_TIMEOUT=120
+# CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set
+CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+CONFIG_SCHEDSTATS=y
+CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+CONFIG_STACKTRACE=y
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_HIGHMEM is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO_REDUCED is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
+# CONFIG_TEST_LIST_SORT is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+CONFIG_BOOT_PRINTK_DELAY=y
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+CONFIG_DEBUG_FORCE_WEAK_PER_CPU=y
+# CONFIG_LKDTM is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_DEBUG_PAGEALLOC is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
+CONFIG_HAVE_DYNAMIC_FTRACE=y
+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
+CONFIG_HAVE_C_RECORDMCOUNT=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+CONFIG_DYNAMIC_DEBUG=y
+# CONFIG_DMA_API_DEBUG is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_STRICT_DEVMEM=y
+# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_LL=y
+# CONFIG_EARLY_PRINTK is not set
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_PCOMP2=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_MANAGER_DISABLE_TESTS is not set
+CONFIG_CRYPTO_GF128MUL=y
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+CONFIG_CRYPTO_SEQIV=y
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+CONFIG_CRYPTO_ECB=y
+# CONFIG_CRYPTO_PCBC is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=y
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+CONFIG_CRYPTO_SHA1=y
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+CONFIG_CRYPTO_AES=y
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=y
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+CONFIG_CRYPTO_ZLIB=y
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=y
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+CONFIG_LIBCRC32C=y
+CONFIG_AUDIT_GENERIC=y
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_XZ_DEC=y
+CONFIG_XZ_DEC_X86=y
+CONFIG_XZ_DEC_POWERPC=y
+CONFIG_XZ_DEC_IA64=y
+CONFIG_XZ_DEC_ARM=y
+CONFIG_XZ_DEC_ARMTHUMB=y
+CONFIG_XZ_DEC_SPARC=y
+CONFIG_XZ_DEC_BCJ=y
+# CONFIG_XZ_DEC_TEST is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_XZ=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+CONFIG_AVERAGE=y
--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:52 PM1/24/13
to linux...@googlegroups.com, Hans de Goede
Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
drivers/power/axp_power/axp15-board.c | 3 ++-
drivers/power/axp_power/axp15-regu.c | 37 ++++++++++++++++++---------------
drivers/power/axp_power/axp15-sply.c | 2 +-
drivers/power/axp_power/virtual15.c | 1 +
drivers/power/axp_power/virtual15_dev.c | 3 ++-
5 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/drivers/power/axp_power/axp15-board.c b/drivers/power/axp_power/axp15-board.c
index b97b2aa..203aaf1 100755
--- a/drivers/power/axp_power/axp15-board.c
+++ b/drivers/power/axp_power/axp15-board.c
@@ -1,5 +1,6 @@
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
@@ -10,7 +11,7 @@
#include <linux/mfd/axp-mfd.h>
#include <linux/input.h>
#include <linux/delay.h>
-#include <mach/sys_config.h>
+#include <plat/sys_config.h>
#include "axp-cfg.h"
//#include "axp-sply.h"

diff --git a/drivers/power/axp_power/axp15-regu.c b/drivers/power/axp_power/axp15-regu.c
index d46e4f7..d5464fb 100755
--- a/drivers/power/axp_power/axp15-regu.c
+++ b/drivers/power/axp_power/axp15-regu.c
@@ -41,8 +41,8 @@ static inline int check_range(struct axp_regulator_info *info,


/* AXP common operations */
-static int axp_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV)
+static int axp_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
+ unsigned *selector)
{
struct axp_regulator_info *info = rdev_get_drvdata(rdev);
struct device *axp_dev = to_axp_dev(rdev);
@@ -132,7 +132,8 @@ static int axp_list_voltage(struct regulator_dev *rdev, unsigned selector)
}

static int axp_set_ldo0_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV)
+ int min_uV, int max_uV,
+ unsigned *selector)
{
struct axp_regulator_info *info = rdev_get_drvdata(rdev);
struct device *axp_dev = to_axp_dev(rdev);
@@ -156,7 +157,8 @@ static int axp_set_ldo0_voltage(struct regulator_dev *rdev,
}

static int axp_set_dcdc1_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV)
+ int min_uV, int max_uV,
+ unsigned *selector)
{
struct axp_regulator_info *info = rdev_get_drvdata(rdev);
struct device *axp_dev = to_axp_dev(rdev);
@@ -180,7 +182,8 @@ static int axp_set_dcdc1_voltage(struct regulator_dev *rdev,
}

static int axp_set_aldo12_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV)
+ int min_uV, int max_uV,
+ unsigned *selector)
{
struct axp_regulator_info *info = rdev_get_drvdata(rdev);
struct device *axp_dev = to_axp_dev(rdev);
@@ -286,37 +289,37 @@ printk("%s,%d\n", __func__, __LINE__);

case AXP15_ID_LDO0:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_ldo0_voltage(rdev, uV, uV);
+ return axp_set_ldo0_voltage(rdev, uV, uV, NULL);
case AXP15_ID_LDO2:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_aldo12_voltage(rdev, uV, uV);
+ return axp_set_aldo12_voltage(rdev, uV, uV, NULL);
case AXP15_ID_LDO3:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_aldo12_voltage(rdev, uV, uV);
+ return axp_set_aldo12_voltage(rdev, uV, uV, NULL);
case AXP15_ID_LDO4:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
case AXP15_ID_LDO5:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
case AXP15_ID_DCDC1:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_dcdc1_voltage(rdev, uV, uV);
+ return axp_set_dcdc1_voltage(rdev, uV, uV, NULL);
case AXP15_ID_DCDC2:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
case AXP15_ID_DCDC3:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
case AXP15_ID_DCDC4:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
case AXP15_ID_LDO1:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
case AXP15_ID_LDOIO0:
printk("%s,line:%d\n", __func__, __LINE__);
- return axp_set_voltage(rdev, uV, uV);
+ return axp_set_voltage(rdev, uV, uV, NULL);
default:
return -EINVAL;
}
@@ -650,7 +653,7 @@ static int __devinit axp_regulator_probe(struct platform_device *pdev)
}

rdev = regulator_register(&ri->desc, &pdev->dev,
- pdev->dev.platform_data, ri);
+ pdev->dev.platform_data, ri, NULL);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
diff --git a/drivers/power/axp_power/axp15-sply.c b/drivers/power/axp_power/axp15-sply.c
index adb7198..087d216 100755
--- a/drivers/power/axp_power/axp15-sply.c
+++ b/drivers/power/axp_power/axp15-sply.c
@@ -29,7 +29,7 @@
#include <linux/mfd/axp-mfd.h>
#include <asm/div64.h>

-#include <mach/sys_config.h>
+#include <plat/sys_config.h>

#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
diff --git a/drivers/power/axp_power/virtual15.c b/drivers/power/axp_power/virtual15.c
index 8e9c4e4..a51adc4 100755
--- a/drivers/power/axp_power/virtual15.c
+++ b/drivers/power/axp_power/virtual15.c
@@ -12,6 +12,7 @@
*/

#include <linux/err.h>
+#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
diff --git a/drivers/power/axp_power/virtual15_dev.c b/drivers/power/axp_power/virtual15_dev.c
index 4c63043..7a3c11e 100755
--- a/drivers/power/axp_power/virtual15_dev.c
+++ b/drivers/power/axp_power/virtual15_dev.c
@@ -1,5 +1,6 @@
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/machine.h>
#include <linux/i2c.h>
@@ -122,4 +123,4 @@ module_exit(virtual_exit);

MODULE_DESCRIPTION("Axp regulator test");
MODULE_AUTHOR("Kyle Cheung");
-MODULE_LICENSE("GPL");
\ No newline at end of file
+MODULE_LICENSE("GPL");
--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:50 PM1/24/13
to linux...@googlegroups.com, hehopmajieh, Hans de Goede
From: hehopmajieh <gami...@gmail.com>

HdG: Note as usual with code imported from the sunxi SDK there are severe
style issues :|

Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
drivers/power/axp_power/axp15-board.c | 787 +++++++++++
drivers/power/axp_power/axp15-gpio.c | 348 +++++
drivers/power/axp_power/axp15-mfd.h | 363 +++++
drivers/power/axp_power/axp15-regu.c | 704 ++++++++++
drivers/power/axp_power/axp15-sply.c | 2318 +++++++++++++++++++++++++++++++
drivers/power/axp_power/virtual15.c | 427 ++++++
drivers/power/axp_power/virtual15_dev.c | 125 ++
7 files changed, 5072 insertions(+)
create mode 100755 drivers/power/axp_power/axp15-board.c
create mode 100755 drivers/power/axp_power/axp15-gpio.c
create mode 100755 drivers/power/axp_power/axp15-mfd.h
create mode 100755 drivers/power/axp_power/axp15-regu.c
create mode 100755 drivers/power/axp_power/axp15-sply.c
create mode 100755 drivers/power/axp_power/virtual15.c
create mode 100755 drivers/power/axp_power/virtual15_dev.c

diff --git a/drivers/power/axp_power/axp15-board.c b/drivers/power/axp_power/axp15-board.c
new file mode 100755
index 0000000..b97b2aa
--- /dev/null
+++ b/drivers/power/axp_power/axp15-board.c
@@ -0,0 +1,787 @@
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <mach/irqs.h>
+#include <linux/power_supply.h>
+#include <linux/apm_bios.h>
+#include <linux/apm-emulation.h>
+#include <linux/mfd/axp-mfd.h>
+#include <linux/input.h>
+#include <linux/delay.h>
+#include <mach/sys_config.h>
+#include "axp-cfg.h"
+//#include "axp-sply.h"
+
+
+
+//int axp_usbcurflag = 0;
+//int axp_usbvolflag= 0;
+
+int pmu_used;
+int pmu_twi_id;
+int pmu_irq_id;
+int pmu_twi_addr;
+int pmu_battery_rdc;
+int pmu_battery_cap;
+int pmu_init_chgcur;
+int pmu_suspend_chgcur;
+int pmu_resume_chgcur;
+int pmu_shutdown_chgcur;
+int pmu_init_chgvol;
+int pmu_init_chgend_rate;
+int pmu_init_chg_enabled;
+int pmu_init_adc_freq;
+int pmu_init_adc_freqc;
+int pmu_init_chg_pretime;
+int pmu_init_chg_csttime;
+
+int pmu_bat_para1;
+int pmu_bat_para2;
+int pmu_bat_para3;
+int pmu_bat_para4;
+int pmu_bat_para5;
+int pmu_bat_para6;
+int pmu_bat_para7;
+int pmu_bat_para8;
+int pmu_bat_para9;
+int pmu_bat_para10;
+int pmu_bat_para11;
+int pmu_bat_para12;
+int pmu_bat_para13;
+int pmu_bat_para14;
+int pmu_bat_para15;
+int pmu_bat_para16;
+
+int pmu_usbvol_limit;
+int pmu_usbvol;
+int pmu_usbcur_limit;
+int pmu_usbcur;
+
+int pmu_pwroff_vol;
+int pmu_pwron_vol;
+
+int dcdc2_vol;
+int dcdc3_vol;
+int ldo2_vol;
+int ldo3_vol;
+int ldo4_vol;
+
+int pmu_pekoff_time;
+int pmu_pekoff_en;
+int pmu_peklong_time;
+int pmu_pekon_time;
+int pmu_pwrok_time;
+int pmu_pwrnoe_time;
+int pmu_intotp_en;
+
+/*
+int axp_usbvol(void)
+{
+ axp_usbvolflag = 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbvol);
+
+int axp_usbcur(void)
+{
+ axp_usbcurflag = 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbcur);
+
+int axp_usbvol_restore(void)
+{
+ axp_usbvolflag = 0;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbvol_restore);
+
+int axp_usbcur_restore(void)
+{
+ axp_usbcurflag = 0;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbcur_restore);
+*/
+
+/* Reverse engineered partly from Platformx drivers */
+enum axp_regls{
+
+ vcc_ldo1,
+ vcc_ldo2,
+ vcc_ldo3,
+ vcc_ldo4,
+ vcc_ldo5,
+ vcc_ldo6,
+ vcc_ldo7,
+
+ vcc_dcdc1,
+ vcc_dcdc2,
+ vcc_dcdc3,
+ vcc_dcdc4,
+};
+
+/* The values of the various regulator constraints are obviously dependent
+ * on exactly what is wired to each ldo. Unfortunately this information is
+ * not generally available. More information has been requested from Xbow
+ * but as of yet they haven't been forthcoming.
+ *
+ * Some of these are clearly Stargate 2 related (no way of plugging
+ * in an lcd on the IM2 for example!).
+ */
+
+static struct regulator_consumer_supply ldo1_data[] = {
+ {
+ .supply = "axp15_rtc",
+ },
+ };
+
+
+
+static struct regulator_consumer_supply ldo2_data[] = {
+ {
+ .supply = "axp15_analog/fm",
+ },
+ };
+
+static struct regulator_consumer_supply ldo3_data[] = {
+ {
+ .supply = "axp15_analog/fm1",
+ },
+ };
+
+static struct regulator_consumer_supply ldo4_data[] = {
+ {
+ .supply = "axp15_analog/fm2",
+ },
+ };
+
+static struct regulator_consumer_supply ldo5_data[] = {
+ {
+ .supply = "axp15_pll/sdram",
+ },
+ };
+
+static struct regulator_consumer_supply ldo6_data[] = {
+ {
+ .supply = "axp15_pll/hdmi",
+ },
+ };
+
+static struct regulator_consumer_supply ldo7_data[] = {
+ {
+ .supply = "axp15_mic",
+ },
+ };
+
+static struct regulator_consumer_supply buck1_data[] = {
+ {
+ .supply = "axp15_io",
+ }
+ };
+
+static struct regulator_consumer_supply buck2_data[] = {
+ {
+ .supply = "axp15_core",
+ },
+ };
+
+static struct regulator_consumer_supply buck3_data[] = {
+ {
+ .supply = "axp15_ddr",
+ },
+ };
+
+static struct regulator_consumer_supply buck4_data[] = {
+ {
+ .supply = "axp15_ddr2",
+ },
+ };
+
+static struct regulator_init_data axp_regl_init_data[] = {
+ [vcc_ldo1] = {
+ .constraints = { /* board default 1.25V */
+ .name = "axp15_ldo1",
+ .min_uV = 2500000,
+ .max_uV = 5000000,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo1_data),
+ .consumer_supplies = ldo1_data,
+ },
+ [vcc_ldo2] = {
+ .constraints = { /* board default 3.0V */
+ .name = "axp15_ldo2",
+ .min_uV = 1300000,
+ .max_uV = 1800000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo2_data),
+ .consumer_supplies = ldo2_data,
+
+ },
+ [vcc_ldo3] = {
+ .constraints = {/* default is 1.8V */
+ .name = "axp15_ldo3",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo3_data),
+ .consumer_supplies = ldo3_data,
+
+ },
+ [vcc_ldo4] = {
+ .constraints = {
+ /* board default is 3.3V */
+ .name = "axp15_ldo4",
+ .min_uV = 1200000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo4_data),
+ .consumer_supplies = ldo4_data,
+ },
+ [vcc_ldo5] = {
+ .constraints = { /* default 3.3V */
+ .name = "axp15_ldo5",
+ .min_uV = 700000,
+ .max_uV = 3500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo5_data),
+ .consumer_supplies = ldo5_data,
+ },
+ [vcc_ldo6] = {
+ .constraints = { /* default 3.3V */
+ .name = "axp15_ldo6",
+ .min_uV = 700000,
+ .max_uV = 3500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo6_data),
+ .consumer_supplies = ldo6_data,
+ },
+ [vcc_ldo7] = {
+ .constraints = { /* default 3.3V */
+ .name = "axp15_ldoIO0",
+ .min_uV = 1800000,
+ .max_uV = 3300000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(ldo7_data),
+ .consumer_supplies = ldo7_data,
+ },
+ [vcc_dcdc1] = {
+ .constraints = { /* default 3.3V */
+ .name = "axp15_dcdc1",
+ .min_uV = 1700000,
+ .max_uV = 3500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE ,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck1_data),
+ .consumer_supplies = buck1_data,
+ },
+ [vcc_dcdc2] = {
+ .constraints = { /* default 1.24V */
+ .name = "axp15_dcdc2",
+ //.min_uV = DCDC2MIN * 1000,
+ //.max_uV = DCDC2MAX * 1000,
+ .min_uV = 700000,
+ .max_uV = 2275000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck2_data),
+ .consumer_supplies = buck2_data,
+ },
+ [vcc_dcdc3] = {
+ .constraints = { /* default 2.5V */
+ .name = "axp15_dcdc3",
+ .min_uV = 700000,
+ .max_uV = 3500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck3_data),
+ .consumer_supplies = buck3_data,
+ },
+ [vcc_dcdc4] = {
+ .constraints = { /* default 2.5V */
+ .name = "axp15_dcdc4",
+ .min_uV = 700000,
+ .max_uV = 3500000,
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(buck4_data),
+ .consumer_supplies = buck4_data,
+ },
+};
+
+static struct axp_funcdev_info axp_regldevs[] = {
+ {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDO0,
+ .platform_data = &axp_regl_init_data[vcc_ldo1],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDO1,
+ .platform_data = &axp_regl_init_data[vcc_ldo2],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDO2,
+ .platform_data = &axp_regl_init_data[vcc_ldo3],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDO3,
+ .platform_data = &axp_regl_init_data[vcc_ldo4],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDO4,
+ .platform_data = &axp_regl_init_data[vcc_ldo5],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDO5,
+ .platform_data = &axp_regl_init_data[vcc_ldo6],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_LDOIO0,
+ .platform_data = &axp_regl_init_data[vcc_ldo7],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_DCDC1,
+ .platform_data = &axp_regl_init_data[vcc_dcdc1],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_DCDC2,
+ .platform_data = &axp_regl_init_data[vcc_dcdc2],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_DCDC3,
+ .platform_data = &axp_regl_init_data[vcc_dcdc3],
+ }, {
+ .name = "axp15-regulator",
+ .id = AXP15_ID_DCDC4,
+ .platform_data = &axp_regl_init_data[vcc_dcdc4],
+ },
+};
+static struct power_supply_info battery_data ={
+ .name ="PTI PL336078",
+ .technology = POWER_SUPPLY_TECHNOLOGY_LiFe,
+ //.voltage_max_design = pmu_init_chgvol,
+ //.voltage_min_design = pmu_pwroff_vol,
+ //.energy_full_design = pmu_battery_cap,
+ .use_for_apm = 1,
+};
+
+
+static struct axp_supply_init_data axp_sply_init_data = {
+ .battery_info = &battery_data,
+ //.chgcur = pmu_init_chgcur,
+ //.chgvol = pmu_init_chgvol,
+ //.chgend = pmu_init_chgend_rate,
+ //.chgen = pmu_init_chg_enabled,
+ //.sample_time = pmu_init_adc_freq,
+ //.chgpretime = pmu_init_chg_pretime,
+ //.chgcsttime = pmu_init_chg_csttime,
+};
+
+static struct axp_funcdev_info axp_splydev[]={
+ {
+ .name = "axp15-supplyer",
+ .id = AXP15_ID_SUPPLY,
+ .platform_data = &axp_sply_init_data,
+ },
+};
+
+static struct axp_funcdev_info axp_gpiodev[]={
+ { .name = "axp15-gpio",
+ .id = AXP15_ID_GPIO,
+ },
+};
+
+
+static struct axp_platform_data axp_pdata = {
+ .num_regl_devs = ARRAY_SIZE(axp_regldevs),
+ .num_sply_devs = ARRAY_SIZE(axp_splydev),
+ .num_gpio_devs = ARRAY_SIZE(axp_gpiodev),
+ .regl_devs = axp_regldevs,
+ .sply_devs = axp_splydev,
+ .gpio_devs = axp_gpiodev,
+ .gpio_base = 0,
+};
+
+static struct i2c_board_info __initdata axp_mfd_i2c_board_info[] = {
+ {
+ .type = "axp15_mfd",
+ .addr = AXP15_ADDR,
+ .platform_data = &axp_pdata,
+ .irq = SW_INT_IRQNO_ENMI,
+ },
+};
+
+static int __init axp_board_init(void)
+{
+ int ret;
+ ret = script_parser_fetch("pmu_para", "pmu_used", &pmu_used, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ return ;
+ }
+ if (pmu_used)
+ {
+ ret = script_parser_fetch("pmu_para", "pmu_twi_id", &pmu_twi_id, sizeof(int));
+ printk("line:%d,pmu_twi_id=%d\n",__LINE__,pmu_twi_id);
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_twi_id = AXP15_I2CBUS;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_irq_id", &pmu_irq_id, sizeof(int));
+ printk("line:%d,pmu_irq_id=%d\n",__LINE__,pmu_irq_id);
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_irq_id = AXP15_IRQNO;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_twi_addr", &pmu_twi_addr, sizeof(int));
+ printk("line:%d,pmu_twi_addr=%d\n",__LINE__,pmu_twi_addr);
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_twi_addr = AXP15_ADDR;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_battery_rdc", &pmu_battery_rdc, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ //int BATRDC = 0;
+ pmu_battery_rdc = BATRDC;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_battery_cap", &pmu_battery_cap, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_battery_cap = BATTERYCAP;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_init_chgcur", &pmu_init_chgcur, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chgcur = INTCHGCUR / 1000;
+ }
+ pmu_init_chgcur = pmu_init_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_suspend_chgcur", &pmu_suspend_chgcur, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_suspend_chgcur = SUSCHGCUR / 1000;
+ }
+ pmu_suspend_chgcur = pmu_suspend_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_resume_chgcur", &pmu_resume_chgcur, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_resume_chgcur = RESCHGCUR / 1000;
+ }
+ pmu_resume_chgcur = pmu_resume_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_shutdown_chgcur", &pmu_shutdown_chgcur, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_shutdown_chgcur = CLSCHGCUR / 1000;
+ }
+ pmu_shutdown_chgcur = pmu_shutdown_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_init_chgvol", &pmu_init_chgvol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chgvol = INTCHGVOL / 1000;
+ }
+ pmu_init_chgvol = pmu_init_chgvol * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_init_chgend_rate", &pmu_init_chgend_rate, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chgend_rate = INTCHGENDRATE;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_init_chg_enabled", &pmu_init_chg_enabled, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chg_enabled = INTCHGENABLED;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_init_adc_freq", &pmu_init_adc_freq, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_adc_freq = INTADCFREQ;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_init_adc_freqc", &pmu_init_adc_freqc, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_adc_freq = INTADCFREQC;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_init_chg_pretime", &pmu_init_chg_pretime, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chg_pretime = INTCHGPRETIME;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_init_chg_csttime", &pmu_init_chg_csttime, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chg_csttime = INTCHGCSTTIME;
+ }
+
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para1", &pmu_bat_para1, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para1 = OCVREG0;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para2", &pmu_bat_para2, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para2 = OCVREG1;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para3", &pmu_bat_para3, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para3 = OCVREG2;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para4", &pmu_bat_para4, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para4 = OCVREG3;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para5", &pmu_bat_para5, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para5 = OCVREG4;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para6", &pmu_bat_para6, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para6 = OCVREG5;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para7", &pmu_bat_para7, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para7 = OCVREG6;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para8", &pmu_bat_para8, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para8 = OCVREG7;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para9", &pmu_bat_para9, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para9 = OCVREG8;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para10", &pmu_bat_para10, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para10 = OCVREG9;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para11", &pmu_bat_para11, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para11 = OCVREGA;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para12", &pmu_bat_para12, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para12 = OCVREGB;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para13", &pmu_bat_para13, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para13 = OCVREGC;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para14", &pmu_bat_para14, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para14 = OCVREGD;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para15", &pmu_bat_para15, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para15 = OCVREGE;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_bat_para16", &pmu_bat_para16, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_bat_para16 = OCVREGF;
+ }
+
+ ret = script_parser_fetch("pmu_para", "pmu_usbvol_limit", &pmu_usbvol_limit, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_usbvol_limit = 1;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_usbvol", &pmu_usbvol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_usbvol = 4400;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_usbcur_limit", &pmu_usbcur_limit, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_usbcur_limit = 1;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_usbcur", &pmu_usbcur, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_usbcur = 0;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_pwroff_vol", &pmu_pwroff_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pwroff_vol = 3300;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_pwron_vol", &pmu_pwron_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pwron_vol = 2900;
+ }
+
+ ret = script_parser_fetch("target", "dcdc2_vol", &dcdc2_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ dcdc2_vol = 1400;
+ }
+ ret = script_parser_fetch("target", "dcdc3_vol", &dcdc3_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ dcdc3_vol = 1250;
+ }
+ ret = script_parser_fetch("target", "ldo2_vol", &ldo2_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ ldo2_vol = 3000;
+ }
+ ret = script_parser_fetch("target", "ldo3_vol", &ldo3_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ ldo3_vol = 2800;
+ }
+ ret = script_parser_fetch("target", "ldo4_vol", &ldo4_vol, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ ldo4_vol = 2800;
+ }
+
+ ret = script_parser_fetch("pmu_para", "pmu_pekoff_time", &pmu_pekoff_time, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pekoff_time = 6000;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_pekoff_en", &pmu_pekoff_en, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pekoff_en = 1;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_peklong_time", &pmu_peklong_time, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_peklong_time = 1500;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_pwrok_time", &pmu_pwrok_time, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pwrok_time = 64;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_pwrnoe_time", &pmu_pwrnoe_time, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pwrnoe_time = 2000;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_intotp_en", &pmu_intotp_en, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_intotp_en = 1;
+ }
+ ret = script_parser_fetch("pmu_para", "pmu_pekon_time", &pmu_pekon_time, sizeof(int));
+ if (ret)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_pekon_time = 1000;
+ }
+
+ axp_regl_init_data[1].constraints.state_standby.uV = ldo2_vol * 1000;
+ axp_regl_init_data[2].constraints.state_standby.uV = ldo3_vol * 1000;
+ axp_regl_init_data[3].constraints.state_standby.uV = ldo4_vol * 1000;
+ axp_regl_init_data[5].constraints.state_standby.uV = dcdc2_vol * 1000;
+ axp_regl_init_data[6].constraints.state_standby.uV = dcdc3_vol * 1000;
+ axp_regl_init_data[1].constraints.state_standby.enabled = (ldo2_vol)?1:0;
+ axp_regl_init_data[1].constraints.state_standby.disabled = (ldo2_vol)?0:1;
+ axp_regl_init_data[2].constraints.state_standby.enabled = (ldo3_vol)?1:0;
+ axp_regl_init_data[2].constraints.state_standby.disabled = (ldo3_vol)?0:1;
+ axp_regl_init_data[3].constraints.state_standby.enabled = (ldo4_vol)?1:0;
+ axp_regl_init_data[3].constraints.state_standby.disabled = (ldo4_vol)?0:1;
+ axp_regl_init_data[5].constraints.state_standby.enabled = (dcdc2_vol)?1:0;
+ axp_regl_init_data[5].constraints.state_standby.disabled = (dcdc2_vol)?0:1;
+ axp_regl_init_data[6].constraints.state_standby.enabled = (dcdc3_vol)?1:0;
+ axp_regl_init_data[6].constraints.state_standby.disabled = (dcdc3_vol)?0:1;
+ battery_data.voltage_max_design = pmu_init_chgvol;
+ battery_data.voltage_min_design = pmu_pwroff_vol;
+ battery_data.energy_full_design = pmu_battery_cap;
+ axp_sply_init_data.chgcur = pmu_init_chgcur;
+ axp_sply_init_data.chgvol = pmu_init_chgvol;
+ axp_sply_init_data.chgend = pmu_init_chgend_rate;
+ axp_sply_init_data.chgen = pmu_init_chg_enabled;
+ axp_sply_init_data.sample_time = pmu_init_adc_freq;
+ axp_sply_init_data.chgpretime = pmu_init_chg_pretime;
+ axp_sply_init_data.chgcsttime = pmu_init_chg_csttime;
+ axp_mfd_i2c_board_info[0].addr = pmu_twi_addr;
+ axp_mfd_i2c_board_info[0].irq = pmu_irq_id;
+
+ return i2c_register_board_info(pmu_twi_id, axp_mfd_i2c_board_info,
+ ARRAY_SIZE(axp_mfd_i2c_board_info));
+ }
+ else
+ return -1;
+
+}
+fs_initcall(axp_board_init);
+
+MODULE_DESCRIPTION("Axp board");
+MODULE_AUTHOR("Kyle Cheung");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/power/axp_power/axp15-gpio.c b/drivers/power/axp_power/axp15-gpio.c
new file mode 100755
index 0000000..2faf11c
--- /dev/null
+++ b/drivers/power/axp_power/axp15-gpio.c
@@ -0,0 +1,348 @@
+/*
+ * axp15-gpio.c -- gpiolib support for X-Power &axp PMICs
+ *
+ * Copyright 2012 X-Powers Microelectronics PLC.
+ *
+ * Author: Kyle Cheung <>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/mfd/core.h>
+#include <linux/platform_device.h>
+#include <linux/seq_file.h>
+#include <linux/i2c.h>
+#include <linux/mfd/axp-mfd.h>
+
+#include "axp-gpio.h"
+
+struct virtual_gpio_data {
+ struct mutex lock;
+ int gpio; //gpio number : 0/1/2/...
+ int io; //0: input 1: output
+ int value; //0: low 1: high
+};
+
+int axp_gpio_set_io(int gpio, int io_state)
+{
+ if(io_state == 1){
+ switch(gpio)
+ {
+ case 0: return axp_clr_bits(&axp->dev,AXP15_GPIO0_CFG, 0x06);
+ case 1: return axp_clr_bits(&axp->dev,AXP15_GPIO1_CFG, 0x06);
+ case 2: return axp_clr_bits(&axp->dev,AXP15_GPIO2_CFG, 0x06);
+ case 3: return axp_clr_bits(&axp->dev,AXP15_GPIO3_CFG, 0x04);
+ default:return -ENXIO;
+ }
+ }
+ else if(io_state == 0){
+ switch(gpio)
+ {
+ case 0: axp_clr_bits(&axp->dev,AXP15_GPIO0_CFG,0x05);
+ return axp_set_bits(&axp->dev,AXP15_GPIO0_CFG,0x02);
+ case 1: axp_clr_bits(&axp->dev,AXP15_GPIO1_CFG,0x05);
+ return axp_set_bits(&axp->dev,AXP15_GPIO1_CFG,0x02);
+ case 2: axp_clr_bits(&axp->dev,AXP15_GPIO2_CFG,0x05);
+ return axp_set_bits(&axp->dev,AXP15_GPIO2_CFG,0x02);
+ case 3: return axp_set_bits(&axp->dev,AXP15_GPIO3_CFG,0x04);
+ default:return -ENXIO;
+ }
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL_GPL(axp_gpio_set_io);
+
+
+int axp_gpio_get_io(int gpio, int *io_state)
+{
+ uint8_t val;
+ switch(gpio)
+ {
+ case 0: axp_read(&axp->dev,AXP15_GPIO0_CFG,&val);val &= 0x07;
+ if(val < 0x02)
+ *io_state = 1;
+ else if (val == 0x02)
+ *io_state = 0;
+ else
+ return -EIO;
+ break;
+ case 1: axp_read(&axp->dev,AXP15_GPIO1_CFG,&val);val &= 0x07;
+ if(val < 0x02)
+ *io_state = 1;
+ else if (val == 0x02)
+ *io_state = 0;
+ else
+ return -EIO;
+ break;
+ case 2: axp_read(&axp->dev,AXP15_GPIO2_CFG,&val);val &= 0x07;
+ if(val < 0x02)
+ *io_state = 1;
+ else if (val == 0x02)
+ *io_state = 0;
+ else
+ return -EIO;
+ break;
+ case 3: axp_read(&axp->dev,AXP15_GPIO3_CFG,&val);val &= 0x04;
+ if(val == 0x0)
+ *io_state = 1;
+ else
+ *io_state = 0;
+ break;
+ default:return -ENXIO;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_gpio_get_io);
+
+
+int axp_gpio_set_value(int gpio, int value)
+{
+ int io_state,ret;
+ ret = axp_gpio_get_io(gpio,&io_state);
+ if(ret)
+ return ret;
+ if(io_state){
+ if(value){
+ switch(gpio)
+ {
+ case 0: axp_clr_bits(&axp->dev,AXP15_GPIO0_CFG,0x06);
+ return axp_set_bits(&axp->dev,AXP15_GPIO0_CFG,0x01);
+ case 1: axp_clr_bits(&axp->dev,AXP15_GPIO1_CFG,0x06);
+ return axp_set_bits(&axp->dev,AXP15_GPIO1_CFG,0x01);
+ case 2: return axp_set_bits(&axp->dev,AXP15_GPIO2_CFG,0x01);
+ case 3: return axp_set_bits(&axp->dev,AXP15_GPIO3_CFG,0x02);
+ default:break;
+ }
+ }
+ else{
+ switch(gpio)
+ {
+ case 0: return axp_clr_bits(&axp->dev,AXP15_GPIO0_CFG,0x03);
+ case 1: return axp_clr_bits(&axp->dev,AXP15_GPIO1_CFG,0x03);
+ case 2: return axp_clr_bits(&axp->dev,AXP15_GPIO2_CFG,0x03);
+ case 3: return axp_clr_bits(&axp->dev,AXP15_GPIO3_CFG,0x02);
+ default:break;
+ }
+ }
+ return -ENXIO;
+ }
+ return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(axp_gpio_set_value);
+
+
+int axp_gpio_get_value(int gpio, int *value)
+{
+ int io_state;
+ int ret;
+ uint8_t val;
+ ret = axp_gpio_get_io(gpio,&io_state);
+ if(ret)
+ return ret;
+ if(io_state){
+ switch(gpio)
+ {
+ case 0:ret = axp_read(&axp->dev,AXP15_GPIO0_CFG,&val);*value = val & 0x01;break;
+ case 1:ret =axp_read(&axp->dev,AXP15_GPIO1_CFG,&val);*value = val & 0x01;break;
+ case 2:ret = axp_read(&axp->dev,AXP15_GPIO2_CFG,&val);*value = val & 0x01;break;
+ case 3:ret = axp_read(&axp->dev,AXP15_GPIO3_CFG,&val);val &= 0x02;*value = val>>1;break;
+ default:return -ENXIO;
+ }
+ }
+ else{
+ switch(gpio)
+ {
+ case 0:ret = axp_read(&axp->dev,AXP15_GPIO0123_STATE,&val);val &= 0x01;break;
+ case 1:ret = axp_read(&axp->dev,AXP15_GPIO0123_STATE,&val);val &= 0x02;*value = val>>1;break;
+ case 2:ret = axp_read(&axp->dev,AXP15_GPIO0123_STATE,&val);val &= 0x04;*value = val>>2;break;
+ case 3:ret = axp_read(&axp->dev,AXP15_GPIO0123_STATE,&val);val &= 0x08;*value = val>>3;break;
+ default:return -ENXIO;
+ }
+ }
+ return ret;
+}
+EXPORT_SYMBOL_GPL(axp_gpio_get_value);
+
+static ssize_t show_gpio(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_gpio_data *data = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", data->gpio);
+}
+
+static ssize_t set_gpio(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_gpio_data *data = dev_get_drvdata(dev);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+
+ data->gpio = val;
+
+ return count;
+}
+
+static ssize_t show_io(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_gpio_data *data = dev_get_drvdata(dev);
+ int ret;
+ mutex_lock(&data->lock);
+
+ ret = axp_gpio_get_io(data->gpio,&data->io);
+
+ mutex_unlock(&data->lock);
+
+ if(ret)
+ return ret;
+
+ return sprintf(buf, "%d\n", data->io);
+}
+
+static ssize_t set_io(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_gpio_data *data = dev_get_drvdata(dev);
+ long val;
+ int ret;
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+
+ mutex_lock(&data->lock);
+
+ data->io = val;
+ ret = axp_gpio_set_io(data->gpio,data->io);
+
+ mutex_unlock(&data->lock);
+ if(ret)
+ return ret;
+ return count;
+}
+
+
+static ssize_t show_value(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_gpio_data *data = dev_get_drvdata(dev);
+ int ret;
+
+ mutex_lock(&data->lock);
+
+ ret = axp_gpio_get_value(data->gpio,&data->value);
+
+ mutex_unlock(&data->lock);
+
+ if(ret)
+ return ret;
+
+ return sprintf(buf, "%d\n", data->value);
+}
+
+static ssize_t set_value(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_gpio_data *data = dev_get_drvdata(dev);
+ long val;
+ int ret;
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+
+ mutex_lock(&data->lock);
+
+ data->value = val;
+ ret = axp_gpio_set_value(data->gpio,data->value);
+
+ mutex_unlock(&data->lock);
+
+ if(ret){
+ return ret;
+ }
+
+ return count;
+}
+
+
+static DEVICE_ATTR(gpio,0664, show_gpio, set_gpio);
+static DEVICE_ATTR(io, 0664, show_io, set_io);
+static DEVICE_ATTR(value, 0664, show_value, set_value);
+
+struct device_attribute *attributes[] = {
+ &dev_attr_gpio,
+ &dev_attr_io,
+ &dev_attr_value,
+};
+
+
+static int __devinit axp_gpio_probe(struct platform_device *pdev)
+{
+ //struct axp_mfd_chip *axp_chip = dev_get_drvdata(pdev->dev.parent);
+ struct virtual_gpio_data *drvdata;
+ int ret, i;
+
+ drvdata = kzalloc(sizeof(struct virtual_gpio_data), GFP_KERNEL);
+ if (drvdata == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ mutex_init(&drvdata->lock);
+
+ for (i = 0; i < ARRAY_SIZE(attributes); i++) {
+ ret = device_create_file(&pdev->dev, attributes[i]);
+ if (ret != 0)
+ goto err;
+ }
+
+ platform_set_drvdata(pdev, drvdata);
+
+ return 0;
+
+err:
+ for (i = 0; i < ARRAY_SIZE(attributes); i++)
+ device_remove_file(&pdev->dev, attributes[i]);
+ kfree(drvdata);
+ return ret;
+
+return 0;
+}
+
+static int __devexit axp_gpio_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static struct platform_driver axp_gpio_driver = {
+ .driver.name = "axp20-gpio",
+ .driver.owner = THIS_MODULE,
+ .probe = axp_gpio_probe,
+ .remove = __devexit_p(axp_gpio_remove),
+};
+
+static int __init axp_gpio_init(void)
+{
+ return platform_driver_register(&axp_gpio_driver);
+}
+subsys_initcall(axp_gpio_init);
+
+static void __exit axp_gpio_exit(void)
+{
+ platform_driver_unregister(&axp_gpio_driver);
+}
+module_exit(axp_gpio_exit);
+
+MODULE_AUTHOR("Kyle Cheung ");
+MODULE_DESCRIPTION("GPIO interface for AXP PMICs");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:axp-gpio");
diff --git a/drivers/power/axp_power/axp15-mfd.h b/drivers/power/axp_power/axp15-mfd.h
new file mode 100755
index 0000000..6d6463d
--- /dev/null
+++ b/drivers/power/axp_power/axp15-mfd.h
@@ -0,0 +1,363 @@
+#include "axp-rw.h"
+
+
+static int __devinit axp15_init_chip(struct axp_mfd_chip *chip)
+{
+ uint8_t chip_id;
+ uint8_t v[11] = {0x00,POWER15_INTEN2, 0x03,POWER15_INTEN3,0x00,
+ POWER15_INTSTS1,0xff,POWER15_INTSTS2, 0xff,
+ POWER15_INTSTS3,0xff,};
+ int err;
+ /*read chip id*/
+ err = __axp_read(chip->client, POWER15_IC_TYPE, &chip_id);
+ if (err) {
+ printk("[AXP15-MFD] try to read chip id failed!\n");
+ return err;
+ }
+
+ /*enable irqs and clear*/
+ err = __axp_writes(chip->client, POWER15_INTEN1, 11, v);
+ if (err) {
+ printk("[AXP15-MFD] try to clear irq failed!\n");
+ return err;
+ }
+
+ dev_info(chip->dev, "AXP (CHIP ID: 0x%02x) detected\n", chip_id);
+ chip->type = AXP15;
+
+ /* mask and clear all IRQs */
+ chip->irqs_enabled = 0xffffff;
+ chip->ops->disable_irqs(chip, chip->irqs_enabled);
+
+ return 0;
+}
+
+static int axp15_disable_irqs(struct axp_mfd_chip *chip, uint64_t irqs)
+{
+ uint8_t v[5];
+ int ret;
+
+ chip->irqs_enabled &= ~irqs;
+
+ v[0] = ((chip->irqs_enabled) & 0xff);
+ v[1] = POWER15_INTEN2;
+ v[2] = ((chip->irqs_enabled) >> 8) & 0xff;
+ v[3] = POWER15_INTEN3;
+ v[4] = ((chip->irqs_enabled) >> 16) & 0xff;
+ ret = __axp_writes(chip->client, POWER15_INTEN1, 5, v);
+
+ return ret;
+
+}
+
+static int axp15_enable_irqs(struct axp_mfd_chip *chip, uint64_t irqs)
+{
+ uint8_t v[5];
+ int ret;
+
+ chip->irqs_enabled |= irqs;
+
+ v[0] = ((chip->irqs_enabled) & 0xff);
+ v[1] = POWER15_INTEN2;
+ v[2] = ((chip->irqs_enabled) >> 8) & 0xff;
+ v[3] = POWER15_INTEN3;
+ v[4] = ((chip->irqs_enabled) >> 16) & 0xff;
+ ret = __axp_writes(chip->client, POWER15_INTEN1, 5, v);
+
+ return ret;
+}
+
+static int axp15_read_irqs(struct axp_mfd_chip *chip, uint64_t *irqs)
+{
+ uint8_t v[3] = {0, 0, 0};
+ int ret;
+ ret = __axp_reads(chip->client, POWER15_INTSTS1, 3, v);
+ if (ret < 0)
+ return ret;
+
+ *irqs =((((uint64_t) v[2])<< 16) | (((uint64_t)v[1]) << 8) | ((uint64_t) v[0]));
+ return 0;
+}
+
+
+static ssize_t axp15_offvol_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val = 0;
+ axp_read(dev,POWER15_VOFF_SET,&val);
+ return sprintf(buf,"%d\n",(val & 0x07) * 100 + 2600);
+}
+
+static ssize_t axp15_offvol_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if (tmp < 2600)
+ tmp = 2600;
+ if (tmp > 3300)
+ tmp = 3300;
+
+ axp_read(dev,POWER15_VOFF_SET,&val);
+ val &= 0xf8;
+ val |= ((tmp - 2600) / 100);
+ axp_write(dev,POWER15_VOFF_SET,val);
+ return count;
+}
+
+static ssize_t axp15_noedelay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ axp_read(dev,POWER15_OFF_CTL,&val);
+ if( (val & 0x03) == 0)
+ return sprintf(buf,"%d\n",128);
+ else
+ return sprintf(buf,"%d\n",(val & 0x03) * 1000);
+}
+
+static ssize_t axp15_noedelay_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if (tmp < 1000)
+ tmp = 128;
+ if (tmp > 3000)
+ tmp = 3000;
+ axp_read(dev,POWER15_OFF_CTL,&val);
+ val &= 0xfc;
+ val |= ((tmp) / 1000);
+ axp_write(dev,POWER15_OFF_CTL,val);
+ return count;
+}
+
+static ssize_t axp15_pekopen_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ int tmp = 0;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ switch(val >> 6){
+ case 0: tmp = 128;break;
+ case 1: tmp = 3000;break;
+ case 2: tmp = 1000;break;
+ case 3: tmp = 2000;break;
+ default:
+ tmp = 0;break;
+ }
+ return sprintf(buf,"%d\n",tmp);
+}
+
+static ssize_t axp15_pekopen_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ axp_read(dev,POWER15_PEK_SET,&val);
+ if (tmp < 1000)
+ val &= 0x3f;
+ else if(tmp < 2000){
+ val &= 0x3f;
+ val |= 0x80;
+ }
+ else if(tmp < 3000){
+ val &= 0x3f;
+ val |= 0xc0;
+ }
+ else {
+ val &= 0x3f;
+ val |= 0x40;
+ }
+ axp_write(dev,POWER15_PEK_SET,val);
+ return count;
+}
+
+static ssize_t axp15_peklong_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val = 0;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ return sprintf(buf,"%d\n",((val >> 4) & 0x03) * 500 + 1000);
+}
+
+static ssize_t axp15_peklong_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if(tmp < 1000)
+ tmp = 1000;
+ if(tmp > 2500)
+ tmp = 2500;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ val &= 0xcf;
+ val |= (((tmp - 1000) / 500) << 4);
+ axp_write(dev,POWER15_PEK_SET,val);
+ return count;
+}
+
+static ssize_t axp15_peken_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ return sprintf(buf,"%d\n",((val >> 3) & 0x01));
+}
+
+static ssize_t axp15_peken_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if(tmp)
+ tmp = 1;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ val &= 0xf7;
+ val |= (tmp << 3);
+ axp_write(dev,POWER15_PEK_SET,val);
+ return count;
+}
+
+static ssize_t axp15_pekdelay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ axp_read(dev,POWER15_PEK_SET,&val);
+
+ return sprintf(buf,"%d\n",((val >> 2) & 0x01)? 64:8);
+}
+
+static ssize_t axp15_pekdelay_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if(tmp <= 8)
+ tmp = 0;
+ else
+ tmp = 1;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ val &= 0xfb;
+ val |= tmp << 2;
+ axp_write(dev,POWER15_PEK_SET,val);
+ return count;
+}
+
+static ssize_t axp15_pekclose_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ return sprintf(buf,"%d\n",((val & 0x03) * 2000) + 4000);
+}
+
+static ssize_t axp15_pekclose_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if(tmp < 4000)
+ tmp = 4000;
+ if(tmp > 10000)
+ tmp =10000;
+ tmp = (tmp - 4000) / 2000 ;
+ axp_read(dev,POWER15_PEK_SET,&val);
+ val &= 0xfc;
+ val |= tmp ;
+ axp_write(dev,POWER15_PEK_SET,val);
+ return count;
+}
+
+static ssize_t axp15_ovtemclsen_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ axp_read(dev,POWER15_HOTOVER_CTL,&val);
+ return sprintf(buf,"%d\n",((val >> 2) & 0x01));
+}
+
+static ssize_t axp15_ovtemclsen_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 10);
+ if(tmp)
+ tmp = 1;
+ axp_read(dev,POWER15_HOTOVER_CTL,&val);
+ val &= 0xfb;
+ val |= tmp << 2 ;
+ axp_write(dev,POWER15_HOTOVER_CTL,val);
+ return count;
+}
+
+static ssize_t axp15_reg_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val;
+ axp_read(dev,axp_reg_addr,&val);
+ return sprintf(buf,"REG[%x]=%x\n",axp_reg_addr,val);
+}
+
+static ssize_t axp15_reg_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val;
+ tmp = simple_strtoul(buf, NULL, 16);
+ if( tmp < 256 )
+ axp_reg_addr = tmp;
+ else {
+ val = tmp & 0x00FF;
+ axp_reg_addr= (tmp >> 8) & 0x00FF;
+ axp_write(dev,axp_reg_addr, val);
+ }
+ return count;
+}
+
+static ssize_t axp15_regs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ uint8_t val[2];
+ axp_reads(dev,axp_reg_addr,2,val);
+ return sprintf(buf,"REG[0x%x]=0x%x,REG[0x%x]=0x%x\n",axp_reg_addr,val[0],axp_reg_addr+1,val[1]);
+}
+
+static ssize_t axp15_regs_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+ uint8_t val[3];
+ tmp = simple_strtoul(buf, NULL, 16);
+ if( tmp < 256 )
+ axp_reg_addr = tmp;
+ else {
+ axp_reg_addr= (tmp >> 16) & 0xFF;
+ val[0] = (tmp >> 8) & 0xFF;
+ val[1] = axp_reg_addr + 1;
+ val[2] = tmp & 0xFF;
+ axp_writes(dev,axp_reg_addr,3,val);
+ }
+ return count;
+}
+
+static struct device_attribute axp15_mfd_attrs[] = {
+ AXP_MFD_ATTR(axp15_offvol),
+ AXP_MFD_ATTR(axp15_noedelay),
+ AXP_MFD_ATTR(axp15_pekopen),
+ AXP_MFD_ATTR(axp15_peklong),
+ AXP_MFD_ATTR(axp15_peken),
+ AXP_MFD_ATTR(axp15_pekdelay),
+ AXP_MFD_ATTR(axp15_pekclose),
+ AXP_MFD_ATTR(axp15_ovtemclsen),
+ AXP_MFD_ATTR(axp15_reg),
+ AXP_MFD_ATTR(axp15_regs),
+};
diff --git a/drivers/power/axp_power/axp15-regu.c b/drivers/power/axp_power/axp15-regu.c
new file mode 100755
index 0000000..d46e4f7
--- /dev/null
+++ b/drivers/power/axp_power/axp15-regu.c
@@ -0,0 +1,704 @@
+/*
+ * Regulators driver for Dialog Semiconductor DA903x
+ *
+ * Copyright (C) 2006-2008 Marvell International Ltd.
+ * Copyright (C) 2008 Compulab Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/module.h>
+
+#include "axp-regu.h"
+
+static int axp15_ldo0_data[] = { 5000, 3300, 2800, 2500};
+static int axp15_dcdc1_data[] = { 1700, 1800, 1900, 2000, 2100, 2400, 2500, 2600,\
+ 2700, 2800, 3000, 3100, 3200, 3300, 3400, 3500};
+static int axp15_aldo12_data[] = { 1200, 1300, 1400, 1500, 1600, 1700, 1800, 1900,\
+ 2000, 2500, 2700, 2800, 3000, 3100, 3200, 3300};
+
+static inline struct device *to_axp_dev(struct regulator_dev *rdev)
+{
+ return rdev_get_dev(rdev)->parent->parent;
+}
+
+static inline int check_range(struct axp_regulator_info *info,
+ int min_uV, int max_uV)
+{
+ if (min_uV < info->min_uV || min_uV > info->max_uV)
+ return -EINVAL;
+
+ return 0;
+}
+
+
+/* AXP common operations */
+static int axp_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+
+
+ if (check_range(info, min_uV, max_uV)) {
+ pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV;
+ val <<= info->vol_shift;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ printk("reg=[%x],val=%d,mask=%d,line=%d\n",info->vol_reg,val,mask,__LINE__);
+ return axp_update(axp_dev, info->vol_reg, val, mask);
+}
+
+static int axp_get_voltage(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int ret;
+
+ ret = axp_read(axp_dev, info->vol_reg, &val);
+ if (ret)
+ return ret;
+
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ val = (val & mask) >> info->vol_shift;
+
+ return info->min_uV + info->step_uV * val;
+
+}
+
+static int axp_enable(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+
+ return axp_set_bits(axp_dev, info->enable_reg,
+ 1 << info->enable_bit);
+}
+
+static int axp_disable(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+
+ return axp_clr_bits(axp_dev, info->enable_reg,
+ 1 << info->enable_bit);
+}
+
+static int axp_is_enabled(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t reg_val;
+ int ret;
+
+ ret = axp_read(axp_dev, info->enable_reg, &reg_val);
+ if (ret)
+ return ret;
+
+ return !!(reg_val & (1 << info->enable_bit));
+}
+
+static int axp_list_voltage(struct regulator_dev *rdev, unsigned selector)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ int ret;
+
+ if(info->desc.id == AXP15_ID_LDO0)
+ return axp15_ldo0_data[selector] * 1000;
+ if(info->desc.id == AXP15_ID_DCDC1)
+ return axp15_dcdc1_data[selector] * 1000;
+ if(info->desc.id == AXP15_ID_LDO2)
+ return axp15_aldo12_data[selector] * 1000;
+ if(info->desc.id == AXP15_ID_LDO3)
+ return axp15_aldo12_data[selector] * 1000;
+
+ ret = info->min_uV + info->step_uV * selector;
+ if (ret > info->max_uV)
+ return -EINVAL;
+ return ret;
+}
+
+static int axp_set_ldo0_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int i;
+
+ if (check_range(info, min_uV, max_uV)) {
+ pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ for(i = 0,val = 0; i < sizeof(axp15_ldo0_data);i++){
+ if(min_uV <= axp15_ldo0_data[i] * 1000){
+ val = i;
+ break;
+ }
+ }
+ val <<= info->vol_shift;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ return axp_update(axp_dev, info->vol_reg, val, mask);
+}
+
+static int axp_set_dcdc1_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int i;
+
+ if (check_range(info, min_uV, max_uV)) {
+ pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ for(i = 0,val = 0; i < sizeof(axp15_dcdc1_data);i++){
+ if(min_uV <= axp15_dcdc1_data[i] * 1000){
+ val = i;
+ break;
+ }
+ }
+ val <<= info->vol_shift;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ return axp_update(axp_dev, info->vol_reg, val, mask);
+}
+
+static int axp_set_aldo12_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int i;
+
+ if (check_range(info, min_uV, max_uV)) {
+ pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ for(i = 0,val = 0; i < sizeof(axp15_aldo12_data);i++){
+ if(min_uV <= axp15_aldo12_data[i] * 1000){
+ val = i;
+ break;
+ }
+ }
+ val <<= info->vol_shift;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ return axp_update(axp_dev, info->vol_reg, val, mask);
+}
+
+/*static int axp_set_ldoio0_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int i;
+
+ if (check_range(info, min_uV, max_uV)) {
+ pr_err("invalid voltage range (%d, %d) uV\n", min_uV, max_uV);
+ return -EINVAL;
+ }
+
+ for(i = 0,val = 0; i < sizeof(axp15_ldoio0_data);i++){
+ if(min_uV <= axp15_ldoio0_data[i] * 1000){
+ val = i;
+ break;
+ }
+ }
+ val <<= info->vol_shift;
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ return axp_update(axp_dev, info->vol_reg, val, mask);
+}*/
+
+static int axp_get_ldo0_voltage(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int ret;
+
+ ret = axp_read(axp_dev, info->vol_reg, &val);
+ if (ret)
+ return ret;
+
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ val = (val & mask) >> info->vol_shift;
+ ret = axp15_ldo0_data[val]*1000;
+ return ret;
+}
+
+static int axp_get_dcdc1_voltage(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int ret;
+
+ ret = axp_read(axp_dev, info->vol_reg, &val);
+ if (ret)
+ return ret;
+
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ val = (val & mask) >> info->vol_shift;
+ ret = axp15_dcdc1_data[val]*1000;
+ return ret;
+}
+
+static int axp_get_aldo12_voltage(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val, mask;
+ int ret;
+
+ ret = axp_read(axp_dev, info->vol_reg, &val);
+ if (ret)
+ return ret;
+
+ mask = ((1 << info->vol_nbits) - 1) << info->vol_shift;
+ val = (val & mask) >> info->vol_shift;
+ ret = axp15_aldo12_data[val]*1000;
+ return ret;
+}
+
+static int axp_set_suspend_voltage(struct regulator_dev *rdev, int uV)
+{
+ int ldo = rdev_get_id(rdev);
+printk("%s,%d\n", __func__, __LINE__);
+ switch (ldo) {
+
+ case AXP15_ID_LDO0:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_ldo0_voltage(rdev, uV, uV);
+ case AXP15_ID_LDO2:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_aldo12_voltage(rdev, uV, uV);
+ case AXP15_ID_LDO3:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_aldo12_voltage(rdev, uV, uV);
+ case AXP15_ID_LDO4:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ case AXP15_ID_LDO5:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ case AXP15_ID_DCDC1:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_dcdc1_voltage(rdev, uV, uV);
+ case AXP15_ID_DCDC2:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ case AXP15_ID_DCDC3:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ case AXP15_ID_DCDC4:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ case AXP15_ID_LDO1:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ case AXP15_ID_LDOIO0:
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return axp_set_voltage(rdev, uV, uV);
+ default:
+ return -EINVAL;
+ }
+}
+
+
+static struct regulator_ops axp15_ops = {
+ .set_voltage = axp_set_voltage,
+ .get_voltage = axp_get_voltage,
+ .list_voltage = axp_list_voltage,
+ .enable = axp_enable,
+ .disable = axp_disable,
+ .is_enabled = axp_is_enabled,
+ .set_suspend_enable = axp_enable,
+ .set_suspend_disable = axp_disable,
+ .set_suspend_voltage = axp_set_suspend_voltage,
+};
+
+static struct regulator_ops axp15_ldo0_ops = {
+ .set_voltage = axp_set_ldo0_voltage,
+ .get_voltage = axp_get_ldo0_voltage,
+ .list_voltage = axp_list_voltage,
+ .enable = axp_enable,
+ .disable = axp_disable,
+ .is_enabled = axp_is_enabled,
+ .set_suspend_enable = axp_enable,
+ .set_suspend_disable = axp_disable,
+ .set_suspend_voltage = axp_set_suspend_voltage,
+};
+
+static struct regulator_ops axp15_dcdc1_ops = {
+ .set_voltage = axp_set_dcdc1_voltage,
+ .get_voltage = axp_get_dcdc1_voltage,
+ .list_voltage = axp_list_voltage,
+ .enable = axp_enable,
+ .disable = axp_disable,
+ .is_enabled = axp_is_enabled,
+ .set_suspend_enable = axp_enable,
+ .set_suspend_disable = axp_disable,
+ .set_suspend_voltage = axp_set_suspend_voltage,
+};
+
+static struct regulator_ops axp15_aldo12_ops = {
+ .set_voltage = axp_set_aldo12_voltage,
+ .get_voltage = axp_get_aldo12_voltage,
+ .list_voltage = axp_list_voltage,
+ .enable = axp_enable,
+ .disable = axp_disable,
+ .is_enabled = axp_is_enabled,
+ .set_suspend_enable = axp_enable,
+ .set_suspend_disable = axp_disable,
+ .set_suspend_voltage = axp_set_suspend_voltage,
+};
+
+static int axp_ldoio0_enable(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+
+ axp_set_bits(axp_dev, info->enable_reg,0x03);
+ return axp_clr_bits(axp_dev, info->enable_reg,0x04);
+}
+
+static int axp_ldoio0_disable(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+
+ return axp_clr_bits(axp_dev, info->enable_reg,0x07);
+}
+
+static int axp_ldoio0_is_enabled(struct regulator_dev *rdev)
+{
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t reg_val;
+ int ret;
+
+ ret = axp_read(axp_dev, info->enable_reg, &reg_val);
+ if (ret)
+ return ret;
+
+ return (((reg_val &= 0x07)== 0x03)?1:0);
+}
+
+static struct regulator_ops axp15_ldoio0_ops = {
+ .set_voltage = axp_set_voltage,
+ .get_voltage = axp_get_voltage,
+ .list_voltage = axp_list_voltage,
+ .enable = axp_ldoio0_enable,
+ .disable = axp_ldoio0_disable,
+ .is_enabled = axp_ldoio0_is_enabled,
+ .set_suspend_enable = axp_ldoio0_enable,
+ .set_suspend_disable = axp_ldoio0_disable,
+ .set_suspend_voltage = axp_set_suspend_voltage,
+};
+
+
+#define AXP15_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
+ AXP_LDO(AXP15, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
+
+#define AXP15_BUCK(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
+ AXP_BUCK(AXP15, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
+
+#define AXP15_DCDC(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \
+ AXP_DCDC(AXP15, _id, min, max, step, vreg, shift, nbits, ereg, ebit)
+
+static struct axp_regulator_info axp_regulator_info[] = {
+ AXP15_LDO( 0, 2500, 5000, 833, LDO0, 4, 2, LDO0EN, 7),//ldo0
+ AXP15_LDO( 1, 1200, 3100, 100, RTC, 0, 0, RTCLDOEN, 0),//ldo1 for rtc
+ AXP15_LDO( 2, 1200, 3300, 120, ANALOG1, 4, 4, ANALOG1EN, 3),//ldo2 for analog1
+ AXP15_LDO( 3, 1200, 3300, 120, ANALOG2, 0, 4, ANALOG2EN, 2),//ldo3 for analog2
+ AXP15_LDO( 4, 700, 3500, 100, DIGITAL1, 0, 4, ANALOG1EN, 1),//ldo2 for DigtalLDO1
+ AXP15_LDO( 5, 700, 3500, 100, DIGITAL2, 0, 4, ANALOG2EN, 0),//ldo3 for DigtalLDO2
+ AXP15_DCDC( 1, 1700, 3500, 120, DCDC1, 0, 4, DCDC1EN, 7) , //buck1
+ AXP15_DCDC( 2, 700, 2275, 25, DCDC2, 0, 6, DCDC2EN, 6),//buck2
+ AXP15_DCDC( 3, 700, 3500, 50, DCDC3, 0, 6, DCDC3EN, 5),//buck3
+ AXP15_DCDC( 4, 700, 3500, 25, DCDC4, 0, 7, DCDC4EN, 4),//buck4
+ AXP15_LDO( IO0, 1800, 3300, 100, LDOIO0, 0, 4, LDOI0EN, 1),//ldoio0
+};
+
+static ssize_t workmode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ int ret;
+ uint8_t val;
+ ret = axp_read(axp_dev, AXP15_BUCKMODE, &val);
+ if (ret)
+ return sprintf(buf, "IO ERROR\n");
+
+ if(info->desc.id == AXP15_ID_DCDC1){
+ switch (val & 0x08) {
+ case 0:return sprintf(buf, "AUTO\n");
+ case 8:return sprintf(buf, "PWM\n");
+ default:return sprintf(buf, "UNKNOWN\n");
+ }
+ }
+ if(info->desc.id == AXP15_ID_DCDC2){
+ switch (val & 0x04) {
+ case 0:return sprintf(buf, "AUTO\n");
+ case 4:return sprintf(buf, "PWM\n");
+ default:return sprintf(buf, "UNKNOWN\n");
+ }
+ }
+ if(info->desc.id == AXP15_ID_DCDC3){
+ switch (val & 0x02) {
+ case 0:return sprintf(buf, "AUTO\n");
+ case 2:return sprintf(buf, "PWM\n");
+ default:return sprintf(buf, "UNKNOWN\n");
+ }
+ }
+ else if(info->desc.id == AXP15_ID_DCDC4){
+ switch (val & 0x01) {
+ case 0:return sprintf(buf, "AUTO\n");
+ case 1:return sprintf(buf, "PWM\n");
+ default:return sprintf(buf, "UNKNOWN\n");
+ }
+ }
+ else
+ return sprintf(buf, "IO ID ERROR\n");
+}
+
+static ssize_t workmode_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ struct axp_regulator_info *info = rdev_get_drvdata(rdev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ char mode;
+ uint8_t val;
+ if( buf[0] > '0' && buf[0] < '9' )// 1/AUTO: auto mode; 2/PWM: pwm mode;
+ mode = buf[0];
+ else
+ mode = buf[1];
+
+ switch(mode){
+ case 'U':
+ case 'u':
+ case '1':
+ val = 0;break;
+ case 'W':
+ case 'w':
+ case '2':
+ val = 1;break;
+ default:
+ val =0;
+ }
+
+ if(info->desc.id == AXP15_ID_DCDC1){
+ if(val)
+ axp_set_bits(axp_dev, AXP15_BUCKMODE,0x08);
+ else
+ axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x08);
+ }
+ if(info->desc.id == AXP15_ID_DCDC2){
+ if(val)
+ axp_set_bits(axp_dev, AXP15_BUCKMODE,0x04);
+ else
+ axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x04);
+ }
+ if(info->desc.id == AXP15_ID_DCDC3){
+ if(val)
+ axp_set_bits(axp_dev, AXP15_BUCKMODE,0x02);
+ else
+ axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x02);
+ }
+ else if(info->desc.id == AXP15_ID_DCDC4){
+ if(val)
+ axp_set_bits(axp_dev, AXP15_BUCKMODE,0x01);
+ else
+ axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x01);
+ }
+
+ return count;
+}
+
+static ssize_t frequency_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ int ret;
+ uint8_t val;
+ ret = axp_read(axp_dev, AXP15_BUCKFREQ, &val);
+ if (ret)
+ return ret;
+ ret = val & 0x0F;
+ return sprintf(buf, "%d\n",(ret*5 + 50));
+}
+
+static ssize_t frequency_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct regulator_dev *rdev = dev_get_drvdata(dev);
+ struct device *axp_dev = to_axp_dev(rdev);
+ uint8_t val,tmp;
+ int var;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var < 50)
+ var = 50;
+ if(var > 100)
+ var = 100;
+
+ val = (var -50)/5;
+ val &= 0x0F;
+
+ axp_read(axp_dev, AXP15_BUCKFREQ, &tmp);
+ tmp &= 0xF0;
+ val |= tmp;
+ axp_write(axp_dev, AXP15_BUCKFREQ, val);
+ return count;
+}
+
+
+static struct device_attribute axp_regu_attrs[] = {
+ AXP_REGU_ATTR(workmode),
+ AXP_REGU_ATTR(frequency),
+};
+
+int axp_regu_create_attrs(struct platform_device *pdev)
+{
+ int j,ret;
+ for (j = 0; j < ARRAY_SIZE(axp_regu_attrs); j++) {
+ ret = device_create_file(&pdev->dev,&axp_regu_attrs[j]);
+ if (ret)
+ goto sysfs_failed;
+ }
+ goto succeed;
+
+sysfs_failed:
+ while (j--)
+ device_remove_file(&pdev->dev,&axp_regu_attrs[j]);
+succeed:
+ return ret;
+}
+
+static inline struct axp_regulator_info *find_regulator_info(int id)
+{
+ struct axp_regulator_info *ri;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(axp_regulator_info); i++) {
+ ri = &axp_regulator_info[i];
+ if (ri->desc.id == id)
+ return ri;
+ }
+ return NULL;
+}
+
+static int __devinit axp_regulator_probe(struct platform_device *pdev)
+{
+ struct axp_regulator_info *ri = NULL;
+ struct regulator_dev *rdev;
+ int ret;
+
+ ri = find_regulator_info(pdev->id);
+ if (ri == NULL) {
+ dev_err(&pdev->dev, "invalid regulator ID specified\n");
+ return -EINVAL;
+ }
+
+ if (ri->desc.id == AXP15_ID_LDO4 || ri->desc.id == AXP15_ID_LDO5 \
+ ||ri->desc.id == AXP15_ID_DCDC1 ||ri->desc.id == AXP15_ID_DCDC2 \
+ ||ri->desc.id == AXP15_ID_DCDC3 ||ri->desc.id == AXP15_ID_DCDC4 \
+ ||ri->desc.id == AXP15_ID_LDO1 ||ri->desc.id == AXP15_ID_LDOIO0)
+ {
+ ri->desc.ops = &axp15_ops;
+ printk("Register AXP15_OPS sucess!\n");
+ }
+
+
+ if(ri->desc.id == AXP15_ID_LDO0)
+ {
+ ri->desc.ops = &axp15_ldo0_ops;
+ printk("Register AXP15_ldo0_OPS finish!\n");
+ }
+
+ if(ri->desc.id == AXP15_ID_LDO3 || ri->desc.id == AXP15_ID_LDO2)
+ {
+ ri->desc.ops = &axp15_aldo12_ops;
+ printk("Register AXP15_aldo12_OPS finish!\n");
+ }
+
+ if(ri->desc.id == AXP15_ID_DCDC1)
+ {
+ ri->desc.ops = &axp15_dcdc1_ops;
+ printk("Register AXP15_dcdc1_OPS finish!\n");
+ }
+
+ rdev = regulator_register(&ri->desc, &pdev->dev,
+ pdev->dev.platform_data, ri);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "failed to register regulator %s\n",
+ ri->desc.name);
+ return PTR_ERR(rdev);
+ }
+ platform_set_drvdata(pdev, rdev);
+
+ if(ri->desc.id == AXP15_ID_DCDC1 ||ri->desc.id == AXP15_ID_DCDC2 \
+ ||ri->desc.id == AXP15_ID_DCDC3 ||ri->desc.id == AXP15_ID_DCDC4){
+ ret = axp_regu_create_attrs(pdev);
+ if(ret){
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int __devexit axp_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+ return 0;
+}
+
+static struct platform_driver axp_regulator_driver = {
+ .driver = {
+ .name = "axp15-regulator",
+ .owner = THIS_MODULE,
+ },
+ .probe = axp_regulator_probe,
+ .remove = axp_regulator_remove,
+};
+
+static int __init axp_regulator_init(void)
+{
+ return platform_driver_register(&axp_regulator_driver);
+}
+module_init(axp_regulator_init);
+
+static void __exit axp_regulator_exit(void)
+{
+ platform_driver_unregister(&axp_regulator_driver);
+}
+module_exit(axp_regulator_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Kyle Cheung");
+MODULE_DESCRIPTION("Regulator Driver for AXP15 PMIC");
+MODULE_ALIAS("platform:axp-regulator");
diff --git a/drivers/power/axp_power/axp15-sply.c b/drivers/power/axp_power/axp15-sply.c
new file mode 100755
index 0000000..adb7198
--- /dev/null
+++ b/drivers/power/axp_power/axp15-sply.c
@@ -0,0 +1,2318 @@
+/*
+ * Battery charger driver for KrossPower AXP15X
+ *
+ * Copyright (C) 2012 X-Power, Ltd.
+ * Zhang Donglu <zhang...@x-powers.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/workqueue.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+#include <linux/delay.h>
+#include <linux/kthread.h>
+#include <linux/slab.h>
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+#include <linux/input.h>
+#include <linux/mfd/axp-mfd.h>
+#include <asm/div64.h>
+
+#include <mach/sys_config.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+#include "axp-cfg.h"
+#include "axp-sply.h"
+
+#define DBG_AXP_PSY 1
+#if DBG_AXP_PSY
+#define DBG_PSY_MSG(format,args...) printk("[AXP]"format,##args)
+#else
+#define DBG_PSY_MSG(format,args...) do {} while (0)
+#endif
+static int axp_debug = 0;
+static int pmu_used2 = 0;
+static int gpio_adp_hdle = 0;
+static int pmu_suspendpwroff_vol = 0;
+static int pmu_earlysuspend_chgcur = 0;
+static int pmu_batdeten = 0;
+struct axp_adc_res adc;
+static int count_rdc = 0;
+static int count_dis = 0;
+struct delayed_work usbwork;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct early_suspend axp_early_suspend;
+int early_suspend_flag = 0;
+#endif
+
+int pmu_usbvolnew ;
+int pmu_usbcurnew ;
+int axp_usbcurflag ;
+int axp_usbvolflag ;
+
+int axp_usbvol(void)
+{
+ axp_usbvolflag = 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbvol);
+
+int axp_usbcur(void)
+{
+ axp_usbcurflag = 1;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbcur);
+
+int axp_usbvol_restore(void)
+{
+ axp_usbvolflag = 0;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbvol_restore);
+
+int axp_usbcur_restore(void)
+{
+ axp_usbcurflag = 0;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(axp_usbcur_restore);
+
+static ssize_t axpdebug_store(struct class *class,
+ struct class_attribute *attr, const char *buf, size_t count)
+{
+ if(buf[0] == '1'){
+ axp_debug = 1;
+ }
+ else{
+ axp_debug = 0;
+ }
+ return count;
+}
+
+static ssize_t axpdebug_show(struct class *class,
+ struct class_attribute *attr, char *buf)
+{
+ return sprintf(buf, "bat-debug value is %d\n", axp_debug);
+}
+
+static struct class_attribute axppower_class_attrs[] = {
+ __ATTR(axpdebug,S_IRUGO|S_IWUSR,axpdebug_show,axpdebug_store),
+ __ATTR_NULL
+};
+static struct class axppower_class = {
+ .name = "axppower",
+ .class_attrs = axppower_class_attrs,
+};
+
+int ADC_Freq_Get(struct axp_charger *charger)
+{
+ //uint8_t temp;
+ int rValue = 25;
+
+// axp_read(charger->master, AXP15_ADC_CONTROL3,&temp);
+// temp &= 0xc0;
+// switch(temp >> 6)
+// {
+// case 0:
+// rValue = 25;
+// break;
+// case 1:
+// rValue = 50;
+// break;
+// case 2:
+// rValue = 100;
+// break;
+// case 3:
+// rValue = 200;
+// break;
+// default:
+// break;
+// }
+ return rValue;
+}
+
+static inline int axp15_vbat_to_mV(uint16_t reg)
+{
+ return 4000;
+ //return ((int)((( reg >> 8) << 4 ) | (reg & 0x000F))) * 1100 / 1000;
+}
+
+static inline int axp15_vdc_to_mV(uint16_t reg)
+{
+ return 5000;
+ //return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 1700 / 1000;
+}
+
+
+static inline int axp15_ibat_to_mA(uint16_t reg)
+{
+ return 200;
+ //return ((int)(((reg >> 8) << 5 ) | (reg & 0x001F))) * 500 / 1000;
+}
+
+static inline int axp15_icharge_to_mA(uint16_t reg)
+{
+ return 200;
+ //return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 500 / 1000;
+}
+
+static inline int axp15_iac_to_mA(uint16_t reg)
+{
+ return 200;
+
+ //return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 625 / 1000;
+}
+
+static inline int axp15_iusb_to_mA(uint16_t reg)
+{
+ return 200;
+
+ //return ((int)(((reg >> 8) << 4 ) | (reg & 0x000F))) * 375 / 1000;
+}
+
+/*adc may not be used*/
+static inline void axp_read_adc(struct axp_charger *charger,
+ struct axp_adc_res *adc)
+{
+// uint8_t tmp[8];
+//
+// axp_reads(charger->master,AXP15_VACH_RES,8,tmp);
+// adc->vac_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
+// adc->iac_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
+// adc->vusb_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
+// adc->iusb_res = ((uint16_t) tmp[6] << 8 )| tmp[7];
+// axp_reads(charger->master,AXP15_VBATH_RES,6,tmp);
+// adc->vbat_res = ((uint16_t) tmp[0] << 8 )| tmp[1];
+// adc->ichar_res = ((uint16_t) tmp[2] << 8 )| tmp[3];
+// adc->idischar_res = ((uint16_t) tmp[4] << 8 )| tmp[5];
+// return 0xEEA;
+}
+
+
+static void axp_charger_update_state(struct axp_charger *charger)
+{
+// uint8_t val[2];
+// uint16_t tmp;
+//
+// axp_reads(charger->master,AXP15_CHARGE_STATUS,2,val);
+// tmp = (val[1] << 8 )+ val[0];
+// charger->is_on = (val[1] & AXP15_IN_CHARGE) ? 1 : 0;
+// charger->fault = val[1];
+// charger->bat_det = (tmp & AXP15_STATUS_BATEN)?1:0;
+// charger->ac_det = (tmp & AXP15_STATUS_ACEN)?1:0;
+// charger->usb_det = (tmp & AXP15_STATUS_USBEN)?1:0;
+// charger->usb_valid = (tmp & AXP15_STATUS_USBVA)?1:0;
+// charger->ac_valid = (tmp & AXP15_STATUS_ACVA)?1:0;
+// charger->ext_valid = charger->ac_valid | charger->usb_valid;
+// charger->bat_current_direction = (tmp & AXP15_STATUS_BATCURDIR)?1:0;
+// charger->in_short = (tmp& AXP15_STATUS_ACUSBSH)?1:0;
+// charger->batery_active = (tmp & AXP15_STATUS_BATINACT)?1:0;
+// charger->low_charge_current = (tmp & AXP15_STATUS_CHACURLOEXP)?1:0;
+// charger->int_over_temp = (tmp & AXP15_STATUS_ICTEMOV)?1:0;
+// axp_read(charger->master,AXP15_CHARGE_CONTROL1,val);
+// charger->charge_on = ((val[0] >> 7) & 0x01);
+}
+/*
+static void axp_charger_update(struct axp_charger *charger)
+{
+ uint16_t tmp;
+ uint8_t val[2];
+ //struct axp_adc_res adc;
+ charger->adc = &adc;
+ axp_read_adc(charger, &adc);
+ tmp = charger->adc->vbat_res;
+ charger->vbat = axp15_vbat_to_mV(tmp);
+ //tmp = charger->adc->ichar_res + charger->adc->idischar_res;
+ charger->ibat = ABS(axp15_icharge_to_mA(charger->adc->ichar_res)-axp15_ibat_to_mA(charger->adc->idischar_res));
+ tmp = charger->adc->vac_res;
+ charger->vac = axp15_vdc_to_mV(tmp);
+ tmp = charger->adc->iac_res;
+ charger->iac = axp15_iac_to_mA(tmp);
+ tmp = charger->adc->vusb_res;
+ charger->vusb = axp15_vdc_to_mV(tmp);
+ tmp = charger->adc->iusb_res;
+ charger->iusb = axp15_iusb_to_mA(tmp);
+ axp_reads(charger->master,AXP15_INTTEMP,2,val);
+ //DBG_PSY_MSG("TEMPERATURE:val1=0x%x,val2=0x%x\n",val[1],val[0]);
+ tmp = (val[0] << 4 ) + (val[1] & 0x0F);
+ charger->ic_temp = (int) tmp - 1447;
+ if(!charger->ext_valid){
+ charger->disvbat = charger->vbat;
+ charger->disibat = charger->ibat;
+ }
+}
+*/
+static void axp_charger_update(struct axp_charger *charger)
+{
+ uint16_t tmp;
+ uint8_t val[2];
+ //struct axp_adc_res adc;
+
+
+ charger->vbat = 4000;
+ //tmp = charger->adc->ichar_res + charger->adc->idischar_res;
+ charger->ibat = 200;
+ charger->vac = 5000;
+ charger->iac = 500;
+ charger->vusb = 5000;
+ charger->iusb = 200;
+
+ charger->ic_temp = 30;
+
+ charger->disvbat = charger->vbat;
+ charger->disibat = charger->ibat;
+
+}
+
+
+#if defined (CONFIG_AXP_CHARGEINIT)
+static void axp_set_charge(struct axp_charger *charger)
+{
+/*
+ uint8_t val=0x00;
+ uint8_t tmp=0x00;
+ if(charger->chgvol < 4150000)
+ val &= ~(3 << 5);
+ else if (charger->chgvol<4150000){
+ val &= ~(3 << 5);
+ val |= 1 << 5;
+ }
+ else if (charger->chgvol<4360000){
+ val &= ~(3 << 5);
+ val |= 1 << 6;
+ }
+ else
+ val |= 3 << 5;
+
+ if(charger->chgcur == 0)
+ charger->chgen = 0;
+
+ if(charger->chgcur< 300000)
+ charger->chgcur = 300000;
+ else if(charger->chgcur > 1800000)
+ charger->chgcur = 1800000;
+
+ val |= (charger->chgcur - 150001) / 100000 ;
+ if(charger ->chgend == 10){
+ val &= ~(1 << 4);
+ }
+ else {
+ val |= 1 << 4;
+ }
+ val &= 0x7F;
+ val |= charger->chgen << 7;
+ if(charger->chgpretime < 30)
+ charger->chgpretime = 30;
+ if(charger->chgcsttime < 360)
+ charger->chgcsttime = 360;
+
+ tmp = ((((charger->chgpretime - 40) / 10) << 6) \
+ | ((charger->chgcsttime - 360) / 120));
+ axp_write(charger->master, AXP15_CHARGE_CONTROL1,val);
+ axp_update(charger->master, AXP15_CHARGE_CONTROL2,tmp,0xC2);
+*/
+}
+#else
+static void axp_set_charge(struct axp_charger *charger)
+{
+
+}
+#endif
+
+/*may not be used*/
+static enum power_supply_property axp_battery_props[] = {
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_TECHNOLOGY,
+ POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+ //POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN,
+ //POWER_SUPPLY_PROP_CHARGE_FULL,
+ POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN,
+ POWER_SUPPLY_PROP_CAPACITY,
+ //POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW,
+ //POWER_SUPPLY_PROP_TIME_TO_FULL_NOW,
+ POWER_SUPPLY_PROP_TEMP,
+};
+
+static enum power_supply_property axp_ac_props[] = {
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+};
+
+static enum power_supply_property axp_usb_props[] = {
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_VOLTAGE_NOW,
+ POWER_SUPPLY_PROP_CURRENT_NOW,
+};
+
+/*may not be used*/
+static void axp_battery_check_status(struct axp_charger *charger,
+ union power_supply_propval *val)
+{
+/*
+ if (charger->bat_det) {
+ if (charger->ext_valid){
+ if( charger->rest_vol == 100)
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+ else if(charger->charge_on)
+ val->intval = POWER_SUPPLY_STATUS_CHARGING;
+ else
+ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ }
+ else
+ val->intval = POWER_SUPPLY_STATUS_DISCHARGING;
+ }
+ else
+*/
+ val->intval = POWER_SUPPLY_STATUS_FULL;
+}
+
+/*may not be used*/
+static void axp_battery_check_health(struct axp_charger *charger,
+ union power_supply_propval *val)
+{
+/*
+ if (charger->fault & AXP15_FAULT_LOG_BATINACT)
+ val->intval = POWER_SUPPLY_HEALTH_DEAD;
+ else if (charger->fault & AXP15_FAULT_LOG_OVER_TEMP)
+ val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
+ else if (charger->fault & AXP15_FAULT_LOG_COLD)
+ val->intval = POWER_SUPPLY_HEALTH_COLD;
+ else
+*/
+ val->intval = POWER_SUPPLY_HEALTH_GOOD;
+}
+
+/*may not be used*/
+static int axp_battery_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct axp_charger *charger;
+ int ret = 0;
+ charger = container_of(psy, struct axp_charger, batt);
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ axp_battery_check_status(charger, val);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ axp_battery_check_health(charger, val);
+ break;
+ case POWER_SUPPLY_PROP_TECHNOLOGY:
+ val->intval = charger->battery_info->technology;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MAX_DESIGN:
+ val->intval = charger->battery_info->voltage_max_design;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_MIN_DESIGN:
+ val->intval = charger->battery_info->voltage_min_design;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = charger->ocv * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = charger->ibat * 1000;
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = charger->batt.name;
+ break;
+/* case POWER_SUPPLY_PROP_CHARGE_FULL_DESIGN:
+ case POWER_SUPPLY_PROP_CHARGE_FULL:
+ val->intval = charger->battery_info->charge_full_design;
+ break;
+*/
+ case POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:
+ val->intval = charger->battery_info->energy_full_design;
+ // DBG_PSY_MSG("POWER_SUPPLY_PROP_ENERGY_FULL_DESIGN:%d\n",val->intval);
+ break;
+ case POWER_SUPPLY_PROP_CAPACITY:
+ charger->rest_vol = 100;
+ val->intval = charger->rest_vol;
+ break;
+/* case POWER_SUPPLY_PROP_TIME_TO_EMPTY_NOW:
+ if(charger->bat_det && !(charger->is_on) && !(charger->ext_valid))
+ val->intval = charger->rest_time;
+ else
+ val->intval = 0;
+ break;
+ case POWER_SUPPLY_PROP_TIME_TO_FULL_NOW:
+ if(charger->bat_det && charger->is_on)
+ val->intval = charger->rest_time;
+ else
+ val->intval = 0;
+ break;
+*/
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = (!charger->is_on)&&(charger->bat_det) && (! charger->ext_valid);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = charger->bat_det;
+ break;
+ case POWER_SUPPLY_PROP_TEMP:
+ //val->intval = charger->ic_temp - 150;
+ val->intval = 300;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+static int axp_ac_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct axp_charger *charger;
+ int ret = 0;
+ charger = container_of(psy, struct axp_charger, ac);
+
+ switch(psp){
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = charger->ac.name;break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = charger->ac_det;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = charger->ac_valid;break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = charger->vac * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = charger->iac * 1000;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int axp_usb_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct axp_charger *charger;
+ int ret = 0;
+ charger = container_of(psy, struct axp_charger, usb);
+
+ switch(psp){
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = charger->usb.name;break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = charger->usb_det;
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = charger->usb_valid;
+ break;
+ case POWER_SUPPLY_PROP_VOLTAGE_NOW:
+ val->intval = charger->vusb * 1000;
+ break;
+ case POWER_SUPPLY_PROP_CURRENT_NOW:
+ val->intval = charger->iusb * 1000;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static void axp_change(struct axp_charger *charger)
+{
+/*
+ uint8_t val,tmp;
+ int var;
+ DBG_PSY_MSG("battery state change\n");
+ axp_charger_update_state(charger);
+ axp_charger_update(charger);
+ printk("charger->usb_valid = %d\n",charger->usb_valid);
+ if(!charger->usb_valid){
+ printk("set usb vol-lim to %d mV, cur-lim to %d mA\n",pmu_usbvolnew,pmu_usbcurnew);
+ cancel_delayed_work_sync(&usbwork);
+ //reset usb-pc after usb removed
+ if(pmu_usbcurnew){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ var = pmu_usbcurnew * 1000;
+ if(var >= 900000)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ else if ((var >= 500000)&& (var < 900000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ }
+ else if ((var >= 100000)&& (var < 500000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ }
+ else
+ printk("set usb limit current error,%d mA\n",pmu_usbcur);
+ }
+ else
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+
+ if(pmu_usbvolnew){
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ var = pmu_usbvolnew * 1000;
+ if(var >= 4000000 && var <=4700000){
+ tmp = (var - 4000000)/100000;
+ axp_read(charger->master, AXP15_CHARGE_VBUS,&val);
+ val &= 0xC7;
+ val |= tmp << 3;
+ axp_write(charger->master, AXP15_CHARGE_VBUS,val);
+ }
+ else
+ printk("set usb limit voltage error,%d mV\n",pmu_usbvol);
+ }
+ else
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ }
+ else {
+ schedule_delayed_work(&usbwork, msecs_to_jiffies(4 * 1000));
+ }
+
+ flag_state_change = 1;
+ power_supply_changed(&charger->batt);
+*/
+}
+
+static void axp_presslong(struct axp_charger *charger)
+{
+ DBG_PSY_MSG("press long\n");
+ input_report_key(powerkeydev, KEY_POWER, 1);
+ input_sync(powerkeydev);
+ ssleep(2);
+ DBG_PSY_MSG("press long up\n");
+ input_report_key(powerkeydev, KEY_POWER, 0);
+ input_sync(powerkeydev);
+}
+
+static void axp_pressshort(struct axp_charger *charger)
+{
+ DBG_PSY_MSG("press short\n");
+ input_report_key(powerkeydev, KEY_POWER, 1);
+ input_sync(powerkeydev);
+ msleep(100);
+ input_report_key(powerkeydev, KEY_POWER, 0);
+ input_sync(powerkeydev);
+}
+
+static void axp_capchange(struct axp_charger *charger)
+{
+/*
+ uint8_t val;
+ int k;
+
+ DBG_PSY_MSG("battery change\n");
+ ssleep(2);
+ axp_charger_update_state(charger);
+ axp_charger_update(charger);
+ axp_read(charger->master, AXP15_CAP,&val);
+ charger->rest_vol = (int) (val & 0x7F);
+
+ if((charger->bat_det == 0) || (charger->rest_vol == 127)){
+ charger->rest_vol = 100;
+ }
+
+ DBG_PSY_MSG("rest_vol = %d\n",charger->rest_vol);
+ memset(Bat_Cap_Buffer, 0, sizeof(Bat_Cap_Buffer));
+ for(k = 0;k < AXP15_VOL_MAX; k++){
+ Bat_Cap_Buffer[k] = charger->rest_vol;
+ }
+ Total_Cap = charger->rest_vol * AXP15_VOL_MAX;
+ power_supply_changed(&charger->batt);
+*/
+}
+
+static void axp_close(struct axp_charger *charger)
+{
+/*
+ charger->rest_vol = 5;
+ axp_write(charger->master,AXP15_DATA_BUFFER1,0x85);
+ DBG_PSY_MSG("\n==================event in close==============\n");
+ power_supply_changed(&charger->batt);
+*/
+}
+
+
+static int axp_battery_event(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ struct axp_charger *charger =
+ container_of(nb, struct axp_charger, nb);
+
+ uint8_t w[5];
+
+ w[0] = (uint8_t) ((event) & 0xFF);
+ w[1] = POWER15_INTSTS2;
+ w[2] = (uint8_t) ((event >> 8) & 0xFF);
+ w[3] = POWER15_INTSTS3;
+ w[4] = (uint8_t) ((event >> 16) & 0xFF);
+
+
+// if(event & (AXP15_IRQ_BATIN|AXP15_IRQ_BATRE)) {
+// axp_capchange(charger);
+// }
+/*
+ if(event & (AXP15_IRQ_ACIN|AXP15_IRQ_USBIN|AXP15_IRQ_ACOV|AXP15_IRQ_USBOV|AXP15_IRQ_CHAOV
+ |AXP15_IRQ_CHAST|AXP15_IRQ_TEMOV|AXP15_IRQ_TEMLO)) {
+ axp_change(charger);
+ }
+
+ if(event & (AXP15_IRQ_ACRE|AXP15_IRQ_USBRE)) {
+ axp_change(charger);
+ axp_clr_bits(charger->master,0x32,0x38);
+ }
+*/
+ if(event & AXP15_IRQ_PEKLO) {
+ axp_presslong(charger);
+ }
+
+ if(event & AXP15_IRQ_PEKSH) {
+ axp_pressshort(charger);
+ }
+
+ DBG_PSY_MSG("event = 0x%x\n",(int) event);
+ axp_writes(charger->master,POWER15_INTSTS1,9,w);
+
+ return 0;
+}
+
+//may not used
+static char *supply_list[] = {
+ "battery",
+};
+
+
+
+static void axp_battery_setup_psy(struct axp_charger *charger)
+{
+ struct power_supply *batt = &charger->batt; /*may not used*/
+ struct power_supply *ac = &charger->ac;
+ struct power_supply *usb = &charger->usb;
+ struct power_supply_info *info = charger->battery_info; /*may not used*/
+
+/*may not used*/
+ batt->name = "battery";
+ batt->use_for_apm = info->use_for_apm;
+ batt->type = POWER_SUPPLY_TYPE_BATTERY;
+ batt->get_property = axp_battery_get_property;
+
+ batt->properties = axp_battery_props;
+ batt->num_properties = ARRAY_SIZE(axp_battery_props);
+
+ ac->name = "ac";
+ ac->type = POWER_SUPPLY_TYPE_MAINS;
+ ac->get_property = axp_ac_get_property;
+
+ ac->supplied_to = supply_list,
+ ac->num_supplicants = ARRAY_SIZE(supply_list),
+
+ ac->properties = axp_ac_props;
+ ac->num_properties = ARRAY_SIZE(axp_ac_props);
+
+ usb->name = "usb";
+ usb->type = POWER_SUPPLY_TYPE_USB;
+ usb->get_property = axp_usb_get_property;
+
+ usb->supplied_to = supply_list,
+ usb->num_supplicants = ARRAY_SIZE(supply_list),
+
+ usb->properties = axp_usb_props;
+ usb->num_properties = ARRAY_SIZE(axp_usb_props);
+};
+
+#if defined (CONFIG_AXP_CHARGEINIT)
+static int axp_battery_adc_set(struct axp_charger *charger)
+{
+/*
+ int ret ;
+ uint8_t val;
+
+ //enable adc and set adc
+ val= AXP15_ADC_BATVOL_ENABLE | AXP15_ADC_BATCUR_ENABLE
+ | AXP15_ADC_DCINCUR_ENABLE | AXP15_ADC_DCINVOL_ENABLE
+ | AXP15_ADC_USBVOL_ENABLE | AXP15_ADC_USBCUR_ENABLE;
+
+ ret = axp_update(charger->master, AXP15_ADC_CONTROL1, val , val);
+ if (ret)
+ return ret;
+ ret = axp_update(charger->master, AXP15_COULOMB_CONTROL, AXP15_COULOMB_ENABLE , AXP15_COULOMB_ENABLE);
+ if (ret)
+ return ret;
+ ret = axp_read(charger->master, AXP15_ADC_CONTROL3, &val);
+ switch (charger->sample_time/25){
+ case 1: val &= ~(3 << 6);break;
+ case 2: val &= ~(3 << 6);val |= 1 << 6;break;
+ case 4: val &= ~(3 << 6);val |= 2 << 6;break;
+ case 8: val |= 3 << 6;break;
+ default: break;
+ }
+ ret = axp_write(charger->master, AXP15_ADC_CONTROL3, val);
+ if (ret)
+ return ret;
+*/
+ return 0;
+}
+#else
+static int axp_battery_adc_set(struct axp_charger *charger)
+{
+ return 0;
+}
+#endif
+
+static int axp_battery_first_init(struct axp_charger *charger)
+{
+// int ret;
+// uint8_t val;
+// axp_set_charge(charger);
+// ret = axp_battery_adc_set(charger);
+// if(ret)
+// return ret;
+//
+// ret = axp_read(charger->master, AXP15_ADC_CONTROL3, &val);
+// switch ((val >> 6) & 0x03){
+// case 0: charger->sample_time = 25;break;
+// case 1: charger->sample_time = 50;break;
+// case 2: charger->sample_time = 100;break;
+// case 3: charger->sample_time = 200;break;
+// default:break;
+// }
+// return ret;
+ return 0;
+}
+
+/*may not used*/
+static int axp_get_rdc(struct axp_charger *charger)
+{
+/*
+ int temp;
+ int rdc;
+ uint8_t v[2];
+ axp_reads(charger->master,0xba,2,v);
+ rdc = (((v[0] & 0x1F) << 8) | v[1]) * 10742 / 10000;
+ DBG_PSY_MSG("===========================calculate rdc \n");
+
+ if(!charger->bat_det){
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ return rdc;
+ }
+ if( charger->ext_valid){
+ axp_charger_update(charger);
+ if( axp15_ibat_to_mA(charger->adc->idischar_res) == 0 && axp15_icharge_to_mA(charger->adc->ichar_res) > 150){
+ } else {
+ DBG_PSY_MSG("%s->%d\n",__FUNCTION__,__LINE__);
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ return rdc;
+ }
+ DBG_PSY_MSG("CHARGING: charger->vbat = %d, charger->ibat = %d\n",charger->vbat,charger->ibat);
+ DBG_PSY_MSG("DISCHARGING:charger->disvbat = %d,charger->disibat = %d\n",charger->disvbat,charger->disibat);
+ axp_charger_update_state(charger);
+ if(!charger->bat_current_direction){
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ return rdc;
+ }
+ if(charger->disvbat == 0){
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ return rdc;
+ }else{
+ temp = 1000 * ABS(charger->vbat - charger->disvbat) / ABS(charger->ibat + charger->disibat);
+ DBG_PSY_MSG("CALRDC:temp = %d\n",temp);
+ if((temp < 75) || (temp > pmu_battery_rdc * 2)){
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ return rdc;
+ } else {
+ axp_set_bits(charger->master,0x04,0x08);
+ return temp;
+ }
+ }
+ }else{
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ return rdc;
+ }
+ */
+ return 100;
+}
+
+static ssize_t chgen_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+/*
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ uint8_t val;
+ axp_read(charger->master, AXP15_CHARGE_CONTROL1, &val);
+ charger->chgen = val >> 7;
+ return sprintf(buf, "%d\n",charger->chgen);
+ */
+ return 1;
+}
+
+static ssize_t chgen_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var){
+ charger->chgen = 1;
+ //axp_set_bits(charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ }
+ else{
+ charger->chgen = 0;
+ //axp_clr_bits(charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ }
+ return count;
+}
+
+static ssize_t chgmicrovol_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ struct axp_charger *charger = dev_get_drvdata(dev);
+/* uint8_t val;
+ axp_read(charger->master, AXP15_CHARGE_CONTROL1, &val);
+ switch ((val >> 5) & 0x03){
+ case 0: charger->chgvol = 4100000;break;
+ case 1: charger->chgvol = 4150000;break;
+ case 2: charger->chgvol = 4200000;break;
+ case 3: charger->chgvol = 4360000;break;
+ */
+ charger->chgvol = 4200000;
+ //}
+ return sprintf(buf, "%d\n",charger->chgvol);
+}
+
+static ssize_t chgmicrovol_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ uint8_t tmp, val;
+ var = simple_strtoul(buf, NULL, 10);
+ switch(var){
+ case 4100000:tmp = 0;break;
+ case 4150000:tmp = 1;break;
+ case 4200000:tmp = 2;break;
+ case 4360000:tmp = 3;break;
+ default: tmp = 4;break;
+ }
+ if(tmp < 4){
+ charger->chgvol = var;
+ //axp_read(charger->master, AXP15_CHARGE_CONTROL1, &val);
+ val &= 0x9F;
+ val |= tmp << 5;
+ //axp_write(charger->master, AXP15_CHARGE_CONTROL1, val);
+ }
+ return count;
+}
+
+static ssize_t chgintmicrocur_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ /*uint8_t val;
+ axp_read(charger->master, AXP15_CHARGE_CONTROL1, &val);
+ charger->chgcur = (val & 0x0F) * 100000 +300000;
+ */
+ charger->chgcur = 300000;
+ return sprintf(buf, "%d\n",charger->chgcur);
+}
+
+static ssize_t chgintmicrocur_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ uint8_t val,tmp;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var >= 300000 && var <= 1800000){
+ tmp = (var -200001)/100000;
+ charger->chgcur = tmp *100000 + 300000;
+ //axp_read(charger->master, AXP15_CHARGE_CONTROL1, &val);
+ val &= 0xF0;
+ val |= tmp;
+ //axp_write(charger->master, AXP15_CHARGE_CONTROL1, val);
+ }
+ return count;
+}
+
+static ssize_t chgendcur_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ /*uint8_t val;
+ axp_read(charger->master, AXP15_CHARGE_CONTROL1, &val);
+ charger->chgend = ((val >> 4)& 0x01)? 15 : 10;
+ */
+ charger->chgend = 10;
+ return sprintf(buf, "%d\n",charger->chgend);
+}
+
+static ssize_t chgendcur_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var == 10 ){
+ charger->chgend = var;
+ //axp_clr_bits(charger->master ,AXP15_CHARGE_CONTROL1,0x10);
+ }
+ else if (var == 15){
+ charger->chgend = var;
+ // axp_set_bits(charger->master ,AXP15_CHARGE_CONTROL1,0x10);
+
+ }
+ return count;
+}
+
+static ssize_t chgpretimemin_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ /* uint8_t val;
+ axp_read(charger->master,AXP15_CHARGE_CONTROL2, &val);
+ charger->chgpretime = (val >> 6) * 10 +40;
+ */
+ charger->chgpretime = 40;
+ return sprintf(buf, "%d\n",charger->chgpretime);
+}
+
+static ssize_t chgpretimemin_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ uint8_t tmp,val;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var >= 40 && var <= 70){
+ tmp = (var - 40)/10;
+ charger->chgpretime = tmp * 10 + 40;
+ //axp_read(charger->master,AXP15_CHARGE_CONTROL2,&val);
+ val &= 0x3F;
+ val |= (tmp << 6);
+ //axp_write(charger->master,AXP15_CHARGE_CONTROL2,val);
+ }
+ return count;
+}
+
+static ssize_t chgcsttimemin_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ //uint8_t val;
+ //axp_read(charger->master,AXP15_CHARGE_CONTROL2, &val);
+ //charger->chgcsttime = (val & 0x03) *120 + 360;
+ charger->chgcsttime = 360;
+ return sprintf(buf, "%d\n",charger->chgcsttime);
+}
+
+static ssize_t chgcsttimemin_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ uint8_t tmp,val;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var >= 360 && var <= 720){
+ tmp = (var - 360)/120;
+ charger->chgcsttime = tmp * 120 + 360;
+ //axp_read(charger->master,AXP15_CHARGE_CONTROL2,&val);
+ val &= 0xFC;
+ val |= tmp;
+ //axp_write(charger->master,AXP15_CHARGE_CONTROL2,val);
+ }
+ return count;
+}
+
+static ssize_t adcfreq_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ /*uint8_t val;
+ axp_read(charger->master, AXP15_ADC_CONTROL3, &val);
+ switch ((val >> 6) & 0x03){
+ case 0: charger->sample_time = 25;break;
+ case 1: charger->sample_time = 50;break;
+ case 2: charger->sample_time = 100;break;
+ case 3: charger->sample_time = 200;break;
+ default:break;
+ }
+ */
+ charger->sample_time = 25;
+ return sprintf(buf, "%d\n",charger->sample_time);
+}
+
+static ssize_t adcfreq_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ uint8_t val;
+ var = simple_strtoul(buf, NULL, 10);
+ //axp_read(charger->master, AXP15_ADC_CONTROL3, &val);
+ switch (var/25){
+ case 1: val &= ~(3 << 6);charger->sample_time = 25;break;
+ case 2: val &= ~(3 << 6);val |= 1 << 6;charger->sample_time = 50;break;
+ case 4: val &= ~(3 << 6);val |= 2 << 6;charger->sample_time = 100;break;
+ case 8: val |= 3 << 6;charger->sample_time = 200;break;
+ default: break;
+ }
+ //axp_write(charger->master, AXP15_ADC_CONTROL3, val);
+ return count;
+}
+
+
+static ssize_t vholden_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ uint8_t val;
+ //axp_read(charger->master,AXP15_CHARGE_VBUS, &val);
+ //val = (val>>6) & 0x01;
+ val = 0x01;
+ return sprintf(buf, "%d\n",val);
+}
+
+static ssize_t vholden_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ var = simple_strtoul(buf, NULL, 10);
+/*
+ if(var)
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ else
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ */
+
+ return count;
+}
+
+static ssize_t vhold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ uint8_t val;
+ int vhold;
+ //axp_read(charger->master,AXP15_CHARGE_VBUS, &val);
+ //vhold = ((val >> 3) & 0x07) * 100000 + 4000000;
+ vhold = 4000000;
+ return sprintf(buf, "%d\n",vhold);
+}
+
+static ssize_t vhold_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ uint8_t val,tmp;
+ var = simple_strtoul(buf, NULL, 10);
+ if(var >= 4000000 && var <=4700000){
+ tmp = (var - 4000000)/100000;
+ //printk("tmp = 0x%x\n",tmp);
+ //axp_read(charger->master, AXP15_CHARGE_VBUS,&val);
+ val &= 0xC7;
+ val |= tmp << 3;
+ //printk("val = 0x%x\n",val);
+ //axp_write(charger->master, AXP15_CHARGE_VBUS,val);
+ }
+ return count;
+}
+
+static ssize_t iholden_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ uint8_t val = 1;
+ //axp_read(charger->master,AXP15_CHARGE_VBUS, &val);
+ return sprintf(buf, "%d\n",((val & 0x03) == 0x03)?0:1);
+}
+
+static ssize_t iholden_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ var = simple_strtoul(buf, NULL, 10);
+ /*
+ if(var)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ else
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+*/
+ return count;
+}
+
+static ssize_t ihold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ uint8_t val,tmp;
+ int ihold;
+ /*
+ axp_read(charger->master,AXP15_CHARGE_VBUS, &val);
+ tmp = (val) & 0x03;
+ switch(tmp){
+ case 0: ihold = 900000;break;
+ case 1: ihold = 500000;break;
+ case 2: ihold = 100000;break;
+ default: ihold = 0;break;
+ }
+ */
+ ihold = 900000;
+ return sprintf(buf, "%d\n",ihold);
+}
+
+static ssize_t ihold_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct axp_charger *charger = dev_get_drvdata(dev);
+ int var;
+ var = simple_strtoul(buf, NULL, 10);
+ /*
+ if(var == 900000)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ else if (var == 500000){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ }
+ else if (var == 100000){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ }
+*/
+ return count;
+}
+
+static struct device_attribute axp_charger_attrs[] = {
+ AXP_CHG_ATTR(chgen),
+ AXP_CHG_ATTR(chgmicrovol),
+ AXP_CHG_ATTR(chgintmicrocur),
+ AXP_CHG_ATTR(chgendcur),
+ AXP_CHG_ATTR(chgpretimemin),
+ AXP_CHG_ATTR(chgcsttimemin),
+ AXP_CHG_ATTR(adcfreq),
+ AXP_CHG_ATTR(vholden),
+ AXP_CHG_ATTR(vhold),
+ AXP_CHG_ATTR(iholden),
+ AXP_CHG_ATTR(ihold),
+};
+
+#if defined CONFIG_HAS_EARLYSUSPEND
+static void axp_earlysuspend(struct early_suspend *h)
+{
+ uint8_t tmp;
+ DBG_PSY_MSG("======early suspend=======\n");
+
+#if defined (CONFIG_AXP_CHGCHANGE)
+ early_suspend_flag = 1;
+/* if(pmu_earlysuspend_chgcur == 0)
+ axp_clr_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ else
+ axp_set_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+
+ if(pmu_earlysuspend_chgcur >= 300000 && pmu_earlysuspend_chgcur <= 1800000){
+ tmp = (pmu_earlysuspend_chgcur -200001)/100000;
+ axp_update(axp_charger->master, AXP15_CHARGE_CONTROL1, tmp,0x0F);
+ }
+*/
+
+#endif
+
+}
+static void axp_lateresume(struct early_suspend *h)
+{
+ uint8_t tmp;
+ DBG_PSY_MSG("======late resume=======\n");
+
+#if defined (CONFIG_AXP_CHGCHANGE)
+ early_suspend_flag = 0;
+/*
+ if(pmu_resume_chgcur == 0)
+ axp_clr_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ else
+ axp_set_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+
+ if(pmu_resume_chgcur >= 300000 && pmu_resume_chgcur <= 1800000){
+ tmp = (pmu_resume_chgcur -200001)/100000;
+ axp_update(axp_charger->master, AXP15_CHARGE_CONTROL1, tmp,0x0F);
+ }
+*/
+#endif
+
+}
+#endif
+
+int axp_charger_create_attrs(struct power_supply *psy)
+{
+ int j,ret;
+ for (j = 0; j < ARRAY_SIZE(axp_charger_attrs); j++) {
+ ret = device_create_file(psy->dev,
+ &axp_charger_attrs[j]);
+ if (ret)
+ goto sysfs_failed;
+ }
+ goto succeed;
+
+sysfs_failed:
+ while (j--)
+ device_remove_file(psy->dev,
+ &axp_charger_attrs[j]);
+succeed:
+ return ret;
+}
+
+int Get_Bat_Coulomb_Count(struct axp_charger *charger)
+{
+/*
+ uint8_t temp[8];
+ int64_t rValue1,rValue2,rValue;
+ int Cur_CoulombCounter_tmp,m;
+
+ axp_reads(charger->master, AXP15_CCHAR3_RES,8,temp);
+ rValue1 = ((temp[0] << 24) + (temp[1] << 16) + (temp[2] << 8) + temp[3]);
+ rValue2 = ((temp[4] << 24) + (temp[5] << 16) + (temp[6] << 8) + temp[7]);
+ if(axp_debug){
+ DBG_PSY_MSG("%s->%d - CHARGINGOULB:[0]=0x%x,[1]=0x%x,[2]=0x%x,[3]=0x%x\n",__FUNCTION__,__LINE__,temp[0],temp[1],temp[2],temp[3]);
+ DBG_PSY_MSG("%s->%d - DISCHARGINGCLOUB:[4]=0x%x,[5]=0x%x,[6]=0x%x,[7]=0x%x\n",__FUNCTION__,__LINE__,temp[4],temp[5],temp[6],temp[7]);
+ }
+ rValue = (ABS(rValue1 - rValue2)) * 4369;
+ m = ADC_Freq_Get(charger) * 480;
+ do_div(rValue,m);
+ if(rValue1 >= rValue2)
+ Cur_CoulombCounter_tmp = (int)rValue;
+ else
+ Cur_CoulombCounter_tmp = (int)(0 - rValue);
+ if(axp_debug){
+ DBG_PSY_MSG("Cur_CoulombCounter_tmp = %d\n",Cur_CoulombCounter_tmp);
+ }
+ */
+ return 1000; //unit mAh
+}
+
+static void axp_usb(struct work_struct *work)
+{
+/*
+ int var;
+ uint8_t tmp,val;
+ struct axp_charger *charger;
+
+ charger = axp_charger;
+
+ if(axp_usbcurflag){
+ printk("set usbcur %d mA\n",pmu_usbcurnew);
+ if(pmu_usbcurnew){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ var = pmu_usbcurnew * 1000;
+ if(var >= 900000)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ else if ((var >= 500000)&& (var < 900000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ }
+ else if ((var >= 100000)&& (var < 500000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ }
+ else{
+ printk("set usb limit current error,%d mA\n",pmu_usbcurnew);
+ }
+ }
+ else
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ }else {
+ printk("set usbcur %d mA\n",pmu_usbcur);
+ if((pmu_usbcur) && (pmu_usbcur_limit)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ var = pmu_usbcur * 1000;
+ if(var >= 900000)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ else if ((var >= 500000)&& (var < 900000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ }
+ else if ((var >= 100000)&& (var < 500000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ }
+ else
+ printk("set usb limit current error,%d mA\n",pmu_usbcur);
+ }
+ else
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ }
+
+ if(axp_usbvolflag){
+ printk("set usbvol %d mV\n",pmu_usbvolnew);
+ if(pmu_usbvolnew){
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ var = pmu_usbvolnew * 1000;
+ if(var >= 4000000 && var <=4700000){
+ tmp = (var - 4000000)/100000;
+ axp_read(charger->master, AXP15_CHARGE_VBUS,&val);
+ val &= 0xC7;
+ val |= tmp << 3;
+ axp_write(charger->master, AXP15_CHARGE_VBUS,val);
+ }
+ else
+ printk("set usb limit voltage error,%d mV\n",pmu_usbvolnew);
+ }
+ else
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ }else {
+ printk("set usbvol %d mV\n",pmu_usbvol);
+ if((pmu_usbvol) && (pmu_usbvol_limit)){
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ var = pmu_usbvol * 1000;
+ if(var >= 4000000 && var <=4700000){
+ tmp = (var - 4000000)/100000;
+ axp_read(charger->master, AXP15_CHARGE_VBUS,&val);
+ val &= 0xC7;
+ val |= tmp << 3;
+ axp_write(charger->master, AXP15_CHARGE_VBUS,val);
+ }
+ else
+ printk("set usb limit voltage error,%d mV\n",pmu_usbvol);
+ }
+ else
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ }
+*/
+}
+
+static void axp_charging_monitor(struct work_struct *work)
+{
+ struct axp_charger *charger;
+
+ uint8_t val;
+ uint8_t v[5];
+ int pre_rest_vol;
+ int rdc,k,i;
+ int rt_rest_vol;
+ int rest_vol;
+ uint16_t tmp;
+ int Cur_CoulombCounter;
+ int cap_index_p = 0;
+ int gpio_adp_val,ret;
+ /*
+
+ charger = container_of(work, struct axp_charger, work.work);
+
+ Cur_CoulombCounter = ABS(Get_Bat_Coulomb_Count(charger));
+ if(axp_debug){
+ DBG_PSY_MSG("Cur_CoulombCounter = %d\n",Cur_CoulombCounter);
+ }
+ axp_reads(charger->master,0xbc,2,v);
+ charger->ocv = ((v[0] << 4) + (v[1] & 0x0f)) * 11 /10 ;
+ axp_reads(charger->master,AXP15_IC_TYPE,2,v);
+ //DBG_PSY_MSG("v[0] = 0x%x,v[1] = 0x%x\n",v[0],v[1]);
+ pre_rest_vol = charger->rest_vol;
+ axp_charger_update_state(charger);
+ axp_charger_update(charger);
+
+ if(charger->is_on && axp15_icharge_to_mA(charger->adc->ichar_res) > 200 && charger->vbat > 3600 && charger->disvbat != 0){
+ if((((v[1] >> 7) == 0) || (((v[1] >> 3) & 0x1) == 0)) && count_rdc >= 3){
+ axp_set_bits(charger->master,AXP15_CAP,0x80);
+ axp_clr_bits(charger->master,0xBA,0x80);
+ rdc = (axp_get_rdc(charger) * 10000 + 5371) / 10742;
+ tmp = (uint16_t) rdc;
+ axp_write(charger->master,0xBB,tmp & 0x00FF);
+ axp_update(charger->master, 0xBA, (tmp >> 8), 0x1F);
+ axp_clr_bits(charger->master,AXP15_CAP,0x80);
+ axp_set_bits(charger->master,0x04,0x80);
+ if(axp_debug){
+ DBG_PSY_MSG("==============================rdc = %d\n",rdc * 10742 / 10000);
+ }
+ count_rdc = 0;
+ }
+ else if((((v[1] >> 7) == 0) || (((v[1] >> 3) & 0x1) == 0)) && count_rdc < 3){
+ count_rdc ++;
+ }
+ else{
+ count_rdc = 0;
+ }
+ }
+ else{
+ count_rdc = 0;
+ }
+
+ if(flag_state_change){
+ rt_rest_vol = charger->rest_vol;
+ rest_vol = charger->rest_vol;
+ flag_state_change = 0;
+ }
+ else{
+ axp_read(charger->master, AXP15_CAP,&val);
+ rt_rest_vol = (int) (val & 0x7F);
+ if((charger->bat_det == 0) || (rt_rest_vol == 127) ){
+ rt_rest_vol = 100;
+ }
+
+ Total_Cap -= Bat_Cap_Buffer[Cap_Index];
+ if(Cap_Index == 0){
+ cap_index_p = AXP15_VOL_MAX - 1;
+ }
+ else{
+ cap_index_p = Cap_Index - 1;
+ }
+ if(ABS(rt_rest_vol - Bat_Cap_Buffer[cap_index_p]) > 5){
+ if(axp_debug){
+ DBG_PSY_MSG("-----------correct rdc-----------\n");
+ }
+ axp_clr_bits(charger->master,0x04,0x08);
+ }
+
+ Bat_Cap_Buffer[Cap_Index] = rt_rest_vol;
+ Total_Cap += Bat_Cap_Buffer[Cap_Index];
+ Cap_Index++;
+ if(Cap_Index == AXP15_VOL_MAX){
+ Cap_Index = 0;
+ }
+
+ rest_vol = (Total_Cap + AXP15_VOL_MAX / 2 ) / AXP15_VOL_MAX;
+ if(axp_debug){
+ DBG_PSY_MSG("Before Modify:Cap_Index = %d,val = 0x%x,pre_rest_vol = %d,rest_vol = %d\n",Cap_Index,val,pre_rest_vol,rest_vol);
+ }
+
+ if(charger->is_on && (rest_vol < pre_rest_vol)){
+ rest_vol = pre_rest_vol;
+ }
+ else if(!charger->ext_valid && (rest_vol > pre_rest_vol)){
+ rest_vol = pre_rest_vol;
+ }
+ if(axp_debug){
+ DBG_PSY_MSG("After Modify:val = 0x%x,pre_rest_vol = %d,rest_vol = %d\n",val,pre_rest_vol,rest_vol);
+ }
+ // full
+ if(charger->ocv >= 4100 && !charger->is_on && charger->ext_valid && charger->charge_on){
+ rest_vol = 100;
+ for(k = 0;k < AXP15_VOL_MAX; k++){
+ Bat_Cap_Buffer[k] = rest_vol;
+ }
+ Total_Cap = rest_vol * AXP15_VOL_MAX;
+ charger->bat_current_direction = 1;
+// if(charger->rest_vol < 100)
+// axp_set_bits(charger->master,0x32,0x38);
+ }
+
+ // charging
+ if(charger->is_on && rest_vol == 100){
+ rest_vol = 99;
+ }
+
+
+ if(rest_vol > pre_rest_vol){
+ if(counter >= 3){
+ charger->rest_vol ++;
+ counter = 0;
+ } else
+ counter ++;
+ } else if(rest_vol < pre_rest_vol){
+ if(counter >= 3){
+ charger->rest_vol --;
+ counter = 0;
+ } else
+ counter ++;
+ } else
+ counter = 0;
+ }
+
+ if((count_dis >= 8) && (charger->disvbat != 0)){
+ charger->disvbat = 0;
+ charger->disibat = 0;
+ count_dis = 0;
+ }
+ if(charger->bat_current_direction == 1){
+ count_dis++;
+ } else
+ count_dis = 0;
+
+ if(axp_debug){
+#if DBG_AXP_PSY
+ for(i = 0; i < AXP15_VOL_MAX; i ++){
+ DBG_PSY_MSG("Bat_Cap_Buffer[%d] = %d,Cap_Index = %d,cap_index_p = %d\n",i,Bat_Cap_Buffer[i],Cap_Index-1,cap_index_p);
+ }
+ DBG_PSY_MSG("charger->ic_temp = %d\n",charger->ic_temp);
+ DBG_PSY_MSG("charger->vbat = %d\n",charger->vbat);
+ DBG_PSY_MSG("charger->ibat = %d\n",charger->ibat);
+ DBG_PSY_MSG("charger->vusb = %d\n",charger->vusb);
+ DBG_PSY_MSG("charger->iusb = %d\n",charger->iusb);
+ DBG_PSY_MSG("charger->vac = %d\n",charger->vac);
+ DBG_PSY_MSG("charger->iac = %d\n",charger->iac);
+ DBG_PSY_MSG("charger->ocv = %d\n",charger->ocv);
+ DBG_PSY_MSG("charger->disvbat = %d\n",charger->disvbat);
+ DBG_PSY_MSG("charger->disibat = %d\n",charger->disibat);
+ DBG_PSY_MSG("rt_rest_vol = %d\n",rt_rest_vol);
+ DBG_PSY_MSG("rest_vol = %d\n",rest_vol);
+ DBG_PSY_MSG("charger->rest_vol = %d\n",charger->rest_vol);
+ //axp_reads(charger->master,0xba,2,v);
+ //rdc = (((v[0] & 0x1F) << 8) | v[1]) * 10742 / 10000;
+ DBG_PSY_MSG("rdc = %d\n",rdc);
+ DBG_PSY_MSG("charger->is_on = %d\n",charger->is_on);
+ DBG_PSY_MSG("charger->charge_on = %d\n",charger->charge_on);
+ DBG_PSY_MSG("charger->ext_valid = %d\n",charger->ext_valid);
+ //DBG_PSY_MSG("count_dis = %d\n",count_dis);
+ //DBG_PSY_MSG("count_rdc = %d\n",count_rdc);
+#endif
+ }
+*//*
+#if defined (CONFIG_AXP_CHGCHANGE)
+ if(pmu_used2){
+ gpio_adp_val = gpio_read_one_pin_value(gpio_adp_hdle,"pmu_adpdet");
+ DBG_PSY_MSG("GPIO->H2 = %d\n",gpio_adp_val);
+ if(!gpio_adp_val){
+ ret = script_parser_fetch("pmu_para", "pmu_init_chgcur2", &pmu_init_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chgcur = INTCHGCUR / 1000;
+ }
+ pmu_init_chgcur = pmu_init_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_earlysuspend_chgcur2", &pmu_earlysuspend_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_earlysuspend_chgcur = SUSCHGCUR / 1000;
+ }
+ pmu_earlysuspend_chgcur = pmu_earlysuspend_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_suspend_chgcur2", &pmu_suspend_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_suspend_chgcur = SUSCHGCUR / 1000;
+ }
+ pmu_suspend_chgcur = pmu_suspend_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_resume_chgcur2", &pmu_resume_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_resume_chgcur = RESCHGCUR / 1000;
+ }
+ pmu_resume_chgcur = pmu_resume_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_shutdown_chgcur2", &pmu_shutdown_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_shutdown_chgcur = CLSCHGCUR / 1000;
+ }
+ pmu_shutdown_chgcur = pmu_shutdown_chgcur * 1000;
+ }
+ else{
+ ret = script_parser_fetch("pmu_para", "pmu_init_chgcur", &pmu_init_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_init_chgcur = INTCHGCUR / 1000;
+ }
+ pmu_init_chgcur = pmu_init_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_earlysuspend_chgcur", &pmu_earlysuspend_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_earlysuspend_chgcur = SUSCHGCUR / 1000;
+ }
+ pmu_earlysuspend_chgcur = pmu_earlysuspend_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_suspend_chgcur", &pmu_suspend_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_suspend_chgcur = SUSCHGCUR / 1000;
+ }
+ pmu_suspend_chgcur = pmu_suspend_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_resume_chgcur", &pmu_resume_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_resume_chgcur = RESCHGCUR / 1000;
+ }
+ pmu_resume_chgcur = pmu_resume_chgcur * 1000;
+ ret = script_parser_fetch("pmu_para", "pmu_shutdown_chgcur", &pmu_shutdown_chgcur, sizeof(int));
+ if (ret){
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_shutdown_chgcur = CLSCHGCUR / 1000;
+ }
+ pmu_shutdown_chgcur = pmu_shutdown_chgcur * 1000;
+ }
+
+
+#if defined CONFIG_HAS_EARLYSUSPEND
+ if(early_suspend_flag){
+ if(pmu_earlysuspend_chgcur == 0){
+ axp_clr_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ }
+ else if(pmu_earlysuspend_chgcur >= 300000 && pmu_init_chgcur <= 1800000){
+ axp_set_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ tmp = (pmu_earlysuspend_chgcur -150001)/100000;
+ charger->chgcur = tmp *100000 + 300000;
+ axp_update(charger->master, AXP15_CHARGE_CONTROL1, tmp, 0x0F);
+ }
+ }else
+#endif
+ {
+ if(pmu_init_chgcur == 0){
+ axp_clr_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ }
+ else if (pmu_init_chgcur >= 300000 && pmu_init_chgcur <= 1800000){
+ axp_set_bits(axp_charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ tmp = (pmu_init_chgcur -150001)/100000;
+ charger->chgcur = tmp *100000 + 300000;
+ axp_update(charger->master, AXP15_CHARGE_CONTROL1, tmp, 0x0F);
+ }
+ }
+
+ }
+#endif
+ if(axp_debug){
+ DBG_PSY_MSG("pmu_init_chgcur = %d\n",pmu_init_chgcur);
+ DBG_PSY_MSG("pmu_earlysuspend_chgcur = %d\n",pmu_earlysuspend_chgcur);
+ DBG_PSY_MSG("pmu_suspend_chgcur = %d\n",pmu_suspend_chgcur);
+ DBG_PSY_MSG("pmu_resume_chgcur = %d\n",pmu_resume_chgcur);
+ DBG_PSY_MSG("pmu_shutdown_chgcur = %d\n",pmu_shutdown_chgcur);
+ }*/
+ /* if battery volume changed, inform uevent
+ if(charger->rest_vol - pre_rest_vol){
+ printk("battery vol change: %d->%d \n", pre_rest_vol, charger->rest_vol);
+ pre_rest_vol = charger->rest_vol;
+ axp_write(charger->master,AXP15_DATA_BUFFER1,charger->rest_vol | 0x80);
+ if(charger->rest_vol == 100){
+ axp_clr_bits(charger->master,0x32,0x38);
+ }*/
+ charger->rest_vol = 100;
+ power_supply_changed(&charger->batt);
+ //}
+
+ /* reschedule for the next time */
+ schedule_delayed_work(&charger->work, charger->interval);
+}
+
+static int axp_battery_probe(struct platform_device *pdev)
+{
+ struct axp_charger *charger;
+ struct axp_supply_init_data *pdata = pdev->dev.platform_data;
+ int ret,k,var;
+ uint8_t val1,val2,tmp,val;
+ uint8_t ocv_cap[31],v[2];
+ int Cur_CoulombCounter,rdc;
+
+
+
+ powerkeydev = input_allocate_device();
+ if (!powerkeydev) {
+ kfree(powerkeydev);
+ return -ENODEV;
+ }
+
+ powerkeydev->name = pdev->name;
+ powerkeydev->phys = "m1kbd/input2";
+ powerkeydev->id.bustype = BUS_HOST;
+ powerkeydev->id.vendor = 0x0001;
+ powerkeydev->id.product = 0x0001;
+ powerkeydev->id.version = 0x0100;
+ powerkeydev->open = NULL;
+ powerkeydev->close = NULL;
+ powerkeydev->dev.parent = &pdev->dev;
+
+ set_bit(EV_KEY, powerkeydev->evbit);
+ set_bit(EV_REL, powerkeydev->evbit);
+ //set_bit(EV_REP, powerkeydev->evbit);
+ set_bit(KEY_POWER, powerkeydev->keybit);
+
+ ret = input_register_device(powerkeydev);
+ if(ret) {
+ printk("Unable to Register the power key\n");
+ }
+
+ if (pdata == NULL)
+ return -EINVAL;
+
+ if (pdata->chgcur > 1800000 ||
+ pdata->chgvol < 4100000 ||
+ pdata->chgvol > 4360000){
+ printk("charger milliamp is too high or target voltage is over range\n");
+ return -EINVAL;
+ }
+
+ if (pdata->chgpretime < 40 || pdata->chgpretime >70 ||
+ pdata->chgcsttime < 360 || pdata->chgcsttime > 720){
+ printk("prechaging time or constant current charging time is over range\n");
+ return -EINVAL;
+ }
+
+ charger = kzalloc(sizeof(*charger), GFP_KERNEL);
+ if (charger == NULL)
+ return -ENOMEM;
+
+ charger->master = pdev->dev.parent;
+
+ charger->chgcur = pdata->chgcur;
+ charger->chgvol = pdata->chgvol;
+ charger->chgend = pdata->chgend;
+ charger->sample_time = pdata->sample_time;
+ charger->chgen = pdata->chgen;
+ charger->chgpretime = pdata->chgpretime;
+ charger->chgcsttime = pdata->chgcsttime;
+ charger->battery_info = pdata->battery_info;
+ charger->disvbat = 0;
+ charger->disibat = 0;
+
+ ret = axp_battery_first_init(charger);
+ if (ret)
+ goto err_charger_init;
+
+ charger->nb.notifier_call = axp_battery_event;
+ ret = axp_register_notifier(charger->master, &charger->nb, AXP15_NOTIFIER_ON);
+ if (ret)
+ goto err_notifier;
+
+ axp_battery_setup_psy(charger);
+ ret = power_supply_register(&pdev->dev, &charger->batt);
+ if (ret)
+ goto err_ps_register;
+
+ //axp_read(charger->master,AXP15_CHARGE_STATUS,&val);
+ //if(!((val >> 1) & 0x01)){
+ ret = power_supply_register(&pdev->dev, &charger->ac);
+ if (ret){
+ power_supply_unregister(&charger->batt);
+ goto err_ps_register;
+ }
+ //}
+ ret = power_supply_register(&pdev->dev, &charger->usb);
+ if (ret){
+ power_supply_unregister(&charger->ac);
+ power_supply_unregister(&charger->batt);
+ goto err_ps_register;
+ }
+
+ ret = axp_charger_create_attrs(&charger->batt);
+ if(ret){
+ return ret;
+ }
+
+
+ platform_set_drvdata(pdev, charger);
+
+#if defined (CONFIG_AXP_CHGCHANGE)
+ if(pmu_used2){
+ gpio_adp_hdle = gpio_request_ex("pmu_para", "pmu_adpdet");
+ if (!gpio_adp_hdle)
+ {
+ DBG_PSY_MSG("get adapter parameter failed\n");
+ }
+ }
+#endif
+
+ axp_charger = charger;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ axp_early_suspend.suspend = axp_earlysuspend;
+ axp_early_suspend.resume = axp_lateresume;
+ axp_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 2;
+ register_early_suspend(&axp_early_suspend);
+#endif
+
+ /* ���Խӿ�ע�� */
+ class_register(&axppower_class);
+
+ return ret;
+
+ err_ps_register:
+ axp_unregister_notifier(charger->master, &charger->nb, AXP15_NOTIFIER_ON);
+
+ err_notifier:
+ cancel_delayed_work_sync(&charger->work);
+
+ err_charger_init:
+ kfree(charger);
+ input_unregister_device(powerkeydev);
+ kfree(powerkeydev);
+
+ return ret;
+}
+
+ /* initial restvol*/
+
+/* usb current and voltage limit
+ if((pmu_usbvol) && (pmu_usbvol_limit)){
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ var = pmu_usbvol * 1000;
+ if(var >= 4000000 && var <=4700000){
+ tmp = (var - 4000000)/100000;
+ axp_read(charger->master, AXP15_CHARGE_VBUS,&val);
+ val &= 0xC7;
+ val |= tmp << 3;
+ axp_write(charger->master, AXP15_CHARGE_VBUS,val);
+ }
+ }
+ else
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+
+ if((pmu_usbcur) && (pmu_usbcur_limit)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ var = pmu_usbcur * 1000;
+ if(var >= 900000)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ else if ((var >= 500000)&& (var < 900000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ }
+ else if ((var >= 100000)&& (var < 500000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ }
+ }
+ else
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+*/
+
+
+ /* set lowe power warning/shutdown voltage
+ var = script_parser_fetch("pmu_para", "pmu_suspendpwroff_vol", &pmu_suspendpwroff_vol, sizeof(int));
+ if (var)
+ {
+ printk("[AXP]axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_suspendpwroff_vol = 3500;
+ printk("[AXP]pmu_suspendpwroff_vol = %d\n",pmu_suspendpwroff_vol);
+ }
+ pmu_suspendpwroff_vol = pmu_suspendpwroff_vol * 1000;
+
+ if(pmu_suspendpwroff_vol >= 2867200 && pmu_suspendpwroff_vol <= 4200000){
+ val = (pmu_suspendpwroff_vol - 2867200) / 5600;
+ }*/
+
+ /* 3.5552V--%5 close
+ axp_write(charger->master, AXP15_APS_WARNING1,val);
+ axp_write(charger->master, AXP15_APS_WARNING2,(val - 0x0a));
+
+ ocv_cap[0] = pmu_bat_para1;
+ ocv_cap[1] = 0xC1;
+ ocv_cap[2] = pmu_bat_para2;
+ ocv_cap[3] = 0xC2;
+ ocv_cap[4] = pmu_bat_para3;
+ ocv_cap[5] = 0xC3;
+ ocv_cap[6] = pmu_bat_para4;
+ ocv_cap[7] = 0xC4;
+ ocv_cap[8] = pmu_bat_para5;
+ ocv_cap[9] = 0xC5;
+ ocv_cap[10] = pmu_bat_para6;
+ ocv_cap[11] = 0xC6;
+ ocv_cap[12] = pmu_bat_para7;
+ ocv_cap[13] = 0xC7;
+ ocv_cap[14] = pmu_bat_para8;
+ ocv_cap[15] = 0xC8;
+ ocv_cap[16] = pmu_bat_para9;
+ ocv_cap[17] = 0xC9;
+ ocv_cap[18] = pmu_bat_para10;
+ ocv_cap[19] = 0xCA;
+ ocv_cap[20] = pmu_bat_para11;
+ ocv_cap[21] = 0xCB;
+ ocv_cap[22] = pmu_bat_para12;
+ ocv_cap[23] = 0xCC;
+ ocv_cap[24] = pmu_bat_para13;
+ ocv_cap[25] = 0xCD;
+ ocv_cap[26] = pmu_bat_para14;
+ ocv_cap[27] = 0xCE;
+ ocv_cap[28] = pmu_bat_para15;
+ ocv_cap[29] = 0xCF;
+ ocv_cap[30] = pmu_bat_para16;
+ axp_writes(charger->master, 0xC0,31,ocv_cap);*/
+
+ /* open/close set
+ printk("pmu_pekoff_time = %d\n",pmu_pekoff_time);
+ printk("pmu_pekoff_en = %d\n",pmu_pekoff_en);
+ printk("pmu_peklong_time = %d\n",pmu_peklong_time);
+ printk("pmu_pekon_time = %d\n",pmu_pekon_time);
+ printk("pmu_pwrok_time = %d\n",pmu_pwrok_time);
+ printk("pmu_pwrnoe_time = %d\n",pmu_pwrnoe_time);
+ printk("pmu_intotp_en = %d\n",pmu_intotp_en);*/
+
+ /* //n_oe delay time set
+ if (pmu_pwrnoe_time < 1000)
+ pmu_pwrnoe_time = 128;
+ if (pmu_pwrnoe_time > 3000)
+ pmu_pwrnoe_time = 3000;
+ axp_read(charger->master,POWER15_OFF_CTL,&val);
+ val &= 0xfc;
+ val |= ((pmu_pwrnoe_time) / 1000);
+ axp_write(charger->master,POWER15_OFF_CTL,val);
+ DBG_PSY_MSG("%d-->0x%x\n",__LINE__,val);
+
+ // pek open time set
+ axp_read(charger->master,POWER15_PEK_SET,&val);
+ if (pmu_pekon_time < 1000)
+ val &= 0x3f;
+ else if(pmu_pekon_time < 2000){
+ val &= 0x3f;
+ val |= 0x80;
+ }
+ else if(pmu_pekon_time < 3000){
+ val &= 0x3f;
+ val |= 0xc0;
+ }
+ else {
+ val &= 0x3f;
+ val |= 0x40;
+ }
+ axp_write(charger->master,POWER15_PEK_SET,val);
+ printk("POWER15_PEK_SET:%d-->0x%x\n",__LINE__,val);
+
+ // pek long time set
+ if(pmu_peklong_time < 1000)
+ pmu_peklong_time = 1000;
+ if(pmu_peklong_time > 2500)
+ pmu_peklong_time = 2500;
+ axp_read(charger->master,POWER15_PEK_SET,&val);
+ val &= 0xcf;
+ val |= (((pmu_peklong_time - 1000) / 500) << 4);
+ axp_write(charger->master,POWER15_PEK_SET,val);
+ printk("POWER15_PEK_SET:%d-->0x%x\n",__LINE__,val);
+
+ // pek en set
+ if(pmu_pekoff_en)
+ pmu_pekoff_en = 1;
+ axp_read(charger->master,POWER15_PEK_SET,&val);
+ val &= 0xf7;
+ val |= (pmu_pekoff_en << 3);
+ axp_write(charger->master,POWER15_PEK_SET,val);
+ printk("POWER15_PEK_SET:%d-->0x%x\n",__LINE__,val);
+
+ // pek delay set
+ if(pmu_pwrok_time <= 8)
+ pmu_pwrok_time = 0;
+ else
+ pmu_pwrok_time = 1;
+ axp_read(charger->master,POWER15_PEK_SET,&val);
+ val &= 0xfb;
+ val |= pmu_pwrok_time << 2;
+ axp_write(charger->master,POWER15_PEK_SET,val);
+ printk("POWER15_PEK_SET:%d-->0x%x\n",__LINE__,val);
+
+ // pek off time set
+ if(pmu_pekoff_time < 4000)
+ pmu_pekoff_time = 4000;
+ if(pmu_pekoff_time > 10000)
+ pmu_pekoff_time =10000;
+ pmu_pekoff_time = (pmu_pekoff_time - 4000) / 2000 ;
+ axp_read(charger->master,POWER15_PEK_SET,&val);
+ val &= 0xfc;
+ val |= pmu_pekoff_time ;
+ axp_write(charger->master,POWER15_PEK_SET,val);
+ printk("POWER15_PEK_SET:%d-->0x%x\n",__LINE__,val);
+
+ // enable overtemperture off
+ if(pmu_intotp_en)
+ pmu_intotp_en = 1;
+ axp_read(charger->master,POWER15_HOTOVER_CTL,&val);
+ val &= 0xfb;
+ val |= pmu_intotp_en << 2;
+ axp_write(charger->master,POWER15_HOTOVER_CTL,val);
+ printk("POWER15_HOTOVER_CTL:%d-->0x%x\n",__LINE__,val);
+
+ // disable
+ axp_set_bits(charger->master,AXP15_CAP,0x80);
+ axp_clr_bits(charger->master,0xBA,0x80);
+ axp_reads(charger->master,0xbA,2,v);
+ rdc = (((v[0] & 0x1F) << 8) | v[1]) * 10742 / 10000;
+ axp_read(charger->master,AXP15_DATA_BUFFER0,&val1);
+ if((((val1 >> 7) & 0x1) == 0)||(rdc > pmu_battery_rdc * 2)){
+ rdc = (pmu_battery_rdc * 10000 + 5371) / 10742;
+ axp_write(charger->master,0xBB,rdc & 0x00FF);
+ axp_update(charger->master, 0xBA, (rdc >> 8), 0x1F);
+ }
+ axp_clr_bits(charger->master,AXP15_CAP,0x80);
+
+ axp_set_bits(charger->master,0x8F,0x88);
+ axp_clr_bits(charger->master,0x81,0x04);
+
+ axp_charger_update_state(charger);
+ axp_charger_update(charger);
+
+ axp_read(charger->master,AXP15_DATA_BUFFER1,&val1);
+ charger->rest_vol = (int) (val1 & 0x7F);
+
+ axp_read(charger->master, AXP15_CAP,&val2);
+
+ Cur_CoulombCounter = ABS(Get_Bat_Coulomb_Count(charger));
+ printk("Cur_CoulombCounter = %d\n",Cur_CoulombCounter);
+ //if(ABS(charger->rest_vol-(val2 & 0x7F)) >= 3 && (val1 >> 7)){
+ if((!(val1 >> 7))|| ABS(charger->rest_vol-(val2 & 0x7F)) >= 10 || Cur_CoulombCounter > 20){
+ charger->rest_vol = (val2 & 0x7F)? (val2 & 0x7F): 1;
+ }
+ if((charger->bat_det == 0) || (charger->rest_vol == 127)){
+ charger->rest_vol = 100;
+ }
+ if(((charger->vbat) >= 4100) && !charger->is_on && charger->ext_valid && charger->charge_on){
+ charger->rest_vol = 100;
+ }
+
+ printk("last_rest_vol = %d, now_rest_vol = %d\n",(val1 & 0x7F),(val2 & 0x7F));
+ memset(Bat_Cap_Buffer, 0, sizeof(Bat_Cap_Buffer));
+ for(k = 0;k < AXP15_VOL_MAX; k++){
+ Bat_Cap_Buffer[k] = charger->rest_vol;
+ }
+ Total_Cap = charger->rest_vol * AXP15_VOL_MAX;
+
+ charger->interval = msecs_to_jiffies(10 * 1000);
+ INIT_DELAYED_WORK(&charger->work, axp_charging_monitor);
+ schedule_delayed_work(&charger->work, charger->interval);
+ // set usb cur-vol limit
+ INIT_DELAYED_WORK(&usbwork, axp_usb);
+ if(charger->usb_valid){
+ schedule_delayed_work(&usbwork, msecs_to_jiffies(7 * 1000));
+ }
+
+ var = script_parser_fetch("pmu_para", "pmu_used2", &pmu_used2, sizeof(int));
+ if (var)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_used2 = 0;
+ printk("pmu_used2 = %d\n",pmu_used2);
+ }
+
+ var = script_parser_fetch("pmu_para", "pmu_earlysuspend_chgcur", &pmu_earlysuspend_chgcur, sizeof(int));
+ if (var)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_earlysuspend_chgcur = pmu_suspend_chgcur / 1000;
+ printk("pmu_earlysuspend_chgcur = %d\n",pmu_earlysuspend_chgcur);
+ }
+ pmu_earlysuspend_chgcur = pmu_earlysuspend_chgcur * 1000;
+
+ var = script_parser_fetch("pmu_para", "pmu_batdeten", &pmu_batdeten, sizeof(int));
+ if (var)
+ {
+ printk("axp driver uning configuration failed(%d)\n", __LINE__);
+ pmu_batdeten = 1;
+ printk("pmu_batdeten = %d\n",pmu_batdeten);
+ }
+ if(!pmu_batdeten)
+ axp_clr_bits(charger->master,0x32,0x40);
+ else
+ axp_set_bits(charger->master,0x32,0x40);
+
+ //axp usb-pc limite
+ var = script_parser_fetch("pmu_para", "pmu_usbvol_pc", &pmu_usbvolnew, sizeof(int));
+ if (var)
+ {
+ printk("axp driver uning configuration failed-pmu_usbvol_pc\n");
+ pmu_usbvolnew = 4000;
+ printk("pmu_usbvolnew = %d\n",pmu_usbvolnew);
+ }
+ else
+ {
+ // usb current and voltage limit
+ if(pmu_usbvolnew){
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ var = pmu_usbvolnew * 1000;
+ if(var >= 4000000 && var <=4700000){
+ tmp = (var - 4000000)/100000;
+ axp_read(charger->master, AXP15_CHARGE_VBUS,&val);
+ val &= 0xC7;
+ val |= tmp << 3;
+ axp_write(charger->master, AXP15_CHARGE_VBUS,val);
+ }
+ }
+ else
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x40);
+ }
+
+ var = script_parser_fetch("pmu_para", "pmu_usbcur_pc", &pmu_usbcurnew, sizeof(int));
+ if (var)
+ {
+ printk("axp driver uning configuration failed-pmu_usbcurnew\n");
+ pmu_usbcurnew = 500;
+ printk("pmu_usbcurnew = %d\n",pmu_usbcurnew);
+ }
+ else
+ {
+ if(pmu_usbcurnew){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ var = pmu_usbcurnew * 1000;
+ if(var >= 900000)
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ else if ((var >= 500000)&& (var < 900000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ }
+ else if ((var >= 100000)&& (var < 500000)){
+ axp_clr_bits(charger->master, AXP15_CHARGE_VBUS, 0x01);
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x02);
+ }
+ }
+ else
+ axp_set_bits(charger->master, AXP15_CHARGE_VBUS, 0x03);
+ }
+
+*/
+
+//}
+
+static int axp_battery_remove(struct platform_device *dev)
+{
+ struct axp_charger *charger = platform_get_drvdata(dev);
+
+ if(main_task){
+ kthread_stop(main_task);
+ main_task = NULL;
+ }
+
+ axp_unregister_notifier(charger->master, &charger->nb, AXP15_NOTIFIER_ON);
+ cancel_delayed_work_sync(&charger->work);
+ power_supply_unregister(&charger->usb);
+ power_supply_unregister(&charger->ac);
+ power_supply_unregister(&charger->batt);
+
+ kfree(charger);
+ input_unregister_device(powerkeydev);
+ kfree(powerkeydev);
+
+ return 0;
+}
+
+
+static int axp15_suspend(struct platform_device *dev, pm_message_t state)
+{
+ uint8_t irq_w[5];
+ uint8_t tmp;
+
+ struct axp_charger *charger = platform_get_drvdata(dev);
+
+
+ cancel_delayed_work_sync(&charger->work);
+
+ /*clear all irqs events*/
+ irq_w[0] = 0xff;
+ irq_w[1] = POWER15_INTSTS2;
+ irq_w[2] = 0xff;
+ irq_w[3] = POWER15_INTSTS3;
+ irq_w[4] = 0xff;
+
+ axp_writes(charger->master, POWER15_INTSTS1, 5, irq_w);
+
+ /* close all irqs*/
+ axp_unregister_notifier(charger->master, &charger->nb, AXP15_NOTIFIER_ON);
+
+/*
+ // timer
+ axp_write(charger->master, 0x8A, 0x80);
+ axp_write(charger->master, 0x8A, 0x02);
+
+ // clear and enable coulomb
+ tmp = 0xff;
+ axp_read(charger->master, POWER15_COULOMB_CTL, &tmp);
+
+ //tmp |= 0x20;
+ tmp &= 0x3f;
+
+ axp_write(charger->master, POWER15_COULOMB_CTL, tmp);
+ tmp |= 0x80;
+ tmp &= 0xbf;
+
+ axp_write(charger->master, POWER15_COULOMB_CTL, tmp);
+*/
+ return 0;
+}
+
+static int axp15_resume(struct platform_device *dev)
+{
+ struct axp_charger *charger = platform_get_drvdata(dev);
+
+ int pre_rest_vol,k;
+ uint8_t val,val1,tmp;
+ uint8_t v[2];
+ int rt_rest_vol;
+ int Cur_CoulombCounter;
+
+ axp_register_notifier(charger->master, &charger->nb, AXP15_NOTIFIER_ON);
+
+ axp_charger_update_state(charger);
+
+
+
+ charger->rest_vol = 100;
+
+ schedule_delayed_work(&charger->work, charger->interval);
+
+ return 0;
+}
+
+static void axp15_shutdown(struct platform_device *dev)
+{
+ uint8_t tmp;
+ struct axp_charger *charger = platform_get_drvdata(dev);
+
+ cancel_delayed_work_sync(&charger->work);
+ //axp_clr_bits(charger->master,AXP15_CAP,0x80);
+ /*
+
+#if defined (CONFIG_AXP_CHGCHANGE)
+ if(pmu_shutdown_chgcur == 0)
+ axp_clr_bits(charger->master,AXP15_CHARGE_CONTROL1,0x80);
+ else
+ axp_set_bits(charger->master,AXP15_CHARGE_CONTROL1,0x80);
+
+ printk("pmu_shutdown_chgcur = %d\n", pmu_shutdown_chgcur);
+
+ if(pmu_shutdown_chgcur >= 300000 && pmu_shutdown_chgcur <= 1800000){
+ tmp = (pmu_shutdown_chgcur -200001)/100000;
+ charger->chgcur = tmp *100000 + 300000;
+ axp_update(charger->master, AXP15_CHARGE_CONTROL1, tmp, 0x0F);
+ }
+
+#endif*/
+}
+
+static struct platform_driver axp_battery_driver = {
+ .driver = {
+ .name = "axp15-supplyer",
+ .owner = THIS_MODULE,
+ },
+ .probe = axp_battery_probe,
+ .remove = axp_battery_remove,
+ .suspend = axp15_suspend,
+ .resume = axp15_resume,
+ .shutdown = axp15_shutdown,
+};
+
+static int axp_battery_init(void)
+{
+ return platform_driver_register(&axp_battery_driver);
+}
+
+static void axp_battery_exit(void)
+{
+ platform_driver_unregister(&axp_battery_driver);
+}
+
+module_init(axp_battery_init);
+module_exit(axp_battery_exit);
+
+MODULE_DESCRIPTION("axp15 battery charger driver");
+MODULE_AUTHOR("Kyle Cheung, X-power");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/axp_power/virtual15.c b/drivers/power/axp_power/virtual15.c
new file mode 100755
index 0000000..8e9c4e4
--- /dev/null
+++ b/drivers/power/axp_power/virtual15.c
@@ -0,0 +1,427 @@
+/*
+ * reg-virtual-consumer.c
+ *
+ * Copyright 2008 Wolfson Microelectronics PLC.
+ *
+ * Author: Mark Brown <bro...@opensource.wolfsonmicro.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+
+struct virtual_consumer_data {
+ struct mutex lock;
+ struct regulator *regulator;
+ int enabled;
+ int min_uV;
+ int max_uV;
+ int min_uA;
+ int max_uA;
+ unsigned int mode;
+};
+
+static void update_voltage_constraints(struct virtual_consumer_data *data)
+{
+ int ret;
+
+ if (data->min_uV && data->max_uV
+ && data->min_uV <= data->max_uV) {
+ ret = regulator_set_voltage(data->regulator,
+ data->min_uV, data->max_uV);
+ printk("%s,line=%d,%d,%d\n",__func__,__LINE__,data->min_uV,data->max_uV);
+ if (ret != 0) {
+ printk(KERN_ERR "regulator_set_voltage() failed: %d\n",
+ ret);
+ return;
+ }
+ }
+
+ if (data->min_uV && data->max_uV && !data->enabled) {
+ ret = regulator_enable(data->regulator);
+ if (ret == 0)
+ data->enabled = 1;
+ else
+ printk(KERN_ERR "regulator_enable() failed: %d\n",
+ ret);
+ }
+
+ if (!(data->min_uV && data->max_uV) && data->enabled) {
+ ret = regulator_disable(data->regulator);
+ if (ret == 0)
+ data->enabled = 0;
+ else
+ printk(KERN_ERR "regulator_disable() failed: %d\n",
+ ret);
+ }
+}
+
+static void update_current_limit_constraints(struct virtual_consumer_data
+ *data)
+{
+ int ret;
+
+ if (data->max_uA
+ && data->min_uA <= data->max_uA) {
+ ret = regulator_set_current_limit(data->regulator,
+ data->min_uA, data->max_uA);
+ if (ret != 0) {
+ pr_err("regulator_set_current_limit() failed: %d\n",
+ ret);
+ return;
+ }
+ }
+
+ if (data->max_uA && !data->enabled) {
+ ret = regulator_enable(data->regulator);
+ if (ret == 0)
+ data->enabled = 1;
+ else
+ printk(KERN_ERR "regulator_enable() failed: %d\n",
+ ret);
+ }
+
+ if (!(data->min_uA && data->max_uA) && data->enabled) {
+ ret = regulator_disable(data->regulator);
+ if (ret == 0)
+ data->enabled = 0;
+ else
+ printk(KERN_ERR "regulator_disable() failed: %d\n",
+ ret);
+ }
+}
+
+static ssize_t show_min_uV(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return sprintf(buf, "%d\n", data->min_uV);
+}
+
+static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+printk("%s,line:%d\n", __func__, __LINE__);
+ mutex_lock(&data->lock);
+
+ data->min_uV = val;
+ update_voltage_constraints(data);
+ printk("%s,line:%d\n", __func__, __LINE__);
+
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_max_uV(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return sprintf(buf, "%d\n", data->max_uV);
+}
+
+static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ long val;
+
+printk("%s,line:%d\n", __func__, __LINE__);
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+
+ mutex_lock(&data->lock);
+
+ data->max_uV = val;
+ update_voltage_constraints(data);
+printk("%s,line:%d\n", __func__, __LINE__);
+
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_min_uA(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ printk("%s,line:%d\n", __func__, __LINE__);
+ return sprintf(buf, "%d\n", data->min_uA);
+}
+
+static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+printk("%s,line:%d\n", __func__, __LINE__);
+ mutex_lock(&data->lock);
+
+ data->min_uA = val;
+ update_current_limit_constraints(data);
+ printk("%s,line:%d\n", __func__, __LINE__);
+
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_max_uA(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", data->max_uA);
+}
+
+static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ long val;
+
+ if (strict_strtol(buf, 10, &val) != 0)
+ return count;
+
+ mutex_lock(&data->lock);
+
+ data->max_uA = val;
+ update_current_limit_constraints(data);
+
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static ssize_t show_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+
+ switch (data->mode) {
+ case REGULATOR_MODE_FAST:
+ return sprintf(buf, "fast\n");
+ case REGULATOR_MODE_NORMAL:
+ return sprintf(buf, "normal\n");
+ case REGULATOR_MODE_IDLE:
+ return sprintf(buf, "idle\n");
+ case REGULATOR_MODE_STANDBY:
+ return sprintf(buf, "standby\n");
+ default:
+ return sprintf(buf, "unknown\n");
+ }
+}
+
+static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct virtual_consumer_data *data = dev_get_drvdata(dev);
+ unsigned int mode;
+ int ret;
+
+ if (strncmp(buf, "fast", strlen("fast")) == 0)
+ mode = REGULATOR_MODE_FAST;
+ else if (strncmp(buf, "normal", strlen("normal")) == 0)
+ mode = REGULATOR_MODE_NORMAL;
+ else if (strncmp(buf, "idle", strlen("idle")) == 0)
+ mode = REGULATOR_MODE_IDLE;
+ else if (strncmp(buf, "standby", strlen("standby")) == 0)
+ mode = REGULATOR_MODE_STANDBY;
+ else {
+ dev_err(dev, "Configuring invalid mode\n");
+ return count;
+ }
+
+ mutex_lock(&data->lock);
+ ret = regulator_set_mode(data->regulator, mode);
+ if (ret == 0)
+ data->mode = mode;
+ else
+ dev_err(dev, "Failed to configure mode: %d\n", ret);
+ mutex_unlock(&data->lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(min_microvolts, 0666, show_min_uV, set_min_uV);
+static DEVICE_ATTR(max_microvolts, 0666, show_max_uV, set_max_uV);
+static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA);
+static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
+static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
+
+struct device_attribute *attributes_virtual[] = {
+ &dev_attr_min_microvolts,
+ &dev_attr_max_microvolts,
+ &dev_attr_min_microamps,
+ &dev_attr_max_microamps,
+ &dev_attr_mode,
+};
+
+static int regulator_virtual_consumer_probe(struct platform_device *pdev)
+{
+ char *reg_id = pdev->dev.platform_data;
+ struct virtual_consumer_data *drvdata;
+ int ret, i;
+
+ drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL);
+ if (drvdata == NULL) {
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ mutex_init(&drvdata->lock);
+
+ //drvdata->regulator = regulator_get(&pdev->dev, reg_id);
+ drvdata->regulator = regulator_get(NULL, reg_id);
+ //drvdata->regulator = regulator_get(NULL, "axp20_analog/fm");
+ if (IS_ERR(drvdata->regulator)) {
+ ret = PTR_ERR(drvdata->regulator);
+ goto err;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(attributes_virtual); i++) {
+ ret = device_create_file(&pdev->dev, attributes_virtual[i]);
+ if (ret != 0)
+ goto err;
+ }
+
+ drvdata->mode = regulator_get_mode(drvdata->regulator);
+
+ platform_set_drvdata(pdev, drvdata);
+
+ return 0;
+
+err:
+ for (i = 0; i < ARRAY_SIZE(attributes_virtual); i++)
+ device_remove_file(&pdev->dev, attributes_virtual[i]);
+ kfree(drvdata);
+ return ret;
+}
+
+static int regulator_virtual_consumer_remove(struct platform_device *pdev)
+{
+ struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev);
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attributes_virtual); i++)
+ device_remove_file(&pdev->dev, attributes_virtual[i]);
+ if (drvdata->enabled)
+ regulator_disable(drvdata->regulator);
+ regulator_put(drvdata->regulator);
+
+ kfree(drvdata);
+
+ return 0;
+}
+
+static struct platform_driver regulator_virtual_consumer_driver[] = {
+ {
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-aldo1",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-aldo2",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-dldo1",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-dldo2",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-ldoio0",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-gpiodldo",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-buck1",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-buck2",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-buck3",
+ },
+ },{
+ .probe = regulator_virtual_consumer_probe,
+ .remove = regulator_virtual_consumer_remove,
+ .driver = {
+ .name = "reg-15-cs-buck4",
+ },
+ },
+};
+
+
+static int __init regulator_virtual_consumer_init(void)
+{
+ int j,ret;
+ for (j = 0; j < ARRAY_SIZE(regulator_virtual_consumer_driver); j++){
+ ret = platform_driver_register(&regulator_virtual_consumer_driver[j]);
+ if (ret)
+ goto creat_drivers_failed;
+ }
+ return ret;
+
+creat_drivers_failed:
+ while (j--)
+ platform_driver_unregister(&regulator_virtual_consumer_driver[j]);
+ return ret;
+}
+module_init(regulator_virtual_consumer_init);
+
+static void __exit regulator_virtual_consumer_exit(void)
+{
+ int j;
+ for (j = ARRAY_SIZE(regulator_virtual_consumer_driver) - 1; j >= 0; j--){
+ platform_driver_unregister(&regulator_virtual_consumer_driver[j]);
+ }
+}
+module_exit(regulator_virtual_consumer_exit);
+
+MODULE_AUTHOR("Kyle Cheung");
+MODULE_DESCRIPTION("Virtual regulator consumer");
+MODULE_LICENSE("GPL");
diff --git a/drivers/power/axp_power/virtual15_dev.c b/drivers/power/axp_power/virtual15_dev.c
new file mode 100755
index 0000000..4c63043
--- /dev/null
+++ b/drivers/power/axp_power/virtual15_dev.c
@@ -0,0 +1,125 @@
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
+#include <linux/i2c.h>
+#include <mach/irqs.h>
+#include <linux/power_supply.h>
+#include <linux/mfd/axp-mfd.h>
+
+
+#include "axp-cfg.h"
+
+
+static struct platform_device virt[]={
+
+ {
+ .name = "reg-15-cs-ldo0",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_ldo0",
+ }
+
+ },{
+ .name = "reg-15-cs-rtcldo",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_rtc",
+ }
+ },{
+ .name = "reg-15-cs-aldo1",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_analog/fm",
+ }
+ },{
+ .name = "reg-15-cs-aldo2",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_analog/fm2",
+ }
+ },{
+ .name = "reg-15-cs-dldo1",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_pll/sdram",
+ }
+ },{
+ .name = "reg-15-cs-dldo2",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_pll/hdmi",
+ }
+ },{
+ .name = "reg-15-cs-gpioldo",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_gpio",
+ }
+ },{
+ .name = "reg-15-cs-buck1",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_io",
+ }
+ },{
+ .name = "reg-15-cs-buck2",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_core",
+ }
+ },{
+ .name = "reg-15-cs-buck3",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_ddr",
+ }
+ },{
+ .name = "reg-15-cs-buck4",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_ddr2",
+ }
+ },{
+ .name = "reg-15-cs-ldoio0",
+ .id = -1,
+ .dev = {
+ .platform_data = "axp15_mic",
+ }
+ },
+};
+
+
+
+ static int __init virtual_init(void)
+{
+ int j,ret;
+ for (j = 0; j < ARRAY_SIZE(virt); j++){
+ ret = platform_device_register(&virt[j]);
+ if (ret)
+ goto creat_devices_failed;
+ }
+
+ return ret;
+
+creat_devices_failed:
+ while (j--)
+ platform_device_register(&virt[j]);
+ return ret;
+
+}
+
+module_init(virtual_init);
+
+static void __exit virtual_exit(void)
+{
+ int j;
+ for (j = ARRAY_SIZE(virt) - 1; j >= 0; j--){
+ platform_device_unregister(&virt[j]);
+ }
+}
+module_exit(virtual_exit);
+
+MODULE_DESCRIPTION("Axp regulator test");
+MODULE_AUTHOR("Kyle Cheung");
+MODULE_LICENSE("GPL");
\ No newline at end of file
--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:51 PM1/24/13
to linux...@googlegroups.com, hehopmajieh, Hans de Goede
From: hehopmajieh <gami...@gmail.com>

HdG: Fixed some checkpatch warnings

Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
drivers/power/axp_power/Kconfig | 5 +++
drivers/power/axp_power/Makefile | 11 ++++-
drivers/power/axp_power/axp-cfg.h | 13 +++++-
drivers/power/axp_power/axp-gpio.h | 8 ++++
drivers/power/axp_power/axp-mfd.c | 22 +++++++++
drivers/power/axp_power/axp-regu.h | 49 ++++++++++++++++++++
drivers/power/axp_power/axp-sply.h | 2 +
include/linux/mfd/axp-mfd.h | 92 ++++++++++++++++++++++++++++++++++++++
8 files changed, 200 insertions(+), 2 deletions(-)

diff --git a/drivers/power/axp_power/Kconfig b/drivers/power/axp_power/Kconfig
index 039679f..d47e808 100644
--- a/drivers/power/axp_power/Kconfig
+++ b/drivers/power/axp_power/Kconfig
@@ -11,6 +11,11 @@ choice
prompt "AXP PMU type"
default AW_AXP20

+config AW_AXP15
+ bool "AXP15 driver"
+ ---help---
+ AXP15 driver
+
config AW_AXP18
bool "AXP18 driver"
---help---
diff --git a/drivers/power/axp_power/Makefile b/drivers/power/axp_power/Makefile
index ba3e717..89b0414 100644
--- a/drivers/power/axp_power/Makefile
+++ b/drivers/power/axp_power/Makefile
@@ -2,6 +2,15 @@ obj-y += axp-mfd.o

#axp 199
#Make this built-in, so that it will be loaded before I2C driver
+
+obj-$(CONFIG_AW_AXP15) += axp15-board.o
+obj-$(CONFIG_AW_AXP15) += axp15-gpio.o
+obj-$(CONFIG_AW_AXP15) += axp15-regu.o
+obj-$(CONFIG_AW_AXP15) += axp15-sply.o
+obj-$(CONFIG_AW_AXP15) += virtual15.o
+obj-$(CONFIG_AW_AXP15) += virtual15_dev.o
+
+
obj-$(CONFIG_AW_AXP18) += axp18-board.o
obj-$(CONFIG_AW_AXP18) += axp18-regu.o
obj-$(CONFIG_AW_AXP18) += axp18-sply.o
@@ -20,4 +29,4 @@ obj-$(CONFIG_AW_AXP20) += axp20-regu.o
obj-$(CONFIG_AW_AXP20) += axp20-sply.o
obj-$(CONFIG_AW_AXP20) += axp20-gpio.o
obj-$(CONFIG_AW_AXP20) += virtual20.o
-obj-$(CONFIG_AW_AXP20) += virtual20_dev.o
\ No newline at end of file
+obj-$(CONFIG_AW_AXP20) += virtual20_dev.o
diff --git a/drivers/power/axp_power/axp-cfg.h b/drivers/power/axp_power/axp-cfg.h
index a3293d9..7157c46 100644
--- a/drivers/power/axp_power/axp-cfg.h
+++ b/drivers/power/axp_power/axp-cfg.h
@@ -22,16 +22,20 @@

#ifndef __LINUX_AXP_CFG_H_
#define __LINUX_AXP_CFG_H_
+/*AXP15 addr*/
+#define AXP15_ADDR 0x60 >> 1

#define AXP18_ADDR 0x2C >> 1
#define AXP19_ADDR 0x68 >> 1
#define AXP20_ADDR 0x68 >> 1
#define AXP18_I2CBUS 1
#define AXP19_I2CBUS 0
+#define AXP15_I2CBUS 0
+
#define AXP20_I2CBUS 0
#define BATRDC 200 //initial rdc
#define AXP20_IRQNO 0
-
+#define AXP15_IRQNO 0

#define LDO1SET 0 //0: LDO1SET connect AGND, 1: LDO1SET connect AIPS, for axp189 LDOSET bonding to AGND
#define DC2SET 1 //0: DC2SET connect GND, 1: DC2SET connect IPSOUT, for axp189 DC2SET bonding to IPSOUT
@@ -39,6 +43,7 @@

#define AXP19LDO1 1250
#define AXP20LDO1 1300
+#define AXP15LDO1 1300


#if !LDO1SET
@@ -69,6 +74,11 @@
#define LDO3MAX 2600
#endif

+#define AXP15_VOL_MAX 50
+#define AXP15_TIME_MAX 20
+#define AXP15_AVER_MAX 10
+#define AXP15_RDC_COUNT 10
+
#define AXP18_VOL_MAX 50//1200
#define AXP18_TIME_MAX 20//100
#define AXP18_RDC_COUNT 10
@@ -77,6 +87,7 @@
#define MAX_BAT_CUR 15
#define DISCHARGE_RDC_CAL 53

+
#define AXP19_VOL_MAX 50
#define AXP19_TIME_MAX 20
#define AXP19_AVER_MAX 10
diff --git a/drivers/power/axp_power/axp-gpio.h b/drivers/power/axp_power/axp-gpio.h
index 44fae57..eade364 100644
--- a/drivers/power/axp_power/axp-gpio.h
+++ b/drivers/power/axp_power/axp-gpio.h
@@ -16,6 +16,14 @@
/*
* GPIO Registers.
*/
+/*AXP15*/
+#define AXP15_GPIO0_CFG (POWER15_GPIO0_CTL)
+#define AXP15_GPIO1_CFG (POWER15_GPIO1_CTL)
+#define AXP15_GPIO2_CFG (POWER15_GPIO2_CTL)
+#define AXP15_GPIO3_CFG (POWER15_GPIO3_CTL)
+
+#define AXP15_GPIO0123_STATE (POWER15_GPIO0123_SIGNAL)
+
/* AXP19 */
#define AXP19_GPIO0_CFG (POWER19_GPIO0_CTL)
#define AXP19_GPIO1_CFG (POWER19_GPIO1_CTL)
diff --git a/drivers/power/axp_power/axp-mfd.c b/drivers/power/axp_power/axp-mfd.c
index 5cd0d43..9ed6490 100644
--- a/drivers/power/axp_power/axp-mfd.c
+++ b/drivers/power/axp_power/axp-mfd.c
@@ -17,6 +17,7 @@
#include <linux/slab.h>

#include "axp-cfg.h"
+#include "axp15-mfd.h"
#include "axp18-mfd.h"
#include "axp19-mfd.h"
#include "axp20-mfd.h"
@@ -75,12 +76,20 @@ static struct axp_mfd_chip_ops axp_mfd_ops[] = {
.disable_irqs = axp20_disable_irqs,
.read_irqs = axp20_read_irqs,
},
+ [3] = {
+ .init_chip = axp15_init_chip,
+ .enable_irqs = axp15_enable_irqs,
+ .disable_irqs = axp15_disable_irqs,
+ .read_irqs = axp15_read_irqs,
+ },
+
};

static const struct i2c_device_id axp_mfd_id_table[] = {
{ "axp18_mfd", 0 },
{ "axp19_mfd", 1 },
{ "axp20_mfd", 2 },
+ { "axp15_mfd", 3 },
{},
};
MODULE_DEVICE_TABLE(i2c, axp_mfd_id_table);
@@ -88,6 +97,14 @@ MODULE_DEVICE_TABLE(i2c, axp_mfd_id_table);
int axp_mfd_create_attrs(struct axp_mfd_chip *chip)
{
int j,ret;
+ if(chip->type == AXP15){
+ for (j = 0; j < ARRAY_SIZE(axp15_mfd_attrs); j++) {
+ ret = device_create_file(chip->dev,&axp15_mfd_attrs[j]);
+ if (ret)
+ goto sysfs_failed;
+ }
+ }
+
if(chip->type == AXP19){
for (j = 0; j < ARRAY_SIZE(axp19_mfd_attrs); j++) {
ret = device_create_file(chip->dev,&axp19_mfd_attrs[j]);
@@ -194,6 +211,11 @@ static void axp_power_off(void)
{
uint8_t val;

+#if defined (CONFIG_AW_AXP15)
+ axp_set_bits(&axp->dev, POWER15_OFF_CTL , 0x80);
+#endif
+
+
#if defined (CONFIG_AW_AXP18)
axp_set_bits(&axp->dev, POWER18_ONOFF, 0x80);
#endif
diff --git a/drivers/power/axp_power/axp-regu.h b/drivers/power/axp_power/axp-regu.h
index 1142d49..bdaa6c7 100644
--- a/drivers/power/axp_power/axp-regu.h
+++ b/drivers/power/axp_power/axp-regu.h
@@ -27,6 +27,36 @@

#include "axp-cfg.h"

+/*AXP15 Registers*/
+#define AXP15_LDO0 POWER15_LDO0OUT_VOL
+#define AXP15_RTC POWER15_STATUS
+#define AXP15_ANALOG1 POWER15_LDO34OUT_VOL
+#define AXP15_ANALOG2 POWER15_LDO34OUT_VOL
+#define AXP15_DIGITAL1 POWER15_LDO5OUT_VOL
+#define AXP15_DIGITAL2 POWER15_LDO6OUT_VOL
+#define AXP15_LDOIO0 POWER15_GPIO0_VOL
+
+#define AXP15_DCDC1 POWER15_DC1OUT_VOL
+#define AXP15_DCDC2 POWER15_DC2OUT_VOL
+#define AXP15_DCDC3 POWER15_DC3OUT_VOL
+#define AXP15_DCDC4 POWER15_DC4OUT_VOL
+
+#define AXP15_LDO0EN POWER15_LDO0_CTL //REG[15H]
+#define AXP15_RTCLDOEN POWER15_STATUS //REG[00H]
+#define AXP15_ANALOG1EN POWER15_LDO3456_DC1234_CTL //REG[12H]
+#define AXP15_ANALOG2EN POWER15_LDO3456_DC1234_CTL
+#define AXP15_DIGITAL1EN POWER15_LDO3456_DC1234_CTL
+#define AXP15_DIGITAL2EN POWER15_LDO3456_DC1234_CTL
+#define AXP15_LDOI0EN POWER15_GPIO0_CTL //REG[92H]
+
+#define AXP15_DCDC1EN POWER15_LDO3456_DC1234_CTL
+#define AXP15_DCDC2EN POWER15_LDO3456_DC1234_CTL
+#define AXP15_DCDC3EN POWER15_LDO3456_DC1234_CTL
+#define AXP15_DCDC4EN POWER15_LDO3456_DC1234_CTL
+/*Need to check !!!!*/
+#define AXP15_BUCKMODE POWER15_DCDC_MODESET //REG[80H]
+#define AXP15_BUCKFREQ POWER15_DCDC_FREQSET //REG[37H]
+

/* AXP18 Regulator Registers */
#define AXP18_RTC POWER18_STATUS
@@ -135,6 +165,25 @@
.enable_bit = (ebit), \
}

+#define AXP_DCDC(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \
+{ \
+ .desc = { \
+ .name = #_pmic"_DCDC" #_id, \
+ .type = REGULATOR_VOLTAGE, \
+ .id = _pmic##_ID_DCDC##_id, \
+ .n_voltages = (step) ? ((max - min) / step + 1) : 1, \
+ .owner = THIS_MODULE, \
+ }, \
+ .min_uV = (min) * 1000, \
+ .max_uV = (max) * 1000, \
+ .step_uV = (step) * 1000, \
+ .vol_reg = _pmic##_##vreg, \
+ .vol_shift = (shift), \
+ .vol_nbits = (nbits), \
+ .enable_reg = _pmic##_##ereg, \
+ .enable_bit = (ebit), \
+}
+
#define AXP_SW(_pmic, _id, min, max, step, vreg, shift, nbits, ereg, ebit) \
{ \
.desc = { \
diff --git a/drivers/power/axp_power/axp-sply.h b/drivers/power/axp_power/axp-sply.h
index 72c1072..3a100f8 100644
--- a/drivers/power/axp_power/axp-sply.h
+++ b/drivers/power/axp_power/axp-sply.h
@@ -23,6 +23,8 @@
#ifndef _LINUX_AXP_SPLY_H_
#define _LINUX_AXP_SPLY_H_

+const unsigned int AXP15_NOTIFIER_ON = AXP15_IRQ_PEKLO |AXP15_IRQ_PEKSH ;
+
/* AXP18 */
#define AXP18_STATUS POWER18_STATUS
#define AXP18_CHARGE_STATUS POWER18_ONOFF
diff --git a/include/linux/mfd/axp-mfd.h b/include/linux/mfd/axp-mfd.h
index 2511473..b96be90 100644
--- a/include/linux/mfd/axp-mfd.h
+++ b/include/linux/mfd/axp-mfd.h
@@ -25,6 +25,21 @@

/* Unified sub device IDs for AXP */
enum {
+
+ AXP15_ID_LDO0,
+ AXP15_ID_LDO1,
+ AXP15_ID_LDO2,
+ AXP15_ID_LDO3,
+ AXP15_ID_LDO4,
+ AXP15_ID_LDO5,
+ AXP15_ID_LDOIO0,
+ AXP15_ID_DCDC1,
+ AXP15_ID_DCDC2,
+ AXP15_ID_DCDC3,
+ AXP15_ID_DCDC4,
+ AXP15_ID_SUPPLY,
+ AXP15_ID_GPIO,
+
AXP18_ID_LDO1,
AXP18_ID_LDO2,
AXP18_ID_LDO3,
@@ -140,6 +155,83 @@ struct axp_mfd_chip_ops {
int (*read_irqs)(struct axp_mfd_chip *, uint64_t *irqs);
};

+/*Need to Modify */
+#define AXP15 15
+#define POWER15_STATUS (0x00)
+#define POWER15_MODE_CHGSTATUS (0x01)
+#define POWER15_OTG_STATUS (0x02)
+#define POWER15_IC_TYPE (0x03)
+#define POWER15_DATA_BUFFER1 (0x04)
+#define POWER15_DATA_BUFFER2 (0x05)
+#define POWER15_DATA_BUFFER3 (0x06)
+#define POWER15_DATA_BUFFER4 (0x07)
+#define POWER15_DATA_BUFFER5 (0x08)
+#define POWER15_DATA_BUFFER6 (0x09)
+#define POWER15_DATA_BUFFER7 (0x0A)
+#define POWER15_DATA_BUFFER8 (0x0B)
+#define POWER15_DATA_BUFFER9 (0x0C)
+#define POWER15_DATA_BUFFERA (0x0D)
+#define POWER15_DATA_BUFFERB (0x0E)
+#define POWER15_DATA_BUFFERC (0x0F)
+#define POWER15_IPS_SET (0x30)
+#define POWER15_VOFF_SET (0x31)
+#define POWER15_OFF_CTL (0x32)
+#define POWER15_CHARGE1 (0x33)
+#define POWER15_CHARGE2 (0x34)
+#define POWER15_BACKUP_CHG (0x35)
+#define POWER15_PEK_SET (0x36)
+#define POWER15_DCDC_FREQSET (0x37)
+#define POWER15_VLTF_CHGSET (0x38)
+#define POWER15_VHTF_CHGSET (0x39)
+#define POWER15_APS_WARNING1 (0x3A)
+#define POWER15_APS_WARNING2 (0x3B)
+#define POWER15_TLTF_DISCHGSET (0x3C)
+#define POWER15_THTF_DISCHGSET (0x3D)
+#define POWER15_DCDC_MODESET (0x80)
+#define POWER15_ADC_EN1 (0x82)
+#define POWER15_ADC_EN2 (0x83)
+#define POWER15_ADC_SPEED (0x84)
+#define POWER15_ADC_INPUTRANGE (0x85)
+#define POWER15_ADC_IRQ_RETFSET (0x86)
+#define POWER15_ADC_IRQ_FETFSET (0x87)
+#define POWER15_TIMER_CTL (0x8A)
+#define POWER15_VBUS_DET_SRP (0x8B)
+#define POWER15_HOTOVER_CTL (0x8F)
+#define POWER15_GPIO012_SIGNAL (0x94)
+
+#define POWER15_INTEN1 (0x40)
+#define POWER15_INTEN2 (0x41)
+#define POWER15_INTEN3 (0x42)
+#define POWER15_INTSTS1 (0x48)
+#define POWER15_INTSTS2 (0x49)
+#define POWER15_INTSTS3 (0x4A)
+
+/*For ajust axp15-reg only*/
+#define POWER15_STATUS (0x00)
+#define POWER15_LDO0OUT_VOL (0x15)
+#define POWER15_LDO34OUT_VOL (0x28)
+#define POWER15_LDO5OUT_VOL (0x29)
+#define POWER15_LDO6OUT_VOL (0x2A)
+#define POWER15_GPIO0_VOL (0x96)
+#define POWER15_DC1OUT_VOL (0x26)
+#define POWER15_DC2OUT_VOL (0x23)
+#define POWER15_DC3OUT_VOL (0x27)
+#define POWER15_DC4OUT_VOL (0x2B)
+#define POWER15_LDO0_CTL (0x15)
+#define POWER15_LDO3456_DC1234_CTL (0x12)
+#define POWER15_GPIO0_CTL (0x90)
+#define POWER15_GPIO1_CTL (0x91)
+#define POWER15_GPIO2_CTL (0x92)
+#define POWER15_GPIO3_CTL (0x93)
+#define POWER15_GPIO0123_SIGNAL (0x97)
+#define POWER15_DCDC_MODESET (0x80)
+#define POWER15_DCDC_FREQSET (0x37)
+
+#define AXP15_IRQ_PEKLO ( 1 << 8)
+#define AXP15_IRQ_PEKSH ( 1 << 9)
+
+
+
#define AXP18 18
#define POWER18_STATUS (0x00)
#define POWER18_IPS_SET (0x01)
--
1.8.1

Hans de Goede

unread,
Jan 24, 2013, 6:00:53 PM1/24/13
to linux...@googlegroups.com, Hans de Goede
I encountered this while testing my A10s TV-stick, which uses uart0 for
its uart test-pads.

Having this device always registered + uart0_used set in the fex file,
caused 2 uart driver to get registered for uart0, both the regular
serial8250 as well as the 8250-sunxi driver, then when the first uart0
interrupt happens things go boom.

Signed-off-by: Hans de Goede <hdeg...@redhat.com>
---
arch/arm/mach-sun5i/devices.c | 23 -----------------------
1 file changed, 23 deletions(-)

diff --git a/arch/arm/mach-sun5i/devices.c b/arch/arm/mach-sun5i/devices.c
index 9ce0558..389a54f 100644
--- a/arch/arm/mach-sun5i/devices.c
+++ b/arch/arm/mach-sun5i/devices.c
@@ -43,28 +43,6 @@
#include <mach/hardware.h>
#include <mach/i2c.h>

-/* uart */
-static struct plat_serial8250_port debug_uart_platform_data[] = {
- {
- .membase = (void __iomem *)SW_VA_UART0_IO_BASE,
- .irq = SW_INT_IRQNO_UART0,
- .flags = UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM32,
- .regshift = 2,
- .uartclk = 24000000,
- }, {
- .flags = 0
- }
-};
-
-static struct platform_device debug_uart = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = debug_uart_platform_data,
- },
-};
-
/* dma */
static struct platform_device sw_pdev_dmac = {
.name = "sw_dmac",
@@ -192,7 +170,6 @@ struct platform_device sun5i_pmu_device = {
};

static struct platform_device *sw_pdevs[] __initdata = {
- &debug_uart,
&sw_pdev_dmac,
&sw_pdev_nand,
&sun5i_twi0_device,
--
1.8.1

Jari Helaakoski

unread,
Jan 25, 2013, 4:09:40 AM1/25/13
to linux...@googlegroups.com


2013/1/25 Hans de Goede <hdeg...@redhat.com>

I encountered this while testing my A10s TV-stick, which uses uart0 for
its uart test-pads.

Having this device always registered + uart0_used set in the fex file,
caused 2 uart driver to get registered for uart0, both the regular
serial8250 as well as the 8250-sunxi driver, then when the first uart0
interrupt happens things go boom.

Should this be done for sun4i also?

-Jari

Hans de Goede

unread,
Jan 25, 2013, 4:36:08 AM1/25/13
to linux...@googlegroups.com, Jari Helaakoski
Hi,

On 01/25/2013 10:09 AM, Jari Helaakoski wrote:
>
>
> 2013/1/25 Hans de Goede <hdeg...@redhat.com <mailto:hdeg...@redhat.com>>
It is already done for sun4i, although slightly less "final" then my sun5i patch:

linux-sunxi/arch/arm/mach-sun4i/devices.c:

#if 0
/* uart */
static struct plat_serial8250_port debug_uart_platform_data[] = {

...

.platform_data = debug_uart_platform_data,
},
};
#endif

...

static struct platform_device *sw_pdevs[] __initdata = {
#if 0
&debug_uart,
#endif

Regards,

Hans

Jari Helaakoski

unread,
Jan 25, 2013, 4:50:57 AM1/25/13
to Hans de Goede, linux...@googlegroups.com
2013/1/25 Hans de Goede <hdeg...@redhat.com>
Hi,

On 01/25/2013 10:09 AM, Jari Helaakoski wrote:


2013/1/25 Hans de Goede <hdeg...@redhat.com <mailto:hdeg...@redhat.com>>


    I encountered this while testing my A10s TV-stick, which uses uart0 for
    its uart test-pads.

    Having this device always registered + uart0_used set in the fex file,
    caused 2 uart driver to get registered for uart0, both the regular
    serial8250 as well as the 8250-sunxi driver, then when the first uart0
    interrupt happens things go boom.


Should this be done for sun4i also?

It is already done for sun4i, although slightly less "final" then my sun5i patch:
Oh.. 3.4 seems to be ok. But 3.0 has it still enabled.

-Jari

Hans de Goede

unread,
Jan 25, 2013, 4:54:39 AM1/25/13
to linux...@googlegroups.com, Jari Helaakoski
Hi,

On 01/25/2013 10:50 AM, Jari Helaakoski wrote:
>
>
> 2013/1/25 Hans de Goede <hdeg...@redhat.com <mailto:hdeg...@redhat.com>>
>
> Hi,
>
> On 01/25/2013 10:09 AM, Jari Helaakoski wrote:
>
>
>
> 2013/1/25 Hans de Goede <hdeg...@redhat.com <mailto:hdeg...@redhat.com> <mailto:hdeg...@redhat.com <mailto:hdeg...@redhat.com>>>
>
>
> I encountered this while testing my A10s TV-stick, which uses uart0 for
> its uart test-pads.
>
> Having this device always registered + uart0_used set in the fex file,
> caused 2 uart driver to get registered for uart0, both the regular
> serial8250 as well as the 8250-sunxi driver, then when the first uart0
> interrupt happens things go boom.
>
>
> Should this be done for sun4i also?
>
>
> It is already done for sun4i, although slightly less "final" then my sun5i patch:
>
> Oh.. 3.4 seems to be ok. But 3.0 has it still enabled.

Ah, well patches welcome :)

Regards,

Hans

Hans de Goede

unread,
Jan 29, 2013, 7:01:08 AM1/29/13
to linux...@googlegroups.com, Daniel Mosquera
Hi,

On 01/28/2013 11:08 PM, Daniel Mosquera wrote:
> El viernes, 25 de enero de 2013 00:00:45 UTC+1, Hans de Goede escribi�:
> Please, could you tell what reporitory/branch and defconfig should I use to be able to produce a stable Olinuxino a13 micro 3.4 kernel? The micro is an amazing board but it has been a little difficult to me to find documentation regarding the kernel sources for this board.

All the necessary changes are in this git repro:
https://github.com/linux-sunxi/linux-sunxi/

You need to use the stage/sunxi-3.4 branch.

Copy the attached file to
arch/arm/configs

And then run:
make ARCH=arm CROSS_COMPILE=arm-linux-gnu- a13om_defconfig

To create the .config you need.

You may beed to adjust the CROSS_COMPILE= setting to match
your environment.

Regards,

Hans
a13om_defconfig

Daniel Mosquera

unread,
Jan 29, 2013, 8:39:33 AM1/29/13
to linux...@googlegroups.com, Daniel Mosquera
Thanks alot!

Daniel

Hans de Goede

unread,
Jan 30, 2013, 6:17:54 AM1/30/13
to linux...@googlegroups.com, bel...@gmail.com, Daniel Mosquera
Hi,

On 01/30/2013 12:07 AM, bel...@gmail.com wrote:
>
>>
>> All the necessary changes are in this git repro:
>>
>> https://github.com/linux-sunxi/linux-sunxi/
>>
>>
>>
>> You need to use the stage/sunxi-3.4 branch.
>>
>
> Does it include the changes for A10s too ?

No, I've finally found the bug which made
kernels build from that tree hang all the time,
so I've Linux (Fedora 18) running more or less
reliable now, but my work on that is not available
anywhere yet (I need to clean it up), and I only
have things working when rebooting from android or
copying my own uImage to nand and then using the
build in nand uboot to boot it.

sdcard u-boot is not yet working ...

I've already spend many many hours on this, and
progress is slowly being made. All I can say to
A10s owners now is: patience please.

I'll be at fosdem Brussels this weekend, so I
don't expect any more progress till at-least
next week.

> Does a13om_defconfig will work too with A10s ?

No.

Regards,

Hans

Hans de Goede

unread,
Jan 31, 2013, 3:29:50 AM1/31/13
to linux...@googlegroups.com, vinic...@gmail.com, Daniel Mosquera
Hi,

On 01/31/2013 06:21 AM, vinic...@gmail.com wrote:
> Em ter�a-feira, 29 de janeiro de 2013 09h01min08s UTC-3, Hans de Goede escreveu:
>>
>>
>> All the necessary changes are in this git repro:
>>
>> https://github.com/linux-sunxi/linux-sunxi/
>>
> Hi Hans.
>
> But the only patch included in repository was this "[PATCH 3.4 1/8] sunxi-disp: Fix compiling for sun5i", am I right? Already was included another patch for A13_micro?

Yes, as said already, you need to use the stage/sunxi-3.4 branch


Regards,

Hans

Jason Plum

unread,
Jan 31, 2013, 9:33:18 AM1/31/13
to linux...@googlegroups.com, vinic...@gmail.com, Daniel Mosquera
On Thursday, January 31, 2013 3:29:50 AM UTC-5, Hans de Goede wrote:
Hi,

On 01/31/2013 06:21 AM, vinic...@gmail.com wrote:
> Em ter�a-feira, 29 de janeiro de 2013 09h01min08s UTC-3, Hans de Goede  escreveu:
>>
>>
>> All the necessary changes are in this git repro:
>>
>> https://github.com/linux-sunxi/linux-sunxi/
>>
> Hi Hans.
>
> But the only patch included in repository was this "[PATCH 3.4 1/8] sunxi-disp: Fix compiling for sun5i", am I right? Already was included another patch for A13_micro?

Yes, as said already, you need to use the stage/sunxi-3.4 branch


Regards,

Hans

Hans,

I commited the changes for the a13-olinuxino-micro to the sunxi-3.0 branch a bit ago, so the 3.0 branch is okay to use as well. I am using it at the moment for the Arch Linux ARM images.

Jason Plum
Reply all
Reply to author
Forward
0 new messages