unsigned long parent_rate);
long (*round_rate)(struct clk_hw *hw, unsigned long,
unsigned long *);
- long (*determine_rate)(struct clk_hw *hw,
- unsigned long rate,
- unsigned long *best_parent_rate,
- struct clk **best_parent_clk);
int (*set_parent)(struct clk_hw *hw, u8 index);
u8 (*get_parent)(struct clk_hw *hw);
int (*set_rate)(struct clk_hw *hw, unsigned long);
callback is invalid or otherwise unnecessary. Empty cells are either
optional or must be evaluated on a case-by-case basis.
- clock hardware characteristics
- -----------------------------------------------------------
- | gate | change rate | single parent | multiplexer | root |
- |------|-------------|---------------|-------------|------|
-.prepare | | | | | |
-.unprepare | | | | | |
- | | | | | |
-.enable | y | | | | |
-.disable | y | | | | |
-.is_enabled | y | | | | |
- | | | | | |
-.recalc_rate | | y | | | |
-.round_rate | | y [1] | | | |
-.determine_rate | | y [1] | | | |
-.set_rate | | y | | | |
- | | | | | |
-.set_parent | | | n | y | n |
-.get_parent | | | n | y | n |
- | | | | | |
-.init | | | | | |
- -----------------------------------------------------------
-[1] either one of round_rate or determine_rate is required.
+ clock hardware characteristics
+ -----------------------------------------------------------
+ | gate | change rate | single parent | multiplexer | root |
+ |------|-------------|---------------|-------------|------|
+.prepare | | | | | |
+.unprepare | | | | | |
+ | | | | | |
+.enable | y | | | | |
+.disable | y | | | | |
+.is_enabled | y | | | | |
+ | | | | | |
+.recalc_rate | | y | | | |
+.round_rate | | y | | | |
+.set_rate | | y | | | |
+ | | | | | |
+.set_parent | | | n | y | n |
+.get_parent | | | n | y | n |
+ | | | | | |
+.init | | | | | |
+ -----------------------------------------------------------
Finally, register your clock at run-time with a hardware-specific
registration function. This function simply populates struct clk_foo's
- compatible : should be one of
"arm,cortex-a15-pmu"
- "arm,cortex-a12-pmu"
"arm,cortex-a9-pmu"
"arm,cortex-a8-pmu"
"arm,cortex-a7-pmu"
- reg : SRAM iomem address range
-Optional properties:
-
-- map-exec: Map range to allow code execution
-- map-cacheable: Map range as cacheable
-
Example:
sram: sram@5c000000 {
"bus-width = <1>" property.
- sdhci,auto-cmd12: specifies that a controller can only handle auto
CMD12.
- - voltage-ranges : two cells are required, first cell specifies minimum
- slot voltage (mV), second cell specifies maximum slot voltage (mV).
- Several ranges could be specified.
Example:
interrupt-parent = <&ipic>;
/* Filled in by U-Boot */
clock-frequency = <0>;
- voltage-ranges = <3300 3300>;
};
- cap-mmc-highspeed: MMC high-speed timing is supported
- cap-power-off-card: powering off the card is safe
- cap-sdio-irq: enable SDIO IRQ signalling on this interface
-- full-pwr-cycle: full power cycle of the card is supported
*NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
polarity properties, we have to fix the meaning of the "normal" and "inverted"
-* Synopsys Designware Mobile Storage Host Controller
+* Synopsis Designware Mobile Storage Host Controller
-The Synopsys designware mobile storage host controller is used to interface
+The Synopsis designware mobile storage host controller is used to interface
a SoC with storage medium such as eMMC or SD/MMC cards. This file documents
differences between the core mmc properties described by mmc.txt and the
-properties used by the Synopsys Designware Mobile Storage Host Controller.
+properties used by the Synopsis Designware Mobile Storage Host Controller.
Required Properties:
* compatible: should be
- - snps,dw-mshc: for controllers compliant with synopsys dw-mshc.
+ - snps,dw-mshc: for controllers compliant with synopsis dw-mshc.
* #address-cells: should be 1.
* #size-cells: should be 0.
Optional properties:
-* clocks: from common clock binding: handle to biu and ciu clocks for the
- bus interface unit clock and the card interface unit clock.
-
-* clock-names: from common clock binding: Shall be "biu" and "ciu".
- If the biu clock is missing we'll simply skip enabling it. If the
- ciu clock is missing we'll just assume that the clock is running at
- clock-frequency. It is an error to omit both the ciu clock and the
- clock-frequency.
-
-* clock-frequency: should be the frequency (in Hz) of the ciu clock. If this
- is specified and the ciu clock is specified then we'll try to set the ciu
- clock to this at probe time.
-
-* clock-freq-min-max: Minimum and Maximum clock frequency for card output
- clock(cclk_out). If it's not specified, max is 200MHZ and min is 400KHz by default.
-
* num-slots: specifies the number of slots supported by the controller.
The number of physical slots actually used could be equal or less than the
value specified by num-slots. If this property is not specified, the value
* card-detect-delay: Delay in milli-seconds before detecting card after card
insert event. The default value is 0.
-* supports-highspeed: Enables support for high speed cards (up to 50MHz)
-
-* caps2-mmc-hs200-1_8v: Supports mmc HS200 SDR 1.8V mode
-
-* caps2-mmc-hs200-1_2v: Supports mmc HS200 SDR 1.2V mode
+* supports-highspeed: Enables support for high speed cards (upto 50MHz)
* broken-cd: as documented in mmc core bindings.
-* vmmc-supply: The phandle to the regulator to use for vmmc. If this is
- specified we'll defer probe until we can find this regulator.
-
Aliases:
- All the MSHC controller nodes should be represented in the aliases node using
dwmmc0@12200000 {
compatible = "snps,dw-mshc";
- clocks = <&clock 351>, <&clock 132>;
- clock-names = "biu", "ciu";
reg = <0x12200000 0x1000>;
interrupts = <0 75 0>;
#address-cells = <1>;
};
dwmmc0@12200000 {
- clock-frequency = <400000000>;
- clock-freq-min-max = <400000 200000000>;
num-slots = <1>;
supports-highspeed;
- caps2-mmc-hs200-1_8v;
broken-cd;
fifo-depth = <0x80>;
card-detect-delay = <200>;
- vmmc-supply = <&buck8>;
slot@0 {
reg = <0>;
Arguments for parameters:
-- bias-pull-up, -down and -pin-default take as optional argument on hardware
- supporting it the pull strength in Ohm. bias-disable will disable the pull.
+- bias-pull-up, -down and -pin-default take as optional argument 0 to disable
+ the pull, on hardware supporting it the pull strength in Ohm. bias-disable
+ will also disable any active pull.
- drive-strength takes as argument the target strength in mA.
ramtron Ramtron International
realtek Realtek Semiconductor Corp.
renesas Renesas Electronics Corporation
-rockchip Fuzhou Rockchip Electronics Co., Ltd
samsung Samsung Semiconductor
sbs Smart Battery System
schindler Schindler
Optional properties:
- pwm-names: a list of names for the PWM devices specified in the
"pwms" property (see PWM binding[0])
- - enable-gpios: contains a single GPIO specifier for the GPIO which enables
- and disables the backlight (see GPIO binding[1])
[0]: Documentation/devicetree/bindings/pwm/pwm.txt
-[1]: Documentation/devicetree/bindings/gpio/gpio.txt
Example:
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <6>;
-
- enable-gpios = <&gpio 58 0>;
};
vfront-porch, vback-porch, vsync-len: vertical display timing parameters in
lines
- clock-frequency: display clock in Hz
- - screen-type: screen interface type,such as SCREEN_LVDS/SCREEN_RGB/SCREEN_DEP/SCREEN_MIPI,
- defined in include/dt-bindings/rkfb/rk_fb.h,this is used on RockChip platform
- - out-face : screen data width, such as OUT_P888/OUT_D888_P666/OUT_P666/OUT_P565,
- defined in include/dt-bindings/rkfb/rk_fb.h,this is used on RockChip platform
- - lvds-format: lvds data format for lvds screen,such as LVDS_8BIT_1/2/3/LVDS_6BIT,
- defined in include/dt-bindings/rkfb/rk_fb.h,this is used on RockChip platform
- - swap-rb/rg/gb: set to 1 if some screen rgb need to swap,this is used on RockChip platform
+
optional properties:
- hsync-active: hsync pulse is active low/high/ignored
- vsync-active: vsync pulse is active low/high/ignored
management callbacks provided by the PM core, defined in
driver/base/power/generic_ops.c:
+ int pm_generic_runtime_idle(struct device *dev);
+ - invoke the ->runtime_idle() callback provided by the driver of this
+ device, if defined, and call pm_runtime_suspend() for this device if the
+ return value is 0 or the callback is not defined
+
int pm_generic_runtime_suspend(struct device *dev);
- invoke the ->runtime_suspend() callback provided by the driver of this
device and return its result, or return -EINVAL if not defined
T: git git://git.xilinx.com/linux-xlnx.git
S: Supported
F: arch/arm/mach-zynq/
-F: drivers/cpuidle/cpuidle-zynq.c
-F: drivers/mmc/host/sdhci-of-arasan.c
-
-ARM SMMU DRIVER
-M: Will Deacon <will.deacon@arm.com>
-L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
-S: Maintained
-F: drivers/iommu/arm-smmu.c
ARM64 PORT (AARCH64 ARCHITECTURE)
M: Catalin Marinas <catalin.marinas@arm.com>
# Comments in this file are targeted only to the developer, do not
# expect to learn how to build the kernel reading this file.
-SUBLEVEL = 0
-
# Do not:
# o use make's built-in rules and variables
# (this increases performance and avoids hard-to-debug behaviour);
# "make" in the configured kernel build directory always uses that.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
-ARCH ?= arm
ARCH ?= $(SUBARCH)
-ifeq ($(ARCH),arm64)
-ifneq ($(wildcard ../prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9),)
-CROSS_COMPILE ?= ../prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-
-endif
-endif
-ifeq ($(ARCH),arm)
-ifneq ($(wildcard ../prebuilts/gcc/linux-x86/arm/arm-eabi-4.6),)
-CROSS_COMPILE ?= ../prebuilts/gcc/linux-x86/arm/arm-eabi-4.6/bin/arm-eabi-
-endif
-endif
CROSS_COMPILE ?= $(CONFIG_CROSS_COMPILE:"%"=%)
# Architecture as present in compile.h
PERL = perl
CHECK = sparse
-# Use the wrapper for the compiler. This wrapper scans for new
-# warnings and causes the build to stop upon encountering them.
-ifneq ($(wildcard $(srctree)/scripts/gcc-wrapper.py),)
-CC = $(srctree)/scripts/gcc-wrapper.py $(CROSS_COMPILE)gcc
-endif
-
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void $(CF)
CFLAGS_MODULE =
export KBUILD_AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
export KBUILD_AFLAGS_MODULE KBUILD_CFLAGS_MODULE KBUILD_LDFLAGS_MODULE
export KBUILD_AFLAGS_KERNEL KBUILD_CFLAGS_KERNEL
-export KBUILD_ARFLAGS OBJCOPY_OUTPUT_FORMAT
+export KBUILD_ARFLAGS
# When compiling out-of-tree modules, put MODVERDIR in the module
# tree rather than in the kernel tree. The kernel tree might
LDFLAGS_vmlinux += $(call ld-option, -X,)
endif
-ifeq ($(CONFIG_PIE),y)
-LDFLAGS_vmlinux += --just-symbols=pie/pie.syms
-endif
-
# Default kernel image to build when no specific target is given.
# KBUILD_IMAGE may be overruled on the command line or
# set in the environment
vmlinux-dirs := $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
$(core-y) $(core-m) $(drivers-y) $(drivers-m) \
- $(net-y) $(net-m) $(libs-y) $(libs-m) $(libpie-y)))
+ $(net-y) $(net-m) $(libs-y) $(libs-m)))
vmlinux-alldirs := $(sort $(vmlinux-dirs) $(patsubst %/,%,$(filter %/, \
$(init-n) $(init-) \
$(core-n) $(core-) $(drivers-n) $(drivers-) \
- $(net-n) $(net-) $(libs-n) $(libs-) $(libpie-))))
-
-pie-$(CONFIG_PIE) := pie/
+ $(net-n) $(net-) $(libs-n) $(libs-))))
init-y := $(patsubst %/, %/built-in.o, $(init-y))
core-y := $(patsubst %/, %/built-in.o, $(core-y))
libs-y1 := $(patsubst %/, %/lib.a, $(libs-y))
libs-y2 := $(patsubst %/, %/built-in.o, $(libs-y))
libs-y := $(libs-y1) $(libs-y2)
-pie-y := $(patsubst %/, %/built-in.o, $(pie-y))
-libpie-y := $(patsubst %/, %/built-in.o, $(libpie-y))
# Externally visible symbols (used by link-vmlinux.sh)
export KBUILD_VMLINUX_INIT := $(head-y) $(init-y)
export KBUILD_VMLINUX_MAIN := $(core-y) $(libs-y) $(drivers-y) $(net-y)
-export KBUILD_VMLINUX_PIE := $(pie-y)
-export KBUILD_LIBPIE := $(libpie-y)
-export KBUILD_PIE_LDS := $(PIE_LDS)
export KBUILD_LDS := arch/$(SRCARCH)/kernel/vmlinux.lds
export LDFLAGS_vmlinux
# used by scripts/pacmage/Makefile
export KBUILD_ALLDIRS := $(sort $(filter-out arch/%,$(vmlinux-alldirs)) arch Documentation include samples scripts tools virt)
-vmlinux-deps := $(KBUILD_LDS) $(KBUILD_PIE_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN) $(KBUILD_VMLINUX_PIE) $(KBUILD_LIBPIE)
+vmlinux-deps := $(KBUILD_LDS) $(KBUILD_VMLINUX_INIT) $(KBUILD_VMLINUX_MAIN)
# Final link of vmlinux
cmd_link-vmlinux = $(CONFIG_SHELL) $< $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux)
#
clean: rm-dirs := $(CLEAN_DIRS)
clean: rm-files := $(CLEAN_FILES)
-clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation samples pie)
+clean-dirs := $(addprefix _clean_, . $(vmlinux-alldirs) Documentation samples)
PHONY += $(clean-dirs) clean archclean vmlinuxclean
$(clean-dirs):
select HAVE_MEMBLOCK
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_PERF_EVENTS
- select HAVE_PIE
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_UID16
source "arch/arm/mach-realview/Kconfig"
-source "arch/arm/mach-rockchip/Kconfig"
-
source "arch/arm/mach-sa1100/Kconfig"
source "arch/arm/plat-samsung/Kconfig"
which sends an IPI to the CPUs that are running the same ASID
as the one being invalidated.
-config ARM_ERRATA_818325
- bool "ARM errata: Execution of an UNPREDICTABLE STR or STM instruction might deadlock"
- depends on CPU_V7
- help
- This option enables the workaround for the 818325 Cortex-A12
- (r0p0..r0p1-00lac0-rc11) erratum. When a CPU executes a sequence of
- two conditional store instructions with opposite condition code and
- updating the same register, the system might enter a deadlock if the
- second conditional instruction is an UNPREDICTABLE STR or STM
- instruction. This workaround setting bit[12] of the Feature Register
- prevents the erratum. This bit disables an optimisation applied to a
- sequence of 2 instructions that use opposing condition codes.
-
-config ARM_ERRATA_821420
- bool "ARM errata: A sequence of VMOV to core registers instruction might lead to a deadlock"
- depends on CPU_V7
- help
- This option enables the workaround for the 821420 Cortex-A12 (r0p0,
- r0p1) erratum. In very rare timing conditions, a sequence of VMOV to
- Core registers instructions, for which the second one is in the
- shadow of a branch or abort, can lead to a deadlock when the VMOV
- instructions are issued out-of-order.
-
endmenu
source "arch/arm/common/Kconfig"
int
default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
default 512 if SOC_OMAP5
- default 512 if ARCH_ROCKCHIP
default 392 if ARCH_U8500
default 352 if ARCH_VT8500
default 288 if ARCH_SUNXI
their output to the standard serial port on the RealView
PB1176 platform.
- config DEBUG_ROCKCHIP_UART
- depends on ARCH_ROCKCHIP
- bool "Use UART on Rockchip SoCs"
- help
- Say Y here if you want kernel low-level debugging support
- on Rockchip SoCs.
-
config DEBUG_S3C_UART0
depends on PLAT_SAMSUNG
select DEBUG_EXYNOS_UART if ARCH_EXYNOS
default "debug/picoxcell.S" if DEBUG_PICOXCELL_UART
default "debug/pxa.S" if DEBUG_PXA_UART1 || DEBUG_MMP_UART2 || \
DEBUG_MMP_UART3
- default "debug/rockchip.S" if DEBUG_ROCKCHIP_UART
default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
default "debug/socfpga.S" if DEBUG_SOCFPGA_UART
default "debug/sunxi.S" if DEBUG_SUNXI_UART0 || DEBUG_SUNXI_UART1
kernel low-level debugging functions. Add earlyprintk to your
kernel parameters to enable this console.
-config EARLY_PRINTK_DIRECT
- bool "Early printk direct"
- depends on DEBUG_LL
- help
- Say Y here if you want to have an early console using the
- kernel low-level debugging functions and EARLY_PRINTK is
- not early enough.
-
config ARM_KPROBES_TEST
tristate "Kprobes test module"
depends on KPROBES && MODULES
CHECKFLAGS += -D__arm__
-OBJCOPY_OUTPUT_FORMAT := elf32-littlearm
-
#Default value
head-y := arch/arm/kernel/head$(MMUEXT).o
textofs-y := 0x00008000
machine-$(CONFIG_ARCH_PRIMA2) += prima2
machine-$(CONFIG_ARCH_PXA) += pxa
machine-$(CONFIG_ARCH_REALVIEW) += realview
-machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip
machine-$(CONFIG_ARCH_RPC) += rpc
machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx
machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx
libs-y := arch/arm/lib/ $(libs-y)
-PIE_LDS := arch/arm/kernel/pie.lds
-libpie-$(CONFIG_PIE) += arch/arm/libpie/
-
# Default target when executing plain make
ifeq ($(CONFIG_XIP_KERNEL),y)
KBUILD_IMAGE := xipImage
echo ' (distribution) /sbin/$(INSTALLKERNEL) or'
echo ' install to $$(INSTALL_PATH) and run lilo'
endef
-
-kernel.img: zImage
- $(Q)$(srctree)/mkkrnlimg $(objtree)/arch/arm/boot/zImage $(objtree)/kernel.img >/dev/null
- @echo ' Image: kernel.img is ready'
-
-%_kernel.img: %.dtb zImage
- $(Q)cat $(objtree)/arch/arm/boot/zImage $(objtree)/arch/arm/boot/dts/$*.dtb > $(objtree)/zImage-dtb && \
- $(srctree)/mkkrnlimg $(objtree)/zImage-dtb $(objtree)/kernel.img >/dev/null && \
- rm -f $(objtree)/zImage-dtb
- @echo ' Image: kernel.img (with $*.dtb) is ready'
-
-LOGO := $(notdir $(wildcard $(srctree)/logo.bmp))
-LOGO_KERNEL := $(notdir $(wildcard $(srctree)/logo_kernel.bmp))
-%.img: %.dtb kernel.img $(LOGO) $(LOGO_KERNEL)
- $(Q)$(srctree)/resource_tool $(objtree)/arch/arm/boot/dts/$*.dtb $(LOGO) $(LOGO_KERNEL)
- @echo ' Image: resource.img (with $*.dtb $(LOGO) $(LOGO_KERNEL)) is ready'
KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS))
endif
-ifeq ($(CONFIG_CC_STACKPROTECTOR),y)
-ORIG_CFLAGS := $(KBUILD_CFLAGS)
-KBUILD_CFLAGS = $(subst -fstack-protector, , $(ORIG_CFLAGS))
-endif
-
ccflags-y := -fpic -mno-single-pic-base -fno-builtin -I$(obj)
asflags-y := -DZIMAGE
#include <linux/linkage.h>
#include <asm/assembler.h>
-#ifdef CONFIG_ARM_TRUSTZONE
-#undef CONFIG_MMU
-#endif
.arch armv7-a
/*
* Debugging stuff
@ determine final kernel image address
mov r4, pc
and r4, r4, #0xf8000000
-#ifdef CONFIG_ARM_TRUSTZONE
- mov r4, #0
-#endif
add r4, r4, #TEXT_OFFSET
#else
ldr r4, =zreladdr
movne r1, #0xfffffffd @ domain 0 = client
bic r6, r6, #1 << 31 @ 32-bit translation system
bic r6, r6, #3 << 0 @ use only ttbr0
-#ifdef CONFIG_ARM_TRUSTZONE
- mov r6, #0
-#endif
mcrne p15, 0, r3, c2, c0, 0 @ load page table pointer
mcrne p15, 0, r0, c8, c7, 0 @ flush I,D TLBs
mcr p15, 0, r0, c7, c5, 4 @ ISB
am335x-bone.dtb
dtb-$(CONFIG_ARCH_ORION5X) += orion5x-lacie-ethernet-disk-mini-v2.dtb
dtb-$(CONFIG_ARCH_PRIMA2) += prima2-evb.dtb
-dtb-$(CONFIG_ARCH_ROCKCHIP) += \
- rk3036-fpga.dtb \
- rk3036-new.dtb \
- rk3036-rk88.dtb \
- rk3036-sdk.dtb \
- rk3126-86v.dtb \
- rk3126-fpga.dtb \
- rk3126-sdk.dtb \
- rk3128-86v.dtb \
- rk3128-box.dtb \
- rk3128-box-ns.dtb \
- rk3128-box-rk88.dtb \
- rk3128-sdk.dtb \
- rk3228-fpga.dtb \
- rk3228-sdk.dtb \
- rk3288-box.dtb \
- rk3288-p977_8846.dtb \
- rk3288-p977.dtb \
- rk3288-popmetal.dtb \
- rk3288-tb_8846.dtb \
- rk3288-tb.dtb \
- rk3288-tb_sec.dtb
dtb-$(CONFIG_ARCH_U8500) += snowball.dtb \
hrefprev60.dtb \
hrefv60plus.dtb \
return val;
}
-static inline u64 arch_counter_get_cntpct(void)
-{
- u64 cval;
-
- isb();
- asm volatile("mrrc p15, 0, %Q0, %R0, c14" : "=r" (cval));
- return cval;
-}
-
static inline u64 arch_counter_get_cntvct(void)
{
u64 cval;
#define R_ARM_NONE 0
#define R_ARM_PC24 1
#define R_ARM_ABS32 2
-#define R_ARM_RELATIVE 23
#define R_ARM_CALL 28
#define R_ARM_JUMP24 29
#define R_ARM_V4BX 40
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#ifndef __ASM_FNCPY_H
-#define __ASM_FNCPY_H
-
-#include <linux/types.h>
-
/*
+ * These macros are intended for use when there is a need to copy a low-level
+ * function body into special memory.
+ *
+ * For example, when reconfiguring the SDRAM controller, the code doing the
+ * reconfiguration may need to run from SRAM.
+ *
+ * NOTE: that the copied function body must be entirely self-contained and
+ * position-independent in order for this to work properly.
+ *
* NOTE: in order for embedded literals and data to get referenced correctly,
* the alignment of functions must be preserved when copying. To ensure this,
* the source and destination addresses for fncpy() must be aligned to a
* You will typically need a ".align 3" directive in the assembler where the
* function to be copied is defined, and ensure that your allocator for the
* destination buffer returns 8-byte-aligned pointers.
-*/
-#define ARCH_FNCPY_ALIGN 3
+ *
+ * Typical usage example:
+ *
+ * extern int f(args);
+ * extern uint32_t size_of_f;
+ * int (*copied_f)(args);
+ * void *sram_buffer;
+ *
+ * copied_f = fncpy(sram_buffer, &f, size_of_f);
+ *
+ * ... later, call the function: ...
+ *
+ * copied_f(args);
+ *
+ * The size of the function to be copied can't be determined from C:
+ * this must be determined by other means, such as adding assmbler directives
+ * in the file where f is defined.
+ */
-/* Clear the Thumb bit */
-#define fnptr_to_addr(funcp) ({ \
+#ifndef __ASM_FNCPY_H
+#define __ASM_FNCPY_H
+
+#include <linux/types.h>
+#include <linux/string.h>
+
+#include <asm/bug.h>
+#include <asm/cacheflush.h>
+
+/*
+ * Minimum alignment requirement for the source and destination addresses
+ * for function copying.
+ */
+#define FNCPY_ALIGN 8
+
+#define fncpy(dest_buf, funcp, size) ({ \
uintptr_t __funcp_address; \
+ typeof(funcp) __result; \
\
asm("" : "=r" (__funcp_address) : "0" (funcp)); \
- __funcp_address & ~1; \
-})
-
-/* Put the Thumb bit back */
-#define fnptr_translate(orig_funcp, new_addr) ({ \
- uintptr_t __funcp_address; \
- typeof(orig_funcp) __result; \
\
- asm("" : "=r" (__funcp_address) : "0" (orig_funcp)); \
+ /* \
+ * Ensure alignment of source and destination addresses, \
+ * disregarding the function's Thumb bit: \
+ */ \
+ BUG_ON((uintptr_t)(dest_buf) & (FNCPY_ALIGN - 1) || \
+ (__funcp_address & ~(uintptr_t)1 & (FNCPY_ALIGN - 1))); \
+ \
+ memcpy(dest_buf, (void const *)(__funcp_address & ~1), size); \
+ flush_icache_range((unsigned long)(dest_buf), \
+ (unsigned long)(dest_buf) + (size)); \
+ \
asm("" : "=r" (__result) \
- : "0" ((uintptr_t)(new_addr) | (__funcp_address & 1))); \
+ : "0" ((uintptr_t)(dest_buf) | (__funcp_address & 1))); \
\
__result; \
})
-#include <asm-generic/fncpy.h>
-
#endif /* !__ASM_FNCPY_H */
#define ioremap_nocache(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE)
#define ioremap_cached(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_CACHED)
#define ioremap_wc(cookie,size) __arm_ioremap((cookie), (size), MT_DEVICE_WC)
-#define ioremap_exec(cookie,size) __arm_ioremap_exec((cookie), (size), true)
-#define ioremap_exec_nocache(cookie,size) __arm_ioremap_exec((cookie), (size), false)
#define iounmap __arm_iounmap
/*
#ifndef __ASM_ARM_SUSPEND_H
#define __ASM_ARM_SUSPEND_H
-#include <asm/pie.h>
-
extern void cpu_resume(void);
extern int cpu_suspend(unsigned long, int (*)(unsigned long));
-/**
- * ARM_PIE_RESUME - generate a PIE trampoline for resume
- * @proc: SoC, should match argument used with PIE_OVERLAY_SECTION()
- * @func: C or asm function to call at resume
- * @stack: stack to use before calling func
- */
-#define ARM_PIE_RESUME(proc, func, stack) \
-static void __naked __noreturn __pie(proc) proc##_resume_trampoline2(void) \
-{ \
- __asm__ __volatile__( \
- " mov sp, %0\n" \
- : : "r"((stack)) : "sp"); \
- \
- func(); \
-} \
- \
-void __naked __noreturn __pie(proc) proc##_resume_trampoline(void) \
-{ \
- pie_relocate_from_pie(); \
- proc##_resume_trampoline2(); \
-} \
-EXPORT_PIE_SYMBOL(proc##_resume_trampoline)
-
#endif
obj-$(CONFIG_SMP) += psci_smp.o
endif
-obj-$(CONFIG_PIE) += pie.o
-
-extra-y := $(head-y) vmlinux.lds pie.lds
+extra-y := $(head-y) vmlinux.lds
*/
static struct of_device_id cpu_pmu_of_device_ids[] = {
{.compatible = "arm,cortex-a15-pmu", .data = armv7_a15_pmu_init},
- {.compatible = "arm,cortex-a12-pmu", .data = armv7_a12_pmu_init},
{.compatible = "arm,cortex-a9-pmu", .data = armv7_a9_pmu_init},
{.compatible = "arm,cortex-a8-pmu", .data = armv7_a8_pmu_init},
{.compatible = "arm,cortex-a7-pmu", .data = armv7_a7_pmu_init},
ARMV7_A15_PERFCTR_PC_WRITE_SPEC = 0x76,
};
-/* ARMv7 Cortex-A12 specific event types */
-enum armv7_a12_perf_types {
- ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ = 0x40,
- ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE = 0x41,
-
- ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ = 0x50,
- ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE = 0x51,
-
- ARMV7_A12_PERFCTR_PC_WRITE_SPEC = 0x76,
-
- ARMV7_A12_PERFCTR_PF_TLB_REFILL = 0xe7,
-};
-
/*
* Cortex-A8 HW events mapping
*
},
};
-/*
- * Cortex-A12 HW events mapping
- */
-static const unsigned armv7_a12_perf_map[PERF_COUNT_HW_MAX] = {
- [PERF_COUNT_HW_CPU_CYCLES] = ARMV7_PERFCTR_CPU_CYCLES,
- [PERF_COUNT_HW_INSTRUCTIONS] = ARMV7_PERFCTR_INSTR_EXECUTED,
- [PERF_COUNT_HW_CACHE_REFERENCES] = ARMV7_PERFCTR_L1_DCACHE_ACCESS,
- [PERF_COUNT_HW_CACHE_MISSES] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_A12_PERFCTR_PC_WRITE_SPEC,
- [PERF_COUNT_HW_BRANCH_MISSES] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- [PERF_COUNT_HW_BUS_CYCLES] = ARMV7_PERFCTR_BUS_CYCLES,
- [PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = HW_OP_UNSUPPORTED,
- [PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = HW_OP_UNSUPPORTED,
-};
-
-static const unsigned armv7_a12_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
- [PERF_COUNT_HW_CACHE_OP_MAX]
- [PERF_COUNT_HW_CACHE_RESULT_MAX] = {
- [C(L1D)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_READ,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L1_DCACHE_ACCESS_WRITE,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_DCACHE_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(L1I)] = {
- /*
- * Not all performance counters differentiate between read
- * and write accesses/misses so we're not always strictly
- * correct, but it's the best we can do. Writes and reads get
- * combined in these cases.
- */
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_L1_ICACHE_ACCESS,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L1_ICACHE_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(LL)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_READ,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_A12_PERFCTR_L2_CACHE_ACCESS_WRITE,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_L2_CACHE_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(DTLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_DTLB_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_A12_PERFCTR_PF_TLB_REFILL,
- },
- },
- [C(ITLB)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_ITLB_REFILL,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(BPU)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = ARMV7_PERFCTR_PC_BRANCH_PRED,
- [C(RESULT_MISS)] = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
- [C(NODE)] = {
- [C(OP_READ)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_WRITE)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- [C(OP_PREFETCH)] = {
- [C(RESULT_ACCESS)] = CACHE_OP_UNSUPPORTED,
- [C(RESULT_MISS)] = CACHE_OP_UNSUPPORTED,
- },
- },
-};
-
/*
* Perf Events' indices
*/
&armv7_a7_perf_cache_map, 0xFF);
}
-static int armv7_a12_map_event(struct perf_event *event)
-{
- return armpmu_map_event(event, &armv7_a12_perf_map,
- &armv7_a12_perf_cache_map, 0xFF);
-}
-
static void armv7pmu_init(struct arm_pmu *cpu_pmu)
{
cpu_pmu->handle_irq = armv7pmu_handle_irq;
cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
return 0;
}
-
-static int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
-{
- armv7pmu_init(cpu_pmu);
- cpu_pmu->name = "ARMv7 Cortex-A12";
- cpu_pmu->map_event = armv7_a12_map_event;
- cpu_pmu->num_events = armv7_read_num_pmnc_events();
- cpu_pmu->set_event_filter = armv7pmu_set_event_filter;
- return 0;
-}
#else
static inline int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu)
{
{
return -ENODEV;
}
-
-static inline int armv7_a12_pmu_init(struct arm_pmu *cpu_pmu)
-{
- return -ENODEV;
-}
#endif /* CONFIG_CPU_V7 */
*/
void machine_halt(void)
{
- local_irq_disable();
smp_send_stop();
local_irq_disable();
*/
void machine_power_off(void)
{
- local_irq_disable();
smp_send_stop();
if (pm_power_off)
*/
void machine_restart(char *cmd)
{
- local_irq_disable();
smp_send_stop();
/* Flush the console to make sure all the relevant messages make it
int i, j;
u32 cpuid;
-#ifdef CONFIG_ARCH_ROCKCHIP
- seq_printf(m, "Processor\t: %s rev %d (%s)\n",
- cpu_name, read_cpuid_id() & 15, elf_platform);
-#endif
for_each_online_cpu(i) {
/*
* glibc reads /proc/cpuinfo to determine the number of
#ifndef CONFIG_SMP_ON_UP
*(.alt.smp.init)
#endif
- *(.pie.*)
- *(.ARM.exidx.pie.*.text)
*(.discard)
*(.discard.*)
}
return ret;
}
+static int _od_runtime_idle(struct device *dev)
+{
+ return pm_generic_runtime_idle(dev);
+}
+
static int _od_runtime_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct dev_pm_domain omap_device_pm_domain = {
.ops = {
SET_RUNTIME_PM_OPS(_od_runtime_suspend, _od_runtime_resume,
- NULL)
+ _od_runtime_idle)
USE_PLATFORM_PM_SLEEP_OPS
.suspend_noirq = _od_suspend_noirq,
.resume_noirq = _od_resume_noirq,
comment "Processor Features"
-config ARM_TRUSTZONE
- bool "Support TrustZone-enabled Trusted Execution Environment"
- default n
- help
- Select if you want a kernel to be executed at non-secure world.
- This option should be used with related secure bootloader and
- TrustZone software.
-
- If you don't know about TrustZone, say 'N'.
-
config ARM_LPAE
bool "Support for the Large Physical Address Extension"
depends on MMU && CPU_32v7 && !CPU_32v6 && !CPU_32v5 && \
static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page,
-#ifdef CONFIG_ARCH_ROCKCHIP
- struct dma_attrs *attrs,
-#endif
const void *caller);
static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
if (IS_ENABLED(CONFIG_DMA_CMA))
ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page,
-#ifdef CONFIG_ARCH_ROCKCHIP
- NULL,
-#endif
atomic_pool_init);
else
ptr = __alloc_remap_buffer(NULL, pool->size, gfp, prot, &page,
static void *__alloc_from_contiguous(struct device *dev, size_t size,
pgprot_t prot, struct page **ret_page,
-#ifdef CONFIG_ARCH_ROCKCHIP
- struct dma_attrs *attrs,
-#endif
const void *caller)
{
unsigned long order = get_order(size);
__dma_clear_buffer(page, size);
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
- return (*ret_page=page);
-#endif
-
if (PageHighMem(page)) {
ptr = __dma_alloc_remap(page, size, GFP_KERNEL, prot, caller);
if (!ptr) {
return ptr;
}
-#ifdef CONFIG_ARCH_ROCKCHIP
-static void __free_from_contiguous(struct device *dev, struct page *page,
- void *cpu_addr, size_t size,
- struct dma_attrs *attrs)
-{
- if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) {
- if (PageHighMem(page))
- __dma_free_remap(cpu_addr, size);
- else
- __dma_remap(page, size, pgprot_kernel);
- }
- dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
-}
-#else
static void __free_from_contiguous(struct device *dev, struct page *page,
void *cpu_addr, size_t size)
{
__dma_remap(page, size, pgprot_kernel);
dma_release_from_contiguous(dev, page, size >> PAGE_SHIFT);
}
-#endif
static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
{
#define __get_dma_pgprot(attrs, prot) __pgprot(0)
#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL
#define __alloc_from_pool(size, ret_page) NULL
-#ifdef CONFIG_ARCH_ROCKCHIP
-#define __alloc_from_contiguous(dev, size, prot, ret, attrs, c) NULL
-#else
#define __alloc_from_contiguous(dev, size, prot, ret, c) NULL
-#endif
#define __free_from_pool(cpu_addr, size) 0
-#ifdef CONFIG_ARCH_ROCKCHIP
-#define __free_from_contiguous(dev, page, cpu_addr, size, attrs) do { } while (0)
-#else
#define __free_from_contiguous(dev, page, cpu_addr, size) do { } while (0)
-#endif
#define __dma_free_remap(cpu_addr, size) do { } while (0)
#endif /* CONFIG_MMU */
static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
-#ifdef CONFIG_ARCH_ROCKCHIP
- gfp_t gfp, pgprot_t prot, bool is_coherent,
- struct dma_attrs *attrs, const void *caller)
-#else
gfp_t gfp, pgprot_t prot, bool is_coherent, const void *caller)
-#endif
{
u64 mask = get_coherent_dma_mask(dev);
struct page *page = NULL;
else if (!IS_ENABLED(CONFIG_DMA_CMA))
addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
else
-#ifdef CONFIG_ARCH_ROCKCHIP
- addr = __alloc_from_contiguous(dev, size, prot, &page, attrs, caller);
-#else
addr = __alloc_from_contiguous(dev, size, prot, &page, caller);
-#endif
if (addr)
*handle = pfn_to_dma(dev, page_to_pfn(page));
return memory;
return __dma_alloc(dev, size, handle, gfp, prot, false,
-#ifdef CONFIG_ARCH_ROCKCHIP
- attrs,
-#endif
__builtin_return_address(0));
}
return memory;
return __dma_alloc(dev, size, handle, gfp, prot, true,
-#ifdef CONFIG_ARCH_ROCKCHIP
- attrs,
-#endif
__builtin_return_address(0));
}
* Non-atomic allocations cannot be freed with IRQs disabled
*/
WARN_ON(irqs_disabled());
-#ifdef CONFIG_ARCH_ROCKCHIP
- __free_from_contiguous(dev, page, cpu_addr, size, attrs);
-#else
__free_from_contiguous(dev, page, cpu_addr, size);
-#endif
}
}
for (i = 0; i < mi->nr_banks; i++)
memblock_add(mi->bank[i].start, mi->bank[i].size);
-//#ifdef CONFIG_ARCH_ROCKCHIP
- for (i = 1; i < memblock.memory.cnt; i++) {
- struct memblock_region *rgn = &memblock.memory.regions[i];
-
- if (rgn->size != memblock.memory.regions[i-1].size)
- memblock_reserve(rgn->base+rgn->size-PAGE_SIZE, PAGE_SIZE);
- }
-//#endif
-
/* Register the kernel text, kernel data and initrd with memblock. */
#ifdef CONFIG_XIP_KERNEL
memblock_reserve(__pa(_sdata), _end - _sdata);
mov r10, #(1 << 0) @ TLB ops broadcasting
b 1f
__v7_ca7mp_setup:
-__v7_ca12mp_setup:
__v7_ca15mp_setup:
mov r10, #0
1:
1:
#endif
- /* Cortex-A12 Errata */
-3: ldr r10, =0x00000c0d @ Cortex-A12 primary part number
- teq r0, r10
- bne 4f
-#ifdef CONFIG_ARM_ERRATA_818325
- teq r6, #0x00 @ present in r0p0
- teqne r6, #0x01 @ present in r0p1-00lac0-rc11
- mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
- orreq r10, r10, #1 << 12 @ set bit #12
- mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
- isb
-#endif
-#ifdef CONFIG_ARM_ERRATA_821420
- teq r6, #0x00 @ present in r0p0
- teqne r6, #0x01 @ present in r0p1
- mrceq p15, 0, r10, c15, c0, 2
- orreq r10, r10, #1 << 1
- mcreq p15, 0, r10, c15, c0, 2
- isb
-#endif
-
-4: mov r10, #0
+3: mov r10, #0
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
#ifdef CONFIG_MMU
mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs
__v7_proc __v7_ca7mp_setup
.size __v7_ca7mp_proc_info, . - __v7_ca7mp_proc_info
- /*
- * ARM Ltd. Cortex A12 processor.
- */
- .type __v7_ca12mp_proc_info, #object
-__v7_ca12mp_proc_info:
- .long 0x410fc0d0
- .long 0xff0ffff0
- __v7_proc __v7_ca12mp_setup
- .size __v7_ca12mp_proc_info, . - __v7_ca12mp_proc_info
-
/*
* ARM Ltd. Cortex A15 processor.
*/
}
new_ceil -= size;
- new_ceil = ROUND_DOWN(new_ceil, 1 << ARCH_FNCPY_ALIGN);
+ new_ceil = ROUND_DOWN(new_ceil, FNCPY_ALIGN);
omap_sram_ceil = IOMEM(new_ceil);
return (void *)omap_sram_ceil;
config IOMMU_HELPER
def_bool SWIOTLB
-config KERNEL_MODE_NEON
- def_bool y
-
config FIX_EARLYCON_MEM
def_bool y
menu "Platform selection"
-config ARCH_ROCKCHIP
- bool "Rockchip SoCs"
- select PINCTRL
- select PINCTRL_RK3368
- select ARCH_REQUIRE_GPIOLIB
-
-source "arch/arm64/mach-rockchip/Kconfig"
-
config ARCH_VEXPRESS
bool "ARMv8 software model (Versatile Express)"
select ARCH_REQUIRE_GPIOLIB
source "drivers/cpuidle/Kconfig"
-source "drivers/cpuquiet/Kconfig"
-
endmenu
source "net/Kconfig"
export TEXT_OFFSET GZFLAGS
core-y += arch/arm64/kernel/ arch/arm64/mm/
-core-$(CONFIG_ARCH_ROCKCHIP) += arch/arm64/mach-rockchip/
core-$(CONFIG_KVM) += arch/arm64/kvm/
core-$(CONFIG_CRYPTO) += arch/arm64/crypto/
libs-y := arch/arm64/lib/ $(libs-y)
echo ' (distribution) /sbin/installkernel or'
echo ' install to $$(INSTALL_PATH) and run lilo'
endef
-
-kernel.img: Image
- $(Q)$(srctree)/mkkrnlimg $(objtree)/arch/arm64/boot/Image $(objtree)/kernel.img >/dev/null
- @echo ' Image: kernel.img is ready'
-
-LOGO := $(notdir $(wildcard $(srctree)/logo.bmp))
-LOGO_KERNEL := $(notdir $(wildcard $(srctree)/logo_kernel.bmp))
-%.img: %.dtb kernel.img $(LOGO) $(LOGO_KERNEL)
- $(Q)$(srctree)/resource_tool $(objtree)/arch/arm64/boot/dts/$*.dtb $(LOGO) $(LOGO_KERNEL)
- @echo ' Image: resource.img (with $*.dtb $(LOGO) $(LOGO_KERNEL)) is ready'
-dtb-$(CONFIG_ARCH_ROCKCHIP) += \
- rk3368-box.dtb \
- rk3368-box-r88_808.dtb \
- rk3368-box-r88.dtb \
- rk3368-fpga.dtb \
- rk3368-p9_818.dtb \
- rk3368-tb_8846.dtb \
- rk3368-tb_mipi.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += rtsm_ve-aemv8a.dtb foundation-v8.dtb \
fvp-base-gicv2-psci.dtb
dtb-$(CONFIG_ARCH_VEXPRESS) += juno.dtb
#endif
}
-static inline u64 arch_counter_get_cntpct(void)
-{
- u64 cval;
-
- isb();
- asm volatile("mrs %0, cntpct_el0" : "=r" (cval));
-
- return cval;
-}
-
static inline u64 arch_counter_get_cntvct(void)
{
u64 cval;
phys_addr_t save_ptr_stash_phys;
};
-extern int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long));
extern void cpu_resume(void);
extern int cpu_suspend(unsigned long);
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/signal.h>
-#include <linux/hardirq.h>
#include <asm/fpsimd.h>
#include <asm/cputype.h>
}
#endif
-/*
- * Called by kexec, immediately prior to machine_kexec().
- *
- * This must completely disable all secondary CPUs; simply causing those CPUs
- * to execute e.g. a RAM-based pin loop is not sufficient. This allows the
- * kexec'd kernel to use any and all RAM as it sees fit, without having to
- * avoid any code or data used by any SW CPU pin loop. The CPU hotplug
- * functionality embodied in disable_nonboot_cpus() to achieve this.
- */
void machine_shutdown(void)
{
- disable_nonboot_cpus();
+#ifdef CONFIG_SMP
+ smp_send_stop();
+#endif
}
-/*
- * Halting simply requires that the secondary CPUs stop performing any
- * activity (executing tasks, handling interrupts). smp_send_stop()
- * achieves this.
- */
void machine_halt(void)
{
- local_irq_disable();
- smp_send_stop();
+ machine_shutdown();
while (1);
}
-/*
- * Power-off simply requires that the secondary CPUs stop performing any
- * activity (executing tasks, handling interrupts). smp_send_stop()
- * achieves this. When the system power is turned off, it will take all CPUs
- * with it.
- */
void machine_power_off(void)
{
- local_irq_disable();
- smp_send_stop();
+ machine_shutdown();
if (pm_power_off)
pm_power_off();
}
-/*
- * Restart requires that the secondary CPUs stop performing any activity
- * while the primary CPU resets the system. Systems with a single CPU can
- * use soft_restart() as their machine descriptor's .restart hook, since that
- * will cause the only available CPU to reset. Systems with multiple CPUs must
- * provide a HW restart implementation, to ensure that all CPUs reset at once.
- * This is required so that any code running after reset on the primary CPU
- * doesn't have to co-ordinate with other CPUs to ensure they aren't still
- * executing pre-reset code, and using RAM that the primary CPU's code wishes
- * to use. Implementing such co-ordination would be essentially impossible.
- */
void machine_restart(char *cmd)
{
+ machine_shutdown();
+
/* Disable interrupts first */
local_irq_disable();
local_fiq_disable();
- smp_send_stop();
/* Now call the architecture specific reboot code. */
if (arm_pm_restart)
{
return randomize_base(base);
}
-
-void arch_cpu_idle_enter(void)
-{
- idle_notifier_call_chain(IDLE_START);
-}
-
-void arch_cpu_idle_exit(void)
-{
- idle_notifier_call_chain(IDLE_END);
-}
#include <linux/reboot.h>
#include <linux/pm.h>
#include <linux/delay.h>
-#include <linux/slab.h>
#include <uapi/linux/psci.h>
#include <asm/compiler.h>
static void psci_power_state_unpack(u32 power_state,
struct psci_power_state *state)
{
- state->id = (power_state & PSCI_0_2_POWER_STATE_ID_MASK) >>
- PSCI_0_2_POWER_STATE_ID_SHIFT;
- state->type = (power_state & PSCI_0_2_POWER_STATE_TYPE_MASK) >>
- PSCI_0_2_POWER_STATE_TYPE_SHIFT;
- state->affinity_level =
- (power_state & PSCI_0_2_POWER_STATE_AFFL_MASK) >>
- PSCI_0_2_POWER_STATE_AFFL_SHIFT;
+ state->id = (power_state >> PSCI_0_2_POWER_STATE_ID_SHIFT)
+ & PSCI_0_2_POWER_STATE_ID_MASK;
+ state->type = (power_state >> PSCI_0_2_POWER_STATE_TYPE_SHIFT)
+ & PSCI_0_2_POWER_STATE_TYPE_MASK;
+ state->affinity_level = (power_state >> PSCI_0_2_POWER_STATE_AFFL_SHIFT)
+ & PSCI_0_2_POWER_STATE_AFFL_MASK;
}
static int psci_get_version(void)
return err;
}
-static int __maybe_unused cpu_psci_cpu_init_idle(struct device_node *cpu_node,
- unsigned int cpu)
-{
- int i, ret, count = 0;
- struct psci_power_state *psci_states;
- struct device_node *state_node;
-
- /*
- * If the PSCI cpu_suspend function hook has not been initialized
- * idle states must not be enabled, so bail out
- */
- if (!psci_ops.cpu_suspend)
- return -EOPNOTSUPP;
-
- /* Count idle states */
- while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
- count))) {
- count++;
- of_node_put(state_node);
- }
-
- if (!count)
- return -ENODEV;
-
- psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
- if (!psci_states)
- return -ENOMEM;
-
- for (i = 0; i < count; i++) {
- u32 psci_power_state;
-
- state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
-
- ret = of_property_read_u32(state_node,
- "arm,psci-suspend-param",
- &psci_power_state);
- if (ret) {
- pr_warn(" * %s missing arm,psci-suspend-param property\n",
- state_node->full_name);
- of_node_put(state_node);
- goto free_mem;
- }
-
- of_node_put(state_node);
- pr_debug("psci-power-state %#x index %d\n", psci_power_state,
- i);
- psci_power_state_unpack(psci_power_state, &psci_states[i]);
- }
- /* Idle states parsed correctly, initialize per-cpu pointer */
- per_cpu(psci_power_state, cpu) = psci_states;
- return 0;
-
-free_mem:
- kfree(psci_states);
- return ret;
-}
-
static int get_set_conduit_method(struct device_node *np)
{
const char *method;
PSCI_0_2_FN_MIGRATE_INFO_TYPE;
psci_ops.migrate_info_type = psci_migrate_info_type;
-#ifndef CONFIG_ARCH_ROCKCHIP
arm_pm_restart = psci_sys_reset;
pm_power_off = psci_sys_poweroff;
-#endif
out_put_node:
of_node_put(np);
for (i = 0; i < 10; i++) {
err = psci_ops.affinity_info(cpu_logical_map(cpu), 0);
if (err == PSCI_0_2_AFFINITY_LEVEL_OFF) {
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- if (system_state != SYSTEM_RUNNING)
-#endif
pr_info("CPU%d killed.\n", cpu);
return 1;
}
msleep(10);
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- if (system_state != SYSTEM_RUNNING)
-#endif
pr_info("Retrying again to check for CPU kill\n");
}
#endif
#ifdef CONFIG_ARM64_CPU_SUSPEND
-static int psci_suspend_finisher(unsigned long index)
+static int cpu_psci_cpu_suspend(unsigned long index)
{
struct psci_power_state *state = __get_cpu_var(psci_power_state);
- return psci_ops.cpu_suspend(state[index - 1],
- virt_to_phys(cpu_resume));
-}
-
-static int __maybe_unused cpu_psci_cpu_suspend(unsigned long index)
-{
- int ret;
- struct psci_power_state *state = __get_cpu_var(psci_power_state);
- /*
- * idle state index 0 corresponds to wfi, should never be called
- * from the cpu_suspend operations
- */
- if (WARN_ON_ONCE(!index))
- return -EINVAL;
-
if (!state)
return -EOPNOTSUPP;
- if (state[index - 1].type == PSCI_POWER_STATE_TYPE_STANDBY)
- ret = psci_ops.cpu_suspend(state[index - 1], 0);
- else
- ret = __cpu_suspend(index, psci_suspend_finisher);
- return ret;
+ return psci_ops.cpu_suspend(state[index], virt_to_phys(cpu_resume));
}
#endif
const struct cpu_operations cpu_psci_ops = {
.name = "psci",
-#ifdef CONFIG_CPU_IDLE
- .cpu_init_idle = cpu_psci_cpu_init_idle,
-#endif
#ifdef CONFIG_SMP
.cpu_init = cpu_psci_cpu_init,
.cpu_prepare = cpu_psci_cpu_prepare,
static const char *cpu_name;
static const char *machine_name;
-
-unsigned int system_rev;
-EXPORT_SYMBOL(system_rev);
-
-unsigned int system_serial_low;
-EXPORT_SYMBOL(system_serial_low);
-
-unsigned int system_serial_high;
-EXPORT_SYMBOL(system_serial_high);
-
phys_addr_t __fdt_pointer __initdata;
/*
* software which does already (at least for 32-bit).
*/
seq_puts(m, "Features\t:");
- if (personality(current->personality) == PER_LINUX32 ||
- is_compat_task()) {
+ if (personality(current->personality) == PER_LINUX32) {
#ifdef CONFIG_COMPAT
for (j = 0; compat_hwcap_str[j]; j++)
if (COMPAT_ELF_HWCAP & (1 << j))
seq_printf(m, "CPU revision\t: %d\n\n", (midr & 0xf));
}
- seq_printf(m, "Hardware\t: %s\n", machine_name);
- seq_printf(m, "Revision\t: %04x\n", system_rev);
- seq_printf(m, "Serial\t\t: %08x%08x\n",
- system_serial_high, system_serial_low);
-
return 0;
}
orr \dst, \dst, \mask // dst|=(aff3>>rs3)
.endm
/*
- * Save CPU state for a suspend and execute the suspend finisher.
- * On success it will return 0 through cpu_resume - ie through a CPU
- * soft/hard reboot from the reset vector.
- * On failure it returns the suspend finisher return value or force
- * -EOPNOTSUPP if the finisher erroneously returns 0 (the suspend finisher
- * is not allowed to return, if it does this must be considered failure).
- * It saves callee registers, and allocates space on the kernel stack
- * to save the CPU specific registers + some other data for resume.
+ * Save CPU state for a suspend. This saves callee registers, and allocates
+ * space on the kernel stack to save the CPU specific registers + some
+ * other data for resume.
*
* x0 = suspend finisher argument
- * x1 = suspend finisher function pointer
*/
-ENTRY(__cpu_suspend_enter)
+ENTRY(__cpu_suspend)
stp x29, lr, [sp, #-96]!
stp x19, x20, [sp,#16]
stp x21, x22, [sp,#32]
stp x23, x24, [sp,#48]
stp x25, x26, [sp,#64]
stp x27, x28, [sp,#80]
- /*
- * Stash suspend finisher and its argument in x20 and x19
- */
- mov x19, x0
- mov x20, x1
mov x2, sp
sub sp, sp, #CPU_SUSPEND_SZ // allocate cpu_suspend_ctx
- mov x0, sp
+ mov x1, sp
/*
- * x0 now points to struct cpu_suspend_ctx allocated on the stack
+ * x1 now points to struct cpu_suspend_ctx allocated on the stack
*/
- str x2, [x0, #CPU_CTX_SP]
- ldr x1, =sleep_save_sp
- ldr x1, [x1, #SLEEP_SAVE_SP_VIRT]
+ str x2, [x1, #CPU_CTX_SP]
+ ldr x2, =sleep_save_sp
+ ldr x2, [x2, #SLEEP_SAVE_SP_VIRT]
#ifdef CONFIG_SMP
mrs x7, mpidr_el1
ldr x9, =mpidr_hash
ldp w3, w4, [x9, #MPIDR_HASH_SHIFTS]
ldp w5, w6, [x9, #(MPIDR_HASH_SHIFTS + 8)]
compute_mpidr_hash x8, x3, x4, x5, x6, x7, x10
- add x1, x1, x8, lsl #3
+ add x2, x2, x8, lsl #3
#endif
- bl __cpu_suspend_save
- /*
- * Grab suspend finisher in x20 and its argument in x19
- */
- mov x0, x19
- mov x1, x20
- /*
- * We are ready for power down, fire off the suspend finisher
- * in x1, with argument in x0
- */
- blr x1
+ bl __cpu_suspend_finisher
/*
- * Never gets here, unless suspend finisher fails.
+ * Never gets here, unless suspend fails.
* Successful cpu_suspend should return from cpu_resume, returning
* through this code path is considered an error
* If the return value is set to 0 force x0 = -EOPNOTSUPP
ldp x27, x28, [sp, #80]
ldp x29, lr, [sp], #96
ret
-ENDPROC(__cpu_suspend_enter)
+ENDPROC(__cpu_suspend)
.ltorg
/*
ret
ENDPROC(cpu_resume_after_mmu)
+ .data
ENTRY(cpu_resume)
bl el2_setup // if in EL2 drop to EL1 cleanly
#ifdef CONFIG_SMP
mrs x1, mpidr_el1
- adrp x8, mpidr_hash
- add x8, x8, #:lo12:mpidr_hash // x8 = struct mpidr_hash phys address
+ adr x4, mpidr_hash_ptr
+ ldr x5, [x4]
+ add x8, x4, x5 // x8 = struct mpidr_hash phys address
/* retrieve mpidr_hash members to compute the hash */
ldr x2, [x8, #MPIDR_HASH_MASK]
ldp w3, w4, [x8, #MPIDR_HASH_SHIFTS]
#else
mov x7, xzr
#endif
- adrp x0, sleep_save_sp
- add x0, x0, #:lo12:sleep_save_sp
+ adr x0, sleep_save_sp
ldr x0, [x0, #SLEEP_SAVE_SP_PHYS]
ldr x0, [x0, x7, lsl #3]
/* load sp from context */
ldr x2, [x0, #CPU_CTX_SP]
- adrp x1, sleep_idmap_phys
+ adr x1, sleep_idmap_phys
/* load physical address of identity map page table in x1 */
- ldr x1, [x1, #:lo12:sleep_idmap_phys]
+ ldr x1, [x1]
mov sp, x2
/*
* cpu_do_resume expects x0 to contain context physical address
bl cpu_do_resume // PC relative jump, MMU off
b cpu_resume_mmu // Resume MMU, never returns
ENDPROC(cpu_resume)
+
+ .align 3
+mpidr_hash_ptr:
+ /*
+ * offset of mpidr_hash symbol from current location
+ * used to obtain run-time mpidr_hash address with MMU off
+ */
+ .quad mpidr_hash - .
+/*
+ * physical address of identity mapped page tables
+ */
+ .type sleep_idmap_phys, #object
+ENTRY(sleep_idmap_phys)
+ .quad 0
+/*
+ * struct sleep_save_sp {
+ * phys_addr_t *save_ptr_stash;
+ * phys_addr_t save_ptr_stash_phys;
+ * };
+ */
+ .type sleep_save_sp, #object
+ENTRY(sleep_save_sp)
+ .space SLEEP_SAVE_SP_SZ // struct sleep_save_sp
cpumask_set_cpu(cpu, mm_cpumask(mm));
set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- if (system_state != SYSTEM_RUNNING)
-#endif
printk("CPU%u: Booted secondary processor\n", cpu);
/*
pr_crit("CPU%u: cpu didn't die\n", cpu);
return;
}
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- if (system_state != SYSTEM_RUNNING)
-#endif
pr_notice("CPU%u: shutdown\n", cpu);
/*
#include <asm/debug-monitors.h>
#include <asm/pgtable.h>
#include <asm/memory.h>
-#include <asm/mmu_context.h>
#include <asm/smp_plat.h>
#include <asm/suspend.h>
#include <asm/tlbflush.h>
-extern int __cpu_suspend_enter(unsigned long arg, int (*fn)(unsigned long));
+extern int __cpu_suspend(unsigned long);
/*
- * This is called by __cpu_suspend_enter() to save the state, and do whatever
+ * This is called by __cpu_suspend() to save the state, and do whatever
* flushing is required to ensure that when the CPU goes to sleep we have
* the necessary data available when the caches are not searched.
*
- * ptr: CPU context virtual address
- * save_ptr: address of the location where the context physical address
- * must be saved
+ * @arg: Argument to pass to suspend operations
+ * @ptr: CPU context virtual address
+ * @save_ptr: address of the location where the context physical address
+ * must be saved
*/
-void notrace __cpu_suspend_save(struct cpu_suspend_ctx *ptr,
- phys_addr_t *save_ptr)
+int __cpu_suspend_finisher(unsigned long arg, struct cpu_suspend_ctx *ptr,
+ phys_addr_t *save_ptr)
{
+ int cpu = smp_processor_id();
+
*save_ptr = virt_to_phys(ptr);
cpu_do_suspend(ptr);
*/
__flush_dcache_area(ptr, sizeof(*ptr));
__flush_dcache_area(save_ptr, sizeof(*save_ptr));
+
+ return cpu_ops[cpu]->cpu_suspend(arg);
}
/*
}
/**
- * cpu_suspend() - function to enter a low-power state
- * @arg: argument to pass to CPU suspend operations
+ * cpu_suspend
*
- * Return: 0 on success, -EOPNOTSUPP if CPU suspend hook not initialized, CPU
- * operations back-end error code otherwise.
+ * @arg: argument to pass to the finisher function
*/
int cpu_suspend(unsigned long arg)
{
- int cpu = smp_processor_id();
+ struct mm_struct *mm = current->active_mm;
+ int ret, cpu = smp_processor_id();
+ unsigned long flags;
/*
* If cpu_ops have not been registered or suspend
*/
if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_suspend)
return -EOPNOTSUPP;
- return cpu_ops[cpu]->cpu_suspend(arg);
-}
-
-/*
- * __cpu_suspend
- *
- * arg: argument to pass to the finisher function
- * fn: finisher function pointer
- *
- */
-int __cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
-{
- struct mm_struct *mm = current->active_mm;
- int ret;
- unsigned long flags;
/*
* From this point debug exceptions are disabled to prevent
* page tables, so that the thread address space is properly
* set-up on function return.
*/
- ret = __cpu_suspend_enter(arg, fn);
+ ret = __cpu_suspend(arg);
if (ret == 0) {
- /*
- * We are resuming from reset with TTBR0_EL1 set to the
- * idmap to enable the MMU; restore the active_mm mappings in
- * TTBR0_EL1 unless the active_mm == &init_mm, in which case
- * the thread entered __cpu_suspend with TTBR0_EL1 set to
- * reserved TTBR0 page tables and should be restored as such.
- */
- if (mm == &init_mm)
- cpu_set_reserved_ttbr0();
- else
- cpu_switch_mm(mm->pgd, mm);
-
+ cpu_switch_mm(mm->pgd, mm);
flush_tlb_all();
/*
* Restore per-cpu offset before any kernel
* subsystem relying on it has a chance to run.
*/
- set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+ set_my_cpu_offset(per_cpu_offset(cpu));
/*
* Restore HW breakpoint registers to sane values
return ret;
}
-struct sleep_save_sp sleep_save_sp;
-phys_addr_t sleep_idmap_phys;
+extern struct sleep_save_sp sleep_save_sp;
+extern phys_addr_t sleep_idmap_phys;
-static int __init cpu_suspend_init(void)
+static int cpu_suspend_init(void)
{
void *ctx_ptr;
if (!ptr)
goto no_mem;
- if (flags & __GFP_ZERO)
- memset(ptr, 0, size);
-
/* remove any dirty cache lines on the kernel alias */
__dma_flush_range(ptr, ptr + size);
int i, ret;
ret = swiotlb_map_sg_attrs(dev, sgl, nelems, dir, attrs);
- if (!dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs)) {
- for_each_sg(sgl, sg, ret, i)
- __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
- sg->length, dir);
- }
+ for_each_sg(sgl, sg, ret, i)
+ __dma_map_area(phys_to_virt(dma_to_phys(dev, sg->dma_address)),
+ sg->length, dir);
+
return ret;
}
#include <asm/sizes.h>
#include <asm/tlb.h>
-#ifdef CONFIG_ARCH_ROCKCHIP
-#include <linux/rockchip/common.h>
-#endif
-
#include "mm.h"
static unsigned long phys_initrd_start __initdata = 0;
}
early_init_fdt_scan_reserved_mem();
-#ifdef CONFIG_ARCH_ROCKCHIP
- /* reserve memory for uboot */
- rockchip_uboot_mem_reserve();
-
- /* reserve memory for ION */
- rockchip_ion_reserve();
-#endif
/* 4GB maximum for 32-bit only capable devices */
if (IS_ENABLED(CONFIG_ZONE_DMA))
partition table format used by Motorola Delta machines (using
sysv68).
Otherwise, say N.
-
-
-config RK_PARTITION
- bool "Rockchip partition table support" if PARTITION_ADVANCED
- default y if ARCH_ROCKCHIP
- ---help---
- Like most systems, Rockchip use its own hard disk partition table
- format,incompatible with all others. Say Y here if you would like
- to be able to read the hard diskpartition table format used by Rockchip
- Soc inside machines with eMMC as main storage disk. Otherwise, as well
- as you don't know what all this about, say N.
obj-$(CONFIG_EFI_PARTITION) += efi.o
obj-$(CONFIG_KARMA_PARTITION) += karma.o
obj-$(CONFIG_SYSV68_PARTITION) += sysv68.o
-obj-$(CONFIG_RK_PARTITION) += rk.o
#include <linux/genhd.h>
#include "check.h"
+
#include "acorn.h"
#include "amiga.h"
#include "atari.h"
#include "efi.h"
#include "karma.h"
#include "sysv68.h"
-#include "rk.h"
int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
#ifdef CONFIG_SYSV68_PARTITION
sysv68_partition,
#endif
-#ifdef CONFIG_RK_PARTITION
- rkpart_partition,
-#endif
-
NULL
};
sprintf(state->name, "p");
i = res = err = 0;
-
- /* Rockchip partition table ONLY used by eMMC disk */
- #ifdef CONFIG_RK_PARTITION
- if ((179 == MAJOR(bdev->bd_dev) && (1 == hd->emmc_disk)))
- i = sizeof(check_part) / sizeof(struct parsed_partitions *) - 2;
- #endif
-
while (!res && check_part[i]) {
memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
res = check_part[i++](state);
source "drivers/gator/Kconfig"
-source "drivers/headset_observe/Kconfig"
-
source "drivers/android/Kconfig"
endmenu
obj-y += lguest/
obj-$(CONFIG_CPU_FREQ) += cpufreq/
obj-$(CONFIG_CPU_IDLE) += cpuidle/
-obj-$(CONFIG_CPUQUIET_FRAMEWORK)+= cpuquiet/
obj-y += mmc/
obj-$(CONFIG_MEMSTICK) += memstick/
obj-y += leds/
obj-$(CONFIG_NTB) += ntb/
obj-$(CONFIG_GATOR) += gator/
-obj-y += headset_observe/
obj-$(CONFIG_CORESIGHT) += coresight/
obj-$(CONFIG_ANDROID) += android/
#ifdef CONFIG_PM_RUNTIME
.runtime_suspend = acpi_subsys_runtime_suspend,
.runtime_resume = acpi_subsys_runtime_resume,
+ .runtime_idle = pm_generic_runtime_idle,
#endif
#ifdef CONFIG_PM_SLEEP
.prepare = acpi_subsys_prepare,
SET_RUNTIME_PM_OPS(
amba_pm_runtime_suspend,
amba_pm_runtime_resume,
- NULL
+ pm_generic_runtime_idle
)
};
{
drv->drv.bus = &amba_bustype;
-
#define SETFN(fn) if (drv->fn) drv->drv.fn = amba_##fn
SETFN(probe);
SETFN(remove);
}
ret = amba_get_enable_pclk(dev);
- ret = 0;
if (ret == 0) {
u32 pid, cid;
return -EBUSY;
}
- return 0;
+ return pm_runtime_suspend(dev);
}
static int ata_port_runtime_suspend(struct device *dev)
static int device_add_groups(struct device *dev,
const struct attribute_group **groups)
{
- return sysfs_create_groups(&dev->kobj, groups);
+ int error = 0;
+ int i;
+
+ if (groups) {
+ for (i = 0; groups[i]; i++) {
+ error = sysfs_create_group(&dev->kobj, groups[i]);
+ if (error) {
+ while (--i >= 0)
+ sysfs_remove_group(&dev->kobj,
+ groups[i]);
+ break;
+ }
+ }
+ }
+ return error;
}
static void device_remove_groups(struct device *dev,
const struct attribute_group **groups)
{
- sysfs_remove_groups(&dev->kobj, groups);
+ int i;
+
+ if (groups)
+ for (i = 0; groups[i]; i++)
+ sysfs_remove_group(&dev->kobj, groups[i]);
}
static int device_add_attrs(struct device *dev)
cpu->dev.id = num;
cpu->dev.bus = &cpu_subsys;
cpu->dev.release = cpu_device_release;
- cpu->dev.of_node = of_get_cpu_node(num, NULL);
#ifdef CONFIG_HAVE_CPU_AUTOPROBE
cpu->dev.bus->uevent = cpu_uevent;
#endif
return file->f_op == &dma_buf_fops;
}
-#ifdef CONFIG_ARCH_ROCKCHIP
-int dma_buf_is_dma_buf(struct file *file)
-{
- return is_dma_buf_file(file);
-}
-#endif
-
/**
* dma_buf_export_named - Creates a new dma_buf, and associates an anon file
* with this buffer, so it can be exported.
static int driver_add_groups(struct device_driver *drv,
const struct attribute_group **groups)
{
- return sysfs_create_groups(&drv->p->kobj, groups);
+ int error = 0;
+ int i;
+
+ if (groups) {
+ for (i = 0; groups[i]; i++) {
+ error = sysfs_create_group(&drv->p->kobj, groups[i]);
+ if (error) {
+ while (--i >= 0)
+ sysfs_remove_group(&drv->p->kobj,
+ groups[i]);
+ break;
+ }
+ }
+ }
+ return error;
}
static void driver_remove_groups(struct device_driver *drv,
const struct attribute_group **groups)
{
- sysfs_remove_groups(&drv->p->kobj, groups);
+ int i;
+
+ if (groups)
+ for (i = 0; groups[i]; i++)
+ sysfs_remove_group(&drv->p->kobj, groups[i]);
}
/**
goto cleanup_get;
}
-#ifdef CONFIG_PM
- /*
- * If power management is enabled, we also look for the optional
- * sleep and idle pin states, with semantics as defined in
- * <linux/pinctrl/pinctrl-state.h>
- */
- dev->pins->sleep_state = pinctrl_lookup_state(dev->pins->p,
- PINCTRL_STATE_SLEEP);
- if (IS_ERR(dev->pins->sleep_state))
- /* Not supplying this state is perfectly legal */
- dev_dbg(dev, "no sleep pinctrl state\n");
-
- dev->pins->idle_state = pinctrl_lookup_state(dev->pins->p,
- PINCTRL_STATE_IDLE);
- if (IS_ERR(dev->pins->idle_state))
- /* Not supplying this state is perfectly legal */
- dev_dbg(dev, "no idle pinctrl state\n");
-#endif
-
return 0;
/*
static const struct dev_pm_ops platform_dev_pm_ops = {
.runtime_suspend = pm_generic_runtime_suspend,
.runtime_resume = pm_generic_runtime_resume,
+ .runtime_idle = pm_generic_runtime_idle,
USE_PLATFORM_PM_SLEEP_OPS
};
genpd->max_off_time_changed = true;
genpd->domain.ops.runtime_suspend = pm_genpd_runtime_suspend;
genpd->domain.ops.runtime_resume = pm_genpd_runtime_resume;
+ genpd->domain.ops.runtime_idle = pm_generic_runtime_idle;
genpd->domain.ops.prepare = pm_genpd_prepare;
genpd->domain.ops.suspend = pm_genpd_suspend;
genpd->domain.ops.suspend_late = pm_genpd_suspend_late;
#include <linux/export.h>
#ifdef CONFIG_PM_RUNTIME
+/**
+ * pm_generic_runtime_idle - Generic runtime idle callback for subsystems.
+ * @dev: Device to handle.
+ *
+ * If PM operations are defined for the @dev's driver and they include
+ * ->runtime_idle(), execute it and return its error code, if nonzero.
+ * Otherwise, execute pm_runtime_suspend() for the device and return 0.
+ */
+int pm_generic_runtime_idle(struct device *dev)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+ if (pm && pm->runtime_idle) {
+ int ret = pm->runtime_idle(dev);
+ if (ret)
+ return ret;
+ }
+
+ pm_runtime_suspend(dev);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pm_generic_runtime_idle);
+
/**
* pm_generic_runtime_suspend - Generic runtime suspend callback for subsystems.
* @dev: Device to suspend.
/* Pending requests need to be canceled. */
dev->power.request = RPM_REQ_NONE;
- if (dev->power.no_callbacks)
+ if (dev->power.no_callbacks) {
+ /* Assume ->runtime_idle() callback would have suspended. */
+ retval = rpm_suspend(dev, rpmflags);
goto out;
+ }
/* Carry out an asynchronous or a synchronous idle notification. */
if (rpmflags & RPM_ASYNC) {
dev->power.request_pending = true;
queue_work(pm_wq, &dev->power.work);
}
- trace_rpm_return_int(dev, _THIS_IP_, 0);
- return 0;
+ goto out;
}
dev->power.idle_notification = true;
callback = dev->driver->pm->runtime_idle;
if (callback)
- retval = __rpm_callback(callback, dev);
+ __rpm_callback(callback, dev);
dev->power.idle_notification = false;
wake_up_all(&dev->power.wait_queue);
out:
trace_rpm_return_int(dev, _THIS_IP_, retval);
- return retval ? retval : rpm_suspend(dev, rpmflags);
+ return retval;
}
/**
struct regmap {
struct mutex mutex;
spinlock_t spinlock;
- unsigned long spinlock_flags;
regmap_lock lock;
regmap_unlock unlock;
void *lock_arg; /* This is passed to lock/unlock functions */
xfer[0].flags = 0;
xfer[0].len = reg_size;
xfer[0].buf = (void *)reg;
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- xfer[0].scl_rate = 100*1000;
-#endif
xfer[1].addr = i2c->addr;
xfer[1].flags = I2C_M_NOSTART;
xfer[1].len = val_size;
xfer[1].buf = (void *)val;
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- xfer[1].scl_rate = 100*1000;
-#endif
ret = i2c_transfer(i2c->adapter, xfer, 2);
if (ret == 2)
xfer[0].flags = 0;
xfer[0].len = reg_size;
xfer[0].buf = (void *)reg;
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- xfer[0].scl_rate = 100*1000;
-#endif
xfer[1].addr = i2c->addr;
xfer[1].flags = I2C_M_RD;
xfer[1].len = val_size;
xfer[1].buf = val;
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- xfer[1].scl_rate = 100*1000;
-#endif
ret = i2c_transfer(i2c->adapter, xfer, 2);
if (ret == 2)
static void regmap_lock_spinlock(void *__map)
{
struct regmap *map = __map;
- unsigned long flags;
-
- spin_lock_irqsave(&map->spinlock, flags);
- map->spinlock_flags = flags;
+ spin_lock(&map->spinlock);
}
static void regmap_unlock_spinlock(void *__map)
{
struct regmap *map = __map;
- spin_unlock_irqrestore(&map->spinlock, map->spinlock_flags);
+ spin_unlock(&map->spinlock);
}
static void dev_get_regmap_release(struct device *dev, void *res)
Say Y here to compile support for Bluetooth USB devices into the
kernel or say M to compile it as module (btusb).
-config BT_RTKBTUSB
- tristate "RTK HCI USB driver"
- depends on USB
- help
- RTK Bluetooth HCI USB driver
-
config BT_HCIBTSDIO
tristate "HCI SDIO driver"
depends on MMC
# Makefile for the Linux Bluetooth HCI device drivers.
#
-obj-$(CONFIG_BT) += vflash.o
obj-$(CONFIG_BT_HCIVHCI) += hci_vhci.o
obj-$(CONFIG_BT_HCIUART) += hci_uart.o
obj-$(CONFIG_BT_HCIBCM203X) += bcm203x.o
obj-$(CONFIG_BT_HCIBTUART) += btuart_cs.o
obj-$(CONFIG_BT_HCIBTUSB) += btusb.o
-obj-$(CONFIG_BT_RTKBTUSB) += rtk_btusb.o
obj-$(CONFIG_BT_HCIBTSDIO) += btsdio.o
obj-$(CONFIG_BT_ATH3K) += ath3k.o
bool "DebugFS representation of clock tree"
select DEBUG_FS
---help---
- Creates a directory hierarchy in debugfs for visualizing the clk
+ Creates a directory hierchy in debugfs for visualizing the clk
tree structure. Each directory contains read-only members
that export information specific to that clk node: clk_rate,
clk_flags, clk_prepare_count, clk_enable_count &
obj-$(CONFIG_COMMON_CLK_VERSATILE) += versatile/
obj-$(CONFIG_ARCH_PRIMA2) += clk-prima2.o
obj-$(CONFIG_PLAT_ORION) += mvebu/
-obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
ifeq ($(CONFIG_COMMON_CLK), y)
obj-$(CONFIG_ARCH_MMP) += mmp/
endif
return rate_ops->recalc_rate(rate_hw, parent_rate);
}
-static long clk_composite_determine_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *best_parent_rate,
- struct clk **best_parent_p)
-{
- struct clk_composite *composite = to_clk_composite(hw);
- const struct clk_ops *rate_ops = composite->rate_ops;
- const struct clk_ops *mux_ops = composite->mux_ops;
- struct clk_hw *rate_hw = composite->rate_hw;
- struct clk_hw *mux_hw = composite->mux_hw;
-
- if (rate_hw && rate_ops && rate_ops->determine_rate) {
- rate_hw->clk = hw->clk;
- return rate_ops->determine_rate(rate_hw, rate, best_parent_rate,
- best_parent_p);
- } else if (mux_hw && mux_ops && mux_ops->determine_rate) {
- mux_hw->clk = hw->clk;
- return mux_ops->determine_rate(mux_hw, rate, best_parent_rate,
- best_parent_p);
- } else {
- pr_err("clk: clk_composite_determine_rate function called, but no mux or rate callback set!\n");
- return 0;
- }
-}
-
static long clk_composite_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
composite->mux_ops = mux_ops;
clk_composite_ops->get_parent = clk_composite_get_parent;
clk_composite_ops->set_parent = clk_composite_set_parent;
- if (mux_ops->determine_rate)
- clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (rate_hw && rate_ops) {
composite->rate_hw = rate_hw;
composite->rate_ops = rate_ops;
clk_composite_ops->recalc_rate = clk_composite_recalc_rate;
- if (rate_ops->determine_rate)
- clk_composite_ops->determine_rate = clk_composite_determine_rate;
}
if (gate_hw && gate_ops) {
if (divider->lock)
spin_lock_irqsave(divider->lock, flags);
- if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
- val = div_mask(divider) << (divider->shift + 16);
- } else {
- val = readl(divider->reg);
- val &= ~(div_mask(divider) << divider->shift);
- }
+ val = readl(divider->reg);
+ val &= ~(div_mask(divider) << divider->shift);
val |= value << divider->shift;
writel(val, divider->reg);
struct clk *clk;
struct clk_init_data init;
- if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
- if (width + shift > 16) {
- pr_warn("divider value exceeds LOWORD field\n");
- return ERR_PTR(-EINVAL);
- }
- }
-
/* allocate the divider */
div = kzalloc(sizeof(struct clk_divider), GFP_KERNEL);
if (!div) {
if (gate->lock)
spin_lock_irqsave(gate->lock, flags);
- if (gate->flags & CLK_GATE_HIWORD_MASK) {
- reg = BIT(gate->bit_idx + 16);
- if (set)
- reg |= BIT(gate->bit_idx);
- } else {
- reg = readl(gate->reg);
-
- if (set)
- reg |= BIT(gate->bit_idx);
- else
- reg &= ~BIT(gate->bit_idx);
- }
+ reg = readl(gate->reg);
+
+ if (set)
+ reg |= BIT(gate->bit_idx);
+ else
+ reg &= ~BIT(gate->bit_idx);
writel(reg, gate->reg);
struct clk *clk;
struct clk_init_data init;
- if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
- if (bit_idx > 16) {
- pr_err("gate bit exceeds LOWORD field\n");
- return ERR_PTR(-EINVAL);
- }
- }
-
/* allocate the gate */
gate = kzalloc(sizeof(struct clk_gate), GFP_KERNEL);
if (!gate) {
if (mux->lock)
spin_lock_irqsave(mux->lock, flags);
- if (mux->flags & CLK_MUX_HIWORD_MASK) {
- val = mux->mask << (mux->shift + 16);
- } else {
- val = readl(mux->reg);
- val &= ~(mux->mask << mux->shift);
- }
+ val = readl(mux->reg);
+ val &= ~(mux->mask << mux->shift);
val |= index << mux->shift;
writel(val, mux->reg);
const struct clk_ops clk_mux_ops = {
.get_parent = clk_mux_get_parent,
.set_parent = clk_mux_set_parent,
- .determine_rate = __clk_mux_determine_rate,
};
EXPORT_SYMBOL_GPL(clk_mux_ops);
struct clk_mux *mux;
struct clk *clk;
struct clk_init_data init;
- u8 width = 0;
-
- if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
- width = fls(mask) - ffs(mask) + 1;
- if (width + shift > 16) {
- pr_err("mux value exceeds LOWORD field\n");
- return ERR_PTR(-EINVAL);
- }
- }
/* allocate the mux */
mux = kzalloc(sizeof(struct clk_mux), GFP_KERNEL);
seq_printf(s, "%*s%-*s %-11d %-12d %-10lu",
level * 3 + 1, "",
30 - level * 3, c->name,
- c->enable_count, c->prepare_count, clk_get_rate(c));
+ c->enable_count, c->prepare_count, c->rate);
seq_printf(s, "\n");
}
seq_printf(s, "\"%s\": { ", c->name);
seq_printf(s, "\"enable_count\": %d,", c->enable_count);
seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
- seq_printf(s, "\"rate\": %lu", clk_get_rate(c));
+ seq_printf(s, "\"rate\": %lu", c->rate);
}
static void clk_dump_subtree(struct seq_file *s, struct clk *c, int level)
clk->ops->unprepare(clk->hw);
}
}
+EXPORT_SYMBOL_GPL(__clk_get_flags);
/* caller must hold prepare_lock */
static void clk_disable_unused_subtree(struct clk *clk)
return 0;
}
-late_initcall_sync(clk_disable_unused);
+late_initcall(clk_disable_unused);
/*** helper functions ***/
return !clk ? NULL : clk->parent;
}
-struct clk *clk_get_parent_by_index(struct clk *clk, u8 index)
-{
- if (!clk || index >= clk->num_parents)
- return NULL;
- else if (!clk->parents)
- return __clk_lookup(clk->parent_names[index]);
- else if (!clk->parents[index])
- return clk->parents[index] =
- __clk_lookup(clk->parent_names[index]);
- else
- return clk->parents[index];
-}
-
unsigned int __clk_get_enable_count(struct clk *clk)
{
return !clk ? 0 : clk->enable_count;
{
return !clk ? 0 : clk->flags;
}
-EXPORT_SYMBOL_GPL(__clk_get_flags);
bool __clk_is_prepared(struct clk *clk)
{
return NULL;
}
-/*
- * Helper for finding best parent to provide a given frequency. This can be used
- * directly as a determine_rate callback (e.g. for a mux), or from a more
- * complex clock that may combine a mux with other operations.
- */
-long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *best_parent_rate,
- struct clk **best_parent_p)
-{
- struct clk *clk = hw->clk, *parent, *best_parent = NULL;
- int i, num_parents;
- unsigned long parent_rate, best = 0;
-
- /* if NO_REPARENT flag set, pass through to current parent */
- if (clk->flags & CLK_SET_RATE_NO_REPARENT) {
- parent = clk->parent;
- if (clk->flags & CLK_SET_RATE_PARENT)
- best = __clk_round_rate(parent, rate);
- else if (parent)
- best = __clk_get_rate(parent);
- else
- best = __clk_get_rate(clk);
- goto out;
- }
-
- /* find the parent that can provide the fastest rate <= rate */
- num_parents = clk->num_parents;
- for (i = 0; i < num_parents; i++) {
- parent = clk_get_parent_by_index(clk, i);
- if (!parent)
- continue;
- if (clk->flags & CLK_SET_RATE_PARENT)
- parent_rate = __clk_round_rate(parent, rate);
- else
- parent_rate = __clk_get_rate(parent);
- if (parent_rate <= rate && parent_rate > best) {
- best_parent = parent;
- best = parent_rate;
- }
- }
-
-out:
- if (best_parent)
- *best_parent_p = best_parent;
- *best_parent_rate = best;
-
- return best;
-}
-
/*** clk api ***/
void __clk_unprepare(struct clk *clk)
/**
* clk_unprepare - undo preparation of a clock source
- * @clk: the clk being unprepared
+ * @clk: the clk being unprepare
*
* clk_unprepare may sleep, which differentiates it from clk_disable. In a
* simple case, clk_unprepare can be used instead of clk_disable to gate a clk
/**
* __clk_round_rate - round the given rate for a clk
* @clk: round the rate of this clock
- * @rate: the rate which is to be rounded
*
* Caller must hold prepare_lock. Useful for clk_ops such as .set_rate
*/
unsigned long __clk_round_rate(struct clk *clk, unsigned long rate)
{
unsigned long parent_rate = 0;
- struct clk *parent;
if (!clk)
return 0;
- parent = clk->parent;
- if (parent)
- parent_rate = parent->rate;
-
- if (clk->ops->determine_rate)
- return clk->ops->determine_rate(clk->hw, rate, &parent_rate,
- &parent);
- else if (clk->ops->round_rate)
- return clk->ops->round_rate(clk->hw, rate, &parent_rate);
- else if (clk->flags & CLK_SET_RATE_PARENT)
- return __clk_round_rate(clk->parent, rate);
- else
- return clk->rate;
+ if (!clk->ops->round_rate) {
+ if (clk->flags & CLK_SET_RATE_PARENT)
+ return __clk_round_rate(clk->parent, rate);
+ else
+ return clk->rate;
+ }
+
+ if (clk->parent)
+ parent_rate = clk->parent->rate;
+
+ return clk->ops->round_rate(clk->hw, rate, &parent_rate);
}
/**
*
* Walks the subtree of clks starting with clk and recalculates rates as it
* goes. Note that if a clk does not implement the .recalc_rate callback then
- * it is assumed that the clock will take on the rate of its parent.
+ * it is assumed that the clock will take on the rate of it's parent.
*
* clk_recalc_rates also propagates the POST_RATE_CHANGE notification,
* if necessary.
}
EXPORT_SYMBOL_GPL(clk_get_rate);
-static int clk_fetch_parent_index(struct clk *clk, struct clk *parent)
-{
- int i;
-
- if (!clk->parents) {
- clk->parents = kcalloc(clk->num_parents,
- sizeof(struct clk *), GFP_KERNEL);
- if (!clk->parents)
- return -ENOMEM;
- }
-
- /*
- * find index of new parent clock using cached parent ptrs,
- * or if not yet cached, use string name comparison and cache
- * them now to avoid future calls to __clk_lookup.
- */
- for (i = 0; i < clk->num_parents; i++) {
- if (clk->parents[i] == parent)
- return i;
-
- if (clk->parents[i])
- continue;
-
- if (!strcmp(clk->parent_names[i], parent->name)) {
- clk->parents[i] = __clk_lookup(parent->name);
- return i;
- }
- }
-
- return -EINVAL;
-}
-
-static void clk_reparent(struct clk *clk, struct clk *new_parent)
-{
- hlist_del(&clk->child_node);
-
- if (new_parent) {
- /* avoid duplicate POST_RATE_CHANGE notifications */
- if (new_parent->new_child == clk)
- new_parent->new_child = NULL;
-
- hlist_add_head(&clk->child_node, &new_parent->children);
- } else {
- hlist_add_head(&clk->child_node, &clk_orphan_list);
- }
-
- clk->parent = new_parent;
-}
-
-static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
-{
- unsigned long flags;
- int ret = 0;
- struct clk *old_parent = clk->parent;
-
- /*
- * Migrate prepare state between parents and prevent race with
- * clk_enable().
- *
- * If the clock is not prepared, then a race with
- * clk_enable/disable() is impossible since we already have the
- * prepare lock (future calls to clk_enable() need to be preceded by
- * a clk_prepare()).
- *
- * If the clock is prepared, migrate the prepared state to the new
- * parent and also protect against a race with clk_enable() by
- * forcing the clock and the new parent on. This ensures that all
- * future calls to clk_enable() are practically NOPs with respect to
- * hardware and software states.
- *
- * See also: Comment for clk_set_parent() below.
- */
- if (clk->prepare_count) {
- __clk_prepare(parent);
- clk_enable(parent);
- clk_enable(clk);
- }
-
- /* update the clk tree topology */
- flags = clk_enable_lock();
- clk_reparent(clk, parent);
- clk_enable_unlock(flags);
-
- /* change clock input source */
- if (parent && clk->ops->set_parent)
- ret = clk->ops->set_parent(clk->hw, p_index);
-
- if (ret) {
- flags = clk_enable_lock();
- clk_reparent(clk, old_parent);
- clk_enable_unlock(flags);
-
- if (clk->prepare_count) {
- clk_disable(clk);
- clk_disable(parent);
- __clk_unprepare(parent);
- }
- return ret;
- }
-
- /*
- * Finish the migration of prepare state and undo the changes done
- * for preventing a race with clk_enable().
- */
- if (clk->prepare_count) {
- clk_disable(clk);
- clk_disable(old_parent);
- __clk_unprepare(old_parent);
- }
-
- /* update debugfs with new clk tree topology */
- clk_debug_reparent(clk, parent);
- return 0;
-}
-
/**
* __clk_speculate_rates
* @clk: first clk in the subtree
* pre-rate change notifications and returns early if no clks in the
* subtree have subscribed to the notifications. Note that if a clk does not
* implement the .recalc_rate callback then it is assumed that the clock will
- * take on the rate of its parent.
+ * take on the rate of it's parent.
*
* Caller must hold prepare_lock.
*/
return ret;
}
-static void clk_calc_subtree(struct clk *clk, unsigned long new_rate,
- struct clk *new_parent, u8 p_index)
+static void clk_calc_subtree(struct clk *clk, unsigned long new_rate)
{
struct clk *child;
clk->new_rate = new_rate;
- clk->new_parent = new_parent;
- clk->new_parent_index = p_index;
- /* include clk in new parent's PRE_RATE_CHANGE notifications */
- clk->new_child = NULL;
- if (new_parent && new_parent != clk->parent)
- new_parent->new_child = clk;
hlist_for_each_entry(child, &clk->children, child_node) {
if (child->ops->recalc_rate)
child->new_rate = child->ops->recalc_rate(child->hw, new_rate);
else
child->new_rate = new_rate;
- clk_calc_subtree(child, child->new_rate, NULL, 0);
+ clk_calc_subtree(child, child->new_rate);
}
}
static struct clk *clk_calc_new_rates(struct clk *clk, unsigned long rate)
{
struct clk *top = clk;
- struct clk *old_parent, *parent;
unsigned long best_parent_rate = 0;
unsigned long new_rate;
- int p_index = 0;
/* sanity */
if (IS_ERR_OR_NULL(clk))
return NULL;
/* save parent rate, if it exists */
- parent = old_parent = clk->parent;
- if (parent)
- best_parent_rate = parent->rate;
-
- /* find the closest rate and parent clk/rate */
- if (clk->ops->determine_rate) {
- new_rate = clk->ops->determine_rate(clk->hw, rate,
- &best_parent_rate,
- &parent);
- } else if (clk->ops->round_rate) {
- new_rate = clk->ops->round_rate(clk->hw, rate,
- &best_parent_rate);
- } else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
- /* pass-through clock without adjustable parent */
- clk->new_rate = clk->rate;
- return NULL;
- } else {
- /* pass-through clock with adjustable parent */
- top = clk_calc_new_rates(parent, rate);
- new_rate = parent->new_rate;
+ if (clk->parent)
+ best_parent_rate = clk->parent->rate;
+
+ /* never propagate up to the parent */
+ if (!(clk->flags & CLK_SET_RATE_PARENT)) {
+ if (!clk->ops->round_rate) {
+ clk->new_rate = clk->rate;
+ return NULL;
+ }
+ new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
goto out;
}
- /* some clocks must be gated to change parent */
- if (parent != old_parent &&
- (clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) {
- pr_debug("%s: %s not gated but wants to reparent\n",
- __func__, clk->name);
+ /* need clk->parent from here on out */
+ if (!clk->parent) {
+ pr_debug("%s: %s has NULL parent\n", __func__, clk->name);
return NULL;
}
- /* try finding the new parent index */
- if (parent) {
- p_index = clk_fetch_parent_index(clk, parent);
- if (p_index < 0) {
- pr_debug("%s: clk %s can not be parent of clk %s\n",
- __func__, parent->name, clk->name);
- return NULL;
- }
+ if (!clk->ops->round_rate) {
+ top = clk_calc_new_rates(clk->parent, rate);
+ new_rate = clk->parent->new_rate;
+
+ goto out;
}
- if ((clk->flags & CLK_SET_RATE_PARENT) && parent &&
- best_parent_rate != parent->rate)
- top = clk_calc_new_rates(parent, best_parent_rate);
+ new_rate = clk->ops->round_rate(clk->hw, rate, &best_parent_rate);
+
+ if (best_parent_rate != clk->parent->rate) {
+ top = clk_calc_new_rates(clk->parent, best_parent_rate);
+
+ goto out;
+ }
out:
- clk_calc_subtree(clk, new_rate, parent, p_index);
+ clk_calc_subtree(clk, new_rate);
return top;
}
*/
static struct clk *clk_propagate_rate_change(struct clk *clk, unsigned long event)
{
- struct clk *child, *tmp_clk, *fail_clk = NULL;
+ struct clk *child, *fail_clk = NULL;
int ret = NOTIFY_DONE;
if (clk->rate == clk->new_rate)
}
hlist_for_each_entry(child, &clk->children, child_node) {
- /* Skip children who will be reparented to another clock */
- if (child->new_parent && child->new_parent != clk)
- continue;
- tmp_clk = clk_propagate_rate_change(child, event);
- if (tmp_clk)
- fail_clk = tmp_clk;
- }
-
- /* handle the new child who might not be in clk->children yet */
- if (clk->new_child) {
- tmp_clk = clk_propagate_rate_change(clk->new_child, event);
- if (tmp_clk)
- fail_clk = tmp_clk;
+ clk = clk_propagate_rate_change(child, event);
+ if (clk)
+ fail_clk = clk;
}
return fail_clk;
static void clk_change_rate(struct clk *clk)
{
struct clk *child;
- unsigned long old_rate, tmp_rate;
+ unsigned long old_rate;
unsigned long best_parent_rate = 0;
old_rate = clk->rate;
- /* set parent */
- if (clk->new_parent && clk->new_parent != clk->parent) {
- if (clk->flags & CLK_SET_RATE_PARENT_IN_ORDER) {
- tmp_rate = clk->ops->recalc_rate(clk->hw, clk->new_parent->rate);
- if ((tmp_rate > clk->rate) && (tmp_rate > clk->new_rate)) {
- if (clk->ops->set_rate)
- clk->ops->set_rate(clk->hw, clk->new_rate, clk->new_parent->rate);
- }
- }
-
- __clk_set_parent(clk, clk->new_parent, clk->new_parent_index);
- }
-
if (clk->parent)
best_parent_rate = clk->parent->rate;
if (clk->notifier_count && old_rate != clk->rate)
__clk_notify(clk, POST_RATE_CHANGE, old_rate, clk->rate);
- hlist_for_each_entry(child, &clk->children, child_node) {
- /* Skip children who will be reparented to another clock */
- if (child->new_parent && child->new_parent != clk)
- continue;
+ hlist_for_each_entry(child, &clk->children, child_node)
clk_change_rate(child);
- }
-
- /* handle the new child who might not be in clk->children yet */
- if (clk->new_child)
- clk_change_rate(clk->new_child);
}
/**
* outcome of clk's .round_rate implementation. If *parent_rate is unchanged
* after calling .round_rate then upstream parent propagation is ignored. If
* *parent_rate comes back with a new rate for clk's parent then we propagate
- * up to clk's parent and set its rate. Upward propagation will continue
+ * up to clk's parent and set it's rate. Upward propagation will continue
* until either a clk does not support the CLK_SET_RATE_PARENT flag or
* .round_rate stops requesting changes to clk's parent_rate.
*
struct clk *top, *fail_clk;
int ret = 0;
- if (!clk)
- return 0;
-
/* prevent racing with updates to the clock topology */
clk_prepare_lock();
/* bail early if nothing to do */
- if (rate == clk_get_rate(clk))
+ if (rate == clk->rate)
goto out;
if ((clk->flags & CLK_SET_RATE_GATE) && clk->prepare_count) {
if (!clk->parents)
clk->parents =
- kcalloc(clk->num_parents, sizeof(struct clk *),
+ kzalloc((sizeof(struct clk*) * clk->num_parents),
GFP_KERNEL);
- ret = clk_get_parent_by_index(clk, index);
+ if (!clk->parents)
+ ret = __clk_lookup(clk->parent_names[index]);
+ else if (!clk->parents[index])
+ ret = clk->parents[index] =
+ __clk_lookup(clk->parent_names[index]);
+ else
+ ret = clk->parents[index];
out:
return ret;
}
+static void clk_reparent(struct clk *clk, struct clk *new_parent)
+{
+ hlist_del(&clk->child_node);
+
+ if (new_parent)
+ hlist_add_head(&clk->child_node, &new_parent->children);
+ else
+ hlist_add_head(&clk->child_node, &clk_orphan_list);
+
+ clk->parent = new_parent;
+}
+
void __clk_reparent(struct clk *clk, struct clk *new_parent)
{
clk_reparent(clk, new_parent);
__clk_recalc_rates(clk, POST_RATE_CHANGE);
}
+static u8 clk_fetch_parent_index(struct clk *clk, struct clk *parent)
+{
+ u8 i;
+
+ if (!clk->parents)
+ clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
+ GFP_KERNEL);
+
+ /*
+ * find index of new parent clock using cached parent ptrs,
+ * or if not yet cached, use string name comparison and cache
+ * them now to avoid future calls to __clk_lookup.
+ */
+ for (i = 0; i < clk->num_parents; i++) {
+ if (clk->parents && clk->parents[i] == parent)
+ break;
+ else if (!strcmp(clk->parent_names[i], parent->name)) {
+ if (clk->parents)
+ clk->parents[i] = __clk_lookup(parent->name);
+ break;
+ }
+ }
+
+ return i;
+}
+
+static int __clk_set_parent(struct clk *clk, struct clk *parent, u8 p_index)
+{
+ unsigned long flags;
+ int ret = 0;
+ struct clk *old_parent = clk->parent;
+ bool migrated_enable = false;
+
+ /* migrate prepare */
+ if (clk->prepare_count)
+ __clk_prepare(parent);
+
+ flags = clk_enable_lock();
+
+ /* migrate enable */
+ if (clk->enable_count) {
+ __clk_enable(parent);
+ migrated_enable = true;
+ }
+
+ /* update the clk tree topology */
+ clk_reparent(clk, parent);
+
+ clk_enable_unlock(flags);
+
+ /* change clock input source */
+ if (parent && clk->ops->set_parent)
+ ret = clk->ops->set_parent(clk->hw, p_index);
+
+ if (ret) {
+ /*
+ * The error handling is tricky due to that we need to release
+ * the spinlock while issuing the .set_parent callback. This
+ * means the new parent might have been enabled/disabled in
+ * between, which must be considered when doing rollback.
+ */
+ flags = clk_enable_lock();
+
+ clk_reparent(clk, old_parent);
+
+ if (migrated_enable && clk->enable_count) {
+ __clk_disable(parent);
+ } else if (migrated_enable && (clk->enable_count == 0)) {
+ __clk_disable(old_parent);
+ } else if (!migrated_enable && clk->enable_count) {
+ __clk_disable(parent);
+ __clk_enable(old_parent);
+ }
+
+ clk_enable_unlock(flags);
+
+ if (clk->prepare_count)
+ __clk_unprepare(parent);
+
+ return ret;
+ }
+
+ /* clean up enable for old parent if migration was done */
+ if (migrated_enable) {
+ flags = clk_enable_lock();
+ __clk_disable(old_parent);
+ clk_enable_unlock(flags);
+ }
+
+ /* clean up prepare for old parent if migration was done */
+ if (clk->prepare_count)
+ __clk_unprepare(old_parent);
+
+ /* update debugfs with new clk tree topology */
+ clk_debug_reparent(clk, parent);
+ return 0;
+}
+
/**
* clk_set_parent - switch the parent of a mux clk
* @clk: the mux clk whose input we are switching
* @parent: the new input to clk
*
- * Re-parent clk to use parent as its new input source. If clk is in
- * prepared state, the clk will get enabled for the duration of this call. If
- * that's not acceptable for a specific clk (Eg: the consumer can't handle
- * that, the reparenting is glitchy in hardware, etc), use the
- * CLK_SET_PARENT_GATE flag to allow reparenting only when clk is unprepared.
- *
- * After successfully changing clk's parent clk_set_parent will update the
- * clk topology, sysfs topology and propagate rate recalculation via
- * __clk_recalc_rates.
- *
- * Returns 0 on success, -EERROR otherwise.
+ * Re-parent clk to use parent as it's new input source. If clk has the
+ * CLK_SET_PARENT_GATE flag set then clk must be gated for this
+ * operation to succeed. After successfully changing clk's parent
+ * clk_set_parent will update the clk topology, sysfs topology and
+ * propagate rate recalculation via __clk_recalc_rates. Returns 0 on
+ * success, -EERROR otherwise.
*/
int clk_set_parent(struct clk *clk, struct clk *parent)
{
int ret = 0;
- int p_index = 0;
+ u8 p_index = 0;
unsigned long p_rate = 0;
- if (!clk)
- return 0;
-
- if (!clk->ops)
+ if (!clk || !clk->ops)
return -EINVAL;
/* verify ops for for multi-parent clks */
if (parent) {
p_index = clk_fetch_parent_index(clk, parent);
p_rate = parent->rate;
- if (p_index < 0) {
+ if (p_index == clk->num_parents) {
pr_debug("%s: clk %s can not be parent of clk %s\n",
__func__, parent->name, clk->name);
- ret = p_index;
+ ret = -EINVAL;
goto out;
}
}
/* propagate PRE_RATE_CHANGE notifications */
- ret = __clk_speculate_rates(clk, p_rate);
+ if (clk->notifier_count)
+ ret = __clk_speculate_rates(clk, p_rate);
/* abort if a driver objects */
if (ret & NOTIFY_STOP_MASK)
/* check that clk_ops are sane. See Documentation/clk.txt */
if (clk->ops->set_rate &&
- !((clk->ops->round_rate || clk->ops->determine_rate) &&
- clk->ops->recalc_rate)) {
- pr_warning("%s: %s must implement .round_rate or .determine_rate in addition to .recalc_rate\n",
+ !(clk->ops->round_rate && clk->ops->recalc_rate)) {
+ pr_warning("%s: %s must implement .round_rate & .recalc_rate\n",
__func__, clk->name);
ret = -EINVAL;
goto out;
* for clock drivers to statically initialize clk->parents.
*/
if (clk->num_parents > 1 && !clk->parents) {
- clk->parents = kcalloc(clk->num_parents, sizeof(struct clk *),
- GFP_KERNEL);
+ clk->parents = kzalloc((sizeof(struct clk*) * clk->num_parents),
+ GFP_KERNEL);
/*
* __clk_lookup returns NULL for parents that have not been
* clk_init'd; thus any access to clk->parents[] must check
* this clock
*/
hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
- if (orphan->num_parents && orphan->ops->get_parent) {
+ if (orphan->ops->get_parent) {
i = orphan->ops->get_parent(orphan->hw);
if (!strcmp(clk->name, orphan->parent_names[i]))
__clk_reparent(orphan, clk);
* The .init callback is not used by any of the basic clock types, but
* exists for weird hardware that must perform initialization magic.
* Please consider other ways of solving initialization problems before
- * using this callback, as its use is discouraged.
+ * using this callback, as it's use is discouraged.
*/
if (clk->ops->init)
clk->ops->init(clk->hw);
* very large numbers of clocks that need to be statically initialized. It is
* a layering violation to include clk-private.h from any code which implements
* a clock's .ops; as such any statically initialized clock data MUST be in a
- * separate C file from the logic that implements its operations. Returns 0
+ * separate C file from the logic that implements it's operations. Returns 0
* on success, otherwise an error code.
*/
struct clk *__clk_register(struct device *dev, struct clk_hw *hw)
hw->clk = clk;
/* allocate local copy in case parent_names is __initdata */
- clk->parent_names = kcalloc(clk->num_parents, sizeof(char *),
- GFP_KERNEL);
+ clk->parent_names = kzalloc((sizeof(char*) * clk->num_parents),
+ GFP_KERNEL);
if (!clk->parent_names) {
pr_err("%s: could not allocate clk->parent_names\n", __func__);
*/
void __init of_clk_init(const struct of_device_id *matches)
{
- const struct of_device_id *match;
struct device_node *np;
if (!matches)
matches = __clk_of_table;
- for_each_matching_node_and_match(np, matches, &match) {
+ for_each_matching_node(np, matches) {
+ const struct of_device_id *match = of_match_node(matches, np);
of_clk_init_cb_t clk_init_cb = match->data;
clk_init_cb(np);
}
obj-$(CONFIG_CLKSRC_MMIO) += mmio.o
obj-$(CONFIG_DW_APB_TIMER) += dw_apb_timer.o
obj-$(CONFIG_DW_APB_TIMER_OF) += dw_apb_timer_of.o
-obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip_timer.o
obj-$(CONFIG_CLKSRC_NOMADIK_MTU) += nomadik-mtu.o
obj-$(CONFIG_CLKSRC_DBX500_PRCMU) += clksrc-dbx500-prcmu.o
obj-$(CONFIG_ARMADA_370_XP_TIMER) += time-armada-370-xp.o
static cycle_t arch_counter_read(struct clocksource *cs)
{
- return arch_timer_read_counter();
+ return arch_counter_get_cntvct();
}
static cycle_t arch_counter_read_cc(const struct cyclecounter *cc)
{
- return arch_timer_read_counter();
+ return arch_counter_get_cntvct();
}
static struct clocksource clocksource_counter = {
else
arch_timer_read_counter = arch_counter_get_cntvct_mem;
- if (!arch_timer_use_virtual)
- if (arch_timer_read_counter == arch_counter_get_cntvct)
- arch_timer_read_counter = arch_counter_get_cntpct;
-
start_count = arch_timer_read_counter();
clocksource_register_hz(&clocksource_counter, arch_timer_rate);
cyclecounter.mult = clocksource_counter.mult;
default ARCH_OMAP2PLUS
select CPU_FREQ_TABLE
-config ARM_ROCKCHIP_CPUFREQ
- bool "CPUfreq driver for Rockchip CPUs"
- depends on ARCH_ROCKCHIP
- default y
- help
- This enables the CPUfreq driver for Rockchips CPUs.
- If in doubt, say Y.
-
-config ARM_ROCKCHIP_BL_CPUFREQ
- bool "CPUfreq driver for Rockchip big LITTLE CPUs"
- depends on ARCH_ROCKCHIP
- help
- This enables the CPUfreq driver for Rockchips big LITTLE CPUs.
- If in doubt, say Y.
-
config ARM_S3C2416_CPUFREQ
bool "S3C2416 CPU Frequency scaling support"
depends on CPU_S3C2416
obj-$(CONFIG_PXA25x) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA27x) += pxa2xx-cpufreq.o
obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o
-obj-$(CONFIG_ARM_ROCKCHIP_CPUFREQ) += rockchip-cpufreq.o
-obj-$(CONFIG_ARM_ROCKCHIP_BL_CPUFREQ) += rockchip_big_little.o
obj-$(CONFIG_ARM_S3C2416_CPUFREQ) += s3c2416-cpufreq.o
obj-$(CONFIG_ARM_S3C64XX_CPUFREQ) += s3c64xx-cpufreq.o
obj-$(CONFIG_ARM_S5PV210_CPUFREQ) += s5pv210-cpufreq.o
#include <linux/cpu.h>
#include <linux/cpumask.h>
#include <linux/cpufreq.h>
-#ifdef CONFIG_ARCH_ROCKCHIP
-#include <linux/input.h>
-#endif
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/rwsem.h>
int boostpulse_duration_val;
/* End time of boost pulse in ktime converted to usecs */
u64 boostpulse_endtime;
-#ifdef CONFIG_ARCH_ROCKCHIP
- /* Frequency to which a touch boost takes the cpus to */
- unsigned long touchboost_freq;
- /* Duration of a touchboost pulse in usecs */
- int touchboostpulse_duration_val;
- /* End time of touchboost pulse in ktime converted to usecs */
- u64 touchboostpulse_endtime;
-#endif
bool boosted;
/*
* Max additional time to wait in idle, beyond timer_rate, at speeds
cpu_load = loadadjfreq / pcpu->policy->cur;
tunables->boosted = tunables->boost_val || now < tunables->boostpulse_endtime;
-#ifdef CONFIG_ARCH_ROCKCHIP
- pcpu->target_freq = pcpu->policy->cur;
- tunables->boosted |= now < tunables->touchboostpulse_endtime;
-#endif
-
if (cpu_load >= tunables->go_hispeed_load || tunables->boosted) {
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (now < tunables->touchboostpulse_endtime) {
- new_freq = choose_freq(pcpu, loadadjfreq);
- if (new_freq < tunables->touchboost_freq)
- new_freq = tunables->touchboost_freq;
- } else
-#endif
if (pcpu->target_freq < tunables->hispeed_freq) {
new_freq = tunables->hispeed_freq;
} else {
.notifier_call = cpufreq_interactive_idle_notifier,
};
-#ifdef CONFIG_ARCH_ROCKCHIP
-static void cpufreq_interactive_input_event(struct input_handle *handle, unsigned int type,
- unsigned int code, int value)
-{
- u64 now, endtime;
- int i;
- int anyboost = 0;
- unsigned long flags[2];
- struct cpufreq_interactive_cpuinfo *pcpu;
- struct cpufreq_interactive_tunables *tunables;
-
- if (type != EV_ABS)
- return;
-
- trace_cpufreq_interactive_boost("touch");
- spin_lock_irqsave(&speedchange_cpumask_lock, flags[0]);
-
- now = ktime_to_us(ktime_get());
- for_each_online_cpu(i) {
- pcpu = &per_cpu(cpuinfo, i);
- if (have_governor_per_policy())
- tunables = pcpu->policy->governor_data;
- else
- tunables = common_tunables;
- if (!tunables)
- continue;
-
- endtime = now + tunables->touchboostpulse_duration_val;
- if (endtime < (tunables->touchboostpulse_endtime + 10 * USEC_PER_MSEC))
- continue;
- tunables->touchboostpulse_endtime = endtime;
-
- spin_lock_irqsave(&pcpu->target_freq_lock, flags[1]);
- if (pcpu->target_freq < tunables->touchboost_freq) {
- pcpu->target_freq = tunables->touchboost_freq;
- cpumask_set_cpu(i, &speedchange_cpumask);
- pcpu->hispeed_validate_time =
- ktime_to_us(ktime_get());
- anyboost = 1;
- }
-
- pcpu->floor_freq = tunables->touchboost_freq;
- pcpu->floor_validate_time = ktime_to_us(ktime_get());
-
- spin_unlock_irqrestore(&pcpu->target_freq_lock, flags[1]);
- }
-
- spin_unlock_irqrestore(&speedchange_cpumask_lock, flags[0]);
- if (anyboost)
- wake_up_process(speedchange_task);
-}
-
-static int cpufreq_interactive_input_connect(struct input_handler *handler,
- struct input_dev *dev, const struct input_device_id *id)
-{
- struct input_handle *handle;
- int error;
-
- handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
- if (!handle)
- return -ENOMEM;
-
- handle->dev = dev;
- handle->handler = handler;
- handle->name = "cpufreq";
-
- error = input_register_handle(handle);
- if (error)
- goto err2;
-
- error = input_open_device(handle);
- if (error)
- goto err1;
-
- return 0;
-err1:
- input_unregister_handle(handle);
-err2:
- kfree(handle);
- return error;
-}
-
-static void cpufreq_interactive_input_disconnect(struct input_handle *handle)
-{
- input_close_device(handle);
- input_unregister_handle(handle);
- kfree(handle);
-}
-
-static const struct input_device_id cpufreq_interactive_ids[] = {
- {
- .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
- INPUT_DEVICE_ID_MATCH_ABSBIT,
- .evbit = { BIT_MASK(EV_ABS) },
- .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
- BIT_MASK(ABS_MT_POSITION_X) |
- BIT_MASK(ABS_MT_POSITION_Y) },
- },
- {
- .flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
- INPUT_DEVICE_ID_MATCH_ABSBIT,
- .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
- .absbit = { [BIT_WORD(ABS_X)] =
- BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
- },
- { },
-};
-
-static struct input_handler cpufreq_interactive_input_handler = {
- .event = cpufreq_interactive_input_event,
- .connect = cpufreq_interactive_input_connect,
- .disconnect = cpufreq_interactive_input_disconnect,
- .name = "cpufreq_interactive",
- .id_table = cpufreq_interactive_ids,
-};
-#endif
-
static int cpufreq_governor_interactive(struct cpufreq_policy *policy,
unsigned int event)
{
spin_lock_init(&tunables->target_loads_lock);
spin_lock_init(&tunables->above_hispeed_delay_lock);
-#ifdef CONFIG_ARCH_ROCKCHIP
- {
- unsigned int index;
- freq_table = cpufreq_frequency_get_table(policy->cpu);
- tunables->hispeed_freq = policy->max;
- if (policy->min < 600000)
- tunables->hispeed_freq = 600000;
- else if (cpufreq_frequency_table_target(policy, freq_table, policy->min + 1, CPUFREQ_RELATION_L, &index) == 0)
- tunables->hispeed_freq = freq_table[index].frequency;
- tunables->timer_slack_val = 20 * USEC_PER_MSEC;
- tunables->min_sample_time = 40 * USEC_PER_MSEC;
- store_above_hispeed_delay(tunables, "20000 1000000:80000 1200000:100000 1700000:20000", 0);
- store_target_loads(tunables, "70 600000:70 800000:75 1500000:80 1700000:90", 0);
- tunables->boostpulse_duration_val = 40 * USEC_PER_MSEC;
- tunables->touchboostpulse_duration_val = 500 * USEC_PER_MSEC;
- tunables->touchboost_freq = 1200000;
- }
-#endif
-
policy->governor_data = tunables;
if (!have_governor_per_policy())
common_tunables = tunables;
idle_notifier_register(&cpufreq_interactive_idle_nb);
cpufreq_register_notifier(&cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
-#ifdef CONFIG_ARCH_ROCKCHIP
- rc = input_register_handler(&cpufreq_interactive_input_handler);
-#endif
}
break;
case CPUFREQ_GOV_POLICY_EXIT:
if (!--tunables->usage_count) {
if (policy->governor->initialized == 1) {
-#ifdef CONFIG_ARCH_ROCKCHIP
- input_unregister_handler(&cpufreq_interactive_input_handler);
-#endif
cpufreq_unregister_notifier(&cpufreq_notifier_block,
CPUFREQ_TRANSITION_NOTIFIER);
idle_notifier_unregister(&cpufreq_interactive_idle_nb);
spin_lock(&cpufreq_stats_lock);
stat->last_time = get_jiffies_64();
stat->last_index = freq_table_get_index(stat, policy->cur);
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (stat->last_index == -1)
- stat->last_index = 0;
-#endif
spin_unlock(&cpufreq_stats_lock);
cpufreq_cpu_put(data);
return 0;
comment "DEVFREQ Drivers"
-config ROCKCHIP_RK3368_DDR_FREQ
- bool "ROCKCHIP RK3368 DDR FREQ Driver"
- depends on ARCH_ROCKCHIP
- help
- This adds the rockchip ddr change freq driver for rk3368 it
- used MCU to change ddr freq,and mast enadle rockchip mailbox
- and scpi.
-
config ARM_EXYNOS4_BUS_DEVFREQ
bool "ARM Exynos4210/4212/4412 Memory Bus DEVFREQ Driver"
depends on CPU_EXYNOS4210 || CPU_EXYNOS4212 || CPU_EXYNOS4412
obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o
obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o
-obj-$(CONFIG_ROCKCHIP_RK3368_DDR_FREQ) += ddr_rk3368.o
# DEVFREQ Drivers
obj-$(CONFIG_ARM_EXYNOS4_BUS_DEVFREQ) += exynos4_bus.o
return -EAGAIN;
}
- return 0;
+ return pm_schedule_suspend(dev, 0);
}
/******************************************************************************
#include <linux/of.h>
#include <linux/of_dma.h>
#include <linux/err.h>
-#include <asm/unaligned.h>
#include "dmaengine.h"
#define PL330_MAX_CHAN 8
/* The number of default descriptors */
-#define NR_DEFAULT_DESC 32
+#define NR_DEFAULT_DESC 16
/* Populated by the PL330 core driver for DMA API driver's info */
struct pl330_config {
struct pl330_xfer *x;
/* Hook to attach to DMAC's list of reqs with due callback */
struct list_head rqd;
- unsigned int infiniteloop;
};
/*
/* Maximum possible events/irqs */
int events[32];
/* BUS address of MicroCode buffer */
- dma_addr_t mcode_bus;
+ u32 mcode_bus;
/* CPU address of MicroCode buffer */
void *mcode_cpu;
/* List of all Channel threads */
/* for cyclic capability */
bool cyclic;
-
- enum dma_status chan_status;
};
struct dma_pl330_dmac {
void __iomem *regs = pi->base;
u32 id = 0;
-#ifdef CONFIG_ARCH_ROCKCHIP
- id |= ((readl(regs + off + 0x0) & 0xff) << 0);
- id |= ((readl(regs + off + 0x4) & 0xff) << 8);
- id |= ((readl(regs + off + 0x8) & 0xff) << 16);
- id |= ((readl(regs + off + 0xc) & 0xff) << 24);
-#else
id |= (readb(regs + off + 0x0) << 0);
id |= (readb(regs + off + 0x4) << 8);
id |= (readb(regs + off + 0x8) << 16);
id |= (readb(regs + off + 0xc) << 24);
-#endif
return id;
}
buf[0] = CMD_DMAADDH;
buf[0] |= (da << 1);
- put_unaligned(val, (u16 *)&buf[1]); //*((u16 *)&buf[1]) = val;
+ *((u16 *)&buf[1]) = val;
PL330_DBGCMD_DUMP(SZ_DMAADDH, "\tDMAADDH %s %u\n",
da == 1 ? "DA" : "SA", val);
buf[0] = CMD_DMAMOV;
buf[1] = dst;
- put_unaligned(val, (u32 *)&buf[2]); //*((u32 *)&buf[2]) = val;
+ *((u32 *)&buf[2]) = val;
PL330_DBGCMD_DUMP(SZ_DMAMOV, "\tDMAMOV %s 0x%x\n",
dst == SAR ? "SAR" : (dst == DAR ? "DAR" : "CCR"), val);
buf[1] = chan & 0x7;
- put_unaligned(addr, (u32 *)&buf[2]); //*((u32 *)&buf[2]) = addr;
+ *((u32 *)&buf[2]) = addr;
return SZ_DMAGO;
}
int off = 0;
while (cyc--) {
-#ifdef CONFIG_ARCH_ROCKCHIP
- off += _emit_WFP(dry_run, &buf[off], BURST, pxs->r->peri);
- off += _emit_LDP(dry_run, &buf[off], BURST, pxs->r->peri);
- off += _emit_ST(dry_run, &buf[off], ALWAYS);
- //off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri); //for sdmmc sdio
-#else
off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
off += _emit_LDP(dry_run, &buf[off], SINGLE, pxs->r->peri);
off += _emit_ST(dry_run, &buf[off], ALWAYS);
off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
-#endif
}
return off;
int off = 0;
while (cyc--) {
-#ifdef CONFIG_ARCH_ROCKCHIP
- off += _emit_WFP(dry_run, &buf[off], BURST, pxs->r->peri);
- off += _emit_LD(dry_run, &buf[off], ALWAYS);
- off += _emit_STP(dry_run, &buf[off], BURST, pxs->r->peri);
- //off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
-#else
off += _emit_WFP(dry_run, &buf[off], SINGLE, pxs->r->peri);
off += _emit_LD(dry_run, &buf[off], ALWAYS);
off += _emit_STP(dry_run, &buf[off], SINGLE, pxs->r->peri);
off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
-#endif
}
return off;
return off;
}
-/* Returns bytes consumed */
-static inline int _loop_infiniteloop(unsigned dry_run, u8 buf[],
- unsigned long bursts, const struct _xfer_spec *pxs, int ev)
-{
- int cyc, off;
- unsigned lcnt0, lcnt1, ljmp0, ljmp1, ljmpfe;
- struct _arg_LPEND lpend;
-
- off = 0;
- ljmpfe = off;
- lcnt0 = pxs->r->infiniteloop;
-
- if (bursts > 256) {
- lcnt1 = 256;
- cyc = bursts / 256;
- } else {
- lcnt1 = bursts;
- cyc = 1;
- }
-
- /* forever loop */
- off += _emit_MOV(dry_run, &buf[off], SAR, pxs->x->src_addr);
- off += _emit_MOV(dry_run, &buf[off], DAR, pxs->x->dst_addr);
- if (pxs->r->rqtype != MEMTOMEM)
- off += _emit_FLUSHP(dry_run, &buf[off], pxs->r->peri);
-
- /* loop0 */
- off += _emit_LP(dry_run, &buf[off], 0, lcnt0);
- ljmp0 = off;
-
- /* loop1 */
- off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
- ljmp1 = off;
- off += _bursts(dry_run, &buf[off], pxs, cyc);
- lpend.cond = ALWAYS;
- lpend.forever = false;
- lpend.loop = 1;
- lpend.bjump = off - ljmp1;
- off += _emit_LPEND(dry_run, &buf[off], &lpend);
-
- /* remainder */
- lcnt1 = bursts - (lcnt1 * cyc);
-
- if (lcnt1) {
- off += _emit_LP(dry_run, &buf[off], 1, lcnt1);
- ljmp1 = off;
- off += _bursts(dry_run, &buf[off], pxs, 1);
- lpend.cond = ALWAYS;
- lpend.forever = false;
- lpend.loop = 1;
- lpend.bjump = off - ljmp1;
- off += _emit_LPEND(dry_run, &buf[off], &lpend);
- }
-
- off += _emit_SEV(dry_run, &buf[off], ev);
-
- lpend.cond = ALWAYS;
- lpend.forever = false;
- lpend.loop = 0;
- lpend.bjump = off - ljmp0;
- off += _emit_LPEND(dry_run, &buf[off], &lpend);
-
- lpend.cond = ALWAYS;
- lpend.forever = true;
- lpend.loop = 1;
- lpend.bjump = off - ljmpfe;
- off += _emit_LPEND(dry_run, &buf[off], &lpend);
-
- return off;
-}
-
/* Returns bytes consumed and updates bursts */
static inline int _loop(unsigned dry_run, u8 buf[],
unsigned long *bursts, const struct _xfer_spec *pxs)
return off;
}
-static inline int _setup_xfer_infiniteloop(unsigned dry_run, u8 buf[],
- const struct _xfer_spec *pxs, int ev)
-{
- struct pl330_xfer *x = pxs->x;
- u32 ccr = pxs->ccr;
- unsigned long bursts = BYTE_TO_BURST(x->bytes, ccr);
- int off = 0;
-
- /* Setup Loop(s) */
- off += _loop_infiniteloop(dry_run, &buf[off], bursts, pxs, ev);
-
- return off;
-}
-
static inline int _setup_loops(unsigned dry_run, u8 buf[],
const struct _xfer_spec *pxs)
{
off += _emit_MOV(dry_run, &buf[off], CCR, pxs->ccr);
x = pxs->r->x;
- if (!pxs->r->infiniteloop) {
- do {
- /* Error if xfer length is not aligned at burst size */
- if (x->bytes % (BRST_SIZE(pxs->ccr) *
- BRST_LEN(pxs->ccr)))
- return -EINVAL;
-
- pxs->x = x;
- off += _setup_xfer(dry_run, &buf[off], pxs);
-
- x = x->next;
- } while (x);
-
- /* DMASEV peripheral/event */
- off += _emit_SEV(dry_run, &buf[off], thrd->ev);
- /* DMAEND */
- off += _emit_END(dry_run, &buf[off]);
- } else {
+ do {
/* Error if xfer length is not aligned at burst size */
if (x->bytes % (BRST_SIZE(pxs->ccr) * BRST_LEN(pxs->ccr)))
return -EINVAL;
pxs->x = x;
- off += _setup_xfer_infiniteloop(dry_run, &buf[off],
- pxs, thrd->ev);
- }
+ off += _setup_xfer(dry_run, &buf[off], pxs);
+
+ x = x->next;
+ } while (x);
+
+ /* DMASEV peripheral/event */
+ off += _emit_SEV(dry_run, &buf[off], thrd->ev);
+ /* DMAEND */
+ off += _emit_END(dry_run, &buf[off]);
return off;
}
id = pl330->events[ev];
- if (id == -1)
- continue;
-
thrd = &pl330->channels[id];
active = thrd->req_running;
/* Detach the req */
rqdone = thrd->req[active].r;
- if (!rqdone->infiniteloop) {
+ thrd->req[active].r = NULL;
- /* Detach the req */
- thrd->req[active].r = NULL;
+ mark_free(thrd, active);
- mark_free(thrd, active);
-
- /* Get going again ASAP */
- _start(thrd);
- }
+ /* Get going again ASAP */
+ _start(thrd);
/* For now, just make a list of callbacks to be done */
list_add_tail(&rqdone->rqd, &pl330->req_done);
{
struct pl330_dmac *pl330 = thrd->dmac;
struct pl330_info *pi = pl330->pinfo;
- void __iomem *regs = pi->base;
- u32 inten = readl(regs + INTEN);
/* If the event is valid and was held by the thread */
if (ev >= 0 && ev < pi->pcfg.num_events
- && pl330->events[ev] == thrd->id) {
+ && pl330->events[ev] == thrd->id)
pl330->events[ev] = -1;
-
- if (readl(regs + ES) & (1 << ev)) {
- if (!(inten & (1 << ev)))
- writel(inten | (1 << ev), regs + INTEN);
- writel(1 << ev, regs + INTCLR);
- writel(inten & ~(1 << ev) , regs + INTEN);
- }
- }
}
static void pl330_release_channel(void *ch_id)
}
/* pch will be unset if list was empty */
- if (!pch || !pch->dmac)
+ if (!pch)
return;
spin_lock_irqsave(&pch->lock, flags);
- if (pch->chan_status == DMA_PAUSED) {
- list_for_each_entry(desc, list, node) {
- desc->status = DONE;
- }
- list_splice_tail_init(list, &pch->dmac->desc_pool);
- } else {
- list_splice_tail_init(list, &pch->work_list);
- }
+ list_splice_tail_init(list, &pch->work_list);
spin_unlock_irqrestore(&pch->lock, flags);
}
spin_lock_irqsave(&pch->lock, flags);
- pch->chan_status = DMA_SUCCESS;
/* Pick up ripe tomatoes */
list_for_each_entry_safe(desc, _dt, &pch->work_list, node)
if (desc->status == DONE) {
return false;
peri_id = chan->private;
- return *peri_id == (unsigned long)param;
+ return *peri_id == (unsigned)param;
}
EXPORT_SYMBOL(pl330_filter);
}
list_splice_tail_init(&list, &pdmac->desc_pool);
- pch->chan_status = DMA_PAUSED;
spin_unlock_irqrestore(&pch->lock, flags);
break;
case DMA_SLAVE_CONFIG:
pl330_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
struct dma_tx_state *txstate)
{
- struct dma_pl330_chan *pch = to_pchan(chan);
- void __iomem *regs = pch->dmac->pif.base;
- struct pl330_thread *pt = pch->pl330_chid;
- enum dma_status st;
- st = dma_cookie_status(chan, cookie, txstate);
- txstate->residue = readl(regs + DA(pt->id));
- return st;
+ return dma_cookie_status(chan, cookie, txstate);
}
static void pl330_issue_pending(struct dma_chan *chan)
if (!pdmac)
return 0;
- desc = kzalloc(count * sizeof(*desc), flg);
+ desc = kmalloc(count * sizeof(*desc), flg);
if (!desc)
return 0;
struct dma_pl330_dmac *pdmac = pch->dmac;
u8 *peri_id = pch->chan.private;
struct dma_pl330_desc *desc;
- int i = 0;
/* Pluck one desc from the pool of DMAC */
desc = pluck_desc(pdmac);
/* If the DMAC pool is empty, alloc new */
if (!desc) {
- for(i = 0; i < 3; i++) {
- if (!add_desc(pdmac, GFP_ATOMIC, 1))
- continue;
-
- /* Try again */
- desc = pluck_desc(pdmac);
- if (!desc) {
- dev_err(pch->dmac->pif.dev,
- "%s:%d i=%d ALERT!\n", __func__, __LINE__,i);
- continue;
- }
- break;
- }
+ if (!add_desc(pdmac, GFP_ATOMIC, 1))
+ return NULL;
- if(!desc && i >= 3)
+ /* Try again */
+ desc = pluck_desc(pdmac);
+ if (!desc) {
+ dev_err(pch->dmac->pif.dev,
+ "%s:%d ALERT!\n", __func__, __LINE__);
return NULL;
+ }
}
/* Initialize the descriptor */
desc->txd.cookie = 0;
async_tx_ack(&desc->txd);
- desc->req.infiniteloop = 0;
desc->req.peri = peri_id ? pch->chan.chan_id : 0;
desc->rqcfg.pcfg = &pch->dmac->pif.pcfg;
unsigned int i;
dma_addr_t dst;
dma_addr_t src;
- unsigned int *infinite = context;
if (len % period_len != 0)
return NULL;
}
desc->rqcfg.brst_size = pch->burst_sz;
-#ifdef CONFIG_ARCH_ROCKCHIP
- desc->rqcfg.brst_len = pch->burst_len;
-#else
desc->rqcfg.brst_len = 1;
-#endif
- desc->req.infiniteloop = *infinite;
fill_px(&desc->px, dst, src, period_len);
if (!first)
}
desc->rqcfg.brst_size = pch->burst_sz;
-#ifdef CONFIG_ARCH_ROCKCHIP
- desc->rqcfg.brst_len = pch->burst_len;
-#else
desc->rqcfg.brst_len = 1;
-#endif
}
/* Return the last desc in the chain */
return IRQ_NONE;
}
-int pl330_dma_getposition(struct dma_chan *chan,
- dma_addr_t *src, dma_addr_t *dst)
-{
- struct dma_pl330_chan *pch = to_pchan(chan);
- struct pl330_info *pi;
- void __iomem *regs;
- struct pl330_thread *thrd;
-
- if (unlikely(!pch))
- return -EINVAL;
-
- thrd = pch->pl330_chid;
- pi = &pch->dmac->pif;
- regs = pi->base;
-
- *src = readl(regs + SA(thrd->id));
- *dst = readl(regs + DA(thrd->id));
-
- return 0;
-}
-EXPORT_SYMBOL(pl330_dma_getposition);
-
static int
pl330_probe(struct amba_device *adev, const struct amba_id *id)
{
pd->device_prep_slave_sg = pl330_prep_slave_sg;
pd->device_control = pl330_control;
pd->device_issue_pending = pl330_issue_pending;
-#ifdef CONFIG_ARCH_ROCKCHIP
- pd->dma_getposition = pl330_dma_getposition;
-#endif
ret = dma_async_device_register(pd);
if (ret) {
help
Say yes here to support GPIO on Renesas R-Car SoCs.
-config GPIO_RT5025
- bool "Richtek RT5025 GPIO support"
- depends on MFD_RT5025
- default n
- help
- This is the gpio driver for RT5025 PMIC.
-
config GPIO_SPEAR_SPICS
bool "ST SPEAr13xx SPI Chip Select as GPIO support"
depends on PLAT_SPEAR
obj-$(CONFIG_GPIO_WM8350) += gpio-wm8350.o
obj-$(CONFIG_GPIO_WM8994) += gpio-wm8994.o
obj-$(CONFIG_GPIO_XILINX) += gpio-xilinx.o
-obj-$(CONFIG_GPIO_RT5025) += gpio-rt5025.o
static int lnw_gpio_runtime_idle(struct device *dev)
{
- pm_schedule_suspend(dev, 500);
+ int err = pm_schedule_suspend(dev, 500);
+
+ if (!err)
+ return 0;
+
return -EBUSY;
}
-obj-y += drm/ vga/ arm/
+obj-y += drm/ vga/
obj-$(CONFIG_TEGRA_HOST1X) += host1x/
-obj-$(CONFIG_POWERVR_ROGUE) += rogue/
source "drivers/gpu/drm/exynos/Kconfig"
-source "drivers/gpu/drm/rockchip/Kconfig"
-
source "drivers/gpu/drm/vmwgfx/Kconfig"
source "drivers/gpu/drm/gma500/Kconfig"
obj-$(CONFIG_DRM_VIA) +=via/
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
obj-$(CONFIG_DRM_EXYNOS) +=exynos/
-obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/
obj-$(CONFIG_DRM_AST) += ast/
ret = -ENOSPC;
goto out;
}
- fb->pixel_format = crtc->fb->pixel_format;
+
if (crtc->fb->pixel_format != fb->pixel_format) {
DRM_DEBUG_KMS("Page flip is not allowed to change frame buffer format.\n");
ret = -EINVAL;
#include <drm/drmP.h>
#include <drm/drm_core.h>
-unsigned int drm_debug = 0xf; /* 1 to enable debug output */
+unsigned int drm_debug = 0; /* 1 to enable debug output */
EXPORT_SYMBOL(drm_debug);
unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */
unsigned int minor = iminor(inode);
struct hidraw *dev;
struct hidraw_list *list;
- unsigned long flags;
int err = 0;
if (!(list = kzalloc(sizeof(struct hidraw_list), GFP_KERNEL))) {
goto out_unlock;
}
+ list->hidraw = hidraw_table[minor];
+ mutex_init(&list->read_mutex);
+ list_add_tail(&list->node, &hidraw_table[minor]->list);
+ file->private_data = list;
+
dev = hidraw_table[minor];
if (!dev->open++) {
err = hid_hw_power(dev->hid, PM_HINT_FULLON);
if (err < 0) {
hid_hw_power(dev->hid, PM_HINT_NORMAL);
dev->open--;
- goto out_unlock;
}
}
- list->hidraw = hidraw_table[minor];
- mutex_init(&list->read_mutex);
- spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
- list_add_tail(&list->node, &hidraw_table[minor]->list);
- spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags);
- file->private_data = list;
out_unlock:
mutex_unlock(&minors_lock);
out:
{
unsigned int minor = iminor(inode);
struct hidraw_list *list = file->private_data;
- unsigned long flags;
mutex_lock(&minors_lock);
- spin_lock_irqsave(&hidraw_table[minor]->list_lock, flags);
list_del(&list->node);
- spin_unlock_irqrestore(&hidraw_table[minor]->list_lock, flags);
kfree(list);
drop_ref(hidraw_table[minor], 0);
struct hidraw *dev = hid->hidraw;
struct hidraw_list *list;
int ret = 0;
- unsigned long flags;
- spin_lock_irqsave(&dev->list_lock, flags);
list_for_each_entry(list, &dev->list, node) {
int new_head = (list->head + 1) & (HIDRAW_BUFFER_SIZE - 1);
list->head = new_head;
kill_fasync(&list->fasync, SIGIO, POLL_IN);
}
- spin_unlock_irqrestore(&dev->list_lock, flags);
wake_up_interruptible(&dev->wait);
return ret;
mutex_unlock(&minors_lock);
init_waitqueue_head(&dev->wait);
- spin_lock_init(&dev->list_lock);
INIT_LIST_HEAD(&dev->list);
dev->hid = hid;
usbhid_set_leds(hid);
device_set_wakeup_enable(&dev->dev, 1);
}
- device_set_wakeup_enable(&dev->dev, 1);
return 0;
fail:
This driver can also be built as a module. If so, the module
will be called sht21.
-config SENSORS_ROCKCHIP_TSADC
- tristate "ROCKCHIP built-in TSADC"
- help
- If you say yes here you get support for the on-board TSADCs of
- the ROCKCHIP RK3288 and other series of SoC
-
- This driver can also be built as a module. If so, the module
- will be called rockchip-hwmon.
-
config SENSORS_S3C
tristate "Samsung built-in ADC"
depends on S3C_ADC
obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
-obj-$(CONFIG_SENSORS_ROCKCHIP_TSADC) += rockchip-hwmon.o rockchip_tsadc.o
obj-$(CONFIG_SENSORS_S3C) += s3c-hwmon.o
obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
obj-$(CONFIG_SENSORS_SCH5627) += sch5627.o
is necessary for systems where the PXA may be a target on the
I2C bus.
-config I2C_ROCKCHIP
- tristate "Rockchip I2C interface"
- depends on ARCH_ROCKCHIP
- help
- If you say yes to this option, support will be included for the
- Rockchip I2C interface.
-
- This driver can also be built as a module. If so, the module
- will be called i2c-rockchip.
-
-config I2C_ROCKCHIP_COMPAT
- bool "Support set sclk rate on i2c_msg (DEPRECATED)"
- depends on I2C_ROCKCHIP
-
config HAVE_S3C2410_I2C
bool
help
obj-$(CONFIG_I2C_PUV3) += i2c-puv3.o
obj-$(CONFIG_I2C_PXA) += i2c-pxa.o
obj-$(CONFIG_I2C_PXA_PCI) += i2c-pxa-pci.o
-obj-$(CONFIG_I2C_ROCKCHIP) += i2c-rockchip.o
obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o
obj-$(CONFIG_I2C_S6000) += i2c-s6000.o
obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o
static DEFINE_IDR(i2c_adapter_idr);
static struct device_type i2c_client_type;
-static int i2c_check_addr_ex(struct i2c_adapter *adapter, int addr);
static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver);
/* ------------------------------------------------------------------------- */
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
- NULL
+ pm_generic_runtime_idle
)
};
}
/* Check for address business */
- #if 0
status = i2c_check_addr_busy(adap, client->addr);
if (status)
goto out_err;
- #else
- /* ddl@rock-chips.com : Devices which have some i2c addr can work in same i2c bus,
- if devices havn't work at the same time.*/
- status = i2c_check_addr_ex(adap, client->addr);
- if (status != 0)
- dev_err(&adap->dev, "%d i2c clients have been registered at 0x%02x",
- status, client->addr);
- #endif
client->dev.parent = &client->adapter->dev;
client->dev.bus = &i2c_bus_type;
ACPI_HANDLE_SET(&client->dev, info->acpi_node.handle);
/* For 10-bit clients, add an arbitrary offset to avoid collisions */
-
- /* ddl@rock-chips.com : Devices which have some i2c addr can work in same i2c bus,
- if devices havn't work at the same time.*/
- #if 0
dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
client->addr | ((client->flags & I2C_CLIENT_TEN)
? 0xa000 : 0));
- #else
- if (status == 0)
- dev_set_name(&client->dev, "%d-%04x", i2c_adapter_id(adap),
- client->addr);
- else
- dev_set_name(&client->dev, "%d-%04x-%01x", i2c_adapter_id(adap),
- client->addr,status);
- #endif
-
status = device_register(&client->dev);
if (status)
goto out_err;
EXPORT_SYMBOL(i2c_del_driver);
/* ------------------------------------------------------------------------- */
-/* ddl@rock-chips.com : Devices which have some i2c addr can work in same i2c bus,
- if devices havn't work at the same time.*/
-struct i2c_addr_cnt
-{
- int addr;
- int cnt;
-};
-static int __i2c_check_addr_ex(struct device *dev, void *addrp)
-{
- struct i2c_client *client = i2c_verify_client(dev);
- struct i2c_addr_cnt *addrinfo = (struct i2c_addr_cnt *)addrp;
- int addr = addrinfo->addr;
-
- if (client && client->addr == addr) {
- addrinfo->cnt++;
- }
- return 0;
-}
-static int i2c_check_addr_ex(struct i2c_adapter *adapter, int addr)
-{
- struct i2c_addr_cnt addrinfo;
-
- addrinfo.addr = addr;
- addrinfo.cnt = 0;
- device_for_each_child(&adapter->dev, &addrinfo, __i2c_check_addr_ex);
- return addrinfo.cnt;
-}
/**
* i2c_use_client - increments the reference count of the i2c client structure
msg.flags = client->flags & I2C_M_TEN;
msg.len = count;
msg.buf = (char *)buf;
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- msg.scl_rate = 100 * 1000;
-#endif
ret = i2c_transfer(adap, &msg, 1);
msg.flags |= I2C_M_RD;
msg.len = count;
msg.buf = buf;
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- msg.scl_rate = 100 * 1000;
-#endif
ret = i2c_transfer(adap, &msg, 1);
.flags = flags,
.len = 1,
.buf = msgbuf0,
- #ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- .scl_rate = 100 * 1000,
- #endif
}, {
.addr = addr,
.flags = flags | I2C_M_RD,
.len = 0,
.buf = msgbuf1,
- #ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- .scl_rate = 100 * 1000,
- #endif
},
};
Say yes here to access the ADC part of the Nano River
Technologies Viperboard.
-config ROCKCHIP_ADC
- tristate "Rockchip ADC support"
- depends on OF
- help
- Core support for the ADC block found in the Rockchip series
- of SoCs for drivers such as the key and battery to use it.
endmenu
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
-obj-$(CONFIG_ROCKCHIP_ADC) += rockchip_adc.o
source "drivers/input/misc/Kconfig"
-source "drivers/input/sensors/Kconfig"
-
-source "drivers/input/remotectl/Kconfig"
endif
menu "Hardware I/O ports"
obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
obj-$(CONFIG_INPUT_MISC) += misc/
-obj-$(CONFIG_SENSOR_DEVICE) += sensors/
+
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o
-obj-$(CONFIG_ROCKCHIP_REMOTECTL)+= remotectl/
obj-$(CONFIG_INPUT_KEYCOMBO) += keycombo.o
{
int disposition;
- /*
- * When inhibited, skip all events. For devices that do not implement
- * inhibit() themselves.
- */
- if (dev->inhibited)
- return;
-
disposition = input_get_disposition(dev, type, code, &value);
if ((disposition & INPUT_PASS_TO_DEVICE) && dev->event)
}
static DEVICE_ATTR(properties, S_IRUGO, input_dev_show_properties, NULL);
-static int input_inhibit(struct input_dev *dev);
-static int input_uninhibit(struct input_dev *dev);
-
-static ssize_t input_dev_show_inhibited(struct device *dev,
- struct device_attribute *attr,
- char *buf)
-{
- struct input_dev *input_dev = to_input_dev(dev);
- return scnprintf(buf, PAGE_SIZE, "%d\n", input_dev->inhibited);
-}
-
-static ssize_t input_dev_store_inhibited(struct device *dev,
- struct device_attribute *attr,
- const char *buf,
- size_t len)
-{
- struct input_dev *input_dev = to_input_dev(dev);
- ssize_t rv;
- bool inhibited;
-
- if (strtobool(buf, &inhibited))
- return -EINVAL;
-
- if (inhibited)
- rv = input_inhibit(input_dev);
- else
- rv = input_uninhibit(input_dev);
-
- if (rv != 0)
- return rv;
-
- return len;
-}
-
-static DEVICE_ATTR(inhibited, S_IWUSR | S_IRUGO, input_dev_show_inhibited,
- input_dev_store_inhibited);
-
static struct attribute *input_dev_attrs[] = {
&dev_attr_name.attr,
&dev_attr_phys.attr,
&dev_attr_uniq.attr,
&dev_attr_modalias.attr,
&dev_attr_properties.attr,
- &dev_attr_inhibited.attr,
NULL
};
}
EXPORT_SYMBOL(input_reset_device);
-static int input_inhibit(struct input_dev *dev)
-{
- int rv = 0;
-
- mutex_lock(&dev->mutex);
-
- if (dev->inhibited)
- goto out;
-
- if (dev->inhibit) {
- rv = dev->inhibit(dev);
- if (rv != 0)
- goto out;
- }
-
- input_dev_release_keys(dev);
- input_dev_toggle(dev, false);
-
- dev->inhibited = true;
-
-out:
- mutex_unlock(&dev->mutex);
- return rv;
-}
-
-static int input_uninhibit(struct input_dev *dev)
-{
- int rv = 0;
-
- mutex_lock(&dev->mutex);
-
- if (!dev->inhibited)
- goto out;
-
- input_dev_toggle(dev, true);
-
- if (dev->uninhibit) {
- rv = dev->uninhibit(dev);
- if (rv != 0) {
- input_dev_toggle(dev, false);
- goto out;
- }
- }
-
- dev->inhibited = false;
-
-out:
- mutex_unlock(&dev->mutex);
- return rv;
-}
-
#ifdef CONFIG_PM
static int input_dev_suspend(struct device *dev)
{
if INPUT_KEYBOARD
-config KEYS_RK
- tristate "rk keyboard"
- depends on IIO
- default y
- help
- rk keyboard drivers(gpio and adc)
-
config KEYBOARD_ADP5520
tristate "Keypad Support for ADP5520 PMIC"
depends on PMIC_ADP5520
# Each configuration option enables a list of files.
-obj-$(CONFIG_KEYS_RK) += rk_keys.o
obj-$(CONFIG_KEYBOARD_ADP5520) += adp5520-keys.o
obj-$(CONFIG_KEYBOARD_ADP5588) += adp5588-keys.o
obj-$(CONFIG_KEYBOARD_ADP5589) += adp5589-keys.o
To compile this driver as a module, choose M here. The module will
be called twl4030_pwrbutton.
-config INPUT_RICOH619_PWRKEY
- tristate "RICOH RC5T619 PMU PWRKEY driver"
- depends on MFD_RICOH619
- default n
- help
- If you say yes here you get support for the RICOH RC5T619 PWRKEY module.
-
- This driver can also be built as a module. If so, the module
- will be called rc5t619-pwrkey.
config INPUT_TWL4030_VIBRA
tristate "Support for TWL4030 Vibrator"
depends on TWL4030_CORE
obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o
obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o
obj-$(CONFIG_INPUT_YEALINK) += yealink.o
-obj-$(CONFIG_INPUT_RICOH619_PWRKEY) += ricoh619-pwrkey.o
if INPUT_TOUCHSCREEN
-config TOUCHSCREEN_ZET62XX
- tristate "zet62xx touchscreen driver"
- help
- zet62xx touchscreen driver
-
-
-config TOUCHSCREEN_GSLX680
- tristate "gslX680 touchscreen driver"
- help
- gslX680 touchscreen driver
-
-config TOUCHSCREEN_GT8XX
- tristate "Goodix touch screen gt801X2 support for rockchip based platform"
- help
- Say Y here if you have a touchscreen interface using the
- two goodix gt801 , and your board-specific initialization
- code includes that in its table of IIC devices.
- If unsure, say N.
-
-config TOUCHSCREEN_GT9XX
- tristate "Goodix touch screen gt9xx support for rockchip based platform"
- help
- Say Y here if you have a touchscreen interface using the
- two goodix gt9xx, and your board-specific initialization
- code includes that in its table of IIC devices.
- If unsure, say N.
-
-config TOUCHSCREEN_CT36X_TS
- tristate "CT36X touchscreens support"
-
-config TOUCHSCREEN_VTL_CT36X
- tristate "VTL touchscreens support"
-
config TOUCHSCREEN_88PM860X
tristate "Marvell 88PM860x touchscreen"
depends on MFD_88PM860X
# Each configuration option enables a list of files.
wm97xx-ts-y := wm97xx-core.o
-obj-$(CONFIG_TOUCHSCREEN_ZET62XX) += zet62xx/
-obj-$(CONFIG_TOUCHSCREEN_GSLX680) += rockchip_gslX680_rk3128.o
-obj-$(CONFIG_TOUCHSCREEN_CT36X_TS) += ct36x/
-obj-$(CONFIG_TOUCHSCREEN_GT8XX) += rk29_i2c_goodix.o
-obj-$(CONFIG_TOUCHSCREEN_GT9XX) += gt9xx/
+
obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
obj-$(CONFIG_TOUCHSCREEN_DA9034) += da9034-ts.o
obj-$(CONFIG_TOUCHSCREEN_DA9052) += da9052_tsi.o
obj-$(CONFIG_TOUCHSCREEN_DYNAPRO) += dynapro.o
-obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += ft5506_wgj.o
+obj-$(CONFIG_TOUCHSCREEN_EDT_FT5X06) += edt-ft5x06.o
obj-$(CONFIG_TOUCHSCREEN_HAMPSHIRE) += hampshire.o
obj-$(CONFIG_TOUCHSCREEN_GUNZE) += gunze.o
obj-$(CONFIG_TOUCHSCREEN_EETI) += eeti_ts.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
-obj-$(CONFIG_TOUCHSCREEN_VTL_CT36X) += vtl_ts/
To use x2apic mode in the CPU's which support x2APIC enhancements or
to support platforms with CPU's having > 8 bit APIC ID, say Y.
-config ROCKCHIP_IOMMU
- bool "Rockchip IOMMU Support"
- depends on ARCH_ROCKCHIP
- select IOMMU_API
- help
- Support for the IOMMU(System MMU) of Rockchip rk32xx application
- processor family. This enables H/W multimedia accellerators to see
- non-linear physical memory chunks as a linear memory in their
- address spaces
-
- If unsure, say N here.
-
-config ROCKCHIP_IOVMM
- bool "IO Virtual Memory Manager for Rockcihp IOMMUs"
- select GENERIC_ALLOCATOR
- depends on ROCKCHIP_IOMMU
- default n
- help
- Supporting the users of Rockchip IOMMU for allocating and mapping
- an IO virtual memory region with a physical memory region
- and managing the allocated virtual memory regions.
-
-config ROCKCHIP_IOMMU_DEBUG
- bool "Debugging log for Rockchip IOMMU"
- depends on ROCKCHIP_IOMMU
- help
- Select this to see the detailed log message that shows what
- happens in the IOMMU driver
-
- Say N unless you need kernel log message for IOMMU debugging
-
# OMAP IOMMU support
config OMAP_IOMMU
bool "OMAP IOMMU Support"
obj-$(CONFIG_DMAR_TABLE) += dmar.o
obj-$(CONFIG_INTEL_IOMMU) += iova.o intel-iommu.o
obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
-obj-$(CONFIG_ROCKCHIP_IOVMM) += rockchip-iovmm.o
-obj-$(CONFIG_ROCKCHIP_IOMMU) += rockchip-iommu.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu2.o
obj-$(CONFIG_OMAP_IOVMM) += omap-iovmm.o
static int gic_retrigger(struct irq_data *d)
{
-#ifdef CONFIG_FIQ_DEBUGGER
- u32 mask = 1 << (gic_irq(d) % 32);
-#endif
-
if (gic_arch_extn.irq_retrigger)
return gic_arch_extn.irq_retrigger(d);
-#ifdef CONFIG_FIQ_DEBUGGER
- /* set irq pending to retrigger to cpu */
- writel_relaxed(mask, gic_dist_base(d) + GIC_DIST_PENDING_SET + (gic_irq(d) / 32) * 4);
-#endif
/* the genirq layer expects 0 if we can't retrigger in hardware */
return 0;
}
-#ifdef CONFIG_FIQ_GLUE
-/*
- * ICDISR each bit 0 -- Secure 1--Non-Secure
- */
-void gic_set_irq_secure(struct irq_data *d)
-{
- u32 mask = 0;
- void __iomem *base = gic_dist_base(d);
-
- //raw_spin_lock(&irq_controller_lock);
- base += GIC_DIST_IGROUP + ((gic_irq(d) / 32) * 4);
- mask = readl_relaxed(base);
- mask &= ~(1 << (gic_irq(d) % 32));
- writel_relaxed(mask, base);
- //raw_spin_unlock(&irq_controller_lock);
-}
-
-void gic_set_irq_priority(struct irq_data *d, u8 pri)
-{
- writeb_relaxed(pri, gic_dist_base(d) + GIC_DIST_PRI + gic_irq(d));
-}
-#endif
-
#ifdef CONFIG_SMP
static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val,
bool force)
gic_dist_config(base, gic_irqs, NULL);
-#ifdef CONFIG_FIQ_GLUE
- // set all the interrupt to non-secure state
- for (i = 0; i < gic_irqs; i += 32) {
- writel_relaxed(0xffffffff, base + GIC_DIST_IGROUP + i * 4 / 32);
- }
- dsb(sy);
- writel_relaxed(3, base + GIC_DIST_CTRL);
-#else
writel_relaxed(1, base + GIC_DIST_CTRL);
-#endif
}
static void __cpuinit gic_cpu_init(struct gic_chip_data *gic)
gic_cpu_config(dist_base, NULL);
writel_relaxed(0xf0, base + GIC_CPU_PRIMASK);
-#ifdef CONFIG_FIQ_GLUE
- writel_relaxed(0x0f, base + GIC_CPU_CTRL);
-#else
writel_relaxed(1, base + GIC_CPU_CTRL);
-#endif
}
void gic_cpu_if_down(void)
writel_relaxed(gic_data[gic_nr].saved_spi_enable[i],
dist_base + GIC_DIST_ENABLE_SET + i * 4);
-#ifdef CONFIG_FIQ_GLUE
- writel_relaxed(3, dist_base + GIC_DIST_CTRL);
-#else
writel_relaxed(1, dist_base + GIC_DIST_CTRL);
-#endif
}
static void gic_cpu_save(unsigned int gic_nr)
writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4);
writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK);
-#ifdef CONFIG_FIQ_GLUE
- writel_relaxed(0x0f, cpu_base + GIC_CPU_CTRL);
-#else
writel_relaxed(1, cpu_base + GIC_CPU_CTRL);
-#endif
}
static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v)
dmb(ishst);
/* this always happens on GIC0 */
-#ifdef CONFIG_FIQ_GLUE
- /* enable non-secure SGI for GIC with security extensions */
- writel_relaxed(map << 16 | irq | 0x8000, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
-#else
writel_relaxed(map << 16 | irq, gic_data_dist_base(&gic_data[0]) + GIC_DIST_SOFTINT);
-#endif
raw_spin_unlock_irqrestore(&irq_controller_lock, flags);
}
{
if (action == CPU_STARTING || action == CPU_STARTING_FROZEN)
gic_cpu_init(&gic_data[0]);
-#ifdef CONFIG_FIQ_GLUE
- if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) {
- /*set SGI to none secure state*/
- writel_relaxed(0xffffffff, gic_data_dist_base(&gic_data[0]) + GIC_DIST_IGROUP);
- writel_relaxed(0xf, gic_data_cpu_base(&gic_data[0]) + GIC_CPU_CTRL);
- }
-#endif
return NOTIFY_OK;
}
Management Engine, primarily for cpufreq. Say Y here if you want
to use the PL320 IPCM support.
-config ROCKCHIP_MAILBOX
- bool "Rockchip Soc Intergrated Mailbox Support"
- depends on ARCH_ROCKCHIP
- help
- This driver provides support for inter-processor communication
- between CPU cores and MCU processor on Some Rockchip SOCs.
- Please check it that the Soc you use have Mailbox hardware.
- Say Y here if you want to use the Rockchip Mailbox support.
-
-config SCPI_PROTOCOL
- bool "ARM System Control and Power Interface (SCPI) Message Protocol"
- select ROCKCHIP_MBOX
- help
- System Control and Power Interface (SCPI) Message Protocol is
- defined for the purpose of communication between the Application
- Cores(AP) and the System Control Processor(SCP). The mailbox
- provides a mechanism for inter-processor communication between SCP
- and AP.
-
- This protocol library provides interface for all the client drivers
- making use of the features offered by the SCP.
-
endif
obj-$(CONFIG_MAILBOX) += mailbox.o
obj-$(CONFIG_PL320_MBOX) += pl320-ipc.o
-
-obj-$(CONFIG_ROCKCHIP_MAILBOX) += rockchip_mailbox.o
-
-obj-$(CONFIG_SCPI_PROTOCOL) += scpi_protocol.o
source "drivers/media/i2c/Kconfig"
source "drivers/media/tuners/Kconfig"
source "drivers/media/dvb-frontends/Kconfig"
-source "drivers/media/video/rk_camsys/Kconfig"
-source "drivers/media/video/Kconfig"
endif # MEDIA_SUPPORT
obj-$(CONFIG_MEDIA_SUPPORT) += media.o
endif
-#obj-$(CONFIG_VIDEO_DEV) += v4l2-core/
-obj-y += v4l2-core/
+obj-$(CONFIG_VIDEO_DEV) += v4l2-core/
obj-$(CONFIG_DVB_CORE) += dvb-core/
# There are both core and drivers at RC subtree - merge before drivers
obj-y += common/ platform/ pci/ usb/ mmc/ firewire/ parport/
obj-$(CONFIG_VIDEO_DEV) += radio/
-obj-y += video/rk_camsys/
-obj-y += video/
-obj-y += platform/
+
icd->user_width, icd->user_height);
/* set physical bus parameters */
- return ici->ops->set_bus_param(icd, pix->pixelformat);/*yzm*/
+ return ici->ops->set_bus_param(icd);
}
static int soc_camera_open(struct file *file)
return ret;
}
-/**************yzm*************/
-/* ddl@rock-chips.com : Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera */
-static int soc_camera_enum_frameintervals (struct file *file, void *priv,
- struct v4l2_frmivalenum *fival)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret;
-
- WARN_ON(priv != file->private_data);
- ret = v4l2_subdev_call(sd, video, enum_frameintervals, fival);
- if (ret == -ENOIOCTLCMD) {
- if (ici->ops->enum_frameinervals)
- ret = ici->ops->enum_frameinervals(icd, fival);
- else
- ret = -ENOIOCTLCMD;
- }
-
- return ret;
-}
-/************yzm**************end*/
static int soc_camera_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
else
ret = vb2_streamon(&icd->vb2_vidq, i);
- if (!ret){
- v4l2_subdev_call(sd, video, s_stream, 1);
- if (ici->ops->s_stream)
- ici->ops->s_stream(icd, 1); /* ddl@rock-chips.com : Add stream control for host */
- }
+ if (!ret)
+ v4l2_subdev_call(sd, video, s_stream, 1);
return ret;
}
if (icd->streamer != file)
return -EBUSY;
- /* ddl@rock-chips.com: v0.1.1 */
- v4l2_subdev_call(sd, video, s_stream, 0);
- if (ici->ops->s_stream)
- ici->ops->s_stream(icd, 0); /* ddl@rock-chips.com : Add stream control for host */
/*
* This calls buf_release from host driver's videobuf_queue_ops for all
* remaining buffers. When the last buffer is freed, stop capture
return 0;
}
-/*************yzm*************/
-static int soc_camera_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *qc)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- int i;
- //printk( "/___________//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
-
- WARN_ON(priv != file->private_data);
-
- //printk("icd->ops->num_controls = %d ~~~~~~~~~~~~\n",icd->ops->num_controls);//yzm
- //printk("ici->ops->num_controls = %d ~~~~~~~~~~~~\n",ici->ops->num_controls);//yzm
-
- if (!qc->id)
- return -EINVAL;
-
- /* first device controls */
- //if device support digital zoom ,first use it to do zoom,zyc
- for (i = 0; i < icd->ops->num_controls; i++)
- if (qc->id == icd->ops->controls[i].id) {
- memcpy(qc, &(icd->ops->controls[i]),
- sizeof(*qc));
- return 0;
- }
-
- /* then check host controls */
- for (i = 0; i < ici->ops->num_controls; i++)
- if (qc->id == ici->ops->controls[i].id) {
- memcpy(qc, &(ici->ops->controls[i]),
- sizeof(*qc));
- return 0;
- }
- //printk( "/___________//n Here I am: %s:%i-------%s()\n", __FILE__, __LINE__,__FUNCTION__);
- return -EINVAL;
-}
-
-/* ddl@rock-chips.com : Add ioctrl -VIDIOC_QUERYMENU */
-static int soc_camera_querymenu(struct file *file, void *priv,
- struct v4l2_querymenu *qm)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_queryctrl qctrl;
- int i,j;
-
- qctrl.id = qm->id;
-
- if (soc_camera_queryctrl(file,priv, &qctrl) == 0) {
- for (i = 0; i < icd->ops->num_menus; i++) {
- if (qm->id == icd->ops->menus[i].id) {
- for (j=0; j<=(qctrl.maximum - qctrl.minimum); j++) {
-
- if (qm->index == icd->ops->menus[i].index) {
- snprintf(qm->name, sizeof(qm->name), icd->ops->menus[i].name);
- qm->reserved = 0;
-
- return 0;
- } else {
- i++;
- if ( i >= icd->ops->num_menus)
- return -EINVAL;
- }
- }
- }
- }
- }
-
- return -EINVAL;
-}
-
-static int soc_camera_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret;
-
- WARN_ON(priv != file->private_data);
-
- if (ici->ops->get_ctrl) {
- ret = ici->ops->get_ctrl(icd, ctrl);
- if (ret != -ENOIOCTLCMD)
- return ret;
- }
-
- return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
-}
-
-static int soc_camera_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct soc_camera_device *icd = file->private_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
- int ret;
-
- WARN_ON(priv != file->private_data);
-
- if (ici->ops->set_ctrl) {
- ret = ici->ops->set_ctrl(icd, ctrl);
- if (ret != -ENOIOCTLCMD)
- return ret;
- }
-
- return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
-}
-
- /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */
-static int soc_camera_try_ext_ctrl(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrl)
-{
- struct soc_camera_device *icd = file->private_data;
- const struct v4l2_queryctrl *qctrl;
- int i;
-
- WARN_ON(priv != file->private_data);
-
- if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA)
- return -EINVAL;
-
- for (i=0; i<ctrl->count; i++) {
- qctrl = soc_camera_find_qctrl(icd->ops, ctrl->controls[i].id);
- if (!qctrl)
- return -EINVAL;
-
- if ((ctrl->controls[i].value < qctrl->minimum) ||(ctrl->controls[i].value > qctrl->minimum))
- return -ERANGE;
- }
-
- return 0;
-}
-
- /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */
-static int soc_camera_g_ext_ctrl(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrl)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- WARN_ON(priv != file->private_data);
-
- if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, core, g_ext_ctrls, ctrl);
-}
-
- /* ddl@rock-chips.com : Add ioctrl -VIDIOC_XXX_ext_ctrl for soc-camera */
-static int soc_camera_s_ext_ctrl(struct file *file, void *priv,
- struct v4l2_ext_controls *ctrl)
-{
- struct soc_camera_device *icd = file->private_data;
- struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
-
- WARN_ON(priv != file->private_data);
-
- if (ctrl->ctrl_class != V4L2_CTRL_CLASS_CAMERA)
- return -EINVAL;
-
- return v4l2_subdev_call(sd, core, s_ext_ctrls, ctrl);
-}
- /*************yzm*************end*/
static int soc_camera_cropcap(struct file *file, void *fh,
struct v4l2_cropcap *a)
/* The camera could have been already on, try to reset */
if (ssdd->reset)
ssdd->reset(icd->pdev);
- /*********yzm**********/
- ret = soc_camera_power_on(icd->pdev,ssdd);
- if (ret < 0)
- goto eadd;
- /*********yzm*********/
+
mutex_lock(&ici->host_lock);
ret = ici->ops->add(icd);
mutex_unlock(&ici->host_lock);
ret = video_dev_create(icd);
if (ret < 0)
goto evdc;
- ssdd->socdev = icd;/*yzm*/
+
/* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
if (shd->board_info) {
ret = soc_camera_init_i2c(icd, sdesc);
evdc:
mutex_lock(&ici->host_lock);
ici->ops->remove(icd);
- soc_camera_power_off(icd->pdev,ssdd);/*yzm*/
mutex_unlock(&ici->host_lock);
eadd:
v4l2_ctrl_handler_free(&icd->ctrl_handler);
.vidioc_prepare_buf = soc_camera_prepare_buf,
.vidioc_streamon = soc_camera_streamon,
.vidioc_streamoff = soc_camera_streamoff,
- /**************yzm***************/
- .vidioc_queryctrl = soc_camera_queryctrl,
- .vidioc_querymenu = soc_camera_querymenu, /* ddl@rock-chips.com: Add ioctrl - vidioc_querymenu for soc-camera */
- .vidioc_g_ctrl = soc_camera_g_ctrl,
- .vidioc_s_ctrl = soc_camera_s_ctrl,
- .vidioc_g_ext_ctrls = soc_camera_g_ext_ctrl, /* ddl@rock-chips.com: Add ioctrl - vidioc_g_ext_ctrls for soc-camera */
- .vidioc_s_ext_ctrls = soc_camera_s_ext_ctrl, /* ddl@rock-chips.com: Add ioctrl - vidioc_s_ext_ctrls for soc-camera */
- .vidioc_try_ext_ctrls = soc_camera_try_ext_ctrl,/* ddl@rock-chips.com: Add ioctrl - vidioc_try_ext_ctrls for soc-camera */
- .vidioc_enum_frameintervals = soc_camera_enum_frameintervals,/* ddl@rock-chips.com: Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera */
- /**************yzm***************end*/
.vidioc_cropcap = soc_camera_cropcap,
.vidioc_g_crop = soc_camera_g_crop,
.vidioc_s_crop = soc_camera_s_crop,
vdev->ioctl_ops = &soc_camera_ioctl_ops;
vdev->release = video_device_release;
vdev->tvnorms = V4L2_STD_UNKNOWN;
- vdev->ctrl_handler = NULL;//&icd->ctrl_handler; /**************yzm***************/
+ vdev->ctrl_handler = &icd->ctrl_handler;
vdev->lock = &ici->host_lock;
icd->vdev = vdev;
static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
{
- #if 0 /* ddl@rock-chips.com: address must align to 4-bytes */
return ctrl->uvc_data + id * ctrl->info.size;
- #else
- return ctrl->uvc_data + id * ((ctrl->info.size+3)/4*4);
- #endif
}
static inline int uvc_test_bit(const __u8 *data, int bit)
INIT_LIST_HEAD(&ctrl->info.mappings);
/* Allocate an array to save control values (cur, def, max, etc.) */
- #if 0 /* ddl@rock-chips.com: address must align to 4-bytes */
ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1,
GFP_KERNEL);
- #else
- ctrl->uvc_data = kzalloc(((ctrl->info.size+3)/4*4) * UVC_CTRL_DATA_LAST + 1,
- GFP_KERNEL);
- #endif
if (ctrl->uvc_data == NULL) {
ret = -ENOMEM;
goto done;
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
-#include <linux/of.h>
+
#include "uvcvideo.h"
/* ------------------------------------------------------------------------
case VIDIOC_QUERYCAP:
{
struct v4l2_capability *cap = arg;
- struct device_node *vpu_node;
- int vpu_iommu_enabled = 0;
memset(cap, 0, sizeof *cap);
strlcpy(cap->driver, "uvcvideo", sizeof cap->driver);
else
cap->device_caps = V4L2_CAP_VIDEO_OUTPUT
| V4L2_CAP_STREAMING;
- vpu_node = of_find_node_by_name(NULL, "vpu_service");
- if(vpu_node){
- ret = of_property_read_u32(vpu_node, "iommu_enabled", &vpu_iommu_enabled);
- }else{
- printk("get vpu_node failed,vpu_iommu_enabled == 0 !!!!!!\n");
- }
- cap->reserved[0] = vpu_iommu_enabled;
break;
}
uvc_trace(UVC_TRACE_FRAME, "Frame complete (FID bit "
"toggled).\n");
buf->state = UVC_BUF_STATE_READY;
- buf->error = 1;
return -EAGAIN;
}
if (len > maxlen) {
uvc_trace(UVC_TRACE_FRAME, "Frame complete (overflow).\n");
buf->state = UVC_BUF_STATE_READY;
- buf->error = 1;
}
}
urb->transfer_buffer_length = stream->urb_size - len;
}
-/* ddl@rock-chips.com : uvc_video_complete is run in_interrupt(), so uvc decode operation delay run in tasklet for
-* usb host reenable interrupt soon
-*/
-static void uvc_video_complete_fun (struct urb *urb)
-{
+
+static void uvc_video_complete(struct urb *urb)
+{
struct uvc_streaming *stream = urb->context;
struct uvc_video_queue *queue = &stream->queue;
struct uvc_buffer *buf = NULL;
unsigned long flags;
int ret;
- int i;
- atomic_t *urb_state=NULL;
switch (urb->status) {
case 0:
return;
}
- for (i = 0; i < UVC_URBS; ++i) {
- if (stream->urb[i] == urb) {
- urb_state = &stream->urb_state[i];
- break;
- }
- }
-
- if (urb_state == NULL) {
- printk("urb(%p) cann't be finded in stream->urb(%p, %p, %p, %p, %p)\n",
- urb,stream->urb[0],stream->urb[1],stream->urb[2],stream->urb[3],stream->urb[4]);
- /* BUG(); */
- uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
- return;
- }
-
- if (atomic_read(urb_state)==UrbDeactive) {
- printk(KERN_DEBUG "urb is deactive, this urb complete cancel!");
- uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
- return;
- }
-
spin_lock_irqsave(&queue->irqlock, flags);
if (!list_empty(&queue->irqqueue))
buf = list_first_entry(&queue->irqqueue, struct uvc_buffer,
if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) < 0) {
uvc_printk(KERN_ERR, "Failed to resubmit video URB (%d).\n",
ret);
- uvc_queue_cancel(queue, urb->status == -ESHUTDOWN);
- return;
- }
-}
-static void uvc_video_complete_tasklet(unsigned long data)
-{
- struct urb *urb = (struct urb*)data;
-
- uvc_video_complete_fun(urb);
-
- return;
-}
-static void uvc_video_complete(struct urb *urb)
-{
- int i;
- struct uvc_streaming *stream = urb->context;
- struct tasklet_struct *tasklet = NULL;
- atomic_t *urb_state;
-
- for (i = 0; i < UVC_URBS; ++i) {
- if (stream->urb[i] == urb) {
- tasklet = stream->tasklet[i];
- urb_state = &stream->urb_state[i];
- break;
- }
- }
-
- if ((tasklet != NULL)&&(atomic_read(urb_state)==UrbActive)) {
- tasklet_hi_schedule(tasklet);
- } else {
- uvc_video_complete_fun(urb);
}
}
urb = stream->urb[i];
if (urb == NULL)
continue;
- else
- atomic_set(&stream->urb_state[i],UrbDeactive);
-
- if (stream->tasklet[i]) {
- tasklet_kill(stream->tasklet[i]);
- kfree(stream->tasklet[i]);
- stream->tasklet[i] = NULL;
- }
usb_kill_urb(urb);
usb_free_urb(urb);
}
stream->urb[i] = urb;
- /* ddl@rock-chips.com */
- atomic_set(&stream->urb_state[i],UrbActive);
- stream->tasklet[i] = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
- if (stream->tasklet[i] == NULL) {
- uvc_printk(KERN_ERR, "device %s requested tasklet memory fail!\n",
- stream->dev->name);
- } else {
- tasklet_init(stream->tasklet[i], uvc_video_complete_tasklet, (unsigned long)urb);
- }
}
return 0;
#endif
stream->urb[i] = urb;
-
- /* ddl@rock-chips.com */
- stream->tasklet[i] = kmalloc(sizeof(struct tasklet_struct), GFP_KERNEL);
- if (stream->tasklet[i] == NULL) {
- uvc_printk(KERN_ERR, "device %s requested tasklet memory fail!\n",
- stream->dev->name);
- } else {
- tasklet_init(stream->tasklet[i], uvc_video_complete_tasklet, (unsigned long)urb);
- }
}
return 0;
unsigned int max_sof; /* Maximum STC.SOF value */
};
-enum uvc_urb_state {
- UrbActive,
- UrbDeactive
-};
-
struct uvc_streaming {
struct list_head list;
struct uvc_device *dev;
__u32 sequence;
__u8 last_fid;
- struct tasklet_struct *tasklet[UVC_URBS]; /* ddl@rock-chips.com */
- atomic_t urb_state[UVC_URBS];
-
/* debugfs */
struct dentry *debugfs_dir;
struct {
int retval;
MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
+
if (b->memory == V4L2_MEMORY_MMAP)
down_read(¤t->mm->mmap_sem);
+
videobuf_queue_lock(q);
retval = -EBUSY;
if (q->reading) {
dprintk(1, "qbuf: requesting next field\n");
field = videobuf_next_field(q);
-
retval = q->ops->buf_prepare(q, buf, field);
if (0 != retval) {
dprintk(1, "qbuf: buffer_prepare returned %d\n", retval);
goto done;
}
+
list_add_tail(&buf->stream, &q->stream);
if (q->streaming) {
spin_lock_irqsave(q->irqlock, flags);
done:
videobuf_queue_unlock(q);
+
if (b->memory == V4L2_MEMORY_MMAP)
up_read(¤t->mm->mmap_sem);
+
return retval;
}
EXPORT_SYMBOL_GPL(videobuf_qbuf);
static int stream_next_buffer_check_queue(struct videobuf_queue *q, int noblock)
{
int retval;
- bool is_ext_locked;
checks:
if (!q->streaming) {
} else {
dprintk(2, "next_buffer: waiting on buffer\n");
- /* Drop lock to avoid deadlock with qbuf */
- videobuf_queue_unlock(q);
- /*ddl@rock-chips.com */
- is_ext_locked = q->ext_lock && mutex_is_locked(q->ext_lock);
-
- /* Release vdev lock to prevent this wait from blocking outside access to
- the device. */
- if (is_ext_locked)
- mutex_unlock(q->ext_lock);
-
-
+ /* Drop lock to avoid deadlock with qbuf */
+ videobuf_queue_unlock(q);
+
/* Checking list_empty and streaming is safe without
* locks because we goto checks to validate while
* holding locks before proceeding */
retval = wait_event_interruptible(q->wait,
!list_empty(&q->stream) || !q->streaming);
+ videobuf_queue_lock(q);
- videobuf_queue_lock(q);
- /*ddl@rock-chips.com */
- if (is_ext_locked)
- mutex_lock(q->ext_lock);
if (retval)
goto done;
return -ENOMEM;
break;
case V4L2_MEMORY_OVERLAY:
- break; /* ddl@rock-chips.com : nzy modify V4L2_MEMORY_OVERLAY */
default:
dev_dbg(q->dev, "%s memory method OVERLAY/unknown\n", __func__);
return -EINVAL;
*/
static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
{
- int count = 0;
/*
* All operations on vb_done_list are performed under done_lock
* spinlock protection. However, buffers may be removed from
* All locks have been released, it is safe to sleep now.
*/
dprintk(3, "Will sleep waiting for buffers\n");
- /*
ret = wait_event_interruptible(q->done_wq,
!list_empty(&q->done_list) || !q->streaming);
- */
-
- ret = wait_event_interruptible_timeout(q->done_wq,
- !list_empty(&q->done_list) || !q->streaming, msecs_to_jiffies(500));
/*
* We need to reevaluate both conditions again after reacquiring
* the locks or return an error if one occurred.
*/
call_qop(q, wait_finish, q);
- /*
if (ret) {
dprintk(1, "Sleep was interrupted\n");
return ret;
}
- */
- if (ret < 0) {
- dprintk(1, "Sleep was interrupted\n");
- return ret;
- } else if (ret == 0) {
- count ++;
- if(count >= 5)
- return -EIO;
- }
}
return 0;
}
help
Select this if your MC13xxx is connected via an I2C bus.
-config MFD_RT5025
- bool "RT5025 PMIC Chip Core driver"
- depends on I2C
- select MFD_CORE
- default n
- help
- Enable RT5025 core driver.
-
-config MISC_RT5025
- bool "RT5025 PMIC chip misc configuration"
- depends on MFD_RT5025
- default n
- help
- Enable RT5025 Misc configuration.
-
-config IRQ_RT5025
- bool "RT5025_PMIC chip irq driver"
- depends on MFD_RT5025
- default n
- help
- Enable RT5025 IRQ configuration and interrupt.
-
-config DEBUG_RT5025
- bool "RT5025 PMIC Chip Core Debug"
- depends on MFD_RT5025 && DEBUG_FS
- default n
- help
- Enable RT5025 core debug driver.
-
-config MFD_RT_SHOW_INFO
- bool "RT5025 PMIC Debug log Flag"
- depends on MFD_RT5025
- default n
- help
- Enable the RT5025 PMIC debug log.
-
-config MFD_RT5036
- bool "Richtek RT5036 PMIC support"
- select MFD_CORE
- default n
- help
- Enable the RT5036 MFD driver.
-
-config MFD_RT5036_DBGINFO
- bool "Richtek RT5036 debug message enable."
- depends on MFD_RT5036
- default n
- help
- Enable the RT5036 debug log.
-
-config MISC_RT5036
- bool "Richtek RT5036 MISC option driver support"
- depends on MFD_RT5036
- default n
- help
- Enable the RT5036 Misc option driver support.
-
-config MISC_RT5036_PWRKEY
- bool "Richtek RT5036 Power key report in Misc module"
- depends on MISC_RT5036
- default n
- help
- Enable the RT5036 Power Key report in Misc module.
-
-config IRQ_RT5036
- bool "Richtek RT5036 irq option driver support"
- depends on MFD_RT5036
- default n
- help
- Enable the Rt5036 IRQ option driver support.
-
-config DEBUG_RT5036
- bool "Richtek RT5036 PMIC DEBUGFS Support"
- depends on DEBUG_FS && MFD_RT5036
- default n
- help
- Enable the RT5036 debugfs node that support
- read/write registers.
-
config HTC_EGPIO
bool "HTC EGPIO support"
depends on GENERIC_HARDIRQS && GPIOLIB && ARM
additional drivers must be enabled in order to use the functionality
of the device.
-config MFD_RK808
- bool "RK808 Power Management chip"
- depends on I2C=y
- select REGMAP_I2C
- select MFD_CORE
- select RK808_RTC
- help
- if you say yes here you get support for the RK808 series of
- Power Management chips.
-
-config MFD_RK818
- bool "RK818 Power Management chip"
- depends on I2C=y
- select MFD_CORE
- select RK818_RTC
- help
- if you say yes here you get support for the RK818 series of
- Power Management chips.
-
config EZX_PCAP
bool "Motorola EZXPCAP Support"
depends on GENERIC_HARDIRQS && SPI_MASTER
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the
functionality of the device (audio, vibra).
-
-config MFD_RICOH619
- bool "Ricoh RC5T619 Power Management system device"
- depends on I2C && GPIOLIB && GENERIC_HARDIRQS
- select MFD_CORE
- default n
- help
- If you say yes here you get support for the RICOH619 Power
- Management system device.
- This driver provides common support for accessing the device,
- additional drivers must be enabled in order to use the
- functionality of the device.
config MENELAUS
bool "TI TWL92330/Menelaus PM chip"
core support for the WM8994, in order to use the actual
functionaltiy of the device other drivers must be enabled.
-config MFD_RK1000
- bool "RK1000 Multimedia support"
- depends on I2C=y && GPIOLIB
- select MFD_CORE
- help
- if you say yes here you get support for the RK1000, with func as
- TVEncoder CODEC.
-
-config MFD_RK610
- bool "RK610(Jetta) Multimedia support"
- depends on I2C=y && GPIOLIB
- select MFD_CORE
- help
- if you say yes here you get support for the RK610, with func as
- HDMI LCD LVDS TVOUT CODEC.
-
-config MFD_RK616
- bool "RK616(Jetta B) Multifunction device support"
- depends on I2C=y
- select MFD_CORE
- help
- if you say yes here you get support for the RK616, with func as
- HDMI、LCD、LVDS、CODEC、MIPI.
-
-config RK616_USE_MCLK_12M
- bool "Enable 12M clock for timing reconstruction"
- depends on MFD_RK616
- select RK_HDMI_CTL_CODEC
- default y
- help
- if you say y here ,it will enable 12M clock for timing reconstruction
-
-config RK616_DEBUG
- bool "RK616(JettaB) debug enable"
- depends on MFD_RK616
- help
- if you say y here ,it will enable rk616 debug function
-
endmenu
endif
depends on VEXPRESS_CONFIG
help
Serial Power Controller driver for ARM Ltd. test chips.
-
obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o
obj-$(CONFIG_MFD_WM8994) += wm8994-core.o wm8994-irq.o wm8994-regmap.o
-obj-$(CONFIG_MFD_RT5025) += rt5025-i2c.o rt5025-core.o
-obj-$(CONFIG_MISC_RT5025) += rt5025-misc.o
-obj-$(CONFIG_IRQ_RT5025) += rt5025-irq.o
-obj-$(CONFIG_DEBUG_RT5025) += rt5025-debug.o
-
-obj-$(CONFIG_MFD_RT5036) += rt5036-i2c.o rt5036-core.o
-obj-$(CONFIG_MISC_RT5036) += rt5036-misc.o
-obj-$(CONFIG_IRQ_RT5036) += rt5036-irq.o
-obj-$(CONFIG_DEBUG_RT5036) += rt5036-debug.o
-
obj-$(CONFIG_TPS6105X) += tps6105x.o
obj-$(CONFIG_TPS65010) += tps65010.o
obj-$(CONFIG_TPS6507X) += tps6507x.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o
obj-$(CONFIG_MFD_TPS65090) += tps65090.o
-obj-$(CONFIG_MFD_RK808) += rk808.o rk808-irq.o
-obj-$(CONFIG_MFD_RK818) += rk818.o rk818-irq.o
-obj-$(CONFIG_MFD_RICOH619) += ricoh619.o ricoh619-irq.o
obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
obj-$(CONFIG_MFD_INTEL_MSIC) += intel_msic.o
obj-$(CONFIG_MFD_PALMAS) += palmas.o
obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o
obj-$(CONFIG_VEXPRESS_SPC) += vexpress-spc.o
obj-$(CONFIG_MFD_RETU) += retu-mfd.o
-obj-$(CONFIG_MFD_RK1000) += rk1000-core.o
-obj-$(CONFIG_MFD_RK610) += rk610-core.o
obj-$(CONFIG_MFD_AS3711) += as3711.o
-obj-$(CONFIG_MFD_RK616) += rk616-core.o rk616-vif.o
return ret;
}
+static int ab8500_gpadc_runtime_idle(struct device *dev)
+{
+ pm_runtime_suspend(dev);
+ return 0;
+}
+
static int ab8500_gpadc_suspend(struct device *dev)
{
struct ab8500_gpadc *gpadc = dev_get_drvdata(dev);
static const struct dev_pm_ops ab8500_gpadc_pm_ops = {
SET_RUNTIME_PM_OPS(ab8500_gpadc_runtime_suspend,
ab8500_gpadc_runtime_resume,
- NULL)
+ ab8500_gpadc_runtime_idle)
SET_SYSTEM_SLEEP_PM_OPS(ab8500_gpadc_suspend,
ab8500_gpadc_resume)
help
Per UID based cpu time statistics exported to /proc/uid_cputime
-config 5V_EN
- bool "5v en power control for otg and hdmi"
- default y
- help
- This driver is control enable 5v power when startup and disable it
- when suspend and no insert otg. if your board is control this power
- by a gpio please select it.
-
source "drivers/misc/c2port/Kconfig"
source "drivers/misc/eeprom/Kconfig"
source "drivers/misc/cb710/Kconfig"
-source "drivers/misc/inv_mpu/Kconfig"
source "drivers/misc/ti-st/Kconfig"
source "drivers/misc/lis3lv02d/Kconfig"
source "drivers/misc/carma/Kconfig"
obj-$(CONFIG_INTEL_MEI) += mei/
obj-$(CONFIG_VMWARE_VMCI) += vmw_vmci/
obj-$(CONFIG_LATTICE_ECP3_CONFIG) += lattice-ecp3-config.o
-obj-y += inv_mpu/
obj-$(CONFIG_SRAM) += sram.o
obj-$(CONFIG_UID_CPUTIME) += uid_cputime.o
-
-obj-$(CONFIG_5V_EN) += 5v_en.o
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/genalloc.h>
-#include <linux/platform_data/sram.h>
#define SRAM_GRANULARITY 32
static int sram_probe(struct platform_device *pdev)
{
- struct sram_platform_data *pdata = pdev->dev.platform_data;
void __iomem *virt_base;
struct sram_dev *sram;
struct resource *res;
unsigned long size;
- bool map_exec = false;
int ret;
- if (of_get_property(pdev->dev.of_node, "map-exec", NULL))
- map_exec = true;
- if (pdata && pdata->map_exec)
- map_exec |= true;
-
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res && of_get_property(pdev->dev.of_node, "map-cacheable", NULL))
- res->flags |= IORESOURCE_CACHEABLE;
- if (map_exec)
- virt_base = devm_ioremap_exec_resource(&pdev->dev, res);
- else
- virt_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(virt_base))
- return PTR_ERR(virt_base);
+ if (!res)
+ return -EINVAL;
size = resource_size(res);
+ virt_base = devm_request_and_ioremap(&pdev->dev, res);
+ if (!virt_base)
+ return -EADDRNOTAVAIL;
+
sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL);
if (!sram)
return -ENOMEM;
#include <linux/delay.h>
#include <linux/capability.h>
#include <linux/compat.h>
-#include <linux/pm_runtime.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/mmc.h>
#include <linux/mmc/ioctl.h>
#include <linux/mmc/card.h>
#define INAND_CMD38_ARG_SECTRIM1 0x81
#define INAND_CMD38_ARG_SECTRIM2 0x88
#define MMC_BLK_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
-#define MMC_SANITIZE_REQ_TIMEOUT 240000
-#define MMC_EXTRACT_INDEX_FROM_ARG(x) ((x & 0x00FF0000) >> 16)
-#define mmc_req_rel_wr(req) ((req->cmd_flags & REQ_FUA) && \
+#define mmc_req_rel_wr(req) (((req->cmd_flags & REQ_FUA) || \
+ (req->cmd_flags & REQ_META)) && \
(rq_data_dir(req) == WRITE))
#define PACKED_CMD_VER 0x01
#define PACKED_CMD_WR 0x02
md = mmc_blk_get(dev_to_disk(dev));
card = md->queue.card;
- mmc_get_card(card);
+ mmc_claim_host(card->host);
ret = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP,
card->ext_csd.boot_ro_lock |
else
card->ext_csd.boot_ro_lock |= EXT_CSD_BOOT_WP_B_PWR_WP_EN;
- mmc_put_card(card);
+ mmc_release_host(card->host);
if (!ret) {
pr_info("%s: Locking boot partition ro until next power on\n",
return err;
}
-static int ioctl_do_sanitize(struct mmc_card *card)
-{
- int err;
-
- if (!(mmc_can_sanitize(card) &&
- (card->host->caps2 & MMC_CAP2_SANITIZE))) {
- pr_warn("%s: %s - SANITIZE is not supported\n",
- mmc_hostname(card->host), __func__);
- err = -EOPNOTSUPP;
- goto out;
- }
-
- pr_debug("%s: %s - SANITIZE IN PROGRESS...\n",
- mmc_hostname(card->host), __func__);
-
- err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_SANITIZE_START, 1,
- MMC_SANITIZE_REQ_TIMEOUT);
-
- if (err)
- pr_err("%s: %s - EXT_CSD_SANITIZE_START failed. err=%d\n",
- mmc_hostname(card->host), __func__, err);
-
- pr_debug("%s: %s - SANITIZE COMPLETED\n", mmc_hostname(card->host),
- __func__);
-out:
- return err;
-}
-
static int mmc_blk_ioctl_cmd(struct block_device *bdev,
struct mmc_ioc_cmd __user *ic_ptr)
{
mrq.cmd = &cmd;
- mmc_get_card(card);
+ mmc_claim_host(card->host);
err = mmc_blk_part_switch(card, md);
if (err)
goto cmd_rel_host;
}
- if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&
- (cmd.opcode == MMC_SWITCH)) {
- err = ioctl_do_sanitize(card);
-
- if (err)
- pr_err("%s: ioctl_do_sanitize() failed. err = %d",
- __func__, err);
-
- goto cmd_rel_host;
- }
-
mmc_wait_for_req(card->host, &mrq);
if (cmd.error) {
}
cmd_rel_host:
- mmc_put_card(card);
+ mmc_release_host(card->host);
cmd_done:
mmc_blk_put(md);
{
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
- unsigned int from, nr, arg;
+ unsigned int from, nr, arg, trim_arg, erase_arg;
int err = 0, type = MMC_BLK_SECDISCARD;
- if (!(mmc_can_secure_erase_trim(card))) {
+ if (!(mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))) {
err = -EOPNOTSUPP;
goto out;
}
from = blk_rq_pos(req);
nr = blk_rq_sectors(req);
- if (mmc_can_trim(card) && !mmc_erase_group_aligned(card, from, nr))
- arg = MMC_SECURE_TRIM1_ARG;
- else
- arg = MMC_SECURE_ERASE_ARG;
+ /* The sanitize operation is supported at v4.5 only */
+ if (mmc_can_sanitize(card)) {
+ erase_arg = MMC_ERASE_ARG;
+ trim_arg = MMC_TRIM_ARG;
+ } else {
+ erase_arg = MMC_SECURE_ERASE_ARG;
+ trim_arg = MMC_SECURE_TRIM1_ARG;
+ }
+ if (mmc_erase_group_aligned(card, from, nr))
+ arg = erase_arg;
+ else if (mmc_can_trim(card))
+ arg = trim_arg;
+ else {
+ err = -EINVAL;
+ goto out;
+ }
retry:
if (card->quirks & MMC_QUIRK_INAND_CMD38) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
goto out;
}
+ if (mmc_can_sanitize(card)) {
+ trace_mmc_blk_erase_start(EXT_CSD_SANITIZE_START, 0, 0);
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_SANITIZE_START, 1, 0);
+ trace_mmc_blk_erase_end(EXT_CSD_SANITIZE_START, 0, 0);
+ }
out_retry:
if (err && !mmc_blk_reset(md, card->host, type))
goto retry;
mmc_active);
struct mmc_blk_request *brq = &mq_mrq->brq;
struct request *req = mq_mrq->req;
- int need_retune = card->host->need_retune;
int ecc_err = 0, gen_err = 0;
/*
}
if (brq->data.error) {
- pr_err("need_retune:%d,brq->retune_retry_done:%d.\n",need_retune,brq->retune_retry_done);
- if (need_retune && !brq->retune_retry_done) {
- pr_err("%s: retrying because a re-tune was needed\n",
- req->rq_disk->disk_name);
- brq->retune_retry_done = 1;
- return MMC_BLK_RETRY;
- }
-
pr_err("%s: error %d transferring data, sector %u, nr %u, cmd response %#x, card status %#x\n",
req->rq_disk->disk_name, brq->data.error,
(unsigned)blk_rq_pos(req),
/*
* Reliable writes are used to implement Forced Unit Access and
- * are supported only on MMCs.
+ * REQ_META accesses, and are supported only on MMCs.
+ *
+ * XXX: this really needs a good explanation of why REQ_META
+ * is treated special.
*/
- bool do_rel_wr = (req->cmd_flags & REQ_FUA) &&
+ bool do_rel_wr = ((req->cmd_flags & REQ_FUA) ||
+ (req->cmd_flags & REQ_META)) &&
(rq_data_dir(req) == WRITE) &&
(md->flags & MMC_BLK_REL_WR);
brq->data.flags |= MMC_DATA_WRITE;
}
- if (req->cmd_flags & REQ_KERNEL)
- brq->data.flags |= MMC_DATA_DIRECT;
-
if (do_rel_wr)
mmc_apply_rel_rw(brq, card, req);
struct mmc_blk_data *md = mq->data;
struct mmc_card *card = md->queue.card;
struct mmc_blk_request *brq = &mq->mqrq_cur->brq;
- int ret = 1, disable_multi = 0, retry = 0, retune_retry_done = 0, type;
+ int ret = 1, disable_multi = 0, retry = 0, type;
enum mmc_blk_status status;
struct mmc_queue_req *mq_rq;
struct request *req = rqc;
goto start_new_req;
break;
case MMC_BLK_RETRY:
- retune_retry_done = brq->retune_retry_done;
if (retry++ < 5)
break;
/* Fall through */
mmc_start_req(card->host,
&mq_rq->mmc_active, NULL);
}
- mq_rq->brq.retune_retry_done = retune_retry_done;
}
} while (ret);
if (req && !mq->mqrq_prev->req)
/* claim host only for the first request */
- mmc_get_card(card);
+ mmc_claim_host(card->host);
ret = mmc_blk_part_switch(card, md);
if (ret) {
* In case sepecial request, there is no reentry to
* the 'mmc_blk_issue_rq' with 'mqrq_prev->req'.
*/
- mmc_put_card(card);
+ mmc_release_host(card->host);
return ret;
}
struct mmc_card *card;
if (md) {
- /*
- * Flush remaining requests and free queues. It
- * is freeing the queue that stops new requests
- * from being accepted.
- */
card = md->queue.card;
- mmc_cleanup_queue(&md->queue);
- if (md->flags & MMC_BLK_PACKED_CMD)
- mmc_packed_clean(&md->queue);
if (md->disk->flags & GENHD_FL_UP) {
device_remove_file(disk_to_dev(md->disk), &md->force_ro);
if ((md->area_type & MMC_BLK_DATA_AREA_BOOT) &&
device_remove_file(disk_to_dev(md->disk),
&md->power_ro_lock);
+ /* Stop new requests from getting into the queue */
del_gendisk(md->disk);
}
+
+ /* Then flush out any already in there */
+ mmc_cleanup_queue(&md->queue);
+ if (md->flags & MMC_BLK_PACKED_CMD)
+ mmc_packed_clean(&md->queue);
mmc_blk_put(md);
}
}
#define CID_MANFID_TOSHIBA 0x11
#define CID_MANFID_MICRON 0x13
#define CID_MANFID_SAMSUNG 0x15
-#define CID_MANFID_HYNIX 0x90
static const struct mmc_fixup blk_fixups[] =
{
MMC_FIXUP("VZL00M", CID_MANFID_SAMSUNG, CID_OEMID_ANY, add_quirk_mmc,
MMC_QUIRK_SEC_ERASE_TRIM_BROKEN),
- /* Hynix 4.41 iNAND execute trim will lead boot up failed. */
- MMC_FIXUP(CID_NAME_ANY, CID_MANFID_HYNIX, CID_OEMID_ANY, add_quirk_mmc,
- MMC_QUIRK_TRIM_UNSTABLE),
-
END_FIXUP
};
-#if defined(CONFIG_MMC_DW_ROCKCHIP)
-extern struct mmc_card *this_card;
-#endif
-
static int mmc_blk_probe(struct mmc_card *card)
{
struct mmc_blk_data *md, *part_md;
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
mmc_set_bus_resume_policy(card->host, 1);
-#endif
-#if defined(CONFIG_MMC_DW_ROCKCHIP)
- if (card->host->restrict_caps & RESTRICT_CARD_TYPE_EMMC) {
- this_card = card;
- md->disk->emmc_disk = 1;
- } else {
- md->disk->emmc_disk = 0;
- }
#endif
if (mmc_add_disk(md))
goto out;
if (mmc_add_disk(part_md))
goto out;
}
-
- pm_runtime_set_autosuspend_delay(&card->dev, 3000);
- pm_runtime_use_autosuspend(&card->dev);
-
- /*
- * Don't enable runtime PM for SD-combo cards here. Leave that
- * decision to be taken during the SDIO init sequence instead.
- */
- if (card->type != MMC_TYPE_SD_COMBO) {
- pm_runtime_set_active(&card->dev);
- pm_runtime_enable(&card->dev);
- }
-
return 0;
out:
{
struct mmc_blk_data *md = mmc_get_drvdata(card);
-#if defined(CONFIG_MMC_DW_ROCKCHIP)
- if (card->host->restrict_caps & RESTRICT_CARD_TYPE_EMMC)
- this_card = NULL;
-#endif
mmc_blk_remove_parts(card, md);
- pm_runtime_get_sync(&card->dev);
mmc_claim_host(card->host);
mmc_blk_part_switch(card, md);
mmc_release_host(card->host);
- if (card->type != MMC_TYPE_SD_COMBO)
- pm_runtime_disable(&card->dev);
- pm_runtime_put_noidle(&card->dev);
mmc_blk_remove_req(md);
mmc_set_drvdata(card, NULL);
#ifdef CONFIG_MMC_BLOCK_DEFERRED_RESUME
#endif
}
-static int _mmc_blk_suspend(struct mmc_card *card)
+#ifdef CONFIG_PM
+static int mmc_blk_suspend(struct mmc_card *card)
{
struct mmc_blk_data *part_md;
struct mmc_blk_data *md = mmc_get_drvdata(card);
return 0;
}
-static void mmc_blk_shutdown(struct mmc_card *card)
-{
- _mmc_blk_suspend(card);
-}
-
-#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card)
-{
- return _mmc_blk_suspend(card);
-}
-
static int mmc_blk_resume(struct mmc_card *card)
{
struct mmc_blk_data *part_md;
.remove = mmc_blk_remove,
.suspend = mmc_blk_suspend,
.resume = mmc_blk_resume,
- .shutdown = mmc_blk_shutdown,
};
static int __init mmc_blk_init(void)
mmc_test_free_dbgfs_file(card);
}
-static void mmc_test_shutdown(struct mmc_card *card)
-{
-}
-
static struct mmc_driver mmc_driver = {
.drv = {
.name = "mmc_test",
},
.probe = mmc_test_probe,
.remove = mmc_test_remove,
- .shutdown = mmc_test_shutdown,
};
static int __init mmc_test_init(void)
#include <linux/freezer.h>
#include <linux/kthread.h>
#include <linux/scatterlist.h>
-#include <linux/dma-mapping.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
down(&mq->thread_sem);
do {
struct request *req = NULL;
+ struct mmc_queue_req *tmp;
unsigned int cmd_flags = 0;
spin_lock_irq(q->queue_lock);
mq->mqrq_prev->brq.mrq.data = NULL;
mq->mqrq_prev->req = NULL;
- swap(mq->mqrq_prev, mq->mqrq_cur);
+ tmp = mq->mqrq_prev;
+ mq->mqrq_prev = mq->mqrq_cur;
+ mq->mqrq_cur = tmp;
} else {
if (kthread_should_stop()) {
set_current_state(TASK_RUNNING);
/* granularity must not be greater than max. discard */
if (card->pref_erase > max_discard)
q->limits.discard_granularity = 0;
- if (mmc_can_secure_erase_trim(card))
+ if (mmc_can_secure_erase_trim(card) || mmc_can_sanitize(card))
queue_flag_set_unlocked(QUEUE_FLAG_SECDISCARD, q);
}
struct mmc_queue_req *mqrq_prev = &mq->mqrq[1];
if (mmc_dev(host)->dma_mask && *mmc_dev(host)->dma_mask)
- limit = (u64)dma_max_pfn(mmc_dev(host)) << PAGE_SHIFT;
+ limit = *mmc_dev(host)->dma_mask;
mq->card = card;
mq->queue = blk_init_queue(mmc_request_fn, lock);
struct mmc_command cmd;
struct mmc_command stop;
struct mmc_data data;
- int retune_retry_done;
};
enum mmc_packed_type {
return 0;
}
-static void mmc_bus_shutdown(struct device *dev)
-{
- struct mmc_driver *drv = to_mmc_driver(dev->driver);
- struct mmc_card *card = mmc_dev_to_card(dev);
- struct mmc_host *host = card->host;
- int ret = 0;
-
- if (dev->driver && drv->shutdown)
- drv->shutdown(card);
-
- if (host->bus_ops->shutdown) {
- ret = host->bus_ops->shutdown(host);
-
- if (ret)
- pr_warn("%s: error %d during shutdown\n",mmc_hostname(host), ret);
- }
-
-}
-
#ifdef CONFIG_PM_SLEEP
static int mmc_bus_suspend(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
- struct mmc_host *host = card->host;
int ret = 0;
- if (dev->driver && drv->suspend) {
+ if (dev->driver && drv->suspend)
ret = drv->suspend(card);
- if (ret)
- return ret;
- }
-
- if(host->bus_ops->suspend)
- ret = host->bus_ops->suspend(host);
return ret;
}
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
- struct mmc_host *host = card->host;
int ret = 0;
- if(host->bus_ops->resume){
- ret = host->bus_ops->resume(host);
- if (ret)
- pr_warn("%s: error %d during resume (card was removed?)\n",
- mmc_hostname(host), ret);
- }
-
if (dev->driver && drv->resume)
ret = drv->resume(card);
-
return ret;
}
#endif
static int mmc_runtime_suspend(struct device *dev)
{
struct mmc_card *card = mmc_dev_to_card(dev);
- struct mmc_host *host = card->host;
- int ret = 0;
-
- if (host->bus_ops->runtime_suspend)
- ret = host->bus_ops->runtime_suspend(host);
- return ret;
+ return mmc_power_save_host(card->host);
}
static int mmc_runtime_resume(struct device *dev)
{
struct mmc_card *card = mmc_dev_to_card(dev);
- struct mmc_host *host = card->host;
- int ret = 0;
-
- if (host->bus_ops->runtime_resume)
- ret = host->bus_ops->runtime_resume(host);
- return ret;
+ return mmc_power_restore_host(card->host);
}
static int mmc_runtime_idle(struct device *dev)
{
- return 0;
+ return pm_runtime_suspend(dev);
}
#endif /* !CONFIG_PM_RUNTIME */
.uevent = mmc_bus_uevent,
.probe = mmc_bus_probe,
.remove = mmc_bus_remove,
- .shutdown = mmc_bus_shutdown,
.pm = &mmc_bus_pm_ops,
};
break;
}
- if (mmc_card_uhs(card) &&
+ if (mmc_sd_card_uhs(card) &&
(card->sd_bus_speed < ARRAY_SIZE(uhs_speeds)))
uhs_bus_speed_mode = uhs_speeds[card->sd_bus_speed];
#include <linux/log2.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h>
-#include <linux/pm_wakeup.h>
#include <linux/suspend.h>
#include <linux/fault-inject.h>
#include <linux/random.h>
#include <linux/slab.h>
-#include <linux/of.h>
+#include <linux/wakelock.h>
+
+#include <trace/events/mmc.h>
#include <linux/mmc/card.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
#include <linux/mmc/sd.h>
-#include <linux/mmc/sdio.h>
#include "core.h"
#include "bus.h"
led_trigger_event(host->led, LED_OFF);
pr_debug("%s: req done (CMD%u): %d: %08x %08x %08x %08x\n",
- mmc_hostname(host), cmd->opcode, err,
- cmd->resp[0], cmd->resp[1],
- cmd->resp[2], cmd->resp[3]);
+ mmc_hostname(host), cmd->opcode, err,
+ cmd->resp[0], cmd->resp[1],
+ cmd->resp[2], cmd->resp[3]);
if (mrq->data) {
pr_debug("%s: %d bytes transferred: %d\n",
- mmc_hostname(host),
- mrq->data->bytes_xfered, mrq->data->error);
+ mmc_hostname(host),
+ mrq->data->bytes_xfered, mrq->data->error);
+ trace_mmc_blk_rw_end(cmd->opcode, cmd->arg, mrq->data);
}
if (mrq->stop) {
pr_debug("%s: (CMD%u): %d: %08x %08x %08x %08x\n",
- mmc_hostname(host), mrq->stop->opcode,
- mrq->stop->error,
- mrq->stop->resp[0], mrq->stop->resp[1],
- mrq->stop->resp[2], mrq->stop->resp[3]);
+ mmc_hostname(host), mrq->stop->opcode,
+ mrq->stop->error,
+ mrq->stop->resp[0], mrq->stop->resp[1],
+ mrq->stop->resp[2], mrq->stop->resp[3]);
}
if (mrq->done)
mmc_host_clk_release(host);
}
}
-EXPORT_SYMBOL(mmc_request_done);
-
-static void __mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
-{
- int err;
-
- /* Assumes host controller has been runtime resumed by mmc_claim_host */
- err = mmc_retune(host);
- if (err) {
- mrq->cmd->error = err;
- mmc_request_done(host, mrq);
- return;
- }
- host->ops->request(host, mrq);
-}
+EXPORT_SYMBOL(mmc_request_done);
static void
mmc_start_request(struct mmc_host *host, struct mmc_request *mrq)
unsigned int i, sz;
struct scatterlist *sg;
#endif
- mmc_retune_hold(host);
if (mrq->sbc) {
pr_debug("<%s: starting CMD%u arg %08x flags %08x>\n",
mrq->cmd->arg, mrq->cmd->flags);
if (mrq->data) {
- pr_debug("%s: blksz %d blocks %d flags %08x tsac %d ms nsac %d\n",
- mmc_hostname(host), mrq->data->blksz,
- mrq->data->blocks, mrq->data->flags,
- mrq->data->timeout_ns / 1000000,
- mrq->data->timeout_clks);
+ pr_debug("%s: blksz %d blocks %d flags %08x "
+ "tsac %d ms nsac %d\n",
+ mmc_hostname(host), mrq->data->blksz,
+ mrq->data->blocks, mrq->data->flags,
+ mrq->data->timeout_ns / 1000000,
+ mrq->data->timeout_clks);
}
if (mrq->stop) {
}
mmc_host_clk_hold(host);
led_trigger_event(host->led, LED_FULL);
- __mmc_start_request(host, mrq);
+ host->ops->request(host, mrq);
}
/**
timeout = MMC_BKOPS_MAX_TIMEOUT;
use_busy_signal = true;
} else {
- /* Hold re-tuning for ongoing bkops */
- mmc_retune_hold(card->host);
timeout = 0;
use_busy_signal = false;
}
err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_BKOPS_START, 1,
- timeout, use_busy_signal, true);
+ EXT_CSD_BKOPS_START, 1, timeout, use_busy_signal);
if (err) {
pr_warn("%s: Error %d starting bkops\n",
mmc_hostname(card->host), err);
- /* bkops not ongoing, so release re-tuning */
- if (!use_busy_signal)
- mmc_retune_release(card->host);
goto out;
}
return 0;
}
-static void mmc_get_req_timeout(struct mmc_request *mrq, u32 *timeout)
-{
- if (!mrq->cmd->data) {
- if (mrq->cmd->opcode == MMC_ERASE ||
- (mrq->cmd->opcode == MMC_ERASE_GROUP_START) ||
- (mrq->cmd->opcode == MMC_ERASE_GROUP_END) ||
- (mrq->cmd->opcode == MMC_SEND_STATUS))
- ((mrq->cmd->opcode == MMC_ERASE) &&
- ((mrq->cmd->arg == MMC_DISCARD_ARG) ||
- (mrq->cmd->arg == MMC_TRIM_ARG))) ?
- (*timeout = 10000) : (*timeout = 25000);
- else if (mrq->cmd->opcode == MMC_SWITCH)
- *timeout = mrq->cmd->cmd_timeout_ms;
- else
- *timeout = 500;
-
- } else {
- *timeout = mrq->cmd->data->blocks *
- mrq->cmd->data->blksz * 500;
- *timeout = (*timeout) ? (*timeout) : 1000;
- if (*timeout > 8000)
- *timeout = 8000;
- }
-
- if ((mrq->cmd->opcode == SD_IO_RW_DIRECT) ||
- (mrq->cmd->opcode == SD_IO_RW_EXTENDED))
- *timeout = 8000;
- else if ((mrq->cmd->opcode == MMC_SEND_TUNING_BLOCK_HS200) ||
- (mrq->cmd->opcode == MMC_SEND_TUNING_BLOCK))
- *timeout = 100;
-}
-
-
/*
* mmc_wait_for_data_req_done() - wait for request completed
* @host: MMC host to prepare the command.
struct mmc_context_info *context_info = &host->context_info;
int err;
unsigned long flags;
- u32 timeout = 0;
-
- mmc_get_req_timeout(mrq, &timeout);
while (1) {
- if (!wait_event_interruptible_timeout(context_info->wait,
- (context_info->is_done_rcv ||
- context_info->is_new_req),
- msecs_to_jiffies(timeout))) {
- cmd = mrq->cmd;
- cmd->error = -ETIMEDOUT;
- dev_err(mmc_dev(host),
- "req failed (CMD%u): error = %d, timeout = %dms\n",
- cmd->opcode, cmd->error, timeout);
- host->ops->post_tmo(host);
- context_info->is_done_rcv = true;
- }
-
+ wait_event_interruptible(context_info->wait,
+ (context_info->is_done_rcv ||
+ context_info->is_new_req));
spin_lock_irqsave(&context_info->lock, flags);
context_info->is_waiting_last_req = false;
spin_unlock_irqrestore(&context_info->lock, flags);
context_info->is_done_rcv = false;
context_info->is_new_req = false;
cmd = mrq->cmd;
-
if (!cmd->error || !cmd->retries ||
mmc_card_removed(host->card)) {
err = host->areq->err_check(host->card,
host->areq);
break; /* return err */
} else {
- mmc_retune_recheck(host);
pr_info("%s: req failed (CMD%u): %d, retrying...\n",
mmc_hostname(host),
cmd->opcode, cmd->error);
cmd->retries--;
cmd->error = 0;
- __mmc_start_request(host, mrq);
+ host->ops->request(host, mrq);
continue; /* wait for done/new event again */
}
} else if (context_info->is_new_req) {
context_info->is_new_req = false;
- if (!next_req)
- return MMC_BLK_NEW_REQUEST;
+ if (!next_req) {
+ err = MMC_BLK_NEW_REQUEST;
+ break; /* return err */
+ }
}
}
- mmc_retune_release(host);
return err;
}
struct mmc_request *mrq)
{
struct mmc_command *cmd;
- u32 timeout = 0;
-
- mmc_get_req_timeout(mrq, &timeout);
while (1) {
- if (!wait_for_completion_timeout(&mrq->completion,
- msecs_to_jiffies(timeout))) {
- cmd = mrq->cmd;
- cmd->error = -ETIMEDOUT;
- dev_err(mmc_dev(host),
- "req failed (CMD%u): error = %d, timeout = %dms\n",
- cmd->opcode, cmd->error, timeout);
- host->ops->post_tmo(host);
- }
+ wait_for_completion(&mrq->completion);
cmd = mrq->cmd;
-
- /*
- * If host has timed out waiting for the sanitize
- * to complete, card might be still in programming state
- * so let's try to bring the card out of programming
- * state.
- */
- if (cmd->sanitize_busy && cmd->error == -ETIMEDOUT) {
- if (!mmc_interrupt_hpi(host->card)) {
- pr_warn("%s: %s: Interrupted sanitize\n",
- mmc_hostname(host), __func__);
- cmd->error = 0;
- break;
- } else {
- pr_err("%s: %s: Failed to interrupt sanitize\n",
- mmc_hostname(host), __func__);
- }
- }
if (!cmd->error || !cmd->retries ||
mmc_card_removed(host->card))
break;
mmc_hostname(host), cmd->opcode, cmd->error);
cmd->retries--;
cmd->error = 0;
- __mmc_start_request(host, mrq);
+ host->ops->request(host, mrq);
}
- mmc_retune_release(host);
}
/**
* performed while another request is running on the host.
*/
static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq,
- bool is_first_req)
+ bool is_first_req)
{
if (host->ops->pre_req) {
mmc_host_clk_hold(host);
mmc_start_bkops(host->card, true);
}
- if (!err && areq)
+ if (!err && areq) {
+ trace_mmc_blk_rw_start(areq->mrq->cmd->opcode,
+ areq->mrq->cmd->arg,
+ areq->mrq->data);
start_err = __mmc_start_data_req(host, areq->mrq);
+ }
if (host->areq)
mmc_post_req(host, host->areq->mrq, 0);
default:
/* In all other states, it's illegal to issue HPI */
pr_debug("%s: HPI cannot be sent. Card state=%d\n",
- mmc_hostname(card->host), R1_CURRENT_STATE(status));
+ mmc_hostname(card->host), R1_CURRENT_STATE(status));
err = -EINVAL;
goto out;
}
* to complete. Return any error that occurred while the command
* was executing. Do not attempt to parse the response.
*/
-int mmc_wait_for_cmd(struct mmc_host *host,
- struct mmc_command *cmd,
- int retries)
+int mmc_wait_for_cmd(struct mmc_host *host, struct mmc_command *cmd, int retries)
{
struct mmc_request mrq = {NULL};
return cmd->error;
}
+
EXPORT_SYMBOL(mmc_wait_for_cmd);
/**
*/
if (!err || (err == -EINVAL)) {
mmc_card_clr_doing_bkops(card);
- mmc_retune_release(card->host);
err = 0;
}
host->claimed = 1;
host->claimer = current;
host->claim_cnt += 1;
- } else {
+ } else
wake_up(&host->wq);
- }
-
spin_unlock_irqrestore(&host->lock, flags);
remove_wait_queue(&host->wq, &wait);
if (host->ops->enable && !stop && host->claim_cnt == 1)
host->ops->enable(host);
return stop;
}
+
EXPORT_SYMBOL(__mmc_claim_host);
+/**
+ * mmc_try_claim_host - try exclusively to claim a host
+ * @host: mmc host to claim
+ *
+ * Returns %1 if the host is claimed, %0 otherwise.
+ */
+int mmc_try_claim_host(struct mmc_host *host)
+{
+ int claimed_host = 0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&host->lock, flags);
+ if (!host->claimed || host->claimer == current) {
+ host->claimed = 1;
+ host->claimer = current;
+ host->claim_cnt += 1;
+ claimed_host = 1;
+ }
+ spin_unlock_irqrestore(&host->lock, flags);
+ if (host->ops->enable && claimed_host && host->claim_cnt == 1)
+ host->ops->enable(host);
+ return claimed_host;
+}
+EXPORT_SYMBOL(mmc_try_claim_host);
+
/**
* mmc_release_host - release a host
* @host: mmc host to release
}
EXPORT_SYMBOL(mmc_release_host);
-/*
- * This is a helper function, which fetches a runtime pm reference for the
- * card device and also claims the host.
- */
-void mmc_get_card(struct mmc_card *card)
-{
- pm_runtime_get_sync(&card->dev);
- mmc_claim_host(card->host);
-}
-EXPORT_SYMBOL(mmc_get_card);
-
-/*
- * This is a helper function, which releases the host and drops the runtime
- * pm reference for the card device.
- */
-void mmc_put_card(struct mmc_card *card)
-{
- mmc_release_host(card->host);
- pm_runtime_mark_last_busy(&card->dev);
- pm_runtime_put_autosuspend(&card->dev);
-}
-EXPORT_SYMBOL(mmc_put_card);
-
/*
* Internal function that does the actual ios call to the host driver,
* optionally printing some debug output.
{
struct mmc_ios *ios = &host->ios;
- pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u width %u timing %u\n",
+ pr_debug("%s: clock %uHz busmode %u powermode %u cs %u Vdd %u "
+ "width %u timing %u\n",
mmc_hostname(host), ios->clock, ios->bus_mode,
ios->power_mode, ios->chip_select, ios->vdd,
ios->bus_width, ios->timing);
}
#endif
-int mmc_execute_tuning(struct mmc_card *card)
-{
- struct mmc_host *host = card->host;
- u32 opcode;
- int err;
-
- if (!host->ops->execute_tuning)
- return 0;
-
- if (mmc_card_mmc(card))
- opcode = MMC_SEND_TUNING_BLOCK_HS200;
- else
- opcode = MMC_SEND_TUNING_BLOCK;
-
- mmc_host_clk_hold(host);
- err = host->ops->execute_tuning(host, opcode);
- mmc_host_clk_release(host);
-
- if (err)
- pr_err("%s: tuning execution failed\n", mmc_hostname(host));
- else
- mmc_retune_enable(host);
-
- return err;
-}
-
/*
* Change the bus mode (open drain/push-pull) of a host.
*/
}
EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
-#ifdef CONFIG_OF
-
-/**
- * mmc_of_parse_voltage - return mask of supported voltages
- * @np: The device node need to be parsed.
- * @mask: mask of voltages available for MMC/SD/SDIO
- *
- * 1. Return zero on success.
- * 2. Return negative errno: voltage-range is invalid.
- */
-int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
-{
- const u32 *voltage_ranges;
- int num_ranges, i;
-
- voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
- num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
- if (!voltage_ranges || !num_ranges) {
- pr_info("%s: voltage-ranges unspecified\n", np->full_name);
- return -EINVAL;
- }
-
- for (i = 0; i < num_ranges; i++) {
- const int j = i * 2;
- u32 ocr_mask;
-
- ocr_mask = mmc_vddrange_to_ocrmask(
- be32_to_cpu(voltage_ranges[j]),
- be32_to_cpu(voltage_ranges[j + 1]));
- if (!ocr_mask) {
- pr_err("%s: voltage-range #%d is invalid\n",
- np->full_name, i);
- return -EINVAL;
- }
- *mask |= ocr_mask;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(mmc_of_parse_voltage);
-
-#endif /* CONFIG_OF */
-
#ifdef CONFIG_REGULATOR
/**
* set_ios() method.
*/
int mmc_regulator_set_ocr(struct mmc_host *mmc,
- struct regulator *supply,
- unsigned short vdd_bit)
+ struct regulator *supply,
+ unsigned short vdd_bit)
{
int result = 0;
int min_uV, max_uV;
*/
voltage = regulator_get_voltage(supply);
- if (!regulator_can_change_voltage(supply)) {
- max_uV = voltage;
- min_uV = max_uV;
- }
+ if (!regulator_can_change_voltage(supply))
+ min_uV = max_uV = voltage;
if (voltage < 0)
result = voltage;
supply = devm_regulator_get(dev, "vmmc");
mmc->supply.vmmc = supply;
- mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
+ mmc->supply.vqmmc = devm_regulator_get(dev, "vqmmc");
if (IS_ERR(supply))
return PTR_ERR(supply);
{
int bit;
- /*
- * Sanity check the voltages that the card claims to
- * support.
- */
- if (ocr & 0x7F) {
- dev_warn(mmc_dev(host),
- "card claims to support voltages below defined range\n");
- ocr &= ~0x7F;
- }
-
ocr &= host->ocr_avail;
- if (!ocr) {
- dev_warn(mmc_dev(host), "no support for card's volts\n");
- return 0;
- }
- if (host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) {
- bit = ffs(ocr) - 1;
+ bit = ffs(ocr);
+ if (bit) {
+ bit -= 1;
+
ocr &= 3 << bit;
- mmc_power_cycle(host, ocr);
+
+ mmc_host_clk_hold(host);
+ host->ios.vdd = bit;
+ mmc_set_ios(host);
+ mmc_host_clk_release(host);
} else {
- bit = fls(ocr) - 1;
- ocr &= 3 << bit;
- if (bit != host->ios.vdd)
- dev_warn(mmc_dev(host), "exceeding card's volts\n");
+ pr_warning("%s: host doesn't support card's voltages\n",
+ mmc_hostname(host));
+ ocr = 0;
}
return ocr;
host->ios.signal_voltage = old_signal_voltage;
return err;
+
}
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr)
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage)
{
struct mmc_command cmd = {0};
int err = 0;
if (!host->ops->start_signal_voltage_switch)
return -EPERM;
if (!host->ops->card_busy)
- pr_warn("%s: cannot verify signal voltage switch\n",
- mmc_hostname(host));
+ pr_warning("%s: cannot verify signal voltage switch\n",
+ mmc_hostname(host));
cmd.opcode = SD_SWITCH_VOLTAGE;
cmd.arg = 0;
power_cycle:
if (err) {
- pr_debug("%s: Signal voltage switch failed, power cycling card\n",
- mmc_hostname(host));
- mmc_power_cycle(host, ocr);
+ pr_debug("%s: Signal voltage switch failed, "
+ "power cycling card\n", mmc_hostname(host));
+ mmc_power_cycle(host);
}
mmc_host_clk_release(host);
* If a host does all the power sequencing itself, ignore the
* initial MMC_POWER_UP stage.
*/
-void mmc_power_up(struct mmc_host *host, u32 ocr)
+static void mmc_power_up(struct mmc_host *host)
{
+ int bit;
+
if (host->ios.power_mode == MMC_POWER_ON)
return;
mmc_host_clk_hold(host);
- mmc_retune_disable(host);
- host->ios.vdd = fls(ocr) - 1;
+ /* If ocr is set, we use it */
+ if (host->ocr)
+ bit = ffs(host->ocr) - 1;
+ else
+ bit = fls(host->ocr_avail) - 1;
+
+ host->ios.vdd = bit;
if (mmc_host_is_spi(host))
host->ios.chip_select = MMC_CS_HIGH;
else
return;
mmc_host_clk_hold(host);
- mmc_retune_disable(host);
host->ios.clock = 0;
host->ios.vdd = 0;
+
+ /*
+ * Reset ocr mask to be the highest possible voltage supported for
+ * this mmc host. This value will be used at next power up.
+ */
+ host->ocr = 1 << (fls(host->ocr_avail) - 1);
+
if (!mmc_host_is_spi(host)) {
host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN;
host->ios.chip_select = MMC_CS_DONTCARE;
mmc_host_clk_release(host);
}
-void mmc_power_cycle(struct mmc_host *host, u32 ocr)
+void mmc_power_cycle(struct mmc_host *host)
{
mmc_power_off(host);
/* Wait at least 1 ms according to SD spec */
mmc_delay(1);
- mmc_power_up(host, ocr);
+ mmc_power_up(host);
}
/*
spin_unlock_irqrestore(&host->lock, flags);
}
-/*
int mmc_resume_bus(struct mmc_host *host)
{
unsigned long flags;
}
EXPORT_SYMBOL(mmc_resume_bus);
-*/
/*
* Assign a mmc bus handler to a host. Only one bus handler may control a
mmc_bus_put(host);
}
-static void _mmc_detect_change(struct mmc_host *host, unsigned long delay,
- bool cd_irq)
-{
-#ifdef CONFIG_MMC_DEBUG
- unsigned long flags;
-
- spin_lock_irqsave(&host->lock, flags);
- WARN_ON(host->removed);
- spin_unlock_irqrestore(&host->lock, flags);
-#endif
-
- /*
- * If the device is configured as wakeup, we prevent a new sleep for
- * 5 s to give provision for user space to consume the event.
- */
- if (cd_irq && !(host->caps & MMC_CAP_NEEDS_POLL) &&
- device_can_wakeup(mmc_dev(host)))
- pm_wakeup_event(mmc_dev(host), 5000);
-
- host->detect_change = 1;
- mmc_schedule_delayed_work(&host->detect, delay);
-}
-
/**
* mmc_detect_change - process change of state on a MMC socket
* @host: host which changed state.
*/
void mmc_detect_change(struct mmc_host *host, unsigned long delay)
{
- _mmc_detect_change(host, delay, true);
+#ifdef CONFIG_MMC_DEBUG
+ unsigned long flags;
+ spin_lock_irqsave(&host->lock, flags);
+ WARN_ON(host->removed);
+ spin_unlock_irqrestore(&host->lock, flags);
+#endif
+ host->detect_change = 1;
+
+ wake_lock(&host->detect_wake_lock);
+ mmc_schedule_delayed_work(&host->detect, delay);
}
+
EXPORT_SYMBOL(mmc_detect_change);
void mmc_init_erase(struct mmc_card *card)
card->pref_erase = 2 * 1024 * 1024 / 512;
else
card->pref_erase = 4 * 1024 * 1024 / 512;
- if (card->pref_erase < card->erase_size) {
+ if (card->pref_erase < card->erase_size)
card->pref_erase = card->erase_size;
- } else {
+ else {
sz = card->pref_erase % card->erase_size;
if (sz)
card->pref_erase += card->erase_size - sz;
}
static unsigned int mmc_mmc_erase_timeout(struct mmc_card *card,
- unsigned int arg, unsigned int qty)
+ unsigned int arg, unsigned int qty)
{
unsigned int erase_timeout;
unsigned int fr, nr;
int err;
- mmc_retune_hold(card->host);
-
fr = from;
nr = to - from + 1;
+ trace_mmc_blk_erase_start(arg, fr, nr);
/*
* qty is used to calculate the erase timeout which depends on how many
cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
err = mmc_wait_for_cmd(card->host, &cmd, 0);
if (err) {
- pr_err("mmc_erase: group start error %d, status %#x\n",
- err, cmd.resp[0]);
+ pr_err("mmc_erase: group start error %d, "
+ "status %#x\n", err, cmd.resp[0]);
err = -EIO;
goto out;
}
err = mmc_wait_for_cmd(card->host, &cmd, 0);
if (err || (cmd.resp[0] & 0xFDF92000)) {
pr_err("error %d requesting status %#x\n",
- err, cmd.resp[0]);
+ err, cmd.resp[0]);
err = -EIO;
goto out;
}
*/
if (time_after(jiffies, timeout)) {
pr_err("%s: Card stuck in programming state! %s\n",
- mmc_hostname(card->host), __func__);
+ mmc_hostname(card->host), __func__);
err = -EIO;
goto out;
}
} while (!(cmd.resp[0] & R1_READY_FOR_DATA) ||
(R1_CURRENT_STATE(cmd.resp[0]) == R1_STATE_PRG));
out:
- mmc_retune_release(card->host);
+
+ trace_mmc_blk_erase_end(arg, fr, nr);
return err;
}
int mmc_can_trim(struct mmc_card *card)
{
- if ((card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN) &&
- !(card->quirks & MMC_QUIRK_TRIM_UNSTABLE))
+ if (card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN)
return 1;
return 0;
}
EXPORT_SYMBOL(mmc_set_blocklen);
int mmc_set_blockcount(struct mmc_card *card, unsigned int blockcount,
- bool is_rel_write)
+ bool is_rel_write)
{
struct mmc_command cmd = {0};
pr_info("%s: %s: trying to init card at %u Hz\n",
mmc_hostname(host), __func__, host->f_init);
#endif
- mmc_power_up(host, host->ocr_avail);
+ mmc_power_up(host);
/*
* Some eMMCs (with VCCQ always on) may not be reset after power up, so
* if the card is being re-initialized, just send it. CMD52
* should be ignored by SD/eMMC cards.
*/
-#ifdef MMC_STANDARD_PROBE
sdio_reset(host);
mmc_go_idle(host);
return 0;
if (!mmc_attach_mmc(host))
return 0;
-#else
- /*
- * Simplifying initialization process.
- */
- if (host->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
- sdio_reset(host);
-
- mmc_go_idle(host);
-
- if (host->restrict_caps &
- (RESTRICT_CARD_TYPE_SDIO | RESTRICT_CARD_TYPE_SD))
- mmc_send_if_cond(host, host->ocr_avail);
-
- /* Order's important: probe SDIO, then SD, then MMC */
- if ((host->restrict_caps & RESTRICT_CARD_TYPE_SDIO) &&
- !mmc_attach_sdio(host))
- return 0;
- if ((host->restrict_caps & RESTRICT_CARD_TYPE_SD) &&
- !mmc_attach_sd(host))
- return 0;
- if ((host->restrict_caps & RESTRICT_CARD_TYPE_EMMC) &&
- !mmc_attach_mmc(host))
- return 0;
-#endif
mmc_power_off(host);
return -EIO;
* The card will be considered unchanged unless we have been asked to
* detect a change or host requires polling to provide card detection.
*/
- if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL))
+ if (!host->detect_change && !(host->caps & MMC_CAP_NEEDS_POLL) &&
+ !(host->caps2 & MMC_CAP2_DETECT_ON_ERR))
return ret;
host->detect_change = 0;
if (!ret) {
ret = _mmc_detect_card_removed(host);
- if (ret && (host->caps & MMC_CAP_NEEDS_POLL)) {
+ if (ret && (host->caps2 & MMC_CAP2_DETECT_ON_ERR)) {
/*
* Schedule a detect work as soon as possible to let a
* rescan handle the card removal.
*/
cancel_delayed_work(&host->detect);
- _mmc_detect_change(host, 0, false);
+ mmc_detect_change(host, 0);
}
}
* if there is a _removable_ card registered, check whether it is
* still present
*/
- if (host->bus_ops && host->bus_ops->detect && !host->bus_dead &&
- !(host->caps & MMC_CAP_NONREMOVABLE))
+ if (host->bus_ops && host->bus_ops->detect && !host->bus_dead
+ && !(host->caps & MMC_CAP_NONREMOVABLE))
host->bus_ops->detect(host);
host->detect_change = 0;
*/
mmc_bus_put(host);
- if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->get_cd &&
- host->ops->get_cd(host) == 0) {
+ if (host->ops->get_cd && host->ops->get_cd(host) == 0) {
mmc_claim_host(host);
mmc_power_off(host);
mmc_release_host(host);
if (host->caps2 & MMC_CAP2_NO_PRESCAN_POWERUP)
mmc_power_off(host);
else
- mmc_power_up(host, host->ocr_avail);
- _mmc_detect_change(host, 0, false);
+ mmc_power_up(host);
+ mmc_detect_change(host, 0);
}
void mmc_stop_host(struct mmc_host *host)
{
#ifdef CONFIG_MMC_DEBUG
unsigned long flags;
-
spin_lock_irqsave(&host->lock, flags);
host->removed = 1;
spin_unlock_irqrestore(&host->lock, flags);
mmc_bus_get(host);
if (host->bus_ops && !host->bus_dead) {
/* Calling bus_ops->remove() with a claimed host can deadlock */
- host->bus_ops->remove(host);
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
return -EINVAL;
}
- mmc_power_up(host, host->card->ocr);
+ mmc_power_up(host);
ret = host->bus_ops->power_restore(host);
mmc_bus_put(host);
}
EXPORT_SYMBOL(mmc_power_restore_host);
+int mmc_card_awake(struct mmc_host *host)
+{
+ int err = -ENOSYS;
+
+ if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
+ return 0;
+
+ mmc_bus_get(host);
+
+ if (host->bus_ops && !host->bus_dead && host->bus_ops->awake)
+ err = host->bus_ops->awake(host);
+
+ mmc_bus_put(host);
+
+ return err;
+}
+EXPORT_SYMBOL(mmc_card_awake);
+
+int mmc_card_sleep(struct mmc_host *host)
+{
+ int err = -ENOSYS;
+
+ if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
+ return 0;
+
+ mmc_bus_get(host);
+
+ if (host->bus_ops && !host->bus_dead && host->bus_ops->sleep)
+ err = host->bus_ops->sleep(host);
+
+ mmc_bus_put(host);
+
+ return err;
+}
+EXPORT_SYMBOL(mmc_card_sleep);
+
+int mmc_card_can_sleep(struct mmc_host *host)
+{
+ struct mmc_card *card = host->card;
+
+ if (card && mmc_card_mmc(card) && card->ext_csd.rev >= 3)
+ return 1;
+ return 0;
+}
+EXPORT_SYMBOL(mmc_card_can_sleep);
+
/*
* Flush the cache to the non-volatile storage.
*/
return err;
if (mmc_card_mmc(card) &&
- (card->ext_csd.cache_size > 0) &&
- (card->ext_csd.cache_ctrl & 1)) {
+ (card->ext_csd.cache_size > 0) &&
+ (card->ext_csd.cache_ctrl & 1)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_FLUSH_CACHE, 1, 0);
+ EXT_CSD_FLUSH_CACHE, 1, 0);
if (err)
pr_err("%s: cache flush error %d\n",
- mmc_hostname(card->host), err);
+ mmc_hostname(card->host), err);
}
return err;
int err = 0;
if (!(host->caps2 & MMC_CAP2_CACHE_CTRL) ||
- mmc_card_is_removable(host))
+ mmc_card_is_removable(host))
return err;
if (card && mmc_card_mmc(card) &&
- (card->ext_csd.cache_size > 0)) {
+ (card->ext_csd.cache_size > 0)) {
enable = !!enable;
if (card->ext_csd.cache_ctrl ^ enable) {
timeout = enable ? card->ext_csd.generic_cmd6_time : 0;
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_CACHE_CTRL, enable, timeout);
+ EXT_CSD_CACHE_CTRL, enable, timeout);
if (err)
pr_err("%s: cache %s error %d\n",
- mmc_hostname(card->host),
- enable ? "on" : "off",
- err);
+ mmc_hostname(card->host),
+ enable ? "on" : "off",
+ err);
else
card->ext_csd.cache_ctrl = enable;
}
#ifdef CONFIG_PM
+/**
+ * mmc_suspend_host - suspend a host
+ * @host: mmc host
+ */
+int mmc_suspend_host(struct mmc_host *host)
+{
+ int err = 0;
+
+ if (mmc_bus_needs_resume(host))
+ return 0;
+
+ if (cancel_delayed_work(&host->detect))
+ wake_unlock(&host->detect_wake_lock);
+ mmc_flush_scheduled_work();
+
+ mmc_bus_get(host);
+ if (host->bus_ops && !host->bus_dead) {
+ if (host->bus_ops->suspend) {
+ if (mmc_card_doing_bkops(host->card)) {
+ err = mmc_stop_bkops(host->card);
+ if (err)
+ goto out;
+ }
+ err = host->bus_ops->suspend(host);
+ }
+
+ if (err == -ENOSYS || !host->bus_ops->resume) {
+ /*
+ * We simply "remove" the card in this case.
+ * It will be redetected on resume. (Calling
+ * bus_ops->remove() with a claimed host can
+ * deadlock.)
+ */
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+ mmc_claim_host(host);
+ mmc_detach_bus(host);
+ mmc_power_off(host);
+ mmc_release_host(host);
+ host->pm_flags = 0;
+ err = 0;
+ }
+ }
+ mmc_bus_put(host);
+
+ if (!err && !mmc_card_keep_power(host))
+ mmc_power_off(host);
+
+out:
+ return err;
+}
+
+EXPORT_SYMBOL(mmc_suspend_host);
+
+/**
+ * mmc_resume_host - resume a previously suspended host
+ * @host: mmc host
+ */
+int mmc_resume_host(struct mmc_host *host)
+{
+ int err = 0;
+
+ mmc_bus_get(host);
+ if (mmc_bus_manual_resume(host)) {
+ host->bus_resume_flags |= MMC_BUSRESUME_NEEDS_RESUME;
+ mmc_bus_put(host);
+ return 0;
+ }
+
+ if (host->bus_ops && !host->bus_dead) {
+ if (!mmc_card_keep_power(host)) {
+ mmc_power_up(host);
+ mmc_select_voltage(host, host->ocr);
+ /*
+ * Tell runtime PM core we just powered up the card,
+ * since it still believes the card is powered off.
+ * Note that currently runtime PM is only enabled
+ * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
+ */
+ if (mmc_card_sdio(host->card) &&
+ (host->caps & MMC_CAP_POWER_OFF_CARD)) {
+ pm_runtime_disable(&host->card->dev);
+ pm_runtime_set_active(&host->card->dev);
+ pm_runtime_enable(&host->card->dev);
+ }
+ }
+ BUG_ON(!host->bus_ops->resume);
+ err = host->bus_ops->resume(host);
+ if (err) {
+ pr_warning("%s: error %d during resume "
+ "(card was removed?)\n",
+ mmc_hostname(host), err);
+ err = 0;
+ }
+ }
+ host->pm_flags &= ~MMC_PM_KEEP_POWER;
+ mmc_bus_put(host);
+
+ return err;
+}
+EXPORT_SYMBOL(mmc_resume_host);
+
/* Do the card removal on suspend if card is assumed removeable
* Do that in pm notifier while userspace isn't yet frozen, so we will be able
to sync the card.
*/
int mmc_pm_notify(struct notifier_block *notify_block,
- unsigned long mode, void *unused)
+ unsigned long mode, void *unused)
{
struct mmc_host *host = container_of(
notify_block, struct mmc_host, pm_notify);
switch (mode) {
case PM_HIBERNATION_PREPARE:
case PM_SUSPEND_PREPARE:
+ if (host->card && mmc_card_mmc(host->card) &&
+ mmc_card_doing_bkops(host->card)) {
+ err = mmc_stop_bkops(host->card);
+ if (err) {
+ pr_err("%s: didn't stop bkops\n",
+ mmc_hostname(host));
+ return err;
+ }
+ mmc_card_clr_doing_bkops(host->card);
+ }
+
spin_lock_irqsave(&host->lock, flags);
if (mmc_bus_needs_resume(host)) {
spin_unlock_irqrestore(&host->lock, flags);
if (cancel_delayed_work_sync(&host->detect))
wake_unlock(&host->detect_wake_lock);
- if (!host->bus_ops)
- break;
-
- /* Validate prerequisites for suspend */
- if (host->bus_ops->pre_suspend)
- err = host->bus_ops->pre_suspend(host);
- if (!err && host->bus_ops->suspend)
+ if (!host->bus_ops || host->bus_ops->suspend)
break;
/* Calling bus_ops->remove() with a claimed host can deadlock */
- host->bus_ops->remove(host);
+ if (host->bus_ops->remove)
+ host->bus_ops->remove(host);
+
mmc_claim_host(host);
mmc_detach_bus(host);
mmc_power_off(host);
}
host->rescan_disable = 0;
spin_unlock_irqrestore(&host->lock, flags);
- _mmc_detect_change(host, 0, false);
+ mmc_detect_change(host, 0);
+
}
return 0;
host->embedded_sdio_data.funcs = funcs;
host->embedded_sdio_data.num_funcs = num_funcs;
}
+
EXPORT_SYMBOL(mmc_set_embedded_sdio_data);
#endif
#define MMC_CMD_RETRIES 3
struct mmc_bus_ops {
+ int (*awake)(struct mmc_host *);
+ int (*sleep)(struct mmc_host *);
void (*remove)(struct mmc_host *);
void (*detect)(struct mmc_host *);
- int (*pre_suspend)(struct mmc_host *);
int (*suspend)(struct mmc_host *);
int (*resume)(struct mmc_host *);
- int (*runtime_suspend)(struct mmc_host *);
- int (*runtime_resume)(struct mmc_host *);
int (*power_save)(struct mmc_host *);
int (*power_restore)(struct mmc_host *);
int (*alive)(struct mmc_host *);
- int (*shutdown)(struct mmc_host *);
};
void mmc_attach_bus(struct mmc_host *host, const struct mmc_bus_ops *ops);
void mmc_set_bus_mode(struct mmc_host *host, unsigned int mode);
void mmc_set_bus_width(struct mmc_host *host, unsigned int width);
u32 mmc_select_voltage(struct mmc_host *host, u32 ocr);
-int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, u32 ocr);
+int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
int __mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage);
void mmc_set_timing(struct mmc_host *host, unsigned int timing);
void mmc_set_driver_type(struct mmc_host *host, unsigned int drv_type);
-void mmc_power_up(struct mmc_host *host, u32 ocr);
void mmc_power_off(struct mmc_host *host);
-void mmc_power_cycle(struct mmc_host *host, u32 ocr);
+void mmc_power_cycle(struct mmc_host *host);
static inline void mmc_delay(unsigned int ms)
{
void mmc_remove_card_debugfs(struct mmc_card *card);
void mmc_init_context_info(struct mmc_host *host);
-int mmc_execute_tuning(struct mmc_card *card);
#endif
u32 status;
int ret;
- mmc_get_card(card);
+ mmc_claim_host(card->host);
ret = mmc_send_status(data, &status);
if (!ret)
*val = status;
- mmc_put_card(card);
+ mmc_release_host(card->host);
return ret;
}
goto out_free;
}
- mmc_get_card(card);
+ mmc_claim_host(card->host);
err = mmc_send_ext_csd(card, ext_csd);
- mmc_put_card(card);
+ mmc_release_host(card->host);
if (err)
goto out_free;
static void mmc_host_classdev_release(struct device *dev)
{
struct mmc_host *host = cls_dev_to_mmc_host(dev);
-
mutex_destroy(&host->slot.lock);
kfree(host);
}
#ifdef CONFIG_MMC_CLKGATE
static ssize_t clkgate_delay_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr, char *buf)
{
struct mmc_host *host = cls_dev_to_mmc_host(dev);
-
return snprintf(buf, PAGE_SIZE, "%lu\n", host->clkgate_delay);
}
static ssize_t clkgate_delay_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+ struct device_attribute *attr, const char *buf, size_t count)
{
struct mmc_host *host = cls_dev_to_mmc_host(dev);
unsigned long flags, value;
host->clkgate_delay_attr.attr.mode = S_IRUGO | S_IWUSR;
if (device_create_file(&host->class_dev, &host->clkgate_delay_attr))
pr_err("%s: Failed to create clkgate_delay sysfs entry\n",
- mmc_hostname(host));
+ mmc_hostname(host));
}
#else
#endif
-void mmc_retune_enable(struct mmc_host *host)
-{
- host->can_retune = 1;
-}
-
-void mmc_retune_disable(struct mmc_host *host)
-{
- host->can_retune = 0;
- host->need_retune = 0;
-}
-
-void mmc_retune_hold(struct mmc_host *host)
-{
- if (!host->hold_retune)
- host->retune_now = 1;
- host->hold_retune += 1;
-}
-EXPORT_SYMBOL(mmc_retune_hold);
-
-void mmc_retune_release(struct mmc_host *host)
-{
- if (host->hold_retune)
- host->hold_retune -= 1;
- else
- WARN_ON(1);
-}
-EXPORT_SYMBOL(mmc_retune_release);
-
-int mmc_retune(struct mmc_host *host)
-{
- int err;
-
- if (!host->need_retune || host->doing_retune || !host->card)
- return 0;
-
- host->need_retune = 0;
-
- host->doing_retune = 1;
-
- err = mmc_execute_tuning(host->card);
-
- host->doing_retune = 0;
-
- return err;
-}
-EXPORT_SYMBOL(mmc_retune);
-
/**
* mmc_of_parse() - parse host's device-tree node
* @host: host whose node should be parsed.
* parse the properties and set respective generic mmc-host flags and
* parameters.
*/
-int mmc_of_parse(struct mmc_host *host)
+void mmc_of_parse(struct mmc_host *host)
{
struct device_node *np;
u32 bus_width;
int len, ret, gpio;
if (!host->parent || !host->parent->of_node)
- return 0;
+ return;
np = host->parent->of_node;
default:
dev_err(host->parent,
"Invalid \"bus-width\" value %ud!\n", bus_width);
- return -EINVAL;
}
/* f_max is obtained from the optional "max-frequency" property */
host->caps |= MMC_CAP_NEEDS_POLL;
gpio = of_get_named_gpio_flags(np, "cd-gpios", 0, &flags);
- if (gpio == -EPROBE_DEFER)
- return gpio;
if (gpio_is_valid(gpio)) {
if (!(flags & OF_GPIO_ACTIVE_LOW))
gpio_inv_cd = true;
- ret = mmc_gpio_request_cd(host, gpio, 0);
- if (ret < 0) {
+ ret = mmc_gpio_request_cd(host, gpio);
+ if (ret < 0)
dev_err(host->parent,
"Failed to request CD GPIO #%d: %d!\n",
gpio, ret);
- return ret;
- } else {
+ else
dev_info(host->parent, "Got CD GPIO #%d.\n",
gpio);
- }
}
if (explicit_inv_cd ^ gpio_inv_cd)
explicit_inv_wp = of_property_read_bool(np, "wp-inverted");
gpio = of_get_named_gpio_flags(np, "wp-gpios", 0, &flags);
- if (gpio == -EPROBE_DEFER) {
- ret = -EPROBE_DEFER;
- goto out;
- }
if (gpio_is_valid(gpio)) {
if (!(flags & OF_GPIO_ACTIVE_LOW))
gpio_inv_wp = true;
ret = mmc_gpio_request_ro(host, gpio);
- if (ret < 0) {
+ if (ret < 0)
dev_err(host->parent,
"Failed to request WP GPIO: %d!\n", ret);
- goto out;
- } else {
- dev_info(host->parent, "Got WP GPIO #%d.\n",
- gpio);
- }
}
if (explicit_inv_wp ^ gpio_inv_wp)
host->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
host->caps |= MMC_CAP_POWER_OFF_CARD;
if (of_find_property(np, "cap-sdio-irq", &len))
host->caps |= MMC_CAP_SDIO_IRQ;
- if (of_find_property(np, "full-pwr-cycle", &len))
- host->caps2 |= MMC_CAP2_FULL_PWR_CYCLE;
if (of_find_property(np, "keep-power-in-suspend", &len))
host->pm_caps |= MMC_PM_KEEP_POWER;
if (of_find_property(np, "enable-sdio-wakeup", &len))
host->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
-
- return 0;
-
-out:
- mmc_gpio_free_cd(host);
- return ret;
}
+
EXPORT_SYMBOL(mmc_of_parse);
/**
int err;
struct mmc_host *host;
- host = kzalloc(sizeof(*host) + extra, GFP_KERNEL);
+ host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL);
if (!host)
return NULL;
spin_lock_init(&host->lock);
init_waitqueue_head(&host->wq);
wake_lock_init(&host->detect_wake_lock, WAKE_LOCK_SUSPEND,
- kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
+ kasprintf(GFP_KERNEL, "%s_detect", mmc_hostname(host)));
INIT_DELAYED_WORK(&host->detect, mmc_rescan);
#ifdef CONFIG_PM
host->pm_notify.notifier_call = mmc_pm_notify;
kfree(host);
return NULL;
}
+
EXPORT_SYMBOL(mmc_alloc_host);
/**
* prepared to start servicing requests before this function
* completes.
*/
-static struct mmc_host *primary_sdio_host;
int mmc_add_host(struct mmc_host *host)
{
int err;
if (!(host->pm_flags & MMC_PM_IGNORE_PM_NOTIFY))
register_pm_notifier(&host->pm_notify);
- if (host->restrict_caps & RESTRICT_CARD_TYPE_SDIO)
- primary_sdio_host = host;
-
return 0;
}
-EXPORT_SYMBOL(mmc_add_host);
+EXPORT_SYMBOL(mmc_add_host);
/**
* mmc_remove_host - remove host hardware
mmc_host_clk_exit(host);
}
+
EXPORT_SYMBOL(mmc_remove_host);
/**
put_device(&host->class_dev);
}
-EXPORT_SYMBOL(mmc_free_host);
-
-/**
- * mmc_host_rescan - triger software rescan flow
- * @host: mmc host
- *
- * rescan slot attach in the assigned host.
- * If @host is NULL, default rescan primary_sdio_host
- * saved by mmc_add_host().
- * OR, rescan host from argument.
- *
- */
-int mmc_host_rescan(struct mmc_host *host, int val, int is_cap_sdio_irq)
-{
- if (NULL != primary_sdio_host) {
- if (!host)
- host = primary_sdio_host;
- else
- pr_info("%s: mmc_host_rescan pass in host from argument!\n",
- mmc_hostname(host));
- } else {
- pr_err("sdio: host isn't initialization successfully.\n");
- return -ENOMEDIUM;
- }
-
- pr_info("%s:mmc host rescan start!\n", mmc_hostname(host));
-
- /* 0: oob 1:cap-sdio-irq */
- if (is_cap_sdio_irq == 1) {
- host->caps |= MMC_CAP_SDIO_IRQ;
- } else if (is_cap_sdio_irq == 0) {
- host->caps &= ~MMC_CAP_SDIO_IRQ;
- } else {
- dev_err(&host->class_dev, "sdio: host doesn't identify oob or sdio_irq mode!\n");
- return -ENOMEDIUM;
- }
-
- if (!(host->caps & MMC_CAP_NONREMOVABLE) && host->ops->set_sdio_status)
- host->ops->set_sdio_status(host, val);
-
- return 0;
-}
-EXPORT_SYMBOL(mmc_host_rescan);
+EXPORT_SYMBOL(mmc_free_host);
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/stat.h>
-#include <linux/pm_runtime.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
}
}
- /*
- * The EXT_CSD format is meant to be forward compatible. As long
- * as CSD_STRUCTURE does not change, all values for EXT_CSD_REV
- * are authorized, see JEDEC JESD84-B50 section B.8.
- */
card->ext_csd.rev = ext_csd[EXT_CSD_REV];
+ if (card->ext_csd.rev > 6) {
+ pr_err("%s: unrecognised EXT_CSD revision %d\n",
+ mmc_hostname(card->host), card->ext_csd.rev);
+ err = -EINVAL;
+ goto out;
+ }
card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0];
card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1];
}
if (card->ext_csd.rev >= 5) {
- /* Adjust production date as per JEDEC JESD84-B451 */
- if (card->cid.year < 2010)
- card->cid.year += 16;
-
/* check whether the eMMC card supports BKOPS */
if (ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1) {
card->ext_csd.bkops = 1;
* RPMB regions are defined in multiples of 128K.
*/
card->ext_csd.raw_rpmb_size_mult = ext_csd[EXT_CSD_RPMB_MULT];
- #if 0 //noted by xbw,2014-03-11
if (ext_csd[EXT_CSD_RPMB_MULT] && mmc_host_cmd23(card->host)) {
mmc_part_add(card, ext_csd[EXT_CSD_RPMB_MULT] << 17,
EXT_CSD_PART_CONFIG_ACC_RPMB,
"rpmb", 0, false,
MMC_BLK_DATA_AREA_RPMB);
}
- #endif
}
card->ext_csd.raw_erased_mem_count = ext_csd[EXT_CSD_ERASED_MEM_CONT];
* mmc_switch command.
*/
static int mmc_select_powerclass(struct mmc_card *card,
- unsigned int bus_width)
+ unsigned int bus_width, u8 *ext_csd)
{
int err = 0;
- unsigned int pwrclass_val = 0;
+ unsigned int pwrclass_val;
+ unsigned int index = 0;
struct mmc_host *host;
BUG_ON(!card);
host = card->host;
BUG_ON(!host);
+ if (ext_csd == NULL)
+ return 0;
+
/* Power class selection is supported for versions >= 4.0 */
if (card->csd.mmca_vsn < CSD_SPEC_VER_4)
return 0;
switch (1 << host->ios.vdd) {
case MMC_VDD_165_195:
if (host->ios.clock <= 26000000)
- pwrclass_val = card->ext_csd.raw_pwr_cl_26_195;
+ index = EXT_CSD_PWR_CL_26_195;
else if (host->ios.clock <= 52000000)
- pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
- card->ext_csd.raw_pwr_cl_52_195 :
- card->ext_csd.raw_pwr_cl_ddr_52_195;
+ index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
+ EXT_CSD_PWR_CL_52_195 :
+ EXT_CSD_PWR_CL_DDR_52_195;
else if (host->ios.clock <= 200000000)
- pwrclass_val = card->ext_csd.raw_pwr_cl_200_195;
+ index = EXT_CSD_PWR_CL_200_195;
break;
case MMC_VDD_27_28:
case MMC_VDD_28_29:
case MMC_VDD_34_35:
case MMC_VDD_35_36:
if (host->ios.clock <= 26000000)
- pwrclass_val = card->ext_csd.raw_pwr_cl_26_360;
+ index = EXT_CSD_PWR_CL_26_360;
else if (host->ios.clock <= 52000000)
- pwrclass_val = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
- card->ext_csd.raw_pwr_cl_52_360 :
- card->ext_csd.raw_pwr_cl_ddr_52_360;
+ index = (bus_width <= EXT_CSD_BUS_WIDTH_8) ?
+ EXT_CSD_PWR_CL_52_360 :
+ EXT_CSD_PWR_CL_DDR_52_360;
else if (host->ios.clock <= 200000000)
- pwrclass_val = card->ext_csd.raw_pwr_cl_200_360;
+ index = EXT_CSD_PWR_CL_200_360;
break;
default:
pr_warning("%s: Voltage range not supported "
return -EINVAL;
}
+ pwrclass_val = ext_csd[index];
+
if (bus_width & (EXT_CSD_BUS_WIDTH_8 | EXT_CSD_DDR_BUS_WIDTH_8))
pwrclass_val = (pwrclass_val & EXT_CSD_PWR_CL_8BIT_MASK) >>
EXT_CSD_PWR_CL_8BIT_SHIFT;
goto err;
}
- card->ocr = ocr;
card->type = MMC_TYPE_MMC;
card->rca = 1;
memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
}
/*
- * Enable power_off_notification byte in the ext_csd register
+ * If the host supports the power_off_notify capability then
+ * set the notification byte in the ext_csd register of device
*/
- if (card->ext_csd.rev >= 6) {
+ if ((host->caps2 & MMC_CAP2_POWEROFF_NOTIFY) &&
+ (card->ext_csd.rev >= 6)) {
err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_POWER_OFF_NOTIFICATION,
EXT_CSD_POWER_ON,
*/
if (mmc_card_highspeed(card)) {
if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_8V)
- && (host->caps & MMC_CAP_1_8V_DDR))
+ && ((host->caps & (MMC_CAP_1_8V_DDR |
+ MMC_CAP_UHS_DDR50))
+ == (MMC_CAP_1_8V_DDR | MMC_CAP_UHS_DDR50)))
ddr = MMC_1_8V_DDR_MODE;
else if ((card->ext_csd.card_type & EXT_CSD_CARD_TYPE_DDR_1_2V)
- && (host->caps & MMC_CAP_1_2V_DDR))
+ && ((host->caps & (MMC_CAP_1_2V_DDR |
+ MMC_CAP_UHS_DDR50))
+ == (MMC_CAP_1_2V_DDR | MMC_CAP_UHS_DDR50)))
ddr = MMC_1_2V_DDR_MODE;
}
* 3. set the clock to > 52Mhz <=200MHz and
* 4. execute tuning for HS200
*/
- /*
if ((host->caps2 & MMC_CAP2_HS200) &&
card->host->ops->execute_tuning) {
mmc_host_clk_hold(card->host);
mmc_hostname(card->host));
goto err;
}
- */
- if (host->caps2 & MMC_CAP2_HS200)
- mmc_execute_tuning(card);
ext_csd_bits = (bus_width == MMC_BUS_WIDTH_8) ?
EXT_CSD_BUS_WIDTH_8 : EXT_CSD_BUS_WIDTH_4;
- err = mmc_select_powerclass(card, ext_csd_bits);
+ err = mmc_select_powerclass(card, ext_csd_bits, ext_csd);
if (err)
pr_warning("%s: power class selection to bus width %d"
" failed\n", mmc_hostname(card->host),
bus_width = bus_widths[idx];
if (bus_width == MMC_BUS_WIDTH_1)
ddr = 0; /* no DDR for 1-bit width */
- err = mmc_select_powerclass(card, ext_csd_bits[idx][0]);
+ err = mmc_select_powerclass(card, ext_csd_bits[idx][0],
+ ext_csd);
if (err)
pr_warning("%s: power class selection to "
"bus width %d failed\n",
}
if (!err && ddr) {
- err = mmc_select_powerclass(card, ext_csd_bits[idx][1]);
+ err = mmc_select_powerclass(card, ext_csd_bits[idx][1],
+ ext_csd);
if (err)
pr_warning("%s: power class selection to "
"bus width %d ddr %d failed\n",
return err;
}
-static int mmc_can_sleep(struct mmc_card *card)
-{
- return (card && card->ext_csd.rev >= 3);
-}
-
-static int mmc_sleep(struct mmc_host *host)
-{
- struct mmc_command cmd = {0};
- struct mmc_card *card = host->card;
- int err;
-
- if (host->caps2 & MMC_CAP2_NO_SLEEP_CMD)
- return 0;
-
- err = mmc_deselect_cards(host);
- if (err)
- return err;
-
- cmd.opcode = MMC_SLEEP_AWAKE;
- cmd.arg = card->rca << 16;
- cmd.arg |= 1 << 15;
-
- cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
- err = mmc_wait_for_cmd(host, &cmd, 0);
- if (err)
- return err;
-
- /*
- * If the host does not wait while the card signals busy, then we will
- * will have to wait the sleep/awake timeout. Note, we cannot use the
- * SEND_STATUS command to poll the status because that command (and most
- * others) is invalid while the card sleeps.
- */
- if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
- mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
-
- return err;
-}
-
static int mmc_can_poweroff_notify(const struct mmc_card *card)
{
return card &&
if (notify_type == EXT_CSD_POWER_OFF_LONG)
timeout = card->ext_csd.power_off_longtime;
- err = __mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
- EXT_CSD_POWER_OFF_NOTIFICATION,
- notify_type, timeout, true, false);
+ err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_POWER_OFF_NOTIFICATION,
+ notify_type, timeout);
if (err)
pr_err("%s: Power Off Notification timed out, %u\n",
mmc_hostname(card->host), timeout);
BUG_ON(!host);
BUG_ON(!host->card);
- mmc_get_card(host->card);
+ mmc_claim_host(host);
/*
* Just check if our card has been removed.
*/
err = _mmc_detect_card_removed(host);
- mmc_put_card(host->card);
+ mmc_release_host(host);
if (err) {
mmc_remove(host);
}
}
-static int _mmc_suspend(struct mmc_host *host, bool is_suspend)
+/*
+ * Suspend callback from host.
+ */
+static int mmc_suspend(struct mmc_host *host)
{
int err = 0;
- unsigned int notify_type = is_suspend ? EXT_CSD_POWER_OFF_SHORT :
- EXT_CSD_POWER_OFF_LONG;
BUG_ON(!host);
BUG_ON(!host->card);
mmc_claim_host(host);
- if (mmc_card_suspended(host->card))
- goto out;
-
- if (mmc_card_doing_bkops(host->card)) {
- err = mmc_stop_bkops(host->card);
- if (err)
- goto out;
- }
-
err = mmc_cache_ctrl(host, 0);
if (err)
goto out;
- if (mmc_can_poweroff_notify(host->card) &&
- ((host->caps2 & MMC_CAP2_FULL_PWR_CYCLE) || !is_suspend))
- err = mmc_poweroff_notify(host->card, notify_type);
- else if (mmc_can_sleep(host->card))
- err = mmc_sleep(host);
+ if (mmc_can_poweroff_notify(host->card))
+ err = mmc_poweroff_notify(host->card, EXT_CSD_POWER_OFF_SHORT);
+ else if (mmc_card_can_sleep(host))
+ err = mmc_card_sleep(host);
else if (!mmc_host_is_spi(host))
err = mmc_deselect_cards(host);
host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
- if (!err) {
- mmc_power_off(host);
- mmc_card_set_suspended(host->card);
- }
out:
mmc_release_host(host);
return err;
}
-/*
- * Suspend callback
- */
-static int mmc_suspend(struct mmc_host *host)
-{
- int err;
-
- err = _mmc_suspend(host, true);
- if (!err) {
- pm_runtime_disable(&host->card->dev);
- pm_runtime_set_suspended(&host->card->dev);
- }
-
- return err;
-}
-
/*
* Resume callback from host.
*
* This function tries to determine if the same card is still present
* and, if so, restore all state to it.
*/
-static int _mmc_resume(struct mmc_host *host)
+static int mmc_resume(struct mmc_host *host)
{
- int err = 0;
+ int err;
BUG_ON(!host);
BUG_ON(!host->card);
mmc_claim_host(host);
-
- if (!mmc_card_suspended(host->card))
- goto out;
-
- mmc_power_up(host, host->card->ocr);
- err = mmc_init_card(host, host->card->ocr, host->card);
- mmc_card_clr_suspended(host->card);
-
-out:
+ err = mmc_init_card(host, host->ocr, host->card);
mmc_release_host(host);
- return err;
-}
-
-
-/*
- * Callback for resume.
- */
-static int mmc_resume(struct mmc_host *host)
-{
- int err = 0;
- if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
- err = _mmc_resume(host);
- pm_runtime_set_active(&host->card->dev);
- pm_runtime_mark_last_busy(&host->card->dev);
- }
- pm_runtime_enable(&host->card->dev);
return err;
}
-/*
- * Shutdown callback
- */
-static int mmc_shutdown(struct mmc_host *host)
-{
- int err = 0;
- /*
- * In a specific case for poweroff notify, we need to resume the card
- * before we can shutdown it properly.
- */
- if (mmc_can_poweroff_notify(host->card) &&
- !(host->caps2 & MMC_CAP2_FULL_PWR_CYCLE))
- err = mmc_resume(host);
-
- if (!err)
- err = _mmc_suspend(host, false);
-
- return err;
-}
-
-/*
- * Callback for runtime_suspend.
- */
-static int mmc_runtime_suspend(struct mmc_host *host)
+static int mmc_power_restore(struct mmc_host *host)
{
- int err;
-
- if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
- return 0;
+ int ret;
- err = _mmc_suspend(host, true);
- if (err)
- pr_err("%s: error %d doing aggessive suspend\n",
- mmc_hostname(host), err);
+ host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
+ mmc_claim_host(host);
+ ret = mmc_init_card(host, host->ocr, host->card);
+ mmc_release_host(host);
- return err;
+ return ret;
}
-/*
- * Callback for runtime_resume.
- */
-static int mmc_runtime_resume(struct mmc_host *host)
+static int mmc_sleep(struct mmc_host *host)
{
- int err;
-
- if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME)))
- return 0;
+ struct mmc_card *card = host->card;
+ int err = -ENOSYS;
- err = _mmc_resume(host);
- if (err)
- pr_err("%s: error %d doing aggessive resume\n",
- mmc_hostname(host), err);
+ if (card && card->ext_csd.rev >= 3) {
+ err = mmc_card_sleepawake(host, 1);
+ if (err < 0)
+ pr_debug("%s: Error %d while putting card into sleep",
+ mmc_hostname(host), err);
+ }
- return 0;
+ return err;
}
-static int mmc_power_restore(struct mmc_host *host)
+static int mmc_awake(struct mmc_host *host)
{
- int ret;
+ struct mmc_card *card = host->card;
+ int err = -ENOSYS;
- host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200);
- mmc_claim_host(host);
- ret = mmc_init_card(host, host->card->ocr, host->card);
- mmc_release_host(host);
+ if (card && card->ext_csd.rev >= 3) {
+ err = mmc_card_sleepawake(host, 0);
+ if (err < 0)
+ pr_debug("%s: Error %d while awaking sleeping card",
+ mmc_hostname(host), err);
+ }
- return ret;
+ return err;
}
static const struct mmc_bus_ops mmc_ops = {
+ .awake = mmc_awake,
+ .sleep = mmc_sleep,
.remove = mmc_remove,
.detect = mmc_detect,
.suspend = NULL,
.resume = NULL,
.power_restore = mmc_power_restore,
.alive = mmc_alive,
- .shutdown = mmc_shutdown,
};
static const struct mmc_bus_ops mmc_ops_unsafe = {
+ .awake = mmc_awake,
+ .sleep = mmc_sleep,
.remove = mmc_remove,
.detect = mmc_detect,
.suspend = mmc_suspend,
.resume = mmc_resume,
- .runtime_suspend = mmc_runtime_suspend,
- .runtime_resume = mmc_runtime_resume,
.power_restore = mmc_power_restore,
.alive = mmc_alive,
- .shutdown = mmc_shutdown,
};
static void mmc_attach_bus_ops(struct mmc_host *host)
int mmc_attach_mmc(struct mmc_host *host)
{
int err;
- u32 ocr, rocr;
+ u32 ocr;
BUG_ON(!host);
WARN_ON(!host->claimed);
goto err;
}
- rocr = mmc_select_voltage(host, ocr);
+ /*
+ * Sanity check the voltages that the card claims to
+ * support.
+ */
+ if (ocr & 0x7F) {
+ pr_warning("%s: card claims to support voltages "
+ "below the defined range. These will be ignored.\n",
+ mmc_hostname(host));
+ ocr &= ~0x7F;
+ }
+
+ host->ocr = mmc_select_voltage(host, ocr);
/*
* Can we support the voltage of the card?
*/
- if (!rocr) {
+ if (!host->ocr) {
err = -EINVAL;
goto err;
}
/*
* Detect and init the card.
*/
- err = mmc_init_card(host, rocr, NULL);
+ err = mmc_init_card(host, host->ocr, NULL);
if (err)
goto err;
#define MMC_OPS_TIMEOUT_MS (10 * 60 * 1000) /* 10 minute timeout */
-static inline int __mmc_send_status(struct mmc_card *card, u32 *status,
- bool ignore_crc)
-{
- int err;
- struct mmc_command cmd = {0};
-
- BUG_ON(!card);
- BUG_ON(!card->host);
-
- cmd.opcode = MMC_SEND_STATUS;
- if (!mmc_host_is_spi(card->host))
- cmd.arg = card->rca << 16;
- cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
- if (ignore_crc)
- cmd.flags &= ~MMC_RSP_CRC;
-
- err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
- if (err)
- return err;
-
- /* NOTE: callers are required to understand the difference
- * between "native" and SPI format status words!
- */
- if (status)
- *status = cmd.resp[0];
-
- return 0;
-}
-
-int mmc_send_status(struct mmc_card *card, u32 *status)
-{
- return __mmc_send_status(card, status, false);
-}
-
static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
{
int err;
return _mmc_select_card(host, NULL);
}
+int mmc_card_sleepawake(struct mmc_host *host, int sleep)
+{
+ struct mmc_command cmd = {0};
+ struct mmc_card *card = host->card;
+ int err;
+
+ if (sleep)
+ mmc_deselect_cards(host);
+
+ cmd.opcode = MMC_SLEEP_AWAKE;
+ cmd.arg = card->rca << 16;
+ if (sleep)
+ cmd.arg |= 1 << 15;
+
+ cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
+ err = mmc_wait_for_cmd(host, &cmd, 0);
+ if (err)
+ return err;
+
+ /*
+ * If the host does not wait while the card signals busy, then we will
+ * will have to wait the sleep/awake timeout. Note, we cannot use the
+ * SEND_STATUS command to poll the status because that command (and most
+ * others) is invalid while the card sleeps.
+ */
+ if (!(host->caps & MMC_CAP_WAIT_WHILE_BUSY))
+ mmc_delay(DIV_ROUND_UP(card->ext_csd.sa_timeout, 10000));
+
+ if (!sleep)
+ err = mmc_select_card(card);
+
+ return err;
+}
+
int mmc_go_idle(struct mmc_host *host)
{
int err;
return err;
}
-int mmc_switch_status_error(struct mmc_host *host, u32 status)
-{
- if (mmc_host_is_spi(host)) {
- if (status & R1_SPI_ILLEGAL_COMMAND)
- return -EBADMSG;
- } else {
- if (status & 0xFDFFA000)
- pr_warn("%s: unexpected status %#x after switch\n",
- mmc_hostname(host), status);
- if (status & R1_SWITCH_ERROR)
- return -EBADMSG;
- }
- return 0;
-}
-
/**
* __mmc_switch - modify EXT_CSD register
* @card: the MMC card associated with the data transfer
* @timeout_ms: timeout (ms) for operation performed by register write,
* timeout of zero implies maximum possible timeout
* @use_busy_signal: use the busy signal as response type
- * @send_status: send status cmd to poll for busy
*
* Modifies the EXT_CSD register for selected card.
*/
int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
- unsigned int timeout_ms, bool use_busy_signal, bool send_status)
+ unsigned int timeout_ms, bool use_busy_signal)
{
- struct mmc_host *host = card->host;
int err;
struct mmc_command cmd = {0};
unsigned long timeout;
- u32 status = 0;
- bool ignore_crc = false;
+ u32 status;
BUG_ON(!card);
BUG_ON(!card->host);
- mmc_retune_hold(host);
-
cmd.opcode = MMC_SWITCH;
cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
(index << 16) |
cmd.cmd_timeout_ms = timeout_ms;
- if (index == EXT_CSD_SANITIZE_START)
- cmd.sanitize_busy = true;
err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
if (err)
- goto out;
+ return err;
/* No need to check card status in case of unblocking command */
if (!use_busy_signal)
- goto out;
-
- /*
- * Must check status to be sure of no errors
- * If CMD13 is to check the busy completion of the timing change,
- * disable the check of CRC error.
- */
- if (index == EXT_CSD_HS_TIMING &&
- !(card->host->caps & MMC_CAP_WAIT_WHILE_BUSY))
- ignore_crc = true;
+ return 0;
+ /* Must check status to be sure of no errors */
timeout = jiffies + msecs_to_jiffies(MMC_OPS_TIMEOUT_MS);
do {
- if (send_status) {
- err = __mmc_send_status(card, &status, ignore_crc);
- if (err)
- goto out;
- }
+ err = mmc_send_status(card, &status);
+ if (err)
+ return err;
if (card->host->caps & MMC_CAP_WAIT_WHILE_BUSY)
break;
if (mmc_host_is_spi(card->host))
break;
- /*
- * We are not allowed to issue a status command and the host
- * does'nt support MMC_CAP_WAIT_WHILE_BUSY, then we can only
- * rely on waiting for the stated timeout to be sufficient.
- */
- if (!send_status) {
- mmc_delay(timeout_ms);
- goto out;
- }
-
/* Timeout if the device never leaves the program state. */
if (time_after(jiffies, timeout)) {
pr_err("%s: Card stuck in programming state! %s\n",
mmc_hostname(card->host), __func__);
- err = -ETIMEDOUT;
- goto out;
+ return -ETIMEDOUT;
}
} while (R1_CURRENT_STATE(status) == R1_STATE_PRG);
- err = mmc_switch_status_error(host, status);
-out:
- mmc_retune_release(host);
- return err;
+ if (mmc_host_is_spi(card->host)) {
+ if (status & R1_SPI_ILLEGAL_COMMAND)
+ return -EBADMSG;
+ } else {
+ if (status & 0xFDFFA000)
+ pr_warning("%s: unexpected status %#x after "
+ "switch", mmc_hostname(card->host), status);
+ if (status & R1_SWITCH_ERROR)
+ return -EBADMSG;
+ }
+
+ return 0;
}
EXPORT_SYMBOL_GPL(__mmc_switch);
int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
unsigned int timeout_ms)
{
- return __mmc_switch(card, set, index, value, timeout_ms, true, true);
+ return __mmc_switch(card, set, index, value, timeout_ms, true);
}
EXPORT_SYMBOL_GPL(mmc_switch);
+int mmc_send_status(struct mmc_card *card, u32 *status)
+{
+ int err;
+ struct mmc_command cmd = {0};
+
+ BUG_ON(!card);
+ BUG_ON(!card->host);
+
+ cmd.opcode = MMC_SEND_STATUS;
+ if (!mmc_host_is_spi(card->host))
+ cmd.arg = card->rca << 16;
+ cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
+
+ err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
+ if (err)
+ return err;
+
+ /* NOTE: callers are required to understand the difference
+ * between "native" and SPI format status words!
+ */
+ if (status)
+ *status = cmd.resp[0];
+
+ return 0;
+}
+
static int
mmc_send_bus_test(struct mmc_card *card, struct mmc_host *host, u8 opcode,
u8 len)
data.sg = &sg;
data.sg_len = 1;
- mmc_set_data_timeout(&data, card);
sg_init_one(&sg, data_buf, len);
mmc_wait_for_req(host, &mrq);
err = 0;
int mmc_send_cid(struct mmc_host *host, u32 *cid);
int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp);
int mmc_spi_set_crc(struct mmc_host *host, int use_crc);
+int mmc_card_sleepawake(struct mmc_host *host, int sleep);
int mmc_bus_test(struct mmc_card *card, u8 bus_width);
int mmc_send_hpi_cmd(struct mmc_card *card, u32 *status);
-int mmc_switch_status_error(struct mmc_host *host, u32 status);
+
#endif
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/mmc/card.h>
-#include <linux/mmc/sdio_ids.h>
#ifndef SDIO_VENDOR_ID_TI
#define SDIO_VENDOR_ID_TI 0x0097
#define SDIO_DEVICE_ID_STE_CW1200 0x2280
#endif
-#ifndef SDIO_DEVICE_ID_MARVELL_8797_F0
-#define SDIO_DEVICE_ID_MARVELL_8797_F0 0x9128
-#endif
-
/*
* This hook just adds a quirk for all sdio devices
*/
SDIO_FIXUP(SDIO_VENDOR_ID_STE, SDIO_DEVICE_ID_STE_CW1200,
add_quirk, MMC_QUIRK_BROKEN_BYTE_MODE_512),
- SDIO_FIXUP(SDIO_VENDOR_ID_MARVELL, SDIO_DEVICE_ID_MARVELL_8797_F0,
- add_quirk, MMC_QUIRK_BROKEN_IRQ_POLLING),
-
END_FIXUP
};
*/
#include <linux/err.h>
-#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/stat.h>
-#include <linux/pm_runtime.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
35, 40, 45, 50, 55, 60, 70, 80,
};
-static const unsigned int sd_au_size[] = {
- 0, SZ_16K / 512, SZ_32K / 512, SZ_64K / 512,
- SZ_128K / 512, SZ_256K / 512, SZ_512K / 512, SZ_1M / 512,
- SZ_2M / 512, SZ_4M / 512, SZ_8M / 512, (SZ_8M + SZ_4M) / 512,
- SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512,
-};
-
#define UNSTUFF_BITS(resp,start,size) \
({ \
const int __size = size; \
* bitfield positions accordingly.
*/
au = UNSTUFF_BITS(ssr, 428 - 384, 4);
- if (au) {
- if (au <= 9 || card->scr.sda_spec3) {
- card->ssr.au = sd_au_size[au];
- es = UNSTUFF_BITS(ssr, 408 - 384, 16);
- et = UNSTUFF_BITS(ssr, 402 - 384, 6);
- if (es && et) {
- eo = UNSTUFF_BITS(ssr, 400 - 384, 2);
- card->ssr.erase_timeout = (et * 1000) / es;
- card->ssr.erase_offset = eo * 1000;
- }
- } else {
- pr_warning("%s: SD Status: Invalid Allocation Unit size.\n",
- mmc_hostname(card->host));
+ if (au > 0 && au <= 9) {
+ card->ssr.au = 1 << (au + 4);
+ es = UNSTUFF_BITS(ssr, 408 - 384, 16);
+ et = UNSTUFF_BITS(ssr, 402 - 384, 6);
+ eo = UNSTUFF_BITS(ssr, 400 - 384, 2);
+ if (es && et) {
+ card->ssr.erase_timeout = (et * 1000) / es;
+ card->ssr.erase_offset = eo * 1000;
}
+ } else {
+ pr_warning("%s: SD Status: Invalid Allocation Unit "
+ "size.\n", mmc_hostname(card->host));
}
out:
kfree(ssr);
if (err)
goto out;
- /*
- * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
- * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
- */
- if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning &&
- (card->sd_bus_speed == UHS_SDR50_BUS_SPEED ||
- card->sd_bus_speed == UHS_SDR104_BUS_SPEED)) {
+ /* SPI mode doesn't define CMD19 */
+ if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) {
mmc_host_clk_hold(card->host);
err = card->host->ops->execute_tuning(card->host,
MMC_SEND_TUNING_BLOCK);
int err;
u32 max_current;
int retries = 10;
- u32 pocr = ocr;
try_again:
if (!retries) {
*/
if (!mmc_host_is_spi(host) && rocr &&
((*rocr & 0x41000000) == 0x41000000)) {
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
- pocr);
+ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
if (err == -EAGAIN) {
retries--;
goto try_again;
if (IS_ERR(card))
return PTR_ERR(card);
- card->ocr = ocr;
card->type = MMC_TYPE_SD;
memcpy(card->raw_cid, cid, sizeof(card->raw_cid));
}
if (!mmc_host_is_spi(host)) {
err = mmc_send_relative_addr(host, &card->rca);
if (err)
- goto free_card;
+ return err;
}
if (!oldcard) {
err = mmc_sd_get_csd(host, card);
if (err)
- goto free_card;
+ return err;
mmc_decode_cid(card);
}
if (!mmc_host_is_spi(host)) {
err = mmc_select_card(card);
if (err)
- goto free_card;
+ return err;
}
err = mmc_sd_setup_card(host, card, oldcard != NULL);
BUG_ON(!host);
BUG_ON(!host->card);
- mmc_get_card(host->card);
+ mmc_claim_host(host);
/*
* Just check if our card has been removed.
err = _mmc_detect_card_removed(host);
#endif
- mmc_put_card(host->card);
+ mmc_release_host(host);
if (err) {
mmc_sd_remove(host);
}
/*
- * Callback for suspend
+ * Suspend callback from host.
*/
static int mmc_sd_suspend(struct mmc_host *host)
{
BUG_ON(!host->card);
mmc_claim_host(host);
-
- if (mmc_card_suspended(host->card))
- goto out;
-
if (!mmc_host_is_spi(host))
err = mmc_deselect_cards(host);
host->card->state &= ~MMC_STATE_HIGHSPEED;
- if (!err) {
- mmc_power_off(host);
- mmc_card_set_suspended(host->card);
- }
-
-out:
mmc_release_host(host);
+
return err;
}
/*
+ * Resume callback from host.
+ *
* This function tries to determine if the same card is still present
* and, if so, restore all state to it.
*/
-static int _mmc_sd_resume(struct mmc_host *host)
+static int mmc_sd_resume(struct mmc_host *host)
{
- int err = 0;
+ int err;
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+ int retries;
+#endif
BUG_ON(!host);
BUG_ON(!host->card);
mmc_claim_host(host);
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+ retries = 5;
+ while (retries) {
+ err = mmc_sd_init_card(host, host->ocr, host->card);
- if (!mmc_card_suspended(host->card))
- goto out;
-
- mmc_power_up(host, host->card->ocr);
- err = mmc_sd_init_card(host, host->card->ocr, host->card);
- mmc_card_clr_suspended(host->card);
-
-out:
- mmc_release_host(host);
- return err;
-}
-
-/*
- * Callback for resume
- */
-static int mmc_sd_resume(struct mmc_host *host)
-{
- int err = 0;
-
- if (!(host->caps & MMC_CAP_RUNTIME_RESUME)) {
- err = _mmc_sd_resume(host);
- pm_runtime_set_active(&host->card->dev);
- pm_runtime_mark_last_busy(&host->card->dev);
+ if (err) {
+ printk(KERN_ERR "%s: Re-init card rc = %d (retries = %d)\n",
+ mmc_hostname(host), err, retries);
+ mdelay(5);
+ retries--;
+ continue;
+ }
+ break;
}
- pm_runtime_enable(&host->card->dev);
-
- return err;
-}
-
-/*
- * Callback for runtime_suspend.
- */
-static int mmc_sd_runtime_suspend(struct mmc_host *host)
-{
- int err;
-
- if (!(host->caps & MMC_CAP_AGGRESSIVE_PM))
- return 0;
-
- err = mmc_sd_suspend(host);
- if (err)
- pr_err("%s: error %d doing aggessive suspend\n",
- mmc_hostname(host), err);
+#else
+ err = mmc_sd_init_card(host, host->ocr, host->card);
+#endif
+ mmc_release_host(host);
return err;
}
-/*
- * Callback for runtime_resume.
- */
-static int mmc_sd_runtime_resume(struct mmc_host *host)
-{
- int err;
-
- if (!(host->caps & (MMC_CAP_AGGRESSIVE_PM | MMC_CAP_RUNTIME_RESUME)))
- return 0;
-
- err = _mmc_sd_resume(host);
- if (err)
- pr_err("%s: error %d doing aggessive resume\n",
- mmc_hostname(host), err);
-
- return 0;
-}
-
static int mmc_sd_power_restore(struct mmc_host *host)
{
int ret;
host->card->state &= ~MMC_STATE_HIGHSPEED;
mmc_claim_host(host);
- ret = mmc_sd_init_card(host, host->card->ocr, host->card);
+ ret = mmc_sd_init_card(host, host->ocr, host->card);
mmc_release_host(host);
return ret;
.resume = NULL,
.power_restore = mmc_sd_power_restore,
.alive = mmc_sd_alive,
- .shutdown = mmc_sd_suspend,
};
static const struct mmc_bus_ops mmc_sd_ops_unsafe = {
.remove = mmc_sd_remove,
.detect = mmc_sd_detect,
- .runtime_suspend = mmc_sd_runtime_suspend,
- .runtime_resume = mmc_sd_runtime_resume,
.suspend = mmc_sd_suspend,
.resume = mmc_sd_resume,
.power_restore = mmc_sd_power_restore,
.alive = mmc_sd_alive,
- .shutdown = mmc_sd_suspend,
};
static void mmc_sd_attach_bus_ops(struct mmc_host *host)
int mmc_attach_sd(struct mmc_host *host)
{
int err;
- u32 ocr, rocr;
+ u32 ocr;
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+ int retries;
+#endif
BUG_ON(!host);
WARN_ON(!host->claimed);
goto err;
}
- rocr = mmc_select_voltage(host, ocr);
+ /*
+ * Sanity check the voltages that the card claims to
+ * support.
+ */
+ if (ocr & 0x7F) {
+ pr_warning("%s: card claims to support voltages "
+ "below the defined range. These will be ignored.\n",
+ mmc_hostname(host));
+ ocr &= ~0x7F;
+ }
+
+ if ((ocr & MMC_VDD_165_195) &&
+ !(host->ocr_avail_sd & MMC_VDD_165_195)) {
+ pr_warning("%s: SD card claims to support the "
+ "incompletely defined 'low voltage range'. This "
+ "will be ignored.\n", mmc_hostname(host));
+ ocr &= ~MMC_VDD_165_195;
+ }
+
+ host->ocr = mmc_select_voltage(host, ocr);
/*
* Can we support the voltage(s) of the card(s)?
*/
- if (!rocr) {
+ if (!host->ocr) {
err = -EINVAL;
goto err;
}
/*
* Detect and init the card.
*/
- err = mmc_sd_init_card(host, rocr, NULL);
+#ifdef CONFIG_MMC_PARANOID_SD_INIT
+ retries = 5;
+ while (retries) {
+ err = mmc_sd_init_card(host, host->ocr, NULL);
+ if (err) {
+ retries--;
+ continue;
+ }
+ break;
+ }
+
+ if (!retries) {
+ printk(KERN_ERR "%s: mmc_sd_init_card() failure (err = %d)\n",
+ mmc_hostname(host), err);
+ goto err;
+ }
+#else
+ err = mmc_sd_init_card(host, host->ocr, NULL);
if (err)
goto err;
+#endif
mmc_release_host(host);
err = mmc_add_card(host->card);
if (err)
goto out;
- /*
- * SPI mode doesn't define CMD19 and tuning is only valid for SDR50 and
- * SDR104 mode SD-cards. Note that tuning is mandatory for SDR104.
- */
- if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning &&
- ((card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR50) ||
- (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR104))) {
- mmc_host_clk_hold(card->host);
+ /* Initialize and start re-tuning timer */
+ if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning)
err = card->host->ops->execute_tuning(card->host,
MMC_SEND_TUNING_BLOCK);
- mmc_host_clk_release(card->host);
- }
out:
struct mmc_card *card;
int err;
int retries = 10;
- u32 rocr = 0;
- u32 ocr_card = ocr;
BUG_ON(!host);
WARN_ON(!host->claimed);
- /* to query card if 1.8V signalling is supported */
- if (mmc_host_uhs(host))
- ocr |= R4_18V_PRESENT;
-
try_again:
if (!retries) {
pr_warning("%s: Skipping voltage switch\n",
mmc_hostname(host));
ocr &= ~R4_18V_PRESENT;
+ host->ocr &= ~R4_18V_PRESENT;
}
/*
* Inform the card of the voltage
*/
if (!powered_resume) {
- err = mmc_send_io_op_cond(host, ocr, &rocr);
+ err = mmc_send_io_op_cond(host, host->ocr, &ocr);
if (err)
goto err;
}
goto err;
}
- if ((rocr & R4_MEMORY_PRESENT) &&
- mmc_sd_get_cid(host, ocr & rocr, card->raw_cid, NULL) == 0) {
+ if ((ocr & R4_MEMORY_PRESENT) &&
+ mmc_sd_get_cid(host, host->ocr & ocr, card->raw_cid, NULL) == 0) {
card->type = MMC_TYPE_SD_COMBO;
if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
* systems that claim 1.8v signalling in fact do not support
* it.
*/
-
- /*
- * Fixme: ap6335 should not set S18A=1 if mmc I/F voltage
- * has been 1.8v yet.
- */
- #ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
- #ifdef CONFIG_AP6335
- rocr &= ~R4_18V_PRESENT;
- #endif
- #endif
-
- if (!powered_resume && (rocr & ocr & R4_18V_PRESENT)) {
- err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180,
- ocr);
+ if (!powered_resume && (ocr & R4_18V_PRESENT) && mmc_host_uhs(host)) {
+ err = mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
if (err == -EAGAIN) {
sdio_reset(host);
mmc_go_idle(host);
goto try_again;
} else if (err) {
ocr &= ~R4_18V_PRESENT;
+ host->ocr &= ~R4_18V_PRESENT;
}
err = 0;
} else {
- #ifdef CONFIG_MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
- #ifdef CONFIG_AP6335
- #else
- ocr &= ~R4_18V_PRESENT;
- #endif
- #endif
+ ocr &= ~R4_18V_PRESENT;
+ host->ocr &= ~R4_18V_PRESENT;
}
/*
card = oldcard;
}
- card->ocr = ocr_card;
mmc_fixup_device(card, NULL);
if (card->type == MMC_TYPE_SD_COMBO) {
}
/*
- * SDIO pre_suspend. We need to suspend all functions separately.
+ * SDIO suspend. We need to suspend all functions separately.
* Therefore all registered functions must have drivers with suspend
* and resume methods. Failing that we simply remove the whole card.
*/
-static int mmc_sdio_pre_suspend(struct mmc_host *host)
+static int mmc_sdio_suspend(struct mmc_host *host)
{
int i, err = 0;
if (!pmops || !pmops->suspend || !pmops->resume) {
/* force removal of entire card in that case */
err = -ENOSYS;
- break;
- }
- }
- }
-
- return err;
-}
-
-/*
- * SDIO suspend. Suspend all functions separately.
- */
-static int mmc_sdio_suspend(struct mmc_host *host)
-{
- int i, err = 0;
-
- for (i = 0; i < host->card->sdio_funcs; i++) {
- struct sdio_func *func = host->card->sdio_func[i];
- if (func && sdio_func_present(func) && func->dev.driver) {
- const struct dev_pm_ops *pmops = func->dev.driver->pm;
- err = pmops->suspend(&func->dev);
+ } else
+ err = pmops->suspend(&func->dev);
if (err)
break;
}
mmc_release_host(host);
}
- if (!err && !mmc_card_keep_power(host))
- mmc_power_off(host);
-
return err;
}
/* Basic card reinitialization. */
mmc_claim_host(host);
- /* Restore power if needed */
- if (!mmc_card_keep_power(host)) {
- mmc_power_up(host, host->card->ocr);
- /*
- * Tell runtime PM core we just powered up the card,
- * since it still believes the card is powered off.
- * Note that currently runtime PM is only enabled
- * for SDIO cards that are MMC_CAP_POWER_OFF_CARD
- */
- if (host->caps & MMC_CAP_POWER_OFF_CARD) {
- pm_runtime_disable(&host->card->dev);
- pm_runtime_set_active(&host->card->dev);
- pm_runtime_enable(&host->card->dev);
- }
- }
-
/* No need to reinitialize powered-resumed nonremovable cards */
- // tmp modify for wifi abnormal after suspend (gwl)
- // mmc2: error -110 during resume (card was removed?)
- // dpm_run_callback(): mmc_bus_resume+0x0/0x78 returns -110
- // PM: Device mmc2:0001 failed to resume: error -110
- if (!(host->restrict_caps & RESTRICT_CARD_TYPE_SDIO) &&
- (mmc_card_is_removable(host) || !mmc_card_keep_power(host))) {
+ if (mmc_card_is_removable(host) || !mmc_card_keep_power(host)) {
sdio_reset(host);
mmc_go_idle(host);
- err = mmc_sdio_init_card(host, host->card->ocr, host->card,
+ err = mmc_sdio_init_card(host, host->ocr, host->card,
mmc_card_keep_power(host));
} else if (mmc_card_keep_power(host) && mmc_card_wake_sdio_irq(host)) {
/* We may have switched to 1-bit mode during suspend */
}
}
- host->pm_flags &= ~MMC_PM_KEEP_POWER;
return err;
}
static int mmc_sdio_power_restore(struct mmc_host *host)
{
int ret;
+ u32 ocr;
BUG_ON(!host);
BUG_ON(!host->card);
* for OLPC SD8686 (which expects a [CMD5,5,3,7] init sequence), and
* harmless in other situations.
*
+ * With these steps taken, mmc_select_voltage() is also required to
+ * restore the correct voltage setting of the card.
*/
sdio_reset(host);
mmc_go_idle(host);
mmc_send_if_cond(host, host->ocr_avail);
- ret = mmc_send_io_op_cond(host, 0, NULL);
+ ret = mmc_send_io_op_cond(host, 0, &ocr);
if (ret)
goto out;
- ret = mmc_sdio_init_card(host, host->card->ocr, host->card,
+ if (host->ocr_avail_sdio)
+ host->ocr_avail = host->ocr_avail_sdio;
+
+ host->ocr = mmc_select_voltage(host, ocr & ~0x7F);
+ if (!host->ocr) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (mmc_host_uhs(host))
+ /* to query card if 1.8V signalling is supported */
+ host->ocr |= R4_18V_PRESENT;
+
+ ret = mmc_sdio_init_card(host, host->ocr, host->card,
mmc_card_keep_power(host));
if (!ret && host->sdio_irqs)
mmc_signal_sdio_irq(host);
return ret;
}
-static int mmc_sdio_runtime_suspend(struct mmc_host *host)
-{
- /* No references to the card, cut the power to it. */
- mmc_power_off(host);
- return 0;
-}
-
-static int mmc_sdio_runtime_resume(struct mmc_host *host)
-{
- /* Restore power and re-initialize. */
- mmc_power_up(host, host->card->ocr);
- return mmc_sdio_power_restore(host);
-}
-
static const struct mmc_bus_ops mmc_sdio_ops = {
.remove = mmc_sdio_remove,
.detect = mmc_sdio_detect,
- .pre_suspend = mmc_sdio_pre_suspend,
.suspend = mmc_sdio_suspend,
.resume = mmc_sdio_resume,
- .runtime_suspend = mmc_sdio_runtime_suspend,
- .runtime_resume = mmc_sdio_runtime_resume,
.power_restore = mmc_sdio_power_restore,
.alive = mmc_sdio_alive,
};
int mmc_attach_sdio(struct mmc_host *host)
{
int err, i, funcs;
- u32 ocr, rocr;
+ u32 ocr;
struct mmc_card *card;
BUG_ON(!host);
if (host->ocr_avail_sdio)
host->ocr_avail = host->ocr_avail_sdio;
+ /*
+ * Sanity check the voltages that the card claims to
+ * support.
+ */
+ if (ocr & 0x7F) {
+ pr_warning("%s: card claims to support voltages "
+ "below the defined range. These will be ignored.\n",
+ mmc_hostname(host));
+ ocr &= ~0x7F;
+ }
- rocr = mmc_select_voltage(host, ocr);
+ host->ocr = mmc_select_voltage(host, ocr);
/*
* Can we support the voltage(s) of the card(s)?
*/
- if (!rocr) {
+ if (!host->ocr) {
err = -EINVAL;
goto err;
}
/*
* Detect and init the card.
*/
- err = mmc_sdio_init_card(host, rocr, NULL, 0);
- if (err)
- goto err;
+ if (mmc_host_uhs(host))
+ /* to query card if 1.8V signalling is supported */
+ host->ocr |= R4_18V_PRESENT;
+ err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
+ if (err) {
+ if (err == -EAGAIN) {
+ /*
+ * Retry initialization with S18R set to 0.
+ */
+ host->ocr &= ~R4_18V_PRESENT;
+ err = mmc_sdio_init_card(host, host->ocr, NULL, 0);
+ }
+ if (err)
+ goto err;
+ }
card = host->card;
/*
return err;
}
-
int sdio_reset_comm(struct mmc_card *card)
{
struct mmc_host *host = card->host;
if (err)
goto err;
- host->ocr_avail_sdio = mmc_select_voltage(host, ocr);
- if (!host->ocr_avail_sdio) {
+ host->ocr = mmc_select_voltage(host, ocr);
+ if (!host->ocr) {
err = -EINVAL;
goto err;
}
- err = mmc_sdio_init_card(host, host->ocr_avail_sdio, card, 0);
+ err = mmc_sdio_init_card(host, host->ocr, card, 0);
if (err)
goto err;
return err;
}
EXPORT_SYMBOL(sdio_reset_comm);
-
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
- NULL
+ pm_generic_runtime_idle
)
};
return ret;
}
- if (pending && mmc_card_broken_irq_polling(card) &&
- !(host->caps & MMC_CAP_SDIO_IRQ)) {
- unsigned char dummy;
-
- /* A fake interrupt could be created when we poll SDIO_CCCR_INTx
- * register with a Marvell SD8797 card. A dummy CMD52 read to
- * function 0 register 0xff can avoid this.
- */
- mmc_io_rw_direct(card, 0, 0, 0xff, 0, &dummy);
- }
-
count = 0;
for (i = 1; i <= 7; i++) {
if (pending & (1 << i)) {
* mmc_gpio_request_cd - request a gpio for card-detection
* @host: mmc host
* @gpio: gpio number requested
- * @debounce: debounce time in microseconds
*
* As devm_* managed functions are used in mmc_gpio_request_cd(), client
* drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up,
* switching for card-detection, they are responsible for calling
* mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own.
*
- * If GPIO debouncing is desired, set the debounce parameter to a non-zero
- * value. The caller is responsible for ensuring that the GPIO driver associated
- * with the GPIO supports debouncing, otherwise an error will be returned.
- *
* Returns zero on success, else an error.
*/
-int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,
- unsigned int debounce)
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio)
{
struct mmc_gpio *ctx;
int irq = gpio_to_irq(gpio);
*/
return ret;
- if (debounce) {
- ret = gpio_set_debounce(gpio, debounce);
- if (ret < 0)
- return ret;
- }
-
/*
* Even if gpio_to_irq() returns a valid IRQ number, the platform might
* still prefer to poll, e.g., because that IRQ number is already used
If unsure, say N.
-config MMC_SDHCI_OF_ARASAN
- tristate "SDHCI OF support for the Arasan SDHCI controllers"
- depends on MMC_SDHCI_PLTFM
- depends on OF
- help
- This selects the Arasan Secure Digital Host Controller Interface
- (SDHCI). This hardware is found e.g. in Xilinx' Zynq SoC.
-
- If you have a controller with this interface, say Y or M here.
-
- If unsure, say N.
-
config MMC_SDHCI_OF_ESDHC
tristate "SDHCI OF support for the Freescale eSDHC controller"
depends on MMC_SDHCI_PLTFM
config MMC_DW
tristate "Synopsys DesignWare Memory Card Interface"
- depends on ARM || ARM64
+ depends on ARM
help
This selects support for the Synopsys DesignWare Mobile Storage IP
block, this provides host support for SD and MMC interfaces, in both
If unsure, say Y.
-config MMC_DW_ROCKCHIP
- tristate "Rockchip specific extensions for Synopsys DW Memory Card Interface"
- depends on MMC_DW
- select MMC_DW_PLTFM
- help
- This selects support for Rockchip RK32XX SoC specific extensions to the
- Synopsys DesignWare Memory Card Interface driver. Select this option
- for platforms based on RK32XX SoC's.
-
-config MMC_DW_ROCKCHIP_SWITCH_VOLTAGE
- tristate "Supoort voltage switch for higher level standard"
- depends on MMC_DW_ROCKCHIP
- default n
- help
- This selects support for Rockchip RK32XX Soc specific extensions to voltage
- switch squence
-
-config MMC_DW_SKIP_CACHE_OP
- bool "Skip operations for cache coherency"
- depends on MMC_DW
- help
- This selects support for skipping operations for cache coherency
- to reduce I/O overhead if file system layer do same thing.
-
config MMC_DW_EXYNOS
tristate "Exynos specific extensions for Synopsys DW Memory Card Interface"
depends on MMC_DW
obj-$(CONFIG_MMC_CB710) += cb710-mmc.o
obj-$(CONFIG_MMC_VIA_SDMMC) += via-sdmmc.o
obj-$(CONFIG_SDH_BFIN) += bfin_sdh.o
-
-#obj-$(CONFIG_MMC_DW) += dw_mmc.o
-obj-$(CONFIG_MMC_DW) += rk_sdmmc.o
-
+obj-$(CONFIG_MMC_DW) += dw_mmc.o
obj-$(CONFIG_MMC_DW_PLTFM) += dw_mmc-pltfm.o
-
-# To Specific Extensions for Synopsys DW Multimedia Card Interface in Rockchip Soc. Added by XBW.
-obj-$(CONFIG_MMC_DW_ROCKCHIP) += dw_mmc-rockchip.o rk_sdmmc_dbg.o rk_sdmmc_ops.o
-
obj-$(CONFIG_MMC_DW_EXYNOS) += dw_mmc-exynos.o
obj-$(CONFIG_MMC_DW_PCI) += dw_mmc-pci.o
obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o
obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o
obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
obj-$(CONFIG_MMC_SDHCI_TEGRA) += sdhci-tegra.o
-obj-$(CONFIG_MMC_SDHCI_OF_ARASAN) += sdhci-of-arasan.o
obj-$(CONFIG_MMC_SDHCI_OF_ESDHC) += sdhci-of-esdhc.o
obj-$(CONFIG_MMC_SDHCI_OF_HLWD) += sdhci-of-hlwd.o
obj-$(CONFIG_MMC_SDHCI_BCM2835) += sdhci-bcm2835.o
#include <linux/slab.h>
#include <linux/mmc/host.h>
#include <linux/mmc/mmc.h>
-#include <linux/mmc/rk_mmc.h>
+#include <linux/mmc/dw_mmc.h>
#include <linux/of.h>
-#include "dw_mmc-pltfm.h"
-#include "rk_sdmmc.h"
+
+#include "dw_mmc.h"
int dw_mci_pltfm_register(struct platform_device *pdev,
- const struct dw_mci_drv_data *drv_data)
+ const struct dw_mci_drv_data *drv_data)
{
struct dw_mci *host;
struct resource *regs;
host->irq_flags = 0;
host->pdata = pdev->dev.platform_data;
host->regs = devm_ioremap_resource(&pdev->dev, regs);
- #ifdef CONFIG_MMC_DW_IDMAC
- host->phy_regs = (void *)(regs->start);
- #endif
if (IS_ERR(host->regs))
return PTR_ERR(host->regs);
return dw_mci_pltfm_register(pdev, NULL);
}
-int dw_mci_pltfm_remove(struct platform_device *pdev)
+static int dw_mci_pltfm_remove(struct platform_device *pdev)
{
struct dw_mci *host = platform_get_drvdata(pdev);
#define dw_mci_pltfm_resume NULL
#endif /* CONFIG_PM_SLEEP */
-SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops,
- dw_mci_pltfm_suspend,
- dw_mci_pltfm_resume);
+SIMPLE_DEV_PM_OPS(dw_mci_pltfm_pmops, dw_mci_pltfm_suspend, dw_mci_pltfm_resume);
EXPORT_SYMBOL_GPL(dw_mci_pltfm_pmops);
static const struct of_device_id dw_mci_pltfm_match[] = {
const struct dw_mci_drv_data *drv_data);
extern int dw_mci_pltfm_remove(struct platform_device *pdev);
extern const struct dev_pm_ops dw_mci_pltfm_pmops;
-extern int dw_mci_probe(struct dw_mci *host);
-extern void dw_mci_remove(struct dw_mci *host);
-#endif /* _DW_MMC_PLTFM_H_ */
-
+#endif /* _DW_MMC_PLTFM_H_ */
"MMC read only", false, 0);
if (ret)
goto err_free_gpio_card_detect;
- if (gpio_is_valid(pdata->gpio_card_detect)) {
- ret = mmc_gpio_request_cd(mmc, pdata->gpio_card_detect, 0);
- if (ret)
- return ret;
- }
ret = jz4740_mmc_request_gpio(&pdev->dev, pdata->gpio_power,
"MMC read only", true, pdata->power_active_low);
host->base_clock = mvsd_data->clock / 2;
gpio_card_detect = mvsd_data->gpio_card_detect ? : -EINVAL;
gpio_write_protect = mvsd_data->gpio_write_protect ? : -EINVAL;
- /* GPIO 0 regarded as invalid for backward compatibility */
- if (mvsd_data->gpio_card_detect &&
- gpio_is_valid(mvsd_data->gpio_card_detect)) {
- ret = mmc_gpio_request_cd(mmc,
- mvsd_data->gpio_card_detect,
- 0);
- if (ret)
- goto out;
- } else {
- mmc->caps |= MMC_CAP_NEEDS_POLL;
- }
-
- if (mvsd_data->gpio_write_protect &&
- gpio_is_valid(mvsd_data->gpio_write_protect))
- mmc_gpio_request_ro(mmc, mvsd_data->gpio_write_protect);
}
mmc->ops = &mvsd_ops;
struct mmc_host *mmc = host->mmc;
struct mmc_card *card = mmc->card;
struct mmc_data *data = mrq->data;
- int uhs = mmc_card_uhs(card);
+ int uhs = mmc_sd_card_uhs(card);
int read = (data->flags & MMC_DATA_READ) ? 1 : 0;
u8 cfg2, trans_mode;
int err;
/* card_detect */
switch (boarddata->cd_type) {
case ESDHC_CD_GPIO:
- err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0);
+ err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio);
if (err) {
dev_err(mmc_dev(host->mmc),
"failed to request card-detect gpio!\n");
host->mmc->pm_caps |= pdata->pm_caps;
if (gpio_is_valid(pdata->ext_cd_gpio)) {
- ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio,
- 0);
+ ret = mmc_gpio_request_cd(host->mmc, pdata->ext_cd_gpio);
if (ret) {
dev_err(mmc_dev(host->mmc),
"failed to allocate card detect gpio\n");
* gets setup in sdhci_add_host() and we oops.
*/
if (gpio_is_valid(priv->gpio_cd)) {
- ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd, 0);
+ ret = mmc_gpio_request_cd(host->mmc, priv->gpio_cd);
if (ret) {
dev_err(&pdev->dev, "card detect irq request failed: %d\n",
ret);
}
if (pd && pd->use_cd_gpio) {
- ret = mmc_gpio_request_cd(mmc, pd->cd_gpio, 0);
+ ret = mmc_gpio_request_cd(mmc, pd->cd_gpio);
if (ret < 0)
goto erqcd;
}
dev_pm_qos_expose_latency_limit(&pdev->dev, 100);
if (pdata->flags & TMIO_MMC_USE_GPIO_CD) {
- ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio, 0);
+ ret = mmc_gpio_request_cd(mmc, pdata->cd_gpio);
if (ret < 0) {
tmio_mmc_host_remove(_host);
return ret;
source "drivers/mtd/nand/Kconfig"
-source "drivers/mtd/rknand/Kconfig"
-
source "drivers/mtd/onenand/Kconfig"
source "drivers/mtd/lpddr/Kconfig"
nftl-objs := nftlcore.o nftlmount.o
inftl-objs := inftlcore.o inftlmount.o
-obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/ rknand/
+obj-y += chips/ lpddr/ maps/ devices/ nand/ onenand/ tests/
obj-$(CONFIG_MTD_UBI) += ubi/
source "drivers/net/ethernet/wiznet/Kconfig"
source "drivers/net/ethernet/xilinx/Kconfig"
source "drivers/net/ethernet/xircom/Kconfig"
-source "drivers/net/ethernet/rockchip/Kconfig"
endif # ETHERNET
obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/
obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/
obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/
-obj-$(CONFIG_NET_VENDOR_ROCKCHIP) += rockchip/
#define RTL821x_INER_INIT 0x6400
#define RTL821x_INSR 0x13
-#define RTL8211E_INER_LINK_STAT 0x400
+#define RTL8211E_INER_LINK_STAT 0x10
MODULE_DESCRIPTION("Realtek PHY driver");
MODULE_AUTHOR("Johnson Leung");
else
err = phy_write(phydev, RTL821x_INER, 0);
- phy_read(phydev, RTL821x_INSR);
return err;
}
This option adds support for Davicom DM9601 based USB 1.1
10/100 Ethernet adapters.
-config USB_NET_DM9620
- tristate "Davicom DM9620 based USB 2.0 10/100 ethernet devices"
- depends on USB_USBNET
- select CRC32
- help
- This option adds support for Davicom DM9620 based USB 2.0
- 10/100 Ethernet adapters.
-
config USB_NET_SMSC75XX
tristate "SMSC LAN75XX based USB 2.0 gigabit ethernet devices"
depends on USB_USBNET
obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o
obj-$(CONFIG_USB_NET_DM9601) += dm9601.o
-obj-$(CONFIG_USB_NET_DM9620) += dm9620.o
obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o
obj-$(CONFIG_USB_NET_SMSC95XX) += smsc95xx.o
obj-$(CONFIG_USB_NET_GL620A) += gl620a.o
rx->size = skb->len - offset;
}
- if (!rx->ax_skb) {
- rx->size = 0;
- netdev_err(dev->net, "asix_rx_fixup_internal Bad ax_skb buf.\n");
- return 0;
- }
-
data = skb_put(rx->ax_skb, rx->size);
memcpy(data, skb->data + offset, rx->size);
if (!remaining)
* ethernet frames.
*/
dev->rx_urb_size = dev->net->mtu + ETH_HLEN + DM_RX_OVERHEAD + 1;
- dev->rx_urb_size = (dev->rx_urb_size > 2048) ? dev->rx_urb_size : 2048;
dev->mii.dev = dev->net;
dev->mii.mdio_read = dm9601_mdio_read;
if WLAN
-# config RDA5990
-# depends on WLAN_80211 && MMC
-# select WIRELESS_EXT
-# select WEXT_PRIV
-# select IEEE80211
-# bool "rda 5990p"
-# ---help---
-# rda5990P fm bt wifi
-
-config WIFI_LOAD_DRIVER_WHEN_KERNEL_BOOTUP
- bool "Wifi load driver when kernel bootup"
- default y
- ---help---
- Wifi driver will be load (use late_initcall) when kernel bootup
-
-menuconfig RTL_WIRELESS_SOLUTION
- bool "Realtek Wireless Device Driver Support"
- default y
-
-if RTL_WIRELESS_SOLUTION
-choice
- prompt "Realtek WiFi Device Driver Support"
- default RTL8188EU
-
- config RTL_WIFI_NONE
- bool "No Realtek WiFi"
-
-source "drivers/net/wireless/rockchip_wlan/rtl8188eu/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8189es/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8192cu/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8192du/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8723au/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8723bu/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8723bs/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8723bs-vq0/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rtl8812au/Kconfig"
-endchoice
-endif
-
-#source "drivers/net/wireless/rockchip_wlan/mt5931/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/esp8089/Kconfig"
-source "drivers/net/wireless/rockchip_wlan/rkwifi/Kconfig"
-
-choice
- depends on RKWIFI
- prompt "Select the wifi module"
- default RK903
-
- config BCM4330
- bool "BCM4330"
- depends on RKWIFI
-
- config RK903
- bool "RK903"
- depends on RKWIFI
-
- config RK901
- bool "RK901"
- depends on RKWIFI
-
- config AP6181
- bool "AP6181"
- depends on RKWIFI
-
- config AP6210
- bool "AP6210"
- depends on RKWIFI
-
- config AP6234
- bool "AP6234"
- depends on RKWIFI
-
- config AP6330
- bool "AP6330"
- depends on RKWIFI
-
- config AP6335
- bool "AP6335"
- depends on RKWIFI
-
- config AP6441
- bool "AP6441"
- depends on RKWIFI
- select BCM2079X_NFC
-
- config AP6476
- bool "AP6476"
- depends on RKWIFI
-
- config AP6493
- bool "AP6493"
- depends on RKWIFI
- select BCM2079X_NFC
-
- config GB86302I
- bool "GB86302I"
- depends on RKWIFI
-
-endchoice
-
-choice
- depends on RKWIFI
- prompt "Select the wifi module crystal freq"
- default RKWIFI_26M
-
- config RKWIFI_37_4M
- bool "37_4M"
- depends on RKWIFI
-
- config RKWIFI_26M
- bool "26M"
- depends on RKWIFI && !AP6335 && !AP6234 && !AP6441
-
- config RKWIFI_24M
- bool "24M"
- depends on RKWIFI && AP6210
-
-endchoice
-
-#menuconfig MTK_WIRELESS_SOLUTION
-# bool "MTK wireless chip configuration"
-# help
-# "enable/disable and config MTK wireless solution"
-
-#if MTK_WIRELESS_SOLUTION
-#source "drivers/net/wireless/rockchip_wlan/combo_mt66xx/Kconfig"
-#source "drivers/net/wireless/rockchip_wlan/mt5931_kk/Kconfig"
-#endif # MTK_WIRELESS_SOLUTION
-
-endif
+config PCMCIA_RAYCS
+ tristate "Aviator/Raytheon 2.4GHz wireless support"
+ depends on PCMCIA
+ select WIRELESS_EXT
+ select WEXT_SPY
+ select WEXT_PRIV
+ ---help---
+ Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
+ (PC-card) wireless Ethernet networking card to your computer.
+ Please read the file <file:Documentation/networking/ray_cs.txt> for
+ details.
+
+ To compile this driver as a module, choose M here: the module will be
+ called ray_cs. If unsure, say N.
+
+config LIBERTAS_THINFIRM
+ tristate "Marvell 8xxx Libertas WLAN driver support with thin firmware"
+ depends on MAC80211
+ select FW_LOADER
+ ---help---
+ A library for Marvell Libertas 8xxx devices using thinfirm.
+
+config LIBERTAS_THINFIRM_DEBUG
+ bool "Enable full debugging output in the Libertas thin firmware module."
+ depends on LIBERTAS_THINFIRM
+ ---help---
+ Debugging support.
+
+config LIBERTAS_THINFIRM_USB
+ tristate "Marvell Libertas 8388 USB 802.11b/g cards with thin firmware"
+ depends on LIBERTAS_THINFIRM && USB
+ ---help---
+ A driver for Marvell Libertas 8388 USB devices using thinfirm.
+
+config AIRO
+ tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
+ depends on ISA_DMA_API && (PCI || BROKEN)
+ select WIRELESS_EXT
+ select CRYPTO
+ select WEXT_SPY
+ select WEXT_PRIV
+ ---help---
+ This is the standard Linux driver to support Cisco/Aironet ISA and
+ PCI 802.11 wireless cards.
+ It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
+ - with or without encryption) as well as card before the Cisco
+ acquisition (Aironet 4500, Aironet 4800, Aironet 4800B).
+
+ This driver support both the standard Linux Wireless Extensions
+ and Cisco proprietary API, so both the Linux Wireless Tools and the
+ Cisco Linux utilities can be used to configure the card.
+
+ The driver can be compiled as a module and will be named "airo".
+
+config ATMEL
+ tristate "Atmel at76c50x chipset 802.11b support"
+ depends on (PCI || PCMCIA)
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ select FW_LOADER
+ select CRC32
+ ---help---
+ A driver 802.11b wireless cards based on the Atmel fast-vnet
+ chips. This driver supports standard Linux wireless extensions.
+
+ Many cards based on this chipset do not have flash memory
+ and need their firmware loaded at start-up. If yours is
+ one of these, you will need to provide a firmware image
+ to be loaded into the card by the driver. The Atmel
+ firmware package can be downloaded from
+ <http://www.thekelleys.org.uk/atmel>
+
+config PCI_ATMEL
+ tristate "Atmel at76c506 PCI cards"
+ depends on ATMEL && PCI
+ ---help---
+ Enable support for PCI and mini-PCI cards containing the
+ Atmel at76c506 chip.
+
+config PCMCIA_ATMEL
+ tristate "Atmel at76c502/at76c504 PCMCIA cards"
+ depends on ATMEL && PCMCIA
+ select WIRELESS_EXT
+ select FW_LOADER
+ select CRC32
+ ---help---
+ Enable support for PCMCIA cards containing the
+ Atmel at76c502 and at76c504 chips.
+
+config AT76C50X_USB
+ tristate "Atmel at76c503/at76c505/at76c505a USB cards"
+ depends on MAC80211 && USB
+ select FW_LOADER
+ ---help---
+ Enable support for USB Wireless devices using Atmel at76c503,
+ at76c505 or at76c505a chips.
+
+config AIRO_CS
+ tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
+ depends on PCMCIA && (BROKEN || !M32R)
+ select WIRELESS_EXT
+ select WEXT_SPY
+ select WEXT_PRIV
+ select CRYPTO
+ select CRYPTO_AES
+ ---help---
+ This is the standard Linux driver to support Cisco/Aironet PCMCIA
+ 802.11 wireless cards. This driver is the same as the Aironet
+ driver part of the Linux Pcmcia package.
+ It supports the new 802.11b cards from Cisco (Cisco 34X, Cisco 35X
+ - with or without encryption) as well as card before the Cisco
+ acquisition (Aironet 4500, Aironet 4800, Aironet 4800B). It also
+ supports OEM of Cisco such as the DELL TrueMobile 4800 and Xircom
+ 802.11b cards.
+
+ This driver support both the standard Linux Wireless Extensions
+ and Cisco proprietary API, so both the Linux Wireless Tools and the
+ Cisco Linux utilities can be used to configure the card.
+
+config PCMCIA_WL3501
+ tristate "Planet WL3501 PCMCIA cards"
+ depends on PCMCIA
+ select WIRELESS_EXT
+ select WEXT_SPY
+ help
+ A driver for WL3501 PCMCIA 802.11 wireless cards made by Planet.
+ It has basic support for Linux wireless extensions and initial
+ micro support for ethtool.
+
+config PRISM54
+ tristate 'Intersil Prism GT/Duette/Indigo PCI/Cardbus (DEPRECATED)'
+ depends on PCI
+ select WIRELESS_EXT
+ select WEXT_SPY
+ select WEXT_PRIV
+ select FW_LOADER
+ ---help---
+ This enables support for FullMAC PCI/Cardbus prism54 devices. This
+ driver is now deprecated in favor for the SoftMAC driver, p54pci.
+ p54pci supports FullMAC PCI/Cardbus devices as well.
+
+ For more information refer to the p54 wiki:
+
+ http://wireless.kernel.org/en/users/Drivers/p54
+
+ Note: You need a motherboard with DMA support to use any of these cards
+
+ When built as module you get the module prism54
+
+config USB_ZD1201
+ tristate "USB ZD1201 based Wireless device support"
+ depends on USB
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ select FW_LOADER
+ ---help---
+ Say Y if you want to use wireless LAN adapters based on the ZyDAS
+ ZD1201 chip.
+
+ This driver makes the adapter appear as a normal Ethernet interface,
+ typically on wlan0.
+
+ The zd1201 device requires external firmware to be loaded.
+ This can be found at http://linux-lc100020.sourceforge.net/
+
+ To compile this driver as a module, choose M here: the
+ module will be called zd1201.
+
+config USB_NET_RNDIS_WLAN
+ tristate "Wireless RNDIS USB support"
+ depends on USB
+ depends on CFG80211
+ select USB_USBNET
+ select USB_NET_CDCETHER
+ select USB_NET_RNDIS_HOST
+ ---help---
+ This is a driver for wireless RNDIS devices.
+ These are USB based adapters found in devices such as:
+
+ Buffalo WLI-U2-KG125S
+ U.S. Robotics USR5421
+ Belkin F5D7051
+ Linksys WUSB54GSv2
+ Linksys WUSB54GSC
+ Asus WL169gE
+ Eminent EM4045
+ BT Voyager 1055
+ Linksys WUSB54GSv1
+ U.S. Robotics USR5420
+ BUFFALO WLI-USB-G54
+
+ All of these devices are based on Broadcom 4320 chip which is the
+ only wireless RNDIS chip known to date.
+
+ If you choose to build a module, it'll be called rndis_wlan.
+
+source "drivers/net/wireless/rtl818x/Kconfig"
+
+config ADM8211
+ tristate "ADMtek ADM8211 support"
+ depends on MAC80211 && PCI
+ select CRC32
+ select EEPROM_93CX6
+ ---help---
+ This driver is for ADM8211A, ADM8211B, and ADM8211C based cards.
+ These are PCI/mini-PCI/Cardbus 802.11b chips found in cards such as:
+
+ Xterasys Cardbus XN-2411b
+ Blitz NetWave Point PC
+ TrendNet 221pc
+ Belkin F5D6001
+ SMC 2635W
+ Linksys WPC11 v1
+ Fiberline FL-WL-200X
+ 3com Office Connect (3CRSHPW796)
+ Corega WLPCIB-11
+ SMC 2602W V2 EU
+ D-Link DWL-520 Revision C
+
+ However, some of these cards have been replaced with other chips
+ like the RTL8180L (Xterasys Cardbus XN-2411b, Belkin F5D6001) or
+ the Ralink RT2400 (SMC2635W) without a model number change.
+
+ Thanks to Infineon-ADMtek for their support of this driver.
+
+config MAC80211_HWSIM
+ tristate "Simulated radio testing tool for mac80211"
+ depends on MAC80211
+ ---help---
+ This driver is a developer testing tool that can be used to test
+ IEEE 802.11 networking stack (mac80211) functionality. This is not
+ needed for normal wireless LAN usage and is only for testing. See
+ Documentation/networking/mac80211_hwsim for more information on how
+ to use this tool.
+
+ To compile this driver as a module, choose M here: the module will be
+ called mac80211_hwsim. If unsure, say N.
+
+config MWL8K
+ tristate "Marvell 88W8xxx PCI/PCIe Wireless support"
+ depends on MAC80211 && PCI
+ ---help---
+ This driver supports Marvell TOPDOG 802.11 wireless cards.
+
+ To compile this driver as a module, choose M here: the module
+ will be called mwl8k. If unsure, say N.
+
+config WIFI_CONTROL_FUNC
+ bool "Enable WiFi control function abstraction"
+ help
+ Enables Power/Reset/Carddetect function abstraction
+
+source "drivers/net/wireless/ath/Kconfig"
+source "drivers/net/wireless/b43/Kconfig"
+source "drivers/net/wireless/b43legacy/Kconfig"
+source "drivers/net/wireless/brcm80211/Kconfig"
+source "drivers/net/wireless/hostap/Kconfig"
+source "drivers/net/wireless/ipw2x00/Kconfig"
+source "drivers/net/wireless/iwlwifi/Kconfig"
+source "drivers/net/wireless/iwlegacy/Kconfig"
+source "drivers/net/wireless/libertas/Kconfig"
+source "drivers/net/wireless/orinoco/Kconfig"
+source "drivers/net/wireless/p54/Kconfig"
+source "drivers/net/wireless/rt2x00/Kconfig"
+source "drivers/net/wireless/rtlwifi/Kconfig"
+source "drivers/net/wireless/ti/Kconfig"
+source "drivers/net/wireless/zd1211rw/Kconfig"
+source "drivers/net/wireless/mwifiex/Kconfig"
+endif # WLAN
#
# Makefile for the Linux Wireless network device drivers.
#
-obj-y += rockchip_wlan/wifi_sys/rkwifi_sys_iface.o
-obj-$(CONFIG_RTL8192CU) += rockchip_wlan/rtl8192cu/
-obj-$(CONFIG_RTL8192DU) += rockchip_wlan/rtl8192du/
-obj-$(CONFIG_RTL8188EU) += rockchip_wlan/rtl8188eu/
-obj-$(CONFIG_RTL8189ES) += rockchip_wlan/rtl8189es/
-obj-$(CONFIG_RTL8723AU) += rockchip_wlan/rtl8723au/
-obj-$(CONFIG_RTL8723BU) += rockchip_wlan/rtl8723bu/
-obj-$(CONFIG_RTL8812AU) += rockchip_wlan/rtl8812au/
-obj-$(CONFIG_RKWIFI) += rockchip_wlan/rkwifi/
-obj-$(CONFIG_RTL8723BS) += rockchip_wlan/rtl8723bs/
-obj-$(CONFIG_RTL8723BS_VQ0) += rockchip_wlan/rtl8723bs-vq0/
-obj-$(CONFIG_ESP8089) += rockchip_wlan/esp8089/
+
+obj-$(CONFIG_IPW2100) += ipw2x00/
+obj-$(CONFIG_IPW2200) += ipw2x00/
+
+obj-$(CONFIG_HERMES) += orinoco/
+
+obj-$(CONFIG_AIRO) += airo.o
+obj-$(CONFIG_AIRO_CS) += airo_cs.o airo.o
+
+obj-$(CONFIG_ATMEL) += atmel.o
+obj-$(CONFIG_PCI_ATMEL) += atmel_pci.o
+obj-$(CONFIG_PCMCIA_ATMEL) += atmel_cs.o
+
+obj-$(CONFIG_AT76C50X_USB) += at76c50x-usb.o
+
+obj-$(CONFIG_PRISM54) += prism54/
+
+obj-$(CONFIG_HOSTAP) += hostap/
+obj-$(CONFIG_B43) += b43/
+obj-$(CONFIG_B43LEGACY) += b43legacy/
+obj-$(CONFIG_ZD1211RW) += zd1211rw/
+obj-$(CONFIG_RTL8180) += rtl818x/
+obj-$(CONFIG_RTL8187) += rtl818x/
+obj-$(CONFIG_RTLWIFI) += rtlwifi/
+
+# 16-bit wireless PCMCIA client drivers
+obj-$(CONFIG_PCMCIA_RAYCS) += ray_cs.o
+obj-$(CONFIG_PCMCIA_WL3501) += wl3501_cs.o
+
+obj-$(CONFIG_USB_NET_RNDIS_WLAN) += rndis_wlan.o
+
+obj-$(CONFIG_USB_ZD1201) += zd1201.o
+obj-$(CONFIG_LIBERTAS) += libertas/
+
+obj-$(CONFIG_LIBERTAS_THINFIRM) += libertas_tf/
+
+obj-$(CONFIG_ADM8211) += adm8211.o
+
+obj-$(CONFIG_MWL8K) += mwl8k.o
+
+obj-$(CONFIG_IWLWIFI) += iwlwifi/
+obj-$(CONFIG_IWLEGACY) += iwlegacy/
+obj-$(CONFIG_RT2X00) += rt2x00/
+
+obj-$(CONFIG_P54_COMMON) += p54/
+
+obj-$(CONFIG_ATH_CARDS) += ath/
+
+obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
+
+obj-$(CONFIG_WL_TI) += ti/
+
+obj-$(CONFIG_MWIFIEX) += mwifiex/
+
+obj-$(CONFIG_BRCMFMAC) += brcm80211/
+obj-$(CONFIG_BRCMSMAC) += brcm80211/
menu "Near Field Communication (NFC) devices"
depends on NFC
-config BCM2079X_NFC
- tristate "bcm2079x NFC driver"
- depends on AP6493 && AP6441
- default n
- ---help---
- Say yes if you want bcm2079x Near Field Communication driver.
- This is for i2c connected version. If unsure, say N here.
-
config NFC_PN533
tristate "NXP PN533 USB driver"
depends on USB
# Makefile for nfc devices
#
-obj-$(CONFIG_BCM2079X_NFC) += bcm2079x-i2c.o
obj-$(CONFIG_NFC_PN544) += pn544/
obj-$(CONFIG_NFC_MICROREAD) += microread/
obj-$(CONFIG_NFC_PN533) += pn533.o
}
EXPORT_SYMBOL_GPL(of_property_read_u8_array);
-
-int of_property_read_u8_array_tp(const struct device_node *np,
- const char *propname, u8 *out_values, size_t sz)
-{
- const __be32 *val = of_find_property_value_of_size(np, propname,
- (sz * sizeof(*out_values)));
-
- if (IS_ERR(val))
- return PTR_ERR(val);
-
- while (sz--)
- *out_values++ = (unsigned char)(be32_to_cpup(val++));
- return 0;
-}
-EXPORT_SYMBOL_GPL(of_property_read_u8_array_tp);
-
-
-
/**
* of_property_read_u16_array - Find and read an array of u16 from a property.
*
/* name and id have to be set so that the platform bus doesn't get
* confused on matching */
-#ifdef CONFIG_ARCH_ROCKCHIP
- ofdev->name = kasprintf(GFP_KERNEL, "%s", dev_name(&ofdev->dev));
-#else
ofdev->name = dev_name(&ofdev->dev);
-#endif
ofdev->id = -1;
/* device_add will assume that this device is on the same node as
memset((void *)mem, 0, size);
+ memset((void *)mem, 0, size);
+
((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef);
pr_debug(" unflattening %p...\n", mem);
{
struct pci_dev *pci_dev = to_pci_dev(dev);
const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
- int ret = 0;
/*
* If pci_dev->driver is not set (unbound), the device should
* always remain in D0 regardless of the runtime PM status
*/
if (!pci_dev->driver)
- return 0;
+ goto out;
if (!pm)
return -ENOSYS;
- if (pm->runtime_idle)
- ret = pm->runtime_idle(dev);
+ if (pm->runtime_idle) {
+ int ret = pm->runtime_idle(dev);
+ if (ret)
+ return ret;
+ }
- return ret;
+out:
+ pm_runtime_suspend(dev);
+ return 0;
}
#else /* !CONFIG_PM_RUNTIME */
bool "DB8540 pin controller driver"
depends on PINCTRL_NOMADIK && ARCH_U8500
-config PINCTRL_ROCKCHIP
- bool
- select PINMUX
- select GENERIC_PINCONF
- select GENERIC_IRQ_CHIP
-
-config PINCTRL_RK3368
- bool
- select PINMUX
- select GENERIC_PINCONF
- select GENERIC_IRQ_CHIP
- select MFD_SYSCON
-
config PINCTRL_SINGLE
tristate "One-register-per-pin type device tree based pinctrl driver"
depends on OF
obj-$(CONFIG_PINCTRL_STN8815) += pinctrl-nomadik-stn8815.o
obj-$(CONFIG_PINCTRL_DB8500) += pinctrl-nomadik-db8500.o
obj-$(CONFIG_PINCTRL_DB8540) += pinctrl-nomadik-db8540.o
-obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
-obj-$(CONFIG_PINCTRL_RK3368) += pinctrl-rk3368.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
obj-$(CONFIG_PINCTRL_SUNXI) += pinctrl-sunxi.o
}
EXPORT_SYMBOL_GPL(pinctrl_force_default);
-#ifdef CONFIG_PM
-
-/**
- * pinctrl_pm_select_state() - select pinctrl state for PM
- * @dev: device to select default state for
- * @state: state to set
- */
-static int pinctrl_pm_select_state(struct device *dev,
- struct pinctrl_state *state)
-{
- struct dev_pin_info *pins = dev->pins;
- int ret;
-
- if (IS_ERR(state))
- return 0; /* No such state */
- ret = pinctrl_select_state(pins->p, state);
- if (ret)
- dev_err(dev, "failed to activate pinctrl state %s\n",
- state->name);
- return ret;
-}
-
-/**
- * pinctrl_pm_select_default_state() - select default pinctrl state for PM
- * @dev: device to select default state for
- */
-int pinctrl_pm_select_default_state(struct device *dev)
-{
- if (!dev->pins)
- return 0;
-
- return pinctrl_pm_select_state(dev, dev->pins->default_state);
-}
-EXPORT_SYMBOL_GPL(pinctrl_pm_select_default_state);
-
-/**
- * pinctrl_pm_select_sleep_state() - select sleep pinctrl state for PM
- * @dev: device to select sleep state for
- */
-int pinctrl_pm_select_sleep_state(struct device *dev)
-{
- if (!dev->pins)
- return 0;
-
- return pinctrl_pm_select_state(dev, dev->pins->sleep_state);
-}
-EXPORT_SYMBOL_GPL(pinctrl_pm_select_sleep_state);
-
-/**
- * pinctrl_pm_select_idle_state() - select idle pinctrl state for PM
- * @dev: device to select idle state for
- */
-int pinctrl_pm_select_idle_state(struct device *dev)
-{
- if (!dev->pins)
- return 0;
-
- return pinctrl_pm_select_state(dev, dev->pins->idle_state);
-}
-EXPORT_SYMBOL_GPL(pinctrl_pm_select_idle_state);
-#endif
-
#ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what)
* <devicename> <state> <pinname> are values that should match the pinctrl-maps
* <newvalue> reflects the new config and is driver dependant
*/
-static ssize_t pinconf_dbg_config_write(struct file *file,
+static int pinconf_dbg_config_write(struct file *file,
const char __user *user_buf, size_t count, loff_t *ppos)
{
struct pinctrl_maps *maps_node;
Say Y here to enable support for the power management unit
provided by the Wolfson Microelectronics WM8350 PMIC.
-config CHARGER_RT5025
- bool "RT5025 Charger Driver"
- depends on MFD_RT5025
- default n
- help
- Enable RT5025 Charger driver.
-
-config BATTERY_RT5025
- bool "RT5025 PMIC ADC Type gauge driver"
- depends on MFD_RT5025
- default n
- help
- Enable the RT5025 ADC Fuelgauge driver.
-
-config RT_JEITA_REMOVE
- bool "RT Jeita function remobe"
- depends on CHARGER_RT5025 && BATTERY_RT5025
- default n
- help
- Say Y here to remove Jeita function.
-
-config CHARGER_RT5036
- bool "RT5036 charger support"
- depends on MFD_RT5036
- default n
- help
- Say Y here to enable support for RT5036 chip charger subdevice.
-
-config CHARGER_RT5036_VMID_HDMI
- bool "RT5036 charger VMID HDMI support"
- depends on CHARGER_RT5036
- default n
- help
- Say Y here to enable support for RT5036 charger VMID HDMI Boost.
-
-config RT_POWER
- bool "RT PMIC cable report"
- depends on CHARGER_RT5036 || CHARGER_RT5025
- default n
- help
- Enable AC/USB report.
-
-config RT_SUPPORT_ACUSB_DUALIN
- bool "RT AC/USB Dualin Option"
- depends on RT_POWER
- default n
- help
- Say Y here to enable dualin, otherwise
- N is just singlein.
-
-config RT_BATTERY
- bool "RT Test Battery"
- depends on CHARGER_RT5036
- default n
- help
- Enable Test Battery report.
-
-config BATTERY_RICOH619
- tristate "Ricoh RC5T619 PMIC battery driver"
- depends on MFD_RICOH619 && I2C && GENERIC_HARDIRQS
- help
- Say Y to enable support for the battery control of the Ricoh RC5T619
- Power Management device.
-
config TEST_POWER
tristate "Test power driver"
help
help
Say Y here to enable support for batteries with BQ27000 (HDQ) chips.
-config BATTERY_BQ24296
- tristate "BQ24296 chargeIC driver"
- help
- Say Y here to enable support for batteries with BQ24296 (I2C/HDQ) chips.
-
-config BATTERY_BQ27320
- tristate "BQ27320 battery driver"
- depends on I2C
- help
- Say Y here to enable support for batteries with BQ27320(I2C) chip.
-
config BATTERY_DA9030
tristate "DA9030 battery driver"
depends on PMIC_DA903X
Say Y to enable support for the battery charger control sysfs and
platform data of MAX8998/LP3974 PMICs.
-config BATTERY_RK30_ADC_FAC
- tristate "RK30 ADC Battery Factory"
- help
- Say Y to enable support for the battery on the RK30.
-
-config BATTERY_RK30_USB_CHARGE
- tristate "RK30 USB CHARGE"
- depends on BATTERY_RK30_ADC||BATTERY_RK30_ADC_FAC
- default y
- help
- say Y to enable suspport for the USB battery charge
-
-
config CHARGER_BQ2415X
tristate "TI BQ2415x battery charger driver"
depends on I2C
Say Y here to enable support for battery charging with TPS65090
PMIC chips.
-config CW2015_BATTERY
- tristate "CW2015 battery driver"
- help
- Say Y to enable support for the cw2015 on the Rockchip
-
config AB8500_BM
bool "AB8500 Battery Management Driver"
depends on AB8500_CORE && AB8500_GPADC
Say Y to enable support for the battery and AC power in the
Goldfish emulator.
-config BATTERY_RK818
- bool "RK818 Battery driver"
- depends on MFD_RK818
- default n
- help
- Support for RK818 Battery driver.
- This driver can give support for Rk818 Battery Charge Interface.
-
-config CHARGER_DISPLAY
- bool "Support charger display"
-
source "drivers/power/reset/Kconfig"
endif # POWER_SUPPLY
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_SBS) += sbs-battery.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
-obj-$(CONFIG_BATTERY_BQ24296) += bq24296_charger.o
-obj-$(CONFIG_BATTERY_BQ27320) += bq27320_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
obj-$(CONFIG_BATTERY_DA9052) += da9052-battery.o
obj-$(CONFIG_BATTERY_MAX17040) += max17040_battery.o
obj-$(CONFIG_POWER_AVS) += avs/
obj-$(CONFIG_CHARGER_SMB347) += smb347-charger.o
obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
-obj-$(CONFIG_BATTERY_RK30_ADC_FAC) += rk30_factory_adc_battery.o
-obj-$(CONFIG_CW2015_BATTERY) += cw2015_battery.o
-obj-$(CONFIG_BATTERY_RICOH619) += ricoh619-battery.o
-obj-$(CONFIG_CHARGER_DISPLAY) += rk29_charger_display.o
obj-$(CONFIG_POWER_RESET) += reset/
-obj-$(CONFIG_BATTERY_RK818) += rk818_battery.o
-obj-$(CONFIG_CHARGER_RT5025) += rt5025-charger.o
-obj-$(CONFIG_RT_POWER) += rt-power.o
-obj-$(CONFIG_BATTERY_RT5025) += rt5025-battery.o
-obj-$(CONFIG_CHARGER_RT5036) += rt5036-charger.o
-obj-$(CONFIG_RT_BATTERY) += rt-battery.o
AVS is also called SmartReflex on OMAP devices.
Say Y here to enable Adaptive Voltage Scaling class support.
-
-config ROCKCHIP_IODOMAIN
- tristate "Rockchip IO domain support"
- depends on ARCH_ROCKCHIP && OF
- help
- Say y here to enable support io domains on Rockchip SoCs. It is
- necessary for the io domain setting of the SoC to match the
- voltage supplied by the regulators.
obj-$(CONFIG_POWER_AVS_OMAP) += smartreflex.o
-obj-$(CONFIG_ROCKCHIP_IODOMAIN) += rockchip-io-domain.o
Instead they restart, and u-boot holds the SoC until the
user presses a key. u-boot then boots into Linux.
-config POWER_RESET_ROCKCHIP
- bool "Rockchip reset driver"
- depends on POWER_RESET && MFD_SYSCON && ARCH_ROCKCHIP
- help
- Restart support for Rockchip SoCs.
-
config POWER_RESET_VEXPRESS
bool "ARM Versatile Express power-off and reset driver"
depends on ARM || ARM64
obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o
obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o
obj-$(CONFIG_POWER_RESET_RESTART) += restart-poweroff.o
-obj-$(CONFIG_POWER_RESET_ROCKCHIP) += rockchip-reboot.o
obj-$(CONFIG_POWER_RESET_VEXPRESS) += vexpress-poweroff.o
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/vermagic.h>
-#include <linux/of.h>
-#include <linux/of_address.h>
-#include <linux/err.h>
-
static int ac_online = 1;
static int usb_online = 1;
{
int i;
int ret;
- struct device_node *dev_node;
-
- dev_node = of_find_node_by_name(NULL, "test-power");
-
- if (IS_ERR_OR_NULL(dev_node)) {
- pr_info("not find %s dev node\n", __func__);
- return 0;
- }
- if (!of_device_is_available(dev_node)) {
- pr_info("test power disabled\n");
- return 0;
- }
for (i = 0; i < ARRAY_SIZE(test_power_supplies); i++) {
ret = power_supply_register(NULL, &test_power_supplies[i]);
To compile this driver as a module, choose M here: the module
will be called pwm-vt8500.
-config PWM_ROCKCHIP
- tristate "ROCKCHIP PWM support"
- depends on OF
- help
- Generic PWM framework driver for ROCKCHIP.
-
- To compile this driver as a module, choose M here: the module
- will be called pwm-rockchip.
-
endif
obj-$(CONFIG_PWM_TWL) += pwm-twl.o
obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o
obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o
-obj-$(CONFIG_PWM_ROCKCHIP) += pwm-rockchip.o
via I2C bus. The provided regulator is suitable for
Exynos-4 chips to control VARM and VINT voltages.
-config REGULATOR_ACT8846
- tristate "Active Semi ACT8846 PMIC regulators"
- depends on I2C
- help
- Support the voltage and current regulators of the ACT8846 series of PMIC devices.
-
-config ACT8846_SUPPORT_RESET
- tristate "ACT8846 PMIC SUPPORT RESET"
- depends on REGULATOR_ACT8846=y
- help
- Support short press key to restart.
-
-config REGULATOR_ACT8931
- tristate "Active Semi ACT8931 PMIC regulators"
- depends on I2C
- help
- Support the voltage and current regulators of the ACT8931 series of PMIC devices.
-
-config REGULATOR_RT5025
- bool "Richtek RT5025 PMIC Voltage regulstors"
- depends on MFD_RT5025
- default n
- help
- This driver supports voltage regulator in RT5025 PMIC chips.
-
-config REGULATOR_RT5036
- bool "RT5036 regulator support"
- depends on MFD_RT5036
- help
- This driver support voltage regulator in Richtek RT5036.
-
-config ROCKCHIP_PWM_REGULATOR
- tristate "rockchip pwm voltage regulator for discrete dcdc or ldo"
- help
- Say Y to enable support for the voltage regulators control on the ROCKCHIP.
-
-config REGULATOR_SYR82X
- tristate "SYR82X DCDC SUPPORT REGULATOR"
- depends on I2C
- help
- Support the voltage and current regulators of the SYR82X series of DCDC devices.
-
-config REGULATOR_XZ3216
- tristate "XZ3216 DCDC SUPPORT REGULATOR"
- depends on I2C
- help
- Support the voltage and current regulators of the XZ321X series of DCDC devices.
-
config REGULATOR_PCAP
tristate "Motorola PCAP2 regulator driver"
depends on EZX_PCAP
This driver provides support for the voltage regulators on the
WM8994 CODEC.
-config REGULATOR_RICOH619
- tristate "RICOH 619 Power regulators"
- depends on MFD_RICOH619
- default n
- help
- This driver supports regulator driver for RICOH619 PMIC.
config REGULATOR_AS3711
tristate "AS3711 PMIC"
depends on MFD_AS3711
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o ab8500-ext.o
-obj-$(CONFIG_REGULATOR_ACT8931) += act8931.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
obj-$(CONFIG_REGULATOR_RC5T583) += rc5t583-regulator.o
obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
obj-$(CONFIG_REGULATOR_S5M8767) += s5m8767.o
-
-obj-$(CONFIG_ROCKCHIP_PWM_REGULATOR) += rockchip-pwm-regulator.o
-
obj-$(CONFIG_REGULATOR_TPS6105X) += tps6105x-regulator.o
obj-$(CONFIG_REGULATOR_TPS62360) += tps62360-regulator.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
-obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
-obj-$(CONFIG_REGULATOR_SYR82X) += syr82x.o
-obj-$(CONFIG_REGULATOR_XZ3216) += xz3216.o
-obj-$(CONFIG_REGULATOR_RICOH619) += ricoh619-regulator.o
-obj-$(CONFIG_REGULATOR_RT5025) += rt5025-regulator.o
-obj-$(CONFIG_REGULATOR_RT5036) += rt5036-regulator.o
-
-obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip_io_vol_domain.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
static int _regulator_get_voltage(struct regulator_dev *rdev);
static int _regulator_get_current_limit(struct regulator_dev *rdev);
static unsigned int _regulator_get_mode(struct regulator_dev *rdev);
-static int _notifier_call_chain(struct regulator_dev *rdev,
+static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data);
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV);
}
EXPORT_SYMBOL_GPL(regulator_map_voltage_linear);
-static int _regulator_call_set_voltage(struct regulator_dev *rdev,
- int min_uV, int max_uV,
- unsigned *selector)
-{
- struct pre_voltage_change_data data;
- int ret;
-
- data.old_uV = _regulator_get_voltage(rdev);
- data.min_uV = min_uV;
- data.max_uV = max_uV;
- ret = _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE,
- &data);
- if (ret & NOTIFY_STOP_MASK)
- return -EINVAL;
-
- ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, selector);
- if (ret >= 0)
- return ret;
-
- _notifier_call_chain(rdev, REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE,
- (void *)data.old_uV);
-
- return ret;
-}
-
-static int _regulator_call_set_voltage_sel(struct regulator_dev *rdev,
- int uV, unsigned selector)
-{
- struct pre_voltage_change_data data;
- int ret;
-
- data.old_uV = _regulator_get_voltage(rdev);
- data.min_uV = uV;
- data.max_uV = uV;
- ret = _notifier_call_chain(rdev, REGULATOR_EVENT_PRE_VOLTAGE_CHANGE,
- &data);
- if (ret & NOTIFY_STOP_MASK)
- return -EINVAL;
-
- ret = rdev->desc->ops->set_voltage_sel(rdev, selector);
- if (ret >= 0)
- return ret;
-
- _notifier_call_chain(rdev, REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE,
- (void *)data.old_uV);
-
- return ret;
-}
-
static int _regulator_do_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
}
if (rdev->desc->ops->set_voltage) {
- ret = _regulator_call_set_voltage(rdev, min_uV, max_uV,
- &selector);
+ ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
+ &selector);
if (ret >= 0) {
if (rdev->desc->ops->list_voltage)
if (old_selector == selector)
ret = 0;
else
- ret = _regulator_call_set_voltage_sel(
- rdev, best_val, selector);
+ ret = rdev->desc->ops->set_voltage_sel(
+ rdev, ret);
} else {
ret = -EINVAL;
}
}
EXPORT_SYMBOL_GPL(regulator_get_current_limit);
-int regulator_is_supported_mode(struct regulator *regulator, int *mode)
-{
- struct regulator_dev *rdev = regulator->rdev;
- int ret;
-
- mutex_lock(&rdev->mutex);
-
- ret = regulator_mode_constrain(rdev, mode);
-
- mutex_unlock(&rdev->mutex);
-
- return ret;
-}
-
/**
* regulator_set_mode - set regulator operating mode
* @regulator: regulator source
/* notify regulator consumers and downstream regulator consumers.
* Note mutex must be held by caller.
*/
-static int _notifier_call_chain(struct regulator_dev *rdev,
+static void _notifier_call_chain(struct regulator_dev *rdev,
unsigned long event, void *data)
{
/* call rdev chain first */
- return blocking_notifier_call_chain(&rdev->notifier, event, data);
+ blocking_notifier_call_chain(&rdev->notifier, event, data);
}
/**
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
-static void set_regulator_state_constraints(struct device_node *np,
- struct regulator_state *state)
-{
- of_property_read_u32(np, "regulator-state-uv", &state->uV);
- of_property_read_u32(np, "regulator-state-mode", &state->mode);
- state->enabled = of_property_read_bool(np, "regulator-state-enabled");
- state->disabled = of_property_read_bool(np, "regulator-state-disabled");
-}
-
static void of_get_regulation_constraints(struct device_node *np,
struct regulator_init_data **init_data)
{
const __be32 *min_uV, *max_uV, *uV_offset;
const __be32 *min_uA, *max_uA, *ramp_delay;
- struct device_node *state;
struct regulation_constraints *constraints = &(*init_data)->constraints;
constraints->name = of_get_property(np, "regulator-name", NULL);
ramp_delay = of_get_property(np, "regulator-ramp-delay", NULL);
if (ramp_delay)
constraints->ramp_delay = be32_to_cpu(*ramp_delay);
-
- of_property_read_u32(np, "regulator-valid-modes-mask",
- &constraints->valid_modes_mask);
- if (constraints->valid_modes_mask)
- constraints->valid_ops_mask |= REGULATOR_CHANGE_MODE;
-
- of_property_read_u32(np, "regulator-input-uv",
- &constraints->input_uV);
- of_property_read_u32(np, "regulator-initial-mode",
- &constraints->initial_mode);
- of_property_read_u32(np, "regulator-initial-state",
- &constraints->initial_state);
-
- /* regulator state during low power system states */
- state = of_find_node_by_name(np, "regulator-state-mem");
- if (state)
- set_regulator_state_constraints(state,
- &constraints->state_mem);
-
- state = of_find_node_by_name(np, "regulator-state-disk");
- if (state)
- set_regulator_state_constraints(state,
- &constraints->state_disk);
-
- state = of_find_node_by_name(np, "regulator-state-standby");
- if (state)
- set_regulator_state_constraints(state,
- &constraints->state_standby);
-
-
}
/**
obj-$(CONFIG_RESET_CONTROLLER) += core.o
-
-obj-$(CONFIG_ARCH_ROCKCHIP) += reset-rockchip.o
This driver can also be built as a module. If so, the module
will be called rtc-pcf8563.
-config RTC_HYM8563
- tristate "rtc of HYM8563"
- help
- If you say yes here you get support for the
- HYM8563 RTC chip. The HYM8564 should work as well.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-HYM8563.
-
config RTC_DRV_PCF8583
tristate "Philips PCF8583"
help
This driver can also be built as a module. If so, the module
will be called rtc-tps65910.
-config RK808_RTC
- tristate "rk808 rtc for rk"
- depends on MFD_RK808
- help
- enable rk808 rtc for system
-
-config RK818_RTC
- tristate "rk818 rtc for rk"
- depends on MFD_RK818
- help
- enable rk818 rtc for system
-
-config RTC_RT5036
- bool "RT5036 RTC driver support"
- depends on MFD_RT5036
- default n
- help
- Say Y here if you want to support Richtek RT5036 RTC.
-
config RTC_DRV_TPS80031
tristate "TI TPS80031/TPS80032 RTC driver"
depends on MFD_TPS80031
If this driver is compiled as a module, it will be named
rtc-hid-sensor-time.
-
-config RTC_DRV_RC5T619
- tristate "RICOH RC5T619 PMU RTC driver"
- depends on MFD_RICOH619
- default n
- help
- If you say yes here you get support for the RICOH RC5T619 RTC module.
-
- This driver can also be built as a module. If so, the module
- will be called rtc-rc5t619.
endif # RTC_CLASS
obj-$(CONFIG_RTC_DRV_PCAP) += rtc-pcap.o
obj-$(CONFIG_RTC_DRV_PCF8523) += rtc-pcf8523.o
obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o
-obj-$(CONFIG_RTC_HYM8563) += rtc-HYM8563.o
obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o
obj-$(CONFIG_RTC_DRV_PCF2123) += rtc-pcf2123.o
obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_VT8500) += rtc-vt8500.o
obj-$(CONFIG_RTC_DRV_WM831X) += rtc-wm831x.o
-obj-$(CONFIG_RK808_RTC) += rtc-rk808.o
-obj-$(CONFIG_RK818_RTC) += rtc-rk818.o
-obj-$(CONFIG_RTC_RT5036) += rtc-rt5036.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
-obj-$(CONFIG_RTC_DRV_RC5T619) += rtc-ricoh619.o
-
host_dev = scsi_get_device(shost);
if (host_dev && host_dev->dma_mask)
- bounce_limit = (u64)dma_max_pfn(host_dev) << PAGE_SHIFT;
+ bounce_limit = *host_dev->dma_mask;
return bounce_limit;
}
static int scsi_runtime_idle(struct device *dev)
{
+ int err;
+
dev_dbg(dev, "scsi_runtime_idle\n");
/* Insert hooks here for targets, hosts, and transport classes */
if (sdev->request_queue->dev) {
pm_runtime_mark_last_busy(dev);
- pm_runtime_autosuspend(dev);
- return -EBUSY;
+ err = pm_runtime_autosuspend(dev);
+ } else {
+ err = pm_runtime_suspend(dev);
}
+ } else {
+ err = pm_runtime_suspend(dev);
}
- return 0;
+ return err;
}
int scsi_autopm_get_device(struct scsi_device *sdev)
static int default_platform_runtime_idle(struct device *dev)
{
/* suspend synchronously to disable clocks immediately */
- return 0;
+ return pm_runtime_suspend(dev);
}
static struct dev_pm_domain default_pm_domain = {
tristate "Memory-mapped io interface driver for DW SPI core"
depends on SPI_DESIGNWARE && HAVE_CLK
-config SPI_ROCKCHIP_CORE
- tristate "ROCKCHIP SPI controller core support"
- help
- general driver for SPI controller core from ROCKCHIP
-
-config SPI_ROCKCHIP
- tristate "ROCKCHIP SPI interface driver"
- depends on SPI_ROCKCHIP_CORE
-
-config SPI_ROCKCHIP_DMA
- bool "DMA support for ROCKCHIP SPI"
- depends on SPI_ROCKCHIP
-
-config SPI_ROCKCHIP_TEST
- bool "ROCKCHIP spi test code"
- depends on SPI_ROCKCHIP
-
#
# There are lots of SPI device types, with sensors and memory
# being probably the most widely used ones.
obj-$(CONFIG_SPI_TXX9) += spi-txx9.o
obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
-obj-$(CONFIG_SPI_ROCKCHIP_CORE) += spi-rockchip-core.o
-obj-$(CONFIG_SPI_ROCKCHIP_DMA) += spi-rockchip-dma.o
-obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
-obj-$(CONFIG_SPI_ROCKCHIP_TEST) += spi-rockchip-test.o
\ No newline at end of file
SET_RUNTIME_PM_OPS(
pm_generic_runtime_suspend,
pm_generic_runtime_resume,
- NULL
+ pm_generic_runtime_idle
)
};
It is, in theory, a good memory allocator for low-memory devices,
because it can discard shared memory units when under memory pressure.
-config ANDROID_LOGGER
- tristate "Android log driver"
- default n
- ---help---
- This adds support for system-wide logging using four log buffers.
-
- These are:
-
- 1: main
- 2: events
- 3: radio
- 4: system
-
- Log reading and writing is performed via normal Linux reads and
- optimized writes. This optimization avoids logging having too
- much overhead in the system.
-
config ANDROID_TIMED_OUTPUT
bool "Timed output class driver"
default y
/sys/module/lowmemorykiller/parameters/adj and convert them
to oom_score_adj values.
-config ANDROID_INTF_ALARM_DEV
- bool "Android alarm driver"
- depends on RTC_CLASS
- default n
- ---help---
- Provides non-wakeup and rtc backed wakeup alarms based on rtc or
- elapsed realtime, and a non-wakeup alarm on the monotonic clock.
- Also exports the alarm interface to user-space.
-
config SYNC
bool "Synchronization framework"
default n
obj-$(CONFIG_FIQ_DEBUGGER) += fiq_debugger/
obj-$(CONFIG_ASHMEM) += ashmem.o
-obj-$(CONFIG_ANDROID_LOGGER) += logger.o
obj-$(CONFIG_ANDROID_TIMED_OUTPUT) += timed_output.o
obj-$(CONFIG_ANDROID_TIMED_GPIO) += timed_gpio.o
obj-$(CONFIG_ANDROID_LOW_MEMORY_KILLER) += lowmemorykiller.o
-obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
obj-$(CONFIG_SYNC) += sync.o
obj-$(CONFIG_SW_SYNC) += sw_sync.o
select FIQ_DEBUGGER
select PSTORE_RAM
default n
-
-config FIQ_DEBUGGER_EL3_TO_EL1
- bool "Uart FIQ is captured by EL3, then passed to EL1"
- depends on FIQ_DEBUGGER && ARM64
- default n
- help
- It is for ARM V8 arch.
#endif
#include <linux/uaccess.h>
-#include <linux/rockchip/grf.h>
-#include <linux/rockchip/iomap.h>
-#include <linux/rockchip/cpu.h>
#include "fiq_debugger.h"
#include "fiq_debugger_priv.h"
#include "fiq_debugger_ringbuf.h"
-#ifdef CONFIG_RK29_WATCHDOG
-extern void rk29_wdt_keepalive(void);
-#define wdt_keepalive() rk29_wdt_keepalive()
-#else
-#define wdt_keepalive() do {} while (0)
-#endif
#define DEBUG_MAX 64
-#define CMD_COUNT 0x0f
#define MAX_UNHANDLED_FIQ_COUNT 1000000
-#ifdef CONFIG_ARCH_ROCKCHIP
-#define MAX_FIQ_DEBUGGER_PORTS 1
-#else
#define MAX_FIQ_DEBUGGER_PORTS 4
-#endif
struct fiq_debugger_state {
#ifdef CONFIG_FIQ_GLUE
char debug_buf[DEBUG_MAX];
int debug_count;
-#ifdef CONFIG_ARCH_ROCKCHIP
- char cmd_buf[CMD_COUNT+1][DEBUG_MAX];
- int back_pointer;
- int current_pointer;
-#endif
bool no_sleep;
bool debug_enable;
bool ignore_next_wakeup_irq;
bool syslog_dumping;
#endif
-#ifdef CONFIG_ARCH_ROCKCHIP
- unsigned int last_irqs[1024];
- unsigned int last_local_irqs[NR_CPUS][32];
-#else
unsigned int last_irqs[NR_IRQS];
unsigned int last_local_timer_irqs[NR_CPUS];
-#endif
};
#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
static bool initial_console_enable;
#endif
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
-static struct fiq_debugger_state *state_tf;
-#endif
-
static bool fiq_kgdb_enable;
-static unsigned long jif = 0, recv_count0 = 0, recv_count1 = 0;
-
module_param_named(no_sleep, initial_no_sleep, bool, 0644);
module_param_named(debug_enable, initial_debug_enable, bool, 0644);
module_param_named(console_enable, initial_console_enable, bool, 0644);
module_param_named(kgdb_enable, fiq_kgdb_enable, bool, 0644);
-void gic_set_irq_secure(struct irq_data *d);
-void gic_set_irq_priority(struct irq_data *d, u8 pri);
-
#ifdef CONFIG_FIQ_DEBUGGER_WAKEUP_IRQ_ALWAYS_ON
static inline
void fiq_debugger_enable_wakeup_irq(struct fiq_debugger_state *state) {}
return (state->fiq >= 0);
}
-#if defined(CONFIG_FIQ_GLUE) || defined(CONFIG_FIQ_DEBUGGER_EL3_TO_EL1)
+#ifdef CONFIG_FIQ_GLUE
static void fiq_debugger_force_irq(struct fiq_debugger_state *state)
{
unsigned int irq = state->signal_irq;
if (WARN_ON(!fiq_debugger_have_fiq(state)))
return;
- if (irq < 0)
- return;
if (state->pdata->force_irq) {
state->pdata->force_irq(state->pdev, irq);
} else {
static void fiq_debugger_dump_kernel_log(struct fiq_debugger_state *state)
{
-#ifdef CONFIG_ARCH_ROCKCHIP
- char buf[968];
-#else
char buf[512];
-#endif
size_t len;
struct kmsg_dumper dumper = { .active = true };
sizeof(buf) - 1, &len)) {
buf[len] = 0;
fiq_debugger_puts(state, buf);
-#ifdef CONFIG_ARCH_ROCKCHIP
- wdt_keepalive();
-#endif
}
}
-#ifdef CONFIG_RK_LAST_LOG
-#include <linux/ctype.h>
-extern char *rk_last_log_get(unsigned *size);
-static void fiq_debugger_dump_last_kernel_log(struct fiq_debugger_state *state)
-{
- unsigned size, i, c;
- char *s = rk_last_log_get(&size);
-
- for (i = 0; i < size; i++) {
- if (i % 1024 == 0)
- wdt_keepalive();
- c = s[i];
- if (c == '\n') {
- state->pdata->uart_putc(state->pdev, '\r');
- state->pdata->uart_putc(state->pdev, c);
- } else if (isascii(c) && isprint(c)) {
- state->pdata->uart_putc(state->pdev, c);
- }
- }
-}
-#endif
-
static void fiq_debugger_printf(struct fiq_debugger_output *output,
const char *fmt, ...)
{
static void fiq_debugger_dump_irqs(struct fiq_debugger_state *state)
{
int n;
- unsigned int cpu;
struct irq_desc *desc;
fiq_debugger_printf(&state->output,
(act && act->name) ? act->name : "???");
state->last_irqs[n] = kstat_irqs(n);
}
-
-#ifdef CONFIG_ARCH_ROCKCHIP
- for (n = 16; n < 32; n++) {
- desc = irq_to_desc(n);
- if (!desc)
- continue;
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- unsigned int irqs = kstat_irqs_cpu(n, cpu);
- struct irqaction *act = desc->action;
- const char *name = (act && act->name) ? act->name : "???";
- if (!irqs)
- continue;
- fiq_debugger_printf(&state->output,
- "%5d: %10u %11u %s (CPU%d)\n", n,
- irqs, irqs - state->last_local_irqs[cpu][n],
- name, cpu);
- state->last_local_irqs[cpu][n] = irqs;
- }
- }
- for (n = 0; n < NR_IPI; n++) {
-#define S(x,s) [x] = s
-#ifdef CONFIG_ARM
- enum ipi_msg_type {
- IPI_WAKEUP,
- IPI_TIMER,
- IPI_RESCHEDULE,
- IPI_CALL_FUNC,
- IPI_CALL_FUNC_SINGLE,
- IPI_CPU_STOP,
- IPI_COMPLETION,
- IPI_CPU_BACKTRACE,
- };
- static const char *ipi_types[NR_IPI] = {
- S(IPI_WAKEUP, "CPU wakeup"),
- S(IPI_TIMER, "Timer broadcast"),
- S(IPI_RESCHEDULE, "Rescheduling"),
- S(IPI_CALL_FUNC, "Function call"),
- S(IPI_CALL_FUNC_SINGLE, "Single function call"),
- S(IPI_CPU_STOP, "CPU stop"),
- S(IPI_COMPLETION, "Completion"),
- S(IPI_CPU_BACKTRACE, "CPU backtrace"),
- };
-#elif defined(CONFIG_ARM64)
- enum ipi_msg_type {
- IPI_RESCHEDULE,
- IPI_CALL_FUNC,
- IPI_CALL_FUNC_SINGLE,
- IPI_CPU_STOP,
- IPI_TIMER,
- };
- static const char *ipi_types[NR_IPI] = {
- S(IPI_RESCHEDULE, "Rescheduling"),
- S(IPI_CALL_FUNC, "Function call"),
- S(IPI_CALL_FUNC_SINGLE, "Single function call"),
- S(IPI_CPU_STOP, "CPU stop"),
- S(IPI_TIMER, "Timer broadcast"),
- };
-#endif
-#undef S
- for (cpu = 0; cpu < NR_CPUS; cpu++) {
- unsigned int irqs = __get_irq_stat(cpu, ipi_irqs[n]);
- if (irqs == 0)
- continue;
- fiq_debugger_printf(&state->output,
- "%5d: %10u %11u %s (CPU%d)\n",
- n, irqs, irqs - state->last_local_irqs[cpu][n],
- ipi_types[n], cpu);
- state->last_local_irqs[cpu][n] = irqs;
- }
- }
-#endif
}
static void fiq_debugger_do_ps(struct fiq_debugger_state *state)
/* This function CANNOT be called in FIQ context */
static void fiq_debugger_irq_exec(struct fiq_debugger_state *state, char *cmd)
{
- int invalid_cmd = 0;
if (!strcmp(cmd, "ps"))
fiq_debugger_do_ps(state);
if (!strcmp(cmd, "sysrq"))
#endif
if (!strncmp(cmd, "reboot", 6))
fiq_debugger_schedule_work(state, cmd);
-#ifdef CONFIG_ARCH_ROCKCHIP
- else {
- invalid_cmd = 1;
- memset(state->debug_buf, 0, DEBUG_MAX);
- }
-
- if (invalid_cmd == 0) {
- state->current_pointer = (state->current_pointer-1) & CMD_COUNT;
- if (strcmp(state->cmd_buf[state->current_pointer], state->debug_buf)) {
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
- memset(state->cmd_buf[state->current_pointer], 0, DEBUG_MAX);
- strcpy(state->cmd_buf[state->current_pointer], state->debug_buf);
- }
- memset(state->debug_buf, 0, DEBUG_MAX);
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
- state->back_pointer = state->current_pointer;
- }
-#endif
}
-#ifdef CONFIG_ARCH_ROCKCHIP
-static char cmd_buf[][16] = {
- {"pc"},
- {"regs"},
- {"allregs"},
- {"bt"},
- {"reboot"},
- {"irqs"},
- {"kmsg"},
-#ifdef CONFIG_RK_LAST_LOG
- {"last_kmsg"},
-#endif
- {"version"},
- {"sleep"},
- {"nosleep"},
- {"console"},
- {"cpu"},
- {"ps"},
- {"sysrq"},
- {"reset"},
-#ifdef CONFIG_KGDB
- {"kgdb"},
-#endif
-};
-#endif
-
-
static void fiq_debugger_help(struct fiq_debugger_state *state)
{
fiq_debugger_printf(&state->output,
" irqs Interupt status\n"
" kmsg Kernel log\n"
" version Kernel version\n");
-#ifdef CONFIG_RK_LAST_LOG
- fiq_debugger_printf(&state->output,
- " last_kmsg Last kernel log\n");
-#endif
fiq_debugger_printf(&state->output,
" sleep Allow sleep while in FIQ\n"
" nosleep Disable sleep while in FIQ\n"
if (!fiq_debugger_have_fiq(state))
smp_call_function_single(cpu, fiq_debugger_take_affinity, state,
false);
-#ifdef CONFIG_ARCH_ROCKCHIP
- else {
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (state->pdata->switch_cpu)
- state->pdata->switch_cpu(state->pdev, cpu);
-#else
- struct cpumask cpumask;
-
- if (!cpu_online(cpu)) {
- fiq_debugger_printf(&state->output, "cpu %d offline\n", cpu);
- return;
- }
-
- cpumask_clear(&cpumask);
- cpumask_set_cpu(cpu, &cpumask);
-
- irq_set_affinity(state->fiq, &cpumask);
- irq_set_affinity(state->uart_irq, &cpumask);
-#endif
- }
-#endif
state->current_cpu = cpu;
}
fiq_debugger_dump_irqs(state);
} else if (!strcmp(cmd, "kmsg")) {
fiq_debugger_dump_kernel_log(state);
-#ifdef CONFIG_RK_LAST_LOG
- } else if (!strcmp(cmd, "last_kmsg")) {
- fiq_debugger_dump_last_kernel_log(state);
-#endif
} else if (!strcmp(cmd, "version")) {
fiq_debugger_printf(&state->output, "%s\n", linux_banner);
} else if (!strcmp(cmd, "sleep")) {
fiq_debugger_printf(&state->output, "console mode\n");
fiq_debugger_uart_flush(state);
state->console_enable = true;
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (state->pdata->enable_debug)
- state->pdata->enable_debug(state->pdev, false);
-#endif
} else if (!strcmp(cmd, "cpu")) {
fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
} else if (!strncmp(cmd, "cpu ", 4)) {
return state->pdata->uart_getc(state->pdev);
}
-static int fiq_debugger_cmd_check_back(struct fiq_debugger_state *state, char c)
-{
- char *s;
- int i = 0;
- if (c == 'A') {
- state->back_pointer = (state->back_pointer-1) & CMD_COUNT;
- if (state->back_pointer != state->current_pointer) {
- s = state->cmd_buf[state->back_pointer];
- if (*s != 0) {
- for(i = 0; i < strlen(state->debug_buf)-1; i++) {
- state->pdata->uart_putc(state->pdev, 8);
- state->pdata->uart_putc(state->pdev, ' ');
- state->pdata->uart_putc(state->pdev, 8);
- }
- memset(state->debug_buf, 0, DEBUG_MAX);
- strcpy(state->debug_buf, s);
- state->debug_count = strlen(state->debug_buf);
- fiq_debugger_printf(&state->output, state->debug_buf);
- } else {
- state->back_pointer = (state->back_pointer+1) & CMD_COUNT;
- }
-
- } else {
- state->back_pointer = (state->back_pointer+1) & CMD_COUNT;
- }
- } else if (c == 'B') {
-
- if (state->back_pointer != state->current_pointer) {
- state->back_pointer = (state->back_pointer+1) & CMD_COUNT;
- if(state->back_pointer == state->current_pointer){
- goto cmd_clear;
- } else {
- s = state->cmd_buf[state->back_pointer];
- if (*s != 0) {
- for(i = 0; i < strlen(state->debug_buf)-1; i++) {
- state->pdata->uart_putc(state->pdev, 8);
- state->pdata->uart_putc(state->pdev, ' ');
- state->pdata->uart_putc(state->pdev, 8);
- }
- memset(state->debug_buf, 0, DEBUG_MAX);
- strcpy(state->debug_buf, s);
- state->debug_count = strlen(state->debug_buf);
- fiq_debugger_printf(&state->output, state->debug_buf);
- }
- }
- } else {
-cmd_clear:
- for(i = 0; i < strlen(state->debug_buf)-1; i++) {
- state->pdata->uart_putc(state->pdev, 8);
- state->pdata->uart_putc(state->pdev, ' ');
- state->pdata->uart_putc(state->pdev, 8);
- }
- memset(state->debug_buf, 0, DEBUG_MAX);
- state->debug_count = 0;
- }
- }
- return 0;
-}
-
-static void fiq_debugger_cmd_tab(struct fiq_debugger_state *state)
-{
- int i,j;
- int count = 0;
-
- for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) {
- cmd_buf[i][15] = 1;
- }
-
- for (j = 1; j <= strlen(state->debug_buf); j++) {
- count = 0;
- for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) {
- if (cmd_buf[i][15] == 1) {
- if (strncmp(state->debug_buf, cmd_buf[i], j)) {
- cmd_buf[i][15] = 0;
- } else {
- count++;
- }
- }
- }
- if (count == 0)
- break;
- }
-
- if (count == 1) {
- for (i = 0; i < ARRAY_SIZE(cmd_buf); i++) {
- if (cmd_buf[i][15] == 1)
- break;
- }
-
- for(j = 0; j < strlen(state->debug_buf); j++) {
- state->pdata->uart_putc(state->pdev, 8);
- state->pdata->uart_putc(state->pdev, ' ');
- state->pdata->uart_putc(state->pdev, 8);
- }
- memset(state->debug_buf, 0, DEBUG_MAX);
- strcpy(state->debug_buf, cmd_buf[i]);
- state->debug_count = strlen(state->debug_buf);
- fiq_debugger_printf(&state->output, state->debug_buf);
-
- }
-}
-
static bool fiq_debugger_handle_uart_interrupt(struct fiq_debugger_state *state,
int this_cpu, const struct pt_regs *regs, void *svc_sp)
{
static int last_c;
int count = 0;
bool signal_helper = false;
- unsigned long ms = 0;
if (this_cpu != state->current_cpu) {
if (state->in_fiq)
state->in_fiq = true;
while ((c = fiq_debugger_getc(state)) != FIQ_DEBUGGER_NO_CHAR) {
- recv_count0++;
- if((recv_count0 - recv_count1) > 128) {
- ms = jiffies_to_msecs(jiffies - jif);
- if(ms < 1000) {
- if(cpu_is_rk3288()){
- writel_relaxed((0x00c0 << 16),
- RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
- }
- }
- jif = jiffies;
- recv_count1 = recv_count0;
- }
- count++;
+ count++;
if (!state->debug_enable) {
if ((c == 13) || (c == 10)) {
state->debug_enable = true;
}
} else if (c == FIQ_DEBUGGER_BREAK) {
state->console_enable = false;
-#ifdef CONFIG_ARCH_ROCKCHIP
- fiq_debugger_puts(state, "\nWelcome to ");
-#endif
- if (fiq_debugger_have_fiq(state))
- fiq_debugger_puts(state,
- "fiq debugger mode\n");
- else
- fiq_debugger_puts(state,
- "irq debugger mode\n");
-
+ fiq_debugger_puts(state, "fiq debugger mode\n");
state->debug_count = 0;
-#ifdef CONFIG_ARCH_ROCKCHIP
- fiq_debugger_puts(state, "Enter ? to get command help\n");
- state->back_pointer = CMD_COUNT;
- state->current_pointer = CMD_COUNT;
- memset(state->cmd_buf, 0, (CMD_COUNT+1)*DEBUG_MAX);
-#endif
-
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (state->pdata->enable_debug)
- state->pdata->enable_debug(state->pdev, true);
-#endif
fiq_debugger_prompt(state);
#ifdef CONFIG_FIQ_DEBUGGER_CONSOLE
} else if (state->console_enable && state->tty_rbuf) {
fiq_debugger_ringbuf_push(state->tty_rbuf, c);
signal_helper = true;
-#endif
-#ifdef CONFIG_ARCH_ROCKCHIP
- } else if (last_c == '[' && (c == 'A' || c == 'B' || c == 'C' || c == 'D')) {
- if (state->debug_count > 0) {
- state->debug_count--;
- state->pdata->uart_putc(state->pdev, 8);
- state->pdata->uart_putc(state->pdev, ' ');
- state->pdata->uart_putc(state->pdev, 8);
- }
- fiq_debugger_cmd_check_back(state, c);
- //tab
- } else if (c == 9) {
- fiq_debugger_cmd_tab(state);
#endif
} else if ((c >= ' ') && (c < 127)) {
if (state->debug_count < (DEBUG_MAX - 1)) {
signal_helper |=
fiq_debugger_fiq_exec(state,
state->debug_buf,
- regs, svc_sp);
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (signal_helper == false) {
- state->current_pointer = (state->current_pointer-1) & CMD_COUNT;
- if (strcmp(state->cmd_buf[state->current_pointer], state->debug_buf)) {
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
- memset(state->cmd_buf[state->current_pointer], 0, DEBUG_MAX);
- strcpy(state->cmd_buf[state->current_pointer], state->debug_buf);
- }
- memset(state->debug_buf, 0, DEBUG_MAX);
- state->current_pointer = (state->current_pointer+1) & CMD_COUNT;
- state->back_pointer = state->current_pointer;
- }
-#endif
+ regs, svc_sp);
} else {
fiq_debugger_prompt(state);
}
#ifdef CONFIG_FIQ_GLUE
static void fiq_debugger_fiq(struct fiq_glue_handler *h,
- void *regs, void *svc_sp)
+ const struct pt_regs *regs, void *svc_sp)
{
struct fiq_debugger_state *state =
container_of(h, struct fiq_debugger_state, handler);
unsigned int this_cpu = THREAD_INFO(svc_sp)->cpu;
bool need_irq;
- /* RK2928 USB-UART function, otg dp/dm default in uart status;
- * connect with otg cable&usb device, dp/dm will be hi-z status
- * and make uart controller enter infinite fiq loop
- */
-#ifdef CONFIG_RK_USB_UART
- if (cpu_is_rk3188()) {
- if (!(readl_relaxed(RK_GRF_VIRT + RK3188_GRF_SOC_STATUS0) & (1 << 13)) ||
- (readl_relaxed(RK_GRF_VIRT + RK3188_GRF_SOC_STATUS0) & (1 << 10))) {
- /* id low or bvalid high, enter usb phy */
- writel_relaxed((0x0300 << 16), RK_GRF_VIRT + RK3188_GRF_UOC0_CON0);
- }
- } else if (cpu_is_rk3288()) {
- if (!(readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2) & (1 << 17)) ||
- (readl_relaxed(RK_GRF_VIRT + RK3288_GRF_SOC_STATUS2) & (1 << 14))) {
- /* id low or bvalid high, enter usb phy */
- writel_relaxed((0x00c0 << 16), RK_GRF_VIRT + RK3288_GRF_UOC0_CON3);
- }
- }
-#endif
need_irq = fiq_debugger_handle_uart_interrupt(state, this_cpu, regs,
svc_sp);
if (need_irq)
return IRQ_HANDLED;
}
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
-void fiq_debugger_fiq(void *regs)
-{
- struct fiq_debugger_state *state = state_tf;
- bool need_irq;
-
- if (!state)
- return;
- need_irq = fiq_debugger_handle_uart_interrupt(state, smp_processor_id(),
- regs,
- current_thread_info());
- if (need_irq)
- fiq_debugger_force_irq(state);
-}
-#endif
-
/*
* If FIQs are used, not everything can happen in fiq context.
* FIQ handler does what it can and then signals this interrupt to finish the
if (!state->console_enable && !state->syslog_dumping)
return;
-#ifdef CONFIG_RK_CONSOLE_THREAD
- if (state->pdata->console_write) {
- state->pdata->console_write(state->pdev, s, count);
- return;
- }
-#endif
-
fiq_debugger_uart_enable(state);
spin_lock_irqsave(&state->console_lock, flags);
while (count--) {
state->console_enable = initial_console_enable;
state->fiq = fiq;
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- if (fiq > 0)
- state->uart_irq = fiq;
- else
- state->uart_irq = uart_irq;
-#else
state->uart_irq = uart_irq;
-#endif
-
state->signal_irq = platform_get_irq_byname(pdev, "signal");
state->wakeup_irq = platform_get_irq_byname(pdev, "wakeup");
pr_err("%s: could not install fiq handler\n", __func__);
goto err_register_irq;
}
-#ifdef CONFIG_ARCH_ROCKCHIP
- //set state->fiq to secure state, so fiq is avalable
- gic_set_irq_secure(irq_get_irq_data(state->fiq));
- //set state->fiq priority a little higher than other interrupts (normal is 0xa0)
- gic_set_irq_priority(irq_get_irq_data(state->fiq), 0x90);
-#endif
+
pdata->fiq_enable(pdev, state->fiq, 1);
} else
#endif
if (state->no_sleep)
fiq_debugger_handle_wakeup(state);
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- state_tf = state;
-#endif
-
#if defined(CONFIG_FIQ_DEBUGGER_CONSOLE)
spin_lock_init(&state->console_lock);
state->console = fiq_debugger_console;
void (*force_irq)(struct platform_device *pdev, unsigned int irq);
void (*force_irq_ack)(struct platform_device *pdev, unsigned int irq);
-
-#ifdef CONFIG_RK_CONSOLE_THREAD
- void (*console_write)(struct platform_device *pdev, const char *s,
- unsigned int count);
-#endif
-
-#ifdef CONFIG_FIQ_DEBUGGER_EL3_TO_EL1
- void (*switch_cpu)(struct platform_device *pdev, u32 cpu);
- void (*enable_debug)(struct platform_device *pdev, bool val);
-#endif
};
#endif
help
Choose this option if you wish to use ion on an nVidia Tegra.
-config ION_ROCKCHIP
- tristate "Ion for Rockchip"
- depends on ARCH_ROCKCHIP && ION
- select ARM_HAS_SG_CHAIN
- help
- Choose this option if you wish to use ion on an Rockchip.
-
-if ION_ROCKCHIP
-
-config ION_CMA_HIGHMEM
- bool "CMA Support HighMem Zone"
- depends on ION_ROCKCHIP && CMA
- help
- Choose this option to support CMA regions placed in highmem zone.
- This will allocate memory from CMA regions without mapping.
-
-config ION_ROCKCHIP_SNAPSHOT
- bool "Snapshot for rockchip ion"
- depends on ION_ROCKCHIP
- help
- Provide ion snapshot for debug
-
-config ION_SNAPSHOT_BUF_SHIFT
- int "ION snapshot buffer size (18 => 256KB, 19 => 512KB)"
- depends on ION_ROCKCHIP_SNAPSHOT
- range 12 21
- default 18
- help
- Select ION snapshot buffer size as a power of 2
-
-endif
-
config ION_POOL_CACHE_POLICY
bool "Ion set page pool cache policy"
depends on ION
obj-$(CONFIG_ION) += ion.o ion_heap.o ion_page_pool.o ion_system_heap.o \
- ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o \
- ion_drm_heap.o
+ ion_carveout_heap.o ion_chunk_heap.o ion_cma_heap.o
obj-$(CONFIG_ION_TEST) += ion_test.o
ifdef CONFIG_COMPAT
obj-$(CONFIG_ION) += compat_ion.o
obj-$(CONFIG_ION_DUMMY) += ion_dummy_driver.o
obj-$(CONFIG_ION_TEGRA) += tegra/
-obj-$(CONFIG_ION_ROCKCHIP) += rockchip/
+
#include <linux/debugfs.h>
#include <linux/dma-buf.h>
#include <linux/idr.h>
-#include <linux/rockchip_ion.h>
-#include <linux/dma-contiguous.h>
#include "ion.h"
#include "ion_priv.h"
#include "compat_ion.h"
-#define CREATE_TRACE_POINTS
-#include "../trace/ion.h"
-
/**
* struct ion_device - the metadata of the ion device node
* @dev: the actual misc device
int id;
};
-#ifdef CONFIG_ROCKCHIP_IOMMU
-static void ion_iommu_force_unmap(struct ion_buffer *buffer);
-#endif
-#ifdef CONFIG_ION_ROCKCHIP_SNAPSHOT
-extern char *rockchip_ion_snapshot_get(size_t *size);
-extern int rockchip_ion_snapshot_debugfs(struct dentry* root);
-static int ion_snapshot_save(struct ion_device *idev, size_t len);
-#endif
-
bool ion_buffer_fault_user_mappings(struct ion_buffer *buffer)
{
return (buffer->flags & ION_FLAG_CACHED) &&
allocation via dma_map_sg. The implicit contract here is that
memory comming from the heaps is ready for dma, ie if it has a
cached mapping that mapping has been invalidated */
- for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i) {
+ for_each_sg(buffer->sg_table->sgl, sg, buffer->sg_table->nents, i)
sg_dma_address(sg) = sg_phys(sg);
-#ifdef CONFIG_NEED_SG_DMA_LENGTH
- sg_dma_len(sg) = sg->length;
-#endif
- }
mutex_lock(&dev->buffer_lock);
ion_buffer_add(dev, buffer);
mutex_unlock(&dev->buffer_lock);
void ion_buffer_destroy(struct ion_buffer *buffer)
{
- trace_ion_buffer_destroy("", (void*)buffer, buffer->size);
-
if (WARN_ON(buffer->kmap_cnt > 0))
buffer->heap->ops->unmap_kernel(buffer->heap, buffer);
buffer->heap->ops->unmap_dma(buffer->heap, buffer);
-#ifdef CONFIG_ROCKCHIP_IOMMU
- ion_iommu_force_unmap(buffer);
-#endif
buffer->heap->ops->free(buffer);
if (buffer->pages)
vfree(buffer->pages);
return handle->buffer;
}
-void ion_handle_get(struct ion_handle *handle)
+static void ion_handle_get(struct ion_handle *handle)
{
kref_get(&handle->ref);
}
-int ion_handle_put(struct ion_handle *handle)
+static int ion_handle_put(struct ion_handle *handle)
{
struct ion_client *client = handle->client;
int ret;
return ERR_PTR(-EINVAL);
}
-struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
+static struct ion_handle *ion_handle_get_by_id(struct ion_client *client,
int id)
{
struct ion_handle *handle;
if (buffer == NULL)
return ERR_PTR(-ENODEV);
- if (IS_ERR(buffer)) {
-#ifdef CONFIG_ION_ROCKCHIP_SNAPSHOT
- ion_snapshot_save(client->dev, len);
-#endif
+ if (IS_ERR(buffer))
return ERR_PTR(PTR_ERR(buffer));
- }
handle = ion_handle_create(client, buffer);
handle = ERR_PTR(ret);
}
- trace_ion_buffer_alloc(client->display_name, (void*)buffer,
- buffer->size);
-
return handle;
}
EXPORT_SYMBOL(ion_alloc);
return;
}
mutex_unlock(&client->lock);
- trace_ion_buffer_free(client->display_name, (void*)handle->buffer,
- handle->buffer->size);
ion_handle_put(handle);
}
EXPORT_SYMBOL(ion_free);
vaddr = ion_handle_kmap_get(handle);
mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock);
- trace_ion_kernel_map(client->display_name, (void*)buffer,
- buffer->size, (void*)vaddr);
return vaddr;
}
EXPORT_SYMBOL(ion_map_kernel);
mutex_lock(&client->lock);
buffer = handle->buffer;
mutex_lock(&buffer->lock);
- trace_ion_kernel_unmap(client->display_name, (void*)buffer,
- buffer->size);
ion_handle_kmap_put(handle);
mutex_unlock(&buffer->lock);
mutex_unlock(&client->lock);
}
EXPORT_SYMBOL(ion_unmap_kernel);
-#ifdef CONFIG_ROCKCHIP_IOMMU
-static void ion_iommu_add(struct ion_buffer *buffer,
- struct ion_iommu_map *iommu)
-{
- struct rb_node **p = &buffer->iommu_maps.rb_node;
- struct rb_node *parent = NULL;
- struct ion_iommu_map *entry;
-
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct ion_iommu_map, node);
-
- if (iommu->key < entry->key) {
- p = &(*p)->rb_left;
- } else if (iommu->key > entry->key) {
- p = &(*p)->rb_right;
- } else {
- pr_err("%s: buffer %p already has mapping for domainid %lx\n",
- __func__,
- buffer,
- iommu->key);
- BUG();
- }
- }
-
- rb_link_node(&iommu->node, parent, p);
- rb_insert_color(&iommu->node, &buffer->iommu_maps);
-}
-
-static struct ion_iommu_map *ion_iommu_lookup(struct ion_buffer *buffer,
- unsigned long key)
-{
- struct rb_node **p = &buffer->iommu_maps.rb_node;
- struct rb_node *parent = NULL;
- struct ion_iommu_map *entry;
-
- while (*p) {
- parent = *p;
- entry = rb_entry(parent, struct ion_iommu_map, node);
-
- if (key < entry->key)
- p = &(*p)->rb_left;
- else if (key > entry->key)
- p = &(*p)->rb_right;
- else
- return entry;
- }
-
- return NULL;
-}
-
-static struct ion_iommu_map *__ion_iommu_map(struct ion_buffer *buffer,
- struct device *iommu_dev, unsigned long *iova)
-{
- struct ion_iommu_map *data;
- int ret;
-
- data = kmalloc(sizeof(*data), GFP_ATOMIC);
-
- if (!data)
- return ERR_PTR(-ENOMEM);
-
- data->buffer = buffer;
- data->key = (unsigned long)iommu_dev;
-
- ret = buffer->heap->ops->map_iommu(buffer, iommu_dev, data,
- buffer->size, buffer->flags);
- if (ret)
- goto out;
-
- kref_init(&data->ref);
- *iova = data->iova_addr;
-
- ion_iommu_add(buffer, data);
-
- return data;
-
-out:
- kfree(data);
- return ERR_PTR(ret);
-}
-
-int ion_map_iommu(struct device *iommu_dev, struct ion_client *client,
- struct ion_handle *handle, unsigned long *iova, unsigned long *size)
-{
- struct ion_buffer *buffer;
- struct ion_iommu_map *iommu_map;
- int ret = 0;
-
- mutex_lock(&client->lock);
- if (!ion_handle_validate(client, handle)) {
- pr_err("%s: invalid handle passed to map_kernel.\n",
- __func__);
- mutex_unlock(&client->lock);
- return -EINVAL;
- }
-
- buffer = handle->buffer;
- pr_debug("%s: map buffer(%p)\n", __func__, buffer);
-
- mutex_lock(&buffer->lock);
-
- if (!handle->buffer->heap->ops->map_iommu) {
- pr_err("%s: map_iommu is not implemented by this heap.\n",
- __func__);
- ret = -ENODEV;
- goto out;
- }
-
- if (buffer->size & ~PAGE_MASK) {
- pr_debug("%s: buffer size %zu is not aligned to %lx", __func__,
- buffer->size, PAGE_SIZE);
- ret = -EINVAL;
- goto out;
- }
-
- iommu_map = ion_iommu_lookup(buffer, (unsigned long)iommu_dev);
- if (!iommu_map) {
- pr_debug("%s: create new map for buffer(%p)\n", __func__, buffer);
- iommu_map = __ion_iommu_map(buffer, iommu_dev, iova);
- if (IS_ERR(iommu_map))
- ret = PTR_ERR(iommu_map);
- } else {
- pr_debug("%s: buffer(%p) already mapped\n", __func__, buffer);
- if (iommu_map->mapped_size != buffer->size) {
- pr_err("%s: handle %p is already mapped with length"
- " %d, trying to map with length %zu\n",
- __func__, handle, iommu_map->mapped_size, buffer->size);
- ret = -EINVAL;
- } else {
- kref_get(&iommu_map->ref);
- *iova = iommu_map->iova_addr;
- }
- }
- if (!ret)
- buffer->iommu_map_cnt++;
- *size = buffer->size;
- trace_ion_iommu_map(client->display_name, (void*)buffer, buffer->size,
- dev_name(iommu_dev), *iova, *size, buffer->iommu_map_cnt);
-out:
- mutex_unlock(&buffer->lock);
- mutex_unlock(&client->lock);
- return ret;
-}
-EXPORT_SYMBOL(ion_map_iommu);
-
-static void ion_iommu_release(struct kref *kref)
-{
- struct ion_iommu_map *map = container_of(kref, struct ion_iommu_map,
- ref);
- struct ion_buffer *buffer = map->buffer;
-
- trace_ion_iommu_release("", (void*)buffer, buffer->size,
- "", map->iova_addr, map->mapped_size, buffer->iommu_map_cnt);
-
- rb_erase(&map->node, &buffer->iommu_maps);
- buffer->heap->ops->unmap_iommu((struct device*)map->key, map);
- kfree(map);
-}
-
-/**
- * Unmap any outstanding mappings which would otherwise have been leaked.
- */
-static void ion_iommu_force_unmap(struct ion_buffer *buffer)
-{
- struct ion_iommu_map *iommu_map;
- struct rb_node *node;
- const struct rb_root *rb = &(buffer->iommu_maps);
-
- pr_debug("%s: force unmap buffer(%p)\n", __func__, buffer);
-
- mutex_lock(&buffer->lock);
-
- while ((node = rb_first(rb)) != 0) {
- iommu_map = rb_entry(node, struct ion_iommu_map, node);
- /* set ref count to 1 to force release */
- kref_init(&iommu_map->ref);
- kref_put(&iommu_map->ref, ion_iommu_release);
- }
-
- mutex_unlock(&buffer->lock);
-}
-
-void ion_unmap_iommu(struct device *iommu_dev, struct ion_client *client,
- struct ion_handle *handle)
-{
- struct ion_iommu_map *iommu_map;
- struct ion_buffer *buffer;
-
- mutex_lock(&client->lock);
- buffer = handle->buffer;
- pr_debug("%s: unmap buffer(%p)\n", __func__, buffer);
-
- mutex_lock(&buffer->lock);
-
- iommu_map = ion_iommu_lookup(buffer, (unsigned long)iommu_dev);
-
- if (!iommu_map) {
- WARN(1, "%s: (%p) was never mapped for %p\n", __func__,
- iommu_dev, buffer);
- goto out;
- }
-
- buffer->iommu_map_cnt--;
-
- trace_ion_iommu_unmap(client->display_name, (void*)buffer, buffer->size,
- dev_name(iommu_dev), iommu_map->iova_addr,
- iommu_map->mapped_size, buffer->iommu_map_cnt);
-
- kref_put(&iommu_map->ref, ion_iommu_release);
-out:
- mutex_unlock(&buffer->lock);
- mutex_unlock(&client->lock);
-}
-EXPORT_SYMBOL(ion_unmap_iommu);
-
-static int ion_debug_client_show_buffer_map(struct seq_file *s, struct ion_buffer *buffer)
-{
- struct ion_iommu_map *iommu_map;
- const struct rb_root *rb;
- struct rb_node *node;
-
- pr_debug("%s: buffer(%p)\n", __func__, buffer);
-
- mutex_lock(&buffer->lock);
- rb = &(buffer->iommu_maps);
- node = rb_first(rb);
-
- while (node != NULL) {
- iommu_map = rb_entry(node, struct ion_iommu_map, node);
- seq_printf(s, "%16.16s: 0x%08lx 0x%08x 0x%08x %8zuKB %4d\n",
- "<iommu>", iommu_map->iova_addr, 0, 0,
- (size_t)iommu_map->mapped_size>>10,
- atomic_read(&iommu_map->ref.refcount));
-
- node = rb_next(node);
- }
-
- mutex_unlock(&buffer->lock);
-
- return 0;
-}
-#else
-int ion_map_iommu(struct device *iommu_dev, struct ion_client *client,
- struct ion_handle *handle, unsigned long *iova, unsigned long *size)
-{
- return 0;
-}
-void ion_unmap_iommu(struct device *iommu_dev, struct ion_client *client,
- struct ion_handle *handle)
-{
-}
-#endif
-
-static int ion_debug_client_show_buffer(struct seq_file *s, void *unused)
-{
- struct ion_client *client = s->private;
- struct rb_node *n;
-
- seq_printf(s, "----------------------------------------------------\n");
- seq_printf(s, "%16.s: %12.s %12.s %12.s %10.s %4.s %4.s %4.s\n",
- "heap_name", "VA", "PA", "IBUF", "size", "HC", "IBR", "IHR");
- mutex_lock(&client->lock);
- for (n = rb_first(&client->handles); n; n = rb_next(n)) {
- struct ion_handle *handle = rb_entry(n, struct ion_handle, node);
- struct ion_buffer *buffer = handle->buffer;
- ion_phys_addr_t pa = 0;
- size_t len = buffer->size;
-
- mutex_lock(&buffer->lock);
-
- if (buffer->heap->ops->phys)
- buffer->heap->ops->phys(buffer->heap, buffer, &pa, &len);
-
- seq_printf(s, "%16.16s: 0x%08lx 0x%08lx 0x%08lx %8zuKB %4d %4d %4d\n",
- buffer->heap->name, (unsigned long)buffer->vaddr, pa,
- (unsigned long)buffer, len>>10, buffer->handle_count,
- atomic_read(&buffer->ref.refcount),
- atomic_read(&handle->ref.refcount));
-
- mutex_unlock(&buffer->lock);
-
-#ifdef CONFIG_ROCKCHIP_IOMMU
- ion_debug_client_show_buffer_map(s, buffer);
-#endif
- }
- mutex_unlock(&client->lock);
-
- return 0;
-}
-
static int ion_debug_client_show(struct seq_file *s, void *unused)
{
struct ion_client *client = s->private;
continue;
seq_printf(s, "%16.16s: %16zu\n", names[i], sizes[i]);
}
- ion_debug_client_show_buffer(s, unused);
return 0;
}
path, client->display_name);
}
- trace_ion_client_create(client->display_name);
-
up_write(&dev->lock);
return client;
debugfs_remove_recursive(client->debug_root);
up_write(&dev->lock);
- trace_ion_client_destroy(client->display_name);
-
kfree(client->display_name);
kfree(client->name);
kfree(client);
pr_err("%s: failure mapping buffer to userspace\n",
__func__);
- trace_ion_buffer_mmap("", (void*)buffer, buffer->size,
- vma->vm_start, vma->vm_end);
-
return ret;
}
-int ion_munmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
-{
- struct ion_buffer *buffer = dmabuf->priv;
-
- trace_ion_buffer_munmap("", (void*)buffer, buffer->size,
- vma->vm_start, vma->vm_end);
-
- return 0;
-}
-
static void ion_dma_buf_release(struct dma_buf *dmabuf)
{
struct ion_buffer *buffer = dmabuf->priv;
if (fd < 0)
dma_buf_put(dmabuf);
- trace_ion_buffer_share(client->display_name, (void*)handle->buffer,
- handle->buffer->size, fd);
return fd;
}
EXPORT_SYMBOL(ion_share_dma_buf_fd);
mutex_unlock(&client->lock);
goto end;
}
+ mutex_unlock(&client->lock);
handle = ion_handle_create(client, buffer);
- if (IS_ERR(handle)) {
- mutex_unlock(&client->lock);
+ if (IS_ERR(handle))
goto end;
- }
+ mutex_lock(&client->lock);
ret = ion_handle_add(client, handle);
mutex_unlock(&client->lock);
if (ret) {
handle = ERR_PTR(ret);
}
- trace_ion_buffer_import(client->display_name, (void*)buffer,
- buffer->size);
end:
dma_buf_put(dmabuf);
return handle;
continue;
total_size += buffer->size;
if (!buffer->handle_count) {
- seq_printf(s, "%16.s %16u %16zu 0x%p %d %d\n",
+ seq_printf(s, "%16.s %16u %16zu %d %d\n",
buffer->task_comm, buffer->pid,
- buffer->size, buffer,
- buffer->kmap_cnt,
+ buffer->size, buffer->kmap_cnt,
atomic_read(&buffer->ref.refcount));
total_orphaned_size += buffer->size;
}
debug_shrink_set, "%llu\n");
#endif
-#ifdef CONFIG_CMA
-// struct "cma" quoted from drivers/base/dma-contiguous.c
-struct cma {
- unsigned long base_pfn;
- unsigned long count;
- unsigned long *bitmap;
-};
-
-// struct "ion_cma_heap" quoted from drivers/staging/android/ion/ion_cma_heap.c
-struct ion_cma_heap {
- struct ion_heap heap;
- struct device *dev;
-};
-
-static int ion_cma_heap_debug_show(struct seq_file *s, void *unused)
-{
- struct ion_heap *heap = s->private;
- struct ion_cma_heap *cma_heap = container_of(heap,
- struct ion_cma_heap,
- heap);
- struct device *dev = cma_heap->dev;
- struct cma *cma = dev_get_cma_area(dev);
- int i;
- int rows = cma->count/(SZ_1M >> PAGE_SHIFT);
- phys_addr_t base = __pfn_to_phys(cma->base_pfn);
-
- seq_printf(s, "%s Heap bitmap:\n", heap->name);
-
- for(i = rows - 1; i>= 0; i--){
- seq_printf(s, "%.4uM@0x%lx: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
- i+1, (unsigned long)base+(i)*SZ_1M,
- cma->bitmap[i*8 + 7],
- cma->bitmap[i*8 + 6],
- cma->bitmap[i*8 + 5],
- cma->bitmap[i*8 + 4],
- cma->bitmap[i*8 + 3],
- cma->bitmap[i*8 + 2],
- cma->bitmap[i*8 + 1],
- cma->bitmap[i*8]);
- }
- seq_printf(s, "Heap size: %luM, Heap base: 0x%lx\n",
- (cma->count)>>8, (unsigned long)base);
-
- return 0;
-}
-
-static int ion_debug_heap_bitmap_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ion_cma_heap_debug_show, inode->i_private);
-}
-
-static const struct file_operations debug_heap_bitmap_fops = {
- .open = ion_debug_heap_bitmap_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-#endif
-
-static ssize_t
-rockchip_ion_debug_write(struct file *filp, const char __user *ubuf, size_t cnt,
- loff_t *ppos)
-{
- char buf[64];
-
- if (copy_from_user(buf, ubuf, cnt>63?63:cnt)) {
- return -EFAULT;
- }
- buf[cnt] = '\0';
- ion_trace_lvl = simple_strtol(buf, NULL, 10);
- *ppos += cnt;
- return cnt;
-}
-
-static ssize_t
-rockchip_ion_debug_read(struct file *filp, char __user *ubuf, size_t cnt,
- loff_t *ppos)
-{
- int r;
- char buf[64];
-
- if (*ppos)
- return 0;
-
- snprintf(buf, 63, "%d\n", ion_trace_lvl);
- r = simple_read_from_buffer(ubuf, cnt, ppos, buf, strlen(buf));
-
- return r;
-}
-
-static const struct file_operations rockchip_ion_debug_fops = {
- .read = rockchip_ion_debug_read,
- .write = rockchip_ion_debug_write,
-};
-
void ion_device_add_heap(struct ion_device *dev, struct ion_heap *heap)
{
struct dentry *debug_file;
path, debug_name);
}
}
-#endif
-#ifdef CONFIG_CMA
- if (ION_HEAP_TYPE_DMA==heap->type) {
- char* heap_bitmap_name = kasprintf(
- GFP_KERNEL, "%s-bitmap", heap->name);
- debug_file = debugfs_create_file(heap_bitmap_name, 0664,
- dev->heaps_debug_root, heap,
- &debug_heap_bitmap_fops);
- if (!debug_file) {
- char buf[256], *path;
- path = dentry_path(dev->heaps_debug_root, buf, 256);
- pr_err("Failed to create heap debugfs at %s/%s\n",
- path, heap_bitmap_name);
- }
- kfree(heap_bitmap_name);
- }
#endif
up_write(&dev->lock);
}
{
struct ion_device *idev;
int ret;
- struct dentry* ion_debug;
idev = kzalloc(sizeof(struct ion_device), GFP_KERNEL);
if (!idev)
if (!idev->clients_debug_root)
pr_err("ion: failed to create debugfs clients directory.\n");
-#ifdef CONFIG_ION_ROCKCHIP_SNAPSHOT
- rockchip_ion_snapshot_debugfs(idev->debug_root);
-#endif
-
- ion_debug = debugfs_create_file("debug", 0664, idev->debug_root,
- NULL, &rockchip_ion_debug_fops);
- if (!ion_debug) {
- char buf[256], *path;
- path = dentry_path(idev->debug_root, buf, 256);
- pr_err("Failed to create debugfs at %s/%s\n",path, "ion_debug");
- }
-
debugfs_done:
idev->custom_ioctl = custom_ioctl;
if (data->heaps[i].size == 0)
continue;
- if (data->heaps[i].id==ION_CMA_HEAP_ID) {
- struct device *dev = (struct device*)data->heaps[i].priv;
- int ret = dma_declare_contiguous(dev,
- data->heaps[i].size,
- data->heaps[i].base,
- MEMBLOCK_ALLOC_ANYWHERE);
- if (ret) {
- pr_err("%s: dma_declare_contiguous failed %d\n",
- __func__, ret);
- continue;
- };
- data->heaps[i].base = PFN_PHYS(dev_get_cma_area(dev)->base_pfn);
- } else if (data->heaps[i].base == 0) {
+ if (data->heaps[i].base == 0) {
phys_addr_t paddr;
paddr = memblock_alloc_base(data->heaps[i].size,
} else {
int ret = memblock_reserve(data->heaps[i].base,
data->heaps[i].size);
- if (ret) {
+ if (ret)
pr_err("memblock reserve of %zx@%lx failed\n",
data->heaps[i].size,
data->heaps[i].base);
- continue;
- }
}
pr_info("%s: %s reserved base %lx size %zu\n", __func__,
data->heaps[i].name,
data->heaps[i].size);
}
}
-
-#ifdef CONFIG_ION_ROCKCHIP_SNAPSHOT
-
-// Find the maximum can be allocated memory
-static unsigned long ion_find_max_zero_area(unsigned long *map, unsigned long size)
-{
- unsigned long index, i, zero_sz, max_zero_sz, start;
- start = 0;
- max_zero_sz = 0;
-
- do {
- index = find_next_zero_bit(map, size, start);
- if (index>=size) break;
-
- i = find_next_bit(map, size, index);
- zero_sz = i-index;
- pr_debug("zero[%lx, %lx]\n", index, zero_sz);
- max_zero_sz = max(max_zero_sz, zero_sz);
- start = i + 1;
- } while(start<=size);
-
- pr_debug("max_zero_sz=%lx\n", max_zero_sz);
- return max_zero_sz;
-}
-
-static int ion_snapshot_save(struct ion_device *idev, size_t len)
-{
- static struct seq_file seqf;
- struct ion_heap *heap;
-
- if (!seqf.buf) {
- seqf.buf = rockchip_ion_snapshot_get(&seqf.size);
- if (!seqf.buf)
- return -ENOMEM;
- }
- memset(seqf.buf, 0, seqf.size);
- seqf.count = 0;
- pr_debug("%s: save snapshot 0x%zx@0x%lx\n", __func__, seqf.size,
- (unsigned long)__pa(seqf.buf));
-
- seq_printf(&seqf, "call by comm: %s pid: %d, alloc: %zuKB\n",
- current->comm, current->pid, len>>10);
-
- down_read(&idev->lock);
-
- plist_for_each_entry(heap, &idev->heaps, node) {
- seqf.private = (void*)heap;
- seq_printf(&seqf, "++++++++++++++++ HEAP: %s ++++++++++++++++\n",
- heap->name);
- ion_debug_heap_show(&seqf, NULL);
- if (ION_HEAP_TYPE_DMA==heap->type) {
- struct ion_cma_heap *cma_heap = container_of(heap,
- struct ion_cma_heap,
- heap);
- struct cma *cma = dev_get_cma_area(cma_heap->dev);
- seq_printf(&seqf, "\n");
- seq_printf(&seqf, "Maximum allocation of pages: %ld\n",
- ion_find_max_zero_area(cma->bitmap, cma->count));
- seq_printf(&seqf, "\n");
- }
- }
-
- up_read(&idev->lock);
-
- return 0;
-}
-#endif
*/
struct ion_handle *ion_import_dma_buf(struct ion_client *client, int fd);
-/**
- * ion_handle_get() - ref ion buffer.
- */
-void ion_handle_get(struct ion_handle *handle);
-/**
- * ion_handle_put() - unref ion buffer.
- */
-int ion_handle_put(struct ion_handle *handle);
-
-#ifdef CONFIG_ARCH_ROCKCHIP
-struct device;
-
-int ion_map_iommu(struct device *iommu_dev, struct ion_client *client,
- struct ion_handle *handle, unsigned long *iova,
- unsigned long *size);
-
-void ion_unmap_iommu(struct device *iommu_dev, struct ion_client *client,
- struct ion_handle *handle);
-#endif
#endif /* _LINUX_ION_H */
page = pfn_to_page(PFN_DOWN(heap_data->base));
size = heap_data->size;
- printk("%s: %zx@%lx\n", __func__, size, heap_data->base);
-
ion_pages_sync_for_device(NULL, page, size, DMA_BIDIRECTIONAL);
ret = ion_heap_pages_zero(page, size, pgprot_writecombine(PAGE_KERNEL));
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/dma-mapping.h>
-#include <linux/rockchip_ion.h>
-#include <linux/rockchip-iovmm.h>
#include "ion.h"
#include "ion_priv.h"
* as soon as it will avalaible.
*/
static int ion_cma_get_sgtable(struct device *dev, struct sg_table *sgt,
- dma_addr_t handle, size_t size)
+ void *cpu_addr, dma_addr_t handle, size_t size)
{
- struct page *page = phys_to_page(handle);
+ struct page *page = virt_to_page(cpu_addr);
int ret;
ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
struct ion_cma_heap *cma_heap = to_cma_heap(heap);
struct device *dev = cma_heap->dev;
struct ion_cma_buffer_info *info;
- DEFINE_DMA_ATTRS(attrs);
-#ifdef CONFIG_ION_CMA_HIGHMEM
- dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
-#endif
dev_dbg(dev, "Request buffer allocation len %ld\n", len);
if (buffer->flags & ION_FLAG_CACHED)
return ION_CMA_ALLOCATE_FAILED;
}
- info->cpu_addr = dma_alloc_attrs(dev, len, &(info->handle),
- GFP_USER | __GFP_ZERO, &attrs);
+ info->cpu_addr = dma_alloc_coherent(dev, len, &(info->handle),
+ GFP_HIGHUSER | __GFP_ZERO);
if (!info->cpu_addr) {
- dev_err(dev, "Fail to allocate(%lx) buffer\n", len);
+ dev_err(dev, "Fail to allocate buffer\n");
goto err;
}
goto free_mem;
}
- if (ion_cma_get_sgtable(dev, info->table, info->handle, len))
+ if (ion_cma_get_sgtable
+ (dev, info->table, info->cpu_addr, info->handle, len))
goto free_table;
/* keep this for memory release */
buffer->priv_virt = info;
free_table:
kfree(info->table);
free_mem:
- dma_free_attrs(dev, len, info->cpu_addr, info->handle, &attrs);
+ dma_free_coherent(dev, len, info->cpu_addr, info->handle);
err:
kfree(info);
return ION_CMA_ALLOCATE_FAILED;
struct ion_cma_heap *cma_heap = to_cma_heap(buffer->heap);
struct device *dev = cma_heap->dev;
struct ion_cma_buffer_info *info = buffer->priv_virt;
- DEFINE_DMA_ATTRS(attrs);
-#ifdef CONFIG_ION_CMA_HIGHMEM
- dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
-#endif
dev_dbg(dev, "Release buffer %p\n", buffer);
/* release memory */
- dma_free_attrs(dev, buffer->size, info->cpu_addr, info->handle, &attrs);
+ dma_free_coherent(dev, buffer->size, info->cpu_addr, info->handle);
/* release sg table */
sg_free_table(info->table);
kfree(info->table);
buffer->size);
}
-#ifndef CONFIG_ION_CMA_HIGHMEM
static void *ion_cma_map_kernel(struct ion_heap *heap,
struct ion_buffer *buffer)
{
struct ion_buffer *buffer)
{
}
-#endif
-
-#ifdef CONFIG_ROCKCHIP_IOMMU
-// get device's vaddr
-static int ion_cma_map_iommu(struct ion_buffer *buffer,
- struct device *iommu_dev,
- struct ion_iommu_map *data,
- unsigned long iova_length,
- unsigned long flags)
-{
- int ret = 0;
- struct ion_cma_buffer_info *info = buffer->priv_virt;
-
- data->iova_addr = rockchip_iovmm_map(iommu_dev, info->table->sgl, 0, iova_length);
- pr_debug("%s: map %lx -> %lx\n", __func__, (unsigned long)info->table->sgl->dma_address,
- data->iova_addr);
- if (IS_ERR_VALUE(data->iova_addr)) {
- pr_err("%s: rockchip_iovmm_map() failed: %lx\n", __func__, data->iova_addr);
- ret = data->iova_addr;
- goto out;
- }
-
- data->mapped_size = iova_length;
-
-out:
- return ret;
-}
-
-void ion_cma_unmap_iommu(struct device *iommu_dev, struct ion_iommu_map *data)
-{
- pr_debug("%s: unmap %x@%lx\n", __func__, data->mapped_size, data->iova_addr);
- rockchip_iovmm_unmap(iommu_dev, data->iova_addr);
-
- return;
-}
-#endif
static struct ion_heap_ops ion_cma_ops = {
.allocate = ion_cma_allocate,
.unmap_dma = ion_cma_heap_unmap_dma,
.phys = ion_cma_phys,
.map_user = ion_cma_mmap,
-#ifdef CONFIG_ION_CMA_HIGHMEM
- .map_kernel = ion_heap_map_kernel,
- .unmap_kernel = ion_heap_unmap_kernel,
-#else
.map_kernel = ion_cma_map_kernel,
.unmap_kernel = ion_cma_unmap_kernel,
-#endif
-#ifdef CONFIG_ROCKCHIP_IOMMU
- .map_iommu = ion_cma_map_iommu,
- .unmap_iommu = ion_cma_unmap_iommu,
-#endif
};
struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *data)
case ION_HEAP_TYPE_DMA:
heap = ion_cma_heap_create(heap_data);
break;
- case ION_HEAP_TYPE_DRM:
- heap = ion_drm_heap_create(heap_data);
- break;
default:
pr_err("%s: Invalid heap type %d\n", __func__,
heap_data->type);
case ION_HEAP_TYPE_DMA:
ion_cma_heap_destroy(heap);
break;
- case ION_HEAP_TYPE_DRM:
- ion_drm_heap_destroy(heap);
- break;
default:
pr_err("%s: Invalid heap type %d\n", __func__,
heap->type);
int i;
bool high;
- high = true;
+ high = !!(gfp_mask & __GFP_HIGHMEM);
for (i = 0; i < nr_to_scan; i++) {
struct page *page;
struct ion_buffer *ion_handle_buffer(struct ion_handle *handle);
-/**
- * struct ion_iommu_map - represents a mapping of an ion buffer to an iommu
- * @iova_addr - iommu virtual address
- * @node - rb node to exist in the buffer's tree of iommu mappings
- * @key - contains the iommu device info
- * @ref - for reference counting this mapping
- * @mapped_size - size of the iova space mapped
- * (may not be the same as the buffer size)
- *
- * Represents a mapping of one ion buffer to a particular iommu domain
- * and address range. There may exist other mappings of this buffer in
- * different domains or address ranges. All mappings will have the same
- * cacheability and security.
- */
-struct ion_iommu_map {
- unsigned long iova_addr;
- struct rb_node node;
- unsigned long key;
- struct ion_buffer *buffer;
- struct kref ref;
- int mapped_size;
-};
-
/**
* struct ion_buffer - metadata for a particular buffer
* @ref: refernce count
int handle_count;
char task_comm[TASK_COMM_LEN];
pid_t pid;
- unsigned int iommu_map_cnt;
- struct rb_root iommu_maps;
};
void ion_buffer_destroy(struct ion_buffer *buffer);
int (*map_user) (struct ion_heap *mapper, struct ion_buffer *buffer,
struct vm_area_struct *vma);
int (*shrink)(struct ion_heap *heap, gfp_t gfp_mask, int nr_to_scan);
- int (*map_iommu)(struct ion_buffer *buffer,
- struct device *iommu_dev,
- struct ion_iommu_map *map_data,
- unsigned long iova_length,
- unsigned long flags);
- void (*unmap_iommu)(struct device *iommu_dev, struct ion_iommu_map *data);
};
/**
struct ion_heap *ion_heap_create(struct ion_platform_heap *);
void ion_heap_destroy(struct ion_heap *);
-
struct ion_heap *ion_system_heap_create(struct ion_platform_heap *);
void ion_system_heap_destroy(struct ion_heap *);
struct ion_heap *ion_chunk_heap_create(struct ion_platform_heap *);
void ion_chunk_heap_destroy(struct ion_heap *);
-
struct ion_heap *ion_cma_heap_create(struct ion_platform_heap *);
void ion_cma_heap_destroy(struct ion_heap *);
-struct ion_heap *ion_drm_heap_create(struct ion_platform_heap *);
-void ion_drm_heap_destroy(struct ion_heap *);
-
/**
* kernel api to allocate/free from carveout -- used when carveout is
* used to back an architecture specific custom heap
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
-#include <linux/rockchip-iovmm.h>
#include "ion.h"
#include "ion_priv.h"
return nr_total;
}
-#ifdef CONFIG_ROCKCHIP_IOMMU
-// get device's vaddr
-static int ion_system_map_iommu(struct ion_buffer *buffer,
- struct device *iommu_dev,
- struct ion_iommu_map *data,
- unsigned long iova_length,
- unsigned long flags)
-{
- int ret = 0;
- struct sg_table *table = (struct sg_table*)buffer->priv_virt;
-
- data->iova_addr = rockchip_iovmm_map(iommu_dev, table->sgl, 0, iova_length);
- pr_debug("%s: map %lx -> %lx\n", __func__, (unsigned long)table->sgl->dma_address, data->iova_addr);
- if (IS_ERR_VALUE(data->iova_addr)) {
- pr_err("%s: rockchip_iovmm_map() failed: %lx\n", __func__, data->iova_addr);
- ret = data->iova_addr;
- goto out;
- }
-
- data->mapped_size = iova_length;
-
-out:
- return ret;
-}
-
-void ion_system_unmap_iommu(struct device *iommu_dev, struct ion_iommu_map *data)
-{
- pr_debug("%s: unmap %x@%lx\n", __func__, data->mapped_size, data->iova_addr);
- rockchip_iovmm_unmap(iommu_dev, data->iova_addr);
-
- return;
-}
-#endif
-
static struct ion_heap_ops system_heap_ops = {
.allocate = ion_system_heap_allocate,
.free = ion_system_heap_free,
.unmap_kernel = ion_heap_unmap_kernel,
.map_user = ion_heap_map_user,
.shrink = ion_system_heap_shrink,
-#ifdef CONFIG_ROCKCHIP_IOMMU
- .map_iommu = ion_system_map_iommu,
- .unmap_iommu = ion_system_unmap_iommu,
-#endif
};
static int ion_system_heap_debug_show(struct ion_heap *heap, struct seq_file *s,
int selected_tasksize = 0;
short selected_oom_score_adj;
int array_size = ARRAY_SIZE(lowmem_adj);
- int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages -
- global_page_state(NR_FREE_CMA_PAGES);
+ int other_free = global_page_state(NR_FREE_PAGES) - totalreserve_pages;
int other_file = global_page_state(NR_FILE_PAGES) -
global_page_state(NR_SHMEM);
#include <linux/spinlock.h>
#include <linux/wait.h>
-#include <linux/seq_file.h>
#include "uapi/sync.h"
struct sync_timeline;
ION_HEAP_TYPE_CARVEOUT,
ION_HEAP_TYPE_CHUNK,
ION_HEAP_TYPE_DMA,
- ION_HEAP_TYPE_DRM,
ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always
are at the end of this enum */
ION_NUM_HEAPS = 16,
#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG)
#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT)
#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA)
-#define ION_HEAP_TYPE_DRM_MASK (1 << ION_HEAP_TYPE_DRM)
#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8
Enable this to plug the SPEAr thermal sensor driver into the Linux
thermal framework
-config ROCKCHIP_THERMAL
- tristate "Rockchip thermal driver"
- depends on ARCH_ROCKCHIP
- depends on RESET_CONTROLLER
- help
- Rockchip thermal driver provides support for Temperature sensor
- ADC (TS-ADC) found on Rockchip SoCs. It supports one critical
- trip point and one passive trip point. Cpufreq is used as the
- cooling device and will throttle CPUs when the Temperature
- crosses the passive trip point.
-
config RCAR_THERMAL
tristate "Renesas R-Car thermal driver"
depends on ARCH_SHMOBILE
obj-$(CONFIG_DOVE_THERMAL) += dove_thermal.o
obj-$(CONFIG_DB8500_THERMAL) += db8500_thermal.o
obj-$(CONFIG_ARMADA_THERMAL) += armada_thermal.o
-obj-$(CONFIG_ROCKCHIP_THERMAL) += rockchip_thermal.o
obj-$(CONFIG_DB8500_CPUFREQ_COOLING) += db8500_cpufreq_cooling.o
obj-$(CONFIG_INTEL_POWERCLAMP) += intel_powerclamp.o
If you have enabled the serial port on the bcm63xx CPU
you can make it the console by answering Y to this option.
-config SERIAL_ROCKCHIP
- bool "RockChip SOCS serial port support"
- select SERIAL_CORE
-
-config SERIAL_ROCKCHIP_CONSOLE
- bool "Serial console support"
- depends on SERIAL_ROCKCHIP=y
- select SERIAL_CORE_CONSOLE
-
-
config SERIAL_GRLIB_GAISLER_APBUART
tristate "GRLIB APBUART serial support"
depends on OF && SPARC
obj-$(CONFIG_SERIAL_ALTERA_UART) += altera_uart.o
obj-$(CONFIG_KGDB_SERIAL_CONSOLE) += kgdboc.o
obj-$(CONFIG_SERIAL_QE) += ucc_uart.o
-obj-$(CONFIG_SERIAL_ROCKCHIP) += rk_serial.o
obj-$(CONFIG_SERIAL_TIMBERDALE) += timbuart.o
obj-$(CONFIG_SERIAL_GRLIB_GAISLER_APBUART) += apbuart.o
obj-$(CONFIG_SERIAL_ALTERA_JTAGUART) += altera_jtaguart.o
#ifdef CONFIG_PM_RUNTIME
static int serial_hsu_runtime_idle(struct device *dev)
{
- pm_schedule_suspend(dev, 500);
- return -EBUSY;
+ int err;
+
+ err = pm_schedule_suspend(dev, 500);
+ if (err)
+ return -EBUSY;
+
+ return 0;
}
static int serial_hsu_runtime_suspend(struct device *dev)
source "drivers/usb/gadget/Kconfig"
-source "drivers/usb/dwc_otg_310/Kconfig"
-
endif # USB_SUPPORT
obj-$(CONFIG_USB_ATM) += atm/
obj-$(CONFIG_USB_SPEEDTOUCH) += atm/
-obj-$(CONFIG_DWC_OTG_310) += dwc_otg_310/
-
obj-$(CONFIG_USB_MUSB_HDRC) += musb/
obj-$(CONFIG_USB_CHIPIDEA) += chipidea/
obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/
*/
if (autosuspend_check(udev) == 0)
pm_runtime_autosuspend(dev);
- /* Tell the core not to suspend it, though. */
- return -EBUSY;
+ return 0;
}
int usb_set_usb2_hardware_lpm(struct usb_device *udev, int enable)
/* pass ownership to the completion handler */
urb->status = status;
- if(!atomic_read(&urb->use_count)){
- printk("%s %d\n", __func__, atomic_read(&urb->use_count));
- return;
- }
- atomic_dec (&urb->use_count);
urb->complete (urb);
+ atomic_dec (&urb->use_count);
if (unlikely(atomic_read(&urb->reject)))
wake_up (&usb_kill_urb_queue);
usb_put_urb (urb);
kref_put(&hub->kref, hub_release);
}
-struct usb_hub *g_dwc_otg_root_hub20 = NULL;
static int hub_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_host_interface *desc;
return -ENOMEM;
}
- if(!g_dwc_otg_root_hub20){
- g_dwc_otg_root_hub20 = hub;
- }
kref_init(&hub->kref);
INIT_LIST_HEAD(&hub->event_list);
hub->intfdev = &intf->dev;
udev->ttport = hdev->ttport;
} else if (udev->speed != USB_SPEED_HIGH
&& hdev->speed == USB_SPEED_HIGH) {
- /* yk@rk 20110617
- * parent hub has no TT would be error in rk29
- * only need to be commented in rk29
- */
- #if 1
if (!hub->tt.hub) {
dev_err(&udev->dev, "parent hub has no TT\n");
retval = -EINVAL;
goto fail;
}
- #endif
udev->tt = &hub->tt;
udev->ttport = port1;
}
} /* end while (1) */
}
-/* yk@rk 20100730
- * * disconnect all devices on dwc otg controller root hub
- */
-void dwc_otg_hub_disconnect_device(struct usb_hub *hub)
-{
- hub_port_connect_change(hub, 1, 0, 0x2);
-}
-
-EXPORT_SYMBOL_GPL(dwc_otg_hub_disconnect_device);
-
static int hub_thread(void *__unused)
{
/* khubd needs to be freezable to avoid intefering with USB-PERSIST
#ifdef CONFIG_PM_RUNTIME
.runtime_suspend = usb_port_runtime_suspend,
.runtime_resume = usb_port_runtime_resume,
+ .runtime_idle = pm_generic_runtime_idle,
#endif
};
endchoice
-config USB_CSW_HACK
- boolean "USB Mass storage csw hack Feature"
- default y
- help
- This csw hack feature is for increasing the performance of the mass
- storage
-
-config USB_MSC_PROFILING
- bool "USB MSC performance profiling"
- help
- If you say Y here, support will be added for collecting
- Mass-storage performance numbers at the VFS level.
-
endif # USB_GADGET
static const char longname[] = "Gadget Android";
/* Default vendor and product IDs, overridden by userspace */
-#define VENDOR_ID 0x2207
-#define PRODUCT_ID 0x2910
+#define VENDOR_ID 0x18D1
+#define PRODUCT_ID 0x0001
/* f_midi configuration */
#define MIDI_INPUT_PORTS 1
config->opened = false;
config->data = NULL;
- if (!WARN_ON(!ffs->gadget)) {
- dev->cdev->next_string_id -= ffs->strings_count;
- }
functionfs_unbind(ffs);
mutex_unlock(&dev->mutex);
{
struct mass_storage_function_config *config;
struct fsg_common *common;
- int err, i;
- const char *name[2];
+ int err;
config = kzalloc(sizeof(struct mass_storage_function_config),
GFP_KERNEL);
if (!config)
return -ENOMEM;
- config->fsg.nluns = 2;
- name[0] = "lun";
- name[1] = "lun1";
- for (i = 0; i < config->fsg.nluns; i++) {
- config->fsg.luns[i].removable = 1;
- config->fsg.luns[i].nofua = 1;
- }
+ config->fsg.nluns = 1;
+ config->fsg.luns[0].removable = 1;
common = fsg_common_init(NULL, cdev, &config->fsg);
if (IS_ERR(common)) {
return PTR_ERR(common);
}
- for (i = 0; i < config->fsg.nluns; i++) {
- err = sysfs_create_link(&f->dev->kobj,
- &common->luns[i].dev.kobj,
- name[i]);
- if (err)
- goto error;
+ err = sysfs_create_link(&f->dev->kobj,
+ &common->luns[0].dev.kobj,
+ "lun");
+ if (err) {
+ kfree(config);
+ return err;
}
config->common = common;
f->config = config;
return 0;
-error:
- for (; i > 0 ; i--)
- sysfs_remove_link(&f->dev->kobj, name[i-1]);
- fsg_common_release(&common->ref);
- kfree(config);
- return err;
}
static void mass_storage_function_cleanup(struct android_usb_function *f)
return id;
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
- device_desc.bcdDevice = cpu_to_le16(get_default_bcdDevice());
usb_gadget_set_selfpowered(gadget);
dev->cdev = cdev;
#include <linux/usb/composite.h>
#include <asm/unaligned.h>
-static int gadget_connected = 0;
/*
* The code in this file is utility code, used to build a gadget driver
* from one or more "function" drivers, one or more "configuration"
cdev->config = c;
- /* reset delay status to zero every time usb reconnect */
- cdev->delayed_status = 0;
-
/* Initialize all interfaces by setting them to altsetting zero. */
for (tmp = 0; tmp < MAX_CONFIG_INTERFACES; tmp++) {
struct usb_function *f = c->interface[tmp];
/* when we return, be sure our power usage is valid */
power = c->MaxPower ? c->MaxPower : CONFIG_USB_GADGET_VBUS_DRAW;
- /* usb gadget connect flag */
- gadget_connected = 1;
done:
usb_gadget_vbus_draw(gadget, power);
if (result >= 0 && cdev->delayed_status)
reset_config(cdev);
if (cdev->driver->disconnect)
cdev->driver->disconnect(cdev);
- /* usb gadget connect flag */
- gadget_connected = 0;
spin_unlock_irqrestore(&cdev->lock, flags);
}
-int get_gadget_connect_flag( void )
-{
- return gadget_connected;
-}
/*-------------------------------------------------------------------------*/
static ssize_t composite_show_suspended(struct device *dev,
req->status = 0;
composite_setup_complete(cdev->gadget->ep0, req);
}
- }else{
- WARN(cdev, "%s: Unexpected delayed status 0x%x\n", __func__, cdev->delayed_status);
}
spin_unlock_irqrestore(&cdev->lock, flags);
.read = acc_read,
.write = acc_write,
.unlocked_ioctl = acc_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = acc_ioctl,
-#endif
.open = acc_open,
.release = acc_release,
};
* of the Gadget, USB Mass Storage, and SCSI protocols.
*/
+
/* #define VERBOSE_DEBUG */
/* #define DUMP_MSGS */
#include "gadget_chips.h"
-#ifdef CONFIG_ARCH_ROCKCHIP
-#include <linux/power_supply.h>
-#include <linux/reboot.h>
-#include <linux/syscalls.h>
-#endif
+
/*------------------------------------------------------------------------*/
#define FSG_DRIVER_DESC "Mass Storage Function"
#include "storage_common.c"
-#ifdef CONFIG_USB_CSW_HACK
-static int write_error_after_csw_sent;
-static int csw_hack_sent;
-#endif
+
/*-------------------------------------------------------------------------*/
struct fsg_dev;
* marked as non-removable or with prevent_medium_removal flag
* set).
*/
- int (*thread_exits) (struct fsg_common *common);
- /*
- * Called prior to ejection. Negative return means error,
- * zero means to continue with ejection, positive means not to
- * eject.
- */
- int (*pre_eject) (struct fsg_common *common,
- struct fsg_lun *lun, int num);
- /*
- * Called after ejection. Negative return means error, zero
- * or positive is just a success.
- */
- int (*post_eject) (struct fsg_common *common,
- struct fsg_lun *lun, int num);
+ int (*thread_exits)(struct fsg_common *common);
};
/* Data shared by all the FSG instances. */
struct fsg_common {
- struct usb_gadget *gadget;
+ struct usb_gadget *gadget;
struct usb_composite_dev *cdev;
- struct fsg_dev *fsg, *new_fsg;
- wait_queue_head_t fsg_wait;
+ struct fsg_dev *fsg, *new_fsg;
+ wait_queue_head_t fsg_wait;
/* filesem protects: backing files in use */
- struct rw_semaphore filesem;
+ struct rw_semaphore filesem;
/* lock protects: state, all the req_busy's */
- spinlock_t lock;
-
- struct usb_ep *ep0; /* Copy of gadget->ep0 */
- struct usb_request *ep0req; /* Copy of cdev->req */
- unsigned int ep0_req_tag;
-
- struct fsg_buffhd *next_buffhd_to_fill;
- struct fsg_buffhd *next_buffhd_to_drain;
- struct fsg_buffhd *buffhds;
-
- int cmnd_size;
- u8 cmnd[MAX_COMMAND_SIZE];
-
- unsigned int nluns;
- unsigned int lun;
- struct fsg_lun *luns;
- struct fsg_lun *curlun;
-
- unsigned int bulk_out_maxpacket;
- enum fsg_state state; /* For exception handling */
- unsigned int exception_req_tag;
-
- enum data_direction data_dir;
- u32 data_size;
- u32 data_size_from_cmnd;
- u32 tag;
- u32 residue;
- u32 usb_amount_left;
-
- unsigned int can_stall:1;
- unsigned int free_storage_on_release:1;
- unsigned int phase_error:1;
- unsigned int short_packet_received:1;
- unsigned int bad_lun_okay:1;
- unsigned int running:1;
-
- int thread_wakeup_needed;
- struct completion thread_notifier;
- struct task_struct *thread_task;
+ spinlock_t lock;
+
+ struct usb_ep *ep0; /* Copy of gadget->ep0 */
+ struct usb_request *ep0req; /* Copy of cdev->req */
+ unsigned int ep0_req_tag;
+
+ struct fsg_buffhd *next_buffhd_to_fill;
+ struct fsg_buffhd *next_buffhd_to_drain;
+ struct fsg_buffhd *buffhds;
+
+ int cmnd_size;
+ u8 cmnd[MAX_COMMAND_SIZE];
+
+ unsigned int nluns;
+ unsigned int lun;
+ struct fsg_lun *luns;
+ struct fsg_lun *curlun;
+
+ unsigned int bulk_out_maxpacket;
+ enum fsg_state state; /* For exception handling */
+ unsigned int exception_req_tag;
+
+ enum data_direction data_dir;
+ u32 data_size;
+ u32 data_size_from_cmnd;
+ u32 tag;
+ u32 residue;
+ u32 usb_amount_left;
+
+ unsigned int can_stall:1;
+ unsigned int free_storage_on_release:1;
+ unsigned int phase_error:1;
+ unsigned int short_packet_received:1;
+ unsigned int bad_lun_okay:1;
+ unsigned int running:1;
+
+ int thread_wakeup_needed;
+ struct completion thread_notifier;
+ struct task_struct *thread_task;
/* Callback functions. */
- const struct fsg_operations *ops;
+ const struct fsg_operations *ops;
/* Gadget's private data. */
- void *private_data;
+ void *private_data;
/*
* Vendor (8 chars), product (16 chars), release (4
*/
char inquiry_string[8 + 16 + 4 + 1];
- struct kref ref;
+ struct kref ref;
};
struct fsg_config {
} luns[FSG_MAX_LUNS];
/* Callback functions. */
- const struct fsg_operations *ops;
+ const struct fsg_operations *ops;
/* Gadget's private data. */
- void *private_data;
+ void *private_data;
- const char *vendor_name; /* 8 characters or less */
- const char *product_name; /* 16 characters or less */
+ const char *vendor_name; /* 8 characters or less */
+ const char *product_name; /* 16 characters or less */
- char can_stall;
+ char can_stall;
};
struct fsg_dev {
- struct usb_function function;
- struct usb_gadget *gadget; /* Copy of cdev->gadget */
- struct fsg_common *common;
+ struct usb_function function;
+ struct usb_gadget *gadget; /* Copy of cdev->gadget */
+ struct fsg_common *common;
- u16 interface_number;
+ u16 interface_number;
- unsigned int bulk_in_enabled:1;
- unsigned int bulk_out_enabled:1;
+ unsigned int bulk_in_enabled:1;
+ unsigned int bulk_out_enabled:1;
- unsigned long atomic_bitflags;
+ unsigned long atomic_bitflags;
#define IGNORE_BULK_OUT 0
- struct usb_ep *bulk_in;
- struct usb_ep *bulk_out;
+ struct usb_ep *bulk_in;
+ struct usb_ep *bulk_out;
};
static inline int __fsg_is_set(struct fsg_common *common,
return container_of(f, struct fsg_dev, function);
}
-typedef void (*fsg_routine_t) (struct fsg_dev *);
-static int send_status(struct fsg_common *common);
+typedef void (*fsg_routine_t)(struct fsg_dev *);
static int exception_in_progress(struct fsg_common *common)
{
static void set_bulk_out_req_length(struct fsg_common *common,
struct fsg_buffhd *bh, unsigned int length)
{
- unsigned int rem;
+ unsigned int rem;
bh->bulk_out_intended_length = length;
rem = length % common->bulk_out_maxpacket;
bh->outreq->length = length;
}
+
/*-------------------------------------------------------------------------*/
static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep)
{
- const char *name;
+ const char *name;
if (ep == fsg->bulk_in)
name = "bulk-in";
return usb_ep_set_halt(ep);
}
+
/*-------------------------------------------------------------------------*/
/* These routines may be called in process context or in_irq */
/* Caller must hold fsg->lock */
static void wakeup_thread(struct fsg_common *common)
{
- smp_wmb(); /* ensure the write of bh->state is complete */
+ smp_wmb(); /* ensure the write of bh->state is complete */
/* Tell the main thread that something has happened */
common->thread_wakeup_needed = 1;
if (common->thread_task)
static void raise_exception(struct fsg_common *common, enum fsg_state new_state)
{
- unsigned long flags;
+ unsigned long flags;
/*
* Do nothing if a higher-priority exception is already in progress.
spin_unlock_irqrestore(&common->lock, flags);
}
+
/*-------------------------------------------------------------------------*/
static int ep0_queue(struct fsg_common *common)
{
- int rc;
+ int rc;
rc = usb_ep_queue(common->ep0, common->ep0req, GFP_ATOMIC);
common->ep0->driver_data = common;
return rc;
}
+
/*-------------------------------------------------------------------------*/
/* Completion handlers. These always run in_irq. */
static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req)
{
- struct fsg_common *common = ep->driver_data;
- struct fsg_buffhd *bh = req->context;
+ struct fsg_common *common = ep->driver_data;
+ struct fsg_buffhd *bh = req->context;
if (req->status || req->actual != req->length)
DBG(common, "%s --> %d, %u/%u\n", __func__,
req->status, req->actual, req->length);
- if (req->status == -ECONNRESET) /* Request was cancelled */
+ if (req->status == -ECONNRESET) /* Request was cancelled */
usb_ep_fifo_flush(ep);
/* Hold the lock while we update the request and buffer states */
static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req)
{
- struct fsg_common *common = ep->driver_data;
- struct fsg_buffhd *bh = req->context;
+ struct fsg_common *common = ep->driver_data;
+ struct fsg_buffhd *bh = req->context;
dump_msg(common, "bulk-out", req->buf, req->actual);
if (req->status || req->actual != bh->bulk_out_intended_length)
DBG(common, "%s --> %d, %u/%u\n", __func__,
req->status, req->actual, bh->bulk_out_intended_length);
- if (req->status == -ECONNRESET) /* Request was cancelled */
+ if (req->status == -ECONNRESET) /* Request was cancelled */
usb_ep_fifo_flush(ep);
/* Hold the lock while we update the request and buffer states */
spin_unlock(&common->lock);
}
-static int fsg_setup(struct usb_function *f, const struct usb_ctrlrequest *ctrl)
+static int fsg_setup(struct usb_function *f,
+ const struct usb_ctrlrequest *ctrl)
{
- struct fsg_dev *fsg = fsg_from_func(f);
- struct usb_request *req = fsg->common->ep0req;
- u16 w_index = le16_to_cpu(ctrl->wIndex);
- u16 w_value = le16_to_cpu(ctrl->wValue);
- u16 w_length = le16_to_cpu(ctrl->wLength);
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct usb_request *req = fsg->common->ep0req;
+ u16 w_index = le16_to_cpu(ctrl->wIndex);
+ u16 w_value = le16_to_cpu(ctrl->wValue);
+ u16 w_length = le16_to_cpu(ctrl->wLength);
if (!fsg_is_set(fsg->common))
return -EOPNOTSUPP;
(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
if (w_index != fsg->interface_number || w_value != 0 ||
- w_length != 0)
+ w_length != 0)
return -EDOM;
/*
(USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE))
break;
if (w_index != fsg->interface_number || w_value != 0 ||
- w_length != 1)
+ w_length != 1)
return -EDOM;
VDBG(fsg, "get max LUN\n");
- *(u8 *) req->buf = fsg->common->nluns - 1;
+ *(u8 *)req->buf = fsg->common->nluns - 1;
/* Respond with data/status */
- req->length = min((u16) 1, w_length);
+ req->length = min((u16)1, w_length);
return ep0_queue(fsg->common);
}
return -EOPNOTSUPP;
}
+
/*-------------------------------------------------------------------------*/
/* All the following routines run in process context */
struct usb_request *req, int *pbusy,
enum fsg_buffer_state *state)
{
- int rc;
+ int rc;
if (ep == fsg->bulk_in)
dump_msg(fsg, "bulk-in", req->buf, req->length);
static int sleep_thread(struct fsg_common *common)
{
- int rc = 0;
+ int rc = 0;
/* Wait until a signal arrives or we are woken up */
for (;;) {
}
__set_current_state(TASK_RUNNING);
common->thread_wakeup_needed = 0;
- smp_rmb(); /* ensure the latest bh->state is visible */
+ smp_rmb(); /* ensure the latest bh->state is visible */
return rc;
}
+
/*-------------------------------------------------------------------------*/
static int do_read(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- u32 lba;
- struct fsg_buffhd *bh;
- int rc;
- u32 amount_left;
- loff_t file_offset, file_offset_tmp;
- unsigned int amount;
- ssize_t nread;
-#ifdef CONFIG_USB_MSC_PROFILING
- ktime_t start, diff;
-#endif
+ struct fsg_lun *curlun = common->curlun;
+ u32 lba;
+ struct fsg_buffhd *bh;
+ int rc;
+ u32 amount_left;
+ loff_t file_offset, file_offset_tmp;
+ unsigned int amount;
+ ssize_t nread;
/*
* Get the starting Logical Block Address and check that it's
/* Carry out the file reads */
amount_left = common->data_size_from_cmnd;
if (unlikely(amount_left == 0))
- return -EIO; /* No default reply */
+ return -EIO; /* No default reply */
for (;;) {
/*
* And don't try to read past the end of the file.
*/
amount = min(amount_left, FSG_BUFLEN);
- amount = min((loff_t) amount,
+ amount = min((loff_t)amount,
curlun->file_length - file_offset);
- /* kever@rk
- * max size for dwc_otg ctonroller is 64(max pkt sizt) * 1023(pkt)
- * because of the DOEPTSIZ.PKTCNT has only 10 bits
- */
- if ((common->gadget->speed != USB_SPEED_HIGH)
- && (amount > 0x8000))
- amount = 0x8000;
/* Wait for the next buffer to become available */
bh = common->next_buffhd_to_fill;
*/
if (amount == 0) {
curlun->sense_data =
- SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ file_offset >> curlun->blkbits;
curlun->info_valid = 1;
bh->inreq->length = 0;
bh->state = BUF_STATE_FULL;
/* Perform the read */
file_offset_tmp = file_offset;
-
-#ifdef CONFIG_USB_MSC_PROFILING
- start = ktime_get();
-#endif
nread = vfs_read(curlun->filp,
(char __user *)bh->buf,
amount, &file_offset_tmp);
VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
(unsigned long long)file_offset, (int)nread);
-#ifdef CONFIG_USB_MSC_PROFILING
- diff = ktime_sub(ktime_get(), start);
- curlun->perf.rbytes += nread;
- curlun->perf.rtime = ktime_add(curlun->perf.rtime, diff);
-#endif
if (signal_pending(current))
return -EINTR;
(int)nread, amount);
nread = round_down(nread, curlun->blksize);
}
- file_offset += nread;
- amount_left -= nread;
+ file_offset += nread;
+ amount_left -= nread;
common->residue -= nread;
/*
if (nread < amount) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ file_offset >> curlun->blkbits;
curlun->info_valid = 1;
break;
}
if (amount_left == 0)
- break; /* No more left to read */
+ break; /* No more left to read */
/* Send this buffer and go read some more */
bh->inreq->zero = 0;
return -EIO; /* No default reply */
}
+
/*-------------------------------------------------------------------------*/
static int do_write(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- u32 lba;
- struct fsg_buffhd *bh;
- int get_some_more;
- u32 amount_left_to_req, amount_left_to_write;
- loff_t usb_offset, file_offset, file_offset_tmp;
- unsigned int amount;
- ssize_t nwritten;
- int rc;
-
-#ifdef CONFIG_USB_CSW_HACK
- int i;
-#endif
+ struct fsg_lun *curlun = common->curlun;
+ u32 lba;
+ struct fsg_buffhd *bh;
+ int get_some_more;
+ u32 amount_left_to_req, amount_left_to_write;
+ loff_t usb_offset, file_offset, file_offset_tmp;
+ unsigned int amount;
+ ssize_t nwritten;
+ int rc;
-#ifdef CONFIG_USB_MSC_PROFILING
- ktime_t start, diff;
-#endif
if (curlun->ro) {
curlun->sense_data = SS_WRITE_PROTECTED;
return -EINVAL;
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
- if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
+ if (!curlun->nofua && (common->cmnd[1] & 0x08)) { /* FUA */
spin_lock(&curlun->filp->f_lock);
curlun->filp->f_flags |= O_SYNC;
spin_unlock(&curlun->filp->f_lock);
if (usb_offset >= curlun->file_length) {
get_some_more = 0;
curlun->sense_data =
- SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
curlun->sense_data_info =
- usb_offset >> curlun->blkbits;
+ usb_offset >> curlun->blkbits;
curlun->info_valid = 1;
continue;
}
if (amount_left_to_req == 0)
get_some_more = 0;
- /* kever@rk
- * max size for dwc_otg ctonroller is 64(max pkt sizt) * 1023(pkt)
- * because of the DOEPTSIZ.PKTCNT has only 10 bits
- */
- if ((common->gadget->speed != USB_SPEED_HIGH)
- && (amount > 0x8000))
- amount = 0x8000;
-
/*
* Except at the end of the transfer, amount will be
* equal to the buffer size, which is divisible by
/* Write the received data to the backing file */
bh = common->next_buffhd_to_drain;
if (bh->state == BUF_STATE_EMPTY && !get_some_more)
- break; /* We stopped early */
-#ifdef CONFIG_USB_CSW_HACK
- /*
- * If the csw packet is already submmitted to the hardware,
- * by marking the state of buffer as full, then by checking
- * the residue, we make sure that this csw packet is not
- * written on to the storage media.
- */
- if (bh->state == BUF_STATE_FULL && common->residue) {
-#else
+ break; /* We stopped early */
if (bh->state == BUF_STATE_FULL) {
-#endif
smp_rmb();
common->next_buffhd_to_drain = bh->next;
bh->state = BUF_STATE_EMPTY;
if (bh->outreq->status != 0) {
curlun->sense_data = SS_COMMUNICATION_FAILURE;
curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ file_offset >> curlun->blkbits;
curlun->info_valid = 1;
break;
}
/* Perform the write */
file_offset_tmp = file_offset;
-#ifdef CONFIG_USB_MSC_PROFILING
- start = ktime_get();
-#endif
nwritten = vfs_write(curlun->filp,
(char __user *)bh->buf,
amount, &file_offset_tmp);
VLDBG(curlun, "file write %u @ %llu -> %d\n", amount,
(unsigned long long)file_offset, (int)nwritten);
-#ifdef CONFIG_USB_MSC_PROFILING
- diff = ktime_sub(ktime_get(), start);
- curlun->perf.wbytes += nwritten;
- curlun->perf.wtime =
- ktime_add(curlun->perf.wtime, diff);
-#endif
if (signal_pending(current))
- return -EINTR; /* Interrupted! */
+ return -EINTR; /* Interrupted! */
if (nwritten < 0) {
LDBG(curlun, "error in file write: %d\n",
} else if (nwritten < amount) {
LDBG(curlun, "partial file write: %d/%u\n",
(int)nwritten, amount);
- nwritten =
- round_down(nwritten, curlun->blksize);
+ nwritten = round_down(nwritten, curlun->blksize);
}
file_offset += nwritten;
amount_left_to_write -= nwritten;
if (nwritten < amount) {
curlun->sense_data = SS_WRITE_ERROR;
curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ file_offset >> curlun->blkbits;
curlun->info_valid = 1;
-#ifdef CONFIG_USB_CSW_HACK
- write_error_after_csw_sent = 1;
- goto write_error;
-#endif
break;
}
-#ifdef CONFIG_USB_CSW_HACK
-write_error:
- if ((nwritten == amount) && !csw_hack_sent) {
- if (write_error_after_csw_sent)
- break;
- /*
- * Check if any of the buffer is in the
- * busy state, if any buffer is in busy state,
- * means the complete data is not received
- * yet from the host. So there is no point in
- * csw right away without the complete data.
- */
- for (i = 0; i < fsg_num_buffers; i++) {
- if (common->buffhds[i].state ==
- BUF_STATE_BUSY)
- break;
- }
- if (!amount_left_to_req && i == fsg_num_buffers) {
- csw_hack_sent = 1;
- send_status(common);
- }
- }
-#endif
-empty_write:
+ empty_write:
/* Did the host decide to stop early? */
if (bh->outreq->actual < bh->bulk_out_intended_length) {
common->short_packet_received = 1;
return -EIO; /* No default reply */
}
+
/*-------------------------------------------------------------------------*/
static int do_synchronize_cache(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- int rc;
+ struct fsg_lun *curlun = common->curlun;
+ int rc;
/* We ignore the requested LBA and write out all file's
* dirty data buffers. */
return 0;
}
+
/*-------------------------------------------------------------------------*/
-#ifndef CONFIG_ARCH_ROCKCHIP
+
static void invalidate_sub(struct fsg_lun *curlun)
{
- struct file *filp = curlun->filp;
- struct inode *inode = file_inode(filp);
- unsigned long rc;
+ struct file *filp = curlun->filp;
+ struct inode *inode = file_inode(filp);
+ unsigned long rc;
rc = invalidate_mapping_pages(inode->i_mapping, 0, -1);
VLDBG(curlun, "invalidate_mapping_pages -> %ld\n", rc);
static int do_verify(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- u32 lba;
- u32 verification_length;
- struct fsg_buffhd *bh = common->next_buffhd_to_fill;
- loff_t file_offset, file_offset_tmp;
- u32 amount_left;
- unsigned int amount;
- ssize_t nread;
+ struct fsg_lun *curlun = common->curlun;
+ u32 lba;
+ u32 verification_length;
+ struct fsg_buffhd *bh = common->next_buffhd_to_fill;
+ loff_t file_offset, file_offset_tmp;
+ u32 amount_left;
+ unsigned int amount;
+ ssize_t nread;
/*
* Get the starting Logical Block Address and check that it's
verification_length = get_unaligned_be16(&common->cmnd[7]);
if (unlikely(verification_length == 0))
- return -EIO; /* No default reply */
+ return -EIO; /* No default reply */
/* Prepare to carry out the file verify */
amount_left = verification_length << curlun->blkbits;
* And don't try to read past the end of the file.
*/
amount = min(amount_left, FSG_BUFLEN);
- amount = min((loff_t) amount,
+ amount = min((loff_t)amount,
curlun->file_length - file_offset);
if (amount == 0) {
curlun->sense_data =
- SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
+ SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE;
curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ file_offset >> curlun->blkbits;
curlun->info_valid = 1;
break;
}
/* Perform the read */
file_offset_tmp = file_offset;
nread = vfs_read(curlun->filp,
- (char __user *)bh->buf,
- amount, &file_offset_tmp);
+ (char __user *) bh->buf,
+ amount, &file_offset_tmp);
VLDBG(curlun, "file read %u @ %llu -> %d\n", amount,
- (unsigned long long)file_offset, (int)nread);
+ (unsigned long long) file_offset,
+ (int) nread);
if (signal_pending(current))
return -EINTR;
if (nread == 0) {
curlun->sense_data = SS_UNRECOVERED_READ_ERROR;
curlun->sense_data_info =
- file_offset >> curlun->blkbits;
+ file_offset >> curlun->blkbits;
curlun->info_valid = 1;
break;
}
}
return 0;
}
-#endif
+
/*-------------------------------------------------------------------------*/
static int do_inquiry(struct fsg_common *common, struct fsg_buffhd *bh)
{
struct fsg_lun *curlun = common->curlun;
- u8 *buf = (u8 *) bh->buf;
+ u8 *buf = (u8 *) bh->buf;
if (!curlun) { /* Unsupported LUNs are okay */
common->bad_lun_okay = 1;
memset(buf, 0, 36);
- buf[0] = 0x7f; /* Unsupported, no device-type */
- buf[4] = 31; /* Additional length */
+ buf[0] = 0x7f; /* Unsupported, no device-type */
+ buf[4] = 31; /* Additional length */
return 36;
}
static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
- u8 *buf = (u8 *) bh->buf;
- u32 sd, sdinfo;
- int valid;
+ struct fsg_lun *curlun = common->curlun;
+ u8 *buf = (u8 *) bh->buf;
+ u32 sd, sdinfo;
+ int valid;
/*
* From the SCSI-2 spec., section 7.9 (Unit attention condition):
* generates the contingent allegiance condition), then the
* target shall either:
* a) report any pending sense data and preserve the unit
- * attention condition on the logical unit, or,
+ * attention condition on the logical unit, or,
* b) report the unit attention condition, may discard any
- * pending sense data, and clear the unit attention
- * condition on the logical unit for that initiator.
+ * pending sense data, and clear the unit attention
+ * condition on the logical unit for that initiator.
*
* FSG normally uses option a); enable this code to use option b).
*/
}
memset(buf, 0, 18);
- buf[0] = valid | 0x70; /* Valid, current error */
+ buf[0] = valid | 0x70; /* Valid, current error */
buf[2] = SK(sd);
put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */
- buf[7] = 18 - 8; /* Additional sense length */
+ buf[7] = 18 - 8; /* Additional sense length */
buf[12] = ASC(sd);
buf[13] = ASCQ(sd);
return 18;
static int do_read_capacity(struct fsg_common *common, struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
- u32 lba = get_unaligned_be32(&common->cmnd[2]);
- int pmi = common->cmnd[8];
- u8 *buf = (u8 *) bh->buf;
+ struct fsg_lun *curlun = common->curlun;
+ u32 lba = get_unaligned_be32(&common->cmnd[2]);
+ int pmi = common->cmnd[8];
+ u8 *buf = (u8 *)bh->buf;
/* Check the PMI and LBA fields */
if (pmi > 1 || (pmi == 0 && lba != 0)) {
}
put_unaligned_be32(curlun->num_sectors - 1, &buf[0]);
- /* Max logical block */
- put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
+ /* Max logical block */
+ put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
return 8;
}
static int do_read_header(struct fsg_common *common, struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
- int msf = common->cmnd[1] & 0x02;
- u32 lba = get_unaligned_be32(&common->cmnd[2]);
- u8 *buf = (u8 *) bh->buf;
+ struct fsg_lun *curlun = common->curlun;
+ int msf = common->cmnd[1] & 0x02;
+ u32 lba = get_unaligned_be32(&common->cmnd[2]);
+ u8 *buf = (u8 *)bh->buf;
- if (common->cmnd[1] & ~0x02) { /* Mask away MSF */
+ if (common->cmnd[1] & ~0x02) { /* Mask away MSF */
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
static int do_read_toc(struct fsg_common *common, struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
- int msf = common->cmnd[1] & 0x02;
- int start_track = common->cmnd[6];
- u8 *buf = (u8 *) bh->buf;
+ struct fsg_lun *curlun = common->curlun;
+ int msf = common->cmnd[1] & 0x02;
+ int start_track = common->cmnd[6];
+ u8 *buf = (u8 *)bh->buf;
if ((common->cmnd[1] & ~0x02) != 0 || /* Mask away MSF */
- start_track > 1) {
+ start_track > 1) {
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
memset(buf, 0, 20);
- buf[1] = (20 - 2); /* TOC data length */
- buf[2] = 1; /* First track number */
- buf[3] = 1; /* Last track number */
- buf[5] = 0x16; /* Data track, copying allowed */
- buf[6] = 0x01; /* Only track is number 1 */
+ buf[1] = (20-2); /* TOC data length */
+ buf[2] = 1; /* First track number */
+ buf[3] = 1; /* Last track number */
+ buf[5] = 0x16; /* Data track, copying allowed */
+ buf[6] = 0x01; /* Only track is number 1 */
store_cdrom_address(&buf[8], msf, 0);
- buf[13] = 0x16; /* Lead-out track is data */
- buf[14] = 0xAA; /* Lead-out track number */
+ buf[13] = 0x16; /* Lead-out track is data */
+ buf[14] = 0xAA; /* Lead-out track number */
store_cdrom_address(&buf[16], msf, curlun->num_sectors);
return 20;
}
static int do_mode_sense(struct fsg_common *common, struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
- int mscmnd = common->cmnd[0];
- u8 *buf = (u8 *) bh->buf;
- u8 *buf0 = buf;
- int pc, page_code;
- int changeable_values, all_pages;
- int valid_page = 0;
- int len, limit;
+ struct fsg_lun *curlun = common->curlun;
+ int mscmnd = common->cmnd[0];
+ u8 *buf = (u8 *) bh->buf;
+ u8 *buf0 = buf;
+ int pc, page_code;
+ int changeable_values, all_pages;
+ int valid_page = 0;
+ int len, limit;
if ((common->cmnd[1] & ~0x08) != 0) { /* Mask away DBD */
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
*/
memset(buf, 0, 8);
if (mscmnd == MODE_SENSE) {
- buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */
+ buf[2] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */
buf += 4;
limit = 255;
- } else { /* MODE_SENSE_10 */
- buf[3] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */
+ } else { /* MODE_SENSE_10 */
+ buf[3] = (curlun->ro ? 0x80 : 0x00); /* WP, DPOFUA */
buf += 8;
- limit = 65535; /* Should really be FSG_BUFLEN */
+ limit = 65535; /* Should really be FSG_BUFLEN */
}
/* No block descriptors */
*/
if (page_code == 0x08 || all_pages) {
valid_page = 1;
- buf[0] = 0x08; /* Page code */
- buf[1] = 10; /* Page length */
- memset(buf + 2, 0, 10); /* None of the fields are changeable */
+ buf[0] = 0x08; /* Page code */
+ buf[1] = 10; /* Page length */
+ memset(buf+2, 0, 10); /* None of the fields are changeable */
if (!changeable_values) {
buf[2] = 0x04; /* Write cache enable, */
- /* Read cache not disabled */
- /* No cache retention priorities */
+ /* Read cache not disabled */
+ /* No cache retention priorities */
put_unaligned_be16(0xffff, &buf[4]);
- /* Don't disable prefetch */
- /* Minimum prefetch = 0 */
+ /* Don't disable prefetch */
+ /* Minimum prefetch = 0 */
put_unaligned_be16(0xffff, &buf[8]);
- /* Maximum prefetch */
+ /* Maximum prefetch */
put_unaligned_be16(0xffff, &buf[10]);
- /* Maximum prefetch ceiling */
+ /* Maximum prefetch ceiling */
}
buf += 12;
}
static int do_start_stop(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- int loej, start;
+ struct fsg_lun *curlun = common->curlun;
+ int loej, start;
if (!curlun) {
return -EINVAL;
} else if (!curlun->removable) {
curlun->sense_data = SS_INVALID_COMMAND;
return -EINVAL;
- } else if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */
- (common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */
+ } else if ((common->cmnd[1] & ~0x01) != 0 || /* Mask away Immed */
+ (common->cmnd[4] & ~0x03) != 0) { /* Mask LoEj, Start */
curlun->sense_data = SS_INVALID_FIELD_IN_CDB;
return -EINVAL;
}
- loej = common->cmnd[4] & 0x02;
+ loej = common->cmnd[4] & 0x02;
start = common->cmnd[4] & 0x01;
/*
if (!loej)
return 0;
- /* Simulate an unload/eject */
- if (common->ops && common->ops->pre_eject) {
- int r = common->ops->pre_eject(common, curlun,
- curlun - common->luns);
- if (unlikely(r < 0))
- return r;
- else if (r)
- return 0;
- }
-
up_read(&common->filesem);
down_write(&common->filesem);
fsg_lun_close(curlun);
up_write(&common->filesem);
down_read(&common->filesem);
- return common->ops && common->ops->post_eject
- ? min(0, common->ops->post_eject(common, curlun,
- curlun - common->luns))
- : 0;
+ return 0;
}
static int do_prevent_allow(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- int prevent;
+ struct fsg_lun *curlun = common->curlun;
+ int prevent;
if (!common->curlun) {
return -EINVAL;
return -EINVAL;
}
- if (!curlun->nofua && curlun->prevent_medium_removal && !prevent)
+ if (curlun->prevent_medium_removal && !prevent)
fsg_lun_fsync_sub(curlun);
curlun->prevent_medium_removal = prevent;
return 0;
}
static int do_read_format_capacities(struct fsg_common *common,
- struct fsg_buffhd *bh)
+ struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
- u8 *buf = (u8 *) bh->buf;
+ struct fsg_lun *curlun = common->curlun;
+ u8 *buf = (u8 *) bh->buf;
buf[0] = buf[1] = buf[2] = 0;
- buf[3] = 8; /* Only the Current/Maximum Capacity Descriptor */
+ buf[3] = 8; /* Only the Current/Maximum Capacity Descriptor */
buf += 4;
put_unaligned_be32(curlun->num_sectors, &buf[0]);
- /* Number of blocks */
- put_unaligned_be32(curlun->blksize, &buf[4]); /* Block length */
- buf[4] = 0x02; /* Current capacity */
+ /* Number of blocks */
+ put_unaligned_be32(curlun->blksize, &buf[4]);/* Block length */
+ buf[4] = 0x02; /* Current capacity */
return 12;
}
static int do_mode_select(struct fsg_common *common, struct fsg_buffhd *bh)
{
- struct fsg_lun *curlun = common->curlun;
+ struct fsg_lun *curlun = common->curlun;
/* We don't support MODE SELECT */
if (curlun)
return -EINVAL;
}
+
/*-------------------------------------------------------------------------*/
static int halt_bulk_in_endpoint(struct fsg_dev *fsg)
{
- int rc;
+ int rc;
rc = fsg_set_halt(fsg, fsg->bulk_in);
if (rc == -EAGAIN)
static int wedge_bulk_in_endpoint(struct fsg_dev *fsg)
{
- int rc;
+ int rc;
DBG(fsg, "bulk-in set wedge\n");
rc = usb_ep_set_wedge(fsg->bulk_in);
static int throw_away_data(struct fsg_common *common)
{
- struct fsg_buffhd *bh;
- u32 amount;
- int rc;
+ struct fsg_buffhd *bh;
+ u32 amount;
+ int rc;
for (bh = common->next_buffhd_to_drain;
bh->state != BUF_STATE_EMPTY || common->usb_amount_left > 0;
/* Try to submit another request if we need one */
bh = common->next_buffhd_to_fill;
- if (bh->state == BUF_STATE_EMPTY && common->usb_amount_left > 0) {
+ if (bh->state == BUF_STATE_EMPTY
+ && common->usb_amount_left > 0) {
amount = min(common->usb_amount_left, FSG_BUFLEN);
/*
static int finish_reply(struct fsg_common *common)
{
- struct fsg_buffhd *bh = common->next_buffhd_to_fill;
- int rc = 0;
+ struct fsg_buffhd *bh = common->next_buffhd_to_fill;
+ int rc = 0;
switch (common->data_dir) {
case DATA_DIR_NONE:
- break; /* Nothing to send */
+ break; /* Nothing to send */
- /*
- * If we don't know whether the host wants to read or write,
- * this must be CB or CBI with an unknown command. We mustn't
- * try to send or receive any data. So stall both bulk pipes
- * if we can and wait for a reset.
- */
+ /*
+ * If we don't know whether the host wants to read or write,
+ * this must be CB or CBI with an unknown command. We mustn't
+ * try to send or receive any data. So stall both bulk pipes
+ * if we can and wait for a reset.
+ */
case DATA_DIR_UNKNOWN:
if (!common->can_stall) {
/* Nothing */
}
break;
- /* All but the last buffer of data must have already been sent */
+ /* All but the last buffer of data must have already been sent */
case DATA_DIR_TO_HOST:
if (common->data_size == 0) {
/* Nothing to send */
- /* Don't know what to do if common->fsg is NULL */
+ /* Don't know what to do if common->fsg is NULL */
} else if (!fsg_is_set(common)) {
rc = -EIO;
- /* If there's no residue, simply send the last buffer */
+ /* If there's no residue, simply send the last buffer */
} else if (common->residue == 0) {
bh->inreq->zero = 0;
if (!start_in_transfer(common, bh))
return -EIO;
common->next_buffhd_to_fill = bh->next;
- /*
- * For Bulk-only, mark the end of the data with a short
- * packet. If we are allowed to stall, halt the bulk-in
- * endpoint. (Note: This violates the Bulk-Only Transport
- * specification, which requires us to pad the data if we
- * don't halt the endpoint. Presumably nobody will mind.)
- */
+ /*
+ * For Bulk-only, mark the end of the data with a short
+ * packet. If we are allowed to stall, halt the bulk-in
+ * endpoint. (Note: This violates the Bulk-Only Transport
+ * specification, which requires us to pad the data if we
+ * don't halt the endpoint. Presumably nobody will mind.)
+ */
} else {
bh->inreq->zero = 1;
if (!start_in_transfer(common, bh))
}
break;
- /*
- * We have processed all we want from the data the host has sent.
- * There may still be outstanding bulk-out requests.
- */
+ /*
+ * We have processed all we want from the data the host has sent.
+ * There may still be outstanding bulk-out requests.
+ */
case DATA_DIR_FROM_HOST:
if (common->residue == 0) {
/* Nothing to receive */
- /* Did the host stop sending unexpectedly early? */
+ /* Did the host stop sending unexpectedly early? */
} else if (common->short_packet_received) {
raise_exception(common, FSG_STATE_ABORT_BULK_OUT);
rc = -EINTR;
- /*
- * We haven't processed all the incoming data. Even though
- * we may be allowed to stall, doing so would cause a race.
- * The controller may already have ACK'ed all the remaining
- * bulk-out packets, in which case the host wouldn't see a
- * STALL. Not realizing the endpoint was halted, it wouldn't
- * clear the halt -- leading to problems later on.
- */
+ /*
+ * We haven't processed all the incoming data. Even though
+ * we may be allowed to stall, doing so would cause a race.
+ * The controller may already have ACK'ed all the remaining
+ * bulk-out packets, in which case the host wouldn't see a
+ * STALL. Not realizing the endpoint was halted, it wouldn't
+ * clear the halt -- leading to problems later on.
+ */
#if 0
} else if (common->can_stall) {
if (fsg_is_set(common))
rc = -EINTR;
#endif
- /*
- * We can't stall. Read in the excess data and throw it
- * all away.
- */
+ /*
+ * We can't stall. Read in the excess data and throw it
+ * all away.
+ */
} else {
rc = throw_away_data(common);
}
static int send_status(struct fsg_common *common)
{
- struct fsg_lun *curlun = common->curlun;
- struct fsg_buffhd *bh;
- struct bulk_cs_wrap *csw;
- int rc;
- u8 status = US_BULK_STAT_OK;
- u32 sd, sdinfo = 0;
+ struct fsg_lun *curlun = common->curlun;
+ struct fsg_buffhd *bh;
+ struct bulk_cs_wrap *csw;
+ int rc;
+ u8 status = US_BULK_STAT_OK;
+ u32 sd, sdinfo = 0;
/* Wait for the next buffer to become available */
bh = common->next_buffhd_to_fill;
DBG(common, "sending command-failure status\n");
status = US_BULK_STAT_FAIL;
VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;"
- " info x%x\n", SK(sd), ASC(sd), ASCQ(sd), sdinfo);
+ " info x%x\n",
+ SK(sd), ASC(sd), ASCQ(sd), sdinfo);
}
/* Store and send the Bulk-only CSW */
csw->Signature = cpu_to_le32(US_BULK_CS_SIGN);
csw->Tag = common->tag;
csw->Residue = cpu_to_le32(common->residue);
-#ifdef CONFIG_USB_CSW_HACK
- /* Since csw is being sent early, before
- * writing on to storage media, need to set
- * residue to zero,assuming that write will succeed.
- */
- if (write_error_after_csw_sent) {
- write_error_after_csw_sent = 0;
- csw->Residue = cpu_to_le32(common->residue);
- } else
- csw->Residue = 0;
-#else
- csw->Residue = cpu_to_le32(common->residue);
-#endif
csw->Status = status;
bh->inreq->length = US_BULK_CS_WRAP_LEN;
return 0;
}
+
/*-------------------------------------------------------------------------*/
/*
enum data_direction data_dir, unsigned int mask,
int needs_medium, const char *name)
{
- int i;
- unsigned int lun = common->cmnd[1] >> 5;
- static const char dirletter[4] = { 'u', 'o', 'i', 'n' };
- char hdlen[20];
- struct fsg_lun *curlun;
+ int i;
+ unsigned int lun = common->cmnd[1] >> 5;
+ static const char dirletter[4] = {'u', 'o', 'i', 'n'};
+ char hdlen[20];
+ struct fsg_lun *curlun;
hdlen[0] = 0;
if (common->data_dir != DATA_DIR_UNKNOWN)
- sprintf(hdlen, ", H%c=%u", dirletter[(int)common->data_dir],
+ sprintf(hdlen, ", H%c=%u", dirletter[(int) common->data_dir],
common->data_size);
VDBG(common, "SCSI command: %s; Dc=%d, D%c=%u; Hc=%d%s\n",
- name, cmnd_size, dirletter[(int)data_dir],
+ name, cmnd_size, dirletter[(int) data_dir],
common->data_size_from_cmnd, common->cmnd_size, hdlen);
/*
* REQUEST SENSE commands are allowed; anything else must fail.
*/
if (curlun && curlun->unit_attention_data != SS_NO_SENSE &&
- common->cmnd[0] != INQUIRY && common->cmnd[0] != REQUEST_SENSE) {
+ common->cmnd[0] != INQUIRY &&
+ common->cmnd[0] != REQUEST_SENSE) {
curlun->sense_data = curlun->unit_attention_data;
curlun->unit_attention_data = SS_NO_SENSE;
return -EINVAL;
}
/* Check that only command bytes listed in the mask are non-zero */
- common->cmnd[1] &= 0x1f; /* Mask away the LUN */
+ common->cmnd[1] &= 0x1f; /* Mask away the LUN */
for (i = 1; i < cmnd_size; ++i) {
if (common->cmnd[i] && !(mask & (1 << i))) {
if (curlun)
/* wrapper of check_command for data size in blocks handling */
static int check_command_size_in_blocks(struct fsg_common *common,
- int cmnd_size,
- enum data_direction data_dir,
- unsigned int mask, int needs_medium,
- const char *name)
+ int cmnd_size, enum data_direction data_dir,
+ unsigned int mask, int needs_medium, const char *name)
{
if (common->curlun)
common->data_size_from_cmnd <<= common->curlun->blkbits;
return check_command(common, cmnd_size, data_dir,
- mask, needs_medium, name);
-}
-
-#ifdef CONFIG_ARCH_ROCKCHIP
-static void deferred_restart(struct work_struct *dummy)
-{
- sys_sync();
- kernel_restart("loader");
-}
-
-static DECLARE_WORK(restart_work, deferred_restart);
-
-typedef struct tagLoaderParam {
- int tag;
- int length;
- char parameter[1];
- int crc;
-} PARM_INFO;
-#define PARM_TAG 0x4D524150
-#define MSC_EXT_DBG 1
-extern int GetParamterInfo(char *pbuf, int len);
-
-/* the buf is bh->buf,it is large enough. */
-static char *get_param_tag(char *buf, const char *tag)
-{
- PARM_INFO *pi;
- int i;
- char *pp = buf + 256;
- char *spp;
- i = GetParamterInfo(pp, 1024);
- pi = (PARM_INFO *) pp;
- if (pi->tag != PARM_TAG) {
-error_out:
- printk("paramter error,tag=0x%x\n", pi->tag);
- return NULL;
- }
- if (pi->length + sizeof(PARM_INFO) > i) {
- GetParamterInfo(pp, pi->length + sizeof(PARM_INFO) + 511);
- }
- pp = strstr(pi->parameter, tag);
- if (!pp)
- goto error_out;
- pp += strlen(tag); /* sizeof "MACHINE_MODEL:" */
- while (*pp == ' ' || *pp == '\t') {
- if (pp - pi->parameter >= pi->length)
- break;
- pp++;
- }
- spp = pp;
- while (*pp != 0x0d && *pp != 0x0a) {
- if (pp - pi->parameter >= pi->length)
- break;
- pp++;
- }
- *pp = 0;
- if (spp == pp)
- return NULL;
- return spp;
-}
-
-static int do_get_product_name(int ret, char *buf)
-{
- char *tag = "MACHINE_MODEL:";
- char *pname;
-#if MSC_EXT_DBG
- char tbuf[1024];
- if (buf == NULL)
- buf = tbuf;
-#endif
- memset(buf, 0, ret);
- pname = get_param_tag(buf, tag);
- if (pname) {
- strcpy(buf, pname);
- }
-#if MSC_EXT_DBG
- printk("%s%s\n", tag, buf);
-#endif
- return ret;
-}
-
-static int do_get_versions(int ret, char *buf)
-{
- /* get boot version and fireware version from cmdline
- * bootver=2010-07-08#4.02 firmware_ver=1.0.0 // Firmware Ver:16.01.0000
- * return format: 0x02 0x04 0x00 0x00 0x00 0x01
- * RK29: bootver=2011-07-18#2.05 firmware_ver=0.2.3 (==00.02.0003)
- * for the old loader,the firmware_ver may be empty,so get the fw ver from paramter.
- */
-#define ASC_BCD0(c) (((c-'0'))&0xf)
-#define ASC_BCD1(c) (((c-'0')<<4)&0xf0)
-
- char *ver = buf;
- char *p_l, *p_f;
- char *l_tag = "bootver=";
- char *fw_tag = "FIRMWARE_VER:";
-
-#if MSC_EXT_DBG
- char tbuf[1024];
- if (ver == NULL)
- ver = tbuf;
-#endif
-
- memset(ver, 0x00, ret);
- p_l = strstr(saved_command_line, l_tag);
- if (!p_l) {
- return ret;
- }
- p_l += strlen(l_tag);
- p_l = strchr(p_l, '#');
- if (p_l) {
- p_l++;
- if (p_l[1] == '.') {
- ver[1] = ASC_BCD0(p_l[0]);
- p_l += 2;
- } else {
- ver[1] = ASC_BCD1(p_l[0]) | ASC_BCD0(p_l[1]);
- p_l += 3;
- }
- ver[0] = ASC_BCD1(p_l[0]) | ASC_BCD0(p_l[1]);
- }
-
- p_f = get_param_tag(ver, fw_tag);
- if (!p_f)
- return ret;
-
- if (p_f[1] == '.') {
- ver[5] = ASC_BCD0(p_f[0]);
- p_f += 2;
- } else {
- ver[5] = ASC_BCD1(p_f[0]) | ASC_BCD0(p_f[1]);
- p_f += 3;
- }
- if (p_f[1] == '.') {
- ver[4] = ASC_BCD0(p_f[0]);
- p_f += 2;
- } else {
- ver[4] = ASC_BCD1(p_f[0]) | ASC_BCD0(p_f[1]);
- p_f += 3;
- }
- ver[2] = ASC_BCD0(p_f[0]);
- p_f++;
- if (p_f[0] != ' ') {
- ver[2] |= ASC_BCD1(p_f[0]);
- p_f++;
- }
- /* only support 2 byte version. */
- ver[3] = 0;
-
-#if MSC_EXT_DBG
- printk("VERSION:%02x %02x %02x %02x %02x %02x\n",
- ver[0], ver[1], ver[2], ver[3], ver[4], ver[5]);
-#endif
- return ret;
+ mask, needs_medium, name);
}
-#endif
-
static int do_scsi_command(struct fsg_common *common)
{
- struct fsg_buffhd *bh;
- int rc;
- int reply = -EINVAL;
- int i;
- static char unknown[16];
-#ifdef CONFIG_ARCH_ROCKCHIP
- struct fsg_common *fsg = common;
-#endif
+ struct fsg_buffhd *bh;
+ int rc;
+ int reply = -EINVAL;
+ int i;
+ static char unknown[16];
dump_cdb(common);
case INQUIRY:
common->data_size_from_cmnd = common->cmnd[4];
reply = check_command(common, 6, DATA_DIR_TO_HOST,
- (1 << 4), 0, "INQUIRY");
+ (1<<4), 0,
+ "INQUIRY");
if (reply == 0)
reply = do_inquiry(common, bh);
break;
case MODE_SELECT:
common->data_size_from_cmnd = common->cmnd[4];
reply = check_command(common, 6, DATA_DIR_FROM_HOST,
- (1 << 1) | (1 << 4), 0, "MODE SELECT(6)");
+ (1<<1) | (1<<4), 0,
+ "MODE SELECT(6)");
if (reply == 0)
reply = do_mode_select(common, bh);
break;
case MODE_SELECT_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command(common, 10, DATA_DIR_FROM_HOST,
- (1 << 1) | (3 << 7), 0,
+ (1<<1) | (3<<7), 0,
"MODE SELECT(10)");
if (reply == 0)
reply = do_mode_select(common, bh);
case MODE_SENSE:
common->data_size_from_cmnd = common->cmnd[4];
reply = check_command(common, 6, DATA_DIR_TO_HOST,
- (1 << 1) | (1 << 2) | (1 << 4), 0,
+ (1<<1) | (1<<2) | (1<<4), 0,
"MODE SENSE(6)");
if (reply == 0)
reply = do_mode_sense(common, bh);
case MODE_SENSE_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (1 << 1) | (1 << 2) | (3 << 7), 0,
+ (1<<1) | (1<<2) | (3<<7), 0,
"MODE SENSE(10)");
if (reply == 0)
reply = do_mode_sense(common, bh);
case ALLOW_MEDIUM_REMOVAL:
common->data_size_from_cmnd = 0;
reply = check_command(common, 6, DATA_DIR_NONE,
- (1 << 4), 0,
+ (1<<4), 0,
"PREVENT-ALLOW MEDIUM REMOVAL");
if (reply == 0)
reply = do_prevent_allow(common);
i = common->cmnd[4];
common->data_size_from_cmnd = (i == 0) ? 256 : i;
reply = check_command_size_in_blocks(common, 6,
- DATA_DIR_TO_HOST,
- (7 << 1) | (1 << 4), 1,
- "READ(6)");
+ DATA_DIR_TO_HOST,
+ (7<<1) | (1<<4), 1,
+ "READ(6)");
if (reply == 0)
reply = do_read(common);
break;
case READ_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command_size_in_blocks(common, 10,
- DATA_DIR_TO_HOST,
- (1 << 1) | (0xf << 2) | (3
- <<
- 7),
- 1, "READ(10)");
+ DATA_DIR_TO_HOST,
+ (1<<1) | (0xf<<2) | (3<<7), 1,
+ "READ(10)");
if (reply == 0)
reply = do_read(common);
break;
case READ_12:
common->data_size_from_cmnd =
- get_unaligned_be32(&common->cmnd[6]);
+ get_unaligned_be32(&common->cmnd[6]);
reply = check_command_size_in_blocks(common, 12,
- DATA_DIR_TO_HOST,
- (1 << 1) | (0xf << 2) |
- (0xf << 6), 1, "READ(12)");
+ DATA_DIR_TO_HOST,
+ (1<<1) | (0xf<<2) | (0xf<<6), 1,
+ "READ(12)");
if (reply == 0)
reply = do_read(common);
break;
case READ_CAPACITY:
common->data_size_from_cmnd = 8;
reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (0xf << 2) | (1 << 8), 1,
+ (0xf<<2) | (1<<8), 1,
"READ CAPACITY");
if (reply == 0)
reply = do_read_capacity(common, bh);
if (!common->curlun || !common->curlun->cdrom)
goto unknown_cmnd;
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (3 << 7) | (0x1f << 1), 1, "READ HEADER");
+ (3<<7) | (0x1f<<1), 1,
+ "READ HEADER");
if (reply == 0)
reply = do_read_header(common, bh);
break;
if (!common->curlun || !common->curlun->cdrom)
goto unknown_cmnd;
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (7 << 6) | (1 << 1), 1, "READ TOC");
+ (7<<6) | (1<<1), 1,
+ "READ TOC");
if (reply == 0)
reply = do_read_toc(common, bh);
break;
case READ_FORMAT_CAPACITIES:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command(common, 10, DATA_DIR_TO_HOST,
- (3 << 7), 1, "READ FORMAT CAPACITIES");
+ (3<<7), 1,
+ "READ FORMAT CAPACITIES");
if (reply == 0)
reply = do_read_format_capacities(common, bh);
break;
case REQUEST_SENSE:
common->data_size_from_cmnd = common->cmnd[4];
reply = check_command(common, 6, DATA_DIR_TO_HOST,
- (1 << 4), 0, "REQUEST SENSE");
+ (1<<4), 0,
+ "REQUEST SENSE");
if (reply == 0)
reply = do_request_sense(common, bh);
break;
case START_STOP:
common->data_size_from_cmnd = 0;
reply = check_command(common, 6, DATA_DIR_NONE,
- (1 << 1) | (1 << 4), 0,
+ (1<<1) | (1<<4), 0,
"START-STOP UNIT");
if (reply == 0)
reply = do_start_stop(common);
case SYNCHRONIZE_CACHE:
common->data_size_from_cmnd = 0;
reply = check_command(common, 10, DATA_DIR_NONE,
- (0xf << 2) | (3 << 7), 1,
+ (0xf<<2) | (3<<7), 1,
"SYNCHRONIZE CACHE");
if (reply == 0)
reply = do_synchronize_cache(common);
case TEST_UNIT_READY:
common->data_size_from_cmnd = 0;
reply = check_command(common, 6, DATA_DIR_NONE,
- 0, 1, "TEST UNIT READY");
+ 0, 1,
+ "TEST UNIT READY");
break;
- /*
- * Although optional, this command is used by MS-Windows. We
- * support a minimal version: BytChk must be 0.
- */
+ /*
+ * Although optional, this command is used by MS-Windows. We
+ * support a minimal version: BytChk must be 0.
+ */
case VERIFY:
common->data_size_from_cmnd = 0;
reply = check_command(common, 10, DATA_DIR_NONE,
- (1 << 1) | (0xf << 2) | (3 << 7), 1,
+ (1<<1) | (0xf<<2) | (3<<7), 1,
"VERIFY");
if (reply == 0)
-#ifdef CONFIG_ARCH_ROCKCHIP
- reply = 0; /* zyf 20100302 */
-#else
reply = do_verify(common);
-#endif
break;
case WRITE_6:
i = common->cmnd[4];
common->data_size_from_cmnd = (i == 0) ? 256 : i;
reply = check_command_size_in_blocks(common, 6,
- DATA_DIR_FROM_HOST,
- (7 << 1) | (1 << 4), 1,
- "WRITE(6)");
+ DATA_DIR_FROM_HOST,
+ (7<<1) | (1<<4), 1,
+ "WRITE(6)");
if (reply == 0)
reply = do_write(common);
break;
case WRITE_10:
common->data_size_from_cmnd =
- get_unaligned_be16(&common->cmnd[7]);
+ get_unaligned_be16(&common->cmnd[7]);
reply = check_command_size_in_blocks(common, 10,
- DATA_DIR_FROM_HOST,
- (1 << 1) | (0xf << 2) | (3
- <<
- 7),
- 1, "WRITE(10)");
+ DATA_DIR_FROM_HOST,
+ (1<<1) | (0xf<<2) | (3<<7), 1,
+ "WRITE(10)");
if (reply == 0)
reply = do_write(common);
break;
case WRITE_12:
common->data_size_from_cmnd =
- get_unaligned_be32(&common->cmnd[6]);
+ get_unaligned_be32(&common->cmnd[6]);
reply = check_command_size_in_blocks(common, 12,
- DATA_DIR_FROM_HOST,
- (1 << 1) | (0xf << 2) |
- (0xf << 6), 1,
- "WRITE(12)");
+ DATA_DIR_FROM_HOST,
+ (1<<1) | (0xf<<2) | (0xf<<6), 1,
+ "WRITE(12)");
if (reply == 0)
reply = do_write(common);
break;
- /*
- * Some mandatory commands that we recognize but don't implement.
- * They don't mean much in this setting. It's left as an exercise
- * for anyone interested to implement RESERVE and RELEASE in terms
- * of Posix locks.
- */
+ /*
+ * Some mandatory commands that we recognize but don't implement.
+ * They don't mean much in this setting. It's left as an exercise
+ * for anyone interested to implement RESERVE and RELEASE in terms
+ * of Posix locks.
+ */
case FORMAT_UNIT:
case RELEASE:
case RESERVE:
reply = -EINVAL;
}
break;
-#ifdef CONFIG_ARCH_ROCKCHIP
- case 0xff:
- if (fsg->cmnd[1] != 0xe0 ||
- fsg->cmnd[2] != 0xff || fsg->cmnd[3] != 0xff ||
- fsg->cmnd[4] != 0xff)
- break;
- if (fsg->cmnd_size >= 6 && fsg->cmnd[5] == 0xfe) {
- schedule_work(&restart_work);
- } else if (fsg->cmnd[5] == 0xf3) {
- fsg->data_size_from_cmnd = fsg->data_size;
- /* get product name from parameter section */
- reply = do_get_product_name(fsg->data_size, bh->buf);
- } else if (fsg->cmnd[5] == 0xff) {
- fsg->data_size_from_cmnd = fsg->data_size;
- reply = do_get_versions(fsg->data_size, bh->buf);
- }
- break;
-#endif
}
up_read(&common->filesem);
/* Set up the single reply buffer for finish_reply() */
if (reply == -EINVAL)
- reply = 0; /* Error reply length */
+ reply = 0; /* Error reply length */
if (reply >= 0 && common->data_dir == DATA_DIR_TO_HOST) {
- reply = min((u32) reply, common->data_size_from_cmnd);
+ reply = min((u32)reply, common->data_size_from_cmnd);
bh->inreq->length = reply;
bh->state = BUF_STATE_FULL;
common->residue -= reply;
- }
- /* Otherwise it's already set */
+ } /* Otherwise it's already set */
+
return 0;
}
+
/*-------------------------------------------------------------------------*/
static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh)
{
- struct usb_request *req = bh->outreq;
- struct bulk_cb_wrap *cbw = req->buf;
- struct fsg_common *common = fsg->common;
+ struct usb_request *req = bh->outreq;
+ struct bulk_cb_wrap *cbw = req->buf;
+ struct fsg_common *common = fsg->common;
/* Was this a real packet? Should it be ignored? */
if (req->status || test_bit(IGNORE_BULK_OUT, &fsg->atomic_bitflags))
/* Is the CBW valid? */
if (req->actual != US_BULK_CB_WRAP_LEN ||
- cbw->Signature != cpu_to_le32(US_BULK_CB_SIGN)) {
+ cbw->Signature != cpu_to_le32(
+ US_BULK_CB_SIGN)) {
DBG(fsg, "invalid CBW: len %u sig 0x%x\n",
- req->actual, le32_to_cpu(cbw->Signature));
+ req->actual,
+ le32_to_cpu(cbw->Signature));
/*
* The Bulk-only spec says we MUST stall the IN endpoint
/* Is the CBW meaningful? */
if (cbw->Lun >= FSG_MAX_LUNS || cbw->Flags & ~US_BULK_FLAG_IN ||
- cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
+ cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) {
DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, "
- "cmdlen %u\n", cbw->Lun, cbw->Flags, cbw->Length);
+ "cmdlen %u\n",
+ cbw->Lun, cbw->Flags, cbw->Length);
/*
* We can do anything we want here, so let's stall the
if (common->data_size == 0)
common->data_dir = DATA_DIR_NONE;
common->lun = cbw->Lun;
- if (common->lun >= 0 && common->lun < common->nluns)
+ if (common->lun < common->nluns)
common->curlun = &common->luns[common->lun];
else
common->curlun = NULL;
static int get_next_command(struct fsg_common *common)
{
- struct fsg_buffhd *bh;
- int rc = 0;
+ struct fsg_buffhd *bh;
+ int rc = 0;
/* Wait for the next buffer to become available */
bh = common->next_buffhd_to_fill;
return rc;
}
+
/*-------------------------------------------------------------------------*/
static int alloc_request(struct fsg_common *common, struct usb_ep *ep,
- struct usb_request **preq)
+ struct usb_request **preq)
{
*preq = usb_ep_alloc_request(ep, GFP_ATOMIC);
if (*preq)
/* Allocate the requests */
for (i = 0; i < fsg_num_buffers; ++i) {
- struct fsg_buffhd *bh = &common->buffhds[i];
+ struct fsg_buffhd *bh = &common->buffhds[i];
rc = alloc_request(common, fsg->bulk_in, &bh->inreq);
if (rc)
return rc;
}
+
/****************************** ALT CONFIGS ******************************/
static int fsg_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
}
+
/*-------------------------------------------------------------------------*/
static void handle_exception(struct fsg_common *common)
{
- siginfo_t info;
- int i;
- struct fsg_buffhd *bh;
- enum fsg_state old_state;
- struct fsg_lun *curlun;
- unsigned int exception_req_tag;
+ siginfo_t info;
+ int i;
+ struct fsg_buffhd *bh;
+ enum fsg_state old_state;
+ struct fsg_lun *curlun;
+ unsigned int exception_req_tag;
/*
* Clear the existing signals. Anything but SIGUSR1 is converted
*/
for (;;) {
int sig =
- dequeue_signal_lock(current, ¤t->blocked, &info);
+ dequeue_signal_lock(current, ¤t->blocked, &info);
if (!sig)
break;
if (sig != SIGUSR1) {
* CONFIG_CHANGE cases.
*/
/* for (i = 0; i < common->nluns; ++i) */
- /* common->luns[i].unit_attention_data = */
- /* SS_RESET_OCCURRED; */
+ /* common->luns[i].unit_attention_data = */
+ /* SS_RESET_OCCURRED; */
break;
case FSG_STATE_CONFIG_CHANGE:
case FSG_STATE_EXIT:
case FSG_STATE_TERMINATED:
- do_set_interface(common, NULL); /* Free resources */
+ do_set_interface(common, NULL); /* Free resources */
spin_lock_irq(&common->lock);
common->state = FSG_STATE_TERMINATED; /* Stop the thread */
spin_unlock_irq(&common->lock);
}
}
+
/*-------------------------------------------------------------------------*/
static int fsg_main_thread(void *common_)
{
- struct fsg_common *common = common_;
+ struct fsg_common *common = common_;
/*
* Allow the thread to be killed by a signal, but set the signal mask
common->state = FSG_STATE_STATUS_PHASE;
spin_unlock_irq(&common->lock);
-#ifdef CONFIG_USB_CSW_HACK
- /* Since status is already sent for write scsi command,
- * need to skip sending status once again if it is a
- * write scsi command.
- */
- if (csw_hack_sent) {
- csw_hack_sent = 0;
- continue;
- }
-#endif
if (send_status(common))
continue;
spin_unlock_irq(&common->lock);
if (!common->ops || !common->ops->thread_exits
- || common->ops->thread_exits(common) < 0) {
+ || common->ops->thread_exits(common) < 0) {
struct fsg_lun *curlun = common->luns;
unsigned i = common->nluns;
complete_and_exit(&common->thread_notifier, 0);
}
+
/*************************** DEVICE ATTRIBUTES ***************************/
static DEVICE_ATTR(ro, 0644, fsg_show_ro, fsg_store_ro);
static DEVICE_ATTR(nofua, 0644, fsg_show_nofua, fsg_store_nofua);
static DEVICE_ATTR(file, 0644, fsg_show_file, fsg_store_file);
-#ifdef CONFIG_USB_MSC_PROFILING
-static DEVICE_ATTR(perf, 0644, fsg_show_perf, fsg_store_perf);
-#endif
static struct device_attribute dev_attr_ro_cdrom =
-__ATTR(ro, 0444, fsg_show_ro, NULL);
+ __ATTR(ro, 0444, fsg_show_ro, NULL);
static struct device_attribute dev_attr_file_nonremovable =
-__ATTR(file, 0444, fsg_show_file, NULL);
+ __ATTR(file, 0444, fsg_show_file, NULL);
+
/****************************** FSG COMMON ******************************/
curlun->ro = lcfg->cdrom || lcfg->ro;
curlun->initially_ro = curlun->ro;
curlun->removable = lcfg->removable;
- curlun->nofua = lcfg->nofua;
curlun->dev.release = fsg_lun_release;
curlun->dev.parent = &gadget->dev;
/* curlun->dev.driver = &fsg_driver.driver; XXX */
rc = device_create_file(&curlun->dev,
curlun->cdrom
- ? &dev_attr_ro_cdrom : &dev_attr_ro);
+ ? &dev_attr_ro_cdrom
+ : &dev_attr_ro);
if (rc)
goto error_luns;
rc = device_create_file(&curlun->dev,
curlun->removable
- ? &dev_attr_file
- : &dev_attr_file_nonremovable);
+ ? &dev_attr_file
+ : &dev_attr_file_nonremovable);
if (rc)
goto error_luns;
rc = device_create_file(&curlun->dev, &dev_attr_nofua);
if (rc)
goto error_luns;
-#ifdef CONFIG_USB_MSC_PROFILING
- rc = device_create_file(&curlun->dev, &dev_attr_perf);
- if (rc)
- dev_err(&gadget->dev, "failed to create sysfs entry:"
- "(dev_attr_perf) error: %d\n", rc);
-#endif
+
if (lcfg->filename) {
rc = fsg_lun_open(curlun, lcfg->filename);
if (rc)
/* Prepare inquiryString */
i = get_default_bcdDevice();
snprintf(common->inquiry_string, sizeof common->inquiry_string,
- "%-8s%-16s%04x", cfg->vendor_name ? : "Linux",
+ "%-8s%-16s%04x", cfg->vendor_name ?: "Linux",
/* Assume product name dependent on the first LUN */
- cfg->product_name ? : (common->luns->cdrom
- ? "File-Stor Gadget"
- : "File-CD Gadget"), i);
+ cfg->product_name ?: (common->luns->cdrom
+ ? "File-Stor Gadget"
+ : "File-CD Gadget"),
+ i);
/*
* Some peripheral controllers are known not to be able to
* halt bulk endpoints correctly. If one of them is present,
* disable stalls.
*/
- common->can_stall = cfg->can_stall && !(gadget_is_at91(common->gadget));
+ common->can_stall = cfg->can_stall &&
+ !(gadget_is_at91(common->gadget));
spin_lock_init(&common->lock);
kref_init(&common->ref);
/* Tell the thread to start working */
common->thread_task =
- kthread_create(fsg_main_thread, common, "file-storage");
+ kthread_create(fsg_main_thread, common, "file-storage");
if (IS_ERR(common->thread_task)) {
rc = PTR_ERR(common->thread_task);
goto error_release;
pathbuf = kmalloc(PATH_MAX, GFP_KERNEL);
for (i = 0, nluns = common->nluns, curlun = common->luns;
- i < nluns; ++curlun, ++i) {
+ i < nluns;
+ ++curlun, ++i) {
char *p = "(no medium)";
if (fsg_lun_is_open(curlun)) {
p = "(error)";
LINFO(curlun, "LUN: %s%s%sfile: %s\n",
curlun->removable ? "removable " : "",
curlun->ro ? "read only " : "",
- curlun->cdrom ? "CD-ROM " : "", p);
+ curlun->cdrom ? "CD-ROM " : "",
+ p);
}
kfree(pathbuf);
/* In error recovery common->nluns may be zero. */
for (; i; --i, ++lun) {
-#ifdef CONFIG_USB_MSC_PROFILING
- device_remove_file(&lun->dev, &dev_attr_perf);
-#endif
device_remove_file(&lun->dev, &dev_attr_nofua);
device_remove_file(&lun->dev,
lun->cdrom
- ? &dev_attr_ro_cdrom : &dev_attr_ro);
+ ? &dev_attr_ro_cdrom
+ : &dev_attr_ro);
device_remove_file(&lun->dev,
lun->removable
- ? &dev_attr_file
- : &dev_attr_file_nonremovable);
+ ? &dev_attr_file
+ : &dev_attr_file_nonremovable);
fsg_lun_close(lun);
device_unregister(&lun->dev);
}
kfree(common);
}
+
/*-------------------------------------------------------------------------*/
static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
{
- struct fsg_dev *fsg = fsg_from_func(f);
- struct fsg_common *common = fsg->common;
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct fsg_common *common = fsg->common;
DBG(fsg, "unbind\n");
if (fsg->common->fsg == fsg) {
static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
{
- struct fsg_dev *fsg = fsg_from_func(f);
- struct usb_gadget *gadget = c->cdev->gadget;
- int i;
- struct usb_ep *ep;
- unsigned max_burst;
- int ret;
+ struct fsg_dev *fsg = fsg_from_func(f);
+ struct usb_gadget *gadget = c->cdev->gadget;
+ int i;
+ struct usb_ep *ep;
+ unsigned max_burst;
+ int ret;
fsg->gadget = gadget;
/* Assume endpoint addresses are the same for both speeds */
fsg_hs_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
+ fsg_fs_bulk_in_desc.bEndpointAddress;
fsg_hs_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
+ fsg_fs_bulk_out_desc.bEndpointAddress;
/* Calculate bMaxBurst, we know packet size is 1024 */
max_burst = min_t(unsigned, FSG_BUFLEN / 1024, 15);
fsg_ss_bulk_in_desc.bEndpointAddress =
- fsg_fs_bulk_in_desc.bEndpointAddress;
+ fsg_fs_bulk_in_desc.bEndpointAddress;
fsg_ss_bulk_in_comp_desc.bMaxBurst = max_burst;
fsg_ss_bulk_out_desc.bEndpointAddress =
- fsg_fs_bulk_out_desc.bEndpointAddress;
+ fsg_fs_bulk_out_desc.bEndpointAddress;
fsg_ss_bulk_out_comp_desc.bMaxBurst = max_burst;
ret = usb_assign_descriptors(f, fsg_fs_function, fsg_hs_function,
- fsg_ss_function);
+ fsg_ss_function);
if (ret)
goto autoconf_fail;
if (unlikely(!fsg))
return -ENOMEM;
- fsg->function.name = FSG_DRIVER_DESC;
- fsg->function.strings = fsg_strings_array;
- fsg->function.bind = fsg_bind;
- fsg->function.unbind = fsg_unbind;
- fsg->function.setup = fsg_setup;
- fsg->function.set_alt = fsg_set_alt;
- fsg->function.disable = fsg_disable;
+ fsg->function.name = FSG_DRIVER_DESC;
+ fsg->function.strings = fsg_strings_array;
+ fsg->function.bind = fsg_bind;
+ fsg->function.unbind = fsg_unbind;
+ fsg->function.setup = fsg_setup;
+ fsg->function.set_alt = fsg_set_alt;
+ fsg->function.disable = fsg_disable;
- fsg->common = common;
+ fsg->common = common;
/*
* Our caller holds a reference to common structure so we
* don't have to be worry about it being freed until we return
return rc;
}
+
/************************* Module parameters *************************/
struct fsg_module_parameters {
- char *file[FSG_MAX_LUNS];
- bool ro[FSG_MAX_LUNS];
- bool removable[FSG_MAX_LUNS];
- bool cdrom[FSG_MAX_LUNS];
- bool nofua[FSG_MAX_LUNS];
-
- unsigned int file_count, ro_count, removable_count, cdrom_count;
- unsigned int nofua_count;
- unsigned int luns; /* nluns */
- bool stall; /* can_stall */
+ char *file[FSG_MAX_LUNS];
+ bool ro[FSG_MAX_LUNS];
+ bool removable[FSG_MAX_LUNS];
+ bool cdrom[FSG_MAX_LUNS];
+ bool nofua[FSG_MAX_LUNS];
+
+ unsigned int file_count, ro_count, removable_count, cdrom_count;
+ unsigned int nofua_count;
+ unsigned int luns; /* nluns */
+ bool stall; /* can_stall */
};
#define _FSG_MODULE_PARAM_ARRAY(prefix, params, name, type, desc) \
/* Configure LUNs */
cfg->nluns =
- min(params->luns ? : (params->file_count ? : 1u),
- (unsigned)FSG_MAX_LUNS);
+ min(params->luns ?: (params->file_count ?: 1u),
+ (unsigned)FSG_MAX_LUNS);
for (i = 0, lun = cfg->luns; i < cfg->nluns; ++i, ++lun) {
lun->ro = !!params->ro[i];
lun->cdrom = !!params->cdrom[i];
lun->removable = !!params->removable[i];
- lun->filename = params->file_count > i && params->file[i][0]
- ? params->file[i]
- : 0;
+ lun->filename =
+ params->file_count > i && params->file[i][0]
+ ? params->file[i]
+ : 0;
}
/* Let MSF use defaults */
cfg->can_stall = params->stall;
}
-static inline struct fsg_common *fsg_common_from_params(struct fsg_common
- *common,
- struct usb_composite_dev
- *cdev,
- const struct
- fsg_module_parameters
- *params)
- __attribute__ ((unused));
-static inline struct fsg_common *fsg_common_from_params(struct fsg_common
- *common,
- struct usb_composite_dev
- *cdev,
- const struct
- fsg_module_parameters
- *params)
+static inline struct fsg_common *
+fsg_common_from_params(struct fsg_common *common,
+ struct usb_composite_dev *cdev,
+ const struct fsg_module_parameters *params)
+ __attribute__((unused));
+static inline struct fsg_common *
+fsg_common_from_params(struct fsg_common *common,
+ struct usb_composite_dev *cdev,
+ const struct fsg_module_parameters *params)
{
struct fsg_config cfg;
fsg_config_from_params(&cfg, params);
ret = mtp_send_event(dev, &event);
goto out;
}
-#ifdef CONFIG_COMPAT
- case MTP_SEND_EVENT_32:
- {
- struct mtp_event_32 event_32;
- struct mtp_event event;
- /* return here so we don't change dev->state below,
- * which would interfere with bulk transfer state.
- */
- if (copy_from_user(&event_32, (void __user *)value,
- sizeof(event_32)))
- ret = -EFAULT;
- else {
- event.length = event_32.length;
- event.data = (void *)(unsigned long)event_32.data;
- ret = mtp_send_event(dev, &event);
- }
- goto out;
- }
-#endif
}
fail:
.read = mtp_read,
.write = mtp_write,
.unlocked_ioctl = mtp_ioctl,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = mtp_ioctl,
-#endif
.open = mtp_open,
.release = mtp_release,
};
}
if (skb->len < sizeof *hdr) {
- pr_err("invalid rndis pkt: skblen:%u hdr_len:%zu",
+ pr_err("invalid rndis pkt: skblen:%u hdr_len:%u",
skb->len, sizeof *hdr);
dev_kfree_skb_any(skb);
return -EINVAL;
#define VLDBG(lun, fmt, args...) do { } while (0)
#endif /* VERBOSE_DEBUG */
-#define LDBG(lun, fmt, args...) dev_dbg(&(lun)->dev, fmt, ## args)
-#define LERROR(lun, fmt, args...) dev_err(&(lun)->dev, fmt, ## args)
+#define LDBG(lun, fmt, args...) dev_dbg (&(lun)->dev, fmt, ## args)
+#define LERROR(lun, fmt, args...) dev_err (&(lun)->dev, fmt, ## args)
#define LWARN(lun, fmt, args...) dev_warn(&(lun)->dev, fmt, ## args)
#define LINFO(lun, fmt, args...) dev_info(&(lun)->dev, fmt, ## args)
unsigned int blkbits; /* Bits of logical block size of bound block device */
unsigned int blksize; /* logical block size of bound block device */
struct device dev;
-#ifdef CONFIG_USB_MSC_PROFILING
- spinlock_t lock;
- struct {
-
- unsigned long rbytes;
- unsigned long wbytes;
- ktime_t rtime;
- ktime_t wtime;
- } perf;
-
-#endif
};
static inline bool fsg_lun_is_open(struct fsg_lun *curlun)
#define EP0_BUFSIZE 256
#define DELAYED_STATUS (EP0_BUFSIZE + 999) /* An impossibly large value */
-#ifdef CONFIG_USB_CSW_HACK
-#define fsg_num_buffers 4
-#else
#ifdef CONFIG_USB_GADGET_DEBUG_FILES
static unsigned int fsg_num_buffers = CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS;
#define fsg_num_buffers CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS
#endif /* CONFIG_USB_DEBUG */
-#endif /* CONFIG_USB_CSW_HACK */
/* check if fsg_num_buffers is within a valid range */
static inline int fsg_num_buffers_validate(void)
if (fsg_num_buffers >= 2 && fsg_num_buffers <= 4)
return 0;
pr_err("fsg_num_buffers %u is out of range (%d to %d)\n",
- fsg_num_buffers, 2 , 4);
+ fsg_num_buffers, 2 ,4);
return -EINVAL;
}
/* Default size of buffer length. */
-#define FSG_BUFLEN ((u32)65536)
+#define FSG_BUFLEN ((u32)16384)
/* Maximal number of LUNs supported in mass storage function */
#define FSG_MAX_LUNS 8
return sprintf(buf, "%u\n", curlun->nofua);
}
-#ifdef CONFIG_USB_MSC_PROFILING
-static ssize_t fsg_show_perf(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct fsg_lun *curlun = fsg_lun_from_dev(dev);
- unsigned long rbytes, wbytes;
- int64_t rtime, wtime;
-
- spin_lock(&curlun->lock);
- rbytes = curlun->perf.rbytes;
- wbytes = curlun->perf.wbytes;
- rtime = ktime_to_us(curlun->perf.rtime);
- wtime = ktime_to_us(curlun->perf.wtime);
- spin_unlock(&curlun->lock);
-
- return snprintf(buf, PAGE_SIZE, "Write performance :"
- "%lu bytes in %lld microseconds\n"
- "Read performance :"
- "%lu bytes in %lld microseconds\n",
- wbytes, wtime, rbytes, rtime);
-}
-static ssize_t fsg_store_perf(struct device *dev, struct device_attribute *attr,
- const char *buf, size_t count)
-{
- struct fsg_lun *curlun = fsg_lun_from_dev(dev);
- int value;
-
- sscanf(buf, "%d", &value);
- if (!value) {
- spin_lock(&curlun->lock);
- memset(&curlun->perf, 0, sizeof(curlun->perf));
- spin_unlock(&curlun->lock);
- }
-
- return count;
-}
-#endif
static ssize_t fsg_show_file(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct rw_semaphore *filesem = dev_get_drvdata(dev);
int rc = 0;
-#ifndef CONFIG_USB_G_ANDROID
if (curlun->prevent_medium_removal && fsg_lun_is_open(curlun)) {
LDBG(curlun, "eject attempt prevented\n");
return -EBUSY; /* "Door is locked" */
}
-#endif
/* Remove a trailing newline */
if (count > 0 && buf[count-1] == '\n')
/* Load new medium */
down_write(filesem);
if (count > 0 && buf[0]) {
- LDBG(curlun, "fsg_lun_open\n");
/* fsg_lun_open() will close existing file if any. */
rc = fsg_lun_open(curlun, buf);
if (rc == 0)
curlun->unit_attention_data =
SS_NOT_READY_TO_READY_TRANSITION;
} else if (fsg_lun_is_open(curlun)) {
- LDBG(curlun, "fsg_lun_open\n");
fsg_lun_close(curlun);
curlun->unit_attention_data = SS_MEDIUM_NOT_PRESENT;
}
if USB_EHCI_HCD
-config USB_EHCI1_RK
- tristate "Rockchip EHCI1 support"
- depends on ARCH_ROCKCHIP
- select USB_EHCI_ROOT_HUB_TT
- default n
- ---help---
- Enables support for the EHCI1 USB controller on the RK platform.
-
-config USB_EHCI_RK
- tristate "Rockchip EHCI HOST20 support"
- depends on ARCH_ROCKCHIP
- select USB_EHCI_ROOT_HUB_TT
- default n
- ---help---
- Enables support EHCI for RK3288 and later chips.
-
config USB_EHCI_PCI
tristate
depends on PCI
if USB_OHCI_HCD
-config USB_OHCI_HCD_RK
- bool "OHCI support for RK3288 and later chips"
- depends on ARCH_ROCKCHIP
- default n
- ---help---
- Enable support for the OHCI controller on RK3288 and later chips.
-
config USB_OHCI_HCD_OMAP1
bool "OHCI support for OMAP1/2 chips"
depends on ARCH_OMAP1
obj-$(CONFIG_USB_EHCI_HCD_SYNOPSYS) += ehci-h20ahb.o
obj-$(CONFIG_USB_EHCI_HCD_AT91) += ehci-atmel.o
obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o
-obj-$(CONFIG_USB_EHCI_RK) += ehci-rockchip.o
obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o
obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o
obj-$(CONFIG_USB_ISP1362_HCD) += isp1362-hcd.o
obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o
-obj-$(CONFIG_USB_OHCI_HCD_PLATFORM) += ohci-platform.o
obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o
obj-$(CONFIG_USB_FHCI_HCD) += fhci.o
obj-$(CONFIG_USB_XHCI_HCD) += xhci-hcd.o
#define PLATFORM_DRIVER ehci_hcd_tilegx_driver
#endif
-#ifdef CONFIG_USB_EHCI1_RK
-#include "ehci1-rockchip.c"
-#define ROCKCHIP_PLATFORM_DRIVER ehci1_rk_driver
-#endif
-
#ifdef CONFIG_USB_EHCI_HCD_PMC_MSP
#include "ehci-pmcmsp.c"
#define PLATFORM_DRIVER ehci_hcd_msp_driver
if (retval < 0)
goto clean4;
#endif
-
-#ifdef ROCKCHIP_PLATFORM_DRIVER
- retval = platform_driver_register(&ROCKCHIP_PLATFORM_DRIVER);
- if (retval < 0)
- goto clean5;
-#endif
return retval;
-#ifdef ROCKCHIP_PLATFORM_DRIVER
- platform_driver_unregister(&ROCKCHIP_PLATFORM_DRIVER);
-clean5:
-#endif
-
#ifdef XILINX_OF_PLATFORM_DRIVER
/* platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER); */
clean4:
static void __exit ehci_hcd_cleanup(void)
{
-#ifdef ROCKCHIP_PLATFORM_DRIVER
- platform_driver_unregister(&ROCKCHIP_PLATFORM_DRIVER);
-#endif
#ifdef XILINX_OF_PLATFORM_DRIVER
platform_driver_unregister(&XILINX_OF_PLATFORM_DRIVER);
#endif
*
* Copyright 2007 Steven Brown <sbrown@cortland.com>
* Copyright 2010-2012 Hauke Mehrtens <hauke@hauke-m.de>
- * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
*
* Derived from the ohci-ssb driver
* Copyright 2007 Michael Buesch <m@bues.ch>
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
-#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/err.h>
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
-#include <linux/reset.h>
#include <linux/usb.h>
#include <linux/usb/hcd.h>
#include <linux/usb/ehci_pdriver.h>
#include "ehci.h"
#define DRIVER_DESC "EHCI generic platform driver"
-#define EHCI_MAX_CLKS 3
-#define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv)
-
-struct ehci_platform_priv {
- struct clk *clks[EHCI_MAX_CLKS];
- struct reset_control *rst;
- struct phy *phy;
-};
static const char hcd_name[] = "ehci-platform";
static int ehci_platform_reset(struct usb_hcd *hcd)
{
struct platform_device *pdev = to_platform_device(hcd->self.controller);
- struct usb_ehci_pdata *pdata = dev_get_platdata(&pdev->dev);
+ struct usb_ehci_pdata *pdata = pdev->dev.platform_data;
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
hcd->has_tt = pdata->has_tt;
ehci->has_synopsys_hc_bug = pdata->has_synopsys_hc_bug;
-
- if (pdata->pre_setup) {
- retval = pdata->pre_setup(hcd);
- if (retval < 0)
- return retval;
- }
+ ehci->big_endian_desc = pdata->big_endian_desc;
+ ehci->big_endian_mmio = pdata->big_endian_mmio;
ehci->caps = hcd->regs + pdata->caps_offset;
retval = ehci_setup(hcd);
return 0;
}
-static int ehci_platform_power_on(struct platform_device *dev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
- struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
- int clk, ret;
-
- for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++) {
- ret = clk_prepare_enable(priv->clks[clk]);
- if (ret)
- goto err_disable_clks;
- }
-
- if (priv->phy) {
- ret = phy_init(priv->phy);
- if (ret)
- goto err_disable_clks;
-
- ret = phy_power_on(priv->phy);
- if (ret)
- goto err_exit_phy;
- }
-
- return 0;
-
-err_exit_phy:
- phy_exit(priv->phy);
-err_disable_clks:
- while (--clk >= 0)
- clk_disable_unprepare(priv->clks[clk]);
-
- return ret;
-}
-
-static void ehci_platform_power_off(struct platform_device *dev)
-{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
- struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
- int clk;
-
- if (priv->phy) {
- phy_power_off(priv->phy);
- phy_exit(priv->phy);
- }
-
- for (clk = EHCI_MAX_CLKS - 1; clk >= 0; clk--)
- if (priv->clks[clk])
- clk_disable_unprepare(priv->clks[clk]);
-}
-
static struct hc_driver __read_mostly ehci_platform_hc_driver;
static const struct ehci_driver_overrides platform_overrides __initconst = {
- .reset = ehci_platform_reset,
- .extra_priv_size = sizeof(struct ehci_platform_priv),
+ .reset = ehci_platform_reset,
};
-static struct usb_ehci_pdata ehci_platform_defaults = {
- .power_on = ehci_platform_power_on,
- .power_suspend = ehci_platform_power_off,
- .power_off = ehci_platform_power_off,
-};
+static struct usb_ehci_pdata ehci_platform_defaults;
static int ehci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
- struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
- struct ehci_platform_priv *priv;
- struct ehci_hcd *ehci;
- int err, irq, clk = 0;
+ struct usb_ehci_pdata *pdata;
+ int irq;
+ int err = -ENOMEM;
if (usb_disabled())
return -ENODEV;
/*
- * Use reasonable defaults so platforms don't have to provide these
- * with DT probing on ARM.
+ * use reasonable defaults so platforms don't have to provide these.
+ * with DT probing on ARM, none of these are set.
*/
- if (!pdata)
- pdata = &ehci_platform_defaults;
+ if (!dev->dev.platform_data)
+ dev->dev.platform_data = &ehci_platform_defaults;
+ if (!dev->dev.dma_mask)
+ dev->dev.dma_mask = &dev->dev.coherent_dma_mask;
+ if (!dev->dev.coherent_dma_mask)
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
- err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
- if (err)
- return err;
+ pdata = dev->dev.platform_data;
irq = platform_get_irq(dev, 0);
if (irq < 0) {
dev_err(&dev->dev, "no irq provided");
return irq;
}
-
- hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
- dev_name(&dev->dev));
- if (!hcd)
- return -ENOMEM;
-
- platform_set_drvdata(dev, hcd);
- dev->dev.platform_data = pdata;
- priv = hcd_to_ehci_priv(hcd);
- ehci = hcd_to_ehci(hcd);
-
- if (pdata == &ehci_platform_defaults && dev->dev.of_node) {
- if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
- ehci->big_endian_mmio = 1;
-
- if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
- ehci->big_endian_desc = 1;
-
- if (of_property_read_bool(dev->dev.of_node, "big-endian"))
- ehci->big_endian_mmio = ehci->big_endian_desc = 1;
-
- priv->phy = devm_phy_get(&dev->dev, "usb");
- if (IS_ERR(priv->phy)) {
- err = PTR_ERR(priv->phy);
- if (err == -EPROBE_DEFER)
- goto err_put_hcd;
- priv->phy = NULL;
- }
-
- for (clk = 0; clk < EHCI_MAX_CLKS; clk++) {
- priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
- if (IS_ERR(priv->clks[clk])) {
- err = PTR_ERR(priv->clks[clk]);
- if (err == -EPROBE_DEFER)
- goto err_put_clks;
- priv->clks[clk] = NULL;
- break;
- }
- }
- }
-
- priv->rst = devm_reset_control_get(&dev->dev, NULL);
- if (IS_ERR(priv->rst)) {
- err = PTR_ERR(priv->rst);
- if (err == -EPROBE_DEFER)
- goto err_put_clks;
- priv->rst = NULL;
- } else {
- err = reset_control_deassert(priv->rst);
- if (err)
- goto err_put_clks;
- }
-
- if (pdata->big_endian_desc)
- ehci->big_endian_desc = 1;
- if (pdata->big_endian_mmio)
- ehci->big_endian_mmio = 1;
-
-#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
- if (ehci->big_endian_mmio) {
- dev_err(&dev->dev,
- "Error: CONFIG_USB_EHCI_BIG_ENDIAN_MMIO not set\n");
- err = -EINVAL;
- goto err_reset;
- }
-#endif
-#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_DESC
- if (ehci->big_endian_desc) {
- dev_err(&dev->dev,
- "Error: CONFIG_USB_EHCI_BIG_ENDIAN_DESC not set\n");
- err = -EINVAL;
- goto err_reset;
+ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ dev_err(&dev->dev, "no memory resource provided");
+ return -ENXIO;
}
-#endif
if (pdata->power_on) {
err = pdata->power_on(dev);
if (err < 0)
- goto err_reset;
+ return err;
}
- res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
- hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
- if (IS_ERR(hcd->regs)) {
- err = PTR_ERR(hcd->regs);
+ hcd = usb_create_hcd(&ehci_platform_hc_driver, &dev->dev,
+ dev_name(&dev->dev));
+ if (!hcd) {
+ err = -ENOMEM;
goto err_power;
}
+
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
+ hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
+ if (IS_ERR(hcd->regs)) {
+ err = PTR_ERR(hcd->regs);
+ goto err_put_hcd;
+ }
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_power;
+ goto err_put_hcd;
- device_wakeup_enable(hcd->self.controller);
platform_set_drvdata(dev, hcd);
return err;
+err_put_hcd:
+ usb_put_hcd(hcd);
err_power:
if (pdata->power_off)
pdata->power_off(dev);
-err_reset:
- if (priv->rst)
- reset_control_assert(priv->rst);
-err_put_clks:
- while (--clk >= 0)
- clk_put(priv->clks[clk]);
-err_put_hcd:
- if (pdata == &ehci_platform_defaults)
- dev->dev.platform_data = NULL;
-
- usb_put_hcd(hcd);
return err;
}
static int ehci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
- struct usb_ehci_pdata *pdata = dev_get_platdata(&dev->dev);
- struct ehci_platform_priv *priv = hcd_to_ehci_priv(hcd);
- int clk;
+ struct usb_ehci_pdata *pdata = dev->dev.platform_data;
usb_remove_hcd(hcd);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(dev, NULL);
if (pdata->power_off)
pdata->power_off(dev);
- if (priv->rst)
- reset_control_assert(priv->rst);
-
- for (clk = 0; clk < EHCI_MAX_CLKS && priv->clks[clk]; clk++)
- clk_put(priv->clks[clk]);
-
- usb_put_hcd(hcd);
-
if (pdata == &ehci_platform_defaults)
dev->dev.platform_data = NULL;
return 0;
}
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
+
static int ehci_platform_suspend(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
+ struct usb_ehci_pdata *pdata = dev->platform_data;
struct platform_device *pdev =
container_of(dev, struct platform_device, dev);
bool do_wakeup = device_may_wakeup(dev);
int ret;
ret = ehci_suspend(hcd, do_wakeup);
- if (ret)
- return ret;
if (pdata->power_suspend)
pdata->power_suspend(pdev);
static int ehci_platform_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct usb_ehci_pdata *pdata = dev_get_platdata(dev);
+ struct usb_ehci_pdata *pdata = dev->platform_data;
struct platform_device *pdev =
container_of(dev, struct platform_device, dev);
ehci_resume(hcd, false);
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
+
+#else /* !CONFIG_PM */
+#define ehci_platform_suspend NULL
+#define ehci_platform_resume NULL
+#endif /* CONFIG_PM */
static const struct of_device_id vt8500_ehci_ids[] = {
{ .compatible = "via,vt8500-ehci", },
{ .compatible = "wm,prizm-ehci", },
- { .compatible = "generic-ehci", },
{}
};
-MODULE_DEVICE_TABLE(of, vt8500_ehci_ids);
static const struct platform_device_id ehci_platform_table[] = {
{ "ehci-platform", 0 },
};
MODULE_DEVICE_TABLE(platform, ehci_platform_table);
-static SIMPLE_DEV_PM_OPS(ehci_platform_pm_ops, ehci_platform_suspend,
- ehci_platform_resume);
+static const struct dev_pm_ops ehci_platform_pm_ops = {
+ .suspend = ehci_platform_suspend,
+ .resume = ehci_platform_resume,
+};
static struct platform_driver ehci_platform_driver = {
.id_table = ehci_platform_table,
.remove = ehci_platform_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
+ .owner = THIS_MODULE,
.name = "ehci-platform",
.pm = &ehci_platform_pm_ops,
- .of_match_table = vt8500_ehci_ids,
+ .of_match_table = of_match_ptr(vt8500_ehci_ids),
}
};
return 0;
}
-/* ohci_setup routine for generic controller initialization */
-
-int ohci_setup(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
-
- ohci_hcd_init(ohci);
-
- return ohci_init(ohci);
-}
-EXPORT_SYMBOL_GPL(ohci_setup);
-
-/* ohci_start routine for generic controller start of all OHCI bus glue */
-static int ohci_start(struct usb_hcd *hcd)
-{
- struct ohci_hcd *ohci = hcd_to_ohci(hcd);
- int ret;
-
- ret = ohci_run(ohci);
- if (ret < 0) {
- ohci_err(ohci, "can't start\n");
- ohci_stop(hcd);
- }
- return ret;
-}
-
/*-------------------------------------------------------------------------*/
/* an interrupt happens */
#ifdef CONFIG_PM
-int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
+static int __maybe_unused ohci_suspend(struct usb_hcd *hcd, bool do_wakeup)
{
struct ohci_hcd *ohci = hcd_to_ohci (hcd);
unsigned long flags;
}
-int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
+static int __maybe_unused ohci_resume(struct usb_hcd *hcd, bool hibernated)
{
struct ohci_hcd *ohci = hcd_to_ohci(hcd);
int port;
}
#endif
-/*-------------------------------------------------------------------------*/
-
-/*
- * Generic structure: This gets copied for platform drivers so that
- * individual entries can be overridden as needed.
- */
-
-static const struct hc_driver ohci_hc_driver = {
- .description = hcd_name,
- .product_desc = "OHCI Host Controller",
- .hcd_priv_size = sizeof(struct ohci_hcd),
-
- /*
- * generic hardware linkage
- */
- .irq = ohci_irq,
- .flags = HCD_MEMORY | HCD_USB11,
-
- /*
- * basic lifecycle operations
- */
- .reset = ohci_setup,
- .start = ohci_start,
- .stop = ohci_stop,
- .shutdown = ohci_shutdown,
-
- /*
- * managing i/o requests and associated device resources
- */
- .urb_enqueue = ohci_urb_enqueue,
- .urb_dequeue = ohci_urb_dequeue,
- .endpoint_disable = ohci_endpoint_disable,
-
- /*
- * scheduling support
- */
- .get_frame_number = ohci_get_frame,
-
- /*
- * root hub support
- */
- .hub_status_data = ohci_hub_status_data,
- .hub_control = ohci_hub_control,
-#ifdef CONFIG_PM
- .bus_suspend = ohci_bus_suspend,
- .bus_resume = ohci_bus_resume,
-#endif
- .start_port_reset = ohci_start_port_reset,
-};
-
-void ohci_init_driver(struct hc_driver *drv,
- const struct ohci_driver_overrides *over)
-{
- /* Copy the generic table to drv and then apply the overrides */
- *drv = ohci_hc_driver;
-
- if (over) {
- drv->product_desc = over->product_desc;
- drv->hcd_priv_size += over->extra_priv_size;
- if (over->reset)
- drv->reset = over->reset;
- }
-}
-EXPORT_SYMBOL_GPL(ohci_init_driver);
/*-------------------------------------------------------------------------*/
#define PLATFORM_DRIVER ohci_hcd_tilegx_driver
#endif
-#ifdef CONFIG_USB_OHCI_HCD_RK
-#include "ohci-rockchip.c"
-#define PLATFORM_DRIVER ohci_hcd_rk_driver
+#ifdef CONFIG_USB_OHCI_HCD_PLATFORM
+#include "ohci-platform.c"
+#define PLATFORM_DRIVER ohci_platform_driver
#endif
static int __init ohci_hcd_mod_init(void)
*
* Copyright 2007 Michael Buesch <m@bues.ch>
* Copyright 2011-2012 Hauke Mehrtens <hauke@hauke-m.de>
- * Copyright 2014 Hans de Goede <hdegoede@redhat.com>
*
* Derived from the OCHI-SSB driver
* Derived from the OHCI-PCI driver
*
* Licensed under the GNU/GPL. See COPYING for details.
*/
-
-#include <linux/clk.h>
-#include <linux/dma-mapping.h>
-#include <linux/hrtimer.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
#include <linux/err.h>
-#include <linux/phy/phy.h>
#include <linux/platform_device.h>
-#include <linux/reset.h>
#include <linux/usb/ohci_pdriver.h>
-#include <linux/usb.h>
-#include <linux/usb/hcd.h>
-
-#include "ohci.h"
-#define DRIVER_DESC "OHCI generic platform driver"
-#define OHCI_MAX_CLKS 3
-#define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv)
-
-struct ohci_platform_priv {
- struct clk *clks[OHCI_MAX_CLKS];
- struct reset_control *rst;
- struct phy *phy;
-};
-
-static const char hcd_name[] = "ohci-platform";
-
-static int ohci_platform_power_on(struct platform_device *dev)
+static int ohci_platform_reset(struct usb_hcd *hcd)
{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
- struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
- int clk, ret;
+ struct platform_device *pdev = to_platform_device(hcd->self.controller);
+ struct usb_ohci_pdata *pdata = pdev->dev.platform_data;
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int err;
- for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++) {
- ret = clk_prepare_enable(priv->clks[clk]);
- if (ret)
- goto err_disable_clks;
- }
-
- if (priv->phy) {
- ret = phy_init(priv->phy);
- if (ret)
- goto err_disable_clks;
+ if (pdata->big_endian_desc)
+ ohci->flags |= OHCI_QUIRK_BE_DESC;
+ if (pdata->big_endian_mmio)
+ ohci->flags |= OHCI_QUIRK_BE_MMIO;
+ if (pdata->no_big_frame_no)
+ ohci->flags |= OHCI_QUIRK_FRAME_NO;
- ret = phy_power_on(priv->phy);
- if (ret)
- goto err_exit_phy;
- }
+ ohci_hcd_init(ohci);
- return 0;
+ if (pdata->num_ports)
+ ohci->num_ports = pdata->num_ports;
-err_exit_phy:
- phy_exit(priv->phy);
-err_disable_clks:
- while (--clk >= 0)
- clk_disable_unprepare(priv->clks[clk]);
+ err = ohci_init(ohci);
- return ret;
+ return err;
}
-static void ohci_platform_power_off(struct platform_device *dev)
+static int ohci_platform_start(struct usb_hcd *hcd)
{
- struct usb_hcd *hcd = platform_get_drvdata(dev);
- struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
- int clk;
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int err;
- if (priv->phy) {
- phy_power_off(priv->phy);
- phy_exit(priv->phy);
+ err = ohci_run(ohci);
+ if (err < 0) {
+ ohci_err(ohci, "can't start\n");
+ ohci_stop(hcd);
}
- for (clk = OHCI_MAX_CLKS - 1; clk >= 0; clk--)
- if (priv->clks[clk])
- clk_disable_unprepare(priv->clks[clk]);
+ return err;
}
-static struct hc_driver __read_mostly ohci_platform_hc_driver;
+static const struct hc_driver ohci_platform_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "Generic Platform OHCI Controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
-static const struct ohci_driver_overrides platform_overrides __initconst = {
- .product_desc = "Generic Platform OHCI controller",
- .extra_priv_size = sizeof(struct ohci_platform_priv),
-};
+ .irq = ohci_irq,
+ .flags = HCD_MEMORY | HCD_USB11,
+
+ .reset = ohci_platform_reset,
+ .start = ohci_platform_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
-static struct usb_ohci_pdata ohci_platform_defaults = {
- .power_on = ohci_platform_power_on,
- .power_suspend = ohci_platform_power_off,
- .power_off = ohci_platform_power_off,
+ .get_frame_number = ohci_get_frame,
+
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+#ifdef CONFIG_PM
+ .bus_suspend = ohci_bus_suspend,
+ .bus_resume = ohci_bus_resume,
+#endif
+
+ .start_port_reset = ohci_start_port_reset,
};
static int ohci_platform_probe(struct platform_device *dev)
{
struct usb_hcd *hcd;
struct resource *res_mem;
- struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
- struct ohci_platform_priv *priv;
- struct ohci_hcd *ohci;
- int err, irq, clk = 0;
+ struct usb_ohci_pdata *pdata = dev->dev.platform_data;
+ int irq;
+ int err = -ENOMEM;
- if (usb_disabled())
+ if (!pdata) {
+ WARN_ON(1);
return -ENODEV;
+ }
- /*
- * Use reasonable defaults so platforms don't have to provide these
- * with DT probing on ARM.
- */
- if (!pdata)
- pdata = &ohci_platform_defaults;
-
- err = dma_coerce_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
- if (err)
- return err;
+ if (usb_disabled())
+ return -ENODEV;
irq = platform_get_irq(dev, 0);
if (irq < 0) {
return irq;
}
- hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
- dev_name(&dev->dev));
- if (!hcd)
- return -ENOMEM;
-
- platform_set_drvdata(dev, hcd);
- dev->dev.platform_data = pdata;
- priv = hcd_to_ohci_priv(hcd);
- ohci = hcd_to_ohci(hcd);
-
- if (pdata == &ohci_platform_defaults && dev->dev.of_node) {
- if (of_property_read_bool(dev->dev.of_node, "big-endian-regs"))
- ohci->flags |= OHCI_QUIRK_BE_MMIO;
-
- if (of_property_read_bool(dev->dev.of_node, "big-endian-desc"))
- ohci->flags |= OHCI_QUIRK_BE_DESC;
-
- if (of_property_read_bool(dev->dev.of_node, "big-endian"))
- ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC;
-
- if (of_property_read_bool(dev->dev.of_node, "no-big-frame-no"))
- ohci->flags |= OHCI_QUIRK_FRAME_NO;
-
- of_property_read_u32(dev->dev.of_node, "num-ports",
- &ohci->num_ports);
-
- priv->phy = devm_phy_get(&dev->dev, "usb");
- if (IS_ERR(priv->phy)) {
- err = PTR_ERR(priv->phy);
- if (err == -EPROBE_DEFER)
- goto err_put_hcd;
- priv->phy = NULL;
- }
-
- for (clk = 0; clk < OHCI_MAX_CLKS; clk++) {
- priv->clks[clk] = of_clk_get(dev->dev.of_node, clk);
- if (IS_ERR(priv->clks[clk])) {
- err = PTR_ERR(priv->clks[clk]);
- if (err == -EPROBE_DEFER)
- goto err_put_clks;
- priv->clks[clk] = NULL;
- break;
- }
- }
-
- }
-
- priv->rst = devm_reset_control_get(&dev->dev, NULL);
- if (IS_ERR(priv->rst)) {
- err = PTR_ERR(priv->rst);
- if (err == -EPROBE_DEFER)
- goto err_put_clks;
- priv->rst = NULL;
- } else {
- err = reset_control_deassert(priv->rst);
- if (err)
- goto err_put_clks;
- }
-
- if (pdata->big_endian_desc)
- ohci->flags |= OHCI_QUIRK_BE_DESC;
- if (pdata->big_endian_mmio)
- ohci->flags |= OHCI_QUIRK_BE_MMIO;
- if (pdata->no_big_frame_no)
- ohci->flags |= OHCI_QUIRK_FRAME_NO;
- if (pdata->num_ports)
- ohci->num_ports = pdata->num_ports;
-
-#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO
- if (ohci->flags & OHCI_QUIRK_BE_MMIO) {
- dev_err(&dev->dev,
- "Error: CONFIG_USB_OHCI_BIG_ENDIAN_MMIO not set\n");
- err = -EINVAL;
- goto err_reset;
- }
-#endif
-#ifndef CONFIG_USB_OHCI_BIG_ENDIAN_DESC
- if (ohci->flags & OHCI_QUIRK_BE_DESC) {
- dev_err(&dev->dev,
- "Error: CONFIG_USB_OHCI_BIG_ENDIAN_DESC not set\n");
- err = -EINVAL;
- goto err_reset;
+ res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ if (!res_mem) {
+ dev_err(&dev->dev, "no memory resource provided");
+ return -ENXIO;
}
-#endif
if (pdata->power_on) {
err = pdata->power_on(dev);
if (err < 0)
- goto err_reset;
+ return err;
}
- res_mem = platform_get_resource(dev, IORESOURCE_MEM, 0);
- hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
- if (IS_ERR(hcd->regs)) {
- err = PTR_ERR(hcd->regs);
+ hcd = usb_create_hcd(&ohci_platform_hc_driver, &dev->dev,
+ dev_name(&dev->dev));
+ if (!hcd) {
+ err = -ENOMEM;
goto err_power;
}
+
hcd->rsrc_start = res_mem->start;
hcd->rsrc_len = resource_size(res_mem);
+ hcd->regs = devm_ioremap_resource(&dev->dev, res_mem);
+ if (IS_ERR(hcd->regs)) {
+ err = PTR_ERR(hcd->regs);
+ goto err_put_hcd;
+ }
err = usb_add_hcd(hcd, irq, IRQF_SHARED);
if (err)
- goto err_power;
-
- device_wakeup_enable(hcd->self.controller);
+ goto err_put_hcd;
platform_set_drvdata(dev, hcd);
return err;
+err_put_hcd:
+ usb_put_hcd(hcd);
err_power:
if (pdata->power_off)
pdata->power_off(dev);
-err_reset:
- if (priv->rst)
- reset_control_assert(priv->rst);
-err_put_clks:
- while (--clk >= 0)
- clk_put(priv->clks[clk]);
-err_put_hcd:
- if (pdata == &ohci_platform_defaults)
- dev->dev.platform_data = NULL;
-
- usb_put_hcd(hcd);
return err;
}
static int ohci_platform_remove(struct platform_device *dev)
{
struct usb_hcd *hcd = platform_get_drvdata(dev);
- struct usb_ohci_pdata *pdata = dev_get_platdata(&dev->dev);
- struct ohci_platform_priv *priv = hcd_to_ohci_priv(hcd);
- int clk;
+ struct usb_ohci_pdata *pdata = dev->dev.platform_data;
usb_remove_hcd(hcd);
+ usb_put_hcd(hcd);
+ platform_set_drvdata(dev, NULL);
if (pdata->power_off)
pdata->power_off(dev);
- if (priv->rst)
- reset_control_assert(priv->rst);
-
- for (clk = 0; clk < OHCI_MAX_CLKS && priv->clks[clk]; clk++)
- clk_put(priv->clks[clk]);
-
- usb_put_hcd(hcd);
-
- if (pdata == &ohci_platform_defaults)
- dev->dev.platform_data = NULL;
-
return 0;
}
-#ifdef CONFIG_PM_SLEEP
+#ifdef CONFIG_PM
+
static int ohci_platform_suspend(struct device *dev)
{
- struct usb_hcd *hcd = dev_get_drvdata(dev);
struct usb_ohci_pdata *pdata = dev->platform_data;
struct platform_device *pdev =
container_of(dev, struct platform_device, dev);
- bool do_wakeup = device_may_wakeup(dev);
- int ret;
-
- ret = ohci_suspend(hcd, do_wakeup);
- if (ret)
- return ret;
if (pdata->power_suspend)
pdata->power_suspend(pdev);
- return ret;
+ return 0;
}
static int ohci_platform_resume(struct device *dev)
{
struct usb_hcd *hcd = dev_get_drvdata(dev);
- struct usb_ohci_pdata *pdata = dev_get_platdata(dev);
+ struct usb_ohci_pdata *pdata = dev->platform_data;
struct platform_device *pdev =
container_of(dev, struct platform_device, dev);
ohci_resume(hcd, false);
return 0;
}
-#endif /* CONFIG_PM_SLEEP */
-static const struct of_device_id ohci_platform_ids[] = {
- { .compatible = "generic-ohci", },
- { }
-};
-MODULE_DEVICE_TABLE(of, ohci_platform_ids);
+#else /* !CONFIG_PM */
+#define ohci_platform_suspend NULL
+#define ohci_platform_resume NULL
+#endif /* CONFIG_PM */
static const struct platform_device_id ohci_platform_table[] = {
{ "ohci-platform", 0 },
};
MODULE_DEVICE_TABLE(platform, ohci_platform_table);
-static SIMPLE_DEV_PM_OPS(ohci_platform_pm_ops, ohci_platform_suspend,
- ohci_platform_resume);
+static const struct dev_pm_ops ohci_platform_pm_ops = {
+ .suspend = ohci_platform_suspend,
+ .resume = ohci_platform_resume,
+};
static struct platform_driver ohci_platform_driver = {
.id_table = ohci_platform_table,
.remove = ohci_platform_remove,
.shutdown = usb_hcd_platform_shutdown,
.driver = {
+ .owner = THIS_MODULE,
.name = "ohci-platform",
.pm = &ohci_platform_pm_ops,
- .of_match_table = ohci_platform_ids,
}
};
-
-static int __init ohci_platform_init(void)
-{
- if (usb_disabled())
- return -ENODEV;
-
- pr_info("%s: " DRIVER_DESC "\n", hcd_name);
-
- ohci_init_driver(&ohci_platform_hc_driver, &platform_overrides);
- return platform_driver_register(&ohci_platform_driver);
-}
-module_init(ohci_platform_init);
-
-static void __exit ohci_platform_cleanup(void)
-{
- platform_driver_unregister(&ohci_platform_driver);
-}
-module_exit(ohci_platform_cleanup);
-
-MODULE_DESCRIPTION(DRIVER_DESC);
-MODULE_AUTHOR("Hauke Mehrtens");
-MODULE_AUTHOR("Alan Stern");
-MODULE_LICENSE("GPL");
struct dentry *debug_periodic;
struct dentry *debug_registers;
#endif
-
- /* platform-specific data -- must come last */
- unsigned long priv[0] __aligned(sizeof(s64));
-
};
#ifdef CONFIG_PCI
{ return ohci_readl (hc, &hc->regs->roothub.status); }
static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i)
{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }
-
-/* Declarations of things exported for use by ohci platform drivers */
-
-struct ohci_driver_overrides {
- const char *product_desc;
- size_t extra_priv_size;
- int (*reset)(struct usb_hcd *hcd);
-};
-
-extern void ohci_init_driver(struct hc_driver *drv,
- const struct ohci_driver_overrides *over);
-extern int ohci_setup(struct usb_hcd *hcd);
-#ifdef CONFIG_PM
-extern int ohci_suspend(struct usb_hcd *hcd, bool do_wakeup);
-extern int ohci_resume(struct usb_hcd *hcd, bool hibernated);
-#endif
#define OPTION_PRODUCT_GTM380_MODEM 0x7201
#define HUAWEI_VENDOR_ID 0x12D1
-#define HUAWEI_PRODUCT_E140C 0x140C
+#define HUAWEI_PRODUCT_E173 0x140C
#define HUAWEI_PRODUCT_E1750 0x1406
#define HUAWEI_PRODUCT_K4505 0x1464
#define HUAWEI_PRODUCT_K3765 0x1465
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c05, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c1f, USB_CLASS_COMM, 0x02, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0x1c23, USB_CLASS_COMM, 0x02, 0xff) },
- //{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
- // .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
- { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) },
+ { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173, 0xff, 0xff, 0xff),
+ .driver_info = (kernel_ulong_t) &net_intf1_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S6, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t) &net_intf1_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1750, 0xff, 0xff, 0xff),
#ifdef CONFIG_PM
.suspend = usb_wwan_suspend,
.resume = usb_wwan_resume,
- .reset_resume = usb_wwan_resume,
#endif
};
return 0;
}
- int usb_stor_huawei_init(struct us_data *us)
- {
- int idProduct;
- idProduct = us->pusb_dev->descriptor.idProduct;
- if(idProduct==0x1F01){
- int result ;
- int act_len;
- unsigned char cmd[32] = {0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
- 0x06, 0x30, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, cmd, 31, &act_len);
- printk("usb_stor_bulk_transfer_buf performing result is %d, transfer the actual length=%d\n", result,act_len);
- return result;
- } else {
- int result = 0;
- int act_len = 0;
- struct bulk_cb_wrap *bcbw = (struct bulk_cb_wrap *) us->iobuf;
- char rewind_cmd[] = {0x11, 0x06, 0x20, 0x00, 0x00, 0x01, 0x01, 0x00,
- 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
- bcbw->Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcbw->Tag = 0;
- bcbw->DataTransferLength = 0;
- bcbw->Flags = bcbw->Lun = 0;
- bcbw->Length = sizeof(rewind_cmd);
- memset(bcbw->CDB, 0, sizeof(bcbw->CDB));
- memcpy(bcbw->CDB, rewind_cmd, sizeof(rewind_cmd));
- result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcbw,
- US_BULK_CB_WRAP_LEN, &act_len);
- printk("transfer actual length=%d, result=%d\n", act_len, result);
- return result;
- }
-}
+
/* This places the HUAWEI E220 devices in multi-port mode */
int usb_stor_huawei_e220_init(struct us_data *us)
{
/* This places the HUAWEI E220 devices in multi-port mode */
int usb_stor_huawei_e220_init(struct us_data *us);
-
-int usb_stor_huawei_init(struct us_data *us);
USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_e220_init,
0),
-UNUSUAL_VENDOR_INTF(0x12d1, 0x08, 0x06, 0x50,
- "HUAWEI MOBILE",
- "Mass Storage",
- USB_SC_DEVICE, USB_PR_DEVICE, usb_stor_huawei_init,
- 0),
-
/* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001,
"Minolta",
source "drivers/gpu/host1x/Kconfig"
-source "drivers/gpu/arm/midgard/Kconfig"
-
-source "drivers/gpu/arm/mali400/mali/Kconfig"
-
-source "drivers/gpu/arm/mali400/ump/Kconfig"
-
-source "drivers/gpu/rogue/Kconfig"
-
config VGASTATE
tristate
default n
source "drivers/video/mmp/Kconfig"
source "drivers/video/backlight/Kconfig"
source "drivers/video/adf/Kconfig"
-source "drivers/video/rockchip/Kconfig"
if VT
source "drivers/video/console/Kconfig"
obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
-obj-$(CONFIG_FB_ROCKCHIP) += rockchip/
-obj-$(CONFIG_DRM_ROCKCHIP) += rockchip/
# Platform or fallback drivers go here
obj-$(CONFIG_FB_UVESA) += uvesafb.o
obj-$(CONFIG_FB_MXS) += mxsfb.o
obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
obj-$(CONFIG_FB_SIMPLE) += simplefb.o
+
# the test framebuffer is last
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
* published by the Free Software Foundation.
*/
-#include <linux/gpio.h>
-#include <linux/of_gpio.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
unsigned int period;
unsigned int lth_brightness;
unsigned int *levels;
- bool enabled;
- int enable_gpio;
- unsigned long enable_gpio_flags;
- unsigned int scale;
int (*notify)(struct device *,
int brightness);
void (*notify_after)(struct device *,
void (*exit)(struct device *);
};
-static void pwm_backlight_power_on(struct pwm_bl_data *pb, int brightness)
-{
- if (pb->enabled)
- return;
-
- if (gpio_is_valid(pb->enable_gpio)) {
- if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
- gpio_set_value(pb->enable_gpio, 0);
- else
- gpio_set_value(pb->enable_gpio, 1);
- }
-
- pwm_enable(pb->pwm);
- pb->enabled = true;
-}
-
-static void pwm_backlight_power_off(struct pwm_bl_data *pb)
-{
- if (!pb->enabled)
- return;
-
- pwm_config(pb->pwm, 0, pb->period);
- pwm_disable(pb->pwm);
-
- if (gpio_is_valid(pb->enable_gpio)) {
- if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
- gpio_set_value(pb->enable_gpio, 1);
- else
- gpio_set_value(pb->enable_gpio, 0);
- }
-
- pb->enabled = false;
-}
-
-static int compute_duty_cycle(struct pwm_bl_data *pb, int brightness)
-{
- unsigned int lth = pb->lth_brightness;
- int duty_cycle;
-
- if (pb->levels)
- duty_cycle = pb->levels[brightness];
- else
- duty_cycle = brightness;
-
- return (duty_cycle * (pb->period - lth) / pb->scale) + lth;
-}
-
static int pwm_backlight_update_status(struct backlight_device *bl)
{
struct pwm_bl_data *pb = bl_get_data(bl);
int brightness = bl->props.brightness;
- int duty_cycle;
+ int max = bl->props.max_brightness;
if (bl->props.power != FB_BLANK_UNBLANK ||
bl->props.fb_blank != FB_BLANK_UNBLANK ||
if (pb->notify)
brightness = pb->notify(pb->dev, brightness);
- if (brightness > 0) {
- duty_cycle = compute_duty_cycle(pb, brightness);
+ if (brightness == 0) {
+ pwm_config(pb->pwm, 0, pb->period);
+ pwm_disable(pb->pwm);
+ } else {
+ int duty_cycle;
+
+ if (pb->levels) {
+ duty_cycle = pb->levels[brightness];
+ max = pb->levels[max];
+ } else {
+ duty_cycle = brightness;
+ }
+
+ duty_cycle = pb->lth_brightness +
+ (duty_cycle * (pb->period - pb->lth_brightness) / max);
pwm_config(pb->pwm, duty_cycle, pb->period);
- pwm_backlight_power_on(pb, brightness);
- } else
- pwm_backlight_power_off(pb);
+ pwm_enable(pb->pwm);
+ }
if (pb->notify_after)
pb->notify_after(pb->dev, brightness);
struct platform_pwm_backlight_data *data)
{
struct device_node *node = dev->of_node;
- enum of_gpio_flags flags;
struct property *prop;
int length;
u32 value;
data->max_brightness--;
}
- data->enable_gpio = of_get_named_gpio_flags(node, "enable-gpios", 0,
- &flags);
- if (data->enable_gpio == -EPROBE_DEFER)
- return -EPROBE_DEFER;
-
- if (gpio_is_valid(data->enable_gpio) && (flags & OF_GPIO_ACTIVE_LOW))
- data->enable_gpio_flags |= PWM_BACKLIGHT_GPIO_ACTIVE_LOW;
+ /*
+ * TODO: Most users of this driver use a number of GPIOs to control
+ * backlight power. Support for specifying these needs to be
+ * added.
+ */
return 0;
}
struct backlight_properties props;
struct backlight_device *bl;
struct pwm_bl_data *pb;
+ unsigned int max;
int ret;
if (!data) {
}
if (data->levels) {
- unsigned int i;
-
- for (i = 0; i <= data->max_brightness; i++)
- if (data->levels[i] > pb->scale)
- pb->scale = data->levels[i];
-
+ max = data->levels[data->max_brightness];
pb->levels = data->levels;
} else
- pb->scale = data->max_brightness;
+ max = data->max_brightness;
- pb->enable_gpio = data->enable_gpio;
- pb->enable_gpio_flags = data->enable_gpio_flags;
pb->notify = data->notify;
pb->notify_after = data->notify_after;
pb->check_fb = data->check_fb;
pb->exit = data->exit;
pb->dev = &pdev->dev;
- pb->enabled = false;
-
- if (gpio_is_valid(pb->enable_gpio)) {
- unsigned long flags;
-
- if (pb->enable_gpio_flags & PWM_BACKLIGHT_GPIO_ACTIVE_LOW)
- flags = GPIOF_OUT_INIT_HIGH;
- else
- flags = GPIOF_OUT_INIT_LOW;
-
- ret = gpio_request_one(pb->enable_gpio, flags, "enable");
- if (ret < 0) {
- dev_err(&pdev->dev, "failed to request GPIO#%d: %d\n",
- pb->enable_gpio, ret);
- goto err_alloc;
- }
- }
pb->pwm = devm_pwm_get(&pdev->dev, NULL);
if (IS_ERR(pb->pwm)) {
if (IS_ERR(pb->pwm)) {
dev_err(&pdev->dev, "unable to request legacy PWM\n");
ret = PTR_ERR(pb->pwm);
- goto err_gpio;
+ goto err_alloc;
}
}
pwm_set_period(pb->pwm, data->pwm_period_ns);
pb->period = pwm_get_period(pb->pwm);
- pb->lth_brightness = data->lth_brightness * (pb->period / pb->scale);
+ pb->lth_brightness = data->lth_brightness * (pb->period / max);
memset(&props, 0, sizeof(struct backlight_properties));
props.type = BACKLIGHT_RAW;
props.max_brightness = data->max_brightness;
-#ifdef CONFIG_ARCH_ROCKCHIP
- dev_set_name(&pdev->dev, "rk28_bl");
-#endif
bl = backlight_device_register(dev_name(&pdev->dev), &pdev->dev, pb,
&pwm_backlight_ops, &props);
if (IS_ERR(bl)) {
dev_err(&pdev->dev, "failed to register backlight\n");
ret = PTR_ERR(bl);
- goto err_gpio;
+ goto err_alloc;
}
if (data->dft_brightness > data->max_brightness) {
platform_set_drvdata(pdev, bl);
return 0;
-err_gpio:
- if (gpio_is_valid(pb->enable_gpio))
- gpio_free(pb->enable_gpio);
err_alloc:
if (data->exit)
data->exit(&pdev->dev);
struct pwm_bl_data *pb = bl_get_data(bl);
backlight_device_unregister(bl);
- pwm_backlight_power_off(pb);
-
+ pwm_config(pb->pwm, 0, pb->period);
+ pwm_disable(pb->pwm);
if (pb->exit)
pb->exit(&pdev->dev);
-
return 0;
}
-static void pwm_backlight_shutdown(struct platform_device *pdev)
-{
- struct backlight_device *bl = platform_get_drvdata(pdev);
- struct pwm_bl_data *pb = bl_get_data(bl);
-
- backlight_device_unregister(bl);
- pwm_backlight_power_off(pb);
-
- if (pb->exit)
- pb->exit(&pdev->dev);
-}
#ifdef CONFIG_PM_SLEEP
static int pwm_backlight_suspend(struct device *dev)
if (pb->notify)
pb->notify(pb->dev, 0);
-
- pwm_backlight_power_off(pb);
-
+ pwm_config(pb->pwm, 0, pb->period);
+ pwm_disable(pb->pwm);
if (pb->notify_after)
pb->notify_after(pb->dev, 0);
-
return 0;
}
struct backlight_device *bl = dev_get_drvdata(dev);
backlight_update_status(bl);
-
return 0;
}
#endif
-static const struct dev_pm_ops pwm_backlight_pm_ops = {
-#ifdef CONFIG_PM_SLEEP
- .suspend = pwm_backlight_suspend,
- .resume = pwm_backlight_resume,
- .poweroff = pwm_backlight_suspend,
- .restore = pwm_backlight_resume,
-#endif
-};
+static SIMPLE_DEV_PM_OPS(pwm_backlight_pm_ops, pwm_backlight_suspend,
+ pwm_backlight_resume);
static struct platform_driver pwm_backlight_driver = {
.driver = {
},
.probe = pwm_backlight_probe,
.remove = pwm_backlight_remove,
- .shutdown = pwm_backlight_shutdown,
};
module_platform_driver(pwm_backlight_driver);
MODULE_DESCRIPTION("PWM based Backlight Driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:pwm-backlight");
+
/* 33 1920x1440-75 VESA */
{ NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 34 1920x1200-60 RB VESA */
- { NULL, 60, 1920, 1200, 6493, 80, 48, 26, 3, 32, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 35 1920x1200-60 VESA */
- { NULL, 60, 1920, 1200, 5174, 336, 136, 36, 3, 200, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 36 1920x1200-75 VESA */
- { NULL, 75, 1920, 1200, 4077, 344, 136, 46, 3, 208, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 37 1920x1200-85 VESA */
- { NULL, 85, 1920, 1200, 3555, 352, 144, 53, 3, 208, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 38 2560x1600-60 RB VESA */
- { NULL, 60, 2560, 1600, 3724, 80, 48, 37, 3, 32, 6,
- FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 39 2560x1600-60 VESA */
- { NULL, 60, 2560, 1600, 2869, 472, 192, 49, 3, 280, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 40 2560x1600-75 VESA */
- { NULL, 75, 2560, 1600, 2256, 488, 208, 63, 3, 280, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 41 2560x1600-85 VESA */
- { NULL, 85, 2560, 1600, 1979, 488, 208, 73, 3, 280, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 42 2560x1600-120 RB VESA */
- { NULL, 120, 2560, 1600, 1809, 80, 48, 85, 3, 32, 6,
- FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 43 1360x768-60 VESA */
- { NULL, 60, 1360, 768, 11695, 256, 64, 18, 3, 112, 6,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 44 1366x768-60 VESA */
- { NULL, 60, 1366, 768, 11695, 213, 70, 24, 3, 143, 3,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
- FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 45 1440x900-60 VESA */
- { NULL, 60, 1440, 900, 9389, 232, 80, 25, 3, 152, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 46 1600x900-60 VESA */
- { NULL, 60, 1600, 900, 9259, 96, 24, 96, 1, 80, 3,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
- /* 47 1680x1050-60 VESA */
- { NULL, 60, 1680, 1050, 6837, 280, 104, 30, 3, 176, 6,
- FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
};
EXPORT_SYMBOL(vesa_modes);
#endif /* CONFIG_FB_MODE_HELPERS */
struct display_timing *dt;
u32 val = 0;
int ret = 0;
-#if defined(CONFIG_FB_ROCKCHIP) || defined(CONFIG_DRM_ROCKCHIP)
- struct property *prop;
- int length;
-#endif
+
dt = kzalloc(sizeof(*dt), GFP_KERNEL);
if (!dt) {
pr_err("%s: could not allocate display_timing struct\n",
if (of_property_read_bool(np, "doublescan"))
dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
-#if defined(CONFIG_FB_ROCKCHIP) || defined(CONFIG_DRM_ROCKCHIP)
- if (!of_property_read_u32(np, "swap-rg", &val))
- dt->flags |= val ? DISPLAY_FLAGS_SWAP_RG : 0;
- if (!of_property_read_u32(np, "swap-gb", &val))
- dt->flags |= val ? DISPLAY_FLAGS_SWAP_GB : 0;
- if (!of_property_read_u32(np, "swap-rb", &val))
- dt->flags |= val ? DISPLAY_FLAGS_SWAP_RB : 0;
- if (!of_property_read_u32(np, "screen-type", &val))
- dt->screen_type = val;
- if (!of_property_read_u32(np, "lvds-format", &val))
- dt->lvds_format = val;
- if (!of_property_read_u32(np, "out-face", &val))
- dt->face = val;
- if (!of_property_read_u32(np, "color-mode", &val))
- dt->color_mode = val;
- prop = of_find_property(np, "dsp-lut", &length);
- if (prop) {
- dt->dsp_lut = kzalloc(length, GFP_KERNEL);
- if (dt->dsp_lut)
- ret = of_property_read_u32_array(np,
- "dsp-lut",dt->dsp_lut, length >> 2);
- }
- prop = of_find_property(np, "cabc-lut", &length);
- if (prop) {
- dt->cabc_lut = kzalloc(length, GFP_KERNEL);
- if (dt->cabc_lut)
- ret = of_property_read_u32_array(np,
- "cabc-lut",
- dt->cabc_lut,
- length >> 2);
- }
-
- prop = of_find_property(np, "cabc-gamma-base", &length);
- if (prop) {
- dt->cabc_gamma_base = kzalloc(length, GFP_KERNEL);
- if (dt->cabc_gamma_base)
- ret = of_property_read_u32_array(np,
- "cabc-gamma-base",
- dt->cabc_gamma_base,
- length >> 2);
- }
-#endif
-
if (ret) {
pr_err("%s: error reading timing properties\n",
of_node_full_name(np));
obj-$(CONFIG_COH901327_WATCHDOG) += coh901327_wdt.o
obj-$(CONFIG_STMP3XXX_RTC_WATCHDOG) += stmp3xxx_rtc_wdt.o
obj-$(CONFIG_NUC900_WATCHDOG) += nuc900_wdt.o
-obj-$(CONFIG_ARCH_ROCKCHIP) += rk29_wdt.o
obj-$(CONFIG_TS72XX_WATCHDOG) += ts72xx_wdt.o
obj-$(CONFIG_IMX2_WDT) += imx2_wdt.o
obj-$(CONFIG_UX500_WATCHDOG) += ux500_wdt.o
struct inode *inode = file->f_mapping->host;
return __blockdev_direct_IO(rw, iocb, inode, I_BDEV(inode), iov, offset,
- nr_segs, blkdev_get_block, NULL, NULL, DIO_SKIP_DIO_COUNT);
+ nr_segs, blkdev_get_block, NULL, NULL, 0);
}
int __sync_blockdev(struct block_device *bdev, int wait)
dio->end_io(dio->iocb, offset, transferred,
dio->private, ret, is_async);
} else {
- if (!(dio->flags & DIO_SKIP_DIO_COUNT))
- inode_dio_end(dio->inode);
-
+ inode_dio_done(dio->inode);
if (is_async)
aio_complete(dio->iocb, ret, 0);
}
{
struct bio *bio = sdio->bio;
unsigned long flags;
- int rw;
bio->bi_private = dio;
if (dio->is_async && dio->rw == READ)
bio_set_pages_dirty(bio);
- rw = dio->rw;
- dio->rw |= (dio->rw == READ) ? KERNEL_READ : KERNEL_WRITE;
-
if (sdio->submit_io)
sdio->submit_io(dio->rw, bio, dio->inode,
sdio->logical_offset_in_bio);
/*
* Will be decremented at I/O completion time.
*/
- if (!(dio->flags & DIO_SKIP_DIO_COUNT))
- inode_dio_begin(inode);
+ atomic_inc(&inode->i_dio_count);
/*
* For file extending writes updating i_size before data
* via ext4_inode_block_unlocked_dio(). Check inode's state
* while holding extra i_dio_count ref.
*/
- inode_dio_begin(inode);
+ atomic_inc(&inode->i_dio_count);
smp_mb();
if (unlikely(ext4_test_inode_state(inode,
EXT4_STATE_DIOREAD_LOCK))) {
- inode_dio_end(inode);
+ inode_dio_done(inode);
goto locked;
}
ret = __blockdev_direct_IO(rw, iocb, inode,
inode->i_sb->s_bdev, iov,
offset, nr_segs,
ext4_get_block, NULL, NULL, 0);
- inode_dio_end(inode);
+ inode_dio_done(inode);
} else {
locked:
ret = blockdev_direct_IO(rw, iocb, inode, iov,
if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) {
ext4_free_io_end(io_end);
out:
- inode_dio_end(inode);
+ inode_dio_done(inode);
if (is_async)
aio_complete(iocb, ret, 0);
return;
overwrite = *((int *)iocb->private);
if (overwrite) {
- inode_dio_begin(inode);
+ atomic_inc(&inode->i_dio_count);
down_read(&EXT4_I(inode)->i_data_sem);
mutex_unlock(&inode->i_mutex);
}
retake_lock:
/* take i_mutex locking again if we do a ovewrite dio */
if (overwrite) {
- inode_dio_end(inode);
+ inode_dio_done(inode);
up_read(&EXT4_I(inode)->i_data_sem);
mutex_lock(&inode->i_mutex);
}
if (atomic_dec_and_test(&EXT4_I(inode)->i_unwritten))
wake_up_all(ext4_ioend_wq(inode));
if (io->flag & EXT4_IO_END_DIRECT)
- inode_dio_end(inode);
+ inode_dio_done(inode);
if (io->iocb)
aio_complete(io->iocb, io->result, 0);
return ret;
Linux website <http://acl.bestbits.at/>.
If you don't know what Access Control Lists are, say N
-
-config F2FS_FS_SECURITY
- bool "F2FS Security Labels"
- depends on F2FS_FS_XATTR
- help
- Security labels provide an access control facility to support Linux
- Security Models (LSMs) accepted by AppArmor, SELinux, Smack and TOMOYO
- Linux. This option enables an extended attribute handler for file
- security labels in the f2fs filesystem, so that it requires enabling
- the extended attribute support in advance.
-
- If you are not using a security module, say N.
}
}
- error = f2fs_setxattr(inode, name_index, "", value, size, NULL);
+ error = f2fs_setxattr(inode, name_index, "", value, size);
kfree(value);
if (!error)
*
* Also, caller should grab and release a mutex by calling mutex_lock_op() and
* mutex_unlock_op().
- * Note that, npage is set only by make_empty_dir.
*/
-struct page *get_new_data_page(struct inode *inode,
- struct page *npage, pgoff_t index, bool new_i_size)
+struct page *get_new_data_page(struct inode *inode, pgoff_t index,
+ bool new_i_size)
{
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
struct address_space *mapping = inode->i_mapping;
struct dnode_of_data dn;
int err;
- set_new_dnode(&dn, inode, npage, npage, 0);
+ set_new_dnode(&dn, inode, NULL, NULL, 0);
err = get_dnode_of_data(&dn, index, ALLOC_NODE);
if (err)
return ERR_PTR(err);
if (dn.data_blkaddr == NULL_ADDR) {
if (reserve_new_block(&dn)) {
- if (!npage)
- f2fs_put_dnode(&dn);
+ f2fs_put_dnode(&dn);
return ERR_PTR(-ENOSPC);
}
}
- if (!npage)
- f2fs_put_dnode(&dn);
+ f2fs_put_dnode(&dn);
repeat:
page = grab_cache_page(mapping, index);
if (!page)
#include "f2fs.h"
#include "node.h"
#include "acl.h"
-#include "xattr.h"
static unsigned long dir_blocks(struct inode *inode)
{
f2fs_put_page(page, 1);
}
-static void init_dent_inode(const struct qstr *name, struct page *ipage)
+void init_dent_inode(const struct qstr *name, struct page *ipage)
{
struct f2fs_node *rn;
+ if (IS_ERR(ipage))
+ return;
+
+ wait_on_page_writeback(ipage);
+
/* copy name info. to this inode page */
rn = (struct f2fs_node *)page_address(ipage);
rn->i.i_namelen = cpu_to_le32(name->len);
set_page_dirty(ipage);
}
-static int make_empty_dir(struct inode *inode,
- struct inode *parent, struct page *page)
+static int make_empty_dir(struct inode *inode, struct inode *parent)
{
struct page *dentry_page;
struct f2fs_dentry_block *dentry_blk;
struct f2fs_dir_entry *de;
void *kaddr;
- dentry_page = get_new_data_page(inode, page, 0, true);
+ dentry_page = get_new_data_page(inode, 0, true);
if (IS_ERR(dentry_page))
return PTR_ERR(dentry_page);
return 0;
}
-static struct page *init_inode_metadata(struct inode *inode,
+static int init_inode_metadata(struct inode *inode,
struct inode *dir, const struct qstr *name)
{
- struct page *page;
- int err;
-
if (is_inode_flag_set(F2FS_I(inode), FI_NEW_INODE)) {
- page = new_inode_page(inode, name);
- if (IS_ERR(page))
- return page;
+ int err;
+ err = new_inode_page(inode, name);
+ if (err)
+ return err;
if (S_ISDIR(inode->i_mode)) {
- err = make_empty_dir(inode, dir, page);
- if (err)
- goto error;
+ err = make_empty_dir(inode, dir);
+ if (err) {
+ remove_inode_page(inode);
+ return err;
+ }
}
err = f2fs_init_acl(inode, dir);
- if (err)
- goto error;
-
- err = f2fs_init_security(inode, dir, name, page);
- if (err)
- goto error;
-
- wait_on_page_writeback(page);
+ if (err) {
+ remove_inode_page(inode);
+ return err;
+ }
} else {
- page = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
- if (IS_ERR(page))
- return page;
-
- wait_on_page_writeback(page);
- set_cold_node(inode, page);
+ struct page *ipage;
+ ipage = get_node_page(F2FS_SB(dir->i_sb), inode->i_ino);
+ if (IS_ERR(ipage))
+ return PTR_ERR(ipage);
+ set_cold_node(inode, ipage);
+ init_dent_inode(name, ipage);
+ f2fs_put_page(ipage, 1);
}
-
- init_dent_inode(name, page);
-
- if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK))
+ if (is_inode_flag_set(F2FS_I(inode), FI_INC_LINK)) {
inc_nlink(inode);
- return page;
-
-error:
- f2fs_put_page(page, 1);
- remove_inode_page(inode);
- return ERR_PTR(err);
+ update_inode_page(inode);
+ }
+ return 0;
}
static void update_parent_metadata(struct inode *dir, struct inode *inode,
struct page *dentry_page = NULL;
struct f2fs_dentry_block *dentry_blk = NULL;
int slots = GET_DENTRY_SLOTS(namelen);
- struct page *page;
int err = 0;
int i;
bidx = dir_block_index(level, (le32_to_cpu(dentry_hash) % nbucket));
for (block = bidx; block <= (bidx + nblock - 1); block++) {
- dentry_page = get_new_data_page(dir, NULL, block, true);
+ dentry_page = get_new_data_page(dir, block, true);
if (IS_ERR(dentry_page))
return PTR_ERR(dentry_page);
++level;
goto start;
add_dentry:
+ err = init_inode_metadata(inode, dir, name);
+ if (err)
+ goto fail;
+
wait_on_page_writeback(dentry_page);
- page = init_inode_metadata(inode, dir, name);
- if (IS_ERR(page)) {
- err = PTR_ERR(page);
- goto fail;
- }
de = &dentry_blk->dentry[bit_pos];
de->hash_code = dentry_hash;
de->name_len = cpu_to_le16(namelen);
test_and_set_bit_le(bit_pos + i, &dentry_blk->dentry_bitmap);
set_page_dirty(dentry_page);
- /* we don't need to mark_inode_dirty now */
- F2FS_I(inode)->i_pino = dir->i_ino;
- update_inode(inode, page);
- f2fs_put_page(page, 1);
-
update_parent_metadata(dir, inode, current_depth);
+
+ /* update parent inode number before releasing dentry page */
+ F2FS_I(inode)->i_pino = dir->i_ino;
fail:
kunmap(dentry_page);
f2fs_put_page(dentry_page, 1);
ino_t f2fs_inode_by_name(struct inode *, struct qstr *);
void f2fs_set_link(struct inode *, struct f2fs_dir_entry *,
struct page *, struct inode *);
+void init_dent_inode(const struct qstr *, struct page *);
int __f2fs_add_link(struct inode *, const struct qstr *, struct inode *);
void f2fs_delete_entry(struct f2fs_dir_entry *, struct page *, struct inode *);
int f2fs_make_empty(struct inode *, struct inode *);
int get_dnode_of_data(struct dnode_of_data *, pgoff_t, int);
int truncate_inode_blocks(struct inode *, pgoff_t);
int remove_inode_page(struct inode *);
-struct page *new_inode_page(struct inode *, const struct qstr *);
-struct page *new_node_page(struct dnode_of_data *, unsigned int, struct page *);
+int new_inode_page(struct inode *, const struct qstr *);
+struct page *new_node_page(struct dnode_of_data *, unsigned int);
void ra_node_page(struct f2fs_sb_info *, nid_t);
struct page *get_node_page(struct f2fs_sb_info *, pgoff_t);
struct page *get_node_page_ra(struct page *, int);
void update_extent_cache(block_t, struct dnode_of_data *);
struct page *find_data_page(struct inode *, pgoff_t, bool);
struct page *get_lock_data_page(struct inode *, pgoff_t);
-struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool);
+struct page *get_new_data_page(struct inode *, pgoff_t, bool);
int f2fs_readpage(struct f2fs_sb_info *, struct page *, block_t, int);
int do_write_data_page(struct page *);
f2fs_balance_fs(sbi);
ilock = mutex_lock_op(sbi);
- page = get_new_data_page(inode, NULL, index, false);
+ page = get_new_data_page(inode, index, false);
mutex_unlock_op(sbi, ilock);
if (!IS_ERR(page)) {
}
dn->nid = nids[i];
- npage[i] = new_node_page(dn, noffset[i], NULL);
+ npage[i] = new_node_page(dn, noffset[i]);
if (IS_ERR(npage[i])) {
alloc_nid_failed(sbi, nids[i]);
err = PTR_ERR(npage[i]);
return 0;
}
-struct page *new_inode_page(struct inode *inode, const struct qstr *name)
+int new_inode_page(struct inode *inode, const struct qstr *name)
{
+ struct page *page;
struct dnode_of_data dn;
/* allocate inode page for new inode */
set_new_dnode(&dn, inode, NULL, NULL, inode->i_ino);
-
- /* caller should f2fs_put_page(page, 1); */
- return new_node_page(&dn, 0, NULL);
+ page = new_node_page(&dn, 0);
+ init_dent_inode(name, page);
+ if (IS_ERR(page))
+ return PTR_ERR(page);
+ f2fs_put_page(page, 1);
+ return 0;
}
-struct page *new_node_page(struct dnode_of_data *dn,
- unsigned int ofs, struct page *ipage)
+struct page *new_node_page(struct dnode_of_data *dn, unsigned int ofs)
{
struct f2fs_sb_info *sbi = F2FS_SB(dn->inode->i_sb);
struct address_space *mapping = sbi->node_inode->i_mapping;
set_cold_node(dn->inode, page);
dn->node_page = page;
- if (ipage)
- update_inode(dn->inode, ipage);
- else
- sync_inode_page(dn);
+ sync_inode_page(dn);
set_page_dirty(page);
if (ofs == 0)
inc_valid_inode_count(sbi);
*/
#include <linux/rwsem.h>
#include <linux/f2fs_fs.h>
-#include <linux/security.h>
#include "f2fs.h"
#include "xattr.h"
prefix = XATTR_TRUSTED_PREFIX;
prefix_len = XATTR_TRUSTED_PREFIX_LEN;
break;
- case F2FS_XATTR_INDEX_SECURITY:
- prefix = XATTR_SECURITY_PREFIX;
- prefix_len = XATTR_SECURITY_PREFIX_LEN;
- break;
default:
return -EINVAL;
}
total_len = prefix_len + name_len + 1;
if (list && total_len <= list_size) {
memcpy(list, prefix, prefix_len);
- memcpy(list + prefix_len, name, name_len);
+ memcpy(list+prefix_len, name, name_len);
list[prefix_len + name_len] = '\0';
}
return total_len;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
break;
- case F2FS_XATTR_INDEX_SECURITY:
- break;
default:
return -EINVAL;
}
if (strcmp(name, "") == 0)
return -EINVAL;
- return f2fs_getxattr(dentry->d_inode, type, name, buffer, size);
+ return f2fs_getxattr(dentry->d_inode, type, name,
+ buffer, size);
}
static int f2fs_xattr_generic_set(struct dentry *dentry, const char *name,
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
break;
- case F2FS_XATTR_INDEX_SECURITY:
- break;
default:
return -EINVAL;
}
if (strcmp(name, "") == 0)
return -EINVAL;
- return f2fs_setxattr(dentry->d_inode, type, name, value, size, NULL);
+ return f2fs_setxattr(dentry->d_inode, type, name, value, size);
}
static size_t f2fs_xattr_advise_list(struct dentry *dentry, char *list,
return 0;
}
-#ifdef CONFIG_F2FS_FS_SECURITY
-static int f2fs_initxattrs(struct inode *inode, const struct xattr *xattr_array,
- void *page)
-{
- const struct xattr *xattr;
- int err = 0;
-
- for (xattr = xattr_array; xattr->name != NULL; xattr++) {
- err = f2fs_setxattr(inode, F2FS_XATTR_INDEX_SECURITY,
- xattr->name, xattr->value,
- xattr->value_len, (struct page *)page);
- if (err < 0)
- break;
- }
- return err;
-}
-
-int f2fs_init_security(struct inode *inode, struct inode *dir,
- const struct qstr *qstr, struct page *ipage)
-{
- return security_inode_init_security(inode, dir, qstr,
- &f2fs_initxattrs, ipage);
-}
-#endif
-
const struct xattr_handler f2fs_xattr_user_handler = {
.prefix = XATTR_USER_PREFIX,
.flags = F2FS_XATTR_INDEX_USER,
.set = f2fs_xattr_advise_set,
};
-const struct xattr_handler f2fs_xattr_security_handler = {
- .prefix = XATTR_SECURITY_PREFIX,
- .flags = F2FS_XATTR_INDEX_SECURITY,
- .list = f2fs_xattr_generic_list,
- .get = f2fs_xattr_generic_get,
- .set = f2fs_xattr_generic_set,
-};
-
static const struct xattr_handler *f2fs_xattr_handler_map[] = {
[F2FS_XATTR_INDEX_USER] = &f2fs_xattr_user_handler,
#ifdef CONFIG_F2FS_FS_POSIX_ACL
[F2FS_XATTR_INDEX_POSIX_ACL_DEFAULT] = &f2fs_xattr_acl_default_handler,
#endif
[F2FS_XATTR_INDEX_TRUSTED] = &f2fs_xattr_trusted_handler,
-#ifdef CONFIG_F2FS_FS_SECURITY
- [F2FS_XATTR_INDEX_SECURITY] = &f2fs_xattr_security_handler,
-#endif
[F2FS_XATTR_INDEX_ADVISE] = &f2fs_xattr_advise_handler,
};
&f2fs_xattr_acl_default_handler,
#endif
&f2fs_xattr_trusted_handler,
-#ifdef CONFIG_F2FS_FS_SECURITY
- &f2fs_xattr_security_handler,
-#endif
&f2fs_xattr_advise_handler,
NULL,
};
}
int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
- const void *value, size_t value_len, struct page *ipage)
+ const void *value, size_t value_len)
{
struct f2fs_sb_info *sbi = F2FS_SB(inode->i_sb);
struct f2fs_inode_info *fi = F2FS_I(inode);
set_new_dnode(&dn, inode, NULL, NULL, fi->i_xattr_nid);
mark_inode_dirty(inode);
- page = new_node_page(&dn, XATTR_NODE_OFFSET, ipage);
+ page = new_node_page(&dn, XATTR_NODE_OFFSET);
if (IS_ERR(page)) {
alloc_nid_failed(sbi, fi->i_xattr_nid);
fi->i_xattr_nid = 0;
inode->i_ctime = CURRENT_TIME;
clear_inode_flag(fi, FI_ACL_MODE);
}
- if (ipage)
- update_inode(inode, ipage);
- else
- update_inode_page(inode);
+ update_inode_page(inode);
mutex_unlock_op(sbi, ilock);
return 0;
extern const struct xattr_handler f2fs_xattr_acl_access_handler;
extern const struct xattr_handler f2fs_xattr_acl_default_handler;
extern const struct xattr_handler f2fs_xattr_advise_handler;
-extern const struct xattr_handler f2fs_xattr_security_handler;
extern const struct xattr_handler *f2fs_xattr_handlers[];
-extern int f2fs_setxattr(struct inode *, int, const char *,
- const void *, size_t, struct page *);
-extern int f2fs_getxattr(struct inode *, int, const char *, void *, size_t);
-extern ssize_t f2fs_listxattr(struct dentry *, char *, size_t);
+extern int f2fs_setxattr(struct inode *inode, int name_index, const char *name,
+ const void *value, size_t value_len);
+extern int f2fs_getxattr(struct inode *inode, int name_index, const char *name,
+ void *buffer, size_t buffer_size);
+extern ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer,
+ size_t buffer_size);
+
#else
#define f2fs_xattr_handlers NULL
static inline int f2fs_setxattr(struct inode *inode, int name_index,
- const char *name, const void *value, size_t value_len)
+ const char *name, const void *value, size_t value_len)
{
return -EOPNOTSUPP;
}
}
#endif
-#ifdef CONFIG_F2FS_FS_SECURITY
-extern int f2fs_init_security(struct inode *, struct inode *,
- const struct qstr *, struct page *);
-#else
-static inline int f2fs_init_security(struct inode *inode, struct inode *dir,
- const struct qstr *qstr, struct page *ipage)
-{
- return 0;
-}
-#endif
#endif /* __F2FS_XATTR_H__ */
}
EXPORT_SYMBOL(inode_dio_wait);
+/*
+ * inode_dio_done - signal finish of a direct I/O requests
+ * @inode: inode the direct I/O happens on
+ *
+ * This is called once we've finished processing a direct I/O request,
+ * and is used to wake up callers waiting for direct I/O to be quiesced.
+ */
+void inode_dio_done(struct inode *inode)
+{
+ if (atomic_dec_and_test(&inode->i_dio_count))
+ wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
+}
+EXPORT_SYMBOL(inode_dio_done);
* Copyright (C) 1997 Theodore Ts'o
*/
-#include <linux/hardirq.h>
#include <linux/errno.h>
#include <linux/time.h>
#include <linux/proc_fs.h>
int error;
retry:
- if (!ida_pre_get(&proc_inum_ida, (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL))
+ if (!ida_pre_get(&proc_inum_ida, GFP_KERNEL))
return -ENOMEM;
spin_lock_irq(&proc_inum_lock);
len = strlen(fn);
- ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, (in_atomic() || irqs_disabled()) ? GFP_ATOMIC : GFP_KERNEL);
+ ent = kzalloc(sizeof(struct proc_dir_entry) + len + 1, GFP_KERNEL);
if (!ent)
goto out;
return internal_create_group(kobj, 0, grp);
}
-/**
- * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups
- * @kobj: The kobject to create the group on
- * @groups: The attribute groups to create, NULL terminated
- *
- * This function creates a bunch of attribute groups. If an error occurs when
- * creating a group, all previously created groups will be removed, unwinding
- * everything back to the original state when this function was called.
- * It will explicitly warn and error if any of the attribute files being
- * created already exist.
- *
- * Returns 0 on success or error code from sysfs_create_groups on error.
- */
-int sysfs_create_groups(struct kobject *kobj,
- const struct attribute_group **groups)
-{
- int error = 0;
- int i;
-
- if (!groups)
- return 0;
-
- for (i = 0; groups[i]; i++) {
- error = sysfs_create_group(kobj, groups[i]);
- if (error) {
- while (--i >= 0)
- sysfs_remove_group(kobj, groups[i]);
- break;
- }
- }
- return error;
-}
-EXPORT_SYMBOL_GPL(sysfs_create_groups);
-
/**
* sysfs_update_group - given a directory kobject, update an attribute group
* @kobj: The kobject to update the group on
sysfs_put(sd);
}
-/**
- * sysfs_remove_groups - remove a list of groups
- *
- * kobj: The kobject for the groups to be removed from
- * groups: NULL terminated list of groups to be removed
- *
- * If groups is not NULL, the all groups will be removed from the kobject
- */
-void sysfs_remove_groups(struct kobject *kobj,
- const struct attribute_group **groups)
-{
- int i;
-
- if (!groups)
- return;
- for (i = 0; groups[i]; i++)
- sysfs_remove_group(kobj, groups[i]);
-}
-EXPORT_SYMBOL_GPL(sysfs_remove_groups);
-
/**
* sysfs_merge_group - merge files into a pre-existing attribute group.
* @kobj: The kobject containing the group.
#define ioremap_wc ioremap_nocache
#endif
-#ifndef ARCH_HAS_IOREMAP_EXEC
-#define ioremap_exec ioremap
-#define ioremap_exec_nocache ioremap_nocache
-#endif
-
#ifdef CONFIG_PCI
/* Destroy a virtual mapping cookie for a PCI BAR (memory or IO) */
struct pci_dev;
#define sg_dma_len(sg) ((sg)->length)
#endif
-#ifdef CONFIG_ARCH_ROCKCHIP
-#define ARCH_HAS_SG_CHAIN
-#endif
-
#endif /* __ASM_GENERIC_SCATTERLIST_H */
EXIT_CALL \
*(.discard) \
*(.discard.*) \
- *(.pie.*) \
}
/**
* \param fmt printf() like format string.
* \param arg arguments
*/
-#if 0// DRM_DEBUG_CODE
+#if DRM_DEBUG_CODE
#define DRM_DEBUG(fmt, args...) \
do { \
drm_ut_debug_printk(DRM_UT_CORE, DRM_NAME, \
const char **parent_names;
struct clk **parents;
u8 num_parents;
- u8 new_parent_index;
unsigned long rate;
unsigned long new_rate;
- struct clk *new_parent;
- struct clk *new_child;
unsigned long flags;
unsigned int enable_count;
unsigned int prepare_count;
struct hlist_head children;
struct hlist_node child_node;
unsigned int notifier_count;
-
- void *private_data;
#ifdef CONFIG_COMMON_CLK_DEBUG
struct dentry *dentry;
#endif
#define CLK_IS_ROOT BIT(4) /* root clk, has no parent */
#define CLK_IS_BASIC BIT(5) /* Basic clk, can't do a to_clk_foo() */
#define CLK_GET_RATE_NOCACHE BIT(6) /* do not use the cached clk rate */
-#define CLK_SET_RATE_NO_REPARENT BIT(7) /* don't re-parent on rate change */
-#define CLK_SET_RATE_PARENT_IN_ORDER BIT(8) /* consider the order of re-parent
- and set_div on rate change */
-
struct clk_hw;
* @round_rate: Given a target rate as input, returns the closest rate actually
* supported by the clock.
*
- * @determine_rate: Given a target rate as input, returns the closest rate
- * actually supported by the clock, and optionally the parent clock
- * that should be used to provide the clock rate.
- *
* @get_parent: Queries the hardware to determine the parent of a clock. The
* return value is a u8 which specifies the index corresponding to
* the parent clock. This index can be applied to either the
unsigned long parent_rate);
long (*round_rate)(struct clk_hw *hw, unsigned long,
unsigned long *);
- long (*determine_rate)(struct clk_hw *hw, unsigned long rate,
- unsigned long *best_parent_rate,
- struct clk **best_parent_clk);
int (*set_parent)(struct clk_hw *hw, u8 index);
u8 (*get_parent)(struct clk_hw *hw);
int (*set_rate)(struct clk_hw *hw, unsigned long,
* CLK_GATE_SET_TO_DISABLE - by default this clock sets the bit at bit_idx to
* enable the clock. Setting this flag does the opposite: setting the bit
* disable the clock and clearing it enables the clock
- * CLK_GATE_HIWORD_MASK - The gate settings are only in lower 16-bit
- * of this register, and mask of gate bits are in higher 16-bit of this
- * register. While setting the gate bits, higher 16-bit should also be
- * updated to indicate changing gate bits.
*/
struct clk_gate {
struct clk_hw hw;
};
#define CLK_GATE_SET_TO_DISABLE BIT(0)
-#define CLK_GATE_HIWORD_MASK BIT(1)
extern const struct clk_ops clk_gate_ops;
struct clk *clk_register_gate(struct device *dev, const char *name,
* Some hardware implementations gracefully handle this case and allow a
* zero divisor by not modifying their input clock
* (divide by one / bypass).
- * CLK_DIVIDER_HIWORD_MASK - The divider settings are only in lower 16-bit
- * of this register, and mask of divider bits are in higher 16-bit of this
- * register. While setting the divider bits, higher 16-bit should also be
- * updated to indicate changing divider bits.
* CLK_DIVIDER_ROUND_CLOSEST - Makes the best calculated divider to be rounded
* to the closest integer instead of the up one.
*/
#define CLK_DIVIDER_ONE_BASED BIT(0)
#define CLK_DIVIDER_POWER_OF_TWO BIT(1)
#define CLK_DIVIDER_ALLOW_ZERO BIT(2)
-#define CLK_DIVIDER_HIWORD_MASK BIT(3)
#define CLK_DIVIDER_ROUND_CLOSEST BIT(4)
extern const struct clk_ops clk_divider_ops;
* Flags:
* CLK_MUX_INDEX_ONE - register index starts at 1, not 0
* CLK_MUX_INDEX_BIT - register index is a single bit (power of two)
- * CLK_MUX_HIWORD_MASK - The mux settings are only in lower 16-bit of this
- * register, and mask of mux bits are in higher 16-bit of this register.
- * While setting the mux bits, higher 16-bit should also be updated to
- * indicate changing mux bits.
*/
struct clk_mux {
struct clk_hw hw;
#define CLK_MUX_INDEX_ONE BIT(0)
#define CLK_MUX_INDEX_BIT BIT(1)
-#define CLK_MUX_HIWORD_MASK BIT(2)
extern const struct clk_ops clk_mux_ops;
struct clk_hw *__clk_get_hw(struct clk *clk);
u8 __clk_get_num_parents(struct clk *clk);
struct clk *__clk_get_parent(struct clk *clk);
-struct clk *clk_get_parent_by_index(struct clk *clk, u8 index);
unsigned int __clk_get_enable_count(struct clk *clk);
unsigned int __clk_get_prepare_count(struct clk *clk);
unsigned long __clk_get_rate(struct clk *clk);
bool __clk_is_prepared(struct clk *clk);
bool __clk_is_enabled(struct clk *clk);
struct clk *__clk_lookup(const char *name);
-long __clk_mux_determine_rate(struct clk_hw *hw, unsigned long rate,
- unsigned long *best_parent_rate,
- struct clk **best_parent_p);
/*
* FIXME clock api without lock protection
void __iomem *devm_request_and_ioremap(struct device *dev,
struct resource *res);
-void __iomem *devm_ioremap_exec_resource(struct device *dev,
- struct resource *res);
-void __iomem *devm_request_and_ioremap_exec(struct device *dev,
- struct resource *res);
-
/* allows to add/remove a custom action to devres stack */
int devm_add_action(struct device *dev, void (*action)(void *), void *data);
void devm_remove_action(struct device *dev, void (*action)(void *), void *data);
return -EIO;
}
-#ifndef dma_max_pfn
-static inline unsigned long dma_max_pfn(struct device *dev)
-{
- return *dev->dma_mask >> PAGE_SHIFT;
-}
-#endif
-
static inline void *dma_zalloc_coherent(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
enum dma_status (*device_tx_status)(struct dma_chan *chan,
dma_cookie_t cookie,
struct dma_tx_state *txstate);
-#ifdef CONFIG_ARCH_ROCKCHIP
- int (*dma_getposition)(struct dma_chan *chan,
- dma_addr_t *src, dma_addr_t *dst);
-#endif
void (*device_issue_pending)(struct dma_chan *chan);
};
size_t period_len, enum dma_transfer_direction dir,
unsigned long flags)
{
- unsigned int t=0;
return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len,
- period_len, dir, flags, &t);
+ period_len, dir, flags, NULL);
}
-#ifdef CONFIG_ARCH_ROCKCHIP
-static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_infiniteloop(
- struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
- size_t period_len, enum dma_transfer_direction dir,
- unsigned long flags,unsigned int limit)
-{
- unsigned int t=limit;
- return chan->device->device_prep_dma_cyclic(chan, buf_addr, buf_len,
- period_len, dir, flags, &t);
-}
-#endif
static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
struct dma_chan *chan, struct dma_interleaved_template *xt,
struct fb_videomode *fbmode);
/* drivers/video/modedb.c */
-#define VESA_MODEDB_SIZE 48
+#define VESA_MODEDB_SIZE 34
extern void fb_var_to_videomode(struct fb_videomode *mode,
const struct fb_var_screeninfo *var);
extern void fb_videomode_to_var(struct fb_var_screeninfo *var,
/* filesystem does not support filling holes */
DIO_SKIP_HOLES = 0x02,
-
- /* filesystem can handle aio writes beyond i_size */
- DIO_ASYNC_EXTEND = 0x04,
-
- /* inode/fs/bdev does not need truncate protection */
- DIO_SKIP_DIO_COUNT = 0x08,
};
void dio_end_io(struct bio *bio, int error);
#endif
void inode_dio_wait(struct inode *inode);
+void inode_dio_done(struct inode *inode);
-
-/*
- * inode_dio_begin - signal start of a direct I/O requests
- * @inode: inode the direct I/O happens on
- *
- * This is called once we've finished processing a direct I/O request,
- * and is used to wake up callers waiting for direct I/O to be quiesced.
- */
-static inline void inode_dio_begin(struct inode *inode)
-{
- atomic_inc(&inode->i_dio_count);
-}
-
-/*
- * inode_dio_end - signal finish of a direct I/O requests
- * @inode: inode the direct I/O happens on
- *
- * This is called once we've finished processing a direct I/O request,
- * and is used to wake up callers waiting for direct I/O to be quiesced.
- */
-static inline void inode_dio_end(struct inode *inode)
-{
- if (atomic_dec_and_test(&inode->i_dio_count))
- wake_up_bit(&inode->i_state, __I_DIO_WAKEUP);
-}
extern const struct file_operations generic_ro_fops;
#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))
struct blk_integrity *integrity;
#endif
int node_id;
-
- int emmc_disk;//for emmc devive; added by xbw at 2014-03-22
};
static inline struct gendisk *part_to_disk(struct hd_struct *part)
wait_queue_head_t wait;
struct hid_device *hid;
struct device *dev;
- spinlock_t list_lock;
struct list_head list;
};
struct input_value *vals;
bool devres_managed;
-
- int (*inhibit)(struct input_dev *dev);
- int (*uninhibit)(struct input_dev *dev);
-
- bool inhibited;
};
#define to_input_dev(d) container_of(d, struct input_dev, dev)
unsigned long size);
void __iomem *devm_ioremap_nocache(struct device *dev, resource_size_t offset,
unsigned long size);
-void __iomem *devm_ioremap_exec(struct device *dev, resource_size_t offset,
- unsigned long size);
-void __iomem *devm_ioremap_exec_nocache(struct device *dev, resource_size_t offset,
- unsigned long size);
void devm_iounmap(struct device *dev, void __iomem *addr);
int check_signature(const volatile void __iomem *io_addr,
const unsigned char *signature, int length);
u8 raw_ext_csd_structure; /* 194 */
u8 raw_card_type; /* 196 */
u8 out_of_int_time; /* 198 */
- u8 raw_pwr_cl_52_195; /* 200 */
- u8 raw_pwr_cl_26_195; /* 201 */
- u8 raw_pwr_cl_52_360; /* 202 */
- u8 raw_pwr_cl_26_360; /* 203 */
- u8 raw_s_a_timeout; /* 217 */
+ u8 raw_s_a_timeout; /* 217 */
u8 raw_hc_erase_gap_size; /* 221 */
u8 raw_erase_timeout_mult; /* 223 */
u8 raw_hc_erase_grp_size; /* 224 */
u8 raw_sec_erase_mult; /* 230 */
u8 raw_sec_feature_support;/* 231 */
u8 raw_trim_mult; /* 232 */
- u8 raw_pwr_cl_200_195; /* 236 */
- u8 raw_pwr_cl_200_360; /* 237 */
- u8 raw_pwr_cl_ddr_52_195; /* 238 */
- u8 raw_pwr_cl_ddr_52_360; /* 239 */
u8 raw_bkops_status; /* 246 */
u8 raw_sectors[4]; /* 212 - 4 bytes */
};
/* The number of MMC physical partitions. These consist of:
- * boot partitions (2), general purpose partitions (4) and
- * RPMB partition (1) in MMC v4.4.
+ * boot partitions (2), general purpose partitions (4) in MMC v4.4.
*/
#define MMC_NUM_BOOT_PARTITION 2
#define MMC_NUM_GP_PARTITION 4
-#define MMC_NUM_PHY_PARTITION 7
+#define MMC_NUM_PHY_PARTITION 6
#define MAX_MMC_PART_NAME_LEN 20
/*
struct mmc_card {
struct mmc_host *host; /* the host this device belongs to */
struct device dev; /* the device */
- u32 ocr; /* the current OCR setting */
unsigned int rca; /* relative card address of device */
unsigned int type; /* card type */
#define MMC_TYPE_MMC 0 /* MMC card */
#define MMC_CARD_REMOVED (1<<7) /* card has been removed */
#define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */
#define MMC_STATE_DOING_BKOPS (1<<10) /* card is doing BKOPS */
-#define MMC_STATE_SUSPENDED (1<<11) /* card is suspended */
unsigned int quirks; /* card quirks */
#define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */
#define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */
#define MMC_QUIRK_INAND_CMD38 (1<<6) /* iNAND devices have broken CMD38 */
#define MMC_QUIRK_BLK_NO_CMD23 (1<<7) /* Avoid CMD23 for regular multiblock */
#define MMC_QUIRK_BROKEN_BYTE_MODE_512 (1<<8) /* Avoid sending 512 bytes in */
- /* byte mode */
#define MMC_QUIRK_LONG_READ_TIME (1<<9) /* Data read time > CSD says */
#define MMC_QUIRK_SEC_ERASE_TRIM_BROKEN (1<<10) /* Skip secure for erase/trim */
-#define MMC_QUIRK_BROKEN_IRQ_POLLING (1<<11) /* Polling SDIO_CCCR_INTx could create a fake interrupt */
-#define MMC_QUIRK_TRIM_UNSTABLE (1<<28) /* Skip trim */
+ /* byte mode */
unsigned int erase_size; /* erase size in sectors */
unsigned int erase_shift; /* if erase unit is power 2 */
#define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR)
#define mmc_card_ddr_mode(c) ((c)->state & MMC_STATE_HIGHSPEED_DDR)
#define mmc_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
+#define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC)
#define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED))
#define mmc_card_doing_bkops(c) ((c)->state & MMC_STATE_DOING_BKOPS)
-#define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED)
#define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT)
#define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY)
#define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR)
#define mmc_card_set_ddr_mode(c) ((c)->state |= MMC_STATE_HIGHSPEED_DDR)
#define mmc_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
+#define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED)
#define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC)
#define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED)
#define mmc_card_set_doing_bkops(c) ((c)->state |= MMC_STATE_DOING_BKOPS)
#define mmc_card_clr_doing_bkops(c) ((c)->state &= ~MMC_STATE_DOING_BKOPS)
-#define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED)
-#define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED)
/*
* Quirk add/remove for MMC products.
return c->quirks & MMC_QUIRK_LONG_READ_TIME;
}
-static inline int mmc_card_broken_irq_polling(const struct mmc_card *c)
-{
- return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING;
-}
-
#define mmc_card_name(c) ((c)->cid.prod_name)
#define mmc_card_id(c) (dev_name(&(c)->dev))
void (*remove)(struct mmc_card *);
int (*suspend)(struct mmc_card *);
int (*resume)(struct mmc_card *);
- void (*shutdown)(struct mmc_card *);
};
extern int mmc_register_driver(struct mmc_driver *);
*/
unsigned int cmd_timeout_ms; /* in milliseconds */
- /* Set this flag only for blocking sanitize request */
- bool sanitize_busy;
struct mmc_data *data; /* data segment associated with cmd */
struct mmc_request *mrq; /* associated request */
#define MMC_DATA_WRITE (1 << 8)
#define MMC_DATA_READ (1 << 9)
#define MMC_DATA_STREAM (1 << 10)
-#define MMC_DATA_DIRECT (1 << 11)
unsigned int bytes_xfered;
extern int mmc_wait_for_app_cmd(struct mmc_host *, struct mmc_card *,
struct mmc_command *, int);
extern void mmc_start_bkops(struct mmc_card *card, bool from_exception);
-extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool,
- bool);
+extern int __mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int, bool);
extern int mmc_switch(struct mmc_card *, u8, u8, u8, unsigned int);
extern int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd);
extern int __mmc_claim_host(struct mmc_host *host, atomic_t *abort);
extern void mmc_release_host(struct mmc_host *host);
-
-extern void mmc_get_card(struct mmc_card *card);
-extern void mmc_put_card(struct mmc_card *card);
-
-extern void mmc_get_card(struct mmc_card *card);
-extern void mmc_put_card(struct mmc_card *card);
+extern int mmc_try_claim_host(struct mmc_host *host);
extern int mmc_flush_cache(struct mmc_card *);
__mmc_claim_host(host, NULL);
}
-struct device_node;
extern u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
-extern int mmc_of_parse_voltage(struct device_node *np, u32 *mask);
#endif /* LINUX_MMC_CORE_H */
#define LINUX_MMC_DW_MMC_H
#include <linux/scatterlist.h>
-#include <linux/mmc/core.h>
#define MAX_MCI_SLOTS 2
struct mmc_request *mrq;
struct mmc_command *cmd;
struct mmc_data *data;
- struct mmc_command stop_abort;
- unsigned int prev_blksz;
- unsigned char timing;
struct workqueue_struct *card_workqueue;
/* DMA interface members*/
void (*set_ios)(struct mmc_host *host, struct mmc_ios *ios);
int (*get_ro)(struct mmc_host *host);
int (*get_cd)(struct mmc_host *host);
- int (*set_sdio_status)(struct mmc_host *host, int val);//added by xbw,at 2014-03-24
void (*enable_sdio_irq)(struct mmc_host *host, int enable);
int (*select_drive_strength)(unsigned int max_dtr, int host_drv, int card_drv);
void (*hw_reset)(struct mmc_host *host);
void (*card_event)(struct mmc_host *host);
-
- void (*post_tmo)(struct mmc_host *host);
};
struct mmc_card;
#define MMC_CAP_SPI (1 << 4) /* Talks only SPI protocols */
#define MMC_CAP_NEEDS_POLL (1 << 5) /* Needs polling for card-detection */
#define MMC_CAP_8_BIT_DATA (1 << 6) /* Can the host do 8 bit transfers */
-#define MMC_CAP_AGGRESSIVE_PM (1 << 7) /* Suspend (e)MMC/SD at idle */
+
#define MMC_CAP_NONREMOVABLE (1 << 8) /* Nonremovable e.g. eMMC */
#define MMC_CAP_WAIT_WHILE_BUSY (1 << 9) /* Waits while card is busy */
#define MMC_CAP_ERASE (1 << 10) /* Allow erase/trim commands */
#define MMC_CAP_UHS_SDR50 (1 << 17) /* Host supports UHS SDR50 mode */
#define MMC_CAP_UHS_SDR104 (1 << 18) /* Host supports UHS SDR104 mode */
#define MMC_CAP_UHS_DDR50 (1 << 19) /* Host supports UHS DDR50 mode */
-#define MMC_CAP_RUNTIME_RESUME (1 << 20) /* Resume at runtime_resume. */
#define MMC_CAP_DRIVER_TYPE_A (1 << 23) /* Host supports Driver Type A */
#define MMC_CAP_DRIVER_TYPE_C (1 << 24) /* Host supports Driver Type C */
#define MMC_CAP_DRIVER_TYPE_D (1 << 25) /* Host supports Driver Type D */
#define MMC_CAP2_BOOTPART_NOACC (1 << 0) /* Boot partition no access */
#define MMC_CAP2_CACHE_CTRL (1 << 1) /* Allow cache control */
-#define MMC_CAP2_FULL_PWR_CYCLE (1 << 2) /* Can do full power cycle */
+#define MMC_CAP2_POWEROFF_NOTIFY (1 << 2) /* Notify poweroff supported */
#define MMC_CAP2_NO_MULTI_READ (1 << 3) /* Multiblock reads don't work */
#define MMC_CAP2_NO_SLEEP_CMD (1 << 4) /* Don't allow sleep command */
#define MMC_CAP2_HS200_1_8V_SDR (1 << 5) /* can support */
#define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \
MMC_CAP2_HS200_1_2V_SDR)
#define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */
+#define MMC_CAP2_DETECT_ON_ERR (1 << 8) /* On I/O err check card removal */
#define MMC_CAP2_HC_ERASE_SZ (1 << 9) /* High-capacity erase size */
#define MMC_CAP2_CD_ACTIVE_HIGH (1 << 10) /* Card-detect signal active high */
#define MMC_CAP2_RO_ACTIVE_HIGH (1 << 11) /* Write-protect signal active high */
#define MMC_CAP2_PACKED_CMD (MMC_CAP2_PACKED_RD | \
MMC_CAP2_PACKED_WR)
#define MMC_CAP2_NO_PRESCAN_POWERUP (1 << 14) /* Don't power up before scan */
-#define MMC_CAP2_SANITIZE (1 << 15) /* Support Sanitize */
mmc_pm_flag_t pm_caps; /* supported pm features */
-
- u32 restrict_caps; /*restrict the SDMMC controller to support card type;1--SD card; 2--sdio; 4--eMMC */
-#define RESTRICT_CARD_TYPE_SD (1 << 0) /*support SD*/
-#define RESTRICT_CARD_TYPE_SDIO (1 << 1) /*support SDIO*/
-#define RESTRICT_CARD_TYPE_EMMC (1 << 2) /*support EMMC*/
-#define RESTRICT_CARD_TYPE_TSD (1 << 3) /*support tSD*/
- unsigned int hold_reg_flag;//to fix the hold_reg value
-
#ifdef CONFIG_MMC_CLKGATE
int clk_requests; /* internal reference counter */
spinlock_t lock; /* lock for claim and bus ops */
struct mmc_ios ios; /* current io bus settings */
+ u32 ocr; /* the current OCR setting */
/* group bitfields together to minimize padding */
unsigned int use_spi_crc:1;
int rescan_disable; /* disable card detection */
int rescan_entered; /* used with nonremovable devices */
-
- unsigned int can_retune:1; /* re-tuning can be used */
- unsigned int doing_retune:1; /* re-tuning in progress */
- unsigned int retune_now:1; /* do re-tuning at next req */
- int need_retune; /* re-tuning is needed */
- int hold_retune; /* hold off re-tuning */
-
struct mmc_card *card; /* device attached to this host */
wait_queue_head_t wq;
const struct mmc_bus_ops *bus_ops; /* current bus driver */
unsigned int bus_refs; /* reference counter */
-
- unsigned int re_initialized_flags; //in order to begin the rescan ; added by xbw@2011-04-07
- unsigned int doneflag; //added by xbw at 2011-08-27
- int (*sdmmc_host_hw_init)(void *data);
+
unsigned int bus_resume_flags;
#define MMC_BUSRESUME_MANUAL_RESUME (1 << 0)
#define MMC_BUSRESUME_NEEDS_RESUME (1 << 1)
int mmc_add_host(struct mmc_host *);
void mmc_remove_host(struct mmc_host *);
void mmc_free_host(struct mmc_host *);
-int mmc_of_parse(struct mmc_host *host);
-int mmc_host_rescan(struct mmc_host *host, int val, int irq_type);
+void mmc_of_parse(struct mmc_host *host);
+
#ifdef CONFIG_MMC_EMBEDDED_SDIO
extern void mmc_set_embedded_sdio_data(struct mmc_host *host,
struct sdio_cis *cis,
extern int mmc_resume_bus(struct mmc_host *host);
+int mmc_suspend_host(struct mmc_host *);
+int mmc_resume_host(struct mmc_host *);
+
int mmc_power_save_host(struct mmc_host *host);
int mmc_power_restore_host(struct mmc_host *host);
}
#endif
+int mmc_card_awake(struct mmc_host *host);
+int mmc_card_sleep(struct mmc_host *host);
+int mmc_card_can_sleep(struct mmc_host *host);
+
int mmc_pm_notify(struct notifier_block *notify_block, unsigned long, void *);
/* Module parameter */
return host->ios.clock;
}
#endif
-
-void mmc_retune_enable(struct mmc_host *host);
-void mmc_retune_disable(struct mmc_host *host);
-void mmc_retune_hold(struct mmc_host *host);
-void mmc_retune_release(struct mmc_host *host);
-int mmc_retune(struct mmc_host *host);
-
-static inline void mmc_retune_needed(struct mmc_host *host)
-{
- if ((host->can_retune) && (host->doing_retune == 0)) {
- host->need_retune = 1;
- pr_err("[%s] Data transmission error, need to "
- "try retuning %d.\n", mmc_hostname(host),
- host->need_retune);
- } else {
- pr_err("[%s] host was already tuning, Don't"
- " need to retry tune again ignore %d.\n",
- mmc_hostname(host), host->need_retune);
- }
-}
-
-static inline void mmc_retune_not_needed(struct mmc_host *host)
-{
- host->need_retune = 0;
-}
-
-static inline void mmc_retune_recheck(struct mmc_host *host)
-{
- if (host->hold_retune <= 1)
- host->retune_now = 1;
-}
-
#endif /* LINUX_MMC_HOST_H */
void mmc_gpio_free_ro(struct mmc_host *host);
int mmc_gpio_get_cd(struct mmc_host *host);
-int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio,
- unsigned int debounce);
+int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio);
void mmc_gpio_free_cd(struct mmc_host *host);
#endif
extern int of_property_read_u32_index(const struct device_node *np,
const char *propname,
u32 index, u32 *out_value);
-
-extern int of_property_read_u8_array_tp(const struct device_node *np,
- const char *propname, u8 *out_values, size_t sz);
-
extern int of_property_read_u8_array(const struct device_node *np,
const char *propname, u8 *out_values, size_t sz);
extern int of_property_read_u16_array(const struct device_node *np,
return -ENOSYS;
}
-static inline int of_property_read_u8_array_tp(const struct device_node *np,
- const char *propname, u8 *out_values, size_t sz)
-{
- return -ENOSYS;
-}
-
-
-
static inline int of_property_read_u8_array(const struct device_node *np,
const char *propname, u8 *out_values, size_t sz)
{
extern struct pinctrl * __must_check devm_pinctrl_get(struct device *dev);
extern void devm_pinctrl_put(struct pinctrl *p);
-#ifdef CONFIG_PM
-extern int pinctrl_pm_select_default_state(struct device *dev);
-extern int pinctrl_pm_select_sleep_state(struct device *dev);
-extern int pinctrl_pm_select_idle_state(struct device *dev);
-#else
-static inline int pinctrl_pm_select_default_state(struct device *dev)
-{
- return 0;
-}
-static inline int pinctrl_pm_select_sleep_state(struct device *dev)
-{
- return 0;
-}
-static inline int pinctrl_pm_select_idle_state(struct device *dev)
-{
- return 0;
-}
-#endif
-
#else /* !CONFIG_PINCTRL */
static inline int pinctrl_request_gpio(unsigned gpio)
struct dev_pin_info {
struct pinctrl *p;
struct pinctrl_state *default_state;
-#ifdef CONFIG_PM
- struct pinctrl_state *sleep_state;
- struct pinctrl_state *idle_state;
-#endif
};
extern int pinctrl_bind_pins(struct device *dev);
* tristate. The argument is ignored.
* @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
* impedance to VDD). If the argument is != 0 pull-up is enabled,
- * if it is 0, pull-up is total, i.e. the pin is connected to VDD.
+ * if it is 0, pull-up is disabled.
* @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high
* impedance to GROUND). If the argument is != 0 pull-down is enabled,
- * if it is 0, pull-down is total, i.e. the pin is connected to GROUND.
+ * if it is 0, pull-down is disabled.
* @PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: the pin will be pulled up or down based
- * on embedded knowledge of the controller hardware, like current mux
- * function. The pull direction and possibly strength too will normally
- * be decided completely inside the hardware block and not be readable
- * from the kernel side.
- * If the argument is != 0 pull up/down is enabled, if it is 0, the
- * configuration is ignored. The proper way to disable it is to use
- * @PIN_CONFIG_BIAS_DISABLE.
+ * on embedded knowledge of the controller, like current mux function.
+ * If the argument is != 0 pull up/down is enabled, if it is 0,
+ * the pull is disabled.
* @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
* low, this is the most typical case and is typically achieved with two
* active transistors on the output. Setting this config will enable
* supplies, the argument to this parameter (on a custom format) tells
* the driver which alternative power source to use.
* @PIN_CONFIG_SLEW_RATE: if the pin can select slew rate, the argument to
- * this parameter (on a custom format) tells the driver which alternative
- * slew rate to use.
+ * this parameter (on a custom format) tells the driver which alternative
+ * slew rate to use.
* @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
PM_QOS_CPU_DMA_LATENCY,
PM_QOS_NETWORK_LATENCY,
PM_QOS_NETWORK_THROUGHPUT,
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- PM_QOS_MIN_ONLINE_CPUS,
- PM_QOS_MAX_ONLINE_CPUS,
-#endif
/* insert new class ID */
PM_QOS_NUM_CLASSES,
#define PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_LAT_DEFAULT_VALUE (2000 * USEC_PER_SEC)
#define PM_QOS_NETWORK_THROUGHPUT_DEFAULT_VALUE 0
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
-#define PM_QOS_MIN_ONLINE_CPUS_DEFAULT_VALUE 0
-#define PM_QOS_MAX_ONLINE_CPUS_DEFAULT_VALUE INT_MAX
-#endif
#define PM_QOS_DEV_LAT_DEFAULT_VALUE 0
#define PM_QOS_FLAG_NO_POWER_OFF (1 << 0)
extern void __pm_runtime_disable(struct device *dev, bool check_resume);
extern void pm_runtime_allow(struct device *dev);
extern void pm_runtime_forbid(struct device *dev);
+extern int pm_generic_runtime_idle(struct device *dev);
extern int pm_generic_runtime_suspend(struct device *dev);
extern int pm_generic_runtime_resume(struct device *dev);
extern void pm_runtime_no_callbacks(struct device *dev);
static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
static inline bool pm_runtime_enabled(struct device *dev) { return false; }
+static inline int pm_generic_runtime_idle(struct device *dev) { return 0; }
static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; }
static inline int pm_generic_runtime_resume(struct device *dev) { return 0; }
static inline void pm_runtime_no_callbacks(struct device *dev) {}
#include <linux/backlight.h>
-/* TODO: convert to gpiod_*() API once it has been merged */
-#define PWM_BACKLIGHT_GPIO_ACTIVE_LOW (1 << 0)
-
struct platform_pwm_backlight_data {
int pwm_id;
unsigned int max_brightness;
unsigned int lth_brightness;
unsigned int pwm_period_ns;
unsigned int *levels;
- int enable_gpio;
- unsigned long enable_gpio_flags;
int (*init)(struct device *dev);
int (*notify)(struct device *dev, int brightness);
void (*notify_after)(struct device *dev, int brightness);
* OVER_TEMP Regulator over temp.
* FORCE_DISABLE Regulator forcibly shut down by software.
* VOLTAGE_CHANGE Regulator voltage changed.
- * Data passed is old voltage cast to (void *).
* DISABLE Regulator was disabled.
- * PRE_VOLTAGE_CHANGE Regulator is about to have voltage changed.
- * Data passed is "struct pre_voltage_change_data"
- * ABORT_VOLTAGE_CHANGE Regulator voltage change failed for some reason.
- * Data passed is old voltage cast to (void *).
*
* NOTE: These events can be OR'ed together when passed into handler.
*/
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
#define REGULATOR_EVENT_VOLTAGE_CHANGE 0x40
#define REGULATOR_EVENT_DISABLE 0x80
-#define REGULATOR_EVENT_PRE_VOLTAGE_CHANGE 0x100
-#define REGULATOR_EVENT_ABORT_VOLTAGE_CHANGE 0x200
-
-/**
- * struct pre_voltage_change_data - Data sent with PRE_VOLTAGE_CHANGE event
- *
- * @old_uV: Current voltage before change.
- * @min_uV: Min voltage we'll change to.
- * @max_uV: Max voltage we'll change to.
- */
-struct pre_voltage_change_data {
- unsigned long old_uV;
- unsigned long min_uV;
- unsigned long max_uV;
-};
struct regulator;
int min_uA, int max_uA);
int regulator_get_current_limit(struct regulator *regulator);
-int regulator_is_supported_mode(struct regulator *regulator, int *mode);
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
unsigned int regulator_get_mode(struct regulator *regulator);
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
extern int nr_processes(void);
extern unsigned long nr_running(void);
extern unsigned long nr_iowait(void);
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
-extern u64 nr_running_integral(unsigned int cpu);
-#endif
extern unsigned long nr_iowait_cpu(int cpu);
extern unsigned long this_cpu_load(void);
return spi_sync(spi, &m);
}
-
-static inline int
-spi_write_and_read(struct spi_device *spi, const void *tx_buf, void *rx_buf, size_t len)
-{
- struct spi_transfer t = {
- .tx_buf = tx_buf,
- .rx_buf = rx_buf,
- .len = len,
- };
- struct spi_message m;
-
- spi_message_init(&m);
- spi_message_add_tail(&t, &m);
- return spi_sync(spi, &m);
-}
-
-
/**
* spi_sync_transfer - synchronous SPI data transfer
* @spi: device with which data will be exchanged
int __must_check sysfs_create_group(struct kobject *kobj,
const struct attribute_group *grp);
-int __must_check sysfs_create_groups(struct kobject *kobj,
- const struct attribute_group **groups);
int sysfs_update_group(struct kobject *kobj,
const struct attribute_group *grp);
void sysfs_remove_group(struct kobject *kobj,
const struct attribute_group *grp);
-void sysfs_remove_groups(struct kobject *kobj,
- const struct attribute_group **groups);
int sysfs_add_file_to_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
void sysfs_remove_file_from_group(struct kobject *kobj,
/* Turn on only VBUS suspend power and hotplug detection,
* turn off everything else */
void (*power_suspend)(struct platform_device *pdev);
- int (*pre_setup)(struct usb_hcd *hcd);
};
#endif /* __USB_CORE_EHCI_PDRIVER_H */
#ifndef _LINUX_WLAN_PLAT_H_
#define _LINUX_WLAN_PLAT_H_
+#define WLAN_PLAT_NODFS_FLAG 0x01
+
struct wifi_platform_data {
int (*set_power)(int val);
int (*set_reset)(int val);
void *(*mem_prealloc)(int section, unsigned long size);
int (*get_mac_addr)(unsigned char *buf);
int (*get_wake_irq)(void);
- void *(*get_country_code)(char *ccode);
+ void *(*get_country_code)(char *ccode, u32 flags);
};
#endif
unsigned char iface; /* Host number */
unsigned char devnum; /* Device number per host */
struct soc_camera_sense *sense; /* See comment in struct definition */
-
- struct soc_camera_ops *ops;/*yzm*/
- struct mutex video_lock;/*yzm*/
-
struct video_device *vdev;
struct v4l2_ctrl_handler ctrl_handler;
const struct soc_camera_format_xlate *current_fmt;
struct module *owner;
int (*add)(struct soc_camera_device *);
void (*remove)(struct soc_camera_device *);
- /****************yzm**************/
- int (*suspend)(struct soc_camera_device *, pm_message_t);
- int (*resume)(struct soc_camera_device *);
- int (*enum_frameinervals)(struct soc_camera_device *, struct v4l2_frmivalenum *);/* ddl@rock-chips.com :Add ioctrl - VIDIOC_ENUM_FRAMEINTERVALS for soc-camera */
- int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *);
- int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
- int (*s_stream)(struct soc_camera_device *, int enable);
- const struct v4l2_queryctrl *controls;
- int num_controls;
- /***************yzm*****************/
-
/*
* .get_formats() is called for each client device format, but
* .put_formats() is only called once. Further, if any of the calls to
struct soc_camera_device *);
int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *);
int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
- int (*set_bus_param)(struct soc_camera_device *, __u32);/*yzm*/
+ int (*set_bus_param)(struct soc_camera_device *);
int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
int (*enum_framesizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
/* sensor driver private platform data */
void *drv_priv;
- struct soc_camera_device *socdev;/*yzm*/
-
/* Optional regulators that have to be managed on power on/off events */
struct regulator_bulk_data *regulators;
int num_regulators;
int (*power)(struct device *, int);
int (*reset)(struct device *);
- int (*powerdown)(struct device *, int);/*yzm*/
/*
* some platforms may support different data widths than the sensors
* native ones due to different data line routing. Let the board code
unsigned long flags;
void *priv;
- void *priv_usr; /*yzm*/
+
/* Optional regulators that have to be managed on power on/off events */
struct regulator_bulk_data *regulators;
int num_regulators;
/* Optional callbacks to power on or off and reset the sensor */
int (*power)(struct device *, int);
int (*reset)(struct device *);
- int (*powerdown)(struct device *,int); /*yzm*/
/*
* some platforms may support different data widths than the sensors
* native ones due to different data line routing. Let the board code
const struct soc_mbus_pixelfmt *host_fmt;
};
-/*****************yzm***************/
-struct soc_camera_ops {
- int (*suspend)(struct soc_camera_device *, pm_message_t state);
- int (*resume)(struct soc_camera_device *);
- unsigned long (*query_bus_param)(struct soc_camera_device *);
- int (*set_bus_param)(struct soc_camera_device *, unsigned long);
- int (*enum_input)(struct soc_camera_device *, struct v4l2_input *);
- const struct v4l2_queryctrl *controls;
- struct v4l2_querymenu *menus;
- int num_controls;
- int num_menus;
-};
-/****************yzm***************/
-
#define SOCAM_SENSE_PCLK_CHANGED (1 << 0)
/**
unsigned long pixel_clock_max;
unsigned long pixel_clock;
};
-/***************yzm****************/
-static inline struct v4l2_queryctrl const *soc_camera_find_qctrl(
- struct soc_camera_ops *ops, int id)
-{
- int i;
-
- for (i = 0; i < ops->num_controls; i++)
- if (ops->controls[i].id == id)
- return &ops->controls[i];
-
- return NULL;
-}
-/***************yzm****************rnd*/
#define SOCAM_DATAWIDTH(x) BIT((x) - 1)
#define SOCAM_DATAWIDTH_4 SOCAM_DATAWIDTH(4)
#define SOCAM_DATAWIDTH_16 SOCAM_DATAWIDTH(16)
#define SOCAM_DATAWIDTH_18 SOCAM_DATAWIDTH(18)
#define SOCAM_DATAWIDTH_24 SOCAM_DATAWIDTH(24)
-/**************yzm***********/
-#define SOCAM_MCLK_24MHZ (1<<29)
-#define SOCAM_MCLK_48MHZ (1<<31)
-//*************yzm***********end
+
#define SOCAM_DATAWIDTH_MASK (SOCAM_DATAWIDTH_4 | SOCAM_DATAWIDTH_8 | \
SOCAM_DATAWIDTH_9 | SOCAM_DATAWIDTH_10 | \
SOCAM_DATAWIDTH_12 | SOCAM_DATAWIDTH_15 | \
V4L2_IDENT_OV2640 = 259,
V4L2_IDENT_OV9740 = 260,
V4L2_IDENT_OV5642 = 261,
-/***********yzm**********/
- V4L2_IDENT_OV2655 = 262, /* ddl@rock-chips.com : ov2655 support */
- V4L2_IDENT_OV2659 = 263,
- V4L2_IDENT_OV3640 = 264,
- V4L2_IDENT_OV5640 = 265,
- V4L2_IDENT_OV7675 = 266,
- V4L2_IDENT_OV7690 = 267,
- V4L2_IDENT_OV3660 = 268,
-/***********yzm********end*/
+
/* module saa7146: reserved range 300-309 */
V4L2_IDENT_SAA7146 = 300,
-/***********yzm*************/
- /* Samsung sensors: reserved range 310-319 */
- V4L2_IDENT_S5K66A = 310, /* ddl@rock-chips.com : s5k66a support */
- V4L2_IDENT_S5K5CA = 311, /* ddl@rock-chips.com : s5k5ca support */
-
- V4L2_IDENT_MTK9335ISP = 320, /* ddl@rock-chips.com : MTK9335ISP support */
- V4L2_IDENT_ICATCH7002_MI1040 = 321,
- V4L2_IDENT_ICATCH7002_OV5693 =322,
- V4L2_IDENT_ICATCH7002_OV8825 = 323, //zyt
- V4L2_IDENT_ICATCH7002_OV2720 = 324, //zyt
-/************yzm************end*/
+
/* Conexant MPEG encoder/decoders: reserved range 400-420 */
V4L2_IDENT_CX23418_843 = 403, /* Integrated A/V Decoder on the '418 */
V4L2_IDENT_CX23415 = 415,
/* module sn9c20x: just ident 10000 */
V4L2_IDENT_SN9C20X = 10000,
- /* Siliconfile sensors: reserved range 10100 - 10199 */
- V4L2_IDENT_NOON010PC30 = 10100,/*yzm*/
/* module cx231xx and cx25840 */
V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
V4L2_IDENT_CX23100 = 23100,
V4L2_IDENT_MT9M001C12STM = 45005,
V4L2_IDENT_MT9M111 = 45007,
V4L2_IDENT_MT9M112 = 45008,
- V4L2_IDENT_MT9D112 = 45009, /* ddl@rock-chips.com : MT9D112 support */
V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */
V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */
V4L2_IDENT_MT9T031 = 45020,
V4L2_IDENT_MT9V111 = 45031,
V4L2_IDENT_MT9V112 = 45032,
- V4L2_IDENT_MT9P111 = 45033, /* ddl@rock-chips.com : MT9P111 support */
- V4L2_IDENT_MT9D113 = 45034, /* ddl@rock-chips.com : MT9D113 support */
-
/* HV7131R CMOS sensor: just ident 46000 */
V4L2_IDENT_HV7131R = 46000,
/* module upd64083: just ident 64083 */
V4L2_IDENT_UPD64083 = 64083,
-/*************yzm************/
- V4L2_IDENT_NT99250 = 64100, /* ddl@rock-chips.com : nt99250 support */
- V4L2_IDENT_SID130B = 64101, /* ddl@rock-chips.com : sid130B support */
-
- V4L2_IDENT_GT2005 = 64110, /* ddl@rock-chips.com : GT2005 support */
- V4L2_IDENT_GC0307 = 64111, /* ddl@rock-chips.com : GC0308 support */
- V4L2_IDENT_GC0308 = 64112, /* ddl@rock-chips.com : GC0308 support */
- V4L2_IDENT_GC0309 = 64113, /* ddl@rock-chips.com : GC0309 support */
- V4L2_IDENT_GC2015 = 64114, /* ddl@rock-chips.com : gc2015 support */
- V4L2_IDENT_GC0329 = 64115, /* ddl@rock-chips.com : GC0329 support */
- V4L2_IDENT_GC2035= 64116, /* ddl@rock-chips.com : GC0329 support */
- V4L2_IDENT_GC0328 = 64117,
-
- V4L2_IDENT_SP0838 = 64120, /* ddl@rock-chips.com : SP0838 support */
- V4L2_IDENT_SP2518 = 64121, /* ddl@rock-chips.com : SP2518 support */
- V4L2_IDENT_SP0718 = 64122, /* ddl@rock-chips.com : SP0718 support */
-
- V4L2_IDENT_HI253 = 64130, /* ddl@rock-chips.com : hi253 support */
- V4L2_IDENT_HI704 = 64131, /* ddl@rock-chips.com : hi704 support */
-
- V4L2_IDENT_SIV120B = 64140, /* ddl@rock-chips.com : siv120b support */
- V4L2_IDENT_SIV121D= 64141, /* ddl@rock-chips.com : sid130B support */
-
-
- V4L2_IDENT_HM2057 = 64150,
- V4L2_IDENT_HM5065 = 64151,
-
- V4L2_IDENT_NT99160 = 64161, /* oyyf@rock-chips.com : nt99160 support */
- V4L2_IDENT_NT99340 = 64162, /* oyyf@rock-chips.com : nt99340 support */
- V4L2_IDENT_NT99252 = 64163, /* oyyf@rock-chips.com : nt99252 support */
- V4L2_IDENT_NT99240 = 64164, /* oyyf@rock-chips.com : nt99252 support */
-/***********yzm***********end*/
-
/* Don't just add new IDs at the end: KEEP THIS LIST ORDERED BY ID! */
};
params_channels(p)) / 8;
}
-#define HW_PARAMS_FLAG_LPCM 0
-#define HW_PARAMS_FLAG_NLPCM 1
-
#endif /* __SOUND_PCM_PARAMS_H */
TP_CONDITION(((cmd == MMC_READ_MULTIPLE_BLOCK) ||
(cmd == MMC_WRITE_MULTIPLE_BLOCK)) &&
data));
-
-/*
- * Logging of start of req(sbc) and req done of mmc operation,
- * including cmd, args, size, resp, etc.
- */
-DECLARE_EVENT_CLASS(start_req,
- TP_PROTO(const char * host, unsigned int cmd,
- unsigned int arg, unsigned int flags,
- unsigned int blksz, unsigned int blks),
- TP_ARGS(host, cmd, arg, flags, blksz, blks),
-
- TP_STRUCT__entry(
- __string(host, host)
- __field(unsigned int, cmd )
- __field(unsigned int, arg )
- __field(unsigned int, flags )
- __field(unsigned int, blksz )
- __field(unsigned int, blks )
- ),
-
- TP_fast_assign(
- __assign_str(host, host);
- __entry->cmd = cmd;
- __entry->arg = arg;
- __entry->flags = flags;
- __entry->blksz = blksz;
- __entry->blks = blks;
- ),
-
- TP_printk("host=%s CMD%u arg=%08x flags=%08x blksz=%05x blks=%03x",
- __get_str(host), __entry->cmd,
- __entry->arg, __entry->flags,
- __entry->blksz, __entry->blks )
-);
-
-DEFINE_EVENT(start_req, mmc_start_req_cmd,
- TP_PROTO(const char *host, unsigned int cmd,
- unsigned int arg, unsigned int flags,
- unsigned int blksz, unsigned int blks),
- TP_ARGS(host, cmd, arg, flags, blksz, blks)
-);
-
-DEFINE_EVENT(start_req, mmc_start_req_sbc,
- TP_PROTO(const char *host, unsigned int cmd,
- unsigned int arg, unsigned int flags,
- unsigned int blksz, unsigned int blks),
- TP_ARGS(host, cmd, arg, flags, blksz, blks)
-);
-
-
-DECLARE_EVENT_CLASS(req_done,
- TP_PROTO(const char *host, unsigned int cmd,
- int err, unsigned int resp1,
- unsigned int resp2, unsigned int resp3,
- unsigned int resp4),
- TP_ARGS(host, cmd, err, resp1, resp2, resp3, resp4),
-
- TP_STRUCT__entry(
- __string(host, host)
- __field(unsigned int, cmd )
- __field( int, err )
- __field(unsigned int, resp1 )
- __field(unsigned int, resp2 )
- __field(unsigned int, resp3 )
- __field(unsigned int, resp4 )
- ),
-
- TP_fast_assign(
- __assign_str(host, host);
- __entry->cmd = cmd;
- __entry->err = err;
- __entry->resp1 = resp1;
- __entry->resp2 = resp2;
- __entry->resp3 = resp3;
- __entry->resp4 = resp4;
- ),
-
- TP_printk("host=%s CMD%u err=%08x resp1=%08x resp2=%08x resp3=%08x resp4=%08x",
- __get_str(host), __entry->cmd,
- __entry->err, __entry->resp1,
- __entry->resp2, __entry->resp3,
- __entry->resp4 )
-);
-
-DEFINE_EVENT(req_done, mmc_req_done,
- TP_PROTO(const char *host, unsigned int cmd,
- int err, unsigned int resp1,
- unsigned int resp2, unsigned int resp3,
- unsigned int resp4),
- TP_ARGS(host, cmd, err, resp1, resp2, resp3, resp4)
-);
#endif /* _TRACE_MMC_H */
/* This part must be outside protection */
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
__u16 len; /* msg length */
__u8 *buf; /* pointer to msg data */
-#ifdef CONFIG_I2C_ROCKCHIP_COMPAT
- __u32 scl_rate; /* add by kfx */
-#endif
};
/* To determine what functionality is present */
* Copyright (C) 2010 Google, Inc.
* Author: Mike Lockwood <lockwood@android.com>
*
- * Copyright (C) 2014, NVIDIA CORPORATION. All rights reserved.
- *
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
void *data;
};
-#ifdef CONFIG_COMPAT
-struct mtp_event_32 {
- /* size of the event */
- compat_size_t length;
- /* event data to send */
- compat_uptr_t data;
-};
-
-#define MTP_SEND_EVENT_32 _IOW('M', 3, struct mtp_event_32)
-#endif
-
/* Sends the specified file range to the host */
#define MTP_SEND_FILE _IOW('M', 0, struct mtp_file_range)
/* Receives data from the host and writes it to a file.
#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11)
#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12)
-/**************yzm**************/
-/* ddl@rock-chips.com : Add ioctrl - V4L2_CID_SCENE for camera scene control */
-#define V4L2_CID_CAMERA_CLASS_BASE_ROCK (V4L2_CID_CAMERA_CLASS_BASE + 40)
-#define V4L2_CID_SCENE (V4L2_CID_CAMERA_CLASS_BASE_ROCK+1)
-#define V4L2_CID_EFFECT (V4L2_CID_CAMERA_CLASS_BASE_ROCK+2)
-#define V4L2_CID_FLASH (V4L2_CID_CAMERA_CLASS_BASE_ROCK+3)
-#define V4L2_CID_FOCUS_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE_ROCK+4)
-#define V4L2_CID_FOCUSZONE (V4L2_CID_CAMERA_CLASS_BASE_ROCK+5)
-#define V4L2_CID_FACEDETECT (V4L2_CID_CAMERA_CLASS_BASE_ROCK+6)
-#define V4L2_CID_HDR (V4L2_CID_CAMERA_CLASS_BASE_ROCK+7)
-#define V4L2_CID_ISO (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 8)
-#define V4L2_CID_ANTIBANDING (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 9)
-#define V4L2_CID_WHITEBALANCE_LOCK (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 10)
-#define V4L2_CID_EXPOSURE_LOCK (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 11)
-#define V4L2_CID_METERING_AREAS (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 12)
-#define V4L2_CID_WDR (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 13)
-#define V4L2_CID_EDGE (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 14)
-#define V4L2_CID_JPEG_EXIF (V4L2_CID_CAMERA_CLASS_BASE_ROCK + 15)
-/***************yzm***************/
-
#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13)
#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14)
#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15)
__s64 value64;
char *string;
};
- __s32 rect[4];/*rockchip add for focus zone*/
} __attribute__ ((packed));
struct v4l2_ext_controls {
#define SNDRV_PCM_FORMAT_G723_40_1B ((__force snd_pcm_format_t) 47) /* 1 sample in 1 byte */
#define SNDRV_PCM_FORMAT_DSD_U8 ((__force snd_pcm_format_t) 48) /* DSD, 1-byte samples DSD (x8) */
#define SNDRV_PCM_FORMAT_DSD_U16_LE ((__force snd_pcm_format_t) 49) /* DSD, 2-byte samples DSD (x16), little endian */
-#define SNDRV_NON_LINEAR_PCM_FORMAT_AC3 ((__force snd_pcm_format_t) 50) /* AC3,NON Linear PCM,spdif */
-#define SNDRV_NON_LINEAR_PCM_FORMAT_EAC3 ((__force snd_pcm_format_t) 51) /* EAC3,NON Linear PCM,spdif*/
-#define SNDRV_NON_LINEAR_PCM_FORMAT_DTS_I ((__force snd_pcm_format_t) 52) /* DTS-I,NON Linear PCM,spdif*/
#define SNDRV_PCM_FORMAT_LAST SNDRV_PCM_FORMAT_DSD_U16_LE
#ifdef SNDRV_LITTLE_ENDIAN
DISPLAY_FLAGS_PIXDATA_NEGEDGE = BIT(7),
DISPLAY_FLAGS_INTERLACED = BIT(8),
DISPLAY_FLAGS_DOUBLESCAN = BIT(9),
-#if defined(CONFIG_FB_ROCKCHIP) || defined(CONFIG_DRM_ROCKCHIP)
- DISPLAY_FLAGS_SWAP_GB = BIT(10),
- DISPLAY_FLAGS_SWAP_RG = BIT(11),
- DISPLAY_FLAGS_SWAP_RB = BIT(12),
-#endif
};
/*
struct timing_entry vsync_len; /* ver. sync len */
enum display_flags flags; /* display flags */
-#if defined(CONFIG_FB_ROCKCHIP) || defined(CONFIG_DRM_ROCKCHIP)
- u16 screen_type; /*screen type*/
- u16 lvds_format; /*lvds data format for lvds screen*/
- u16 face; /*display output interface format:24bit 18bit 16bit*/
- u16 color_mode; /* input color mode: RGB or YUV */
- u32 *dsp_lut;
- u32 *cabc_lut;
- u32 *cabc_gamma_base;
-#endif
};
/*
}
#ifdef CONFIG_MODULES
-#ifndef CONFIG_ARCH_ROCKCHIP
read_unlock(&exec_domains_lock);
request_module("personality-%d", pers);
read_lock(&exec_domains_lock);
if (try_module_get(ep->module))
goto out;
}
-#endif
#endif
ep = &default_exec_domain;
{
int retval;
- read_lock_irq(&tasklist_lock);
+ read_lock(&tasklist_lock);
retval = will_become_orphaned_pgrp(task_pgrp(current), NULL);
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
return retval;
}
return;
}
- read_lock_irq(&tasklist_lock);
+ read_lock(&tasklist_lock);
/*
* Search in the children
*/
goto assign_new_owner;
} while_each_thread(g, c);
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
/*
* We found no owner yet mm_users > 1: this implies that we are
* most likely racing with swapoff (try_to_unuse()) or /proc or
* Delay read_unlock() till we have the task_lock()
* to ensure that c does not slip away underneath us
*/
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
if (c->mm != mm) {
task_unlock(c);
put_task_struct(c);
int why;
get_task_struct(p);
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
if ((exit_code & 0x7f) == 0) {
why = CLD_EXITED;
status = exit_code >> 8;
* Now we are sure this task is interesting, and no other
* thread can reap it because we set its state to EXIT_DEAD.
*/
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
retval = wo->wo_rusage
? getrusage(p, RUSAGE_BOTH, wo->wo_rusage) : 0;
get_task_struct(p);
pid = task_pid_vnr(p);
why = ptrace ? CLD_TRAPPED : CLD_STOPPED;
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
if (unlikely(wo->wo_flags & WNOWAIT))
return wait_noreap_copyout(wo, p, pid, uid, why, exit_code);
pid = task_pid_vnr(p);
get_task_struct(p);
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
if (!wo->wo_info) {
retval = wo->wo_rusage
goto notask;
set_current_state(TASK_INTERRUPTIBLE);
- read_lock_irq(&tasklist_lock);
+ read_lock(&tasklist_lock);
tsk = current;
do {
retval = do_wait_thread(wo, tsk);
if (wo->wo_flags & __WNOTHREAD)
break;
} while_each_thread(current, tsk);
- read_unlock_irq(&tasklist_lock);
+ read_unlock(&tasklist_lock);
notask:
retval = wo->notask_error;
.name = "network_throughput",
};
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
-static BLOCKING_NOTIFIER_HEAD(min_online_cpus_notifier);
-static struct pm_qos_constraints min_online_cpus_constraints = {
- .list = PLIST_HEAD_INIT(min_online_cpus_constraints.list),
- .target_value = PM_QOS_MIN_ONLINE_CPUS_DEFAULT_VALUE,
- .default_value = PM_QOS_MIN_ONLINE_CPUS_DEFAULT_VALUE,
- .type = PM_QOS_MAX,
- .notifiers = &min_online_cpus_notifier,
-};
-static struct pm_qos_object min_online_cpus_pm_qos = {
- .constraints = &min_online_cpus_constraints,
- .name = "min_online_cpus",
-};
-
-static BLOCKING_NOTIFIER_HEAD(max_online_cpus_notifier);
-static struct pm_qos_constraints max_online_cpus_constraints = {
- .list = PLIST_HEAD_INIT(max_online_cpus_constraints.list),
- .target_value = PM_QOS_MAX_ONLINE_CPUS_DEFAULT_VALUE,
- .default_value = PM_QOS_MAX_ONLINE_CPUS_DEFAULT_VALUE,
- .type = PM_QOS_MIN,
- .notifiers = &max_online_cpus_notifier,
-};
-static struct pm_qos_object max_online_cpus_pm_qos = {
- .constraints = &max_online_cpus_constraints,
- .name = "max_online_cpus",
-};
-#endif
static struct pm_qos_object *pm_qos_array[] = {
&null_pm_qos,
&cpu_dma_pm_qos,
&network_lat_pm_qos,
- &network_throughput_pm_qos,
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- &min_online_cpus_pm_qos,
- &max_online_cpus_pm_qos,
-#endif
+ &network_throughput_pm_qos
};
static ssize_t pm_qos_power_write(struct file *filp, const char __user *buf,
#define CREATE_TRACE_POINTS
#include <trace/events/printk.h>
-#ifdef CONFIG_EARLY_PRINTK_DIRECT
-extern void printascii(char *);
-#endif
-
/* printk's without a loglevel use this.. */
#define DEFAULT_MESSAGE_LOGLEVEL CONFIG_DEFAULT_MESSAGE_LOGLEVEL
u8 facility; /* syslog facility */
u8 flags:5; /* internal record flags */
u8 level:3; /* syslog level */
-#ifdef CONFIG_PRINTK_PROCESS
- char process[16]; /* process name */
- pid_t pid; /* process id */
- u8 cpu; /* cpu id */
- u8 in_interrupt; /* interrupt context */
-#endif
};
/*
static u64 clear_seq;
static u32 clear_idx;
-#ifdef CONFIG_PRINTK_PROCESS
-#define PREFIX_MAX 48
-#else
#define PREFIX_MAX 32
-#endif
#define LOG_LINE_MAX 1024 - PREFIX_MAX
/* record buffer */
return idx + msg->len;
}
-#ifdef CONFIG_PRINTK_PROCESS
-static bool printk_process = 1;
-static size_t print_process(const struct log *msg, char *buf)
-{
- if (!printk_process)
- return 0;
-
- if (!buf)
- return snprintf(NULL, 0, "%c[%1d:%15s:%5d] ", ' ', 0, " ", 0);
-
- return sprintf(buf, "%c[%1d:%15s:%5d] ",
- msg->in_interrupt ? 'I' : ' ',
- msg->cpu,
- msg->process,
- msg->pid);
-}
-module_param_named(process, printk_process, bool, S_IRUGO | S_IWUSR);
-#endif
-
-#ifdef CONFIG_RK_LAST_LOG
-extern void rk_last_log_text(char *text, size_t size);
-static char rk_text[1024];
-static size_t msg_print_text(const struct log *msg, enum log_flags prev,
- bool syslog, char *buf, size_t size);
-#endif
/* insert record into the buffer, discard old ones, update heads */
static void log_store(int facility, int level,
enum log_flags flags, u64 ts_nsec,
memset(log_dict(msg) + dict_len, 0, pad_len);
msg->len = sizeof(struct log) + text_len + dict_len + pad_len;
-#ifdef CONFIG_PRINTK_PROCESS
- if (printk_process) {
- strncpy(msg->process, current->comm, sizeof(msg->process)-1);
- msg->process[sizeof(msg->process) - 1] = '\0';
- msg->pid = task_pid_nr(current);
- msg->cpu = smp_processor_id();
- msg->in_interrupt = in_interrupt() ? 1 : 0;
- }
-#endif
-
-#ifdef CONFIG_RK_LAST_LOG
- size = msg_print_text(msg, msg->flags, true, rk_text, sizeof(rk_text));
- rk_last_log_text(rk_text, size);
-#endif
/* insert message */
log_next_idx += msg->len;
log_next_seq++;
}
len += print_time(msg->ts_nsec, buf ? buf + len : NULL);
-#ifdef CONFIG_PRINTK_PROCESS
- len += print_process(msg, buf ? buf + len : NULL);
-#endif
return len;
}
if (cont.cons == 0 && (console_prev & LOG_NEWLINE)) {
textlen += print_time(cont.ts_nsec, text);
-#ifdef CONFIG_PRINTK_PROCESS
- *(text+textlen) = ' ';
- textlen += print_process(NULL, NULL);
-#endif
size -= textlen;
}
}
}
-#ifdef CONFIG_EARLY_PRINTK_DIRECT
- printascii(text);
-#endif
-
if (level == -1)
level = default_message_loglevel;
}
EXPORT_SYMBOL(printk);
-#if defined(CONFIG_RK_DEBUG_UART) && (CONFIG_RK_DEBUG_UART >= 0)
-void console_disable_suspend(void)
-{
- console_suspended = 0;
-}
-#endif
#else /* CONFIG_PRINTK */
#define LOG_LINE_MAX 0
return this->cpu_load[0];
}
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
-u64 nr_running_integral(unsigned int cpu)
-{
- unsigned int seqcnt;
- u64 integral;
- struct rq *q;
-
- if (cpu >= nr_cpu_ids)
- return 0;
-
- q = cpu_rq(cpu);
-
- /*
- * Update average to avoid reading stalled value if there were
- * no run-queue changes for a long time. On the other hand if
- * the changes are happening right now, just read current value
- * directly.
- */
-
- seqcnt = read_seqcount_begin(&q->ave_seqcnt);
- integral = do_nr_running_integral(q);
- if (read_seqcount_retry(&q->ave_seqcnt, seqcnt)) {
- read_seqcount_begin(&q->ave_seqcnt);
- integral = q->nr_running_integral;
- }
-
- return integral;
-}
-#endif
/*
* Global load-average calculations
put_online_cpus();
return retval;
}
-EXPORT_SYMBOL(sched_setaffinity);
static int get_user_cpu_mask(unsigned long __user *user_mask_ptr, unsigned len,
struct cpumask *new_mask)
* hmp_packing_enabled: runtime control over pack/spread
* hmp_full_threshold: Consider a CPU with this much unweighted load full
*/
-#ifdef CONFIG_ARCH_ROCKCHIP
-unsigned int hmp_up_threshold = 479;
-unsigned int hmp_down_threshold = 214;
-#else
unsigned int hmp_up_threshold = 700;
unsigned int hmp_down_threshold = 512;
-#endif
#ifdef CONFIG_SCHED_HMP_PRIO_FILTER
unsigned int hmp_up_prio = NICE_TO_PRIO(CONFIG_SCHED_HMP_PRIO_FILTER_VAL);
#endif
#endif
int skip_clock_update;
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- /* time-based average load */
- u64 nr_last_stamp;
- u64 nr_running_integral;
- seqcount_t ave_seqcnt;
-#endif
-
/* capture load from *all* tasks on this cpu: */
struct load_weight load;
unsigned long nr_load_updates;
}
#endif
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
-/* 27 ~= 134217728ns = 134.2ms
- * 26 ~= 67108864ns = 67.1ms
- * 25 ~= 33554432ns = 33.5ms
- * 24 ~= 16777216ns = 16.8ms
- */
-#define NR_AVE_SCALE(x) ((x) << FSHIFT)
-
-static inline u64 do_nr_running_integral(struct rq *rq)
-{
- s64 nr, deltax;
- u64 nr_running_integral = rq->nr_running_integral;
-
- deltax = rq->clock_task - rq->nr_last_stamp;
- nr = NR_AVE_SCALE(rq->nr_running);
-
- nr_running_integral += nr * deltax;
-
- return nr_running_integral;
-}
-#endif
-
static inline void inc_nr_running(struct rq *rq)
{
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- write_seqcount_begin(&rq->ave_seqcnt);
- rq->nr_running_integral = do_nr_running_integral(rq);
- rq->nr_last_stamp = rq->clock_task;
-#endif
rq->nr_running++;
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- write_seqcount_end(&rq->ave_seqcnt);
-#endif
#ifdef CONFIG_NO_HZ_FULL
if (rq->nr_running == 2) {
static inline void dec_nr_running(struct rq *rq)
{
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- write_seqcount_begin(&rq->ave_seqcnt);
- rq->nr_running_integral = do_nr_running_integral(rq);
- rq->nr_last_stamp = rq->clock_task;
-#endif
rq->nr_running--;
-#ifdef CONFIG_CPUQUIET_FRAMEWORK
- write_seqcount_end(&rq->ave_seqcnt);
-#endif
}
static inline void rq_last_tick_reset(struct rq *rq)
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/unistd.h>
-#ifdef CONFIG_ARCH_ROCKCHIP
-#include <asm/system_misc.h>
-#endif
#ifndef SET_UNALIGN_CTL
# define SET_UNALIGN_CTL(a,b) (-EINVAL)
printk(KERN_EMERG "Power down.\n");
kmsg_dump(KMSG_DUMP_POWEROFF);
machine_power_off();
-#ifdef CONFIG_ARCH_ROCKCHIP
- arm_pm_restart('h', "charge");
-#endif
}
EXPORT_SYMBOL_GPL(kernel_power_off);
config NLATTR
bool
-config HAVE_PIE
- bool
- help
- See Documentation/pie.txt for details.
-
-config PIE
- bool "Embedded position independant executables"
- depends on HAVE_PIE
- select GENERIC_ALLOCATOR
- help
- This option adds support for embedding position indepentant (PIE)
- executables into the kernel. The PIEs can then be copied into
- genalloc regions such as SRAM and executed. Some platforms require
- this for suspend/resume support.
-
#
# Generic 64-bit atomic support is selected if needed
#
The behavior is also controlled by the kernel command line
parameter printk.time=1. See Documentation/kernel-parameters.txt
-config PRINTK_PROCESS
- bool "Show process information on printks"
- depends on PRINTK
- help
- Selecting this option causes process to be
- included in printk output. Or add printk.process=1 at boot-time.
-
config DEFAULT_MESSAGE_LOGLEVEL
int "Default message log level (1-7)"
range 1 7
obj-$(CONFIG_STMP_DEVICE) += stmp_device.o
-obj-$(CONFIG_PIE) += pie.o
-
libfdt_files = fdt.o fdt_ro.o fdt_wip.o fdt_rw.o fdt_sw.o fdt_strerror.o \
fdt_empty_tree.o
$(foreach file, $(libfdt_files), \
}
EXPORT_SYMBOL(devm_ioremap_nocache);
-/**
- * devm_ioremap_exec - Managed ioremap_exec()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap_exec(). Map is automatically unmapped on driver detach.
- */
-void __iomem *devm_ioremap_exec(struct device *dev, resource_size_t offset,
- unsigned long size)
-{
- void __iomem **ptr, *addr;
-
- ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- addr = ioremap_exec(offset, size);
- if (addr) {
- *ptr = addr;
- devres_add(dev, ptr);
- } else
- devres_free(ptr);
-
- return addr;
-}
-EXPORT_SYMBOL(devm_ioremap_exec);
-
-/**
- * devm_ioremap_exec_nocache - Managed ioremap_exec_nocache()
- * @dev: Generic device to remap IO address for
- * @offset: BUS offset to map
- * @size: Size of map
- *
- * Managed ioremap_exec_nocache(). Map is automatically unmapped on driver
- * detach.
- */
-void __iomem *devm_ioremap_exec_nocache(struct device *dev,
- resource_size_t offset,
- unsigned long size)
-{
- void __iomem **ptr, *addr;
-
- ptr = devres_alloc(devm_ioremap_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- addr = ioremap_exec_nocache(offset, size);
- if (addr) {
- *ptr = addr;
- devres_add(dev, ptr);
- } else
- devres_free(ptr);
-
- return addr;
-}
-EXPORT_SYMBOL(devm_ioremap_exec_nocache);
-
/**
* devm_iounmap - Managed iounmap()
* @dev: Generic device to unmap for
}
EXPORT_SYMBOL(devm_ioremap_resource);
-void __iomem *devm_ioremap_exec_resource(struct device *dev,
- struct resource *res)
-{
- resource_size_t size;
- const char *name;
- void __iomem *dest_ptr;
-
- BUG_ON(!dev);
-
- if (!res || resource_type(res) != IORESOURCE_MEM) {
- dev_err(dev, "invalid resource\n");
- return ERR_PTR(-EINVAL);
- }
-
- size = resource_size(res);
- name = res->name ?: dev_name(dev);
-
- if (!devm_request_mem_region(dev, res->start, size, name)) {
- dev_err(dev, "can't request region for resource %pR\n", res);
- return ERR_PTR(-EBUSY);
- }
-
- if (res->flags & IORESOURCE_CACHEABLE)
- dest_ptr = devm_ioremap_exec(dev, res->start, size);
- else
- dest_ptr = devm_ioremap_exec_nocache(dev, res->start, size);
-
- if (!dest_ptr) {
- dev_err(dev, "ioremap failed for resource %pR\n", res);
- devm_release_mem_region(dev, res->start, size);
- dest_ptr = ERR_PTR(-ENOMEM);
- }
-
- return dest_ptr;
-}
-EXPORT_SYMBOL(devm_ioremap_exec_resource);
-
/**
* devm_request_and_ioremap() - Check, request region, and ioremap resource
* @dev: Generic device to handle the resource for
}
EXPORT_SYMBOL(devm_request_and_ioremap);
-/**
- * devm_request_and_ioremap_exec() - Check, request region, and ioremap resource
- * @dev: Generic device to handle the resource for
- * @res: resource to be handled
- *
- * Takes all necessary steps to ioremap a mem resource. Uses managed device, so
- * everything is undone on driver detach. Checks arguments, so you can feed
- * it the result from e.g. platform_get_resource() directly. Returns the
- * remapped pointer or NULL on error. Usage example:
- *
- * res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- * base = devm_request_and_ioremap_exec(&pdev->dev, res);
- * if (!base)
- * return -EADDRNOTAVAIL;
- */
-void __iomem *devm_request_and_ioremap_exec(struct device *device,
- struct resource *res)
-{
- void __iomem *dest_ptr;
-
- dest_ptr = devm_ioremap_exec_resource(device, res);
- if (IS_ERR(dest_ptr))
- return NULL;
-
- return dest_ptr;
-}
-EXPORT_SYMBOL(devm_request_and_ioremap_exec);
-
#ifdef CONFIG_HAS_IOPORT
/*
* Generic iomap devres
detach_vmas_to_be_unmapped(mm, vma, prev, end);
unmap_region(mm, vma, prev, start, end);
-#ifdef CONFIG_ARCH_ROCKCHIP
- {
- extern int ion_munmap(void *dmabuf, struct vm_area_struct *vma);
- extern int dma_buf_is_dma_buf(struct file *file);
- if (vma->vm_file && dma_buf_is_dma_buf(vma->vm_file)) {
- ion_munmap(vma->vm_file->private_data, vma);
- }
- }
-#endif
-
/* Fix up all other VM information */
remove_vma_list(mm, vma);
/*
* The interval between `kupdate'-style writebacks
- * modify by wlf@20140515
*/
-unsigned int dirty_writeback_interval = 1 * 100; /* centiseconds */
+unsigned int dirty_writeback_interval = 5 * 100; /* centiseconds */
EXPORT_SYMBOL_GPL(dirty_writeback_interval);
page = list_entry(area->free_list[migratetype].next,
struct page, lru);
-
-#ifdef CONFIG_ARCH_ROCKCHIP
- if (is_migrate_cma(migratetype)){
- int mt = get_pageblock_migratetype(page);
- if (unlikely(is_migrate_isolate(mt)))
- continue;
- }
-#endif
-
area->nr_free--;
/*
#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
-void __paginginit set_pageblock_order(void)
+void __init set_pageblock_order(void)
{
unsigned int order;
* include/linux/pageblock-flags.h for the values of pageblock_order based on
* the kernel config
*/
-void __paginginit set_pageblock_order(void)
+void __init set_pageblock_order(void)
{
}
vbq = &get_cpu_var(vmap_block_queue);
vb->vbq = vbq;
spin_lock(&vbq->lock);
- list_add_tail_rcu(&vb->free_list, &vbq->free);
+ list_add_rcu(&vb->free_list, &vbq->free);
spin_unlock(&vbq->lock);
put_cpu_var(vmap_block_queue);
wiphy_warn(local->hw.wiphy,
"Failed to add default virtual iface\n");
}
- // ESP8089 register p2p0 IFTYPE_STA
- #ifdef CONFIG_ESP8089
- if (local->hw.wiphy->interface_modes &(BIT(NL80211_IFTYPE_P2P_GO) |
- BIT(NL80211_IFTYPE_P2P_CLIENT))) {
- result = ieee80211_if_add(local, "p2p%d", NULL,
- NL80211_IFTYPE_STATION, NULL);
- if (result)
- wiphy_warn(local->hw.wiphy,
- "Failed to add default virtual iface\n");
- }
-
- #endif
+
rtnl_unlock();
local->network_latency_notifier.notifier_call =
If you say yes here you get support of a generic gpio RFKILL
driver. The platform should fill in the appropriate fields in the
rfkill_gpio_platform_data structure and pass that to the driver.
-
-config RFKILL_RK
- bool "Rockchips RFKILL driver"
- depends on RFKILL
- help
- rockchips rfkill driver for rk29/rk3X
obj-$(CONFIG_RFKILL) += rfkill.o
obj-$(CONFIG_RFKILL_REGULATOR) += rfkill-regulator.o
obj-$(CONFIG_RFKILL_GPIO) += rfkill-gpio.o
-obj-$(CONFIG_RFKILL_RK) += rfkill-wlan.o rfkill-bt.o
rtnl_lock();
if (rdev->wiphy.registered) {
- //modify to fix wifi disconnet when suspended.(gwl)
- //if (!rdev->wowlan)
- // cfg80211_leave_all(rdev);
+ if (!rdev->wowlan)
+ cfg80211_leave_all(rdev);
if (rdev->ops->suspend)
ret = rdev_suspend(rdev, rdev->wowlan);
if (ret == 1) {
continue;
} else if (wdev_iter->netdev) {
if (!netif_running(wdev_iter->netdev))
- {
- continue;
- }
- continue;
+ continue;
} else {
WARN_ON(1);
}
# Licensed under the terms of the GNU GPL License version 2
use strict;
-use POSIX;
my $P = $0;
$P =~ s@.*/@@g;
my $emacs = 0;
my $terse = 0;
my $file = 0;
-my $check = 1;
-my $check_orig = 0;
+my $check = 0;
my $summary = 1;
my $mailback = 0;
my $summary_file = 0;
my $show_types = 0;
-my $fix = 0;
-my $fix_inplace = 0;
my $root;
my %debug;
-my %camelcase = ();
-my %use_type = ();
-my @use = ();
my %ignore_type = ();
my @ignore = ();
my $help = 0;
my $configuration_file = ".checkpatch.conf";
my $max_line_length = 80;
-my $ignore_perl_version = 0;
-my $minimum_perl_version = 5.10.0;
sub help {
my ($exitcode) = @_;
--terse one line per report
-f, --file treat FILE as regular source file
--subjective, --strict enable more subjective tests
- --types TYPE(,TYPE2...) show only these comma separated message types
--ignore TYPE(,TYPE2...) ignore various comma separated message types
--max-line-length=n set the maximum line length, if exceeded, warn
--show-types show the message "types" in the output
is all off)
--test-only=WORD report only warnings/errors containing WORD
literally
- --fix EXPERIMENTAL - may create horrible results
- If correctable single-line errors exist, create
- "<inputfile>.EXPERIMENTAL-checkpatch-fixes"
- with potential errors corrected to the preferred
- checkpatch style
- --fix-inplace EXPERIMENTAL - may create horrible results
- Is the same as --fix, but overwrites the input
- file. It's your fault if there's no backup or git
- --ignore-perl-version override checking of perl version. expect
- runtime errors.
-h, --help, --version display this help and exit
When FILE is - read standard input.
'subjective!' => \$check,
'strict!' => \$check,
'ignore=s' => \@ignore,
- 'types=s' => \@use,
'show-types!' => \$show_types,
'max-line-length=i' => \$max_line_length,
'root=s' => \$root,
'summary!' => \$summary,
'mailback!' => \$mailback,
'summary-file!' => \$summary_file,
- 'fix!' => \$fix,
- 'fix-inplace!' => \$fix_inplace,
- 'ignore-perl-version!' => \$ignore_perl_version,
+
'debug=s' => \%debug,
'test-only=s' => \$tst_only,
'h|help' => \$help,
help(0) if ($help);
-$fix = 1 if ($fix_inplace);
-$check_orig = $check;
-
my $exit = 0;
-if ($^V && $^V lt $minimum_perl_version) {
- printf "$P: requires at least perl version %vd\n", $minimum_perl_version;
- if (!$ignore_perl_version) {
- exit(1);
- }
-}
-
if ($#ARGV < 0) {
print "$P: no input files\n";
exit(1);
}
-sub hash_save_array_words {
- my ($hashRef, $arrayRef) = @_;
-
- my @array = split(/,/, join(',', @$arrayRef));
- foreach my $word (@array) {
- $word =~ s/\s*\n?$//g;
- $word =~ s/^\s*//g;
- $word =~ s/\s+/ /g;
- $word =~ tr/[a-z]/[A-Z]/;
+@ignore = split(/,/, join(',',@ignore));
+foreach my $word (@ignore) {
+ $word =~ s/\s*\n?$//g;
+ $word =~ s/^\s*//g;
+ $word =~ s/\s+/ /g;
+ $word =~ tr/[a-z]/[A-Z]/;
- next if ($word =~ m/^\s*#/);
- next if ($word =~ m/^\s*$/);
+ next if ($word =~ m/^\s*#/);
+ next if ($word =~ m/^\s*$/);
- $hashRef->{$word}++;
- }
-}
-
-sub hash_show_words {
- my ($hashRef, $prefix) = @_;
-
- if ($quiet == 0 && keys %$hashRef) {
- print "NOTE: $prefix message types:";
- foreach my $word (sort keys %$hashRef) {
- print " $word";
- }
- print "\n\n";
- }
+ $ignore_type{$word}++;
}
-hash_save_array_words(\%ignore_type, \@ignore);
-hash_save_array_words(\%use_type, \@use);
-
my $dbg_values = 0;
my $dbg_possible = 0;
my $dbg_type = 0;
__ref|
__rcu
}x;
-our $InitAttributePrefix = qr{__(?:mem|cpu|dev|net_|)};
-our $InitAttributeData = qr{$InitAttributePrefix(?:initdata\b)};
-our $InitAttributeConst = qr{$InitAttributePrefix(?:initconst\b)};
-our $InitAttributeInit = qr{$InitAttributePrefix(?:init\b)};
-our $InitAttribute = qr{$InitAttributeData|$InitAttributeConst|$InitAttributeInit};
# Notes to $Attribute:
# We need \b after 'init' otherwise 'initconst' will cause a false positive in a check
__deprecated|
__read_mostly|
__kprobes|
- $InitAttribute|
+ __(?:mem|cpu|dev|)(?:initdata|initconst|init\b)|
____cacheline_aligned|
____cacheline_aligned_in_smp|
____cacheline_internodealigned_in_smp|
__weak
}x;
our $Modifier;
-our $Inline = qr{inline|__always_inline|noinline|__inline|__inline__};
+our $Inline = qr{inline|__always_inline|noinline};
our $Member = qr{->$Ident|\.$Ident|\[[^]]*\]};
our $Lval = qr{$Ident(?:$Member)*};
-our $Int_type = qr{(?i)llu|ull|ll|lu|ul|l|u};
-our $Binary = qr{(?i)0b[01]+$Int_type?};
-our $Hex = qr{(?i)0x[0-9a-f]+$Int_type?};
-our $Int = qr{[0-9]+$Int_type?};
-our $Octal = qr{0[0-7]+$Int_type?};
our $Float_hex = qr{(?i)0x[0-9a-f]+p-?[0-9]+[fl]?};
our $Float_dec = qr{(?i)(?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)(?:e-?[0-9]+)?[fl]?};
our $Float_int = qr{(?i)[0-9]+e-?[0-9]+[fl]?};
our $Float = qr{$Float_hex|$Float_dec|$Float_int};
-our $Constant = qr{$Float|$Binary|$Octal|$Hex|$Int};
+our $Constant = qr{$Float|(?i)(?:0x[0-9a-f]+|[0-9]+)[ul]*};
our $Assignment = qr{\*\=|/=|%=|\+=|-=|<<=|>>=|&=|\^=|\|=|=};
-our $Compare = qr{<=|>=|==|!=|<|(?<!-)>};
-our $Arithmetic = qr{\+|-|\*|\/|%};
+our $Compare = qr{<=|>=|==|!=|<|>};
our $Operators = qr{
<=|>=|==|!=|
=>|->|<<|>>|<|>|!|~|
- &&|\|\||,|\^|\+\+|--|&|\||$Arithmetic
+ &&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%
}x;
-our $c90_Keywords = qr{do|for|while|if|else|return|goto|continue|switch|default|case|break}x;
-
our $NonptrType;
-our $NonptrTypeWithAttr;
our $Type;
our $Declare;
our $logFunctions = qr{(?x:
printk(?:_ratelimited|_once|)|
- (?:[a-z0-9]+_){1,2}(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
+ [a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
WARN(?:_RATELIMIT|_ONCE|)|
panic|
- MODULE_[A-Z_]+|
- seq_vprintf|seq_printf|seq_puts
+ MODULE_[A-Z_]+
)};
our $signature_tags = qr{(?xi:
qr{${Ident}_handler},
qr{${Ident}_handler_fn},
);
-our @typeListWithAttr = (
- @typeList,
- qr{struct\s+$InitAttribute\s+$Ident},
- qr{union\s+$InitAttribute\s+$Ident},
-);
-
our @modifierList = (
qr{fastcall},
);
-our @mode_permission_funcs = (
- ["module_param", 3],
- ["module_param_(?:array|named|string)", 4],
- ["module_param_array_named", 5],
- ["debugfs_create_(?:file|u8|u16|u32|u64|x8|x16|x32|x64|size_t|atomic_t|bool|blob|regset32|u32_array)", 2],
- ["proc_create(?:_data|)", 2],
- ["(?:CLASS|DEVICE|SENSOR)_ATTR", 2],
-);
-
-#Create a search pattern for all these functions to speed up a loop below
-our $mode_perms_search = "";
-foreach my $entry (@mode_permission_funcs) {
- $mode_perms_search .= '|' if ($mode_perms_search ne "");
- $mode_perms_search .= $entry->[0];
-}
-
-our $declaration_macros = qr{(?x:
- (?:$Storage\s+)?(?:DECLARE|DEFINE)_[A-Z]+\s*\(|
- (?:$Storage\s+)?LIST_HEAD\s*\(
-)};
-
our $allowed_asm_includes = qr{(?x:
irq|
memory
sub build_types {
my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
- my $allWithAttr = "(?x: \n" . join("|\n ", @typeListWithAttr) . "\n)";
$Modifier = qr{(?:$Attribute|$Sparse|$mods)};
$NonptrType = qr{
(?:$Modifier\s+|const\s+)*
)
(?:\s+$Modifier|\s+const)*
}x;
- $NonptrTypeWithAttr = qr{
- (?:$Modifier\s+|const\s+)*
- (?:
- (?:typeof|__typeof__)\s*\([^\)]*\)|
- (?:$typeTypedefs\b)|
- (?:${allWithAttr}\b)
- )
- (?:\s+$Modifier|\s+const)*
- }x;
$Type = qr{
$NonptrType
(?:(?:\s|\*|\[\])+\s*const|(?:\s|\*|\[\])+|(?:\s*\[\s*\])+)?
(?:\s+$Inline|\s+$Modifier)*
}x;
- $Declare = qr{(?:$Storage\s+(?:$Inline\s+)?)?$Type};
+ $Declare = qr{(?:$Storage\s+)?$Type};
}
build_types();
+
our $Typecast = qr{\s*(\(\s*$NonptrType\s*\)){0,1}\s*};
# Using $balanced_parens, $LvalOrFunc, or $FuncArg
# Any use must be runtime checked with $^V
our $balanced_parens = qr/(\((?:[^\(\)]++|(?-1))*\))/;
-our $LvalOrFunc = qr{((?:[\&\*]\s*)?$Lval)\s*($balanced_parens{0,1})\s*};
+our $LvalOrFunc = qr{($Lval)\s*($balanced_parens{0,1})\s*};
our $FuncArg = qr{$Typecast{0,1}($LvalOrFunc|$Constant)};
sub deparenthesize {
my ($string) = @_;
return "" if (!defined($string));
-
- while ($string =~ /^\s*\(.*\)\s*$/) {
- $string =~ s@^\s*\(\s*@@;
- $string =~ s@\s*\)\s*$@@;
- }
-
+ $string =~ s@^\s*\(\s*@@g;
+ $string =~ s@\s*\)\s*$@@g;
$string =~ s@\s+@ @g;
-
return $string;
}
-sub seed_camelcase_file {
- my ($file) = @_;
-
- return if (!(-f $file));
-
- local $/;
-
- open(my $include_file, '<', "$file")
- or warn "$P: Can't read '$file' $!\n";
- my $text = <$include_file>;
- close($include_file);
-
- my @lines = split('\n', $text);
-
- foreach my $line (@lines) {
- next if ($line !~ /(?:[A-Z][a-z]|[a-z][A-Z])/);
- if ($line =~ /^[ \t]*(?:#[ \t]*define|typedef\s+$Type)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)/) {
- $camelcase{$1} = 1;
- } elsif ($line =~ /^\s*$Declare\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[\(\[,;]/) {
- $camelcase{$1} = 1;
- } elsif ($line =~ /^\s*(?:union|struct|enum)\s+(\w*(?:[A-Z][a-z]|[a-z][A-Z])\w*)\s*[;\{]/) {
- $camelcase{$1} = 1;
- }
- }
-}
-
-my $camelcase_seeded = 0;
-sub seed_camelcase_includes {
- return if ($camelcase_seeded);
-
- my $files;
- my $camelcase_cache = "";
- my @include_files = ();
-
- $camelcase_seeded = 1;
-
- if (-e ".git") {
- my $git_last_include_commit = `git log --no-merges --pretty=format:"%h%n" -1 -- include`;
- chomp $git_last_include_commit;
- $camelcase_cache = ".checkpatch-camelcase.git.$git_last_include_commit";
- } else {
- my $last_mod_date = 0;
- $files = `find $root/include -name "*.h"`;
- @include_files = split('\n', $files);
- foreach my $file (@include_files) {
- my $date = POSIX::strftime("%Y%m%d%H%M",
- localtime((stat $file)[9]));
- $last_mod_date = $date if ($last_mod_date < $date);
- }
- $camelcase_cache = ".checkpatch-camelcase.date.$last_mod_date";
- }
-
- if ($camelcase_cache ne "" && -f $camelcase_cache) {
- open(my $camelcase_file, '<', "$camelcase_cache")
- or warn "$P: Can't read '$camelcase_cache' $!\n";
- while (<$camelcase_file>) {
- chomp;
- $camelcase{$_} = 1;
- }
- close($camelcase_file);
-
- return;
- }
-
- if (-e ".git") {
- $files = `git ls-files "include/*.h"`;
- @include_files = split('\n', $files);
- }
-
- foreach my $file (@include_files) {
- seed_camelcase_file($file);
- }
-
- if ($camelcase_cache ne "") {
- unlink glob ".checkpatch-camelcase.*";
- open(my $camelcase_file, '>', "$camelcase_cache")
- or warn "$P: Can't write '$camelcase_cache' $!\n";
- foreach (sort { lc($a) cmp lc($b) } keys(%camelcase)) {
- print $camelcase_file ("$_\n");
- }
- close($camelcase_file);
- }
-}
-
$chk_signoff = 0 if ($file);
my @rawlines = ();
my @lines = ();
-my @fixed = ();
my $vname;
for my $filename (@ARGV) {
my $FILE;
}
@rawlines = ();
@lines = ();
- @fixed = ();
}
exit($exit);
$comment = $2 if defined $2;
$formatted_email =~ s/$address.*$//;
$name = $formatted_email;
- $name = trim($name);
+ $name =~ s/^\s+|\s+$//g;
$name =~ s/^\"|\"$//g;
# If there's a name left after stripping spaces and
# leading quotes, and the address doesn't have both
}
}
- $name = trim($name);
+ $name =~ s/^\s+|\s+$//g;
$name =~ s/^\"|\"$//g;
- $address = trim($address);
+ $address =~ s/^\s+|\s+$//g;
$address =~ s/^\<|\>$//g;
if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
my $formatted_email;
- $name = trim($name);
+ $name =~ s/^\s+|\s+$//g;
$name =~ s/^\"|\"$//g;
- $address = trim($address);
+ $address =~ s/^\s+|\s+$//g;
if ($name =~ /[^\w \-]/i) { ##has "must quote" chars
$name =~ s/(?<!\\)"/\\"/g; ##escape quotes
my $prefix = '';
sub show_type {
- my ($type) = @_;
-
- return defined $use_type{$type} if (scalar keys %use_type > 0);
-
- return !defined $ignore_type{$type};
+ return !defined $ignore_type{$_[0]};
}
sub report {
- my ($level, $type, $msg) = @_;
-
- if (!show_type($type) ||
- (defined $tst_only && $msg !~ /\Q$tst_only\E/)) {
+ if (!show_type($_[1]) ||
+ (defined $tst_only && $_[2] !~ /\Q$tst_only\E/)) {
return 0;
}
my $line;
if ($show_types) {
- $line = "$prefix$level:$type: $msg\n";
+ $line = "$prefix$_[0]:$_[1]: $_[2]\n";
} else {
- $line = "$prefix$level: $msg\n";
+ $line = "$prefix$_[0]: $_[2]\n";
}
$line = (split('\n', $line))[0] . "\n" if ($terse);
return 1;
}
-
sub report_dump {
our @report;
}
sub ERROR {
- my ($type, $msg) = @_;
-
- if (report("ERROR", $type, $msg)) {
+ if (report("ERROR", $_[0], $_[1])) {
our $clean = 0;
our $cnt_error++;
- return 1;
}
- return 0;
}
sub WARN {
- my ($type, $msg) = @_;
-
- if (report("WARNING", $type, $msg)) {
+ if (report("WARNING", $_[0], $_[1])) {
our $clean = 0;
our $cnt_warn++;
- return 1;
}
- return 0;
}
sub CHK {
- my ($type, $msg) = @_;
-
- if ($check && report("CHECK", $type, $msg)) {
+ if ($check && report("CHECK", $_[0], $_[1])) {
our $clean = 0;
our $cnt_chk++;
- return 1;
}
- return 0;
}
sub check_absolute_file {
}
}
-sub trim {
- my ($string) = @_;
-
- $string =~ s/^\s+|\s+$//g;
-
- return $string;
-}
-
-sub ltrim {
- my ($string) = @_;
-
- $string =~ s/^\s+//;
-
- return $string;
-}
-
-sub rtrim {
- my ($string) = @_;
-
- $string =~ s/\s+$//;
-
- return $string;
-}
-
-sub string_find_replace {
- my ($string, $find, $replace) = @_;
-
- $string =~ s/$find/$replace/g;
-
- return $string;
-}
-
-sub tabify {
- my ($leading) = @_;
-
- my $source_indent = 8;
- my $max_spaces_before_tab = $source_indent - 1;
- my $spaces_to_tab = " " x $source_indent;
-
- #convert leading spaces to tabs
- 1 while $leading =~ s@^([\t]*)$spaces_to_tab@$1\t@g;
- #Remove spaces before a tab
- 1 while $leading =~ s@^([\t]*)( {1,$max_spaces_before_tab})\t@$1\t@g;
-
- return "$leading";
-}
-
sub pos_last_openparen {
my ($line) = @_;
}
}
- return length(expand_tabs(substr($line, 0, $last_openparen))) + 1;
+ return $last_openparen + 1;
}
sub process {
my %suppress_export;
my $suppress_statement = 0;
- my %signatures = ();
+ my %camelcase = ();
# Pre-scan the patch sanitizing the lines.
# Pre-scan the patch looking for any __setup documentation.
my @setup_docs = ();
my $setup_docs = 0;
- my $camelcase_file_seeded = 0;
-
sanitise_line_reset();
my $line;
foreach my $rawline (@rawlines) {
$linenr++;
$line = $rawline;
- push(@fixed, $rawline) if ($fix);
-
if ($rawline=~/^\+\+\+\s+(\S+)/) {
$setup_docs = 0;
if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
$linenr = 0;
foreach my $line (@lines) {
$linenr++;
- my $sline = $line; #copy of $line
- $sline =~ s/$;/ /g; #with comments as spaces
my $rawline = $rawlines[$linenr - 1];
$here = "#$linenr: " if (!$file);
$here = "#$realline: " if ($file);
- my $found_file = 0;
# extract the filename as it passes
if ($line =~ /^diff --git.*?(\S+)$/) {
$realfile = $1;
- $realfile =~ s@^([^/]*)/@@ if (!$file);
+ $realfile =~ s@^([^/]*)/@@;
$in_commit_log = 0;
- $found_file = 1;
} elsif ($line =~ /^\+\+\+\s+(\S+)/) {
$realfile = $1;
- $realfile =~ s@^([^/]*)/@@ if (!$file);
+ $realfile =~ s@^([^/]*)/@@;
$in_commit_log = 0;
$p1_prefix = $1;
ERROR("MODIFIED_INCLUDE_ASM",
"do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
}
- $found_file = 1;
- }
-
- if ($found_file) {
- if ($realfile =~ m@^(drivers/net/|net/)@) {
- $check = 1;
- } else {
- $check = $check_orig;
- }
next;
}
"Non-standard signature: $sign_off\n" . $herecurr);
}
if (defined $space_before && $space_before ne "") {
- if (WARN("BAD_SIGN_OFF",
- "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =
- "$ucfirst_sign_off $email";
- }
+ WARN("BAD_SIGN_OFF",
+ "Do not use whitespace before $ucfirst_sign_off\n" . $herecurr);
}
if ($sign_off =~ /-by:$/i && $sign_off ne $ucfirst_sign_off) {
- if (WARN("BAD_SIGN_OFF",
- "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =
- "$ucfirst_sign_off $email";
- }
-
+ WARN("BAD_SIGN_OFF",
+ "'$ucfirst_sign_off' is the preferred signature form\n" . $herecurr);
}
if (!defined $space_after || $space_after ne " ") {
- if (WARN("BAD_SIGN_OFF",
- "Use a single space after $ucfirst_sign_off\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =
- "$ucfirst_sign_off $email";
- }
+ WARN("BAD_SIGN_OFF",
+ "Use a single space after $ucfirst_sign_off\n" . $herecurr);
}
my ($email_name, $email_address, $comment) = parse_email($email);
"email address '$email' might be better as '$suggested_email$comment'\n" . $herecurr);
}
}
-
-# Check for duplicate signatures
- my $sig_nospace = $line;
- $sig_nospace =~ s/\s//g;
- $sig_nospace = lc($sig_nospace);
- if (defined $signatures{$sig_nospace}) {
- WARN("BAD_SIGN_OFF",
- "Duplicate signature\n" . $herecurr);
- } else {
- $signatures{$sig_nospace} = 1;
- }
- }
-
-# Check for old stable address
- if ($line =~ /^\s*cc:\s*.*<?\bstable\@kernel\.org\b>?.*$/i) {
- ERROR("STABLE_ADDRESS",
- "The 'stable' address should be 'stable\@vger.kernel.org'\n" . $herecurr);
- }
-
-# Check for unwanted Gerrit info
- if ($in_commit_log && $line =~ /^\s*change-id:/i) {
- ERROR("GERRIT_CHANGE_ID",
- "Remove Gerrit Change-Id's before submitting upstream.\n" . $herecurr);
}
# Check for wrappage within a valid hunk of the file
#trailing whitespace
if ($line =~ /^\+.*\015/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- if (ERROR("DOS_LINE_ENDINGS",
- "DOS line endings\n" . $herevet) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/[\s\015]+$//;
- }
+ ERROR("DOS_LINE_ENDINGS",
+ "DOS line endings\n" . $herevet);
+
} elsif ($rawline =~ /^\+.*\S\s+$/ || $rawline =~ /^\+\s+$/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- if (ERROR("TRAILING_WHITESPACE",
- "trailing whitespace\n" . $herevet) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\s+$//;
- }
-
+ ERROR("TRAILING_WHITESPACE",
+ "trailing whitespace\n" . $herevet);
$rpt_cleaners = 1;
}
-# Check for FSF mailing addresses.
- if ($rawline =~ /\bwrite to the Free/i ||
- $rawline =~ /\b59\s+Temple\s+Pl/i ||
- $rawline =~ /\b51\s+Franklin\s+St/i) {
- my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- my $msg_type = \&ERROR;
- $msg_type = \&CHK if ($file);
- &{$msg_type}("FSF_MAILING_ADDRESS",
- "Do not include the paragraph about writing to the Free Software Foundation's mailing address from the sample GPL notice. The FSF has changed addresses in the past, and may do so again. Linux already includes a copy of the GPL.\n" . $herevet)
- }
-
# check for Kconfig help text having a real description
# Only applies when adding the entry originally, after that we do not have
# sufficient context to determine whether it is indeed long enough.
"Use of $flag is deprecated, please use \`$replacement->{$flag} instead.\n" . $herecurr) if ($replacement->{$flag});
}
-# check for DT compatible documentation
- if (defined $root &&
- (($realfile =~ /\.dtsi?$/ && $line =~ /^\+\s*compatible\s*=\s*\"/) ||
- ($realfile =~ /\.[ch]$/ && $line =~ /^\+.*\.compatible\s*=\s*\"/))) {
-
- my @compats = $rawline =~ /\"([a-zA-Z0-9\-\,\.\+_]+)\"/g;
-
- my $dt_path = $root . "/Documentation/devicetree/bindings/";
- my $vp_file = $dt_path . "vendor-prefixes.txt";
-
- foreach my $compat (@compats) {
- my $compat2 = $compat;
- $compat2 =~ s/\,[a-zA-Z0-9]*\-/\,<\.\*>\-/;
- my $compat3 = $compat;
- $compat3 =~ s/\,([a-z]*)[0-9]*\-/\,$1<\.\*>\-/;
- `grep -Erq "$compat|$compat2|$compat3" $dt_path`;
- if ( $? >> 8 ) {
- WARN("UNDOCUMENTED_DT_STRING",
- "DT compatible string \"$compat\" appears un-documented -- check $dt_path\n" . $herecurr);
- }
-
- next if $compat !~ /^([a-zA-Z0-9\-]+)\,/;
- my $vendor = $1;
- `grep -Eq "^$vendor\\b" $vp_file`;
- if ( $? >> 8 ) {
- WARN("UNDOCUMENTED_DT_STRING",
- "DT compatible string vendor \"$vendor\" appears un-documented -- check $vp_file\n" . $herecurr);
- }
- }
- }
-
# check we are in a valid source file if not then ignore this hunk
next if ($realfile !~ /\.(h|c|s|S|pl|sh)$/);
}
# Check for user-visible strings broken across lines, which breaks the ability
-# to grep for the string. Make exceptions when the previous string ends in a
-# newline (multiple lines in one string constant) or '\t', '\r', ';', or '{'
-# (common in inline assembly) or is a octal \123 or hexadecimal \xaf value
+# to grep for the string. Limited to strings used as parameters (those
+# following an open parenthesis), which almost completely eliminates false
+# positives, as well as warning only once per parameter rather than once per
+# line of the string. Make an exception when the previous string ends in a
+# newline (multiple lines in one string constant) or \n\t (common in inline
+# assembly to indent the instruction on the following line).
if ($line =~ /^\+\s*"/ &&
$prevline =~ /"\s*$/ &&
- $prevrawline !~ /(?:\\(?:[ntr]|[0-7]{1,3}|x[0-9a-fA-F]{1,2})|;\s*|\{\s*)"\s*$/) {
+ $prevline =~ /\(/ &&
+ $prevrawline !~ /\\n(?:\\t)*"\s*$/) {
WARN("SPLIT_STRING",
"quoted string split across lines\n" . $hereprev);
}
# check for spaces before a quoted newline
if ($rawline =~ /^.*\".*\s\\n/) {
- if (WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
- "unnecessary whitespace before a quoted newline\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/^(\+.*\".*)\s+\\n/$1\\n/;
- }
-
+ WARN("QUOTED_WHITESPACE_BEFORE_NEWLINE",
+ "unnecessary whitespace before a quoted newline\n" . $herecurr);
}
# check for adding lines without a newline.
if ($rawline =~ /^\+\s* \t\s*\S/ ||
$rawline =~ /^\+\s* \s*/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
+ ERROR("CODE_INDENT",
+ "code indent should use tabs where possible\n" . $herevet);
$rpt_cleaners = 1;
- if (ERROR("CODE_INDENT",
- "code indent should use tabs where possible\n" . $herevet) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
- }
}
# check for space before tabs.
if ($rawline =~ /^\+/ && $rawline =~ / \t/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- if (WARN("SPACE_BEFORE_TAB",
- "please, no space before tabs\n" . $herevet) &&
- $fix) {
- while ($fixed[$linenr - 1] =~
- s/(^\+.*) {8,8}+\t/$1\t\t/) {}
- while ($fixed[$linenr - 1] =~
- s/(^\+.*) +\t/$1\t/) {}
- }
+ WARN("SPACE_BEFORE_TAB",
+ "please, no space before tabs\n" . $herevet);
}
# check for && or || at the start of a line
# check multi-line statement indentation matches previous line
if ($^V && $^V ge 5.10.0 &&
- $prevline =~ /^\+([ \t]*)((?:$c90_Keywords(?:\s+if)\s*)|(?:$Declare\s*)?(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*|$Ident\s*=\s*$Ident\s*)\(.*(\&\&|\|\||,)\s*$/) {
+ $prevline =~ /^\+(\t*)(if \(|$Ident\().*(\&\&|\|\||,)\s*$/) {
$prevline =~ /^\+(\t*)(.*)$/;
my $oldindent = $1;
my $rest = $2;
if ($newindent ne $goodtabindent &&
$newindent ne $goodspaceindent) {
-
- if (CHK("PARENTHESIS_ALIGNMENT",
- "Alignment should match open parenthesis\n" . $hereprev) &&
- $fix && $line =~ /^\+/) {
- $fixed[$linenr - 1] =~
- s/^\+[ \t]*/\+$goodtabindent/;
- }
+ CHK("PARENTHESIS_ALIGNMENT",
+ "Alignment should match open parenthesis\n" . $hereprev);
}
}
}
- if ($line =~ /^\+.*\*[ \t]*\)[ \t]+(?!$Assignment|$Arithmetic)/) {
- if (CHK("SPACING",
- "No space is necessary after a cast\n" . $hereprev) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/^(\+.*\*[ \t]*\))[ \t]+/$1/;
- }
+ if ($line =~ /^\+.*\*[ \t]*\)[ \t]+/) {
+ CHK("SPACING",
+ "No space is necessary after a cast\n" . $hereprev);
}
if ($realfile =~ m@^(drivers/net/|net/)@ &&
- $prevrawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
- $rawline =~ /^\+[ \t]*\*/ &&
- $realline > 2) {
+ $rawline =~ /^\+[ \t]*\/\*[ \t]*$/ &&
+ $prevrawline =~ /^\+[ \t]*$/) {
WARN("NETWORKING_BLOCK_COMMENT_STYLE",
"networking block comments don't use an empty /* line, use /* Comment...\n" . $hereprev);
}
- if ($realfile =~ m@^(drivers/net/|net/)@ &&
- $prevrawline =~ /^\+[ \t]*\/\*/ && #starting /*
- $prevrawline !~ /\*\/[ \t]*$/ && #no trailing */
- $rawline =~ /^\+/ && #line is new
- $rawline !~ /^\+[ \t]*\*/) { #no leading *
- WARN("NETWORKING_BLOCK_COMMENT_STYLE",
- "networking block comments start with * on subsequent lines\n" . $hereprev);
- }
-
if ($realfile =~ m@^(drivers/net/|net/)@ &&
$rawline !~ m@^\+[ \t]*\*/[ \t]*$@ && #trailing */
$rawline !~ m@^\+.*/\*.*\*/[ \t]*$@ && #inline /*...*/
"networking block comments put the trailing */ on a separate line\n" . $herecurr);
}
-# check for missing blank lines after declarations
- if ($sline =~ /^\+\s+\S/ && #Not at char 1
- # actual declarations
- ($prevline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
- # foo bar; where foo is some local typedef or #define
- $prevline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
- # known declaration macros
- $prevline =~ /^\+\s+$declaration_macros/) &&
- # for "else if" which can look like "$Ident $Ident"
- !($prevline =~ /^\+\s+$c90_Keywords\b/ ||
- # other possible extensions of declaration lines
- $prevline =~ /(?:$Compare|$Assignment|$Operators)\s*$/ ||
- # not starting a section or a macro "\" extended line
- $prevline =~ /(?:\{\s*|\\)$/) &&
- # looks like a declaration
- !($sline =~ /^\+\s+$Declare\s*$Ident\s*[=,;:\[]/ ||
- # foo bar; where foo is some local typedef or #define
- $sline =~ /^\+\s+$Ident(?:\s+|\s*\*\s*)$Ident\s*[=,;\[]/ ||
- # known declaration macros
- $sline =~ /^\+\s+$declaration_macros/ ||
- # start of struct or union or enum
- $sline =~ /^\+\s+(?:union|struct|enum|typedef)\b/ ||
- # start or end of block or continuation of declaration
- $sline =~ /^\+\s+(?:$|[\{\}\.\#\"\?\:\(\[])/ ||
- # bitfield continuation
- $sline =~ /^\+\s+$Ident\s*:\s*\d+\s*[,;]/ ||
- # other possible extensions of declaration lines
- $sline =~ /^\+\s+\(?\s*(?:$Compare|$Assignment|$Operators)/) &&
- # indentation of previous and current line are the same
- (($prevline =~ /\+(\s+)\S/) && $sline =~ /^\+$1\S/)) {
- WARN("SPACING",
- "Missing a blank line after declarations\n" . $hereprev);
- }
-
# check for spaces at the beginning of a line.
# Exceptions:
# 1) within comments
# 2) indented preprocessor commands
# 3) hanging labels
- if ($rawline =~ /^\+ / && $line !~ /^\+ *(?:$;|#|$Ident:)/) {
+ if ($rawline =~ /^\+ / && $line !~ /\+ *(?:$;|#|$Ident:)/) {
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
- if (WARN("LEADING_SPACE",
- "please, no spaces at the start of a line\n" . $herevet) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/^\+([ \t]+)/"\+" . tabify($1)/e;
- }
+ WARN("LEADING_SPACE",
+ "please, no spaces at the start of a line\n" . $herevet);
}
# check we are in a valid C source file if not then ignore this hunk
$realline_next);
#print "LINE<$line>\n";
if ($linenr >= $suppress_statement &&
- $realcnt && $sline =~ /.\s*\S/) {
+ $realcnt && $line =~ /.\s*\S/) {
($stat, $cond, $line_nr_next, $remain_next, $off_next) =
ctx_statement_block($linenr, $realcnt, 0);
$stat =~ s/\n./\n /g;
$prev_values = substr($curr_values, -1);
#ignore lines not being added
- next if ($line =~ /^[^\+]/);
+ if ($line=~/^[^\+]/) {next;}
# TEST: allow direct testing of the type matcher.
if ($dbg_type) {
# no C99 // comments
if ($line =~ m{//}) {
- if (ERROR("C99_COMMENTS",
- "do not use C99 // comments\n" . $herecurr) &&
- $fix) {
- my $line = $fixed[$linenr - 1];
- if ($line =~ /\/\/(.*)$/) {
- my $comment = trim($1);
- $fixed[$linenr - 1] =~ s@\/\/(.*)$@/\* $comment \*/@;
- }
- }
+ ERROR("C99_COMMENTS",
+ "do not use C99 // comments\n" . $herecurr);
}
# Remove C99 comments.
$line =~ s@//.*@@;
}
# check for global initialisers.
- if ($line =~ /^\+(\s*$Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/) {
- if (ERROR("GLOBAL_INITIALISERS",
- "do not initialise globals to 0 or NULL\n" .
- $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/($Type\s*$Ident\s*(?:\s+$Modifier))*\s*=\s*(0|NULL|false)\s*;/$1;/;
- }
+ if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
+ ERROR("GLOBAL_INITIALISERS",
+ "do not initialise globals to 0 or NULL\n" .
+ $herecurr);
}
# check for static initialisers.
- if ($line =~ /^\+.*\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
- if (ERROR("INITIALISED_STATIC",
- "do not initialise statics to 0 or NULL\n" .
- $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/(\bstatic\s.*?)\s*=\s*(0|NULL|false)\s*;/$1;/;
- }
+ if ($line =~ /\bstatic\s.*=\s*(0|NULL|false)\s*;/) {
+ ERROR("INITIALISED_STATIC",
+ "do not initialise statics to 0 or NULL\n" .
+ $herecurr);
}
# check for static const char * arrays.
$herecurr);
}
-# check for non-global char *foo[] = {"bar", ...} declarations.
- if ($line =~ /^.\s+(?:static\s+|const\s+)?char\s+\*\s*\w+\s*\[\s*\]\s*=\s*\{/) {
- WARN("STATIC_CONST_CHAR_ARRAY",
- "char * array declaration might be better as static const\n" .
- $herecurr);
- }
-
-# check for function declarations without arguments like "int foo()"
- if ($line =~ /(\b$Type\s+$Ident)\s*\(\s*\)/) {
- if (ERROR("FUNCTION_WITHOUT_ARGS",
- "Bad function definition - $1() should probably be $1(void)\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/(\b($Type)\s+($Ident))\s*\(\s*\)/$2 $3(void)/;
- }
- }
-
-# check for uses of DEFINE_PCI_DEVICE_TABLE
- if ($line =~ /\bDEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=/) {
- if (WARN("DEFINE_PCI_DEVICE_TABLE",
- "Prefer struct pci_device_id over deprecated DEFINE_PCI_DEVICE_TABLE\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\b(?:static\s+|)DEFINE_PCI_DEVICE_TABLE\s*\(\s*(\w+)\s*\)\s*=\s*/static const struct pci_device_id $1\[\] = /;
- }
+# check for declarations of struct pci_device_id
+ if ($line =~ /\bstruct\s+pci_device_id\s+\w+\s*\[\s*\]\s*\=\s*\{/) {
+ WARN("DEFINE_PCI_DEVICE_TABLE",
+ "Use DEFINE_PCI_DEVICE_TABLE for struct pci_device_id\n" . $herecurr);
}
# check for new typedefs, only function parameters and sparse annotations
# (char*[ const])
while ($line =~ m{(\($NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)\))}g) {
#print "AA<$1>\n";
- my ($ident, $from, $to) = ($1, $2, $2);
+ my ($from, $to) = ($2, $2);
# Should start with a space.
$to =~ s/^(\S)/ $1/;
while ($to =~ s/\*\s+\*/\*\*/) {
}
-## print "1: from<$from> to<$to> ident<$ident>\n";
+ #print "from<$from> to<$to>\n";
if ($from ne $to) {
- if (ERROR("POINTER_LOCATION",
- "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr) &&
- $fix) {
- my $sub_from = $ident;
- my $sub_to = $ident;
- $sub_to =~ s/\Q$from\E/$to/;
- $fixed[$linenr - 1] =~
- s@\Q$sub_from\E@$sub_to@;
- }
+ ERROR("POINTER_LOCATION",
+ "\"(foo$from)\" should be \"(foo$to)\"\n" . $herecurr);
}
}
while ($line =~ m{(\b$NonptrType(\s*(?:$Modifier\b\s*|\*\s*)+)($Ident))}g) {
#print "BB<$1>\n";
- my ($match, $from, $to, $ident) = ($1, $2, $2, $3);
+ my ($from, $to, $ident) = ($2, $2, $3);
# Should start with a space.
$to =~ s/^(\S)/ $1/;
# Modifiers should have spaces.
$to =~ s/(\b$Modifier$)/$1 /;
-## print "2: from<$from> to<$to> ident<$ident>\n";
+ #print "from<$from> to<$to> ident<$ident>\n";
if ($from ne $to && $ident !~ /^$Modifier$/) {
- if (ERROR("POINTER_LOCATION",
- "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr) &&
- $fix) {
-
- my $sub_from = $match;
- my $sub_to = $match;
- $sub_to =~ s/\Q$from\E/$to/;
- $fixed[$linenr - 1] =~
- s@\Q$sub_from\E@$sub_to@;
- }
+ ERROR("POINTER_LOCATION",
+ "\"foo${from}bar\" should be \"foo${to}bar\"\n" . $herecurr);
}
}
my $level2 = $level;
$level2 = "dbg" if ($level eq "debug");
WARN("PREFER_PR_LEVEL",
- "Prefer [subsystem eg: netdev]_$level2([subsystem]dev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
+ "Prefer netdev_$level2(netdev, ... then dev_$level2(dev, ... then pr_$level(... to printk(KERN_$orig ...\n" . $herecurr);
}
if ($line =~ /\bpr_warning\s*\(/) {
- if (WARN("PREFER_PR_LEVEL",
- "Prefer pr_warn(... to pr_warning(...\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\bpr_warning\b/pr_warn/;
- }
+ WARN("PREFER_PR_LEVEL",
+ "Prefer pr_warn(... to pr_warning(...\n" . $herecurr);
}
if ($line =~ /\bdev_printk\s*\(\s*KERN_([A-Z]+)/) {
}
# missing space after union, struct or enum definition
- if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident){1,2}[=\{]/) {
- if (WARN("SPACING",
- "missing space after $1 definition\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/^(.\s*(?:typedef\s+)?(?:enum|union|struct)(?:\s+$Ident){1,2})([=\{])/$1 $2/;
- }
- }
-
-# Function pointer declarations
-# check spacing between type, funcptr, and args
-# canonical declaration is "type (*funcptr)(args...)"
- if ($line =~ /^.\s*($Declare)\((\s*)\*(\s*)($Ident)(\s*)\)(\s*)\(/) {
- my $declare = $1;
- my $pre_pointer_space = $2;
- my $post_pointer_space = $3;
- my $funcname = $4;
- my $post_funcname_space = $5;
- my $pre_args_space = $6;
-
-# the $Declare variable will capture all spaces after the type
-# so check it for a missing trailing missing space but pointer return types
-# don't need a space so don't warn for those.
- my $post_declare_space = "";
- if ($declare =~ /(\s+)$/) {
- $post_declare_space = $1;
- $declare = rtrim($declare);
- }
- if ($declare !~ /\*$/ && $post_declare_space =~ /^$/) {
- WARN("SPACING",
- "missing space after return type\n" . $herecurr);
- $post_declare_space = " ";
- }
-
-# unnecessary space "type (*funcptr)(args...)"
-# This test is not currently implemented because these declarations are
-# equivalent to
-# int foo(int bar, ...)
-# and this is form shouldn't/doesn't generate a checkpatch warning.
-#
-# elsif ($declare =~ /\s{2,}$/) {
-# WARN("SPACING",
-# "Multiple spaces after return type\n" . $herecurr);
-# }
-
-# unnecessary space "type ( *funcptr)(args...)"
- if (defined $pre_pointer_space &&
- $pre_pointer_space =~ /^\s/) {
- WARN("SPACING",
- "Unnecessary space after function pointer open parenthesis\n" . $herecurr);
- }
-
-# unnecessary space "type (* funcptr)(args...)"
- if (defined $post_pointer_space &&
- $post_pointer_space =~ /^\s/) {
- WARN("SPACING",
- "Unnecessary space before function pointer name\n" . $herecurr);
- }
-
-# unnecessary space "type (*funcptr )(args...)"
- if (defined $post_funcname_space &&
- $post_funcname_space =~ /^\s/) {
- WARN("SPACING",
- "Unnecessary space after function pointer name\n" . $herecurr);
- }
-
-# unnecessary space "type (*funcptr) (args...)"
- if (defined $pre_args_space &&
- $pre_args_space =~ /^\s/) {
- WARN("SPACING",
- "Unnecessary space before function pointer arguments\n" . $herecurr);
- }
-
- if (show_type("SPACING") && $fix) {
- $fixed[$linenr - 1] =~
- s/^(.\s*)$Declare\s*\(\s*\*\s*$Ident\s*\)\s*\(/$1 . $declare . $post_declare_space . '(*' . $funcname . ')('/ex;
- }
+ if ($line =~ /^.\s*(?:typedef\s+)?(enum|union|struct)(?:\s+$Ident)?(?:\s+$Ident)?[=\{]/) {
+ WARN("SPACING",
+ "missing space after $1 definition\n" . $herecurr);
}
# check for spacing round square brackets; allowed:
if ($prefix !~ /$Type\s+$/ &&
($where != 0 || $prefix !~ /^.\s+$/) &&
$prefix !~ /[{,]\s+$/) {
- if (ERROR("BRACKET_SPACE",
- "space prohibited before open square bracket '['\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/^(\+.*?)\s+\[/$1\[/;
- }
+ ERROR("BRACKET_SPACE",
+ "space prohibited before open square bracket '['\n" . $herecurr);
}
}
__attribute__|format|__extension__|
asm|__asm__)$/x)
{
+
# cpp #define statements have non-optional spaces, ie
# if there is a space between the name and the open
# parenthesis it is simply not a parameter group.
} elsif ($ctx =~ /$Type$/) {
} else {
- if (WARN("SPACING",
- "space prohibited between function name and open parenthesis '('\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\b$name\s+\(/$name\(/;
- }
+ WARN("SPACING",
+ "space prohibited between function name and open parenthesis '('\n" . $herecurr);
}
}
+# check for whitespace before a non-naked semicolon
+ if ($line =~ /^\+.*\S\s+;/) {
+ WARN("SPACING",
+ "space prohibited before semicolon\n" . $herecurr);
+ }
+
# Check operator spacing.
if (!($line=~/\#\s*include/)) {
- my $fixed_line = "";
- my $line_fixed = 0;
-
my $ops = qr{
<<=|>>=|<=|>=|==|!=|
\+=|-=|\*=|\/=|%=|\^=|\|=|&=|
=>|->|<<|>>|<|>|=|!|~|
&&|\|\||,|\^|\+\+|--|&|\||\+|-|\*|\/|%|
- \?:|\?|:
+ \?|:
}x;
my @elements = split(/($ops|;)/, $opline);
-
-## print("element count: <" . $#elements . ">\n");
-## foreach my $el (@elements) {
-## print("el: <$el>\n");
-## }
-
- my @fix_elements = ();
my $off = 0;
- foreach my $el (@elements) {
- push(@fix_elements, substr($rawline, $off, length($el)));
- $off += length($el);
- }
-
- $off = 0;
-
my $blank = copy_spacing($opline);
- my $last_after = -1;
for (my $n = 0; $n < $#elements; $n += 2) {
-
- my $good = $fix_elements[$n] . $fix_elements[$n + 1];
-
-## print("n: <$n> good: <$good>\n");
-
$off += length($elements[$n]);
# Pick up the preceding and succeeding characters.
} elsif ($op eq ';') {
if ($ctx !~ /.x[WEBC]/ &&
$cc !~ /^\\/ && $cc !~ /^;/) {
- if (ERROR("SPACING",
- "space required after that '$op' $at\n" . $hereptr)) {
- $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "space required after that '$op' $at\n" . $hereptr);
}
# // is a comment
} elsif ($op eq '//') {
- # : when part of a bitfield
- } elsif ($opv eq ':B') {
- # skip the bitfield test for now
-
# No spaces for:
# ->
- } elsif ($op eq '->') {
+ # : when part of a bitfield
+ } elsif ($op eq '->' || $opv eq ':B') {
if ($ctx =~ /Wx.|.xW/) {
- if (ERROR("SPACING",
- "spaces prohibited around that '$op' $at\n" . $hereptr)) {
- $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
- if (defined $fix_elements[$n + 2]) {
- $fix_elements[$n + 2] =~ s/^\s+//;
- }
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "spaces prohibited around that '$op' $at\n" . $hereptr);
}
# , must have a space on the right.
} elsif ($op eq ',') {
if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
- if (ERROR("SPACING",
- "space required after that '$op' $at\n" . $hereptr)) {
- $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
- $line_fixed = 1;
- $last_after = $n;
- }
+ ERROR("SPACING",
+ "space required after that '$op' $at\n" . $hereptr);
}
# '*' as part of a type definition -- reported already.
$opv eq '*U' || $opv eq '-U' ||
$opv eq '&U' || $opv eq '&&U') {
if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
- if (ERROR("SPACING",
- "space required before that '$op' $at\n" . $hereptr)) {
- if ($n != $last_after + 2) {
- $good = $fix_elements[$n] . " " . ltrim($fix_elements[$n + 1]);
- $line_fixed = 1;
- }
- }
+ ERROR("SPACING",
+ "space required before that '$op' $at\n" . $hereptr);
}
if ($op eq '*' && $cc =~/\s*$Modifier\b/) {
# A unary '*' may be const
} elsif ($ctx =~ /.xW/) {
- if (ERROR("SPACING",
- "space prohibited after that '$op' $at\n" . $hereptr)) {
- $good = $fix_elements[$n] . rtrim($fix_elements[$n + 1]);
- if (defined $fix_elements[$n + 2]) {
- $fix_elements[$n + 2] =~ s/^\s+//;
- }
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "space prohibited after that '$op' $at\n" . $hereptr);
}
# unary ++ and unary -- are allowed no space on one side.
} elsif ($op eq '++' or $op eq '--') {
if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
- if (ERROR("SPACING",
- "space required one side of that '$op' $at\n" . $hereptr)) {
- $good = $fix_elements[$n] . trim($fix_elements[$n + 1]) . " ";
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "space required one side of that '$op' $at\n" . $hereptr);
}
if ($ctx =~ /Wx[BE]/ ||
($ctx =~ /Wx./ && $cc =~ /^;/)) {
- if (ERROR("SPACING",
- "space prohibited before that '$op' $at\n" . $hereptr)) {
- $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "space prohibited before that '$op' $at\n" . $hereptr);
}
if ($ctx =~ /ExW/) {
- if (ERROR("SPACING",
- "space prohibited after that '$op' $at\n" . $hereptr)) {
- $good = $fix_elements[$n] . trim($fix_elements[$n + 1]);
- if (defined $fix_elements[$n + 2]) {
- $fix_elements[$n + 2] =~ s/^\s+//;
- }
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "space prohibited after that '$op' $at\n" . $hereptr);
}
+
# << and >> may either have or not have spaces both sides
} elsif ($op eq '<<' or $op eq '>>' or
$op eq '&' or $op eq '^' or $op eq '|' or
$op eq '%')
{
if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
- if (ERROR("SPACING",
- "need consistent spacing around '$op' $at\n" . $hereptr)) {
- $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
- if (defined $fix_elements[$n + 2]) {
- $fix_elements[$n + 2] =~ s/^\s+//;
- }
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "need consistent spacing around '$op' $at\n" .
+ $hereptr);
}
# A colon needs no spaces before when it is
# terminating a case value or a label.
} elsif ($opv eq ':C' || $opv eq ':L') {
if ($ctx =~ /Wx./) {
- if (ERROR("SPACING",
- "space prohibited before that '$op' $at\n" . $hereptr)) {
- $good = rtrim($fix_elements[$n]) . trim($fix_elements[$n + 1]);
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "space prohibited before that '$op' $at\n" . $hereptr);
}
# All the others need spaces both sides.
$ok = 1;
}
- # messages are ERROR, but ?: are CHK
+ # Ignore ?:
+ if (($opv eq ':O' && $ca =~ /\?$/) ||
+ ($op eq '?' && $cc =~ /^:/)) {
+ $ok = 1;
+ }
+
if ($ok == 0) {
- my $msg_type = \&ERROR;
- $msg_type = \&CHK if (($op eq '?:' || $op eq '?' || $op eq ':') && $ctx =~ /VxV/);
-
- if (&{$msg_type}("SPACING",
- "spaces required around that '$op' $at\n" . $hereptr)) {
- $good = rtrim($fix_elements[$n]) . " " . trim($fix_elements[$n + 1]) . " ";
- if (defined $fix_elements[$n + 2]) {
- $fix_elements[$n + 2] =~ s/^\s+//;
- }
- $line_fixed = 1;
- }
+ ERROR("SPACING",
+ "spaces required around that '$op' $at\n" . $hereptr);
}
}
$off += length($elements[$n + 1]);
-
-## print("n: <$n> GOOD: <$good>\n");
-
- $fixed_line = $fixed_line . $good;
- }
-
- if (($#elements % 2) == 0) {
- $fixed_line = $fixed_line . $fix_elements[$#elements];
- }
-
- if ($fix && $line_fixed && $fixed_line ne $fixed[$linenr - 1]) {
- $fixed[$linenr - 1] = $fixed_line;
- }
-
-
- }
-
-# check for whitespace before a non-naked semicolon
- if ($line =~ /^\+.*\S\s+;\s*$/) {
- if (WARN("SPACING",
- "space prohibited before semicolon\n" . $herecurr) &&
- $fix) {
- 1 while $fixed[$linenr - 1] =~
- s/^(\+.*\S)\s+;/$1;/;
}
}
#need space before brace following if, while, etc
if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
$line =~ /do{/) {
- if (ERROR("SPACING",
- "space required before the open brace '{'\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/^(\+.*(?:do|\))){/$1 {/;
- }
+ ERROR("SPACING",
+ "space required before the open brace '{'\n" . $herecurr);
}
-## # check for blank lines before declarations
-## if ($line =~ /^.\t+$Type\s+$Ident(?:\s*=.*)?;/ &&
-## $prevrawline =~ /^.\s*$/) {
-## WARN("SPACING",
-## "No blank lines before declarations\n" . $hereprev);
-## }
-##
-
# closing brace should have a space following it when it has anything
# on the line
if ($line =~ /}(?!(?:,|;|\)))\S/) {
- if (ERROR("SPACING",
- "space required after that close brace '}'\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/}((?!(?:,|;|\)))\S)/} $1/;
- }
+ ERROR("SPACING",
+ "space required after that close brace '}'\n" . $herecurr);
}
# check spacing on square brackets
if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
- if (ERROR("SPACING",
- "space prohibited after that open square bracket '['\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\[\s+/\[/;
- }
+ ERROR("SPACING",
+ "space prohibited after that open square bracket '['\n" . $herecurr);
}
if ($line =~ /\s\]/) {
- if (ERROR("SPACING",
- "space prohibited before that close square bracket ']'\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\s+\]/\]/;
- }
+ ERROR("SPACING",
+ "space prohibited before that close square bracket ']'\n" . $herecurr);
}
# check spacing on parentheses
if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
$line !~ /for\s*\(\s+;/) {
- if (ERROR("SPACING",
- "space prohibited after that open parenthesis '('\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\(\s+/\(/;
- }
+ ERROR("SPACING",
+ "space prohibited after that open parenthesis '('\n" . $herecurr);
}
if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
$line !~ /for\s*\(.*;\s+\)/ &&
$line !~ /:\s+\)/) {
- if (ERROR("SPACING",
- "space prohibited before that close parenthesis ')'\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\s+\)/\)/;
- }
+ ERROR("SPACING",
+ "space prohibited before that close parenthesis ')'\n" . $herecurr);
}
#goto labels aren't indented, allow a single space however
if ($line=~/^.\s+[A-Za-z\d_]+:(?![0-9]+)/ and
!($line=~/^. [A-Za-z\d_]+:/) and !($line=~/^.\s+default:/)) {
- if (WARN("INDENTED_LABEL",
- "labels should not be indented\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/^(.)\s+/$1/;
- }
+ WARN("INDENTED_LABEL",
+ "labels should not be indented\n" . $herecurr);
}
-# return is not a function
- if (defined($stat) && $stat =~ /^.\s*return(\s*)\(/s) {
+# Return is not a function.
+ if (defined($stat) && $stat =~ /^.\s*return(\s*)(\(.*);/s) {
my $spacing = $1;
- if ($^V && $^V ge 5.10.0 &&
- $stat =~ /^.\s*return\s*($balanced_parens)\s*;\s*$/) {
- my $value = $1;
- $value = deparenthesize($value);
- if ($value =~ m/^\s*$FuncArg\s*(?:\?|$)/) {
- ERROR("RETURN_PARENTHESES",
- "return is not a function, parentheses are not required\n" . $herecurr);
- }
+ my $value = $2;
+
+ # Flatten any parentheses
+ $value =~ s/\(/ \(/g;
+ $value =~ s/\)/\) /g;
+ while ($value =~ s/\[[^\[\]]*\]/1/ ||
+ $value !~ /(?:$Ident|-?$Constant)\s*
+ $Compare\s*
+ (?:$Ident|-?$Constant)/x &&
+ $value =~ s/\([^\(\)]*\)/1/) {
+ }
+#print "value<$value>\n";
+ if ($value =~ /^\s*(?:$Ident|-?$Constant)\s*$/) {
+ ERROR("RETURN_PARENTHESES",
+ "return is not a function, parentheses are not required\n" . $herecurr);
+
} elsif ($spacing !~ /\s+/) {
ERROR("SPACING",
"space required before the open parenthesis '('\n" . $herecurr);
}
}
-
-# unnecessary return in a void function
-# at end-of-function, with the previous line a single leading tab, then return;
-# and the line before that not a goto label target like "out:"
- if ($sline =~ /^[ \+]}\s*$/ &&
- $prevline =~ /^\+\treturn\s*;\s*$/ &&
- $linenr >= 3 &&
- $lines[$linenr - 3] =~ /^[ +]/ &&
- $lines[$linenr - 3] !~ /^[ +]\s*$Ident\s*:/) {
- WARN("RETURN_VOID",
- "void function return statements are not generally useful\n" . $hereprev);
- }
-
-# if statements using unnecessary parentheses - ie: if ((foo == bar))
- if ($^V && $^V ge 5.10.0 &&
- $line =~ /\bif\s*((?:\(\s*){2,})/) {
- my $openparens = $1;
- my $count = $openparens =~ tr@\(@\(@;
- my $msg = "";
- if ($line =~ /\bif\s*(?:\(\s*){$count,$count}$LvalOrFunc\s*($Compare)\s*$LvalOrFunc(?:\s*\)){$count,$count}/) {
- my $comp = $4; #Not $1 because of $LvalOrFunc
- $msg = " - maybe == should be = ?" if ($comp eq "==");
- WARN("UNNECESSARY_PARENTHESES",
- "Unnecessary parentheses$msg\n" . $herecurr);
- }
- }
-
# Return of what appears to be an errno should normally be -'ve
if ($line =~ /^.\s*return\s*(E[A-Z]*)\s*;/) {
my $name = $1;
}
# Need a space before open parenthesis after if, while etc
- if ($line =~ /\b(if|while|for|switch)\(/) {
- if (ERROR("SPACING",
- "space required before the open parenthesis '('\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/\b(if|while|for|switch)\(/$1 \(/;
- }
+ if ($line=~/\b(if|while|for|switch)\(/) {
+ ERROR("SPACING", "space required before the open parenthesis '('\n" . $herecurr);
}
# Check for illegal assignment in if conditional -- and check for trailing
}
}
if (!defined $suppress_whiletrailers{$linenr} &&
- defined($stat) && defined($cond) &&
$line =~ /\b(?:if|while|for)\s*\(/ && $line !~ /^.\s*#/) {
my ($s, $c) = ($stat, $cond);
}
}
-#Specific variable tests
+#CamelCase
while ($line =~ m{($Constant|$Lval)}g) {
my $var = $1;
-
-#gcc binary extension
- if ($var =~ /^$Binary$/) {
- if (WARN("GCC_BINARY_CONSTANT",
- "Avoid gcc v4.3+ binary constant extension: <$var>\n" . $herecurr) &&
- $fix) {
- my $hexval = sprintf("0x%x", oct($var));
- $fixed[$linenr - 1] =~
- s/\b$var\b/$hexval/;
- }
- }
-
-#CamelCase
- if ($var !~ /^$Constant$/ &&
- $var =~ /[A-Z][a-z]|[a-z][A-Z]/ &&
-#Ignore Page<foo> variants
- $var !~ /^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
-#Ignore SI style variants like nS, mV and dB (ie: max_uV, regulator_min_uA_show)
- $var !~ /^(?:[a-z_]*?)_?[a-z][A-Z](?:_[a-z_]+)?$/) {
- while ($var =~ m{($Ident)}g) {
- my $word = $1;
- next if ($word !~ /[A-Z][a-z]|[a-z][A-Z]/);
- if ($check) {
- seed_camelcase_includes();
- if (!$file && !$camelcase_file_seeded) {
- seed_camelcase_file($realfile);
- $camelcase_file_seeded = 1;
- }
- }
- if (!defined $camelcase{$word}) {
- $camelcase{$word} = 1;
- CHK("CAMELCASE",
- "Avoid CamelCase: <$word>\n" . $herecurr);
- }
- }
+ if ($var !~ /$Constant/ &&
+ $var =~ /[A-Z]\w*[a-z]|[a-z]\w*[A-Z]/ &&
+ $var !~ /"^(?:Clear|Set|TestClear|TestSet|)Page[A-Z]/ &&
+ !defined $camelcase{$var}) {
+ $camelcase{$var} = 1;
+ WARN("CAMELCASE",
+ "Avoid CamelCase: <$var>\n" . $herecurr);
}
}
#no spaces allowed after \ in define
- if ($line =~ /\#\s*define.*\\\s+$/) {
- if (WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
- "Whitespace after \\ makes next lines useless\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\s+$//;
- }
+ if ($line=~/\#\s*define.*\\\s$/) {
+ WARN("WHITESPACE_AFTER_LINE_CONTINUATION",
+ "Whitepspace after \\ makes next lines useless\n" . $herecurr);
}
#warn if <asm/foo.h> is #included and <linux/foo.h> is available (uses RAW line)
if ($dstat ne '' &&
$dstat !~ /^(?:$Ident|-?$Constant),$/ && # 10, // foo(),
$dstat !~ /^(?:$Ident|-?$Constant);$/ && # foo();
- $dstat !~ /^[!~-]?(?:$Lval|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo // foo->bar // foo.bar->baz
+ $dstat !~ /^[!~-]?(?:$Ident|$Constant)$/ && # 10 // foo() // !foo // ~foo // -foo
$dstat !~ /^'X'$/ && # character constants
$dstat !~ /$exceptions/ &&
$dstat !~ /^\.$Ident\s*=/ && # .foo =
$dstat !~ /^for\s*$Constant$/ && # for (...)
$dstat !~ /^for\s*$Constant\s+(?:$Ident|-?$Constant)$/ && # for (...) bar()
$dstat !~ /^do\s*{/ && # do {...
- $dstat !~ /^\({/ && # ({...
- $ctx !~ /^.\s*#\s*define\s+TRACE_(?:SYSTEM|INCLUDE_FILE|INCLUDE_PATH)\b/)
+ $dstat !~ /^\({/) # ({...
{
$ctx =~ s/\n*$//;
my $herectx = $here . "\n";
WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
"do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
}
- } elsif ($dstat =~ /^\+\s*#\s*define\s+$Ident.*;\s*$/) {
- $ctx =~ s/\n*$//;
- my $cnt = statement_rawlines($ctx);
- my $herectx = $here . "\n";
-
- for (my $n = 0; $n < $cnt; $n++) {
- $herectx .= raw_line($linenr, $n) . "\n";
- }
-
- WARN("TRAILING_SEMICOLON",
- "macros should not use a trailing semicolon\n" . "$herectx");
}
}
}
# check for unnecessary blank lines around braces
- if (($line =~ /^.\s*}\s*$/ && $prevrawline =~ /^.\s*$/)) {
+ if (($line =~ /^.\s*}\s*$/ && $prevline =~ /^.\s*$/)) {
CHK("BRACES",
"Blank lines aren't necessary before a close brace '}'\n" . $hereprev);
}
- if (($rawline =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
+ if (($line =~ /^.\s*$/ && $prevline =~ /^..*{\s*$/)) {
CHK("BRACES",
"Blank lines aren't necessary after an open brace '{'\n" . $hereprev);
}
}
}
-# check for bad placement of section $InitAttribute (e.g.: __initdata)
- if ($line =~ /(\b$InitAttribute\b)/) {
- my $attr = $1;
- if ($line =~ /^\+\s*static\s+(?:const\s+)?(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*[=;]/) {
- my $ptr = $1;
- my $var = $2;
- if ((($ptr =~ /\b(union|struct)\s+$attr\b/ &&
- ERROR("MISPLACED_INIT",
- "$attr should be placed after $var\n" . $herecurr)) ||
- ($ptr !~ /\b(union|struct)\s+$attr\b/ &&
- WARN("MISPLACED_INIT",
- "$attr should be placed after $var\n" . $herecurr))) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/(\bstatic\s+(?:const\s+)?)(?:$attr\s+)?($NonptrTypeWithAttr)\s+(?:$attr\s+)?($Ident(?:\[[^]]*\])?)\s*([=;])\s*/"$1" . trim(string_find_replace($2, "\\s*$attr\\s*", " ")) . " " . trim(string_find_replace($3, "\\s*$attr\\s*", "")) . " $attr" . ("$4" eq ";" ? ";" : " = ")/e;
- }
- }
- }
-
-# check for $InitAttributeData (ie: __initdata) with const
- if ($line =~ /\bconst\b/ && $line =~ /($InitAttributeData)/) {
- my $attr = $1;
- $attr =~ /($InitAttributePrefix)(.*)/;
- my $attr_prefix = $1;
- my $attr_type = $2;
- if (ERROR("INIT_ATTRIBUTE",
- "Use of const init definition must use ${attr_prefix}initconst\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/$InitAttributeData/${attr_prefix}initconst/;
- }
- }
-
-# check for $InitAttributeConst (ie: __initconst) without const
- if ($line !~ /\bconst\b/ && $line =~ /($InitAttributeConst)/) {
- my $attr = $1;
- if (ERROR("INIT_ATTRIBUTE",
- "Use of $attr requires a separate use of const\n" . $herecurr) &&
- $fix) {
- my $lead = $fixed[$linenr - 1] =~
- /(^\+\s*(?:static\s+))/;
- $lead = rtrim($1);
- $lead = "$lead " if ($lead !~ /^\+$/);
- $lead = "${lead}const ";
- $fixed[$linenr - 1] =~ s/(^\+\s*(?:static\s+))/$lead/;
- }
- }
-
-# don't use __constant_<foo> functions outside of include/uapi/
- if ($realfile !~ m@^include/uapi/@ &&
- $line =~ /(__constant_(?:htons|ntohs|[bl]e(?:16|32|64)_to_cpu|cpu_to_[bl]e(?:16|32|64)))\s*\(/) {
- my $constant_func = $1;
- my $func = $constant_func;
- $func =~ s/^__constant_//;
- if (WARN("CONSTANT_CONVERSION",
- "$constant_func should be $func\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\b$constant_func\b/$func/g;
- }
- }
-
# prefer usleep_range over udelay
if ($line =~ /\budelay\s*\(\s*(\d+)\s*\)/) {
- my $delay = $1;
# ignore udelay's < 10, however
- if (! ($delay < 10) ) {
+ if (! ($1 < 10) ) {
CHK("USLEEP_RANGE",
- "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $herecurr);
- }
- if ($delay > 2000) {
- WARN("LONG_UDELAY",
- "long udelay - prefer mdelay; see arch/arm/include/asm/delay.h\n" . $herecurr);
+ "usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
}
}
if ($line =~ /\bmsleep\s*\((\d+)\);/) {
if ($1 < 20) {
WARN("MSLEEP",
- "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $herecurr);
+ "msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
}
}
-# check for comparisons of jiffies
- if ($line =~ /\bjiffies\s*$Compare|$Compare\s*jiffies\b/) {
- WARN("JIFFIES_COMPARISON",
- "Comparing jiffies is almost always wrong; prefer time_after, time_before and friends\n" . $herecurr);
- }
-
-# check for comparisons of get_jiffies_64()
- if ($line =~ /\bget_jiffies_64\s*\(\s*\)\s*$Compare|$Compare\s*get_jiffies_64\s*\(\s*\)/) {
- WARN("JIFFIES_COMPARISON",
- "Comparing get_jiffies_64() is almost always wrong; prefer time_after64, time_before64 and friends\n" . $herecurr);
- }
-
# warn about #ifdefs in C files
# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
# print "#ifdef in C files should be avoided\n";
# warn about spacing in #ifdefs
if ($line =~ /^.\s*\#\s*(ifdef|ifndef|elif)\s\s+/) {
- if (ERROR("SPACING",
- "exactly one space required after that #$1\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~
- s/^(.\s*\#\s*(ifdef|ifndef|elif))\s{2,}/$1 /;
- }
-
+ ERROR("SPACING",
+ "exactly one space required after that #$1\n" . $herecurr);
}
# check for spinlock_t definitions without a comment.
# check for memory barriers without a comment.
if ($line =~ /\b(mb|rmb|wmb|read_barrier_depends|smp_mb|smp_rmb|smp_wmb|smp_read_barrier_depends)\(/) {
if (!ctx_has_comment($first_line, $linenr)) {
- WARN("MEMORY_BARRIER",
- "memory barrier without comment\n" . $herecurr);
+ CHK("MEMORY_BARRIER",
+ "memory barrier without comment\n" . $herecurr);
}
}
# check of hardware specific defines
}
# Check for __inline__ and __inline, prefer inline
- if ($realfile !~ m@\binclude/uapi/@ &&
- $line =~ /\b(__inline__|__inline)\b/) {
- if (WARN("INLINE",
- "plain inline is preferred over $1\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\b(__inline__|__inline)\b/inline/;
-
- }
+ if ($line =~ /\b(__inline__|__inline)\b/) {
+ WARN("INLINE",
+ "plain inline is preferred over $1\n" . $herecurr);
}
# Check for __attribute__ packed, prefer __packed
- if ($realfile !~ m@\binclude/uapi/@ &&
- $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
+ if ($line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {
WARN("PREFER_PACKED",
"__packed is preferred over __attribute__((packed))\n" . $herecurr);
}
# Check for __attribute__ aligned, prefer __aligned
- if ($realfile !~ m@\binclude/uapi/@ &&
- $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
+ if ($line =~ /\b__attribute__\s*\(\s*\(.*aligned/) {
WARN("PREFER_ALIGNED",
"__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr);
}
# Check for __attribute__ format(printf, prefer __printf
- if ($realfile !~ m@\binclude/uapi/@ &&
- $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
- if (WARN("PREFER_PRINTF",
- "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex;
-
- }
+ if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) {
+ WARN("PREFER_PRINTF",
+ "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr);
}
# Check for __attribute__ format(scanf, prefer __scanf
- if ($realfile !~ m@\binclude/uapi/@ &&
- $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
- if (WARN("PREFER_SCANF",
- "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex;
- }
+ if ($line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) {
+ WARN("PREFER_SCANF",
+ "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr);
}
# check for sizeof(&)
# check for sizeof without parenthesis
if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {
- if (WARN("SIZEOF_PARENTHESIS",
- "sizeof $1 should be sizeof($1)\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;
- }
+ WARN("SIZEOF_PARENTHESIS",
+ "sizeof $1 should be sizeof($1)\n" . $herecurr);
}
# check for line continuations in quoted strings with odd counts of "
}
# check for seq_printf uses that could be seq_puts
- if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {
+ if ($line =~ /\bseq_printf\s*\(/) {
my $fmt = get_quoted_string($line, $rawline);
- if ($fmt ne "" && $fmt !~ /[^\\]\%/) {
- if (WARN("PREFER_SEQ_PUTS",
- "Prefer seq_puts to seq_printf\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\bseq_printf\b/seq_puts/;
- }
+ if ($fmt !~ /[^\\]\%/) {
+ WARN("PREFER_SEQ_PUTS",
+ "Prefer seq_puts to seq_printf\n" . $herecurr);
}
}
}
}
-# Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)
- if ($^V && $^V ge 5.10.0 &&
- $line =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/s) {
- if (WARN("PREFER_ETHER_ADDR_COPY",
- "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;
- }
- }
-
# typecasts on min/max could be min_t/max_t
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
}
}
-# check for naked sscanf
- if ($^V && $^V ge 5.10.0 &&
- defined $stat &&
- $line =~ /\bsscanf\b/ &&
- ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&
- $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&
- $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {
- my $lc = $stat =~ tr@\n@@;
- $lc = $lc + $linenr;
- my $stat_real = raw_line($linenr, 0);
- for (my $count = $linenr + 1; $count <= $lc; $count++) {
- $stat_real = $stat_real . "\n" . raw_line($count, 0);
- }
- WARN("NAKED_SSCANF",
- "unchecked sscanf return value\n" . "$here\n$stat_real\n");
- }
-
-# check for simple sscanf that should be kstrto<foo>
- if ($^V && $^V ge 5.10.0 &&
- defined $stat &&
- $line =~ /\bsscanf\b/) {
- my $lc = $stat =~ tr@\n@@;
- $lc = $lc + $linenr;
- my $stat_real = raw_line($linenr, 0);
- for (my $count = $linenr + 1; $count <= $lc; $count++) {
- $stat_real = $stat_real . "\n" . raw_line($count, 0);
- }
- if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {
- my $format = $6;
- my $count = $format =~ tr@%@%@;
- if ($count == 1 &&
- $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {
- WARN("SSCANF_TO_KSTRTO",
- "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");
- }
- }
- }
-
-# check for new externs in .h files.
- if ($realfile =~ /\.h$/ &&
- $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {
- if (CHK("AVOID_EXTERNS",
- "extern prototypes should be avoided in .h files\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;
- }
- }
-
# check for new externs in .c files.
if ($realfile =~ /\.c$/ && defined $stat &&
$stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)
"unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);
}
-# alloc style
-# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)
- if ($^V && $^V ge 5.10.0 &&
- $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*([kv][mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {
- CHK("ALLOC_SIZEOF_STRUCT",
- "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);
- }
-
-# check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc
- if ($^V && $^V ge 5.10.0 &&
- $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/) {
- my $oldfunc = $3;
- my $a1 = $4;
- my $a2 = $10;
- my $newfunc = "kmalloc_array";
- $newfunc = "kcalloc" if ($oldfunc eq "kzalloc");
- if ($a1 =~ /^sizeof\s*\S/ || $a2 =~ /^sizeof\s*\S/) {
- if (WARN("ALLOC_WITH_MULTIPLY",
- "Prefer $newfunc over $oldfunc with multiply\n" . $herecurr) &&
- $fix) {
- my $r1 = $a1;
- my $r2 = $a2;
- if ($a1 =~ /^sizeof\s*\S/) {
- $r1 = $a2;
- $r2 = $a1;
- }
- $fixed[$linenr - 1] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
-
- }
- }
- }
-
# check for krealloc arg reuse
if ($^V && $^V ge 5.10.0 &&
$line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*\1\s*,/) {
# check for multiple semicolons
if ($line =~ /;\s*;\s*$/) {
- if (WARN("ONE_SEMICOLON",
- "Statements terminations use 1 semicolon\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/(\s*;\s*){2,}$/;/g;
- }
- }
-
-# check for case / default statements not preceeded by break/fallthrough/switch
- if ($line =~ /^.\s*(?:case\s+(?:$Ident|$Constant)\s*|default):/) {
- my $has_break = 0;
- my $has_statement = 0;
- my $count = 0;
- my $prevline = $linenr;
- while ($prevline > 1 && $count < 3 && !$has_break) {
- $prevline--;
- my $rline = $rawlines[$prevline - 1];
- my $fline = $lines[$prevline - 1];
- last if ($fline =~ /^\@\@/);
- next if ($fline =~ /^\-/);
- next if ($fline =~ /^.(?:\s*(?:case\s+(?:$Ident|$Constant)[\s$;]*|default):[\s$;]*)*$/);
- $has_break = 1 if ($rline =~ /fall[\s_-]*(through|thru)/i);
- next if ($fline =~ /^.[\s$;]*$/);
- $has_statement = 1;
- $count++;
- $has_break = 1 if ($fline =~ /\bswitch\b|\b(?:break\s*;[\s$;]*$|return\b|goto\b|continue\b)/);
- }
- if (!$has_break && $has_statement) {
- WARN("MISSING_BREAK",
- "Possible switch case/default not preceeded by break or fallthrough comment\n" . $herecurr);
- }
+ WARN("ONE_SEMICOLON",
+ "Statements terminations use 1 semicolon\n" . $herecurr);
}
# check for switch/default statements without a break;
}
# check for gcc specific __FUNCTION__
- if ($line =~ /\b__FUNCTION__\b/) {
- if (WARN("USE_FUNC",
- "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr) &&
- $fix) {
- $fixed[$linenr - 1] =~ s/\b__FUNCTION__\b/__func__/g;
- }
+ if ($line =~ /__FUNCTION__/) {
+ WARN("USE_FUNC",
+ "__func__ should be used instead of gcc specific __FUNCTION__\n" . $herecurr);
}
# check for use of yield()
"Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n" . $herecurr);
}
-# check for comparisons against true and false
- if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {
- my $lead = $1;
- my $arg = $2;
- my $test = $3;
- my $otype = $4;
- my $trail = $5;
- my $op = "!";
-
- ($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i);
-
- my $type = lc($otype);
- if ($type =~ /^(?:true|false)$/) {
- if (("$test" eq "==" && "$type" eq "true") ||
- ("$test" eq "!=" && "$type" eq "false")) {
- $op = "";
- }
-
- CHK("BOOL_COMPARISON",
- "Using comparison to $otype is error prone\n" . $herecurr);
-
-## maybe suggesting a correct construct would better
-## "Using comparison to $otype is error prone. Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr);
-
- }
- }
-
# check for semaphores initialized locked
if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {
WARN("CONSIDER_COMPLETION",
"$1 is obsolete, use k$3 instead\n" . $herecurr);
}
-# check for __initcall(), use device_initcall() explicitly or more appropriate function please
+# check for __initcall(), use device_initcall() explicitly please
if ($line =~ /^.\s*__initcall\s*\(/) {
WARN("USE_DEVICE_INITCALL",
- "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);
+ "please use device_initcall() instead of __initcall()\n" . $herecurr);
}
# check for various ops structs, ensure they are const.
"usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
}
-# Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.
- if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {
- ERROR("DEFINE_ARCH_HAS",
- "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);
- }
-
# check for %L{u,d,i} in strings
my $string;
while ($line =~ /(?:^|")([X\t]*)(?:"|$)/g) {
WARN("EXPORTED_WORLD_WRITABLE",
"Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);
}
-
-# Mode permission misuses where it seems decimal should be octal
-# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
- if ($^V && $^V ge 5.10.0 &&
- $line =~ /$mode_perms_search/) {
- foreach my $entry (@mode_permission_funcs) {
- my $func = $entry->[0];
- my $arg_pos = $entry->[1];
-
- my $skip_args = "";
- if ($arg_pos > 1) {
- $arg_pos--;
- $skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";
- }
- my $test = "\\b$func\\s*\\(${skip_args}([\\d]+)\\s*[,\\)]";
- if ($line =~ /$test/) {
- my $val = $1;
- $val = $6 if ($skip_args ne "");
-
- if ($val !~ /^0$/ &&
- (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||
- length($val) ne 4)) {
- ERROR("NON_OCTAL_PERMISSIONS",
- "Use 4 digit octal (0777) not decimal permissions\n" . $herecurr);
- }
- }
- }
- }
}
# If we have no input at all, then there is nothing to report on
}
}
- hash_show_words(\%use_type, "Used");
- hash_show_words(\%ignore_type, "Ignored");
-
- if ($clean == 0 && $fix && "@rawlines" ne "@fixed") {
- my $newfile = $filename;
- $newfile .= ".EXPERIMENTAL-checkpatch-fixes" if (!$fix_inplace);
- my $linecount = 0;
- my $f;
-
- open($f, '>', $newfile)
- or die "$P: Can't open $newfile for write\n";
- foreach my $fixed_line (@fixed) {
- $linecount++;
- if ($file) {
- if ($linecount > 3) {
- $fixed_line =~ s/^\+//;
- print $f $fixed_line. "\n";
- }
- } else {
- print $f $fixed_line . "\n";
- }
- }
- close($f);
-
- if (!$quiet) {
- print << "EOM";
-Wrote EXPERIMENTAL --fix correction(s) to '$newfile'
-
-Do _NOT_ trust the results written to this file.
-Do _NOT_ submit these changes without inspecting them for correctness.
-
-This EXPERIMENTAL file is simply a convenience to help rewrite patches.
-No warranties, expressed or implied...
-
-EOM
- }
+ if ($quiet == 0 && keys %ignore_type) {
+ print "NOTE: Ignored message types:";
+ foreach my $ignore (sort keys %ignore_type) {
+ print " $ignore";
+ }
+ print "\n\n";
}
if ($clean == 1 && $quiet == 0) {
if [ "${SRCARCH}" != "um" ]; then
${LD} ${LDFLAGS} ${LDFLAGS_vmlinux} -o ${2} \
-T ${lds} ${KBUILD_VMLINUX_INIT} \
- --start-group \
- ${KBUILD_VMLINUX_MAIN} \
- ${KBUILD_VMLINUX_PIE} \
- --end-group ${1}
+ --start-group ${KBUILD_VMLINUX_MAIN} --end-group ${1}
else
${CC} ${CFLAGS_vmlinux} -o ${2} \
-Wl,-T,${lds} ${KBUILD_VMLINUX_INIT} \
-Wl,--start-group \
${KBUILD_VMLINUX_MAIN} \
- ${KBUILD_VMLINUX_PIE} \
-Wl,--end-group \
-lutil ${1}
rm -f linux
#link vmlinux.o
info LD vmlinux.o
modpost_link vmlinux.o
+
# modpost vmlinux.o to check for section mismatches
${MAKE} -f "${srctree}/scripts/Makefile.modpost" vmlinux.o
-if [ -n "${CONFIG_PIE}" ]; then
- ${MAKE} -f "${srctree}/scripts/Makefile.build" obj=pie
-fi
-
# Update version
info GEN .version
if [ ! -r .version ]; then
source security/tomoyo/Kconfig
source security/apparmor/Kconfig
source security/yama/Kconfig
-source security/tlk_driver/Kconfig
-source security/optee_linuxdriver/Kconfig
source security/integrity/Kconfig
# Object integrity file lists
subdir-$(CONFIG_INTEGRITY) += integrity
obj-$(CONFIG_INTEGRITY) += integrity/built-in.o
-
-obj-y += tlk_driver/
-obj-y += optee_linuxdriver/
source "sound/soc/tegra/Kconfig"
source "sound/soc/txx9/Kconfig"
source "sound/soc/ux500/Kconfig"
-source "sound/soc/rockchip/Kconfig"
# Supported codecs
source "sound/soc/codecs/Kconfig"
obj-$(CONFIG_SND_SOC) += tegra/
obj-$(CONFIG_SND_SOC) += txx9/
obj-$(CONFIG_SND_SOC) += ux500/
-obj-$(CONFIG_SND_SOC) += rockchip/
select SND_SOC_DA9055 if I2C
select SND_SOC_DFBMCS320
select SND_SOC_ISABELLE if I2C
- select SND_SOC_ES8323 if SND_SOC_I2C_AND_SPI
- select SND_SOC_ES8316 if I2C
- select SND_SOC_ES8323_PCM if SND_SOC_I2C_AND_SPI
select SND_SOC_JZ4740_CODEC
select SND_SOC_LM4857 if I2C
select SND_SOC_LM49453 if I2C
select SND_SOC_ML26124 if I2C
select SND_SOC_OMAP_HDMI_CODEC if OMAP4_DSS_HDMI
select SND_SOC_PCM3008
+ select SND_SOC_RT5631 if I2C
select SND_SOC_SGTL5000 if I2C
select SND_SOC_SI476X if MFD_SI476X_CORE
select SND_SOC_SN95031 if INTEL_SCU_IPC
- select SND_SOC_HDMI_I2S
- select SND_SOC_HDMI_SPDIF
-
+ select SND_SOC_SPDIF
select SND_SOC_SSM2602 if SND_SOC_I2C_AND_SPI
select SND_SOC_STA32X if I2C
select SND_SOC_STA529 if I2C
select SND_SOC_TLV320AIC3X if I2C
select SND_SOC_TPA6130A2 if I2C
select SND_SOC_TLV320DAC33 if I2C
- select SND_SOC_TLV320AIC3111 if I2C
select SND_SOC_TWL4030 if TWL4030_CORE
select SND_SOC_TWL6040 if TWL6040_CORE
select SND_SOC_UDA134X
select SND_SOC_WM8782
select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI
select SND_SOC_WM8900 if I2C
- select SND_SOC_RT5621 if I2C
- select SND_SOC_RT5631 if I2C
- select SND_SOC_AK4396 if SPI_MASTER
- select SND_SOC_RT5631_PHONE if I2C
- select SND_SOC_RT5625 if I2C
- select SND_SOC_RT5640 if I2C
- select SND_SOC_RT3261 if I2C
- select SND_SOC_RT3224 if I2C
- select SND_SOC_RT5623 if I2C
- select SND_SOC_RT5639 if I2C
- select SND_SOC_RT5616 if I2C
- select SND_SOC_RT5512 if I2C
- select SND_SOC_RK610 if I2C
- select SND_SOC_RK616 if I2C
- select SND_SOC_RK1000 if I2C
select SND_SOC_WM8903 if I2C && GENERIC_HARDIRQS
select SND_SOC_WM8904 if I2C
select SND_SOC_WM8940 if I2C
config SND_SOC_DMIC
tristate
-config SND_SOC_ES8323
- tristate
-
-config SND_SOC_ES8316
- tristate
-
config SND_SOC_ISABELLE
tristate
config SND_SOC_PCM3008
tristate
-config SND_SOC_RK3036
+config SND_SOC_RT5631
tristate
-config SND_SOC_RK312X
- tristate
-
#Freescale sgtl5000 codec
config SND_SOC_SGTL5000
tristate
config SND_SOC_SN95031
tristate
-config SND_SOC_HDMI_I2S
+config SND_SOC_SPDIF
tristate
-config SND_SOC_HDMI_SPDIF
- tristate
-
-
config SND_SOC_SSM2602
tristate
config SND_SOC_TLV320DAC33
tristate
-config SND_SOC_TLV320AIC3111
- tristate
-
config SND_SOC_TWL4030
select MFD_TWL4030_AUDIO
tristate
config SND_SOC_WM8900
tristate
-config SND_SOC_RT5621
- tristate
-
-config SND_SOC_RT5623
- tristate
-
-config SND_SOC_RT5639
- tristate
-
-config SND_SOC_RT5616
- tristate
-
-config SND_SOC_AK4396
- tristate
-
-config SND_SOC_RT5631
- tristate
-
-config SND_SOC_RT5631_PHONE
- tristate
-
-config SND_SOC_RT5625
- tristate
-
-config SND_SOC_RT5640
- select SND_HWDEP
- tristate
-
-config SND_SOC_RT3224
- select SND_HWDEP
- tristate
-
-config SND_SOC_RT3261
- select SND_HWDEP
- tristate
-
config SND_SOC_WM8903
tristate
config SND_SOC_WM9713
tristate
-config SND_SOC_RK1000
- tristate
-# depends on RK1000_CONTROL
-
-config SND_SOC_RK610
- tristate
- depends on MFD_RK610
-
-config SND_SOC_RK616
- tristate
- depends on MFD_RK616
-
-config SND_SOC_RK1000
- tristate
- depends on MFD_RK1000
-
-config SND_SOC_RK2928
- tristate
- depends on ARCH_RK2928
-
-config SND_SOC_RK3026
- tristate
- depends on ARCH_RK3026
-
-config SND_SOC_RK3190
- tristate
- #depends on ARCH_RK3190
-
-
# Amp
config SND_SOC_LM4857
tristate
snd-soc-ak4641-objs := ak4641.o
snd-soc-ak4642-objs := ak4642.o
snd-soc-ak4671-objs := ak4671.o
-snd-soc-ak4396-objs := ak4396.o
snd-soc-ak5386-objs := ak5386.o
snd-soc-arizona-objs := arizona.o
snd-soc-cq93vc-objs := cq93vc.o
snd-soc-da732x-objs := da732x.o
snd-soc-da9055-objs := da9055.o
snd-soc-dfbmcs320-objs := dfbmcs320.o
-snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-dmic-objs := dmic.o
-snd-soc-es8323-objs := es8323.o
-snd-soc-es8316-objs := es8316.o
-snd-soc-es8323-pcm-objs := es8323_pcm.o
snd-soc-isabelle-objs := isabelle.o
+snd-soc-jz4740-codec-objs := jz4740.o
snd-soc-l3-objs := l3.o
snd-soc-lm4857-objs := lm4857.o
snd-soc-lm49453-objs := lm49453.o
snd-soc-sigmadsp-objs := sigmadsp.o
snd-soc-si476x-objs := si476x.o
snd-soc-sn95031-objs := sn95031.o
-snd-soc-hdmi-i2s-objs := hdmi_i2s.o
-snd-soc-hdmi-spdif-objs := hdmi_spdif.o
+snd-soc-spdif-tx-objs := spdif_transciever.o
+snd-soc-spdif-rx-objs := spdif_receiver.o
snd-soc-ssm2602-objs := ssm2602.o
snd-soc-sta32x-objs := sta32x.o
snd-soc-sta529-objs := sta529.o
snd-soc-tlv320aic26-objs := tlv320aic26.o
snd-soc-tlv320aic3x-objs := tlv320aic3x.o
snd-soc-tlv320aic32x4-objs := tlv320aic32x4.o
-snd-soc-tlv320aic3111-objs := tlv320aic3111.o
snd-soc-tlv320dac33-objs := tlv320dac33.o
snd-soc-twl4030-objs := twl4030.o
snd-soc-twl6040-objs := twl6040.o
snd-soc-wm9712-objs := wm9712.o
snd-soc-wm9713-objs := wm9713.o
snd-soc-wm-hubs-objs := wm_hubs.o
-snd-soc-rt5621-objs := rt5621.o
-snd-soc-rt5623-objs := rt5623.o
-snd-soc-rt5631-objs := rt5631.o
-snd-soc-rt5616-objs := rt5616.o
-snd-soc-rt5631-phone-objs := rt5631_phone.o
-snd-soc-rt5625-objs := rt5625.o
-obj-y := rt56xx_ioctl.o
-snd-soc-rt5639-objs := rt5639.o rt5639_ioctl.o
-snd-soc-rt5640-objs := rt5640.o rt5640-dsp.o rt5640_ioctl.o
-snd-soc-rt3224-objs := rt3261.o rt3261_ioctl.o rt_codec_ioctl.o
-snd-soc-rt3261-objs := rt3261-dsp.o
-snd-soc-cs42l52-objs := cs42l52.o
-snd-soc-rk1000-objs := rk1000_codec.o
-snd-soc-rk3036-objs := rk3036_codec.o
-snd-soc-rk312x-objs := rk312x_codec.o
-snd-soc-rk610-objs := rk610_codec.o
-snd-soc-rk616-objs := rk616_codec.o
-snd-soc-rk2928-objs := rk2928_codec.o
-snd-soc-rk3026-objs := rk3026_codec.o
-snd-soc-rk3190-objs := rk3190_codec.o
-
# Amp
snd-soc-max9877-objs := max9877.o
obj-$(CONFIG_SND_SOC_AK4641) += snd-soc-ak4641.o
obj-$(CONFIG_SND_SOC_AK4642) += snd-soc-ak4642.o
obj-$(CONFIG_SND_SOC_AK4671) += snd-soc-ak4671.o
-obj-$(CONFIG_SND_SOC_AK4396) += snd-soc-ak4396.o
obj-$(CONFIG_SND_SOC_AK5386) += snd-soc-ak5386.o
obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o
obj-$(CONFIG_SND_SOC_ALC5632) += snd-soc-alc5632.o
obj-$(CONFIG_SND_SOC_DA9055) += snd-soc-da9055.o
obj-$(CONFIG_SND_SOC_DFBMCS320) += snd-soc-dfbmcs320.o
obj-$(CONFIG_SND_SOC_DMIC) += snd-soc-dmic.o
-obj-$(CONFIG_SND_SOC_ES8323) += snd-soc-es8323.o
-obj-$(CONFIG_SND_SOC_ES8316) += snd-soc-es8316.o
-obj-$(CONFIG_SND_SOC_ES8323_PCM) += snd-soc-es8323-pcm.o
obj-$(CONFIG_SND_SOC_ISABELLE) += snd-soc-isabelle.o
obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o
obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o
obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_OMAP_HDMI_CODEC) += snd-soc-omap-hdmi-codec.o
obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o
+obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
obj-$(CONFIG_SND_SOC_SI476X) += snd-soc-si476x.o
obj-$(CONFIG_SND_SOC_SN95031) +=snd-soc-sn95031.o
-obj-$(CONFIG_SND_SOC_HDMI_I2S) += snd-soc-hdmi-i2s.o
-obj-$(CONFIG_SND_SOC_HDMI_SPDIF) += snd-soc-hdmi-spdif.o
+obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif-rx.o snd-soc-spdif-tx.o
obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o
obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o
obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o
obj-$(CONFIG_SND_SOC_TLV320AIC26) += snd-soc-tlv320aic26.o
obj-$(CONFIG_SND_SOC_TLV320AIC3X) += snd-soc-tlv320aic3x.o
obj-$(CONFIG_SND_SOC_TLV320AIC32X4) += snd-soc-tlv320aic32x4.o
-obj-$(CONFIG_SND_SOC_TLV320AIC3111) += snd-soc-tlv320aic3111.o
obj-$(CONFIG_SND_SOC_TLV320DAC33) += snd-soc-tlv320dac33.o
obj-$(CONFIG_SND_SOC_TWL4030) += snd-soc-twl4030.o
obj-$(CONFIG_SND_SOC_TWL6040) += snd-soc-twl6040.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
-obj-$(CONFIG_SND_SOC_RT5512) += snd-soc-rt5512.o
-obj-$(CONFIG_SND_SOC_RT5621) += snd-soc-rt5621.o
-obj-$(CONFIG_SND_SOC_RT5623) += snd-soc-rt5623.o
-obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
-obj-$(CONFIG_SND_SOC_RT5616) += snd-soc-rt5616.o
-obj-$(CONFIG_SND_SOC_RT5631_PHONE) += snd-soc-rt5631-phone.o
-obj-$(CONFIG_SND_SOC_RT5625) += snd-soc-rt5625.o
-obj-$(CONFIG_SND_SOC_RT3261) += snd-soc-rt3261.o
-obj-$(CONFIG_SND_SOC_RT3224) += snd-soc-rt3224.o
-obj-$(CONFIG_SND_SOC_RT5639) += snd-soc-rt5639.o
-obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
-obj-$(CONFIG_SND_SOC_CS42L52) += snd-soc-cs42l52.o
-obj-$(CONFIG_SND_SOC_RK1000) += snd-soc-rk1000.o
-obj-$(CONFIG_SND_SOC_RK3036) += snd-soc-rk3036.o
-obj-$(CONFIG_SND_SOC_RK312X) += snd-soc-rk312x.o
-obj-$(CONFIG_SND_SOC_RK610) += snd-soc-rk610.o
-obj-$(CONFIG_SND_SOC_RK616) += snd-soc-rk616.o
-obj-$(CONFIG_SND_SOC_RK2928) += snd-soc-rk2928.o
-obj-$(CONFIG_SND_SOC_RK3026) += snd-soc-rk3026.o
-obj-$(CONFIG_SND_SOC_RK3190) += snd-soc-rk3190.o
# Amp
obj-$(CONFIG_SND_SOC_MAX9877) += snd-soc-max9877.o
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/spi/spi.h>
+#include <linux/regmap.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>
#include <sound/tlv.h>
-#include "rt5631.h"
-#include <linux/timer.h>
-
-#if 0
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-/*
-1.0.25
- add support sample rate up to 192k
-1.0.26
- add support kernel3.10
-*/
-#define RT5631_VERSION "0.01 alsa 1.0.26"
-#define RT5631_ALC_DAC_FUNC_ENA 0 //ALC functio for DAC
-#define RT5631_ALC_ADC_FUNC_ENA 0 //ALC function for ADC
-#define RT5631_SPK_TIMER 0 //if enable this, MUST enable RT5631_EQ_FUNC_ENA first!
+#include "rt5631.h"
struct rt5631_priv {
+ struct regmap *regmap;
int codec_version;
int master;
int sysclk;
+ int rx_rate;
+ int bclk_rate;
int dmic_used_flag;
- int eq_mode;
- int phone_det_level;
- int pll_used_flag;
};
-#if (RT5631_SPK_TIMER == 1)
-static struct timer_list spk_timer;
-struct work_struct spk_work;
-//static bool last_is_spk = false; // need modify.
-static int last_is_spk = -1; //bard 9-13
-#endif
-
-static struct snd_soc_codec *rt5631_codec = NULL;
-struct delayed_work rt5631_delay_cap; //bard 7-16
-EXPORT_SYMBOL(rt5631_delay_cap); //bard 7-16
-static const u16 rt5631_reg[0x80];
-static int timesofbclk = 32;
-bool isPlaybackon = false, isCaptureon = false;
-
-module_param(timesofbclk, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-MODULE_PARM_DESC(timeofbclk, "relationship between bclk and fs");
-static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -9435, 37, 0);
-static inline int rt5631_write(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int val)
-{
- return snd_soc_write(codec, reg, val);
-}
-
-static inline unsigned int rt5631_read(struct snd_soc_codec *codec,
- unsigned int reg)
-{
- return snd_soc_read(codec, reg);
-}
-
-static int rt5631_write_mask(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value, unsigned int mask)
-{
- unsigned int reg_val;
- int ret = 0;
-
- if (!mask)
- return 0;
-
- if (mask != 0xffff) {
- reg_val = rt5631_read(codec, reg);
- reg_val &= ~mask;
- reg_val |= (value & mask);
- ret = rt5631_write(codec, reg, reg_val);
- } else {
- ret = rt5631_write(codec, reg, value);
- }
-
- return ret;
-}
+static const struct reg_default rt5631_reg[] = {
+ { RT5631_SPK_OUT_VOL, 0x8888 },
+ { RT5631_HP_OUT_VOL, 0x8080 },
+ { RT5631_MONO_AXO_1_2_VOL, 0xa080 },
+ { RT5631_AUX_IN_VOL, 0x0808 },
+ { RT5631_ADC_REC_MIXER, 0xf0f0 },
+ { RT5631_VDAC_DIG_VOL, 0x0010 },
+ { RT5631_OUTMIXER_L_CTRL, 0xffc0 },
+ { RT5631_OUTMIXER_R_CTRL, 0xffc0 },
+ { RT5631_AXO1MIXER_CTRL, 0x88c0 },
+ { RT5631_AXO2MIXER_CTRL, 0x88c0 },
+ { RT5631_DIG_MIC_CTRL, 0x3000 },
+ { RT5631_MONO_INPUT_VOL, 0x8808 },
+ { RT5631_SPK_MIXER_CTRL, 0xf8f8 },
+ { RT5631_SPK_MONO_OUT_CTRL, 0xfc00 },
+ { RT5631_SPK_MONO_HP_OUT_CTRL, 0x4440 },
+ { RT5631_SDP_CTRL, 0x8000 },
+ { RT5631_MONO_SDP_CTRL, 0x8000 },
+ { RT5631_STEREO_AD_DA_CLK_CTRL, 0x2010 },
+ { RT5631_GEN_PUR_CTRL_REG, 0x0e00 },
+ { RT5631_INT_ST_IRQ_CTRL_2, 0x071a },
+ { RT5631_MISC_CTRL, 0x2040 },
+ { RT5631_DEPOP_FUN_CTRL_2, 0x8000 },
+ { RT5631_SOFT_VOL_CTRL, 0x07e0 },
+ { RT5631_ALC_CTRL_1, 0x0206 },
+ { RT5631_ALC_CTRL_3, 0x2000 },
+ { RT5631_PSEUDO_SPATL_CTRL, 0x0553 },
+};
+/**
+ * rt5631_write_index - write index register of 2nd layer
+ */
static void rt5631_write_index(struct snd_soc_codec *codec,
unsigned int reg, unsigned int value)
{
- rt5631_write(codec, RT5631_INDEX_ADD, reg);
- rt5631_write(codec, RT5631_INDEX_DATA, value);
- return;
+ snd_soc_write(codec, RT5631_INDEX_ADD, reg);
+ snd_soc_write(codec, RT5631_INDEX_DATA, value);
}
+/**
+ * rt5631_read_index - read index register of 2nd layer
+ */
static unsigned int rt5631_read_index(struct snd_soc_codec *codec,
unsigned int reg)
{
unsigned int value;
- int ret = 0;
-
- ret = rt5631_write(codec, RT5631_INDEX_ADD, reg);
- if (ret < 0)
- {
- return ret;
- }
- value = rt5631_read(codec, RT5631_INDEX_DATA);
+ snd_soc_write(codec, RT5631_INDEX_ADD, reg);
+ value = snd_soc_read(codec, RT5631_INDEX_DATA);
return value;
}
-static void rt5631_write_index_mask(struct snd_soc_codec *codec,
- unsigned int reg, unsigned int value, unsigned int mask)
+static int rt5631_reset(struct snd_soc_codec *codec)
{
- unsigned int reg_val;
-
- if (!mask)
- return;
-
- if (mask != 0xffff) {
- reg_val = rt5631_read_index(codec, reg);
- reg_val &= ~mask;
- reg_val |= (value & mask);
- rt5631_write_index(codec, reg, reg_val);
- } else {
- rt5631_write_index(codec, reg, value);
- }
-
- return;
+ return snd_soc_write(codec, RT5631_RESET, 0);
}
-static inline int rt5631_reset(struct snd_soc_codec *codec)
+static bool rt5631_volatile_register(struct device *dev, unsigned int reg)
{
- return snd_soc_write(codec, RT5631_RESET, 0);
+ switch (reg) {
+ case RT5631_RESET:
+ case RT5631_INT_ST_IRQ_CTRL_2:
+ case RT5631_INDEX_ADD:
+ case RT5631_INDEX_DATA:
+ case RT5631_EQ_CTRL:
+ return 1;
+ default:
+ return 0;
+ }
}
-struct rt5631_init_reg {
- u8 reg;
- u16 val;
-};
-
-#ifndef DEF_VOL
-#define DEF_VOL 0xd4//0xd4 -30dB 0xc0 0dB
-#endif
-#ifndef DEF_VOL_SPK
-#define DEF_VOL_SPK 0xc4
-#endif
-
-/*
- * speaker channel volume select SPKMIXER, 0DB by default
- * Headphone channel volume select OUTMIXER,0DB by default
- * AXO1/AXO2 channel volume select OUTMIXER,0DB by default
- * Record Mixer source from Mic1/Mic2 by default
- * Mic1/Mic2 boost 40dB by default
- * DAC_L-->OutMixer_L by default
- * DAC_R-->OutMixer_R by default
- * DAC-->SpeakerMixer
- * Speaker volume-->SPOMixer(L-->L,R-->R)
- * Speaker AMP ratio gain is 1.44X
- * HP from OutMixer,speaker out from SpeakerOut Mixer
- * enable HP zero cross
- * change Mic1 & mic2 to differential mode
- */
-static struct rt5631_init_reg init_list[] = {
-
- {RT5631_SPK_OUT_VOL , (DEF_VOL_SPK<<8) | DEF_VOL_SPK},//speaker channel volume select SPKMIXER,0DB by default
- {RT5631_HP_OUT_VOL , (DEF_VOL<<8) | DEF_VOL},//Headphone channel volume select OUTMIXER,0DB by default
- {RT5631_MONO_AXO_1_2_VOL , 0xE0c0},//AXO1/AXO2 channel volume select OUTMIXER,0DB by default
- //{RT5631_STEREO_DAC_VOL_1 , 0x004C},
- {RT5631_STEREO_DAC_VOL_2 , 0x0303},
- {RT5631_ADC_REC_MIXER , 0xb0f0},//Record Mixer source from Mic1 by default
- {RT5631_ADC_CTRL_1 , 0x0004},//STEREO ADC CONTROL 1
- {RT5631_MIC_CTRL_2 , 0x4400},//0x8800},//0x6600}, //Mic1/Mic2 boost 40DB by default
- {RT5631_PWR_MANAG_ADD1 , 0x93e0},
- {RT5631_SDP_CTRL , 0x8002},
- //increase hpo charge pump VEE
- {RT5631_INDEX_ADD , 0x45},
- {RT5631_INDEX_DATA , 0x6530},
-
-#if RT5631_ALC_ADC_FUNC_ENA
-
- {RT5631_ALC_CTRL_1 , 0x060a},//ALC CONTROL 1
- {RT5631_ALC_CTRL_2 , 0x0002},//ALC CONTROL 2
- {RT5631_ALC_CTRL_3 , 0xe088},//ALC CONTROL 3
-
-#endif
- {RT5631_OUTMIXER_L_CTRL , 0xdfC0},//DAC_L-->OutMixer_L by default
- {RT5631_OUTMIXER_R_CTRL , 0xdfC0},//DAC_R-->OutMixer_R by default
- {RT5631_AXO1MIXER_CTRL , 0x8840},//OutMixer_L-->AXO1Mixer by default
- {RT5631_AXO2MIXER_CTRL , 0x8880},//OutMixer_R-->AXO2Mixer by default
- {RT5631_SPK_MIXER_CTRL , 0xd8d8},//DAC-->SpeakerMixer
- {RT5631_SPK_MONO_OUT_CTRL , 0x0c00},//Speaker volume-->SPOMixer(L-->L,R-->R)
- {RT5631_GEN_PUR_CTRL_REG , 0x4e00},//Speaker AMP ratio gain is 1.27x
-#if defined(CONFIG_ADJUST_VOL_BY_CODEC)
- {RT5631_SPK_MONO_HP_OUT_CTRL , 0x0000},//HP from outputmixer,speaker out from SpeakerOut Mixer
-#else
- {RT5631_SPK_MONO_HP_OUT_CTRL , 0x000c},//HP from DAC,speaker out from SpeakerOut Mixer
-#endif
- {RT5631_DEPOP_FUN_CTRL_2 , 0x8000},//HP depop by register control
- {RT5631_INT_ST_IRQ_CTRL_2 , 0x0f18},//enable HP zero cross
- {RT5631_MIC_CTRL_1 , 0x8000},//set mic 1 to differnetial mode
- {RT5631_GPIO_CTRL , 0x0000},//set GPIO to input pin
-// {RT5631_JACK_DET_CTRL , 0x4e80},//Jack detect for GPIO,high is HP,low is speaker
-// {RT5631_JACK_DET_CTRL , 0x4bc0},//Jack detect for GPIO,high is speaker,low is hp
-};
-#define RT5631_INIT_REG_LEN ARRAY_SIZE(init_list)
-
-/*
- * EQ parameter
- */
-enum {
- NORMAL,
- CLUB,
- DANCE,
- LIVE,
- POP,
- ROCK,
- OPPO,
- TREBLE,
- BASS,
- HFREQ,
- SPK_FR
-};
-
-struct hw_eq_preset {
- u16 type;
- u16 value[22];
- u16 ctrl;
-};
-
-/*
- * EQ param reg : 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7,
- * 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
- * EQ control reg : 0x6e
- */
-struct hw_eq_preset hweq_preset[] = {
- {NORMAL , {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x0000},
- {CLUB , {0x1C10, 0x0000, 0xC1CC, 0x1E5D, 0x0699, 0xCD48,
- 0x188D, 0x0699, 0xC3B6, 0x1CD0, 0x0699, 0x0436,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x000E},
- {DANCE , {0x1F2C, 0x095B, 0xC071, 0x1F95, 0x0616, 0xC96E,
- 0x1B11, 0xFC91, 0xDCF2, 0x1194, 0xFAF2, 0x0436,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
- {LIVE , {0x1EB5, 0xFCB6, 0xC24A, 0x1DF8, 0x0E7C, 0xC883,
- 0x1C10, 0x0699, 0xDA41, 0x1561, 0x0295, 0x0436,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
- {POP , {0x1EB5, 0xFCB6, 0xC1D4, 0x1E5D, 0x0E23, 0xD92E,
- 0x16E6, 0xFCB6, 0x0000, 0x0969, 0xF988, 0x0436,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
- {ROCK , {0x1EB5, 0xFCB6, 0xC071, 0x1F95, 0x0424, 0xC30A,
- 0x1D27, 0xF900, 0x0C5D, 0x0FC7, 0x0E23, 0x0436,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
- {OPPO , {0x0000, 0x0000, 0xCA4A, 0x17F8, 0x0FEC, 0xCA4A,
- 0x17F8, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x000F},
- {TREBLE , {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x188D,
- 0x1699, 0x0000, 0x0000, 0x0000}, 0x0010},
- {BASS , {0x1A43, 0x0C00, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000}, 0x0001},
- // {HFREQ, {0x1BBC,0x0000,0xC9A4,0x1BBC,0x0000,0x2997,0x142D,0xFCB6,0xEF01,0x1BBC,0x0000,0xE835,0x0FEC,0xC66E,0x1A29,0x1CEE},0x0014},//orig
- //{HFREQ, {0x1BBC,0x0000,0xC9A4,0x1BBC,0x0000,0x2997,0x142D,0xFCB6,0x1E97,0x08AC,0xFCB6,0xEEA6,0x095B,0xC66E,0x1A29,0x1CEE},0x0018},//roy 20120904
- {HFREQ, {0x1FBC,0x1D18,0x11C1,0x0B2B,0xFF1B,0x1F8D,0x09F3,0xFB54,0xEF01,0x1BBC,0x0000,0xE835,0x2298,0xC66E,0x1A29,0x1CEE},0x0014},//roy 20120914
- {SPK_FR,{0x1DE4,0xF405,0xC306,0x1D60,0x01F3,0x07CA,0x12AF,0xF805,0xE904,0x1C10,0x0000,0x1C8B,0x0000,0xc5e1,0x1afb,0x1d46},0x0003},
-};
-
-static int rt5631_reg_init(struct snd_soc_codec *codec)
+static bool rt5631_readable_register(struct device *dev, unsigned int reg)
{
- int i;
-
- for (i = 0; i < RT5631_INIT_REG_LEN; i++)
- rt5631_write(codec, init_list[i].reg, init_list[i].val);
-
- return 0;
+ switch (reg) {
+ case RT5631_RESET:
+ case RT5631_SPK_OUT_VOL:
+ case RT5631_HP_OUT_VOL:
+ case RT5631_MONO_AXO_1_2_VOL:
+ case RT5631_AUX_IN_VOL:
+ case RT5631_STEREO_DAC_VOL_1:
+ case RT5631_MIC_CTRL_1:
+ case RT5631_STEREO_DAC_VOL_2:
+ case RT5631_ADC_CTRL_1:
+ case RT5631_ADC_REC_MIXER:
+ case RT5631_ADC_CTRL_2:
+ case RT5631_VDAC_DIG_VOL:
+ case RT5631_OUTMIXER_L_CTRL:
+ case RT5631_OUTMIXER_R_CTRL:
+ case RT5631_AXO1MIXER_CTRL:
+ case RT5631_AXO2MIXER_CTRL:
+ case RT5631_MIC_CTRL_2:
+ case RT5631_DIG_MIC_CTRL:
+ case RT5631_MONO_INPUT_VOL:
+ case RT5631_SPK_MIXER_CTRL:
+ case RT5631_SPK_MONO_OUT_CTRL:
+ case RT5631_SPK_MONO_HP_OUT_CTRL:
+ case RT5631_SDP_CTRL:
+ case RT5631_MONO_SDP_CTRL:
+ case RT5631_STEREO_AD_DA_CLK_CTRL:
+ case RT5631_PWR_MANAG_ADD1:
+ case RT5631_PWR_MANAG_ADD2:
+ case RT5631_PWR_MANAG_ADD3:
+ case RT5631_PWR_MANAG_ADD4:
+ case RT5631_GEN_PUR_CTRL_REG:
+ case RT5631_GLOBAL_CLK_CTRL:
+ case RT5631_PLL_CTRL:
+ case RT5631_INT_ST_IRQ_CTRL_1:
+ case RT5631_INT_ST_IRQ_CTRL_2:
+ case RT5631_GPIO_CTRL:
+ case RT5631_MISC_CTRL:
+ case RT5631_DEPOP_FUN_CTRL_1:
+ case RT5631_DEPOP_FUN_CTRL_2:
+ case RT5631_JACK_DET_CTRL:
+ case RT5631_SOFT_VOL_CTRL:
+ case RT5631_ALC_CTRL_1:
+ case RT5631_ALC_CTRL_2:
+ case RT5631_ALC_CTRL_3:
+ case RT5631_PSEUDO_SPATL_CTRL:
+ case RT5631_INDEX_ADD:
+ case RT5631_INDEX_DATA:
+ case RT5631_EQ_CTRL:
+ case RT5631_VENDOR_ID:
+ case RT5631_VENDOR_ID1:
+ case RT5631_VENDOR_ID2:
+ return 1;
+ default:
+ return 0;
+ }
}
-//bard 7-16 s
-void rt5631_adc_on(struct work_struct *work)
-{
- int val;
-
- val = snd_soc_read(rt5631_codec,RT5631_ADC_REC_MIXER);
- snd_soc_write(rt5631_codec,RT5631_ADC_REC_MIXER,0xf0f0);
- snd_soc_update_bits(rt5631_codec, RT5631_PWR_MANAG_ADD1,
- PWR_ADC_L_CLK | PWR_ADC_R_CLK, 0);
- snd_soc_update_bits(rt5631_codec, RT5631_PWR_MANAG_ADD1,
- PWR_ADC_L_CLK | PWR_ADC_R_CLK,
- PWR_ADC_L_CLK | PWR_ADC_R_CLK);
- snd_soc_write(rt5631_codec,RT5631_ADC_REC_MIXER,val);
- snd_soc_update_bits(rt5631_codec, RT5631_ADC_CTRL_1,
- RT_L_MUTE|RT_R_MUTE,0x0);
-
-}
-//bard 7-16 e
-static const char *rt5631_spol_source_sel[] = {
- "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
-static const char *rt5631_spor_source_sel[] = {
- "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
-static const char *rt5631_mono_source_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
-static const char *rt5631_input_mode_source_sel[] = {
- "Single-end", "Differential"};
-static const char *rt5631_mic_boost[] = {"Bypass", "+20db", "+24db", "+30db",
- "+35db", "+40db", "+44db", "+50db", "+52db"};
-static const char *rt5631_hpl_source_sel[] = {"LEFT HPVOL", "LEFT DAC"};
-static const char *rt5631_hpr_source_sel[] = {"RIGHT HPVOL", "RIGHT DAC"};
-static const char *rt5631_eq_sel[] = {"NORMAL", "CLUB", "DANCE", "LIVE", "POP",
- "ROCK", "OPPO", "TREBLE", "BASS"};
-
-
-static const struct soc_enum rt5631_enum[] = {
-SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 14, 4, rt5631_spol_source_sel),
-SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 10, 4, rt5631_spor_source_sel),
-SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 6, 3, rt5631_mono_source_sel),
-SOC_ENUM_SINGLE(RT5631_MIC_CTRL_1, 15, 2, rt5631_input_mode_source_sel),
-SOC_ENUM_SINGLE(RT5631_MIC_CTRL_1, 7, 2, rt5631_input_mode_source_sel),
-SOC_ENUM_SINGLE(RT5631_MONO_INPUT_VOL, 15, 2, rt5631_input_mode_source_sel),
-SOC_ENUM_SINGLE(RT5631_MIC_CTRL_2, 12, 9, rt5631_mic_boost),
-SOC_ENUM_SINGLE(RT5631_MIC_CTRL_2, 8, 9, rt5631_mic_boost),
-SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 3, 2, rt5631_hpl_source_sel),
-SOC_ENUM_SINGLE(RT5631_SPK_MONO_HP_OUT_CTRL, 2, 2, rt5631_hpr_source_sel),
-SOC_ENUM_SINGLE(0, 4, 9, rt5631_eq_sel),
+static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -4650, 150, 0);
+static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0);
+static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0);
+/* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */
+static unsigned int mic_bst_tlv[] = {
+ TLV_DB_RANGE_HEAD(7),
+ 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0),
+ 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0),
+ 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0),
+ 3, 5, TLV_DB_SCALE_ITEM(3000, 500, 0),
+ 6, 6, TLV_DB_SCALE_ITEM(4400, 0, 0),
+ 7, 7, TLV_DB_SCALE_ITEM(5000, 0, 0),
+ 8, 8, TLV_DB_SCALE_ITEM(5200, 0, 0),
};
static int rt5631_dmic_get(struct snd_kcontrol *kcontrol,
return 0;
}
-static void rt5631_close_dmic(struct snd_soc_codec *codec)
-{
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_L_CH_MUTE | DMIC_R_CH_MUTE,
- DMIC_L_CH_MUTE_MASK | DMIC_R_CH_MUTE_MASK);
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_DIS, DMIC_ENA_MASK);
- return;
-}
-
static int rt5631_dmic_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- if (rt5631->dmic_used_flag == ucontrol->value.integer.value[0])
- return 0;
-
- if (ucontrol->value.integer.value[0]) {
- rt5631->dmic_used_flag = 1;
- } else {
- rt5631_close_dmic(codec);
- rt5631->dmic_used_flag = 0;
- }
-
+ rt5631->dmic_used_flag = ucontrol->value.integer.value[0];
return 0;
}
-static int rt5631_eq_sel_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- ucontrol->value.integer.value[0] = rt5631->eq_mode;
+/* MIC Input Type */
+static const char *rt5631_input_mode[] = {
+ "Single ended", "Differential"};
- return 0;
-}
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_mic1_mode_enum, RT5631_MIC_CTRL_1,
+ RT5631_MIC1_DIFF_INPUT_SHIFT, rt5631_input_mode);
-static void rt5631_update_eqmode(struct snd_soc_codec *codec, int mode)
-{
- int i;
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_mic2_mode_enum, RT5631_MIC_CTRL_1,
+ RT5631_MIC2_DIFF_INPUT_SHIFT, rt5631_input_mode);
- DBG("enter rt5631_update_eqmode=========\n");
- if (NORMAL == mode) {
- /* In Normal mode, the EQ parameter is cleared,
- * and hardware LP, BP1, BP2, BP3, HP1, HP2
- * block control and EQ block are disabled.
- */
- for (i = RT5631_EQ_BW_LOP; i <= RT5631_EQ_HPF_GAIN; i++)
- rt5631_write_index(codec, i,
- hweq_preset[mode].value[i]);
- rt5631_write_mask(codec, RT5631_EQ_CTRL, 0x0000, 0x003f);
- rt5631_write_index_mask(codec, RT5631_EQ_PRE_VOL_CTRL
- , 0x0000, 0x8000);
- } else {
- /* Fill and update EQ parameter,
- * and EQ block are enabled.
- */
- rt5631_write_index_mask(codec, RT5631_EQ_PRE_VOL_CTRL
- , 0x8000, 0x8000);
- rt5631_write(codec, RT5631_EQ_CTRL,
- hweq_preset[mode].ctrl);
- for (i = RT5631_EQ_BW_LOP; i <= RT5631_EQ_HPF_GAIN; i++)
- rt5631_write_index(codec, i,
- hweq_preset[mode].value[i]);
- rt5631_write_mask(codec, RT5631_EQ_CTRL, 0x4000, 0x4000);
- }
+/* MONO Input Type */
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_monoin_mode_enum, RT5631_MONO_INPUT_VOL,
+ RT5631_MONO_DIFF_INPUT_SHIFT, rt5631_input_mode);
- return;
-}
+/* SPK Ratio Gain Control */
+static const char *rt5631_spk_ratio[] = {"1.00x", "1.09x", "1.27x", "1.44x",
+ "1.56x", "1.68x", "1.99x", "2.34x"};
-static int rt5631_eq_sel_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_spk_ratio_enum, RT5631_GEN_PUR_CTRL_REG,
+ RT5631_SPK_AMP_RATIO_CTRL_SHIFT, rt5631_spk_ratio);
- if (rt5631->eq_mode == ucontrol->value.integer.value[0])
- return 0;
+static const struct snd_kcontrol_new rt5631_snd_controls[] = {
+ /* MIC */
+ SOC_ENUM("MIC1 Mode Control", rt5631_mic1_mode_enum),
+ SOC_SINGLE_TLV("MIC1 Boost", RT5631_MIC_CTRL_2,
+ RT5631_MIC1_BOOST_SHIFT, 8, 0, mic_bst_tlv),
+ SOC_ENUM("MIC2 Mode Control", rt5631_mic2_mode_enum),
+ SOC_SINGLE_TLV("MIC2 Boost", RT5631_MIC_CTRL_2,
+ RT5631_MIC2_BOOST_SHIFT, 8, 0, mic_bst_tlv),
+ /* MONO IN */
+ SOC_ENUM("MONOIN Mode Control", rt5631_monoin_mode_enum),
+ SOC_DOUBLE_TLV("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL,
+ RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
+ RT5631_VOL_MASK, 1, in_vol_tlv),
+ /* AXI */
+ SOC_DOUBLE_TLV("AXI Capture Volume", RT5631_AUX_IN_VOL,
+ RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
+ RT5631_VOL_MASK, 1, in_vol_tlv),
+ /* DAC */
+ SOC_DOUBLE_TLV("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2,
+ RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
+ RT5631_DAC_VOL_MASK, 1, dac_vol_tlv),
+ SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1,
+ RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
+ /* AXO */
+ SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
+ RT5631_L_MUTE_SHIFT, 1, 1),
+ SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL,
+ RT5631_R_VOL_SHIFT, 1, 1),
+ /* OUTVOL */
+ SOC_DOUBLE("OUTVOL Channel Switch", RT5631_SPK_OUT_VOL,
+ RT5631_L_EN_SHIFT, RT5631_R_EN_SHIFT, 1, 0),
+
+ /* SPK */
+ SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL,
+ RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
+ SOC_DOUBLE_TLV("Speaker Playback Volume", RT5631_SPK_OUT_VOL,
+ RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT, 39, 1, out_vol_tlv),
+ /* MONO OUT */
+ SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL,
+ RT5631_MUTE_MONO_SHIFT, 1, 1),
+ /* HP */
+ SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL,
+ RT5631_L_MUTE_SHIFT, RT5631_R_MUTE_SHIFT, 1, 1),
+ SOC_DOUBLE_TLV("HP Playback Volume", RT5631_HP_OUT_VOL,
+ RT5631_L_VOL_SHIFT, RT5631_R_VOL_SHIFT,
+ RT5631_VOL_MASK, 1, out_vol_tlv),
+ /* DMIC */
+ SOC_SINGLE_EXT("DMIC Switch", 0, 0, 1, 0,
+ rt5631_dmic_get, rt5631_dmic_put),
+ SOC_DOUBLE("DMIC Capture Switch", RT5631_DIG_MIC_CTRL,
+ RT5631_DMIC_L_CH_MUTE_SHIFT,
+ RT5631_DMIC_R_CH_MUTE_SHIFT, 1, 1),
+
+ /* SPK Ratio Gain Control */
+ SOC_ENUM("SPK Ratio Control", rt5631_spk_ratio_enum),
+};
- rt5631_update_eqmode(codec, ucontrol->value.enumerated.item[0]);
- rt5631->eq_mode = ucontrol->value.integer.value[0];
+static int check_sysclk1_source(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int reg;
- return 0;
+ reg = snd_soc_read(source->codec, RT5631_GLOBAL_CLK_CTRL);
+ return reg & RT5631_SYSCLK_SOUR_SEL_PLL;
}
-#if (RT5631_SPK_TIMER == 1)
-static void spk_work_handler(struct work_struct *work)
+static int check_dmic_used(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
{
- struct snd_soc_codec *codec = rt5631_codec;
- int is_spk = (rt5631_read(codec, 0x4a)) & 0x04; //detect rt5631 reg4a[3], 1'b:SPK, 0'b:HP ; //bard 9-13
- //if(last_is_spk != is_spk)
- // printk("%s---%s is in use.last is %s in use\n", __FUNCTION__,is_spk?"speaker":"headphone",last_is_spk?"speaker":"headphone");
- //printk("last_is_spk=%d is_spk=%d\n",last_is_spk,is_spk);
- if(is_spk && (last_is_spk != is_spk)){
- rt5631_write_index_mask(codec,0x11,0x0000,0x0007); //0db
- rt5631_write_index(codec,0x12,0x0003); //0db
- rt5631_update_eqmode(codec, SPK_FR); // SPK is in use, enable EQ mode of SPK_FR.
-
-
- }else if(!is_spk && (last_is_spk != is_spk)){
- //flove071311 rt5631_update_eqmode(codec, NORMAL); // HP is in use, enable EQ mode of NORMAL.
- rt5631_write_index_mask(codec,0x11,0x0002,0x0003);
- rt5631_write_index(codec,0x12,0x0007);
- rt5631_update_eqmode(codec,HFREQ);
- }
- last_is_spk = is_spk;
+ struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(source->codec);
+ return rt5631->dmic_used_flag;
}
-/* timer to judge SPK or HP in use, and handle EQ issues accordingly. */
-void spk_timer_callback(unsigned long data )
-{
- int ret = 0;
-
- schedule_work(&spk_work);
+static int check_dacl_to_outmixl(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int reg;
- //DBG("Starting timer to fire in 1000ms (%ld)\n", jiffies );
- ret = mod_timer(&spk_timer, jiffies + msecs_to_jiffies(1000));
- if (ret) printk("Error in mod_timer\n");
+ reg = snd_soc_read(source->codec, RT5631_OUTMIXER_L_CTRL);
+ return !(reg & RT5631_M_DAC_L_TO_OUTMIXER_L);
}
-#endif
-
-static const struct snd_kcontrol_new rt5631_snd_controls[] = {
-SOC_ENUM("MIC1 Mode Control", rt5631_enum[3]),
-SOC_ENUM("MIC1 Boost", rt5631_enum[6]),
-SOC_ENUM("MIC2 Mode Control", rt5631_enum[4]),
-SOC_ENUM("MIC2 Boost", rt5631_enum[7]),
-SOC_ENUM("MONOIN Mode Control", rt5631_enum[5]),
-SOC_DOUBLE_TLV("PCM Playback Volume", RT5631_STEREO_DAC_VOL_2, 8, 0, 255, 1, dac_vol_tlv),
-SOC_DOUBLE("PCM Playback Switch", RT5631_STEREO_DAC_VOL_1, 15, 7, 1, 1),
-SOC_DOUBLE("MONOIN_RX Capture Volume", RT5631_MONO_INPUT_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("AXI Capture Volume", RT5631_AUX_IN_VOL, 8, 0, 31, 1),
-SOC_SINGLE("AXO1 Playback Switch", RT5631_MONO_AXO_1_2_VOL, 15, 1, 1),
-SOC_SINGLE("AXO2 Playback Switch", RT5631_MONO_AXO_1_2_VOL, 7, 1, 1),
-SOC_DOUBLE("OUTVOL Playback Volume", RT5631_MONO_AXO_1_2_VOL, 8, 0, 31, 1),
-SOC_DOUBLE("Speaker Playback Switch", RT5631_SPK_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("Speaker Playback Volume", RT5631_SPK_OUT_VOL, 8, 0, 63, 1),
-SOC_SINGLE("MONO Playback Switch", RT5631_MONO_AXO_1_2_VOL, 13, 1, 1),
-SOC_DOUBLE("HP Playback Switch", RT5631_HP_OUT_VOL, 15, 7, 1, 1),
-SOC_DOUBLE("HP Playback Volume", RT5631_HP_OUT_VOL, 8, 0, 63, 1),
-SOC_SINGLE_EXT("DMIC Capture Switch", 0, 2, 1, 0,
- rt5631_dmic_get, rt5631_dmic_put),
-SOC_ENUM_EXT("EQ Mode", rt5631_enum[10], rt5631_eq_sel_get, rt5631_eq_sel_put),
-};
-
-static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = {
-SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER, 14, 1, 1),
-SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER, 13, 1, 1),
-SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER, 12, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = {
-SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER, 4, 1, 1),
-SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER, 5, 1, 1),
-SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER, 6, 1, 1),
-SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = {
-SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL, 12, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = {
-SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL, 4, 1, 1),
-SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL, 5, 1, 1),
-SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL, 6, 1, 1),
-SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = {
-SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL, 15, 1, 1),
-SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL, 12, 1, 1),
-SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL, 11, 1, 1),
-SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL, 10, 1, 1),
-SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL, 9, 1, 1),
-SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL, 8, 1, 1),
-SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL, 7, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = {
-SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL, 7, 1, 1),
-SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL, 8, 1, 1),
-SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL, 9, 1, 1),
-SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL, 10, 1, 1),
-SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL, 11, 1, 1),
-SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL, 12, 1, 1),
-SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL, 14, 1, 1),
-SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL, 15, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = {
-SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL, 15 , 1, 1),
-SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL, 11, 1, 1),
-SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL, 7 , 1 , 1),
-SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL, 6, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = {
-SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL, 15, 1, 1),
-SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL, 11, 1, 1),
-SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL, 7, 1, 1),
-SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL, 6, 1 , 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = {
-SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 15, 1, 1),
-SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 14, 1, 1),
-};
-static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = {
-SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 13, 1, 1),
-SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 12, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
-SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 11, 1, 1),
-SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL, 10, 1, 1),
-};
-
-static const struct snd_kcontrol_new rt5631_spol_mux_control =
-SOC_DAPM_ENUM("Route", rt5631_enum[0]);
-static const struct snd_kcontrol_new rt5631_spor_mux_control =
-SOC_DAPM_ENUM("Route", rt5631_enum[1]);
-static const struct snd_kcontrol_new rt5631_mono_mux_control =
-SOC_DAPM_ENUM("Route", rt5631_enum[2]);
-
-static const struct snd_kcontrol_new rt5631_hpl_mux_control =
-SOC_DAPM_ENUM("Route", rt5631_enum[8]);
-static const struct snd_kcontrol_new rt5631_hpr_mux_control =
-SOC_DAPM_ENUM("Route", rt5631_enum[9]);
-
-//ALC for DAC function
-#if (RT5631_ALC_DAC_FUNC_ENA == 1)
-static void rt5631_alc_enable(struct snd_soc_codec *codec,unsigned int EnableALC)
+static int check_dacr_to_outmixr(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
{
- if(EnableALC)
- {
- rt5631_write(codec, 0x64,0x0206);
- rt5631_write(codec, 0x65,0x0003);
- rt5631_write_index(codec, 0x21,0x5000);
- rt5631_write_index(codec, 0x22,0xa480);
- rt5631_write_index(codec, 0x23,0x0a08);
- rt5631_write(codec, 0x0c,0x0010);
- rt5631_write(codec, 0x66,0x650a);
-
- }
- else
- {
- rt5631_write(codec, 0x66,0x250A);
- rt5631_write(codec, 0x0c,0x0000);
- }
-
+ unsigned int reg;
+
+ reg = snd_soc_read(source->codec, RT5631_OUTMIXER_R_CTRL);
+ return !(reg & RT5631_M_DAC_R_TO_OUTMIXER_R);
}
-#endif
-static int spk_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
+static int check_dacl_to_spkmixl(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
{
- struct snd_soc_codec *codec = w->codec;
- static int spkl_out_enable, spkr_out_enable;
+ unsigned int reg;
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
+ reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
+ return !(reg & RT5631_M_DAC_L_TO_SPKMIXER_L);
+}
-#if (RT5631_ALC_DAC_FUNC_ENA == 1)
- rt5631_alc_enable(codec, 1);
-#endif
-
- if (!spkl_out_enable && !strcmp(w->name, "SPKL Amp")) {
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
- PWR_SPK_L_VOL, PWR_SPK_L_VOL);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
- PWR_CLASS_D, PWR_CLASS_D);
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
- 0, RT_L_MUTE);
- spkl_out_enable = 1;
- }
- if (!spkr_out_enable && !strcmp(w->name, "SPKR Amp")) {
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
- PWR_SPK_R_VOL, PWR_SPK_R_VOL);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
- PWR_CLASS_D, PWR_CLASS_D);
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
- 0, RT_R_MUTE);
- spkr_out_enable = 1;
- }
- break;
+static int check_dacr_to_spkmixr(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int reg;
- case SND_SOC_DAPM_POST_PMD:
- if (spkl_out_enable && !strcmp(w->name, "SPKL Amp")) {
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
- RT_L_MUTE, RT_L_MUTE);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
- 0, PWR_SPK_L_VOL);
- spkl_out_enable = 0;
- }
- if (spkr_out_enable && !strcmp(w->name, "SPKR Amp")) {
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
- RT_R_MUTE, RT_R_MUTE);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD4,
- 0, PWR_SPK_R_VOL);
- spkr_out_enable = 0;
- }
- if (0 == spkl_out_enable && 0 == spkr_out_enable)
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
- 0, PWR_CLASS_D);
+ reg = snd_soc_read(source->codec, RT5631_SPK_MIXER_CTRL);
+ return !(reg & RT5631_M_DAC_R_TO_SPKMIXER_R);
+}
-#if (RT5631_ALC_DAC_FUNC_ENA == 1)
- rt5631_alc_enable(codec, 0);
-#endif
+static int check_adcl_select(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int reg;
- break;
+ reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
+ return !(reg & RT5631_M_MIC1_TO_RECMIXER_L);
+}
- default:
- return 0;
- }
+static int check_adcr_select(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ unsigned int reg;
- return 0;
+ reg = snd_soc_read(source->codec, RT5631_ADC_REC_MIXER);
+ return !(reg & RT5631_M_MIC2_TO_RECMIXER_R);
}
-
-static void hp_depop_mode2_onebit(struct snd_soc_codec *codec, int enable)
+/**
+ * onebit_depop_power_stage - auto depop in power stage.
+ * @enable: power on/off
+ *
+ * When power on/off headphone, the depop sequence is done by hardware.
+ */
+static void onebit_depop_power_stage(struct snd_soc_codec *codec, int enable)
{
unsigned int soft_vol, hp_zc;
- rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2, 0, EN_ONE_BIT_DEPOP);
+ /* enable one-bit depop function */
+ snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+ RT5631_EN_ONE_BIT_DEPOP, 0);
- soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+ /* keep soft volume and zero crossing setting */
+ soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
+ hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
if (enable) {
+ /* config one-bit depop parameter */
rt5631_write_index(codec, RT5631_TEST_MODE_CTRL, 0x84c0);
rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x309f);
rt5631_write_index(codec, RT5631_CP_INTL_REG2, 0x6530);
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_2,
- EN_CAP_FREE_DEPOP);
+ /* power on capless block */
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2,
+ RT5631_EN_CAP_FREE_DEPOP);
} else {
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
- schedule_timeout_uninterruptible(msecs_to_jiffies(100));
+ /* power off capless block */
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_2, 0);
+ msleep(100);
}
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-
- return;
+ /* recover soft volume and zero crossing setting */
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
}
-static void hp_mute_unmute_depop_onebit(struct snd_soc_codec *codec, int enable)
+/**
+ * onebit_depop_mute_stage - auto depop in mute stage.
+ * @enable: mute/unmute
+ *
+ * When mute/unmute headphone, the depop sequence is done by hardware.
+ */
+static void onebit_depop_mute_stage(struct snd_soc_codec *codec, int enable)
{
unsigned int soft_vol, hp_zc;
- rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2, 0, EN_ONE_BIT_DEPOP);
- soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+ /* enable one-bit depop function */
+ snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+ RT5631_EN_ONE_BIT_DEPOP, 0);
+
+ /* keep soft volume and zero crossing setting */
+ soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
+ hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
if (enable) {
schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+ /* config one-bit depop parameter */
rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x307f);
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0,
- RT_L_MUTE | RT_R_MUTE);
- schedule_timeout_uninterruptible(msecs_to_jiffies(300));
-
+ snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+ RT5631_L_MUTE | RT5631_R_MUTE, 0);
+ msleep(300);
} else {
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL,
- RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
- schedule_timeout_uninterruptible(msecs_to_jiffies(100));
+ snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+ RT5631_L_MUTE | RT5631_R_MUTE,
+ RT5631_L_MUTE | RT5631_R_MUTE);
+ msleep(100);
}
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
- return;
+ /* recover soft volume and zero crossing setting */
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
}
-static void hp_depop2(struct snd_soc_codec *codec, int enable)
+/**
+ * onebit_depop_power_stage - step by step depop sequence in power stage.
+ * @enable: power on/off
+ *
+ * When power on/off headphone, the depop sequence is done in step by step.
+ */
+static void depop_seq_power_stage(struct snd_soc_codec *codec, int enable)
{
unsigned int soft_vol, hp_zc;
- rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2,
- EN_ONE_BIT_DEPOP, EN_ONE_BIT_DEPOP);
- soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+ /* depop control by register */
+ snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+ RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
+
+ /* keep soft volume and zero crossing setting */
+ soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
+ hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
if (enable) {
+ /* config depop sequence parameter */
rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303e);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_CHARGE_PUMP | PWR_HP_L_AMP | PWR_HP_R_AMP,
- PWR_CHARGE_PUMP | PWR_HP_L_AMP | PWR_HP_R_AMP);
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- POW_ON_SOFT_GEN | EN_DEPOP2_FOR_HP);
- schedule_timeout_uninterruptible(msecs_to_jiffies(100));
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_HP_DEPOP_DIS, PWR_HP_DEPOP_DIS);
+
+ /* power on headphone and charge pump */
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
+ RT5631_PWR_HP_R_AMP,
+ RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
+ RT5631_PWR_HP_R_AMP);
+
+ /* power on soft generator and depop mode2 */
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP);
+ msleep(100);
+
+ /* stop depop mode */
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_HP_DEPOP_DIS, RT5631_PWR_HP_DEPOP_DIS);
} else {
+ /* config depop sequence parameter */
rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x303F);
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- POW_ON_SOFT_GEN | EN_MUTE_UNMUTE_DEPOP |
- PD_HPAMP_L_ST_UP | PD_HPAMP_R_ST_UP);
- schedule_timeout_uninterruptible(msecs_to_jiffies(75));
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- POW_ON_SOFT_GEN | PD_HPAMP_L_ST_UP | PD_HPAMP_R_ST_UP);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3, 0,
- PWR_HP_DEPOP_DIS);
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- POW_ON_SOFT_GEN | EN_DEPOP2_FOR_HP |
- PD_HPAMP_L_ST_UP | PD_HPAMP_R_ST_UP);
- schedule_timeout_uninterruptible(msecs_to_jiffies(80));
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1, POW_ON_SOFT_GEN);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3, 0,
- PWR_CHARGE_PUMP | PWR_HP_L_AMP | PWR_HP_R_AMP);
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
+ RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
+ msleep(75);
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN | RT5631_PD_HPAMP_L_ST_UP |
+ RT5631_PD_HPAMP_R_ST_UP);
+
+ /* start depop mode */
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_HP_DEPOP_DIS, 0);
+
+ /* config depop sequence parameter */
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN | RT5631_EN_DEPOP2_FOR_HP |
+ RT5631_PD_HPAMP_L_ST_UP | RT5631_PD_HPAMP_R_ST_UP);
+ msleep(80);
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN);
+
+ /* power down headphone and charge pump */
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_CHARGE_PUMP | RT5631_PWR_HP_L_AMP |
+ RT5631_PWR_HP_R_AMP, 0);
}
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-
- return;
+ /* recover soft volume and zero crossing setting */
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
}
-static void hp_mute_unmute_depop(struct snd_soc_codec *codec, int enable)
+/**
+ * depop_seq_mute_stage - step by step depop sequence in mute stage.
+ * @enable: mute/unmute
+ *
+ * When mute/unmute headphone, the depop sequence is done in step by step.
+ */
+static void depop_seq_mute_stage(struct snd_soc_codec *codec, int enable)
{
unsigned int soft_vol, hp_zc;
- rt5631_write_mask(codec, RT5631_DEPOP_FUN_CTRL_2,
- EN_ONE_BIT_DEPOP, EN_ONE_BIT_DEPOP);
- soft_vol = rt5631_read(codec, RT5631_SOFT_VOL_CTRL);
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, 0);
- hp_zc = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
+ /* depop control by register */
+ snd_soc_update_bits(codec, RT5631_DEPOP_FUN_CTRL_2,
+ RT5631_EN_ONE_BIT_DEPOP, RT5631_EN_ONE_BIT_DEPOP);
+
+ /* keep soft volume and zero crossing setting */
+ soft_vol = snd_soc_read(codec, RT5631_SOFT_VOL_CTRL);
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, 0);
+ hp_zc = snd_soc_read(codec, RT5631_INT_ST_IRQ_CTRL_2);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc & 0xf7ff);
if (enable) {
schedule_timeout_uninterruptible(msecs_to_jiffies(10));
+
+ /* config depop sequence parameter */
rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- POW_ON_SOFT_GEN | EN_MUTE_UNMUTE_DEPOP |
- EN_HP_R_M_UN_MUTE_DEPOP | EN_HP_L_M_UN_MUTE_DEPOP);
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0,
- RT_L_MUTE | RT_R_MUTE);
- schedule_timeout_uninterruptible(msecs_to_jiffies(160));
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
+ RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
+ RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
+
+ snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+ RT5631_L_MUTE | RT5631_R_MUTE, 0);
+ msleep(160);
} else {
+ /* config depop sequence parameter */
rt5631_write_index(codec, RT5631_SPK_INTL_CTRL, 0x302f);
- rt5631_write(codec, RT5631_DEPOP_FUN_CTRL_1,
- POW_ON_SOFT_GEN | EN_MUTE_UNMUTE_DEPOP |
- EN_HP_R_M_UN_MUTE_DEPOP | EN_HP_L_M_UN_MUTE_DEPOP);
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL,
- RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
- schedule_timeout_uninterruptible(msecs_to_jiffies(150));
+ snd_soc_write(codec, RT5631_DEPOP_FUN_CTRL_1,
+ RT5631_POW_ON_SOFT_GEN | RT5631_EN_MUTE_UNMUTE_DEPOP |
+ RT5631_EN_HP_R_M_UN_MUTE_DEPOP |
+ RT5631_EN_HP_L_M_UN_MUTE_DEPOP);
+
+ snd_soc_update_bits(codec, RT5631_HP_OUT_VOL,
+ RT5631_L_MUTE | RT5631_R_MUTE,
+ RT5631_L_MUTE | RT5631_R_MUTE);
+ msleep(150);
}
- rt5631_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
- rt5631_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
-
- return;
+ /* recover soft volume and zero crossing setting */
+ snd_soc_write(codec, RT5631_SOFT_VOL_CTRL, soft_vol);
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, hp_zc);
}
static int hp_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = w->codec;
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- static bool hp_en;
- int pu_l, pu_r;
- pu_l = rt5631_read(codec, RT5631_PWR_MANAG_ADD4) & PWR_HP_L_OUT_VOL;
- pu_r = rt5631_read(codec, RT5631_PWR_MANAG_ADD4) & PWR_HP_R_OUT_VOL;
switch (event) {
case SND_SOC_DAPM_PRE_PMD:
- if ((pu_l && pu_r) && hp_en) {
- if (rt5631->codec_version) {
- hp_mute_unmute_depop_onebit(codec, 0);
- hp_depop_mode2_onebit(codec, 0);
- } else {
- hp_mute_unmute_depop(codec, 0);
- hp_depop2(codec, 0);
- }
- hp_en = false;
+ if (rt5631->codec_version) {
+ onebit_depop_mute_stage(codec, 0);
+ onebit_depop_power_stage(codec, 0);
+ } else {
+ depop_seq_mute_stage(codec, 0);
+ depop_seq_power_stage(codec, 0);
}
break;
case SND_SOC_DAPM_POST_PMU:
- if ((pu_l && pu_r) && !hp_en) {
- if (rt5631->codec_version) {
- hp_depop_mode2_onebit(codec, 1);
- hp_mute_unmute_depop_onebit(codec, 1);
- } else {
- hp_depop2(codec, 1);
- hp_mute_unmute_depop(codec, 1);
- }
- hp_en = true;
+ if (rt5631->codec_version) {
+ onebit_depop_power_stage(codec, 1);
+ onebit_depop_mute_stage(codec, 1);
+ } else {
+ depop_seq_power_stage(codec, 1);
+ depop_seq_mute_stage(codec, 1);
}
break;
return 0;
}
-static int dac_to_hp_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
+static int set_dmic_params(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol, int event)
{
struct snd_soc_codec *codec = w->codec;
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- static bool hp_en;
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- if (hp_en) {
- if (rt5631->codec_version) {
- hp_mute_unmute_depop_onebit(codec, 0);
- hp_depop_mode2_onebit(codec, 0);
- } else {
- hp_mute_unmute_depop(codec, 0);
- hp_depop2(codec, 0);
- }
- hp_en = false;
- }
+ switch (rt5631->rx_rate) {
+ case 44100:
+ case 48000:
+ snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+ RT5631_DMIC_CLK_CTRL_MASK,
+ RT5631_DMIC_CLK_CTRL_TO_32FS);
break;
- case SND_SOC_DAPM_POST_PMU:
- if (!hp_en) {
- if (rt5631->codec_version) {
- hp_depop_mode2_onebit(codec, 1);
- hp_mute_unmute_depop_onebit(codec, 1);
- } else {
- hp_depop2(codec, 1);
- hp_mute_unmute_depop(codec, 1);
- }
- hp_en = true;
- }
+ case 32000:
+ case 22050:
+ snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+ RT5631_DMIC_CLK_CTRL_MASK,
+ RT5631_DMIC_CLK_CTRL_TO_64FS);
break;
- default:
+ case 16000:
+ case 11025:
+ case 8000:
+ snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+ RT5631_DMIC_CLK_CTRL_MASK,
+ RT5631_DMIC_CLK_CTRL_TO_128FS);
break;
+
+ default:
+ return -EINVAL;
}
return 0;
}
-static int mic_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- int val_mic1, val_mic2;
+static const struct snd_kcontrol_new rt5631_recmixl_mixer_controls[] = {
+ SOC_DAPM_SINGLE("OUTMIXL Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_OUTMIXL_RECMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC1_BST1 Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_MIC1_RECMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("AXILVOL Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_AXIL_RECMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_MONO_IN_RECMIXL_BIT, 1, 1),
+};
- val_mic1 = rt5631_read(codec, RT5631_PWR_MANAG_ADD2) &
- PWR_MIC1_BOOT_GAIN;
- val_mic2 = rt5631_read(codec, RT5631_PWR_MANAG_ADD2) &
- PWR_MIC2_BOOT_GAIN;
- switch (event) {
- case SND_SOC_DAPM_POST_PMU:
- /*
- * If microphone is stereo, need not copy ADC channel
- * If mic1 is used, copy ADC left to right
- * If mic2 is used, copy ADC right to left
- */
- if (val_mic1 && val_mic2)
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x0000, 0xc000);
- else if (val_mic1)
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x4000, 0xc000);
- else if (val_mic2)
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x8000, 0xc000);
- else
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x0000, 0xc000);
- break;
+static const struct snd_kcontrol_new rt5631_recmixr_mixer_controls[] = {
+ SOC_DAPM_SINGLE("MONOIN_RX Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_MONO_IN_RECMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("AXIRVOL Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_AXIR_RECMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC2_BST2 Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_MIC2_RECMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("OUTMIXR Capture Switch", RT5631_ADC_REC_MIXER,
+ RT5631_M_OUTMIXR_RECMIXR_BIT, 1, 1),
+};
- default:
- break;
- }
+static const struct snd_kcontrol_new rt5631_spkmixl_mixer_controls[] = {
+ SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_RECMIXL_SPKMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC1_P Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_MIC1P_SPKMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_DACL_SPKMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("OUTMIXL Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_OUTMIXL_SPKMIXL_BIT, 1, 1),
+};
- return 0;
-}
+static const struct snd_kcontrol_new rt5631_spkmixr_mixer_controls[] = {
+ SOC_DAPM_SINGLE("OUTMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_OUTMIXR_SPKMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_DACR_SPKMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC2_P Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_MIC2P_SPKMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_SPK_MIXER_CTRL,
+ RT5631_M_RECMIXR_SPKMIXR_BIT, 1, 1),
+};
-static int auxo1_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- static bool aux1_en;
+static const struct snd_kcontrol_new rt5631_outmixl_mixer_controls[] = {
+ SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_RECMIXL_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_RECMIXR_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("DACL Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_DACL_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_MIC1_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_MIC2_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MONOIN_RXP Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_MONO_INP_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_AXIL_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_AXIR_OUTMIXL_BIT, 1, 1),
+ SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_L_CTRL,
+ RT5631_M_VDAC_OUTMIXL_BIT, 1, 1),
+};
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- if (aux1_en) {
- rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
- RT_L_MUTE, RT_L_MUTE);
- aux1_en = false;
- }
- break;
+static const struct snd_kcontrol_new rt5631_outmixr_mixer_controls[] = {
+ SOC_DAPM_SINGLE("VDAC Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_VDAC_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("AXIRVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_AXIR_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("AXILVOL Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_AXIL_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MONOIN_RXN Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_MONO_INN_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_MIC2_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_MIC1_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("DACR Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_DACR_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("RECMIXR Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_RECMIXR_OUTMIXR_BIT, 1, 1),
+ SOC_DAPM_SINGLE("RECMIXL Playback Switch", RT5631_OUTMIXER_R_CTRL,
+ RT5631_M_RECMIXL_OUTMIXR_BIT, 1, 1),
+};
- case SND_SOC_DAPM_POST_PMU:
- if (!aux1_en) {
- rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
- 0, RT_L_MUTE);
- aux1_en = true;
- }
- break;
+static const struct snd_kcontrol_new rt5631_AXO1MIX_mixer_controls[] = {
+ SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO1MIXER_CTRL,
+ RT5631_M_MIC1_AXO1MIX_BIT , 1, 1),
+ SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO1MIXER_CTRL,
+ RT5631_M_MIC2_AXO1MIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO1MIXER_CTRL,
+ RT5631_M_OUTMIXL_AXO1MIX_BIT , 1 , 1),
+ SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO1MIXER_CTRL,
+ RT5631_M_OUTMIXR_AXO1MIX_BIT, 1, 1),
+};
- default:
- break;
- }
+static const struct snd_kcontrol_new rt5631_AXO2MIX_mixer_controls[] = {
+ SOC_DAPM_SINGLE("MIC1_BST1 Playback Switch", RT5631_AXO2MIXER_CTRL,
+ RT5631_M_MIC1_AXO2MIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("MIC2_BST2 Playback Switch", RT5631_AXO2MIXER_CTRL,
+ RT5631_M_MIC2_AXO2MIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_AXO2MIXER_CTRL,
+ RT5631_M_OUTMIXL_AXO2MIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_AXO2MIXER_CTRL,
+ RT5631_M_OUTMIXR_AXO2MIX_BIT, 1 , 1),
+};
- return 0;
-}
+static const struct snd_kcontrol_new rt5631_spolmix_mixer_controls[] = {
+ SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
+ RT5631_M_SPKVOLL_SPOLMIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
+ RT5631_M_SPKVOLR_SPOLMIX_BIT, 1, 1),
+};
-static int auxo2_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- static bool aux2_en;
+static const struct snd_kcontrol_new rt5631_spormix_mixer_controls[] = {
+ SOC_DAPM_SINGLE("SPKVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
+ RT5631_M_SPKVOLL_SPORMIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("SPKVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
+ RT5631_M_SPKVOLR_SPORMIX_BIT, 1, 1),
+};
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- if (aux2_en) {
- rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
- RT_R_MUTE, RT_R_MUTE);
- aux2_en = false;
- }
- break;
+static const struct snd_kcontrol_new rt5631_monomix_mixer_controls[] = {
+ SOC_DAPM_SINGLE("OUTVOLL Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
+ RT5631_M_OUTVOLL_MONOMIX_BIT, 1, 1),
+ SOC_DAPM_SINGLE("OUTVOLR Playback Switch", RT5631_SPK_MONO_OUT_CTRL,
+ RT5631_M_OUTVOLR_MONOMIX_BIT, 1, 1),
+};
- case SND_SOC_DAPM_POST_PMU:
- if (!aux2_en) {
- rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
- 0, RT_R_MUTE);
- aux2_en = true;
- }
- break;
+/* Left SPK Volume Input */
+static const char *rt5631_spkvoll_sel[] = {"Vmid", "SPKMIXL"};
- default:
- break;
- }
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_spkvoll_enum, RT5631_SPK_OUT_VOL,
+ RT5631_L_EN_SHIFT, rt5631_spkvoll_sel);
- return 0;
-}
+static const struct snd_kcontrol_new rt5631_spkvoll_mux_control =
+ SOC_DAPM_ENUM("Left SPKVOL SRC", rt5631_spkvoll_enum);
-static int mono_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- static bool mono_en;
+/* Left HP Volume Input */
+static const char *rt5631_hpvoll_sel[] = {"Vmid", "OUTMIXL"};
- switch (event) {
- case SND_SOC_DAPM_PRE_PMD:
- if (mono_en) {
- rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
- MUTE_MONO, MUTE_MONO);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- 0, PWR_MONO_DEPOP_DIS);
- mono_en = false;
- }
- break;
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_hpvoll_enum, RT5631_HP_OUT_VOL,
+ RT5631_L_EN_SHIFT, rt5631_hpvoll_sel);
- case SND_SOC_DAPM_POST_PMU:
- if (!mono_en) {
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_MONO_DEPOP_DIS, PWR_MONO_DEPOP_DIS);
- rt5631_write_mask(codec, RT5631_MONO_AXO_1_2_VOL,
- 0, MUTE_MONO);
- mono_en = true;
- }
- break;
+static const struct snd_kcontrol_new rt5631_hpvoll_mux_control =
+ SOC_DAPM_ENUM("Left HPVOL SRC", rt5631_hpvoll_enum);
- default:
- break;
- }
+/* Left Out Volume Input */
+static const char *rt5631_outvoll_sel[] = {"Vmid", "OUTMIXL"};
- return 0;
-}
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_outvoll_enum, RT5631_MONO_AXO_1_2_VOL,
+ RT5631_L_EN_SHIFT, rt5631_outvoll_sel);
-/**
- * config_common_power - control all common power of codec system
- * @pmu: power up or not
- */
-static int config_common_power(struct snd_soc_codec *codec, bool pmu)
-{
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- unsigned int mux_val;
-
- if (pmu) {
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
- PWR_MAIN_I2S_EN | PWR_DAC_REF,
- PWR_MAIN_I2S_EN | PWR_DAC_REF);
- mux_val = rt5631_read(codec, RT5631_SPK_MONO_HP_OUT_CTRL);
- //if (!(mux_val & HP_L_MUX_SEL_DAC_L))
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
- PWR_DAC_L_TO_MIXER, PWR_DAC_L_TO_MIXER);
- //if (!(mux_val & HP_R_MUX_SEL_DAC_R))
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1,
- PWR_DAC_R_TO_MIXER, PWR_DAC_R_TO_MIXER);
- if (rt5631->pll_used_flag)
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2,
- PWR_PLL, PWR_PLL);
- } else if (isPlaybackon == false && isCaptureon == false){
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD1, 0,
- PWR_MAIN_I2S_EN | PWR_DAC_REF |
- PWR_DAC_L_TO_MIXER | PWR_DAC_R_TO_MIXER);
- if (rt5631->pll_used_flag)
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2,
- 0, PWR_PLL);
- }
+static const struct snd_kcontrol_new rt5631_outvoll_mux_control =
+ SOC_DAPM_ENUM("Left OUTVOL SRC", rt5631_outvoll_enum);
+
+/* Right Out Volume Input */
+static const char *rt5631_outvolr_sel[] = {"Vmid", "OUTMIXR"};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_outvolr_enum, RT5631_MONO_AXO_1_2_VOL,
+ RT5631_R_EN_SHIFT, rt5631_outvolr_sel);
+
+static const struct snd_kcontrol_new rt5631_outvolr_mux_control =
+ SOC_DAPM_ENUM("Right OUTVOL SRC", rt5631_outvolr_enum);
+
+/* Right HP Volume Input */
+static const char *rt5631_hpvolr_sel[] = {"Vmid", "OUTMIXR"};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_hpvolr_enum, RT5631_HP_OUT_VOL,
+ RT5631_R_EN_SHIFT, rt5631_hpvolr_sel);
+
+static const struct snd_kcontrol_new rt5631_hpvolr_mux_control =
+ SOC_DAPM_ENUM("Right HPVOL SRC", rt5631_hpvolr_enum);
+
+/* Right SPK Volume Input */
+static const char *rt5631_spkvolr_sel[] = {"Vmid", "SPKMIXR"};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_spkvolr_enum, RT5631_SPK_OUT_VOL,
+ RT5631_R_EN_SHIFT, rt5631_spkvolr_sel);
+
+static const struct snd_kcontrol_new rt5631_spkvolr_mux_control =
+ SOC_DAPM_ENUM("Right SPKVOL SRC", rt5631_spkvolr_enum);
+
+/* SPO Left Channel Input */
+static const char *rt5631_spol_src_sel[] = {
+ "SPOLMIX", "MONOIN_RX", "VDAC", "DACL"};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_spol_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
+ RT5631_SPK_L_MUX_SEL_SHIFT, rt5631_spol_src_sel);
- return 0;
-}
+static const struct snd_kcontrol_new rt5631_spol_mux_control =
+ SOC_DAPM_ENUM("SPOL SRC", rt5631_spol_src_enum);
-static int adc_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- static bool pmu;
+/* SPO Right Channel Input */
+static const char *rt5631_spor_src_sel[] = {
+ "SPORMIX", "MONOIN_RX", "VDAC", "DACR"};
- switch (event) {
- case SND_SOC_DAPM_POST_PMD:
- if (pmu) {
- isPlaybackon = false;
- config_common_power(codec, false);
- pmu = false;
- }
- break;
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_spor_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
+ RT5631_SPK_R_MUX_SEL_SHIFT, rt5631_spor_src_sel);
- case SND_SOC_DAPM_PRE_PMU:
- if (!pmu) {
- isPlaybackon = true;
- config_common_power(codec, true);
- pmu = true;
- }
- break;
+static const struct snd_kcontrol_new rt5631_spor_mux_control =
+ SOC_DAPM_ENUM("SPOR SRC", rt5631_spor_src_enum);
- default:
- break;
- }
+/* MONO Input */
+static const char *rt5631_mono_src_sel[] = {"MONOMIX", "MONOIN_RX", "VDAC"};
- return 0;
-}
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_mono_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
+ RT5631_MONO_MUX_SEL_SHIFT, rt5631_mono_src_sel);
-static int dac_event(struct snd_soc_dapm_widget *w,
- struct snd_kcontrol *kcontrol, int event)
-{
- struct snd_soc_codec *codec = w->codec;
- static bool pmu;
+static const struct snd_kcontrol_new rt5631_mono_mux_control =
+ SOC_DAPM_ENUM("MONO SRC", rt5631_mono_src_enum);
- switch (event) {
- case SND_SOC_DAPM_POST_PMD:
- if (pmu) {
- isCaptureon = false;
- config_common_power(codec, false);
- pmu = false;
- }
- break;
+/* Left HPO Input */
+static const char *rt5631_hpl_src_sel[] = {"Left HPVOL", "Left DAC"};
- case SND_SOC_DAPM_PRE_PMU:
- if (!pmu) {
- isCaptureon = true;
- config_common_power(codec, true);
- pmu = true;
- }
- break;
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_hpl_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
+ RT5631_HP_L_MUX_SEL_SHIFT, rt5631_hpl_src_sel);
- default:
- break;
- }
+static const struct snd_kcontrol_new rt5631_hpl_mux_control =
+ SOC_DAPM_ENUM("HPL SRC", rt5631_hpl_src_enum);
- return 0;
-}
+/* Right HPO Input */
+static const char *rt5631_hpr_src_sel[] = {"Right HPVOL", "Right DAC"};
+
+static const SOC_ENUM_SINGLE_DECL(
+ rt5631_hpr_src_enum, RT5631_SPK_MONO_HP_OUT_CTRL,
+ RT5631_HP_R_MUX_SEL_SHIFT, rt5631_hpr_src_sel);
+
+static const struct snd_kcontrol_new rt5631_hpr_mux_control =
+ SOC_DAPM_ENUM("HPR SRC", rt5631_hpr_src_enum);
static const struct snd_soc_dapm_widget rt5631_dapm_widgets[] = {
-SND_SOC_DAPM_INPUT("MIC1"),
-SND_SOC_DAPM_INPUT("MIC2"),
-SND_SOC_DAPM_INPUT("AXIL"),
-SND_SOC_DAPM_INPUT("AXIR"),
-SND_SOC_DAPM_INPUT("MONOIN_RXN"),
-SND_SOC_DAPM_INPUT("MONOIN_RXP"),
-
-SND_SOC_DAPM_MICBIAS("Mic Bias1", RT5631_PWR_MANAG_ADD2, 3, 0),
-SND_SOC_DAPM_MICBIAS("Mic Bias2", RT5631_PWR_MANAG_ADD2, 2, 0),
-
-SND_SOC_DAPM_PGA_E("Mic1 Boost", RT5631_PWR_MANAG_ADD2, 5, 0, NULL, 0,
- mic_event, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("Mic2 Boost", RT5631_PWR_MANAG_ADD2, 4, 0, NULL, 0,
- mic_event, SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4, 7, 0, NULL, 0),
-SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4, 6, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4, 9, 0, NULL, 0),
-SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4, 8, 0, NULL, 0),
-SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2, 11, 0,
+ /* Vmid */
+ SND_SOC_DAPM_VMID("Vmid"),
+ /* PLL1 */
+ SND_SOC_DAPM_SUPPLY("PLL1", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_PLL1_BIT, 0, NULL, 0),
+
+ /* Input Side */
+ /* Input Lines */
+ SND_SOC_DAPM_INPUT("MIC1"),
+ SND_SOC_DAPM_INPUT("MIC2"),
+ SND_SOC_DAPM_INPUT("AXIL"),
+ SND_SOC_DAPM_INPUT("AXIR"),
+ SND_SOC_DAPM_INPUT("MONOIN_RXN"),
+ SND_SOC_DAPM_INPUT("MONOIN_RXP"),
+ SND_SOC_DAPM_INPUT("DMIC"),
+
+ /* MICBIAS */
+ SND_SOC_DAPM_MICBIAS("MIC Bias1", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_MICBIAS1_VOL_BIT, 0),
+ SND_SOC_DAPM_MICBIAS("MIC Bias2", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_MICBIAS2_VOL_BIT, 0),
+
+ /* Boost */
+ SND_SOC_DAPM_PGA("MIC1 Boost", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_MIC1_BOOT_GAIN_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MIC2 Boost", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_MIC2_BOOT_GAIN_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MONOIN_RXP Boost", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_MONO_IN_P_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("MONOIN_RXN Boost", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_MONO_IN_N_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("AXIL Boost", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_AXIL_IN_VOL_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_PGA("AXIR Boost", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_AXIR_IN_VOL_BIT, 0, NULL, 0),
+
+ /* MONO In */
+ SND_SOC_DAPM_MIXER("MONO_IN", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* REC Mixer */
+ SND_SOC_DAPM_MIXER("RECMIXL Mixer", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_RECMIXER_L_BIT, 0,
&rt5631_recmixl_mixer_controls[0],
ARRAY_SIZE(rt5631_recmixl_mixer_controls)),
-SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2, 10, 0,
+ SND_SOC_DAPM_MIXER("RECMIXR Mixer", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_RECMIXER_R_BIT, 0,
&rt5631_recmixr_mixer_controls[0],
ARRAY_SIZE(rt5631_recmixr_mixer_controls)),
-SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_ADC_E("Left ADC", "Left ADC HIFI Capture",
- RT5631_PWR_MANAG_ADD1, 11, 0,
- adc_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_ADC_E("Right ADC", "Right ADC HIFI Capture",
- RT5631_PWR_MANAG_ADD1, 10, 0,
- adc_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_DAC_E("Left DAC", "Left DAC HIFI Playback",
- RT5631_PWR_MANAG_ADD1, 9, 0,
- dac_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_DAC_E("Right DAC", "Right DAC HIFI Playback",
- RT5631_PWR_MANAG_ADD1, 8, 0,
- dac_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_PRE_PMU),
-SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback", SND_SOC_NOPM, 0, 0),
-SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2, 13, 0,
- &rt5631_spkmixl_mixer_controls[0],
- ARRAY_SIZE(rt5631_spkmixl_mixer_controls)),
-SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2, 15, 0,
- &rt5631_outmixl_mixer_controls[0],
- ARRAY_SIZE(rt5631_outmixl_mixer_controls)),
-SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2, 14, 0,
- &rt5631_outmixr_mixer_controls[0],
- ARRAY_SIZE(rt5631_outmixr_mixer_controls)),
-SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2, 12, 0,
- &rt5631_spkmixr_mixer_controls[0],
- ARRAY_SIZE(rt5631_spkmixr_mixer_controls)),
-
-SND_SOC_DAPM_PGA("Left SPK Vol", RT5631_PWR_MANAG_ADD4, 15, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right SPK Vol", RT5631_PWR_MANAG_ADD4, 14, 0, NULL, 0),
-SND_SOC_DAPM_PGA_E("Left HP Vol", RT5631_PWR_MANAG_ADD4, 11, 0, NULL, 0,
- hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("Right HP Vol", RT5631_PWR_MANAG_ADD4, 10, 0, NULL, 0,
+ /* Because of record duplication for L/R channel,
+ * L/R ADCs need power up at the same time */
+ SND_SOC_DAPM_MIXER("ADC Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DMIC */
+ SND_SOC_DAPM_SUPPLY("DMIC Supply", RT5631_DIG_MIC_CTRL,
+ RT5631_DMIC_ENA_SHIFT, 0,
+ set_dmic_params, SND_SOC_DAPM_PRE_PMU),
+ /* ADC Data Srouce */
+ SND_SOC_DAPM_SUPPLY("Left ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
+ RT5631_ADC_DATA_SEL_MIC1_SHIFT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Right ADC Select", RT5631_INT_ST_IRQ_CTRL_2,
+ RT5631_ADC_DATA_SEL_MIC2_SHIFT, 0, NULL, 0),
+
+ /* ADCs */
+ SND_SOC_DAPM_ADC("Left ADC", "HIFI Capture",
+ RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_L_CLK_BIT, 0),
+ SND_SOC_DAPM_ADC("Right ADC", "HIFI Capture",
+ RT5631_PWR_MANAG_ADD1, RT5631_PWR_ADC_R_CLK_BIT, 0),
+
+ /* DAC and ADC supply power */
+ SND_SOC_DAPM_SUPPLY("I2S", RT5631_PWR_MANAG_ADD1,
+ RT5631_PWR_MAIN_I2S_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("DAC REF", RT5631_PWR_MANAG_ADD1,
+ RT5631_PWR_DAC_REF_BIT, 0, NULL, 0),
+
+ /* Output Side */
+ /* DACs */
+ SND_SOC_DAPM_DAC("Left DAC", "HIFI Playback",
+ RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_L_CLK_BIT, 0),
+ SND_SOC_DAPM_DAC("Right DAC", "HIFI Playback",
+ RT5631_PWR_MANAG_ADD1, RT5631_PWR_DAC_R_CLK_BIT, 0),
+ SND_SOC_DAPM_DAC("Voice DAC", "Voice DAC Mono Playback",
+ SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_PGA("Voice DAC Boost", SND_SOC_NOPM, 0, 0, NULL, 0),
+ /* DAC supply power */
+ SND_SOC_DAPM_SUPPLY("Left DAC To Mixer", RT5631_PWR_MANAG_ADD1,
+ RT5631_PWR_DAC_L_TO_MIXER_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Right DAC To Mixer", RT5631_PWR_MANAG_ADD1,
+ RT5631_PWR_DAC_R_TO_MIXER_BIT, 0, NULL, 0),
+
+ /* Left SPK Mixer */
+ SND_SOC_DAPM_MIXER("SPKMIXL Mixer", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_SPKMIXER_L_BIT, 0,
+ &rt5631_spkmixl_mixer_controls[0],
+ ARRAY_SIZE(rt5631_spkmixl_mixer_controls)),
+ /* Left Out Mixer */
+ SND_SOC_DAPM_MIXER("OUTMIXL Mixer", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_OUTMIXER_L_BIT, 0,
+ &rt5631_outmixl_mixer_controls[0],
+ ARRAY_SIZE(rt5631_outmixl_mixer_controls)),
+ /* Right Out Mixer */
+ SND_SOC_DAPM_MIXER("OUTMIXR Mixer", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_OUTMIXER_R_BIT, 0,
+ &rt5631_outmixr_mixer_controls[0],
+ ARRAY_SIZE(rt5631_outmixr_mixer_controls)),
+ /* Right SPK Mixer */
+ SND_SOC_DAPM_MIXER("SPKMIXR Mixer", RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_SPKMIXER_R_BIT, 0,
+ &rt5631_spkmixr_mixer_controls[0],
+ ARRAY_SIZE(rt5631_spkmixr_mixer_controls)),
+
+ /* Volume Mux */
+ SND_SOC_DAPM_MUX("Left SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_SPK_L_VOL_BIT, 0,
+ &rt5631_spkvoll_mux_control),
+ SND_SOC_DAPM_MUX("Left HPVOL Mux", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_HP_L_OUT_VOL_BIT, 0,
+ &rt5631_hpvoll_mux_control),
+ SND_SOC_DAPM_MUX("Left OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_LOUT_VOL_BIT, 0,
+ &rt5631_outvoll_mux_control),
+ SND_SOC_DAPM_MUX("Right OUTVOL Mux", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_ROUT_VOL_BIT, 0,
+ &rt5631_outvolr_mux_control),
+ SND_SOC_DAPM_MUX("Right HPVOL Mux", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_HP_R_OUT_VOL_BIT, 0,
+ &rt5631_hpvolr_mux_control),
+ SND_SOC_DAPM_MUX("Right SPKVOL Mux", RT5631_PWR_MANAG_ADD4,
+ RT5631_PWR_SPK_R_VOL_BIT, 0,
+ &rt5631_spkvolr_mux_control),
+
+ /* DAC To HP */
+ SND_SOC_DAPM_PGA_S("Left DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_PGA_S("Right DAC_HP", 0, SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* HP Depop */
+ SND_SOC_DAPM_PGA_S("HP Depop", 1, SND_SOC_NOPM, 0, 0,
hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("Left DAC_HP", SND_SOC_NOPM, 0, 0, NULL, 0,
- dac_to_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("Right DAC_HP", SND_SOC_NOPM, 0, 0, NULL, 0,
- dac_to_hp_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_PGA("Left Out Vol", RT5631_PWR_MANAG_ADD4, 13, 0, NULL, 0),
-SND_SOC_DAPM_PGA("Right Out Vol", RT5631_PWR_MANAG_ADD4, 12, 0, NULL, 0),
-
-SND_SOC_DAPM_MIXER_E("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3, 11, 0,
- &rt5631_AXO1MIX_mixer_controls[0],
- ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls),
- auxo1_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0,
- &rt5631_spolmix_mixer_controls[0],
- ARRAY_SIZE(rt5631_spolmix_mixer_controls)),
-SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3, 9, 0,
- &rt5631_monomix_mixer_controls[0],
- ARRAY_SIZE(rt5631_monomix_mixer_controls)),
-SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0,
- &rt5631_spormix_mixer_controls[0],
- ARRAY_SIZE(rt5631_spormix_mixer_controls)),
-SND_SOC_DAPM_MIXER_E("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3, 10, 0,
- &rt5631_AXO2MIX_mixer_controls[0],
- ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls),
- auxo2_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0, &rt5631_spol_mux_control),
-SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0, &rt5631_spor_mux_control),
-SND_SOC_DAPM_MUX("Mono Mux", SND_SOC_NOPM, 0, 0, &rt5631_mono_mux_control),
-SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0, &rt5631_hpl_mux_control),
-SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0, &rt5631_hpr_mux_control),
-
-SND_SOC_DAPM_PGA_E("Mono Amp", RT5631_PWR_MANAG_ADD3, 7, 0, NULL, 0,
- mono_event, SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("SPKL Amp", SND_SOC_NOPM, 0, 0, NULL, 0,
- spk_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
-SND_SOC_DAPM_PGA_E("SPKR Amp", SND_SOC_NOPM, 1, 0, NULL, 0,
- spk_event, SND_SOC_DAPM_POST_PMD | SND_SOC_DAPM_POST_PMU),
-
-SND_SOC_DAPM_OUTPUT("AUXO1"),
-SND_SOC_DAPM_OUTPUT("AUXO2"),
-SND_SOC_DAPM_OUTPUT("SPOL"),
-SND_SOC_DAPM_OUTPUT("SPOR"),
-SND_SOC_DAPM_OUTPUT("HPOL"),
-SND_SOC_DAPM_OUTPUT("HPOR"),
-SND_SOC_DAPM_OUTPUT("MONO"),
+ /* AXO1 Mixer */
+ SND_SOC_DAPM_MIXER("AXO1MIX Mixer", RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_AXO1MIXER_BIT, 0,
+ &rt5631_AXO1MIX_mixer_controls[0],
+ ARRAY_SIZE(rt5631_AXO1MIX_mixer_controls)),
+ /* SPOL Mixer */
+ SND_SOC_DAPM_MIXER("SPOLMIX Mixer", SND_SOC_NOPM, 0, 0,
+ &rt5631_spolmix_mixer_controls[0],
+ ARRAY_SIZE(rt5631_spolmix_mixer_controls)),
+ /* MONO Mixer */
+ SND_SOC_DAPM_MIXER("MONOMIX Mixer", RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_MONOMIXER_BIT, 0,
+ &rt5631_monomix_mixer_controls[0],
+ ARRAY_SIZE(rt5631_monomix_mixer_controls)),
+ /* SPOR Mixer */
+ SND_SOC_DAPM_MIXER("SPORMIX Mixer", SND_SOC_NOPM, 0, 0,
+ &rt5631_spormix_mixer_controls[0],
+ ARRAY_SIZE(rt5631_spormix_mixer_controls)),
+ /* AXO2 Mixer */
+ SND_SOC_DAPM_MIXER("AXO2MIX Mixer", RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_AXO2MIXER_BIT, 0,
+ &rt5631_AXO2MIX_mixer_controls[0],
+ ARRAY_SIZE(rt5631_AXO2MIX_mixer_controls)),
+
+ /* Mux */
+ SND_SOC_DAPM_MUX("SPOL Mux", SND_SOC_NOPM, 0, 0,
+ &rt5631_spol_mux_control),
+ SND_SOC_DAPM_MUX("SPOR Mux", SND_SOC_NOPM, 0, 0,
+ &rt5631_spor_mux_control),
+ SND_SOC_DAPM_MUX("MONO Mux", SND_SOC_NOPM, 0, 0,
+ &rt5631_mono_mux_control),
+ SND_SOC_DAPM_MUX("HPL Mux", SND_SOC_NOPM, 0, 0,
+ &rt5631_hpl_mux_control),
+ SND_SOC_DAPM_MUX("HPR Mux", SND_SOC_NOPM, 0, 0,
+ &rt5631_hpr_mux_control),
+
+ /* AMP supply */
+ SND_SOC_DAPM_SUPPLY("MONO Depop", RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_MONO_DEPOP_DIS_BIT, 0, NULL, 0),
+ SND_SOC_DAPM_SUPPLY("Class D", RT5631_PWR_MANAG_ADD1,
+ RT5631_PWR_CLASS_D_BIT, 0, NULL, 0),
+
+ /* Output Lines */
+ SND_SOC_DAPM_OUTPUT("AUXO1"),
+ SND_SOC_DAPM_OUTPUT("AUXO2"),
+ SND_SOC_DAPM_OUTPUT("SPOL"),
+ SND_SOC_DAPM_OUTPUT("SPOR"),
+ SND_SOC_DAPM_OUTPUT("HPOL"),
+ SND_SOC_DAPM_OUTPUT("HPOR"),
+ SND_SOC_DAPM_OUTPUT("MONO"),
};
-
-static const struct snd_soc_dapm_route audio_map[] = {
- {"Mic1 Boost", NULL, "MIC1"},
- {"Mic2 Boost", NULL, "MIC2"},
+static const struct snd_soc_dapm_route rt5631_dapm_routes[] = {
+ {"MIC1 Boost", NULL, "MIC1"},
+ {"MIC2 Boost", NULL, "MIC2"},
{"MONOIN_RXP Boost", NULL, "MONOIN_RXP"},
{"MONOIN_RXN Boost", NULL, "MONOIN_RXN"},
{"AXIL Boost", NULL, "AXIL"},
{"MONO_IN", NULL, "MONOIN_RXN Boost"},
{"RECMIXL Mixer", "OUTMIXL Capture Switch", "OUTMIXL Mixer"},
- {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "Mic1 Boost"},
+ {"RECMIXL Mixer", "MIC1_BST1 Capture Switch", "MIC1 Boost"},
{"RECMIXL Mixer", "AXILVOL Capture Switch", "AXIL Boost"},
{"RECMIXL Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
{"RECMIXR Mixer", "OUTMIXR Capture Switch", "OUTMIXR Mixer"},
- {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "Mic2 Boost"},
+ {"RECMIXR Mixer", "MIC2_BST2 Capture Switch", "MIC2 Boost"},
{"RECMIXR Mixer", "AXIRVOL Capture Switch", "AXIR Boost"},
{"RECMIXR Mixer", "MONOIN_RX Capture Switch", "MONO_IN"},
{"ADC Mixer", NULL, "RECMIXL Mixer"},
{"ADC Mixer", NULL, "RECMIXR Mixer"},
+
{"Left ADC", NULL, "ADC Mixer"},
+ {"Left ADC", NULL, "Left ADC Select", check_adcl_select},
+ {"Left ADC", NULL, "PLL1", check_sysclk1_source},
+ {"Left ADC", NULL, "I2S"},
+ {"Left ADC", NULL, "DAC REF"},
+
{"Right ADC", NULL, "ADC Mixer"},
+ {"Right ADC", NULL, "Right ADC Select", check_adcr_select},
+ {"Right ADC", NULL, "PLL1", check_sysclk1_source},
+ {"Right ADC", NULL, "I2S"},
+ {"Right ADC", NULL, "DAC REF"},
+
+ {"DMIC", NULL, "DMIC Supply", check_dmic_used},
+ {"Left ADC", NULL, "DMIC"},
+ {"Right ADC", NULL, "DMIC"},
+
+ {"Left DAC", NULL, "PLL1", check_sysclk1_source},
+ {"Left DAC", NULL, "I2S"},
+ {"Left DAC", NULL, "DAC REF"},
+ {"Right DAC", NULL, "PLL1", check_sysclk1_source},
+ {"Right DAC", NULL, "I2S"},
+ {"Right DAC", NULL, "DAC REF"},
{"Voice DAC Boost", NULL, "Voice DAC"},
+ {"SPKMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_spkmixl},
{"SPKMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
{"SPKMIXL Mixer", "MIC1_P Playback Switch", "MIC1"},
{"SPKMIXL Mixer", "DACL Playback Switch", "Left DAC"},
{"SPKMIXL Mixer", "OUTMIXL Playback Switch", "OUTMIXL Mixer"},
+ {"SPKMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_spkmixr},
{"SPKMIXR Mixer", "OUTMIXR Playback Switch", "OUTMIXR Mixer"},
{"SPKMIXR Mixer", "DACR Playback Switch", "Right DAC"},
{"SPKMIXR Mixer", "MIC2_P Playback Switch", "MIC2"},
{"SPKMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
+ {"OUTMIXL Mixer", NULL, "Left DAC To Mixer", check_dacl_to_outmixl},
{"OUTMIXL Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
{"OUTMIXL Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
{"OUTMIXL Mixer", "DACL Playback Switch", "Left DAC"},
- {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
- {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
+ {"OUTMIXL Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
+ {"OUTMIXL Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
{"OUTMIXL Mixer", "MONOIN_RXP Playback Switch", "MONOIN_RXP Boost"},
{"OUTMIXL Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
{"OUTMIXL Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
{"OUTMIXL Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
+ {"OUTMIXR Mixer", NULL, "Right DAC To Mixer", check_dacr_to_outmixr},
{"OUTMIXR Mixer", "RECMIXL Playback Switch", "RECMIXL Mixer"},
{"OUTMIXR Mixer", "RECMIXR Playback Switch", "RECMIXR Mixer"},
{"OUTMIXR Mixer", "DACR Playback Switch", "Right DAC"},
- {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
- {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
+ {"OUTMIXR Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
+ {"OUTMIXR Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
{"OUTMIXR Mixer", "MONOIN_RXN Playback Switch", "MONOIN_RXN Boost"},
{"OUTMIXR Mixer", "AXILVOL Playback Switch", "AXIL Boost"},
{"OUTMIXR Mixer", "AXIRVOL Playback Switch", "AXIR Boost"},
{"OUTMIXR Mixer", "VDAC Playback Switch", "Voice DAC Boost"},
- {"Left SPK Vol", NULL, "SPKMIXL Mixer"},
- {"Right SPK Vol", NULL, "SPKMIXR Mixer"},
- {"Left HP Vol", NULL, "OUTMIXL Mixer"},
- {"Left Out Vol", NULL, "OUTMIXL Mixer"},
- {"Right Out Vol", NULL, "OUTMIXR Mixer"},
- {"Right HP Vol", NULL, "OUTMIXR Mixer"},
-
- {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
- {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left Out Vol"},
- {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right Out Vol"},
- {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
-
- {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "Mic1 Boost"},
- {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left Out Vol"},
- {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right Out Vol"},
- {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "Mic2 Boost"},
-
- {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPK Vol"},
- {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPK Vol"},
-
- {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPK Vol"},
- {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPK Vol"},
-
- {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left Out Vol"},
- {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right Out Vol"},
+ {"Left SPKVOL Mux", "SPKMIXL", "SPKMIXL Mixer"},
+ {"Left SPKVOL Mux", "Vmid", "Vmid"},
+ {"Left HPVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
+ {"Left HPVOL Mux", "Vmid", "Vmid"},
+ {"Left OUTVOL Mux", "OUTMIXL", "OUTMIXL Mixer"},
+ {"Left OUTVOL Mux", "Vmid", "Vmid"},
+ {"Right OUTVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
+ {"Right OUTVOL Mux", "Vmid", "Vmid"},
+ {"Right HPVOL Mux", "OUTMIXR", "OUTMIXR Mixer"},
+ {"Right HPVOL Mux", "Vmid", "Vmid"},
+ {"Right SPKVOL Mux", "SPKMIXR", "SPKMIXR Mixer"},
+ {"Right SPKVOL Mux", "Vmid", "Vmid"},
+
+ {"AXO1MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
+ {"AXO1MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
+ {"AXO1MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
+ {"AXO1MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
+
+ {"AXO2MIX Mixer", "MIC1_BST1 Playback Switch", "MIC1 Boost"},
+ {"AXO2MIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
+ {"AXO2MIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
+ {"AXO2MIX Mixer", "MIC2_BST2 Playback Switch", "MIC2 Boost"},
+
+ {"SPOLMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
+ {"SPOLMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
+
+ {"SPORMIX Mixer", "SPKVOLL Playback Switch", "Left SPKVOL Mux"},
+ {"SPORMIX Mixer", "SPKVOLR Playback Switch", "Right SPKVOL Mux"},
+
+ {"MONOMIX Mixer", "OUTVOLL Playback Switch", "Left OUTVOL Mux"},
+ {"MONOMIX Mixer", "OUTVOLR Playback Switch", "Right OUTVOL Mux"},
{"SPOL Mux", "SPOLMIX", "SPOLMIX Mixer"},
{"SPOL Mux", "MONOIN_RX", "MONO_IN"},
{"SPOR Mux", "VDAC", "Voice DAC Boost"},
{"SPOR Mux", "DACR", "Right DAC"},
- {"Mono Mux", "MONOMIX", "MONOMIX Mixer"},
- {"Mono Mux", "MONOIN_RX", "MONO_IN"},
- {"Mono Mux", "VDAC", "Voice DAC Boost"},
+ {"MONO Mux", "MONOMIX", "MONOMIX Mixer"},
+ {"MONO Mux", "MONOIN_RX", "MONO_IN"},
+ {"MONO Mux", "VDAC", "Voice DAC Boost"},
- {"Right DAC_HP", "NULL", "Right DAC"},
- {"Left DAC_HP", "NULL", "Left DAC"},
+ {"Right DAC_HP", NULL, "Right DAC"},
+ {"Left DAC_HP", NULL, "Left DAC"},
- {"HPL Mux", "LEFT HPVOL", "Left HP Vol"},
- {"HPL Mux", "LEFT DAC", "Left DAC_HP"},
- {"HPR Mux", "RIGHT HPVOL", "Right HP Vol"},
- {"HPR Mux", "RIGHT DAC", "Right DAC_HP"},
+ {"HPL Mux", "Left HPVOL", "Left HPVOL Mux"},
+ {"HPL Mux", "Left DAC", "Left DAC_HP"},
+ {"HPR Mux", "Right HPVOL", "Right HPVOL Mux"},
+ {"HPR Mux", "Right DAC", "Right DAC_HP"},
- {"SPKL Amp", NULL, "SPOL Mux"},
- {"SPKR Amp", NULL, "SPOR Mux"},
- {"Mono Amp", NULL, "Mono Mux"},
+ {"HP Depop", NULL, "HPL Mux"},
+ {"HP Depop", NULL, "HPR Mux"},
{"AUXO1", NULL, "AXO1MIX Mixer"},
{"AUXO2", NULL, "AXO2MIX Mixer"},
- {"SPOL", NULL, "SPKL Amp"},
- {"SPOR", NULL, "SPKR Amp"},
-
- {"HPOL", NULL, "HPL Mux"},
- {"HPOR", NULL, "HPR Mux"},
-
- {"MONO", NULL, "Mono Amp"}
-};
-static int rt5631_add_widgets(struct snd_soc_codec *codec)
-{
- struct snd_soc_dapm_context *dapm = &codec->dapm;
+ {"SPOL", NULL, "Class D"},
+ {"SPOL", NULL, "SPOL Mux"},
+ {"SPOR", NULL, "Class D"},
+ {"SPOR", NULL, "SPOR Mux"},
- snd_soc_dapm_new_controls(dapm, rt5631_dapm_widgets,
- ARRAY_SIZE(rt5631_dapm_widgets));
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
+ {"HPOL", NULL, "HP Depop"},
+ {"HPOR", NULL, "HP Depop"},
- return 0;
-}
-#if 0
-static int voltab[2][16] =
-{
- //spk
- {0x27, 0x1b, 0x18, 0x15, 0x13, 0x11, 0x0f, 0x0e, 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06},
- //hp
- {0x1f, 0x1c, 0x1a, 0x18, 0x16, 0x14, 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
+ {"MONO", NULL, "MONO Depop"},
+ {"MONO", NULL, "MONO Mux"},
};
-#endif
-
-#if defined(CONFIG_ADJUST_VOL_BY_CODEC)
-static int gvolume = 0;
-static int get_vol(int max, int min, int stage_num, int stage)
-{
- int ret, step=((max-min)<<8)/(stage_num-1);
- if(stage==stage_num-1)
- ret=min;
- else if(stage==0)
- ret=max;
- else {
- ret=(stage_num-stage-1) * step;
- ret >>= 8;
- ret = min+ret;
- }
- DBG("%s(): ret=%02x, max=0x%02x, min=0x%02x, stage_num=%d, stage=%d\n",
- __FUNCTION__,
- ret,
- max,
- min,
- stage_num,
- stage);
- return ret;
-}
-
-static void rt5631_set_volume(int vollevel)
-{
- struct snd_soc_codec *codec = rt5631_codec;
- int tmpvol1, tmpvol2;
-
- //DBG("rt5631_set_volume = %d\n", vollevel);
-
- if (vollevel > 15) vollevel = 8;
- gvolume = vollevel;
-
-// tmpvol1 = voltab[0][vollevel];
-// tmpvol2 = voltab[1][vollevel];
- tmpvol1=get_vol(0x27, DEF_VOL_SPK&0x3f, 16, vollevel);
- tmpvol2=get_vol(0x1f, DEF_VOL&0x1f, 16, vollevel);
-
- if(vollevel == 0){
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL, 0x8080, 0x8080);
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0x8080, 0x8080);
- }
-// else{
-// rt5631_write_mask(codec, RT5631_SPK_OUT_VOL, 0x00, 0x8080);
-// rt5631_write_mask(codec, RT5631_HP_OUT_VOL, 0x00, 0x8080);
-// }
-
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL, ((tmpvol1<<8)|tmpvol1), 0x3f3f);
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL, ((tmpvol2<<8)|tmpvol2), 0x3f3f);
-}
-
-static void rt5631_set_eq(int on)
-{
- struct snd_soc_codec *codec = rt5631_codec;
- unsigned int Reg0C;
-
- Reg0C = rt5631_read(codec, RT5631_STEREO_DAC_VOL_1);
- DBG("------- rt5631_set_eq: read Reg0C = 0x%04x\n", Reg0C);
-
- Reg0C &= 0xFF80;
- if(on) {
- Reg0C |= 0x10;
- } else {
- Reg0C |= 0x00;
- }
-
- DBG("------- rt5631_set_eq: write Reg0C = 0x%04x\n", Reg0C);
- rt5631_write(codec, RT5631_STEREO_DAC_VOL_1, Reg0C);
-}
-#endif
-#if 0
-static void rt5631_set_volume(int vollevel)
-{
- struct snd_soc_codec *codec = rt5631_codec;
- u8 tmpvol1, tmpvol2;
- u16 spk_vol, hp_vol;
-
- DBG("rt5631_set_volume = %d\n", vollevel);
-
- if (vollevel > 15) vollevel = 8;
- gvolume = vollevel;
-
- tmpvol1 = voltab[0][vollevel];
- tmpvol2 = voltab[1][vollevel];
-
- spk_vol = snd_soc_read(codec, RT5631_SPK_OUT_VOL);
- hp_vol = snd_soc_read(codec, RT5631_HP_OUT_VOL);
-
- DBG("\n\nold value: 0x%04x, 0x%04x\n", spk_vol & 0x3F3F, hp_vol & 0x3F3F);
- DBG("new value: 0x%04x\n", (tmpvol1<<8)|tmpvol1, (tmpvol2<<8)|tmpvol2);
-
- spk_vol &= 0x3C3C;
- spk_vol |= (tmpvol1<<8)|tmpvol1;
- hp_vol &= 0x3C3C;
- hp_vol |= (tmpvol2<<8)|tmpvol2;
-
- snd_soc_write(codec, RT5631_SPK_OUT_VOL, spk_vol);
- snd_soc_write(codec, RT5631_HP_OUT_VOL , hp_vol);
-}
-#endif
struct coeff_clk_div {
u32 mclk;
u32 bclk;
u16 reg_val;
};
-/* PLL divisors yes*/
+/* PLL divisors */
struct pll_div {
u32 pll_in;
u32 pll_out;
static const struct pll_div codec_slave_pll_div[] = {
{256000, 2048000, 0x46f0},
{256000, 4096000, 0x3ea0},
- {352800, 5644800, 0x3ea0},
- {512000, 8192000, 0x3ea0},
+ {352800, 5644800, 0x3ea0},
+ {512000, 8192000, 0x3ea0},
{1024000, 8192000, 0x46f0},
{705600, 11289600, 0x3ea0},
{1024000, 16384000, 0x3ea0},
{22579200, 88200 * 64, 88200, 0x0000},
{24576000, 96000 * 32, 96000, 0x1000},
{24576000, 96000 * 64, 96000, 0x0000},
- {22579200, 176400 * 32, 176400, 0x1000},
- {22579200, 176400 * 64, 176400, 0x0000},
- {24576000, 192000 * 32, 192000, 0x1000},
- {24576000, 162000 * 64, 192000, 0x0000},
/* sysclk is 512fs */
{4096000, 8000 * 32, 8000, 0x3000},
{4096000, 8000 * 64, 8000, 0x2000},
return -EINVAL;
}
-static int get_coeff_in_slave_mode(int mclk, int rate)
-{
- return get_coeff(mclk, rate, timesofbclk);
-}
-
-static int get_coeff_in_master_mode(int mclk, int rate, int bclk)
-{
- return get_coeff(mclk, rate, (bclk / rate));
-}
-
-static void rt5631_set_dmic_params(struct snd_soc_codec *codec,
- struct snd_pcm_hw_params *params)
-{
- int rate;
-
- rt5631_write_mask(codec, RT5631_GPIO_CTRL,
- GPIO_PIN_FUN_SEL_GPIO_DIMC | GPIO_DMIC_FUN_SEL_DIMC,
- GPIO_PIN_FUN_SEL_MASK | GPIO_DMIC_FUN_SEL_MASK);
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL, DMIC_ENA, DMIC_ENA_MASK);
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_L_CH_LATCH_FALLING | DMIC_R_CH_LATCH_RISING,
- DMIC_L_CH_LATCH_MASK|DMIC_R_CH_LATCH_MASK);
-
- rate = params_rate(params);
- switch (rate) {
- case 44100:
- case 48000:
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_CLK_CTRL_TO_32FS, DMIC_CLK_CTRL_MASK);
- break;
-
- case 32000:
- case 22050:
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_CLK_CTRL_TO_64FS, DMIC_CLK_CTRL_MASK);
- break;
-
- case 16000:
- case 11025:
- case 8000:
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_CLK_CTRL_TO_128FS, DMIC_CLK_CTRL_MASK);
- break;
-
- default:
- break;
- }
-
- rt5631_write_mask(codec, RT5631_DIG_MIC_CTRL,
- DMIC_L_CH_UNMUTE | DMIC_R_CH_UNMUTE,
- DMIC_L_CH_MUTE_MASK | DMIC_R_CH_MUTE_MASK);
-
- return;
-}
-
static int rt5631_hifi_pcm_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
{
- struct snd_soc_pcm_runtime *rtd = substream->private_data;
- struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_codec *codec = dai->codec;
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- int stream = substream->stream, rate = params_rate(params), coeff;
+ int timesofbclk = 32, coeff;
unsigned int iface = 0;
- pr_debug("enter %s\n", __func__);
+ dev_dbg(codec->dev, "enter %s\n", __func__);
+
+ rt5631->bclk_rate = snd_soc_params_to_bclk(params);
+ if (rt5631->bclk_rate < 0) {
+ dev_err(codec->dev, "Fail to get BCLK rate\n");
+ return rt5631->bclk_rate;
+ }
+ rt5631->rx_rate = params_rate(params);
- if (!rt5631->master)
- coeff = get_coeff_in_slave_mode(rt5631->sysclk, rate);
+ if (rt5631->master)
+ coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
+ rt5631->bclk_rate / rt5631->rx_rate);
else
- coeff = get_coeff_in_master_mode(rt5631->sysclk, rate,
- rate * timesofbclk);
- if (coeff < 0)
- pr_err("%s: get coeff err!\n", __func__);
+ coeff = get_coeff(rt5631->sysclk, rt5631->rx_rate,
+ timesofbclk);
+ if (coeff < 0) {
+ dev_err(codec->dev, "Fail to get coeff\n");
+ return coeff;
+ }
switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S16_LE:
break;
case SNDRV_PCM_FORMAT_S20_3LE:
- iface |= SDP_I2S_DL_20;
+ iface |= RT5631_SDP_I2S_DL_20;
break;
case SNDRV_PCM_FORMAT_S24_LE:
- iface |= SDP_I2S_DL_24;
+ iface |= RT5631_SDP_I2S_DL_24;
break;
case SNDRV_PCM_FORMAT_S8:
- iface |= SDP_I2S_DL_8;
+ iface |= RT5631_SDP_I2S_DL_8;
break;
default:
return -EINVAL;
}
- if (SNDRV_PCM_STREAM_CAPTURE == stream) {
- if (rt5631->dmic_used_flag)
- rt5631_set_dmic_params(codec, params);
- }
-
- rt5631_write_mask(codec, RT5631_SDP_CTRL, iface, SDP_I2S_DL_MASK);
-
- if (coeff >= 0)
- rt5631_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
+ snd_soc_update_bits(codec, RT5631_SDP_CTRL,
+ RT5631_SDP_I2S_DL_MASK, iface);
+ snd_soc_write(codec, RT5631_STEREO_AD_DA_CLK_CTRL,
coeff_div[coeff].reg_val);
return 0;
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
unsigned int iface = 0;
- pr_debug("enter %s\n", __func__);
+ dev_dbg(codec->dev, "enter %s\n", __func__);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
rt5631->master = 1;
break;
case SND_SOC_DAIFMT_CBS_CFS:
- iface |= SDP_MODE_SEL_SLAVE;
+ iface |= RT5631_SDP_MODE_SEL_SLAVE;
rt5631->master = 0;
break;
default:
case SND_SOC_DAIFMT_I2S:
break;
case SND_SOC_DAIFMT_LEFT_J:
- iface |= SDP_I2S_DF_LEFT;
+ iface |= RT5631_SDP_I2S_DF_LEFT;
break;
case SND_SOC_DAIFMT_DSP_A:
- iface |= SDP_I2S_DF_PCM_A;
+ iface |= RT5631_SDP_I2S_DF_PCM_A;
break;
case SND_SOC_DAIFMT_DSP_B:
- iface |= SDP_I2S_DF_PCM_B;
+ iface |= RT5631_SDP_I2S_DF_PCM_B;
break;
default:
return -EINVAL;
case SND_SOC_DAIFMT_NB_NF:
break;
case SND_SOC_DAIFMT_IB_NF:
- iface |= SDP_I2S_BCLK_POL_CTRL;
+ iface |= RT5631_SDP_I2S_BCLK_POL_CTRL;
break;
default:
return -EINVAL;
}
- rt5631_write(codec, RT5631_SDP_CTRL, iface);
+ snd_soc_write(codec, RT5631_SDP_CTRL, iface);
return 0;
}
struct snd_soc_codec *codec = codec_dai->codec;
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- DBG("enter %s, syclk=%d\n", __func__, freq);
+ dev_dbg(codec->dev, "enter %s, syclk=%d\n", __func__, freq);
+
if ((freq >= (256 * 8000)) && (freq <= (512 * 96000))) {
rt5631->sysclk = freq;
return 0;
}
- pr_info("unsupported sysclk freq %u for audio i2s\n", freq);
- pr_info("set sysclk to 24.576Mhz by default\n");
-
- rt5631->sysclk = 24576000;
- return 0;
+ return -EINVAL;
}
static int rt5631_codec_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
int i, ret = -EINVAL;
- DBG(KERN_DEBUG "enter %s\n", __func__);
+ dev_dbg(codec->dev, "enter %s\n", __func__);
+
+ if (!freq_in || !freq_out) {
+ dev_dbg(codec->dev, "PLL disabled\n");
+
+ snd_soc_update_bits(codec, RT5631_GLOBAL_CLK_CTRL,
+ RT5631_SYSCLK_SOUR_SEL_MASK,
+ RT5631_SYSCLK_SOUR_SEL_MCLK);
- if (!freq_in || !freq_out)
return 0;
+ }
if (rt5631->master) {
for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++)
if (freq_in == codec_master_pll_div[i].pll_in &&
freq_out == codec_master_pll_div[i].pll_out) {
- rt5631_write(codec, RT5631_PLL_CTRL,
+ dev_info(codec->dev,
+ "change PLL in master mode\n");
+ snd_soc_write(codec, RT5631_PLL_CTRL,
codec_master_pll_div[i].reg_val);
schedule_timeout_uninterruptible(
msecs_to_jiffies(20));
- rt5631_write(codec, RT5631_GLOBAL_CLK_CTRL,
- SYSCLK_SOUR_SEL_PLL);
- rt5631->pll_used_flag = 1;
+ snd_soc_update_bits(codec,
+ RT5631_GLOBAL_CLK_CTRL,
+ RT5631_SYSCLK_SOUR_SEL_MASK |
+ RT5631_PLLCLK_SOUR_SEL_MASK,
+ RT5631_SYSCLK_SOUR_SEL_PLL |
+ RT5631_PLLCLK_SOUR_SEL_MCLK);
ret = 0;
break;
}
for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++)
if (freq_in == codec_slave_pll_div[i].pll_in &&
freq_out == codec_slave_pll_div[i].pll_out) {
- rt5631_write(codec, RT5631_PLL_CTRL,
+ dev_info(codec->dev,
+ "change PLL in slave mode\n");
+ snd_soc_write(codec, RT5631_PLL_CTRL,
codec_slave_pll_div[i].reg_val);
schedule_timeout_uninterruptible(
msecs_to_jiffies(20));
- rt5631_write(codec, RT5631_GLOBAL_CLK_CTRL,
- SYSCLK_SOUR_SEL_PLL |
- PLLCLK_SOUR_SEL_BITCLK);
- rt5631->pll_used_flag = 1;
+ snd_soc_update_bits(codec,
+ RT5631_GLOBAL_CLK_CTRL,
+ RT5631_SYSCLK_SOUR_SEL_MASK |
+ RT5631_PLLCLK_SOUR_SEL_MASK,
+ RT5631_SYSCLK_SOUR_SEL_PLL |
+ RT5631_PLLCLK_SOUR_SEL_BCLK);
ret = 0;
break;
}
return ret;
}
-#if defined(CONFIG_ADJUST_VOL_BY_CODEC)
-static int rt5631_trigger(struct snd_pcm_substream *substream, int status, struct snd_soc_dai *dai)
-{
- //DBG("rt5631_trigger\n");
- if(status == SNDRV_PCM_TRIGGER_VOLUME){
- //DBG("rt5631_trigger: vol = %d\n", substream->number);
- if(substream->number < 100){
- rt5631_set_volume(substream->number);
- } else {
- if(substream->number == 100) { // eq off
- DBG("---------- eq off\n");
- rt5631_set_eq(0);
- } else { // eq on +6dB
- DBG("---------- eq on\n");
- rt5631_set_eq(1);
- }
- }
- }
-
- return 0;
-}
-#endif
-
-static ssize_t rt5631_index_reg_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- #define IDX_REG_FMT "%02x: %04x\n"
- #define IDX_REG_LEN 9
- unsigned int val;
- int cnt = 0, i;
-
- cnt += sprintf(buf, "RT5631 index register\n");
- for (i = 0; i < 0x55; i++) {
- if (cnt + IDX_REG_LEN >= PAGE_SIZE - 1)
- break;
- val = rt5631_read_index(rt5631_codec, i);
- if (!val)
- continue;
- cnt += sprintf(buf + cnt, IDX_REG_FMT, i, val);
- }
-
- if (cnt >= PAGE_SIZE)
- cnt = PAGE_SIZE - 1;
-
- return cnt;
-}
-static DEVICE_ATTR(index_reg, 0444, rt5631_index_reg_show, NULL);
-
-#define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_192000
-#define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
- SNDRV_PCM_FMTBIT_S20_3LE | \
- SNDRV_PCM_FMTBIT_S24_LE | \
- SNDRV_PCM_FMTBIT_S8)
-
-static struct snd_soc_dai_ops rt5631_ops = {
- .hw_params = rt5631_hifi_pcm_params,
- .set_fmt = rt5631_hifi_codec_set_dai_fmt,
- .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
- .set_pll = rt5631_codec_set_dai_pll,
-#if defined(CONFIG_ADJUST_VOL_BY_CODEC)
- .trigger = rt5631_trigger,
-#endif
-};
-
-static struct snd_soc_dai_driver rt5631_dai[] = {
- {
- .name = "rt5631-hifi",
- .playback = {
- .stream_name = "HIFI Playback",
- .channels_min = 1,
- .channels_max = 2,
- .rates = RT5631_STEREO_RATES,
- .formats = RT5631_FORMAT,
- },
- .capture = {
- .stream_name = "HIFI Capture",
- .channels_min = 1,
- .channels_max = 2,
- .rates = RT5631_STEREO_RATES,
- .formats = RT5631_FORMAT,
- },
- .ops = &rt5631_ops,
- },
-};
-
static int rt5631_set_bias_level(struct snd_soc_codec *codec,
enum snd_soc_bias_level level)
{
+ struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
+
switch (level) {
case SND_SOC_BIAS_ON:
- break;
-
case SND_SOC_BIAS_PREPARE:
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_VREF | PWR_MAIN_BIAS, PWR_VREF | PWR_MAIN_BIAS);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2,
- PWR_MICBIAS1_VOL | PWR_MICBIAS2_VOL,
- PWR_MICBIAS1_VOL | PWR_MICBIAS2_VOL);
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD2,
+ RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL,
+ RT5631_PWR_MICBIAS1_VOL | RT5631_PWR_MICBIAS2_VOL);
break;
case SND_SOC_BIAS_STANDBY:
- // rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD2, 0,
- // PWR_MICBIAS1_VOL | PWR_MICBIAS2_VOL);
- printk("standby rt5631\n");
- rt5631_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
+ if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
+ RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
+ msleep(80);
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_FAST_VREF_CTRL,
+ RT5631_PWR_FAST_VREF_CTRL);
+ regcache_cache_only(rt5631->regmap, false);
+ regcache_sync(rt5631->regmap);
+ }
break;
case SND_SOC_BIAS_OFF:
- rt5631_write_mask(codec, RT5631_SPK_OUT_VOL,
- RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
- rt5631_write_mask(codec, RT5631_HP_OUT_VOL,
- RT_L_MUTE | RT_R_MUTE, RT_L_MUTE | RT_R_MUTE);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
- rt5631_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
+ snd_soc_write(codec, RT5631_PWR_MANAG_ADD1, 0x0000);
+ snd_soc_write(codec, RT5631_PWR_MANAG_ADD2, 0x0000);
+ snd_soc_write(codec, RT5631_PWR_MANAG_ADD3, 0x0000);
+ snd_soc_write(codec, RT5631_PWR_MANAG_ADD4, 0x0000);
break;
default:
static int rt5631_probe(struct snd_soc_codec *codec)
{
struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
- int val;
+ unsigned int val;
int ret;
- ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C);
+
+ codec->control_data = rt5631->regmap;
+
+ ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- codec->cache_bypass = 1;
val = rt5631_read_index(codec, RT5631_ADDA_MIXER_INTL_REG3);
- if(val < 0)
- {
- return -ENODEV;
- }
if (val & 0x0002)
rt5631->codec_version = 1;
else
rt5631->codec_version = 0;
rt5631_reset(codec);
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_VREF | PWR_MAIN_BIAS, PWR_VREF | PWR_MAIN_BIAS);
- schedule_timeout_uninterruptible(msecs_to_jiffies(80));
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3, PWR_FAST_VREF_CTRL,
- PWR_FAST_VREF_CTRL);
- rt5631_reg_init(codec);
- if (rt5631->phone_det_level == 1)
- rt5631_write(codec, RT5631_JACK_DET_CTRL,0x4e80);
- else
- rt5631_write(codec, RT5631_JACK_DET_CTRL,0x4bc0);
-
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS,
+ RT5631_PWR_VREF | RT5631_PWR_MAIN_BIAS);
+ msleep(80);
+ snd_soc_update_bits(codec, RT5631_PWR_MANAG_ADD3,
+ RT5631_PWR_FAST_VREF_CTRL, RT5631_PWR_FAST_VREF_CTRL);
+ /* enable HP zero cross */
+ snd_soc_write(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0f18);
/* power off ClassD auto Recovery */
if (rt5631->codec_version)
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
+ snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
0x2000, 0x2000);
else
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0, 0x2000);
-
- codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
- rt5631_codec = codec;
-
-#if (RT5631_SPK_TIMER == 1)
- /* Timer module installing */
- setup_timer( &spk_timer, spk_timer_callback, 0 );
- DBG( "Starting timer to fire in 5s (%ld)\n", jiffies );
- ret = mod_timer( &spk_timer, jiffies + msecs_to_jiffies(5000) );
- if (ret) printk("Error in mod_timer\n");
-
- INIT_WORK(&spk_work, spk_work_handler);
-#endif
-//bard 7-16 s
- INIT_DELAYED_WORK(&rt5631_delay_cap,rt5631_adc_on);
-//bard 7-16 e
- snd_soc_add_codec_controls(codec, rt5631_snd_controls,
- ARRAY_SIZE(rt5631_snd_controls));
- rt5631_add_widgets(codec);
-
- ret = device_create_file(codec->dev, &dev_attr_index_reg);
- if (ret != 0) {
- dev_err(codec->dev,
- "Failed to create index_reg sysfs files: %d\n", ret);
- return ret;
+ snd_soc_update_bits(codec, RT5631_INT_ST_IRQ_CTRL_2,
+ 0x2000, 0);
+ /* DMIC */
+ if (rt5631->dmic_used_flag) {
+ snd_soc_update_bits(codec, RT5631_GPIO_CTRL,
+ RT5631_GPIO_PIN_FUN_SEL_MASK |
+ RT5631_GPIO_DMIC_FUN_SEL_MASK,
+ RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC |
+ RT5631_GPIO_DMIC_FUN_SEL_DIMC);
+ snd_soc_update_bits(codec, RT5631_DIG_MIC_CTRL,
+ RT5631_DMIC_L_CH_LATCH_MASK |
+ RT5631_DMIC_R_CH_LATCH_MASK,
+ RT5631_DMIC_L_CH_LATCH_FALLING |
+ RT5631_DMIC_R_CH_LATCH_RISING);
}
- DBG("RT5631 initial ok!\n");
+ codec->dapm.bias_level = SND_SOC_BIAS_STANDBY;
return 0;
}
static int rt5631_remove(struct snd_soc_codec *codec)
{
-
-
-#if (RT5631_SPK_TIMER == 1)
- int ret;
- ret = del_timer(&spk_timer);
- if(ret) printk("The timer is still in use...\n");
- DBG("Timer module uninstalling\n");
-#endif
-
-
rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
return 0;
}
+#ifdef CONFIG_PM
static int rt5631_suspend(struct snd_soc_codec *codec)
{
rt5631_set_bias_level(codec, SND_SOC_BIAS_OFF);
static int rt5631_resume(struct snd_soc_codec *codec)
{
- struct rt5631_priv *rt5631 = snd_soc_codec_get_drvdata(codec);
-
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_VREF | PWR_MAIN_BIAS, PWR_VREF | PWR_MAIN_BIAS);
- schedule_timeout_uninterruptible(msecs_to_jiffies(110));
- rt5631_write_mask(codec, RT5631_PWR_MANAG_ADD3,
- PWR_FAST_VREF_CTRL, PWR_FAST_VREF_CTRL);
- rt5631_reg_init(codec);
-
- /* power off ClassD auto Recovery */
- if (rt5631->codec_version)
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0x2000, 0x2000);
- else
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2,
- 0, 0x2000);
-
-#if (RT5631_SPK_TIMER == 1)
- //last_is_spk = !last_is_spk; //wired~, update eqmode right here by spk_timer.
- last_is_spk = -1; //wired~, update eqmode right here by spk_timer. //bard 9-13
-#endif
-
+ rt5631_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
return 0;
}
+#else
+#define rt5631_suspend NULL
+#define rt5631_resume NULL
+#endif
-/*
- * detect short current for mic1
- */
-int rt5631_ext_mic_detect(void)
-{
- struct snd_soc_codec *codec = rt5631_codec;
- int det;
+#define RT5631_STEREO_RATES SNDRV_PCM_RATE_8000_96000
+#define RT5631_FORMAT (SNDRV_PCM_FMTBIT_S16_LE | \
+ SNDRV_PCM_FMTBIT_S20_3LE | \
+ SNDRV_PCM_FMTBIT_S24_LE | \
+ SNDRV_PCM_FMTBIT_S8)
- rt5631_write_mask(codec, RT5631_MIC_CTRL_2, MICBIAS1_S_C_DET_ENA,
- MICBIAS1_S_C_DET_MASK);
- det = rt5631_read(codec, RT5631_INT_ST_IRQ_CTRL_2) & 0x0001;
- rt5631_write_mask(codec, RT5631_INT_ST_IRQ_CTRL_2, 0x0001, 0x00001);
+static const struct snd_soc_dai_ops rt5631_ops = {
+ .hw_params = rt5631_hifi_pcm_params,
+ .set_fmt = rt5631_hifi_codec_set_dai_fmt,
+ .set_sysclk = rt5631_hifi_codec_set_dai_sysclk,
+ .set_pll = rt5631_codec_set_dai_pll,
+};
- return det;
-}
-EXPORT_SYMBOL_GPL(rt5631_ext_mic_detect);
+static struct snd_soc_dai_driver rt5631_dai[] = {
+ {
+ .name = "rt5631-hifi",
+ .id = 1,
+ .playback = {
+ .stream_name = "HIFI Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT5631_STEREO_RATES,
+ .formats = RT5631_FORMAT,
+ },
+ .capture = {
+ .stream_name = "HIFI Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = RT5631_STEREO_RATES,
+ .formats = RT5631_FORMAT,
+ },
+ .ops = &rt5631_ops,
+ },
+};
static struct snd_soc_codec_driver soc_codec_dev_rt5631 = {
.probe = rt5631_probe,
.suspend = rt5631_suspend,
.resume = rt5631_resume,
.set_bias_level = rt5631_set_bias_level,
- .reg_cache_size = ARRAY_SIZE(rt5631_reg),
- .reg_word_size = sizeof(u16),
- .reg_cache_default = rt5631_reg,
- .reg_cache_step = 1,
+ .controls = rt5631_snd_controls,
+ .num_controls = ARRAY_SIZE(rt5631_snd_controls),
+ .dapm_widgets = rt5631_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(rt5631_dapm_widgets),
+ .dapm_routes = rt5631_dapm_routes,
+ .num_dapm_routes = ARRAY_SIZE(rt5631_dapm_routes),
};
-void rt5631_shutdown(struct i2c_client *client)
-{
-
- if (rt5631_codec != NULL)
- rt5631_set_bias_level(rt5631_codec, SND_SOC_BIAS_OFF);
-}
-
-
static const struct i2c_device_id rt5631_i2c_id[] = {
{ "rt5631", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, rt5631_i2c_id);
+static const struct regmap_config rt5631_regmap_config = {
+ .reg_bits = 8,
+ .val_bits = 16,
+
+ .readable_reg = rt5631_readable_register,
+ .volatile_reg = rt5631_volatile_register,
+ .max_register = RT5631_VENDOR_ID2,
+ .reg_defaults = rt5631_reg,
+ .num_reg_defaults = ARRAY_SIZE(rt5631_reg),
+ .cache_type = REGCACHE_RBTREE,
+};
+
static int rt5631_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct rt5631_priv *rt5631;
- struct device_node *node = i2c->dev.of_node;
int ret;
- char reg;
-
- printk("RT5631 Audio Codec %s\n", RT5631_VERSION);
- reg = RT5631_SPK_OUT_VOL;
- ret = i2c_master_recv(i2c, ®, 1);
- if (ret < 0){
- printk("RT5631 probe error\n");
- return ret;
- }
-
- rt5631 = devm_kzalloc(&i2c->dev,sizeof(struct rt5631_priv), GFP_KERNEL);
+ rt5631 = devm_kzalloc(&i2c->dev, sizeof(struct rt5631_priv),
+ GFP_KERNEL);
if (NULL == rt5631)
- return -ENOMEM;
+ return -ENOMEM;
-#ifdef CONFIG_OF
- ret = of_property_read_u32(node,"phone_det_level",&rt5631->phone_det_level);
- if (ret < 0)
- printk("%s get phone_det_level error\n",__func__);
- else
- printk("RT5631 codec: phone_det_level %s",rt5631->phone_det_level ? "HIGH":"LOW");
-#endif
i2c_set_clientdata(i2c, rt5631);
+ rt5631->regmap = devm_regmap_init_i2c(i2c, &rt5631_regmap_config);
+ if (IS_ERR(rt5631->regmap))
+ return PTR_ERR(rt5631->regmap);
+
ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5631,
rt5631_dai, ARRAY_SIZE(rt5631_dai));
-
return ret;
}
static int rt5631_i2c_remove(struct i2c_client *client)
{
snd_soc_unregister_codec(&client->dev);
- kfree(i2c_get_clientdata(client));
return 0;
}
.probe = rt5631_i2c_probe,
.remove = rt5631_i2c_remove,
.id_table = rt5631_i2c_id,
- .shutdown = rt5631_shutdown,
};
-static int __init rt5631_modinit(void)
-{
- return i2c_add_driver(&rt5631_i2c_driver);
-}
-module_init(rt5631_modinit);
-
-static void __exit rt5631_modexit(void)
-{
- i2c_del_driver(&rt5631_i2c_driver);
-}
-module_exit(rt5631_modexit);
+module_i2c_driver(rt5631_i2c_driver);
MODULE_DESCRIPTION("ASoC RT5631 driver");
MODULE_AUTHOR("flove <flove@realtek.com>");
#define RT5631_ADC_CTRL_1 0x12
#define RT5631_ADC_REC_MIXER 0x14
#define RT5631_ADC_CTRL_2 0x16
+#define RT5631_VDAC_DIG_VOL 0x18
#define RT5631_OUTMIXER_L_CTRL 0x1A
#define RT5631_OUTMIXER_R_CTRL 0x1C
#define RT5631_AXO1MIXER_CTRL 0x1E
#define RT5631_SPK_MONO_OUT_CTRL 0x2A
#define RT5631_SPK_MONO_HP_OUT_CTRL 0x2C
#define RT5631_SDP_CTRL 0x34
+#define RT5631_MONO_SDP_CTRL 0x36
#define RT5631_STEREO_AD_DA_CLK_CTRL 0x38
#define RT5631_PWR_MANAG_ADD1 0x3A
#define RT5631_PWR_MANAG_ADD2 0x3B
#define RT5631_INDEX_ADD 0x6A
#define RT5631_INDEX_DATA 0x6C
#define RT5631_EQ_CTRL 0x6E
+#define RT5631_VENDOR_ID 0x7A
#define RT5631_VENDOR_ID1 0x7C
#define RT5631_VENDOR_ID2 0x7E
/* global definition */
-#define RT_L_MUTE (0x1 << 15)
-#define RT_R_MUTE (0x1 << 7)
+#define RT5631_L_MUTE (0x1 << 15)
+#define RT5631_L_MUTE_SHIFT 15
+#define RT5631_L_EN (0x1 << 14)
+#define RT5631_L_EN_SHIFT 14
+#define RT5631_R_MUTE (0x1 << 7)
+#define RT5631_R_MUTE_SHIFT 7
+#define RT5631_R_EN (0x1 << 6)
+#define RT5631_R_EN_SHIFT 6
+#define RT5631_VOL_MASK 0x1f
+#define RT5631_L_VOL_SHIFT 8
+#define RT5631_R_VOL_SHIFT 0
/* Speaker Output Control(0x02) */
-#define SPK_L_VOL_SEL_MASK (0x1 << 14)
-#define SPK_L_VOL_SEL_VMID (0x0 << 14)
-#define SPK_L_VOL_SEL_SPKMIX_L (0x1 << 14)
-#define SPK_R_VOL_SEL_MASK (0x1 << 6)
-#define SPK_R_VOL_SEL_VMID (0x0 << 6)
-#define SPK_R_VOL_SEL_SPKMIX_R (0x1 << 6)
+#define RT5631_SPK_L_VOL_SEL_MASK (0x1 << 14)
+#define RT5631_SPK_L_VOL_SEL_VMID (0x0 << 14)
+#define RT5631_SPK_L_VOL_SEL_SPKMIX_L (0x1 << 14)
+#define RT5631_SPK_R_VOL_SEL_MASK (0x1 << 6)
+#define RT5631_SPK_R_VOL_SEL_VMID (0x0 << 6)
+#define RT5631_SPK_R_VOL_SEL_SPKMIX_R (0x1 << 6)
/* Headphone Output Control(0x04) */
-#define HP_L_VOL_SEL_MASK (0x1 << 14)
-#define HP_L_VOL_SEL_VMID (0x0 << 14)
-#define HP_L_VOL_SEL_OUTMIX_L (0x1 << 14)
-#define HP_R_VOL_SEL_MASK (0x1 << 6)
-#define HP_R_VOL_SEL_VMID (0x0 << 6)
-#define HP_R_VOL_SEL_OUTMIX_R (0x1 << 6)
+#define RT5631_HP_L_VOL_SEL_MASK (0x1 << 14)
+#define RT5631_HP_L_VOL_SEL_VMID (0x0 << 14)
+#define RT5631_HP_L_VOL_SEL_OUTMIX_L (0x1 << 14)
+#define RT5631_HP_R_VOL_SEL_MASK (0x1 << 6)
+#define RT5631_HP_R_VOL_SEL_VMID (0x0 << 6)
+#define RT5631_HP_R_VOL_SEL_OUTMIX_R (0x1 << 6)
/* Output Control for AUXOUT/MONO(0x06) */
-#define AUXOUT_1_VOL_SEL_MASK (0x1 << 14)
-#define AUXOUT_1_VOL_SEL_VMID (0x0 << 14)
-#define AUXOUT_1_VOL_SEL_OUTMIX_L (0x1 << 14)
-#define MUTE_MONO (0x1 << 13)
-#define AUXOUT_2_VOL_SEL_MASK (0x1 << 6)
-#define AUXOUT_2_VOL_SEL_VMID (0x0 << 6)
-#define AUXOUT_2_VOL_SEL_OUTMIX_R (0x1 << 6)
+#define RT5631_AUXOUT_1_VOL_SEL_MASK (0x1 << 14)
+#define RT5631_AUXOUT_1_VOL_SEL_VMID (0x0 << 14)
+#define RT5631_AUXOUT_1_VOL_SEL_OUTMIX_L (0x1 << 14)
+#define RT5631_MUTE_MONO (0x1 << 13)
+#define RT5631_MUTE_MONO_SHIFT 13
+#define RT5631_AUXOUT_2_VOL_SEL_MASK (0x1 << 6)
+#define RT5631_AUXOUT_2_VOL_SEL_VMID (0x0 << 6)
+#define RT5631_AUXOUT_2_VOL_SEL_OUTMIX_R (0x1 << 6)
/* Microphone Input Control 1(0x0E) */
-#define MIC1_DIFF_INPUT_CTRL (0x1 << 15)
-#define MIC2_DIFF_INPUT_CTRL (0x1 << 7)
+#define RT5631_MIC1_DIFF_INPUT_CTRL (0x1 << 15)
+#define RT5631_MIC1_DIFF_INPUT_SHIFT 15
+#define RT5631_MIC2_DIFF_INPUT_CTRL (0x1 << 7)
+#define RT5631_MIC2_DIFF_INPUT_SHIFT 7
+
+/* Stereo DAC Digital Volume2(0x10) */
+#define RT5631_DAC_VOL_MASK 0xff
/* ADC Recording Mixer Control(0x14) */
-#define M_OUTMIXER_L_TO_RECMIXER_L (0x1 << 15)
-#define M_MIC1_TO_RECMIXER_L (0x1 << 14)
-#define M_AXIL_TO_RECMIXER_L (0x1 << 13)
-#define M_MONO_IN_TO_RECMIXER_L (0x1 << 12)
-#define M_OUTMIXER_R_TO_RECMIXER_R (0x1 << 7)
-#define M_MIC2_TO_RECMIXER_R (0x1 << 6)
-#define M_AXIR_TO_RECMIXER_R (0x1 << 5)
-#define M_MONO_IN_TO_RECMIXER_R (0x1 << 4)
+#define RT5631_M_OUTMIXER_L_TO_RECMIXER_L (0x1 << 15)
+#define RT5631_M_OUTMIXL_RECMIXL_BIT 15
+#define RT5631_M_MIC1_TO_RECMIXER_L (0x1 << 14)
+#define RT5631_M_MIC1_RECMIXL_BIT 14
+#define RT5631_M_AXIL_TO_RECMIXER_L (0x1 << 13)
+#define RT5631_M_AXIL_RECMIXL_BIT 13
+#define RT5631_M_MONO_IN_TO_RECMIXER_L (0x1 << 12)
+#define RT5631_M_MONO_IN_RECMIXL_BIT 12
+#define RT5631_M_OUTMIXER_R_TO_RECMIXER_R (0x1 << 7)
+#define RT5631_M_OUTMIXR_RECMIXR_BIT 7
+#define RT5631_M_MIC2_TO_RECMIXER_R (0x1 << 6)
+#define RT5631_M_MIC2_RECMIXR_BIT 6
+#define RT5631_M_AXIR_TO_RECMIXER_R (0x1 << 5)
+#define RT5631_M_AXIR_RECMIXR_BIT 5
+#define RT5631_M_MONO_IN_TO_RECMIXER_R (0x1 << 4)
+#define RT5631_M_MONO_IN_RECMIXR_BIT 4
/* Left Output Mixer Control(0x1A) */
-#define M_RECMIXER_L_TO_OUTMIXER_L (0x1 << 15)
-#define M_RECMIXER_R_TO_OUTMIXER_L (0x1 << 14)
-#define M_DAC_L_TO_OUTMIXER_L (0x1 << 13)
-#define M_MIC1_TO_OUTMIXER_L (0x1 << 12)
-#define M_MIC2_TO_OUTMIXER_L (0x1 << 11)
-#define M_MONO_IN_P_TO_OUTMIXER_L (0x1 << 10)
-#define M_AXIL_TO_OUTMIXER_L (0x1 << 9)
-#define M_AXIR_TO_OUTMIXER_L (0x1 << 8)
+#define RT5631_M_RECMIXER_L_TO_OUTMIXER_L (0x1 << 15)
+#define RT5631_M_RECMIXL_OUTMIXL_BIT 15
+#define RT5631_M_RECMIXER_R_TO_OUTMIXER_L (0x1 << 14)
+#define RT5631_M_RECMIXR_OUTMIXL_BIT 14
+#define RT5631_M_DAC_L_TO_OUTMIXER_L (0x1 << 13)
+#define RT5631_M_DACL_OUTMIXL_BIT 13
+#define RT5631_M_MIC1_TO_OUTMIXER_L (0x1 << 12)
+#define RT5631_M_MIC1_OUTMIXL_BIT 12
+#define RT5631_M_MIC2_TO_OUTMIXER_L (0x1 << 11)
+#define RT5631_M_MIC2_OUTMIXL_BIT 11
+#define RT5631_M_MONO_IN_P_TO_OUTMIXER_L (0x1 << 10)
+#define RT5631_M_MONO_INP_OUTMIXL_BIT 10
+#define RT5631_M_AXIL_TO_OUTMIXER_L (0x1 << 9)
+#define RT5631_M_AXIL_OUTMIXL_BIT 9
+#define RT5631_M_AXIR_TO_OUTMIXER_L (0x1 << 8)
+#define RT5631_M_AXIR_OUTMIXL_BIT 8
+#define RT5631_M_VDAC_TO_OUTMIXER_L (0x1 << 7)
+#define RT5631_M_VDAC_OUTMIXL_BIT 7
/* Right Output Mixer Control(0x1C) */
-#define M_RECMIXER_L_TO_OUTMIXER_R (0x1 << 15)
-#define M_RECMIXER_R_TO_OUTMIXER_R (0x1 << 14)
-#define M_DAC_R_TO_OUTMIXER_R (0x1 << 13)
-#define M_MIC1_TO_OUTMIXER_R (0x1 << 12)
-#define M_MIC2_TO_OUTMIXER_R (0x1 << 11)
-#define M_MONO_IN_N_TO_OUTMIXER_R (0x1 << 10)
-#define M_AXIL_TO_OUTMIXER_R (0x1 << 9)
-#define M_AXIR_TO_OUTMIXER_R (0x1 << 8)
+#define RT5631_M_RECMIXER_L_TO_OUTMIXER_R (0x1 << 15)
+#define RT5631_M_RECMIXL_OUTMIXR_BIT 15
+#define RT5631_M_RECMIXER_R_TO_OUTMIXER_R (0x1 << 14)
+#define RT5631_M_RECMIXR_OUTMIXR_BIT 14
+#define RT5631_M_DAC_R_TO_OUTMIXER_R (0x1 << 13)
+#define RT5631_M_DACR_OUTMIXR_BIT 13
+#define RT5631_M_MIC1_TO_OUTMIXER_R (0x1 << 12)
+#define RT5631_M_MIC1_OUTMIXR_BIT 12
+#define RT5631_M_MIC2_TO_OUTMIXER_R (0x1 << 11)
+#define RT5631_M_MIC2_OUTMIXR_BIT 11
+#define RT5631_M_MONO_IN_N_TO_OUTMIXER_R (0x1 << 10)
+#define RT5631_M_MONO_INN_OUTMIXR_BIT 10
+#define RT5631_M_AXIL_TO_OUTMIXER_R (0x1 << 9)
+#define RT5631_M_AXIL_OUTMIXR_BIT 9
+#define RT5631_M_AXIR_TO_OUTMIXER_R (0x1 << 8)
+#define RT5631_M_AXIR_OUTMIXR_BIT 8
+#define RT5631_M_VDAC_TO_OUTMIXER_R (0x1 << 7)
+#define RT5631_M_VDAC_OUTMIXR_BIT 7
/* Lout Mixer Control(0x1E) */
-#define M_MIC1_TO_AXO1MIXER (0x1 << 15)
-#define M_MIC2_TO_AXO1MIXER (0x1 << 11)
-#define M_OUTMIXER_L_TO_AXO1MIXER (0x1 << 7)
-#define M_OUTMIXER_R_TO_AXO1MIXER (0x1 << 6)
+#define RT5631_M_MIC1_TO_AXO1MIXER (0x1 << 15)
+#define RT5631_M_MIC1_AXO1MIX_BIT 15
+#define RT5631_M_MIC2_TO_AXO1MIXER (0x1 << 11)
+#define RT5631_M_MIC2_AXO1MIX_BIT 11
+#define RT5631_M_OUTMIXER_L_TO_AXO1MIXER (0x1 << 7)
+#define RT5631_M_OUTMIXL_AXO1MIX_BIT 7
+#define RT5631_M_OUTMIXER_R_TO_AXO1MIXER (0x1 << 6)
+#define RT5631_M_OUTMIXR_AXO1MIX_BIT 6
/* Rout Mixer Control(0x20) */
-#define M_MIC1_TO_AXO2MIXER (0x1 << 15)
-#define M_MIC2_TO_AXO2MIXER (0x1 << 11)
-#define M_OUTMIXER_L_TO_AXO2MIXER (0x1 << 7)
-#define M_OUTMIXER_R_TO_AXO2MIXER (0x1 << 6)
+#define RT5631_M_MIC1_TO_AXO2MIXER (0x1 << 15)
+#define RT5631_M_MIC1_AXO2MIX_BIT 15
+#define RT5631_M_MIC2_TO_AXO2MIXER (0x1 << 11)
+#define RT5631_M_MIC2_AXO2MIX_BIT 11
+#define RT5631_M_OUTMIXER_L_TO_AXO2MIXER (0x1 << 7)
+#define RT5631_M_OUTMIXL_AXO2MIX_BIT 7
+#define RT5631_M_OUTMIXER_R_TO_AXO2MIXER (0x1 << 6)
+#define RT5631_M_OUTMIXR_AXO2MIX_BIT 6
/* Micphone Input Control 2(0x22) */
-#define MIC_BIAS_90_PRECNET_AVDD 1
-#define MIC_BIAS_75_PRECNET_AVDD 2
-
-#define MIC1_BOOST_CTRL_MASK (0xf << 12)
-#define MIC1_BOOST_CTRL_BYPASS (0x0 << 12)
-#define MIC1_BOOST_CTRL_20DB (0x1 << 12)
-#define MIC1_BOOST_CTRL_24DB (0x2 << 12)
-#define MIC1_BOOST_CTRL_30DB (0x3 << 12)
-#define MIC1_BOOST_CTRL_35DB (0x4 << 12)
-#define MIC1_BOOST_CTRL_40DB (0x5 << 12)
-#define MIC1_BOOST_CTRL_34DB (0x6 << 12)
-#define MIC1_BOOST_CTRL_50DB (0x7 << 12)
-#define MIC1_BOOST_CTRL_52DB (0x8 << 12)
-
-#define MIC2_BOOST_CTRL_MASK (0xf << 8)
-#define MIC2_BOOST_CTRL_BYPASS (0x0 << 8)
-#define MIC2_BOOST_CTRL_20DB (0x1 << 8)
-#define MIC2_BOOST_CTRL_24DB (0x2 << 8)
-#define MIC2_BOOST_CTRL_30DB (0x3 << 8)
-#define MIC2_BOOST_CTRL_35DB (0x4 << 8)
-#define MIC2_BOOST_CTRL_40DB (0x5 << 8)
-#define MIC2_BOOST_CTRL_34DB (0x6 << 8)
-#define MIC2_BOOST_CTRL_50DB (0x7 << 8)
-#define MIC2_BOOST_CTRL_52DB (0x8 << 8)
-
-#define MICBIAS1_VOLT_CTRL_MASK (0x1 << 7)
-#define MICBIAS1_VOLT_CTRL_90P (0x0 << 7)
-#define MICBIAS1_VOLT_CTRL_75P (0x1 << 7)
-
-#define MICBIAS1_S_C_DET_MASK (0x1 << 6)
-#define MICBIAS1_S_C_DET_DIS (0x0 << 6)
-#define MICBIAS1_S_C_DET_ENA (0x1 << 6)
-
-#define MICBIAS1_SHORT_CURR_DET_MASK (0x3 << 4)
-#define MICBIAS1_SHORT_CURR_DET_600UA (0x0 << 4)
-#define MICBIAS1_SHORT_CURR_DET_1500UA (0x1 << 4)
-#define MICBIAS1_SHORT_CURR_DET_2000UA (0x2 << 4)
-
-#define MICBIAS2_VOLT_CTRL_MASK (0x1 << 3)
-#define MICBIAS2_VOLT_CTRL_90P (0x0 << 3)
-#define MICBIAS2_VOLT_CTRL_75P (0x1 << 3)
-
-#define MICBIAS2_S_C_DET_MASK (0x1 << 2)
-#define MICBIAS2_S_C_DET_DIS (0x0 << 2)
-#define MICBIAS2_S_C_DET_ENA (0x1 << 2)
-
-#define MICBIAS2_SHORT_CURR_DET_MASK (0x3)
-#define MICBIAS2_SHORT_CURR_DET_600UA (0x0)
-#define MICBIAS2_SHORT_CURR_DET_1500UA (0x1)
-#define MICBIAS2_SHORT_CURR_DET_2000UA (0x2)
+#define RT5631_MIC_BIAS_90_PRECNET_AVDD 1
+#define RT5631_MIC_BIAS_75_PRECNET_AVDD 2
+
+#define RT5631_MIC1_BOOST_CTRL_MASK (0xf << 12)
+#define RT5631_MIC1_BOOST_CTRL_BYPASS (0x0 << 12)
+#define RT5631_MIC1_BOOST_CTRL_20DB (0x1 << 12)
+#define RT5631_MIC1_BOOST_CTRL_24DB (0x2 << 12)
+#define RT5631_MIC1_BOOST_CTRL_30DB (0x3 << 12)
+#define RT5631_MIC1_BOOST_CTRL_35DB (0x4 << 12)
+#define RT5631_MIC1_BOOST_CTRL_40DB (0x5 << 12)
+#define RT5631_MIC1_BOOST_CTRL_34DB (0x6 << 12)
+#define RT5631_MIC1_BOOST_CTRL_50DB (0x7 << 12)
+#define RT5631_MIC1_BOOST_CTRL_52DB (0x8 << 12)
+#define RT5631_MIC1_BOOST_SHIFT 12
+
+#define RT5631_MIC2_BOOST_CTRL_MASK (0xf << 8)
+#define RT5631_MIC2_BOOST_CTRL_BYPASS (0x0 << 8)
+#define RT5631_MIC2_BOOST_CTRL_20DB (0x1 << 8)
+#define RT5631_MIC2_BOOST_CTRL_24DB (0x2 << 8)
+#define RT5631_MIC2_BOOST_CTRL_30DB (0x3 << 8)
+#define RT5631_MIC2_BOOST_CTRL_35DB (0x4 << 8)
+#define RT5631_MIC2_BOOST_CTRL_40DB (0x5 << 8)
+#define RT5631_MIC2_BOOST_CTRL_34DB (0x6 << 8)
+#define RT5631_MIC2_BOOST_CTRL_50DB (0x7 << 8)
+#define RT5631_MIC2_BOOST_CTRL_52DB (0x8 << 8)
+#define RT5631_MIC2_BOOST_SHIFT 8
+
+#define RT5631_MICBIAS1_VOLT_CTRL_MASK (0x1 << 7)
+#define RT5631_MICBIAS1_VOLT_CTRL_90P (0x0 << 7)
+#define RT5631_MICBIAS1_VOLT_CTRL_75P (0x1 << 7)
+
+#define RT5631_MICBIAS1_S_C_DET_MASK (0x1 << 6)
+#define RT5631_MICBIAS1_S_C_DET_DIS (0x0 << 6)
+#define RT5631_MICBIAS1_S_C_DET_ENA (0x1 << 6)
+
+#define RT5631_MICBIAS1_SHORT_CURR_DET_MASK (0x3 << 4)
+#define RT5631_MICBIAS1_SHORT_CURR_DET_600UA (0x0 << 4)
+#define RT5631_MICBIAS1_SHORT_CURR_DET_1500UA (0x1 << 4)
+#define RT5631_MICBIAS1_SHORT_CURR_DET_2000UA (0x2 << 4)
+
+#define RT5631_MICBIAS2_VOLT_CTRL_MASK (0x1 << 3)
+#define RT5631_MICBIAS2_VOLT_CTRL_90P (0x0 << 3)
+#define RT5631_MICBIAS2_VOLT_CTRL_75P (0x1 << 3)
+
+#define RT5631_MICBIAS2_S_C_DET_MASK (0x1 << 2)
+#define RT5631_MICBIAS2_S_C_DET_DIS (0x0 << 2)
+#define RT5631_MICBIAS2_S_C_DET_ENA (0x1 << 2)
+
+#define RT5631_MICBIAS2_SHORT_CURR_DET_MASK (0x3)
+#define RT5631_MICBIAS2_SHORT_CURR_DET_600UA (0x0)
+#define RT5631_MICBIAS2_SHORT_CURR_DET_1500UA (0x1)
+#define RT5631_MICBIAS2_SHORT_CURR_DET_2000UA (0x2)
/* Digital Microphone Control(0x24) */
-#define DMIC_ENA_MASK (0x1 << 15)
+#define RT5631_DMIC_ENA_MASK (0x1 << 15)
+#define RT5631_DMIC_ENA_SHIFT 15
/* DMIC_ENA: DMIC to ADC Digital filter */
-#define DMIC_ENA (0x1 << 15)
+#define RT5631_DMIC_ENA (0x1 << 15)
/* DMIC_DIS: ADC mixer to ADC Digital filter */
-#define DMIC_DIS (0x0 << 15)
-
-#define DMIC_L_CH_MUTE_MASK (0x1 << 13)
-#define DMIC_L_CH_UNMUTE (0x0 << 13)
-#define DMIC_L_CH_MUTE (0x1 << 13)
-
-#define DMIC_R_CH_MUTE_MASK (0x1 << 12)
-#define DMIC_R_CH_UNMUTE (0x0 << 12)
-#define DMIC_R_CH_MUTE (0x1 << 12)
-
-#define DMIC_L_CH_LATCH_MASK (0x1 << 9)
-#define DMIC_L_CH_LATCH_RISING (0x1 << 9)
-#define DMIC_L_CH_LATCH_FALLING (0x0 << 9)
-
-#define DMIC_R_CH_LATCH_MASK (0x1 << 8)
-#define DMIC_R_CH_LATCH_RISING (0x1 << 8)
-#define DMIC_R_CH_LATCH_FALLING (0x0 << 8)
-
-#define DMIC_CLK_CTRL_MASK (0x3 << 4)
-#define DMIC_CLK_CTRL_TO_128FS (0x0 << 4)
-#define DMIC_CLK_CTRL_TO_64FS (0x1 << 4)
-#define DMIC_CLK_CTRL_TO_32FS (0x2 << 4)
+#define RT5631_DMIC_DIS (0x0 << 15)
+#define RT5631_DMIC_L_CH_MUTE (0x1 << 13)
+#define RT5631_DMIC_L_CH_MUTE_SHIFT 13
+#define RT5631_DMIC_R_CH_MUTE (0x1 << 12)
+#define RT5631_DMIC_R_CH_MUTE_SHIFT 12
+#define RT5631_DMIC_L_CH_LATCH_MASK (0x1 << 9)
+#define RT5631_DMIC_L_CH_LATCH_RISING (0x1 << 9)
+#define RT5631_DMIC_L_CH_LATCH_FALLING (0x0 << 9)
+#define RT5631_DMIC_R_CH_LATCH_MASK (0x1 << 8)
+#define RT5631_DMIC_R_CH_LATCH_RISING (0x1 << 8)
+#define RT5631_DMIC_R_CH_LATCH_FALLING (0x0 << 8)
+#define RT5631_DMIC_CLK_CTRL_MASK (0x3 << 4)
+#define RT5631_DMIC_CLK_CTRL_TO_128FS (0x0 << 4)
+#define RT5631_DMIC_CLK_CTRL_TO_64FS (0x1 << 4)
+#define RT5631_DMIC_CLK_CTRL_TO_32FS (0x2 << 4)
+
+/* Microphone Input Volume(0x26) */
+#define RT5631_MONO_DIFF_INPUT_SHIFT 15
/* Speaker Mixer Control(0x28) */
-#define M_RECMIXER_L_TO_SPKMIXER_L (0x1 << 15)
-#define M_MIC1_P_TO_SPKMIXER_L (0x1 << 14)
-#define M_DAC_L_TO_SPKMIXER_L (0x1 << 13)
-#define M_OUTMIXER_L_TO_SPKMIXER_L (0x1 << 12)
-
-#define M_RECMIXER_R_TO_SPKMIXER_R (0x1 << 7)
-#define M_MIC2_P_TO_SPKMIXER_R (0x1 << 6)
-#define M_DAC_R_TO_SPKMIXER_R (0x1 << 5)
-#define M_OUTMIXER_R_TO_SPKMIXER_R (0x1 << 4)
+#define RT5631_M_RECMIXER_L_TO_SPKMIXER_L (0x1 << 15)
+#define RT5631_M_RECMIXL_SPKMIXL_BIT 15
+#define RT5631_M_MIC1_P_TO_SPKMIXER_L (0x1 << 14)
+#define RT5631_M_MIC1P_SPKMIXL_BIT 14
+#define RT5631_M_DAC_L_TO_SPKMIXER_L (0x1 << 13)
+#define RT5631_M_DACL_SPKMIXL_BIT 13
+#define RT5631_M_OUTMIXER_L_TO_SPKMIXER_L (0x1 << 12)
+#define RT5631_M_OUTMIXL_SPKMIXL_BIT 12
+
+#define RT5631_M_RECMIXER_R_TO_SPKMIXER_R (0x1 << 7)
+#define RT5631_M_RECMIXR_SPKMIXR_BIT 7
+#define RT5631_M_MIC2_P_TO_SPKMIXER_R (0x1 << 6)
+#define RT5631_M_MIC2P_SPKMIXR_BIT 6
+#define RT5631_M_DAC_R_TO_SPKMIXER_R (0x1 << 5)
+#define RT5631_M_DACR_SPKMIXR_BIT 5
+#define RT5631_M_OUTMIXER_R_TO_SPKMIXER_R (0x1 << 4)
+#define RT5631_M_OUTMIXR_SPKMIXR_BIT 4
/* Speaker/Mono Output Control(0x2A) */
-#define M_SPKVOL_L_TO_SPOL_MIXER (0x1 << 15)
-#define M_SPKVOL_R_TO_SPOL_MIXER (0x1 << 14)
-#define M_SPKVOL_L_TO_SPOR_MIXER (0x1 << 13)
-#define M_SPKVOL_R_TO_SPOR_MIXER (0x1 << 12)
-#define M_OUTVOL_L_TO_MONOMIXER (0x1 << 11)
-#define M_OUTVOL_R_TO_MONOMIXER (0x1 << 10)
+#define RT5631_M_SPKVOL_L_TO_SPOL_MIXER (0x1 << 15)
+#define RT5631_M_SPKVOLL_SPOLMIX_BIT 15
+#define RT5631_M_SPKVOL_R_TO_SPOL_MIXER (0x1 << 14)
+#define RT5631_M_SPKVOLR_SPOLMIX_BIT 14
+#define RT5631_M_SPKVOL_L_TO_SPOR_MIXER (0x1 << 13)
+#define RT5631_M_SPKVOLL_SPORMIX_BIT 13
+#define RT5631_M_SPKVOL_R_TO_SPOR_MIXER (0x1 << 12)
+#define RT5631_M_SPKVOLR_SPORMIX_BIT 12
+#define RT5631_M_OUTVOL_L_TO_MONOMIXER (0x1 << 11)
+#define RT5631_M_OUTVOLL_MONOMIX_BIT 11
+#define RT5631_M_OUTVOL_R_TO_MONOMIXER (0x1 << 10)
+#define RT5631_M_OUTVOLR_MONOMIX_BIT 10
/* Speaker/Mono/HP Output Control(0x2C) */
-#define SPK_L_MUX_SEL_MASK (0x3 << 14)
-#define SPK_L_MUX_SEL_SPKMIXER_L (0x0 << 14)
-#define SPK_L_MUX_SEL_MONO_IN (0x1 << 14)
-#define SPK_L_MUX_SEL_DAC_L (0x3 << 14)
-
-#define SPK_R_MUX_SEL_MASK (0x3 << 10)
-#define SPK_R_MUX_SEL_SPKMIXER_R (0x0 << 10)
-#define SPK_R_MUX_SEL_MONO_IN (0x1 << 10)
-#define SPK_R_MUX_SEL_DAC_R (0x3 << 10)
-
-#define MONO_MUX_SEL_MASK (0x3 << 6)
-#define MONO_MUX_SEL_MONOMIXER (0x0 << 6)
-#define MONO_MUX_SEL_MONO_IN (0x1 << 6)
-
-#define HP_L_MUX_SEL_MASK (0x1 << 3)
-#define HP_L_MUX_SEL_HPVOL_L (0x0 << 3)
-#define HP_L_MUX_SEL_DAC_L (0x1 << 3)
-
-#define HP_R_MUX_SEL_MASK (0x1 << 2)
-#define HP_R_MUX_SEL_HPVOL_R (0x0 << 2)
-#define HP_R_MUX_SEL_DAC_R (0x1 << 2)
+#define RT5631_SPK_L_MUX_SEL_MASK (0x3 << 14)
+#define RT5631_SPK_L_MUX_SEL_SPKMIXER_L (0x0 << 14)
+#define RT5631_SPK_L_MUX_SEL_MONO_IN (0x1 << 14)
+#define RT5631_SPK_L_MUX_SEL_DAC_L (0x3 << 14)
+#define RT5631_SPK_L_MUX_SEL_SHIFT 14
+
+#define RT5631_SPK_R_MUX_SEL_MASK (0x3 << 10)
+#define RT5631_SPK_R_MUX_SEL_SPKMIXER_R (0x0 << 10)
+#define RT5631_SPK_R_MUX_SEL_MONO_IN (0x1 << 10)
+#define RT5631_SPK_R_MUX_SEL_DAC_R (0x3 << 10)
+#define RT5631_SPK_R_MUX_SEL_SHIFT 10
+
+#define RT5631_MONO_MUX_SEL_MASK (0x3 << 6)
+#define RT5631_MONO_MUX_SEL_MONOMIXER (0x0 << 6)
+#define RT5631_MONO_MUX_SEL_MONO_IN (0x1 << 6)
+#define RT5631_MONO_MUX_SEL_SHIFT 6
+
+#define RT5631_HP_L_MUX_SEL_MASK (0x1 << 3)
+#define RT5631_HP_L_MUX_SEL_HPVOL_L (0x0 << 3)
+#define RT5631_HP_L_MUX_SEL_DAC_L (0x1 << 3)
+#define RT5631_HP_L_MUX_SEL_SHIFT 3
+
+#define RT5631_HP_R_MUX_SEL_MASK (0x1 << 2)
+#define RT5631_HP_R_MUX_SEL_HPVOL_R (0x0 << 2)
+#define RT5631_HP_R_MUX_SEL_DAC_R (0x1 << 2)
+#define RT5631_HP_R_MUX_SEL_SHIFT 2
/* Stereo I2S Serial Data Port Control(0x34) */
-#define SDP_MODE_SEL_MASK (0x1 << 15)
-#define SDP_MODE_SEL_MASTER (0x0 << 15)
-#define SDP_MODE_SEL_SLAVE (0x1 << 15)
-
-#define SDP_ADC_CPS_SEL_MASK (0x3 << 10)
-#define SDP_ADC_CPS_SEL_OFF (0x0 << 10)
-#define SDP_ADC_CPS_SEL_U_LAW (0x1 << 10)
-#define SDP_ADC_CPS_SEL_A_LAW (0x2 << 10)
-
-#define SDP_DAC_CPS_SEL_MASK (0x3 << 8)
-#define SDP_DAC_CPS_SEL_OFF (0x0 << 8)
-#define SDP_DAC_CPS_SEL_U_LAW (0x1 << 8)
-#define SDP_DAC_CPS_SEL_A_LAW (0x2 << 8)
+#define RT5631_SDP_MODE_SEL_MASK (0x1 << 15)
+#define RT5631_SDP_MODE_SEL_MASTER (0x0 << 15)
+#define RT5631_SDP_MODE_SEL_SLAVE (0x1 << 15)
+
+#define RT5631_SDP_ADC_CPS_SEL_MASK (0x3 << 10)
+#define RT5631_SDP_ADC_CPS_SEL_OFF (0x0 << 10)
+#define RT5631_SDP_ADC_CPS_SEL_U_LAW (0x1 << 10)
+#define RT5631_SDP_ADC_CPS_SEL_A_LAW (0x2 << 10)
+
+#define RT5631_SDP_DAC_CPS_SEL_MASK (0x3 << 8)
+#define RT5631_SDP_DAC_CPS_SEL_OFF (0x0 << 8)
+#define RT5631_SDP_DAC_CPS_SEL_U_LAW (0x1 << 8)
+#define RT5631_SDP_DAC_CPS_SEL_A_LAW (0x2 << 8)
/* 0:Normal 1:Invert */
-#define SDP_I2S_BCLK_POL_CTRL (0x1 << 7)
+#define RT5631_SDP_I2S_BCLK_POL_CTRL (0x1 << 7)
/* 0:Normal 1:Invert */
-#define SDP_DAC_R_INV (0x1 << 6)
+#define RT5631_SDP_DAC_R_INV (0x1 << 6)
/* 0:ADC data appear at left phase of LRCK
* 1:ADC data appear at right phase of LRCK
*/
-#define SDP_ADC_DATA_L_R_SWAP (0x1 << 5)
+#define RT5631_SDP_ADC_DATA_L_R_SWAP (0x1 << 5)
/* 0:DAC data appear at left phase of LRCK
* 1:DAC data appear at right phase of LRCK
*/
-#define SDP_DAC_DATA_L_R_SWAP (0x1 << 4)
+#define RT5631_SDP_DAC_DATA_L_R_SWAP (0x1 << 4)
/* Data Length Slection */
-#define SDP_I2S_DL_MASK (0x3 << 2)
-#define SDP_I2S_DL_16 (0x0 << 2)
-#define SDP_I2S_DL_20 (0x1 << 2)
-#define SDP_I2S_DL_24 (0x2 << 2)
-#define SDP_I2S_DL_8 (0x3 << 2)
+#define RT5631_SDP_I2S_DL_MASK (0x3 << 2)
+#define RT5631_SDP_I2S_DL_16 (0x0 << 2)
+#define RT5631_SDP_I2S_DL_20 (0x1 << 2)
+#define RT5631_SDP_I2S_DL_24 (0x2 << 2)
+#define RT5631_SDP_I2S_DL_8 (0x3 << 2)
/* PCM Data Format Selection */
-#define SDP_I2S_DF_MASK (0x3)
-#define SDP_I2S_DF_I2S (0x0)
-#define SDP_I2S_DF_LEFT (0x1)
-#define SDP_I2S_DF_PCM_A (0x2)
-#define SDP_I2S_DF_PCM_B (0x3)
+#define RT5631_SDP_I2S_DF_MASK (0x3)
+#define RT5631_SDP_I2S_DF_I2S (0x0)
+#define RT5631_SDP_I2S_DF_LEFT (0x1)
+#define RT5631_SDP_I2S_DF_PCM_A (0x2)
+#define RT5631_SDP_I2S_DF_PCM_B (0x3)
/* Stereo AD/DA Clock Control(0x38h) */
-#define I2S_PRE_DIV_MASK (0x7 << 13)
-#define I2S_PRE_DIV_1 (0x0 << 13)
-#define I2S_PRE_DIV_2 (0x1 << 13)
-#define I2S_PRE_DIV_4 (0x2 << 13)
-#define I2S_PRE_DIV_8 (0x3 << 13)
-#define I2S_PRE_DIV_16 (0x4 << 13)
-#define I2S_PRE_DIV_32 (0x5 << 13)
+#define RT5631_I2S_PRE_DIV_MASK (0x7 << 13)
+#define RT5631_I2S_PRE_DIV_1 (0x0 << 13)
+#define RT5631_I2S_PRE_DIV_2 (0x1 << 13)
+#define RT5631_I2S_PRE_DIV_4 (0x2 << 13)
+#define RT5631_I2S_PRE_DIV_8 (0x3 << 13)
+#define RT5631_I2S_PRE_DIV_16 (0x4 << 13)
+#define RT5631_I2S_PRE_DIV_32 (0x5 << 13)
/* CLOCK RELATIVE OF BCLK AND LCRK */
-#define I2S_LRCK_SEL_N_BCLK_MASK (0x1 << 12)
-#define I2S_LRCK_SEL_64_BCLK (0x0 << 12) /* 64FS */
-#define I2S_LRCK_SEL_32_BCLK (0x1 << 12) /* 32FS */
+#define RT5631_I2S_LRCK_SEL_N_BCLK_MASK (0x1 << 12)
+#define RT5631_I2S_LRCK_SEL_64_BCLK (0x0 << 12) /* 64FS */
+#define RT5631_I2S_LRCK_SEL_32_BCLK (0x1 << 12) /* 32FS */
-#define DAC_OSR_SEL_MASK (0x3 << 10)
-#define DAC_OSR_SEL_128FS (0x3 << 10)
-#define DAC_OSR_SEL_64FS (0x3 << 10)
-#define DAC_OSR_SEL_32FS (0x3 << 10)
-#define DAC_OSR_SEL_16FS (0x3 << 10)
+#define RT5631_DAC_OSR_SEL_MASK (0x3 << 10)
+#define RT5631_DAC_OSR_SEL_128FS (0x3 << 10)
+#define RT5631_DAC_OSR_SEL_64FS (0x3 << 10)
+#define RT5631_DAC_OSR_SEL_32FS (0x3 << 10)
+#define RT5631_DAC_OSR_SEL_16FS (0x3 << 10)
-#define ADC_OSR_SEL_MASK (0x3 << 8)
-#define ADC_OSR_SEL_128FS (0x3 << 8)
-#define ADC_OSR_SEL_64FS (0x3 << 8)
-#define ADC_OSR_SEL_32FS (0x3 << 8)
-#define ADC_OSR_SEL_16FS (0x3 << 8)
+#define RT5631_ADC_OSR_SEL_MASK (0x3 << 8)
+#define RT5631_ADC_OSR_SEL_128FS (0x3 << 8)
+#define RT5631_ADC_OSR_SEL_64FS (0x3 << 8)
+#define RT5631_ADC_OSR_SEL_32FS (0x3 << 8)
+#define RT5631_ADC_OSR_SEL_16FS (0x3 << 8)
-#define ADDA_FILTER_CLK_SEL_256FS (0 << 7) /* 256FS */
-#define ADDA_FILTER_CLK_SEL_384FS (1 << 7) /* 384FS */
+#define RT5631_ADDA_FILTER_CLK_SEL_256FS (0 << 7) /* 256FS */
+#define RT5631_ADDA_FILTER_CLK_SEL_384FS (1 << 7) /* 384FS */
/* Power managment addition 1 (0x3A) */
-#define PWR_MAIN_I2S_EN (0x1 << 15)
-#define PWR_CLASS_D (0x1 << 12)
-#define PWR_ADC_L_CLK (0x1 << 11)
-#define PWR_ADC_R_CLK (0x1 << 10)
-#define PWR_DAC_L_CLK (0x1 << 9)
-#define PWR_DAC_R_CLK (0x1 << 8)
-#define PWR_DAC_REF (0x1 << 7)
-#define PWR_DAC_L_TO_MIXER (0x1 << 6)
-#define PWR_DAC_R_TO_MIXER (0x1 << 5)
+#define RT5631_PWR_MAIN_I2S_EN (0x1 << 15)
+#define RT5631_PWR_MAIN_I2S_BIT 15
+#define RT5631_PWR_CLASS_D (0x1 << 12)
+#define RT5631_PWR_CLASS_D_BIT 12
+#define RT5631_PWR_ADC_L_CLK (0x1 << 11)
+#define RT5631_PWR_ADC_L_CLK_BIT 11
+#define RT5631_PWR_ADC_R_CLK (0x1 << 10)
+#define RT5631_PWR_ADC_R_CLK_BIT 10
+#define RT5631_PWR_DAC_L_CLK (0x1 << 9)
+#define RT5631_PWR_DAC_L_CLK_BIT 9
+#define RT5631_PWR_DAC_R_CLK (0x1 << 8)
+#define RT5631_PWR_DAC_R_CLK_BIT 8
+#define RT5631_PWR_DAC_REF (0x1 << 7)
+#define RT5631_PWR_DAC_REF_BIT 7
+#define RT5631_PWR_DAC_L_TO_MIXER (0x1 << 6)
+#define RT5631_PWR_DAC_L_TO_MIXER_BIT 6
+#define RT5631_PWR_DAC_R_TO_MIXER (0x1 << 5)
+#define RT5631_PWR_DAC_R_TO_MIXER_BIT 5
/* Power managment addition 2 (0x3B) */
-#define PWR_OUTMIXER_L (0x1 << 15)
-#define PWR_OUTMIXER_R (0x1 << 14)
-#define PWR_SPKMIXER_L (0x1 << 13)
-#define PWR_SPKMIXER_R (0x1 << 12)
-#define PWR_RECMIXER_L (0x1 << 11)
-#define PWR_RECMIXER_R (0x1 << 10)
-#define PWR_MIC1_BOOT_GAIN (0x1 << 5)
-#define PWR_MIC2_BOOT_GAIN (0x1 << 4)
-#define PWR_MICBIAS1_VOL (0x1 << 3)
-#define PWR_MICBIAS2_VOL (0x1 << 2)
-#define PWR_PLL (0x1 << 1)
+#define RT5631_PWR_OUTMIXER_L (0x1 << 15)
+#define RT5631_PWR_OUTMIXER_L_BIT 15
+#define RT5631_PWR_OUTMIXER_R (0x1 << 14)
+#define RT5631_PWR_OUTMIXER_R_BIT 14
+#define RT5631_PWR_SPKMIXER_L (0x1 << 13)
+#define RT5631_PWR_SPKMIXER_L_BIT 13
+#define RT5631_PWR_SPKMIXER_R (0x1 << 12)
+#define RT5631_PWR_SPKMIXER_R_BIT 12
+#define RT5631_PWR_RECMIXER_L (0x1 << 11)
+#define RT5631_PWR_RECMIXER_L_BIT 11
+#define RT5631_PWR_RECMIXER_R (0x1 << 10)
+#define RT5631_PWR_RECMIXER_R_BIT 10
+#define RT5631_PWR_MIC1_BOOT_GAIN (0x1 << 5)
+#define RT5631_PWR_MIC1_BOOT_GAIN_BIT 5
+#define RT5631_PWR_MIC2_BOOT_GAIN (0x1 << 4)
+#define RT5631_PWR_MIC2_BOOT_GAIN_BIT 4
+#define RT5631_PWR_MICBIAS1_VOL (0x1 << 3)
+#define RT5631_PWR_MICBIAS1_VOL_BIT 3
+#define RT5631_PWR_MICBIAS2_VOL (0x1 << 2)
+#define RT5631_PWR_MICBIAS2_VOL_BIT 2
+#define RT5631_PWR_PLL1 (0x1 << 1)
+#define RT5631_PWR_PLL1_BIT 1
+#define RT5631_PWR_PLL2 (0x1 << 0)
+#define RT5631_PWR_PLL2_BIT 0
/* Power managment addition 3(0x3C) */
-#define PWR_VREF (0x1 << 15)
-#define PWR_FAST_VREF_CTRL (0x1 << 14)
-#define PWR_MAIN_BIAS (0x1 << 13)
-#define PWR_AXO1MIXER (0x1 << 11)
-#define PWR_AXO2MIXER (0x1 << 10)
-#define PWR_MONOMIXER (0x1 << 9)
-#define PWR_MONO_DEPOP_DIS (0x1 << 8)
-#define PWR_MONO_AMP_EN (0x1 << 7)
-#define PWR_CHARGE_PUMP (0x1 << 4)
-#define PWR_HP_L_AMP (0x1 << 3)
-#define PWR_HP_R_AMP (0x1 << 2)
-#define PWR_HP_DEPOP_DIS (0x1 << 1)
-#define PWR_HP_AMP_DRIVING (0x1)
+#define RT5631_PWR_VREF (0x1 << 15)
+#define RT5631_PWR_VREF_BIT 15
+#define RT5631_PWR_FAST_VREF_CTRL (0x1 << 14)
+#define RT5631_PWR_FAST_VREF_CTRL_BIT 14
+#define RT5631_PWR_MAIN_BIAS (0x1 << 13)
+#define RT5631_PWR_MAIN_BIAS_BIT 13
+#define RT5631_PWR_AXO1MIXER (0x1 << 11)
+#define RT5631_PWR_AXO1MIXER_BIT 11
+#define RT5631_PWR_AXO2MIXER (0x1 << 10)
+#define RT5631_PWR_AXO2MIXER_BIT 10
+#define RT5631_PWR_MONOMIXER (0x1 << 9)
+#define RT5631_PWR_MONOMIXER_BIT 9
+#define RT5631_PWR_MONO_DEPOP_DIS (0x1 << 8)
+#define RT5631_PWR_MONO_DEPOP_DIS_BIT 8
+#define RT5631_PWR_MONO_AMP_EN (0x1 << 7)
+#define RT5631_PWR_MONO_AMP_EN_BIT 7
+#define RT5631_PWR_CHARGE_PUMP (0x1 << 4)
+#define RT5631_PWR_CHARGE_PUMP_BIT 4
+#define RT5631_PWR_HP_L_AMP (0x1 << 3)
+#define RT5631_PWR_HP_L_AMP_BIT 3
+#define RT5631_PWR_HP_R_AMP (0x1 << 2)
+#define RT5631_PWR_HP_R_AMP_BIT 2
+#define RT5631_PWR_HP_DEPOP_DIS (0x1 << 1)
+#define RT5631_PWR_HP_DEPOP_DIS_BIT 1
+#define RT5631_PWR_HP_AMP_DRIVING (0x1 << 0)
+#define RT5631_PWR_HP_AMP_DRIVING_BIT 0
/* Power managment addition 4(0x3E) */
-#define PWR_SPK_L_VOL (0x1 << 15)
-#define PWR_SPK_R_VOL (0x1 << 14)
-#define PWR_LOUT_VOL (0x1 << 13)
-#define PWR_ROUT_VOL (0x1 << 12)
-#define PWR_HP_L_OUT_VOL (0x1 << 11)
-#define PWR_HP_R_OUT_VOL (0x1 << 10)
-#define PWR_AXIL_IN_VOL (0x1 << 9)
-#define PWR_AXIR_IN_VOL (0x1 << 8)
-#define PWR_MONO_IN_P_VOL (0x1 << 7)
-#define PWR_MONO_IN_N_VOL (0x1 << 6)
+#define RT5631_PWR_SPK_L_VOL (0x1 << 15)
+#define RT5631_PWR_SPK_L_VOL_BIT 15
+#define RT5631_PWR_SPK_R_VOL (0x1 << 14)
+#define RT5631_PWR_SPK_R_VOL_BIT 14
+#define RT5631_PWR_LOUT_VOL (0x1 << 13)
+#define RT5631_PWR_LOUT_VOL_BIT 13
+#define RT5631_PWR_ROUT_VOL (0x1 << 12)
+#define RT5631_PWR_ROUT_VOL_BIT 12
+#define RT5631_PWR_HP_L_OUT_VOL (0x1 << 11)
+#define RT5631_PWR_HP_L_OUT_VOL_BIT 11
+#define RT5631_PWR_HP_R_OUT_VOL (0x1 << 10)
+#define RT5631_PWR_HP_R_OUT_VOL_BIT 10
+#define RT5631_PWR_AXIL_IN_VOL (0x1 << 9)
+#define RT5631_PWR_AXIL_IN_VOL_BIT 9
+#define RT5631_PWR_AXIR_IN_VOL (0x1 << 8)
+#define RT5631_PWR_AXIR_IN_VOL_BIT 8
+#define RT5631_PWR_MONO_IN_P_VOL (0x1 << 7)
+#define RT5631_PWR_MONO_IN_P_VOL_BIT 7
+#define RT5631_PWR_MONO_IN_N_VOL (0x1 << 6)
+#define RT5631_PWR_MONO_IN_N_VOL_BIT 6
/* General Purpose Control Register(0x40) */
-#define SPK_AMP_AUTO_RATIO_EN (0x1 << 15)
-
-#define SPK_AMP_RATIO_CTRL_MASK (0x7 << 12)
-#define SPK_AMP_RATIO_CTRL_2_34 (0x0 << 12) /* 7.40DB */
-#define SPK_AMP_RATIO_CTRL_1_99 (0x1 << 12) /* 5.99DB */
-#define SPK_AMP_RATIO_CTRL_1_68 (0x2 << 12) /* 4.50DB */
-#define SPK_AMP_RATIO_CTRL_1_56 (0x3 << 12) /* 3.86DB */
-#define SPK_AMP_RATIO_CTRL_1_44 (0x4 << 12) /* 3.16DB */
-#define SPK_AMP_RATIO_CTRL_1_27 (0x5 << 12) /* 2.10DB */
-#define SPK_AMP_RATIO_CTRL_1_09 (0x6 << 12) /* 0.80DB */
-#define SPK_AMP_RATIO_CTRL_1_00 (0x7 << 12) /* 0.00DB */
-
-#define STEREO_DAC_HI_PASS_FILT_EN (0x1 << 11)
-#define STEREO_ADC_HI_PASS_FILT_EN (0x1 << 10)
+#define RT5631_SPK_AMP_AUTO_RATIO_EN (0x1 << 15)
+
+#define RT5631_SPK_AMP_RATIO_CTRL_MASK (0x7 << 12)
+#define RT5631_SPK_AMP_RATIO_CTRL_2_34 (0x0 << 12) /* 7.40DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_99 (0x1 << 12) /* 5.99DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_68 (0x2 << 12) /* 4.50DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_56 (0x3 << 12) /* 3.86DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_44 (0x4 << 12) /* 3.16DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_27 (0x5 << 12) /* 2.10DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_09 (0x6 << 12) /* 0.80DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_1_00 (0x7 << 12) /* 0.00DB */
+#define RT5631_SPK_AMP_RATIO_CTRL_SHIFT 12
+
+#define RT5631_STEREO_DAC_HI_PASS_FILT_EN (0x1 << 11)
+#define RT5631_STEREO_ADC_HI_PASS_FILT_EN (0x1 << 10)
/* Select ADC Wind Filter Clock type */
-#define ADC_WIND_FILT_MASK (0x3 << 4)
-#define ADC_WIND_FILT_8_16_32K (0x0 << 4) /* 8/16/32k */
-#define ADC_WIND_FILT_11_22_44K (0x1 << 4) /* 11/22/44k */
-#define ADC_WIND_FILT_12_24_48K (0x2 << 4) /* 12/24/48k */
-#define ADC_WIND_FILT_EN (0x1 << 3)
+#define RT5631_ADC_WIND_FILT_MASK (0x3 << 4)
+#define RT5631_ADC_WIND_FILT_8_16_32K (0x0 << 4) /*8/16/32k*/
+#define RT5631_ADC_WIND_FILT_11_22_44K (0x1 << 4) /*11/22/44k*/
+#define RT5631_ADC_WIND_FILT_12_24_48K (0x2 << 4) /*12/24/48k*/
+#define RT5631_ADC_WIND_FILT_EN (0x1 << 3)
/* SelectADC Wind Filter Corner Frequency */
-#define ADC_WIND_CNR_FREQ_MASK (0x7 << 0)
-#define ADC_WIND_CNR_FREQ_82_113_122 (0x0 << 0) /* 82/113/122 Hz */
-#define ADC_WIND_CNR_FREQ_102_141_153 (0x1 << 0) /* 102/141/153 Hz */
-#define ADC_WIND_CNR_FREQ_131_180_156 (0x2 << 0) /* 131/180/156 Hz */
-#define ADC_WIND_CNR_FREQ_163_225_245 (0x3 << 0) /* 163/225/245 Hz */
-#define ADC_WIND_CNR_FREQ_204_281_306 (0x4 << 0) /* 204/281/306 Hz */
-#define ADC_WIND_CNR_FREQ_261_360_392 (0x5 << 0) /* 261/360/392 Hz */
-#define ADC_WIND_CNR_FREQ_327_450_490 (0x6 << 0) /* 327/450/490 Hz */
-#define ADC_WIND_CNR_FREQ_408_563_612 (0x7 << 0) /* 408/563/612 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_MASK (0x7 << 0)
+#define RT5631_ADC_WIND_CNR_FREQ_82_113_122 (0x0 << 0) /* 82/113/122 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_102_141_153 (0x1 << 0) /* 102/141/153 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_131_180_156 (0x2 << 0) /* 131/180/156 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_163_225_245 (0x3 << 0) /* 163/225/245 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_204_281_306 (0x4 << 0) /* 204/281/306 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_261_360_392 (0x5 << 0) /* 261/360/392 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_327_450_490 (0x6 << 0) /* 327/450/490 Hz */
+#define RT5631_ADC_WIND_CNR_FREQ_408_563_612 (0x7 << 0) /* 408/563/612 Hz */
/* Global Clock Control Register(0x42) */
-#define SYSCLK_SOUR_SEL_MASK (0x1 << 14)
-#define SYSCLK_SOUR_SEL_MCLK (0x0 << 14)
-#define SYSCLK_SOUR_SEL_PLL (0x1 << 14)
-#define SYSCLK_SOUR_SEL_PLL_TCK (0x2 << 14)
+#define RT5631_SYSCLK_SOUR_SEL_MASK (0x3 << 14)
+#define RT5631_SYSCLK_SOUR_SEL_MCLK (0x0 << 14)
+#define RT5631_SYSCLK_SOUR_SEL_PLL (0x1 << 14)
+#define RT5631_SYSCLK_SOUR_SEL_PLL_TCK (0x2 << 14)
-#define PLLCLK_SOUR_SEL_MCLK (0x0 << 12)
-#define PLLCLK_SOUR_SEL_BITCLK (0x1 << 12)
+#define RT5631_PLLCLK_SOUR_SEL_MASK (0x3 << 12)
+#define RT5631_PLLCLK_SOUR_SEL_MCLK (0x0 << 12)
+#define RT5631_PLLCLK_SOUR_SEL_BCLK (0x1 << 12)
+#define RT5631_PLLCLK_SOUR_SEL_VBCLK (0x2 << 12)
-#define PLLCLK_PRE_DIV1 (0x0 << 11)
-#define PLLCLK_PRE_DIV2 (0x1 << 11)
+#define RT5631_PLLCLK_PRE_DIV1 (0x0 << 11)
+#define RT5631_PLLCLK_PRE_DIV2 (0x1 << 11)
/* PLL Control(0x44) */
-#define PLL_CTRL_M_VAL(m) ((m)&0xf)
-#define PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
-#define PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
+#define RT5631_PLL_CTRL_M_VAL(m) ((m)&0xf)
+#define RT5631_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4)
+#define RT5631_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8)
+
+/* Internal Status and IRQ Control2(0x4A) */
+#define RT5631_ADC_DATA_SEL_MASK (0x3 << 14)
+#define RT5631_ADC_DATA_SEL_Disable (0x0 << 14)
+#define RT5631_ADC_DATA_SEL_MIC1 (0x1 << 14)
+#define RT5631_ADC_DATA_SEL_MIC1_SHIFT 14
+#define RT5631_ADC_DATA_SEL_MIC2 (0x2 << 14)
+#define RT5631_ADC_DATA_SEL_MIC2_SHIFT 15
+#define RT5631_ADC_DATA_SEL_STO (0x3 << 14)
+#define RT5631_ADC_DATA_SEL_SHIFT 14
/* GPIO Pin Configuration(0x4C) */
-#define GPIO_PIN_FUN_SEL_MASK (0x1 << 15)
-#define GPIO_PIN_FUN_SEL_IRQ (0x1 << 15)
-#define GPIO_PIN_FUN_SEL_GPIO_DIMC (0x0 << 15)
+#define RT5631_GPIO_PIN_FUN_SEL_MASK (0x1 << 15)
+#define RT5631_GPIO_PIN_FUN_SEL_IRQ (0x1 << 15)
+#define RT5631_GPIO_PIN_FUN_SEL_GPIO_DIMC (0x0 << 15)
-#define GPIO_DMIC_FUN_SEL_MASK (0x1 << 3)
-#define GPIO_DMIC_FUN_SEL_DIMC (0x1 << 3) /* GPIO pin SELECT DMIC */
-#define GPIO_DMIC_FUN_SEL_GPIO (0x0 << 3) /* GPIO PIN SELECT GPIO */
+#define RT5631_GPIO_DMIC_FUN_SEL_MASK (0x1 << 3)
+#define RT5631_GPIO_DMIC_FUN_SEL_DIMC (0x1 << 3)
+#define RT5631_GPIO_DMIC_FUN_SEL_GPIO (0x0 << 3)
-#define GPIO_PIN_CON_MASK (0x1 << 2)
-#define GPIO_PIN_SET_INPUT (0x0 << 2)
-#define GPIO_PIN_SET_OUTPUT (0x1 << 2)
+#define RT5631_GPIO_PIN_CON_MASK (0x1 << 2)
+#define RT5631_GPIO_PIN_SET_INPUT (0x0 << 2)
+#define RT5631_GPIO_PIN_SET_OUTPUT (0x1 << 2)
/* De-POP function Control 1(0x54) */
-#define POW_ON_SOFT_GEN (0x1 << 15)
-#define EN_MUTE_UNMUTE_DEPOP (0x1 << 14)
-#define EN_DEPOP2_FOR_HP (0x1 << 7)
+#define RT5631_POW_ON_SOFT_GEN (0x1 << 15)
+#define RT5631_EN_MUTE_UNMUTE_DEPOP (0x1 << 14)
+#define RT5631_EN_DEPOP2_FOR_HP (0x1 << 7)
/* Power Down HPAMP_L Starts Up Signal */
-#define PD_HPAMP_L_ST_UP (0x1 << 5)
+#define RT5631_PD_HPAMP_L_ST_UP (0x1 << 5)
/* Power Down HPAMP_R Starts Up Signal */
-#define PD_HPAMP_R_ST_UP (0x1 << 4)
+#define RT5631_PD_HPAMP_R_ST_UP (0x1 << 4)
/* Enable left HP mute/unmute depop */
-#define EN_HP_L_M_UN_MUTE_DEPOP (0x1 << 1)
+#define RT5631_EN_HP_L_M_UN_MUTE_DEPOP (0x1 << 1)
/* Enable right HP mute/unmute depop */
-#define EN_HP_R_M_UN_MUTE_DEPOP (0x1 << 0)
+#define RT5631_EN_HP_R_M_UN_MUTE_DEPOP (0x1 << 0)
/* De-POP Fnction Control(0x56) */
-#define EN_ONE_BIT_DEPOP (0x1 << 15)
-#define EN_CAP_FREE_DEPOP (0x1 << 14)
+#define RT5631_EN_ONE_BIT_DEPOP (0x1 << 15)
+#define RT5631_EN_CAP_FREE_DEPOP (0x1 << 14)
/* Jack Detect Control Register(0x5A) */
-#define JD_USE_MASK (0x3 << 14)
-#define JD_USE_JD2 (0x3 << 14)
-#define JD_USE_JD1 (0x2 << 14)
-#define JD_USE_GPIO (0x1 << 14)
-#define JD_OFF (0x0 << 14)
+#define RT5631_JD_USE_MASK (0x3 << 14)
+#define RT5631_JD_USE_JD2 (0x3 << 14)
+#define RT5631_JD_USE_JD1 (0x2 << 14)
+#define RT5631_JD_USE_GPIO (0x1 << 14)
+#define RT5631_JD_OFF (0x0 << 14)
/* JD trigger enable for HP */
-#define JD_HP_EN (0x1 << 11)
-#define JD_HP_TRI_MASK (0x1 << 10)
-#define JD_HP_TRI_HI (0x1 << 10)
-#define JD_HP_TRI_LO (0x1 << 10)
+#define RT5631_JD_HP_EN (0x1 << 11)
+#define RT5631_JD_HP_TRI_MASK (0x1 << 10)
+#define RT5631_JD_HP_TRI_HI (0x1 << 10)
+#define RT5631_JD_HP_TRI_LO (0x1 << 10)
/* JD trigger enable for speaker LP/LN */
-#define JD_SPK_L_EN (0x1 << 9)
-#define JD_SPK_L_TRI_MASK (0x1 << 8)
-#define JD_SPK_L_TRI_HI (0x1 << 8)
-#define JD_SPK_L_TRI_LO (0x0 << 8)
+#define RT5631_JD_SPK_L_EN (0x1 << 9)
+#define RT5631_JD_SPK_L_TRI_MASK (0x1 << 8)
+#define RT5631_JD_SPK_L_TRI_HI (0x1 << 8)
+#define RT5631_JD_SPK_L_TRI_LO (0x0 << 8)
/* JD trigger enable for speaker RP/RN */
-#define JD_SPK_R_EN (0x1 << 7)
-#define JD_SPK_R_TRI_MASK (0x1 << 6)
-#define JD_SPK_R_TRI_HI (0x1 << 6)
-#define JD_SPK_R_TRI_LO (0x0 << 6)
+#define RT5631_JD_SPK_R_EN (0x1 << 7)
+#define RT5631_JD_SPK_R_TRI_MASK (0x1 << 6)
+#define RT5631_JD_SPK_R_TRI_HI (0x1 << 6)
+#define RT5631_JD_SPK_R_TRI_LO (0x0 << 6)
/* JD trigger enable for monoout */
-#define JD_MONO_EN (0x1 << 5)
-#define JD_MONO_TRI_MASK (0x1 << 4)
-#define JD_MONO_TRI_HI (0x1 << 4)
-#define JD_MONO_TRI_LO (0x0 << 4)
+#define RT5631_JD_MONO_EN (0x1 << 5)
+#define RT5631_JD_MONO_TRI_MASK (0x1 << 4)
+#define RT5631_JD_MONO_TRI_HI (0x1 << 4)
+#define RT5631_JD_MONO_TRI_LO (0x0 << 4)
/* JD trigger enable for Lout */
-#define JD_AUX_1_EN (0x1 << 3)
-#define JD_AUX_1_MASK (0x1 << 2)
-#define JD_AUX_1_TRI_HI (0x1 << 2)
-#define JD_AUX_1_TRI_LO (0x0 << 2)
+#define RT5631_JD_AUX_1_EN (0x1 << 3)
+#define RT5631_JD_AUX_1_MASK (0x1 << 2)
+#define RT5631_JD_AUX_1_TRI_HI (0x1 << 2)
+#define RT5631_JD_AUX_1_TRI_LO (0x0 << 2)
/* JD trigger enable for Rout */
-#define JD_AUX_2_EN (0x1 << 1)
-#define JD_AUX_2_MASK (0x1 << 0)
-#define JD_AUX_2_TRI_HI (0x1 << 0)
-#define JD_AUX_2_TRI_LO (0x0 << 0)
+#define RT5631_JD_AUX_2_EN (0x1 << 1)
+#define RT5631_JD_AUX_2_MASK (0x1 << 0)
+#define RT5631_JD_AUX_2_TRI_HI (0x1 << 0)
+#define RT5631_JD_AUX_2_TRI_LO (0x0 << 0)
/* ALC CONTROL 1(0x64) */
-#define ALC_ATTACK_RATE_MASK (0x1F << 8)
-#define ALC_RECOVERY_RATE_MASK (0x1F << 0)
+#define RT5631_ALC_ATTACK_RATE_MASK (0x1F << 8)
+#define RT5631_ALC_RECOVERY_RATE_MASK (0x1F << 0)
/* ALC CONTROL 2(0x65) */
/* select Compensation gain for Noise gate function */
-#define ALC_COM_NOISE_GATE_MASK (0xF << 0)
+#define RT5631_ALC_COM_NOISE_GATE_MASK (0xF << 0)
/* ALC CONTROL 3(0x66) */
-#define ALC_FUN_MASK (0x3 << 14)
-#define ALC_FUN_DIS (0x0 << 14)
-#define ALC_ENA_DAC_PATH (0x1 << 14)
-#define ALC_ENA_ADC_PATH (0x3 << 14)
-#define ALC_PARA_UPDATE (0x1 << 13)
-#define ALC_LIMIT_LEVEL_MASK (0x1F << 8)
-#define ALC_NOISE_GATE_FUN_MASK (0x1 << 7)
-#define ALC_NOISE_GATE_FUN_DIS (0x0 << 7)
-#define ALC_NOISE_GATE_FUN_ENA (0x1 << 7)
+#define RT5631_ALC_FUN_MASK (0x3 << 14)
+#define RT5631_ALC_FUN_DIS (0x0 << 14)
+#define RT5631_ALC_ENA_DAC_PATH (0x1 << 14)
+#define RT5631_ALC_ENA_ADC_PATH (0x3 << 14)
+#define RT5631_ALC_PARA_UPDATE (0x1 << 13)
+#define RT5631_ALC_LIMIT_LEVEL_MASK (0x1F << 8)
+#define RT5631_ALC_NOISE_GATE_FUN_MASK (0x1 << 7)
+#define RT5631_ALC_NOISE_GATE_FUN_DIS (0x0 << 7)
+#define RT5631_ALC_NOISE_GATE_FUN_ENA (0x1 << 7)
/* ALC noise gate hold data function */
-#define ALC_NOISE_GATE_H_D_MASK (0x1 << 6)
-#define ALC_NOISE_GATE_H_D_DIS (0x0 << 6)
-#define ALC_NOISE_GATE_H_D_ENA (0x1 << 6)
+#define RT5631_ALC_NOISE_GATE_H_D_MASK (0x1 << 6)
+#define RT5631_ALC_NOISE_GATE_H_D_DIS (0x0 << 6)
+#define RT5631_ALC_NOISE_GATE_H_D_ENA (0x1 << 6)
/* Psedueo Stereo & Spatial Effect Block Control(0x68) */
-#define SPATIAL_CTRL_EN (0x1 << 15)
-#define ALL_PASS_FILTER_EN (0x1 << 14)
-#define PSEUDO_STEREO_EN (0x1 << 13)
-#define STEREO_EXPENSION_EN (0x1 << 12)
+#define RT5631_SPATIAL_CTRL_EN (0x1 << 15)
+#define RT5631_ALL_PASS_FILTER_EN (0x1 << 14)
+#define RT5631_PSEUDO_STEREO_EN (0x1 << 13)
+#define RT5631_STEREO_EXPENSION_EN (0x1 << 12)
/* 3D gain parameter */
-#define GAIN_3D_PARA_MASK (0x3 << 6)
-#define GAIN_3D_PARA_1_00 (0x0 << 6) /* 3D gain 1.0 */
-#define GAIN_3D_PARA_1_50 (0x1 << 6) /* 3D gain 1.5 */
-#define GAIN_3D_PARA_2_00 (0x2 << 6) /* 3D gain 2.0 */
+#define RT5631_GAIN_3D_PARA_MASK (0x3 << 6)
+#define RT5631_GAIN_3D_PARA_1_00 (0x0 << 6) /* 3D gain 1.0 */
+#define RT5631_GAIN_3D_PARA_1_50 (0x1 << 6) /* 3D gain 1.5 */
+#define RT5631_GAIN_3D_PARA_2_00 (0x2 << 6) /* 3D gain 2.0 */
/* 3D ratio parameter */
-#define RATIO_3D_MASK (0x3 << 4)
-#define RATIO_3D_0_0 (0x0 << 4) /* 3D ratio 0.0 */
-#define RATIO_3D_0_66 (0x1 << 4) /* 3D ratio 0.66 */
-#define RATIO_3D_1_0 (0x2 << 4) /* 3D ratio 1.0 */
+#define RT5631_RATIO_3D_MASK (0x3 << 4)
+#define RT5631_RATIO_3D_0_0 (0x0 << 4) /* 3D ratio 0.0 */
+#define RT5631_RATIO_3D_0_66 (0x1 << 4) /* 3D ratio 0.66 */
+#define RT5631_RATIO_3D_1_0 (0x2 << 4) /* 3D ratio 1.0 */
/* select samplerate for all pass filter */
-#define APF_FUN_SLE_MASK (0x3 << 0)
-#define APF_FUN_SEL_48K (0x3 << 0)
-#define APF_FUN_SEL_44_1K (0x2 << 0)
-#define APF_FUN_SEL_32K (0x1 << 0)
-#define APF_FUN_DIS (0x0 << 0)
+#define RT5631_APF_FUN_SLE_MASK (0x3 << 0)
+#define RT5631_APF_FUN_SEL_48K (0x3 << 0)
+#define RT5631_APF_FUN_SEL_44_1K (0x2 << 0)
+#define RT5631_APF_FUN_SEL_32K (0x1 << 0)
+#define RT5631_APF_FUN_DIS (0x0 << 0)
/* EQ CONTROL 1(0x6E) */
-#define HW_EQ_PATH_SEL_MASK (0x1 << 15)
-#define HW_EQ_PATH_SEL_DAC (0x0 << 15)
-#define HW_EQ_PATH_SEL_ADC (0x1 << 15)
-#define HW_EQ_UPDATE_CTRL (0x1 << 14)
-
-#define EN_HW_EQ_HPF2 (0x1 << 5)
-#define EN_HW_EQ_HPF1 (0x1 << 4)
-#define EN_HW_EQ_BP3 (0x1 << 3)
-#define EN_HW_EQ_BP2 (0x1 << 2)
-#define EN_HW_EQ_BP1 (0x1 << 1)
-#define EN_HW_EQ_LPF (0x1 << 0)
+#define RT5631_HW_EQ_PATH_SEL_MASK (0x1 << 15)
+#define RT5631_HW_EQ_PATH_SEL_DAC (0x0 << 15)
+#define RT5631_HW_EQ_PATH_SEL_ADC (0x1 << 15)
+#define RT5631_HW_EQ_UPDATE_CTRL (0x1 << 14)
+
+#define RT5631_EN_HW_EQ_HPF2 (0x1 << 5)
+#define RT5631_EN_HW_EQ_HPF1 (0x1 << 4)
+#define RT5631_EN_HW_EQ_BP3 (0x1 << 3)
+#define RT5631_EN_HW_EQ_BP2 (0x1 << 2)
+#define RT5631_EN_HW_EQ_BP1 (0x1 << 1)
+#define RT5631_EN_HW_EQ_LPF (0x1 << 0)
+
#endif /* __RTCODEC5631_H__ */
struct snd_soc_codec *codec;
struct snd_soc_codec_conf *codec_conf;
enum snd_soc_compress_type compress_type;
-#ifndef CONFIG_SND_RK_SOC
struct snd_soc_dai_link *dai_link;
- int dai_fmt;
-#endif
- int ret, i, order;
+ int ret, i, order, dai_fmt;
mutex_lock_nested(&card->mutex, SND_SOC_CARD_CLASS_INIT);
snd_soc_dapm_new_widgets(&card->dapm);
-//dai_fmt will and need to be setted in hw_parsms for codecs, so ignore here.
-#ifndef CONFIG_SND_RK_SOC
for (i = 0; i < card->num_links; i++) {
dai_link = &card->dai_link[i];
dai_fmt = dai_link->dai_fmt;
ret);
}
}
-#endif //CONFIG_SND_RK_SOC
snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname),
"%s", card->name);
unsigned int snd_soc_write(struct snd_soc_codec *codec,
unsigned int reg, unsigned int val)
{
- dev_dbg(codec->dev, "write %x => %x\n", reg, val);
+ dev_dbg(codec->dev, "write %x = %x\n", reg, val);
trace_snd_soc_reg_write(codec, reg, val);
return codec->write(codec, reg, val);
}
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_set_config_from_dai_data);
-#ifdef CONFIG_ARCH_ROCKCHIP
-static int debug_audio_timeout = 0;
-module_param(debug_audio_timeout, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-MODULE_PARM_DESC(debug_audio_timeout, "Debug interface Audio DMA buffdone time out");
-#endif
static void dmaengine_pcm_dma_complete(void *arg)
{
struct snd_pcm_substream *substream = arg;
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-#ifdef CONFIG_ARCH_ROCKCHIP
- if(debug_audio_timeout){
- struct snd_pcm_runtime *runtime = substream->runtime;
- static ktime_t before = {0},after = {0};
- s64 t;
- before = after;
- after = ktime_get();
- t = ktime_to_us(ktime_sub(after, before));
-
- if(t > (snd_pcm_lib_period_bytes(substream)/4+32)*1000*1000/runtime->rate
- && t != ktime_to_us(after)) // (23220)4096/4/44100 + 32/44100
- {
- printk(KERN_DEBUG "Time out:: Audio DMA buffdone time out!!! the time = %lld!\n", t);
- }
- //printk(KERN_DEBUG "audio DMA callback time = %lld\n", t);
- }
-#endif
prtd->pos += snd_pcm_lib_period_bytes(substream);
if (prtd->pos >= snd_pcm_lib_buffer_bytes(substream))
prtd->pos = 0;
flags |= DMA_PREP_INTERRUPT;
prtd->pos = 0;
-#ifdef CONFIG_ARCH_ROCKCHIP
- //printk("soc dma buffersize = %d , periodsize=%d, periods=%d\n",
- // snd_pcm_lib_buffer_bytes(substream),
- // snd_pcm_lib_period_bytes(substream),
- // snd_pcm_lib_buffer_bytes(substream)/snd_pcm_lib_period_bytes(substream));
- desc = dmaengine_prep_dma_infiniteloop(chan,
- substream->runtime->dma_addr,
- snd_pcm_lib_buffer_bytes(substream),
- snd_pcm_lib_period_bytes(substream),
- direction, flags,
- snd_pcm_lib_buffer_bytes(substream)/snd_pcm_lib_period_bytes(substream));
-#else
desc = dmaengine_prep_dma_cyclic(chan,
substream->runtime->dma_addr,
snd_pcm_lib_buffer_bytes(substream),
snd_pcm_lib_period_bytes(substream), direction, flags);
-#endif
if (!desc)
return -ENOMEM;
snd_pcm_uframes_t snd_dmaengine_pcm_pointer_no_residue(struct snd_pcm_substream *substream)
{
struct dmaengine_pcm_runtime_data *prtd = substream_to_prtd(substream);
-#ifdef CONFIG_ARCH_ROCKCHIP
- dma_addr_t src, dst;
-
- prtd->dma_chan->device->dma_getposition(prtd->dma_chan, &src, &dst);
- if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
- prtd->pos = dst - substream->runtime->dma_addr;
- else
- prtd->pos = src - substream->runtime->dma_addr;
-#endif
return bytes_to_frames(substream->runtime, prtd->pos);
}
EXPORT_SYMBOL_GPL(snd_dmaengine_pcm_pointer_no_residue);
snd_pcm_lib_preallocate_free_for_all(pcm);
}
-static const char * const dmaengine_pcm_dma_channel_names[] = {
- [SNDRV_PCM_STREAM_PLAYBACK] = "tx",
- [SNDRV_PCM_STREAM_CAPTURE] = "rx",
-};
+static struct dma_chan *dmaengine_pcm_compat_request_channel(
+ struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_substream *substream)
+{
+ struct dmaengine_pcm *pcm = soc_platform_to_pcm(rtd->platform);
+
+ if ((pcm->flags & SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX) && pcm->chan[0])
+ return pcm->chan[0];
+
+ if (pcm->config->compat_request_channel)
+ return pcm->config->compat_request_channel(rtd, substream);
+
+ return snd_dmaengine_pcm_request_channel(pcm->config->compat_filter_fn,
+ snd_soc_dai_get_dma_data(rtd->cpu_dai, substream));
+}
static int dmaengine_pcm_new(struct snd_soc_pcm_runtime *rtd)
{
continue;
if (!pcm->chan[i] && (pcm->flags & SND_DMAENGINE_PCM_FLAG_COMPAT)) {
- pcm->chan[i] = dma_request_slave_channel(rtd->platform->dev,
- dmaengine_pcm_dma_channel_names[i]);
+ pcm->chan[i] = dmaengine_pcm_compat_request_channel(rtd,
+ substream);
}
if (!pcm->chan[i]) {
.probe_order = SND_SOC_COMP_ORDER_LATE,
};
+static const char * const dmaengine_pcm_dma_channel_names[] = {
+ [SNDRV_PCM_STREAM_PLAYBACK] = "tx",
+ [SNDRV_PCM_STREAM_CAPTURE] = "rx",
+};
+
static void dmaengine_pcm_request_chan_of(struct dmaengine_pcm *pcm,
struct device *dev)
{
#include <linux/usb/audio.h>
#include <linux/usb/audio-v2.h>
#include <linux/module.h>
-#ifdef CONFIG_SWITCH
-#include <linux/switch.h>
-#endif
#include <sound/control.h>
#include <sound/core.h>
static DEFINE_MUTEX(register_mutex);
static struct snd_usb_audio *usb_chip[SNDRV_CARDS];
static struct usb_driver usb_audio_driver;
-#ifdef CONFIG_SND_RK_SOC
-#define USB_AUDIO_CARD_NUM 3
-struct switch_dev *usb_audio_sdev;
-#endif
-
-#ifdef CONFIG_SWITCH
-//usb audio card will begin from RBASE_USB_AUDIO_IDX.
-#define RBASE_USB_AUDIO_IDX (3)
-#define NO_USBAUDIO_PLAYBACK (-1)
-#define NO_USBAUDIO_CAPTURE (-1)
-
-struct usb_audio_switch {
- int playback_switch_cur_state;
- int capture_switch_cur_state;
- struct switch_dev sUsbaudio_Playback;
- struct switch_dev sUsbaudio_Capture;
-};
-
-// state: card*10 + device
-static struct usb_audio_switch sUsbaudio_Switch = {
- .playback_switch_cur_state = NO_USBAUDIO_PLAYBACK,
- .capture_switch_cur_state = NO_USBAUDIO_CAPTURE,
- .sUsbaudio_Playback = {
- .name = "usb_audio_playback",
- .state = NO_USBAUDIO_PLAYBACK, //this means no usb audio playback available
- },
-
- .sUsbaudio_Capture = {
- .name = "usb_audio_capture",
- .state = NO_USBAUDIO_CAPTURE, //this means no usb audio capture available
- },
-};
-#endif
/*
* disconnect streams
snd_printk(KERN_ERR "unknown device speed %d\n", snd_usb_get_speed(dev));
return -ENXIO;
}
-#ifdef CONFIG_SND_RK_SOC
- err = snd_card_create(USB_AUDIO_CARD_NUM, id[idx], THIS_MODULE, 0, &card);
-#else
+
err = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
-#endif
if (err < 0) {
snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
return err;
return 0;
}
-#ifdef CONFIG_SWITCH
-static int usb_audio_card_switch_state_update(struct snd_card *card, bool force){
- struct snd_device *dev;
- struct snd_pcm *pcm;
- struct snd_pcm_str *pstr;
-
- if (snd_BUG_ON(!card))
- return -EINVAL;
- //we use the latest devices
- list_for_each_entry(dev, &card->devices, list) {
- if (dev->type == SNDRV_DEV_PCM && dev->state == SNDRV_DEV_REGISTERED) {
- pcm = (struct snd_pcm*)dev->device_data;
- if (NULL != pcm) {
- //playback available?
- pstr = &pcm->streams[SNDRV_PCM_STREAM_PLAYBACK];
- snd_printdd(KERN_INFO "playback substream_count: 0x%x\n", pstr->substream_count);
- if (pstr->substream_count > 0) {
- sUsbaudio_Switch.playback_switch_cur_state = card->number * 10;
- }
- //capture available?
- pstr = &pcm->streams[SNDRV_PCM_STREAM_CAPTURE];
- snd_printdd(KERN_INFO "capture substream_count: 0x%x\n", pstr->substream_count);
- if (pstr->substream_count > 0) {
- sUsbaudio_Switch.capture_switch_cur_state = card->number * 10;
- }
- }
- }
- }
- if (force) {
- switch_set_state(&sUsbaudio_Switch.sUsbaudio_Playback, sUsbaudio_Switch.playback_switch_cur_state);
- switch_set_state(&sUsbaudio_Switch.sUsbaudio_Capture, sUsbaudio_Switch.capture_switch_cur_state);
- }
- return 0;
-
-}
-
-static void usb_audio_switch_state_update_all(void)
-{
- int index = 0;
- struct snd_card *card;
-
- sUsbaudio_Switch.playback_switch_cur_state = NO_USBAUDIO_PLAYBACK;
- sUsbaudio_Switch.capture_switch_cur_state = NO_USBAUDIO_CAPTURE;
-
- for (index = 0; index < SNDRV_CARDS; ++index) {
- if (NULL != usb_chip[index]) {
- card = usb_chip[index]->card;
- usb_audio_card_switch_state_update(card, false);
- }
- }
-
- switch_set_state(&sUsbaudio_Switch.sUsbaudio_Playback,
- sUsbaudio_Switch.playback_switch_cur_state);
- switch_set_state(&sUsbaudio_Switch.sUsbaudio_Capture,
- sUsbaudio_Switch.capture_switch_cur_state);
-}
-#endif
-
-
/*
* probe the active usb device
*
/* it's a fresh one.
* now look for an empty slot and create a new card instance
*/
- // use RBASE_USB_AUDIO_IDX instead of zero, modify by zxg.
for (i = 0; i < SNDRV_CARDS; i++)
if (enable[i] && ! usb_chip[i] &&
(vid[i] == -1 || vid[i] == USB_ID_VENDOR(id)) &&
if (snd_card_register(chip->card) < 0) {
goto __error;
}
-#ifdef CONFIG_SWITCH
- if (usb_audio_card_switch_state_update(chip->card, true) < 0) {
- printk(KERN_ERR "usb_audio_card_switch_state_update failed!!!\n");
- goto __error;
- }
-#endif
+
usb_chip[chip->index] = chip;
chip->num_interfaces++;
chip->probing = 0;
} else {
mutex_unlock(®ister_mutex);
}
-#ifdef CONFIG_SWITCH
- usb_audio_switch_state_update_all();
-#endif
}
/*
chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
if (chip) {
usb_set_intfdata(intf, chip);
-#ifdef CONFIG_SND_RK_SOC
- switch_set_state(usb_audio_sdev, 1);
-#endif
return 0;
} else
return -EIO;
static void usb_audio_disconnect(struct usb_interface *intf)
{
-#ifdef CONFIG_SND_RK_SOC
- switch_set_state(usb_audio_sdev, 0);
-#endif
snd_usb_audio_disconnect(interface_to_usbdev(intf),
usb_get_intfdata(intf));
}
static int __init snd_usb_audio_init(void)
{
- int ret;
-#ifdef CONFIG_SWITCH
- int i;
- ret = switch_dev_register(&sUsbaudio_Switch.sUsbaudio_Playback);
- if (ret)
- goto err;
- ret = switch_dev_register(&sUsbaudio_Switch.sUsbaudio_Capture);
- if (ret)
- goto err_drv;
-
- switch_set_state(&sUsbaudio_Switch.sUsbaudio_Playback, NO_USBAUDIO_PLAYBACK);
- switch_set_state(&sUsbaudio_Switch.sUsbaudio_Capture, NO_USBAUDIO_CAPTURE);
-#endif
-
if (nrpacks < 1 || nrpacks > MAX_PACKS) {
printk(KERN_WARNING "invalid nrpacks value.\n");
return -EINVAL;
}
-#ifdef CONFIG_SND_RK_SOC
- usb_audio_sdev = kzalloc(sizeof(usb_audio_sdev), GFP_KERNEL);
- usb_audio_sdev->name = "usb_audio";
- switch_dev_register(usb_audio_sdev);
- if (!usb_audio_sdev) {
- printk(KERN_WARNING "usb-audio kmalloc fail!");
- return -ENOMEM;
- }
-#endif
-
- //re initial array index for rebasing usb audio cards create, modify by zxg.
- for(i=0; i<SNDRV_CARDS; ++i){
- index[i] = i;
- }
-
return usb_register(&usb_audio_driver);
-
-err_drv:
-#ifdef CONFIG_SWITCH
- switch_dev_unregister(&sUsbaudio_Switch.sUsbaudio_Playback);
-#endif
-err:
- return ret;
-
}
static void __exit snd_usb_audio_cleanup(void)
{
usb_deregister(&usb_audio_driver);
-#ifdef CONFIG_SND_RK_SOC
- kfree(usb_audio_sdev);
-#endif
- switch_dev_unregister(&sUsbaudio_Switch.sUsbaudio_Capture);
- switch_dev_unregister(&sUsbaudio_Switch.sUsbaudio_Playback);
}
-/*module_init(snd_usb_audio_init);*/
-/* use late initcall_sync instead of module_init,
- * make sure that usbaudio probe after board codec.
- * added by zxg@rock-chips.com
- */
-late_initcall_sync(snd_usb_audio_init);
+module_init(snd_usb_audio_init);
module_exit(snd_usb_audio_cleanup);