Merge "msm: camera: Fix crash issue while enabling regular stats" into msm-3.0
diff --git a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
index 4fb653e..084050e 100644
--- a/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
+++ b/Documentation/devicetree/bindings/mmc/msm_sdcc.txt
@@ -24,13 +24,13 @@
Example:
- qcom,sdcc@F9600000 {
+ qcom,sdcc@f9600000 {
/* SDC1 used as eMMC slot */
cell-index = <1>;
compatible = "qcom,msm-sdcc";
- reg = <0xF9600000 0x800 // SDCC register interface
- 0xF9600800 0x1800 // DML register interface
- 0xF9602000 0x2000> // BAM register interface
+ reg = <0xf9600000 0x800 // SDCC register interface
+ 0xf9600800 0x1800 // DML register interface
+ 0xf9602000 0x2000> // BAM register interface
interrupts = <123>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
diff --git a/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
new file mode 100644
index 0000000..8cc3c54
--- /dev/null
+++ b/Documentation/devicetree/bindings/spmi/spmi-pmic-arb.txt
@@ -0,0 +1,32 @@
+Qualcomm SPMI Controller (PMIC Arbiter)
+
+Required properties:
+- cell-index : the bus identifier.
+- compatible : should be "qcom,spmi-pmic-arb".
+- reg : offset and length of the PMIC Arbiter Core register map.
+- reg : offset and length of the PMIC Arbiter Interrupt controller register map.
+- interrupts : the PMIC Arbiter interrupt.
+- qcom,pmic-arb-ee : the execution environment (EE) identifier.
+- qcom,pmic-arb-channel : the assigned channel number for channel registers.
+- qcom,pmic-arb-ppid-map : an array used to map a 12-bit PPID to 8-bit APID.
+
+Peripherals on the SPMI bus are identified with a 12-bit identifier (PPID)
+which is composed of a 4-bit slave address and an 8-bit peripheral identifier.
+The PMIC Arbiter hardware uses an 8-bit APID (Arbiter Peripheral Identifier)
+internally. Software needs the mapping between the APID and the PPID.
+Up to a maximum of 256 peripherals are supported and the mapping is target
+specific.
+
+Example:
+
+ qcom,spmi@fc4c0000 {
+ cell-index = <0>;
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0xfc4cf000 0x1000>,
+ <0Xfc4cb000 0x1000>;
+ interrupts = <0>;
+ qcom,pmic-arb-ee = <0>;
+ qcom,pmic-arb-channel = <0>;
+ qcom,pmic-arb-ppid-map = <0x130 0x00>, /* PPID 0x130, APID 0 */
+ <0x131 0x01>; /* PPID 0x131, APID 1 */
+ };
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
index c1399ae..95ddf34 100644
--- a/Documentation/devicetree/bindings/usb/msm-hsusb.txt
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -35,16 +35,16 @@
- qcom,hsusb-otg-pmic-id-irq: ID, routed to PMIC IRQ number
Example HSUSB OTG controller device node :
- usb@F9690000 {
+ usb@f9690000 {
compatible = "qcom,hsusb-otg";
- reg = <0xF9690000 0x400>;
+ reg = <0xf9690000 0x400>;
interrupts = <134>;
qcom,hsusb-otg-phy-type = <2>;
qcom,hsusb-otg-mode = <1>;
qcom,hsusb-otg-otg-control = <1>;
qcom,hsusb-otg-default-mode = <2>;
- qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xFFFFFFFF>;
+ qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xffffffff>;
qcom,hsusb-otg-power-budget = <500>;
qcom,hsusb-otg-pclk-src-name = "dfab_usb_clk";
qcom,hsusb-otg-pmic-id-irq = <47>
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 57ad77a..725971d 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -27,15 +27,15 @@
interrupts = <1 2 0>;
};
- serial@F991F000 {
+ serial@f991f000 {
compatible = "qcom,msm-lsuart-v14";
- reg = <0xF991F000 0x1000>;
+ reg = <0xf991f000 0x1000>;
interrupts = <0 109 0>;
};
- usb@F9A55000 {
+ usb@f9a55000 {
compatible = "qcom,hsusb-otg";
- reg = <0xF9A55000 0x400>;
+ reg = <0xf9a55000 0x400>;
interrupts = <0 134 0>;
qcom,hsusb-otg-phy-type = <2>;
@@ -43,10 +43,10 @@
qcom,hsusb-otg-otg-control = <1>;
};
- qcom,sdcc@F980B000 {
+ qcom,sdcc@f980b000 {
cell-index = <1>;
compatible = "qcom,msm-sdcc";
- reg = <0xF980B000 0x1000>;
+ reg = <0xf980b000 0x1000>;
interrupts = <0 123 0>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -56,10 +56,10 @@
qcom,sdcc-disable_cmd23;
};
- qcom,sdcc@F984B000 {
+ qcom,sdcc@f984b000 {
cell-index = <3>;
compatible = "qcom,msm-sdcc";
- reg = <0xF984B000 0x1000>;
+ reg = <0xf984b000 0x1000>;
interrupts = <0 127 0>;
qcom,sdcc-clk-rates = <400000 24000000 48000000>;
@@ -68,10 +68,10 @@
qcom,sdcc-disable_cmd23;
};
- qcom,sps@F9980000 {
+ qcom,sps@f9980000 {
compatible = "qcom,msm_sps";
- reg = <0xF9984000 0x15000>,
- <0xF9999000 0xB000>;
+ reg = <0xf9984000 0x15000>,
+ <0xf9999000 0xb000>;
interrupts = <0 94 0>;
qcom,bam-dma-res-pipes = <6>;
@@ -83,4 +83,104 @@
interrupts = <96>;
spi-max-frequency = <24000000>;
};
+
+ qcom,spmi@fc4c0000 {
+ cell-index = <0>;
+ compatible = "qcom,spmi-pmic-arb";
+ reg = <0xfc4cf000 0x1000>,
+ <0Xfc4cb000 0x1000>;
+ /* 190,ee0_krait_hlos_spmi_periph_irq */
+ /* 187,channel_0_krait_hlos_trans_done_irq */
+ interrupts = <0 190 0 0 187 0>;
+ qcom,pmic-arb-ee = <0>;
+ qcom,pmic-arb-channel = <0>;
+ qcom,pmic-arb-ppid-map = <0x130 0x00>, /* PM8941_LDO1 */
+ <0x131 0x01>, /* PM8941_LDO2 */
+ <0x132 0x02>, /* PM8941_LDO3 */
+ <0x133 0x03>, /* PM8941_LDO4 */
+ <0x134 0x04>, /* PM8941_LDO5 */
+ <0x135 0x05>, /* PM8941_LDO6 */
+ <0x136 0x06>, /* PM8941_LDO7 */
+ <0x137 0x07>, /* PM8941_LDO8 */
+ <0x138 0x08>, /* PM8941_LDO9 */
+ <0x139 0x09>, /* PM8941_LDO10 */
+ <0x13a 0x0a>, /* PM8941_LDO11 */
+ <0x13b 0x0b>, /* PM8941_LDO12 */
+ <0x13c 0x0c>, /* PM8941_LDO13 */
+ <0x13d 0x0d>, /* PM8941_LDO14 */
+ <0x13e 0x0e>, /* PM8941_LDO15 */
+ <0x13f 0x0f>, /* PM8941_LDO16 */
+ <0x140 0x10>, /* PM8941_LDO17 */
+ <0x141 0x11>, /* PM8941_LDO18 */
+ <0x142 0x12>, /* PM8941_LDO19 */
+ <0x143 0x13>, /* PM8941_LDO20 */
+ <0x144 0x14>, /* PM8941_LDO21 */
+ <0x145 0x15>, /* PM8941_LDO22 */
+ <0x146 0x16>, /* PM8941_LDO23 */
+ <0x147 0x17>, /* PM8941_LDO24 */
+ <0x148 0x18>, /* PM8941_LDO25 */
+ <0x149 0x19>, /* PM8941_LDO26 */
+ <0x0c0 0x1a>, /* PM8941_GPIO1 */
+ <0x0c1 0x1b>, /* PM8941_GPIO2 */
+ <0x0c2 0x1c>, /* PM8941_GPIO3 */
+ <0x0c3 0x1d>, /* PM8941_GPIO4 */
+ <0x0c4 0x1e>, /* PM8941_GPIO5 */
+ <0x0c5 0x1f>, /* PM8941_GPIO6 */
+ <0x0c6 0x20>, /* PM8941_GPIO7 */
+ <0x0c7 0x21>, /* PM8941_GPIO8 */
+ <0x0c8 0x22>, /* PM8941_GPIO9 */
+ <0x0c9 0x23>, /* PM8941_GPIO10 */
+ <0x0ca 0x24>, /* PM8941_GPIO11 */
+ <0x0cb 0x25>, /* PM8941_GPIO12 */
+ <0x0cc 0x26>, /* PM8941_GPIO13 */
+ <0x0cd 0x27>, /* PM8941_GPIO14 */
+ <0x0ce 0x28>, /* PM8941_GPIO15 */
+ <0x0cf 0x29>, /* PM8941_GPIO16 */
+ <0x0d0 0x2a>, /* PM8941_GPIO17 */
+ <0x0d1 0x2b>, /* PM8941_GPIO18 */
+ <0x0d2 0x2c>, /* PM8941_GPIO19 */
+ <0x0d3 0x2d>, /* PM8941_GPIO20 */
+ <0x0d4 0x2e>, /* PM8941_GPIO21 */
+ <0x0d5 0x2f>, /* PM8941_GPIO22 */
+ <0x0d6 0x30>, /* PM8941_GPIO23 */
+ <0x0d7 0x31>, /* PM8941_GPIO24 */
+ <0x0d8 0x32>, /* PM8941_GPIO25 */
+ <0x0d9 0x33>, /* PM8941_GPIO26 */
+ <0x0da 0x34>, /* PM8941_GPIO27 */
+ <0x0db 0x35>, /* PM8941_GPIO28 */
+ <0x0dc 0x36>, /* PM8941_GPIO29 */
+ <0x0dd 0x37>, /* PM8941_GPIO30 */
+ <0x0de 0x38>, /* PM8941_GPIO31 */
+ <0x0df 0x39>, /* PM8941_GPIO32 */
+ <0x0e0 0x3a>, /* PM8941_GPIO33 */
+ <0x0e1 0x3b>, /* PM8941_GPIO34 */
+ <0x0e2 0x3c>, /* PM8941_GPIO35 */
+ <0x0e3 0x3d>, /* PM8941_GPIO36 */
+ <0x028 0x3e>, /* COINCELL */
+ <0x005 0x3f>, /* INTERRUPT */
+ <0x001 0x40>, /* PM8941_0 */
+ <0x201 0x41>, /* PM8841_0 */
+ <0x101 0x42>, /* PM8941_1 */
+ <0x301 0x43>, /* PM8841_1 */
+ <0x008 0x44>, /* PON0 */
+ <0x208 0x45>, /* PON1 */
+ <0x110 0x46>, /* PM8941_SMPS1 */
+ <0x111 0x47>, /* PM8941_SMPS2 */
+ <0x112 0x48>, /* PM8941_SMPS3 */
+ <0x310 0x49>, /* PM8841_SMPS1 */
+ <0x311 0x4a>, /* PM8841_SMPS2 */
+ <0x312 0x4b>, /* PM8841_SMPS3 */
+ <0x313 0x4c>, /* PM8841_SMPS4 */
+ <0x314 0x4d>, /* PM8841_SMPS5 */
+ <0x315 0x4e>, /* PM8841_SMPS6 */
+ <0x316 0x4f>, /* PM8841_SMPS7 */
+ <0x317 0x50>, /* PM8841_SMPS8 */
+ <0x050 0x51>, /* SHARED_XO */
+ <0x051 0x52>, /* BB_CLK1 */
+ <0x052 0x53>, /* BB_CLK2 */
+ <0x059 0x54>, /* SLEEP_CLK */
+ <0x010 0x55>, /* SMBC_OVP */
+ <0x011 0x56>, /* SMBC_CHG */
+ <0x012 0x57>; /* SMBC_BIF */
+ };
};
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index a708fbc..8a505cc 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -37,10 +37,8 @@
CONFIG_CPU_HAS_L2_PMU=y
# CONFIG_MSM_FIQ_SUPPORT is not set
# CONFIG_MSM_PROC_COMM is not set
-# CONFIG_MSM_DALRPC is not set
# CONFIG_MSM_HW3D is not set
CONFIG_MSM_DIRECT_SCLK_ACCESS=y
-# CONFIG_MSM_JTAG_V7 is not set
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_SMP=y
@@ -94,6 +92,8 @@
CONFIG_SERIAL_MSM_HSL_CONSOLE=y
CONFIG_HW_RANDOM=y
CONFIG_DCC_TTY=y
+CONFIG_SPMI=y
+CONFIG_SPMI_MSM_PMIC_ARB=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y
CONFIG_POWER_SUPPLY=y
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
index 3c87f8d..dd8cb16 100644
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -26,6 +26,7 @@
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
CONFIG_MSM_SOC_REV_A=y
# CONFIG_MACH_MSM7X27_SURF is not set
# CONFIG_MACH_MSM7X27_FFA is not set
@@ -44,7 +45,6 @@
# CONFIG_MSM_HW3D is not set
CONFIG_MSM7X27A_AUDIO=y
CONFIG_MSM_DMA_TEST=y
-# CONFIG_MSM_JTAG_V7 is not set
CONFIG_MSM_SLEEP_STATS_DEVICE=y
CONFIG_BT_MSM_PINTEST=y
CONFIG_MSM_RPC_VIBRATOR=y
@@ -52,6 +52,7 @@
CONFIG_ARM_THUMBEE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
@@ -231,6 +232,7 @@
# CONFIG_MT9T013 is not set
# CONFIG_MT9D112 is not set
CONFIG_OV5640=y
+CONFIG_OV5647=y
CONFIG_WEBCAM_OV7692_QRD=y
CONFIG_WEBCAM_OV9726=y
# CONFIG_MT9P012 is not set
@@ -254,6 +256,7 @@
CONFIG_SOUND=y
CONFIG_SND=y
CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
CONFIG_HID_APPLE=y
CONFIG_HID_MAGICMOUSE=y
CONFIG_HID_MICROSOFT=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
index cc33b8f..199b91f 100644
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -26,6 +26,7 @@
# CONFIG_IOSCHED_DEADLINE is not set
CONFIG_ARCH_MSM=y
CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
CONFIG_MSM_SOC_REV_A=y
# CONFIG_MACH_MSM7X27_SURF is not set
# CONFIG_MACH_MSM7X27_FFA is not set
@@ -52,6 +53,7 @@
CONFIG_ARM_THUMBEE=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
CONFIG_PREEMPT=y
CONFIG_AEABI=y
CONFIG_HIGHMEM=y
@@ -349,3 +351,4 @@
CONFIG_CRYPTO_SHA256=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRC_CCITT=y
+CONFIG_OV5647=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index b71df28..b3a45d2 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -326,6 +326,7 @@
CONFIG_USB_VIDEO_CLASS=y
CONFIG_WEBCAM_OV9726=y
CONFIG_MT9E013=y
+CONFIG_IMX074=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 9fd7e71..1f511bb 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -326,6 +326,7 @@
CONFIG_USB_VIDEO_CLASS=y
CONFIG_WEBCAM_OV9726=y
CONFIG_MT9E013=y
+CONFIG_IMX074=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
diff --git a/arch/arm/configs/msm8960-perf_defconfig b/arch/arm/configs/msm8960-perf_defconfig
index 95dd09c..f1b1fa5 100644
--- a/arch/arm/configs/msm8960-perf_defconfig
+++ b/arch/arm/configs/msm8960-perf_defconfig
@@ -1,4 +1,5 @@
CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="-perf"
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
@@ -52,6 +53,8 @@
CONFIG_MACH_APQ8064_CDP=y
CONFIG_MACH_APQ8064_MTP=y
CONFIG_MACH_APQ8064_LIQUID=y
+CONFIG_MACH_MPQ8064_HRD=y
+CONFIG_MACH_MPQ8064_DTV=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_KERNEL_PMEM_EBI_REGION=y
# CONFIG_MSM_FIQ_SUPPORT is not set
@@ -311,6 +314,9 @@
CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
+CONFIG_IMX074=y
+CONFIG_IMX074_ACT=y
+CONFIG_OV2720=y
CONFIG_S5K3L1YX=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_IRIS=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 3a70b22..e58b94b 100644
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -52,6 +52,8 @@
CONFIG_MACH_APQ8064_CDP=y
CONFIG_MACH_APQ8064_MTP=y
CONFIG_MACH_APQ8064_LIQUID=y
+CONFIG_MACH_MPQ8064_HRD=y
+CONFIG_MACH_MPQ8064_DTV=y
# CONFIG_MSM_STACKED_MEMORY is not set
CONFIG_KERNEL_PMEM_EBI_REGION=y
# CONFIG_MSM_FIQ_SUPPORT is not set
@@ -82,6 +84,8 @@
CONFIG_MSM_QDSS=y
CONFIG_MSM_QDSS_ETM_DEFAULT_ENABLE=y
CONFIG_MSM_SLEEP_STATS=y
+CONFIG_MSM_RTB=y
+CONFIG_MSM_RTB_SEPARATE_CPUS=y
CONFIG_STRICT_MEMORY_RWX=y
CONFIG_NO_HZ=y
CONFIG_HIGH_RES_TIMERS=y
@@ -312,6 +316,9 @@
CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
+CONFIG_IMX074=y
+CONFIG_IMX074_ACT=y
+CONFIG_OV2720=y
CONFIG_S5K3L1YX=y
CONFIG_MSM_GEMINI=y
CONFIG_RADIO_IRIS=y
@@ -433,13 +440,13 @@
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_TIMER_STATS=y
-CONFIG_SLUB_DEBUG_ON=y
CONFIG_DEBUG_KMEMLEAK=y
CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y
# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_SPINLOCK_SLEEP=y
+CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_MEMORY_INIT=y
CONFIG_DEBUG_LIST=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 543a4f9f..7ba17e6 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -142,7 +142,6 @@
CONFIG_IP6_NF_TARGET_REJECT_SKERR=y
CONFIG_IP6_NF_MANGLE=y
CONFIG_IP6_NF_RAW=y
-CONFIG_CFG80211=y
CONFIG_MTD=y
CONFIG_MTD_TESTS=m
CONFIG_MTD_CMDLINE_PARTS=y
@@ -162,7 +161,7 @@
CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
-CONFIG_HOSTAP=y
+CONFIG_ATH6K_LEGACY=y
# CONFIG_MSM_RMNET is not set
CONFIG_MSM_RMNET_BAM=y
# CONFIG_INPUT_MOUSEDEV is not set
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index c3b841a..d2434e6 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -54,79 +54,46 @@
* consider why they can't support the logging.
*/
+#define __raw_write_logged(v, a, _t) ({ \
+ int _ret; \
+ void *_addr = (void *)(a); \
+ _ret = uncached_logk(LOGK_WRITEL, _addr); \
+ ETB_WAYPOINT; \
+ __raw_write##_t##_no_log((v), _addr); \
+ if (_ret) \
+ LOG_BARRIER; \
+ })
+
+
#define __raw_writeb_no_log(v, a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
#define __raw_writew_no_log(v, a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
#define __raw_writel_no_log(v, a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
-#define __raw_writeb(v, a) ({ \
- int _ret; \
- void *_addr = (void *)(a); \
- _ret = uncached_logk(LOGK_WRITEL, _addr); \
- ETB_WAYPOINT; \
- __raw_writeb_no_log(v, _addr); \
- if (_ret) \
- LOG_BARRIER; \
- })
-#define __raw_writew(v, a) ({ \
- int _ret; \
- void *_addr = (void *)(a); \
- _ret = uncached_logk(LOGK_WRITEL, _addr); \
- ETB_WAYPOINT; \
- __raw_writew_no_log(v, _addr); \
- if (_ret) \
- LOG_BARRIER; \
- })
-
-#define __raw_writel(v, a) ({ \
- int _ret; \
- void *_addr = (void *)(a); \
- _ret = uncached_logk(LOGK_WRITEL, _addr); \
- ETB_WAYPOINT; \
- __raw_writel_no_log(v, _addr); \
- if (_ret) \
- LOG_BARRIER; \
- })
+#define __raw_writeb(v, a) __raw_write_logged((v), (a), b)
+#define __raw_writew(v, a) __raw_write_logged((v), (a), w)
+#define __raw_writel(v, a) __raw_write_logged((v), (a), l)
#define __raw_readb_no_log(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
#define __raw_readw_no_log(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
#define __raw_readl_no_log(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
-#define __raw_readb(a) ({ \
- unsigned char __a; \
+#define __raw_read_logged(a, _l, _t) ({ \
+ unsigned _t __a; \
void *_addr = (void *)(a); \
int _ret; \
_ret = uncached_logk(LOGK_READL, _addr); \
ETB_WAYPOINT; \
- __a = __raw_readb_no_log(_addr);\
+ __a = __raw_read##_l##_no_log(_addr);\
if (_ret) \
LOG_BARRIER; \
__a; \
})
-#define __raw_readw(a) ({ \
- unsigned short __a; \
- void *_addr = (void *)(a); \
- int _ret; \
- _ret = uncached_logk(LOGK_READL, _addr); \
- ETB_WAYPOINT; \
- __a = __raw_readw_no_log(_addr);\
- if (_ret) \
- LOG_BARRIER; \
- __a; \
- })
-#define __raw_readl(a) ({ \
- unsigned int __a; \
- void *_addr = (void *)(a); \
- int _ret; \
- _ret = uncached_logk(LOGK_READL, _addr); \
- ETB_WAYPOINT; \
- __a = __raw_readl_no_log(_addr);\
- if (_ret) \
- LOG_BARRIER; \
- __a; \
- })
+#define __raw_readb(a) __raw_read_logged((a), b, char)
+#define __raw_readw(a) __raw_read_logged((a), w, short)
+#define __raw_readl(a) __raw_read_logged((a), l, int)
/*
* Architecture ioremap implementation.
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 0b0f733..18fbcf6 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -747,6 +747,18 @@
help
Support for the Qualcomm APQ8064 LIQUID device.
+config MACH_MPQ8064_HRD
+ depends on ARCH_APQ8064
+ bool "MPQ8064 HRD"
+ help
+ Support for the Qualcomm MPQ8064 HRD device.
+
+config MACH_MPQ8064_DTV
+ depends on ARCH_APQ8064
+ bool "MPQ8064 DTV"
+ help
+ Support for the Qualcomm MPQ8064 DTV device.
+
config MACH_FSM9XXX_SURF
depends on ARCH_FSM9XXX
depends on !MSM_STACKED_MEMORY
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index b2f7c84d..8347a25 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -38,7 +38,12 @@
obj-$(CONFIG_MSM_SOC_REV_NONE) += acpuclock-8x50.o
endif
-obj-$(CONFIG_SMP) += headsmp.o platsmp.o
+obj-$(CONFIG_SMP) += headsmp.o
+ifdef CONFIG_ARCH_MSM8625
+ obj-$(CONFIG_SMP) += platsmp-8625.o
+else
+ obj-$(CONFIG_SMP) += platsmp.o
+endif
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
obj-$(CONFIG_MSM_CPU_AVS) += avs.o
@@ -88,12 +93,14 @@
ifndef CONFIG_ARCH_APQ8064
ifndef CONFIG_ARCH_MSM8960
ifndef CONFIG_ARCH_MSM8X60
+ifndef CONFIG_ARCH_MSMCOPPER
obj-$(CONFIG_MSM_SMD) += pmic.o
obj-$(CONFIG_MSM_ONCRPCROUTER) += rpc_hsusb.o rpc_pmapp.o rpc_fsusb.o
endif
endif
endif
endif
+endif
ifndef CONFIG_ARCH_MSM8960
ifndef CONFIG_ARCH_MSM8X60
ifndef CONFIG_ARCH_APQ8064
diff --git a/arch/arm/mach-msm/acpuclock-7201.c b/arch/arm/mach-msm/acpuclock-7201.c
index 6140559..7ad3f65 100644
--- a/arch/arm/mach-msm/acpuclock-7201.c
+++ b/arch/arm/mach-msm/acpuclock-7201.c
@@ -757,7 +757,7 @@
res = clk_set_rate(drv_state.ebi1_clk, speed->axiclk_khz * 1000);
if (res < 0)
pr_warning("Setting AXI min rate failed (%d)\n", res);
- res = clk_enable(drv_state.ebi1_clk);
+ res = clk_prepare_enable(drv_state.ebi1_clk);
if (res < 0)
pr_warning("Enabling AXI clock failed (%d)\n", res);
diff --git a/arch/arm/mach-msm/acpuclock-8960.c b/arch/arm/mach-msm/acpuclock-8960.c
index 470e836..99c3d78 100644
--- a/arch/arm/mach-msm/acpuclock-8960.c
+++ b/arch/arm/mach-msm/acpuclock-8960.c
@@ -148,10 +148,10 @@
.vreg[VREG_DIG] = { "krait0_dig", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
+ .vreg[VREG_HFPLL_A] = { "hfpll0_s8", 2100000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_S8 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll0_l23", 1800000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_L23 },
},
@@ -160,16 +160,16 @@
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
.vreg[VREG_CORE] = { "krait1", 1300000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", 1150000,
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
+ .vreg[VREG_HFPLL_A] = { "hfpll1_s8", 2100000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_S8 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll1_l23", 1800000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_L23 },
},
@@ -177,10 +177,10 @@
.hfpll_base = MSM_HFPLL_BASE + 0x400,
.aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
.l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_A] = { "hfpll", 2100000,
+ .vreg[VREG_HFPLL_A] = { "hfpll_l2_s8", 2100000,
RPM_VREG_VOTER6,
RPM_VREG_ID_PM8921_S8 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll_l2_l23", 1800000,
RPM_VREG_VOTER6,
RPM_VREG_ID_PM8921_L23 },
},
@@ -201,7 +201,7 @@
.vreg[VREG_DIG] = { "krait0_dig", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8921_LVS7 },
},
@@ -210,13 +210,13 @@
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
.vreg[VREG_CORE] = { "krait1", 1150000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", 1150000,
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8921_LVS7 },
},
@@ -225,13 +225,13 @@
.aux_clk_sel = MSM_ACC2_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
.vreg[VREG_CORE] = { "krait2", 1150000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
+ .vreg[VREG_MEM] = { "krait2_mem", 1150000,
RPM_VREG_VOTER4,
RPM_VREG_ID_PM8921_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", 1150000,
+ .vreg[VREG_DIG] = { "krait2_dig", 1150000,
RPM_VREG_VOTER4,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll2", 1800000,
RPM_VREG_VOTER4,
RPM_VREG_ID_PM8921_LVS7 },
},
@@ -240,13 +240,13 @@
.aux_clk_sel = MSM_ACC3_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
.vreg[VREG_CORE] = { "krait3", 1150000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
+ .vreg[VREG_MEM] = { "krait3_mem", 1150000,
RPM_VREG_VOTER5,
RPM_VREG_ID_PM8921_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", 1150000,
+ .vreg[VREG_DIG] = { "krait3_dig", 1150000,
RPM_VREG_VOTER5,
RPM_VREG_ID_PM8921_S3 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll3", 1800000,
RPM_VREG_VOTER5,
RPM_VREG_ID_PM8921_LVS7 },
},
@@ -254,7 +254,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x300,
.aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
.l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
RPM_VREG_VOTER6,
RPM_VREG_ID_PM8921_LVS7 },
},
@@ -272,7 +272,7 @@
.vreg[VREG_DIG] = { "krait0_dig", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8038_S1 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8038_L23 },
},
@@ -281,13 +281,13 @@
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
.vreg[VREG_CORE] = { "krait1", 1300000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8038_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", 1150000,
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8038_S1 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8038_L23 },
},
@@ -295,7 +295,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x400,
.aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
.l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
RPM_VREG_VOTER6,
RPM_VREG_ID_PM8038_L23 },
},
@@ -314,7 +314,7 @@
.vreg[VREG_DIG] = { "krait0_dig", 1150000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8038_S1 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll0", 1800000,
RPM_VREG_VOTER1,
RPM_VREG_ID_PM8038_L23 },
},
@@ -323,13 +323,13 @@
.aux_clk_sel = MSM_ACC1_BASE + 0x014,
.l2cpmr_iaddr = L2CPUCPMR_IADDR,
.vreg[VREG_CORE] = { "krait1", 1300000 },
- .vreg[VREG_MEM] = { "krait0_mem", 1150000,
+ .vreg[VREG_MEM] = { "krait1_mem", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8038_L24 },
- .vreg[VREG_DIG] = { "krait0_dig", 1150000,
+ .vreg[VREG_DIG] = { "krait1_dig", 1150000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8038_S1 },
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll1", 1800000,
RPM_VREG_VOTER2,
RPM_VREG_ID_PM8038_L23 },
},
@@ -337,7 +337,7 @@
.hfpll_base = MSM_HFPLL_BASE + 0x400,
.aux_clk_sel = MSM_APCS_GCC_BASE + 0x028,
.l2cpmr_iaddr = L2CPMR_IADDR,
- .vreg[VREG_HFPLL_B] = { "hfpll", 1800000,
+ .vreg[VREG_HFPLL_B] = { "hfpll_l2", 1800000,
RPM_VREG_VOTER6,
RPM_VREG_ID_PM8038_L23 },
},
@@ -922,8 +922,8 @@
sc->vreg[VREG_MEM].rpm_vreg_voter, vdd_mem,
sc->vreg[VREG_MEM].max_vdd, 0);
if (rc) {
- pr_err("%s: vdd_mem (cpu%d) increase failed (%d)\n",
- __func__, cpu, rc);
+ pr_err("%s increase failed (%d)\n",
+ sc->vreg[VREG_MEM].name, rc);
return rc;
}
sc->vreg[VREG_MEM].cur_vdd = vdd_mem;
@@ -935,8 +935,8 @@
sc->vreg[VREG_DIG].rpm_vreg_voter, vdd_dig,
sc->vreg[VREG_DIG].max_vdd, 0);
if (rc) {
- pr_err("%s: vdd_dig (cpu%d) increase failed (%d)\n",
- __func__, cpu, rc);
+ pr_err("%s increase failed (%d)\n",
+ sc->vreg[VREG_DIG].name, rc);
return rc;
}
sc->vreg[VREG_DIG].cur_vdd = vdd_dig;
@@ -953,8 +953,8 @@
rc = regulator_set_voltage(sc->vreg[VREG_CORE].reg, vdd_core,
sc->vreg[VREG_CORE].max_vdd);
if (rc) {
- pr_err("%s: vdd_core (cpu%d) increase failed (%d)\n",
- __func__, cpu, rc);
+ pr_err("%s increase failed (%d)\n",
+ sc->vreg[VREG_CORE].name, rc);
return rc;
}
sc->vreg[VREG_CORE].cur_vdd = vdd_core;
@@ -980,8 +980,8 @@
ret = regulator_set_voltage(sc->vreg[VREG_CORE].reg, vdd_core,
sc->vreg[VREG_CORE].max_vdd);
if (ret) {
- pr_err("%s: vdd_core (cpu%d) decrease failed (%d)\n",
- __func__, cpu, ret);
+ pr_err("%s decrease failed (%d)\n",
+ sc->vreg[VREG_CORE].name, ret);
return;
}
sc->vreg[VREG_CORE].cur_vdd = vdd_core;
@@ -993,8 +993,8 @@
sc->vreg[VREG_DIG].rpm_vreg_voter, vdd_dig,
sc->vreg[VREG_DIG].max_vdd, 0);
if (ret) {
- pr_err("%s: vdd_dig (cpu%d) decrease failed (%d)\n",
- __func__, cpu, ret);
+ pr_err("%s decrease failed (%d)\n",
+ sc->vreg[VREG_DIG].name, ret);
return;
}
sc->vreg[VREG_DIG].cur_vdd = vdd_dig;
@@ -1009,8 +1009,8 @@
sc->vreg[VREG_MEM].rpm_vreg_voter, vdd_mem,
sc->vreg[VREG_MEM].max_vdd, 0);
if (ret) {
- pr_err("%s: vdd_mem (cpu%d) decrease failed (%d)\n",
- __func__, cpu, ret);
+ pr_err("%s decrease failed (%d)\n",
+ sc->vreg[VREG_MEM].name, ret);
return;
}
sc->vreg[VREG_MEM].cur_vdd = vdd_mem;
@@ -1147,7 +1147,7 @@
pr_debug("Initializing HFPLL%d\n", sc - scalable);
/* Disable the PLL for re-programming. */
- hfpll_disable(sc, 0);
+ hfpll_disable(sc, 1);
/* Configure PLL parameters for integer mode. */
writel_relaxed(0x7845C665, sc->hfpll_base + HFPLL_CONFIG_CTL);
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index f1abde4..0a56dd2 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -671,7 +671,7 @@
skb = info->skb;
kfree(info);
hdr = (struct bam_mux_hdr *)skb->data;
- DBG_INC_WRITE_CNT(skb->data_len);
+ DBG_INC_WRITE_CNT(skb->len);
event_data = (unsigned long)(skb);
spin_lock_irqsave(&bam_ch[hdr->ch_id].lock, flags);
bam_ch[hdr->ch_id].num_tx_pkts--;
@@ -1194,11 +1194,15 @@
int i = 0;
i += scnprintf(buf + i, max - i,
+ "skb read cnt: %u\n"
+ "skb write cnt: %u\n"
"skb copy cnt: %u\n"
"skb copy bytes: %u\n"
"sps tx failures: %u\n"
"sps tx stalls: %u\n"
"rx queue len: %d\n",
+ bam_dmux_read_cnt,
+ bam_dmux_write_cnt,
bam_dmux_write_cpy_cnt,
bam_dmux_write_cpy_bytes,
bam_dmux_tx_sps_failure_cnt,
diff --git a/arch/arm/mach-msm/board-8064-camera.c b/arch/arm/mach-msm/board-8064-camera.c
index cd84722..109ed2c 100644
--- a/arch/arm/mach-msm/board-8064-camera.c
+++ b/arch/arm/mach-msm/board-8064-camera.c
@@ -41,8 +41,8 @@
},
{
- .func = GPIOMUX_FUNC_1, /*active 3*/
- .drv = GPIOMUX_DRV_8MA,
+ .func = GPIOMUX_FUNC_2, /*active 3*/
+ .drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_NONE,
},
@@ -76,6 +76,27 @@
.pull = GPIOMUX_PULL_KEEPER,
},
+ {
+ .func = GPIOMUX_FUNC_9, /*active 9*/
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ {
+ .func = GPIOMUX_FUNC_A, /*active 10*/
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ {
+ .func = GPIOMUX_FUNC_6, /*active 11*/
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+ {
+ .func = GPIOMUX_FUNC_4, /*active 12*/
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+ },
+
};
@@ -83,7 +104,7 @@
{
.gpio = 2,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[2],
+ [GPIOMUX_ACTIVE] = &cam_settings[12],
[GPIOMUX_SUSPENDED] = &cam_settings[0],
},
},
@@ -97,7 +118,7 @@
{
.gpio = 4,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[1],
+ [GPIOMUX_ACTIVE] = &cam_settings[3],
[GPIOMUX_SUSPENDED] = &cam_settings[0],
},
},
@@ -109,7 +130,7 @@
},
},
{
- .gpio = 76,
+ .gpio = 34,
.settings = {
[GPIOMUX_ACTIVE] = &cam_settings[2],
[GPIOMUX_SUSPENDED] = &cam_settings[0],
@@ -122,39 +143,39 @@
[GPIOMUX_SUSPENDED] = &cam_settings[0],
},
},
-};
-
-static struct msm_gpiomux_config apq8064_cam_2d_configs[] = {
{
.gpio = 10,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_ACTIVE] = &cam_settings[9],
[GPIOMUX_SUSPENDED] = &cam_settings[8],
},
},
{
.gpio = 11,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_ACTIVE] = &cam_settings[10],
[GPIOMUX_SUSPENDED] = &cam_settings[8],
},
},
{
.gpio = 12,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_ACTIVE] = &cam_settings[11],
[GPIOMUX_SUSPENDED] = &cam_settings[8],
},
},
{
.gpio = 13,
.settings = {
- [GPIOMUX_ACTIVE] = &cam_settings[3],
+ [GPIOMUX_ACTIVE] = &cam_settings[11],
[GPIOMUX_SUSPENDED] = &cam_settings[8],
},
},
};
+static struct msm_gpiomux_config apq8064_cam_2d_configs[] = {
+};
+
#ifdef CONFIG_MSM_CAMERA
static struct msm_bus_vectors cam_init_vectors[] = {
@@ -310,27 +331,36 @@
},
};
-static struct camera_vreg_t msm_8064_back_cam_vreg[] = {
+static struct camera_vreg_t apq_8064_back_cam_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
{"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vio", REG_VS, 0, 0, 0},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
};
+static struct camera_vreg_t apq_8064_front_cam_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
+#define CAML_RSTN PM8921_GPIO_PM_TO_SYS(28)
+#define CAMR_RSTN 34
+
static struct gpio apq8064_common_cam_gpio[] = {
- {5, GPIOF_DIR_IN, "CAMIF_MCLK"},
- {20, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
- {21, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
};
static struct gpio apq8064_back_cam_gpio[] = {
- {107, GPIOF_DIR_OUT, "CAM_RESET"},
+ {5, GPIOF_DIR_IN, "CAMIF_MCLK"},
+ {CAML_RSTN, GPIOF_DIR_OUT, "CAM_RESET"},
};
static struct msm_gpio_set_tbl apq8064_back_cam_gpio_set_tbl[] = {
- {107, GPIOF_OUT_INIT_LOW, 1000},
- {107, GPIOF_OUT_INIT_HIGH, 4000},
+ {CAML_RSTN, GPIOF_OUT_INIT_LOW, 10000},
+ {CAML_RSTN, GPIOF_OUT_INIT_HIGH, 10000},
};
static struct msm_camera_gpio_conf apq8064_back_cam_gpio_conf = {
@@ -344,6 +374,41 @@
.cam_gpio_set_tbl_size = ARRAY_SIZE(apq8064_back_cam_gpio_set_tbl),
};
+static struct gpio apq8064_front_cam_gpio[] = {
+ {4, GPIOF_DIR_IN, "CAMIF_MCLK"},
+ {12, GPIOF_DIR_IN, "CAMIF_I2C_DATA"},
+ {13, GPIOF_DIR_IN, "CAMIF_I2C_CLK"},
+ {CAMR_RSTN, GPIOF_DIR_OUT, "CAM_RESET"},
+};
+
+static struct msm_gpio_set_tbl apq8064_front_cam_gpio_set_tbl[] = {
+ {CAMR_RSTN, GPIOF_OUT_INIT_LOW, 10000},
+ {CAMR_RSTN, GPIOF_OUT_INIT_HIGH, 10000},
+};
+
+static struct msm_camera_gpio_conf apq8064_front_cam_gpio_conf = {
+ .cam_gpiomux_conf_tbl = apq8064_cam_2d_configs,
+ .cam_gpiomux_conf_tbl_size = ARRAY_SIZE(apq8064_cam_2d_configs),
+ .cam_gpio_common_tbl = apq8064_common_cam_gpio,
+ .cam_gpio_common_tbl_size = ARRAY_SIZE(apq8064_common_cam_gpio),
+ .cam_gpio_req_tbl = apq8064_front_cam_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(apq8064_front_cam_gpio),
+ .cam_gpio_set_tbl = apq8064_front_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(apq8064_front_cam_gpio_set_tbl),
+};
+
+static struct msm_camera_i2c_conf apq8064_back_cam_i2c_conf = {
+ .use_i2c_mux = 1,
+ .mux_dev = &msm8960_device_i2c_mux_gsbi4,
+ .i2c_mux_mode = MODE_L,
+};
+
+static struct msm_camera_i2c_conf apq8064_front_cam_i2c_conf = {
+ .use_i2c_mux = 1,
+ .mux_dev = &msm8960_device_i2c_mux_gsbi4,
+ .i2c_mux_mode = MODE_L,
+};
+
#ifdef CONFIG_IMX074
static struct msm_camera_sensor_flash_data flash_imx074 = {
.flash_type = MSM_CAMERA_FLASH_NONE,
@@ -351,9 +416,10 @@
static struct msm_camera_sensor_platform_info sensor_board_info_imx074 = {
.mount_angle = 90,
- .cam_vreg = msm_8064_back_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8064_back_cam_vreg),
+ .cam_vreg = apq_8064_back_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_back_cam_vreg),
.gpio_conf = &apq8064_back_cam_gpio_conf,
+ .i2c_conf = &apq8064_back_cam_i2c_conf,
};
static struct msm_camera_sensor_info msm_camera_sensor_imx074_data = {
@@ -366,11 +432,36 @@
};
#endif
+#ifdef CONFIG_OV2720
+static struct msm_camera_sensor_flash_data flash_ov2720 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov2720 = {
+ .mount_angle = 0,
+ .cam_vreg = apq_8064_front_cam_vreg,
+ .num_vreg = ARRAY_SIZE(apq_8064_front_cam_vreg),
+ .gpio_conf = &apq8064_front_cam_gpio_conf,
+ .i2c_conf = &apq8064_front_cam_i2c_conf,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov2720_data = {
+ .sensor_name = "ov2720",
+ .pdata = &msm_camera_csi_device_data[1],
+ .flash_data = &flash_ov2720,
+ .sensor_platform_info = &sensor_board_info_ov2720,
+ .csi_if = 1,
+ .camera_type = FRONT_CAMERA_2D,
+};
+#endif
+
+
void __init apq8064_init_cam(void)
{
msm_gpiomux_install(apq8064_cam_common_configs,
ARRAY_SIZE(apq8064_cam_common_configs));
+ platform_device_register(&msm8960_device_i2c_mux_gsbi4);
platform_device_register(&msm8960_device_csiphy0);
platform_device_register(&msm8960_device_csiphy1);
platform_device_register(&msm8960_device_csid0);
@@ -388,6 +479,12 @@
.platform_data = &msm_camera_sensor_imx074_data,
},
#endif
+#ifdef CONFIG_OV2720
+ {
+ I2C_BOARD_INFO("ov2720", 0x6C),
+ .platform_data = &msm_camera_sensor_ov2720_data,
+ },
+#endif
};
struct msm_camera_board_info apq8064_camera_board_info = {
diff --git a/arch/arm/mach-msm/board-8064-gpiomux.c b/arch/arm/mach-msm/board-8064-gpiomux.c
index c3cc9eb..9b6c253 100644
--- a/arch/arm/mach-msm/board-8064-gpiomux.c
+++ b/arch/arm/mach-msm/board-8064-gpiomux.c
@@ -64,6 +64,18 @@
};
#endif
+static struct gpiomux_setting gpio_i2c_config = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_8MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+
+static struct gpiomux_setting gpio_i2c_config_sus = {
+ .func = GPIOMUX_FUNC_1,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_KEEPER,
+};
+
static struct gpiomux_setting cdc_mclk = {
.func = GPIOMUX_FUNC_1,
.drv = GPIOMUX_DRV_8MA,
@@ -347,6 +359,20 @@
[GPIOMUX_SUSPENDED] = &gsbi7_func1_cfg,
},
},
+ {
+ .gpio = 21, /* GSBI1 QUP I2C_CLK */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_i2c_config_sus,
+ [GPIOMUX_ACTIVE] = &gpio_i2c_config,
+ },
+ },
+ {
+ .gpio = 20, /* GSBI1 QUP I2C_DATA */
+ .settings = {
+ [GPIOMUX_SUSPENDED] = &gpio_i2c_config_sus,
+ [GPIOMUX_ACTIVE] = &gpio_i2c_config,
+ },
+ },
};
static struct msm_gpiomux_config apq8064_slimbus_config[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8064-pmic.c b/arch/arm/mach-msm/board-8064-pmic.c
index 02dfc5e..4c386e9 100644
--- a/arch/arm/mach-msm/board-8064-pmic.c
+++ b/arch/arm/mach-msm/board-8064-pmic.c
@@ -117,6 +117,9 @@
PM8921_GPIO_OUTPUT_BUFCONF(25, 0, LOW, CMOS), /* DISP_RESET_N */
PM8921_GPIO_OUTPUT_FUNC(26, 0, PM_GPIO_FUNC_2), /* Bl: Off, PWM mode */
PM8921_GPIO_OUTPUT_BUFCONF(36, 1, LOW, OPEN_DRAIN),
+ PM8921_GPIO_OUTPUT_FUNC(44, 0, PM_GPIO_FUNC_2),
+ PM8921_GPIO_OUTPUT(33, 0, HIGH),
+ PM8921_GPIO_OUTPUT(20, 0, HIGH),
};
/* Initial PM8XXX MPP configurations */
diff --git a/arch/arm/mach-msm/board-8064-regulator.c b/arch/arm/mach-msm/board-8064-regulator.c
index 4e29feb..caee8ba 100644
--- a/arch/arm/mach-msm/board-8064-regulator.c
+++ b/arch/arm/mach-msm/board-8064-regulator.c
@@ -157,6 +157,7 @@
REGULATOR_SUPPLY("riva_vddpx", "wcnss_wlan.0"),
REGULATOR_SUPPLY("vcc_i2c", "3-005b"),
REGULATOR_SUPPLY("vcc_i2c", "3-0024"),
+ REGULATOR_SUPPLY("vddp", "0-0048"),
};
VREG_CONSUMERS(S5) = {
REGULATOR_SUPPLY("8921_s5", NULL),
diff --git a/arch/arm/mach-msm/board-8064-storage.c b/arch/arm/mach-msm/board-8064-storage.c
index 0d187a9..9069039 100644
--- a/arch/arm/mach-msm/board-8064-storage.c
+++ b/arch/arm/mach-msm/board-8064-storage.c
@@ -121,8 +121,8 @@
static struct msm_mmc_pad_pull sdc1_pad_pull_off_cfg[] = {
{TLMM_PULL_SDC1_CLK, GPIO_CFG_NO_PULL},
- {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_DOWN},
- {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_DOWN}
+ {TLMM_PULL_SDC1_CMD, GPIO_CFG_PULL_UP},
+ {TLMM_PULL_SDC1_DATA, GPIO_CFG_PULL_UP}
};
/* SDC3 pad data */
@@ -146,8 +146,8 @@
static struct msm_mmc_pad_pull sdc3_pad_pull_off_cfg[] = {
{TLMM_PULL_SDC3_CLK, GPIO_CFG_NO_PULL},
- {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_DOWN},
- {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_DOWN}
+ {TLMM_PULL_SDC3_CMD, GPIO_CFG_PULL_UP},
+ {TLMM_PULL_SDC3_DATA, GPIO_CFG_PULL_UP}
};
static struct msm_mmc_pad_pull_data mmc_pad_pull_data[MAX_SDCC_CONTROLLER] = {
@@ -220,7 +220,7 @@
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
static unsigned int sdc3_sup_clk_rates[] = {
- 400000, 24000000, 48000000, 96000000
+ 400000, 24000000, 48000000, 96000000, 192000000
};
static struct mmc_platform_data sdc3_data = {
@@ -234,6 +234,10 @@
.status_irq = MSM_GPIO_TO_INT(26),
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
.is_status_gpio_active_low = 1,
+ .xpc_cap = 1,
+ .uhs_caps = (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_DDR50 |
+ MMC_CAP_UHS_SDR104 | MMC_CAP_MAX_CURRENT_800),
};
static struct mmc_platform_data *apq8064_sdc3_pdata = &sdc3_data;
#else
diff --git a/arch/arm/mach-msm/board-8064.c b/arch/arm/mach-msm/board-8064.c
index c07f497b..12cee78 100644
--- a/arch/arm/mach-msm/board-8064.c
+++ b/arch/arm/mach-msm/board-8064.c
@@ -18,6 +18,7 @@
#include <linux/slimbus/slimbus.h>
#include <linux/mfd/wcd9310/core.h>
#include <linux/mfd/wcd9310/pdata.h>
+#include <linux/mfd/pm8xxx/misc.h>
#include <linux/msm_ssbi.h>
#include <linux/spi/spi.h>
#include <linux/dma-mapping.h>
@@ -26,6 +27,7 @@
#include <linux/memory.h>
#include <linux/i2c/atmel_mxt_ts.h>
#include <linux/cyttsp.h>
+#include <linux/i2c/isa1200.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
@@ -54,6 +56,7 @@
#include <mach/msm_bus_board.h>
#include <mach/cpuidle.h>
#include <mach/mdm2.h>
+#include <linux/msm_tsens.h>
#include "msm_watchdog.h"
#include "board-8064.h"
@@ -78,7 +81,7 @@
#define MSM_ION_SF_SIZE MSM_PMEM_SIZE
#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
#define MSM_ION_MM_SIZE MSM_PMEM_ADSP_SIZE
-#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
+#define MSM_ION_QSECOM_SIZE 0x300000 /* (3MB) */
#define MSM_ION_MFC_SIZE SZ_8K
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 8
@@ -233,6 +236,18 @@
.align = SZ_128K,
};
#endif
+
+/**
+ * These heaps are listed in the order they will be allocated. Due to
+ * video hardware restrictions and content protection the FW heap has to
+ * be allocated adjacent (below) the MM heap and the MFC heap has to be
+ * allocated after the MM heap to ensure MFC heap is not more than 256MB
+ * away from the base address of the FW heap.
+ * However, the order of FW heap and MM heap doesn't matter since these
+ * two heaps are taken care of by separate code to ensure they are adjacent
+ * to each other.
+ * Don't swap the order unless you know what you are doing!
+ */
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
@@ -243,14 +258,6 @@
},
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
{
- .id = ION_SF_HEAP_ID,
- .type = ION_HEAP_TYPE_CARVEOUT,
- .name = ION_SF_HEAP_NAME,
- .size = MSM_ION_SF_SIZE,
- .memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
- },
- {
.id = ION_CP_MM_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_MM_HEAP_NAME,
@@ -275,6 +282,14 @@
.extra_data = (void *) &cp_mfc_ion_pdata,
},
{
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
.id = ION_IOMMU_HEAP_ID,
.type = ION_HEAP_TYPE_IOMMU,
.name = ION_IOMMU_HEAP_NAME,
@@ -528,6 +543,86 @@
},
};
+#define HAP_SHIFT_LVL_OE_GPIO PM8921_MPP_PM_TO_SYS(8)
+#define ISA1200_HAP_EN_GPIO PM8921_GPIO_PM_TO_SYS(33)
+#define ISA1200_HAP_LEN_GPIO PM8921_GPIO_PM_TO_SYS(20)
+#define ISA1200_HAP_CLK PM8921_GPIO_PM_TO_SYS(44)
+
+static int isa1200_power(int on)
+{
+ gpio_set_value_cansleep(ISA1200_HAP_CLK, !!on);
+
+ return 0;
+}
+
+static int isa1200_dev_setup(bool enable)
+{
+ int rc = 0;
+
+ rc = pm8xxx_aux_clk_control(CLK_MP3_2, XO_DIV_1, enable);
+ if (rc) {
+ pr_err("%s: unable to write aux clock register(%d)\n",
+ __func__, rc);
+ return rc;
+ }
+
+ if (!enable)
+ goto free_gpio;
+
+ rc = gpio_request(ISA1200_HAP_CLK, "haptics_clk");
+ if (rc) {
+ pr_err("%s: unable to request gpio %d config(%d)\n",
+ __func__, ISA1200_HAP_CLK, rc);
+ return rc;
+ }
+
+ rc = gpio_direction_output(ISA1200_HAP_CLK, 0);
+ if (rc) {
+ pr_err("%s: unable to set direction\n", __func__);
+ goto free_gpio;
+ }
+
+ return 0;
+
+free_gpio:
+ gpio_free(ISA1200_HAP_CLK);
+ return rc;
+}
+
+static struct isa1200_regulator isa1200_reg_data[] = {
+ {
+ .name = "vddp",
+ .min_uV = ISA_I2C_VTG_MIN_UV,
+ .max_uV = ISA_I2C_VTG_MAX_UV,
+ .load_uA = ISA_I2C_CURR_UA,
+ },
+};
+
+static struct isa1200_platform_data isa1200_1_pdata = {
+ .name = "vibrator",
+ .dev_setup = isa1200_dev_setup,
+ .power_on = isa1200_power,
+ .hap_en_gpio = ISA1200_HAP_EN_GPIO,
+ .hap_len_gpio = ISA1200_HAP_LEN_GPIO,
+ .max_timeout = 15000,
+ .mode_ctrl = PWM_GEN_MODE,
+ .pwm_fd = {
+ .pwm_div = 256,
+ },
+ .is_erm = false,
+ .smart_en = true,
+ .ext_clk_en = true,
+ .chip_en = 1,
+ .regulator_info = isa1200_reg_data,
+ .num_regulators = ARRAY_SIZE(isa1200_reg_data),
+};
+
+static struct i2c_board_info isa1200_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("isa1200_1", 0x90>>1),
+ .platform_data = &isa1200_1_pdata,
+ },
+};
/* configuration data for mxt1386e using V2.1 firmware */
static const u8 mxt1386e_config_data_v2_1[] = {
/* T6 Object */
@@ -890,6 +985,14 @@
.peripheral_platform_device = &apq8064_device_hsic_host,
};
+static struct tsens_platform_data apq_tsens_pdata = {
+ .tsens_factor = 1000,
+ .hw_type = APQ_8064,
+ .tsens_num_sensor = 11,
+ .slope = {1176, 1176, 1154, 1176, 1111,
+ 1132, 1132, 1199, 1132, 1199, 1132},
+};
+
#define MSM_SHARED_RAM_PHYS 0x80000000
static void __init apq8064_map_io(void)
{
@@ -1225,7 +1328,6 @@
static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW_L2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
@@ -1238,9 +1340,7 @@
static struct msm_spm_platform_data msm_spm_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW0_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1255,9 +1355,7 @@
},
[1] = {
.reg_base_addr = MSM_SAW1_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1272,9 +1370,7 @@
},
[2] = {
.reg_base_addr = MSM_SAW2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1289,9 +1385,7 @@
},
[3] = {
.reg_base_addr = MSM_SAW3_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1368,6 +1462,7 @@
static struct platform_device *common_devices[] __initdata = {
&apq8064_device_dmov,
+ &apq8064_device_qup_i2c_gsbi1,
&apq8064_device_qup_i2c_gsbi3,
&apq8064_device_qup_i2c_gsbi4,
&apq8064_device_qup_spi_gsbi5,
@@ -1434,6 +1529,7 @@
&apq_pcm_afe,
&apq_cpudai_auxpcm_rx,
&apq_cpudai_auxpcm_tx,
+ &apq_cpudai_stub,
&apq8064_rpm_device,
&apq8064_rpm_log_device,
&apq8064_rpm_stat_device,
@@ -1496,6 +1592,11 @@
/* add more slimbus slaves as needed */
};
+static struct msm_i2c_platform_data apq8064_i2c_qup_gsbi1_pdata = {
+ .clk_freq = 100000,
+ .src_clk_rate = 24000000,
+};
+
static struct msm_i2c_platform_data apq8064_i2c_qup_gsbi3_pdata = {
.clk_freq = 100000,
.src_clk_rate = 24000000,
@@ -1506,8 +1607,20 @@
.src_clk_rate = 24000000,
};
+#define GSBI_DUAL_MODE_CODE 0x60
+#define MSM_GSBI1_PHYS 0x12440000
static void __init apq8064_i2c_init(void)
{
+ void __iomem *gsbi_mem;
+
+ apq8064_device_qup_i2c_gsbi1.dev.platform_data =
+ &apq8064_i2c_qup_gsbi1_pdata;
+ gsbi_mem = ioremap_nocache(MSM_GSBI1_PHYS, 4);
+ writel_relaxed(GSBI_DUAL_MODE_CODE, gsbi_mem);
+ /* Ensure protocol code is written before proceeding */
+ wmb();
+ iounmap(gsbi_mem);
+ apq8064_i2c_qup_gsbi1_pdata.use_gsbi_shared_mode = 1;
apq8064_device_qup_i2c_gsbi3.dev.platform_data =
&apq8064_i2c_qup_gsbi3_pdata;
apq8064_device_qup_i2c_gsbi4.dev.platform_data =
@@ -1569,6 +1682,12 @@
cyttsp_info,
ARRAY_SIZE(cyttsp_info),
},
+ {
+ I2C_FFA | I2C_LIQUID,
+ APQ_8064_GSBI1_QUP_I2C_BUS_ID,
+ isa1200_board_info,
+ ARRAY_SIZE(isa1200_board_info),
+ },
};
static void __init register_i2c_devices(void)
@@ -1576,6 +1695,14 @@
u8 mach_mask = 0;
int i;
+#ifdef CONFIG_MSM_CAMERA
+ struct i2c_registry apq8064_camera_i2c_devices = {
+ I2C_SURF | I2C_FFA | I2C_LIQUID | I2C_RUMI,
+ APQ_8064_GSBI4_QUP_I2C_BUS_ID,
+ apq8064_camera_board_info.board_info,
+ apq8064_camera_board_info.num_i2c_board_info,
+ };
+#endif
/* Build the matching 'supported_machs' bitmask */
if (machine_is_apq8064_cdp())
mach_mask = I2C_SURF;
@@ -1597,6 +1724,12 @@
apq8064_i2c_devices[i].info,
apq8064_i2c_devices[i].len);
}
+#ifdef CONFIG_MSM_CAMERA
+ if (apq8064_camera_i2c_devices.machs & mach_mask)
+ i2c_register_board_info(apq8064_camera_i2c_devices.bus,
+ apq8064_camera_i2c_devices.info,
+ apq8064_camera_i2c_devices.len);
+#endif
}
static void __init apq8064_common_init(void)
@@ -1652,12 +1785,14 @@
&msm8064_device_watchdog.dev.platform_data;
wdog_pdata->bark_time = 15000;
+ msm_tsens_early_init(&apq_tsens_pdata);
apq8064_common_init();
platform_add_devices(sim_devices, ARRAY_SIZE(sim_devices));
}
static void __init apq8064_rumi3_init(void)
{
+ msm_tsens_early_init(&apq_tsens_pdata);
apq8064_common_init();
ethernet_init();
platform_add_devices(rumi3_devices, ARRAY_SIZE(rumi3_devices));
@@ -1668,6 +1803,7 @@
static void __init apq8064_cdp_init(void)
{
+ msm_tsens_early_init(&apq_tsens_pdata);
apq8064_common_init();
ethernet_init();
platform_add_devices(cdp_devices, ARRAY_SIZE(cdp_devices));
@@ -1676,6 +1812,7 @@
apq8064_init_gpu();
platform_add_devices(msm_footswitch_devices,
msm_num_footswitch_devices);
+ apq8064_init_cam();
}
MACHINE_START(APQ8064_SIM, "QCT APQ8064 SIMULATOR")
@@ -1727,3 +1864,21 @@
.init_early = apq8064_allocate_memory_regions,
MACHINE_END
+MACHINE_START(MPQ8064_HRD, "QCT MPQ8064 HRD")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = apq8064_cdp_init,
+MACHINE_END
+
+MACHINE_START(MPQ8064_DTV, "QCT MPQ8064 DTV")
+ .map_io = apq8064_map_io,
+ .reserve = apq8064_reserve,
+ .init_irq = apq8064_init_irq,
+ .handle_irq = gic_handle_irq,
+ .timer = &msm_timer,
+ .init_machine = apq8064_cdp_init,
+MACHINE_END
+
diff --git a/arch/arm/mach-msm/board-8064.h b/arch/arm/mach-msm/board-8064.h
index d401f4c..e8c8144 100644
--- a/arch/arm/mach-msm/board-8064.h
+++ b/arch/arm/mach-msm/board-8064.h
@@ -64,6 +64,8 @@
extern struct msm_camera_board_info apq8064_camera_board_info;
void apq8064_init_cam(void);
+
+#define APQ_8064_GSBI1_QUP_I2C_BUS_ID 0
#define APQ_8064_GSBI3_QUP_I2C_BUS_ID 3
#define APQ_8064_GSBI4_QUP_I2C_BUS_ID 4
diff --git a/arch/arm/mach-msm/board-8930-camera.c b/arch/arm/mach-msm/board-8930-camera.c
index e0bc723..47a381a 100644
--- a/arch/arm/mach-msm/board-8930-camera.c
+++ b/arch/arm/mach-msm/board-8930-camera.c
@@ -350,16 +350,16 @@
static struct camera_vreg_t msm_8930_back_cam_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
};
static struct camera_vreg_t msm_8930_front_cam_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
};
@@ -409,7 +409,6 @@
.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8930_back_cam_gpio_set_tbl),
};
-#ifdef CONFIG_IMX074_ACT
static struct i2c_board_info imx074_actuator_i2c_info = {
I2C_BOARD_INFO("imx074_act", 0x11),
};
@@ -420,9 +419,7 @@
.vcm_pwd = 0,
.vcm_enable = 1,
};
-#endif
-#ifdef CONFIG_IMX074
static struct msm_camera_sensor_flash_data flash_imx074 = {
.flash_type = MSM_CAMERA_FLASH_LED,
#ifdef CONFIG_MSM_CAMERA_FLASH
@@ -445,21 +442,25 @@
.sensor_platform_info = &sensor_board_info_imx074,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
-#ifdef CONFIG_IMX074_ACT
.actuator_info = &imx074_actuator_info
-#endif
};
-#endif
-#ifdef CONFIG_MT9M114
+static struct camera_vreg_t msm_8930_mt9m114_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vio", REG_LDO, 1800000, 1800000, 16000},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vaf", REG_LDO, 2800000, 2850000, 300000},
+};
+
static struct msm_camera_sensor_flash_data flash_mt9m114 = {
.flash_type = MSM_CAMERA_FLASH_NONE
};
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .cam_vreg = msm_8930_back_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8930_back_cam_vreg),
+ .cam_vreg = msm_8930_mt9m114_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8930_mt9m114_vreg),
.gpio_conf = &msm_8930_back_cam_gpio_conf,
};
@@ -471,9 +472,7 @@
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
};
-#endif
-#ifdef CONFIG_OV2720
static struct msm_camera_sensor_flash_data flash_ov2720 = {
.flash_type = MSM_CAMERA_FLASH_NONE,
};
@@ -493,7 +492,6 @@
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
};
-#endif
static struct camera_vreg_t msm_8930_s5k3l1yx_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
@@ -539,18 +537,14 @@
#ifdef CONFIG_I2C
struct i2c_board_info msm8930_camera_i2c_boardinfo[] = {
-#ifdef CONFIG_IMX074
{
I2C_BOARD_INFO("imx074", 0x1A),
.platform_data = &msm_camera_sensor_imx074_data,
},
-#endif
-#ifdef CONFIG_OV2720
{
I2C_BOARD_INFO("ov2720", 0x6C),
.platform_data = &msm_camera_sensor_ov2720_data,
},
-#endif
{
I2C_BOARD_INFO("mt9m114", 0x48),
.platform_data = &msm_camera_sensor_mt9m114_data,
diff --git a/arch/arm/mach-msm/board-8930-display.c b/arch/arm/mach-msm/board-8930-display.c
index 9175c75..e6b342f 100644
--- a/arch/arm/mach-msm/board-8930-display.c
+++ b/arch/arm/mach-msm/board-8930-display.c
@@ -29,15 +29,19 @@
#include "board-8930.h"
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 3) /* 4 bpp x 3 pages */
+#define MSM_FB_PRIM_BUF_SIZE \
+ (roundup((1376 * 768 * 4), 4096) * 3) /* 4 bpp x 3 pages */
#else
-#define MSM_FB_PRIM_BUF_SIZE (1376 * 768 * 4 * 2) /* 4 bpp x 2 pages */
+#define MSM_FB_PRIM_BUF_SIZE \
+ (roundup((1376 * 768 * 4), 4096) * 2) /* 4 bpp x 2 pages */
#endif
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-#define MSM_FB_EXT_BUF_SIZE (1920 * 1088 * 2 * 1) /* 2 bpp x 1 page */
+#define MSM_FB_EXT_BUF_SIZE \
+ (roundup((1920 * 1088 * 2), 4096) * 1) /* 2 bpp x 1 page */
#elif defined(CONFIG_FB_MSM_TVOUT)
-#define MSM_FB_EXT_BUF_SIZE (720 * 576 * 2 * 2) /* 2 bpp x 2 pages */
+#define MSM_FB_EXT_BUF_SIZE \
+ (roundup((720 * 576 * 2), 4096) * 2) /* 2 bpp x 2 pages */
#else
#define MSM_FB_EXT_BUF_SIZE 0
#endif
@@ -87,7 +91,8 @@
PANEL_NAME_MAX_LEN)))
return 0;
-#ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+#if !defined(CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT) && \
+ !defined(CONFIG_FB_MSM_MIPI_PANEL_DETECT)
if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
PANEL_NAME_MAX_LEN)))
diff --git a/arch/arm/mach-msm/board-8930.c b/arch/arm/mach-msm/board-8930.c
index 90cc3c5..a094ba5 100644
--- a/arch/arm/mach-msm/board-8930.c
+++ b/arch/arm/mach-msm/board-8930.c
@@ -77,6 +77,7 @@
#include <linux/ion.h>
#include <mach/ion.h>
#include <mach/mdm2.h>
+#include <mach/msm_rtb.h>
#include "timer.h"
#include "devices.h"
@@ -130,7 +131,7 @@
#define MSM_ION_SF_SIZE MSM_PMEM_SIZE
#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
#define MSM_ION_MM_SIZE MSM_PMEM_ADSP_SIZE
-#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
+#define MSM_ION_QSECOM_SIZE 0x300000 /* (3MB) */
#define MSM_ION_MFC_SIZE SZ_8K
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 8
@@ -250,6 +251,38 @@
},
};
+#if defined(CONFIG_MSM_RTB)
+static struct msm_rtb_platform_data msm_rtb_pdata = {
+ .size = SZ_1M,
+};
+
+static int __init msm_rtb_set_buffer_size(char *p)
+{
+ int s;
+
+ s = memparse(p, NULL);
+ msm_rtb_pdata.size = ALIGN(s, SZ_4K);
+ return 0;
+}
+early_param("msm_rtb_size", msm_rtb_set_buffer_size);
+
+
+static struct platform_device msm_rtb_device = {
+ .name = "msm_rtb",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm_rtb_pdata,
+ },
+};
+#endif
+
+static void __init reserve_rtb_memory(void)
+{
+#if defined(CONFIG_MSM_RTB)
+ msm8930_reserve_table[MEMTYPE_EBI1].size += msm_rtb_pdata.size;
+#endif
+}
+
static void __init size_pmem_devices(void)
{
#ifdef CONFIG_ANDROID_PMEM
@@ -303,6 +336,18 @@
.align = SZ_128K,
};
#endif
+
+/**
+ * These heaps are listed in the order they will be allocated. Due to
+ * video hardware restrictions and content protection the FW heap has to
+ * be allocated adjacent (below) the MM heap and the MFC heap has to be
+ * allocated after the MM heap to ensure MFC heap is not more than 256MB
+ * away from the base address of the FW heap.
+ * However, the order of FW heap and MM heap doesn't matter since these
+ * two heaps are taken care of by separate code to ensure they are adjacent
+ * to each other.
+ * Don't swap the order unless you know what you are doing!
+ */
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
@@ -313,14 +358,6 @@
},
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
{
- .id = ION_SF_HEAP_ID,
- .type = ION_HEAP_TYPE_CARVEOUT,
- .name = ION_SF_HEAP_NAME,
- .size = MSM_ION_SF_SIZE,
- .memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
- },
- {
.id = ION_CP_MM_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_MM_HEAP_NAME,
@@ -345,6 +382,14 @@
.extra_data = (void *) &cp_mfc_ion_pdata,
},
{
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
.id = ION_IOMMU_HEAP_ID,
.type = ION_HEAP_TYPE_IOMMU,
.name = ION_IOMMU_HEAP_NAME,
@@ -399,6 +444,7 @@
reserve_pmem_memory();
reserve_ion_memory();
reserve_mdp_memory();
+ reserve_rtb_memory();
}
static struct reserve_info msm8930_reserve_info __initdata = {
@@ -1047,9 +1093,7 @@
static struct msm_spm_platform_data msm_spm_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW0_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1064,9 +1108,7 @@
},
[1] = {
.reg_base_addr = MSM_SAW1_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0x9C,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1120,7 +1162,6 @@
static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW_L2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
@@ -1577,7 +1618,7 @@
};
static struct tsens_platform_data msm_tsens_pdata = {
- .slope = 910,
+ .slope = {872, 872, 872, 872, 872},
.tsens_factor = 1000,
.hw_type = MSM_8960,
.tsens_num_sensor = 5,
@@ -1719,6 +1760,9 @@
#ifdef MSM8930_PHASE_2
&gpio_keys_8930,
#endif
+#ifdef CONFIG_MSM_RTB
+ &msm_rtb_device,
+#endif
};
static struct platform_device *cdp_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-8960-camera.c b/arch/arm/mach-msm/board-8960-camera.c
index 23c4928..87cb105 100644
--- a/arch/arm/mach-msm/board-8960-camera.c
+++ b/arch/arm/mach-msm/board-8960-camera.c
@@ -411,20 +411,26 @@
.is_vpe = 1,
.cam_bus_scale_table = &cam_bus_client_pdata,
},
+ {
+ .ioclk.mclk_clk_rate = 24000000,
+ .ioclk.vfe_clk_rate = 228570000,
+ .csid_core = 2,
+ .cam_bus_scale_table = &cam_bus_client_pdata,
+ },
};
static struct camera_vreg_t msm_8960_back_cam_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
- {"cam_vio", REG_VS, 0, 0, 0},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
};
static struct camera_vreg_t msm_8960_front_cam_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
- {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
{"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
};
@@ -474,7 +480,6 @@
.cam_gpio_set_tbl_size = ARRAY_SIZE(msm8960_back_cam_gpio_set_tbl),
};
-#ifdef CONFIG_IMX074_ACT
static struct i2c_board_info imx074_actuator_i2c_info = {
I2C_BOARD_INFO("imx074_act", 0x11),
};
@@ -485,9 +490,7 @@
.vcm_pwd = 0,
.vcm_enable = 1,
};
-#endif
-#ifdef CONFIG_IMX074
static struct msm_camera_sensor_flash_data flash_imx074 = {
.flash_type = MSM_CAMERA_FLASH_LED,
#ifdef CONFIG_MSM_CAMERA_FLASH
@@ -510,21 +513,25 @@
.sensor_platform_info = &sensor_board_info_imx074,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
-#ifdef CONFIG_IMX074_ACT
.actuator_info = &imx074_actuator_info
-#endif
};
-#endif
-#ifdef CONFIG_MT9M114
+static struct camera_vreg_t msm_8960_mt9m114_vreg[] = {
+ {"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
+ {"cam_vio", REG_VS, 0, 0, 0},
+ {"cam_vdig", REG_LDO, 1200000, 1200000, 105000},
+ {"cam_vana", REG_LDO, 2800000, 2850000, 85600},
+ {"cam_vaf", REG_LDO, 2800000, 2800000, 300000},
+};
+
static struct msm_camera_sensor_flash_data flash_mt9m114 = {
.flash_type = MSM_CAMERA_FLASH_NONE
};
static struct msm_camera_sensor_platform_info sensor_board_info_mt9m114 = {
.mount_angle = 90,
- .cam_vreg = msm_8960_back_cam_vreg,
- .num_vreg = ARRAY_SIZE(msm_8960_back_cam_vreg),
+ .cam_vreg = msm_8960_mt9m114_vreg,
+ .num_vreg = ARRAY_SIZE(msm_8960_mt9m114_vreg),
.gpio_conf = &msm_8960_back_cam_gpio_conf,
};
@@ -536,9 +543,7 @@
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
};
-#endif
-#ifdef CONFIG_OV2720
static struct msm_camera_sensor_flash_data flash_ov2720 = {
.flash_type = MSM_CAMERA_FLASH_NONE,
};
@@ -558,7 +563,6 @@
.csi_if = 1,
.camera_type = FRONT_CAMERA_2D,
};
-#endif
static struct camera_vreg_t msm_8960_s5k3l1yx_vreg[] = {
{"mipi_csi_vdd", REG_LDO, 1200000, 1200000, 20000},
@@ -643,8 +647,10 @@
platform_device_register(&msm8960_device_csiphy0);
platform_device_register(&msm8960_device_csiphy1);
+ platform_device_register(&msm8960_device_csiphy2);
platform_device_register(&msm8960_device_csid0);
platform_device_register(&msm8960_device_csid1);
+ platform_device_register(&msm8960_device_csid2);
platform_device_register(&msm8960_device_ispif);
platform_device_register(&msm8960_device_vfe);
platform_device_register(&msm8960_device_vpe);
@@ -652,18 +658,14 @@
#ifdef CONFIG_I2C
static struct i2c_board_info msm8960_camera_i2c_boardinfo[] = {
-#ifdef CONFIG_IMX074
{
I2C_BOARD_INFO("imx074", 0x1A),
.platform_data = &msm_camera_sensor_imx074_data,
},
-#endif
-#ifdef CONFIG_OV2720
{
I2C_BOARD_INFO("ov2720", 0x6C),
.platform_data = &msm_camera_sensor_ov2720_data,
},
-#endif
{
I2C_BOARD_INFO("mt9m114", 0x48),
.platform_data = &msm_camera_sensor_mt9m114_data,
diff --git a/arch/arm/mach-msm/board-8960-display.c b/arch/arm/mach-msm/board-8960-display.c
index aa8477e..9a98058 100644
--- a/arch/arm/mach-msm/board-8960-display.c
+++ b/arch/arm/mach-msm/board-8960-display.c
@@ -29,15 +29,19 @@
#include "board-8960.h"
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_PRIM_BUF_SIZE (1920 * 1200 * 4 * 3) /* 4 bpp x 3 pages */
+#define MSM_FB_PRIM_BUF_SIZE \
+ (roundup((1920 * 1200 * 4), 4096) * 3) /* 4 bpp x 3 pages */
#else
-#define MSM_FB_PRIM_BUF_SIZE (1920 * 1200 * 4 * 2) /* 4 bpp x 2 pages */
+#define MSM_FB_PRIM_BUF_SIZE \
+ (roundup((1920 * 1200 * 4), 4096) * 2) /* 4 bpp x 2 pages */
#endif
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-#define MSM_FB_EXT_BUF_SIZE (1920 * 1088 * 2 * 1) /* 2 bpp x 1 page */
+#define MSM_FB_EXT_BUF_SIZE \
+ (roundup((1920 * 1088 * 2), 4096) * 1) /* 2 bpp x 1 page */
#elif defined(CONFIG_FB_MSM_TVOUT)
-#define MSM_FB_EXT_BUF_SIZE (720 * 576 * 2 * 2) /* 2 bpp x 2 pages */
+#define MSM_FB_EXT_BUF_SIZE \
+ (roundup((720 * 576 * 2), 4096) * 2) /* 2 bpp x 2 pages */
#else
#define MSM_FB_EXT_BUF_SIZE 0
#endif
@@ -68,6 +72,7 @@
#define MIPI_CMD_NOVATEK_QHD_PANEL_NAME "mipi_cmd_novatek_qhd"
#define MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME "mipi_video_novatek_qhd"
#define MIPI_VIDEO_TOSHIBA_WSVGA_PANEL_NAME "mipi_video_toshiba_wsvga"
+#define MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME "mipi_video_toshiba_wuxga"
#define MIPI_VIDEO_CHIMEI_WXGA_PANEL_NAME "mipi_video_chimei_wxga"
#define MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME "mipi_video_chimei_wuxga"
#define MIPI_VIDEO_SIMULATOR_VGA_PANEL_NAME "mipi_video_simulator_vga"
@@ -81,7 +86,7 @@
}
};
-static void set_mdp_clocks_for_liquid_wuxga(void);
+static void set_mdp_clocks_for_wuxga(void);
static int msm_fb_detect_panel(const char *name)
{
@@ -91,7 +96,7 @@
if (!strncmp(name, MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
strnlen(MIPI_VIDEO_CHIMEI_WUXGA_PANEL_NAME,
PANEL_NAME_MAX_LEN))) {
- set_mdp_clocks_for_liquid_wuxga();
+ set_mdp_clocks_for_wuxga();
return 0;
}
} else {
@@ -106,7 +111,8 @@
PANEL_NAME_MAX_LEN)))
return 0;
-#ifndef CONFIG_FB_MSM_MIPI_PANEL_DETECT
+#if !defined(CONFIG_FB_MSM_LVDS_MIPI_PANEL_DETECT) && \
+ !defined(CONFIG_FB_MSM_MIPI_PANEL_DETECT)
if (!strncmp(name, MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
strnlen(MIPI_VIDEO_NOVATEK_QHD_PANEL_NAME,
PANEL_NAME_MAX_LEN)))
@@ -126,6 +132,13 @@
strnlen(MIPI_CMD_RENESAS_FWVGA_PANEL_NAME,
PANEL_NAME_MAX_LEN)))
return 0;
+
+ if (!strncmp(name, MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME,
+ strnlen(MIPI_VIDEO_TOSHIBA_WUXGA_PANEL_NAME,
+ PANEL_NAME_MAX_LEN))) {
+ set_mdp_clocks_for_wuxga();
+ return 0;
+ }
#endif
}
@@ -649,9 +662,9 @@
/**
* Set MDP clocks to high frequency to avoid DSI underflow
- * when using high resolution 1200x1920 WUXGA panel.
+ * when using high resolution 1200x1920 WUXGA panels
*/
-static void set_mdp_clocks_for_liquid_wuxga(void)
+static void set_mdp_clocks_for_wuxga(void)
{
int i;
diff --git a/arch/arm/mach-msm/board-8960.c b/arch/arm/mach-msm/board-8960.c
index 76a27ff..b99ce8a 100644
--- a/arch/arm/mach-msm/board-8960.c
+++ b/arch/arm/mach-msm/board-8960.c
@@ -79,6 +79,7 @@
#include <mach/ion.h>
#include <mach/mdm2.h>
#include <mach/mdm-peripheral.h>
+#include <mach/msm_rtb.h>
#include <linux/fmem.h>
@@ -143,7 +144,7 @@
#define MSM_ION_SF_SIZE MSM_PMEM_SIZE
#define MSM_ION_MM_FW_SIZE 0x200000 /* (2MB) */
#define MSM_ION_MM_SIZE MSM_PMEM_ADSP_SIZE
-#define MSM_ION_QSECOM_SIZE 0x100000 /* (1MB) */
+#define MSM_ION_QSECOM_SIZE 0x300000 /* (3MB) */
#define MSM_ION_MFC_SIZE SZ_8K
#define MSM_ION_AUDIO_SIZE MSM_PMEM_AUDIO_SIZE
#define MSM_ION_HEAP_NUM 8
@@ -270,6 +271,38 @@
},
};
+#if defined(CONFIG_MSM_RTB)
+static struct msm_rtb_platform_data msm_rtb_pdata = {
+ .size = SZ_1M,
+};
+
+static int __init msm_rtb_set_buffer_size(char *p)
+{
+ int s;
+
+ s = memparse(p, NULL);
+ msm_rtb_pdata.size = ALIGN(s, SZ_4K);
+ return 0;
+}
+early_param("msm_rtb_size", msm_rtb_set_buffer_size);
+
+
+static struct platform_device msm_rtb_device = {
+ .name = "msm_rtb",
+ .id = -1,
+ .dev = {
+ .platform_data = &msm_rtb_pdata,
+ },
+};
+#endif
+
+static void __init reserve_rtb_memory(void)
+{
+#if defined(CONFIG_MSM_RTB)
+ msm8960_reserve_table[MEMTYPE_EBI1].size += msm_rtb_pdata.size;
+#endif
+}
+
static void __init size_pmem_devices(void)
{
#ifdef CONFIG_ANDROID_PMEM
@@ -306,30 +339,48 @@
return MEMTYPE_EBI1;
}
+#define FMEM_ENABLED 1
+
#ifdef CONFIG_ION_MSM
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
static struct ion_cp_heap_pdata cp_mm_ion_pdata = {
.permission_type = IPT_TYPE_MM_CARVEOUT,
.align = PAGE_SIZE,
- .reusable = 1,
+ .reusable = FMEM_ENABLED,
+ .mem_is_fmem = FMEM_ENABLED,
};
static struct ion_cp_heap_pdata cp_mfc_ion_pdata = {
.permission_type = IPT_TYPE_MFC_SHAREDMEM,
.align = PAGE_SIZE,
.reusable = 0,
+ .mem_is_fmem = FMEM_ENABLED,
};
static struct ion_co_heap_pdata co_ion_pdata = {
.adjacent_mem_id = INVALID_HEAP_ID,
.align = PAGE_SIZE,
+ .mem_is_fmem = 0,
};
static struct ion_co_heap_pdata fw_co_ion_pdata = {
.adjacent_mem_id = ION_CP_MM_HEAP_ID,
.align = SZ_128K,
+ .mem_is_fmem = FMEM_ENABLED,
};
#endif
+
+/**
+ * These heaps are listed in the order they will be allocated. Due to
+ * video hardware restrictions and content protection the FW heap has to
+ * be allocated adjacent (below) the MM heap and the MFC heap has to be
+ * allocated after the MM heap to ensure MFC heap is not more than 256MB
+ * away from the base address of the FW heap.
+ * However, the order of FW heap and MM heap doesn't matter since these
+ * two heaps are taken care of by separate code to ensure they are adjacent
+ * to each other.
+ * Don't swap the order unless you know what you are doing!
+ */
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
@@ -340,14 +391,6 @@
},
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
{
- .id = ION_SF_HEAP_ID,
- .type = ION_HEAP_TYPE_CARVEOUT,
- .name = ION_SF_HEAP_NAME,
- .size = MSM_ION_SF_SIZE,
- .memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
- },
- {
.id = ION_CP_MM_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_MM_HEAP_NAME,
@@ -372,6 +415,14 @@
.extra_data = (void *) &cp_mfc_ion_pdata,
},
{
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
.id = ION_IOMMU_HEAP_ID,
.type = ION_HEAP_TYPE_IOMMU,
.name = ION_IOMMU_HEAP_NAME,
@@ -432,23 +483,17 @@
msm8960_reserve_table[mem_type].size += size;
}
-static __init const struct ion_platform_heap *find_ion_heap(int heap_id)
-{
- unsigned int i;
- for (i = 0; i < ion_pdata.nr; ++i) {
- const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
- if (heap->id == heap_id)
- return (const struct ion_platform_heap *) heap;
- }
- return 0;
-}
-
/**
* Reserve memory for ION and calculate amount of reusable memory for fmem.
* We only reserve memory for heaps that are not reusable. However, we only
* support one reusable heap at the moment so we ignore the reusable flag for
* other than the first heap with reusable flag set. Also handle special case
- * for adjacent heap when the adjacent heap is adjacent to a reusable heap.
+ * for video heaps (MM,FW, and MFC). Video requires heaps MM and MFC to be
+ * at a higher address than FW in addition to not more than 256MB away from the
+ * base address of the firmware. This means that if MM is reusable the other
+ * two heaps must be allocated in the same region as FW. This is handled by the
+ * mem_is_fmem flag in the platform data. In addition the MM heap must be
+ * adjacent to the FW heap for content protection purposes.
*/
static void __init reserve_ion_memory(void)
{
@@ -458,7 +503,8 @@
adjust_mem_for_liquid();
fmem_pdata.size = 0;
- fmem_pdata.reserved_size = 0;
+ fmem_pdata.reserved_size_low = 0;
+ fmem_pdata.reserved_size_high = 0;
/* We only support 1 reusable heap. Check if more than one heap
* is specified as reusable and set as non-reusable if found.
@@ -483,7 +529,7 @@
for (i = 0; i < ion_pdata.nr; ++i) {
int reusable = 0;
int adjacent_heap_id = INVALID_HEAP_ID;
- int adj_reusable = 0;
+ int mem_is_fmem = 0;
const struct ion_platform_heap *heap = &(ion_pdata.heaps[i]);
if (heap->extra_data) {
@@ -491,31 +537,30 @@
case ION_HEAP_TYPE_CP:
reusable = ((struct ion_cp_heap_pdata *)
heap->extra_data)->reusable;
+ mem_is_fmem = ((struct ion_cp_heap_pdata *)
+ heap->extra_data)->mem_is_fmem;
break;
case ION_HEAP_TYPE_CARVEOUT:
adjacent_heap_id = ((struct ion_co_heap_pdata *)
heap->extra_data)->adjacent_mem_id;
+ mem_is_fmem = ((struct ion_co_heap_pdata *)
+ heap->extra_data)->mem_is_fmem;
break;
default:
break;
}
}
- if (adjacent_heap_id != INVALID_HEAP_ID) {
- const struct ion_platform_heap *adj_heap =
- find_ion_heap(adjacent_heap_id);
- if (adj_heap) {
- adj_reusable = ((struct ion_cp_heap_pdata *)
- adj_heap->extra_data)->reusable;
- if (adj_reusable)
- fmem_pdata.reserved_size += heap->size;
- }
+ if (mem_is_fmem && !reusable) {
+ if (adjacent_heap_id != INVALID_HEAP_ID)
+ fmem_pdata.reserved_size_low += heap->size;
+ else
+ fmem_pdata.reserved_size_high += heap->size;
}
-
- if (!reusable && !adj_reusable)
- reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
- else
+ if (mem_is_fmem)
fmem_pdata.size += heap->size;
+ else
+ reserve_mem_for_ion(MEMTYPE_EBI1, heap->size);
}
#endif
}
@@ -531,6 +576,7 @@
reserve_pmem_memory();
reserve_ion_memory();
reserve_mdp_memory();
+ reserve_rtb_memory();
}
static struct reserve_info msm8960_reserve_info __initdata = {
@@ -1186,9 +1232,7 @@
static struct msm_spm_platform_data msm_spm_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW0_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1203,9 +1247,7 @@
},
[1] = {
.reg_base_addr = MSM_SAW1_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
- .reg_init_values[MSM_SPM_REG_SAW2_VCTL] = 0xB0,
#if defined(CONFIG_MSM_AVS_HW)
.reg_init_values[MSM_SPM_REG_SAW2_AVS_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_AVS_HYSTERESIS] = 0x00,
@@ -1259,7 +1301,6 @@
static struct msm_spm_platform_data msm_spm_l2_data[] __initdata = {
[0] = {
.reg_base_addr = MSM_SAW_L2_BASE,
- .reg_init_values[MSM_SPM_REG_SAW2_SECURE] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x00,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DLY] = 0x02020202,
.reg_init_values[MSM_SPM_REG_SAW2_PMIC_DATA_0] = 0x00A000AE,
@@ -1824,7 +1865,7 @@
};
static struct tsens_platform_data msm_tsens_pdata = {
- .slope = 910,
+ .slope = {910, 910, 910, 910, 910},
.tsens_factor = 1000,
.hw_type = MSM_8960,
.tsens_num_sensor = 5,
@@ -1943,6 +1984,9 @@
#endif
&msm_device_dspcrashd_8960,
&msm8960_device_watchdog,
+#ifdef CONFIG_MSM_RTB
+ &msm_rtb_device,
+#endif
};
static struct platform_device *sim_devices[] __initdata = {
diff --git a/arch/arm/mach-msm/board-9615-regulator.c b/arch/arm/mach-msm/board-9615-regulator.c
index 95a1347..58e40db 100644
--- a/arch/arm/mach-msm/board-9615-regulator.c
+++ b/arch/arm/mach-msm/board-9615-regulator.c
@@ -70,6 +70,7 @@
REGULATOR_SUPPLY("8018_s1", NULL),
REGULATOR_SUPPLY("HSUSB_VDDCX", "msm_otg"),
REGULATOR_SUPPLY("HSIC_VDDCX", "msm_hsic_peripheral"),
+ REGULATOR_SUPPLY("HSIC_VDDCX", "msm_hsic_host"),
};
VREG_CONSUMERS(S2) = {
REGULATOR_SUPPLY("8018_s2", NULL),
diff --git a/arch/arm/mach-msm/board-9615.c b/arch/arm/mach-msm/board-9615.c
index 1f19bf6..74471dd 100644
--- a/arch/arm/mach-msm/board-9615.c
+++ b/arch/arm/mach-msm/board-9615.c
@@ -518,6 +518,7 @@
&msm_device_hsic_peripheral,
&msm_device_gadget_peripheral,
&msm_device_hsusb_host,
+ &msm_device_hsic_host,
&msm_device_usb_bam,
&android_usb_device,
&msm9615_device_uart_gsbi4,
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index b4b0b9a..4b6716e 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -36,6 +36,7 @@
#include <mach/ion.h>
#endif
#include <mach/msm_memtypes.h>
+#include <mach/msm_smd.h>
#include "clock.h"
#define MSM_KERNEL_EBI1_MEM_SIZE 0x280000
@@ -98,6 +99,17 @@
.align = SZ_128K,
};
+/**
+ * These heaps are listed in the order they will be allocated. Due to
+ * video hardware restrictions and content protection the FW heap has to
+ * be allocated adjacent (below) the MM heap and the MFC heap has to be
+ * allocated after the MM heap to ensure MFC heap is not more than 256MB
+ * away from the base address of the FW heap.
+ * However, the order of FW heap and MM heap doesn't matter since these
+ * two heaps are taken care of by separate code to ensure they are adjacent
+ * to each other.
+ * Don't swap the order unless you know what you are doing!
+ */
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
@@ -107,14 +119,6 @@
.name = ION_VMALLOC_HEAP_NAME,
},
{
- .id = ION_SF_HEAP_ID,
- .type = ION_HEAP_TYPE_CARVEOUT,
- .name = ION_SF_HEAP_NAME,
- .size = MSM_ION_SF_SIZE,
- .memory_type = ION_EBI_TYPE,
- .extra_data = (void *) &co_ion_pdata,
- },
- {
.id = ION_CP_MM_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_MM_HEAP_NAME,
@@ -139,6 +143,14 @@
.extra_data = (void *) &cp_mfc_ion_pdata,
},
{
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *) &co_ion_pdata,
+ },
+ {
.id = ION_IOMMU_HEAP_ID,
.type = ION_HEAP_TYPE_IOMMU,
.name = ION_IOMMU_HEAP_NAME,
@@ -182,6 +194,126 @@
}
#endif
+static struct resource smd_resource[] = {
+ {
+ .name = "modem_smd_in",
+ .start = 32 + 17, /* mss_sw_to_kpss_ipc_irq0 */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "modem_smsm_in",
+ .start = 32 + 18, /* mss_sw_to_kpss_ipc_irq1 */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_smd_in",
+ .start = 32 + 156, /* lpass_to_kpss_ipc_irq0 */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "adsp_smsm_in",
+ .start = 32 + 157, /* lpass_to_kpss_ipc_irq1 */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "wcnss_smd_in",
+ .start = 32 + 142, /* WcnssAppsSmdMedIrq */
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "wcnss_smsm_in",
+ .start = 32 + 144, /* RicaAppsWlanSmsmIrq */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct smd_subsystem_config smd_config_list[] = {
+ {
+ .irq_config_id = SMD_MODEM,
+ .subsys_name = "modem",
+ .edge = SMD_APPS_MODEM,
+
+ .smd_int.irq_name = "modem_smd_in",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 12,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "modem_smsm_in",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smsm_dev",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 13,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+ {
+ .irq_config_id = SMD_Q6,
+ .subsys_name = "q6",
+ .edge = SMD_APPS_QDSP,
+
+ .smd_int.irq_name = "adsp_smd_in",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 8,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "adsp_smsm_in",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smsm_dev",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 9,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+ {
+ .irq_config_id = SMD_WCNSS,
+ .subsys_name = "wcnss",
+ .edge = SMD_APPS_WCNSS,
+
+ .smd_int.irq_name = "wcnss_smd_in",
+ .smd_int.flags = IRQF_TRIGGER_RISING,
+ .smd_int.irq_id = -1,
+ .smd_int.device_name = "smd_dev",
+ .smd_int.dev_id = 0,
+ .smd_int.out_bit_pos = 1 << 17,
+ .smd_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smd_int.out_offset = 0x8,
+
+ .smsm_int.irq_name = "wcnss_smsm_in",
+ .smsm_int.flags = IRQF_TRIGGER_RISING,
+ .smsm_int.irq_id = -1,
+ .smsm_int.device_name = "smsm_dev",
+ .smsm_int.dev_id = 0,
+ .smsm_int.out_bit_pos = 1 << 19,
+ .smsm_int.out_base = (void __iomem *)MSM_APCS_GCC_BASE,
+ .smsm_int.out_offset = 0x8,
+ },
+};
+
+static struct smd_platform smd_platform_data = {
+ .num_ss_configs = ARRAY_SIZE(smd_config_list),
+ .smd_ss_configs = smd_config_list,
+};
+
+struct platform_device msm_device_smd_copper = {
+ .name = "msm_smd",
+ .id = -1,
+ .resource = smd_resource,
+ .num_resources = ARRAY_SIZE(smd_resource),
+ .dev = {
+ .platform_data = &smd_platform_data,
+ }
+};
+
static void __init msm_copper_calculate_reserve_sizes(void)
{
#ifdef CONFIG_ION_MSM
@@ -223,6 +355,7 @@
#ifdef CONFIG_ION_MSM
platform_device_register(&ion_dev);
#endif
+ platform_device_register(&msm_device_smd_copper);
}
static struct of_device_id irq_match[] __initdata = {
@@ -266,6 +399,8 @@
"msm_otg", NULL),
OF_DEV_AUXDATA("qcom,spi-qup-v2", 0xF9924000, \
"spi_qsd.1", NULL),
+ OF_DEV_AUXDATA("qcom,spmi-pmic-arb", 0xFC4C0000, \
+ "spmi-pmic-arb.0", NULL),
{}
};
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
index c0b1d16..77af5e2 100644
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -22,6 +22,7 @@
#include <mach/irqs-7xxx.h>
#include "devices-msm7x2xa.h"
#include "board-msm7627a.h"
+#include <mach/vreg.h>
#ifdef CONFIG_MSM_CAMERA_V4L2
static uint32_t camera_off_gpio_table[] = {
@@ -177,6 +178,7 @@
static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
.sensor_name = "s5k4e1",
.sensor_reset_enable = 1,
+ .pmic_gpio_enable = 0,
.pdata = &msm_camera_device_data_csi1,
.flash_data = &flash_s5k4e1,
.sensor_platform_info = &sensor_board_info_s5k4e1,
@@ -205,6 +207,7 @@
static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
.sensor_name = "mt9e013",
.sensor_reset_enable = 1,
+ .pmic_gpio_enable = 0,
.pdata = &msm_camera_device_data_csi1,
.flash_data = &flash_mt9e013,
.sensor_platform_info = &sensor_board_info_mt9e013,
@@ -227,6 +230,7 @@
.sensor_name = "imx072",
.sensor_reset_enable = 1,
.sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N, /* TODO 106,*/
+ .pmic_gpio_enable = 0,
.sensor_pwd = 85,
.vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
.vcm_enable = 1,
@@ -261,6 +265,7 @@
static struct msm_camera_sensor_info msm_camera_sensor_ov9726_data = {
.sensor_name = "ov9726",
.sensor_reset_enable = 0,
+ .pmic_gpio_enable = 0,
.pdata = &msm_camera_device_data_csi0,
.flash_data = &flash_ov9726,
.sensor_platform_info = &sensor_board_info_ov9726,
@@ -385,6 +390,85 @@
gpio_direction_output(QRD_GPIO_CAM_3MP_PWDN, 1);
}
+#define GPIO_SKU3_CAM_5MP_SHDN_N 5 /* PWDN */
+#define GPIO_SKU3_CAM_5MP_CAMIF_RESET 6 /* (board_is(EVT))?123:121 RESET */
+#define GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN 30
+
+#define GPIO_SKU1_CAM_VGA_SHDN 18
+#define GPIO_SKU1_CAM_VGA_RESET_N 29
+
+static void evb_camera_gpio_cfg(void)
+{
+ int rc = 0;
+
+ rc = gpio_request(GPIO_SKU3_CAM_5MP_SHDN_N, "ov5647");
+ if (rc < 0)
+ pr_err("%s: gpio_request GPIO_SKU3_CAM_5MP_SHDN_N failed!",
+ __func__);
+
+ pr_debug("gpio_tlmm_config %d\r\n", GPIO_SKU3_CAM_5MP_SHDN_N);
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU3_CAM_5MP_SHDN_N, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s:unable to enable Powr Dwn gpio for main camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU3_CAM_5MP_SHDN_N);
+ }
+
+ gpio_direction_output(GPIO_SKU3_CAM_5MP_SHDN_N, 1);
+
+ rc = gpio_request(GPIO_SKU3_CAM_5MP_CAMIF_RESET, "ov5647");
+ if (rc < 0)
+ pr_err("%s: gpio_request GPIO_SKU3_CAM_5MP_CAMIF_RESET failed!",
+ __func__);
+
+ pr_debug("gpio_tlmm_config %d\r\n", GPIO_SKU3_CAM_5MP_CAMIF_RESET);
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU3_CAM_5MP_CAMIF_RESET, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s: unable to enable reset gpio for main camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU3_CAM_5MP_CAMIF_RESET);
+ }
+
+ gpio_direction_output(GPIO_SKU3_CAM_5MP_CAMIF_RESET, 1);
+
+ rc = gpio_request(GPIO_SKU1_CAM_VGA_SHDN, "ov7692");
+ if (rc < 0)
+ pr_err("%s: gpio_request---GPIO_SKU1_CAM_VGA_SHDN failed!",
+ __func__);
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU1_CAM_VGA_SHDN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s:unable to enable Powr Dwn gpio for frnt camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU1_CAM_VGA_SHDN);
+ }
+
+ gpio_direction_output(GPIO_SKU1_CAM_VGA_SHDN, 1);
+
+ rc = gpio_request(GPIO_SKU1_CAM_VGA_RESET_N, "ov7692");
+ if (rc < 0)
+ pr_err("%s: gpio_request---GPIO_SKU1_CAM_VGA_RESET_N failed!",
+ __func__);
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU1_CAM_VGA_RESET_N, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+ pr_err("%s: unable to enable reset gpio for front camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU1_CAM_VGA_RESET_N);
+ }
+ gpio_direction_output(GPIO_SKU1_CAM_VGA_RESET_N, 1);
+
+}
+
static void msm_camera_vreg_config(int vreg_en)
{
int rc = vreg_en ?
@@ -495,6 +579,45 @@
.ioext.appsz = MSM7XXX_CLK_CTL_SIZE,
};
+#ifdef CONFIG_OV5647
+
+static struct msm_camera_sensor_platform_info ov5647_sensor_7627a_info = {
+ .mount_angle = 90
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_ov5647 = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "flashlight",
+ ._fsrc.led_src.led_name_len = 10,
+};
+
+static struct msm_camera_sensor_flash_data flash_ov5647 = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ov5647,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov5647_data = {
+ .sensor_name = "ov5647",
+ .sensor_reset_enable = 1,
+ .sensor_reset = GPIO_SKU3_CAM_5MP_CAMIF_RESET,
+ .pmic_gpio_enable = 1,
+ .sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N,
+ .vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN,
+ .vcm_enable = 0,
+ .pdata = &msm_camera_device_data_rear,
+ .flash_data = &flash_ov5647,
+ .sensor_platform_info = &ov5647_sensor_7627a_info,
+ .csi_if = 1
+};
+
+static struct platform_device msm_camera_sensor_ov5647 = {
+ .name = "msm_camera_ov5647",
+ .dev = {
+ .platform_data = &msm_camera_sensor_ov5647_data,
+ },
+};
+#endif
+
#ifdef CONFIG_S5K4E1
static struct msm_camera_sensor_platform_info s5k4e1_sensor_7627a_info = {
.mount_angle = 90
@@ -509,6 +632,7 @@
.sensor_name = "s5k4e1",
.sensor_reset_enable = 1,
.sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N,
+ .pmic_gpio_enable = 0,
.sensor_pwd = 85,
.vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
.vcm_enable = 1,
@@ -540,6 +664,7 @@
.sensor_name = "imx072",
.sensor_reset_enable = 1,
.sensor_reset = GPIO_CAM_GP_CAMIF_RESET_N, /* TODO 106,*/
+ .pmic_gpio_enable = 0,
.sensor_pwd = 85,
.vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
.vcm_enable = 1,
@@ -572,6 +697,7 @@
.sensor_name = "ov9726",
.sensor_reset_enable = 0,
.sensor_reset = GPIO_CAM_GP_CAM1MP_XCLR,
+ .pmic_gpio_enable = 0,
.sensor_pwd = 85,
.vcm_pwd = 1,
.vcm_enable = 0,
@@ -605,6 +731,7 @@
.sensor_name = "mt9e013",
.sensor_reset = 0,
.sensor_reset_enable = 1,
+ .pmic_gpio_enable = 0,
.sensor_pwd = 85,
.vcm_pwd = 1,
.vcm_enable = 0,
@@ -641,6 +768,7 @@
static struct msm_camera_sensor_info msm_camera_sensor_ov5640_data = {
.sensor_name = "ov5640",
.sensor_reset_enable = 1,
+ .pmic_gpio_enable = 0,
.sensor_reset = QRD_GPIO_CAM_5MP_RESET,
.sensor_pwd = QRD_GPIO_CAM_5MP_SHDN_EN,
.vcm_pwd = 0,
@@ -671,8 +799,9 @@
static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
.sensor_name = "ov7692",
.sensor_reset_enable = 0,
- .sensor_reset = 0,
- .sensor_pwd = QRD_GPIO_CAM_3MP_PWDN,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_SKU1_CAM_VGA_RESET_N,
+ .sensor_pwd = GPIO_SKU1_CAM_VGA_SHDN,
.vcm_pwd = 0,
.vcm_enable = 0,
.pdata = &msm_camera_device_data_front,
@@ -731,6 +860,22 @@
#endif
};
+static struct i2c_board_info i2c_camera_devices_evb[] = {
+ #ifdef CONFIG_OV5647
+ {
+ I2C_BOARD_INFO("ov5647", 0x36 << 1),
+ },
+ {
+ I2C_BOARD_INFO("ov5647_af", 0x18 >> 1),
+ },
+ #endif
+ #ifdef CONFIG_WEBCAM_OV7692_QRD
+ {
+ I2C_BOARD_INFO("ov7692", 0x78),
+ },
+ #endif
+};
+
static struct platform_device *camera_devices_msm[] __initdata = {
#ifdef CONFIG_S5K4E1
&msm_camera_sensor_s5k4e1,
@@ -754,6 +899,15 @@
&msm_camera_sensor_ov7692,
#endif
};
+
+static struct platform_device *camera_devices_evb[] __initdata = {
+#ifdef CONFIG_OV5647
+ &msm_camera_sensor_ov5647,
+#endif
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+ &msm_camera_sensor_ov7692,
+#endif
+};
#endif
enum {
@@ -785,24 +939,127 @@
ARRAY_SIZE(cam_exp_i2c_info));
}
+#define LCD_CAMERA_LDO_2V8 35 /* SKU1&SKU3 2.8V LDO */
+#define SKU3_LCD_CAMERA_LDO_1V8 40 /* SKU3 1.8V LDO */
+
+static int lcd_camera_ldo_1v8 = SKU3_LCD_CAMERA_LDO_1V8;
+
+static void lcd_camera_power_init(void)
+{
+ int rc = 0;
+
+ pr_debug("lcd_camera_power_init\n");
+
+ lcd_camera_ldo_1v8 = SKU3_LCD_CAMERA_LDO_1V8; /* SKU3 PVT */
+
+ /* LDO_EXT2V8 */
+ if (gpio_request(LCD_CAMERA_LDO_2V8, "lcd_camera_ldo_2v8")) {
+ pr_err("failed to request gpio lcd_camera_ldo_2v8\n");
+ return;
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(LCD_CAMERA_LDO_2V8, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s: unable to enable lcd_camera_ldo_2v8!\n", __func__);
+ goto fail_gpio2;
+ }
+
+ /* LDO_EVT1V8 */
+ if (gpio_request(lcd_camera_ldo_1v8, "lcd_camera_ldo_1v8")) {
+ pr_err("failed to request gpio lcd_camera_ldo_1v8\n");
+ goto fail_gpio2;
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(lcd_camera_ldo_1v8, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s: unable to enable lcd_camera_ldo_1v8!\n", __func__);
+ goto fail_gpio1;
+ }
+
+ return;
+
+fail_gpio1:
+ gpio_free(lcd_camera_ldo_1v8);
+fail_gpio2:
+ gpio_free(LCD_CAMERA_LDO_2V8);
+
+ return;
+}
+
+static int lcd_camera_power_on_sku3(void)
+{
+ int rc = 0;
+
+ pr_debug("turn on sku3 lcd_camera_ldo_1v8\n");
+ gpio_set_value_cansleep(lcd_camera_ldo_1v8, 1);
+
+ pr_debug("turn on sku3 lcd_camera_ldo\n");
+ gpio_set_value_cansleep(LCD_CAMERA_LDO_2V8, 1);
+
+ return rc;
+}
+
+static int lcd_camera_power_off_sku3(void)
+{
+ int rc = 0;
+
+ pr_debug("turn off sku3 lcd_camera_ldo_1v8\n");
+ gpio_set_value_cansleep(lcd_camera_ldo_1v8, 0);
+
+ pr_debug("turn off sku3 lcd_camera_ldo\n");
+ gpio_set_value_cansleep(LCD_CAMERA_LDO_2V8, 0);
+
+ gpio_free(lcd_camera_ldo_1v8);
+ gpio_free(LCD_CAMERA_LDO_2V8);
+
+ return rc;
+}
+
+int lcd_camera_power_onoff(int on)
+{
+ int rc = 0;
+
+ pr_debug("lcd_camera_power_onoff on = %d,\n", on);
+
+ if (on)
+ rc = lcd_camera_power_on_sku3();
+ else
+ rc = lcd_camera_power_off_sku3();
+
+ return rc;
+}
+EXPORT_SYMBOL(lcd_camera_power_onoff);
+
+
void __init msm7627a_camera_init(void)
{
int rc;
+ pr_debug("msm7627a_camera_init Entered\n");
+ /* LCD and camera power (VREG & LDO) init */
+ if (machine_is_msm7627a_evb())
+ lcd_camera_power_init();
+
#ifndef CONFIG_MSM_CAMERA_V4L2
if (machine_is_msm7627a_qrd1()) {
qrd1_camera_gpio_cfg();
platform_add_devices(camera_devices_qrd,
ARRAY_SIZE(camera_devices_qrd));
- } else if (machine_is_msm7627a_evb())
- return;
- else if (machine_is_msm7627a_qrd3())
+ } else if (machine_is_msm7627a_evb()) {
+ evb_camera_gpio_cfg();
+ platform_add_devices(camera_devices_evb,
+ ARRAY_SIZE(camera_devices_evb));
+ } else if (machine_is_msm7627a_qrd3())
return;
else
platform_add_devices(camera_devices_msm,
ARRAY_SIZE(camera_devices_msm));
#endif
- if (!machine_is_msm7627a_qrd1())
+ if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb())
register_i2c_devices();
rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
@@ -822,11 +1079,16 @@
msm7x27a_init_cam();
#endif
#ifndef CONFIG_MSM_CAMERA_V4L2
- if (machine_is_msm7627a_qrd1())
+ if (machine_is_msm7627a_qrd1()) {
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices_qrd,
ARRAY_SIZE(i2c_camera_devices_qrd));
- else
+ } else if (machine_is_msm7627a_evb()) {
+ pr_debug("machine_is_msm7627a_evb i2c_register_board_info\n");
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ i2c_camera_devices_evb,
+ ARRAY_SIZE(i2c_camera_devices_evb));
+ } else
#endif
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices,
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
index 011a4d4..4e856b1 100644
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -28,10 +28,10 @@
#include "board-msm7627a.h"
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_SIZE 0x260000
+#define MSM_FB_SIZE 0x261000
#define MSM7x25A_MSM_FB_SIZE 0xE1000
#else
-#define MSM_FB_SIZE 0x195000
+#define MSM_FB_SIZE 0x196000
#define MSM7x25A_MSM_FB_SIZE 0x96000
#endif
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
index 93a6178..a10d81a 100644
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -72,17 +72,17 @@
};
static struct msm_gpio sdc2_sleep_cfg_data[] = {
- {GPIO_CFG(62, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ {GPIO_CFG(62, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
"sdc2_clk"},
- {GPIO_CFG(63, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ {GPIO_CFG(63, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
"sdc2_cmd"},
- {GPIO_CFG(64, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ {GPIO_CFG(64, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
"sdc2_dat_3"},
- {GPIO_CFG(65, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ {GPIO_CFG(65, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
"sdc2_dat_2"},
- {GPIO_CFG(66, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ {GPIO_CFG(66, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
"sdc2_dat_1"},
- {GPIO_CFG(67, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+ {GPIO_CFG(67, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
"sdc2_dat_0"},
};
static struct msm_gpio sdc3_cfg_data[] = {
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
index 51da14b..a6b29dc 100644
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -47,6 +47,7 @@
#include <mach/msm_battery.h>
#include <linux/smsc911x.h>
#include <linux/atmel_maxtouch.h>
+#include <linux/fmem.h>
#include "devices.h"
#include "timer.h"
#include "board-msm7x27a-regulator.h"
@@ -370,6 +371,9 @@
.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
.cached = 1,
.memory_type = MEMTYPE_EBI1,
+ .request_region = request_fmem_c_region,
+ .release_region = release_fmem_c_region,
+ .reusable = 1,
};
static struct platform_device android_pmem_adsp_device = {
@@ -672,6 +676,14 @@
static void msm7x27a_cfg_uart2dm_serial(void) { }
#endif
+struct fmem_platform_data fmem_pdata;
+
+struct platform_device fmem_device = {
+ .name = "fmem",
+ .id = -1,
+ .dev = { .platform_data = &fmem_pdata },
+};
+
static struct platform_device *rumi_sim_devices[] __initdata = {
&msm_device_dmov,
&msm_device_smd,
@@ -700,6 +712,7 @@
&msm_gsbi1_qup_i2c_device,
&msm_device_otg,
&msm_device_gadget_peripheral,
+ &fmem_device,
&android_usb_device,
&android_pmem_device,
&android_pmem_adsp_device,
@@ -744,8 +757,19 @@
},
};
+#ifdef CONFIG_ANDROID_PMEM
+static struct android_pmem_platform_data *pmem_pdata_array[] __initdata = {
+ &android_pmem_adsp_pdata,
+ &android_pmem_audio_pdata,
+ &android_pmem_pdata,
+};
+#endif
+
static void __init size_pmem_devices(void)
{
+#ifdef CONFIG_ANDROID_PMEM
+ unsigned int i;
+ unsigned int reusable_count = 0;
if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
pmem_mdp_size = MSM7x25A_MSM_PMEM_MDP_SIZE;
@@ -755,11 +779,30 @@
pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
}
-#ifdef CONFIG_ANDROID_PMEM
android_pmem_adsp_pdata.size = pmem_adsp_size;
android_pmem_pdata.size = pmem_mdp_size;
android_pmem_audio_pdata.size = pmem_audio_size;
+
+ fmem_pdata.size = 0;
+
+ /* Find pmem devices that should use FMEM (reusable) memory.
+ */
+ for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
+ struct android_pmem_platform_data *pdata = pmem_pdata_array[i];
+
+ if (!reusable_count && pdata->reusable)
+ fmem_pdata.size += pdata->size;
+
+ reusable_count += (pdata->reusable) ? 1 : 0;
+
+ if (pdata->reusable && reusable_count > 1) {
+ pr_err("%s: Too many PMEM devices specified as reusable. PMEM device %s was not configured as reusable.\n",
+ __func__, pdata->name);
+ pdata->reusable = 0;
+ }
+ }
#endif
+
}
static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -770,9 +813,12 @@
static void __init reserve_pmem_memory(void)
{
#ifdef CONFIG_ANDROID_PMEM
- reserve_memory_for(&android_pmem_adsp_pdata);
- reserve_memory_for(&android_pmem_pdata);
- reserve_memory_for(&android_pmem_audio_pdata);
+ unsigned int i;
+ for (i = 0; i < ARRAY_SIZE(pmem_pdata_array); ++i) {
+ if (!pmem_pdata_array[i]->reusable)
+ reserve_memory_for(pmem_pdata_array[i]);
+ }
+
msm7x27a_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
#endif
}
@@ -798,6 +844,7 @@
{
reserve_info = &msm7x27a_reserve_info;
msm_reserve();
+ fmem_pdata.phys = reserve_memory_for_fmem(fmem_pdata.size);
}
static void __init msm8625_reserve(void)
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 74ba1b3..c31e6d9 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2643,15 +2643,19 @@
#endif /* CONFIG_MSM_DSPS */
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
-#define MSM_FB_PRIM_BUF_SIZE (1024 * 600 * 4 * 3) /* 4 bpp x 3 pages */
+#define MSM_FB_PRIM_BUF_SIZE \
+ (roundup((1024 * 600 * 4), 4096) * 3) /* 4 bpp x 3 pages */
#else
-#define MSM_FB_PRIM_BUF_SIZE (1024 * 600 * 4 * 2) /* 4 bpp x 2 pages */
+#define MSM_FB_PRIM_BUF_SIZE \
+ (roundup((1024 * 600 * 4), 4096) * 2) /* 4 bpp x 2 pages */
#endif
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
-#define MSM_FB_EXT_BUF_SIZE (1920 * 1080 * 2 * 1) /* 2 bpp x 1 page */
+#define MSM_FB_EXT_BUF_SIZE \
+ (roundup((1920 * 1080 * 2), 4096) * 1) /* 2 bpp x 1 page */
#elif defined(CONFIG_FB_MSM_TVOUT)
-#define MSM_FB_EXT_BUF_SIZE (720 * 576 * 2 * 2) /* 2 bpp x 2 pages */
+#define MSM_FB_EXT_BUF_SIZE \
+ (roundup((720 * 576 * 2), 4096) * 2) /* 2 bpp x 2 pages */
#else
#define MSM_FB_EXT_BUFT_SIZE 0
#endif
@@ -5278,6 +5282,18 @@
.align = PAGE_SIZE,
};
#endif
+
+/**
+ * These heaps are listed in the order they will be allocated. Due to
+ * video hardware restrictions and content protection the FW heap has to
+ * be allocated adjacent (below) the MM heap and the MFC heap has to be
+ * allocated after the MM heap to ensure MFC heap is not more than 256MB
+ * away from the base address of the FW heap.
+ * However, the order of FW heap and MM heap doesn't matter since these
+ * two heaps are taken care of by separate code to ensure they are adjacent
+ * to each other.
+ * Don't swap the order unless you know what you are doing!
+ */
static struct ion_platform_data ion_pdata = {
.nr = MSM_ION_HEAP_NUM,
.heaps = {
@@ -5288,14 +5304,6 @@
},
#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
{
- .id = ION_SF_HEAP_ID,
- .type = ION_HEAP_TYPE_CARVEOUT,
- .name = ION_SF_HEAP_NAME,
- .size = MSM_ION_SF_SIZE,
- .memory_type = ION_EBI_TYPE,
- .extra_data = (void *)&co_ion_pdata,
- },
- {
.id = ION_CP_MM_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_MM_HEAP_NAME,
@@ -5312,14 +5320,6 @@
.extra_data = (void *) &fw_co_ion_pdata,
},
{
- .id = ION_CAMERA_HEAP_ID,
- .type = ION_HEAP_TYPE_CARVEOUT,
- .name = ION_CAMERA_HEAP_NAME,
- .size = MSM_ION_CAMERA_SIZE,
- .memory_type = ION_EBI_TYPE,
- .extra_data = &co_ion_pdata,
- },
- {
.id = ION_CP_MFC_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_MFC_HEAP_NAME,
@@ -5328,6 +5328,22 @@
.extra_data = (void *) &cp_mfc_ion_pdata,
},
{
+ .id = ION_SF_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_SF_HEAP_NAME,
+ .size = MSM_ION_SF_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = (void *)&co_ion_pdata,
+ },
+ {
+ .id = ION_CAMERA_HEAP_ID,
+ .type = ION_HEAP_TYPE_CARVEOUT,
+ .name = ION_CAMERA_HEAP_NAME,
+ .size = MSM_ION_CAMERA_SIZE,
+ .memory_type = ION_EBI_TYPE,
+ .extra_data = &co_ion_pdata,
+ },
+ {
.id = ION_CP_WB_HEAP_ID,
.type = ION_HEAP_TYPE_CP,
.name = ION_WB_HEAP_NAME,
diff --git a/arch/arm/mach-msm/clock-7x30.c b/arch/arm/mach-msm/clock-7x30.c
index 8374636..bd7ec87 100644
--- a/arch/arm/mach-msm/clock-7x30.c
+++ b/arch/arm/mach-msm/clock-7x30.c
@@ -146,7 +146,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = N16(m, n) | SPDIV(SRC_SEL_##s, div), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
#define F_MND8(f, nmsb, nlsb, s, div, m, n) \
@@ -155,7 +154,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(8, m, 0, n), \
.ns_val = N8(nmsb, nlsb, m, n) | SPDIV(SRC_SEL_##s, div), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_ops clk_ops_rcg_7x30;
@@ -227,14 +225,13 @@
static struct clk_ops clk_ops_tcxo = {
.enable = tcxo_clk_enable,
.disable = tcxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = pcom_is_local,
};
static struct fixed_clk tcxo_clk = {
- .rate = 19200000,
.c = {
.dbg_name = "tcxo_clk",
+ .rate = 19200000,
.ops = &clk_ops_tcxo,
CLK_INIT(tcxo_clk.c),
},
@@ -253,66 +250,65 @@
static struct clk_ops clk_ops_lpxo = {
.enable = lpxo_clk_enable,
.disable = lpxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = pcom_is_local,
};
static struct fixed_clk lpxo_clk = {
- .rate = 24576000,
.c = {
.dbg_name = "lpxo_clk",
+ .rate = 24576000,
.ops = &clk_ops_lpxo,
CLK_INIT(lpxo_clk.c),
},
};
static struct pll_vote_clk pll1_clk = {
- .rate = 768000000,
.en_reg = PLL_ENA_REG,
.en_mask = BIT(1),
.status_reg = PLL1_STATUS_BASE_REG,
.parent = &tcxo_clk.c,
.c = {
.dbg_name = "pll1_clk",
+ .rate = 768000000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll1_clk.c),
},
};
static struct pll_vote_clk pll2_clk = {
- .rate = 806400000, /* TODO: Support scaling */
.en_reg = PLL_ENA_REG,
.en_mask = BIT(2),
.status_reg = PLL2_STATUS_BASE_REG,
.parent = &tcxo_clk.c,
.c = {
.dbg_name = "pll2_clk",
+ .rate = 806400000, /* TODO: Support scaling */
.ops = &clk_ops_pll_vote,
CLK_INIT(pll2_clk.c),
},
};
static struct pll_vote_clk pll3_clk = {
- .rate = 737280000,
.en_reg = PLL_ENA_REG,
.en_mask = BIT(3),
.status_reg = PLL3_STATUS_BASE_REG,
.parent = &lpxo_clk.c,
.c = {
.dbg_name = "pll3_clk",
+ .rate = 737280000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll3_clk.c),
},
};
static struct pll_vote_clk pll4_clk = {
- .rate = 891000000,
.en_reg = PLL_ENA_REG,
.en_mask = BIT(4),
.status_reg = PLL4_STATUS_BASE_REG,
.parent = &lpxo_clk.c,
.c = {
.dbg_name = "pll4_clk",
+ .rate = 891000000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll4_clk.c),
},
@@ -321,7 +317,7 @@
static struct clk_ops clk_ops_branch;
static struct clk_freq_tbl clk_tbl_axi[] = {
- F_RAW(1, &lpxo_clk.c, 0, 0, 0, 0, NULL),
+ F_RAW(1, &lpxo_clk.c, 0, 0, 0, NULL),
F_END,
};
@@ -998,6 +994,7 @@
.ns_reg = CSI_NS_REG,
.md_reg = CSI_NS_REG - 4,
.ns_mask = F_MASK_MND8(24, 17),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_csi,
.current_freq = &rcg_dummy_freq,
@@ -1011,7 +1008,7 @@
};
static struct clk_freq_tbl clk_tbl_tcxo[] = {
- F_RAW(19200000, &tcxo_clk.c, 0, 0, 0, 0, NULL),
+ F_RAW(19200000, &tcxo_clk.c, 0, 0, 0, NULL),
F_END,
};
@@ -1142,6 +1139,7 @@
.ns_reg = UART1DM_NS_REG,
.md_reg = UART1DM_NS_REG - 4,
.root_en_mask = BIT(11),
+ .mnd_en_mask = BIT(8),
.freq_tbl = clk_tbl_uartdm,
.ns_mask = F_MASK_MND16,
.current_freq = &rcg_dummy_freq,
@@ -1167,6 +1165,7 @@
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_uartdm,
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -1252,7 +1251,7 @@
F_BASIC(192000000, pll1, 4),
F_BASIC(245760000, pll3, 3),
/* Sync to AXI. Hence this "rate" is not fixed. */
- F_RAW(1, &lpxo_clk.c, 0, BIT(14), 0, 0, NULL),
+ F_RAW(1, &lpxo_clk.c, 0, BIT(14), 0, NULL),
F_END,
};
@@ -1354,6 +1353,7 @@
.ns_reg = SDCn_NS_REG(1),
.md_reg = SDCn_NS_REG(1) - 4,
.ns_mask = F_MASK_MND8(19, 12),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_sdc1_3,
.current_freq = &rcg_dummy_freq,
@@ -1377,6 +1377,7 @@
.ns_reg = SDCn_NS_REG(3),
.md_reg = SDCn_NS_REG(3) - 4,
.ns_mask = F_MASK_MND8(19, 12),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_sdc1_3,
.current_freq = &rcg_dummy_freq,
@@ -1412,6 +1413,7 @@
.ns_reg = SDCn_NS_REG(2),
.md_reg = SDCn_NS_REG(2) - 4,
.ns_mask = F_MASK_MND8(20, 13),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_sdc2_4,
.current_freq = &rcg_dummy_freq,
@@ -1435,6 +1437,7 @@
.ns_reg = SDCn_NS_REG(4),
.md_reg = SDCn_NS_REG(4) - 4,
.ns_mask = F_MASK_MND8(20, 13),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_sdc2_4,
.current_freq = &rcg_dummy_freq,
@@ -1505,6 +1508,7 @@
.md_reg = MDP_LCDC_NS_REG - 4,
.root_en_mask = BIT(11),
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_mdp_lcdc,
.current_freq = &rcg_dummy_freq,
@@ -1533,8 +1537,8 @@
};
static struct clk_freq_tbl clk_tbl_mdp_vsync[] = {
- F_RAW( 0, &gnd_clk.c, 0, (0x3<<2), 0, 0, NULL),
- F_RAW(24576000, &lpxo_clk.c, 0, (0x1<<2), 0, 0, NULL),
+ F_RAW( 0, &gnd_clk.c, 0, (0x3<<2), 0, NULL),
+ F_RAW(24576000, &lpxo_clk.c, 0, (0x1<<2), 0, NULL),
F_END,
};
@@ -1578,6 +1582,7 @@
.md_reg = MI2S_RX_NS_REG - 4,
.root_en_mask = BIT(11),
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_mi2s_codec,
.current_freq = &rcg_dummy_freq,
@@ -1617,6 +1622,7 @@
.md_reg = MI2S_TX_NS_REG - 4,
.root_en_mask = BIT(11),
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_mi2s_codec,
.current_freq = &rcg_dummy_freq,
@@ -1662,6 +1668,7 @@
.md_reg = MI2S_NS_REG - 4,
.root_en_mask = BIT(11),
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_mi2s,
.current_freq = &rcg_dummy_freq,
@@ -1694,7 +1701,6 @@
.freq_hz = f, \
.md_val = MD16(m, n), \
.ns_val = N16(m, n) | SPDIV(SRC_SEL_SDAC_##s, div), \
- .mnd_en_mask = BIT(8) * !!(n), \
.src_clk = &s##_clk.c, \
}
@@ -1722,6 +1728,7 @@
.ns_reg = SDAC_NS_REG,
.md_reg = SDAC_NS_REG - 4,
.root_en_mask = BIT(11),
+ .mnd_en_mask = BIT(8),
.freq_tbl = clk_tbl_sdac,
.ns_mask = F_MASK_MND16,
.set_rate = set_rate_mnd,
@@ -1765,6 +1772,7 @@
},
.md_reg = TV_NS_REG - 4,
.ns_mask = F_MASK_MND8(23, 16),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_tv,
.current_freq = &rcg_dummy_freq,
@@ -1856,6 +1864,7 @@
},
.md_reg = USBH_NS_REG - 4,
.ns_mask = F_MASK_MND8(23, 16),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_usb,
.current_freq = &rcg_dummy_freq,
@@ -1994,6 +2003,7 @@
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_vfe_jpeg,
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -2018,6 +2028,7 @@
.root_en_mask = BIT(13),
.freq_tbl = clk_tbl_vfe_jpeg,
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -2102,6 +2113,7 @@
.root_en_mask = BIT(9),
.freq_tbl = clk_tbl_cam,
.ns_mask = F_MASK_MND16,
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.current_freq = &rcg_dummy_freq,
.c = {
@@ -2134,6 +2146,7 @@
.ns_reg = VPE_NS_REG,
.md_reg = VPE_NS_REG - 4,
.ns_mask = F_MASK_MND8(22, 15),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_vpe,
.current_freq = &rcg_dummy_freq,
@@ -2170,6 +2183,7 @@
.ns_reg = MFC_NS_REG,
.md_reg = MFC_NS_REG - 4,
.ns_mask = F_MASK_MND8(24, 17),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_mfc,
.current_freq = &rcg_dummy_freq,
@@ -2218,6 +2232,7 @@
.ns_reg = SPI_NS_REG,
.md_reg = SPI_NS_REG - 4,
.ns_mask = F_MASK_MND8(19, 12),
+ .mnd_en_mask = BIT(8),
.root_en_mask = BIT(11),
.freq_tbl = clk_tbl_spi,
.current_freq = &rcg_dummy_freq,
@@ -2231,10 +2246,10 @@
};
static struct clk_freq_tbl clk_tbl_lpa_codec[] = {
- F_RAW(1, NULL, 0, 0, 0, 0, NULL), /* src MI2S_CODEC_RX */
- F_RAW(2, NULL, 0, 1, 0, 0, NULL), /* src ECODEC_CIF */
- F_RAW(3, NULL, 0, 2, 0, 0, NULL), /* src MI2S */
- F_RAW(4, NULL, 0, 3, 0, 0, NULL), /* src SDAC */
+ F_RAW(1, NULL, 0, 0, 0, NULL), /* src MI2S_CODEC_RX */
+ F_RAW(2, NULL, 0, 1, 0, NULL), /* src ECODEC_CIF */
+ F_RAW(3, NULL, 0, 2, 0, NULL), /* src MI2S */
+ F_RAW(4, NULL, 0, 3, 0, NULL), /* src SDAC */
F_END,
};
@@ -2260,7 +2275,7 @@
};
static struct clk_freq_tbl clk_tbl_mdc[] = {
- F_RAW(1, NULL, 0, 0, 0, 0, NULL),
+ F_RAW(1, NULL, 0, 0, 0, NULL),
F_END
};
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index 493a210..8188e08 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -423,7 +423,7 @@
RPM_VREG_VOTER3, 1800000, 1800000, 1);
} else {
rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8921_S8,
- RPM_VREG_VOTER3, 2200000, 2200000, 1);
+ RPM_VREG_VOTER3, 2100000, 2100000, 1);
if (rc)
return rc;
rc = rpm_vreg_set_voltage(RPM_VREG_ID_PM8921_L23,
@@ -470,14 +470,13 @@
static struct clk_ops clk_ops_pxo = {
.enable = pxo_clk_enable,
.disable = pxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = local_clk_is_local,
};
static struct fixed_clk pxo_clk = {
- .rate = 27000000,
.c = {
.dbg_name = "pxo_clk",
+ .rate = 27000000,
.ops = &clk_ops_pxo,
CLK_INIT(pxo_clk.c),
},
@@ -496,36 +495,35 @@
static struct clk_ops clk_ops_cxo = {
.enable = cxo_clk_enable,
.disable = cxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = local_clk_is_local,
};
static struct fixed_clk cxo_clk = {
- .rate = 19200000,
.c = {
.dbg_name = "cxo_clk",
+ .rate = 19200000,
.ops = &clk_ops_cxo,
CLK_INIT(cxo_clk.c),
},
};
static struct pll_clk pll2_clk = {
- .rate = 800000000,
.mode_reg = MM_PLL1_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll2_clk",
+ .rate = 800000000,
.ops = &clk_ops_pll,
CLK_INIT(pll2_clk.c),
},
};
static struct pll_clk pll3_clk = {
- .rate = 1200000000,
.mode_reg = BB_MMCC_PLL2_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll3_clk",
+ .rate = 1200000000,
.ops = &clk_ops_pll,
.vdd_class = &vdd_sr2_pll,
.fmax[VDD_SR2_PLL_ON] = ULONG_MAX,
@@ -534,50 +532,50 @@
};
static struct pll_vote_clk pll4_clk = {
- .rate = 393216000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(4),
.status_reg = LCC_PLL0_STATUS_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll4_clk",
+ .rate = 393216000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll4_clk.c),
},
};
static struct pll_vote_clk pll8_clk = {
- .rate = 384000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll8_clk",
+ .rate = 384000000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll8_clk.c),
},
};
static struct pll_vote_clk pll14_clk = {
- .rate = 480000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(14),
.status_reg = BB_PLL14_STATUS_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll14_clk",
+ .rate = 480000000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll14_clk.c),
},
};
static struct pll_clk pll15_clk = {
- .rate = 975000000,
.mode_reg = MM_PLL3_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll15_clk",
+ .rate = 975000000,
.ops = &clk_ops_pll,
CLK_INIT(pll15_clk.c),
},
@@ -1246,6 +1244,7 @@
.md_reg = GPn_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gp, \
.current_freq = &rcg_dummy_freq, \
@@ -1262,7 +1261,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gp[] = {
F_GP( 0, gnd, 1, 0, 0),
@@ -1297,6 +1295,7 @@
.md_reg = GSBIn_UART_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(31, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_uart, \
.current_freq = &rcg_dummy_freq, \
@@ -1313,7 +1312,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_uart[] = {
F_GSBI_UART( 0, gnd, 1, 0, 0),
@@ -1361,6 +1359,7 @@
.md_reg = GSBIn_QUP_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_qup, \
.current_freq = &rcg_dummy_freq, \
@@ -1377,7 +1376,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_qup[] = {
F_GSBI_QUP( 0, gnd, 1, 0, 0),
@@ -1500,6 +1498,7 @@
.md_reg = SDCn_APPS_CLK_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_sdc, \
.current_freq = &rcg_dummy_freq, \
@@ -1516,7 +1515,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_sdc[] = {
F_SDC( 0, gnd, 1, 0, 0),
@@ -1545,7 +1543,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_tsif_ref[] = {
F_TSIF_REF( 0, gnd, 1, 0, 0),
@@ -1564,6 +1561,7 @@
.md_reg = TSIF_REF_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(31, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_tsif_ref,
.current_freq = &rcg_dummy_freq,
@@ -1621,6 +1619,7 @@
.md_reg = USB_HS##n##_XCVR_FS_CLK_MD_REG, \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_usb, \
.current_freq = &rcg_dummy_freq, \
@@ -1638,7 +1637,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_usb[] = {
F_USB( 0, gnd, 1, 0, 0),
@@ -1667,6 +1665,7 @@
.md_reg = USB_HSIC_XCVR_FS_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb_hsic,
.current_freq = &rcg_dummy_freq,
@@ -1787,6 +1786,7 @@
.md_reg = USB_FSn_XCVR_FS_CLK_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_usb, \
.current_freq = &rcg_dummy_freq, \
@@ -2522,6 +2522,7 @@
.md_reg = CAMCLK##n##_MD_REG, \
.root_en_mask = BIT(2), \
.ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0), \
+ .mnd_en_mask = BIT(5), \
.ctl_mask = BM(7, 6), \
.set_rate = set_rate_mnd_8, \
.freq_tbl = clk_tbl_cam, \
@@ -2540,7 +2541,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(31, 24, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_cam[] = {
F_CAM( 0, gnd, 1, 0, 0),
@@ -2569,7 +2569,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(31, 24, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_csi[] = {
F_CSI( 0, gnd, 1, 0, 0),
@@ -2588,6 +2587,7 @@
.md_reg = CSI0_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_csi,
@@ -2643,6 +2643,7 @@
.md_reg = CSI1_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_csi,
@@ -2698,6 +2699,7 @@
.md_reg = CSI2_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = BM(31, 24) | BM(15, 14) | BM(2, 0),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_csi,
@@ -3005,7 +3007,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(31, 24, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_csi_phytimer[] = {
F_CSI_PHYTIMER( 0, gnd, 1, 0, 0),
@@ -3023,6 +3024,7 @@
.md_reg = CSIPHYTIMER_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(31, 24) | BM(15, 14) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd_8,
.freq_tbl = clk_tbl_csi_phytimer,
@@ -3194,7 +3196,6 @@
.md_val = MD4(4, m, 0, n), \
.ns_val = NS_MND_BANKED4(20, 16, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gfx2d[] = {
F_GFX2D( 0, gnd, 0, 0),
@@ -3308,7 +3309,6 @@
.md_val = MD4(4, m, 0, n), \
.ns_val = NS_MND_BANKED4(18, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gfx3d_8960[] = {
@@ -3410,7 +3410,6 @@
.md_val = MD4(4, m, 0, n), \
.ns_val = NS_MND_BANKED4(18, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_vcap[] = {
@@ -3487,7 +3486,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 15, 12, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_ijpeg[] = {
@@ -3527,6 +3525,7 @@
.md_reg = IJPEG_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(23, 16) | BM(15, 12) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_ijpeg,
@@ -3590,7 +3589,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MND_BANKED8(22, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_mdp[] = {
F_MDP( 0, gnd, 0, 0),
@@ -3822,7 +3820,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
#define F_TV(f, s, p_r, d, m, n) \
{ \
@@ -3831,7 +3828,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
.extra_freq_data = (void *)p_r, \
}
/* Switching TV freqs requires PLL reconfiguration. */
@@ -3873,6 +3869,7 @@
.md_reg = TV_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(23, 16) | BM(15, 14) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_tv,
.freq_tbl = clk_tbl_tv,
@@ -3885,6 +3882,21 @@
},
};
+static struct cdiv_clk tv_src_div_clk = {
+ .b = {
+ .ctl_reg = TV_NS_REG,
+ .halt_check = NOCHECK,
+ },
+ .ns_reg = TV_NS_REG,
+ .div_offset = 6,
+ .max_div = 2,
+ .c = {
+ .dbg_name = "tv_src_div_clk",
+ .ops = &clk_ops_cdiv,
+ CLK_INIT(tv_src_div_clk.c),
+ },
+};
+
static struct branch_clk tv_enc_clk = {
.b = {
.ctl_reg = TV_CC_REG,
@@ -3953,6 +3965,36 @@
},
};
+static struct branch_clk rgb_tv_clk = {
+ .b = {
+ .ctl_reg = TV_CC2_REG,
+ .en_mask = BIT(14),
+ .halt_reg = DBG_BUS_VEC_J_REG,
+ .halt_bit = 27,
+ },
+ .parent = &tv_src_clk.c,
+ .c = {
+ .dbg_name = "rgb_tv_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(rgb_tv_clk.c),
+ },
+};
+
+static struct branch_clk npl_tv_clk = {
+ .b = {
+ .ctl_reg = TV_CC2_REG,
+ .en_mask = BIT(16),
+ .halt_reg = DBG_BUS_VEC_J_REG,
+ .halt_bit = 26,
+ },
+ .parent = &tv_src_clk.c,
+ .c = {
+ .dbg_name = "npl_tv_clk",
+ .ops = &clk_ops_branch,
+ CLK_INIT(npl_tv_clk.c),
+ },
+};
+
static struct branch_clk hdmi_app_clk = {
.b = {
.ctl_reg = MISC_CC2_REG,
@@ -3993,7 +4035,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MND_BANKED8(11, 19, n, m, 0, 27, s##_to_mm_mux), \
.ctl_val = CC_BANKED(6, 11, n), \
- .mnd_en_mask = (BIT(10) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_vcodec[] = {
F_VCODEC( 0, gnd, 0, 0),
@@ -4087,7 +4128,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 11, 10, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_vfe[] = {
@@ -4133,6 +4173,7 @@
.md_reg = VFE_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(23, 16) | BM(11, 10) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_vfe,
@@ -4173,7 +4214,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(8, m, 0, n), \
.ns_val = NS(31, 24, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_aif_osr[] = {
F_AIF_OSR( 0, gnd, 1, 0, 0),
@@ -4206,6 +4246,7 @@
.md_reg = md, \
.root_en_mask = BIT(9), \
.ns_mask = (BM(31, 24) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_aif_osr, \
.current_freq = &rcg_dummy_freq, \
@@ -4231,6 +4272,7 @@
.md_reg = md, \
.root_en_mask = BIT(9), \
.ns_mask = (BM(31, 24) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_aif_osr, \
.current_freq = &rcg_dummy_freq, \
@@ -4310,7 +4352,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_pcm[] = {
F_PCM( 0, gnd, 1, 0, 0),
@@ -4342,6 +4383,7 @@
.md_reg = LCC_PCM_MD_REG,
.root_en_mask = BIT(9),
.ns_mask = (BM(31, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_pcm,
.current_freq = &rcg_dummy_freq,
@@ -4367,6 +4409,7 @@
.md_reg = LCC_SLIMBUS_MD_REG,
.root_en_mask = BIT(9),
.ns_mask = (BM(31, 24) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_aif_osr,
.current_freq = &rcg_dummy_freq,
@@ -4632,6 +4675,8 @@
{ TEST_MM_HS(0x33), &vcap_clk.c },
{ TEST_MM_HS(0x34), &vcap_npl_clk.c },
{ TEST_MM_HS(0x35), &vcap_axi_clk.c },
+ { TEST_MM_HS(0x36), &rgb_tv_clk.c },
+ { TEST_MM_HS(0x37), &npl_tv_clk.c },
{ TEST_MM_HS(0x38), &gfx3d_axi_clk.c },
{ TEST_LPA(0x0F), &mi2s_bit_clk.c },
@@ -4877,10 +4922,10 @@
CLK_LOOKUP("core_clk", gsbi5_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi6_uart_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi7_uart_clk.c, "msm_serial_hsl.0"),
- CLK_LOOKUP("core_clk", gsbi1_qup_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi1_qup_clk.c, "qup_i2c.0"),
CLK_LOOKUP("core_clk", gsbi2_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi3_qup_clk.c, "qup_i2c.3"),
- CLK_LOOKUP("core_clk", gsbi4_qup_clk.c, ""),
+ CLK_LOOKUP("core_clk", gsbi4_qup_clk.c, "qup_i2c.4"),
CLK_LOOKUP("core_clk", gsbi5_qup_clk.c, "spi_qsd.0"),
CLK_LOOKUP("core_clk", gsbi6_qup_clk.c, ""),
CLK_LOOKUP("core_clk", gsbi7_qup_clk.c, ""),
@@ -4911,9 +4956,10 @@
CLK_LOOKUP("ce3_core_src_clk", ce3_src_clk.c, "qcrypto.0"),
CLK_LOOKUP("dma_bam_pclk", dma_bam_p_clk.c, NULL),
CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, "msm_serial_hsl.1"),
+ CLK_LOOKUP("iface_clk", gsbi1_p_clk.c, "qup_i2c.0"),
CLK_LOOKUP("iface_clk", gsbi2_p_clk.c, ""),
CLK_LOOKUP("iface_clk", gsbi3_p_clk.c, "qup_i2c.3"),
- CLK_LOOKUP("iface_clk", gsbi4_p_clk.c, ""),
+ CLK_LOOKUP("iface_clk", gsbi4_p_clk.c, "qup_i2c.4"),
CLK_LOOKUP("iface_clk", gsbi5_p_clk.c, "spi_qsd.0"),
CLK_LOOKUP("iface_clk", gsbi6_p_clk.c, ""),
CLK_LOOKUP("iface_clk", gsbi7_p_clk.c, "msm_serial_hsl.0"),
@@ -4934,38 +4980,38 @@
CLK_LOOKUP("core_clk", pmic_ssbi2_clk.c, ""),
CLK_LOOKUP("mem_clk", rpm_msg_ram_p_clk.c, ""),
CLK_LOOKUP("core_clk", amp_clk.c, ""),
- CLK_LOOKUP("cam_clk", cam0_clk.c, ""),
- CLK_LOOKUP("cam_clk", cam1_clk.c, ""),
- CLK_LOOKUP("cam_clk", cam0_clk.c, ""),
- CLK_LOOKUP("cam_clk", cam0_clk.c, ""),
- CLK_LOOKUP("cam_clk", cam0_clk.c, ""),
- CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, ""),
- CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, ""),
- CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, ""),
- CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, ""),
- CLK_LOOKUP("csi_clk", csi0_clk.c, ""),
- CLK_LOOKUP("csi_clk", csi1_clk.c, ""),
- CLK_LOOKUP("csi_clk", csi1_clk.c, ""),
- CLK_LOOKUP("csi_clk", csi2_clk.c, ""),
- CLK_LOOKUP("csi_phy_clk", csi0_phy_clk.c, ""),
- CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, ""),
- CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, ""),
- CLK_LOOKUP("csi_phy_clk", csi2_phy_clk.c, ""),
- CLK_LOOKUP("csi_pix_clk", csi_pix_clk.c, ""),
- CLK_LOOKUP("csi_pix_clk", csi_pix1_clk.c, ""),
- CLK_LOOKUP("csi_rdi_clk", csi_rdi_clk.c, ""),
- CLK_LOOKUP("csi_rdi_clk", csi_rdi1_clk.c, ""),
- CLK_LOOKUP("csi_rdi_clk", csi_rdi2_clk.c, ""),
- CLK_LOOKUP("csiphy_timer_src_clk", csiphy_timer_src_clk.c, ""),
- CLK_LOOKUP("csiphy_timer_clk", csi0phy_timer_clk.c, ""),
- CLK_LOOKUP("csiphy_timer_clk", csi1phy_timer_clk.c, ""),
- CLK_LOOKUP("csiphy_timer_clk", csi2phy_timer_clk.c, ""),
+ CLK_LOOKUP("cam_clk", cam0_clk.c, "4-001a"),
+ CLK_LOOKUP("cam_clk", cam1_clk.c, "4-006c"),
+ CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, "msm_csid.0"),
+ CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, "msm_csid.2"),
+ CLK_LOOKUP("csi_clk", csi0_clk.c, "msm_csid.0"),
+ CLK_LOOKUP("csi_clk", csi1_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_clk", csi2_clk.c, "msm_csid.2"),
+ CLK_LOOKUP("csi_phy_clk", csi0_phy_clk.c, "msm_csid.0"),
+ CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_phy_clk", csi2_phy_clk.c, "msm_csid.2"),
+ CLK_LOOKUP("csi_pix_clk", csi_pix_clk.c, "msm_ispif.0"),
+ CLK_LOOKUP("csi_pix1_clk", csi_pix1_clk.c, "msm_ispif.0"),
+ CLK_LOOKUP("csi_rdi_clk", csi_rdi_clk.c, "msm_ispif.0"),
+ CLK_LOOKUP("csi_rdi1_clk", csi_rdi1_clk.c, "msm_ispif.0"),
+ CLK_LOOKUP("csi_rdi2_clk", csi_rdi2_clk.c, "msm_ispif.0"),
+ CLK_LOOKUP("csiphy_timer_src_clk",
+ csiphy_timer_src_clk.c, "msm_csiphy.0"),
+ CLK_LOOKUP("csiphy_timer_src_clk",
+ csiphy_timer_src_clk.c, "msm_csiphy.1"),
+ CLK_LOOKUP("csiphy_timer_src_clk",
+ csiphy_timer_src_clk.c, "msm_csiphy.2"),
+ CLK_LOOKUP("csiphy_timer_clk", csi0phy_timer_clk.c, "msm_csiphy.0"),
+ CLK_LOOKUP("csiphy_timer_clk", csi1phy_timer_clk.c, "msm_csiphy.1"),
+ CLK_LOOKUP("csiphy_timer_clk", csi2phy_timer_clk.c, "msm_csiphy.2"),
CLK_LOOKUP("dsi_byte_div_clk", dsi1_byte_clk.c, NULL),
CLK_LOOKUP("dsi_byte_div_clk", dsi2_byte_clk.c, NULL),
CLK_LOOKUP("dsi_esc_clk", dsi1_esc_clk.c, NULL),
CLK_LOOKUP("dsi_esc_clk", dsi2_esc_clk.c, NULL),
- CLK_DUMMY("rgb_tv_clk", RGB_TV_CLK, "", OFF),
- CLK_DUMMY("npl_tv_clk", NPL_TV_CLK, "", OFF),
+ CLK_LOOKUP("rgb_clk", rgb_tv_clk.c, ""),
+ CLK_LOOKUP("npl_clk", npl_tv_clk.c, ""),
+
CLK_LOOKUP("core_clk", gfx3d_clk.c, "kgsl-3d0.0"),
CLK_LOOKUP("core_clk", gfx3d_clk.c, "footswitch-8x60.2"),
CLK_LOOKUP("bus_clk", gfx3d_axi_clk.c, "footswitch-8x60.2"),
@@ -4988,18 +5034,19 @@
CLK_LOOKUP("lut_clk", lut_mdp_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("core_clk", rot_clk.c, "msm_rotator.0"),
CLK_LOOKUP("core_clk", rot_clk.c, "footswitch-8x60.6"),
- CLK_DUMMY("tv_src_clk", TV_SRC_CLK, NULL, OFF),
+ CLK_LOOKUP("tv_src_clk", tv_src_clk.c, ""),
+ CLK_LOOKUP("tv_src_div_clk", tv_src_div_clk.c, ""),
CLK_LOOKUP("core_clk", vcodec_clk.c, "msm_vidc.0"),
CLK_LOOKUP("core_clk", vcodec_clk.c, "footswitch-8x60.7"),
- CLK_DUMMY("mdp_tv_clk", MDP_TV_CLK, NULL, OFF),
- CLK_DUMMY("tv_clk", MDP_TV_CLK, "footswitch-8x60.4", OFF),
- CLK_DUMMY("hdmi_clk", HDMI_TV_CLK, "", OFF),
+ CLK_LOOKUP("mdp_tv_clk", mdp_tv_clk.c, ""),
+ CLK_LOOKUP("tv_clk", mdp_tv_clk.c, "footswitch-8x60.4"),
+ CLK_LOOKUP("hdmi_clk", hdmi_tv_clk.c, ""),
CLK_LOOKUP("core_clk", hdmi_app_clk.c, ""),
CLK_LOOKUP("vpe_clk", vpe_clk.c, ""),
CLK_LOOKUP("core_clk", vpe_clk.c, "footswitch-8x60.9"),
- CLK_LOOKUP("vfe_clk", vfe_clk.c, ""),
+ CLK_LOOKUP("vfe_clk", vfe_clk.c, "msm_vfe.0"),
CLK_LOOKUP("core_clk", vfe_clk.c, "footswitch-8x60.8"),
- CLK_LOOKUP("csi_vfe_clk", csi_vfe_clk.c, ""),
+ CLK_LOOKUP("csi_vfe_clk", csi_vfe_clk.c, "msm_vfe.0"),
CLK_LOOKUP("bus_clk", vfe_axi_clk.c, "footswitch-8x60.8"),
CLK_LOOKUP("bus_clk", mdp_axi_clk.c, "footswitch-8x60.4"),
CLK_LOOKUP("bus_clk", rot_axi_clk.c, "footswitch-8x60.6"),
@@ -5008,7 +5055,9 @@
CLK_LOOKUP("bus_b_clk", vcodec_axi_b_clk.c, "footswitch-8x60.7"),
CLK_LOOKUP("bus_clk", vpe_axi_clk.c, "footswitch-8x60.9"),
CLK_LOOKUP("amp_pclk", amp_p_clk.c, NULL),
- CLK_LOOKUP("csi_pclk", csi_p_clk.c, ""),
+ CLK_LOOKUP("csi_pclk", csi_p_clk.c, "msm_csid.0"),
+ CLK_LOOKUP("csi_pclk", csi_p_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_pclk", csi_p_clk.c, "msm_csid.2"),
CLK_LOOKUP("dsi_m_pclk", dsi1_m_p_clk.c, NULL),
CLK_LOOKUP("dsi_s_pclk", dsi1_s_p_clk.c, NULL),
CLK_LOOKUP("dsi_m_pclk", dsi2_m_p_clk.c, NULL),
@@ -5028,24 +5077,32 @@
CLK_LOOKUP("iface_clk", rot_p_clk.c, "footswitch-8x60.6"),
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "msm_vidc.0"),
CLK_LOOKUP("iface_clk", vcodec_p_clk.c, "footswitch-8x60.7"),
- CLK_LOOKUP("vfe_pclk", vfe_p_clk.c, ""),
+ CLK_LOOKUP("vfe_pclk", vfe_p_clk.c, "msm_vfe.0"),
CLK_LOOKUP("iface_clk", vfe_p_clk.c, "footswitch-8x60.8"),
CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, ""),
CLK_LOOKUP("iface_pclk", vpe_p_clk.c, "footswitch-8x60.9"),
- CLK_LOOKUP("mi2s_bit_clk", mi2s_bit_clk.c, ""),
- CLK_LOOKUP("mi2s_osr_clk", mi2s_osr_clk.c, ""),
- CLK_LOOKUP("i2s_mic_bit_clk", codec_i2s_mic_bit_clk.c, ""),
- CLK_LOOKUP("i2s_mic_osr_clk", codec_i2s_mic_osr_clk.c, ""),
- CLK_LOOKUP("i2s_mic_bit_clk", spare_i2s_mic_bit_clk.c, ""),
- CLK_LOOKUP("i2s_mic_osr_clk", spare_i2s_mic_osr_clk.c, ""),
- CLK_LOOKUP("i2s_spkr_bit_clk", codec_i2s_spkr_bit_clk.c, ""),
- CLK_LOOKUP("i2s_spkr_osr_clk", codec_i2s_spkr_osr_clk.c, ""),
- CLK_LOOKUP("i2s_spkr_bit_clk", spare_i2s_spkr_bit_clk.c, ""),
- CLK_LOOKUP("i2s_spkr_osr_clk", spare_i2s_spkr_osr_clk.c, ""),
- CLK_LOOKUP("pcm_clk", pcm_clk.c, ""),
+ CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
+ CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.6"),
+ CLK_LOOKUP("bit_clk", codec_i2s_mic_bit_clk.c,
+ "msm-dai-q6.1"),
+ CLK_LOOKUP("osr_clk", codec_i2s_mic_osr_clk.c,
+ "msm-dai-q6.1"),
+ CLK_LOOKUP("bit_clk", spare_i2s_mic_bit_clk.c,
+ "msm-dai-q6.5"),
+ CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
+ "msm-dai-q6.5"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.16384"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.16384"),
+ CLK_LOOKUP("bit_clk", spare_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.4"),
+ CLK_LOOKUP("osr_clk", spare_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.4"),
+ CLK_LOOKUP("pcm_clk", pcm_clk.c, "msm-dai-q6.2"),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, ""),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
+ CLK_LOOKUP("core_clk", audio_slimbus_clk.c, "msm_slim_ctrl.1"),
CLK_LOOKUP("core_clk", jpegd_axi_clk.c, ""),
CLK_LOOKUP("core_clk", vpe_axi_clk.c, ""),
CLK_LOOKUP("core_clk", mdp_axi_clk.c, ""),
@@ -5220,10 +5277,13 @@
CLK_LOOKUP("cam_clk", cam0_clk.c, "4-0020"),
CLK_LOOKUP("csi_src_clk", csi0_src_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_src_clk", csi1_src_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, "msm_csid.2"),
CLK_LOOKUP("csi_clk", csi0_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_clk", csi1_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_clk", csi2_clk.c, "msm_csid.2"),
CLK_LOOKUP("csi_phy_clk", csi0_phy_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_phy_clk", csi1_phy_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_phy_clk", csi2_phy_clk.c, "msm_csid.2"),
CLK_LOOKUP("csi_pix_clk", csi_pix_clk.c, "msm_ispif.0"),
CLK_LOOKUP("csi_rdi_clk", csi_rdi_clk.c, "msm_ispif.0"),
CLK_LOOKUP("csi_src_clk", csi2_src_clk.c, NULL),
@@ -5237,8 +5297,11 @@
csiphy_timer_src_clk.c, "msm_csiphy.0"),
CLK_LOOKUP("csiphy_timer_src_clk",
csiphy_timer_src_clk.c, "msm_csiphy.1"),
+ CLK_LOOKUP("csiphy_timer_src_clk",
+ csiphy_timer_src_clk.c, "msm_csiphy.2"),
CLK_LOOKUP("csiphy_timer_clk", csi0phy_timer_clk.c, "msm_csiphy.0"),
CLK_LOOKUP("csiphy_timer_clk", csi1phy_timer_clk.c, "msm_csiphy.1"),
+ CLK_LOOKUP("csiphy_timer_clk", csi2phy_timer_clk.c, "msm_csiphy.2"),
CLK_LOOKUP("dsi_byte_div_clk", dsi1_byte_clk.c, NULL),
CLK_LOOKUP("dsi_byte_div_clk", dsi2_byte_clk.c, NULL),
CLK_LOOKUP("dsi_esc_clk", dsi1_esc_clk.c, NULL),
@@ -5287,6 +5350,7 @@
CLK_LOOKUP("amp_pclk", amp_p_clk.c, NULL),
CLK_LOOKUP("csi_pclk", csi_p_clk.c, "msm_csid.0"),
CLK_LOOKUP("csi_pclk", csi_p_clk.c, "msm_csid.1"),
+ CLK_LOOKUP("csi_pclk", csi_p_clk.c, "msm_csid.2"),
CLK_LOOKUP("dsi_m_pclk", dsi1_m_p_clk.c, NULL),
CLK_LOOKUP("dsi_s_pclk", dsi1_s_p_clk.c, NULL),
CLK_LOOKUP("dsi_m_pclk", dsi2_m_p_clk.c, NULL),
@@ -5315,19 +5379,27 @@
CLK_LOOKUP("iface_clk", vfe_p_clk.c, "footswitch-8x60.8"),
CLK_LOOKUP("vpe_pclk", vpe_p_clk.c, "msm_vpe.0"),
CLK_LOOKUP("iface_clk", vpe_p_clk.c, "footswitch-8x60.9"),
- CLK_LOOKUP("mi2s_bit_clk", mi2s_bit_clk.c, NULL),
- CLK_LOOKUP("mi2s_osr_clk", mi2s_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_bit_clk", codec_i2s_mic_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_osr_clk", codec_i2s_mic_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_bit_clk", spare_i2s_mic_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_osr_clk", spare_i2s_mic_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_bit_clk", codec_i2s_spkr_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_osr_clk", codec_i2s_spkr_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_bit_clk", spare_i2s_spkr_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_osr_clk", spare_i2s_spkr_osr_clk.c, NULL),
- CLK_LOOKUP("pcm_clk", pcm_clk.c, NULL),
+ CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
+ CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.6"),
+ CLK_LOOKUP("bit_clk", codec_i2s_mic_bit_clk.c,
+ "msm-dai-q6.1"),
+ CLK_LOOKUP("osr_clk", codec_i2s_mic_osr_clk.c,
+ "msm-dai-q6.1"),
+ CLK_LOOKUP("bit_clk", spare_i2s_mic_bit_clk.c,
+ "msm-dai-q6.5"),
+ CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
+ "msm-dai-q6.5"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.16384"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.16384"),
+ CLK_LOOKUP("bit_clk", spare_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.4"),
+ CLK_LOOKUP("osr_clk", spare_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.4"),
+ CLK_LOOKUP("pcm_clk", pcm_clk.c, "msm-dai-q6.2"),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, NULL),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
+ CLK_LOOKUP("core_clk", audio_slimbus_clk.c, "msm_slim_ctrl.1"),
CLK_LOOKUP("core_clk", jpegd_axi_clk.c, "msm_iommu.0"),
CLK_LOOKUP("core_clk", vpe_axi_clk.c, "msm_iommu.1"),
CLK_LOOKUP("core_clk", mdp_axi_clk.c, "msm_iommu.2"),
@@ -5599,10 +5671,6 @@
/* Local clock driver initialization. */
static void __init msm8960_clock_init(void)
{
- /* Copy gfx2d's frequency table because it's modified by both clocks */
- gfx2d1_clk.freq_tbl = kmemdup(clk_tbl_gfx2d,
- sizeof(struct clk_freq_tbl) * ARRAY_SIZE(clk_tbl_gfx2d),
- GFP_KERNEL);
if (cpu_is_msm8960()) {
rpm_vreg_id_vdd_dig = RPM_VREG_ID_PM8921_S3;
@@ -5672,6 +5740,7 @@
clk_set_rate(&usb_hsic_xcvr_fs_clk.c, 60000000);
clk_set_rate(&usb_hsic_hsic_src_clk.c, 480000000);
clk_set_rate(&usb_hsic_hsio_cal_clk.c, 9000000);
+ clk_set_rate(&usb_hsic_system_clk.c, 60000000);
/*
* Set the CSI rates to a safe default to avoid warnings when
* switching csi pix and rdi clocks.
diff --git a/arch/arm/mach-msm/clock-8x60.c b/arch/arm/mach-msm/clock-8x60.c
index e53d441..d3f5396 100644
--- a/arch/arm/mach-msm/clock-8x60.c
+++ b/arch/arm/mach-msm/clock-8x60.c
@@ -318,14 +318,13 @@
static struct clk_ops clk_ops_pxo = {
.enable = pxo_clk_enable,
.disable = pxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = xo_clk_is_local,
};
static struct fixed_clk pxo_clk = {
- .rate = 27000000,
.c = {
.dbg_name = "pxo_clk",
+ .rate = 27000000,
.ops = &clk_ops_pxo,
CLK_INIT(pxo_clk.c),
},
@@ -344,49 +343,48 @@
static struct clk_ops clk_ops_cxo = {
.enable = cxo_clk_enable,
.disable = cxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = xo_clk_is_local,
};
static struct fixed_clk cxo_clk = {
- .rate = 19200000,
.c = {
.dbg_name = "cxo_clk",
+ .rate = 19200000,
.ops = &clk_ops_cxo,
CLK_INIT(cxo_clk.c),
},
};
static struct pll_vote_clk pll8_clk = {
- .rate = 384000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll8_clk",
+ .rate = 384000000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll8_clk.c),
},
};
static struct pll_clk pll2_clk = {
- .rate = 800000000,
.mode_reg = MM_PLL1_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll2_clk",
+ .rate = 800000000,
.ops = &clk_ops_pll,
CLK_INIT(pll2_clk.c),
},
};
static struct pll_clk pll3_clk = {
- .rate = 0, /* TODO: Detect rate dynamically */
.mode_reg = MM_PLL2_MODE_REG,
.parent = &pxo_clk.c,
.c = {
.dbg_name = "pll3_clk",
+ .rate = 0, /* TODO: Detect rate dynamically */
.ops = &clk_ops_pll,
CLK_INIT(pll3_clk.c),
},
@@ -417,15 +415,14 @@
static struct clk_ops clk_ops_pll4 = {
.enable = pll4_clk_enable,
.disable = pll4_clk_disable,
- .get_rate = fixed_clk_get_rate,
.get_parent = pll4_clk_get_parent,
.is_local = pll4_clk_is_local,
};
static struct fixed_clk pll4_clk = {
- .rate = 540672000,
.c = {
.dbg_name = "pll4_clk",
+ .rate = 540672000,
.ops = &clk_ops_pll4,
CLK_INIT(pll4_clk.c),
},
@@ -1014,6 +1011,7 @@
.md_reg = GPn_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gp, \
.current_freq = &rcg_dummy_freq, \
@@ -1030,7 +1028,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gp[] = {
F_GP( 0, gnd, 1, 0, 0),
@@ -1059,6 +1056,7 @@
.md_reg = GSBIn_UART_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(31, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_uart, \
.current_freq = &rcg_dummy_freq, \
@@ -1075,7 +1073,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_uart[] = {
F_GSBI_UART( 0, gnd, 1, 0, 0),
@@ -1123,6 +1120,7 @@
.md_reg = GSBIn_QUP_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_qup, \
.current_freq = &rcg_dummy_freq, \
@@ -1139,7 +1137,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_qup[] = {
F_GSBI_QUP( 0, gnd, 1, 0, 0),
@@ -1260,6 +1257,7 @@
.md_reg = SDCn_APPS_CLK_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_sdc, \
.current_freq = &rcg_dummy_freq, \
@@ -1276,7 +1274,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_sdc[] = {
F_SDC( 0, gnd, 1, 0, 0),
@@ -1302,7 +1299,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_tsif_ref[] = {
F_TSIF_REF( 0, gnd, 1, 0, 0),
@@ -1321,6 +1317,7 @@
.md_reg = TSIF_REF_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(31, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_tsif_ref,
.current_freq = &rcg_dummy_freq,
@@ -1369,7 +1366,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_usb[] = {
F_USB( 0, gnd, 1, 0, 0),
@@ -1390,6 +1386,7 @@
.md_reg = USB_HS1_XCVR_FS_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb,
.current_freq = &rcg_dummy_freq,
@@ -1423,6 +1420,7 @@
.md_reg = USB_FSn_XCVR_FS_CLK_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_usb, \
.current_freq = &rcg_dummy_freq, \
@@ -2033,7 +2031,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(31, 24, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_cam[] = {
F_CAM( 0, gnd, 1, 0, 0),
@@ -2061,6 +2058,7 @@
.md_reg = CAMCLK_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(31, 24) | BM(15, 14) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd_8,
.freq_tbl = clk_tbl_cam,
@@ -2199,7 +2197,6 @@
.md_val = MD4(4, m, 0, n), \
.ns_val = NS_MND_BANKED4(20, 16, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gfx2d[] = {
F_GFX2D( 0, gnd, 0, 0),
@@ -2313,7 +2310,6 @@
.md_val = MD4(4, m, 0, n), \
.ns_val = NS_MND_BANKED4(18, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gfx3d[] = {
F_GFX3D( 0, gnd, 0, 0),
@@ -2386,7 +2382,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 15, 12, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!n, \
}
static struct clk_freq_tbl clk_tbl_ijpeg[] = {
F_IJPEG( 0, gnd, 1, 0, 0),
@@ -2417,6 +2412,7 @@
.md_reg = IJPEG_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(23, 16) | BM(15, 12) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_ijpeg,
@@ -2479,7 +2475,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MND_BANKED8(22, 14, n, m, 3, 0, s##_to_mm_mux), \
.ctl_val = CC_BANKED(9, 6, n), \
- .mnd_en_mask = (BIT(8) | BIT(5)) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_mdp[] = {
F_MDP( 0, gnd, 0, 0),
@@ -2585,7 +2580,6 @@
.md_val = MD16(m, n), \
.ns_val = NS_MM(31, 16, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_pixel_mdp[] = {
F_PIXEL_MDP( 0, gnd, 1, 0, 0),
@@ -2618,6 +2612,7 @@
},
.root_en_mask = BIT(2),
.ns_mask = (BM(31, 16) | BM(15, 14) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_pixel_mdp,
@@ -2713,7 +2708,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 15, 14, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
.extra_freq_data = p_r, \
}
/* Switching TV freqs requires PLL reconfiguration. */
@@ -2745,6 +2739,7 @@
.md_reg = TV_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(23, 16) | BM(15, 14) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_tv,
.freq_tbl = clk_tbl_tv,
@@ -2846,7 +2841,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(18, 11, n, m, 0, 0, 1, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_vcodec[] = {
F_VCODEC( 0, gnd, 0, 0),
@@ -2876,6 +2870,7 @@
.md_reg = VCODEC_MD0_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(18, 11) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_vcodec,
@@ -2944,7 +2939,6 @@
.md_val = MD8(8, m, 0, n), \
.ns_val = NS_MM(23, 16, n, m, 11, 10, d, 2, 0, s##_to_mm_mux), \
.ctl_val = CC(6, n), \
- .mnd_en_mask = BIT(5) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_vfe[] = {
F_VFE( 0, gnd, 1, 0, 0),
@@ -2982,6 +2976,7 @@
.md_reg = VFE_MD_REG,
.root_en_mask = BIT(2),
.ns_mask = (BM(23, 16) | BM(11, 10) | BM(2, 0)),
+ .mnd_en_mask = BIT(5),
.ctl_mask = BM(7, 6),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_vfe,
@@ -3039,7 +3034,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(8, m, 0, n), \
.ns_val = NS(31, 24, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_aif_osr[] = {
F_AIF_OSR( 0, gnd, 1, 0, 0),
@@ -3071,6 +3065,7 @@
.md_reg = md, \
.root_en_mask = BIT(9), \
.ns_mask = (BM(31, 24) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_aif_osr, \
.current_freq = &rcg_dummy_freq, \
@@ -3131,7 +3126,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_pcm[] = {
F_PCM( 0, gnd, 1, 0, 0),
@@ -3163,6 +3157,7 @@
.md_reg = LCC_PCM_MD_REG,
.root_en_mask = BIT(9),
.ns_mask = (BM(31, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_pcm,
.current_freq = &rcg_dummy_freq,
@@ -3900,11 +3895,6 @@
}
vote_vdd_level(&vdd_dig, VDD_DIG_HIGH);
- /* Copy gfx2d's frequency table because it's modified by both clocks */
- gfx2d1_clk.freq_tbl = kmemdup(clk_tbl_gfx2d,
- sizeof(struct clk_freq_tbl) * ARRAY_SIZE(clk_tbl_gfx2d),
- GFP_KERNEL);
-
/* Initialize clock registers. */
reg_init();
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 0bdacec..df9c152 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -223,14 +223,13 @@
static struct clk_ops clk_ops_cxo = {
.enable = cxo_clk_enable,
.disable = cxo_clk_disable,
- .get_rate = fixed_clk_get_rate,
.is_local = local_clk_is_local,
};
static struct fixed_clk cxo_clk = {
- .rate = 19200000,
.c = {
.dbg_name = "cxo_clk",
+ .rate = 19200000,
.ops = &clk_ops_cxo,
CLK_INIT(cxo_clk.c),
},
@@ -274,7 +273,6 @@
.disable = pll_acpu_vote_clk_disable,
.auto_off = pll_acpu_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
- .get_rate = pll_vote_clk_get_rate,
.get_parent = pll_vote_clk_get_parent,
.is_local = local_clk_is_local,
};
@@ -285,7 +283,6 @@
static unsigned int soft_vote_pll0;
static struct pll_vote_clk pll0_clk = {
- .rate = 276000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(0),
.status_reg = BB_PLL0_STATUS_REG,
@@ -294,13 +291,13 @@
.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
.c = {
.dbg_name = "pll0_clk",
+ .rate = 276000000,
.ops = &clk_ops_pll_acpu_vote,
CLK_INIT(pll0_clk.c),
},
};
static struct pll_vote_clk pll0_acpu_clk = {
- .rate = 276000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(0),
.status_reg = BB_PLL0_STATUS_REG,
@@ -308,19 +305,20 @@
.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
.c = {
.dbg_name = "pll0_acpu_clk",
+ .rate = 276000000,
.ops = &clk_ops_pll_acpu_vote,
CLK_INIT(pll0_acpu_clk.c),
},
};
static struct pll_vote_clk pll4_clk = {
- .rate = 393216000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(4),
.status_reg = LCC_PLL0_STATUS_REG,
.parent = &cxo_clk.c,
.c = {
.dbg_name = "pll4_clk",
+ .rate = 393216000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll4_clk.c),
},
@@ -329,7 +327,6 @@
static unsigned int soft_vote_pll8;
static struct pll_vote_clk pll8_clk = {
- .rate = 384000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
@@ -338,13 +335,13 @@
.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
.c = {
.dbg_name = "pll8_clk",
+ .rate = 384000000,
.ops = &clk_ops_pll_acpu_vote,
CLK_INIT(pll8_clk.c),
},
};
static struct pll_vote_clk pll8_acpu_clk = {
- .rate = 384000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(8),
.status_reg = BB_PLL8_STATUS_REG,
@@ -352,29 +349,30 @@
.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
.c = {
.dbg_name = "pll8_acpu_clk",
+ .rate = 384000000,
.ops = &clk_ops_pll_acpu_vote,
CLK_INIT(pll8_acpu_clk.c),
},
};
static struct pll_clk pll9_acpu_clk = {
- .rate = 440000000,
.mode_reg = SC_PLL0_MODE_REG,
.c = {
.dbg_name = "pll9_acpu_clk",
+ .rate = 440000000,
.ops = &clk_ops_pll,
CLK_INIT(pll9_acpu_clk.c),
},
};
static struct pll_vote_clk pll14_clk = {
- .rate = 480000000,
.en_reg = BB_PLL_ENA_SC0_REG,
.en_mask = BIT(11),
.status_reg = BB_PLL14_STATUS_REG,
.parent = &cxo_clk.c,
.c = {
.dbg_name = "pll14_clk",
+ .rate = 480000000,
.ops = &clk_ops_pll_vote,
CLK_INIT(pll14_clk.c),
},
@@ -428,6 +426,7 @@
.md_reg = GPn_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gp, \
.current_freq = &rcg_dummy_freq, \
@@ -444,7 +443,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gp[] = {
F_GP( 0, gnd, 1, 0, 0),
@@ -471,6 +469,7 @@
.md_reg = GSBIn_UART_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(31, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_uart, \
.current_freq = &rcg_dummy_freq, \
@@ -487,7 +486,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_uart[] = {
F_GSBI_UART( 0, gnd, 1, 0, 0),
@@ -527,6 +525,7 @@
.md_reg = GSBIn_QUP_APPS_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_gsbi_qup, \
.current_freq = &rcg_dummy_freq, \
@@ -543,7 +542,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_gsbi_qup[] = {
F_GSBI_QUP( 0, gnd, 1, 0, 0),
@@ -658,6 +656,7 @@
.md_reg = SDCn_APPS_CLK_MD_REG(n), \
.root_en_mask = BIT(11), \
.ns_mask = (BM(23, 16) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = f_table, \
.current_freq = &rcg_dummy_freq, \
@@ -674,7 +673,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_sdc1_2[] = {
F_SDC( 0, gnd, 1, 0, 0),
@@ -697,7 +695,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(16, m, 0, n), \
.ns_val = NS(23, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_bb_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_usb[] = {
F_USB( 0, gnd, 1, 0, 0),
@@ -724,6 +721,7 @@
.md_reg = USB_HS1_XCVR_FS_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb,
.current_freq = &rcg_dummy_freq,
@@ -748,6 +746,7 @@
.md_reg = USB_HS1_SYS_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb,
.current_freq = &rcg_dummy_freq,
@@ -772,6 +771,7 @@
.md_reg = USB_HSIC_XCVR_FS_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb,
.current_freq = &rcg_dummy_freq,
@@ -796,6 +796,7 @@
.md_reg = USB_HSIC_SYSTEM_CLK_MD_REG,
.root_en_mask = BIT(11),
.ns_mask = (BM(23, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_usb_hsic_sys,
.current_freq = &rcg_dummy_freq,
@@ -1129,7 +1130,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD8(8, m, 0, n), \
.ns_val = NS(31, 24, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_aif_osr[] = {
F_AIF_OSR( 0, gnd, 1, 0, 0),
@@ -1162,6 +1162,7 @@
.md_reg = md, \
.root_en_mask = BIT(9), \
.ns_mask = (BM(31, 24) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_aif_osr, \
.current_freq = &rcg_dummy_freq, \
@@ -1186,6 +1187,7 @@
.md_reg = md, \
.root_en_mask = BIT(9), \
.ns_mask = (BM(31, 24) | BM(6, 0)), \
+ .mnd_en_mask = BIT(8), \
.set_rate = set_rate_mnd, \
.freq_tbl = clk_tbl_aif_osr, \
.current_freq = &rcg_dummy_freq, \
@@ -1264,7 +1266,6 @@
.src_clk = &s##_clk.c, \
.md_val = MD16(m, n), \
.ns_val = NS(31, 16, n, m, 5, 4, 3, d, 2, 0, s##_to_lpa_mux), \
- .mnd_en_mask = BIT(8) * !!(n), \
}
static struct clk_freq_tbl clk_tbl_pcm[] = {
F_PCM( 0, gnd, 1, 0, 0),
@@ -1296,6 +1297,7 @@
.md_reg = LCC_PCM_MD_REG,
.root_en_mask = BIT(9),
.ns_mask = (BM(31, 16) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_pcm,
.current_freq = &rcg_dummy_freq,
@@ -1321,6 +1323,7 @@
.md_reg = LCC_SLIMBUS_MD_REG,
.root_en_mask = BIT(9),
.ns_mask = (BM(31, 24) | BM(6, 0)),
+ .mnd_en_mask = BIT(8),
.set_rate = set_rate_mnd,
.freq_tbl = clk_tbl_aif_osr,
.current_freq = &rcg_dummy_freq,
@@ -1689,21 +1692,29 @@
CLK_LOOKUP("iface_clk", pmic_arb1_p_clk.c, ""),
CLK_LOOKUP("core_clk", pmic_ssbi2_clk.c, ""),
CLK_LOOKUP("mem_clk", rpm_msg_ram_p_clk.c, ""),
- CLK_LOOKUP("mi2s_bit_clk", mi2s_bit_clk.c, NULL),
- CLK_LOOKUP("mi2s_osr_clk", mi2s_osr_clk.c, NULL),
+ CLK_LOOKUP("bit_clk", mi2s_bit_clk.c, "msm-dai-q6.6"),
+ CLK_LOOKUP("osr_clk", mi2s_osr_clk.c, "msm-dai-q6.6"),
- CLK_LOOKUP("i2s_mic_bit_clk", codec_i2s_mic_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_osr_clk", codec_i2s_mic_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_bit_clk", spare_i2s_mic_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_mic_osr_clk", spare_i2s_mic_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_bit_clk", codec_i2s_spkr_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_osr_clk", codec_i2s_spkr_osr_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_bit_clk", spare_i2s_spkr_bit_clk.c, NULL),
- CLK_LOOKUP("i2s_spkr_osr_clk", spare_i2s_spkr_osr_clk.c, NULL),
- CLK_LOOKUP("pcm_clk", pcm_clk.c, NULL),
+ CLK_LOOKUP("bit_clk", codec_i2s_mic_bit_clk.c,
+ "msm-dai-q6.1"),
+ CLK_LOOKUP("osr_clk", codec_i2s_mic_osr_clk.c,
+ "msm-dai-q6.1"),
+ CLK_LOOKUP("bit_clk", spare_i2s_mic_bit_clk.c,
+ "msm-dai-q6.5"),
+ CLK_LOOKUP("osr_clk", spare_i2s_mic_osr_clk.c,
+ "msm-dai-q6.5"),
+ CLK_LOOKUP("bit_clk", codec_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.16384"),
+ CLK_LOOKUP("osr_clk", codec_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.16384"),
+ CLK_LOOKUP("bit_clk", spare_i2s_spkr_bit_clk.c,
+ "msm-dai-q6.4"),
+ CLK_LOOKUP("osr_clk", spare_i2s_spkr_osr_clk.c,
+ "msm-dai-q6.4"),
+ CLK_LOOKUP("pcm_clk", pcm_clk.c, "msm-dai-q6.2"),
CLK_LOOKUP("sps_slimbus_clk", sps_slimbus_clk.c, NULL),
- CLK_LOOKUP("audio_slimbus_clk", audio_slimbus_clk.c, NULL),
+ CLK_LOOKUP("core_clk", audio_slimbus_clk.c, "msm_slim_ctrl.1"),
CLK_LOOKUP("core_clk", dfab_usb_hs_clk.c, "msm_otg"),
CLK_LOOKUP("bus_clk", dfab_sdc1_clk.c, "msm_sdcc.1"),
CLK_LOOKUP("bus_clk", dfab_sdc2_clk.c, "msm_sdcc.2"),
@@ -1821,7 +1832,7 @@
pll9_lval = readl_relaxed(SC_PLL0_L_VAL_REG);
if (pll9_lval == 0x1C)
- pll9_acpu_clk.rate = 550000000;
+ pll9_acpu_clk.c.rate = 550000000;
/* Enable PLL4 source on the LPASS Primary PLL Mux */
regval = readl_relaxed(LCC_PRI_PLL_CLK_CTL_REG);
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index c02c6f3..4f68fb4 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -192,13 +192,8 @@
writel_relaxed(ns_reg_val, clk->ns_reg);
}
- /*
- * If this freq requires the MN counter to be enabled,
- * update the enable mask to match the current bank.
- */
- if (nf->mnd_en_mask)
- nf->mnd_en_mask = new_bank_masks->mnd_en_mask;
- /* Update the NS mask to match the current bank. */
+ /* Update the MND_EN and NS masks to match the current bank. */
+ clk->mnd_en_mask = new_bank_masks->mnd_en_mask;
clk->ns_mask = new_bank_masks->ns_mask;
}
@@ -343,8 +338,8 @@
/* Enable MN counter, if applicable. */
reg_val = readl_relaxed(reg);
- if (clk->current_freq->mnd_en_mask) {
- reg_val |= clk->current_freq->mnd_en_mask;
+ if (clk->current_freq->md_val) {
+ reg_val |= clk->mnd_en_mask;
writel_relaxed(reg_val, reg);
}
/* Enable root. */
@@ -408,8 +403,8 @@
writel_relaxed(reg_val, reg);
}
/* Disable MN counter, if applicable. */
- if (clk->current_freq->mnd_en_mask) {
- reg_val &= ~(clk->current_freq->mnd_en_mask);
+ if (clk->current_freq->md_val) {
+ reg_val &= ~(clk->mnd_en_mask);
writel_relaxed(reg_val, reg);
}
/*
@@ -641,7 +636,7 @@
ns_val = readl_relaxed(clk->ns_reg) & ns_mask;
for (freq = clk->freq_tbl; freq->freq_hz != FREQ_END; freq++) {
if ((freq->ns_val & ns_mask) == ns_val &&
- (!freq->mnd_en_mask || freq->md_val == md_val)) {
+ (!freq->md_val || freq->md_val == md_val)) {
pr_info("%s rate=%d\n", clk->c.dbg_name, freq->freq_hz);
break;
}
@@ -686,12 +681,6 @@
spin_unlock_irqrestore(&local_clock_reg_lock, flags);
}
-unsigned long pll_vote_clk_get_rate(struct clk *clk)
-{
- struct pll_vote_clk *pll = to_pll_vote_clk(clk);
- return pll->rate;
-}
-
struct clk *pll_vote_clk_get_parent(struct clk *clk)
{
struct pll_vote_clk *pll = to_pll_vote_clk(clk);
@@ -709,7 +698,6 @@
.disable = pll_vote_clk_disable,
.auto_off = pll_vote_clk_disable,
.is_enabled = pll_vote_clk_is_enabled,
- .get_rate = pll_vote_clk_get_rate,
.get_parent = pll_vote_clk_get_parent,
.is_local = local_clk_is_local,
};
@@ -766,12 +754,6 @@
spin_unlock_irqrestore(&local_clock_reg_lock, flags);
}
-static unsigned long pll_clk_get_rate(struct clk *clk)
-{
- struct pll_clk *pll = to_pll_clk(clk);
- return pll->rate;
-}
-
static struct clk *pll_clk_get_parent(struct clk *clk)
{
struct pll_clk *pll = to_pll_clk(clk);
@@ -817,13 +799,11 @@
.enable = pll_clk_enable,
.disable = pll_clk_disable,
.auto_off = pll_clk_disable,
- .get_rate = pll_clk_get_rate,
.get_parent = pll_clk_get_parent,
.is_local = local_clk_is_local,
};
struct clk_ops clk_ops_gnd = {
- .get_rate = fixed_clk_get_rate,
.is_local = local_clk_is_local,
};
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index d312f24..c587b43 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -27,10 +27,12 @@
/* MD Registers */
#define MD4(m_lsb, m, n_lsb, n) \
- (BVAL((m_lsb+3), m_lsb, m) | BVAL((n_lsb+3), n_lsb, ~(n)))
+ ((BVAL((m_lsb+3), m_lsb, m) | BVAL((n_lsb+3), n_lsb, ~(n))) \
+ * !!(n))
#define MD8(m_lsb, m, n_lsb, n) \
- (BVAL((m_lsb+7), m_lsb, m) | BVAL((n_lsb+7), n_lsb, ~(n)))
-#define MD16(m, n) (BVAL(31, 16, m) | BVAL(15, 0, ~(n)))
+ ((BVAL((m_lsb+7), m_lsb, m) | BVAL((n_lsb+7), n_lsb, ~(n))) \
+ * !!(n))
+#define MD16(m, n) ((BVAL(31, 16, m) | BVAL(15, 0, ~(n))) * !!(n))
/* NS Registers */
#define NS(n_msb, n_lsb, n, m, mde_lsb, d_msb, d_lsb, d, s_msb, s_lsb, s) \
@@ -101,11 +103,10 @@
*/
struct clk_freq_tbl {
const uint32_t freq_hz;
- struct clk *src_clk;
+ struct clk *const src_clk;
const uint32_t md_val;
const uint32_t ns_val;
const uint32_t ctl_val;
- uint32_t mnd_en_mask;
void *const extra_freq_data;
};
@@ -126,13 +127,12 @@
const struct bank_mask_info bank1_mask;
};
-#define F_RAW(f, sc, m_v, n_v, c_v, m_m, e) { \
+#define F_RAW(f, sc, m_v, n_v, c_v, e) { \
.freq_hz = f, \
.src_clk = sc, \
.md_val = m_v, \
.ns_val = n_v, \
.ctl_val = c_v, \
- .mnd_en_mask = m_m, \
.extra_freq_data = e, \
}
#define FREQ_END (UINT_MAX-1)
@@ -185,6 +185,7 @@
const uint32_t root_en_mask;
uint32_t ns_mask;
const uint32_t ctl_mask;
+ uint32_t mnd_en_mask;
void *bank_info;
void (*set_rate)(struct rcg_clk *, struct clk_freq_tbl *);
@@ -249,29 +250,14 @@
/**
* struct fixed_clk - fixed rate clock (used for crystal oscillators)
- * @rate: output rate
* @c: clk
*/
struct fixed_clk {
- unsigned long rate;
struct clk c;
};
-static inline struct fixed_clk *to_fixed_clk(struct clk *clk)
-{
- return container_of(clk, struct fixed_clk, c);
-}
-
-static inline unsigned long fixed_clk_get_rate(struct clk *clk)
-{
- struct fixed_clk *f = to_fixed_clk(clk);
- return f->rate;
-}
-
-
/**
* struct pll_vote_clk - phase locked loop (HW voteable)
- * @rate: output rate
* @soft_vote: soft voting variable for multiple PLL software instances
* @soft_vote_mask: soft voting mask for multiple PLL software instances
* @en_reg: enable register
@@ -281,8 +267,6 @@
* @c: clk
*/
struct pll_vote_clk {
- unsigned long rate;
-
u32 *soft_vote;
const u32 soft_vote_mask;
void __iomem *const en_reg;
@@ -303,14 +287,11 @@
/**
* struct pll_clk - phase locked loop
- * @rate: output rate
* @mode_reg: enable register
* @parent: clock source
* @c: clk
*/
struct pll_clk {
- unsigned long rate;
-
void __iomem *const mode_reg;
struct clk *parent;
@@ -394,7 +375,6 @@
*/
int pll_vote_clk_enable(struct clk *clk);
void pll_vote_clk_disable(struct clk *clk);
-unsigned long pll_vote_clk_get_rate(struct clk *clk);
struct clk *pll_vote_clk_get_parent(struct clk *clk);
int pll_vote_clk_is_enabled(struct clk *clk);
diff --git a/arch/arm/mach-msm/clock-rpm.c b/arch/arm/mach-msm/clock-rpm.c
index 4757f7d..fc2e83f 100644
--- a/arch/arm/mach-msm/clock-rpm.c
+++ b/arch/arm/mach-msm/clock-rpm.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,9 +23,9 @@
static int rpm_clk_enable(struct clk *clk)
{
unsigned long flags;
- struct msm_rpm_iv_pair iv;
- int rc = 0;
struct rpm_clk *r = to_rpm_clk(clk);
+ struct msm_rpm_iv_pair iv = { .id = r->rpm_clk_id };
+ int rc = 0;
unsigned long this_khz, this_sleep_khz;
unsigned long peer_khz = 0, peer_sleep_khz = 0;
struct rpm_clk *peer = r->peer;
@@ -39,8 +39,6 @@
this_sleep_khz = r->last_set_sleep_khz;
- iv.id = r->rpm_clk_id;
-
/* Take peer clock's rate into account only if it's enabled. */
if (peer->enabled) {
peer_khz = peer->last_set_khz;
@@ -48,11 +46,16 @@
}
iv.value = max(this_khz, peer_khz);
+ if (r->branch)
+ iv.value = !!iv.value;
+
rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
if (rc)
goto out;
iv.value = max(this_sleep_khz, peer_sleep_khz);
+ if (r->branch)
+ iv.value = !!iv.value;
rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
if (rc) {
iv.value = peer_khz;
@@ -76,25 +79,23 @@
spin_lock_irqsave(&rpm_clock_lock, flags);
if (r->last_set_khz) {
- struct msm_rpm_iv_pair iv;
+ struct msm_rpm_iv_pair iv = { .id = r->rpm_clk_id };
struct rpm_clk *peer = r->peer;
unsigned long peer_khz = 0, peer_sleep_khz = 0;
int rc;
- iv.id = r->rpm_clk_id;
-
/* Take peer clock's rate into account only if it's enabled. */
if (peer->enabled) {
peer_khz = peer->last_set_khz;
peer_sleep_khz = peer->last_set_sleep_khz;
}
- iv.value = peer_khz;
+ iv.value = r->branch ? !!peer_khz : peer_khz;
rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_0, &iv, 1);
if (rc)
goto out;
- iv.value = peer_sleep_khz;
+ iv.value = r->branch ? !!peer_sleep_khz : peer_sleep_khz;
rc = msm_rpmrs_set_noirq(MSM_RPM_CTX_SET_SLEEP, &iv, 1);
}
r->enabled = false;
@@ -186,6 +187,12 @@
return false;
}
+static unsigned long rpm_branch_clk_get_rate(struct clk *clk)
+{
+ struct rpm_clk *r = to_rpm_clk(clk);
+ return r->last_set_khz * 1000;
+}
+
struct clk_ops clk_ops_rpm = {
.enable = rpm_clk_enable,
.disable = rpm_clk_disable,
@@ -195,3 +202,10 @@
.round_rate = rpm_clk_round_rate,
.is_local = rpm_clk_is_local,
};
+
+struct clk_ops clk_ops_rpm_branch = {
+ .enable = rpm_clk_enable,
+ .disable = rpm_clk_disable,
+ .is_local = rpm_clk_is_local,
+ .get_rate = rpm_branch_clk_get_rate,
+};
diff --git a/arch/arm/mach-msm/clock-rpm.h b/arch/arm/mach-msm/clock-rpm.h
index 24df9b6..27afd6f 100644
--- a/arch/arm/mach-msm/clock-rpm.h
+++ b/arch/arm/mach-msm/clock-rpm.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -18,6 +18,7 @@
struct clk_ops;
extern struct clk_ops clk_ops_rpm;
+extern struct clk_ops clk_ops_rpm_branch;
struct rpm_clk {
const int rpm_clk_id;
@@ -27,6 +28,7 @@
/* 0 if active_only. Otherwise, same as last_set_khz. */
unsigned last_set_sleep_khz;
bool enabled;
+ bool branch; /* true: RPM only accepts 1 for ON and 0 for OFF */
struct rpm_clk *peer;
struct clk c;
@@ -65,4 +67,35 @@
}, \
};
+#define DEFINE_CLK_RPM_BRANCH(name, active, r_id, rate) \
+ static struct rpm_clk active; \
+ static struct rpm_clk name = { \
+ .rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
+ .rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
+ .peer = &active, \
+ .last_set_khz = ((rate) / 1000), \
+ .last_set_sleep_khz = ((rate) / 1000), \
+ .branch = true, \
+ .c = { \
+ .ops = &clk_ops_rpm_branch, \
+ .flags = CLKFLAG_SKIP_AUTO_OFF, \
+ .dbg_name = #name, \
+ CLK_INIT(name.c), \
+ }, \
+ }; \
+ static struct rpm_clk active = { \
+ .rpm_clk_id = MSM_RPM_ID_##r_id##_CLK, \
+ .rpm_status_id = MSM_RPM_STATUS_ID_##r_id##_CLK, \
+ .peer = &name, \
+ .last_set_khz = ((rate) / 1000), \
+ .active_only = true, \
+ .branch = true, \
+ .c = { \
+ .ops = &clk_ops_rpm_branch, \
+ .flags = CLKFLAG_SKIP_AUTO_OFF, \
+ .dbg_name = #active, \
+ CLK_INIT(active.c), \
+ }, \
+ };
+
#endif
diff --git a/arch/arm/mach-msm/clock.c b/arch/arm/mach-msm/clock.c
index 57fd749..5b89fa9 100644
--- a/arch/arm/mach-msm/clock.c
+++ b/arch/arm/mach-msm/clock.c
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/clock.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2007-2012, Code Aurora Forum. 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
@@ -222,7 +222,7 @@
unsigned long clk_get_rate(struct clk *clk)
{
if (!clk->ops->get_rate)
- return 0;
+ return clk->rate;
return clk->ops->get_rate(clk);
}
diff --git a/arch/arm/mach-msm/cp14.h b/arch/arm/mach-msm/cp14.h
index 9f7241e..d640412 100644
--- a/arch/arm/mach-msm/cp14.h
+++ b/arch/arm/mach-msm/cp14.h
@@ -325,21 +325,21 @@
#define RCP14_ETMACTR14() MRC14(1, c0, c14, 2)
#define RCP14_ETMACTR15() MRC14(1, c0, c15, 2)
#define RCP14_ETMDCVR0() MRC14(1, c0, c0, 3)
-#define RCP14_ETMDCVR1() MRC14(1, c0, c1, 3)
#define RCP14_ETMDCVR2() MRC14(1, c0, c2, 3)
-#define RCP14_ETMDCVR3() MRC14(1, c0, c3, 3)
#define RCP14_ETMDCVR4() MRC14(1, c0, c4, 3)
-#define RCP14_ETMDCVR5() MRC14(1, c0, c5, 3)
#define RCP14_ETMDCVR6() MRC14(1, c0, c6, 3)
-#define RCP14_ETMDCVR7() MRC14(1, c0, c7, 3)
+#define RCP14_ETMDCVR8() MRC14(1, c0, c8, 3)
+#define RCP14_ETMDCVR10() MRC14(1, c0, c10, 3)
+#define RCP14_ETMDCVR12() MRC14(1, c0, c12, 3)
+#define RCP14_ETMDCVR14() MRC14(1, c0, c14, 3)
#define RCP14_ETMDCMR0() MRC14(1, c0, c0, 4)
-#define RCP14_ETMDCMR1() MRC14(1, c0, c1, 4)
#define RCP14_ETMDCMR2() MRC14(1, c0, c2, 4)
-#define RCP14_ETMDCMR3() MRC14(1, c0, c3, 4)
#define RCP14_ETMDCMR4() MRC14(1, c0, c4, 4)
-#define RCP14_ETMDCMR5() MRC14(1, c0, c5, 4)
#define RCP14_ETMDCMR6() MRC14(1, c0, c6, 4)
-#define RCP14_ETMDCMR7() MRC14(1, c0, c7, 4)
+#define RCP14_ETMDCMR8() MRC14(1, c0, c8, 4)
+#define RCP14_ETMDCMR10() MRC14(1, c0, c10, 4)
+#define RCP14_ETMDCMR12() MRC14(1, c0, c12, 4)
+#define RCP14_ETMDCMR14() MRC14(1, c0, c14, 4)
#define RCP14_ETMCNTRLDVR0() MRC14(1, c0, c0, 5)
#define RCP14_ETMCNTRLDVR1() MRC14(1, c0, c1, 5)
#define RCP14_ETMCNTRLDVR2() MRC14(1, c0, c2, 5)
@@ -389,7 +389,7 @@
#define RCP14_ETMAUXCR() MRC14(1, c0, c15, 7)
#define RCP14_ETMTRACEIDR() MRC14(1, c1, c0, 0)
#define RCP14_ETMIDR2() MRC14(1, c1, c2, 0)
-#define RCP14_ETMVMIDCVR() MRC14(1, c1, c1, 0)
+#define RCP14_ETMVMIDCVR() MRC14(1, c1, c0, 1)
#define RCP14_ETMOSLSR() MRC14(1, c1, c1, 4)
/* not available in PFTv1.1 */
#define RCP14_ETMOSSRR() MRC14(1, c1, c2, 4)
@@ -462,21 +462,21 @@
#define WCP14_ETMACTR14(val) MCR14(val, 1, c0, c14, 2)
#define WCP14_ETMACTR15(val) MCR14(val, 1, c0, c15, 2)
#define WCP14_ETMDCVR0(val) MCR14(val, 1, c0, c0, 3)
-#define WCP14_ETMDCVR1(val) MCR14(val, 1, c0, c1, 3)
#define WCP14_ETMDCVR2(val) MCR14(val, 1, c0, c2, 3)
-#define WCP14_ETMDCVR3(val) MCR14(val, 1, c0, c3, 3)
#define WCP14_ETMDCVR4(val) MCR14(val, 1, c0, c4, 3)
-#define WCP14_ETMDCVR5(val) MCR14(val, 1, c0, c5, 3)
#define WCP14_ETMDCVR6(val) MCR14(val, 1, c0, c6, 3)
-#define WCP14_ETMDCVR7(val) MCR14(val, 1, c0, c7, 3)
+#define WCP14_ETMDCVR8(val) MCR14(val, 1, c0, c8, 3)
+#define WCP14_ETMDCVR10(val) MCR14(val, 1, c0, c10, 3)
+#define WCP14_ETMDCVR12(val) MCR14(val, 1, c0, c12, 3)
+#define WCP14_ETMDCVR14(val) MCR14(val, 1, c0, c14, 3)
#define WCP14_ETMDCMR0(val) MCR14(val, 1, c0, c0, 4)
-#define WCP14_ETMDCMR1(val) MCR14(val, 1, c0, c1, 4)
#define WCP14_ETMDCMR2(val) MCR14(val, 1, c0, c2, 4)
-#define WCP14_ETMDCMR3(val) MCR14(val, 1, c0, c3, 4)
#define WCP14_ETMDCMR4(val) MCR14(val, 1, c0, c4, 4)
-#define WCP14_ETMDCMR5(val) MCR14(val, 1, c0, c5, 4)
#define WCP14_ETMDCMR6(val) MCR14(val, 1, c0, c6, 4)
-#define WCP14_ETMDCMR7(val) MCR14(val, 1, c0, c7, 4)
+#define WCP14_ETMDCMR8(val) MCR14(val, 1, c0, c8, 4)
+#define WCP14_ETMDCMR10(val) MCR14(val, 1, c0, c10, 4)
+#define WCP14_ETMDCMR12(val) MCR14(val, 1, c0, c12, 4)
+#define WCP14_ETMDCMR14(val) MCR14(val, 1, c0, c14, 4)
#define WCP14_ETMCNTRLDVR0(val) MCR14(val, 1, c0, c0, 5)
#define WCP14_ETMCNTRLDVR1(val) MCR14(val, 1, c0, c1, 5)
#define WCP14_ETMCNTRLDVR2(val) MCR14(val, 1, c0, c2, 5)
@@ -525,7 +525,7 @@
#define WCP14_ETMAUXCR(val) MCR14(val, 1, c0, c15, 7)
#define WCP14_ETMTRACEIDR(val) MCR14(val, 1, c1, c0, 0)
#define WCP14_ETMIDR2(val) MCR14(val, 1, c1, c2, 0)
-#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c1, 0)
+#define WCP14_ETMVMIDCVR(val) MCR14(val, 1, c1, c0, 1)
#define WCP14_ETMOSLAR(val) MCR14(val, 1, c1, c0, 4)
/* not available in PFTv1.1 */
#define WCP14_ETMOSSRR(val) MCR14(val, 1, c1, c2, 4)
diff --git a/arch/arm/mach-msm/devices-8064.c b/arch/arm/mach-msm/devices-8064.c
index 9328143..6b79fab 100644
--- a/arch/arm/mach-msm/devices-8064.c
+++ b/arch/arm/mach-msm/devices-8064.c
@@ -50,6 +50,7 @@
#define MSM_UART7DM_PHYS (MSM_GSBI7_PHYS + 0x40000)
/* GSBI QUP devices */
+#define MSM_GSBI1_QUP_PHYS (MSM_GSBI1_PHYS + 0x20000)
#define MSM_GSBI3_QUP_PHYS (MSM_GSBI3_PHYS + 0x80000)
#define MSM_GSBI4_QUP_PHYS (MSM_GSBI4_PHYS + 0x80000)
#define MSM_GSBI5_QUP_PHYS (MSM_GSBI5_PHYS + 0x80000)
@@ -195,6 +196,46 @@
},
};
+static struct resource resources_qup_i2c_gsbi1[] = {
+ {
+ .name = "gsbi_qup_i2c_addr",
+ .start = MSM_GSBI1_PHYS,
+ .end = MSM_GSBI1_PHYS + 4 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "qup_phys_addr",
+ .start = MSM_GSBI1_QUP_PHYS,
+ .end = MSM_GSBI1_QUP_PHYS + MSM_QUP_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "qup_err_intr",
+ .start = APQ8064_GSBI1_QUP_IRQ,
+ .end = APQ8064_GSBI1_QUP_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .name = "i2c_clk",
+ .start = 21,
+ .end = 21,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "i2c_sda",
+ .start = 20,
+ .end = 20,
+ .flags = IORESOURCE_IO,
+ },
+};
+
+struct platform_device apq8064_device_qup_i2c_gsbi1 = {
+ .name = "qup_i2c",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(resources_qup_i2c_gsbi1),
+ .resource = resources_qup_i2c_gsbi1,
+};
+
struct platform_device apq8064_device_qup_i2c_gsbi3 = {
.name = "qup_i2c",
.id = 3,
@@ -221,6 +262,18 @@
.end = GSBI4_QUP_IRQ,
.flags = IORESOURCE_IRQ,
},
+ {
+ .name = "i2c_clk",
+ .start = 11,
+ .end = 11,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "i2c_sda",
+ .start = 10,
+ .end = 10,
+ .flags = IORESOURCE_IO,
+ },
};
struct platform_device apq8064_device_qup_i2c_gsbi4 = {
@@ -306,7 +359,7 @@
};
struct platform_device apq_cpudai_hdmi_rx = {
- .name = "msm-dai-q6",
+ .name = "msm-dai-q6-hdmi",
.id = 8,
};
@@ -413,6 +466,11 @@
.id = -1,
};
+struct platform_device apq_cpudai_stub = {
+ .name = "msm-dai-stub",
+ .id = -1,
+};
+
static struct resource resources_ssbi_pmic1[] = {
{
.start = MSM_PMIC1_SSBI_CMD_PHYS,
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 4525bab..4d4b88f 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -1134,27 +1134,27 @@
};
#ifdef CONFIG_MSM_CAMERA
-struct resource msm_camera_resources[] = {
+static struct resource msm_cam_gsbi4_i2c_mux_resources[] = {
{
- .name = "s3d_rw",
+ .name = "i2c_mux_rw",
.start = 0x008003E0,
- .end = 0x008003E0 + SZ_16 - 1,
+ .end = 0x008003E0 + SZ_8 - 1,
.flags = IORESOURCE_MEM,
},
{
- .name = "s3d_ctl",
+ .name = "i2c_mux_ctl",
.start = 0x008020B8,
- .end = 0x008020B8 + SZ_16 - 1,
+ .end = 0x008020B8 + SZ_4 - 1,
.flags = IORESOURCE_MEM,
},
};
-int __init msm_get_cam_resources(struct msm_camera_sensor_info *s_info)
-{
- s_info->resource = msm_camera_resources;
- s_info->num_resources = ARRAY_SIZE(msm_camera_resources);
- return 0;
-}
+struct platform_device msm8960_device_i2c_mux_gsbi4 = {
+ .name = "msm_cam_i2c_mux",
+ .id = 0,
+ .resource = msm_cam_gsbi4_i2c_mux_resources,
+ .num_resources = ARRAY_SIZE(msm_cam_gsbi4_i2c_mux_resources),
+};
static struct resource msm_csiphy0_resources[] = {
{
@@ -1186,6 +1186,21 @@
},
};
+static struct resource msm_csiphy2_resources[] = {
+ {
+ .name = "csiphy",
+ .start = 0x04801400,
+ .end = 0x04801400 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "csiphy",
+ .start = MSM8960_CSIPHY_2_2LN_IRQ,
+ .end = MSM8960_CSIPHY_2_2LN_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
struct platform_device msm8960_device_csiphy0 = {
.name = "msm_csiphy",
.id = 0,
@@ -1200,6 +1215,13 @@
.num_resources = ARRAY_SIZE(msm_csiphy1_resources),
};
+struct platform_device msm8960_device_csiphy2 = {
+ .name = "msm_csiphy",
+ .id = 2,
+ .resource = msm_csiphy2_resources,
+ .num_resources = ARRAY_SIZE(msm_csiphy2_resources),
+};
+
static struct resource msm_csid0_resources[] = {
{
.name = "csid",
@@ -1230,6 +1252,21 @@
},
};
+static struct resource msm_csid2_resources[] = {
+ {
+ .name = "csid",
+ .start = 0x04801800,
+ .end = 0x04801800 + SZ_1K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "csid",
+ .start = CSI_2_IRQ,
+ .end = CSI_2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
struct platform_device msm8960_device_csid0 = {
.name = "msm_csid",
.id = 0,
@@ -1244,6 +1281,13 @@
.num_resources = ARRAY_SIZE(msm_csid1_resources),
};
+struct platform_device msm8960_device_csid2 = {
+ .name = "msm_csid",
+ .id = 2,
+ .resource = msm_csid2_resources,
+ .num_resources = ARRAY_SIZE(msm_csid2_resources),
+};
+
struct resource msm_ispif_resources[] = {
{
.name = "ispif",
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 3944a93..18acb36 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -234,6 +234,30 @@
},
};
+static struct resource resources_hsic_host[] = {
+ {
+ .start = MSM9615_HSIC_PHYS,
+ .end = MSM9615_HSIC_PHYS + MSM9615_HSIC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = USB_HSIC_IRQ,
+ .end = USB_HSIC_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device msm_device_hsic_host = {
+ .name = "msm_hsic_host",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(resources_hsic_host),
+ .resource = resources_hsic_host,
+ .dev = {
+ .dma_mask = &dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
static struct resource resources_uart_gsbi4[] = {
{
.start = GSBI4_UARTDM_IRQ,
@@ -419,7 +443,7 @@
};
static struct tsens_platform_data msm_tsens_pdata = {
- .slope = 910,
+ .slope = {872, 872, 872, 872, 872},
.tsens_factor = 1000,
.hw_type = MSM_9615,
.tsens_num_sensor = 5,
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
index 31eee43..15d4ae6 100644
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -866,6 +866,35 @@
.resource = gsbi0_msm8625_qup_resources,
};
+static struct resource gsbi1_msm8625_qup_i2c_resources[] = {
+ {
+ .name = "qup_phys_addr",
+ .start = MSM_GSBI1_QUP_PHYS,
+ .end = MSM_GSBI1_QUP_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "gsbi_qup_i2c_addr",
+ .start = MSM_GSBI1_PHYS,
+ .end = MSM_GSBI1_PHYS + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "qup_err_intr",
+ .start = MSM8625_INT_ARM11_DMA,
+ .end = MSM8625_INT_ARM11_DMA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Use GSBI1 QUP for /dev/i2c-1 */
+struct platform_device msm8625_device_qup_i2c_gsbi1 = {
+ .name = "qup_i2c",
+ .id = MSM_GSBI1_QUP_I2C_BUS_ID,
+ .num_resources = ARRAY_SIZE(gsbi1_qup_i2c_resources),
+ .resource = gsbi1_msm8625_qup_i2c_resources,
+};
+
static struct resource msm8625_gpio_resources[] = {
{
.start = MSM8625_INT_GPIO_GROUP1,
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index fc732da..e9b94f6 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -1181,6 +1181,7 @@
.set_grp_async = set_grp3d_async,
.idle_timeout = HZ/20,
.nap_allowed = true,
+ .idle_needed = true,
.clk_map = KGSL_CLK_SRC | KGSL_CLK_CORE |
KGSL_CLK_IFACE | KGSL_CLK_MEM,
};
@@ -1223,6 +1224,7 @@
.set_grp_async = NULL,
.idle_timeout = HZ/10,
.nap_allowed = true,
+ .idle_needed = true,
.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE,
};
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index c4f57ab..c86d051 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -59,10 +59,13 @@
extern struct platform_device msm8960_device_qup_i2c_gsbi12;
extern struct platform_device msm8960_device_qup_spi_gsbi1;
extern struct platform_device msm8960_gemini_device;
+extern struct platform_device msm8960_device_i2c_mux_gsbi4;
extern struct platform_device msm8960_device_csiphy0;
extern struct platform_device msm8960_device_csiphy1;
+extern struct platform_device msm8960_device_csiphy2;
extern struct platform_device msm8960_device_csid0;
extern struct platform_device msm8960_device_csid1;
+extern struct platform_device msm8960_device_csid2;
extern struct platform_device msm8960_device_ispif;
extern struct platform_device msm8960_device_vfe;
extern struct platform_device msm8960_device_vpe;
@@ -70,6 +73,7 @@
extern struct platform_device apq8064_device_uart_gsbi1;
extern struct platform_device apq8064_device_uart_gsbi3;
extern struct platform_device apq8064_device_uart_gsbi7;
+extern struct platform_device apq8064_device_qup_i2c_gsbi1;
extern struct platform_device apq8064_device_qup_i2c_gsbi3;
extern struct platform_device apq8064_device_qup_i2c_gsbi4;
extern struct platform_device apq8064_device_qup_spi_gsbi5;
@@ -123,6 +127,7 @@
extern struct platform_device msm_gsbi12_qup_i2c_device;
extern struct platform_device msm8625_device_qup_i2c_gsbi0;
+extern struct platform_device msm8625_device_qup_i2c_gsbi1;
extern struct platform_device msm_slim_ctrl;
extern struct platform_device msm_device_sps;
@@ -222,6 +227,7 @@
extern struct platform_device apq_cpudai_afe_02_rx;
extern struct platform_device apq_cpudai_afe_02_tx;
extern struct platform_device apq_pcm_afe;
+extern struct platform_device apq_cpudai_stub;
extern struct platform_device *msm_footswitch_devices[];
extern unsigned msm_num_footswitch_devices;
diff --git a/arch/arm/mach-msm/etm.c b/arch/arm/mach-msm/etm.c
index bee0975..9d04a58 100644
--- a/arch/arm/mach-msm/etm.c
+++ b/arch/arm/mach-msm/etm.c
@@ -377,9 +377,9 @@
etm_write(etm_config.etm_addr_access_type[6], ETMACTR6);
etm_write(etm_config.etm_addr_access_type[7], ETMACTR7);
etm_write(etm_config.etm_data_comp_value[0], ETMDCVR0);
- etm_write(etm_config.etm_data_comp_value[1], ETMDCVR1);
+ etm_write(etm_config.etm_data_comp_value[1], ETMDCVR2);
etm_write(etm_config.etm_data_comp_mask[0], ETMDCMR0);
- etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR1);
+ etm_write(etm_config.etm_data_comp_mask[1], ETMDCMR2);
etm_write(etm_config.etm_counter_reload_value[0], ETMCNTRLDVR0);
etm_write(etm_config.etm_counter_reload_value[1], ETMCNTRLDVR1);
etm_write(etm_config.etm_counter_enable[0], ETMCNTENR0);
@@ -564,9 +564,9 @@
emit_log_word(etm_read(ETMACTR6));
emit_log_word(etm_read(ETMACTR7));
emit_log_word(etm_read(ETMDCVR0));
- emit_log_word(etm_read(ETMDCVR1));
+ emit_log_word(etm_read(ETMDCVR2));
emit_log_word(etm_read(ETMDCMR0));
- emit_log_word(etm_read(ETMDCMR1));
+ emit_log_word(etm_read(ETMDCMR2));
emit_log_word(etm_read(ETMCNTRLDVR0));
emit_log_word(etm_read(ETMCNTRLDVR1));
emit_log_word(etm_read(ETMCNTENR0));
diff --git a/arch/arm/mach-msm/hotplug.c b/arch/arm/mach-msm/hotplug.c
index 26adec6..8d40908 100644
--- a/arch/arm/mach-msm/hotplug.c
+++ b/arch/arm/mach-msm/hotplug.c
@@ -10,10 +10,13 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/smp.h>
+#include <linux/cpu.h>
#include <asm/cacheflush.h>
#include <asm/vfp.h>
+#include <mach/msm_rtb.h>
+
#include "pm.h"
#include "qdss.h"
#include "spm.h"
@@ -49,6 +52,9 @@
/*
* OK, proper wakeup, we're done
*/
+ pen_release = -1;
+ dmac_flush_range((void *)&pen_release,
+ (void *)(&pen_release + sizeof(pen_release)));
break;
}
@@ -60,6 +66,8 @@
* possible, since we are currently running incoherently, and
* therefore cannot safely call printk() or anything else
*/
+ dmac_inv_range((void *)&pen_release,
+ (void *)(&pen_release + sizeof(pen_release)));
pr_debug("CPU%u: spurious wakeup call\n", cpu);
}
}
@@ -109,6 +117,45 @@
return cpu == 0 ? -EPERM : 0;
}
+#define CPU_SHIFT 0
+#define CPU_MASK 0xF
+#define CPU_OF(n) (((n) & CPU_MASK) << CPU_SHIFT)
+#define CPUSET_SHIFT 4
+#define CPUSET_MASK 0xFFFF
+#define CPUSET_OF(n) (((n) & CPUSET_MASK) << CPUSET_SHIFT)
+
+static int hotplug_rtb_callback(struct notifier_block *nfb,
+ unsigned long action, void *hcpu)
+{
+ /*
+ * Bits [19:4] of the data are the online mask, lower 4 bits are the
+ * cpu number that is being changed. Additionally, changes to the
+ * online_mask that will be done by the current hotplug will be made
+ * even though they aren't necessarily in the online mask yet.
+ *
+ * XXX: This design is limited to supporting at most 16 cpus
+ */
+ int this_cpumask = CPUSET_OF(1 << (int)hcpu);
+ int cpumask = CPUSET_OF(cpumask_bits(cpu_online_mask)[0]);
+ int cpudata = CPU_OF((int)hcpu) | cpumask;
+
+ switch (action & (~CPU_TASKS_FROZEN)) {
+ case CPU_STARTING:
+ uncached_logk(LOGK_HOTPLUG, (void *)(cpudata | this_cpumask));
+ break;
+ case CPU_DYING:
+ uncached_logk(LOGK_HOTPLUG, (void *)(cpudata & ~this_cpumask));
+ break;
+ default:
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+static struct notifier_block hotplug_rtb_notifier = {
+ .notifier_call = hotplug_rtb_callback,
+};
+
int msm_platform_secondary_init(unsigned int cpu)
{
int ret;
@@ -127,3 +174,9 @@
return ret;
}
+
+static int __init init_hotplug_notifier(void)
+{
+ return register_hotcpu_notifier(&hotplug_rtb_notifier);
+}
+early_initcall(init_hotplug_notifier);
diff --git a/arch/arm/mach-msm/idle-v7.S b/arch/arm/mach-msm/idle-v7.S
index c274899..32d162d 100644
--- a/arch/arm/mach-msm/idle-v7.S
+++ b/arch/arm/mach-msm/idle-v7.S
@@ -100,12 +100,14 @@
cmp r1, #1
bne skip
bl v7_flush_dcache_all
+ b skip2
skip: ldr r0, =saved_state
ldr r1, =saved_state_end
sub r1, r1, r0
bl v7_flush_kern_dcache_area
+skip2:
#ifdef CONFIG_ARCH_MSM_KRAIT
ldr r0, =SCM_SVC_BOOT
ldr r1, =SCM_CMD_TERMINATE_PC
@@ -136,7 +138,9 @@
#if (NR_CPUS >= 2)
mrc p15, 0, r1, c0, c0, 5 /* MPIDR */
ands r1, r1, #15 /* What CPU am I */
- addne r0, r0, #CPU_SAVED_STATE_SIZE
+ mov r2, #CPU_SAVED_STATE_SIZE
+ mul r2, r2, r1
+ add r0, r0, r2
#endif
ldmfd r0, {r4-r14}
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
index ba9fc70..96b0083 100644
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -202,6 +202,18 @@
uint8_t cam_gpio_set_tbl_size;
};
+enum msm_camera_i2c_mux_mode {
+ MODE_R,
+ MODE_L,
+ MODE_DUAL
+};
+
+struct msm_camera_i2c_conf {
+ uint8_t use_i2c_mux;
+ struct platform_device *mux_dev;
+ enum msm_camera_i2c_mux_mode i2c_mux_mode;
+};
+
struct msm_camera_sensor_platform_info {
int mount_angle;
int sensor_reset;
@@ -209,6 +221,7 @@
int num_vreg;
int32_t (*ext_power_ctrl) (int enable);
struct msm_camera_gpio_conf *gpio_conf;
+ struct msm_camera_i2c_conf *i2c_conf;
};
struct msm_actuator_info {
@@ -238,6 +251,7 @@
char *eeprom_data;
enum msm_camera_type camera_type;
struct msm_actuator_info *actuator_info;
+ int pmic_gpio_enable;
};
struct msm_camera_board_info {
diff --git a/arch/arm/mach-msm/include/mach/camera.h b/arch/arm/mach-msm/include/mach/camera.h
index 700e28c..ef7be45 100644
--- a/arch/arm/mach-msm/include/mach/camera.h
+++ b/arch/arm/mach-msm/include/mach/camera.h
@@ -631,12 +631,6 @@
S_EXIT
};
-enum msm_cam_mode {
- MODE_R,
- MODE_L,
- MODE_DUAL
-};
-
struct msm_cam_clk_info {
const char *clk_name;
long clk_rate;
@@ -648,7 +642,7 @@
int msm_camio_vpe_clk_enable(uint32_t);
int msm_camio_vpe_clk_disable(void);
-void msm_camio_mode_config(enum msm_cam_mode mode);
+void msm_camio_mode_config(enum msm_camera_i2c_mux_mode mode);
int msm_camio_clk_enable(enum msm_camio_clk_type clk);
int msm_camio_clk_disable(enum msm_camio_clk_type clk);
int msm_camio_clk_config(uint32_t freq);
diff --git a/arch/arm/mach-msm/include/mach/iommu_domains.h b/arch/arm/mach-msm/include/mach/iommu_domains.h
index 48eae0c..2d2d2fb 100644
--- a/arch/arm/mach-msm/include/mach/iommu_domains.h
+++ b/arch/arm/mach-msm/include/mach/iommu_domains.h
@@ -20,8 +20,9 @@
enum {
VIDEO_FIRMWARE_POOL,
- LOW_256MB_POOL,
- HIGH_POOL,
+ VIDEO_MAIN_POOL,
+ VIDEO_MFC_POOL,
+ GEN_POOL,
};
diff --git a/arch/arm/mach-msm/include/mach/irqs-8960.h b/arch/arm/mach-msm/include/mach/irqs-8960.h
index dae0f47..012dd74 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8960.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8960.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -268,6 +268,8 @@
#define PM8921_SEC_IRQ_104 (GIC_SPI_START + 225)
#define PM8018_SEC_IRQ_107 (GIC_SPI_START + 226)
#define USB_HSIC_IRQ (GIC_SPI_START + 229)
+#define MSM8960_CSIPHY_2_2LN_IRQ (GIC_SPI_START + 228)
+#define CSI_2_IRQ (GIC_SPI_START + 227)
/* Backwards compatible IRQ macros. */
#define INT_ADM_AARM ADM_0_SCSS_0_IRQ
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
index 8088a4c..3435c2a 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-8625.h
@@ -48,11 +48,11 @@
#define MSM8625_SCU_PHYS 0xC0600000
#define MSM8625_SCU_SIZE SZ_256
-#define MSM8625_SPM0_PHYS 0xC0200000
-#define MSM8625_SPM0_SIZE SZ_4K
+#define MSM8625_SAW0_PHYS 0xC0200000
+#define MSM8625_SAW0_SIZE SZ_4K
-#define MSM8625_SPM1_PHYS 0xC0700000
-#define MSM8625_SPM1_SIZE SZ_4K
+#define MSM8625_SAW1_PHYS 0xC0700000
+#define MSM8625_SAW1_SIZE SZ_4K
#define MSM8625_CFG_CTL_PHYS 0xA9800000
#define MSM8625_CFG_CTL_SIZE SZ_4K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
index a3c9da8..6311dbe 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap-copper.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2008-2012, Code Aurora Forum. 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
@@ -23,12 +23,17 @@
*
*/
+#define COPPER_MSM_SHARED_RAM_PHYS 0x18D00000
+
#define COPPER_QGIC_DIST_PHYS 0xF9000000
#define COPPER_QGIC_DIST_SIZE SZ_4K
#define COPPER_QGIC_CPU_PHYS 0xF9002000
#define COPPER_QGIC_CPU_SIZE SZ_4K
+#define COPPER_APCS_GCC_PHYS 0xF9011000
+#define COPPER_APCS_GCC_SIZE SZ_4K
+
#define COPPER_TLMM_PHYS 0xFD400000
#define COPPER_TLMM_SIZE SZ_16K
diff --git a/arch/arm/mach-msm/include/mach/msm_iomap.h b/arch/arm/mach-msm/include/mach/msm_iomap.h
index d53910d..27965d3 100644
--- a/arch/arm/mach-msm/include/mach/msm_iomap.h
+++ b/arch/arm/mach-msm/include/mach/msm_iomap.h
@@ -47,7 +47,9 @@
#if defined(CONFIG_ARCH_MSM8960) || defined(CONFIG_ARCH_APQ8064) || \
defined(CONFIG_ARCH_MSM8930) || defined(CONFIG_ARCH_MSM9615) || \
- defined(CONFIG_ARCH_MSMCOPPER)
+ defined(CONFIG_ARCH_MSMCOPPER) || defined(CONFIG_ARCH_MSM7X27) || \
+ defined(CONFIG_ARCH_MSM7X25) || defined(CONFIG_ARCH_MSM7X01A) || \
+ defined(CONFIG_ARCH_MSM8625)
/* Unified iomap */
@@ -80,13 +82,28 @@
#define MSM_APCS_GLB_BASE IOMEM(0xFA702000) /* 4K */
#define MSM_SAW2_BASE IOMEM(0xFA703000) /* 4k */
#define MSM_SAW3_BASE IOMEM(0xFA704000) /* 4k */
+#define MSM_VIC_BASE IOMEM(0xFA100000) /* 4K */
+#define MSM_CSR_BASE IOMEM(0xFA101000) /* 4K */
+#define MSM_GPIO1_BASE IOMEM(0xFA102000) /* 4K */
+#define MSM_GPIO2_BASE IOMEM(0xFA103000) /* 4K */
+#define MSM_SCU_BASE IOMEM(0xFA104000) /* 4K */
+#define MSM_CFG_CTL_BASE IOMEM(0xFA105000) /* 4K */
+#define MSM_MDC_BASE IOMEM(0xFA400000) /* 1M */
+#define MSM_AD5_BASE IOMEM(0xFA900000) /* 13M (D00000)
+ 0xFB600000 */
-#if defined(CONFIG_ARCH_MSM9615)
+#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
+#define MSM8625_SECONDARY_PHYS 0x0FE00000
+
+
+#if defined(CONFIG_ARCH_MSM9615) || defined(CONFIG_ARCH_MSM7X27)
#define MSM_SHARED_RAM_SIZE SZ_1M
#else
#define MSM_SHARED_RAM_SIZE SZ_2M
#endif
+#include "msm_iomap-7xxx.h"
+#include "msm_iomap-8625.h"
#include "msm_iomap-8960.h"
#include "msm_iomap-8930.h"
#include "msm_iomap-8064.h"
@@ -105,29 +122,7 @@
#elif defined(CONFIG_ARCH_FSM9XXX)
#include "msm_iomap-fsm9xxx.h"
#else
-#define MSM_VIC_BASE IOMEM(0xFA000000) /* 4K */
-#define MSM_CSR_BASE IOMEM(0xFA001000) /* 4K */
-#define MSM_TMR_BASE MSM_CSR_BASE /* 4K */
-#define MSM_TMR0_BASE IOMEM(0xFA002000) /* 4K */
-#define MSM_GPIO1_BASE IOMEM(0xFA003000) /* 4K */
-#define MSM_GPIO2_BASE IOMEM(0xFA004000) /* 4K */
-#define MSM_CLK_CTL_BASE IOMEM(0xFA005000) /* 4K */
-#define MSM_L2CC_BASE IOMEM(0xFA006000) /* 4K */
-#define MSM_QGIC_DIST_BASE IOMEM(0xFA007000) /* 4K */
-#define MSM_QGIC_CPU_BASE IOMEM(0xFA008000) /* 4K */
-#define MSM_SCU_BASE IOMEM(0xFA009000) /* 4K */
-#define MSM_SPM0_BASE IOMEM(0xFA00A000) /* 4K */
-#define MSM_SPM1_BASE IOMEM(0xFA00B000) /* 4K */
-#define MSM_CFG_CTL_BASE IOMEM(0xFA00C000) /* 4K */
-#define MSM_SHARED_RAM_BASE IOMEM(0xFA100000) /* 4K */
-#define MSM_MDC_BASE IOMEM(0xFA200000) /* 4K */
-#define MSM_AD5_BASE IOMEM(0xFA300000) /* 4K */
-#define MSM_STRONGLY_ORDERED_PAGE 0xFA0F0000
-#define MSM8625_SECONDARY_PHYS 0x0FE00000
-#define MSM_SHARED_RAM_SIZE SZ_1M
-
-#include "msm_iomap-7xxx.h"
-#include "msm_iomap-8625.h"
+#error "Target compiled without IO map\n"
#endif
#if defined(CONFIG_DEBUG_MSM_UART1)
diff --git a/arch/arm/mach-msm/include/mach/msm_rtb.h b/arch/arm/mach-msm/include/mach/msm_rtb.h
index ac45cbd..a75ab91 100644
--- a/arch/arm/mach-msm/include/mach/msm_rtb.h
+++ b/arch/arm/mach-msm/include/mach/msm_rtb.h
@@ -18,9 +18,14 @@
LOGK_READL,
LOGK_WRITEL,
LOGK_LOGBUF,
+ LOGK_HOTPLUG,
LOGK_OTHER,
};
+struct msm_rtb_platform_data {
+ unsigned int size;
+};
+
#if defined(CONFIG_MSM_RTB)
/*
* returns 1 if data was logged, 0 otherwise
diff --git a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
index d50fe2b..92dfe12 100644
--- a/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
+++ b/arch/arm/mach-msm/include/mach/qdsp5v2/codec_utils.h
@@ -132,6 +132,8 @@
unsigned int minor_no;
struct codec_operations codec_ops;
+ uint32_t buffer_size;
+ uint32_t buffer_count;
};
#endif /* !CODEC_UTILS_H */
diff --git a/arch/arm/mach-msm/include/mach/rpm.h b/arch/arm/mach-msm/include/mach/rpm.h
index 80ec683..bcb1240 100644
--- a/arch/arm/mach-msm/include/mach/rpm.h
+++ b/arch/arm/mach-msm/include/mach/rpm.h
@@ -117,8 +117,8 @@
MSM_RPM_ID_SYS_FABRIC_CFG_CLKMOD_2,
MSM_RPM_ID_SYS_FABRIC_CFG_IOCTL,
MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
- MSM_RPM_ID_SYSTEM_FABRIC_ARB_28 =
- MSM_RPM_ID_SYSTEM_FABRIC_ARB_0 + 28,
+ MSM_RPM_ID_SYSTEM_FABRIC_ARB_29 =
+ MSM_RPM_ID_SYSTEM_FABRIC_ARB_0 + 29,
MSM_RPM_ID_MMSS_FABRIC_CFG_HALT_0,
MSM_RPM_ID_MM_FABRIC_HALT_0 =
diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c
index 830db1f..dcf9f12 100644
--- a/arch/arm/mach-msm/io.c
+++ b/arch/arm/mach-msm/io.c
@@ -292,7 +292,13 @@
static struct map_desc msm_copper_io_desc[] __initdata = {
MSM_CHIP_DEVICE(QGIC_DIST, COPPER),
MSM_CHIP_DEVICE(QGIC_CPU, COPPER),
+ MSM_CHIP_DEVICE(APCS_GCC, COPPER),
MSM_CHIP_DEVICE(TLMM, COPPER),
+ {
+ .virtual = (unsigned long) MSM_SHARED_RAM_BASE,
+ .length = MSM_SHARED_RAM_SIZE,
+ .type = MT_DEVICE,
+ },
#ifdef CONFIG_DEBUG_MSMCOPPER_UART
MSM_DEVICE(DEBUG_UART),
#endif
@@ -300,6 +306,7 @@
void __init msm_map_copper_io(void)
{
+ msm_shared_ram_phys = COPPER_MSM_SHARED_RAM_PHYS;
msm_map_io(msm_copper_io_desc, ARRAY_SIZE(msm_copper_io_desc));
}
#endif /* CONFIG_ARCH_MSMCOPPER */
@@ -410,8 +417,8 @@
MSM_CHIP_DEVICE(SCU, MSM8625),
MSM_CHIP_DEVICE(CFG_CTL, MSM8625),
MSM_CHIP_DEVICE(CLK_CTL, MSM8625),
- MSM_CHIP_DEVICE(SPM0, MSM8625),
- MSM_CHIP_DEVICE(SPM1, MSM8625),
+ MSM_CHIP_DEVICE(SAW0, MSM8625),
+ MSM_CHIP_DEVICE(SAW1, MSM8625),
#if defined(CONFIG_DEBUG_MSM_UART1) || defined(CONFIG_DEBUG_MSM_UART2) || \
defined(CONFIG_DEBUG_MSM_UART3)
MSM_CHIP_DEVICE(DEBUG_UART, MSM7XXX),
diff --git a/arch/arm/mach-msm/iommu_domains.c b/arch/arm/mach-msm/iommu_domains.c
index c856455..727b729 100644
--- a/arch/arm/mach-msm/iommu_domains.c
+++ b/arch/arm/mach-msm/iommu_domains.c
@@ -103,11 +103,11 @@
case MSM_SUBSYSTEM_VIDEO_FWARE:
return VIDEO_FIRMWARE_POOL;
case MSM_SUBSYSTEM_VIDEO:
- return LOW_256MB_POOL;
+ return VIDEO_MAIN_POOL;
case MSM_SUBSYSTEM_CAMERA:
case MSM_SUBSYSTEM_DISPLAY:
case MSM_SUBSYSTEM_ROTATOR:
- return HIGH_POOL;
+ return GEN_POOL;
default:
return 0xFFFFFFFF;
}
diff --git a/arch/arm/mach-msm/jtag.c b/arch/arm/mach-msm/jtag.c
index f720fa9..b75fb38 100644
--- a/arch/arm/mach-msm/jtag.c
+++ b/arch/arm/mach-msm/jtag.c
@@ -22,8 +22,10 @@
#include "qdss.h"
#include "cp14.h"
+ /* no of dbg regs + 1 (for storing the reg count) */
#define MAX_DBG_REGS (90)
#define MAX_DBG_STATE_SIZE (MAX_DBG_REGS * num_possible_cpus())
+ /* no of etm regs + 1 (for storing the reg count) */
#define MAX_ETM_REGS (78)
#define MAX_ETM_STATE_SIZE (MAX_ETM_REGS * num_possible_cpus())
@@ -70,7 +72,7 @@
break;
case 3:
state[i++] = dbg_read(DBGBVR3);
- state[i++] = dbg_read(DBGBVR3);
+ state[i++] = dbg_read(DBGBCR3);
break;
case 4:
state[i++] = dbg_read(DBGBVR4);
@@ -78,7 +80,7 @@
break;
case 5:
state[i++] = dbg_read(DBGBVR5);
- state[i++] = dbg_read(DBGBVR5);
+ state[i++] = dbg_read(DBGBCR5);
break;
case 6:
state[i++] = dbg_read(DBGBVR6);
@@ -143,7 +145,7 @@
break;
case 3:
dbg_write(state[i++], DBGBVR3);
- dbg_write(state[i++], DBGBVR3);
+ dbg_write(state[i++], DBGBCR3);
break;
case 4:
dbg_write(state[i++], DBGBVR4);
@@ -151,7 +153,7 @@
break;
case 5:
dbg_write(state[i++], DBGBVR5);
- dbg_write(state[i++], DBGBVR5);
+ dbg_write(state[i++], DBGBCR5);
break;
case 6:
dbg_write(state[i++], DBGBVR6);
@@ -937,9 +939,9 @@
etm_write(etm.state[i++], ETMSQ12EVR);
etm_write(etm.state[i++], ETMSQ21EVR);
etm_write(etm.state[i++], ETMSQ23EVR);
+ etm_write(etm.state[i++], ETMSQ31EVR);
etm_write(etm.state[i++], ETMSQ32EVR);
etm_write(etm.state[i++], ETMSQ13EVR);
- etm_write(etm.state[i++], ETMSQ31EVR);
etm_write(etm.state[i++], ETMSQR);
for (j = 0; j < etm.nr_ext_out; j++)
i = etm_write_extoutevr(etm.state, i, j);
@@ -1046,9 +1048,9 @@
pr_info("dbg arch %u not supported\n", dbg.arch);
goto dbg_out;
}
- dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23);
- dbg.nr_bp = BMVAL(dbgdidr, 24, 27);
- dbg.nr_wp = BMVAL(dbgdidr, 28, 31);
+ dbg.nr_ctx_cmp = BMVAL(dbgdidr, 20, 23) + 1;
+ dbg.nr_bp = BMVAL(dbgdidr, 24, 27) + 1;
+ dbg.nr_wp = BMVAL(dbgdidr, 28, 31) + 1;
/* Allocate dbg state save space */
dbg.state = kzalloc(MAX_DBG_STATE_SIZE * sizeof(uint32_t), GFP_KERNEL);
diff --git a/arch/arm/mach-msm/mdm2.c b/arch/arm/mach-msm/mdm2.c
index 5db8b40..34bc415 100644
--- a/arch/arm/mach-msm/mdm2.c
+++ b/arch/arm/mach-msm/mdm2.c
@@ -82,7 +82,7 @@
/* Pull RESET gpio low and wait for it to settle. */
pr_debug("Pulling RESET gpio low\n");
gpio_direction_output(mdm_drv->ap2mdm_pmic_reset_n_gpio, 0);
- usleep(1000);
+ usleep_range(5000, 10000);
/* Deassert RESET first and wait for ir to settle. */
pr_debug("%s: Pulling RESET gpio high\n", __func__);
diff --git a/arch/arm/mach-msm/memory.c b/arch/arm/mach-msm/memory.c
index 3b064ff..d26d76b 100644
--- a/arch/arm/mach-msm/memory.c
+++ b/arch/arm/mach-msm/memory.c
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/memory.c
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. 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
@@ -226,6 +226,25 @@
return unstable_limit - mb->start;
}
+/* stable size of all memory banks contiguous to and below this one */
+static unsigned long total_stable_size(unsigned long bank)
+{
+ int i;
+ struct membank *mb = &meminfo.bank[bank];
+ int memtype = reserve_info->paddr_to_memtype(mb->start);
+ unsigned long size;
+
+ size = stable_size(mb, reserve_info->low_unstable_address);
+ for (i = bank - 1, mb = &meminfo.bank[bank - 1]; i >= 0; i--, mb--) {
+ if (mb->start + mb->size != (mb + 1)->start)
+ break;
+ if (reserve_info->paddr_to_memtype(mb->start) != memtype)
+ break;
+ size += stable_size(mb, reserve_info->low_unstable_address);
+ }
+ return size;
+}
+
static void __init calculate_reserve_limits(void)
{
int i;
@@ -242,7 +261,7 @@
continue;
}
mt = &reserve_info->memtype_reserve_table[memtype];
- size = stable_size(mb, reserve_info->low_unstable_address);
+ size = total_stable_size(i);
mt->limit = max(mt->limit, size);
}
}
@@ -277,10 +296,11 @@
if (mt->flags & MEMTYPE_FLAGS_FIXED || !mt->size)
continue;
- /* We know we will find a memory bank of the proper size
+ /* We know we will find memory bank(s) of the proper size
* as we have limited the size of the memory pool for
- * each memory type to the size of the largest memory
- * bank. Choose the memory bank with the highest physical
+ * each memory type to the largest total size of the memory
+ * banks which are contiguous and of the correct memory type.
+ * Choose the memory bank with the highest physical
* address which is large enough, so that we will not
* take memory from the lowest memory bank which the kernel
* is in (and cause boot problems) and so that we might
@@ -293,9 +313,14 @@
reserve_info->paddr_to_memtype(mb->start);
if (memtype != membank_type)
continue;
- size = stable_size(mb,
- reserve_info->low_unstable_address);
+ size = total_stable_size(i);
if (size >= mt->size) {
+ size = stable_size(mb,
+ reserve_info->low_unstable_address);
+ /* mt->size may be larger than size, all this
+ * means is that we are carving the memory pool
+ * out of multiple contiguous memory banks.
+ */
mt->start = mb->start + (size - mt->size);
ret = memblock_remove(mt->start, mt->size);
BUG_ON(ret);
diff --git a/arch/arm/mach-msm/msm_bus/Makefile b/arch/arm/mach-msm/msm_bus/Makefile
index 018e2a6..061998c 100644
--- a/arch/arm/mach-msm/msm_bus/Makefile
+++ b/arch/arm/mach-msm/msm_bus/Makefile
@@ -6,4 +6,5 @@
obj-$(CONFIG_ARCH_MSM8960) += msm_bus_board_8960.o
obj-$(CONFIG_ARCH_MSM9615) += msm_bus_board_9615.o
obj-$(CONFIG_ARCH_APQ8064) += msm_bus_board_8064.o
+obj-$(CONFIG_ARCH_MSM8930) += msm_bus_board_8930.o
obj-$(CONFIG_DEBUG_FS) += msm_bus_dbg.o
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
new file mode 100644
index 0000000..36fe156
--- /dev/null
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8930.c
@@ -0,0 +1,878 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <mach/msm_bus.h>
+#include <mach/msm_bus_board.h>
+#include <mach/board.h>
+#include <mach/rpm.h>
+#include "msm_bus_core.h"
+
+#define NMASTERS 45
+#define NSLAVES 75
+#define NFAB_8930 5
+
+enum msm_bus_fabric_tiered_slave_type {
+ MSM_BUS_SYSTEM_TIERED_SLAVE_FAB_APPSS_0 = 1,
+ MSM_BUS_TIERED_SLAVE_SYSTEM_IMEM,
+
+ MSM_BUS_TIERED_SLAVE_MM_IMEM = 1,
+ MSM_BUS_MMSS_TIERED_SLAVE_FAB_APPS_0,
+
+ MSM_BUS_TIERED_SLAVE_EBI1_CH0 = 1,
+ MSM_BUS_TIERED_SLAVE_KMPSS_L2,
+};
+
+enum msm_bus_8930_master_ports_type {
+ MSM_BUS_SYSTEM_MASTER_PORT_APPSS_FAB = 0,
+ MSM_BUS_MASTER_PORT_SPS,
+ MSM_BUS_MASTER_PORT_ADM_PORT0,
+ MSM_BUS_MASTER_PORT_ADM_PORT1,
+ MSM_BUS_MASTER_PORT_LPASS_PROC,
+ MSM_BUS_MASTER_PORT_MSS,
+ MSM_BUS_MASTER_PORT_RIVA,
+ MSM_BUS_MASTER_PORT_MSS_SW_PROC,
+ MSM_BUS_MASTER_PORT_MSS_FW_PROC,
+ MSM_BUS_MASTER_PORT_LPASS,
+ MSM_BUS_SYSTEM_MASTER_PORT_CPSS_FPB,
+ MSM_BUS_SYSTEM_MASTER_PORT_SYSTEM_FPB,
+ MSM_BUS_SYSTEM_MASTER_PORT_MMSS_FPB,
+ MSM_BUS_SYSTEM_MASTER_PORT_ADM_AHB_CI,
+
+ MSM_BUS_MASTER_PORT_MDP_PORT0 = 0,
+ MSM_BUS_MASTER_PORT_MDP_PORT1,
+ MSM_BUS_MASTER_PORT_GRAPHICS_3D,
+ MSM_BUS_MASTER_PORT_ROTATOR,
+ MSM_BUS_MASTER_PORT_VFE,
+ MSM_BUS_MASTER_PORT_VPE,
+ MSM_BUS_MASTER_PORT_JPEG_ENC,
+ MSM_BUS_MMSS_MASTER_PORT_APPS_FAB,
+ MSM_BUS_MASTER_PORT_HD_CODEC_PORT0,
+ MSM_BUS_MASTER_PORT_HD_CODEC_PORT1,
+
+ MSM_BUS_MASTER_PORT_KMPSS_M0 = 0,
+ MSM_BUS_MASTER_PORT_KMPSS_M1,
+ MSM_BUS_APPSS_MASTER_PORT_FAB_MMSS_0,
+ MSM_BUS_APPSS_MASTER_PORT_FAB_SYSTEM_0,
+};
+
+enum msm_bus_8930_slave_ports_type {
+ MSM_BUS_SLAVE_PORT_MM_IMEM = 0,
+ MSM_BUS_MMSS_SLAVE_PORT_APPS_FAB_0,
+
+ MSM_BUS_SLAVE_PORT_EBI1_CH0 = 0,
+ MSM_BUS_SLAVE_PORT_KMPSS_L2,
+ MSM_BUS_APPSS_SLAVE_PORT_MMSS_FAB,
+ MSM_BUS_SLAVE_PORT_SYSTEM_FAB,
+
+ MSM_BUS_SYSTEM_SLAVE_PORT_APPSS_FAB_0 = 0,
+ MSM_BUS_SLAVE_PORT_SPS,
+ MSM_BUS_SLAVE_PORT_SYSTEM_IMEM,
+ MSM_BUS_SLAVE_PORT_CORESIGHT,
+ MSM_BUS_SLAVE_PORT_KMPSS,
+ MSM_BUS_SLAVE_PORT_MSS,
+ MSM_BUS_SLAVE_PORT_LPASS,
+ MSM_BUS_SYSTEM_SLAVE_PORT_CPSS_FPB,
+ MSM_BUS_SYSTEM_SLAVE_PORT_SYSTEM_FPB,
+ MSM_BUS_SYSTEM_SLAVE_PORT_MMSS_FPB,
+ MSM_BUS_SLAVE_PORT_RIVA,
+};
+
+static int tier2[] = {MSM_BUS_BW_TIER2,};
+static uint32_t master_iids[NMASTERS];
+static uint32_t slave_iids[NSLAVES];
+
+static int mport_kmpss_m0[] = {MSM_BUS_MASTER_PORT_KMPSS_M0,};
+static int mport_kmpss_m1[] = {MSM_BUS_MASTER_PORT_KMPSS_M1,};
+
+static int mmss_mport_apps_fab[] = {MSM_BUS_MMSS_MASTER_PORT_APPS_FAB,};
+static int system_mport_appss_fab[] = {MSM_BUS_SYSTEM_MASTER_PORT_APPSS_FAB,};
+static int sport_ebi1_ch0[] = {
+ MSM_BUS_SLAVE_PORT_EBI1_CH0,
+};
+static int sport_kmpss_l2[] = {MSM_BUS_SLAVE_PORT_KMPSS_L2,};
+static int appss_sport_mmss_fab[] = {MSM_BUS_APPSS_SLAVE_PORT_MMSS_FAB,};
+static int sport_system_fab[] = {MSM_BUS_SLAVE_PORT_SYSTEM_FAB,};
+
+static int tiered_slave_ebi1_ch0[] = {
+ MSM_BUS_TIERED_SLAVE_EBI1_CH0,
+};
+
+static int tiered_slave_kmpss[] = {MSM_BUS_TIERED_SLAVE_KMPSS_L2,};
+
+static struct msm_bus_node_info apps_fabric_info[] = {
+ {
+ .id = MSM_BUS_MASTER_AMPSS_M0,
+ .masterp = mport_kmpss_m0,
+ .num_mports = ARRAY_SIZE(mport_kmpss_m0),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_AMPSS_M1,
+ .masterp = mport_kmpss_m1,
+ .num_mports = ARRAY_SIZE(mport_kmpss_m1),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI_CH0,
+ .slavep = sport_ebi1_ch0,
+ .num_sports = ARRAY_SIZE(sport_ebi1_ch0),
+ .tier = tiered_slave_ebi1_ch0,
+ .num_tiers = ARRAY_SIZE(tiered_slave_ebi1_ch0),
+ .buswidth = 8,
+ .slaveclk[DUAL_CTX] = "mem_clk",
+ .slaveclk[ACTIVE_CTX] = "mem_a_clk",
+ },
+ {
+ .id = MSM_BUS_SLAVE_AMPSS_L2,
+ .slavep = sport_kmpss_l2,
+ .num_sports = ARRAY_SIZE(sport_kmpss_l2),
+ .tier = tiered_slave_kmpss,
+ .num_tiers = ARRAY_SIZE(tiered_slave_kmpss),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_FAB_MMSS,
+ .gateway = 1,
+ .slavep = appss_sport_mmss_fab,
+ .num_sports = ARRAY_SIZE(appss_sport_mmss_fab),
+ .masterp = mmss_mport_apps_fab,
+ .num_mports = ARRAY_SIZE(mmss_mport_apps_fab),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_FAB_SYSTEM,
+ .gateway = 1,
+ .slavep = sport_system_fab,
+ .num_sports = ARRAY_SIZE(sport_system_fab),
+ .masterp = system_mport_appss_fab,
+ .num_mports = ARRAY_SIZE(system_mport_appss_fab),
+ .buswidth = 8,
+ },
+};
+
+static int mport_sps[] = {MSM_BUS_MASTER_PORT_SPS,};
+static int mport_adm_port0[] = {MSM_BUS_MASTER_PORT_ADM_PORT0,};
+static int mport_adm_port1[] = {MSM_BUS_MASTER_PORT_ADM_PORT1,};
+static int mport_mss[] = {MSM_BUS_MASTER_PORT_MSS,};
+static int mport_lpass_proc[] = {MSM_BUS_MASTER_PORT_LPASS_PROC,};
+static int mport_riva[] = {MSM_BUS_MASTER_PORT_RIVA,};
+static int mport_mss_sw_proc[] = {MSM_BUS_MASTER_PORT_MSS_SW_PROC,};
+static int mport_mss_fw_proc[] = {MSM_BUS_MASTER_PORT_MSS_FW_PROC,};
+static int mport_lpass[] = {MSM_BUS_MASTER_PORT_LPASS,};
+static int system_mport_mmss_fpb[] = {MSM_BUS_SYSTEM_MASTER_PORT_MMSS_FPB,};
+static int system_mport_adm_ahb_ci[] = {MSM_BUS_SYSTEM_MASTER_PORT_ADM_AHB_CI,};
+static int appss_mport_fab_system[] = {
+ MSM_BUS_APPSS_MASTER_PORT_FAB_SYSTEM_0,
+};
+static int mport_system_fpb[] = {MSM_BUS_SYSTEM_MASTER_PORT_SYSTEM_FPB,};
+static int system_mport_cpss_fpb[] = {MSM_BUS_SYSTEM_MASTER_PORT_CPSS_FPB,};
+
+static int system_sport_appss_fab[] = {
+ MSM_BUS_SYSTEM_SLAVE_PORT_APPSS_FAB_0,
+};
+static int system_sport_system_fpb[] = {MSM_BUS_SYSTEM_SLAVE_PORT_SYSTEM_FPB,};
+static int system_sport_cpss_fpb[] = {MSM_BUS_SYSTEM_SLAVE_PORT_CPSS_FPB,};
+static int sport_sps[] = {MSM_BUS_SLAVE_PORT_SPS,};
+static int sport_system_imem[] = {MSM_BUS_SLAVE_PORT_SYSTEM_IMEM,};
+static int sport_coresight[] = {MSM_BUS_SLAVE_PORT_CORESIGHT,};
+static int sport_riva[] = {MSM_BUS_SLAVE_PORT_RIVA,};
+static int sport_kmpss[] = {MSM_BUS_SLAVE_PORT_KMPSS,};
+static int sport_mss[] = {MSM_BUS_SLAVE_PORT_MSS,};
+static int sport_lpass[] = {MSM_BUS_SLAVE_PORT_LPASS,};
+static int sport_mmss_fpb[] = {MSM_BUS_SYSTEM_SLAVE_PORT_MMSS_FPB,};
+
+static int tiered_slave_system_imem[] = {MSM_BUS_TIERED_SLAVE_SYSTEM_IMEM,};
+static int system_tiered_slave_fab_appss[] = {
+ MSM_BUS_SYSTEM_TIERED_SLAVE_FAB_APPSS_0,
+};
+
+static struct msm_bus_node_info system_fabric_info[] = {
+ {
+ .id = MSM_BUS_MASTER_SPS,
+ .masterp = mport_sps,
+ .num_mports = ARRAY_SIZE(mport_sps),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_ADM_PORT0,
+ .masterp = mport_adm_port0,
+ .num_mports = ARRAY_SIZE(mport_adm_port0),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_ADM_PORT1,
+ .masterp = mport_adm_port1,
+ .num_mports = ARRAY_SIZE(mport_adm_port1),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_LPASS_PROC,
+ .masterp = mport_lpass_proc,
+ .num_mports = ARRAY_SIZE(mport_lpass_proc),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_MSS,
+ .masterp = mport_mss,
+ .num_mports = ARRAY_SIZE(mport_mss),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_RIVA,
+ .masterp = mport_riva,
+ .num_mports = ARRAY_SIZE(mport_riva),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_MSS_SW_PROC,
+ .masterp = mport_mss_sw_proc,
+ .num_mports = ARRAY_SIZE(mport_mss_sw_proc),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_MSS_FW_PROC,
+ .masterp = mport_mss_fw_proc,
+ .num_mports = ARRAY_SIZE(mport_mss_fw_proc),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_LPASS,
+ .masterp = mport_lpass,
+ .num_mports = ARRAY_SIZE(mport_lpass),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_SYSTEM_MASTER_MMSS_FPB,
+ .masterp = system_mport_mmss_fpb,
+ .num_mports = ARRAY_SIZE(system_mport_mmss_fpb),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_ADM0_CI,
+ .masterp = system_mport_adm_ahb_ci,
+ .num_mports = ARRAY_SIZE(system_mport_adm_ahb_ci),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_FAB_APPSS,
+ .gateway = 1,
+ .slavep = system_sport_appss_fab,
+ .num_sports = ARRAY_SIZE(system_sport_appss_fab),
+ .masterp = appss_mport_fab_system,
+ .num_mports = ARRAY_SIZE(appss_mport_fab_system),
+ .tier = system_tiered_slave_fab_appss,
+ .num_tiers = ARRAY_SIZE(system_tiered_slave_fab_appss),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_FAB_SYSTEM_FPB,
+ .gateway = 1,
+ .slavep = system_sport_system_fpb,
+ .num_sports = ARRAY_SIZE(system_sport_system_fpb),
+ .masterp = mport_system_fpb,
+ .num_mports = ARRAY_SIZE(mport_system_fpb),
+ .buswidth = 4,
+ },
+ {
+ .id = MSM_BUS_FAB_CPSS_FPB,
+ .gateway = 1,
+ .slavep = system_sport_cpss_fpb,
+ .num_sports = ARRAY_SIZE(system_sport_cpss_fpb),
+ .masterp = system_mport_cpss_fpb,
+ .num_mports = ARRAY_SIZE(system_mport_cpss_fpb),
+ .buswidth = 4,
+ },
+ {
+ .id = MSM_BUS_SLAVE_SPS,
+ .slavep = sport_sps,
+ .num_sports = ARRAY_SIZE(sport_sps),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SLAVE_SYSTEM_IMEM,
+ .slavep = sport_system_imem,
+ .num_sports = ARRAY_SIZE(sport_system_imem),
+ .tier = tiered_slave_system_imem,
+ .num_tiers = ARRAY_SIZE(tiered_slave_system_imem),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SLAVE_CORESIGHT,
+ .slavep = sport_coresight,
+ .num_sports = ARRAY_SIZE(sport_coresight),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SLAVE_RIVA,
+ .slavep = sport_riva,
+ .num_sports = ARRAY_SIZE(sport_riva),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SLAVE_AMPSS,
+ .slavep = sport_kmpss,
+ .num_sports = ARRAY_SIZE(sport_kmpss),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MSS,
+ .slavep = sport_mss,
+ .num_sports = ARRAY_SIZE(sport_mss),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SLAVE_LPASS,
+ .slavep = sport_lpass,
+ .num_sports = ARRAY_SIZE(sport_lpass),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+ {
+ .id = MSM_BUS_SYSTEM_SLAVE_MMSS_FPB,
+ .slavep = sport_mmss_fpb,
+ .num_sports = ARRAY_SIZE(sport_mmss_fpb),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ .buswidth = 8,
+ },
+};
+
+static int mport_mdp[] = {
+ MSM_BUS_MASTER_PORT_MDP_PORT0,
+ MSM_BUS_MASTER_PORT_MDP_PORT1,
+};
+static int mport_mdp1[] = {MSM_BUS_MASTER_PORT_MDP_PORT1,};
+static int mport_rotator[] = {MSM_BUS_MASTER_PORT_ROTATOR,};
+static int mport_graphics_3d[] = {MSM_BUS_MASTER_PORT_GRAPHICS_3D,};
+static int mport_vfe[] = {MSM_BUS_MASTER_PORT_VFE,};
+static int mport_vpe[] = {MSM_BUS_MASTER_PORT_VPE,};
+static int mport_jpeg_enc[] = {MSM_BUS_MASTER_PORT_JPEG_ENC,};
+static int mport_hd_codec_port0[] = {MSM_BUS_MASTER_PORT_HD_CODEC_PORT0,};
+static int mport_hd_codec_port1[] = {MSM_BUS_MASTER_PORT_HD_CODEC_PORT1,};
+static int appss_mport_fab_mmss[] = {
+ MSM_BUS_APPSS_MASTER_PORT_FAB_MMSS_0,
+};
+
+static int mmss_sport_apps_fab[] = {
+ MSM_BUS_MMSS_SLAVE_PORT_APPS_FAB_0,
+};
+static int sport_mm_imem[] = {MSM_BUS_SLAVE_PORT_MM_IMEM,};
+
+static int mmss_tiered_slave_fab_apps[] = {
+ MSM_BUS_MMSS_TIERED_SLAVE_FAB_APPS_0,
+};
+static int tiered_slave_mm_imem[] = {MSM_BUS_TIERED_SLAVE_MM_IMEM,};
+
+
+static struct msm_bus_node_info mmss_fabric_info[] = {
+ {
+ .id = MSM_BUS_MASTER_MDP_PORT0,
+ .masterp = mport_mdp,
+ .num_mports = ARRAY_SIZE(mport_mdp),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_MDP_PORT1,
+ .masterp = mport_mdp1,
+ .num_mports = ARRAY_SIZE(mport_mdp1),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_ROTATOR,
+ .masterp = mport_rotator,
+ .num_mports = ARRAY_SIZE(mport_rotator),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_GRAPHICS_3D,
+ .masterp = mport_graphics_3d,
+ .num_mports = ARRAY_SIZE(mport_graphics_3d),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_VFE,
+ .masterp = mport_vfe,
+ .num_mports = ARRAY_SIZE(mport_vfe),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_VPE,
+ .masterp = mport_vpe,
+ .num_mports = ARRAY_SIZE(mport_vpe),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_JPEG_ENC,
+ .masterp = mport_jpeg_enc,
+ .num_mports = ARRAY_SIZE(mport_jpeg_enc),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_HD_CODEC_PORT0,
+ .masterp = mport_hd_codec_port0,
+ .num_mports = ARRAY_SIZE(mport_hd_codec_port0),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_HD_CODEC_PORT1,
+ .masterp = mport_hd_codec_port1,
+ .num_mports = ARRAY_SIZE(mport_hd_codec_port1),
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_FAB_APPSS,
+ .gateway = 1,
+ .slavep = mmss_sport_apps_fab,
+ .num_sports = ARRAY_SIZE(mmss_sport_apps_fab),
+ .masterp = appss_mport_fab_mmss,
+ .num_mports = ARRAY_SIZE(appss_mport_fab_mmss),
+ .tier = mmss_tiered_slave_fab_apps,
+ .num_tiers = ARRAY_SIZE(mmss_tiered_slave_fab_apps),
+ .buswidth = 16,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MM_IMEM,
+ .slavep = sport_mm_imem,
+ .num_sports = ARRAY_SIZE(sport_mm_imem),
+ .tier = tiered_slave_mm_imem,
+ .num_tiers = ARRAY_SIZE(tiered_slave_mm_imem),
+ .buswidth = 8,
+ },
+};
+
+static struct msm_bus_node_info sys_fpb_fabric_info[] = {
+ {
+ .id = MSM_BUS_FAB_SYSTEM,
+ .gateway = 1,
+ .slavep = system_sport_system_fpb,
+ .num_sports = ARRAY_SIZE(system_sport_system_fpb),
+ .masterp = mport_system_fpb,
+ .num_mports = ARRAY_SIZE(mport_system_fpb),
+ .buswidth = 4,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_MASTER_SPDM,
+ .ahb = 1,
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_MASTER_RPM,
+ .ahb = 1,
+ .tier = tier2,
+ .num_tiers = ARRAY_SIZE(tier2),
+ },
+ {
+ .id = MSM_BUS_SLAVE_SPDM,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_RPM,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_RPM_MSG_RAM,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MPM,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_PMIC1_SSBI1_A,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_PMIC1_SSBI1_B,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_PMIC1_SSBI1_C,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_PMIC2_SSBI2_A,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_PMIC2_SSBI2_B,
+ .buswidth = 4,
+ .ahb = 1,
+ },
+};
+
+static struct msm_bus_node_info cpss_fpb_fabric_info[] = {
+ {
+ .id = MSM_BUS_FAB_SYSTEM,
+ .gateway = 1,
+ .slavep = system_sport_cpss_fpb,
+ .num_sports = ARRAY_SIZE(system_sport_cpss_fpb),
+ .masterp = system_mport_cpss_fpb,
+ .num_mports = ARRAY_SIZE(system_mport_cpss_fpb),
+ .buswidth = 4,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI1_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI2_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI3_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI4_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI5_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI6_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI7_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI8_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI9_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI10_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI11_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI12_UART,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI1_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI2_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI3_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI4_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI5_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI6_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI7_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI8_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI9_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI10_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI11_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_GSBI12_QUP,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_NAND,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_CS0,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_CS1,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_CS2,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_CS3,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_CS4,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_EBI2_CS5,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_USB_FS1,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_USB_FS2,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_TSIF,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MSM_TSSC,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MSM_PDM,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MSM_DIMEM,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MSM_TCSR,
+ .buswidth = 8,
+ .ahb = 1,
+ },
+ {
+ .id = MSM_BUS_SLAVE_MSM_PRNG,
+ .buswidth = 4,
+ .ahb = 1,
+ },
+};
+
+static void msm_bus_board_assign_iids(struct msm_bus_fabric_registration
+ *fabreg, int fabid)
+{
+ int i;
+ for (i = 0; i < fabreg->len; i++) {
+ if (!fabreg->info[i].gateway) {
+ fabreg->info[i].priv_id = fabid + fabreg->info[i].id;
+ if (fabreg->info[i].id < SLAVE_ID_KEY)
+ master_iids[fabreg->info[i].id] =
+ fabreg->info[i].priv_id;
+ else
+ slave_iids[fabreg->info[i].id - (SLAVE_ID_KEY)]
+ = fabreg->info[i].priv_id;
+ } else
+ fabreg->info[i].priv_id = fabreg->info[i].id;
+ }
+}
+
+static int msm_bus_board_8930_get_iid(int id)
+{
+ if ((id < SLAVE_ID_KEY && id >= NMASTERS) ||
+ id >= (SLAVE_ID_KEY + NSLAVES)) {
+ MSM_BUS_ERR("Cannot get iid. Invalid id %d passed\n", id);
+ return -EINVAL;
+ }
+
+ return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
+ slave_iids[id - SLAVE_ID_KEY]), id);
+}
+
+static struct msm_bus_board_algorithm msm_bus_board_algo = {
+ .board_nfab = NFAB_8930,
+ .get_iid = msm_bus_board_8930_get_iid,
+ .assign_iids = msm_bus_board_assign_iids,
+};
+
+struct msm_bus_fabric_registration msm_bus_8930_apps_fabric_pdata = {
+ .id = MSM_BUS_FAB_APPSS,
+ .name = "msm_apps_fab",
+ .info = apps_fabric_info,
+ .len = ARRAY_SIZE(apps_fabric_info),
+ .ahb = 0,
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
+ .haltid = MSM_RPM_ID_APPS_FABRIC_CFG_HALT_0,
+ .offset = MSM_RPM_ID_APPS_FABRIC_ARB_0,
+ .nmasters = 4,
+ .nslaves = 4,
+ .ntieredslaves = 2,
+ .board_algo = &msm_bus_board_algo,
+};
+
+struct msm_bus_fabric_registration msm_bus_8930_sys_fabric_pdata = {
+ .id = MSM_BUS_FAB_SYSTEM,
+ .name = "msm_sys_fab",
+ system_fabric_info,
+ ARRAY_SIZE(system_fabric_info),
+ .ahb = 0,
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
+ .haltid = MSM_RPM_ID_SYS_FABRIC_CFG_HALT_0,
+ .offset = MSM_RPM_ID_SYSTEM_FABRIC_ARB_0,
+ .nmasters = 14,
+ .nslaves = 11,
+ .ntieredslaves = 2,
+ .board_algo = &msm_bus_board_algo,
+};
+
+struct msm_bus_fabric_registration msm_bus_8930_mm_fabric_pdata = {
+ .id = MSM_BUS_FAB_MMSS,
+ .name = "msm_mm_fab",
+ mmss_fabric_info,
+ ARRAY_SIZE(mmss_fabric_info),
+ .ahb = 0,
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
+ .haltid = MSM_RPM_ID_MMSS_FABRIC_CFG_HALT_0,
+ .offset = MSM_RPM_ID_MM_FABRIC_ARB_0,
+ .nmasters = 10,
+ .nslaves = 2,
+ .ntieredslaves = 2,
+ .board_algo = &msm_bus_board_algo,
+};
+
+struct msm_bus_fabric_registration msm_bus_8930_sys_fpb_pdata = {
+ .id = MSM_BUS_FAB_SYSTEM_FPB,
+ .name = "msm_sys_fpb",
+ sys_fpb_fabric_info,
+ ARRAY_SIZE(sys_fpb_fabric_info),
+ .ahb = 1,
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
+ .nmasters = 0,
+ .nslaves = 0,
+ .ntieredslaves = 0,
+ .board_algo = &msm_bus_board_algo,
+};
+
+struct msm_bus_fabric_registration msm_bus_8930_cpss_fpb_pdata = {
+ .id = MSM_BUS_FAB_CPSS_FPB,
+ .name = "msm_cpss_fpb",
+ cpss_fpb_fabric_info,
+ ARRAY_SIZE(cpss_fpb_fabric_info),
+ .ahb = 1,
+ .fabclk[DUAL_CTX] = "bus_clk",
+ .fabclk[ACTIVE_CTX] = "bus_a_clk",
+ .nmasters = 0,
+ .nslaves = 0,
+ .ntieredslaves = 0,
+ .board_algo = &msm_bus_board_algo,
+};
diff --git a/arch/arm/mach-msm/msm_rtb.c b/arch/arm/mach-msm/msm_rtb.c
index f93a79b..6e79dfe 100644
--- a/arch/arm/mach-msm/msm_rtb.c
+++ b/arch/arm/mach-msm/msm_rtb.c
@@ -16,6 +16,7 @@
#include <linux/kernel.h>
#include <linux/memory_alloc.h>
#include <linux/module.h>
+#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/string.h>
@@ -64,7 +65,6 @@
#endif
struct msm_rtb_state msm_rtb = {
- .size = SZ_1M,
.filter = 1 << LOGK_LOGBUF,
};
@@ -107,16 +107,6 @@
start->data = data;
}
-static int __init msm_rtb_set_buffer_size(char *p)
-{
- int s;
-
- s = memparse(p, NULL);
- msm_rtb.size = ALIGN(s, SZ_4K);
- return 0;
-}
-early_param("msm_rtb_size", msm_rtb_set_buffer_size);
-
#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
static int msm_rtb_get_idx(void)
{
@@ -178,12 +168,15 @@
}
EXPORT_SYMBOL(uncached_logk);
-int msm_rtb_init(void)
+int msm_rtb_probe(struct platform_device *pdev)
{
+ struct msm_rtb_platform_data *d = pdev->dev.platform_data;
#if defined(CONFIG_MSM_RTB_SEPARATE_CPUS)
unsigned int cpu;
#endif
+ msm_rtb.size = d->size;
+
if (msm_rtb.size <= 0 || msm_rtb.size > SZ_1M)
return -EINVAL;
@@ -227,4 +220,22 @@
msm_rtb.enabled = 1;
return 0;
}
+
+static struct platform_driver msm_rtb_driver = {
+ .driver = {
+ .name = "msm_rtb",
+ .owner = THIS_MODULE
+ },
+};
+
+static int __init msm_rtb_init(void)
+{
+ return platform_driver_probe(&msm_rtb_driver, msm_rtb_probe);
+}
+
+static void __exit msm_rtb_exit(void)
+{
+ platform_driver_unregister(&msm_rtb_driver);
+}
module_init(msm_rtb_init)
+module_exit(msm_rtb_exit)
diff --git a/arch/arm/mach-msm/pil-gss.c b/arch/arm/mach-msm/pil-gss.c
index 6ec9b5d..2b4dae1 100644
--- a/arch/arm/mach-msm/pil-gss.c
+++ b/arch/arm/mach-msm/pil-gss.c
@@ -25,6 +25,7 @@
#include <mach/msm_iomap.h>
#include <mach/msm_xo.h>
+#include <mach/socinfo.h>
#include "peripheral-loader.h"
#include "scm-pas.h"
@@ -142,13 +143,17 @@
writel_relaxed(A5_RESET, base + GSS_CSR_RESET);
}
-static void setup_qgic2_bus_access(void *data)
+static void cfg_qgic2_bus_access(void *data)
{
struct gss_data *drv = data;
- void __iomem *base = drv->base;
int i;
- writel_relaxed(0x2, base + GSS_CSR_CFG_HID);
+ /*
+ * Apply a 8064 v1.0 workaround to configure QGIC bus access.
+ * This must be done from Krait 0 to configure the Master ID
+ * correctly.
+ */
+ writel_relaxed(0x2, drv->base + GSS_CSR_CFG_HID);
for (i = 0; i <= 3; i++)
readl_relaxed(drv->qgic2_base);
}
@@ -233,15 +238,15 @@
while (!(readl_relaxed(base + GSS_CSR_POWER_UP_DOWN) & A5_POWER_STATUS))
cpu_relax();
- /*
- * Apply a 8064 v1.0 workaround to configure QGIC bus access. This must
- * be done from Krait 0 to configure the Master ID correctly.
- */
- ret = smp_call_function_single(0, setup_qgic2_bus_access, drv, 1);
- if (ret) {
- pr_err("Failed to configure QGIC2 bus access\n");
- pil_gss_shutdown(pil);
- return ret;
+ if (cpu_is_apq8064() &&
+ ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) &&
+ (SOCINFO_VERSION_MINOR(socinfo_get_version()) == 0))) {
+ ret = smp_call_function_single(0, cfg_qgic2_bus_access, drv, 1);
+ if (ret) {
+ pr_err("Failed to configure QGIC2 bus access\n");
+ pil_gss_shutdown(pil);
+ return ret;
+ }
}
/* Release A5 from reset. */
@@ -263,6 +268,20 @@
return pas_init_image(PAS_GSS, metadata, size);
}
+static int pil_gss_shutdown_trusted(struct pil_desc *pil)
+{
+ struct gss_data *drv = dev_get_drvdata(pil->dev);
+ int ret;
+
+ ret = pas_shutdown(PAS_GSS);
+ if (ret)
+ return ret;
+
+ remove_gss_proxy_votes_now(drv);
+
+ return ret;
+}
+
static int pil_gss_reset_trusted(struct pil_desc *pil)
{
struct gss_data *drv = dev_get_drvdata(pil->dev);
@@ -276,23 +295,26 @@
if (err)
remove_gss_proxy_votes_now(drv);
+ if (cpu_is_apq8064() &&
+ ((SOCINFO_VERSION_MAJOR(socinfo_get_version()) == 1) &&
+ (SOCINFO_VERSION_MINOR(socinfo_get_version()) == 0))) {
+ err = smp_call_function_single(0, cfg_qgic2_bus_access, drv, 1);
+ if (err) {
+ pr_err("Failed to configure QGIC2 bus access\n");
+ pil_gss_shutdown_trusted(pil);
+ return err;
+ }
+ /*
+ * On 8064v1.0, pas_auth_and_reset() will not release the A5
+ * from reset. Linux must do this after cfg_qgic2_bus_access()
+ * is called on CPU0.
+ */
+ writel_relaxed(0x0, drv->base + GSS_CSR_RESET);
+ }
+
return err;
}
-static int pil_gss_shutdown_trusted(struct pil_desc *pil)
-{
- struct gss_data *drv = dev_get_drvdata(pil->dev);
- int ret;
-
- ret = pas_shutdown(PAS_GSS);
- if (ret)
- return ret;
-
- remove_gss_proxy_votes_now(drv);
-
- return ret;
-}
-
static struct pil_reset_ops pil_gss_ops_trusted = {
.init_image = pil_gss_init_image_trusted,
.verify_blob = nop_verify_blob,
diff --git a/arch/arm/mach-msm/pil-q6v4.c b/arch/arm/mach-msm/pil-q6v4.c
index 511377d..b0bce02 100644
--- a/arch/arm/mach-msm/pil-q6v4.c
+++ b/arch/arm/mach-msm/pil-q6v4.c
@@ -29,11 +29,10 @@
#include "pil-q6v4.h"
#include "scm-pas.h"
-#define PROXY_VOTE_TIMEOUT 40000
+#define PROXY_VOTE_TIMEOUT 10000
#define QDSP6SS_RST_EVB 0x0
#define QDSP6SS_RESET 0x04
-#define QDSP6SS_CGC_OVERRIDE 0x18
#define QDSP6SS_STRAP_TCM 0x1C
#define QDSP6SS_STRAP_AHB 0x20
#define QDSP6SS_GFMUX_CTL 0x30
@@ -62,7 +61,6 @@
#define Q6SS_CLK_ENA BIT(1)
#define Q6SS_SRC_SWITCH_CLK_OVR BIT(8)
-#define Q6SS_AXIS_ACLK_EN BIT(9)
struct q6v4_data {
void __iomem *base;
@@ -220,15 +218,6 @@
if (err)
dev_err(pil->dev, "Failed to unhalt bus port\n");
- /*
- * Assert AXIS_ACLK_EN override to allow for correct updating of the
- * QDSP6_CORE_STATE status bit. This is mandatory only for the SW Q6
- * in 8960v1 and optional elsewhere.
- */
- reg = readl_relaxed(drv->base + QDSP6SS_CGC_OVERRIDE);
- reg |= Q6SS_AXIS_ACLK_EN;
- writel_relaxed(reg, drv->base + QDSP6SS_CGC_OVERRIDE);
-
/* Deassert Q6SS_SS_ARES */
reg = readl_relaxed(drv->base + QDSP6SS_RESET);
reg &= ~(Q6SS_SS_ARES);
@@ -278,16 +267,6 @@
/* Bring Q6 core out of reset and start execution. */
writel_relaxed(0x0, drv->base + QDSP6SS_RESET);
- /*
- * Re-enable auto-gating of AXIS_ACLK at lease one AXI clock cycle
- * after resets are de-asserted.
- */
- mb();
- usleep_range(1, 10);
- reg = readl_relaxed(drv->base + QDSP6SS_CGC_OVERRIDE);
- reg &= ~Q6SS_AXIS_ACLK_EN;
- writel_relaxed(reg, drv->base + QDSP6SS_CGC_OVERRIDE);
-
return 0;
}
diff --git a/arch/arm/mach-msm/platsmp-8625.c b/arch/arm/mach-msm/platsmp-8625.c
new file mode 100644
index 0000000..534fc0e
--- /dev/null
+++ b/arch/arm/mach-msm/platsmp-8625.c
@@ -0,0 +1,202 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+
+#include <asm/cacheflush.h>
+#include <asm/hardware/gic.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <asm/smp_scu.h>
+#include <asm/unified.h>
+#include <mach/msm_iomap.h>
+#include <mach/smp.h>
+#include "pm.h"
+
+#define MSM_CORE1_RESET 0xA8600590
+/*
+ * control for which core is the next to come out of the secondary
+ * boot "holding pen"
+ */
+int pen_release = -1;
+
+static bool cold_boot_done;
+
+static uint32_t *msm8625_boot_vector;
+
+/*
+ * Write pen_release in a way that is guaranteed to be visible to all
+ * observers, irrespective of whether they're taking part in coherency
+ * or not. This is necessary for the hotplug code to work reliably.
+ */
+static void __cpuinit write_pen_release(int val)
+{
+ pen_release = val;
+ smp_wmb();
+ __cpuc_flush_dcache_area((void *)&pen_release, sizeof(pen_release));
+ outer_clean_range(__pa(&pen_release), __pa(&pen_release + 1));
+}
+
+static void __iomem *scu_base_addr(void)
+{
+ return MSM_SCU_BASE;
+}
+
+static DEFINE_SPINLOCK(boot_lock);
+
+void __cpuinit platform_secondary_init(unsigned int cpu)
+{
+ /*
+ * if any interrupts are already enabled for the primary
+ * core (e.g. timer irq), then they will not have been enabled
+ * for us: do so
+ */
+ gic_secondary_init(0);
+
+ /*
+ * let the primary processor know we're out of the
+ * pen, then head off into the C entry point
+ */
+ write_pen_release(-1);
+
+ /*
+ * Synchronise with the boot thread.
+ */
+ spin_lock(&boot_lock);
+ spin_unlock(&boot_lock);
+}
+
+int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ unsigned long timeout;
+ void __iomem *base_ptr;
+
+ if (cold_boot_done == false) {
+ base_ptr = ioremap_nocache(MSM_CORE1_RESET, SZ_4);
+ if (!base_ptr)
+ return -ENODEV;
+ /* Reset core 1 out of reset */
+ __raw_writel(0x0, base_ptr);
+ mb();
+ cold_boot_done = true;
+ iounmap(base_ptr);
+ }
+
+ /*
+ * Set synchronisation state between this boot processor
+ * and the secondary one
+ */
+ spin_lock(&boot_lock);
+
+ /*
+ * This is really belt and braces; we hold unintended secondary
+ * CPUs in the holding pen until we're ready for them. However,
+ * since we haven't sent them a soft interrupt, they shouldn't
+ * be there.
+ */
+ write_pen_release(cpu);
+
+ /*
+ * Send the secondary CPU a soft interrupt, thereby causing
+ * the boot monitor to read the system wide flags register,
+ * and branch to the address found there.
+ */
+ gic_raise_softirq(cpumask_of(cpu), 1);
+
+ timeout = jiffies + (1 * HZ);
+ while (time_before(jiffies, timeout)) {
+ smp_rmb();
+ if (pen_release == -1)
+ break;
+
+ udelay(10);
+ }
+
+ /*
+ * now the secondary core is starting up let it run its
+ * calibrations, then wait for it to finish
+ */
+ spin_unlock(&boot_lock);
+
+ return 0;
+}
+
+/*
+ * Initialise the CPU possible map early - this describes the CPUs
+ * which may be present or become present in the system.
+ */
+void __init smp_init_cpus(void)
+{
+ void __iomem *scu_base = scu_base_addr();
+
+ unsigned int i, ncores;
+
+ ncores = scu_base ? scu_get_core_count(scu_base) : 1;
+
+ for (i = 0; i < ncores; i++)
+ set_cpu_possible(i, true);
+
+ set_smp_cross_call(gic_raise_softirq);
+}
+
+static void __init msm8625_boot_vector_init(uint32_t *boot_vector,
+ unsigned long entry)
+{
+ if (!boot_vector)
+ return;
+ msm8625_boot_vector = boot_vector;
+
+ msm8625_boot_vector[0] = 0xE51FF004; /* ldr pc, 4 */
+ msm8625_boot_vector[1] = entry;
+}
+
+void __init platform_smp_prepare_cpus(unsigned int max_cpus)
+{
+ int i, value;
+ void __iomem *second_ptr;
+
+ /*
+ * Initialise the present map, which describes the set of CPUs
+ * actually populated at the present time.
+ */
+ for (i = 0; i < max_cpus; i++)
+ set_cpu_present(i, true);
+
+ scu_enable(scu_base_addr());
+
+ /*
+ * Write the address of secondary startup into the
+ * boot remapper register. The secondary CPU branches to this address.
+ */
+ __raw_writel(MSM8625_SECONDARY_PHYS, (MSM_CFG_CTL_BASE + 0x34));
+ mb();
+
+ second_ptr = ioremap_nocache(MSM8625_SECONDARY_PHYS, SZ_8);
+ if (!second_ptr) {
+ pr_err("failed to ioremap for secondary core\n");
+ return;
+ }
+
+ msm8625_boot_vector_init(second_ptr,
+ virt_to_phys(msm_secondary_startup));
+ iounmap(second_ptr);
+
+ /* Enable boot remapper address: bit 26 for core1 */
+ value = __raw_readl(MSM_CFG_CTL_BASE + 0x30);
+ __raw_writel(value | (0x4 << 24), MSM_CFG_CTL_BASE + 0x30) ;
+ mb();
+}
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index e1934bb..7977d22 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -1668,6 +1668,13 @@
.valid = suspend_valid_only_mem,
};
+/* Hotplug the "non boot" CPU's and put
+ * the cores into low power mode
+ */
+void msm_pm_cpu_enter_lowpower(unsigned int cpu)
+{
+ return;
+}
/******************************************************************************
* Restart Definitions
diff --git a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
index c38fefc..d43c961 100644
--- a/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
+++ b/arch/arm/mach-msm/qdsp5v2/audio_lpa.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 Google, Inc.
* Copyright (C) 2008 HTC Corporation
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. 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
@@ -76,6 +76,9 @@
#define MASK_32BITS 0xFFFFFFFF
+#define MAX_BUF 4
+#define BUFSZ (524288)
+
#define __CONTAINS(r, v, l) ({ \
typeof(r) __r = r; \
typeof(v) __v = v; \
@@ -1192,6 +1195,8 @@
audio->out_sample_rate = config.sample_rate;
audio->out_channel_mode = config.channel_count;
audio->out_bits = config.bits;
+ audio->buffer_count = config.buffer_count;
+ audio->buffer_size = config.buffer_size;
MM_DBG("AUDIO_SET_CONFIG: config.bits = %d\n", config.bits);
rc = 0;
break;
@@ -1199,7 +1204,8 @@
case AUDIO_GET_CONFIG:{
struct msm_audio_config config;
- config.buffer_count = 2;
+ config.buffer_count = audio->buffer_count;
+ config.buffer_size = audio->buffer_size;
config.sample_rate = audio->out_sample_rate;
if (audio->out_channel_mode == AUDPP_CMD_PCM_INTF_MONO_V)
config.channel_count = 1;
@@ -1518,6 +1524,8 @@
dec_attrb |= audlpa_decs[audio->minor_no].dec_attrb;
audio->codec_ops.ioctl = audlpa_decs[audio->minor_no].ioctl;
audio->codec_ops.adec_params = audlpa_decs[audio->minor_no].adec_params;
+ audio->buffer_size = BUFSZ;
+ audio->buffer_count = MAX_BUF;
dec_attrb |= MSM_AUD_MODE_LP;
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 37428da..541f62f 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -505,12 +505,19 @@
return;
pr_debug("%s: handle[%p]\n", __func__, handle);
+ if (apr_reset_workqueue == NULL) {
+ pr_err("%s: apr_reset_workqueue is NULL\n", __func__);
+ return;
+ }
+
apr_reset_worker = kzalloc(sizeof(struct apr_reset_work),
- GFP_ATOMIC);
- if (apr_reset_worker == NULL || apr_reset_workqueue == NULL) {
+ GFP_ATOMIC);
+
+ if (apr_reset_worker == NULL) {
pr_err("%s: mem failure\n", __func__);
return;
}
+
apr_reset_worker->handle = handle;
INIT_WORK(&apr_reset_worker->work, apr_reset_deregister);
queue_work(apr_reset_workqueue, &apr_reset_worker->work);
diff --git a/arch/arm/mach-msm/qdss-ptm.c b/arch/arm/mach-msm/qdss-ptm.c
index 96a727a..c0dc58e 100644
--- a/arch/arm/mach-msm/qdss-ptm.c
+++ b/arch/arm/mach-msm/qdss-ptm.c
@@ -67,9 +67,9 @@
#define ETMSQ12EVR (0x180)
#define ETMSQ21EVR (0x184)
#define ETMSQ23EVR (0x188)
-#define ETMSQ32EVR (0x18C)
-#define ETMSQ13EVR (0x190)
-#define ETMSQ31EVR (0x194)
+#define ETMSQ31EVR (0x18C)
+#define ETMSQ32EVR (0x190)
+#define ETMSQ13EVR (0x194)
#define ETMSQR (0x19C)
#define ETMEXTOUTEVRn(n) (0x1A0 + (n * 4))
#define ETMCIDCVRn(n) (0x1B0 + (n * 4))
@@ -91,7 +91,7 @@
#define ETMTSEVR (0x1F8)
#define ETMAUXCR (0x1FC)
#define ETMTRACEIDR (0x200)
-#define ETMVMIDCVR (0x204)
+#define ETMVMIDCVR (0x240)
/* Management registers (0x300-0x314) */
#define ETMOSLAR (0x300)
#define ETMOSLSR (0x304)
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index b95c3aa..bca1e0c 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -273,6 +273,38 @@
#define MSM_TRIG_A2WCNSS_SMSM_INT
#endif
+/*
+ * stub out legacy macros if they are not being used so that the legacy
+ * code compiles even though it is not used
+ *
+ * these definitions should not be used in active code and will cause
+ * an early failure
+ */
+#ifndef INT_A9_M2A_0
+#define INT_A9_M2A_0 -1
+#endif
+#ifndef INT_A9_M2A_5
+#define INT_A9_M2A_5 -1
+#endif
+#ifndef INT_ADSP_A11
+#define INT_ADSP_A11 -1
+#endif
+#ifndef INT_ADSP_A11_SMSM
+#define INT_ADSP_A11_SMSM -1
+#endif
+#ifndef INT_DSPS_A11
+#define INT_DSPS_A11 -1
+#endif
+#ifndef INT_DSPS_A11_SMSM
+#define INT_DSPS_A11_SMSM -1
+#endif
+#ifndef INT_WCNSS_A11
+#define INT_WCNSS_A11 -1
+#endif
+#ifndef INT_WCNSS_A11_SMSM
+#define INT_WCNSS_A11_SMSM -1
+#endif
+
#define SMD_LOOPBACK_CID 100
#define SMEM_SPINLOCK_SMEM_ALLOC "S:3"
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index 0ec88d5..a1bf280 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -218,6 +218,7 @@
/* 8064 IDs */
[109] = MSM_CPU_8064,
+ [130] = MSM_CPU_8064,
/* 8930 IDs */
[116] = MSM_CPU_8930,
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index 78fd922..b155781 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -65,12 +65,7 @@
#elif defined(CONFIG_MSM_SPM_V2)
enum {
- MSM_SPM_REG_SAW2_SECURE,
- MSM_SPM_REG_SAW2_ID,
MSM_SPM_REG_SAW2_CFG,
- MSM_SPM_REG_SAW2_STS0,
- MSM_SPM_REG_SAW2_STS1,
- MSM_SPM_REG_SAW2_VCTL,
MSM_SPM_REG_SAW2_AVS_CTL,
MSM_SPM_REG_SAW2_AVS_HYSTERESIS,
MSM_SPM_REG_SAW2_SPM_CTL,
@@ -79,8 +74,13 @@
MSM_SPM_REG_SAW2_PMIC_DATA_1,
MSM_SPM_REG_SAW2_RST,
- MSM_SPM_REG_NR_INITIALIZE,
- MSM_SPM_REG_SAW2_SEQ_ENTRY = MSM_SPM_REG_NR_INITIALIZE,
+ MSM_SPM_REG_NR_INITIALIZE = MSM_SPM_REG_SAW2_RST,
+ MSM_SPM_REG_SAW2_ID,
+ MSM_SPM_REG_SAW2_SECURE,
+ MSM_SPM_REG_SAW2_STS0,
+ MSM_SPM_REG_SAW2_STS1,
+ MSM_SPM_REG_SAW2_VCTL,
+ MSM_SPM_REG_SAW2_SEQ_ENTRY ,
MSM_SPM_REG_NR
};
diff --git a/arch/arm/mach-msm/wcnss-ssr-8960.c b/arch/arm/mach-msm/wcnss-ssr-8960.c
index 07a9241..9970c90 100644
--- a/arch/arm/mach-msm/wcnss-ssr-8960.c
+++ b/arch/arm/mach-msm/wcnss-ssr-8960.c
@@ -122,9 +122,13 @@
if (pdev && pwlanconfig)
ret = wcnss_wlan_power(&pdev->dev, pwlanconfig,
WCNSS_WLAN_SWITCH_ON);
- if (!ret)
+ /* delay PIL operation, this SSR may be happening soon after kernel
+ * resumes because of a SMSM RESET by Riva when APPS was suspended.
+ * PIL fails to locate the images without this delay */
+ if (!ret) {
+ msleep(1000);
pil_force_boot("wcnss");
-
+ }
ss_restart_inprogress = false;
enable_irq(RIVA_APSS_WDOG_BITE_RESET_RDY_IRQ);
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
old mode 100644
new mode 100755
index 7d2e44f..8dcce03
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1136,4 +1136,6 @@
apq8064_cdp MACH_APQ8064_CDP APQ8064_CDP 3948
apq8064_mtp MACH_APQ8064_MTP APQ8064_MTP 3949
apq8064_liquid MACH_APQ8064_LIQUID APQ8064_LIQUID 3951
+mpq8064_hrd MACH_MPQ8064_HRD MPQ8064_HRD 3994
+mpq8064_dtv MACH_MPQ8064_DTV MPQ8064_DTV 3995
msm7627a_qrd3 MACH_MSM7627A_QRD3 MSM7627A_QRD3 4005
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 851189d..58bf45d 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -52,6 +52,8 @@
source "drivers/spi/Kconfig"
+source "drivers/spmi/Kconfig"
+
source "drivers/slimbus/Kconfig"
source "drivers/pps/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index e18822cd..82008ed 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -51,6 +51,7 @@
obj-$(CONFIG_TARGET_CORE) += target/
obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPI) += spi/
+obj-$(CONFIG_SPMI) += spmi/
obj-$(CONFIG_SLIMBUS) += slimbus/
obj-y += net/
obj-$(CONFIG_ATM) += atm/
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
index a9faff0..7d28604 100644
--- a/drivers/char/diag/diagchar.h
+++ b/drivers/char/diag/diagchar.h
@@ -128,6 +128,7 @@
struct diag_client_map *client_map;
int *data_ready;
int num_clients;
+ int polling_reg_flag;
struct diag_write_device *buf_tbl;
/* Memory pool parameters */
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index a703148..e24d896 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -60,8 +60,8 @@
static unsigned int max_clients = 15;
static unsigned int threshold_client_limit = 30;
/* This is the maximum number of pkt registrations supported at initialization*/
-unsigned int diag_max_registration = 500;
-unsigned int diag_threshold_registration = 650;
+unsigned int diag_max_registration = 600;
+unsigned int diag_threshold_registration = 750;
/* Timer variables */
static struct timer_list drain_timer;
@@ -256,15 +256,49 @@
return -ENOMEM;
}
+int diag_find_polling_reg(int i)
+{
+ uint16_t subsys_id, cmd_code_lo, cmd_code_hi;
+
+ subsys_id = driver->table[i].subsys_id;
+ cmd_code_lo = driver->table[i].cmd_code_lo;
+ cmd_code_hi = driver->table[i].cmd_code_hi;
+ if (driver->table[i].cmd_code == 0x0C)
+ return 1;
+ else if (driver->table[i].cmd_code == 0xFF) {
+ if (subsys_id == 0x04 && cmd_code_hi == 0x0E &&
+ cmd_code_lo == 0x0E)
+ return 1;
+ else if (subsys_id == 0x08 && cmd_code_hi == 0x02 &&
+ cmd_code_lo == 0x02)
+ return 1;
+ else if (subsys_id == 0x32 && cmd_code_hi == 0x03 &&
+ cmd_code_lo == 0x03)
+ return 1;
+ }
+ return 0;
+}
+
void diag_clear_reg(int proc_num)
{
int i;
+ mutex_lock(&driver->diagchar_mutex);
+ /* reset polling flag */
+ driver->polling_reg_flag = 0;
for (i = 0; i < diag_max_registration; i++) {
if (driver->table[i].client_id == proc_num) {
driver->table[i].process_id = 0;
}
}
+ /* re-scan the registration table */
+ for (i = 0; i < diag_max_registration; i++) {
+ if (diag_find_polling_reg(i) == 1) {
+ driver->polling_reg_flag = 1;
+ break;
+ }
+ }
+ mutex_unlock(&driver->diagchar_mutex);
}
void diag_add_reg(int j, struct bindpkt_params *params,
@@ -275,6 +309,11 @@
driver->table[j].subsys_id = params->subsys_id;
driver->table[j].cmd_code_lo = params->cmd_code_lo;
driver->table[j].cmd_code_hi = params->cmd_code_hi;
+
+ /* check if incoming reg is polling & polling is yet not registered */
+ if (driver->polling_reg_flag == 0)
+ if (diag_find_polling_reg(j) == 1)
+ driver->polling_reg_flag = 1;
if (params->proc_id == APPS_PROC) {
driver->table[j].process_id = current->tgid;
driver->table[j].client_id = APPS_PROC;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 07322cd..079e04b 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -891,8 +891,8 @@
/* Check for polling for Apps only DIAG */
else if ((*buf == 0x4b) && (*(buf+1) == 0x32) &&
(*(buf+2) == 0x03)) {
- /* If there is NO MODEM present */
- if (!(driver->ch)) {
+ /* If no one has registered for polling */
+ if (!(driver->polling_reg_flag)) {
/* Respond to polling for Apps only DIAG */
for (i = 0; i < 3; i++)
driver->apps_rsp_buf[i] = *(buf+i);
@@ -901,13 +901,10 @@
ENCODE_RSP_AND_SEND(15);
return 0;
- } else {
- /* Since Modem is present, send error response */
- return 1;
}
}
/* Check for ID for NO MODEM present */
- else if (!(driver->ch)) {
+ else if (!(driver->polling_reg_flag)) {
/* respond to 0x0 command */
if (*buf == 0x00) {
for (i = 0; i < 55; i++)
@@ -1041,9 +1038,9 @@
queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_work));
queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_work));
/* Poll SMD CNTL channels to check for data */
- queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
- queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_cntl_work));
- queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_cntl_work));
+ diag_smd_cntl_notify(NULL, SMD_EVENT_DATA);
+ diag_smd_qdsp_cntl_notify(NULL, SMD_EVENT_DATA);
+ diag_smd_wcnss_cntl_notify(NULL, SMD_EVENT_DATA);
/* Poll USB channel to check for data*/
queue_work(driver->diag_wq, &(driver->diag_read_work));
#ifdef CONFIG_DIAG_SDIO_PIPE
diff --git a/drivers/char/diag/diagfwd_cntl.c b/drivers/char/diag/diagfwd_cntl.c
index df2cd65..2c3dc54 100644
--- a/drivers/char/diag/diagfwd_cntl.c
+++ b/drivers/char/diag/diagfwd_cntl.c
@@ -19,6 +19,66 @@
#define HDR_SIZ 8
+void diag_smd_cntl_notify(void *ctxt, unsigned event)
+{
+ int r1, r2;
+
+ if (!(driver->ch_cntl))
+ return;
+
+ switch (event) {
+ case SMD_EVENT_DATA:
+ r1 = smd_read_avail(driver->ch_cntl);
+ r2 = smd_cur_packet_size(driver->ch_cntl);
+ if (r1 > 0 && r1 == r2)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_cntl_work));
+ else
+ pr_debug("diag: incomplete pkt on Modem CNTL ch\n");
+ break;
+ }
+}
+
+void diag_smd_qdsp_cntl_notify(void *ctxt, unsigned event)
+{
+ int r1, r2;
+
+ if (!(driver->chqdsp_cntl))
+ return;
+
+ switch (event) {
+ case SMD_EVENT_DATA:
+ r1 = smd_read_avail(driver->chqdsp_cntl);
+ r2 = smd_cur_packet_size(driver->chqdsp_cntl);
+ if (r1 > 0 && r1 == r2)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_qdsp_cntl_work));
+ else
+ pr_debug("diag: incomplete pkt on LPASS CNTL ch\n");
+ break;
+ }
+}
+
+void diag_smd_wcnss_cntl_notify(void *ctxt, unsigned event)
+{
+ int r1, r2;
+
+ if (!(driver->ch_wcnss_cntl))
+ return;
+
+ switch (event) {
+ case SMD_EVENT_DATA:
+ r1 = smd_read_avail(driver->ch_wcnss_cntl);
+ r2 = smd_cur_packet_size(driver->ch_wcnss_cntl);
+ if (r1 > 0 && r1 == r2)
+ queue_work(driver->diag_wq,
+ &(driver->diag_read_smd_wcnss_cntl_work));
+ else
+ pr_debug("diag: incomplete pkt on WCNSS CNTL ch\n");
+ break;
+ }
+}
+
static void diag_smd_cntl_send_req(int proc_num)
{
int data_len = 0, type = -1, count_bytes = 0, j, r, flag = 0;
@@ -30,6 +90,11 @@
void *buf = NULL;
smd_channel_t *smd_ch = NULL;
+ if (pkt_params == NULL) {
+ pr_alert("diag: Memory allocation failure\n");
+ return;
+ }
+
if (proc_num == MODEM_PROC) {
buf = driver->buf_in_cntl;
smd_ch = driver->ch_cntl;
@@ -62,6 +127,17 @@
while (count_bytes + HDR_SIZ <= r) {
type = *(uint32_t *)(buf);
data_len = *(uint32_t *)(buf + 4);
+ if (type < DIAG_CTRL_MSG_REG ||
+ type > DIAG_CTRL_MSG_F3_MASK_V2) {
+ pr_alert("diag: Invalid Msg type %d proc %d",
+ type, proc_num);
+ break;
+ }
+ if (data_len < 0 || data_len > r) {
+ pr_alert("diag: Invalid data len %d proc %d",
+ data_len, proc_num);
+ break;
+ }
count_bytes = count_bytes+HDR_SIZ+data_len;
if (type == DIAG_CTRL_MSG_REG && r >= count_bytes) {
msg = buf+HDR_SIZ;
@@ -70,6 +146,10 @@
pkt_params->count = msg->count_entries;
temp = kzalloc(pkt_params->count * sizeof(struct
bindpkt_params), GFP_KERNEL);
+ if (temp == NULL) {
+ pr_alert("diag: Memory alloc fail\n");
+ return;
+ }
for (j = 0; j < pkt_params->count; j++) {
temp->cmd_code = msg->cmd_code;
temp->subsys_id = msg->subsysid;
@@ -93,11 +173,12 @@
kfree(pkt_params);
if (flag) {
/* Poll SMD CNTL channels to check for data */
- queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
- queue_work(driver->diag_wq,
- &(driver->diag_read_smd_qdsp_cntl_work));
- queue_work(driver->diag_wq,
- &(driver->diag_read_smd_wcnss_cntl_work));
+ if (proc_num == MODEM_PROC)
+ diag_smd_cntl_notify(NULL, SMD_EVENT_DATA);
+ else if (proc_num == QDSP_PROC)
+ diag_smd_qdsp_cntl_notify(NULL, SMD_EVENT_DATA);
+ else if (proc_num == WCNSS_PROC)
+ diag_smd_wcnss_cntl_notify(NULL, SMD_EVENT_DATA);
}
}
@@ -116,21 +197,6 @@
diag_smd_cntl_send_req(WCNSS_PROC);
}
-static void diag_smd_cntl_notify(void *ctxt, unsigned event)
-{
- queue_work(driver->diag_wq, &(driver->diag_read_smd_cntl_work));
-}
-
-static void diag_smd_qdsp_cntl_notify(void *ctxt, unsigned event)
-{
- queue_work(driver->diag_wq, &(driver->diag_read_smd_qdsp_cntl_work));
-}
-
-static void diag_smd_wcnss_cntl_notify(void *ctxt, unsigned event)
-{
- queue_work(driver->diag_wq, &(driver->diag_read_smd_wcnss_cntl_work));
-}
-
static int diag_smd_cntl_probe(struct platform_device *pdev)
{
int r = 0;
@@ -192,6 +258,7 @@
void diagfwd_cntl_init(void)
{
+ driver->polling_reg_flag = 0;
if (driver->buf_in_cntl == NULL) {
driver->buf_in_cntl = kzalloc(IN_BUF_SIZE, GFP_KERNEL);
if (driver->buf_in_cntl == NULL)
diff --git a/drivers/char/diag/diagfwd_cntl.h b/drivers/char/diag/diagfwd_cntl.h
index 542138d..a76d36d 100644
--- a/drivers/char/diag/diagfwd_cntl.h
+++ b/drivers/char/diag/diagfwd_cntl.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -13,7 +13,26 @@
#ifndef DIAGFWD_CNTL_H
#define DIAGFWD_CNTL_H
-#define DIAG_CTRL_MSG_REG 1 /* Message registration commands */
+/* Message registration commands */
+#define DIAG_CTRL_MSG_REG 1
+/* Message passing for DTR events */
+#define DIAG_CTRL_MSG_DTR 2
+/* Control Diag sleep vote, buffering etc */
+#define DIAG_CTRL_MSG_DIAGMODE 3
+/* Diag data based on "light" diag mask */
+#define DIAG_CTRL_MSG_DIAGDATA 4
+/* Deprecated */
+#define DIAG_CTRL_MSG_LOG_MASK 5
+#define DIAG_CTRL_MSG_EVENT_MASK 6
+#define DIAG_CTRL_MSG_F3_MASK 7
+/* Send diag internal feature mask 'diag_int_feature_mask' */
+#define DIAG_CTRL_MSG_FEATURE 8
+/* Send Diag log mask for a particular equip id */
+#define DIAG_CTRL_MSG_EQUIP_LOG_MASK 9
+/* Send Diag event mask */
+#define DIAG_CTRL_MSG_EVENT_MASK_V2 10
+/* Send Diag F3 mask */
+#define DIAG_CTRL_MSG_F3_MASK_V2 11
struct cmd_code_range {
uint16_t cmd_code_lo;
@@ -34,5 +53,8 @@
void diag_read_smd_cntl_work_fn(struct work_struct *);
void diag_read_smd_qdsp_cntl_work_fn(struct work_struct *);
void diag_read_smd_wcnss_cntl_work_fn(struct work_struct *);
+void diag_smd_cntl_notify(void *ctxt, unsigned event);
+void diag_smd_qdsp_cntl_notify(void *ctxt, unsigned event);
+void diag_smd_wcnss_cntl_notify(void *ctxt, unsigned event);
#endif
diff --git a/drivers/crypto/msm/qce40.c b/drivers/crypto/msm/qce40.c
index d725851..5276bcc 100644
--- a/drivers/crypto/msm/qce40.c
+++ b/drivers/crypto/msm/qce40.c
@@ -1,6 +1,6 @@
/* Qualcomm Crypto Engine driver.
*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011 - 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -42,6 +42,7 @@
#define DST_INDEX_SG_CMD(index) (index & 0x3fff)
#define ADM_DESC_LAST (1 << 31)
#define QCE_FIFO_SIZE 0x8000
+
/*
* CE HW device structure.
* Each engine has an instance of the structure.
@@ -128,6 +129,7 @@
{
unsigned int val;
unsigned int rev;
+ unsigned int ret;
val = (uint32_t)(*((uint32_t *)pce_dev->ce_dm.buffer.version));
if (((val & 0xfffffff) != 0x0000043) &&
@@ -144,6 +146,23 @@
"Qualcomm Crypto 4.2 device found at 0x%x\n",
pce_dev->phy_iobase);
pce_dev->ce_dm.ce_block_size = 64;
+
+ /* Configure the crypto register to support 64byte CRCI if it
+ * is not XPU protected and the HW version of device is greater
+ * than 0x42.
+ * Crypto config register returns a 0 when it is XPU protected.
+ */
+
+ ret = readl_relaxed(pce_dev->iobase + CRYPTO_CONFIG_REG);
+ if (ret) {
+ val = (CRYPTO_REQ_SIZE_ENUM_64_BYTES <<
+ CRYPTO_REQ_SIZE) |
+ (CRYPTO_FIFO_ENUM_64_BYTES <<
+ CRYPTO_FIFO_THRESHOLD);
+
+ writel_relaxed(val, pce_dev->iobase +
+ CRYPTO_CONFIG_REG);
+ } /* end of if (ret) */
} else {
if (rev == 0x40) {
dev_info(pce_dev->pdev,
@@ -152,12 +171,6 @@
pce_dev->ce_dm.ce_block_size = 16;
}
}
- /*
- * This is a temporary change - until Data Mover changes its
- * configuration from 16 byte crci to 64 byte crci.
- */
- if (cpu_is_msm9615())
- pce_dev->ce_dm.ce_block_size = 16;
dev_info(pce_dev->pdev,
"IO base 0x%x\n, ce_in channel %d , "
@@ -2609,4 +2622,4 @@
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Mona Hossain <mhossain@codeaurora.org>");
MODULE_DESCRIPTION("Crypto Engine driver");
-MODULE_VERSION("2.14");
+MODULE_VERSION("2.15");
diff --git a/drivers/gpu/ion/msm/msm_ion.c b/drivers/gpu/ion/msm/msm_ion.c
index 2a2892e..a81dbd3 100644
--- a/drivers/gpu/ion/msm/msm_ion.c
+++ b/drivers/gpu/ion/msm/msm_ion.c
@@ -91,7 +91,7 @@
const struct fmem_data *fmem_info =
fmem_get_info();
heap->base = fmem_info->phys -
- fmem_info->reserved_size;
+ fmem_info->reserved_size_low;
cp_data->virt_addr = fmem_info->virt;
pr_info("ION heap %s using FMEM\n",
shared_heap->name);
@@ -159,6 +159,10 @@
heap->base = fmem_info->phys;
data->virt_addr = fmem_info->virt;
pr_info("ION heap %s using FMEM\n", heap->name);
+ } else if (data->mem_is_fmem) {
+ const struct fmem_data *fmem_info =
+ fmem_get_info();
+ heap->base = fmem_info->phys + fmem_info->size;
}
align = data->align;
break;
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
index 06f4a14..79a0e0b 100644
--- a/drivers/gpu/msm/adreno.c
+++ b/drivers/gpu/msm/adreno.c
@@ -978,15 +978,6 @@
}
mutex_unlock(&kgsl_driver.process_mutex);
- BUG_ON(!mutex_is_locked(&device->mutex));
- list_for_each_entry(entry, &device->memqueue, list) {
- if (kgsl_gpuaddr_in_memdesc(&entry->memdesc, gpuaddr, size)) {
- result = &entry->memdesc;
- return result;
- }
-
- }
-
while (1) {
struct adreno_context *adreno_context = NULL;
context = idr_get_next(&device->context_idr, &next);
diff --git a/drivers/gpu/msm/adreno_ringbuffer.h b/drivers/gpu/msm/adreno_ringbuffer.h
index caedf26..0361387 100644
--- a/drivers/gpu/msm/adreno_ringbuffer.h
+++ b/drivers/gpu/msm/adreno_ringbuffer.h
@@ -64,7 +64,7 @@
#define GSL_RB_WRITE(ring, gpuaddr, data) \
do { \
- writel_relaxed(data, ring); \
+ *ring = data; \
wmb(); \
kgsl_cffdump_setmem(gpuaddr, data, 4); \
ring++; \
@@ -93,7 +93,7 @@
#define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */
#define GSL_RB_GET_READPTR(rb, data) \
do { \
- *(data) = readl_relaxed(&(rb)->memptrs->rptr); \
+ *(data) = rb->memptrs->rptr; \
} while (0)
#else
#define GSL_RB_CNTL_NO_UPDATE 0x1 /* disable */
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
index 1a0a17d..120b129 100644
--- a/drivers/gpu/msm/kgsl.c
+++ b/drivers/gpu/msm/kgsl.c
@@ -49,20 +49,20 @@
static struct ion_client *kgsl_ion_client;
-#ifdef CONFIG_GENLOCK
-
/**
* kgsl_add_event - Add a new timstamp event for the KGSL device
* @device - KGSL device for the new event
* @ts - the timestamp to trigger the event on
* @cb - callback function to call when the timestamp expires
* @priv - private data for the specific event type
+ * @owner - driver instance that owns this event
*
* @returns - 0 on success or error code on failure
*/
static int kgsl_add_event(struct kgsl_device *device, u32 ts,
- void (*cb)(struct kgsl_device *, void *, u32), void *priv)
+ void (*cb)(struct kgsl_device *, void *, u32), void *priv,
+ struct kgsl_device_private *owner)
{
struct kgsl_event *event;
struct list_head *n;
@@ -86,6 +86,7 @@
event->timestamp = ts;
event->priv = priv;
event->func = cb;
+ event->owner = owner;
/* Add the event in order to the list */
@@ -105,7 +106,36 @@
queue_work(device->work_queue, &device->ts_expired_ws);
return 0;
}
-#endif
+
+/**
+ * kgsl_cancel_events - Cancel all events for a process
+ * @device - KGSL device for the events to cancel
+ * @owner - driver instance that owns the events to cancel
+ *
+ */
+static void kgsl_cancel_events(struct kgsl_device *device,
+ struct kgsl_device_private *owner)
+{
+ struct kgsl_event *event, *event_tmp;
+ unsigned int cur = device->ftbl->readtimestamp(device,
+ KGSL_TIMESTAMP_RETIRED);
+
+ list_for_each_entry_safe(event, event_tmp, &device->events, list) {
+ if (event->owner != owner)
+ continue;
+ /*
+ * "cancel" the events by calling their callback.
+ * Currently, events are used for lock and memory
+ * management, so if the process is dying the right
+ * thing to do is release or free.
+ */
+ if (event->func)
+ event->func(device, event->priv, cur);
+
+ list_del(&event->list);
+ kfree(event);
+ }
+}
static inline struct kgsl_mem_entry *
kgsl_mem_entry_create(void)
@@ -227,44 +257,10 @@
idr_remove(&dev_priv->device->context_idr, id);
}
-/* to be called when a process is destroyed, this walks the memqueue and
- * frees any entryies that belong to the dying process
- */
-static void kgsl_memqueue_cleanup(struct kgsl_device *device,
- struct kgsl_process_private *private)
-{
- struct kgsl_mem_entry *entry, *entry_tmp;
-
- if (!private)
- return;
-
- BUG_ON(!mutex_is_locked(&device->mutex));
-
- list_for_each_entry_safe(entry, entry_tmp, &device->memqueue, list) {
- if (entry->priv == private) {
- list_del(&entry->list);
- kgsl_mem_entry_put(entry);
- }
- }
-}
-
-static void kgsl_memqueue_freememontimestamp(struct kgsl_device *device,
- struct kgsl_mem_entry *entry,
- uint32_t timestamp,
- enum kgsl_timestamp_type type)
-{
- BUG_ON(!mutex_is_locked(&device->mutex));
-
- entry->free_timestamp = timestamp;
-
- list_add_tail(&entry->list, &device->memqueue);
-}
-
static void kgsl_timestamp_expired(struct work_struct *work)
{
struct kgsl_device *device = container_of(work, struct kgsl_device,
ts_expired_ws);
- struct kgsl_mem_entry *entry, *entry_tmp;
struct kgsl_event *event, *event_tmp;
uint32_t ts_processed;
@@ -274,15 +270,6 @@
ts_processed = device->ftbl->readtimestamp(device,
KGSL_TIMESTAMP_RETIRED);
- /* Flush the freememontimestamp queue */
- list_for_each_entry_safe(entry, entry_tmp, &device->memqueue, list) {
- if (timestamp_cmp(ts_processed, entry->free_timestamp) < 0)
- break;
-
- list_del(&entry->list);
- kgsl_mem_entry_put(entry);
- }
-
/* Process expired events */
list_for_each_entry_safe(event, event_tmp, &device->events, list) {
if (timestamp_cmp(ts_processed, event->timestamp) < 0)
@@ -652,7 +639,7 @@
/* clean up any to-be-freed entries that belong to this
* process and this device
*/
- kgsl_memqueue_cleanup(device, private);
+ kgsl_cancel_events(device, dev_priv);
mutex_unlock(&device->mutex);
kfree(dev_priv);
@@ -997,6 +984,16 @@
return 0;
}
+static void kgsl_freemem_event_cb(struct kgsl_device *device,
+ void *priv, u32 timestamp)
+{
+ struct kgsl_mem_entry *entry = priv;
+ spin_lock(&entry->priv->mem_lock);
+ list_del(&entry->list);
+ spin_unlock(&entry->priv->mem_lock);
+ kgsl_mem_entry_put(entry);
+}
+
static long kgsl_ioctl_cmdstream_freememontimestamp(struct kgsl_device_private
*dev_priv, unsigned int cmd,
void *data)
@@ -1007,13 +1004,11 @@
spin_lock(&dev_priv->process_priv->mem_lock);
entry = kgsl_sharedmem_find(dev_priv->process_priv, param->gpuaddr);
- if (entry)
- list_del(&entry->list);
spin_unlock(&dev_priv->process_priv->mem_lock);
if (entry) {
- kgsl_memqueue_freememontimestamp(dev_priv->device, entry,
- param->timestamp, param->type);
+ result = kgsl_add_event(dev_priv->device, param->timestamp,
+ kgsl_freemem_event_cb, entry, dev_priv);
} else {
KGSL_DRV_ERR(dev_priv->device,
"invalid gpuaddr %08x\n", param->gpuaddr);
@@ -1763,6 +1758,7 @@
* @timestamp - Timestamp to trigger the event
* @data - User space buffer containing struct kgsl_genlock_event_priv
* @len - length of the userspace buffer
+ * @owner - driver instance that owns this event
* @returns 0 on success or error code on error
*
* Attack to a genlock handle and register an event to release the
@@ -1770,7 +1766,8 @@
*/
static int kgsl_add_genlock_event(struct kgsl_device *device,
- u32 timestamp, void __user *data, int len)
+ u32 timestamp, void __user *data, int len,
+ struct kgsl_device_private *owner)
{
struct kgsl_genlock_event_priv *event;
struct kgsl_timestamp_event_genlock priv;
@@ -1795,7 +1792,8 @@
return ret;
}
- ret = kgsl_add_event(device, timestamp, kgsl_genlock_event_cb, event);
+ ret = kgsl_add_event(device, timestamp, kgsl_genlock_event_cb, event,
+ owner);
if (ret)
kfree(event);
@@ -1803,7 +1801,8 @@
}
#else
static long kgsl_add_genlock_event(struct kgsl_device *device,
- u32 timestamp, void __user *data, int len)
+ u32 timestamp, void __user *data, int len,
+ struct kgsl_device_private *owner)
{
return -EINVAL;
}
@@ -1826,7 +1825,8 @@
switch (param->type) {
case KGSL_TIMESTAMP_EVENT_GENLOCK:
ret = kgsl_add_genlock_event(dev_priv->device,
- param->timestamp, param->priv, param->len);
+ param->timestamp, param->priv, param->len,
+ dev_priv);
break;
default:
ret = -EINVAL;
@@ -2183,7 +2183,6 @@
INIT_WORK(&device->idle_check_ws, kgsl_idle_check);
INIT_WORK(&device->ts_expired_ws, kgsl_timestamp_expired);
- INIT_LIST_HEAD(&device->memqueue);
INIT_LIST_HEAD(&device->events);
ret = kgsl_mmu_init(device);
diff --git a/drivers/gpu/msm/kgsl_device.h b/drivers/gpu/msm/kgsl_device.h
index 8ea5279..2fb1e43 100644
--- a/drivers/gpu/msm/kgsl_device.h
+++ b/drivers/gpu/msm/kgsl_device.h
@@ -126,6 +126,7 @@
void (*func)(struct kgsl_device *, void *, u32);
void *priv;
struct list_head list;
+ struct kgsl_device_private *owner;
};
@@ -154,7 +155,6 @@
uint32_t state;
uint32_t requested_state;
- struct list_head memqueue;
unsigned int active_cnt;
struct completion suspend_gate;
diff --git a/drivers/gpu/msm/kgsl_gpummu.c b/drivers/gpu/msm/kgsl_gpummu.c
index fe5677e..a16b954 100644
--- a/drivers/gpu/msm/kgsl_gpummu.c
+++ b/drivers/gpu/msm/kgsl_gpummu.c
@@ -382,15 +382,16 @@
kgsl_pt_map_set(struct kgsl_gpummu_pt *pt, uint32_t pte, uint32_t val)
{
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
-
- writel_relaxed(val, &baseptr[pte]);
+ BUG_ON(pte*sizeof(uint32_t) >= pt->base.size);
+ baseptr[pte] = val;
}
static inline uint32_t
kgsl_pt_map_get(struct kgsl_gpummu_pt *pt, uint32_t pte)
{
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
- return readl_relaxed(&baseptr[pte]) & GSL_PT_PAGE_ADDR_MASK;
+ BUG_ON(pte*sizeof(uint32_t) >= pt->base.size);
+ return baseptr[pte] & GSL_PT_PAGE_ADDR_MASK;
}
static unsigned int kgsl_gpummu_pt_get_flags(struct kgsl_pagetable *pt,
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.c b/drivers/gpu/msm/kgsl_pwrctrl.c
index 1ef71a4..ae50183 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.c
+++ b/drivers/gpu/msm/kgsl_pwrctrl.c
@@ -66,8 +66,17 @@
struct kgsl_pwrlevel *pwrlevel = &pwr->pwrlevels[new_level];
pwr->active_pwrlevel = new_level;
if ((test_bit(KGSL_PWRFLAGS_CLK_ON, &pwr->power_flags)) ||
- (device->state == KGSL_STATE_NAP))
+ (device->state == KGSL_STATE_NAP)) {
+ /*
+ * On some platforms, instability is caused on
+ * changing clock freq when the core is busy.
+ * Idle the gpu core before changing the clock freq.
+ */
+ if (pwr->idle_needed == true)
+ device->ftbl->idle(device,
+ KGSL_TIMEOUT_DEFAULT);
clk_set_rate(pwr->grp_clks[0], pwrlevel->gpu_freq);
+ }
if (test_bit(KGSL_PWRFLAGS_AXI_ON, &pwr->power_flags)) {
if (pwr->pcl)
msm_bus_scale_client_update_request(pwr->pcl,
@@ -499,6 +508,7 @@
pwr->power_flags = 0;
pwr->nap_allowed = pdata->nap_allowed;
+ pwr->idle_needed = pdata->idle_needed;
pwr->interval_timeout = pdata->idle_timeout;
pwr->ebi1_clk = clk_get(&pdev->dev, "bus_clk");
if (IS_ERR(pwr->ebi1_clk))
diff --git a/drivers/gpu/msm/kgsl_pwrctrl.h b/drivers/gpu/msm/kgsl_pwrctrl.h
index 23e2bd1..99dbae9 100644
--- a/drivers/gpu/msm/kgsl_pwrctrl.h
+++ b/drivers/gpu/msm/kgsl_pwrctrl.h
@@ -50,6 +50,7 @@
struct regulator *gpu_reg;
uint32_t pcl;
unsigned int nap_allowed;
+ unsigned int idle_needed;
const char *regulator_name;
const char *irq_name;
s64 time;
diff --git a/drivers/gpu/msm/kgsl_sharedmem.c b/drivers/gpu/msm/kgsl_sharedmem.c
index 7211879..389ed6d 100644
--- a/drivers/gpu/msm/kgsl_sharedmem.c
+++ b/drivers/gpu/msm/kgsl_sharedmem.c
@@ -636,13 +636,17 @@
uint32_t *dst,
unsigned int offsetbytes)
{
+ uint32_t *src;
BUG_ON(memdesc == NULL || memdesc->hostptr == NULL || dst == NULL);
- WARN_ON(offsetbytes + sizeof(unsigned int) > memdesc->size);
+ WARN_ON(offsetbytes % sizeof(uint32_t) != 0);
+ if (offsetbytes % sizeof(uint32_t) != 0)
+ return -EINVAL;
- if (offsetbytes + sizeof(unsigned int) > memdesc->size)
+ WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
+ if (offsetbytes + sizeof(uint32_t) > memdesc->size)
return -ERANGE;
-
- *dst = readl_relaxed(memdesc->hostptr + offsetbytes);
+ src = (uint32_t *)(memdesc->hostptr + offsetbytes);
+ *dst = *src;
return 0;
}
EXPORT_SYMBOL(kgsl_sharedmem_readl);
@@ -652,12 +656,19 @@
unsigned int offsetbytes,
uint32_t src)
{
+ uint32_t *dst;
BUG_ON(memdesc == NULL || memdesc->hostptr == NULL);
- BUG_ON(offsetbytes + sizeof(unsigned int) > memdesc->size);
+ WARN_ON(offsetbytes % sizeof(uint32_t) != 0);
+ if (offsetbytes % sizeof(uint32_t) != 0)
+ return -EINVAL;
+ WARN_ON(offsetbytes + sizeof(uint32_t) > memdesc->size);
+ if (offsetbytes + sizeof(uint32_t) > memdesc->size)
+ return -ERANGE;
kgsl_cffdump_setmem(memdesc->gpuaddr + offsetbytes,
- src, sizeof(uint));
- writel_relaxed(src, memdesc->hostptr + offsetbytes);
+ src, sizeof(uint32_t));
+ dst = (uint32_t *)(memdesc->hostptr + offsetbytes);
+ *dst = src;
return 0;
}
EXPORT_SYMBOL(kgsl_sharedmem_writel);
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
index c8b4707..4988313 100644
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -324,13 +324,13 @@
{
dev->clk_state = state;
if (state != 0) {
- clk_prepare_enable(dev->clk);
- clk_prepare_enable(dev->pclk);
+ clk_enable(dev->clk);
+ clk_enable(dev->pclk);
} else {
qup_update_state(dev, QUP_RESET_STATE);
- clk_disable_unprepare(dev->clk);
+ clk_disable(dev->clk);
qup_config_core_on_en(dev);
- clk_disable_unprepare(dev->pclk);
+ clk_disable(dev->pclk);
}
}
@@ -1285,6 +1285,8 @@
dev->suspended = 0;
mutex_init(&dev->mlock);
dev->clk_state = 0;
+ clk_prepare(dev->clk);
+ clk_prepare(dev->pclk);
setup_timer(&dev->pwr_timer, qup_i2c_pwr_timer, (unsigned long) dev);
pm_runtime_set_active(&pdev->dev);
@@ -1344,6 +1346,8 @@
}
free_irq(dev->err_irq, dev);
i2c_del_adapter(&dev->adapter);
+ clk_unprepare(dev->clk);
+ clk_unprepare(dev->pclk);
clk_put(dev->clk);
clk_put(dev->pclk);
qup_i2c_free_gpios(dev);
@@ -1378,6 +1382,8 @@
del_timer_sync(&dev->pwr_timer);
if (dev->clk_state != 0)
qup_i2c_pwr_mgmt(dev, 0);
+ clk_unprepare(dev->clk);
+ clk_unprepare(dev->pclk);
qup_i2c_free_gpios(dev);
return 0;
}
@@ -1387,6 +1393,8 @@
struct platform_device *pdev = to_platform_device(device);
struct qup_i2c_dev *dev = platform_get_drvdata(pdev);
BUG_ON(qup_i2c_request_gpios(dev) != 0);
+ clk_prepare(dev->clk);
+ clk_prepare(dev->pclk);
dev->suspended = 0;
return 0;
}
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index d2a8879..40aae69 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -18,7 +18,7 @@
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/i2c/atmel_mxt_ts.h>
-#include <linux/input.h>
+#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/gpio.h>
@@ -611,22 +611,23 @@
if (!finger[id].status)
continue;
- input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
- finger[id].status != MXT_RELEASE ?
- finger[id].area : 0);
- input_report_abs(input_dev, ABS_MT_POSITION_X,
- finger[id].x);
- input_report_abs(input_dev, ABS_MT_POSITION_Y,
- finger[id].y);
- input_report_abs(input_dev, ABS_MT_PRESSURE,
- finger[id].status != MXT_RELEASE ?
- finger[id].pressure : 0);
- input_mt_sync(input_dev);
+ input_mt_slot(input_dev, id);
+ input_mt_report_slot_state(input_dev, MT_TOOL_FINGER,
+ finger[id].status != MXT_RELEASE);
- if (finger[id].status == MXT_RELEASE)
- finger[id].status = 0;
- else
+ if (finger[id].status != MXT_RELEASE) {
finger_num++;
+ input_report_abs(input_dev, ABS_MT_TOUCH_MAJOR,
+ finger[id].area);
+ input_report_abs(input_dev, ABS_MT_POSITION_X,
+ finger[id].x);
+ input_report_abs(input_dev, ABS_MT_POSITION_Y,
+ finger[id].y);
+ input_report_abs(input_dev, ABS_MT_PRESSURE,
+ finger[id].area);
+ } else {
+ finger[id].status = 0;
+ }
}
input_report_key(input_dev, BTN_TOUCH, finger_num > 0);
@@ -1841,6 +1842,7 @@
0, 255, 0, 0);
/* For multi touch */
+ input_mt_init_slots(input_dev, MXT_MAX_FINGER);
input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR,
0, MXT_MAX_AREA, 0, 0);
input_set_abs_params(input_dev, ABS_MT_POSITION_X,
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index a60dbf5..267e481 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -710,25 +710,26 @@
else if (!(g_bl_data.bl_status & BL_CHECKSUM_MASK) &&
(appid_lo == ts->platform_data->correct_fw_ver))
fw_upgrade = 1;
- else
- if ((appid_hi == g_bl_data.appid_hi) &&
- (appid_lo == g_bl_data.appid_lo)) {
- if (appver_hi > g_bl_data.appver_hi) {
+ else if ((appid_hi == g_bl_data.appid_hi) &&
+ (appid_lo == g_bl_data.appid_lo))
+ if (appver_hi > g_bl_data.appver_hi)
fw_upgrade = 1;
- } else if ((appver_hi == g_bl_data.appver_hi) &&
- (appver_lo > g_bl_data.appver_lo)) {
- fw_upgrade = 1;
- } else {
- fw_upgrade = 0;
- pr_info("%s: Firmware version "
- "lesser/equal to existing firmware, "
- "upgrade not needed\n", __func__);
- }
- } else {
- fw_upgrade = 0;
- pr_info("%s: Firware versions do not match, "
- "cannot upgrade\n", __func__);
- }
+ else if ((appver_hi == g_bl_data.appver_hi) &&
+ (appver_lo > g_bl_data.appver_lo))
+ fw_upgrade = 1;
+ else {
+ fw_upgrade = 0;
+ pr_info("%s: Firmware version "
+ "lesser/equal to existing firmware, "
+ "upgrade not needed\n", __func__);
+ }
+ else if (appid_lo == ts->platform_data->correct_fw_ver)
+ fw_upgrade = 1;
+ else {
+ fw_upgrade = 0;
+ pr_info("%s: Firmware versions do not match, "
+ "cannot upgrade\n", __func__);
+ }
if (fw_upgrade) {
pr_info("%s: Starting firmware upgrade\n", __func__);
diff --git a/drivers/media/radio/radio-iris-transport.c b/drivers/media/radio/radio-iris-transport.c
index 57b11c9..ed6ab4d 100644
--- a/drivers/media/radio/radio-iris-transport.c
+++ b/drivers/media/radio/radio-iris-transport.c
@@ -4,7 +4,7 @@
* FM HCI_SMD ( FM HCI Shared Memory Driver) is Qualcomm's Shared memory driver
* for the HCI protocol. This file is based on drivers/bluetooth/hci_vhci.c
*
- * Copyright (c) 2000-2001, 2011 Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2000-2001, 2011-2012 Code Aurora Forum. All rights reserved.
*
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
@@ -25,6 +25,7 @@
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/skbuff.h>
+#include <linux/workqueue.h>
#include <mach/msm_smd.h>
#include <media/radio-iris.h>
@@ -35,6 +36,8 @@
};
struct radio_data hs;
+static struct work_struct *reset_worker;
+
static void radio_hci_smd_destruct(struct radio_hci_dev *hdev)
{
radio_hci_unregister_dev(hs.hdev);
@@ -92,6 +95,30 @@
return 0;
}
+
+static void send_disable_event(struct work_struct *worker)
+{
+ struct sk_buff *skb;
+ unsigned char buf[6] = { 0x0f, 0x04, 0x01, 0x02, 0x4c, 0x00 };
+ int len = sizeof(buf);
+
+ skb = alloc_skb(len, GFP_ATOMIC);
+ if (!skb) {
+ FMDERR("Memory not allocated for the socket");
+ return;
+ }
+
+ FMDERR("FM INSERT DISABLE Rx Event");
+
+ memcpy(skb_put(skb, len), buf, len);
+
+ skb_orphan(skb);
+ skb->dev = (struct net_device *)hs.hdev;
+
+ radio_hci_recv_frame(skb);
+ kfree(worker);
+}
+
static void radio_hci_smd_notify_cmd(void *data, unsigned int event)
{
struct radio_hci_dev *hdev = hs.hdev;
@@ -106,7 +133,15 @@
tasklet_schedule(&hs.rx_task);
break;
case SMD_EVENT_OPEN:
+ break;
case SMD_EVENT_CLOSE:
+ reset_worker = kzalloc(sizeof(*reset_worker), GFP_ATOMIC);
+ if (!reset_worker) {
+ FMDERR("Out of memory");
+ break;
+ }
+ INIT_WORK(reset_worker, send_disable_event);
+ schedule_work(reset_worker);
break;
default:
break;
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
index 545c61c..476300c 100644
--- a/drivers/media/radio/radio-iris.c
+++ b/drivers/media/radio/radio-iris.c
@@ -1589,7 +1589,7 @@
if (status)
return;
- iris_q_event(radio, IRIS_EVT_RADIO_READY);
+ iris_q_event(radio, IRIS_EVT_RADIO_DISABLED);
radio_hci_req_complete(hdev, status);
}
diff --git a/drivers/media/video/msm/Kconfig b/drivers/media/video/msm/Kconfig
index ca44c34..e70a0a5 100644
--- a/drivers/media/video/msm/Kconfig
+++ b/drivers/media/video/msm/Kconfig
@@ -33,8 +33,7 @@
MICRON 2M YUV Sensor
config IMX074
bool "Sensor IMX074 (BAYER 13.5M)"
- depends on MSM_CAMERA && (ARCH_MSM8X60 || ARCH_MSM8960)
- default y
+ depends on MSM_CAMERA
---help---
SONY 13.5 MP Bayer Sensor
config OV5640
@@ -43,6 +42,12 @@
default n
---help---
Omni 5M YUV Sensor
+
+config OV5647
+ bool "Sensor ov5647 (BAYER 5M)"
+ depends on MSM_CAMERA
+ ---help---
+ OV 5M Bayer Sensor with AutoFocus
config WEBCAM_OV7692_QRD
bool "Sensor OV7692 QRD(VGA YUV)"
depends on MSM_CAMERA && ARCH_MSM7X27A && !MSM_CAMERA_V4L2
@@ -51,7 +56,7 @@
Omni Vision VGA YUV Sensor for QRD Devices
config MT9M114
bool "Sensor MT9M114 (YUV 1.26M)"
- depends on MSM_CAMERA && ARCH_MSM8960
+ depends on MSM_CAMERA
---help---
APTINA 1.26 MP yuv Sensor
config WEBCAM_OV7692
@@ -120,8 +125,7 @@
config IMX074_ACT
bool "Actuator IMX074 (BAYER 13.5M)"
- depends on MSM_CAMERA && ARCH_MSM8960
- default y
+ depends on MSM_CAMERA
---help---
Actuator for SONY 13.5 MP Bayer Sensor
@@ -177,8 +181,7 @@
config OV2720
bool "Sensor ov2720 (Omnivision 2MP)"
- depends on MSM_CAMERA && ARCH_MSM8960
- default y
+ depends on MSM_CAMERA
config VB6801
bool "Sensor vb6801"
diff --git a/drivers/media/video/msm/Makefile b/drivers/media/video/msm/Makefile
index b91449a..8703669 100644
--- a/drivers/media/video/msm/Makefile
+++ b/drivers/media/video/msm/Makefile
@@ -44,6 +44,8 @@
obj-$(CONFIG_QS_S5K4E1) += qs_s5k4e1.o qs_s5k4e1_reg.o
obj-$(CONFIG_VB6801) += vb6801.o
obj-$(CONFIG_IMX072) += imx072.o imx072_reg.o
+obj-$(CONFIG_WEBCAM_OV9726) += ov9726.o ov9726_reg.o
+obj-$(CONFIG_OV5647) += ov5647.o ov5647_reg.o
obj-$(CONFIG_WEBCAM_OV7692) += ov7692.o
obj-$(CONFIG_WEBCAM_OV7692_QRD) += ov7692_qrd.o
obj-$(CONFIG_OV5640) += ov5640.o
diff --git a/drivers/media/video/msm/actuators/imx074_act.c b/drivers/media/video/msm/actuators/imx074_act.c
index e4d340d4..fab3a21 100644
--- a/drivers/media/video/msm/actuators/imx074_act.c
+++ b/drivers/media/video/msm/actuators/imx074_act.c
@@ -197,6 +197,11 @@
(struct v4l2_subdev *)sdev);
}
+static int imx074_act_power_down(void *act_info)
+{
+ return (int) msm_actuator_af_power_down(&imx074_act_t);
+}
+
static struct msm_actuator_ctrl_t imx074_act_t = {
.i2c_driver = &imx074_act_i2c_driver,
.i2c_addr = 0xE4,
@@ -205,6 +210,7 @@
.a_init_table = imx074_i2c_add_driver_table,
.a_create_subdevice = imx074_act_create_subdevice,
.a_config = imx074_act_config,
+ .a_power_down = imx074_act_power_down,
},
.i2c_client = {
diff --git a/drivers/media/video/msm/csi/msm_csiphy.c b/drivers/media/video/msm/csi/msm_csiphy.c
index 109b3dd..315cca7 100644
--- a/drivers/media/video/msm/csi/msm_csiphy.c
+++ b/drivers/media/video/msm/csi/msm_csiphy.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -79,21 +79,14 @@
msm_io_w(0x1, csiphybase + MIPI_CSIPHY_T_WAKEUP_CFG0_ADDR);
for (i = 0; i < csiphy_params->lane_cnt; i++) {
- msm_io_w(0x00, csiphybase + MIPI_CSIPHY_LNn_CFG1_ADDR + 0x40*i);
- msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
+ msm_io_w(0x10, csiphybase + MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
msm_io_w(csiphy_params->settle_cnt,
csiphybase + MIPI_CSIPHY_LNn_CFG3_ADDR + 0x40*i);
- msm_io_w(0x00000052,
- csiphybase + MIPI_CSIPHY_LNn_CFG5_ADDR + 0x40*i);
}
- msm_io_w(0x00000000, csiphybase + MIPI_CSIPHY_LNCK_CFG1_ADDR);
- msm_io_w(0x5F, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
+ msm_io_w(0x10, csiphybase + MIPI_CSIPHY_LNCK_CFG2_ADDR);
msm_io_w(csiphy_params->settle_cnt,
csiphybase + MIPI_CSIPHY_LNCK_CFG3_ADDR);
- msm_io_w(0x5, csiphybase + MIPI_CSIPHY_LNCK_CFG4_ADDR);
- msm_io_w(0x2, csiphybase + MIPI_CSIPHY_LNCK_CFG5_ADDR);
- msm_io_w(0x0, csiphybase + 0x128);
msm_io_w(0x24,
csiphybase + MIPI_CSIPHY_INTERRUPT_MASK0_ADDR);
diff --git a/drivers/media/video/msm/io/Makefile b/drivers/media/video/msm/io/Makefile
index 584738d..c567be2 100644
--- a/drivers/media/video/msm/io/Makefile
+++ b/drivers/media/video/msm/io/Makefile
@@ -1,3 +1,4 @@
GCC_VERSION := $(shell $(CONFIG_SHELL) $(PWD)/scripts/gcc-version.sh $(CROSS_COMPILE)gcc)
-obj-$(CONFIG_MSM_CAMERA) += msm_camera_i2c.o msm_camera_eeprom.o
+EXTRA_CFLAGS += -Idrivers/media/video/msm
+obj-$(CONFIG_MSM_CAMERA) += msm_camera_i2c.o msm_camera_eeprom.o msm_camera_i2c_mux.o
obj-$(CONFIG_MSM_CAMERA) += msm_io_util.o
diff --git a/drivers/media/video/msm/io/msm_camera_i2c_mux.c b/drivers/media/video/msm/io/msm_camera_i2c_mux.c
new file mode 100644
index 0000000..ad3128b
--- /dev/null
+++ b/drivers/media/video/msm/io/msm_camera_i2c_mux.c
@@ -0,0 +1,186 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/board.h>
+#include <mach/camera.h>
+#include "msm.h"
+#include "msm_camera_i2c_mux.h"
+
+static int msm_i2c_mux_config(struct i2c_mux_device *mux_device, uint8_t *mode)
+{
+ uint32_t val;
+ val = msm_io_r(mux_device->ctl_base);
+ if (*mode == MODE_DUAL) {
+ msm_io_w(val | 0x3, mux_device->ctl_base);
+ } else if (*mode == MODE_L) {
+ msm_io_w(((val | 0x2) & ~(0x1)), mux_device->ctl_base);
+ val = msm_io_r(mux_device->ctl_base);
+ CDBG("the camio mode config left value is %d\n", val);
+ } else {
+ msm_io_w(((val | 0x1) & ~(0x2)), mux_device->ctl_base);
+ val = msm_io_r(mux_device->ctl_base);
+ CDBG("the camio mode config right value is %d\n", val);
+ }
+ return 0;
+}
+
+static int msm_i2c_mux_init(struct i2c_mux_device *mux_device)
+{
+ int rc = 0, val = 0;
+ if (mux_device->use_count == 0) {
+ mux_device->ctl_base = ioremap(mux_device->ctl_mem->start,
+ resource_size(mux_device->ctl_mem));
+ if (!mux_device->ctl_base) {
+ rc = -ENOMEM;
+ return rc;
+ }
+ mux_device->rw_base = ioremap(mux_device->rw_mem->start,
+ resource_size(mux_device->rw_mem));
+ if (!mux_device->rw_base) {
+ rc = -ENOMEM;
+ iounmap(mux_device->ctl_base);
+ return rc;
+ }
+ val = msm_io_r(mux_device->rw_base);
+ msm_io_w((val | 0x200), mux_device->rw_base);
+ }
+ mux_device->use_count++;
+ return 0;
+};
+
+static int msm_i2c_mux_release(struct i2c_mux_device *mux_device)
+{
+ int val = 0;
+ mux_device->use_count--;
+ if (mux_device->use_count == 0) {
+ val = msm_io_r(mux_device->rw_base);
+ msm_io_w((val & ~0x200), mux_device->rw_base);
+ iounmap(mux_device->rw_base);
+ iounmap(mux_device->ctl_base);
+ }
+ return 0;
+}
+
+static long msm_i2c_mux_subdev_ioctl(struct v4l2_subdev *sd,
+ unsigned int cmd, void *arg)
+{
+ struct i2c_mux_device *mux_device;
+ int rc = 0;
+ mux_device = v4l2_get_subdevdata(sd);
+ if (mux_device == NULL) {
+ rc = -ENOMEM;
+ return rc;
+ }
+ mutex_lock(&mux_device->mutex);
+ switch (cmd) {
+ case VIDIOC_MSM_I2C_MUX_CFG:
+ rc = msm_i2c_mux_config(mux_device, (uint8_t *) arg);
+ break;
+ case VIDIOC_MSM_I2C_MUX_INIT:
+ rc = msm_i2c_mux_init(mux_device);
+ break;
+ case VIDIOC_MSM_I2C_MUX_RELEASE:
+ rc = msm_i2c_mux_release(mux_device);
+ break;
+ default:
+ rc = -ENOIOCTLCMD;
+ }
+ mutex_unlock(&mux_device->mutex);
+ return rc;
+}
+
+static struct v4l2_subdev_core_ops msm_i2c_mux_subdev_core_ops = {
+ .ioctl = &msm_i2c_mux_subdev_ioctl,
+};
+
+static const struct v4l2_subdev_ops msm_i2c_mux_subdev_ops = {
+ .core = &msm_i2c_mux_subdev_core_ops,
+};
+
+static int __devinit i2c_mux_probe(struct platform_device *pdev)
+{
+ struct i2c_mux_device *mux_device;
+ int rc = 0;
+ CDBG("%s: device id = %d\n", __func__, pdev->id);
+ mux_device = kzalloc(sizeof(struct i2c_mux_device), GFP_KERNEL);
+ if (!mux_device) {
+ pr_err("%s: no enough memory\n", __func__);
+ return -ENOMEM;
+ }
+
+ v4l2_subdev_init(&mux_device->subdev, &msm_i2c_mux_subdev_ops);
+ v4l2_set_subdevdata(&mux_device->subdev, mux_device);
+ platform_set_drvdata(pdev, &mux_device->subdev);
+ mutex_init(&mux_device->mutex);
+
+ mux_device->ctl_mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "i2c_mux_ctl");
+ if (!mux_device->ctl_mem) {
+ pr_err("%s: no mem resource?\n", __func__);
+ rc = -ENODEV;
+ goto i2c_mux_no_resource;
+ }
+ mux_device->ctl_io = request_mem_region(mux_device->ctl_mem->start,
+ resource_size(mux_device->ctl_mem), pdev->name);
+ if (!mux_device->ctl_io) {
+ pr_err("%s: no valid mem region\n", __func__);
+ rc = -EBUSY;
+ goto i2c_mux_no_resource;
+ }
+ mux_device->rw_mem = platform_get_resource_byname(pdev,
+ IORESOURCE_MEM, "i2c_mux_rw");
+ if (!mux_device->rw_mem) {
+ pr_err("%s: no mem resource?\n", __func__);
+ rc = -ENODEV;
+ goto i2c_mux_no_resource;
+ }
+ mux_device->rw_io = request_mem_region(mux_device->rw_mem->start,
+ resource_size(mux_device->rw_mem), pdev->name);
+ if (!mux_device->rw_io) {
+ pr_err("%s: no valid mem region\n", __func__);
+ rc = -EBUSY;
+ goto i2c_mux_no_resource;
+ }
+ mux_device->pdev = pdev;
+ return 0;
+
+i2c_mux_no_resource:
+ mutex_destroy(&mux_device->mutex);
+ kfree(mux_device);
+ return 0;
+}
+
+static struct platform_driver i2c_mux_driver = {
+ .probe = i2c_mux_probe,
+ .driver = {
+ .name = MSM_I2C_MUX_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_camera_i2c_mux_init_module(void)
+{
+ return platform_driver_register(&i2c_mux_driver);
+}
+
+static void __exit msm_camera_i2c_mux_exit_module(void)
+{
+ platform_driver_unregister(&i2c_mux_driver);
+}
+
+module_init(msm_camera_i2c_mux_init_module);
+module_exit(msm_camera_i2c_mux_exit_module);
+MODULE_DESCRIPTION("MSM Camera I2C mux driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/io/msm_camera_i2c_mux.h b/drivers/media/video/msm/io/msm_camera_i2c_mux.h
new file mode 100644
index 0000000..94394fc
--- /dev/null
+++ b/drivers/media/video/msm/io/msm_camera_i2c_mux.h
@@ -0,0 +1,46 @@
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MSM_I2C_MUX_H
+#define MSM_I2C_MUX_H
+
+#include <linux/io.h>
+#include <media/v4l2-subdev.h>
+
+struct i2c_mux_device {
+ struct platform_device *pdev;
+ struct v4l2_subdev subdev;
+ struct resource *ctl_mem;
+ struct resource *ctl_io;
+ void __iomem *ctl_base;
+ struct resource *rw_mem;
+ struct resource *rw_io;
+ void __iomem *rw_base;
+ struct mutex mutex;
+ unsigned use_count;
+};
+
+struct i2c_mux_cfg_params {
+ struct v4l2_subdev *subdev;
+ void *parms;
+};
+
+#define VIDIOC_MSM_I2C_MUX_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 13, struct i2c_mux_cfg_params)
+
+#define VIDIOC_MSM_I2C_MUX_INIT \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 14, struct v4l2_subdev*)
+
+#define VIDIOC_MSM_I2C_MUX_RELEASE \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 15, struct v4l2_subdev*)
+
+#endif
diff --git a/drivers/media/video/msm/msm.c b/drivers/media/video/msm/msm.c
index ed77185..84d441d 100644
--- a/drivers/media/video/msm/msm.c
+++ b/drivers/media/video/msm/msm.c
@@ -157,7 +157,7 @@
D("Waiting for config status\n");
rc = wait_event_interruptible_timeout(queue->wait,
!list_empty_careful(&queue->list),
- out->timeout_ms);
+ msecs_to_jiffies(out->timeout_ms));
D("Waiting is over for config status\n");
if (list_empty_careful(&queue->list)) {
if (!rc)
diff --git a/drivers/media/video/msm/msm.h b/drivers/media/video/msm/msm.h
index 40bc160..55c0da1 100644
--- a/drivers/media/video/msm/msm.h
+++ b/drivers/media/video/msm/msm.h
@@ -48,6 +48,7 @@
#define MSM_VFE_DRV_NAME "msm_vfe"
#define MSM_VPE_DRV_NAME "msm_vpe"
#define MSM_GEMINI_DRV_NAME "msm_gemini"
+#define MSM_I2C_MUX_DRV_NAME "msm_cam_i2c_mux"
/* msm queue management APIs*/
diff --git a/drivers/media/video/msm/msm_io_8960.c b/drivers/media/video/msm/msm_io_8960.c
index d111452..ea969cf 100644
--- a/drivers/media/video/msm/msm_io_8960.c
+++ b/drivers/media/video/msm/msm_io_8960.c
@@ -32,11 +32,6 @@
static struct clk *camio_imem_clk;
static struct regulator *fs_ijpeg;
-static struct platform_device *camio_dev;
-static struct resource *s3drw_io, *s3dctl_io;
-static struct resource *s3drw_mem, *s3dctl_mem;
-void __iomem *s3d_rw, *s3d_ctl;
-
void msm_io_w(u32 data, void __iomem *addr)
{
CDBG("%s: %08x %08x\n", __func__, (int) (addr), (data));
@@ -234,89 +229,6 @@
return rc;
}
-int32_t msm_camio_3d_enable(const struct msm_camera_sensor_info *s_info)
-{
- int32_t val = 0, rc = 0;
- char s3drw[] = "s3d_rw";
- char s3dctl[] = "s3d_ctl";
- struct platform_device *pdev = camio_dev;
- pdev->resource = s_info->resource;
- pdev->num_resources = s_info->num_resources;
-
- s3drw_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, s3drw);
- if (!s3drw_mem) {
- pr_err("%s: no mem resource?\n", __func__);
- return -ENODEV;
- }
- s3dctl_mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, s3dctl);
- if (!s3dctl_mem) {
- pr_err("%s: no mem resource?\n", __func__);
- return -ENODEV;
- }
- s3drw_io = request_mem_region(s3drw_mem->start,
- resource_size(s3drw_mem), pdev->name);
- if (!s3drw_io)
- return -EBUSY;
-
- s3d_rw = ioremap(s3drw_mem->start,
- resource_size(s3drw_mem));
- if (!s3d_rw) {
- rc = -ENOMEM;
- goto s3drw_nomem;
- }
- s3dctl_io = request_mem_region(s3dctl_mem->start,
- resource_size(s3dctl_mem), pdev->name);
- if (!s3dctl_io) {
- rc = -EBUSY;
- goto s3dctl_busy;
- }
- s3d_ctl = ioremap(s3dctl_mem->start,
- resource_size(s3dctl_mem));
- if (!s3d_ctl) {
- rc = -ENOMEM;
- goto s3dctl_nomem;
- }
-
- val = msm_io_r(s3d_rw);
- msm_io_w((val | 0x200), s3d_rw);
- return rc;
-
-s3dctl_nomem:
- release_mem_region(s3dctl_mem->start, resource_size(s3dctl_mem));
-s3dctl_busy:
- iounmap(s3d_rw);
-s3drw_nomem:
- release_mem_region(s3drw_mem->start, resource_size(s3drw_mem));
-return rc;
-}
-
-void msm_camio_3d_disable(void)
-{
- int32_t val = 0;
- msm_io_w((val & ~0x200), s3d_rw);
- iounmap(s3d_ctl);
- release_mem_region(s3dctl_mem->start, resource_size(s3dctl_mem));
- iounmap(s3d_rw);
- release_mem_region(s3drw_mem->start, resource_size(s3drw_mem));
-}
-
-void msm_camio_mode_config(enum msm_cam_mode mode)
-{
- uint32_t val;
- val = msm_io_r(s3d_ctl);
- if (mode == MODE_DUAL) {
- msm_io_w(val | 0x3, s3d_ctl);
- } else if (mode == MODE_L) {
- msm_io_w(((val | 0x2) & ~(0x1)), s3d_ctl);
- val = msm_io_r(s3d_ctl);
- CDBG("the camio mode config left value is %d\n", val);
- } else {
- msm_io_w(((val | 0x1) & ~(0x2)), s3d_ctl);
- val = msm_io_r(s3d_ctl);
- CDBG("the camio mode config right value is %d\n", val);
- }
-}
-
void msm_camio_bus_scale_cfg(struct msm_bus_scale_pdata *cam_bus_scale_table,
enum msm_bus_perf_setting perf_setting)
{
diff --git a/drivers/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index 89bdf0f..b539d19 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -598,6 +598,14 @@
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CFG);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_MODULE_CFG);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_PIXEL_IF_CFG);
+ if (msm_io_r(vfe32_ctrl->vfebase + V32_GET_HW_VERSION_OFF) ==
+ VFE33_HW_NUMBER) {
+ msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_RDI0_CFG);
+ msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_RDI1_CFG);
+ } else {
+ ++p;
+ ++p;
+ }
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_REALIGN_BUF);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_CHROMA_UP);
msm_io_w(*(++p), vfe32_ctrl->vfebase + VFE_STATS_CFG);
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index 62c3639..0d8be58 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -223,7 +223,7 @@
#define V32_OUT_CLAMP_OFF 0x00000524
#define V32_OUT_CLAMP_LEN 8
-#define V32_OPERATION_CFG_LEN 36
+#define V32_OPERATION_CFG_LEN 44
#define V32_AXI_OUT_OFF 0x00000038
#define V32_AXI_OUT_LEN 216
@@ -875,6 +875,9 @@
#define VFE_DMI_DATA_LO 0x000005A4
#define VFE_BUS_IO_FORMAT_CFG 0x000006F8
#define VFE_PIXEL_IF_CFG 0x000006FC
+#define VFE_RDI0_CFG 0x00000734
+#define VFE_RDI1_CFG 0x000007A4
+
#define VFE_VIOLATION_STATUS 0x000007B4
#define VFE33_DMI_DATA_HI 0x000005A0
diff --git a/drivers/media/video/msm/ov5647.c b/drivers/media/video/msm/ov5647.c
new file mode 100644
index 0000000..2a6e7be
--- /dev/null
+++ b/drivers/media/video/msm/ov5647.c
@@ -0,0 +1,1201 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/debugfs.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/bitops.h>
+#include <linux/leds.h>
+#include <mach/camera.h>
+#include <media/msm_camera.h>
+#include "ov5647.h"
+
+/* 16bit address - 8 bit context register structure */
+#define Q8 0x00000100
+#define Q10 0x00000400
+
+#define REG_OV5647_GAIN_MSB 0x350A
+#define REG_OV5647_GAIN_LSB 0x350B
+#define REG_OV5647_LINE_HSB 0x3500
+#define REG_OV5647_LINE_MSB 0x3501
+#define REG_OV5647_LINE_LSB 0x3502
+
+/* MCLK */
+#define OV5647_MASTER_CLK_RATE 24000000
+
+/* AF Total steps parameters */
+#define OV5647_TOTAL_STEPS_NEAR_TO_FAR 32
+
+#define OV5647_REG_PREV_FRAME_LEN_1 31
+#define OV5647_REG_PREV_FRAME_LEN_2 32
+#define OV5647_REG_PREV_LINE_LEN_1 33
+#define OV5647_REG_PREV_LINE_LEN_2 34
+
+#define OV5647_REG_SNAP_FRAME_LEN_1 15
+#define OV5647_REG_SNAP_FRAME_LEN_2 16
+#define OV5647_REG_SNAP_LINE_LEN_1 17
+#define OV5647_REG_SNAP_LINE_LEN_2 18
+#define MSB 1
+#define LSB 0
+
+/* Debug switch */
+#ifdef CDBG
+#undef CDBG
+#endif
+#ifdef CDBG_HIGH
+#undef CDBG_HIGH
+#endif
+
+/*#define OV5647_VERBOSE_DGB*/
+
+#ifdef OV5647_VERBOSE_DGB
+#define CDBG(fmt, args...) pr_debug(fmt, ##args)
+#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
+#else
+#define CDBG(fmt, args...) do { } while (0)
+#define CDBG_HIGH(fmt, args...) pr_debug(fmt, ##args)
+#endif
+
+/*for debug*/
+#ifdef CDBG
+#undef CDBG
+#endif
+#define CDBG(fmt, args...) printk(fmt, ##args)
+
+static uint8_t mode_mask = 0x09;
+struct ov5647_work_t {
+ struct work_struct work;
+};
+
+static struct ov5647_work_t *ov5647_sensorw;
+static struct ov5647_work_t *ov5647_af_sensorw;
+static struct i2c_client *ov5647_af_client;
+static struct i2c_client *ov5647_client;
+
+struct ov5647_ctrl_t {
+ const struct msm_camera_sensor_info *sensordata;
+
+ uint32_t sensormode;
+ uint32_t fps_divider;/* init to 1 * 0x00000400 */
+ uint32_t pict_fps_divider;/* init to 1 * 0x00000400 */
+ uint16_t fps;
+
+ uint16_t curr_lens_pos;
+ uint16_t curr_step_pos;
+ uint16_t my_reg_gain;
+ uint32_t my_reg_line_count;
+ uint16_t total_lines_per_frame;
+
+ enum ov5647_resolution_t prev_res;
+ enum ov5647_resolution_t pict_res;
+ enum ov5647_resolution_t curr_res;
+ enum ov5647_test_mode_t set_test;
+};
+
+static bool CSI_CONFIG;
+static struct ov5647_ctrl_t *ov5647_ctrl;
+
+static DECLARE_WAIT_QUEUE_HEAD(ov5647_wait_queue);
+static DECLARE_WAIT_QUEUE_HEAD(ov5647_af_wait_queue);
+DEFINE_MUTEX(ov5647_mut);
+
+static uint16_t prev_line_length_pck;
+static uint16_t prev_frame_length_lines;
+static uint16_t snap_line_length_pck;
+static uint16_t snap_frame_length_lines;
+
+static int ov5647_i2c_rxdata(unsigned short saddr,
+ unsigned char *rxdata, int length)
+{
+ struct i2c_msg msgs[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = 2,
+ .buf = rxdata,
+ },
+ {
+ .addr = saddr,
+ .flags = I2C_M_RD,
+ .len = 1,
+ .buf = rxdata,
+ },
+ };
+ if (i2c_transfer(ov5647_client->adapter, msgs, 2) < 0) {
+ CDBG("ov5647_i2c_rxdata faild 0x%x\n", saddr);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int32_t ov5647_i2c_txdata(unsigned short saddr,
+ unsigned char *txdata, int length)
+{
+ struct i2c_msg msg[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = length,
+ .buf = txdata,
+ },
+ };
+ if (i2c_transfer(ov5647_client->adapter, msg, 1) < 0) {
+ CDBG("ov5647_i2c_txdata faild 0x%x\n", saddr);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int32_t ov5647_i2c_read(unsigned short raddr,
+ unsigned short *rdata)
+{
+ int32_t rc = 0;
+ unsigned char buf[2];
+
+ if (!rdata)
+ return -EIO;
+ CDBG("%s:saddr:0x%x raddr:0x%x data:0x%x",
+ __func__, ov5647_client->addr, raddr, *rdata);
+ memset(buf, 0, sizeof(buf));
+ buf[0] = (raddr & 0xFF00) >> 8;
+ buf[1] = (raddr & 0x00FF);
+ rc = ov5647_i2c_rxdata(ov5647_client->addr >> 1, buf, 1);
+ if (rc < 0) {
+ CDBG("ov5647_i2c_read 0x%x failed!\n", raddr);
+ return rc;
+ }
+ *rdata = buf[0];
+ CDBG("ov5647_i2c_read 0x%x val = 0x%x!\n", raddr, *rdata);
+
+ return rc;
+}
+
+static int32_t ov5647_i2c_write_b_sensor(unsigned short waddr, uint8_t bdata)
+{
+ int32_t rc = -EFAULT;
+ unsigned char buf[3];
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = (waddr & 0xFF00) >> 8;
+ buf[1] = (waddr & 0x00FF);
+ buf[2] = bdata;
+ CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+ rc = ov5647_i2c_txdata(ov5647_client->addr >> 1, buf, 3);
+ if (rc < 0) {
+ pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+ waddr, bdata);
+ }
+ return rc;
+}
+
+static int32_t ov5647_i2c_write_b_table(struct ov5647_i2c_reg_conf const
+ *reg_conf_tbl, int num)
+{
+ int i;
+ int32_t rc = -EIO;
+
+ for (i = 0; i < num; i++) {
+ rc = ov5647_i2c_write_b_sensor(reg_conf_tbl->waddr,
+ reg_conf_tbl->wdata);
+ if (rc < 0)
+ break;
+ reg_conf_tbl++;
+ }
+ return rc;
+}
+
+static int32_t ov5647_af_i2c_txdata(unsigned short saddr,
+ unsigned char *txdata, int length)
+{
+ struct i2c_msg msg[] = {
+ {
+ .addr = saddr,
+ .flags = 0,
+ .len = length,
+ .buf = txdata,
+ },
+ };
+ if (i2c_transfer(ov5647_af_client->adapter, msg, 1) < 0) {
+ pr_err("ov5647_af_i2c_txdata faild 0x%x\n", saddr);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int32_t ov5647_af_i2c_write_b_sensor(uint8_t waddr, uint8_t bdata)
+{
+ int32_t rc = -EFAULT;
+ unsigned char buf[2];
+
+ memset(buf, 0, sizeof(buf));
+ buf[0] = waddr;
+ buf[1] = bdata;
+ CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
+ rc = ov5647_af_i2c_txdata(ov5647_af_client->addr, buf, 2);
+ if (rc < 0) {
+ pr_err("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
+ waddr, bdata);
+ }
+ return rc;
+}
+
+static void ov5647_start_stream(void)
+{
+ CDBG("CAMERA_DBG: 0x4202 0x0, stream on...\r\n");
+ ov5647_i2c_write_b_sensor(0x4202, 0x00);/* streaming on */
+}
+
+static void ov5647_stop_stream(void)
+{
+ CDBG("CAMERA_DBG: 0x4202 0xf, stream off...\r\n");
+ ov5647_i2c_write_b_sensor(0x4202, 0x0f);/* streaming off */
+}
+
+static void ov5647_group_hold_on(void)
+{
+ ov5647_i2c_write_b_sensor(0x0104, 0x01);
+}
+
+static void ov5647_group_hold_off(void)
+{
+ ov5647_i2c_write_b_sensor(0x0104, 0x0);
+}
+
+static void ov5647_get_pict_fps(uint16_t fps, uint16_t *pfps)
+{
+ /* input fps is preview fps in Q8 format */
+ uint32_t divider, d1, d2;
+ uint32_t preview_pclk = 0x37, snapshot_pclk = 0x4f;
+
+ d1 = (prev_frame_length_lines * 0x00000400) / snap_frame_length_lines;
+ d2 = (prev_line_length_pck * 0x00000400) / snap_line_length_pck;
+ divider = (d1 * d2*preview_pclk/snapshot_pclk) / 0x400;
+ CDBG(KERN_ERR "ov5647_get_pict_fps divider = %d", divider);
+ /*Verify PCLK settings and frame sizes.*/
+ *pfps = (uint16_t) (fps * divider / 0x400);
+}
+
+static uint16_t ov5647_get_prev_lines_pf(void)
+{
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ return prev_frame_length_lines;
+ else
+ return snap_frame_length_lines;
+}
+
+static uint16_t ov5647_get_prev_pixels_pl(void)
+{
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ return prev_line_length_pck;
+ else
+ return snap_line_length_pck;
+}
+
+static uint16_t ov5647_get_pict_lines_pf(void)
+{
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ return prev_frame_length_lines;
+ else
+ return snap_frame_length_lines;
+}
+
+static uint16_t ov5647_get_pict_pixels_pl(void)
+{
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ return prev_line_length_pck;
+ else
+ return snap_line_length_pck;
+}
+
+static uint32_t ov5647_get_pict_max_exp_lc(void)
+{
+ return snap_frame_length_lines * 24;
+}
+
+static int32_t ov5647_set_fps(struct fps_cfg *fps)
+{
+ uint16_t total_lines_per_frame;
+ int32_t rc = 0;
+
+ ov5647_ctrl->fps_divider = fps->fps_div;
+ ov5647_ctrl->pict_fps_divider = fps->pict_fps_div;
+
+ if (ov5647_ctrl->sensormode == SENSOR_PREVIEW_MODE) {
+ total_lines_per_frame = (uint16_t)
+ ((prev_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
+ } else {
+ total_lines_per_frame = (uint16_t)
+ ((snap_frame_length_lines * ov5647_ctrl->fps_divider) / 0x400);
+ }
+
+ ov5647_group_hold_on();
+ rc = ov5647_i2c_write_b_sensor(0x0340,
+ ((total_lines_per_frame & 0xFF00) >> 8));
+ rc = ov5647_i2c_write_b_sensor(0x0341,
+ (total_lines_per_frame & 0x00FF));
+ ov5647_group_hold_off();
+
+ return rc;
+}
+
+static inline uint8_t ov5647_byte(uint16_t word, uint8_t offset)
+{
+ return word >> (offset * BITS_PER_BYTE);
+}
+
+static int32_t ov5647_write_exp_gain(uint16_t gain, uint32_t line)
+{
+ int rc = 0;
+ uint16_t max_line;
+ u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+ uint8_t gain_lsb, gain_hsb;
+ ov5647_ctrl->my_reg_gain = gain;
+ ov5647_ctrl->my_reg_line_count = (uint16_t)line;
+
+ CDBG(KERN_ERR "preview exposure setting 0x%x, 0x%x, %d",
+ gain, line, line);
+
+ gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
+ gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
+ /* adjust frame rate */
+ if (line > 980) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)((line+4) >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)((line+4) & 0x00FF)) ;
+ max_line = line + 4;
+ } else if (max_line > 984) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)(984 >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)(984 & 0x00FF)) ;
+ max_line = 984;
+ }
+
+ line = line<<4;
+ /* ov5647 need this operation */
+ intg_time_hsb = (u8)(line>>16);
+ intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+ intg_time_lsb = (u8) (line & 0x00FF);
+
+ ov5647_group_hold_on();
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
+ ov5647_group_hold_off();
+
+ return rc;
+}
+
+
+static int32_t ov5647_set_pict_exp_gain(uint16_t gain, uint32_t line)
+{
+ uint16_t max_line;
+ int rc = 0;
+ uint8_t gain_lsb, gain_hsb;
+ u8 intg_time_hsb, intg_time_msb, intg_time_lsb;
+
+ ov5647_ctrl->my_reg_gain = gain;
+ ov5647_ctrl->my_reg_line_count = (uint16_t)line;
+
+ gain_lsb = (uint8_t) (ov5647_ctrl->my_reg_gain);
+ gain_hsb = (uint8_t)((ov5647_ctrl->my_reg_gain & 0x300)>>8);
+
+ CDBG(KERN_ERR "snapshot exposure seting 0x%x, 0x%x, %d"
+ , gain, line, line);
+
+ if (line > 1964) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)((line+4) >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)((line+4) & 0x00FF)) ;
+ max_line = line + 4;
+ } else if (max_line > 1968) {
+ rc = ov5647_i2c_write_b_sensor(0x380E,
+ (uint8_t)(1968 >> 8)) ;
+ rc = ov5647_i2c_write_b_sensor(0x380F,
+ (uint8_t)(1968 & 0x00FF)) ;
+ max_line = 1968;
+ }
+ line = line<<4;
+ /* ov5647 need this operation */
+ intg_time_hsb = (u8)(line>>16);
+ intg_time_msb = (u8) ((line & 0xFF00) >> 8);
+ intg_time_lsb = (u8) (line & 0x00FF);
+
+ /* FIXME for BLC trigger */
+ ov5647_group_hold_on();
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb - 1) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_HSB, intg_time_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_MSB, intg_time_msb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_LINE_LSB, intg_time_lsb) ;
+
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_MSB, gain_hsb) ;
+ rc = ov5647_i2c_write_b_sensor(REG_OV5647_GAIN_LSB, gain_lsb) ;
+ ov5647_group_hold_off();
+
+ msleep(500);
+ return rc;
+
+}
+
+static int32_t ov5647_move_focus(int direction, int32_t num_steps)
+{
+ uint8_t code_val_msb = 0;
+ uint8_t code_val_lsb = 0;
+ int16_t step_direction, actual_step, next_position;
+ int rc;
+
+ if (num_steps == 0)
+ return 0;
+
+ if (direction == MOVE_NEAR)
+ step_direction = 20;
+ else if (direction == MOVE_FAR)
+ step_direction = -20;
+ else
+ return -EINVAL;
+
+ actual_step = (int16_t)(step_direction * num_steps);
+ next_position = (int16_t)ov5647_ctrl->curr_lens_pos + actual_step;
+ if (next_position < 0) {
+ CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
+ __func__, next_position);
+ next_position = 0;
+ }
+ if (next_position > 0x3FF) {
+ CDBG(KERN_ERR "%s: OV5647 position(=%d) out of range",
+ __func__, next_position);
+ next_position = 0x3FF;
+ }
+ ov5647_ctrl->curr_lens_pos = next_position;
+
+ code_val_msb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4);
+ code_val_lsb = (uint8_t)((ov5647_ctrl->curr_lens_pos & 0x000F) << 4);
+ code_val_lsb |= mode_mask;
+
+ rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
+ /* DAC Setting */
+ if (rc != 0) {
+ CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+ } else {
+ CDBG(KERN_ERR "%s: Successful lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+ /* delay may set based on the steps moved
+ when I2C write successful */
+ msleep(100);
+ }
+ return 0;
+}
+
+static int32_t ov5647_set_default_focus(uint8_t af_step)
+{
+ uint8_t code_val_msb = 0;
+ uint8_t code_val_lsb = 0;
+ int rc = 0;
+
+ ov5647_ctrl->curr_lens_pos = 200;
+
+
+ code_val_msb = (ov5647_ctrl->curr_lens_pos & 0x03FF) >> 4;
+ code_val_lsb = (ov5647_ctrl->curr_lens_pos & 0x000F) << 4;
+ code_val_lsb |= mode_mask;
+
+ CDBG(KERN_ERR "ov5647_set_default_focus:lens pos = %d",
+ ov5647_ctrl->curr_lens_pos);
+ rc = ov5647_af_i2c_write_b_sensor(code_val_msb, code_val_lsb);
+ /* DAC Setting */
+ if (rc != 0)
+ CDBG(KERN_ERR "%s: WRITE ERROR lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+ else
+ CDBG(KERN_ERR "%s: WRITE successful lsb = 0x%x, msb = 0x%x",
+ __func__, code_val_lsb, code_val_msb);
+
+ usleep_range(10000, 11000);
+ return 0;
+}
+
+static int32_t ov5647_test(enum ov5647_test_mode_t mo)
+{
+ int32_t rc = 0;
+
+ if (mo != TEST_OFF)
+ rc = ov5647_i2c_write_b_sensor(0x0601, (uint8_t) mo);
+
+ return rc;
+}
+
+static void ov5647_reset_sensor(void)
+{
+ ov5647_i2c_write_b_sensor(0x103, 0x1);
+}
+
+
+static int32_t ov5647_sensor_setting(int update_type, int rt)
+{
+
+ int32_t rc = 0;
+ struct msm_camera_csi_params ov5647_csi_params;
+
+ ov5647_stop_stream();
+
+ /* wait for clk/data really stop */
+ if ((rt == RES_CAPTURE) || (CSI_CONFIG == 0))
+ msleep(66);
+ else
+ msleep(266);
+
+ CDBG("CAMERA_DBG1: 0x4800 regVal:0x25\r\n");
+ ov5647_i2c_write_b_sensor(0x4800, 0x25);/* streaming off */
+
+ usleep_range(10000, 11000);
+
+ if (update_type == REG_INIT) {
+ ov5647_reset_sensor();
+ ov5647_i2c_write_b_table(ov5647_regs.rec_settings,
+ ov5647_regs.rec_size);
+ CSI_CONFIG = 0;
+ } else if (update_type == UPDATE_PERIODIC) {
+ /* turn off flash when preview */
+
+ if (rt == RES_PREVIEW) {
+ ov5647_i2c_write_b_table(ov5647_regs.reg_prev,
+ ov5647_regs.reg_prev_size);
+ CDBG("CAMERA_DBG:preview settings...\r\n");
+ } else {
+ ov5647_i2c_write_b_table(ov5647_regs.reg_snap,
+ ov5647_regs.reg_snap_size);
+ CDBG("CAMERA_DBG:snapshot settings...\r\n");
+ }
+
+ msleep(20);
+ if (!CSI_CONFIG) {
+ msm_camio_vfe_clk_rate_set(192000000);
+ ov5647_csi_params.data_format = CSI_8BIT;
+ ov5647_csi_params.lane_cnt = 2;
+ ov5647_csi_params.lane_assign = 0xe4;
+ ov5647_csi_params.dpcm_scheme = 0;
+ ov5647_csi_params.settle_cnt = 10;
+ rc = msm_camio_csi_config(&ov5647_csi_params);
+ msleep(20);
+ CSI_CONFIG = 1;
+ /* exit powerdown state */
+ ov5647_i2c_write_b_sensor(0x0100, 0x01);
+ }
+ CDBG("CAMERA_DBG: 0x4800 regVal:0x04\r\n");
+ /* streaming on */
+ ov5647_i2c_write_b_sensor(0x4800, 0x04);
+ msleep(266);
+ ov5647_start_stream();
+ msleep(30);
+ }
+ return rc;
+}
+
+static int32_t ov5647_video_config(int mode)
+{
+ int32_t rc = 0;
+ int rt;
+ CDBG("video config\n");
+ /* change sensor resolution if needed */
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ rt = RES_PREVIEW;
+ else
+ rt = RES_CAPTURE;
+ if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+ return rc;
+ if (ov5647_ctrl->set_test) {
+ if (ov5647_test(ov5647_ctrl->set_test) < 0)
+ return rc;
+ }
+
+ ov5647_ctrl->curr_res = ov5647_ctrl->prev_res;
+ ov5647_ctrl->sensormode = mode;
+ return rc;
+}
+
+static int32_t ov5647_snapshot_config(int mode)
+{
+ int32_t rc = 0;
+ int rt;
+
+ /*change sensor resolution if needed */
+ if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ rt = RES_PREVIEW;
+ else
+ rt = RES_CAPTURE;
+ if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+ return rc;
+ }
+
+ ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
+ ov5647_ctrl->sensormode = mode;
+ return rc;
+}
+
+static int32_t ov5647_raw_snapshot_config(int mode)
+{
+ int32_t rc = 0;
+ int rt;
+
+ /* change sensor resolution if needed */
+ if (ov5647_ctrl->curr_res != ov5647_ctrl->pict_res) {
+ if (ov5647_ctrl->pict_res == QTR_SIZE)
+ rt = RES_PREVIEW;
+ else
+ rt = RES_CAPTURE;
+ if (ov5647_sensor_setting(UPDATE_PERIODIC, rt) < 0)
+ return rc;
+ }
+
+ ov5647_ctrl->curr_res = ov5647_ctrl->pict_res;
+ ov5647_ctrl->sensormode = mode;
+ return rc;
+}
+
+static int32_t ov5647_set_sensor_mode(int mode,
+ int res)
+{
+ int32_t rc = 0;
+
+ switch (mode) {
+ case SENSOR_PREVIEW_MODE:
+ rc = ov5647_video_config(mode);
+ break;
+ case SENSOR_SNAPSHOT_MODE:
+ rc = ov5647_snapshot_config(mode);
+ break;
+ case SENSOR_RAW_SNAPSHOT_MODE:
+ rc = ov5647_raw_snapshot_config(mode);
+ break;
+ default:
+ rc = -EINVAL;
+ break;
+ }
+ return rc;
+}
+
+static int32_t ov5647_power_down(void)
+{
+ ov5647_stop_stream();
+ return 0;
+}
+
+static int ov5647_probe_init_done(const struct msm_camera_sensor_info *data)
+{
+ CDBG("probe done\n");
+ gpio_direction_output(data->sensor_pwd, 1);
+ return 0;
+}
+
+static int ov5647_probe_init_sensor(const struct msm_camera_sensor_info *data)
+{
+ int32_t rc = 0;
+ uint16_t regaddress1 = 0x300a;
+ uint16_t regaddress2 = 0x300b;
+ uint16_t chipid1 = 0;
+ uint16_t chipid2 = 0;
+
+ CDBG("%s: %d\n", __func__, __LINE__);
+
+ gpio_direction_output(data->sensor_pwd, 0);
+ usleep_range(4000, 4100);
+ gpio_direction_output(data->sensor_reset, 1);
+ usleep_range(2000, 2100);
+
+ ov5647_i2c_read(regaddress1, &chipid1);
+ if (chipid1 != 0x56) {
+ rc = -ENODEV;
+ pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
+ goto init_probe_fail;
+ }
+
+ ov5647_i2c_read(regaddress2, &chipid2);
+ if (chipid2 != 0x47) {
+ rc = -ENODEV;
+ pr_err("ov5647_probe_init_sensor fail chip id doesnot match\n");
+ goto init_probe_fail;
+ }
+
+ pr_err("ID1: 0x%x\n", chipid1);
+ pr_err("ID2: 0x%x\n", chipid2);
+ goto init_probe_done;
+
+init_probe_fail:
+ pr_err(" ov5647_probe_init_sensor fails\n");
+ ov5647_probe_init_done(data);
+ return rc;
+init_probe_done:
+ pr_debug(" ov5647_probe_init_sensor finishes\n");
+ gpio_direction_output(data->sensor_pwd, 1);
+ return rc;
+}
+
+
+static int ov5647_sensor_open_init(const struct msm_camera_sensor_info *data)
+{
+ int32_t rc = 0;
+
+ CDBG("%s: %d\n", __func__, __LINE__);
+ CDBG("Calling ov5647_sensor_open_init\n");
+
+ ov5647_ctrl = kzalloc(sizeof(struct ov5647_ctrl_t), GFP_KERNEL);
+ if (!ov5647_ctrl) {
+ CDBG("ov5647_init failed!\n");
+ rc = -ENOMEM;
+ goto init_done;
+ }
+ ov5647_ctrl->fps_divider = 1 * 0x00000400;
+ ov5647_ctrl->pict_fps_divider = 1 * 0x00000400;
+ ov5647_ctrl->set_test = TEST_OFF;
+ ov5647_ctrl->prev_res = QTR_SIZE;
+ ov5647_ctrl->pict_res = FULL_SIZE;
+
+ if (data)
+ ov5647_ctrl->sensordata = data;
+
+ prev_frame_length_lines = 0x3d8;
+
+ prev_line_length_pck = 0x768*2;
+
+ snap_frame_length_lines = 0x7b0;
+
+ snap_line_length_pck = 0xa8c;
+
+ /* enable mclk first */
+ msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
+
+ gpio_direction_output(data->sensor_pwd, 1);
+ gpio_direction_output(data->sensor_reset, 0);
+ usleep_range(10000, 11000);
+ /* power on camera ldo and vreg */
+ if (ov5647_ctrl->sensordata->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
+ usleep_range(10000, 11000); /*waiting for ldo stable*/
+ gpio_direction_output(data->sensor_pwd, 0);
+ msleep(20);
+ gpio_direction_output(data->sensor_reset, 1);
+ msleep(25);
+
+ CDBG("init settings\n");
+ if (ov5647_ctrl->prev_res == QTR_SIZE)
+ rc = ov5647_sensor_setting(REG_INIT, RES_PREVIEW);
+ else
+ rc = ov5647_sensor_setting(REG_INIT, RES_CAPTURE);
+ ov5647_ctrl->fps = 30 * Q8;
+
+ /* enable AF actuator */
+ if (ov5647_ctrl->sensordata->vcm_enable) {
+ CDBG("enable AF actuator, gpio = %d\n",
+ ov5647_ctrl->sensordata->vcm_pwd);
+ rc = gpio_request(ov5647_ctrl->sensordata->vcm_pwd,
+ "ov5647_af");
+ if (!rc)
+ gpio_direction_output(
+ ov5647_ctrl->sensordata->vcm_pwd,
+ 1);
+ else {
+ pr_err("ov5647_ctrl gpio request failed!\n");
+ goto init_fail;
+ }
+ msleep(20);
+ rc = ov5647_set_default_focus(0);
+ if (rc < 0) {
+ gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd,
+ 0);
+ gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
+ }
+ }
+ if (rc < 0)
+ goto init_fail;
+ else
+ goto init_done;
+init_fail:
+ CDBG("init_fail\n");
+ ov5647_probe_init_done(data);
+ /* No need to power OFF camera ldo and vreg
+ affects Display while resume */
+init_done:
+ CDBG("init_done\n");
+ return rc;
+}
+
+static int ov5647_i2c_remove(struct i2c_client *client)
+{
+ return 0;
+}
+
+static int ov5647_init_client(struct i2c_client *client)
+{
+ /* Initialize the MSM_CAMI2C Chip */
+ init_waitqueue_head(&ov5647_wait_queue);
+ return 0;
+}
+
+static int ov5647_af_init_client(struct i2c_client *client)
+{
+ /* Initialize the MSM_CAMI2C Chip */
+ init_waitqueue_head(&ov5647_af_wait_queue);
+ return 0;
+}
+
+static const struct i2c_device_id ov5647_af_i2c_id[] = {
+ {"ov5647_af", 0},
+ { }
+};
+
+static int ov5647_af_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ CDBG("ov5647_af_probe called!\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ CDBG("i2c_check_functionality failed\n");
+ goto probe_failure;
+ }
+
+ ov5647_af_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
+ if (!ov5647_af_sensorw) {
+ CDBG("kzalloc failed.\n");
+ rc = -ENOMEM;
+ goto probe_failure;
+ }
+
+ i2c_set_clientdata(client, ov5647_af_sensorw);
+ ov5647_af_init_client(client);
+ ov5647_af_client = client;
+
+ msleep(50);
+
+ CDBG("ov5647_af_probe successed! rc = %d\n", rc);
+ return 0;
+
+probe_failure:
+ CDBG("ov5647_af_probe failed! rc = %d\n", rc);
+ return rc;
+}
+
+static const struct i2c_device_id ov5647_i2c_id[] = {
+ {"ov5647", 0}, {}
+};
+
+static int ov5647_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int rc = 0;
+ CDBG("ov5647_probe called!\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ CDBG("i2c_check_functionality failed\n");
+ goto probe_failure;
+ }
+
+ ov5647_sensorw = kzalloc(sizeof(struct ov5647_work_t), GFP_KERNEL);
+ if (!ov5647_sensorw) {
+ CDBG("kzalloc failed.\n");
+ rc = -ENOMEM;
+ goto probe_failure;
+ }
+
+ i2c_set_clientdata(client, ov5647_sensorw);
+ ov5647_init_client(client);
+ ov5647_client = client;
+
+ msleep(50);
+
+ CDBG("ov5647_probe successed! rc = %d\n", rc);
+ return 0;
+
+probe_failure:
+ CDBG("ov5647_probe failed! rc = %d\n", rc);
+ return rc;
+}
+
+static int __devexit ov5647_remove(struct i2c_client *client)
+{
+ struct ov5647_work_t *sensorw = i2c_get_clientdata(client);
+ free_irq(client->irq, sensorw);
+ ov5647_client = NULL;
+ kfree(sensorw);
+ return 0;
+}
+
+static int __devexit ov5647_af_remove(struct i2c_client *client)
+{
+ struct ov5647_work_t *ov5647_af = i2c_get_clientdata(client);
+ free_irq(client->irq, ov5647_af);
+ ov5647_af_client = NULL;
+ kfree(ov5647_af);
+ return 0;
+}
+
+static struct i2c_driver ov5647_i2c_driver = {
+ .id_table = ov5647_i2c_id,
+ .probe = ov5647_i2c_probe,
+ .remove = ov5647_i2c_remove,
+ .driver = {
+ .name = "ov5647",
+ },
+};
+
+static struct i2c_driver ov5647_af_i2c_driver = {
+ .id_table = ov5647_af_i2c_id,
+ .probe = ov5647_af_i2c_probe,
+ .remove = __exit_p(ov5647_af_i2c_remove),
+ .driver = {
+ .name = "ov5647_af",
+ },
+};
+
+int ov5647_sensor_config(void __user *argp)
+{
+ struct sensor_cfg_data cdata;
+ long rc = 0;
+ if (copy_from_user(&cdata,
+ (void *)argp,
+ sizeof(struct sensor_cfg_data)))
+ return -EFAULT;
+ mutex_lock(&ov5647_mut);
+ CDBG("ov5647_sensor_config: cfgtype = %d\n",
+ cdata.cfgtype);
+ switch (cdata.cfgtype) {
+ case CFG_GET_PICT_FPS:
+ ov5647_get_pict_fps(
+ cdata.cfg.gfps.prevfps,
+ &(cdata.cfg.gfps.pictfps));
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PREV_L_PF:
+ cdata.cfg.prevl_pf =
+ ov5647_get_prev_lines_pf();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PREV_P_PL:
+ cdata.cfg.prevp_pl =
+ ov5647_get_prev_pixels_pl();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PICT_L_PF:
+ cdata.cfg.pictl_pf =
+ ov5647_get_pict_lines_pf();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PICT_P_PL:
+ cdata.cfg.pictp_pl =
+ ov5647_get_pict_pixels_pl();
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_GET_PICT_MAX_EXP_LC:
+ cdata.cfg.pict_max_exp_lc =
+ ov5647_get_pict_max_exp_lc();
+
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_SET_FPS:
+ case CFG_SET_PICT_FPS:
+ rc = ov5647_set_fps(&(cdata.cfg.fps));
+ break;
+ case CFG_SET_EXP_GAIN:
+ rc = ov5647_write_exp_gain(cdata.cfg.exp_gain.gain,
+ cdata.cfg.exp_gain.line);
+ break;
+ case CFG_SET_PICT_EXP_GAIN:
+ rc = ov5647_set_pict_exp_gain(cdata.cfg.exp_gain.gain,
+ cdata.cfg.exp_gain.line);
+ break;
+ case CFG_SET_MODE:
+ rc = ov5647_set_sensor_mode(cdata.mode, cdata.rs);
+ break;
+ case CFG_PWR_DOWN:
+ rc = ov5647_power_down();
+ break;
+ case CFG_MOVE_FOCUS:
+ rc = ov5647_move_focus(cdata.cfg.focus.dir,
+ cdata.cfg.focus.steps);
+ break;
+ case CFG_SET_DEFAULT_FOCUS:
+ rc = ov5647_set_default_focus(cdata.cfg.focus.steps);
+ break;
+
+ case CFG_GET_AF_MAX_STEPS:
+ cdata.max_steps = OV5647_TOTAL_STEPS_NEAR_TO_FAR;
+ if (copy_to_user((void *)argp,
+ &cdata,
+ sizeof(struct sensor_cfg_data)))
+ rc = -EFAULT;
+ break;
+ case CFG_SET_EFFECT:
+ rc = ov5647_set_default_focus(cdata.cfg.effect);
+ break;
+ default:
+ rc = -EFAULT;
+ break;
+ }
+ mutex_unlock(&ov5647_mut);
+
+ return rc;
+}
+
+static int ov5647_sensor_release(void)
+{
+ int rc = -EBADF;
+ unsigned short rdata;
+
+ mutex_lock(&ov5647_mut);
+ ov5647_power_down();
+ msleep(20);
+ ov5647_i2c_read(0x3018, &rdata);
+ rdata |= 0x18; /*set bit 3 bit 4 to 1*/
+ ov5647_i2c_write_b_sensor(0x3018, rdata);/*write back*/
+ msleep(20);
+
+ gpio_set_value(ov5647_ctrl->sensordata->sensor_pwd, 1);
+ usleep_range(5000, 5100);
+ if (ov5647_ctrl->sensordata->vcm_enable) {
+ gpio_direction_output(ov5647_ctrl->sensordata->vcm_pwd, 0);
+ gpio_free(ov5647_ctrl->sensordata->vcm_pwd);
+ }
+
+ /* No need to power OFF camera ldo and vreg
+ affects Display while resume */
+
+ kfree(ov5647_ctrl);
+ ov5647_ctrl = NULL;
+ CDBG("ov5647_release completed\n");
+ mutex_unlock(&ov5647_mut);
+
+ return rc;
+}
+
+static int ov5647_sensor_probe(const struct msm_camera_sensor_info *info,
+ struct msm_sensor_ctrl *s)
+{
+ int rc = 0;
+
+ CDBG("%s E\n", __func__);
+
+ gpio_direction_output(info->sensor_pwd, 1);
+ gpio_direction_output(info->sensor_reset, 0);
+ usleep_range(1000, 1100);
+ /* turn on ldo and vreg */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
+
+ rc = i2c_add_driver(&ov5647_i2c_driver);
+ if (rc < 0 || ov5647_client == NULL) {
+ rc = -ENOTSUPP;
+ CDBG("I2C add driver ov5647 failed");
+ goto probe_fail_2;
+ }
+ if (info->vcm_enable) {
+ rc = i2c_add_driver(&ov5647_af_i2c_driver);
+ if (rc < 0 || ov5647_af_client == NULL) {
+ rc = -ENOTSUPP;
+ CDBG("I2C add driver ov5647 af failed");
+ goto probe_fail_3;
+ }
+ }
+ msm_camio_clk_rate_set(OV5647_MASTER_CLK_RATE);
+
+ rc = ov5647_probe_init_sensor(info);
+ if (rc < 0)
+ goto probe_fail_1;
+
+ s->s_init = ov5647_sensor_open_init;
+ s->s_release = ov5647_sensor_release;
+ s->s_config = ov5647_sensor_config;
+ s->s_mount_angle = info->sensor_platform_info->mount_angle;
+ gpio_set_value(info->sensor_pwd, 1);
+ ov5647_probe_init_done(info);
+ /* turn off ldo and vreg */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
+
+ CDBG("%s X", __func__);
+ return rc;
+
+probe_fail_3:
+ i2c_del_driver(&ov5647_af_i2c_driver);
+probe_fail_2:
+ i2c_del_driver(&ov5647_i2c_driver);
+probe_fail_1:
+ /* turn off ldo and vreg */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
+ CDBG("ov5647_sensor_probe: SENSOR PROBE FAILS!\n");
+ CDBG("%s X", __func__);
+ return rc;
+}
+
+static int __devinit ov5647_probe(struct platform_device *pdev)
+{
+ return msm_camera_drv_start(pdev, ov5647_sensor_probe);
+}
+
+static struct platform_driver msm_camera_driver = {
+ .probe = ov5647_probe,
+ .driver = {
+ .name = "msm_camera_ov5647",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ov5647_init(void)
+{
+ return platform_driver_register(&msm_camera_driver);
+}
+
+module_init(ov5647_init);
+MODULE_DESCRIPTION("Omnivision 5 MP Bayer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/msm/ov5647.h b/drivers/media/video/msm/ov5647.h
new file mode 100644
index 0000000..b43f15c
--- /dev/null
+++ b/drivers/media/video/msm/ov5647.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef OV5647_H
+#define OV5647_H
+#include <linux/types.h>
+#include <mach/board.h>
+
+extern struct ov5647_reg ov5647_regs;
+extern int lcd_camera_power_onoff(int on);
+extern struct rw_semaphore leds_list_lock;
+extern struct list_head leds_list;
+
+struct ov5647_i2c_reg_conf {
+ unsigned short waddr;
+ unsigned short wdata;
+};
+
+enum ov5647_test_mode_t {
+ TEST_OFF,
+ TEST_1,
+ TEST_2,
+ TEST_3
+};
+
+enum ov5647_resolution_t {
+ QTR_SIZE,
+ FULL_SIZE,
+ INVALID_SIZE
+};
+enum ov5647_setting {
+ RES_PREVIEW,
+ RES_CAPTURE
+};
+enum ov5647_reg_update {
+ /* Sensor egisters that need to be updated during initialization */
+ REG_INIT,
+ /* Sensor egisters that needs periodic I2C writes */
+ UPDATE_PERIODIC,
+ /* All the sensor Registers will be updated */
+ UPDATE_ALL,
+ /* Not valid update */
+ UPDATE_INVALID
+};
+
+enum ov5647_reg_pll {
+ E013_VT_PIX_CLK_DIV,
+ E013_VT_SYS_CLK_DIV,
+ E013_PRE_PLL_CLK_DIV,
+ E013_PLL_MULTIPLIER,
+ E013_OP_PIX_CLK_DIV,
+ E013_OP_SYS_CLK_DIV
+};
+
+enum ov5647_reg_mode {
+ E013_X_ADDR_START,
+ E013_X_ADDR_END,
+ E013_Y_ADDR_START,
+ E013_Y_ADDR_END,
+ E013_X_OUTPUT_SIZE,
+ E013_Y_OUTPUT_SIZE,
+ E013_DATAPATH_SELECT,
+ E013_READ_MODE,
+ E013_ANALOG_CONTROL5,
+ E013_DAC_LD_4_5,
+ E013_SCALING_MODE,
+ E013_SCALE_M,
+ E013_LINE_LENGTH_PCK,
+ E013_FRAME_LENGTH_LINES,
+ E013_COARSE_INTEGRATION_TIME,
+ E013_FINE_INTEGRATION_TIME,
+ E013_FINE_CORRECTION
+};
+
+struct ov5647_reg {
+ const struct ov5647_i2c_reg_conf *rec_settings;
+ const unsigned short rec_size;
+ const struct ov5647_i2c_reg_conf *reg_prev;
+ const unsigned short reg_prev_size;
+ const struct ov5647_i2c_reg_conf *reg_snap;
+ const unsigned short reg_snap_size;
+};
+#endif /* OV5647_H */
diff --git a/drivers/media/video/msm/ov5647_reg.c b/drivers/media/video/msm/ov5647_reg.c
new file mode 100644
index 0000000..4a0fed4
--- /dev/null
+++ b/drivers/media/video/msm/ov5647_reg.c
@@ -0,0 +1,219 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#include "ov5647.h"
+struct ov5647_i2c_reg_conf ov5647_prev_settings[] = {
+ /*1280*960 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps
+ for back to preview*/
+ {0x3035, 0x21},
+ {0x3036, 0x37},
+ {0x3821, 0x07},
+ {0x3820, 0x41},
+ {0x3612, 0x09},
+ {0x3618, 0x00},
+ {0x380c, 0x07},
+ {0x380d, 0x68},
+ {0x380e, 0x03},
+ {0x380f, 0xd8},
+ {0x3814, 0x31},
+ {0x3815, 0x31},
+ {0x3709, 0x52},
+ {0x3808, 0x05},
+ {0x3809, 0x00},
+ {0x380a, 0x03},
+ {0x380b, 0xc0},
+ {0x3800, 0x00},
+ {0x3801, 0x18},
+ {0x3802, 0x00},
+ {0x3803, 0x0e},
+ {0x3804, 0x0a},
+ {0x3805, 0x27},
+ {0x3806, 0x07},
+ {0x3807, 0x95},
+ {0x4004, 0x02},
+};
+
+struct ov5647_i2c_reg_conf ov5647_snap_settings[] = {
+ /*2608*1952 Reference Setting 24M MCLK 2lane 280Mbps/lane 30fps*/
+ {0x3035, 0x21},
+ {0x3036, 0x4f},
+ {0x3821, 0x06},
+ {0x3820, 0x00},
+ {0x3612, 0x0b},
+ {0x3618, 0x04},
+ {0x380c, 0x0a},
+ {0x380d, 0x8c},
+ {0x380e, 0x07},
+ {0x380f, 0xb0},
+ {0x3814, 0x11},
+ {0x3815, 0x11},
+ {0x3709, 0x12},
+ {0x3808, 0x0a},
+ {0x3809, 0x30},
+ {0x380a, 0x07},
+ {0x380b, 0xa0},
+ {0x3800, 0x00},
+ {0x3801, 0x04},
+ {0x3802, 0x00},
+ {0x3803, 0x00},
+ {0x3804, 0x0a},
+ {0x3805, 0x3b},
+ {0x3806, 0x07},
+ {0x3807, 0xa3},
+ {0x4004, 0x04},
+};
+
+struct ov5647_i2c_reg_conf ov5647_recommend_settings[] = {
+ {0x3035, 0x11},
+ {0x303c, 0x11},
+ {0x370c, 0x03},
+ {0x5000, 0x06},
+ {0x5003, 0x08},
+ {0x5a00, 0x08},
+ {0x3000, 0xff},
+ {0x3001, 0xff},
+ {0x3002, 0xff},
+ {0x301d, 0xf0},
+ {0x3a18, 0x00},
+ {0x3a19, 0xf8},
+ {0x3c01, 0x80},
+ {0x3b07, 0x0c},
+ {0x3708, 0x64},
+ {0x3630, 0x2e},
+ {0x3632, 0xe2},
+ {0x3633, 0x23},
+ {0x3634, 0x44},
+ {0x3620, 0x64},
+ {0x3621, 0xe0},
+ {0x3600, 0x37},
+ {0x3704, 0xa0},
+ {0x3703, 0x5a},
+ {0x3715, 0x78},
+ {0x3717, 0x01},
+ {0x3731, 0x02},
+ {0x370b, 0x60},
+ {0x3705, 0x1a},
+ {0x3f05, 0x02},
+ {0x3f06, 0x10},
+ {0x3f01, 0x0a},
+ {0x3a08, 0x01},
+ {0x3a0f, 0x58},
+ {0x3a10, 0x50},
+ {0x3a1b, 0x58},
+ {0x3a1e, 0x50},
+ {0x3a11, 0x60},
+ {0x3a1f, 0x28},
+ {0x4001, 0x02},
+ {0x4000, 0x09},
+ {0x3000, 0x00},
+ {0x3001, 0x00},
+ {0x3002, 0x00},
+ {0x3017, 0xe0},
+ {0x301c, 0xfc},
+ {0x3636, 0x06},
+ {0x3016, 0x08},
+ {0x3827, 0xec},
+ {0x3018, 0x44},
+ {0x3035, 0x21},
+ {0x3106, 0xf5},
+ {0x3034, 0x18},
+ {0x301c, 0xf8},
+ /*lens setting*/
+ {0x5000, 0x86},
+ {0x5800, 0x11},
+ {0x5801, 0x0c},
+ {0x5802, 0x0a},
+ {0x5803, 0x0b},
+ {0x5804, 0x0d},
+ {0x5805, 0x13},
+ {0x5806, 0x09},
+ {0x5807, 0x05},
+ {0x5808, 0x03},
+ {0x5809, 0x03},
+ {0x580a, 0x06},
+ {0x580b, 0x08},
+ {0x580c, 0x05},
+ {0x580d, 0x01},
+ {0x580e, 0x00},
+ {0x580f, 0x00},
+ {0x5810, 0x02},
+ {0x5811, 0x06},
+ {0x5812, 0x05},
+ {0x5813, 0x01},
+ {0x5814, 0x00},
+ {0x5815, 0x00},
+ {0x5816, 0x02},
+ {0x5817, 0x06},
+ {0x5818, 0x09},
+ {0x5819, 0x05},
+ {0x581a, 0x04},
+ {0x581b, 0x04},
+ {0x581c, 0x06},
+ {0x581d, 0x09},
+ {0x581e, 0x11},
+ {0x581f, 0x0c},
+ {0x5820, 0x0b},
+ {0x5821, 0x0b},
+ {0x5822, 0x0d},
+ {0x5823, 0x13},
+ {0x5824, 0x22},
+ {0x5825, 0x26},
+ {0x5826, 0x26},
+ {0x5827, 0x24},
+ {0x5828, 0x24},
+ {0x5829, 0x24},
+ {0x582a, 0x22},
+ {0x582b, 0x20},
+ {0x582c, 0x22},
+ {0x582d, 0x26},
+ {0x582e, 0x22},
+ {0x582f, 0x22},
+ {0x5830, 0x42},
+ {0x5831, 0x22},
+ {0x5832, 0x02},
+ {0x5833, 0x24},
+ {0x5834, 0x22},
+ {0x5835, 0x22},
+ {0x5836, 0x22},
+ {0x5837, 0x26},
+ {0x5838, 0x42},
+ {0x5839, 0x26},
+ {0x583a, 0x06},
+ {0x583b, 0x26},
+ {0x583c, 0x24},
+ {0x583d, 0xce},
+ /* manual AWB,manual AE,close Lenc,open WBC*/
+ {0x3503, 0x03}, /*manual AE*/
+ {0x3501, 0x10},
+ {0x3502, 0x80},
+ {0x350a, 0x00},
+ {0x350b, 0x7f},
+ {0x5001, 0x01}, /*manual AWB*/
+ {0x5180, 0x08},
+ {0x5186, 0x04},
+ {0x5187, 0x00},
+ {0x5188, 0x04},
+ {0x5189, 0x00},
+ {0x518a, 0x04},
+ {0x518b, 0x00},
+ {0x5000, 0x06}, /*No lenc,WBC on*/
+};
+
+struct ov5647_reg ov5647_regs = {
+ .rec_settings = &ov5647_recommend_settings[0],
+ .rec_size = ARRAY_SIZE(ov5647_recommend_settings),
+ .reg_prev = &ov5647_prev_settings[0],
+ .reg_prev_size = ARRAY_SIZE(ov5647_prev_settings),
+ .reg_snap = &ov5647_snap_settings[0],
+ .reg_snap_size = ARRAY_SIZE(ov5647_snap_settings),
+};
diff --git a/drivers/media/video/msm/ov7692.h b/drivers/media/video/msm/ov7692.h
index e43a17d..fc9cf1c 100644
--- a/drivers/media/video/msm/ov7692.h
+++ b/drivers/media/video/msm/ov7692.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -14,6 +14,11 @@
#include <linux/types.h>
#include <mach/board.h>
+#define INVMASK(v) (0xff-v)
+#define OV7692Core_WritePREG(pTbl) OV7692_WritePRegs \
+ (pTbl, sizeof(pTbl)/sizeof(pTbl[0]))
+
+extern int lcd_camera_power_onoff(int on);
struct reg_addr_val_pair_struct {
uint8_t reg_addr;
uint8_t reg_val;
@@ -46,5 +51,616 @@
/* Not valid update */
UPDATE_INVALID
};
+
+/*OV SENSOR SCCB*/
+struct OV7692_WREG {
+ uint8_t addr;
+ uint8_t data;
+ uint8_t mask;
+} OV7692_WREG;
+
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+/* 96MHz PCLK @ 24MHz MCLK */
+struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
+ {0x12, 0x80},
+ {0x0e, 0x08},
+ {0x69, 0x52},
+ {0x1e, 0xb3},
+ {0x48, 0x42},
+ {0xff, 0x01},
+ {0xae, 0xa0},
+ {0xa8, 0x26},
+ {0xb4, 0xc0},
+ {0xb5, 0x40},
+ {0xff, 0x00},
+ {0x0c, 0x00},
+ {0x62, 0x10},
+ {0x12, 0x00},
+ {0x17, 0x65},
+ {0x18, 0xa4},
+ {0x19, 0x0a},
+ {0x1a, 0xf6},
+ {0x3e, 0x30},
+ {0x64, 0x0a},
+ {0xff, 0x01},
+ {0xb4, 0xc0},
+ {0xff, 0x00},
+ {0x67, 0x20},
+ {0x81, 0x3f},
+ {0xcc, 0x02},
+ {0xcd, 0x80},
+ {0xce, 0x01},
+ {0xcf, 0xe0},
+ {0xc8, 0x02},
+ {0xc9, 0x80},
+ {0xca, 0x01},
+ {0xcb, 0xe0},
+ {0xd0, 0x48},
+ {0x82, 0x03},
+ /*{0x0e, 0x00},*/
+ {0x70, 0x00},
+ {0x71, 0x34},
+ {0x74, 0x28},
+ {0x75, 0x98},
+ {0x76, 0x00},
+ {0x77, 0x64},
+ {0x78, 0x01},
+ {0x79, 0xc2},
+ {0x7a, 0x4e},
+ {0x7b, 0x1f},
+ {0x7c, 0x00},
+ {0x11, 0x00},
+ {0x20, 0x00},
+ {0x21, 0x23},
+ {0x50, 0x9a},
+ {0x51, 0x80},
+ {0x4c, 0x7d},
+ /*{0x0e, 0x00},*/
+ {0x85, 0x10},
+ {0x86, 0x00},
+ {0x87, 0x00},
+ {0x88, 0x00},
+ {0x89, 0x2a},
+ {0x8a, 0x26},
+ {0x8b, 0x22},
+ {0xbb, 0x7a},
+ {0xbc, 0x69},
+ {0xbd, 0x11},
+ {0xbe, 0x13},
+ {0xbf, 0x81},
+ {0xc0, 0x96},
+ {0xc1, 0x1e},
+ {0xb7, 0x05},
+ {0xb8, 0x09},
+ {0xb9, 0x00},
+ {0xba, 0x18},
+ {0x5a, 0x1f},
+ {0x5b, 0x9f},
+ {0x5c, 0x6a},
+ {0x5d, 0x42},
+ {0x24, 0x78},
+ {0x25, 0x68},
+ {0x26, 0xb3},
+ {0xa3, 0x0b},
+ {0xa4, 0x15},
+ {0xa5, 0x2a},
+ {0xa6, 0x51},
+ {0xa7, 0x63},
+ {0xa8, 0x74},
+ {0xa9, 0x83},
+ {0xaa, 0x91},
+ {0xab, 0x9e},
+ {0xac, 0xaa},
+ {0xad, 0xbe},
+ {0xae, 0xce},
+ {0xaf, 0xe5},
+ {0xb0, 0xf3},
+ {0xb1, 0xfb},
+ {0xb2, 0x06},
+ {0x8c, 0x5c},
+ {0x8d, 0x11},
+ {0x8e, 0x12},
+ {0x8f, 0x19},
+ {0x90, 0x50},
+ {0x91, 0x20},
+ {0x92, 0x96},
+ {0x93, 0x80},
+ {0x94, 0x13},
+ {0x95, 0x1b},
+ {0x96, 0xff},
+ {0x97, 0x00},
+ {0x98, 0x3d},
+ {0x99, 0x36},
+ {0x9a, 0x51},
+ {0x9b, 0x43},
+ {0x9c, 0xf0},
+ {0x9d, 0xf0},
+ {0x9e, 0xf0},
+ {0x9f, 0xff},
+ {0xa0, 0x68},
+ {0xa1, 0x62},
+ {0xa2, 0x0e},
+};
+#endif
+/* Exposure Compensation */
+struct OV7692_WREG ov7692_exposure_compensation_lv0_tbl[] = {
+ /*@@ +1.7EV*/
+ {0x24, 0xc0},
+ {0x25, 0xb8},
+ {0x26, 0xe6},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv1_tbl[] = {
+ /*@@ +1.0EV*/
+ {0x24, 0xa8},
+ {0x25, 0xa0},
+ {0x26, 0xc4},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv2_default_tbl[] = {
+ /*@@ default*/
+ {0x24, 0x86},
+ {0x25, 0x76},
+ {0x26, 0xb3},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv3_tbl[] = {
+ /*@@ -1.0EV*/
+ {0x24, 0x70},
+ {0x25, 0x60},
+ {0x26, 0xa2},
+};
+
+struct OV7692_WREG ov7692_exposure_compensation_lv4_tbl[] = {
+ /*@@ -1.7EV*/
+ {0x24, 0x50},
+ {0x25, 0x40},
+ {0x26, 0xa2},
+};
+
+struct OV7692_WREG ov7692_antibanding_off_tbl[] = {
+ {0x13, 0xE5, INVMASK(0x20)},
+};
+
+struct OV7692_WREG ov7692_antibanding_auto_tbl[] = {
+ {0x13, 0x20, INVMASK(0x20)},
+ {0x14, 0x14, INVMASK(0x17)},
+};
+
+struct OV7692_WREG ov7692_antibanding_50z_tbl[] = {
+ /*Band 50Hz*/
+ {0x13, 0x20, INVMASK(0x20)},
+ {0x14, 0x17, INVMASK(0x17)},
+};
+
+struct OV7692_WREG ov7692_antibanding_60z_tbl[] = {
+ /*Band 60Hz*/
+ {0x13, 0x20, INVMASK(0x20)},
+ {0x14, 0x16, INVMASK(0x17)},
+};
+
+/*Saturation*/
+struct OV7692_WREG ov7692_saturation_lv0_tbl[] = {
+ /*Saturation level 0*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x00, INVMASK(0xff)},
+ {0xd9, 0x00, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv1_tbl[] = {
+ /*Saturation level 1*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x10, INVMASK(0xff)},
+ {0xd9, 0x10, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv2_tbl[] = {
+ /*Saturation level 2*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x20, INVMASK(0xff)},
+ {0xd9, 0x20, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+
+};
+
+struct OV7692_WREG ov7692_saturation_lv3_tbl[] = {
+ /*Saturation level 3*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x30, INVMASK(0xff)},
+ {0xd9, 0x30, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+
+};
+
+struct OV7692_WREG ov7692_saturation_default_lv4_tbl[] = {
+ /*Saturation level 4 (default)*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x40, INVMASK(0xff)},
+ {0xd9, 0x40, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv5_tbl[] = {
+ /*Saturation level 5*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x50, INVMASK(0xff)},
+ {0xd9, 0x50, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv6_tbl[] = {
+ /*Saturation level 6*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x60, INVMASK(0xff)},
+ {0xd9, 0x60, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv7_tbl[] = {
+ /*Saturation level 7*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x70, INVMASK(0xff)},
+ {0xd9, 0x70, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+struct OV7692_WREG ov7692_saturation_lv8_tbl[] = {
+ /*Saturation level 8*/
+ {0x81, 0x33, INVMASK(0x33)},
+ {0xd8, 0x80, INVMASK(0xff)},
+ {0xd9, 0x80, INVMASK(0xff)},
+ {0xd2, 0x02, INVMASK(0xff)},
+};
+
+/*EFFECT*/
+struct OV7692_WREG ov7692_effect_normal_tbl[] = {
+ {0x81, 0x00, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x00, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_mono_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_bw_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_sepia_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x40, },
+ {0xdb, 0xa0, },
+};
+
+struct OV7692_WREG ov7692_effect_bluish_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0xc0, },
+ {0xdb, 0x80, },
+};
+
+struct OV7692_WREG ov7692_effect_reddish_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x80, },
+ {0xdb, 0xc0, },
+};
+
+struct OV7692_WREG ov7692_effect_greenish_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x00, },
+ {0xd2, 0x18, },
+ {0xda, 0x60, },
+ {0xdb, 0x60, },
+};
+
+struct OV7692_WREG ov7692_effect_negative_tbl[] = {
+ {0x81, 0x20, INVMASK(0x20)},
+ {0x28, 0x80, },
+ {0xd2, 0x40, },
+ {0xda, 0x80, },
+ {0xdb, 0x80, },
+};
+
+/*Contrast*/
+struct OV7692_WREG ov7692_contrast_lv0_tbl[] = {
+ /*Contrast -4*/
+ {0xb2, 0x29},
+ {0xa3, 0x55},
+ {0xa4, 0x5b},
+ {0xa5, 0x67},
+ {0xa6, 0x7e},
+ {0xa7, 0x89},
+ {0xa8, 0x93},
+ {0xa9, 0x9c},
+ {0xaa, 0xa4},
+ {0xab, 0xac},
+ {0xac, 0xb3},
+ {0xad, 0xbe},
+ {0xae, 0xc7},
+ {0xaf, 0xd5},
+ {0xb0, 0xdd},
+ {0xb1, 0xe1},
+};
+
+struct OV7692_WREG ov7692_contrast_lv1_tbl[] = {
+ /*Contrast -3*/
+ {0xb2, 0x20},
+ {0xa3, 0x43},
+ {0xa4, 0x4a},
+ {0xa5, 0x58},
+ {0xa6, 0x73},
+ {0xa7, 0x80},
+ {0xa8, 0x8b},
+ {0xa9, 0x96},
+ {0xaa, 0x9f},
+ {0xab, 0xa8},
+ {0xac, 0xb1},
+ {0xad, 0xbe},
+ {0xae, 0xc9},
+ {0xaf, 0xd8},
+ {0xb0, 0xe2},
+ {0xb1, 0xe8},
+};
+
+struct OV7692_WREG ov7692_contrast_lv2_tbl[] = {
+ /*Contrast -2*/
+ {0xb2, 0x18},
+ {0xa3, 0x31},
+ {0xa4, 0x39},
+ {0xa5, 0x4a},
+ {0xa6, 0x68},
+ {0xa7, 0x77},
+ {0xa8, 0x84},
+ {0xa9, 0x90},
+ {0xaa, 0x9b},
+ {0xab, 0xa5},
+ {0xac, 0xaf},
+ {0xad, 0xbe},
+ {0xae, 0xca},
+ {0xaf, 0xdc},
+ {0xb0, 0xe7},
+ {0xb1, 0xee},
+};
+
+struct OV7692_WREG ov7692_contrast_lv3_tbl[] = {
+ /*Contrast -1*/
+ {0xb2, 0x10},
+ {0xa3, 0x1f},
+ {0xa4, 0x28},
+ {0xa5, 0x3b},
+ {0xa6, 0x5d},
+ {0xa7, 0x6e},
+ {0xa8, 0x7d},
+ {0xa9, 0x8a},
+ {0xaa, 0x96},
+ {0xab, 0xa2},
+ {0xac, 0xad},
+ {0xad, 0xbe},
+ {0xae, 0xcc},
+ {0xaf, 0xe0},
+ {0xb0, 0xed},
+ {0xb1, 0xf4},
+};
+
+struct OV7692_WREG ov7692_contrast_default_lv4_tbl[] = {
+ /*Contrast 0*/
+ {0xb2, 0x6},
+ {0xa3, 0xb},
+ {0xa4, 0x15},
+ {0xa5, 0x2a},
+ {0xa6, 0x51},
+ {0xa7, 0x63},
+ {0xa8, 0x74},
+ {0xa9, 0x83},
+ {0xaa, 0x91},
+ {0xab, 0x9e},
+ {0xac, 0xaa},
+ {0xad, 0xbe},
+ {0xae, 0xce},
+ {0xaf, 0xe5},
+ {0xb0, 0xf3},
+ {0xb1, 0xfb},
+};
+
+struct OV7692_WREG ov7692_contrast_lv5_tbl[] = {
+ /*Contrast 1*/
+ {0xb2, 0xc},
+ {0xa3, 0x4},
+ {0xa4, 0xc},
+ {0xa5, 0x1f},
+ {0xa6, 0x45},
+ {0xa7, 0x58},
+ {0xa8, 0x6b},
+ {0xa9, 0x7c},
+ {0xaa, 0x8d},
+ {0xab, 0x9d},
+ {0xac, 0xac},
+ {0xad, 0xc3},
+ {0xae, 0xd2},
+ {0xaf, 0xe8},
+ {0xb0, 0xf2},
+ {0xb1, 0xf7},
+};
+
+struct OV7692_WREG ov7692_contrast_lv6_tbl[] = {
+ /*Contrast 2*/
+ {0xb2, 0x1},
+ {0xa3, 0x2},
+ {0xa4, 0x9},
+ {0xa5, 0x1a},
+ {0xa6, 0x3e},
+ {0xa7, 0x4a},
+ {0xa8, 0x59},
+ {0xa9, 0x6a},
+ {0xaa, 0x79},
+ {0xab, 0x8e},
+ {0xac, 0xa4},
+ {0xad, 0xc1},
+ {0xae, 0xdb},
+ {0xaf, 0xf4},
+ {0xb0, 0xff},
+ {0xb1, 0xff},
+};
+
+struct OV7692_WREG ov7692_contrast_lv7_tbl[] = {
+ /*Contrast 3*/
+ {0xb2, 0xc},
+ {0xa3, 0x4},
+ {0xa4, 0x8},
+ {0xa5, 0x17},
+ {0xa6, 0x27},
+ {0xa7, 0x3d},
+ {0xa8, 0x54},
+ {0xa9, 0x60},
+ {0xaa, 0x77},
+ {0xab, 0x85},
+ {0xac, 0xa4},
+ {0xad, 0xc6},
+ {0xae, 0xd2},
+ {0xaf, 0xe9},
+ {0xb0, 0xf0},
+ {0xb1, 0xf7},
+};
+
+struct OV7692_WREG ov7692_contrast_lv8_tbl[] = {
+ /*Contrast 4*/
+ {0xb2, 0x1},
+ {0xa3, 0x4},
+ {0xa4, 0x4},
+ {0xa5, 0x7},
+ {0xa6, 0xb},
+ {0xa7, 0x17},
+ {0xa8, 0x2a},
+ {0xa9, 0x41},
+ {0xaa, 0x59},
+ {0xab, 0x6b},
+ {0xac, 0x8b},
+ {0xad, 0xb1},
+ {0xae, 0xd2},
+ {0xaf, 0xea},
+ {0xb0, 0xf4},
+ {0xb1, 0xff},
+};
+
+ /*Sharpness*/
+struct OV7692_WREG ov7692_sharpness_lv0_tbl[] = {
+ /*Sharpness 0*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x00, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv1_tbl[] = {
+ /*Sharpness 1*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x01, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_default_lv2_tbl[] = {
+ /*Sharpness Auto (Default)*/
+ {0xb4, 0x00, INVMASK(0x20)},
+ {0xb6, 0x00, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv3_tbl[] = {
+ /*Sharpness 3*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x66, INVMASK(0x04)},
+};
+struct OV7692_WREG ov7692_sharpness_lv4_tbl[] = {
+ /*Sharpness 4*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0x99, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv5_tbl[] = {
+ /*Sharpness 5*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0xcc, INVMASK(0x1f)},
+};
+struct OV7692_WREG ov7692_sharpness_lv6_tbl[] = {
+ /*Sharpness 6*/
+ {0xb4, 0x20, INVMASK(0x20)},
+ {0xb6, 0xff, INVMASK(0x1f)},
+};
+
+ /* ISO TYPE*/
+struct OV7692_WREG ov7692_iso_type_auto[] = {
+ /*@@ISO Auto*/
+ {0x14, 0x20, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_100[] = {
+ /*@@ISO 100*/
+ {0x14, 0x00, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_200[] = {
+ /*@@ISO 200*/
+ {0x14, 0x10, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_400[] = {
+ /*@@ISO 400*/
+ {0x14, 0x20, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_800[] = {
+ /*@@ISO 800*/
+ {0x14, 0x30, INVMASK(0x70)},
+};
+
+struct OV7692_WREG ov7692_iso_type_1600[] = {
+ /*@@ISO 1600*/
+ {0x14, 0x40, INVMASK(0x70)},
+};
+
+ /*Light Mode*/
+struct OV7692_WREG ov7692_wb_def[] = {
+ {0x13, 0xf7},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_custom[] = {
+ {0x13, 0xf5},
+ {0x01, 0x56},
+ {0x02, 0x50},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_inc[] = {
+ {0x13, 0xf5},
+ {0x01, 0x66},
+ {0x02, 0x40},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_daylight[] = {
+ {0x13, 0xf5},
+ {0x01, 0x43},
+ {0x02, 0x5d},
+ {0x15, 0x00},
+};
+
+struct OV7692_WREG ov7692_wb_cloudy[] = {
+ {0x13, 0xf5},
+ {0x01, 0x48},
+ {0x02, 0x63},
+ {0x15, 0x00},
+};
+
#endif
diff --git a/drivers/media/video/msm/ov7692_qrd.c b/drivers/media/video/msm/ov7692_qrd.c
index e558e57..d83f28e 100644
--- a/drivers/media/video/msm/ov7692_qrd.c
+++ b/drivers/media/video/msm/ov7692_qrd.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -10,8 +10,6 @@
* GNU General Public License for more details.
*/
-/* #define DEBUG */
-
#include <linux/delay.h>
#include <linux/types.h>
#include <linux/i2c.h>
@@ -52,129 +50,9 @@
/*============================================================================
- DATA DECLARATIONS
- ============================================================================*/
-/* 96MHz PCLK @ 24MHz MCLK */
-struct reg_addr_val_pair_struct ov7692_init_settings_array[] = {
- {0x12, 0x80},
- {0x0e, 0x08},
- {0x69, 0x52},
- {0x1e, 0xb3},
- {0x48, 0x42},
- {0xff, 0x01},
- {0xae, 0xa0},
- {0xa8, 0x26},
- {0xb4, 0xc0},
- {0xb5, 0x40},
- {0xff, 0x00},
- {0x0c, 0x00},
- {0x62, 0x10},
- {0x12, 0x00},
- {0x17, 0x65},
- {0x18, 0xa4},
- {0x19, 0x0a},
- {0x1a, 0xf6},
- {0x3e, 0x30},
- {0x64, 0x0a},
- {0xff, 0x01},
- {0xb4, 0xc0},
- {0xff, 0x00},
- {0x67, 0x20},
- {0x81, 0x3f},
- {0xcc, 0x02},
- {0xcd, 0x80},
- {0xce, 0x01},
- {0xcf, 0xe0},
- {0xc8, 0x02},
- {0xc9, 0x80},
- {0xca, 0x01},
- {0xcb, 0xe0},
- {0xd0, 0x48},
- {0x82, 0x03},
- {0x0e, 0x00},
- {0x70, 0x00},
- {0x71, 0x34},
- {0x74, 0x28},
- {0x75, 0x98},
- {0x76, 0x00},
- {0x77, 0x64},
- {0x78, 0x01},
- {0x79, 0xc2},
- {0x7a, 0x4e},
- {0x7b, 0x1f},
- {0x7c, 0x00},
- {0x11, 0x00},
- {0x20, 0x00},
- {0x21, 0x23},
- {0x50, 0x9a},
- {0x51, 0x80},
- {0x4c, 0x7d},
- {0x0e, 0x00},
- {0x85, 0x10},
- {0x86, 0x00},
- {0x87, 0x00},
- {0x88, 0x00},
- {0x89, 0x2a},
- {0x8a, 0x26},
- {0x8b, 0x22},
- {0xbb, 0x7a},
- {0xbc, 0x69},
- {0xbd, 0x11},
- {0xbe, 0x13},
- {0xbf, 0x81},
- {0xc0, 0x96},
- {0xc1, 0x1e},
- {0xb7, 0x05},
- {0xb8, 0x09},
- {0xb9, 0x00},
- {0xba, 0x18},
- {0x5a, 0x1f},
- {0x5b, 0x9f},
- {0x5c, 0x6a},
- {0x5d, 0x42},
- {0x24, 0x78},
- {0x25, 0x68},
- {0x26, 0xb3},
- {0xa3, 0x0b},
- {0xa4, 0x15},
- {0xa5, 0x2a},
- {0xa6, 0x51},
- {0xa7, 0x63},
- {0xa8, 0x74},
- {0xa9, 0x83},
- {0xaa, 0x91},
- {0xab, 0x9e},
- {0xac, 0xaa},
- {0xad, 0xbe},
- {0xae, 0xce},
- {0xaf, 0xe5},
- {0xb0, 0xf3},
- {0xb1, 0xfb},
- {0xb2, 0x06},
- {0x8c, 0x5c},
- {0x8d, 0x11},
- {0x8e, 0x12},
- {0x8f, 0x19},
- {0x90, 0x50},
- {0x91, 0x20},
- {0x92, 0x96},
- {0x93, 0x80},
- {0x94, 0x13},
- {0x95, 0x1b},
- {0x96, 0xff},
- {0x97, 0x00},
- {0x98, 0x3d},
- {0x99, 0x36},
- {0x9a, 0x51},
- {0x9b, 0x43},
- {0x9c, 0xf0},
- {0x9d, 0xf0},
- {0x9e, 0xf0},
- {0x9f, 0xff},
- {0xa0, 0x68},
- {0xa1, 0x62},
- {0xa2, 0x0e},
-};
+ DATA DECLARATIONS
+============================================================================*/
+
static bool OV7692_CSI_CONFIG;
/* 816x612, 24MHz MCLK 96MHz PCLK */
@@ -214,6 +92,10 @@
static struct ov7692_ctrl_t *ov7692_ctrl;
static DECLARE_WAIT_QUEUE_HEAD(ov7692_wait_queue);
DEFINE_MUTEX(ov7692_mut);
+static int effect_value;
+static int16_t ov7692_effect = CAMERA_EFFECT_OFF;
+static unsigned int SAT_U = 0x80;
+static unsigned int SAT_V = 0x80;
/*=============================================================*/
@@ -284,14 +166,33 @@
memset(buf, 0, sizeof(buf));
buf[0] = waddr;
buf[1] = bdata;
-
+ CDBG("i2c_write_b addr = 0x%x, val = 0x%x\n", waddr, bdata);
rc = ov7692_i2c_txdata(ov7692_client->addr >> 1, buf, 2);
if (rc < 0)
CDBG("i2c_write_b failed, addr = 0x%x, val = 0x%x!\n",
- waddr, bdata);
+ waddr, bdata);
+
return rc;
}
+static int32_t OV7692_WritePRegs(struct OV7692_WREG *pTb, int32_t len)
+{
+ int32_t i, ret = 0;
+ uint8_t regv;
+
+ for (i = 0; i < len; i++) {
+ if (pTb[i].mask == 0) {
+ ov7692_i2c_write_b_sensor(pTb[i].addr, pTb[i].data);
+ } else {
+ ov7692_i2c_read(pTb[i].addr, ®v, 1);
+ regv &= pTb[i].mask;
+ regv |= (pTb[i].data & (~pTb[i].mask));
+ ov7692_i2c_write_b_sensor(pTb[i].addr, regv);
+ }
+ }
+ return ret;
+}
+
static int32_t ov7692_sensor_setting(int update_type, int rt)
{
int32_t i, array_length;
@@ -314,8 +215,6 @@
ov7692_csi_params.dpcm_scheme = 0;
ov7692_csi_params.settle_cnt = 0x14;
- rc = msm_camio_csi_config(&ov7692_csi_params);
- msleep(20);
array_length = sizeof(ov7692_init_settings_array) /
sizeof(ov7692_init_settings_array[0]);
for (i = 0; i < array_length; i++) {
@@ -325,6 +224,10 @@
if (rc < 0)
return rc;
}
+ usleep_range(10000, 11000);
+ rc = msm_camio_csi_config(&ov7692_csi_params);
+ usleep_range(10000, 11000);
+ ov7692_i2c_write_b_sensor(0x0e, 0x00);
OV7692_CSI_CONFIG = 1;
msleep(20);
return rc;
@@ -371,6 +274,442 @@
return rc;
}
+static int ov7692_set_exposure_compensation(int compensation)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...exposure_compensation = %d\n",
+ __func__ , compensation);
+ switch (compensation) {
+ case CAMERA_EXPOSURE_COMPENSATION_LV0:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV0\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv0_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV1:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV1\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv1_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV2:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV2\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv2_default_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV3:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv3_tbl);
+ break;
+ case CAMERA_EXPOSURE_COMPENSATION_LV4:
+ CDBG("--CAMERA--CAMERA_EXPOSURE_COMPENSATION_LV3\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_exposure_compensation_lv4_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--ERROR CAMERA_EXPOSURE_COMPENSATION\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static long ov7692_set_antibanding(int antibanding)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...antibanding = %d\n", __func__, antibanding);
+ switch (antibanding) {
+ case CAMERA_ANTIBANDING_OFF:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_OFF\n");
+ break;
+ case CAMERA_ANTIBANDING_60HZ:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_60HZ\n");
+ rc = OV7692Core_WritePREG(ov7692_antibanding_60z_tbl);
+ break;
+ case CAMERA_ANTIBANDING_50HZ:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_50HZ\n");
+ rc = OV7692Core_WritePREG(ov7692_antibanding_50z_tbl);
+ break;
+ case CAMERA_ANTIBANDING_AUTO:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_AUTO\n");
+ rc = OV7692Core_WritePREG(ov7692_antibanding_auto_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_ANTIBANDING_ERROR COMMAND\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_saturation(int saturation)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...saturation = %d\n", __func__ , saturation);
+
+ if (effect_value == CAMERA_EFFECT_OFF) {
+ switch (saturation) {
+ case CAMERA_SATURATION_LV0:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv0_tbl);
+ break;
+ case CAMERA_SATURATION_LV1:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv1_tbl);
+ break;
+ case CAMERA_SATURATION_LV2:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv2_tbl);
+ break;
+ case CAMERA_SATURATION_LV3:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv3_tbl);
+ break;
+ case CAMERA_SATURATION_LV4:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_saturation_default_lv4_tbl);
+ break;
+ case CAMERA_SATURATION_LV5:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv5_tbl);
+ break;
+ case CAMERA_SATURATION_LV6:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv6_tbl);
+ break;
+ case CAMERA_SATURATION_LV7:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv7_tbl);
+ break;
+ case CAMERA_SATURATION_LV8:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+ rc = OV7692Core_WritePREG(ov7692_saturation_lv8_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+ break;
+ }
+ }
+
+ /*for recover saturation level when change special effect*/
+ switch (saturation) {
+ case CAMERA_SATURATION_LV0:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV0\n");
+ SAT_U = 0x00;
+ SAT_V = 0x00;
+ break;
+ case CAMERA_SATURATION_LV1:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV1\n");
+ SAT_U = 0x10;
+ SAT_V = 0x10;
+ break;
+ case CAMERA_SATURATION_LV2:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV2\n");
+ SAT_U = 0x20;
+ SAT_V = 0x20;
+ break;
+ case CAMERA_SATURATION_LV3:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV3\n");
+ SAT_U = 0x30;
+ SAT_V = 0x30;
+ break;
+ case CAMERA_SATURATION_LV4:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV4\n");
+ SAT_U = 0x40;
+ SAT_V = 0x40;
+ break;
+ case CAMERA_SATURATION_LV5:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV5\n");
+ SAT_U = 0x50;
+ SAT_V = 0x50;
+ break;
+ case CAMERA_SATURATION_LV6:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV6\n");
+ SAT_U = 0x60;
+ SAT_V = 0x60;
+ break;
+ case CAMERA_SATURATION_LV7:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV7\n");
+ SAT_U = 0x70;
+ SAT_V = 0x70;
+ break;
+ case CAMERA_SATURATION_LV8:
+ CDBG("--CAMERA--CAMERA_SATURATION_LV8\n");
+ SAT_U = 0x80;
+ SAT_V = 0x80;
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_SATURATION_ERROR COMMAND\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static long ov7692_set_effect(int mode, int effect)
+{
+ int rc = 0;
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+
+ switch (mode) {
+ case SENSOR_PREVIEW_MODE:
+ break;
+ case SENSOR_HFR_60FPS_MODE:
+ break;
+ case SENSOR_HFR_90FPS_MODE:
+ /* Context A Special Effects */
+ CDBG("-CAMERA- %s ...SENSOR_PREVIEW_MODE\n", __func__);
+ break;
+ case SENSOR_SNAPSHOT_MODE:
+ /* Context B Special Effects */
+ CDBG("-CAMERA- %s ...SENSOR_SNAPSHOT_MODE\n", __func__);
+ break;
+ default:
+ break;
+ }
+ effect_value = effect;
+ switch (effect) {
+ case CAMERA_EFFECT_OFF: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_OFF\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_normal_tbl);
+ /* for recover saturation level
+ when change special effect*/
+ ov7692_i2c_write_b_sensor(0xda, SAT_U);
+ /* for recover saturation level
+ when change special effect*/
+ ov7692_i2c_write_b_sensor(0xdb, SAT_V);
+ break;
+ }
+ case CAMERA_EFFECT_MONO: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_MONO\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_mono_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_BW: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BW\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_bw_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_BLUISH: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_BLUISH\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_bluish_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_SOLARIZE: {
+ CDBG("%s ...CAMERA_EFFECT_NEGATIVE(No Support)!\n", __func__);
+ break;
+ }
+ case CAMERA_EFFECT_SEPIA: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_SEPIA\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_sepia_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_REDDISH: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_REDDISH\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_reddish_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_GREENISH: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_GREENISH\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_greenish_tbl);
+ break;
+ }
+ case CAMERA_EFFECT_NEGATIVE: {
+ CDBG("--CAMERA-- %s ...CAMERA_EFFECT_NEGATIVE\n", __func__);
+ rc = OV7692Core_WritePREG(ov7692_effect_negative_tbl);
+ break;
+ }
+ default: {
+ CDBG("--CAMERA-- %s ...Default(Not Support)\n", __func__);
+ }
+ }
+ ov7692_effect = effect;
+ /*Refresh Sequencer */
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_contrast(int contrast)
+{
+ int rc = 0;
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...contrast = %d\n", __func__ , contrast);
+
+ if (effect_value == CAMERA_EFFECT_OFF) {
+ switch (contrast) {
+ case CAMERA_CONTRAST_LV0:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV0\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv0_tbl);
+ break;
+ case CAMERA_CONTRAST_LV1:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV1\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv1_tbl);
+ break;
+ case CAMERA_CONTRAST_LV2:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV2\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv2_tbl);
+ break;
+ case CAMERA_CONTRAST_LV3:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV3\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv3_tbl);
+ break;
+ case CAMERA_CONTRAST_LV4:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV4\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_contrast_default_lv4_tbl);
+ break;
+ case CAMERA_CONTRAST_LV5:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV5\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv5_tbl);
+ break;
+ case CAMERA_CONTRAST_LV6:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV6\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv6_tbl);
+ break;
+ case CAMERA_CONTRAST_LV7:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV7\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv7_tbl);
+ break;
+ case CAMERA_CONTRAST_LV8:
+ CDBG("--CAMERA--CAMERA_CONTRAST_LV8\n");
+ rc = OV7692Core_WritePREG(ov7692_contrast_lv8_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_CONTRAST_ERROR COMMAND\n");
+ break;
+ }
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_sharpness(int sharpness)
+{
+ int rc = 0;
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...sharpness = %d\n", __func__ , sharpness);
+
+ if (effect_value == CAMERA_EFFECT_OFF) {
+ switch (sharpness) {
+ case CAMERA_SHARPNESS_LV0:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV0\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv0_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV1:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV1\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv1_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV2:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV2\n");
+ rc = OV7692Core_WritePREG(
+ ov7692_sharpness_default_lv2_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV3:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV3\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv3_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV4:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV4\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv4_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV5:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV5\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv5_tbl);
+ break;
+ case CAMERA_SHARPNESS_LV6:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_LV6\n");
+ rc = OV7692Core_WritePREG(ov7692_sharpness_lv6_tbl);
+ break;
+ default:
+ CDBG("--CAMERA--CAMERA_SHARPNESS_ERROR COMMAND\n");
+ break;
+ }
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_iso(int8_t iso_type)
+{
+ long rc = 0;
+
+ CDBG("--CAMERA-- %s ...(Start)\n", __func__);
+ CDBG("--CAMERA-- %s ...iso_type = %d\n", __func__ , iso_type);
+ switch (iso_type) {
+ case CAMERA_ISO_TYPE_AUTO:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_AUTO\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
+ break;
+ case CAMEAR_ISO_TYPE_HJR:
+ CDBG("--CAMERA--CAMEAR_ISO_TYPE_HJR\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_auto);
+ break;
+ case CAMEAR_ISO_TYPE_100:
+ CDBG("--CAMERA--CAMEAR_ISO_TYPE_100\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_100);
+ break;
+ case CAMERA_ISO_TYPE_200:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_200\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_200);
+ break;
+ case CAMERA_ISO_TYPE_400:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_400\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_400);
+ break;
+ case CAMEAR_ISO_TYPE_800:
+ CDBG("--CAMERA--CAMEAR_ISO_TYPE_800\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_800);
+ break;
+ case CAMERA_ISO_TYPE_1600:
+ CDBG("--CAMERA--CAMERA_ISO_TYPE_1600\n");
+ rc = OV7692Core_WritePREG(ov7692_iso_type_1600);
+ break;
+ default:
+ CDBG("--CAMERA--ERROR ISO TYPE\n");
+ break;
+ }
+ CDBG("--CAMERA-- %s ...(End)\n", __func__);
+ return rc;
+}
+
+static int ov7692_set_wb_oem(uint8_t param)
+{
+ int rc = 0;
+ CDBG("--CAMERA--%s runs\r\n", __func__);
+
+ switch (param) {
+ case CAMERA_WB_AUTO:
+ CDBG("--CAMERA--CAMERA_WB_AUTO\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_def);
+ break;
+ case CAMERA_WB_CUSTOM:
+ CDBG("--CAMERA--CAMERA_WB_CUSTOM\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_custom);
+ break;
+ case CAMERA_WB_INCANDESCENT:
+ CDBG("--CAMERA--CAMERA_WB_INCANDESCENT\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_inc);
+ break;
+ case CAMERA_WB_DAYLIGHT:
+ CDBG("--CAMERA--CAMERA_WB_DAYLIGHT\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_daylight);
+ break;
+ case CAMERA_WB_CLOUDY_DAYLIGHT:
+ CDBG("--CAMERA--CAMERA_WB_CLOUDY_DAYLIGHT\n");
+ rc = OV7692Core_WritePREG(ov7692_wb_cloudy);
+ break;
+ default:
+ break;
+ }
+ return rc;
+}
+
static void ov7692_power_on(void)
{
CDBG("%s\n", __func__);
@@ -392,13 +731,12 @@
static void ov7692_hw_reset(void)
{
CDBG("--CAMERA-- %s ... (Start...)\n", __func__);
- gpio_set_value(ov7692_reset_gpio, 1); /* reset camera reset pin */
- msleep(20);
+ gpio_set_value(ov7692_reset_gpio, 1); /*reset camera reset pin*/
+ usleep_range(5000, 5100);
gpio_set_value(ov7692_reset_gpio, 0);
- msleep(20);
+ usleep_range(5000, 5100);
gpio_set_value(ov7692_reset_gpio, 1);
- msleep(20);
-
+ usleep_range(1000, 1100);
CDBG("--CAMERA-- %s ... (End...)\n", __func__);
}
@@ -458,6 +796,9 @@
if (data)
ov7692_ctrl->sensordata = data;
+ /* turn on LDO for PVT */
+ if (data->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
/* enable mclk first */
@@ -465,7 +806,7 @@
msleep(20);
ov7692_power_on();
- msleep(20);
+ usleep_range(5000, 5100);
rc = ov7692_probe_init_sensor(data);
if (rc < 0) {
@@ -481,6 +822,8 @@
init_fail:
CDBG(" ov7692_sensor_open_init fail\n");
+ if (data->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
kfree(ov7692_ctrl);
init_done:
CDBG("ov7692_sensor_open_init done\n");
@@ -559,14 +902,160 @@
CDBG("ov7692_sensor_config: cfgtype = %d\n", cdata.cfgtype);
switch (cdata.cfgtype) {
case CFG_SET_MODE:
- rc = ov7692_set_sensor_mode(cdata.mode,
- cdata.rs);
+ rc = ov7692_set_sensor_mode(cdata.mode, cdata.rs);
+ break;
+ case CFG_SET_EFFECT:
+ CDBG("--CAMERA-- CFG_SET_EFFECT mode=%d, effect = %d !!\n",
+ cdata.mode, cdata.cfg.effect);
+ rc = ov7692_set_effect(cdata.mode, cdata.cfg.effect);
+ break;
+ case CFG_START:
+ CDBG("--CAMERA-- CFG_START (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_PWR_UP:
+ CDBG("--CAMERA-- CFG_PWR_UP (Not Support) !!\n");
+ /* Not Support */
break;
case CFG_PWR_DOWN:
+ CDBG("--CAMERA-- CFG_PWR_DOWN !!\n");
ov7692_power_down();
break;
+ case CFG_WRITE_EXPOSURE_GAIN:
+ CDBG("--CAMERA-- CFG_WRITE_EXPOSURE_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_DEFAULT_FOCUS:
+ CDBG("--CAMERA-- CFG_SET_DEFAULT_FOCUS (Not Implement) !!\n");
+ break;
+ case CFG_MOVE_FOCUS:
+ CDBG("--CAMERA-- CFG_MOVE_FOCUS (Not Implement) !!\n");
+ break;
+ case CFG_REGISTER_TO_REAL_GAIN:
+ CDBG("--CAMERA-- CFG_REGISTER_TO_REAL_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_REAL_TO_REGISTER_GAIN:
+ CDBG("--CAMERA-- CFG_REAL_TO_REGISTER_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_FPS:
+ CDBG("--CAMERA-- CFG_SET_FPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_PICT_FPS:
+ CDBG("--CAMERA-- CFG_SET_PICT_FPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_BRIGHTNESS:
+ CDBG("--CAMERA-- CFG_SET_BRIGHTNESS !!\n");
+ /* rc = ov7692_set_brightness(cdata.cfg.brightness); */
+ break;
+ case CFG_SET_CONTRAST:
+ CDBG("--CAMERA-- CFG_SET_CONTRAST !!\n");
+ rc = ov7692_set_contrast(cdata.cfg.contrast);
+ break;
+ case CFG_SET_ZOOM:
+ CDBG("--CAMERA-- CFG_SET_ZOOM (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_EXPOSURE_MODE:
+ CDBG("--CAMERA-- CFG_SET_EXPOSURE_MODE !!\n");
+ /* rc = ov7692_set_exposure_mode(cdata.cfg.ae_mode); */
+ break;
+ case CFG_SET_WB:
+ CDBG("--CAMERA-- CFG_SET_WB!!\n");
+ ov7692_set_wb_oem(cdata.cfg.wb_val);
+ rc = 0 ;
+ break;
+ case CFG_SET_ANTIBANDING:
+ CDBG("--CAMERA-- CFG_SET_ANTIBANDING antibanding = %d !!\n",
+ cdata.cfg.antibanding);
+ rc = ov7692_set_antibanding(cdata.cfg.antibanding);
+ break;
+ case CFG_SET_EXP_GAIN:
+ CDBG("--CAMERA-- CFG_SET_EXP_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_PICT_EXP_GAIN:
+ CDBG("--CAMERA-- CFG_SET_PICT_EXP_GAIN (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_LENS_SHADING:
+ CDBG("--CAMERA-- CFG_SET_LENS_SHADING !!\n");
+ /* rc = ov7692_lens_shading_enable(cdata.cfg.lens_shading); */
+ break;
+ case CFG_GET_PICT_FPS:
+ CDBG("--CAMERA-- CFG_GET_PICT_FPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PREV_L_PF:
+ CDBG("--CAMERA-- CFG_GET_PREV_L_PF (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PREV_P_PL:
+ CDBG("--CAMERA-- CFG_GET_PREV_P_PL (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PICT_L_PF:
+ CDBG("--CAMERA-- CFG_GET_PICT_L_PF (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PICT_P_PL:
+ CDBG("--CAMERA-- CFG_GET_PICT_P_PL (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_AF_MAX_STEPS:
+ CDBG("--CAMERA-- CFG_GET_AF_MAX_STEPS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_GET_PICT_MAX_EXP_LC:
+ CDBG("--CAMERA-- CFG_GET_PICT_MAX_EXP_LC (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SEND_WB_INFO:
+ CDBG("--CAMERA-- CFG_SEND_WB_INFO (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SENSOR_INIT:
+ CDBG("--CAMERA-- CFG_SENSOR_INIT (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_SATURATION:
+ CDBG("--CAMERA-- CFG_SET_SATURATION !!\n");
+ rc = ov7692_set_saturation(cdata.cfg.saturation);
+ break;
+ case CFG_SET_SHARPNESS:
+ CDBG("--CAMERA-- CFG_SET_SHARPNESS !!\n");
+ rc = ov7692_set_sharpness(cdata.cfg.sharpness);
+ break;
+ case CFG_SET_TOUCHAEC:
+ CDBG("--CAMERA-- CFG_SET_TOUCHAEC!!\n");
+ /* ov7692_set_touchaec(cdata.cfg.aec_cord.x,
+ cdata.cfg.aec_cord.y); */
+ rc = 0 ;
+ break;
+ case CFG_SET_AUTO_FOCUS:
+ CDBG("--CAMERA-- CFG_SET_AUTO_FOCUS (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_AUTOFLASH:
+ CDBG("--CAMERA-- CFG_SET_AUTOFLASH (Not Support) !!\n");
+ /* Not Support */
+ break;
+ case CFG_SET_EXPOSURE_COMPENSATION:
+ CDBG("--CAMERA-- CFG_SET_EXPOSURE_COMPENSATION !\n");
+ rc = ov7692_set_exposure_compensation(
+ cdata.cfg.exp_compensation);
+ break;
+ case CFG_SET_ISO:
+ CDBG("--CAMERA-- CFG_SET_ISO !\n");
+ rc = ov7692_set_iso(cdata.cfg.iso_type);
+ break;
default:
- rc = -EFAULT;
+ CDBG("--CAMERA-- %s: Command=%d (Not Implement) !!\n",
+ __func__, cdata.cfgtype);
+ rc = -EINVAL;
break;
}
@@ -577,6 +1066,7 @@
static int ov7692_sensor_release(void)
{
int rc = -EBADF;
+
mutex_lock(&ov7692_mut);
ov7692_sw_reset();
ov7692_power_down();
@@ -614,20 +1104,23 @@
rc = -ENOTSUPP;
goto probe_fail;
}
-
+ pr_debug("%s: %d Entered\n", __func__, __LINE__);
rc = ov7692_probe_init_gpio(info);
if (rc < 0) {
CDBG("%s: gpio init failed\n", __func__);
goto probe_fail;
}
+ /* turn on LDO for PVT */
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(1);
ov7692_power_down();
msm_camio_clk_rate_set(24000000);
- msleep(20);
+ usleep_range(5000, 5100);
ov7692_power_on();
- msleep(20);
+ usleep_range(5000, 5100);
if (info->sensor_reset_enable)
ov7692_hw_reset();
@@ -645,12 +1138,18 @@
s->s_camera_type = FRONT_CAMERA_2D;
s->s_mount_angle = info->sensor_platform_info->mount_angle;
+ /* ov7692_sw_reset(); */
ov7692_power_down();
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
+
return rc;
probe_fail:
CDBG("ov7692_sensor_probe: SENSOR PROBE FAILS!\n");
+ if (info->pmic_gpio_enable)
+ lcd_camera_power_onoff(0);
i2c_del_driver(&ov7692_i2c_driver);
return rc;
}
diff --git a/drivers/media/video/msm/sensors/imx074_v4l2.c b/drivers/media/video/msm/sensors/imx074_v4l2.c
index f31aece..92700f6 100644
--- a/drivers/media/video/msm/sensors/imx074_v4l2.c
+++ b/drivers/media/video/msm/sensors/imx074_v4l2.c
@@ -38,7 +38,7 @@
static struct msm_camera_i2c_reg_conf imx074_prev_settings[] = {
{0x0307, 0x2D}, /*pll_multiplier*/
{0x0340, 0x06}, /*frame_length_lines_hi*/
- {0x0341, 0x2D}, /*frame_length_lines_lo*/
+ {0x0341, 0x34}, /*frame_length_lines_lo*/
{0x0342, 0x11}, /*line_length_pclk_hi*/
{0x0343, 0x78}, /*line_length_pclk_lo*/
{0x0347, 0x00}, /*y_addr_start*/
@@ -161,9 +161,9 @@
.x_output = 0x838,
.y_output = 0x618,
.line_length_pclk = 0x1178,
- .frame_length_lines = 0x62D,
+ .frame_length_lines = 0x634,
.vt_pixel_clk = 216000000,
- .op_pixel_clk = 216000000,
+ .op_pixel_clk = 108000000,
.binning_factor = 2,
},
};
diff --git a/drivers/media/video/msm/sensors/msm_sensor.c b/drivers/media/video/msm/sensors/msm_sensor.c
index d0b4f1f..cade3d6 100644
--- a/drivers/media/video/msm/sensors/msm_sensor.c
+++ b/drivers/media/video/msm/sensors/msm_sensor.c
@@ -13,6 +13,7 @@
#include "msm_sensor.h"
#include "msm.h"
#include "msm_ispif.h"
+#include "msm_camera_i2c_mux.h"
/*=============================================================*/
@@ -449,6 +450,26 @@
{"cam_clk", MSM_SENSOR_MCLK_24HZ},
};
+int32_t msm_sensor_enable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+ struct v4l2_subdev *i2c_mux_sd =
+ dev_get_drvdata(&i2c_conf->mux_dev->dev);
+ v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+ VIDIOC_MSM_I2C_MUX_INIT, NULL);
+ v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+ VIDIOC_MSM_I2C_MUX_CFG, (void *)&i2c_conf->i2c_mux_mode);
+ return 0;
+}
+
+int32_t msm_sensor_disable_i2c_mux(struct msm_camera_i2c_conf *i2c_conf)
+{
+ struct v4l2_subdev *i2c_mux_sd =
+ dev_get_drvdata(&i2c_conf->mux_dev->dev);
+ v4l2_subdev_call(i2c_mux_sd, core, ioctl,
+ VIDIOC_MSM_I2C_MUX_RELEASE, NULL);
+ return 0;
+}
+
int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
{
int32_t rc = 0;
@@ -506,6 +527,10 @@
if (data->sensor_platform_info->ext_power_ctrl != NULL)
data->sensor_platform_info->ext_power_ctrl(1);
+ if (data->sensor_platform_info->i2c_conf &&
+ data->sensor_platform_info->i2c_conf->use_i2c_mux)
+ msm_sensor_enable_i2c_mux(data->sensor_platform_info->i2c_conf);
+
return rc;
enable_clk_failed:
msm_camera_config_gpio_table(data, 0);
@@ -531,6 +556,11 @@
{
struct msm_camera_sensor_info *data = s_ctrl->sensordata;
CDBG("%s\n", __func__);
+ if (data->sensor_platform_info->i2c_conf &&
+ data->sensor_platform_info->i2c_conf->use_i2c_mux)
+ msm_sensor_disable_i2c_mux(
+ data->sensor_platform_info->i2c_conf);
+
if (data->sensor_platform_info->ext_power_ctrl != NULL)
data->sensor_platform_info->ext_power_ctrl(0);
msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
diff --git a/drivers/media/video/msm/sensors/s5k3l1yx.c b/drivers/media/video/msm/sensors/s5k3l1yx.c
index 2177991..954dd2f 100644
--- a/drivers/media/video/msm/sensors/s5k3l1yx.c
+++ b/drivers/media/video/msm/sensors/s5k3l1yx.c
@@ -114,8 +114,8 @@
{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
{0x0306, 0x00}, /* pll_multiplier */
{0x0307, 0xA5}, /* pll_multiplier */
- {0x0202, 0x02}, /* coarse_integration_time */
- {0x0203, 0x1C}, /* coarse_integration_time */
+ {0x0202, 0x03}, /* coarse_integration_time */
+ {0x0203, 0xD8}, /* coarse_integration_time */
{0x0340, 0x03}, /* frame_length_lines */
{0x0341, 0xE0}, /* frame_length_lines */
{0x0342, 0x14}, /* line_length_pck */
@@ -152,7 +152,7 @@
{0x0306, 0x00}, /* pll_multiplier */
{0x0307, 0xA5}, /* pll_multiplier */
{0x0202, 0x02}, /* coarse_integration_time */
- {0x0203, 0x1C}, /* coarse_integration_time */
+ {0x0203, 0x90}, /* coarse_integration_time */
{0x0340, 0x02}, /* frame_length_lines */
{0x0341, 0x98}, /* frame_length_lines */
{0x0342, 0x14}, /* line_length_pck */
@@ -188,10 +188,10 @@
{0x0113, 0x0A}, /* CCP_data_format_L raw8=0808 ,DCPM10 -->8= 0A08 */
{0x0306, 0x00}, /* pll_multiplier */
{0x0307, 0xA5}, /* pll_multiplier */
- {0x0202, 0x02}, /* coarse_integration_time */
- {0x0203, 0x1C}, /* coarse_integration_time */
+ {0x0202, 0x01}, /* coarse_integration_time */
+ {0x0203, 0xFA}, /* coarse_integration_time */
{0x0340, 0x02}, /* frame_length_lines */
- {0x0341, 0x0D}, /* frame_length_lines */
+ {0x0341, 0x02}, /* frame_length_lines */
{0x0342, 0x14}, /* line_length_pck */
{0x0343, 0xD8}, /* line_length_pck */
{0x0344, 0x01}, /* x_addr_start */
@@ -519,7 +519,7 @@
.x_output = 864,
.y_output = 480,
.line_length_pclk = 5336,
- .frame_length_lines = 525,
+ .frame_length_lines = 514,
.vt_pixel_clk = 330000000,
.op_pixel_clk = 320000000,
.binning_factor = 1,
diff --git a/drivers/mfd/pm8921-core.c b/drivers/mfd/pm8921-core.c
index e4d8bd5..6be3f2d 100644
--- a/drivers/mfd/pm8921-core.c
+++ b/drivers/mfd/pm8921-core.c
@@ -42,7 +42,7 @@
#define PM8921_VERSION_MASK 0xFFF0
#define PM8921_VERSION_VALUE 0x06F0
#define PM8922_VERSION_VALUE 0x0AF0
-#define PM8917_VERSION_VALUE 0x12F0
+#define PM8917_VERSION_VALUE 0x0CF0
#define PM8921_REVISION_MASK 0x000F
#define REG_PM8921_PON_CNTRL_3 0x01D
diff --git a/drivers/mfd/pm8xxx-misc.c b/drivers/mfd/pm8xxx-misc.c
index eb0048a..b655848 100644
--- a/drivers/mfd/pm8xxx-misc.c
+++ b/drivers/mfd/pm8xxx-misc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -139,6 +139,12 @@
#define PM8901_DELAY_AFTER_REG_DISABLE_MS 4
#define PM8901_DELAY_BEFORE_SHUTDOWN_MS 8
+#define REG_PM8XXX_XO_CNTRL_2 0x114
+#define MP3_1_MASK 0xE0
+#define MP3_2_MASK 0x1C
+#define MP3_1_SHIFT 5
+#define MP3_2_SHIFT 2
+
struct pm8xxx_misc_chip {
struct list_head link;
struct pm8xxx_misc_platform_data pdata;
@@ -540,7 +546,7 @@
case PM8XXX_VERSION_8018:
rc = pm8xxx_misc_masked_write(chip,
REG_PM8018_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
- (enable ? SLEEP_CTRL_SMPL_EN_PWR_OFF
+ (enable ? SLEEP_CTRL_SMPL_EN_RESET
: SLEEP_CTRL_SMPL_EN_PWR_OFF));
break;
case PM8XXX_VERSION_8058:
@@ -552,7 +558,7 @@
case PM8XXX_VERSION_8921:
rc = pm8xxx_misc_masked_write(chip,
REG_PM8921_SLEEP_CTRL, SLEEP_CTRL_SMPL_EN_MASK,
- (enable ? SLEEP_CTRL_SMPL_EN_PWR_OFF
+ (enable ? SLEEP_CTRL_SMPL_EN_RESET
: SLEEP_CTRL_SMPL_EN_PWR_OFF));
break;
default:
@@ -1046,6 +1052,48 @@
}
EXPORT_SYMBOL_GPL(pm8xxx_preload_dVdd);
+int pm8xxx_aux_clk_control(enum pm8xxx_aux_clk_id clk_id,
+ enum pm8xxx_aux_clk_div divider, bool enable)
+{
+ struct pm8xxx_misc_chip *chip;
+ unsigned long flags;
+ u8 clk_mask = 0, value = 0;
+
+ if (clk_id == CLK_MP3_1) {
+ clk_mask = MP3_1_MASK;
+ value = divider << MP3_1_SHIFT;
+ } else if (clk_id == CLK_MP3_2) {
+ clk_mask = MP3_2_MASK;
+ value = divider << MP3_2_SHIFT;
+ } else {
+ pr_err("Invalid clock id of %d\n", clk_id);
+ return -EINVAL;
+ }
+ if (!enable)
+ value = 0;
+
+ spin_lock_irqsave(&pm8xxx_misc_chips_lock, flags);
+
+ /* Loop over all attached PMICs and call specific functions for them. */
+ list_for_each_entry(chip, &pm8xxx_misc_chips, link) {
+ switch (chip->version) {
+ case PM8XXX_VERSION_8038:
+ case PM8XXX_VERSION_8921:
+ pm8xxx_misc_masked_write(chip,
+ REG_PM8XXX_XO_CNTRL_2, clk_mask, value);
+ break;
+ default:
+ /* Functionality not supported */
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&pm8xxx_misc_chips_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pm8xxx_aux_clk_control);
+
static int __devinit pm8xxx_misc_probe(struct platform_device *pdev)
{
const struct pm8xxx_misc_platform_data *pdata = pdev->dev.platform_data;
diff --git a/drivers/mfd/wcd9310-core.c b/drivers/mfd/wcd9310-core.c
index 87abcda..56774e9 100644
--- a/drivers/mfd/wcd9310-core.c
+++ b/drivers/mfd/wcd9310-core.c
@@ -241,6 +241,12 @@
},
};
+static struct mfd_cell tabla1x_devs[] = {
+ {
+ .name = "tabla1x_codec",
+ },
+};
+
static void tabla_bring_up(struct tabla *tabla)
{
tabla_reg_write(tabla, TABLA_A_LEAKAGE_CTL, 0x4);
@@ -367,6 +373,8 @@
static int tabla_device_init(struct tabla *tabla, int irq)
{
int ret;
+ struct mfd_cell *tabla_dev;
+ int tabla_dev_size;
mutex_init(&tabla->io_lock);
mutex_init(&tabla->xfer_lock);
@@ -386,9 +394,19 @@
pr_err("IRQ initialization failed\n");
goto err;
}
+ tabla->version = tabla_reg_read(tabla, TABLA_A_CHIP_VERSION) & 0x1F;
+ pr_info("%s : Tabla version %u initialized\n",
+ __func__, tabla->version);
+ if (TABLA_IS_1_X(tabla->version)) {
+ tabla_dev = tabla1x_devs;
+ tabla_dev_size = ARRAY_SIZE(tabla1x_devs);
+ } else {
+ tabla_dev = tabla_devs;
+ tabla_dev_size = ARRAY_SIZE(tabla_devs);
+ }
ret = mfd_add_devices(tabla->dev, -1,
- tabla_devs, ARRAY_SIZE(tabla_devs),
+ tabla_dev, tabla_dev_size,
NULL, 0);
if (ret != 0) {
dev_err(tabla->dev, "Failed to add children: %d\n", ret);
diff --git a/drivers/misc/pmem.c b/drivers/misc/pmem.c
index f0d523e..2f48d71 100644
--- a/drivers/misc/pmem.c
+++ b/drivers/misc/pmem.c
@@ -2785,7 +2785,8 @@
pmem[id].dev.name = pdata->name;
pmem[id].dev.minor = id;
pmem[id].dev.fops = &pmem_fops;
- pr_info("pmem: Initializing %s (user-space) as %s\n",
+ pmem[id].reusable = pdata->reusable;
+ pr_info("pmem: Initializing %s as %s\n",
pdata->name, pdata->cached ? "cached" : "non-cached");
if (misc_register(&pmem[id].dev)) {
@@ -2793,24 +2794,23 @@
goto err_cant_register_device;
}
- pmem[id].base = allocate_contiguous_memory_nomap(pmem[id].size,
- pmem[id].memory_type, PAGE_SIZE);
- if (!pmem[id].base) {
- pr_err("pmem: Cannot allocate from reserved memory for %s\n",
- pdata->name);
- goto err_misc_deregister;
+ if (!pmem[id].reusable) {
+ pmem[id].base = allocate_contiguous_memory_nomap(pmem[id].size,
+ pmem[id].memory_type, PAGE_SIZE);
+ if (!pmem[id].base) {
+ pr_err("pmem: Cannot allocate from reserved memory for %s\n",
+ pdata->name);
+ goto err_misc_deregister;
+ }
}
- pr_info("allocating %lu bytes at %p (%lx physical) for %s\n",
- pmem[id].size, pmem[id].vbase, pmem[id].base, pmem[id].name);
-
- pmem[id].reusable = pdata->reusable;
/* reusable pmem requires map on demand */
pmem[id].map_on_demand = pdata->map_on_demand || pdata->reusable;
if (pmem[id].map_on_demand) {
if (pmem[id].reusable) {
const struct fmem_data *fmem_info = fmem_get_info();
pmem[id].area = fmem_info->area;
+ pmem[id].base = fmem_info->phys;
} else {
pmem_vma = get_vm_area(pmem[id].size, VM_IOREMAP);
if (!pmem_vma) {
@@ -2844,12 +2844,17 @@
if (pdata->release_region)
pmem[id].mem_release = pdata->release_region;
+ pr_info("allocating %lu bytes at %lx physical for %s\n",
+ pmem[id].size, pmem[id].base, pmem[id].name);
+
return 0;
cleanup_vm:
- remove_vm_area(pmem_vma);
+ if (!pmem[id].reusable)
+ remove_vm_area(pmem_vma);
err_free:
- free_contiguous_memory_by_paddr(pmem[id].base);
+ if (!pmem[id].reusable)
+ free_contiguous_memory_by_paddr(pmem[id].base);
err_misc_deregister:
misc_deregister(&pmem[id].dev);
err_cant_register_device:
diff --git a/drivers/misc/tzcom.c b/drivers/misc/tzcom.c
index e662f43..2b1484c 100644
--- a/drivers/misc/tzcom.c
+++ b/drivers/misc/tzcom.c
@@ -1002,7 +1002,10 @@
}
spin_unlock_irqrestore(&tzcom_data->registered_svc_list_lock, flags);
PDEBUG("After removing svc list");
-
+ if (pil != NULL) {
+ pil_put(pil);
+ pil = NULL;
+ }
PDEBUG("Freeing tzcom data");
kfree(tzcom_data);
return 0;
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index 3ae639e..e364eac 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -1042,8 +1042,6 @@
host->curr.got_dataend = 0;
host->curr.got_auto_prog_done = 0;
- memset(&host->pio, 0, sizeof(host->pio));
-
datactrl = MCI_DPSM_ENABLE | (data->blksz << 4);
if (host->curr.wait_for_auto_prog_done)
@@ -1078,17 +1076,21 @@
/* Is data transfer in PIO mode required? */
if (!(datactrl & MCI_DPSM_DMAENABLE)) {
- host->pio.sg = data->sg;
- host->pio.sg_len = data->sg_len;
- host->pio.sg_off = 0;
+ unsigned int sg_miter_flags = SG_MITER_ATOMIC;
if (data->flags & MMC_DATA_READ) {
+ sg_miter_flags |= SG_MITER_TO_SG;
pio_irqmask = MCI_RXFIFOHALFFULLMASK;
if (host->curr.xfer_remain < MCI_FIFOSIZE)
pio_irqmask |= MCI_RXDATAAVLBLMASK;
- } else
+ } else {
+ sg_miter_flags |= SG_MITER_FROM_SG;
pio_irqmask = MCI_TXFIFOHALFEMPTYMASK |
MCI_TXFIFOEMPTYMASK;
+ }
+
+ sg_miter_start(&host->sg_miter, data->sg, data->sg_len,
+ sg_miter_flags);
}
if (data->flags & MMC_DATA_READ)
@@ -1254,6 +1256,7 @@
struct msmsdcc_host *host = dev_id;
void __iomem *base = host->base;
uint32_t status;
+ unsigned long flags;
spin_lock(&host->lock);
@@ -1268,9 +1271,10 @@
#if IRQ_DEBUG
msmsdcc_print_status(host, "irq1-r", status);
#endif
+ local_irq_save(flags);
- do {
- unsigned long flags;
+ while (sg_miter_next(&host->sg_miter)) {
+
unsigned int remain, len;
char *buffer;
@@ -1278,12 +1282,8 @@
| MCI_RXDATAAVLBL)))
break;
- /* Map the current scatter buffer */
- local_irq_save(flags);
- buffer = kmap_atomic(sg_page(host->pio.sg),
- KM_BIO_SRC_IRQ) + host->pio.sg->offset;
- buffer += host->pio.sg_off;
- remain = host->pio.sg->length - host->pio.sg_off;
+ buffer = host->sg_miter.addr;
+ remain = host->sg_miter.length;
len = 0;
if (status & MCI_RXACTIVE)
@@ -1294,11 +1294,7 @@
if (len > remain)
len = remain;
- /* Unmap the buffer */
- kunmap_atomic(buffer, KM_BIO_SRC_IRQ);
- local_irq_restore(flags);
-
- host->pio.sg_off += len;
+ host->sg_miter.consumed = len;
host->curr.xfer_remain -= len;
host->curr.data_xfered += len;
remain -= len;
@@ -1306,20 +1302,11 @@
if (remain) /* Done with this page? */
break; /* Nope */
- if (status & MCI_RXACTIVE && host->curr.user_pages)
- flush_dcache_page(sg_page(host->pio.sg));
-
- if (!--host->pio.sg_len) {
- memset(&host->pio, 0, sizeof(host->pio));
- break;
- }
-
- /* Advance to next sg */
- host->pio.sg++;
- host->pio.sg_off = 0;
-
status = readl_relaxed(base + MMCISTATUS);
- } while (1);
+ }
+
+ sg_miter_stop(&host->sg_miter);
+ local_irq_restore(flags);
if (status & MCI_RXACTIVE && host->curr.xfer_remain < MCI_FIFOSIZE) {
writel_relaxed((readl_relaxed(host->base + MMCIMASK0) &
@@ -2300,6 +2287,10 @@
/* Select free running MCLK as input clock of cm_dll_sdc4 */
clk |= (2 << 23);
+ /* Clear IO_PAD_PWR_SWITCH while powering off the card */
+ if (!ios->vdd)
+ host->io_pad_pwr_switch = 0;
+
if (host->io_pad_pwr_switch)
clk |= IO_PAD_PWR_SWITCH;
@@ -2575,6 +2566,10 @@
unsigned long flags;
int rc = 0;
+ spin_lock_irqsave(&host->lock, flags);
+ host->io_pad_pwr_switch = 0;
+ spin_unlock_irqrestore(&host->lock, flags);
+
if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
/* Change voltage level of VDDPX to high voltage */
rc = msmsdcc_set_vddp_high_vol(host);
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index ee7a3e5..319d721 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -361,7 +361,7 @@
struct msmsdcc_sps_data sps;
bool is_dma_mode;
bool is_sps_mode;
- struct msmsdcc_pio_data pio;
+ struct sg_mapping_iter sg_miter;
#ifdef CONFIG_HAS_EARLYSUSPEND
struct early_suspend early_suspend;
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig
index 4be8373..167efd9 100644
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -318,6 +318,17 @@
The driver provides wear leveling by storing erase counter into the
OOB.
+config MTD_LAZYECCSTATS
+ bool "MTD Lazy ECC Stats collection support"
+ default y
+ help
+ Normally bad block counts for ECC stats are collected at boot time.
+ This option delays the badblock stats collection until ECCGETSTATS
+ ioctl is invoked on the partition.
+
+ This can significantly decrease boot times depending on the size of
+ the partition. If unsure, say 'N'.
+
source "drivers/mtd/chips/Kconfig"
source "drivers/mtd/maps/Kconfig"
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index f1af222..ed9468c 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -34,6 +34,7 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
#include <asm/uaccess.h>
@@ -904,6 +905,9 @@
case ECCGETSTATS:
{
+#ifdef CONFIG_MTD_LAZYECCSTATS
+ part_fill_badblockstats(mtd);
+#endif
if (copy_to_user(argp, &mtd->ecc_stats,
sizeof(struct mtd_ecc_stats)))
return -EFAULT;
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c
index 630be3e..4c75f32 100644
--- a/drivers/mtd/mtdpart.c
+++ b/drivers/mtd/mtdpart.c
@@ -353,6 +353,21 @@
kfree(p);
}
+void part_fill_badblockstats(struct mtd_info *mtd)
+{
+ struct mtd_part *part = PART(mtd);
+ if (part->master->block_isbad) {
+ uint64_t offs = 0;
+ mtd->ecc_stats.badblocks = 0;
+ while (offs < mtd->size) {
+ if (part->master->block_isbad(part->master,
+ offs + part->offset))
+ mtd->ecc_stats.badblocks++;
+ offs += mtd->erasesize;
+ }
+ }
+}
+
/*
* This function unregisters and destroy all slave MTD objects which are
* attached to the given master MTD object.
@@ -542,16 +557,10 @@
}
slave->mtd.ecclayout = master->ecclayout;
- if (master->block_isbad) {
- uint64_t offs = 0;
- while (offs < slave->mtd.size) {
- if (master->block_isbad(master,
- offs + slave->offset))
- slave->mtd.ecc_stats.badblocks++;
- offs += slave->mtd.erasesize;
- }
- }
+#ifndef CONFIG_MTD_LAZYECCSTATS
+ part_fill_badblockstats(&(slave->mtd));
+#endif
out_register:
return slave;
diff --git a/drivers/net/qfec.c b/drivers/net/qfec.c
index fc27837..e1f4be2 100644
--- a/drivers/net/qfec.c
+++ b/drivers/net/qfec.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -1899,6 +1899,11 @@
setup_timer(&priv->phy_tmr, qfec_phy_monitor, (unsigned long)dev);
mod_timer(&priv->phy_tmr, jiffies + HZ);
+ /* driver supports AN capable PHY only */
+ qfec_mdio_write(dev, priv->phy_id, MII_BMCR, BMCR_RESET);
+ res = (BMCR_ANENABLE|BMCR_ANRESTART);
+ qfec_mdio_write(dev, priv->phy_id, MII_BMCR, res);
+
/* initialize interrupts */
QFEC_LOG(QFEC_LOG_DBG, " %s: request irq %d\n", __func__, dev->irq);
res = request_irq(dev->irq, qfec_int, 0, dev->name, dev);
diff --git a/drivers/net/wireless/libra/qcomwlan_pwrif.c b/drivers/net/wireless/libra/qcomwlan_pwrif.c
index 8268f24..6a0c78f 100644
--- a/drivers/net/wireless/libra/qcomwlan_pwrif.c
+++ b/drivers/net/wireless/libra/qcomwlan_pwrif.c
@@ -72,7 +72,7 @@
static const int vregs_qwlan_peek_current[] = {
4000,
150000,
- 200000,
+ 60000,
0,
32000,
130000,
diff --git a/drivers/power/pm8921-charger.c b/drivers/power/pm8921-charger.c
index fa8f866..aca724a 100644
--- a/drivers/power/pm8921-charger.c
+++ b/drivers/power/pm8921-charger.c
@@ -415,14 +415,6 @@
disable ? CHG_CHARGE_DIS_BIT : 0);
}
-static bool pm_is_chg_charge_dis_bit_set(struct pm8921_chg_chip *chip)
-{
- u8 temp = 0;
-
- pm8xxx_readb(chip->dev->parent, CHG_CNTRL, &temp);
- return !!(temp & CHG_CHARGE_DIS_BIT);
-}
-
#define PM8921_CHG_V_MIN_MV 3240
#define PM8921_CHG_V_STEP_MV 20
#define PM8921_CHG_V_STEP_10_MV_BIT BIT(7)
@@ -1024,24 +1016,34 @@
break;
case POWER_SUPPLY_PROP_PRESENT:
case POWER_SUPPLY_PROP_ONLINE:
- if (pm_is_chg_charge_dis_bit_set(the_chip) ||
- !is_usb_chg_plugged_in(the_chip))
- val->intval = 0;
- else if (psy->type == POWER_SUPPLY_TYPE_USB ||
+ val->intval = 0;
+ if (charging_disabled)
+ return 0;
+
+ /* USB charging */
+ if (psy->type == POWER_SUPPLY_TYPE_USB ||
psy->type == POWER_SUPPLY_TYPE_USB_DCP ||
psy->type == POWER_SUPPLY_TYPE_USB_CDP ||
psy->type == POWER_SUPPLY_TYPE_USB_ACA) {
- val->intval = 1;
- } else if (psy->type == POWER_SUPPLY_TYPE_MAINS) {
+ val->intval = is_usb_chg_plugged_in(the_chip);
+ return 0;
+ }
+
+ /* DC charging */
+ if (psy->type == POWER_SUPPLY_TYPE_MAINS) {
+ /* external charger is connected */
+ if (the_chip->dc_present || is_ext_charging(the_chip)) {
+ val->intval = 1;
+ return 0;
+ }
+ /* USB with max current greater than 500 mA connected */
pm_chg_iusbmax_get(the_chip, ¤t_max);
if (current_max > USB_WALL_THRESHOLD_MA)
- val->intval = 1;
- else
- val->intval = 0;
- } else {
- val->intval = 0;
- pr_err("Unkown POWER_SUPPLY_TYPE %d\n", psy->type);
+ val->intval = is_usb_chg_plugged_in(the_chip);
+ return 0;
}
+
+ pr_err("Unkown POWER_SUPPLY_TYPE %d\n", psy->type);
break;
default:
return -EINVAL;
@@ -1592,6 +1594,7 @@
the_chip->usb_psy.type = type;
power_supply_changed(&the_chip->usb_psy);
+ power_supply_changed(&the_chip->dc_psy);
return 0;
}
EXPORT_SYMBOL_GPL(pm8921_set_usb_power_supply_type);
@@ -1639,6 +1642,7 @@
power_supply_set_charge_type(chip->ext_psy,
POWER_SUPPLY_CHARGE_TYPE_NONE);
pm8921_disable_source_current(false); /* release BATFET */
+ power_supply_changed(&chip->dc_psy);
chip->ext_charging = false;
chip->ext_charge_done = false;
bms_notify_check(chip);
@@ -1686,8 +1690,10 @@
return;
}
+ power_supply_set_online(chip->ext_psy, dc_present);
power_supply_set_charge_type(chip->ext_psy,
POWER_SUPPLY_CHARGE_TYPE_FAST);
+ power_supply_changed(&chip->dc_psy);
chip->ext_charging = true;
chip->ext_charge_done = false;
bms_notify_check(chip);
@@ -1768,6 +1774,7 @@
power_supply_changed(&chip->batt_psy);
power_supply_changed(&chip->usb_psy);
+ power_supply_changed(&chip->dc_psy);
return IRQ_HANDLED;
}
@@ -1819,6 +1826,7 @@
power_supply_changed(&chip->batt_psy);
power_supply_changed(&chip->usb_psy);
+ power_supply_changed(&chip->dc_psy);
bms_notify_check(chip);
@@ -1841,6 +1849,7 @@
power_supply_changed(&chip->batt_psy);
power_supply_changed(&chip->usb_psy);
+ power_supply_changed(&chip->dc_psy);
return IRQ_HANDLED;
}
@@ -1851,6 +1860,7 @@
pr_debug("state_changed_to=%d\n", pm_chg_get_fsm_state(data));
power_supply_changed(&chip->batt_psy);
power_supply_changed(&chip->usb_psy);
+ power_supply_changed(&chip->dc_psy);
bms_notify_check(chip);
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 02d1c39..d053cd6 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -1886,7 +1886,7 @@
}
- dev->rclk = clk_get(dev->dev, "audio_slimbus_clk");
+ dev->rclk = clk_get(dev->dev, "core_clk");
if (!dev->rclk) {
dev_err(dev->dev, "slimbus clock not found");
goto err_clk_get_failed;
diff --git a/drivers/spmi/Kconfig b/drivers/spmi/Kconfig
new file mode 100644
index 0000000..648d2e9
--- /dev/null
+++ b/drivers/spmi/Kconfig
@@ -0,0 +1,22 @@
+#
+# SPMI driver configuration
+#
+menuconfig SPMI
+ bool "SPMI support"
+ help
+ SPMI (System Power Management Interface) is a two-wire
+ serial interface between baseband and application processors
+ and Power Management Integrated Circuits (PMIC).
+
+if SPMI
+config SPMI_MSM_PMIC_ARB
+ tristate "Qualcomm MSM SPMI Controller (PMIC Arbiter)"
+ help
+ If you say yes to this option, support will be included for the
+ built-in SPMI PMIC Arbiter interface on Qualcomm MSM family
+ processors.
+
+ This is required for communicating with Qualcomm PMICs and
+ other devices that have the SPMI interface.
+
+endif
diff --git a/drivers/spmi/Makefile b/drivers/spmi/Makefile
new file mode 100644
index 0000000..8406134
--- /dev/null
+++ b/drivers/spmi/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for kernel SPMI framework.
+#
+obj-$(CONFIG_SPMI) += spmi.o
+obj-$(CONFIG_SPMI_MSM_PMIC_ARB) += spmi-pmic-arb.o
diff --git a/drivers/spmi/spmi-pmic-arb.c b/drivers/spmi/spmi-pmic-arb.c
new file mode 100644
index 0000000..e5a9d40
--- /dev/null
+++ b/drivers/spmi/spmi-pmic-arb.c
@@ -0,0 +1,733 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/spmi.h>
+#include <linux/of.h>
+#include <linux/interrupt.h>
+#include <linux/of_spmi.h>
+#include <mach/qpnp-int.h>
+
+#define SPMI_PMIC_ARB_NAME "spmi_pmic_arb"
+
+/* PMIC Arbiter configuration registers */
+#define PMIC_ARB_VERSION 0x0000
+#define PMIC_ARB_INT_EN 0x0004
+
+/* PMIC Arbiter channel registers */
+#define PMIC_ARB_CMD(N) (0x0800 + (0x80 * (N)))
+#define PMIC_ARB_CONFIG(N) (0x0804 + (0x80 * (N)))
+#define PMIC_ARB_STATUS(N) (0x0808 + (0x80 * (N)))
+#define PMIC_ARB_WDATA0(N) (0x0810 + (0x80 * (N)))
+#define PMIC_ARB_WDATA1(N) (0x0814 + (0x80 * (N)))
+#define PMIC_ARB_RDATA0(N) (0x0818 + (0x80 * (N)))
+#define PMIC_ARB_RDATA1(N) (0x081C + (0x80 * (N)))
+
+/* Interrupt Controller */
+#define SPMI_PIC_OWNER_ACC_STATUS(M, N) (0x0000 + ((32 * (M)) + (4 * (N))))
+#define SPMI_PIC_ACC_ENABLE(N) (0x0200 + (4 * (N)))
+#define SPMI_PIC_IRQ_STATUS(N) (0x0600 + (4 * (N)))
+#define SPMI_PIC_IRQ_CLEAR(N) (0x0A00 + (4 * (N)))
+
+/* Channel Status fields */
+enum pmic_arb_chnl_status {
+ PMIC_ARB_STATUS_DONE = (1 << 0),
+ PMIC_ARB_STATUS_FAILURE = (1 << 1),
+ PMIC_ARB_STATUS_DENIED = (1 << 2),
+ PMIC_ARB_STATUS_DROPPED = (1 << 3),
+};
+
+/* Command register fields */
+#define PMIC_ARB_CMD_MAX_BYTE_COUNT 8
+
+/* Command Opcodes */
+enum pmic_arb_cmd_op_code {
+ PMIC_ARB_OP_EXT_WRITEL = 0,
+ PMIC_ARB_OP_EXT_READL = 1,
+ PMIC_ARB_OP_EXT_WRITE = 2,
+ PMIC_ARB_OP_RESET = 3,
+ PMIC_ARB_OP_SLEEP = 4,
+ PMIC_ARB_OP_SHUTDOWN = 5,
+ PMIC_ARB_OP_WAKEUP = 6,
+ PMIC_ARB_OP_AUTHENTICATE = 7,
+ PMIC_ARB_OP_MSTR_READ = 8,
+ PMIC_ARB_OP_MSTR_WRITE = 9,
+ PMIC_ARB_OP_EXT_READ = 13,
+ PMIC_ARB_OP_WRITE = 14,
+ PMIC_ARB_OP_READ = 15,
+ PMIC_ARB_OP_ZERO_WRITE = 16,
+};
+
+/* Maximum number of support PMIC peripherals */
+#define PMIC_ARB_MAX_PERIPHS 256
+#define PMIC_ARB_PERIPH_ID_VALID (1 << 15)
+#define PMIC_ARB_TIMEOUT_US 100
+#define PMIC_ARB_APID_MASK 0xFF
+#define PMIC_ARB_PPID_MASK 0xFFF
+
+/**
+ * base - base address of the PMIC Arbiter core registers.
+ * intr - base address of the SPMI interrupt control registers
+ */
+struct spmi_pmic_arb_dev {
+ struct spmi_controller controller;
+ struct device *dev;
+ struct device *slave;
+ void __iomem *base;
+ void __iomem *intr;
+ int pic_irq;
+ int pic_enable_cnt;
+ spinlock_t lock;
+ u8 owner;
+ u8 channel;
+ u8 min_apid;
+ u8 max_apid;
+ u16 periph_id_map[PMIC_ARB_MAX_PERIPHS];
+};
+
+static u32 pmic_arb_read(struct spmi_pmic_arb_dev *dev, u32 offset)
+{
+ u32 val = readl_relaxed(dev->base + offset);
+ pr_debug("address 0x%p, val 0x%x\n", dev->base + offset, val);
+ return val;
+}
+
+static void pmic_arb_write(struct spmi_pmic_arb_dev *dev, u32 offset, u32 val)
+{
+ pr_debug("address 0x%p, val 0x%x\n", dev->base + offset, val);
+ writel_relaxed(val, dev->base + offset);
+}
+
+static int pmic_arb_wait_for_done(struct spmi_pmic_arb_dev *dev)
+{
+ u32 status = 0;
+ u32 timeout = PMIC_ARB_TIMEOUT_US;
+ u32 offset = PMIC_ARB_STATUS(dev->channel);
+
+ while (timeout--) {
+ status = pmic_arb_read(dev, offset);
+
+ if (status & PMIC_ARB_STATUS_DONE) {
+ if (status & PMIC_ARB_STATUS_DENIED) {
+ dev_err(dev->dev,
+ "%s: transaction denied (0x%x)\n",
+ __func__, status);
+ return -EPERM;
+ }
+
+ if (status & PMIC_ARB_STATUS_FAILURE) {
+ dev_err(dev->dev,
+ "%s: transaction failed (0x%x)\n",
+ __func__, status);
+ return -EIO;
+ }
+
+ if (status & PMIC_ARB_STATUS_DROPPED) {
+ dev_err(dev->dev,
+ "%s: transaction dropped (0x%x)\n",
+ __func__, status);
+ return -EIO;
+ }
+
+ return 0;
+ }
+ udelay(1);
+ }
+
+ dev_err(dev->dev, "%s: timeout, status 0x%x\n", __func__, status);
+ return -ETIMEDOUT;
+}
+
+static void pa_read_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
+{
+ u32 data = pmic_arb_read(dev, reg);
+
+ switch (bc & 0x3) {
+ case 3:
+ *buf++ = data & 0xff;
+ data >>= 8;
+ case 2:
+ *buf++ = data & 0xff;
+ data >>= 8;
+ case 1:
+ *buf++ = data & 0xff;
+ data >>= 8;
+ case 0:
+ *buf++ = data & 0xff;
+ default:
+ break;
+ }
+}
+
+static void
+pa_write_data(struct spmi_pmic_arb_dev *dev, u8 *buf, u32 reg, u8 bc)
+{
+ u32 data = 0;
+
+ switch (bc & 0x3) {
+ case 3:
+ data = (buf[0]|buf[1]<<8|buf[2]<<16|buf[3]<<24);
+ break;
+ case 2:
+ data = (buf[0]|buf[1]<<8|buf[2]<<16);
+ break;
+ case 1:
+ data = (buf[0]|buf[1]<<8);
+ break;
+ case 0:
+ data = (buf[0]);
+ break;
+ default:
+ break;
+ }
+
+ pmic_arb_write(dev, reg, data);
+}
+
+/* Non-data command */
+static int pmic_arb_cmd(struct spmi_controller *ctrl, u8 opc, u8 sid)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
+ unsigned long flags;
+ u32 cmd;
+ int rc;
+
+ pr_debug("op:0x%x sid:%d\n", opc, sid);
+
+ /* Check for valid non-data command */
+ if (opc < SPMI_CMD_RESET || opc > SPMI_CMD_WAKEUP)
+ return -EINVAL;
+
+ cmd = ((opc | 0x40) << 27) | ((sid & 0xf) << 20);
+
+ spin_lock_irqsave(&pmic_arb->lock, flags);
+ pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
+ rc = pmic_arb_wait_for_done(pmic_arb);
+ spin_unlock_irqrestore(&pmic_arb->lock, flags);
+
+ return rc;
+}
+
+static int pmic_arb_read_cmd(struct spmi_controller *ctrl,
+ u8 opc, u8 sid, u16 addr, u8 bc, u8 *buf)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
+ unsigned long flags;
+ u32 cmd;
+ int rc;
+
+ pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
+
+ /* Check the opcode */
+ if (opc >= 0x60 && opc <= 0x7F)
+ opc = PMIC_ARB_OP_READ;
+ else if (opc >= 0x20 && opc <= 0x2F)
+ opc = PMIC_ARB_OP_EXT_READ;
+ else if (opc >= 0x38 && opc <= 0x3F)
+ opc = PMIC_ARB_OP_EXT_READL;
+ else
+ return -EINVAL;
+
+ cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
+
+ spin_lock_irqsave(&pmic_arb->lock, flags);
+ pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
+ rc = pmic_arb_wait_for_done(pmic_arb);
+ if (rc)
+ goto done;
+
+ /* Read from FIFO, note 'bc' is actually number of bytes minus 1 */
+ pa_read_data(pmic_arb, buf, PMIC_ARB_RDATA0(pmic_arb->channel), bc);
+
+ if (bc > 3)
+ pa_read_data(pmic_arb, buf + 4,
+ PMIC_ARB_RDATA1(pmic_arb->channel), bc);
+
+done:
+ spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ return rc;
+}
+
+static int pmic_arb_write_cmd(struct spmi_controller *ctrl,
+ u8 opc, u8 sid, u16 addr, u8 bc, u8 *buf)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
+ unsigned long flags;
+ u32 cmd;
+ int rc;
+
+ pr_debug("op:0x%x sid:%d bc:%d addr:0x%x\n", opc, sid, bc, addr);
+
+ /* Check the opcode */
+ if (opc >= 0x40 && opc <= 0x5F)
+ opc = PMIC_ARB_OP_WRITE;
+ else if (opc >= 0x00 && opc <= 0x0F)
+ opc = PMIC_ARB_OP_EXT_WRITE;
+ else if (opc >= 0x30 && opc <= 0x37)
+ opc = PMIC_ARB_OP_EXT_WRITEL;
+ else if (opc >= 0x80 && opc <= 0xFF)
+ opc = PMIC_ARB_OP_ZERO_WRITE;
+ else
+ return -EINVAL;
+
+ cmd = (opc << 27) | ((sid & 0xf) << 20) | (addr << 4) | (bc & 0x7);
+
+ /* Write data to FIFOs */
+ spin_lock_irqsave(&pmic_arb->lock, flags);
+ pa_write_data(pmic_arb, buf, PMIC_ARB_WDATA0(pmic_arb->channel), bc);
+
+ if (bc > 3)
+ pa_write_data(pmic_arb, buf + 4,
+ PMIC_ARB_WDATA1(pmic_arb->channel), bc);
+
+ /* Start the transaction */
+ pmic_arb_write(pmic_arb, PMIC_ARB_CMD(pmic_arb->channel), cmd);
+ rc = pmic_arb_wait_for_done(pmic_arb);
+ spin_unlock_irqrestore(&pmic_arb->lock, flags);
+
+ return rc;
+}
+
+/* APID to PPID */
+static u16 get_peripheral_id(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
+{
+ return pmic_arb->periph_id_map[apid] & PMIC_ARB_PPID_MASK;
+}
+
+/* APID to PPID, returns valid flag */
+static int is_apid_valid(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
+{
+ return pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID;
+}
+
+/* PPID to APID */
+static uint32_t map_peripheral_id(struct spmi_pmic_arb_dev *pmic_arb, u16 ppid)
+{
+ int first = pmic_arb->min_apid;
+ int last = pmic_arb->max_apid;
+ int i;
+
+ /* Search table for a matching PPID */
+ for (i = first; i <= last; ++i) {
+ if ((pmic_arb->periph_id_map[i] & PMIC_ARB_PPID_MASK) == ppid)
+ return i;
+ }
+
+ dev_err(pmic_arb->dev, "Unknown ppid 0x%x\n", ppid);
+ return PMIC_ARB_MAX_PERIPHS;
+}
+
+/* Enable interrupt at the PMIC Arbiter PIC */
+static int pmic_arb_pic_enable(struct spmi_controller *ctrl,
+ struct qpnp_irq_spec *spec, uint32_t data)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
+ u8 apid = data & PMIC_ARB_APID_MASK;
+ unsigned long flags;
+ u32 status;
+
+ dev_dbg(pmic_arb->dev, "PIC enable, apid:0x%x, sid:0x%x, pid:0x%x\n",
+ apid, spec->slave, spec->per);
+
+ if (data < pmic_arb->min_apid || data > pmic_arb->max_apid) {
+ dev_err(pmic_arb->dev, "int enable: invalid APID %d\n", data);
+ return -EINVAL;
+ }
+
+ if (!is_apid_valid(pmic_arb, apid)) {
+ dev_err(pmic_arb->dev, "int enable: int not supported\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pmic_arb->lock, flags);
+ status = readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
+ if (!status) {
+ if (pmic_arb->pic_enable_cnt++ == 0)
+ enable_irq(pmic_arb->pic_irq);
+ writel_relaxed(0x1, pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
+ /* Interrupt needs to be enabled before returning to caller */
+ wmb();
+ }
+ spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ return 0;
+}
+
+/* Disable interrupt at the PMIC Arbiter PIC */
+static int pmic_arb_pic_disable(struct spmi_controller *ctrl,
+ struct qpnp_irq_spec *spec, uint32_t data)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
+ u8 apid = data & PMIC_ARB_APID_MASK;
+ unsigned long flags;
+ u32 status;
+
+ dev_dbg(pmic_arb->dev, "PIC disable, apid:0x%x, sid:0x%x, pid:0x%x\n",
+ apid, spec->slave, spec->per);
+
+ if (data < pmic_arb->min_apid || data > pmic_arb->max_apid) {
+ dev_err(pmic_arb->dev, "int disable: invalid APID %d\n", data);
+ return -EINVAL;
+ }
+
+ if (!is_apid_valid(pmic_arb, apid)) {
+ dev_err(pmic_arb->dev, "int disable: int not supported\n");
+ return -EINVAL;
+ }
+
+ spin_lock_irqsave(&pmic_arb->lock, flags);
+ status = readl_relaxed(pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
+ if (status) {
+ if (pmic_arb->pic_enable_cnt-- == 1)
+ disable_irq(pmic_arb->pic_irq);
+ writel_relaxed(0x0, pmic_arb->intr + SPMI_PIC_ACC_ENABLE(apid));
+ /* Interrupt needs to be disabled before returning to caller */
+ wmb();
+ }
+ spin_unlock_irqrestore(&pmic_arb->lock, flags);
+ return 0;
+}
+
+static irqreturn_t
+periph_interrupt(struct spmi_pmic_arb_dev *pmic_arb, u8 apid)
+{
+ u16 ppid = get_peripheral_id(pmic_arb, apid);
+ void __iomem *base = pmic_arb->intr;
+ u8 sid = (ppid >> 8) & 0x0F;
+ u8 pid = ppid & 0xFF;
+ u32 status;
+ int i;
+
+ if (!is_apid_valid(pmic_arb, apid)) {
+ dev_err(pmic_arb->dev, "unknown peripheral id 0x%x\n", ppid);
+ /* return IRQ_NONE; */
+ }
+
+ /* Read the peripheral specific interrupt bits */
+ status = readl_relaxed(base + SPMI_PIC_IRQ_STATUS(apid));
+
+ /* Clear the peripheral interrupts */
+ writel_relaxed(status, base + SPMI_PIC_IRQ_CLEAR(apid));
+ /* Interrupt needs to be cleared/acknowledged before exiting ISR */
+ mb();
+
+ dev_dbg(pmic_arb->dev,
+ "interrupt, apid:0x%x, sid:0x%x, pid:0x%x, intr:0x%x\n",
+ apid, sid, pid, status);
+
+ /* Send interrupt notification */
+ for (i = 0; status && i < 8; ++i, status >>= 1) {
+ if (status & 0x1) {
+ struct qpnp_irq_spec irq_spec = {
+ .slave = sid,
+ .per = pid,
+ .irq = i,
+ };
+ qpnpint_handle_irq(&pmic_arb->controller, &irq_spec);
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+/* Peripheral interrupt handler */
+static irqreturn_t pmic_arb_periph_irq(int irq, void *dev_id)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = dev_id;
+ void __iomem *intr = pmic_arb->intr;
+ u8 ee = pmic_arb->owner;
+ u32 ret = IRQ_NONE;
+ u32 status;
+
+ int first = pmic_arb->min_apid >> 5;
+ int last = pmic_arb->max_apid >> 5;
+ int i, j;
+
+ dev_dbg(pmic_arb->dev, "Peripheral interrupt detected\n");
+
+ /* Check the accumulated interrupt status */
+ for (i = first; i <= last; ++i) {
+ status = readl_relaxed(intr + SPMI_PIC_OWNER_ACC_STATUS(ee, i));
+
+ for (j = 0; status && j < 32; ++j, status >>= 1) {
+ if (status & 0x1) {
+ u8 id = (i * 32) + j;
+ ret |= periph_interrupt(pmic_arb, id);
+ }
+ }
+ }
+
+ return ret;
+}
+
+/* Callback to register an APID for specific slave/peripheral */
+static int pmic_arb_intr_priv_data(struct spmi_controller *ctrl,
+ struct qpnp_irq_spec *spec, uint32_t *data)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = spmi_get_ctrldata(ctrl);
+ u16 ppid = ((spec->slave & 0x0F) << 8) | (spec->per & 0xFF);
+ *data = map_peripheral_id(pmic_arb, ppid);
+ return 0;
+}
+
+static int __devinit
+spmi_pmic_arb_get_property(struct platform_device *pdev, char *pname, u32 *prop)
+{
+ int ret = of_property_read_u32(pdev->dev.of_node, pname, prop);
+
+ if (ret)
+ dev_err(&pdev->dev, "missing property: %s\n", pname);
+ else
+ pr_debug("%s = 0x%x\n", pname, *prop);
+
+ return ret;
+}
+
+static int __devinit spmi_pmic_arb_get_map_data(struct platform_device *pdev,
+ struct spmi_pmic_arb_dev *pmic_arb)
+{
+ int i;
+ int ret;
+ int map_size;
+ u32 *map_data;
+ const int map_width = 2 * sizeof(*map_data);
+ const struct device_node *of_node = pdev->dev.of_node;
+
+ /* Get size of the mapping table (in bytes) */
+ if (!of_get_property(of_node, "qcom,pmic-arb-ppid-map", &map_size)) {
+ dev_err(&pdev->dev, "missing ppid mapping table\n");
+ return -ENODEV;
+ }
+
+ /* Map size can't exceed the maximum number of peripherals */
+ if (map_size == 0 || map_size % map_width ||
+ map_size > map_width * PMIC_ARB_MAX_PERIPHS) {
+ dev_err(&pdev->dev, "map size of %d is not valid\n", map_size);
+ return -ENODEV;
+ }
+
+ map_data = kzalloc(map_size, GFP_KERNEL);
+ if (!map_data) {
+ dev_err(&pdev->dev, "can not allocate map data\n");
+ return -ENOMEM;
+ }
+
+ ret = of_property_read_u32_array(of_node,
+ "qcom,pmic-arb-ppid-map", map_data, map_size/sizeof(u32));
+ if (ret) {
+ dev_err(&pdev->dev, "invalid or missing property: ppid-map\n");
+ goto err;
+ };
+
+ pmic_arb->max_apid = 0;
+ pmic_arb->min_apid = PMIC_ARB_MAX_PERIPHS - 1;
+
+ /* Build the mapping table from the data */
+ for (i = 0; i < map_size/sizeof(u32);) {
+ u32 ppid = map_data[i++];
+ u32 apid = map_data[i++];
+
+ if (apid > PMIC_ARB_APID_MASK) {
+ ret = -ENODEV;
+ dev_err(&pdev->dev, "invalid APID: 0x%x\n", apid);
+ goto err;
+ }
+
+ if (ppid > PMIC_ARB_PPID_MASK) {
+ ret = -ENODEV;
+ dev_err(&pdev->dev, "invalid PPID: 0x%x\n", ppid);
+ goto err;
+ }
+
+ if (pmic_arb->periph_id_map[apid] & PMIC_ARB_PERIPH_ID_VALID)
+ dev_warn(&pdev->dev, "duplicate APID 0x%x\n", apid);
+
+ pmic_arb->periph_id_map[apid] = ppid | PMIC_ARB_PERIPH_ID_VALID;
+
+ if (apid > pmic_arb->max_apid)
+ pmic_arb->max_apid = apid;
+
+ if (apid < pmic_arb->min_apid)
+ pmic_arb->min_apid = apid;
+ }
+
+ pr_debug("%d value(s) mapped, min:%d, max:%d\n",
+ map_size/map_width, pmic_arb->min_apid, pmic_arb->max_apid);
+
+err:
+ kfree(map_data);
+ return ret;
+}
+
+static struct qpnp_local_int spmi_pmic_arb_intr_cb = {
+ .mask = pmic_arb_pic_disable,
+ .unmask = pmic_arb_pic_enable,
+ .register_priv_data = pmic_arb_intr_priv_data,
+};
+
+static int __devinit spmi_pmic_arb_probe(struct platform_device *pdev)
+{
+ struct spmi_pmic_arb_dev *pmic_arb;
+ struct resource *mem_res;
+ u32 cell_index;
+ u32 prop;
+ int ret = 0;
+
+ pr_debug("SPMI PMIC Arbiter\n");
+
+ pmic_arb = devm_kzalloc(&pdev->dev,
+ sizeof(struct spmi_pmic_arb_dev), GFP_KERNEL);
+ if (!pmic_arb) {
+ dev_err(&pdev->dev, "can not allocate pmic_arb data\n");
+ return -ENOMEM;
+ }
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!mem_res) {
+ dev_err(&pdev->dev, "missing base memory resource\n");
+ return -ENODEV;
+ }
+
+ pmic_arb->base = devm_ioremap(&pdev->dev,
+ mem_res->start, resource_size(mem_res));
+ if (!pmic_arb->base) {
+ dev_err(&pdev->dev, "ioremap of 'base' failed\n");
+ return -ENOMEM;
+ }
+
+ mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (!mem_res) {
+ dev_err(&pdev->dev, "missing mem resource (interrupts)\n");
+ return -ENODEV;
+ }
+
+ pmic_arb->intr = devm_ioremap(&pdev->dev,
+ mem_res->start, resource_size(mem_res));
+ if (!pmic_arb->intr) {
+ dev_err(&pdev->dev, "ioremap of 'intr' failed\n");
+ return -ENOMEM;
+ }
+
+ pmic_arb->pic_irq = platform_get_irq(pdev, 0);
+ if (!pmic_arb->pic_irq) {
+ dev_err(&pdev->dev, "missing IRQ resource\n");
+ return -ENODEV;
+ }
+
+ ret = devm_request_irq(&pdev->dev, pmic_arb->pic_irq,
+ pmic_arb_periph_irq, IRQF_TRIGGER_HIGH, pdev->name, pmic_arb);
+ if (ret) {
+ dev_err(&pdev->dev, "request IRQ failed\n");
+ return ret;
+ }
+ disable_irq(pmic_arb->pic_irq);
+
+ /* Get properties from the device tree */
+ ret = spmi_pmic_arb_get_property(pdev, "cell-index", &cell_index);
+ if (ret)
+ return -ENODEV;
+
+ ret = spmi_pmic_arb_get_map_data(pdev, pmic_arb);
+ if (ret)
+ return ret;
+
+ ret = spmi_pmic_arb_get_property(pdev, "qcom,pmic-arb-ee", &prop);
+ if (ret)
+ return -ENODEV;
+ pmic_arb->owner = (u8)prop;
+
+ ret = spmi_pmic_arb_get_property(pdev, "qcom,pmic-arb-channel", &prop);
+ if (ret)
+ return -ENODEV;
+ pmic_arb->channel = (u8)prop;
+
+ pmic_arb->dev = &pdev->dev;
+ platform_set_drvdata(pdev, pmic_arb);
+ spmi_set_ctrldata(&pmic_arb->controller, pmic_arb);
+
+ spin_lock_init(&pmic_arb->lock);
+
+ pmic_arb->controller.nr = cell_index;
+ pmic_arb->controller.dev.parent = pdev->dev.parent;
+ pmic_arb->controller.dev.of_node = of_node_get(pdev->dev.of_node);
+
+ /* Callbacks */
+ pmic_arb->controller.cmd = pmic_arb_cmd;
+ pmic_arb->controller.read_cmd = pmic_arb_read_cmd;
+ pmic_arb->controller.write_cmd = pmic_arb_write_cmd;
+
+ ret = spmi_add_controller(&pmic_arb->controller);
+ if (ret)
+ goto err_add_controller;
+
+ /* Register the interrupt enable/disable functions */
+ qpnpint_register_controller(cell_index, &spmi_pmic_arb_intr_cb);
+
+ /* Register device(s) from the device tree */
+ of_spmi_register_devices(&pmic_arb->controller);
+
+ pr_debug("PMIC Arb Version 0x%x\n",
+ pmic_arb_read(pmic_arb, PMIC_ARB_VERSION));
+
+ return 0;
+
+err_add_controller:
+ platform_set_drvdata(pdev, NULL);
+ return ret;
+}
+
+static int __devexit spmi_pmic_arb_remove(struct platform_device *pdev)
+{
+ struct spmi_pmic_arb_dev *pmic_arb = platform_get_drvdata(pdev);
+
+ free_irq(pmic_arb->pic_irq, pmic_arb);
+ platform_set_drvdata(pdev, NULL);
+ spmi_del_controller(&pmic_arb->controller);
+ return 0;
+}
+
+static struct of_device_id spmi_pmic_arb_match_table[] = {
+ { .compatible = "qcom,spmi-pmic-arb",
+ },
+ {}
+};
+
+static struct platform_driver spmi_pmic_arb_driver = {
+ .probe = spmi_pmic_arb_probe,
+ .remove = __exit_p(spmi_pmic_arb_remove),
+ .driver = {
+ .name = SPMI_PMIC_ARB_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = spmi_pmic_arb_match_table,
+ },
+};
+
+static int __init spmi_pmic_arb_init(void)
+{
+ return platform_driver_register(&spmi_pmic_arb_driver);
+}
+postcore_initcall(spmi_pmic_arb_init);
+
+static void __exit spmi_pmic_arb_exit(void)
+{
+ platform_driver_unregister(&spmi_pmic_arb_driver);
+}
+module_exit(spmi_pmic_arb_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:spmi_pmic_arb");
diff --git a/drivers/spmi/spmi.c b/drivers/spmi/spmi.c
new file mode 100644
index 0000000..2842cd8
--- /dev/null
+++ b/drivers/spmi/spmi.c
@@ -0,0 +1,789 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#define pr_fmt(fmt) "%s: " fmt, __func__
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/idr.h>
+#include <linux/slab.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/spmi.h>
+
+struct spmii_boardinfo {
+ struct list_head list;
+ struct spmi_boardinfo board_info;
+};
+
+static DEFINE_MUTEX(board_lock);
+static LIST_HEAD(board_list);
+static LIST_HEAD(spmi_ctrl_list);
+static DEFINE_IDR(ctrl_idr);
+static struct device_type spmi_ctrl_type = { 0 };
+
+#define to_spmi(dev) platform_get_drvdata(to_platform_device(dev))
+
+/* Forward declarations */
+struct bus_type spmi_bus_type;
+static int spmi_register_controller(struct spmi_controller *ctrl);
+
+/**
+ * spmi_busnum_to_ctrl: Map bus number to controller
+ * @busnum: bus number
+ * Returns controller representing this bus number
+ */
+struct spmi_controller *spmi_busnum_to_ctrl(u32 bus_num)
+{
+ struct spmi_controller *ctrl;
+
+ mutex_lock(&board_lock);
+ list_for_each_entry(ctrl, &spmi_ctrl_list, list) {
+ if (bus_num == ctrl->nr) {
+ mutex_unlock(&board_lock);
+ return ctrl;
+ }
+ }
+ mutex_unlock(&board_lock);
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(spmi_busnum_to_ctrl);
+
+/**
+ * spmi_add_controller: Controller bring-up.
+ * @ctrl: controller to be registered.
+ * A controller is registered with the framework using this API. ctrl->nr is the
+ * desired number with which SPMI framework registers the controller.
+ * Function will return -EBUSY if the number is in use.
+ */
+int spmi_add_controller(struct spmi_controller *ctrl)
+{
+ int id;
+ int status;
+
+ pr_debug("adding controller for bus %d (0x%p)\n", ctrl->nr, ctrl);
+
+ if (ctrl->nr & ~MAX_ID_MASK) {
+ pr_err("invalid bus identifier %d\n", ctrl->nr);
+ return -EINVAL;
+ }
+
+retry:
+ if (idr_pre_get(&ctrl_idr, GFP_KERNEL) == 0) {
+ pr_err("no free memory for idr\n");
+ return -ENOMEM;
+ }
+
+ mutex_lock(&board_lock);
+ status = idr_get_new_above(&ctrl_idr, ctrl, ctrl->nr, &id);
+ if (status == 0 && id != ctrl->nr) {
+ status = -EAGAIN;
+ idr_remove(&ctrl_idr, id);
+ }
+ mutex_unlock(&board_lock);
+ if (status == -EAGAIN)
+ goto retry;
+
+ if (status == 0)
+ status = spmi_register_controller(ctrl);
+ return status;
+}
+EXPORT_SYMBOL_GPL(spmi_add_controller);
+
+/**
+ * spmi_del_controller: Controller tear-down.
+ * @ctrl: controller to which this device is to be added to.
+ *
+ * Controller added with the above API is torn down using this API.
+ */
+int spmi_del_controller(struct spmi_controller *ctrl)
+{
+ return -ENXIO;
+}
+EXPORT_SYMBOL_GPL(spmi_del_controller);
+
+#define spmi_device_attr_gr NULL
+#define spmi_device_uevent NULL
+static void spmi_dev_release(struct device *dev)
+{
+ struct spmi_device *spmidev = to_spmi_device(dev);
+ kfree(spmidev);
+}
+
+static struct device_type spmi_dev_type = {
+ .groups = spmi_device_attr_gr,
+ .uevent = spmi_device_uevent,
+ .release = spmi_dev_release,
+};
+
+/**
+ * spmi_alloc_device: Allocate a new SPMI devices.
+ * @ctrl: controller to which this device is to be added to.
+ * Context: can sleep
+ *
+ * Allows a driver to allocate and initialize a SPMI device without
+ * registering it immediately. This allows a driver to directly fill
+ * the spmi_device structure before calling spmi_add_device().
+ *
+ * Caller is responsible to call spmi_add_device() on the returned
+ * spmi_device. If the caller needs to discard the spmi_device without
+ * adding it, then spmi_dev_put() should be called.
+ */
+struct spmi_device *spmi_alloc_device(struct spmi_controller *ctrl)
+{
+ struct spmi_device *spmidev;
+
+ if (!ctrl) {
+ pr_err("Missing SPMI controller\n");
+ return NULL;
+ }
+
+ spmidev = kzalloc(sizeof(*spmidev), GFP_KERNEL);
+ if (!spmidev) {
+ dev_err(&ctrl->dev, "unable to allocate spmi_device\n");
+ return NULL;
+ }
+
+ spmidev->ctrl = ctrl;
+ spmidev->dev.parent = ctrl->dev.parent;
+ spmidev->dev.bus = &spmi_bus_type;
+ spmidev->dev.type = &spmi_dev_type;
+ device_initialize(&spmidev->dev);
+
+ return spmidev;
+}
+EXPORT_SYMBOL_GPL(spmi_alloc_device);
+
+/* Validate the SPMI device structure */
+static struct device *get_valid_device(struct spmi_device *spmidev)
+{
+ struct device *dev;
+
+ if (!spmidev)
+ return NULL;
+
+ dev = &spmidev->dev;
+ if (dev->bus != &spmi_bus_type || dev->type != &spmi_dev_type)
+ return NULL;
+
+ return dev;
+}
+
+/**
+ * spmi_add_device: Add a new device without register board info.
+ * @ctrl: controller to which this device is to be added to.
+ *
+ * Called when device doesn't have an explicit client-driver to be probed, or
+ * the client-driver is a module installed dynamically.
+ */
+int spmi_add_device(struct spmi_device *spmidev)
+{
+ int rc;
+ struct device *dev = get_valid_device(spmidev);
+
+ if (!dev) {
+ pr_err("%s: invalid SPMI device\n", __func__);
+ return -EINVAL;
+ }
+
+ /* Set the device name */
+ dev_set_name(dev, "%s-%p", spmidev->name, spmidev);
+
+ /* Device may be bound to an active driver when this returns */
+ rc = device_add(dev);
+
+ if (rc < 0)
+ dev_err(dev, "Can't add %s, status %d\n", dev_name(dev), rc);
+ else
+ dev_dbg(dev, "device %s registered\n", dev_name(dev));
+
+ return rc;
+}
+EXPORT_SYMBOL_GPL(spmi_add_device);
+
+/**
+ * spmi_new_device: Instantiates a new SPMI device
+ * @ctrl: controller to which this device is to be added to.
+ * @info: board information for this device.
+ *
+ * Returns the new device or NULL.
+ */
+struct spmi_device *spmi_new_device(struct spmi_controller *ctrl,
+ struct spmi_boardinfo const *info)
+{
+ struct spmi_device *spmidev;
+ int rc;
+
+ if (!ctrl || !info)
+ return NULL;
+
+ spmidev = spmi_alloc_device(ctrl);
+ if (!spmidev)
+ return NULL;
+
+ spmidev->name = info->name;
+ spmidev->sid = info->slave_id;
+ spmidev->dev.of_node = info->of_node;
+ spmidev->resource = info->resource;
+ spmidev->num_resources = info->num_resources;
+ spmidev->dev.platform_data = (void *)info->platform_data;
+
+ rc = spmi_add_device(spmidev);
+ if (rc < 0) {
+ spmi_dev_put(spmidev);
+ return NULL;
+ }
+
+ return spmidev;
+}
+EXPORT_SYMBOL_GPL(spmi_new_device);
+
+/* spmi_remove_device: Remove the effect of spmi_add_device() */
+void spmi_remove_device(struct spmi_device *spmi_dev)
+{
+ device_unregister(&spmi_dev->dev);
+}
+EXPORT_SYMBOL_GPL(spmi_remove_device);
+
+/* If controller is not present, only add to boards list */
+static void spmi_match_ctrl_to_boardinfo(struct spmi_controller *ctrl,
+ struct spmi_boardinfo *bi)
+{
+ struct spmi_device *spmidev;
+
+ spmidev = spmi_new_device(ctrl, bi);
+ if (!spmidev)
+ dev_err(ctrl->dev.parent, "can't create new device for %s\n",
+ bi->name);
+}
+
+/**
+ * spmi_register_board_info: Board-initialization routine.
+ * @bus_num: controller number (bus) on which this device will sit.
+ * @info: list of all devices on all controllers present on the board.
+ * @n: number of entries.
+ * API enumerates respective devices on corresponding controller.
+ * Called from board-init function.
+ */
+int spmi_register_board_info(int busnum,
+ struct spmi_boardinfo const *info, unsigned n)
+{
+ int i;
+ struct spmii_boardinfo *bi;
+
+ bi = kzalloc(n * sizeof(*bi), GFP_KERNEL);
+ if (!bi)
+ return -ENOMEM;
+
+ for (i = 0; i < n; i++, bi++, info++) {
+ struct spmi_controller *ctrl;
+
+ memcpy(&bi->board_info, info, sizeof(*info));
+ mutex_lock(&board_lock);
+ list_add_tail(&bi->list, &board_list);
+ list_for_each_entry(ctrl, &spmi_ctrl_list, list)
+ if (ctrl->nr == busnum)
+ spmi_match_ctrl_to_boardinfo(ctrl,
+ &bi->board_info);
+ mutex_unlock(&board_lock);
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(spmi_register_board_info);
+
+/* ------------------------------------------------------------------------- */
+
+static inline int
+spmi_cmd(struct spmi_controller *ctrl, u8 opcode, u8 sid)
+{
+ BUG_ON(!ctrl || !ctrl->cmd);
+ return ctrl->cmd(ctrl, opcode, sid);
+}
+
+static inline int spmi_read_cmd(struct spmi_controller *ctrl,
+ u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf)
+{
+ BUG_ON(!ctrl || !ctrl->read_cmd);
+ return ctrl->read_cmd(ctrl, opcode, sid, addr, bc, buf);
+}
+
+static inline int spmi_write_cmd(struct spmi_controller *ctrl,
+ u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf)
+{
+ BUG_ON(!ctrl || !ctrl->write_cmd);
+ return ctrl->write_cmd(ctrl, opcode, sid, addr, bc, buf);
+}
+
+/*
+ * register read/write: 5-bit address, 1 byte of data
+ * extended register read/write: 8-bit address, up to 16 bytes of data
+ * extended register read/write long: 16-bit address, up to 8 bytes of data
+ */
+
+/**
+ * spmi_register_read() - register read
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @ad: slave register address (5-bit address).
+ * @buf: buffer to be populated with data from the Slave.
+ *
+ * Reads 1 byte of data from a Slave device register.
+ */
+int spmi_register_read(struct spmi_controller *ctrl, u8 sid, u8 addr, u8 *buf)
+{
+ /* 4-bit Slave Identifier, 5-bit register address */
+ if (sid > SPMI_MAX_SLAVE_ID || addr > 0x1F)
+ return -EINVAL;
+
+ return spmi_read_cmd(ctrl, SPMI_CMD_READ, sid, addr, 0, buf);
+}
+EXPORT_SYMBOL_GPL(spmi_register_read);
+
+/**
+ * spmi_ext_register_read() - extended register read
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @ad: slave register address (8-bit address).
+ * @len: the request number of bytes to read (up to 16 bytes).
+ * @buf: buffer to be populated with data from the Slave.
+ *
+ * Reads up to 16 bytes of data from the extended register space on a
+ * Slave device.
+ */
+int spmi_ext_register_read(struct spmi_controller *ctrl,
+ u8 sid, u8 addr, u8 *buf, int len)
+{
+ /* 4-bit Slave Identifier, 8-bit register address, up to 16 bytes */
+ if (sid > SPMI_MAX_SLAVE_ID || len <= 0 || len > 16)
+ return -EINVAL;
+
+ return spmi_read_cmd(ctrl, SPMI_CMD_EXT_READ, sid, addr, len - 1, buf);
+}
+EXPORT_SYMBOL_GPL(spmi_ext_register_read);
+
+/**
+ * spmi_ext_register_readl() - extended register read long
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @ad: slave register address (16-bit address).
+ * @len: the request number of bytes to read (up to 8 bytes).
+ * @buf: buffer to be populated with data from the Slave.
+ *
+ * Reads up to 8 bytes of data from the extended register space on a
+ * Slave device using 16-bit address.
+ */
+int spmi_ext_register_readl(struct spmi_controller *ctrl,
+ u8 sid, u16 addr, u8 *buf, int len)
+{
+ /* 4-bit Slave Identifier, 16-bit register address, up to 8 bytes */
+ if (sid > SPMI_MAX_SLAVE_ID || len <= 0 || len > 8)
+ return -EINVAL;
+
+ return spmi_read_cmd(ctrl, SPMI_CMD_EXT_READL, sid, addr, len - 1, buf);
+}
+EXPORT_SYMBOL_GPL(spmi_ext_register_readl);
+
+/**
+ * spmi_register_write() - register write
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @ad: slave register address (5-bit address).
+ * @buf: buffer containing the data to be transferred to the Slave.
+ *
+ * Writes 1 byte of data to a Slave device register.
+ */
+int spmi_register_write(struct spmi_controller *ctrl, u8 sid, u8 addr, u8 *buf)
+{
+ u8 op = SPMI_CMD_WRITE;
+
+ /* 4-bit Slave Identifier, 5-bit register address */
+ if (sid > SPMI_MAX_SLAVE_ID || addr > 0x1F)
+ return -EINVAL;
+
+ return spmi_write_cmd(ctrl, op, sid, addr, 0, buf);
+}
+EXPORT_SYMBOL_GPL(spmi_register_write);
+
+/**
+ * spmi_register_zero_write() - register zero write
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @data: the data to be written to register 0 (7-bits).
+ *
+ * Writes data to register 0 of the Slave device.
+ */
+int spmi_register_zero_write(struct spmi_controller *ctrl, u8 sid, u8 data)
+{
+ u8 op = SPMI_CMD_ZERO_WRITE;
+
+ /* 4-bit Slave Identifier, 5-bit register address */
+ if (sid > SPMI_MAX_SLAVE_ID)
+ return -EINVAL;
+
+ return spmi_write_cmd(ctrl, op, sid, 0, 0, &data);
+}
+EXPORT_SYMBOL_GPL(spmi_register_zero_write);
+
+/**
+ * spmi_ext_register_write() - extended register write
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @ad: slave register address (8-bit address).
+ * @buf: buffer containing the data to be transferred to the Slave.
+ * @len: the request number of bytes to read (up to 16 bytes).
+ *
+ * Writes up to 16 bytes of data to the extended register space of a
+ * Slave device.
+ */
+int spmi_ext_register_write(struct spmi_controller *ctrl,
+ u8 sid, u8 addr, u8 *buf, int len)
+{
+ u8 op = SPMI_CMD_EXT_WRITE;
+
+ /* 4-bit Slave Identifier, 8-bit register address, up to 16 bytes */
+ if (sid > SPMI_MAX_SLAVE_ID || len <= 0 || len > 16)
+ return -EINVAL;
+
+ return spmi_write_cmd(ctrl, op, sid, addr, len - 1, buf);
+}
+EXPORT_SYMBOL_GPL(spmi_ext_register_write);
+
+/**
+ * spmi_ext_register_writel() - extended register write long
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ * @ad: slave register address (16-bit address).
+ * @buf: buffer containing the data to be transferred to the Slave.
+ * @len: the request number of bytes to read (up to 8 bytes).
+ *
+ * Writes up to 8 bytes of data to the extended register space of a
+ * Slave device using 16-bit address.
+ */
+int spmi_ext_register_writel(struct spmi_controller *ctrl,
+ u8 sid, u16 addr, u8 *buf, int len)
+{
+ u8 op = SPMI_CMD_EXT_WRITEL;
+
+ /* 4-bit Slave Identifier, 16-bit register address, up to 8 bytes */
+ if (sid > SPMI_MAX_SLAVE_ID || len <= 0 || len > 8)
+ return -EINVAL;
+
+ return spmi_write_cmd(ctrl, op, sid, addr, len - 1, buf);
+}
+EXPORT_SYMBOL_GPL(spmi_ext_register_writel);
+
+/**
+ * spmi_command_reset() - sends RESET command to the specified slave
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ *
+ * The Reset command initializes the Slave and forces all registers to
+ * their reset values. The Slave shall enter the STARTUP state after
+ * receiving a Reset command.
+ *
+ * Returns
+ * -EINVAL for invalid Slave Identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+int spmi_command_reset(struct spmi_controller *ctrl, u8 sid)
+{
+ if (sid > SPMI_MAX_SLAVE_ID)
+ return -EINVAL;
+ return spmi_cmd(ctrl, SPMI_CMD_RESET, sid);
+}
+EXPORT_SYMBOL_GPL(spmi_command_reset);
+
+/**
+ * spmi_command_sleep() - sends SLEEP command to the specified slave
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ *
+ * The Sleep command causes the Slave to enter the user defined SLEEP state.
+ *
+ * Returns
+ * -EINVAL for invalid Slave Identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+int spmi_command_sleep(struct spmi_controller *ctrl, u8 sid)
+{
+ if (sid > SPMI_MAX_SLAVE_ID)
+ return -EINVAL;
+ return spmi_cmd(ctrl, SPMI_CMD_SLEEP, sid);
+}
+EXPORT_SYMBOL_GPL(spmi_command_sleep);
+
+/**
+ * spmi_command_wakeup() - sends WAKEUP command to the specified slave
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ *
+ * The Wakeup command causes the Slave to move from the SLEEP state to
+ * the ACTIVE state.
+ *
+ * Returns
+ * -EINVAL for invalid Slave Identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+int spmi_command_wakeup(struct spmi_controller *ctrl, u8 sid)
+{
+ if (sid > SPMI_MAX_SLAVE_ID)
+ return -EINVAL;
+ return spmi_cmd(ctrl, SPMI_CMD_WAKEUP, sid);
+}
+EXPORT_SYMBOL_GPL(spmi_command_wakeup);
+
+/**
+ * spmi_command_shutdown() - sends SHUTDOWN command to the specified slave
+ * @dev: SPMI device.
+ * @sid: slave identifier.
+ *
+ * The Shutdown command causes the Slave to enter the SHUTDOWN state.
+ *
+ * Returns
+ * -EINVAL for invalid Slave Identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+int spmi_command_shutdown(struct spmi_controller *ctrl, u8 sid)
+{
+ if (sid > SPMI_MAX_SLAVE_ID)
+ return -EINVAL;
+ return spmi_cmd(ctrl, SPMI_CMD_SHUTDOWN, sid);
+}
+EXPORT_SYMBOL_GPL(spmi_command_shutdown);
+
+/* ------------------------------------------------------------------------- */
+
+static const struct spmi_device_id *spmi_match(const struct spmi_device_id *id,
+ const struct spmi_device *spmi_dev)
+{
+ while (id->name[0]) {
+ if (strncmp(spmi_dev->name, id->name, SPMI_NAME_SIZE) == 0)
+ return id;
+ id++;
+ }
+ return NULL;
+}
+
+static int spmi_device_match(struct device *dev, struct device_driver *drv)
+{
+ struct spmi_device *spmi_dev;
+ struct spmi_driver *sdrv = to_spmi_driver(drv);
+
+ if (dev->type == &spmi_dev_type)
+ spmi_dev = to_spmi_device(dev);
+ else
+ return 0;
+
+ /* Attempt an OF style match */
+ if (of_driver_match_device(dev, drv))
+ return 1;
+
+ if (sdrv->id_table)
+ return spmi_match(sdrv->id_table, spmi_dev) != NULL;
+
+ if (drv->name)
+ return strncmp(spmi_dev->name, drv->name, SPMI_NAME_SIZE) == 0;
+ return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int spmi_legacy_suspend(struct device *dev, pm_message_t mesg)
+{
+ struct spmi_device *spmi_dev = NULL;
+ struct spmi_driver *driver;
+ if (dev->type == &spmi_dev_type)
+ spmi_dev = to_spmi_device(dev);
+
+ if (!spmi_dev || !dev->driver)
+ return 0;
+
+ driver = to_spmi_driver(dev->driver);
+ if (!driver->suspend)
+ return 0;
+
+ return driver->suspend(spmi_dev, mesg);
+}
+
+static int spmi_legacy_resume(struct device *dev)
+{
+ struct spmi_device *spmi_dev = NULL;
+ struct spmi_driver *driver;
+ if (dev->type == &spmi_dev_type)
+ spmi_dev = to_spmi_device(dev);
+
+ if (!spmi_dev || !dev->driver)
+ return 0;
+
+ driver = to_spmi_driver(dev->driver);
+ if (!driver->resume)
+ return 0;
+
+ return driver->resume(spmi_dev);
+}
+
+static int spmi_pm_suspend(struct device *dev)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+ if (pm)
+ return pm_generic_suspend(dev);
+ else
+ return spmi_legacy_suspend(dev, PMSG_SUSPEND);
+}
+
+static int spmi_pm_resume(struct device *dev)
+{
+ const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL;
+
+ if (pm)
+ return pm_generic_resume(dev);
+ else
+ return spmi_legacy_resume(dev);
+}
+
+#else
+#define spmi_pm_suspend NULL
+#define spmi_pm_resume NULL
+#endif
+
+static const struct dev_pm_ops spmi_pm_ops = {
+ .suspend = spmi_pm_suspend,
+ .resume = spmi_pm_resume,
+ SET_RUNTIME_PM_OPS(
+ pm_generic_suspend,
+ pm_generic_resume,
+ pm_generic_runtime_idle
+ )
+};
+struct bus_type spmi_bus_type = {
+ .name = "spmi",
+ .match = spmi_device_match,
+ .pm = &spmi_pm_ops,
+};
+EXPORT_SYMBOL_GPL(spmi_bus_type);
+
+struct device spmi_dev = {
+ .init_name = "spmi",
+};
+
+static int spmi_drv_probe(struct device *dev)
+{
+ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
+
+ return sdrv->probe(to_spmi_device(dev));
+}
+
+static int spmi_drv_remove(struct device *dev)
+{
+ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
+
+ return sdrv->remove(to_spmi_device(dev));
+}
+
+static void spmi_drv_shutdown(struct device *dev)
+{
+ const struct spmi_driver *sdrv = to_spmi_driver(dev->driver);
+
+ sdrv->shutdown(to_spmi_device(dev));
+}
+
+/**
+ * spmi_driver_register: Client driver registration with SPMI framework.
+ * @drv: client driver to be associated with client-device.
+ *
+ * This API will register the client driver with the SPMI framework.
+ * It is called from the driver's module-init function.
+ */
+int spmi_driver_register(struct spmi_driver *drv)
+{
+ drv->driver.bus = &spmi_bus_type;
+
+ if (drv->probe)
+ drv->driver.probe = spmi_drv_probe;
+
+ if (drv->remove)
+ drv->driver.remove = spmi_drv_remove;
+
+ if (drv->shutdown)
+ drv->driver.shutdown = spmi_drv_shutdown;
+
+ return driver_register(&drv->driver);
+}
+EXPORT_SYMBOL_GPL(spmi_driver_register);
+
+static int spmi_register_controller(struct spmi_controller *ctrl)
+{
+ int ret = 0;
+
+ /* Can't register until after driver model init */
+ if (WARN_ON(!spmi_bus_type.p)) {
+ ret = -EAGAIN;
+ goto exit;
+ }
+
+ dev_set_name(&ctrl->dev, "spmi-%d", ctrl->nr);
+ ctrl->dev.bus = &spmi_bus_type;
+ ctrl->dev.type = &spmi_ctrl_type;
+ ret = device_register(&ctrl->dev);
+ if (ret)
+ goto exit;
+
+ dev_dbg(&ctrl->dev, "Bus spmi-%d registered: dev:%x\n",
+ ctrl->nr, (u32)&ctrl->dev);
+
+ mutex_lock(&board_lock);
+ list_add_tail(&ctrl->list, &spmi_ctrl_list);
+ mutex_unlock(&board_lock);
+
+ return 0;
+
+exit:
+ mutex_lock(&board_lock);
+ idr_remove(&ctrl_idr, ctrl->nr);
+ mutex_unlock(&board_lock);
+ return ret;
+}
+
+static void __exit spmi_exit(void)
+{
+ device_unregister(&spmi_dev);
+ bus_unregister(&spmi_bus_type);
+}
+
+static int __init spmi_init(void)
+{
+ int retval;
+
+ retval = bus_register(&spmi_bus_type);
+ if (!retval)
+ retval = device_register(&spmi_dev);
+
+ if (retval)
+ bus_unregister(&spmi_bus_type);
+
+ return retval;
+}
+postcore_initcall(spmi_init);
+module_exit(spmi_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_DESCRIPTION("SPMI module");
+MODULE_ALIAS("platform:spmi");
diff --git a/drivers/staging/qcache/fmem.c b/drivers/staging/qcache/fmem.c
index d12c8e8..c900647 100644
--- a/drivers/staging/qcache/fmem.c
+++ b/drivers/staging/qcache/fmem.c
@@ -51,9 +51,11 @@
{
struct fmem_platform_data *pdata = pdev->dev.platform_data;
- fmem_data.phys = pdata->phys + pdata->reserved_size;
- fmem_data.size = pdata->size - pdata->reserved_size;
- fmem_data.reserved_size = pdata->reserved_size;
+ fmem_data.phys = pdata->phys + pdata->reserved_size_low;
+ fmem_data.size = pdata->size - pdata->reserved_size_low -
+ pdata->reserved_size_high;
+ fmem_data.reserved_size_low = pdata->reserved_size_low;
+ fmem_data.reserved_size_high = pdata->reserved_size_high;
if (!fmem_data.size)
return -ENODEV;
diff --git a/drivers/thermal/msm8960_tsens.c b/drivers/thermal/msm8960_tsens.c
index 2a2166a..0e279b8 100644
--- a/drivers/thermal/msm8960_tsens.c
+++ b/drivers/thermal/msm8960_tsens.c
@@ -23,6 +23,7 @@
#include <linux/slab.h>
#include <linux/msm_tsens.h>
#include <linux/io.h>
+#include <linux/err.h>
#include <mach/msm_iomap.h>
#include <mach/socinfo.h>
@@ -56,10 +57,12 @@
#define SENSOR4_EN BIT(7)
#define SENSORS_EN (SENSOR0_EN | SENSOR1_EN | \
SENSOR2_EN | SENSOR3_EN | SENSOR4_EN)
-#define TSENS_MIN_STATUS_MASK BIT(8)
-#define TSENS_LOWER_STATUS_CLR BIT(9)
-#define TSENS_UPPER_STATUS_CLR BIT(10)
-#define TSENS_MAX_STATUS_MASK BIT(11)
+#define TSENS_STATUS_CNTL_OFFSET 8
+#define TSENS_MIN_STATUS_MASK BIT((tsens_status_cntl_start))
+#define TSENS_LOWER_STATUS_CLR BIT((tsens_status_cntl_start + 1))
+#define TSENS_UPPER_STATUS_CLR BIT((tsens_status_cntl_start + 2))
+#define TSENS_MAX_STATUS_MASK BIT((tsens_status_cntl_start + 3))
+
#define TSENS_MEASURE_PERIOD 4 /* 1 sec. default */
#define TSENS_8960_SLP_CLK_ENA BIT(26)
@@ -86,6 +89,7 @@
#define TSENS_S0_STATUS_ADDR (MSM_CLK_CTL_BASE + 0x00003628)
#define TSENS_STATUS_ADDR_OFFSET 2
+#define TSENS_SENSOR_STATUS_SIZE 4
#define TSENS_INT_STATUS_ADDR (MSM_CLK_CTL_BASE + 0x0000363c)
#define TSENS_LOWER_INT_MASK BIT(1)
@@ -113,6 +117,26 @@
#define TSENS_8660_CONFIG_MASK (3 << TSENS_8660_CONFIG_SHIFT)
#define TSENS_8660_SLP_CLK_ENA BIT(24)
+#define TSENS_8064_SENSOR5_EN BIT(8)
+#define TSENS_8064_SENSOR6_EN BIT(9)
+#define TSENS_8064_SENSOR7_EN BIT(10)
+#define TSENS_8064_SENSOR8_EN BIT(11)
+#define TSENS_8064_SENSOR9_EN BIT(12)
+#define TSENS_8064_SENSOR10_EN BIT(13)
+#define TSENS_8064_SENSORS_EN (SENSORS_EN | \
+ TSENS_8064_SENSOR5_EN | \
+ TSENS_8064_SENSOR6_EN | \
+ TSENS_8064_SENSOR7_EN | \
+ TSENS_8064_SENSOR8_EN | \
+ TSENS_8064_SENSOR9_EN | \
+ TSENS_8064_SENSOR10_EN)
+#define TSENS_8064_STATUS_CNTL (MSM_CLK_CTL_BASE + 0x00003660)
+#define TSENS_8064_S5_STATUS_ADDR (MSM_CLK_CTL_BASE + 0x00003664)
+#define TSENS_8064_SEQ_SENSORS 5
+#define TSENS_8064_S4_S5_OFFSET 40
+
+static int tsens_status_cntl_start;
+
struct tsens_tm_device_sensor {
struct thermal_zone_device *tz_dev;
enum thermal_device_mode mode;
@@ -121,11 +145,11 @@
int offset;
int calib_data;
int calib_data_backup;
+ uint32_t slope_mul_tsens_factor;
};
struct tsens_tm_device {
bool prev_reading_avail;
- int slope_mul_tsens_factor;
int tsens_factor;
uint32_t tsens_num_sensor;
enum platform_type hw_type;
@@ -137,26 +161,28 @@
/* Temperature on y axis and ADC-code on x-axis */
static int tsens_tz_code_to_degC(int adc_code, int sensor_num)
{
- int degC, degcbeforefactor;
- degcbeforefactor = adc_code * tmdev->slope_mul_tsens_factor
- + tmdev->sensor[sensor_num].offset;
+ int degcbeforefactor, degc;
+ degcbeforefactor = (adc_code *
+ tmdev->sensor[sensor_num].slope_mul_tsens_factor
+ + tmdev->sensor[sensor_num].offset);
+
if (degcbeforefactor == 0)
- degC = degcbeforefactor;
+ degc = degcbeforefactor;
else if (degcbeforefactor > 0)
- degC = (degcbeforefactor + tmdev->tsens_factor/2)
- / tmdev->tsens_factor;
- else /* rounding for negative degrees */
- degC = (degcbeforefactor - tmdev->tsens_factor/2)
- / tmdev->tsens_factor;
- return degC;
+ degc = (degcbeforefactor + tmdev->tsens_factor/2)
+ / tmdev->tsens_factor;
+ else
+ degc = (degcbeforefactor - tmdev->tsens_factor/2)
+ / tmdev->tsens_factor;
+ return degc;
}
static int tsens_tz_degC_to_code(int degC, int sensor_num)
{
int code = (degC * tmdev->tsens_factor -
- tmdev->sensor[sensor_num].offset
- + tmdev->slope_mul_tsens_factor/2)
- / tmdev->slope_mul_tsens_factor;
+ tmdev->sensor[sensor_num].offset
+ + tmdev->sensor[sensor_num].slope_mul_tsens_factor/2)
+ / tmdev->sensor[sensor_num].slope_mul_tsens_factor;
if (code > TSENS_THRESHOLD_MAX_CODE)
code = TSENS_THRESHOLD_MAX_CODE;
@@ -167,7 +193,7 @@
static void tsens8960_get_temp(int sensor_num, unsigned long *temp)
{
- unsigned int code;
+ unsigned int code, offset = 0, sensor_addr;
if (!tmdev->prev_reading_avail) {
while (!(readl_relaxed(TSENS_INT_STATUS_ADDR)
@@ -176,7 +202,12 @@
TSENS_TRDY_RDY_MAX_TIME);
tmdev->prev_reading_avail = true;
}
- code = readl_relaxed(TSENS_S0_STATUS_ADDR +
+
+ sensor_addr = (unsigned int)TSENS_S0_STATUS_ADDR;
+ if (tmdev->hw_type == APQ_8064 &&
+ sensor_num >= TSENS_8064_SEQ_SENSORS)
+ offset = TSENS_8064_S4_S5_OFFSET;
+ code = readl_relaxed(sensor_addr + offset +
(sensor_num << TSENS_STATUS_ADDR_OFFSET));
*temp = tsens_tz_code_to_degC(code, sensor_num);
}
@@ -247,7 +278,8 @@
}
writel_relaxed(reg | TSENS_SW_RST, TSENS_CNTL_ADDR);
if (tmdev->hw_type == MSM_8960 ||
- tmdev->hw_type == MSM_9615)
+ tmdev->hw_type == MSM_9615 ||
+ tmdev->hw_type == APQ_8064)
reg |= mask | TSENS_8960_SLP_CLK_ENA
| TSENS_EN;
else
@@ -257,7 +289,11 @@
} else {
reg &= ~mask;
if (!(reg & SENSOR0_EN)) {
- if (tmdev->hw_type == MSM_8960 ||
+ if (tmdev->hw_type == APQ_8064)
+ reg &= ~(TSENS_8064_SENSORS_EN |
+ TSENS_8960_SLP_CLK_ENA |
+ TSENS_EN);
+ else if (tmdev->hw_type == MSM_8960 ||
tmdev->hw_type == MSM_9615)
reg &= ~(SENSORS_EN |
TSENS_8960_SLP_CLK_ENA |
@@ -319,7 +355,11 @@
lo_code = TSENS_THRESHOLD_MIN_CODE;
hi_code = TSENS_THRESHOLD_MAX_CODE;
- reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
+ if (tmdev->hw_type == APQ_8064)
+ reg_cntl = readl_relaxed(TSENS_8064_STATUS_CNTL);
+ else
+ reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
+
reg_th = readl_relaxed(TSENS_THRESHOLD_ADDR);
switch (trip) {
case TSENS_TRIP_STAGE3:
@@ -386,14 +426,21 @@
return -EINVAL;
}
- if (mode == THERMAL_TRIP_ACTIVATION_DISABLED)
- writel_relaxed(reg_cntl | mask, TSENS_CNTL_ADDR);
- else {
+ if (mode == THERMAL_TRIP_ACTIVATION_DISABLED) {
+ if (tmdev->hw_type == APQ_8064)
+ writel_relaxed(reg_cntl | mask, TSENS_8064_STATUS_CNTL);
+ else
+ writel_relaxed(reg_cntl | mask, TSENS_CNTL_ADDR);
+ } else {
if (code < lo_code || code > hi_code) {
pr_info("%s with invalid code %x\n", __func__, code);
return -EINVAL;
}
- writel_relaxed(reg_cntl & ~mask, TSENS_CNTL_ADDR);
+ if (tmdev->hw_type == APQ_8064)
+ writel_relaxed(reg_cntl & ~mask,
+ TSENS_8064_STATUS_CNTL);
+ else
+ writel_relaxed(reg_cntl & ~mask, TSENS_CNTL_ADDR);
}
mb();
return 0;
@@ -465,7 +512,10 @@
lo_code = TSENS_THRESHOLD_MIN_CODE;
hi_code = TSENS_THRESHOLD_MAX_CODE;
- reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
+ if (tmdev->hw_type == APQ_8064)
+ reg_cntl = readl_relaxed(TSENS_8064_STATUS_CNTL);
+ else
+ reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
reg_th = readl_relaxed(TSENS_THRESHOLD_ADDR);
switch (trip) {
case TSENS_TRIP_STAGE3:
@@ -561,25 +611,40 @@
{
struct tsens_tm_device *tm = data;
unsigned int threshold, threshold_low, i, code, reg, sensor, mask;
+ unsigned int sensor_addr;
bool upper_th_x, lower_th_x;
int adc_code;
- reg = readl_relaxed(TSENS_CNTL_ADDR);
- writel_relaxed(reg | TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR,
- TSENS_CNTL_ADDR);
+ if (tmdev->hw_type == APQ_8064) {
+ reg = readl_relaxed(TSENS_8064_STATUS_CNTL);
+ writel_relaxed(reg | TSENS_LOWER_STATUS_CLR |
+ TSENS_UPPER_STATUS_CLR, TSENS_8064_STATUS_CNTL);
+ } else {
+ reg = readl_relaxed(TSENS_CNTL_ADDR);
+ writel_relaxed(reg | TSENS_LOWER_STATUS_CLR |
+ TSENS_UPPER_STATUS_CLR, TSENS_CNTL_ADDR);
+ }
mask = ~(TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR);
threshold = readl_relaxed(TSENS_THRESHOLD_ADDR);
threshold_low = (threshold & TSENS_THRESHOLD_LOWER_LIMIT_MASK)
>> TSENS_THRESHOLD_LOWER_LIMIT_SHIFT;
threshold = (threshold & TSENS_THRESHOLD_UPPER_LIMIT_MASK)
>> TSENS_THRESHOLD_UPPER_LIMIT_SHIFT;
- reg = sensor = readl_relaxed(TSENS_CNTL_ADDR);
- sensor &= (uint32_t) SENSORS_EN;
+ sensor = readl_relaxed(TSENS_CNTL_ADDR);
+ if (tmdev->hw_type == APQ_8064) {
+ reg = readl_relaxed(TSENS_8064_STATUS_CNTL);
+ sensor &= (uint32_t) TSENS_8064_SENSORS_EN;
+ } else {
+ reg = sensor;
+ sensor &= (uint32_t) SENSORS_EN;
+ }
sensor >>= TSENS_SENSOR0_SHIFT;
+ sensor_addr = (unsigned int)TSENS_S0_STATUS_ADDR;
for (i = 0; i < tmdev->tsens_num_sensor; i++) {
+ if (i == TSENS_8064_SEQ_SENSORS)
+ sensor_addr += TSENS_8064_S4_S5_OFFSET;
if (sensor & TSENS_MASK1) {
- code = readl_relaxed(TSENS_S0_STATUS_ADDR +
- (i << TSENS_STATUS_ADDR_OFFSET));
+ code = readl_relaxed(sensor_addr);
upper_th_x = code >= threshold;
lower_th_x = code <= threshold_low;
if (upper_th_x)
@@ -589,8 +654,7 @@
if (upper_th_x || lower_th_x) {
/* Notify user space */
schedule_work(&tm->sensor[i].work);
- adc_code = readl_relaxed(TSENS_S0_STATUS_ADDR
- + (i << TSENS_STATUS_ADDR_OFFSET));
+ adc_code = readl_relaxed(sensor_addr);
pr_info("\nTrip point triggered by "
"current temperature (%d degrees) "
"measured by Temperature-Sensor %d\n",
@@ -598,18 +662,37 @@
}
}
sensor >>= 1;
+ sensor_addr += TSENS_SENSOR_STATUS_SIZE;
}
+ if (tmdev->hw_type == APQ_8064)
+ writel_relaxed(reg & mask, TSENS_8064_STATUS_CNTL);
+ else
writel_relaxed(reg & mask, TSENS_CNTL_ADDR);
mb();
return IRQ_HANDLED;
}
+static void tsens8960_sensor_mode_init(void)
+{
+ unsigned int reg_cntl = 0;
+
+ reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
+ if (tmdev->hw_type == MSM_8960 || tmdev->hw_type == MSM_9615 ||
+ tmdev->hw_type == APQ_8064) {
+ writel_relaxed(reg_cntl &
+ ~((((1 << tmdev->tsens_num_sensor) - 1) >> 1)
+ << (TSENS_SENSOR0_SHIFT + 1)), TSENS_CNTL_ADDR);
+ tmdev->sensor[TSENS_MAIN_SENSOR].mode = THERMAL_DEVICE_ENABLED;
+ }
+}
+
static void tsens_disable_mode(void)
{
unsigned int reg_cntl = 0;
reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
- if (tmdev->hw_type == MSM_8960 || tmdev->hw_type == MSM_9615)
+ if (tmdev->hw_type == MSM_8960 || tmdev->hw_type == MSM_9615 ||
+ tmdev->hw_type == APQ_8064)
writel_relaxed(reg_cntl &
~((((1 << tmdev->tsens_num_sensor) - 1) <<
TSENS_SENSOR0_SHIFT) | TSENS_8960_SLP_CLK_ENA
@@ -624,6 +707,7 @@
static void tsens_hw_init(void)
{
unsigned int reg_cntl = 0, reg_cfg = 0, reg_thr = 0;
+ unsigned int reg_status_cntl = 0;
reg_cntl = readl_relaxed(TSENS_CNTL_ADDR);
writel_relaxed(reg_cntl | TSENS_SW_RST, TSENS_CNTL_ADDR);
@@ -657,6 +741,25 @@
(TSENS_8660_CONFIG << TSENS_8660_CONFIG_SHIFT);
writel_relaxed(reg_cntl, TSENS_CNTL_ADDR);
+ } else if (tmdev->hw_type == APQ_8064) {
+ reg_cntl |= TSENS_8960_SLP_CLK_ENA |
+ (TSENS_MEASURE_PERIOD << 18) |
+ (((1 << tmdev->tsens_num_sensor) - 1) <<
+ TSENS_SENSOR0_SHIFT);
+ writel_relaxed(reg_cntl, TSENS_CNTL_ADDR);
+ reg_status_cntl = readl_relaxed(TSENS_8064_STATUS_CNTL);
+ reg_status_cntl |= TSENS_LOWER_STATUS_CLR |
+ TSENS_UPPER_STATUS_CLR |
+ TSENS_MIN_STATUS_MASK |
+ TSENS_MAX_STATUS_MASK;
+ writel_relaxed(reg_status_cntl, TSENS_8064_STATUS_CNTL);
+ reg_cntl |= TSENS_EN;
+ writel_relaxed(reg_cntl, TSENS_CNTL_ADDR);
+
+ reg_cfg = readl_relaxed(TSENS_8960_CONFIG_ADDR);
+ reg_cfg = (reg_cfg & ~TSENS_8960_CONFIG_MASK) |
+ (TSENS_8960_CONFIG << TSENS_8960_CONFIG_SHIFT);
+ writel_relaxed(reg_cfg, TSENS_8960_CONFIG_ADDR);
}
reg_thr |= (TSENS_LOWER_LIMIT_TH << TSENS_THRESHOLD_LOWER_LIMIT_SHIFT) |
@@ -692,8 +795,10 @@
}
tmdev->sensor[TSENS_MAIN_SENSOR].offset = tmdev->tsens_factor *
- TSENS_CAL_DEGC - tmdev->slope_mul_tsens_factor *
+ TSENS_CAL_DEGC -
+ tmdev->sensor[TSENS_MAIN_SENSOR].slope_mul_tsens_factor *
tmdev->sensor[TSENS_MAIN_SENSOR].calib_data;
+
tmdev->prev_reading_avail = false;
INIT_WORK(&tmdev->sensor[TSENS_MAIN_SENSOR].work,
notify_uspace_tsens_fn);
@@ -703,35 +808,27 @@
static int tsens_calib_sensors8960(void)
{
- uint32_t *main_sensor_addr, sensor_shift, *backup_sensor_addr;
- uint32_t sensor_mask, i;
+ uint32_t i;
+ uint8_t *main_sensor_addr, *backup_sensor_addr;
for (i = 0; i < tmdev->tsens_num_sensor; i++) {
- main_sensor_addr = TSENS_8960_QFPROM_ADDR0 +
- (TSENS_8960_QFPROM_SHIFT *
- ((i & TSENS_8960_QFPROM_SHIFT) >> TSENS_SENSOR_QFPROM_SHIFT));
- sensor_shift = (i % TSENS_8960_QFPROM_SHIFT) * TSENS_RED_SHIFT;
- sensor_mask = TSENS_THRESHOLD_MAX_CODE << sensor_shift;
- backup_sensor_addr = TSENS_8960_QFPROM_SPARE_ADDR0 +
- (TSENS_8960_QFPROM_SHIFT *
- ((i & TSENS_8960_QFPROM_SHIFT) >> TSENS_SENSOR_QFPROM_SHIFT));
+ main_sensor_addr = TSENS_8960_QFPROM_ADDR0 + i;
+ backup_sensor_addr = TSENS_8960_QFPROM_SPARE_ADDR0 + i;
- tmdev->sensor[i].calib_data = (readl_relaxed(main_sensor_addr)
- & sensor_mask) >> sensor_shift;
+ tmdev->sensor[i].calib_data = readb_relaxed(main_sensor_addr);
tmdev->sensor[i].calib_data_backup =
- (readl_relaxed(backup_sensor_addr) &
- sensor_mask) >> sensor_shift;
+ readb_relaxed(backup_sensor_addr);
if (tmdev->sensor[i].calib_data_backup)
tmdev->sensor[i].calib_data =
tmdev->sensor[i].calib_data_backup;
-
if (!tmdev->sensor[i].calib_data) {
WARN(1, "%s: No temperature sensor:%d data for"
" calibration in QFPROM!\n", __func__, i);
return -ENODEV;
}
- tmdev->sensor[i].offset = tmdev->tsens_factor *
- TSENS_CAL_DEGC - tmdev->slope_mul_tsens_factor *
- tmdev->sensor[i].calib_data;
+ tmdev->sensor[i].offset = (TSENS_CAL_DEGC *
+ tmdev->tsens_factor)
+ - (tmdev->sensor[i].calib_data *
+ tmdev->sensor[i].slope_mul_tsens_factor);
tmdev->prev_reading_avail = false;
INIT_WORK(&tmdev->sensor[i].work, notify_uspace_tsens_fn);
}
@@ -756,7 +853,8 @@
if (tmdev->hw_type == MSM_8660)
rc = tsens_calib_sensors8660();
- else if (tmdev->hw_type == MSM_8960 || tmdev->hw_type == MSM_9615)
+ else if (tmdev->hw_type == MSM_8960 || tmdev->hw_type == MSM_9615 ||
+ tmdev->hw_type == APQ_8064)
rc = tsens_calib_sensors8960();
return rc;
@@ -764,7 +862,7 @@
int msm_tsens_early_init(struct tsens_platform_data *pdata)
{
- int rc = 0;
+ int rc = 0, i;
if (!pdata) {
pr_err("No TSENS Platform data\n");
@@ -780,7 +878,8 @@
return -ENOMEM;
}
- tmdev->slope_mul_tsens_factor = pdata->slope;
+ for (i = 0; i < pdata->tsens_num_sensor; i++)
+ tmdev->sensor[i].slope_mul_tsens_factor = pdata->slope[i];
tmdev->tsens_factor = pdata->tsens_factor;
tmdev->tsens_num_sensor = pdata->tsens_num_sensor;
tmdev->hw_type = pdata->hw_type;
@@ -799,9 +898,14 @@
return rc;
}
+ if (tmdev->hw_type == APQ_8064)
+ tsens_status_cntl_start = 0;
+ else
+ tsens_status_cntl_start = TSENS_STATUS_CNTL_OFFSET;
+
tsens_hw_init();
- pr_info("msm_tsens_early_init: done\n");
+ pr_debug("msm_tsens_early_init: done\n");
return rc;
}
@@ -823,7 +927,7 @@
tmdev->sensor[i].tz_dev = thermal_zone_device_register(name,
TSENS_TRIP_NUM, &tmdev->sensor[i],
&tsens_thermal_zone_ops, 0, 0, 0, 0);
- if (tmdev->sensor[i].tz_dev == NULL) {
+ if (IS_ERR(tmdev->sensor[i].tz_dev)) {
pr_err("%s: thermal_zone_device_register() failed.\n",
__func__);
rc = -ENODEV;
@@ -832,6 +936,8 @@
tmdev->sensor[i].mode = THERMAL_DEVICE_DISABLED;
}
+ tsens8960_sensor_mode_init();
+
rc = request_irq(TSENS_UPPER_LOWER_INT, tsens_isr,
IRQF_TRIGGER_RISING, "tsens_interrupt", tmdev);
if (rc < 0) {
@@ -841,7 +947,7 @@
goto fail;
}
- pr_notice("%s: OK\n", __func__);
+ pr_debug("%s: OK\n", __func__);
mb();
return 0;
fail:
diff --git a/drivers/thermal/msm_thermal.c b/drivers/thermal/msm_thermal.c
index ed80b1b..ef28844 100644
--- a/drivers/thermal/msm_thermal.c
+++ b/drivers/thermal/msm_thermal.c
@@ -51,10 +51,7 @@
cpu_policy->user_policy.max = max_freq;
ret = cpufreq_update_policy(cpu);
- if (ret)
- pr_err("msm_thermal: cpufreq update to core%d %d err:%d\n",
- cpu, max_freq, ret);
- else
+ if (!ret)
pr_info("msm_thermal: Limiting core%d max frequency to %d\n",
cpu, max_freq);
diff --git a/drivers/tty/serial/msm_serial.c b/drivers/tty/serial/msm_serial.c
index 9e85eb5..32e9dc0 100644
--- a/drivers/tty/serial/msm_serial.c
+++ b/drivers/tty/serial/msm_serial.c
@@ -2,7 +2,7 @@
* drivers/serial/msm_serial.c - driver for msm7k serial device and console
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
* Author: Robert Love <rlove@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -102,48 +102,32 @@
{
struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
-
msm_port->imr &= ~UART_IMR_TXLEV;
msm_write(port, msm_port->imr, UART_IMR);
-
- clk_disable(msm_port->clk);
}
static void msm_start_tx(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
-
msm_port->imr |= UART_IMR_TXLEV;
msm_write(port, msm_port->imr, UART_IMR);
-
- clk_disable(msm_port->clk);
}
static void msm_stop_rx(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
-
msm_port->imr &= ~(UART_IMR_RXLEV | UART_IMR_RXSTALE);
msm_write(port, msm_port->imr, UART_IMR);
-
- clk_disable(msm_port->clk);
}
static void msm_enable_ms(struct uart_port *port)
{
struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
-
msm_port->imr |= UART_IMR_DELTA_CTS;
msm_write(port, msm_port->imr, UART_IMR);
-
- clk_disable(msm_port->clk);
}
#ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL
@@ -365,7 +349,6 @@
unsigned int misr;
spin_lock_irqsave(&port->lock, flags);
- clk_enable(msm_port->clk);
misr = msm_read(port, UART_MISR);
msm_write(port, 0, UART_IMR); /* disable interrupt */
@@ -377,7 +360,6 @@
handle_delta_cts(port);
msm_write(port, msm_port->imr, UART_IMR); /* restore interrupt */
- clk_disable(msm_port->clk);
spin_unlock_irqrestore(&port->lock, flags);
return IRQ_HANDLED;
@@ -386,12 +368,8 @@
static unsigned int msm_tx_empty(struct uart_port *port)
{
unsigned int ret;
- struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
ret = (msm_read(port, UART_SR) & UART_SR_TX_EMPTY) ? TIOCSER_TEMT : 0;
- clk_disable(msm_port->clk);
-
return ret;
}
@@ -403,9 +381,6 @@
static void msm_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
unsigned int mr;
- struct msm_port *msm_port = UART_TO_MSM(port);
-
- clk_enable(msm_port->clk);
mr = msm_read(port, UART_MR1);
@@ -417,22 +392,14 @@
mr |= UART_MR1_RX_RDY_CTL;
msm_write(port, mr, UART_MR1);
}
-
- clk_disable(msm_port->clk);
}
static void msm_break_ctl(struct uart_port *port, int break_ctl)
{
- struct msm_port *msm_port = UART_TO_MSM(port);
-
- clk_enable(msm_port->clk);
-
if (break_ctl)
msm_write(port, UART_CR_CMD_START_BREAK, UART_CR);
else
msm_write(port, UART_CR_CMD_STOP_BREAK, UART_CR);
-
- clk_disable(msm_port->clk);
}
static void msm_set_baud_rate(struct uart_port *port, unsigned int baud)
@@ -520,9 +487,14 @@
static void msm_init_clock(struct uart_port *port)
{
+ int ret;
struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
+ ret = clk_prepare_enable(msm_port->clk);
+ if (ret) {
+ pr_err("%s(): Can't enable uartclk. ret:%d\n", __func__, ret);
+ return;
+ }
#ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL
msm_port->clk_state = MSM_CLK_ON;
@@ -552,7 +524,7 @@
clk_disable(msm_port->clk);
msm_port->clk_state = MSM_CLK_PORT_OFF;
#else
- clk_disable(msm_port->clk);
+ clk_disable_unprepare(msm_port->clk);
#endif
}
@@ -631,13 +603,9 @@
{
struct msm_port *msm_port = UART_TO_MSM(port);
- clk_enable(msm_port->clk);
-
msm_port->imr = 0;
msm_write(port, 0, UART_IMR); /* disable interrupts */
- clk_disable(msm_port->clk);
-
free_irq(port->irq, port);
#ifdef CONFIG_SERIAL_MSM_RX_WAKEUP
@@ -657,10 +625,8 @@
{
unsigned long flags;
unsigned int baud, mr;
- struct msm_port *msm_port = UART_TO_MSM(port);
spin_lock_irqsave(&port->lock, flags);
- clk_enable(msm_port->clk);
/* calculate and set baud rate */
baud = uart_get_baud_rate(port, termios, old, 300, 115200);
@@ -723,8 +689,6 @@
port->read_status_mask |= UART_SR_RX_BREAK;
uart_update_timeout(port, termios->c_cflag, baud);
-
- clk_disable(msm_port->clk);
spin_unlock_irqrestore(&port->lock, flags);
}
@@ -792,20 +756,23 @@
static void msm_power(struct uart_port *port, unsigned int state,
unsigned int oldstate)
{
-#ifndef CONFIG_SERIAL_MSM_CLOCK_CONTROL
+ int ret;
struct msm_port *msm_port = UART_TO_MSM(port);
switch (state) {
case 0:
- clk_enable(msm_port->clk);
+ ret = clk_prepare_enable(msm_port->clk);
+ if (ret)
+ pr_err("msm_serial: %s(): Can't enable uartclk.\n",
+ __func__);
break;
case 3:
- clk_disable(msm_port->clk);
+ clk_disable_unprepare(msm_port->clk);
break;
default:
- printk(KERN_ERR "msm_serial: Unknown PM state %d\n", state);
+ pr_err("msm_serial: %s(): Unknown PM state %d\n",
+ __func__, state);
}
-#endif
}
static struct uart_ops msm_uart_pops = {
diff --git a/drivers/usb/gadget/u_data_hsic.c b/drivers/usb/gadget/u_data_hsic.c
index 7b77a1d..818e2a6 100644
--- a/drivers/usb/gadget/u_data_hsic.c
+++ b/drivers/usb/gadget/u_data_hsic.c
@@ -85,8 +85,7 @@
unsigned port_num;
/* gadget */
- spinlock_t port_lock;
- void *port_usb;
+ atomic_t connected;
struct usb_ep *in;
struct usb_ep *out;
@@ -96,10 +95,12 @@
unsigned int tx_q_size;
struct list_head tx_idle;
struct sk_buff_head tx_skb_q;
+ spinlock_t tx_lock;
unsigned int rx_q_size;
struct list_head rx_idle;
struct sk_buff_head rx_skb_q;
+ spinlock_t rx_lock;
/* work */
struct workqueue_struct *wq;
@@ -175,17 +176,16 @@
struct gdata_port *port = ctx;
unsigned long flags;
- if (!port)
+ if (!port || !atomic_read(&port->connected))
return;
- spin_lock_irqsave(&port->port_lock, flags);
- if (port->port_usb) {
- port->tx_unthrottled_cnt++;
- queue_work(port->wq, &port->write_tomdm_w);
- pr_debug("%s: port num =%d unthrottled\n", __func__,
- port->port_num);
- }
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
+ port->tx_unthrottled_cnt++;
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+
+ queue_work(port->wq, &port->write_tomdm_w);
+ pr_debug("%s: port num =%d unthrottled\n", __func__,
+ port->port_num);
}
static void ghsic_data_write_tohost(struct work_struct *w)
@@ -200,14 +200,16 @@
port = container_of(w, struct gdata_port, write_tohost_w);
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock, flags);
+ if (!port)
+ return;
+
+ spin_lock_irqsave(&port->tx_lock, flags);
+ ep = port->in;
+ if (!ep) {
+ spin_unlock_irqrestore(&port->tx_lock, flags);
return;
}
- ep = port->in;
-
while (!list_empty(&port->tx_idle)) {
skb = __skb_dequeue(&port->tx_skb_q);
if (!skb)
@@ -231,9 +233,9 @@
info = (struct timestamp_info *)skb->cb;
info->tx_queued = get_timestamp();
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
ret = usb_ep_queue(ep, req, GFP_KERNEL);
- spin_lock_irqsave(&port->port_lock, flags);
+ spin_lock_irqsave(&port->tx_lock, flags);
if (ret) {
pr_err("%s: usb epIn failed\n", __func__);
list_add(&req->list, &port->tx_idle);
@@ -252,7 +254,7 @@
data_bridge_unthrottle_rx(port->brdg.ch_id);
}
}
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
static int ghsic_data_receive(void *p, void *data, size_t len)
@@ -261,21 +263,15 @@
unsigned long flags;
struct sk_buff *skb = data;
- if (!port) {
+ if (!port || !atomic_read(&port->connected)) {
dev_kfree_skb_any(skb);
- return -EINVAL;
+ return -ENOTCONN;
}
pr_debug("%s: p:%p#%d skb_len:%d\n", __func__,
port, port->port_num, skb->len);
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock, flags);
- dev_kfree_skb_any(skb);
- return -ENOTCONN;
- }
-
+ spin_lock_irqsave(&port->tx_lock, flags);
__skb_queue_tail(&port->tx_skb_q, skb);
if (ghsic_data_fctrl_support &&
@@ -284,12 +280,12 @@
port->rx_throttled_cnt++;
pr_debug_ratelimited("%s: flow ctrl enabled: tx skbq len: %u\n",
__func__, port->tx_skb_q.qlen);
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
queue_work(port->wq, &port->write_tohost_w);
return -EBUSY;
}
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
queue_work(port->wq, &port->write_tohost_w);
@@ -306,14 +302,12 @@
port = container_of(w, struct gdata_port, write_tomdm_w);
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock, flags);
+ if (!port || !atomic_read(&port->connected))
return;
- }
+ spin_lock_irqsave(&port->rx_lock, flags);
if (test_bit(TX_THROTTLED, &port->brdg.flags)) {
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
goto start_rx;
}
@@ -323,9 +317,9 @@
info = (struct timestamp_info *)skb->cb;
info->rx_done_sent = get_timestamp();
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
ret = data_bridge_write(port->brdg.ch_id, skb);
- spin_lock_irqsave(&port->port_lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
if (ret < 0) {
if (ret == -EBUSY) {
/*flow control*/
@@ -340,7 +334,7 @@
}
port->to_modem++;
}
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
start_rx:
ghsic_data_start_rx(port);
}
@@ -370,9 +364,9 @@
dev_kfree_skb_any(skb);
- spin_lock(&port->port_lock);
+ spin_lock(&port->tx_lock);
list_add_tail(&req->list, &port->tx_idle);
- spin_unlock(&port->port_lock);
+ spin_unlock(&port->tx_lock);
queue_work(port->wq, &port->write_tohost_w);
}
@@ -406,14 +400,14 @@
break;
}
- spin_lock(&port->port_lock);
+ spin_lock(&port->rx_lock);
if (queue) {
info->rx_done = get_timestamp();
__skb_queue_tail(&port->rx_skb_q, skb);
list_add_tail(&req->list, &port->rx_idle);
queue_work(port->wq, &port->write_tomdm_w);
}
- spin_unlock(&port->port_lock);
+ spin_unlock(&port->rx_lock);
}
static void ghsic_data_start_rx(struct gdata_port *port)
@@ -427,15 +421,17 @@
unsigned int created;
pr_debug("%s: port:%p\n", __func__, port);
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock, flags);
+ if (!port)
+ return;
+
+ spin_lock_irqsave(&port->rx_lock, flags);
+ ep = port->out;
+ if (!ep) {
+ spin_unlock_irqrestore(&port->rx_lock, flags);
return;
}
- ep = port->out;
-
- while (port->port_usb && !list_empty(&port->rx_idle)) {
+ while (atomic_read(&port->connected) && !list_empty(&port->rx_idle)) {
if (port->rx_skb_q.qlen > ghsic_data_pend_limit_with_bridge)
break;
@@ -454,22 +450,22 @@
req->context = skb;
info->rx_queued = get_timestamp();
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
ret = usb_ep_queue(ep, req, GFP_KERNEL);
- spin_lock_irqsave(&port->port_lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
if (ret) {
dev_kfree_skb_any(skb);
pr_err_ratelimited("%s: rx queue failed\n", __func__);
- if (port->port_usb)
+ if (atomic_read(&port->connected))
list_add(&req->list, &port->rx_idle);
else
usb_ep_free_request(ep, req);
break;
}
}
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
}
static void ghsic_data_start_io(struct gdata_port *port)
@@ -480,32 +476,41 @@
pr_debug("%s: port:%p\n", __func__, port);
- spin_lock_irqsave(&port->port_lock, flags);
- if (!port->port_usb) {
- spin_unlock_irqrestore(&port->port_lock, flags);
+ if (!port)
+ return;
+
+ spin_lock_irqsave(&port->rx_lock, flags);
+ ep = port->out;
+ if (!ep) {
+ spin_unlock_irqrestore(&port->rx_lock, flags);
return;
}
- ep = port->out;
ret = ghsic_data_alloc_requests(ep, &port->rx_idle,
port->rx_q_size, ghsic_data_epout_complete, GFP_ATOMIC);
if (ret) {
pr_err("%s: rx req allocation failed\n", __func__);
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+ return;
+ }
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+
+ spin_lock_irqsave(&port->tx_lock, flags);
+ ep = port->in;
+ if (!ep) {
+ spin_unlock_irqrestore(&port->tx_lock, flags);
return;
}
- ep = port->in;
ret = ghsic_data_alloc_requests(ep, &port->tx_idle,
port->tx_q_size, ghsic_data_epin_complete, GFP_ATOMIC);
if (ret) {
pr_err("%s: tx req allocation failed\n", __func__);
ghsic_data_free_requests(ep, &port->rx_idle);
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
return;
}
-
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
/* queue out requests */
ghsic_data_start_rx(port);
@@ -517,7 +522,8 @@
container_of(w, struct gdata_port, connect_w);
int ret;
- if (!port || !test_bit(CH_READY, &port->bridge_sts))
+ if (!port || !atomic_read(&port->connected) ||
+ !test_bit(CH_READY, &port->bridge_sts))
return;
pr_debug("%s: port:%p\n", __func__, port);
@@ -551,28 +557,37 @@
struct sk_buff *skb;
unsigned long flags;
- spin_lock_irqsave(&port->port_lock, flags);
+ if (!port)
+ return;
- if (!port || !port->port_usb)
- goto free_buf_out;
+ spin_lock_irqsave(&port->tx_lock, flags);
+ if (!port->in) {
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+ return;
+ }
ghsic_data_free_requests(port->in, &port->tx_idle);
- ghsic_data_free_requests(port->out, &port->rx_idle);
while ((skb = __skb_dequeue(&port->tx_skb_q)))
dev_kfree_skb_any(skb);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+
+ spin_lock_irqsave(&port->rx_lock, flags);
+ if (!port->out) {
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+ return;
+ }
+
+ ghsic_data_free_requests(port->out, &port->rx_idle);
while ((skb = __skb_dequeue(&port->rx_skb_q)))
dev_kfree_skb_any(skb);
-
-free_buf_out:
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
}
static int ghsic_data_probe(struct platform_device *pdev)
{
struct gdata_port *port;
- unsigned long flags;
pr_debug("%s: name:%s no_data_ports= %d\n",
__func__, pdev->name, no_data_ports);
@@ -585,11 +600,9 @@
port = gdata_ports[pdev->id].port;
set_bit(CH_READY, &port->bridge_sts);
- spin_lock_irqsave(&port->port_lock, flags);
/* if usb is online, try opening bridge */
- if (port->port_usb)
+ if (atomic_read(&port->connected))
queue_work(port->wq, &port->connect_w);
- spin_unlock_irqrestore(&port->port_lock, flags);
return 0;
}
@@ -598,9 +611,8 @@
static int ghsic_data_remove(struct platform_device *pdev)
{
struct gdata_port *port;
- struct usb_ep *ep_in = NULL;
- struct usb_ep *ep_out = NULL;
- unsigned long flags;
+ struct usb_ep *ep_in;
+ struct usb_ep *ep_out;
pr_debug("%s: name:%s\n", __func__, pdev->name);
@@ -611,15 +623,11 @@
port = gdata_ports[pdev->id].port;
- spin_lock_irqsave(&port->port_lock, flags);
- if (port->port_usb) {
- ep_in = port->in;
- ep_out = port->out;
- }
- spin_unlock_irqrestore(&port->port_lock, flags);
-
+ ep_in = port->in;
if (ep_in)
usb_ep_fifo_flush(ep_in);
+
+ ep_out = port->out;
if (ep_out)
usb_ep_fifo_flush(ep_out);
@@ -663,7 +671,8 @@
port->port_num = port_num;
/* port initialization */
- spin_lock_init(&port->port_lock);
+ spin_lock_init(&port->rx_lock);
+ spin_lock_init(&port->tx_lock);
INIT_WORK(&port->connect_w, ghsic_data_connect_w);
INIT_WORK(&port->disconnect_w, ghsic_data_disconnect_w);
@@ -724,14 +733,18 @@
if (port->out)
usb_ep_disable(port->in);
- spin_lock_irqsave(&port->port_lock, flags);
- port->port_usb = 0;
+ atomic_set(&port->connected, 0);
+
+ spin_lock_irqsave(&port->tx_lock, flags);
port->in = NULL;
- port->out = NULL;
port->n_tx_req_queued = 0;
- clear_bit(TX_THROTTLED, &port->brdg.flags);
clear_bit(RX_THROTTLED, &port->brdg.flags);
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+
+ spin_lock_irqsave(&port->rx_lock, flags);
+ port->out = NULL;
+ clear_bit(TX_THROTTLED, &port->brdg.flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
queue_work(port->wq, &port->disconnect_w);
}
@@ -762,8 +775,15 @@
if (port->gtype == USB_GADGET_SERIAL) {
gser = gptr;
+
+ spin_lock_irqsave(&port->tx_lock, flags);
port->in = gser->in;
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+
+ spin_lock_irqsave(&port->rx_lock, flags);
port->out = gser->out;
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+
port->tx_q_size = ghsic_data_serial_tx_q_size;
port->rx_q_size = ghsic_data_serial_rx_q_size;
gser->in->driver_data = port;
@@ -772,8 +792,15 @@
out_desc = gser->out_desc;
} else {
gr = gptr;
+
+ spin_lock_irqsave(&port->tx_lock, flags);
port->in = gr->in;
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+
+ spin_lock_irqsave(&port->rx_lock, flags);
port->out = gr->out;
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+
port->tx_q_size = ghsic_data_rmnet_tx_q_size;
port->rx_q_size = ghsic_data_rmnet_rx_q_size;
gr->in->driver_data = port;
@@ -796,17 +823,22 @@
usb_ep_disable(port->in);
goto fail;
}
- spin_lock_irqsave(&port->port_lock, flags);
- port->port_usb = gptr;
+
+ atomic_set(&port->connected, 1);
+
+ spin_lock_irqsave(&port->tx_lock, flags);
port->to_host = 0;
- port->to_modem = 0;
- port->tomodem_drp_cnt = 0;
port->rx_throttled_cnt = 0;
port->rx_unthrottled_cnt = 0;
+ port->unthrottled_pnd_skbs = 0;
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+
+ spin_lock_irqsave(&port->rx_lock, flags);
+ port->to_modem = 0;
+ port->tomodem_drp_cnt = 0;
port->tx_throttled_cnt = 0;
port->tx_unthrottled_cnt = 0;
- port->unthrottled_pnd_skbs = 0;
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->rx_lock, flags);
queue_work(port->wq, &port->connect_w);
fail:
@@ -932,42 +964,49 @@
if (!port)
continue;
pdrv = &gdata_ports[i].pdrv;
- spin_lock_irqsave(&port->port_lock, flags);
+ spin_lock_irqsave(&port->rx_lock, flags);
temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
"\nName: %s\n"
"#PORT:%d port#: %p\n"
- "dpkts_to_usbhost: %lu\n"
+ "data_ch_open: %d\n"
+ "data_ch_ready: %d\n"
+ "\n******UL INFO*****\n\n"
"dpkts_to_modem: %lu\n"
"tomodem_drp_cnt: %u\n"
- "tx_buf_len: %u\n"
"rx_buf_len: %u\n"
- "rx thld cnt %u\n"
- "rx unthld cnt %u\n"
"tx thld cnt %u\n"
"tx unthld cnt %u\n"
- "uthld pnd skbs %u\n"
- "RX_THROTTLED %d\n"
- "TX_THROTTLED %d\n"
- "data_ch_open: %d\n"
- "data_ch_ready: %d\n",
+ "TX_THROTTLED %d\n",
pdrv->driver.name,
i, port,
- port->to_host, port->to_modem,
+ test_bit(CH_OPENED, &port->bridge_sts),
+ test_bit(CH_READY, &port->bridge_sts),
+ port->to_modem,
port->tomodem_drp_cnt,
- port->tx_skb_q.qlen,
port->rx_skb_q.qlen,
- port->rx_throttled_cnt,
- port->rx_unthrottled_cnt,
port->tx_throttled_cnt,
port->tx_unthrottled_cnt,
- port->unthrottled_pnd_skbs,
- test_bit(RX_THROTTLED, &port->brdg.flags),
- test_bit(TX_THROTTLED, &port->brdg.flags),
- test_bit(CH_OPENED, &port->bridge_sts),
- test_bit(CH_READY, &port->bridge_sts));
+ test_bit(TX_THROTTLED, &port->brdg.flags));
+ spin_unlock_irqrestore(&port->rx_lock, flags);
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_lock_irqsave(&port->tx_lock, flags);
+ temp += scnprintf(buf + temp, DEBUG_BUF_SIZE - temp,
+ "\n******DL INFO******\n\n"
+ "dpkts_to_usbhost: %lu\n"
+ "tx_buf_len: %u\n"
+ "rx thld cnt %u\n"
+ "rx unthld cnt %u\n"
+ "uthld pnd skbs %u\n"
+ "RX_THROTTLED %d\n",
+ port->to_host,
+ port->tx_skb_q.qlen,
+ port->rx_throttled_cnt,
+ port->rx_unthrottled_cnt,
+ port->unthrottled_pnd_skbs,
+ test_bit(RX_THROTTLED, &port->brdg.flags));
+ spin_unlock_irqrestore(&port->tx_lock, flags);
+
}
ret = simple_read_from_buffer(ubuf, count, ppos, buf, temp);
@@ -989,16 +1028,19 @@
if (!port)
continue;
- spin_lock_irqsave(&port->port_lock, flags);
- port->to_host = 0;
+ spin_lock_irqsave(&port->rx_lock, flags);
port->to_modem = 0;
port->tomodem_drp_cnt = 0;
- port->rx_throttled_cnt = 0;
- port->rx_unthrottled_cnt = 0;
port->tx_throttled_cnt = 0;
port->tx_unthrottled_cnt = 0;
+ spin_unlock_irqrestore(&port->rx_lock, flags);
+
+ spin_lock_irqsave(&port->tx_lock, flags);
+ port->to_host = 0;
+ port->rx_throttled_cnt = 0;
+ port->rx_unthrottled_cnt = 0;
port->unthrottled_pnd_skbs = 0;
- spin_unlock_irqrestore(&port->port_lock, flags);
+ spin_unlock_irqrestore(&port->tx_lock, flags);
}
return count;
}
diff --git a/drivers/usb/host/ehci-msm-hsic.c b/drivers/usb/host/ehci-msm-hsic.c
index af7f2cf..d64f223 100644
--- a/drivers/usb/host/ehci-msm-hsic.c
+++ b/drivers/usb/host/ehci-msm-hsic.c
@@ -72,6 +72,8 @@
#define USB_PHY_VDD_DIG_VOL_MAX 1320000 /* uV */
#define USB_PHY_VDD_DIG_LOAD 49360 /* uA */
+#define HSIC_DBG1_REG 0x38
+
static int msm_hsic_init_vddcx(struct msm_hsic_hcd *mehci, int init)
{
int ret = 0;
@@ -160,7 +162,7 @@
static struct regulator *hsic_hub_reg;
pdata = mehci->dev->platform_data;
- if (!pdata->hub_reset)
+ if (!pdata || !pdata->hub_reset)
return ret;
if (!init)
@@ -233,7 +235,7 @@
pdata = mehci->dev->platform_data;
- if (!pdata->strobe || !pdata->data)
+ if (!pdata || !pdata->strobe || !pdata->data)
return rc;
if (gpio_status == gpio_en)
@@ -270,16 +272,16 @@
{
int ret;
- clk_enable(mehci->alt_core_clk);
+ clk_prepare_enable(mehci->alt_core_clk);
ret = clk_reset(mehci->core_clk, CLK_RESET_ASSERT);
if (ret) {
- clk_disable(mehci->alt_core_clk);
+ clk_disable_unprepare(mehci->alt_core_clk);
dev_err(mehci->dev, "usb phy clk assert failed\n");
return ret;
}
usleep_range(10000, 12000);
- clk_disable(mehci->alt_core_clk);
+ clk_disable_unprepare(mehci->alt_core_clk);
ret = clk_reset(mehci->core_clk, CLK_RESET_DEASSERT);
if (ret)
@@ -320,6 +322,7 @@
struct usb_hcd *hcd = hsic_to_hcd(mehci);
int cnt = 0;
int ret;
+ struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data;
ret = msm_hsic_phy_reset(mehci);
if (ret) {
@@ -337,36 +340,59 @@
if (cnt >= LINK_RESET_TIMEOUT_USEC)
return -ETIMEDOUT;
- /* select ULPI phy */
+ /* Reset PORTSC and select ULPI phy */
writel_relaxed(0x80000000, USB_PORTSC);
/* TODO: Need to confirm if HSIC PHY also requires delay after RESET */
msleep(100);
/* HSIC PHY Initialization */
- /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */
- writel_relaxed(HSIC_LV_MODE, HSIC_CAL_PAD_CTL);
- /*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */
- ulpi_write(mehci, 0xFF, 0x33);
+ /* HSIC init sequence when HSIC signals (Strobe/Data) are
+ routed via GPIOs */
+ if (pdata && pdata->strobe && pdata->data) {
- /* Enable periodic IO calibration in HSIC_CFG register */
- ulpi_write(mehci, HSIC_PAD_CALIBRATION, 0x30);
+ /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */
+ writel_relaxed(HSIC_LV_MODE, HSIC_CAL_PAD_CTL);
- /* Configure GPIO 150/151 pins for HSIC functionality mode */
- ret = msm_hsic_config_gpios(mehci, 1);
- if (ret) {
- dev_err(mehci->dev, " gpio configuarion failed\n");
- return ret;
+ /*set periodic calibration interval to ~2.048sec in
+ HSIC_IO_CAL_REG */
+ ulpi_write(mehci, 0xFF, 0x33);
+
+ /* Enable periodic IO calibration in HSIC_CFG register */
+ ulpi_write(mehci, HSIC_PAD_CALIBRATION, 0x30);
+
+ /* Configure GPIO 150/151 pins for HSIC functionality mode */
+ ret = msm_hsic_config_gpios(mehci, 1);
+ if (ret) {
+ dev_err(mehci->dev, " gpio configuarion failed\n");
+ return ret;
+ }
+ /* Set LV_MODE=0x1 and DCC=0x2 in HSIC_GPIO150/151_PAD_CTL
+ register */
+ writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO150_PAD_CTL);
+ writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO151_PAD_CTL);
+ /* Enable HSIC mode in HSIC_CFG register */
+ ulpi_write(mehci, 0x01, 0x31);
+ } else {
+ /* HSIC init sequence when HSIC signals (Strobe/Data) are routed
+ via dedicated I/O */
+
+ /* programmable length of connect signaling (33.2ns) */
+ ret = ulpi_write(mehci, 3, HSIC_DBG1_REG);
+ if (ret) {
+ pr_err("%s: Unable to program length of connect "
+ "signaling\n", __func__);
+ }
+
+ /*set periodic calibration interval to ~2.048sec in
+ HSIC_IO_CAL_REG */
+ ulpi_write(mehci, 0xFF, 0x33);
+
+ /* Enable HSIC mode in HSIC_CFG register */
+ ulpi_write(mehci, 0xA9, 0x30);
}
- /* Set LV_MODE=0x1 and DCC=0x2 in HSIC_GPIO150/151_PAD_CTL register */
- writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO150_PAD_CTL);
- writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_GPIO151_PAD_CTL);
-
- /* Enable HSIC mode in HSIC_CFG register */
- ulpi_write(mehci, 0x01, 0x31);
-
return 0;
}
@@ -423,12 +449,12 @@
*/
mb();
- clk_disable(mehci->core_clk);
- clk_disable(mehci->phy_clk);
- clk_disable(mehci->cal_clk);
- clk_disable(mehci->ahb_clk);
+ clk_disable_unprepare(mehci->core_clk);
+ clk_disable_unprepare(mehci->phy_clk);
+ clk_disable_unprepare(mehci->cal_clk);
+ clk_disable_unprepare(mehci->ahb_clk);
pdata = mehci->dev->platform_data;
- if (pdata->hub_reset) {
+ if (pdata && pdata->hub_reset) {
ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_OFF);
if (ret)
pr_err("%s failed to devote for"
@@ -471,16 +497,16 @@
dev_err(mehci->dev, "unable to set vddcx voltage: min:1v max:1.3v\n");
pdata = mehci->dev->platform_data;
- if (pdata->hub_reset) {
+ if (pdata && pdata->hub_reset) {
ret = msm_xo_mode_vote(mehci->xo_handle, MSM_XO_MODE_ON);
if (ret)
pr_err("%s failed to vote for"
"TCXO D1 buffer%d\n", __func__, ret);
}
- clk_enable(mehci->core_clk);
- clk_enable(mehci->phy_clk);
- clk_enable(mehci->cal_clk);
- clk_enable(mehci->ahb_clk);
+ clk_prepare_enable(mehci->core_clk);
+ clk_prepare_enable(mehci->phy_clk);
+ clk_prepare_enable(mehci->cal_clk);
+ clk_prepare_enable(mehci->ahb_clk);
temp = readl_relaxed(USB_USBCMD);
temp &= ~ASYNC_INTR_CTRL;
@@ -634,32 +660,32 @@
if (!init)
goto put_clocks;
- /*core_clk is required for LINK protocol engine,it should be at 60MHz */
+ /*core_clk is required for LINK protocol engine
+ *clock rate appropriately set by target specific clock driver */
mehci->core_clk = clk_get(mehci->dev, "core_clk");
if (IS_ERR(mehci->core_clk)) {
dev_err(mehci->dev, "failed to get core_clk\n");
ret = PTR_ERR(mehci->core_clk);
return ret;
}
- clk_set_rate(mehci->core_clk, 60000000);
- /* 60MHz alt_core_clk is for LINK to be used during PHY RESET */
+ /* alt_core_clk is for LINK to be used during PHY RESET
+ * clock rate appropriately set by target specific clock driver */
mehci->alt_core_clk = clk_get(mehci->dev, "alt_core_clk");
if (IS_ERR(mehci->alt_core_clk)) {
dev_err(mehci->dev, "failed to core_clk\n");
ret = PTR_ERR(mehci->alt_core_clk);
goto put_core_clk;
}
- clk_set_rate(mehci->alt_core_clk, 60000000);
- /* 480MHz phy_clk is required for HSIC PHY operation */
+ /* phy_clk is required for HSIC PHY operation
+ * clock rate appropriately set by target specific clock driver */
mehci->phy_clk = clk_get(mehci->dev, "phy_clk");
if (IS_ERR(mehci->phy_clk)) {
dev_err(mehci->dev, "failed to get phy_clk\n");
ret = PTR_ERR(mehci->phy_clk);
goto put_alt_core_clk;
}
- clk_set_rate(mehci->phy_clk, 480000000);
/* 10MHz cal_clk is required for calibration of I/O pads */
mehci->cal_clk = clk_get(mehci->dev, "cal_clk");
@@ -678,18 +704,18 @@
goto put_cal_clk;
}
- clk_enable(mehci->core_clk);
- clk_enable(mehci->phy_clk);
- clk_enable(mehci->cal_clk);
- clk_enable(mehci->ahb_clk);
+ clk_prepare_enable(mehci->core_clk);
+ clk_prepare_enable(mehci->phy_clk);
+ clk_prepare_enable(mehci->cal_clk);
+ clk_prepare_enable(mehci->ahb_clk);
return 0;
put_clocks:
- clk_disable(mehci->core_clk);
- clk_disable(mehci->phy_clk);
- clk_disable(mehci->cal_clk);
- clk_disable(mehci->ahb_clk);
+ clk_disable_unprepare(mehci->core_clk);
+ clk_disable_unprepare(mehci->phy_clk);
+ clk_disable_unprepare(mehci->cal_clk);
+ clk_disable_unprepare(mehci->ahb_clk);
clk_put(mehci->ahb_clk);
put_cal_clk:
clk_put(mehci->cal_clk);
@@ -778,7 +804,7 @@
}
pdata = mehci->dev->platform_data;
- if (pdata->hub_reset) {
+ if (pdata && pdata->hub_reset) {
mehci->xo_handle = msm_xo_get(MSM_XO_TCXO_D1, "hsic");
if (IS_ERR(mehci->xo_handle)) {
pr_err(" %s not able to get the handle"
@@ -843,7 +869,7 @@
deinit_hub:
msm_hsic_config_hub(mehci, 0);
free_xo_handle:
- if (pdata->hub_reset)
+ if (pdata && pdata->hub_reset)
msm_xo_put(mehci->xo_handle);
deinit_vddcx:
msm_hsic_init_vddcx(mehci, 0);
@@ -874,7 +900,7 @@
msm_hsic_config_gpios(mehci, 0);
msm_hsic_config_hub(mehci, 0);
pdata = mehci->dev->platform_data;
- if (pdata->hub_reset)
+ if (pdata && pdata->hub_reset)
msm_xo_put(mehci->xo_handle);
msm_hsic_init_vddcx(mehci, 0);
diff --git a/drivers/usb/host/ehci-msm72k.c b/drivers/usb/host/ehci-msm72k.c
index 87c75e7..b3939ef 100644
--- a/drivers/usb/host/ehci-msm72k.c
+++ b/drivers/usb/host/ehci-msm72k.c
@@ -79,9 +79,9 @@
return;
if (vote)
- clk_enable(pdata->ebi1_clk);
+ clk_prepare_enable(pdata->ebi1_clk);
else
- clk_disable(pdata->ebi1_clk);
+ clk_disable_unprepare(pdata->ebi1_clk);
}
static void msm_xusb_enable_clks(struct msmusb_hcd *mhcd)
@@ -96,8 +96,8 @@
/* OTG driver takes care of clock management */
break;
case USB_PHY_SERIAL_PMIC:
- clk_enable(mhcd->alt_core_clk);
- clk_enable(mhcd->iface_clk);
+ clk_prepare_enable(mhcd->alt_core_clk);
+ clk_prepare_enable(mhcd->iface_clk);
break;
default:
pr_err("%s: undefined phy type ( %X )\n", __func__,
@@ -119,8 +119,8 @@
/* OTG driver takes care of clock management */
break;
case USB_PHY_SERIAL_PMIC:
- clk_disable(mhcd->alt_core_clk);
- clk_disable(mhcd->iface_clk);
+ clk_disable_unprepare(mhcd->alt_core_clk);
+ clk_disable_unprepare(mhcd->iface_clk);
break;
default:
pr_err("%s: undefined phy type ( %X )\n", __func__,
diff --git a/drivers/usb/otg/msm72k_otg.c b/drivers/usb/otg/msm72k_otg.c
index 59d9769..0ee1827 100644
--- a/drivers/usb/otg/msm72k_otg.c
+++ b/drivers/usb/otg/msm72k_otg.c
@@ -562,9 +562,9 @@
if (on)
/* enable clocks */
- clk_enable(dev->alt_core_clk);
+ clk_prepare_enable(dev->alt_core_clk);
else
- clk_disable(dev->alt_core_clk);
+ clk_disable_unprepare(dev->alt_core_clk);
return 0;
}
@@ -589,7 +589,7 @@
* low power mode routine
*/
if (dev->pdata->pclk_required_during_lpm)
- clk_enable(dev->iface_clk);
+ clk_prepare_enable(dev->iface_clk);
usb_gadget_vbus_connect(xceiv->gadget);
} else {
@@ -601,7 +601,7 @@
* low power mode routine
*/
if (dev->pdata->pclk_required_during_lpm)
- clk_disable(dev->iface_clk);
+ clk_disable_unprepare(dev->iface_clk);
otg_pm_qos_update_latency(dev, 0);
if (pdata->setup_gpio)
@@ -628,9 +628,9 @@
*/
if (dev->pdata->pclk_required_during_lpm) {
if (on)
- clk_enable(dev->iface_clk);
+ clk_prepare_enable(dev->iface_clk);
else
- clk_disable(dev->iface_clk);
+ clk_disable_unprepare(dev->iface_clk);
}
dev->start_host(xceiv->host, on);
@@ -759,9 +759,9 @@
mb();
if (dev->iface_clk)
- clk_disable(dev->iface_clk);
+ clk_disable_unprepare(dev->iface_clk);
- clk_disable(dev->core_clk);
+ clk_disable_unprepare(dev->core_clk);
/* usb phy no more require TCXO clock, hence vote for TCXO disable*/
ret = msm_xo_mode_vote(dev->xo_handle, MSM_XO_MODE_OFF);
if (ret)
@@ -835,10 +835,10 @@
pr_err("%s failed to vote for"
"TCXO D1 buffer%d\n", __func__, ret);
- clk_enable(dev->core_clk);
+ clk_prepare_enable(dev->core_clk);
if (dev->iface_clk)
- clk_enable(dev->iface_clk);
+ clk_prepare_enable(dev->iface_clk);
temp = readl(USB_USBCMD);
temp &= ~ASYNC_INTR_CTRL;
@@ -1550,7 +1550,7 @@
unsigned long timeout;
u32 mode, work = 0;
- clk_enable(dev->alt_core_clk);
+ clk_prepare_enable(dev->alt_core_clk);
if (!phy_reset)
goto reset_link;
@@ -1596,7 +1596,7 @@
/* Ensure that RESET operation is completed before turning off clock */
mb();
- clk_disable(dev->alt_core_clk);
+ clk_disable_unprepare(dev->alt_core_clk);
if ((xceiv->gadget && xceiv->gadget->is_a_peripheral) ||
test_bit(ID, &dev->inputs))
@@ -2646,7 +2646,7 @@
*/
clk_set_rate(dev->core_clk, INT_MAX);
- clk_enable(dev->core_clk);
+ clk_prepare_enable(dev->core_clk);
if (!dev->pdata->pclk_is_hw_gated) {
dev->iface_clk = clk_get(&pdev->dev, "iface_clk");
@@ -2655,7 +2655,7 @@
ret = PTR_ERR(dev->iface_clk);
goto put_core_clk;
}
- clk_enable(dev->iface_clk);
+ clk_prepare_enable(dev->iface_clk);
}
if (!dev->pdata->phy_reset) {
@@ -2888,11 +2888,11 @@
clk_put(dev->phy_reset_clk);
put_iface_clk:
if (dev->iface_clk) {
- clk_disable(dev->iface_clk);
+ clk_disable_unprepare(dev->iface_clk);
clk_put(dev->iface_clk);
}
put_core_clk:
- clk_disable(dev->core_clk);
+ clk_disable_unprepare(dev->core_clk);
clk_put(dev->core_clk);
put_alt_core_clk:
clk_put(dev->alt_core_clk);
@@ -2942,10 +2942,10 @@
dev->pdata->chg_init(0);
free_irq(dev->irq, pdev);
iounmap(dev->regs);
- clk_disable(dev->core_clk);
+ clk_disable_unprepare(dev->core_clk);
clk_put(dev->core_clk);
if (dev->iface_clk) {
- clk_disable(dev->iface_clk);
+ clk_disable_unprepare(dev->iface_clk);
clk_put(dev->iface_clk);
}
if (dev->alt_core_clk)
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 4e1895f..6964835 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -538,7 +538,7 @@
motg->reset_counter++;
}
- clk_enable(motg->clk);
+ clk_prepare_enable(motg->clk);
ret = msm_otg_phy_reset(motg);
if (ret) {
dev_err(otg->dev, "phy_reset failed\n");
@@ -558,7 +558,7 @@
/* Ensure that RESET operation is completed before turning off clock */
mb();
- clk_disable(motg->clk);
+ clk_disable_unprepare(motg->clk);
if (pdata->otg_control == OTG_PHY_CONTROL) {
val = readl_relaxed(USB_OTGSC);
@@ -711,8 +711,8 @@
/* Ensure that above operation is completed before turning off clocks */
mb();
- clk_disable(motg->pclk);
- clk_disable(motg->core_clk);
+ clk_disable_unprepare(motg->pclk);
+ clk_disable_unprepare(motg->core_clk);
/* usb phy no more require TCXO clock, hence vote for TCXO disable */
clk_disable_unprepare(motg->xo_handle);
@@ -765,9 +765,9 @@
dev_err(otg->dev, "%s failed to vote for "
"TCXO D0 buffer%d\n", __func__, ret);
- clk_enable(motg->core_clk);
+ clk_prepare_enable(motg->core_clk);
- clk_enable(motg->pclk);
+ clk_prepare_enable(motg->pclk);
if (motg->lpm_flags & PHY_PWR_COLLAPSED) {
msm_hsusb_ldo_enable(motg, 1);
@@ -2529,7 +2529,7 @@
goto free_xo_handle;
}
- clk_enable(motg->pclk);
+ clk_prepare_enable(motg->pclk);
ret = msm_hsusb_init_vddcx(motg, 1);
if (ret) {
@@ -2554,7 +2554,7 @@
dev_err(&pdev->dev, "hsusb vreg enable failed\n");
goto free_ldo_init;
}
- clk_enable(motg->core_clk);
+ clk_prepare_enable(motg->core_clk);
writel(0, USB_USBINTR);
writel(0, USB_OTGSC);
@@ -2652,14 +2652,14 @@
free_irq(motg->irq, motg);
destroy_wlock:
wake_lock_destroy(&motg->wlock);
- clk_disable(motg->core_clk);
+ clk_disable_unprepare(motg->core_clk);
msm_hsusb_ldo_enable(motg, 0);
free_ldo_init:
msm_hsusb_ldo_init(motg, 0);
free_init_vddcx:
msm_hsusb_init_vddcx(motg, 0);
devote_xo_handle:
- clk_disable(motg->pclk);
+ clk_disable_unprepare(motg->pclk);
clk_disable_unprepare(motg->xo_handle);
free_xo_handle:
clk_put(motg->xo_handle);
@@ -2726,8 +2726,8 @@
if (cnt >= PHY_SUSPEND_TIMEOUT_USEC)
dev_err(otg->dev, "Unable to suspend PHY\n");
- clk_disable(motg->pclk);
- clk_disable(motg->core_clk);
+ clk_disable_unprepare(motg->pclk);
+ clk_disable_unprepare(motg->core_clk);
clk_put(motg->xo_handle);
msm_hsusb_ldo_enable(motg, 0);
msm_hsusb_ldo_init(motg, 0);
diff --git a/drivers/video/msm/Kconfig b/drivers/video/msm/Kconfig
index d3f8b2b..0110df9 100644
--- a/drivers/video/msm/Kconfig
+++ b/drivers/video/msm/Kconfig
@@ -270,6 +270,11 @@
select FB_MSM_MIPI_DSI_TOSHIBA
default n
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
+ bool
+ select FB_MSM_MIPI_DSI_TOSHIBA
+ default n
+
config FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
bool
select FB_MSM_MIPI_DSI_NOVATEK
@@ -446,6 +451,7 @@
bool "MIPI Panel Detect"
select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
@@ -497,9 +503,20 @@
config FB_MSM_LVDS_MIPI_PANEL_DETECT
bool "LVDS + MIPI Panel Auto Detect"
- select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
select FB_MSM_LVDS_CHIMEI_WXGA
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
+ select FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT
+ select FB_MSM_MIPI_RENESAS_CMD_FWVGA_PT
+ select FB_MSM_MIPI_TRULY_VIDEO_WVGA_PT
+ select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
+ select FB_MSM_MIPI_NOVATEK_CMD_QHD_PT
+ select FB_MSM_MIPI_NT35510_VIDEO_WVGA_PT
+ select FB_MSM_MIPI_NT35510_CMD_WVGA_PT
+ select FB_MSM_MIPI_SIMULATOR_VIDEO
select FB_MSM_MIPI_CHIMEI_WXGA
+ select FB_MSM_MIPI_CHIMEI_WUXGA
---help---
Support for LVDS + MIPI panel auto detect
@@ -541,6 +558,10 @@
bool "MIPI Toshiba WSVGA PT Panel"
select FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT
+config FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA_PANEL
+ bool "MIPI Toshiba WUXGA (1920x1200) Panel"
+ select FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA
+
config FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT_PANEL
bool "MIPI NOVATEK VIDEO QHD PT Panel"
select FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index bd7628d..2bdab74 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -114,7 +114,7 @@
endif
ifeq ($(CONFIG_FB_MSM_MIPI_PANEL_DETECT),y)
-obj-y += mipi_toshiba_video_wvga_pt.o mipi_toshiba_video_wsvga_pt.o
+obj-y += mipi_toshiba_video_wvga_pt.o mipi_toshiba_video_wsvga_pt.o mipi_toshiba_video_wuxga.o
obj-y += mipi_novatek_video_qhd_pt.o mipi_novatek_cmd_qhd_pt.o
obj-y += mipi_renesas_video_fwvga_pt.o mipi_renesas_cmd_fwvga_pt.o
obj-y += mipi_NT35510_video_wvga_pt.o mipi_NT35510_cmd_wvga_pt.o
@@ -124,6 +124,7 @@
else
obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WVGA_PT) += mipi_toshiba_video_wvga_pt.o
obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WSVGA_PT) += mipi_toshiba_video_wsvga_pt.o
+obj-$(CONFIG_FB_MSM_MIPI_TOSHIBA_VIDEO_WUXGA) += mipi_toshiba_video_wuxga.o
obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_VIDEO_QHD_PT) += mipi_novatek_video_qhd_pt.o
obj-$(CONFIG_FB_MSM_MIPI_NOVATEK_CMD_QHD_PT) += mipi_novatek_cmd_qhd_pt.o
obj-$(CONFIG_FB_MSM_MIPI_RENESAS_VIDEO_FWVGA_PT) += mipi_renesas_video_fwvga_pt.o
diff --git a/drivers/video/msm/external_common.c b/drivers/video/msm/external_common.c
index 07a075c..0a86a50 100644
--- a/drivers/video/msm/external_common.c
+++ b/drivers/video/msm/external_common.c
@@ -480,16 +480,19 @@
static ssize_t hdmi_msm_wta_cec_frame(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
+ int i;
int retry = ((struct hdmi_msm_cec_msg *) buf)->retransmit;
- if (retry > 15)
- retry = 15;
- while (1) {
+ for (i = 0; i < RETRANSMIT_MAX_NUM; i++) {
hdmi_msm_cec_msg_send((struct hdmi_msm_cec_msg *) buf);
if (hdmi_msm_state->cec_frame_wr_status
- & CEC_STATUS_WR_ERROR && retry--)
+ & CEC_STATUS_WR_ERROR && retry--) {
+ mutex_lock(&hdmi_msm_state_mutex);
+ if (hdmi_msm_state->fsm_reset_done)
+ retry++;
+ mutex_unlock(&hdmi_msm_state_mutex);
msleep(360);
- else
+ } else
break;
}
@@ -911,8 +914,13 @@
uint32 offset = 4;
*len = 0;
- if ((in_buf[2] == 4) && (type != 2)) { /* no non-DTD data present */
- DEV_WARN("EDID: no non-DTD data present\n");
+
+ /*edid buffer 1, byte 2 being 4 means no non-DTD/Data block collection
+ present.
+ edid buffer 1, byte 2 being 0 menas no non-DTD/DATA block collection
+ present and no DTD data present.*/
+ if ((in_buf[2] == 0) || (in_buf[2] == 4)) {
+ DEV_WARN("EDID: no DTD or non-DTD data present\n");
return NULL;
}
while (offset < 0x80) {
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 93e6d40..a0665ac 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -79,6 +79,8 @@
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+static void hdmi_msm_cec_line_latch_detect(void);
+
#ifdef TOGGLE_CEC_HARDWARE_FSM
static boolean msg_send_complete = TRUE;
static boolean msg_recv_complete = TRUE;
@@ -111,7 +113,7 @@
#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_ACK BIT(0)
#define HDMI_MSM_CEC_INT_FRAME_WR_DONE_INT BIT(0)
-#define HDMI_MSM_CEC_FRAME_WR_SUCCESS(___st) (((___st)&0xF) ==\
+#define HDMI_MSM_CEC_FRAME_WR_SUCCESS(___st) (((___st)&0xB) ==\
(HDMI_MSM_CEC_INT_FRAME_WR_DONE_INT |\
HDMI_MSM_CEC_INT_FRAME_WR_DONE_MASK |\
HDMI_MSM_CEC_INT_FRAME_ERROR_MASK))
@@ -142,8 +144,8 @@
*/
HDMI_OUTP(0x02A0, HDMI_MSM_CEC_ADDR_LOGICAL_ADDR(4));
- /* 0x028C CEC_CTRL */
- HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+ hdmi_msm_state->first_monitor = 0;
+ hdmi_msm_state->fsm_reset_done = false;
/* 0x029C CEC_INT */
/* Enable CEC interrupts */
@@ -161,7 +163,11 @@
* BIT_1_ERR_RANGE_HI = 8 => 750us, the test used 775us,
* so increased this to 9 which => 800us.
*/
- HDMI_OUTP(0x02E0, 0x889788);
+ /*
+ * CEC latch up issue - To fire monitor interrupt
+ * for every start of message
+ */
+ HDMI_OUTP(0x02E0, 0x880000);
/*
* Slight adjustment to logic 0 low period on write
@@ -173,6 +179,8 @@
*/
HDMI_OUTP(0x02A4, 0x1 | (7 * 0x30) << 7);
+ /* 0x028C CEC_CTRL */
+ HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
}
void hdmi_msm_cec_write_logical_addr(int addr)
@@ -207,6 +215,9 @@
boolean frameType = (msg->recvr_id == 15 ? BIT(0) : 0);
+ mutex_lock(&hdmi_msm_state_mutex);
+ hdmi_msm_state->fsm_reset_done = false;
+ mutex_unlock(&hdmi_msm_state_mutex);
#ifdef TOGGLE_CEC_HARDWARE_FSM
msg_send_complete = FALSE;
#endif
@@ -278,9 +289,34 @@
msg_recv_complete = TRUE;
}
msg_send_complete = TRUE;
+#else
+ HDMI_OUTP(0x028C, 0x0);
+ HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
#endif
}
+void hdmi_msm_cec_line_latch_detect(void)
+{
+ /*
+ * CECT 9-5-1
+ * The timer period needs to be changed to appropriate value
+ */
+ /*
+ * Timedout without RD_DONE, WR_DONE or ERR_INT
+ * Toggle CEC hardware FSM
+ */
+ mutex_lock(&hdmi_msm_state_mutex);
+ if (hdmi_msm_state->first_monitor == 1) {
+ DEV_WARN("CEC line is probably latched up - CECT 9-5-1");
+ if (!msg_recv_complete)
+ hdmi_msm_state->fsm_reset_done = true;
+ HDMI_OUTP(0x028C, 0x0);
+ HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
+ hdmi_msm_state->first_monitor = 0;
+ }
+ mutex_unlock(&hdmi_msm_state_mutex);
+}
+
void hdmi_msm_cec_msg_recv(void)
{
uint32 data;
@@ -476,6 +512,14 @@
temp_msg.frame_size = i + 2;
hdmi_msm_cec_msg_send(&temp_msg);
break;
+ case 0x44:
+ /* User Control Pressed */
+ DEV_INFO("User Control Pressed\n");
+ break;
+ case 0x45:
+ /* User Control Released */
+ DEV_INFO("User Control Released\n");
+ break;
default:
DEV_INFO("Recvd an unknown cmd = [%u]\n",
hdmi_msm_state->cec_queue_wr->opcode);
@@ -837,6 +881,13 @@
HDMI_OUTP(0x0254, 4 | (hpd_state ? 0 : 2));
}
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+static void hdmi_msm_cec_latch_work(struct work_struct *work)
+{
+ hdmi_msm_cec_line_latch_detect();
+}
+#endif
+
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT
static void hdcp_deauthenticate(void);
static void hdmi_msm_hdcp_reauth_work(struct work_struct *work)
@@ -1099,6 +1150,8 @@
HDMI_MSM_CEC_INT_FRAME_WR_DONE_ACK);
mutex_lock(&hdmi_msm_state_mutex);
hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_DONE;
+ hdmi_msm_state->first_monitor = 0;
+ del_timer(&hdmi_msm_state->cec_read_timer);
mutex_unlock(&hdmi_msm_state_mutex);
complete(&hdmi_msm_state->cec_frame_wr_done);
return IRQ_HANDLED;
@@ -1112,17 +1165,50 @@
#endif
HDMI_OUTP(0x029C, cec_intr_status);
mutex_lock(&hdmi_msm_state_mutex);
+ hdmi_msm_state->first_monitor = 0;
+ del_timer(&hdmi_msm_state->cec_read_timer);
hdmi_msm_state->cec_frame_wr_status |= CEC_STATUS_WR_ERROR;
mutex_unlock(&hdmi_msm_state_mutex);
complete(&hdmi_msm_state->cec_frame_wr_done);
return IRQ_HANDLED;
}
- if ((cec_intr_status & (1 << 4)) && (cec_intr_status & (1 << 5)))
+ if ((cec_intr_status & (1 << 4)) && (cec_intr_status & (1 << 5))) {
DEV_DBG("CEC_IRQ_MONITOR\n");
+ HDMI_OUTP(0x029C, cec_intr_status |
+ HDMI_MSM_CEC_INT_MONITOR_ACK);
+
+ /*
+ * CECT 9-5-1
+ * On the first occassion start a timer
+ * for few hundred ms, if it expires then
+ * reset the CEC block else go on with
+ * frame transactions as usual.
+ * Below adds hdmi_msm_cec_msg_recv() as an
+ * item into the work queue instead of running in
+ * interrupt context
+ */
+ mutex_lock(&hdmi_msm_state_mutex);
+ if (hdmi_msm_state->first_monitor == 0) {
+ /* This timer might have to be changed
+ * worst case theoritical =
+ * 16 bytes * 8 * 2.7msec = 346 msec
+ */
+ mod_timer(&hdmi_msm_state->cec_read_timer,
+ jiffies + HZ/2);
+ hdmi_msm_state->first_monitor = 1;
+ }
+ mutex_unlock(&hdmi_msm_state_mutex);
+ return IRQ_HANDLED;
+ }
if ((cec_intr_status & (1 << 6)) && (cec_intr_status & (1 << 7))) {
DEV_DBG("CEC_IRQ_FRAME_RD_DONE\n");
+
+ mutex_lock(&hdmi_msm_state_mutex);
+ hdmi_msm_state->first_monitor = 0;
+ del_timer(&hdmi_msm_state->cec_read_timer);
+ mutex_unlock(&hdmi_msm_state_mutex);
HDMI_OUTP(0x029C, cec_intr_status |
HDMI_MSM_CEC_INT_FRAME_RD_DONE_ACK);
hdmi_msm_cec_msg_recv();
@@ -1135,6 +1221,9 @@
HDMI_OUTP(0x028C, 0x0);
HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
}
+#else
+ HDMI_OUTP(0x028C, 0x0);
+ HDMI_OUTP(0x028C, HDMI_MSM_CEC_CTRL_ENABLE);
#endif
return IRQ_HANDLED;
@@ -2371,6 +2460,8 @@
[8] AN_0_READY
[9] AN_1_READY */
/* wait for an0 and an1 ready bits to be set in LINK0_STATUS */
+
+ mutex_lock(&hdcp_auth_state_mutex);
timeout_count = 100;
while (((HDMI_INP_ND(0x011C) & (0x3 << 8)) != (0x3 << 8))
&& timeout_count--)
@@ -2404,6 +2495,7 @@
[31:0] LINK0_AN_1 */
/* read an1 calculation */
link0_an_1 = HDMI_INP(0x0150);
+ mutex_unlock(&hdcp_auth_state_mutex);
/* three bits 28..30 */
hdcp_key_state((HDMI_INP(0x011C) >> 28) & 0x7);
@@ -3867,7 +3959,11 @@
"AUDIO CFG is %08x", i, audio_pkt_ctrl, audio_cfg);
msleep(20);
}
+
+ mutex_lock(&hdcp_auth_state_mutex);
hdmi_msm_reset_core();
+ mutex_unlock(&hdcp_auth_state_mutex);
+
hdmi_msm_init_phy(external_common_state->video_resolution);
/* HDMI_USEC_REFTIMER[0x0208] */
HDMI_OUTP(0x0208, 0x0001001B);
@@ -3924,6 +4020,13 @@
}
#endif
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+static void hdmi_msm_cec_read_timer_func(unsigned long data)
+{
+ queue_work(hdmi_work_queue, &hdmi_msm_state->cec_latch_detect_work);
+}
+#endif
+
static void hdmi_msm_hpd_read_work(struct work_struct *work)
{
uint32 hpd_ctrl;
@@ -3965,6 +4068,7 @@
hdmi_msm_set_mode(FALSE);
hdmi_msm_state->hpd_initialized = FALSE;
+ hdmi_msm_powerdown_phy();
hdmi_msm_state->pd->cec_power(0);
hdmi_msm_state->pd->enable_5v(0);
hdmi_msm_state->pd->core_power(0, 1);
@@ -4248,6 +4352,15 @@
add_timer(&hdmi_msm_state->hdcp_timer);
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
+#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+ init_timer(&hdmi_msm_state->cec_read_timer);
+ hdmi_msm_state->cec_read_timer.function =
+ hdmi_msm_cec_read_timer_func;
+ hdmi_msm_state->cec_read_timer.data = (uint32)NULL;
+
+ hdmi_msm_state->cec_read_timer.expires = 0xffffffffL;
+ #endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
+
fb_dev = msm_fb_add_device(pdev);
if (fb_dev) {
rc = external_common_state_create(fb_dev);
@@ -4452,7 +4565,10 @@
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_HDCP_SUPPORT */
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
+ INIT_WORK(&hdmi_msm_state->cec_latch_detect_work,
+ hdmi_msm_cec_latch_work);
init_completion(&hdmi_msm_state->cec_frame_wr_done);
+ init_completion(&hdmi_msm_state->cec_line_latch_wait);
#endif
rc = platform_device_register(&this_device);
diff --git a/drivers/video/msm/hdmi_msm.h b/drivers/video/msm/hdmi_msm.h
index 6d19d157..9675fd5 100644
--- a/drivers/video/msm/hdmi_msm.h
+++ b/drivers/video/msm/hdmi_msm.h
@@ -75,8 +75,10 @@
#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT
boolean cec_enabled;
+ unsigned int first_monitor;
int cec_logical_addr;
struct completion cec_frame_wr_done;
+ struct timer_list cec_read_timer;
#define CEC_STATUS_WR_ERROR 0x0001
#define CEC_STATUS_WR_DONE 0x0002
#define CEC_STATUS_WR_TMOUT 0x0004
@@ -86,8 +88,17 @@
struct hdmi_msm_cec_msg *cec_queue_wr;
struct hdmi_msm_cec_msg *cec_queue_rd;
boolean cec_queue_full;
+ boolean fsm_reset_done;
+
+ /*
+ * CECT 9-5-1
+ */
+ struct completion cec_line_latch_wait;
+ struct work_struct cec_latch_detect_work;
+
#define CEC_QUEUE_SIZE 16
#define CEC_QUEUE_END (hdmi_msm_state->cec_queue_start + CEC_QUEUE_SIZE)
+#define RETRANSMIT_MAX_NUM 7
#endif /* CONFIG_FB_MSM_HDMI_MSM_PANEL_CEC_SUPPORT */
int irq;
diff --git a/drivers/video/msm/lcdc_gordon.c b/drivers/video/msm/lcdc_gordon.c
index f9532b4..8327c6c 100644
--- a/drivers/video/msm/lcdc_gordon.c
+++ b/drivers/video/msm/lcdc_gordon.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2009-2010, 2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -84,6 +84,7 @@
static int spi_sdo;
static int spi_sdi;
static int spi_dac;
+static int bl_level;
static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
(1 << 6),
(1 << 5),
@@ -313,6 +314,17 @@
spi_init(); /* LCD needs SPI */
gordon_disp_powerup();
gordon_disp_on();
+ if (bl_level <= 1) {
+ /* keep back light OFF */
+ serigo(GORDON_REG_LCDIFCTL2, 0x0B);
+ udelay(15);
+ serigo(GORDON_REG_VALTRAN, 0x01);
+ } else {
+ /* keep back light ON */
+ serigo(GORDON_REG_LCDIFCTL2, 0x7B);
+ udelay(15);
+ serigo(GORDON_REG_VALTRAN, 0x01);
+ }
gordon_state.disp_initialized = TRUE;
}
return 0;
@@ -351,18 +363,20 @@
static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
{
- int bl_level = mfd->bl_level;
+ bl_level = mfd->bl_level;
- if (bl_level <= 1) {
- /* keep back light OFF */
- serigo(GORDON_REG_LCDIFCTL2, 0x0B);
- udelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
- } else {
- /* keep back light ON */
- serigo(GORDON_REG_LCDIFCTL2, 0x7B);
- udelay(15);
- serigo(GORDON_REG_VALTRAN, 0x01);
+ if (gordon_state.disp_initialized) {
+ if (bl_level <= 1) {
+ /* keep back light OFF */
+ serigo(GORDON_REG_LCDIFCTL2, 0x0B);
+ udelay(15);
+ serigo(GORDON_REG_VALTRAN, 0x01);
+ } else {
+ /* keep back light ON */
+ serigo(GORDON_REG_LCDIFCTL2, 0x7B);
+ udelay(15);
+ serigo(GORDON_REG_VALTRAN, 0x01);
+ }
}
}
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
index 43520e0..e43f729 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/msm/mdp.c
@@ -875,15 +875,16 @@
/* LCDC Frame Start */
if (mdp_interrupt & LCDC_FRAME_START) {
+ dma = &dma2_data;
+ spin_lock_irqsave(&mdp_spin_lock, flag);
/* let's disable LCDC interrupt */
mdp_intr_mask &= ~LCDC_FRAME_START;
outp32(MDP_INTR_ENABLE, mdp_intr_mask);
-
- dma = &dma2_data;
if (dma->waiting) {
dma->waiting = FALSE;
complete(&dma->comp);
}
+ spin_unlock_irqrestore(&mdp_spin_lock, flag);
}
/* DMA2 LCD-Out Complete */
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index bf53c73..4f8be7e 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -370,17 +370,18 @@
static uint32 mdp4_scale_phase_step(int f_num, uint32 src, uint32 dst)
{
- uint32 val;
+ uint32 val, s;
int n;
n = mdp4_leading_0(src);
if (n > f_num)
n = f_num;
- val = src << n; /* maximum to reduce lose of resolution */
- val /= dst;
+ s = src << n; /* maximum to reduce lose of resolution */
+ val = s / dst;
if (n < f_num) {
n = f_num - n;
val <<= n;
+ val |= ((s % dst) << n) / dst;
}
return val;
@@ -2342,6 +2343,9 @@
mdp4_stat.overlay_unset[pipe->mixer_num]++;
mdp4_overlay_pipe_free(pipe);
+
+ mdp4_set_perf_level();
+
mutex_unlock(&mfd->dma->ov_mutex);
return 0;
diff --git a/drivers/video/msm/mdp4_overlay_atv.c b/drivers/video/msm/mdp4_overlay_atv.c
index 5cdafe1..0b707d7 100644
--- a/drivers/video/msm/mdp4_overlay_atv.c
+++ b/drivers/video/msm/mdp4_overlay_atv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -38,13 +38,16 @@
{
uint8 *buf;
int bpp, ptype;
+ int yres, remainder;
struct fb_info *fbi;
struct fb_var_screeninfo *var;
struct msm_fb_data_type *mfd;
struct mdp4_overlay_pipe *pipe;
+ struct msm_panel_info *panel_info;
int ret;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+ panel_info = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -55,10 +58,28 @@
fbi = mfd->fbi;
var = &fbi->var;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
if (atv_pipe == NULL) {
ptype = mdp4_overlay_format2type(mfd->fb_imgType);
@@ -150,16 +171,36 @@
uint8 *buf;
int bpp;
unsigned long flag;
+ int yres, remainder;
struct mdp4_overlay_pipe *pipe;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
if (!mfd->panel_power_on)
return;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* no need to power on cmd block since it's lcdc mode */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
mutex_lock(&mfd->dma->ov_mutex);
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 3f12827..a3be2af 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -96,13 +96,16 @@
int hsync_end_x;
uint8 *buf;
int bpp, ptype;
+ int yres, remainder;
struct fb_info *fbi;
struct fb_var_screeninfo *var;
struct msm_fb_data_type *mfd;
struct mdp4_overlay_pipe *pipe;
+ struct msm_panel_info *panel_info;
int ret;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+ panel_info = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -115,10 +118,28 @@
fbi = mfd->fbi;
var = &fbi->var;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
if (dsi_pipe == NULL) {
ptype = mdp4_overlay_format2type(mfd->fb_imgType);
@@ -295,7 +316,9 @@
{
struct fb_info *fbi;
struct mdp4_overlay_pipe *pipe;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
int bpp;
+ int yres, remainder;
uint8 *buf = NULL;
if (dsi_pipe == NULL)
@@ -314,10 +337,28 @@
fbi = mfd->fbi;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
if (pipe->is_3d) {
pipe->src_height = pipe->src_height_3d;
@@ -648,16 +689,36 @@
struct fb_info *fbi = mfd->fbi;
uint8 *buf;
int bpp;
+ int yres, remainder;
struct mdp4_overlay_pipe *pipe;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
if (!mfd->panel_power_on)
return;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* no need to power on cmd block since it's dsi video mode */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
mutex_lock(&mfd->dma->ov_mutex);
diff --git a/drivers/video/msm/mdp4_overlay_dtv.c b/drivers/video/msm/mdp4_overlay_dtv.c
index 3a1a9aa..590ad65 100644
--- a/drivers/video/msm/mdp4_overlay_dtv.c
+++ b/drivers/video/msm/mdp4_overlay_dtv.c
@@ -231,8 +231,15 @@
return -EINVAL;
mdp4_overlay_panel_mode(MDP4_MIXER1, MDP4_PANEL_DTV);
- if (dtv_pipe != NULL)
- ret = mdp4_dtv_start(mfd);
+
+ /* Allocate dtv_pipe at dtv_on*/
+ if (dtv_pipe == NULL) {
+ if (mdp4_overlay_dtv_set(mfd, NULL)) {
+ pr_warn("%s: dtv_pipe is NULL, dtv_set failed\n",
+ __func__);
+ return -EINVAL;
+ }
+ }
ret = panel_next_on(pdev);
if (ret != 0)
@@ -527,7 +534,7 @@
*/
temp_src_format = inpdw(rgb_base + 0x0050);
MDP_OUTP(rgb_base + 0x0050, temp_src_format | BIT(22));
- mdp4_mixer_stage_up(pipe);
+ mdp4_mixer_stage_up(dtv_pipe);
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
#endif
@@ -604,14 +611,6 @@
return;
mutex_lock(&mfd->dma->ov_mutex);
- if (dtv_pipe == NULL) {
- if (mdp4_overlay_dtv_set(mfd, NULL)) {
- pr_warn("%s: dtv_pipe == NULL\n", __func__);
- mutex_unlock(&mfd->dma->ov_mutex);
- return;
- }
- }
-
pipe = dtv_pipe;
if (pipe->pipe_type == OVERLAY_TYPE_RGB) {
pipe->srcp0_addr = (uint32) mfd->ibuf.buf;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index 3dece1f..ae498fc 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -84,8 +84,11 @@
struct msm_fb_data_type *mfd;
struct mdp4_overlay_pipe *pipe;
int ret;
+ int yres, remainder;
+ struct msm_panel_info *panel_info;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+ panel_info = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -98,6 +101,17 @@
fbi = mfd->fbi;
var = &fbi->var;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
if (is_mdp4_hw_reset()) {
@@ -107,8 +121,15 @@
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
if (lcdc_pipe == NULL) {
ptype = mdp4_overlay_format2type(mfd->fb_imgType);
@@ -552,16 +573,36 @@
struct fb_info *fbi = mfd->fbi;
uint8 *buf;
int bpp;
+ int yres, remainder;
struct mdp4_overlay_pipe *pipe;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
if (!mfd->panel_power_on)
return;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* no need to power on cmd block since it's lcdc mode */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
mutex_lock(&mfd->dma->ov_mutex);
diff --git a/drivers/video/msm/mdp4_overlay_writeback.c b/drivers/video/msm/mdp4_overlay_writeback.c
index cd4afd0..7739837 100644
--- a/drivers/video/msm/mdp4_overlay_writeback.c
+++ b/drivers/video/msm/mdp4_overlay_writeback.c
@@ -394,20 +394,49 @@
temp = kzalloc(sizeof(struct msmfb_writeback_data_list),
GFP_KERNEL);
if (temp == NULL) {
- pr_err("Out of memory\n");
- goto err;
+ pr_err("%s: out of memory\n", __func__);
+ goto register_alloc_fail;
}
- temp->addr = (void *)(data->iova + data->offset);
+ if (data->iova)
+ temp->addr = (void *)(data->iova + data->offset);
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+ else {
+ struct ion_handle *srcp_ihdl;
+ ulong len;
+ srcp_ihdl = ion_import_fd(mfd->iclient,
+ data->memory_id);
+ if (IS_ERR_OR_NULL(srcp_ihdl)) {
+ pr_err("%s: ion import fd failed\n", __func__);
+ goto register_ion_fail;
+ }
+ if (ion_phys(mfd->iclient,
+ srcp_ihdl,
+ (ulong *)&temp->addr,
+ (size_t *)&len)) {
+ pr_err("%s: unable to get ion phys\n",
+ __func__);
+ goto register_ion_fail;
+ }
+ temp->addr += data->offset;
+ }
+#else
+ else {
+ pr_err("%s: only support ion memory\n", __func__);
+ goto register_ion_fail;
+ }
+#endif
memcpy(&temp->buf_info, data, sizeof(struct msmfb_data));
if (mdp4_overlay_writeback_register_buffer(mfd, temp)) {
- pr_err("Error registering node\n");
- kfree(temp);
- temp = NULL;
+ pr_err("%s: error registering node\n", __func__);
+ goto register_ion_fail;
}
}
-err:
return temp;
+ register_ion_fail:
+ kfree(temp);
+ register_alloc_fail:
+ return NULL;
}
int mdp4_writeback_start(
struct fb_info *info)
diff --git a/drivers/video/msm/mdp_dma.c b/drivers/video/msm/mdp_dma.c
index 3997814..e8b288f 100644
--- a/drivers/video/msm/mdp_dma.c
+++ b/drivers/video/msm/mdp_dma.c
@@ -522,14 +522,37 @@
boolean sync)
{
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
+ struct fb_info *fbi = mfd->fbi;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
MDPIBUF *iBuf;
int bpp = info->var.bits_per_pixel / 8;
+ int yres, remainder;
+
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
down(&mfd->sem);
+
iBuf = &mfd->ibuf;
iBuf->buf = (uint8 *) info->fix.smem_start;
- iBuf->buf += info->var.xoffset * bpp +
- info->var.yoffset * info->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ iBuf->buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ iBuf->buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ iBuf->buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
iBuf->ibuf_width = info->var.xres_virtual;
iBuf->bpp = bpp;
diff --git a/drivers/video/msm/mdp_dma_dsi_video.c b/drivers/video/msm/mdp_dma_dsi_video.c
index 505eb74..0e76a07 100644
--- a/drivers/video/msm/mdp_dma_dsi_video.c
+++ b/drivers/video/msm/mdp_dma_dsi_video.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -67,14 +67,17 @@
int hsync_end_x;
uint8 *buf;
uint32 dma2_cfg_reg;
+ int yres, remainder;
int bpp;
struct fb_info *fbi;
struct fb_var_screeninfo *var;
struct msm_fb_data_type *mfd;
+ struct msm_panel_info *panel_info;
int ret;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+ panel_info = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -85,10 +88,29 @@
fbi = mfd->fbi;
var = &fbi->var;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_DSI_VIDEO;
@@ -239,17 +261,38 @@
uint8 *buf;
int bpp;
unsigned long flag;
+ int yres, remainder;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
int irq_block = MDP_DMA2_TERM;
if (!mfd->panel_power_on)
return;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
down(&mfd->dma->mutex);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
/* no need to power on cmd block since it's dsi mode */
/* starting address */
MDP_OUTP(MDP_BASE + DMA_P_BASE + 0x8, (uint32) buf);
diff --git a/drivers/video/msm/mdp_dma_lcdc.c b/drivers/video/msm/mdp_dma_lcdc.c
index 9ce7e13..5dada35 100644
--- a/drivers/video/msm/mdp_dma_lcdc.c
+++ b/drivers/video/msm/mdp_dma_lcdc.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -89,12 +89,15 @@
struct fb_info *fbi;
struct fb_var_screeninfo *var;
struct msm_fb_data_type *mfd;
+ struct msm_panel_info *panel_info;
uint32 dma_base;
uint32 timer_base = LCDC_BASE;
uint32 block = MDP_DMA2_BLOCK;
int ret;
+ int yres, remainder;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+ panel_info = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -105,12 +108,32 @@
fbi = mfd->fbi;
var = &fbi->var;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp + fbi->var.yoffset * fbi->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
dma2_cfg_reg = DMA_PACK_ALIGN_LSB | DMA_OUT_SEL_LCDC;
@@ -299,6 +322,7 @@
}
#endif
+ down(&mfd->dma->mutex);
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
MDP_OUTP(MDP_BASE + timer_base, 0);
@@ -307,6 +331,7 @@
mdp_pipe_ctrl(block, MDP_BLOCK_POWER_OFF, FALSE);
ret = panel_next_off(pdev);
+ up(&mfd->dma->mutex);
/* delay to make sure the last frame finishes */
msleep(16);
@@ -317,23 +342,45 @@
void mdp_lcdc_update(struct msm_fb_data_type *mfd)
{
struct fb_info *fbi = mfd->fbi;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
uint8 *buf;
int bpp;
unsigned long flag;
uint32 dma_base;
+ int yres, remainder;
int irq_block = MDP_DMA2_TERM;
#ifdef CONFIG_FB_MSM_MDP40
int intr = INTR_DMA_P_DONE;
#endif
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
if (!mfd->panel_power_on)
return;
+ down(&mfd->dma->mutex);
/* no need to power on cmd block since it's lcdc mode */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
dma_base = DMA_P_BASE;
@@ -365,4 +412,5 @@
spin_unlock_irqrestore(&mdp_spin_lock, flag);
wait_for_completion_killable(&mfd->dma->comp);
mdp_disable_irq(irq_block);
+ up(&mfd->dma->mutex);
}
diff --git a/drivers/video/msm/mdp_dma_tv.c b/drivers/video/msm/mdp_dma_tv.c
index 66d9422..1305e03 100644
--- a/drivers/video/msm/mdp_dma_tv.c
+++ b/drivers/video/msm/mdp_dma_tv.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2008-2009, 2012 Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -39,12 +39,15 @@
int mdp_dma3_on(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
+ struct msm_panel_info *panel_info;
struct fb_info *fbi;
uint8 *buf;
int bpp;
int ret = 0;
+ int yres, remainder;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
+ panel_info = &mfd->panel_info;
if (!mfd)
return -ENODEV;
@@ -53,13 +56,33 @@
return -EINVAL;
fbi = mfd->fbi;
+
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* MDP cmd block enable */
mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
/* starting address[31..8] of Video frame buffer is CS0 */
MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
@@ -112,15 +135,37 @@
uint8 *buf;
int bpp;
unsigned long flag;
+ int yres, remainder;
+ struct msm_panel_info *panel_info = &mfd->panel_info;
if (!mfd->panel_power_on)
return;
+ if (panel_info->mode2_yres != 0) {
+ yres = panel_info->mode2_yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ } else {
+ yres = panel_info->yres;
+ remainder = (fbi->fix.line_length*yres)%PAGE_SIZE;
+ }
+
+ if (!remainder)
+ remainder = PAGE_SIZE;
+
/* no need to power on cmd block since dma3 is running */
bpp = fbi->var.bits_per_pixel / 8;
buf = (uint8 *) fbi->fix.smem_start;
- buf += fbi->var.xoffset * bpp +
- fbi->var.yoffset * fbi->fix.line_length;
+
+ if (fbi->var.yoffset < yres) {
+ buf += fbi->var.xoffset * bpp;
+ } else if (fbi->var.yoffset >= yres && fbi->var.yoffset < 2 * yres) {
+ buf += fbi->var.xoffset * bpp + yres *
+ fbi->fix.line_length + PAGE_SIZE - remainder;
+ } else {
+ buf += fbi->var.xoffset * bpp + 2 * yres *
+ fbi->fix.line_length + 2 * (PAGE_SIZE - remainder);
+ }
+
MDP_OUTP(MDP_BASE + 0xC0008, (uint32) buf >> 3);
spin_lock_irqsave(&mdp_spin_lock, flag);
diff --git a/drivers/video/msm/mipi_dsi.h b/drivers/video/msm/mipi_dsi.h
index 9907109..4fbb044 100644
--- a/drivers/video/msm/mipi_dsi.h
+++ b/drivers/video/msm/mipi_dsi.h
@@ -50,7 +50,8 @@
#define MIPI_DSI_PANEL_WSVGA_PT 4
#define MIPI_DSI_PANEL_QHD_PT 5
#define MIPI_DSI_PANEL_WXGA 6
-#define DSI_PANEL_MAX 6
+#define MIPI_DSI_PANEL_WUXGA 7
+#define DSI_PANEL_MAX 7
enum { /* mipi dsi panel */
DSI_VIDEO_MODE,
diff --git a/drivers/video/msm/mipi_toshiba.c b/drivers/video/msm/mipi_toshiba.c
index 5788f27..2db8bcf 100644
--- a/drivers/video/msm/mipi_toshiba.c
+++ b/drivers/video/msm/mipi_toshiba.c
@@ -196,7 +196,8 @@
mipi_dsi_cmds_tx(mfd, &toshiba_tx_buf,
toshiba_wvga_display_on_cmds,
ARRAY_SIZE(toshiba_wvga_display_on_cmds));
- else if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WSVGA_PT)
+ else if (TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WSVGA_PT ||
+ TM_GET_PID(mfd->panel.id) == MIPI_DSI_PANEL_WUXGA)
mipi_dsi_cmds_tx(mfd, &toshiba_tx_buf,
toshiba_wsvga_display_on_cmds,
ARRAY_SIZE(toshiba_wsvga_display_on_cmds));
diff --git a/drivers/video/msm/mipi_toshiba_video_wuxga.c b/drivers/video/msm/mipi_toshiba_video_wuxga.c
new file mode 100644
index 0000000..297248f
--- /dev/null
+++ b/drivers/video/msm/mipi_toshiba_video_wuxga.c
@@ -0,0 +1,97 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include "msm_fb.h"
+#include "mipi_dsi.h"
+#include "mipi_toshiba.h"
+
+static struct msm_panel_info pinfo;
+
+static struct mipi_dsi_phy_ctrl dsi_video_mode_phy_db = {
+ /* 1920*1200, RGB888, 4 Lane 60 fps video mode */
+ /* regulator */
+ {0x03, 0x0a, 0x04, 0x00, 0x20},
+ /* timing */
+ {0x66, 0x26, 0x1F, 0x00, 0x55, 0x9C, 0x16, 0x90,
+ 0x23, 0x03, 0x04, 0xa0},
+ /* phy ctrl */
+ {0x5f, 0x00, 0x00, 0x10},
+ /* strength */
+ {0xff, 0x00, 0x06, 0x00},
+ /* pll control */
+ {0x0, 0xD7, 0x1, 0x19, 0x00, 0x50, 0x48, 0x63,
+ 0x41, 0x0f, 0x01,
+ 0x00, 0x14, 0x03, 0x00, 0x02, 0x00, 0x20, 0x00, 0x01 },
+};
+
+static int __init mipi_video_toshiba_wuxga_init(void)
+{
+ int ret;
+
+ if (msm_fb_detect_client("mipi_video_toshiba_wuxga"))
+ return 0;
+
+ pinfo.xres = 1920;
+ pinfo.yres = 1200;
+
+ pinfo.type = MIPI_VIDEO_PANEL;
+ pinfo.pdest = DISPLAY_1;
+ pinfo.wait_cycle = 0;
+ pinfo.bpp = 24;
+ pinfo.lcdc.h_back_porch = 50;
+ pinfo.lcdc.h_front_porch = 50;
+ pinfo.lcdc.h_pulse_width = 170;
+ pinfo.lcdc.v_back_porch = 7;
+ pinfo.lcdc.v_front_porch = 8;
+ pinfo.lcdc.v_pulse_width = 30;
+ pinfo.lcdc.border_clr = 0; /* blk */
+ pinfo.lcdc.underflow_clr = 0xff; /* blue */
+ pinfo.lcdc.hsync_skew = 0;
+ pinfo.bl_max = MIPI_TOSHIBA_PWM_LEVEL;
+ pinfo.bl_min = 1;
+ pinfo.fb_num = 2;
+ pinfo.clk_rate = 981560000;
+
+ pinfo.mipi.mode = DSI_VIDEO_MODE;
+ pinfo.mipi.pulse_mode_hsa_he = TRUE;
+ pinfo.mipi.hfp_power_stop = FALSE;
+ pinfo.mipi.hbp_power_stop = FALSE;
+ pinfo.mipi.hsa_power_stop = FALSE;
+ pinfo.mipi.eof_bllp_power_stop = TRUE;
+ pinfo.mipi.bllp_power_stop = TRUE;
+ pinfo.mipi.traffic_mode = DSI_NON_BURST_SYNCH_PULSE;
+ pinfo.mipi.dst_format = DSI_VIDEO_DST_FORMAT_RGB888;
+ pinfo.mipi.vc = 0;
+ pinfo.mipi.rgb_swap = DSI_RGB_SWAP_BGR;
+ pinfo.mipi.data_lane0 = TRUE;
+ pinfo.mipi.data_lane1 = TRUE;
+ pinfo.mipi.data_lane2 = TRUE;
+ pinfo.mipi.data_lane3 = TRUE;
+ pinfo.mipi.tx_eot_append = TRUE;
+ pinfo.mipi.t_clk_post = 0x04;
+ pinfo.mipi.t_clk_pre = 0x1c;
+ pinfo.mipi.stream = 0; /* dma_p */
+ pinfo.mipi.mdp_trigger = DSI_CMD_TRIGGER_SW;
+ pinfo.mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
+ pinfo.mipi.frame_rate = 60;
+ pinfo.mipi.dsi_phy_db = &dsi_video_mode_phy_db;
+
+ ret = mipi_toshiba_device_register(&pinfo, MIPI_DSI_PRIM,
+ MIPI_DSI_PANEL_WUXGA);
+ if (ret)
+ printk(KERN_ERR "%s: failed to register device!\n", __func__);
+
+ return ret;
+}
+
+module_init(mipi_video_toshiba_wuxga_init);
diff --git a/drivers/video/msm/mipi_truly_video_wvga_pt.c b/drivers/video/msm/mipi_truly_video_wvga_pt.c
index 931c564..03ef32b 100644
--- a/drivers/video/msm/mipi_truly_video_wvga_pt.c
+++ b/drivers/video/msm/mipi_truly_video_wvga_pt.c
@@ -38,10 +38,8 @@
{
int ret;
-#ifdef CONFIG_FB_MSM_MIPI_PANEL_DETECT
if (msm_fb_detect_client("mipi_video_truly_wvga"))
return 0;
-#endif
pinfo.xres = 480;
pinfo.yres = 800;
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
index 489e6d2..019acce 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/msm/msm_fb.c
@@ -606,6 +606,7 @@
return 0;
}
+#if (defined(CONFIG_SUSPEND) && defined(CONFIG_FB_MSM_HDMI_MSM_PANEL))
static int msm_fb_ext_suspend(struct device *dev)
{
struct msm_fb_data_type *mfd = dev_get_drvdata(dev);
@@ -635,13 +636,16 @@
return ret;
}
+#endif
static struct dev_pm_ops msm_fb_dev_pm_ops = {
.runtime_suspend = msm_fb_runtime_suspend,
.runtime_resume = msm_fb_runtime_resume,
.runtime_idle = msm_fb_runtime_idle,
+#if (defined(CONFIG_SUSPEND) && defined(CONFIG_FB_MSM_HDMI_MSM_PANEL))
.suspend = msm_fb_ext_suspend,
.resume = msm_fb_ext_resume,
+#endif
};
static struct platform_driver msm_fb_driver = {
@@ -969,6 +973,7 @@
struct fb_var_screeninfo *var;
int *id;
int fbram_offset;
+ int remainder, remainder_mode2;
/*
* fb info initialization
@@ -1105,15 +1110,28 @@
fix->line_length = msm_fb_line_length(mfd->index, panel_info->xres,
bpp);
+
+ /* Make sure all buffers can be addressed on a page boundary by an x
+ * and y offset */
+
+ remainder = (fix->line_length * panel_info->yres) % PAGE_SIZE;
+ if (!remainder)
+ remainder = PAGE_SIZE;
+ remainder_mode2 = (fix->line_length *
+ panel_info->mode2_yres) % PAGE_SIZE;
+ if (!remainder_mode2)
+ remainder_mode2 = PAGE_SIZE;
+
/* calculate smem_len based on max size of two supplied modes */
- fix->smem_len = roundup(MAX(msm_fb_line_length(mfd->index,
- panel_info->xres,
- bpp) *
- panel_info->yres * mfd->fb_page,
- msm_fb_line_length(mfd->index,
+ fix->smem_len = MAX((msm_fb_line_length(mfd->index, panel_info->xres,
+ bpp) *
+ panel_info->yres + PAGE_SIZE -
+ remainder) * mfd->fb_page,
+ (msm_fb_line_length(mfd->index,
panel_info->mode2_xres,
bpp) *
- panel_info->mode2_yres * mfd->fb_page), PAGE_SIZE);
+ panel_info->mode2_yres + PAGE_SIZE -
+ remainder_mode2) * mfd->fb_page);
diff --git a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
index f63ebcd..a5a8e57 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
+++ b/drivers/video/msm/vidc/1080p/ddl/vidc_hwio.h
@@ -24,8 +24,8 @@
#define VIDC_REG_IN(x...)
#endif
-#define __inpdw(port) (*((u32 *) (port)))
-#define __outpdw(port, val) (*((u32 *) (port)) = ((u32) (val)))
+#define __inpdw(port) __raw_readl(port)
+#define __outpdw(port, val) __raw_writel(val, port)
#define in_dword(addr) (__inpdw(addr))
#define in_dword_masked(addr, mask) (__inpdw(addr) & (mask))
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
index b300fbc..dee4da7 100644
--- a/drivers/video/msm/vidc/common/dec/vdec.c
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
@@ -2111,8 +2111,10 @@
struct video_client_ctx *client_ctx = file->private_data;
INFO("msm_vidc_dec: Inside %s()", __func__);
- res_trk_close_secure_session();
+ vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT);
+ vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT);
vid_dec_close_client(client_ctx);
+ res_trk_close_secure_session();
vidc_release_firmware();
#ifndef USE_RES_TRACKER
vidc_disable_clk();
@@ -2125,13 +2127,15 @@
{
struct video_client_ctx *client_ctx = file->private_data;
- DBG("msm_vidc_dec: Inside %s()", __func__);
+ INFO("msm_vidc_dec: Inside %s()", __func__);
+ vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_OUTPUT);
+ vidc_cleanup_addr_table(client_ctx, BUFFER_TYPE_INPUT);
vid_dec_close_client(client_ctx);
vidc_release_firmware();
#ifndef USE_RES_TRACKER
vidc_disable_clk();
#endif
- DBG("msm_vidc_dec: Return from %s()", __func__);
+ INFO("msm_vidc_dec: Return from %s()", __func__);
return 0;
}
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index cd3f954..f799a6c 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -384,6 +384,59 @@
}
EXPORT_SYMBOL(vidc_get_fd_info);
+void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx,
+ enum buffer_dir buffer)
+{
+ u32 *num_of_buffers = NULL;
+ u32 i = 0;
+ struct buf_addr_table *buf_addr_table;
+ if (buffer == BUFFER_TYPE_INPUT) {
+ buf_addr_table = client_ctx->input_buf_addr_table;
+ num_of_buffers = &client_ctx->num_of_input_buffers;
+ DBG("%s(): buffer = INPUT\n", __func__);
+
+ } else {
+ buf_addr_table = client_ctx->output_buf_addr_table;
+ num_of_buffers = &client_ctx->num_of_output_buffers;
+ DBG("%s(): buffer = OUTPUT\n", __func__);
+ }
+
+ if (!*num_of_buffers)
+ goto bail_out_cleanup;
+ if (!client_ctx->user_ion_client)
+ goto bail_out_cleanup;
+ for (i = 0; i < *num_of_buffers; ++i) {
+ if (buf_addr_table[i].client_data) {
+ msm_subsystem_unmap_buffer(
+ (struct msm_mapped_buffer *)
+ buf_addr_table[i].client_data);
+ buf_addr_table[i].client_data = NULL;
+ }
+ if (buf_addr_table[i].buff_ion_handle) {
+ ion_unmap_kernel(client_ctx->user_ion_client,
+ buf_addr_table[i].buff_ion_handle);
+ ion_free(client_ctx->user_ion_client,
+ buf_addr_table[i].buff_ion_handle);
+ buf_addr_table[i].buff_ion_handle = NULL;
+ }
+ }
+ if (client_ctx->vcd_h264_mv_buffer.client_data) {
+ msm_subsystem_unmap_buffer((struct msm_mapped_buffer *)
+ client_ctx->vcd_h264_mv_buffer.client_data);
+ client_ctx->vcd_h264_mv_buffer.client_data = NULL;
+ }
+ if (client_ctx->h264_mv_ion_handle) {
+ ion_unmap_kernel(client_ctx->user_ion_client,
+ client_ctx->h264_mv_ion_handle);
+ ion_free(client_ctx->user_ion_client,
+ client_ctx->h264_mv_ion_handle);
+ client_ctx->h264_mv_ion_handle = NULL;
+ }
+bail_out_cleanup:
+ return;
+}
+EXPORT_SYMBOL(vidc_cleanup_addr_table);
+
u32 vidc_lookup_addr_table(struct video_client_ctx *client_ctx,
enum buffer_dir buffer,
u32 search_with_user_vaddr,
@@ -540,9 +593,10 @@
client_ctx->user_ion_client,
buff_ion_handle,
ionflag);
- if (!(*kernel_vaddr)) {
+ if (IS_ERR_OR_NULL((void *)*kernel_vaddr)) {
ERR("%s():ION virtual addr fail\n",
__func__);
+ *kernel_vaddr = (unsigned long)NULL;
goto ion_error;
}
if (ion_phys(client_ctx->user_ion_client,
@@ -587,7 +641,7 @@
mutex_unlock(&client_ctx->enrty_queue_lock);
return true;
ion_error:
- if (*kernel_vaddr)
+ if (*kernel_vaddr && buff_ion_handle)
ion_unmap_kernel(client_ctx->user_ion_client, buff_ion_handle);
if (!IS_ERR_OR_NULL(buff_ion_handle))
ion_free(client_ctx->user_ion_client, buff_ion_handle);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.h b/drivers/video/msm/vidc/common/init/vidc_init.h
index ced99ff..a67329c 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.h
+++ b/drivers/video/msm/vidc/common/init/vidc_init.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010-2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -80,6 +80,8 @@
u32 vidc_delete_addr_table(struct video_client_ctx *client_ctx,
enum buffer_dir buffer, unsigned long user_vaddr,
unsigned long *kernel_vaddr);
+void vidc_cleanup_addr_table(struct video_client_ctx *client_ctx,
+ enum buffer_dir buffer);
u32 vidc_timer_create(void (*timer_handler)(void *),
void *user_data, void **timer_handle);
diff --git a/include/linux/fmem.h b/include/linux/fmem.h
index aebeec4..44b7005 100644
--- a/include/linux/fmem.h
+++ b/include/linux/fmem.h
@@ -20,7 +20,8 @@
struct fmem_platform_data {
unsigned long phys;
unsigned long size;
- unsigned long reserved_size;
+ unsigned long reserved_size_low;
+ unsigned long reserved_size_high;
};
struct fmem_data {
@@ -28,7 +29,8 @@
void *virt;
struct vm_struct *area;
unsigned long size;
- unsigned long reserved_size;
+ unsigned long reserved_size_low;
+ unsigned long reserved_size_high;
};
enum fmem_state {
diff --git a/include/linux/ion.h b/include/linux/ion.h
index ade87e6..3256fba 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -64,12 +64,12 @@
enum ion_heap_ids {
INVALID_HEAP_ID = -1,
- ION_IOMMU_HEAP_ID = 4,
ION_CP_MM_HEAP_ID = 8,
ION_CP_MFC_HEAP_ID = 12,
ION_CP_WB_HEAP_ID = 16, /* 8660 only */
ION_CAMERA_HEAP_ID = 20, /* 8660 only */
ION_SF_HEAP_ID = 24,
+ ION_IOMMU_HEAP_ID = 25,
ION_QSECOM_HEAP_ID = 27,
ION_AUDIO_HEAP_ID = 28,
@@ -160,6 +160,8 @@
* of this heap in the case of a shared heap.
* @reusable Flag indicating whether this heap is reusable of not.
* (see FMEM)
+ * @mem_is_fmem Flag indicating whether this memory is coming from fmem
+ * or not.
* @virt_addr: Virtual address used when using fmem.
* @request_region: function to be called when the number of allocations
* goes from 0 -> 1
@@ -174,6 +176,7 @@
ion_phys_addr_t secure_base; /* Base addr used when heap is shared */
size_t secure_size; /* Size used for securing heap when heap is shared*/
int reusable;
+ int mem_is_fmem;
ion_virt_addr_t *virt_addr;
int (*request_region)(void *);
int (*release_region)(void *);
@@ -184,6 +187,8 @@
* struct ion_co_heap_pdata - defines a carveout heap in the given platform
* @adjacent_mem_id: Id of heap that this heap must be adjacent to.
* @align: Alignment requirement for the memory
+ * @mem_is_fmem Flag indicating whether this memory is coming from fmem
+ * or not.
* @request_region: function to be called when the number of allocations
* goes from 0 -> 1
* @release_region: function to be called when the number of allocations
@@ -194,6 +199,7 @@
struct ion_co_heap_pdata {
int adjacent_mem_id;
unsigned int align;
+ int mem_is_fmem;
int (*request_region)(void *);
int (*release_region)(void *);
void *(*setup_region)(void);
diff --git a/include/linux/mfd/pm8xxx/misc.h b/include/linux/mfd/pm8xxx/misc.h
index c4f601b..c90d8d1 100644
--- a/include/linux/mfd/pm8xxx/misc.h
+++ b/include/linux/mfd/pm8xxx/misc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -73,6 +73,22 @@
PM8XXX_RESTART_ON_HARD_RESET,
};
+enum pm8xxx_aux_clk_id {
+ CLK_MP3_1,
+ CLK_MP3_2,
+};
+
+enum pm8xxx_aux_clk_div {
+ X0_DIV_NONE,
+ XO_DIV_1,
+ XO_DIV_2,
+ XO_DIV_4,
+ XO_DIV_8,
+ XO_DIV_16,
+ XO_DIV_32,
+ XO_DIV_64,
+};
+
#if defined(CONFIG_MFD_PM8XXX_MISC) || defined(CONFIG_MFD_PM8XXX_MISC_MODULE)
/**
@@ -181,6 +197,19 @@
*/
int pm8xxx_usb_id_pullup(int enable);
+/**
+ * pm8xxx_aux_clk_control - Control an auxiliary clock
+ * @clk_id: ID of clock to be programmed, registers of XO_CNTRL2
+ * @divider: divisor to use when configuring desired clock
+ * @enable: enable (1) the designated clock with the supplied division,
+ * or disable (0) the designated clock
+ *
+ * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
+ */
+int pm8xxx_aux_clk_control(enum pm8xxx_aux_clk_id clk_id,
+ enum pm8xxx_aux_clk_div divider,
+ bool enable);
+
#else
static inline int pm8xxx_reset_pwr_off(int reset)
@@ -225,6 +254,12 @@
{
return -ENODEV;
}
+static inline int pm8xxx_aux_clk_control(enum pm8xxx_aux_clk_id clk_id,
+ enum pm8xxx_aux_clk_div divider, bool enable)
+{
+ return -ENODEV;
+}
+
#endif
#endif
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 18997d7..cb394e8 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -436,6 +436,15 @@
__attribute__((aligned(sizeof(kernel_ulong_t))));
};
+#define SPMI_NAME_SIZE 32
+#define SPMI_MODULE_PREFIX "spmi:"
+
+struct spmi_device_id {
+ char name[SPMI_NAME_SIZE];
+ kernel_ulong_t driver_data /* Data private to the driver */
+ __attribute__((aligned(sizeof(kernel_ulong_t))));
+};
+
/* dmi */
enum dmi_field {
DMI_NONE,
diff --git a/include/linux/msm_kgsl.h b/include/linux/msm_kgsl.h
index 9eb6dda..37b9d35 100644
--- a/include/linux/msm_kgsl.h
+++ b/include/linux/msm_kgsl.h
@@ -148,6 +148,7 @@
unsigned int idle_timeout;
unsigned int nap_allowed;
unsigned int clk_map;
+ unsigned int idle_needed;
struct msm_bus_scale_pdata *bus_scale_table;
const char *iommu_user_ctx_name;
const char *iommu_priv_ctx_name;
diff --git a/include/linux/msm_tsens.h b/include/linux/msm_tsens.h
index 189548c..99b5acd 100644
--- a/include/linux/msm_tsens.h
+++ b/include/linux/msm_tsens.h
@@ -22,14 +22,15 @@
MSM_8660 = 0,
MSM_8960,
MSM_9615,
+ APQ_8064,
MSM_TYPE
};
struct tsens_platform_data {
- int slope;
int tsens_factor;
uint32_t tsens_num_sensor;
enum platform_type hw_type;
+ int slope[11];
};
struct tsens_device {
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 3a6f037..cf58d27 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -49,6 +49,8 @@
struct mtd_info;
+void part_fill_badblockstats(struct mtd_info *mtd);
+
/*
* Functions dealing with the various ways of partitioning the space
*/
diff --git a/include/linux/spmi.h b/include/linux/spmi.h
new file mode 100644
index 0000000..ffcb24e
--- /dev/null
+++ b/include/linux/spmi.h
@@ -0,0 +1,408 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _LINUX_SPMI_H
+#define _LINUX_SPMI_H
+
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/mod_devicetable.h>
+
+/* Maximum slave identifier */
+#define SPMI_MAX_SLAVE_ID 16
+
+/* SPMI Commands */
+enum spmi_commands {
+ SPMI_CMD_EXT_WRITE = 0x00,
+ SPMI_CMD_RESET = 0x10,
+ SPMI_CMD_SLEEP = 0x11,
+ SPMI_CMD_SHUTDOWN = 0x12,
+ SPMI_CMD_WAKEUP = 0x13,
+ SPMI_CMD_AUTHENTICATE = 0x14,
+ SPMI_CMD_MSTR_READ = 0x15,
+ SPMI_CMD_MSTR_WRITE = 0x16,
+ SPMI_CMD_TRANSFER_BUS_OWNERSHIP = 0x1A,
+ SPMI_CMD_DDB_MASTER_READ = 0x1B,
+ SPMI_CMD_DDB_SLAVE_READ = 0x1C,
+ SPMI_CMD_EXT_READ = 0x20,
+ SPMI_CMD_EXT_WRITEL = 0x30,
+ SPMI_CMD_EXT_READL = 0x38,
+ SPMI_CMD_WRITE = 0x40,
+ SPMI_CMD_READ = 0x60,
+ SPMI_CMD_ZERO_WRITE = 0x80,
+};
+
+struct spmi_device;
+
+/**
+ * struct spmi_controller: interface to the SPMI master controller
+ * @nr: board-specific number identifier for this controller/bus
+ * @name: name for this controller
+ * @cmd: sends a non-data command sequence on the SPMI bus.
+ * @read_cmd: sends a register read command sequence on the SPMI bus.
+ * @write_cmd: sends a register write command sequence on the SPMI bus.
+ */
+struct spmi_controller {
+ struct device dev;
+ unsigned int nr;
+ struct list_head list;
+ int (*cmd)(struct spmi_controller *, u8 opcode, u8 sid);
+ int (*read_cmd)(struct spmi_controller *,
+ u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf);
+ int (*write_cmd)(struct spmi_controller *,
+ u8 opcode, u8 sid, u16 addr, u8 bc, u8 *buf);
+};
+#define to_spmi_controller(d) container_of(d, struct spmi_controller, dev)
+
+/**
+ * struct spmi_driver: Manage SPMI generic/slave device driver
+ * @probe: binds this driver to a SPMI device.
+ * @remove: unbinds this driver from the SPMI device.
+ * @shutdown: standard shutdown callback used during powerdown/halt.
+ * @suspend: standard suspend callback used during system suspend
+ * @resume: standard resume callback used during system resume
+ * @driver: SPMI device drivers should initialize name and owner field of
+ * this structure
+ * @id_table: list of SPMI devices supported by this driver
+ */
+struct spmi_driver {
+ int (*probe)(struct spmi_device *dev);
+ int (*remove)(struct spmi_device *dev);
+ void (*shutdown)(struct spmi_device *dev);
+ int (*suspend)(struct spmi_device *dev,
+ pm_message_t pmesg);
+ int (*resume)(struct spmi_device *dev);
+
+ struct device_driver driver;
+ const struct spmi_device_id *id_table;
+};
+#define to_spmi_driver(d) container_of(d, struct spmi_driver, driver)
+
+/**
+ * Client/device handle (struct spmi_device):
+ * ------------------------------------------
+ * This is the client/device handle returned when a SPMI device
+ * is registered with a controller.
+ * Pointer to this structure is used by client-driver as a handle.
+ * @dev: driver model representation of the device.
+ * @name: name of driver to use with this device.
+ * @ctrl: SPMI controller managing the bus hosting this device.
+ * @resource: array of resources for this device_node
+ * @num_resources: number of resources for this device node
+ * @sid: slave identifier.
+ */
+struct spmi_device {
+ struct device dev;
+ const char *name;
+ struct spmi_controller *ctrl;
+ struct resource *resource;
+ u32 num_resources;
+ u8 sid;
+};
+#define to_spmi_device(d) container_of(d, struct spmi_device, dev)
+
+/**
+ * struct spmi_boardinfo: Declare board info for SPMI device bringup.
+ * @slave_id: slave identifier.
+ * @spmi_device: device to be registered with the SPMI framework.
+ * @of_node: pointer to the OpenFirmware device node.
+ * @num_resources: number of resources for this device node
+ * @resource: array of resources for this device_node
+ * @platform_data: goes to spmi_device.dev.platform_data
+ */
+struct spmi_boardinfo {
+ char name[SPMI_NAME_SIZE];
+ uint8_t slave_id;
+ struct device_node *of_node;
+ u32 num_resources;
+ struct resource *resource;
+ const void *platform_data;
+};
+
+/**
+ * spmi_driver_register: Client driver registration with SPMI framework.
+ * @drv: client driver to be associated with client-device.
+ *
+ * This API will register the client driver with the SPMI framework.
+ * It is called from the driver's module-init function.
+ */
+extern int spmi_driver_register(struct spmi_driver *drv);
+
+/**
+ * spmi_driver_unregister - reverse effect of spmi_driver_register
+ * @sdrv: the driver to unregister
+ * Context: can sleep
+ */
+static inline void spmi_driver_unregister(struct spmi_driver *sdrv)
+{
+ if (sdrv)
+ driver_unregister(&sdrv->driver);
+}
+
+/**
+ * spmi_add_controller: Controller bring-up.
+ * @ctrl: controller to be registered.
+ *
+ * A controller is registered with the framework using this API. ctrl->nr is the
+ * desired number with which SPMI framework registers the controller.
+ * Function will return -EBUSY if the number is in use.
+ */
+extern int spmi_add_controller(struct spmi_controller *ctrl);
+
+/**
+ * spmi_del_controller: Controller tear-down.
+ * Controller added with the above API is teared down using this API.
+ */
+extern int spmi_del_controller(struct spmi_controller *ctrl);
+
+/**
+ * spmi_busnum_to_ctrl: Map bus number to controller
+ * @busnum: bus number
+ *
+ * Returns controller device representing this bus number
+ */
+extern struct spmi_controller *spmi_busnum_to_ctrl(u32 bus_num);
+
+/**
+ * spmi_alloc_device: Allocate a new SPMI devices.
+ * @ctrl: controller to which this device is to be added to.
+ * Context: can sleep
+ *
+ * Allows a driver to allocate and initialize a SPMI device without
+ * registering it immediately. This allows a driver to directly fill
+ * the spmi_device structure before calling spmi_add_device().
+ *
+ * Caller is responsible to call spmi_add_device() on the returned
+ * spmi_device. If the caller needs to discard the spmi_device without
+ * adding it, then spmi_dev_put() should be called.
+ */
+extern struct spmi_device *spmi_alloc_device(struct spmi_controller *ctrl);
+
+/**
+ * spmi_add_device: Add spmi_device allocated with spmi_alloc_device().
+ * @spmi_dev: spmi_device to be added (registered).
+ */
+extern int spmi_add_device(struct spmi_device *spmi_dev);
+
+/**
+ * spmi_new_device: Instantiates a new SPMI device
+ * @ctrl: controller to which this device is to be added to.
+ * @info: board information for this device.
+ *
+ * Returns the new device or NULL.
+ */
+extern struct spmi_device *spmi_new_device(struct spmi_controller *ctrl,
+ struct spmi_boardinfo const *info);
+
+/* spmi_remove_device: Remove the effect of spmi_add_device() */
+extern void spmi_remove_device(struct spmi_device *spmi_dev);
+
+#ifdef CONFIG_SPMI
+/**
+ * spmi_register_board_info: Board-initialization routine.
+ * @bus_num: controller number (bus) on which this device will sit.
+ * @info: list of all devices on all controllers present on the board.
+ * @n: number of entries.
+ *
+ * API enumerates respective devices on corresponding controller.
+ * Called from board-init function.
+ */
+extern int spmi_register_board_info(int busnum,
+ struct spmi_boardinfo const *info, unsigned n);
+#else
+static inline int spmi_register_board_info(int busnum,
+ struct spmi_boardinfo const *info, unsigned n)
+{
+ return 0;
+}
+#endif
+
+static inline void *spmi_get_ctrldata(const struct spmi_controller *ctrl)
+{
+ return dev_get_drvdata(&ctrl->dev);
+}
+
+static inline void spmi_set_ctrldata(struct spmi_controller *ctrl, void *data)
+{
+ dev_set_drvdata(&ctrl->dev, data);
+}
+
+static inline void *spmi_get_devicedata(const struct spmi_device *dev)
+{
+ return dev_get_drvdata(&dev->dev);
+}
+
+static inline void spmi_set_devicedata(struct spmi_device *dev, void *data)
+{
+ dev_set_drvdata(&dev->dev, data);
+}
+
+static inline void spmi_dev_put(struct spmi_device *spmidev)
+{
+ if (spmidev)
+ put_device(&spmidev->dev);
+}
+
+/**
+ * spmi_register_read() - register read
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @ad: slave register address (5-bit address).
+ * @buf: buffer to be populated with data from the Slave.
+ *
+ * Reads 1 byte of data from a Slave device register.
+ */
+extern int spmi_register_read(struct spmi_controller *ctrl,
+ u8 sid, u8 ad, u8 *buf);
+
+/**
+ * spmi_ext_register_read() - extended register read
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @ad: slave register address (8-bit address).
+ * @len: the request number of bytes to read (up to 16 bytes).
+ * @buf: buffer to be populated with data from the Slave.
+ *
+ * Reads up to 16 bytes of data from the extended register space on a
+ * Slave device.
+ */
+extern int spmi_ext_register_read(struct spmi_controller *ctrl,
+ u8 sid, u8 ad, u8 *buf, int len);
+
+/**
+ * spmi_ext_register_readl() - extended register read long
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @ad: slave register address (16-bit address).
+ * @len: the request number of bytes to read (up to 8 bytes).
+ * @buf: buffer to be populated with data from the Slave.
+ *
+ * Reads up to 8 bytes of data from the extended register space on a
+ * Slave device using 16-bit address.
+ */
+extern int spmi_ext_register_readl(struct spmi_controller *ctrl,
+ u8 sid, u16 ad, u8 *buf, int len);
+
+/**
+ * spmi_register_write() - register write
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @ad: slave register address (5-bit address).
+ * @buf: buffer containing the data to be transferred to the Slave.
+ *
+ * Writes 1 byte of data to a Slave device register.
+ */
+extern int spmi_register_write(struct spmi_controller *ctrl,
+ u8 sid, u8 ad, u8 *buf);
+
+/**
+ * spmi_register_zero_write() - register zero write
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @data: the data to be written to register 0 (7-bits).
+ *
+ * Writes data to register 0 of the Slave device.
+ */
+extern int spmi_register_zero_write(struct spmi_controller *ctrl,
+ u8 sid, u8 data);
+
+/**
+ * spmi_ext_register_write() - extended register write
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @ad: slave register address (8-bit address).
+ * @buf: buffer containing the data to be transferred to the Slave.
+ * @len: the request number of bytes to read (up to 16 bytes).
+ *
+ * Writes up to 16 bytes of data to the extended register space of a
+ * Slave device.
+ */
+extern int spmi_ext_register_write(struct spmi_controller *ctrl,
+ u8 sid, u8 ad, u8 *buf, int len);
+
+/**
+ * spmi_ext_register_writel() - extended register write long
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ * @ad: slave register address (16-bit address).
+ * @buf: buffer containing the data to be transferred to the Slave.
+ * @len: the request number of bytes to read (up to 8 bytes).
+ *
+ * Writes up to 8 bytes of data to the extended register space of a
+ * Slave device using 16-bit address.
+ */
+extern int spmi_ext_register_writel(struct spmi_controller *ctrl,
+ u8 sid, u16 ad, u8 *buf, int len);
+
+/**
+ * spmi_command_reset() - sends RESET command to the specified slave
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ *
+ * The Reset command initializes the Slave and forces all registers to
+ * their reset values. The Slave shall enter the STARTUP state after
+ * receiving a Reset command.
+ *
+ * Returns
+ * -EINVAL for invalid slave identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+extern int spmi_command_reset(struct spmi_controller *ctrl, u8 sid);
+
+/**
+ * spmi_command_sleep() - sends SLEEP command to the specified slave
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ *
+ * The Sleep command causes the Slave to enter the user defined SLEEP state.
+ *
+ * Returns
+ * -EINVAL for invalid slave identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+extern int spmi_command_sleep(struct spmi_controller *ctrl, u8 sid);
+
+/**
+ * spmi_command_wakeup() - sends WAKEUP command to the specified slave
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ *
+ * The Wakeup command causes the Slave to move from the SLEEP state to
+ * the ACTIVE state.
+ *
+ * Returns
+ * -EINVAL for invalid slave identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+extern int spmi_command_wakeup(struct spmi_controller *ctrl, u8 sid);
+
+/**
+ * spmi_command_shutdown() - sends SHUTDOWN command to the specified slave
+ * @ctrl: SPMI controller.
+ * @sid: slave identifier.
+ *
+ * The Shutdown command causes the Slave to enter the SHUTDOWN state.
+ *
+ * Returns
+ * -EINVAL for invalid slave identifier.
+ * -EPERM if the SPMI transaction is denied due to permission issues.
+ * -EIO if the SPMI transaction fails (parity errors, etc).
+ * -ETIMEDOUT if the SPMI transaction times out.
+ */
+extern int spmi_command_shutdown(struct spmi_controller *ctrl, u8 sid);
+#endif
diff --git a/include/media/msm_camera.h b/include/media/msm_camera.h
index 1a6f68f..e0a04dc 100644
--- a/include/media/msm_camera.h
+++ b/include/media/msm_camera.h
@@ -184,10 +184,10 @@
_IOW(MSM_CAM_IOCTL_MAGIC, 51, uint32_t *)
#define MSM_CAM_IOCTL_GET_MCTL_INFO \
- _IOR(MSM_CAM_IOCTL_MAGIC, 51, struct msm_mctl_node_info *)
+ _IOR(MSM_CAM_IOCTL_MAGIC, 52, struct msm_mctl_node_info *)
#define MSM_CAM_IOCTL_MCTL_DIVERT_DONE \
- _IOR(MSM_CAM_IOCTL_MAGIC, 52, struct msm_cam_evt_divert_frame *)
+ _IOR(MSM_CAM_IOCTL_MAGIC, 53, struct msm_cam_evt_divert_frame *)
struct msm_mctl_pp_cmd {
int32_t id;
@@ -765,8 +765,16 @@
#define CFG_GET_OUTPUT_INFO 32
#define CFG_GET_EEPROM_DATA 33
#define CFG_SET_ACTUATOR_INFO 34
-#define CFG_GET_ACTUATOR_INFO 35
-#define CFG_MAX 36
+#define CFG_GET_ACTUATOR_INFO 35
+/* TBD: QRD */
+#define CFG_SET_SATURATION 36
+#define CFG_SET_SHARPNESS 37
+#define CFG_SET_TOUCHAEC 38
+#define CFG_SET_AUTO_FOCUS 39
+#define CFG_SET_AUTOFLASH 40
+#define CFG_SET_EXPOSURE_COMPENSATION 41
+#define CFG_SET_ISO 42
+#define CFG_MAX 43
#define MOVE_NEAR 0
@@ -857,14 +865,6 @@
#define CAMERA_SETAE_AVERAGE 0
#define CAMERA_SETAE_CENWEIGHT 1
-#define CFG_SET_SATURATION 30
-#define CFG_SET_SHARPNESS 31
-#define CFG_SET_TOUCHAEC 32
-#define CFG_SET_AUTO_FOCUS 33
-#define CFG_SET_AUTOFLASH 34
-/* QRD */
-#define CFG_SET_EXPOSURE_COMPENSATION 35
-
#define CAMERA_WB_AUTO 1 /* This list must match aeecamera.h */
#define CAMERA_WB_CUSTOM 2
#define CAMERA_WB_INCANDESCENT 3
@@ -948,6 +948,14 @@
MSM_V4L2_POWER_LINE_AUTO,
};
+#define CAMERA_ISO_TYPE_AUTO 0
+#define CAMEAR_ISO_TYPE_HJR 1
+#define CAMEAR_ISO_TYPE_100 2
+#define CAMERA_ISO_TYPE_200 3
+#define CAMERA_ISO_TYPE_400 4
+#define CAMEAR_ISO_TYPE_800 5
+#define CAMERA_ISO_TYPE_1600 6
+
struct sensor_pict_fps {
uint16_t prevfps;
uint16_t pictfps;
@@ -1083,6 +1091,7 @@
uint16_t pictp_pl;
uint32_t pict_max_exp_lc;
uint16_t p_fps;
+ uint8_t iso_type;
struct sensor_init_cfg init_info;
struct sensor_pict_fps gfps;
struct exp_gain_cfg exp_gain;
diff --git a/include/media/radio-iris.h b/include/media/radio-iris.h
index 36139ba..34a21bd 100644
--- a/include/media/radio-iris.h
+++ b/include/media/radio-iris.h
@@ -590,7 +590,8 @@
IRIS_EVT_NEW_SRCH_LIST,
IRIS_EVT_NEW_AF_LIST,
IRIS_EVT_TXRDSDAT,
- IRIS_EVT_TXRDSDONE
+ IRIS_EVT_TXRDSDONE,
+ IRIS_EVT_RADIO_DISABLED
};
enum emphasis_type {
FM_RX_EMP75 = 0x0,
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 8e66a25..164d3b4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -931,7 +931,7 @@
if (conn->sec_level == BT_SECURITY_SDP)
conn->sec_level = BT_SECURITY_LOW;
- if (conn->pending_sec_level > conn->sec_level)
+ if (!status && encrypt && conn->pending_sec_level > conn->sec_level)
conn->sec_level = conn->pending_sec_level;
hci_proto_encrypt_cfm(conn, status, encrypt);
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 312de3f..d5c4189 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -489,6 +489,7 @@
__u8 fixed_channel;
__u8 num_conf_req;
__u8 num_conf_rsp;
+ __u8 incoming;
__u8 fcs;
__u8 sec_level;
@@ -648,6 +649,8 @@
#define L2CAP_AMP_STATE_RESEGMENT 12
#define L2CAP_ATT_ERROR 0x01
+#define L2CAP_ATT_MTU_REQ 0x02
+#define L2CAP_ATT_MTU_RSP 0x03
#define L2CAP_ATT_RESPONSE_BIT 0x01
#define L2CAP_ATT_INDICATE 0x1D
#define L2CAP_ATT_NOT_SUPPORTED 0x06
@@ -689,6 +692,8 @@
void l2cap_sock_init(struct sock *sk, struct sock *parent);
struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
int proto, gfp_t prio);
+struct sock *l2cap_find_sock_by_fixed_cid_and_dir(__le16 cid, bdaddr_t *src,
+ bdaddr_t *dst, int server);
void l2cap_send_disconn_req(struct l2cap_conn *conn, struct sock *sk, int err);
void l2cap_chan_del(struct sock *sk, int err);
int l2cap_do_connect(struct sock *sk);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 47bfde5..4c2bd37 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -561,6 +561,19 @@
goto done;
}
+ if (!skb_queue_empty(&hdev->cmd_q)) {
+ BT_ERR("command queue is not empty, purging");
+ skb_queue_purge(&hdev->cmd_q);
+ }
+ if (!skb_queue_empty(&hdev->rx_q)) {
+ BT_ERR("rx queue is not empty, purging");
+ skb_queue_purge(&hdev->rx_q);
+ }
+ if (!skb_queue_empty(&hdev->raw_q)) {
+ BT_ERR("raw queue is not empty, purging");
+ skb_queue_purge(&hdev->raw_q);
+ }
+
if (!test_bit(HCI_RAW, &hdev->flags)) {
atomic_set(&hdev->cmd_cnt, 1);
set_bit(HCI_INIT, &hdev->flags);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b4dde4c..9662795 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -930,18 +930,24 @@
}
/* Find socket with fixed cid with given source and destination bdaddrs.
- * Returns closest match, locked.
+ * Direction of the req/rsp must match.
*/
-static struct sock *l2cap_get_sock_by_fixed_scid(int state,
- __le16 cid, bdaddr_t *src, bdaddr_t *dst)
+struct sock *l2cap_find_sock_by_fixed_cid_and_dir(__le16 cid, bdaddr_t *src,
+ bdaddr_t *dst, int incoming)
{
struct sock *sk = NULL, *sk1 = NULL;
struct hlist_node *node;
+ BT_DBG(" %d", incoming);
+
read_lock(&l2cap_sk_list.lock);
sk_for_each(sk, node, &l2cap_sk_list.head) {
- if (state && sk->sk_state != state)
+
+ if (incoming && !l2cap_pi(sk)->incoming)
+ continue;
+
+ if (!incoming && l2cap_pi(sk)->incoming)
continue;
if (l2cap_pi(sk)->scid == cid && !bacmp(&bt_sk(sk)->dst, dst)) {
@@ -1022,13 +1028,12 @@
l2cap_sock_init(sk, parent);
bacpy(&bt_sk(sk)->src, conn->src);
bacpy(&bt_sk(sk)->dst, conn->dst);
+ l2cap_pi(sk)->incoming = 1;
bt_accept_enqueue(parent, sk);
__l2cap_chan_add(conn, sk);
- l2cap_sock_set_timer(sk, sk->sk_sndtimeo);
-
sk->sk_state = BT_CONNECTED;
parent->sk_data_ready(parent, 0);
@@ -1061,10 +1066,10 @@
if (pending_sec > sec_level)
sec_level = pending_sec;
- if (smp_conn_security(conn, sec_level)) {
+ if (smp_conn_security(conn, sec_level))
l2cap_chan_ready(sk);
- hci_conn_put(conn->hcon);
- }
+
+ hci_conn_put(conn->hcon);
} else if (sk->sk_type != SOCK_SEQPACKET &&
sk->sk_type != SOCK_STREAM) {
@@ -1081,6 +1086,9 @@
}
read_unlock(&l->lock);
+
+ if (conn->hcon->out && conn->hcon->type == LE_LINK)
+ l2cap_le_conn_ready(conn);
}
/* Notify sockets that we cannot guaranty reliability anymore */
@@ -3035,7 +3043,8 @@
{
lock_sock(sk);
- if (l2cap_pi(sk)->mode != L2CAP_MODE_ERTM) {
+ if (l2cap_pi(sk)->mode != L2CAP_MODE_ERTM ||
+ sk->sk_state != BT_CONNECTED) {
release_sock(sk);
return;
}
@@ -7209,15 +7218,24 @@
return 0;
}
-static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid, struct sk_buff *skb)
+static inline int l2cap_att_channel(struct l2cap_conn *conn, __le16 cid,
+ struct sk_buff *skb)
{
struct sock *sk;
struct sk_buff *skb_rsp;
struct l2cap_hdr *lh;
+ int dir;
+ u8 mtu_rsp[] = {L2CAP_ATT_MTU_RSP, 23, 0};
u8 err_rsp[] = {L2CAP_ATT_ERROR, 0x00, 0x00, 0x00,
L2CAP_ATT_NOT_SUPPORTED};
- sk = l2cap_get_sock_by_fixed_scid(0, cid, conn->src, conn->dst);
+ dir = (skb->data[0] & L2CAP_ATT_RESPONSE_BIT) ? 0 : 1;
+
+ sk = l2cap_find_sock_by_fixed_cid_and_dir(cid, conn->src,
+ conn->dst, dir);
+
+ BT_DBG("sk %p, dir:%d", sk, dir);
+
if (!sk)
goto drop;
@@ -7231,6 +7249,22 @@
if (l2cap_pi(sk)->imtu < skb->len)
goto drop;
+ if (skb->data[0] == L2CAP_ATT_MTU_REQ) {
+ skb_rsp = bt_skb_alloc(sizeof(mtu_rsp) + L2CAP_HDR_SIZE,
+ GFP_ATOMIC);
+ if (!skb_rsp)
+ goto drop;
+
+ lh = (struct l2cap_hdr *) skb_put(skb_rsp, L2CAP_HDR_SIZE);
+ lh->len = cpu_to_le16(sizeof(mtu_rsp));
+ lh->cid = cpu_to_le16(L2CAP_CID_LE_DATA);
+ memcpy(skb_put(skb_rsp, sizeof(mtu_rsp)), mtu_rsp,
+ sizeof(mtu_rsp));
+ hci_send_acl(conn->hcon, NULL, skb_rsp, 0);
+
+ goto free_skb;
+ }
+
if (!sock_queue_rcv_skb(sk, skb))
goto done;
@@ -7333,7 +7367,7 @@
struct hlist_node *node;
if (type != ACL_LINK)
- return -EINVAL;
+ return 0;
BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
@@ -7424,6 +7458,7 @@
struct l2cap_chan_list *l;
struct l2cap_conn *conn = hcon->l2cap_data;
struct sock *sk;
+ int smp = 0;
if (!conn)
return 0;
@@ -7445,9 +7480,7 @@
l2cap_chan_ready(sk);
}
- del_timer(&hcon->smp_timer);
- smp_link_encrypt_cmplt(conn, status, encrypt);
-
+ smp = 1;
bh_unlock_sock(sk);
continue;
}
@@ -7511,6 +7544,11 @@
read_unlock(&l->lock);
+ if (smp) {
+ del_timer(&hcon->smp_timer);
+ smp_link_encrypt_cmplt(conn, status, encrypt);
+ }
+
return 0;
}
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 94cacde..6a4a2f0 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -611,8 +611,16 @@
case L2CAP_MODE_BASIC:
l2cap_pi(sk)->conf_state &= ~L2CAP_CONF_STATE2_DEVICE;
break;
- case L2CAP_MODE_ERTM:
case L2CAP_MODE_STREAMING:
+ if (!disable_ertm) {
+ /* No fallback to ERTM or Basic mode */
+ l2cap_pi(sk)->conf_state |=
+ L2CAP_CONF_STATE2_DEVICE;
+ break;
+ }
+ err = -EINVAL;
+ break;
+ case L2CAP_MODE_ERTM:
if (!disable_ertm)
break;
/* fall through */
@@ -957,7 +965,8 @@
else
err = bt_sock_recvmsg(iocb, sock, msg, len, flags);
- l2cap_ertm_recv_done(sk);
+ if (err >= 0)
+ l2cap_ertm_recv_done(sk);
return err;
}
@@ -1096,6 +1105,7 @@
static int l2cap_sock_release(struct socket *sock)
{
struct sock *sk = sock->sk;
+ struct sock *srv_sk = NULL;
int err;
BT_DBG("sock %p, sk %p", sock, sk);
@@ -1103,6 +1113,16 @@
if (!sk)
return 0;
+ /* If this is an ATT Client socket, find the matching Server */
+ if (l2cap_pi(sk)->scid == L2CAP_CID_LE_DATA && !l2cap_pi(sk)->incoming)
+ srv_sk = l2cap_find_sock_by_fixed_cid_and_dir(L2CAP_CID_LE_DATA,
+ &bt_sk(sk)->src, &bt_sk(sk)->dst, 1);
+
+ /* If server socket found, request tear down */
+ BT_DBG("client:%p server:%p", sk, srv_sk);
+ if (srv_sk)
+ l2cap_sock_set_timer(srv_sk, 1);
+
err = l2cap_sock_shutdown(sock, 2);
sock_orphan(sk);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 2e4c47a..910ef77 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -762,7 +762,7 @@
struct list_head *p;
size_t name_len;
- name_len = strlen(hdev->dev_name);
+ name_len = strnlen(hdev->dev_name, HCI_MAX_EIR_LENGTH);
if (name_len > 0) {
/* EIR Data type */
@@ -890,13 +890,17 @@
list_add(&uuid->list, &hdev->uuids);
- err = update_class(hdev);
- if (err < 0)
- goto failed;
+ if (test_bit(HCI_UP, &hdev->flags)) {
- err = update_eir(hdev);
- if (err < 0)
- goto failed;
+ err = update_class(hdev);
+ if (err < 0)
+ goto failed;
+
+ err = update_eir(hdev);
+ if (err < 0)
+ goto failed;
+ } else
+ err = 0;
err = cmd_complete(sk, index, MGMT_OP_ADD_UUID, NULL, 0);
@@ -950,13 +954,16 @@
goto unlock;
}
- err = update_class(hdev);
- if (err < 0)
- goto unlock;
+ if (test_bit(HCI_UP, &hdev->flags)) {
+ err = update_class(hdev);
+ if (err < 0)
+ goto unlock;
- err = update_eir(hdev);
- if (err < 0)
- goto unlock;
+ err = update_eir(hdev);
+ if (err < 0)
+ goto unlock;
+ } else
+ err = 0;
err = cmd_complete(sk, index, MGMT_OP_REMOVE_UUID, NULL, 0);
@@ -991,7 +998,10 @@
hdev->major_class |= cp->major & MGMT_MAJOR_CLASS_MASK;
hdev->minor_class = cp->minor;
- err = update_class(hdev);
+ if (test_bit(HCI_UP, &hdev->flags))
+ err = update_class(hdev);
+ else
+ err = 0;
if (err == 0)
err = cmd_complete(sk, index, MGMT_OP_SET_DEV_CLASS, NULL, 0);
@@ -1027,9 +1037,12 @@
err = 0;
} else {
clear_bit(HCI_SERVICE_CACHE, &hdev->flags);
- err = update_class(hdev);
- if (err == 0)
- err = update_eir(hdev);
+ if (test_bit(HCI_UP, &hdev->flags)) {
+ err = update_class(hdev);
+ if (err == 0)
+ err = update_eir(hdev);
+ } else
+ err = 0;
}
if (err == 0)
@@ -1514,6 +1527,7 @@
}
pairing_complete(cmd, status);
+ hci_conn_put(conn);
}
static void pairing_security_complete_cb(struct hci_conn *conn, u8 status)
@@ -1936,12 +1950,14 @@
if (hdev->disco_state != SCAN_IDLE) {
struct hci_cp_le_set_scan_enable le_cp = {0, 0};
- if (hdev->disco_state == SCAN_LE)
- hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE,
+ if (test_bit(HCI_UP, &hdev->flags)) {
+ if (hdev->disco_state == SCAN_LE)
+ hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE,
sizeof(le_cp), &le_cp);
- else
- hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL);
-
+ else
+ hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0,
+ NULL);
+ }
hdev->disco_state = SCAN_IDLE;
}
@@ -1969,18 +1985,20 @@
hci_dev_lock_bh(hdev);
- if (hdev->disco_state == SCAN_LE)
- hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE,
- sizeof(le_cp), &le_cp);
+ if (test_bit(HCI_UP, &hdev->flags)) {
+ if (hdev->disco_state == SCAN_LE)
+ hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE,
+ sizeof(le_cp), &le_cp);
/* re-start BR scan */
- if (hdev->disco_state != SCAN_IDLE) {
- struct hci_cp_inquiry cp = {{0x33, 0x8b, 0x9e}, 4, 0};
- hdev->disco_int_phase *= 2;
- hdev->disco_int_count = 0;
- cp.num_rsp = (u8) hdev->disco_int_phase;
- hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
- hdev->disco_state = SCAN_BR;
+ if (hdev->disco_state != SCAN_IDLE) {
+ struct hci_cp_inquiry cp = {{0x33, 0x8b, 0x9e}, 4, 0};
+ hdev->disco_int_phase *= 2;
+ hdev->disco_int_count = 0;
+ cp.num_rsp = (u8) hdev->disco_int_phase;
+ hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp);
+ hdev->disco_state = SCAN_BR;
+ }
}
hci_dev_unlock_bh(hdev);
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 3b1e54c..99c4559 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -917,7 +917,7 @@
int lm = 0;
if (type != SCO_LINK && type != ESCO_LINK)
- return -EINVAL;
+ return 0;
BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index e301edf..2484a9a 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -652,6 +652,7 @@
static int smp_encrypt_link(struct hci_conn *hcon, struct link_key *key)
{
struct key_master_id *master;
+ u8 sec_level;
u8 zerobuf[8];
if (!hcon || !key || !key->data)
@@ -666,6 +667,17 @@
hcon->enc_key_size = key->pin_len;
hcon->sec_req = TRUE;
+ sec_level = authreq_to_seclevel(key->auth);
+
+ BT_DBG("cur %d, req: %d", hcon->sec_level, sec_level);
+
+ if (sec_level > hcon->sec_level)
+ hcon->pending_sec_level = sec_level;
+
+
+ if (!(hcon->link_mode & HCI_LM_ENCRYPT))
+ hci_conn_hold(hcon);
+
hci_le_start_enc(hcon, master->ediv, master->rand, key->val);
return 0;
@@ -690,11 +702,6 @@
if (smp_encrypt_link(hcon, key) < 0)
goto invalid_key;
- hcon->sec_level = authreq_to_seclevel(key->auth);
-
- if (!(hcon->link_mode & HCI_LM_ENCRYPT))
- hci_conn_hold(hcon);
-
return 0;
}
@@ -729,33 +736,26 @@
struct hci_conn *hcon = conn->hcon;
__u8 authreq;
- BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level);
+ BT_DBG("conn %p hcon %p %d req: %d",
+ conn, hcon, hcon->sec_level, sec_level);
- if (IS_ERR(hcon->hdev->tfm)) {
- BT_DBG("IS_ERR");
+ if (IS_ERR(hcon->hdev->tfm))
return 1;
- }
- if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend)) {
- BT_DBG("HCI_CONN_ENCRYPT_PEND");
+ if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
return -EINPROGRESS;
- }
- if (sec_level == BT_SECURITY_LOW) {
- BT_DBG("BT_SECURITY_LOW");
+ if (sec_level == BT_SECURITY_LOW)
return 1;
- }
- if (hcon->sec_level > sec_level) {
- BT_DBG("hcon->sec_level > sec_level");
+
+ if (hcon->sec_level >= sec_level)
return 1;
- }
authreq = seclevel_to_authreq(sec_level);
- BT_ERR("conn = %p, sec: %d", conn, sec_level);
hcon->smp_conn = conn;
- hcon->sec_level = sec_level;
+ hcon->pending_sec_level = sec_level;
if ((hcon->link_mode & HCI_LM_MASTER) && !hcon->sec_req) {
struct link_key *key;
@@ -785,6 +785,7 @@
msecs_to_jiffies(SMP_TIMEOUT));
smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
+ hci_conn_hold(hcon);
} else {
struct smp_cmd_security_req cp;
cp.auth_req = authreq;
@@ -792,7 +793,6 @@
}
done:
- hcon->pending_sec_level = sec_level;
set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
return 0;
@@ -1045,15 +1045,17 @@
clear_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
+ if (!status && encrypt && hcon->sec_level < hcon->pending_sec_level)
+ hcon->sec_level = hcon->pending_sec_level;
+
if (!status && encrypt && !hcon->sec_req)
- smp_distribute_keys(conn, 0);
+ return smp_distribute_keys(conn, 0);
/* Fall back to Pairing request if failed a Link Security request */
else if (hcon->sec_req && (status || !encrypt))
- smp_conn_security(conn, hcon->sec_level);
+ smp_conn_security(conn, hcon->pending_sec_level);
- else
- hci_conn_put(hcon);
+ hci_conn_put(hcon);
return 0;
}
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index ac7f050..46f6461 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -49,7 +49,8 @@
#define AIF1_PB 1
#define AIF1_CAP 2
-#define NUM_CODEC_DAIS 2
+#define AIF2_PB 3
+#define NUM_CODEC_DAIS 3
struct tabla_codec_dai_data {
u32 rate;
@@ -570,6 +571,8 @@
-84, 40, digital_gain),
SOC_SINGLE_S8_TLV("RX6 Digital Volume", TABLA_A_CDC_RX6_VOL_CTL_B2_CTL,
-84, 40, digital_gain),
+ SOC_SINGLE_S8_TLV("RX7 Digital Volume", TABLA_A_CDC_RX7_VOL_CTL_B2_CTL,
+ -84, 40, digital_gain),
SOC_SINGLE_S8_TLV("DEC1 Volume", TABLA_A_CDC_TX1_VOL_CTL_GAIN, -84, 40,
digital_gain),
@@ -2086,71 +2089,99 @@
{"RX1 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX1 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX1 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX1 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX1 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX1 MIX1 INP1", "IIR1", "IIR1"},
{"RX1 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX1 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX1 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX1 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX1 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX1 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX1 MIX1 INP2", "IIR1", "IIR1"},
{"RX2 MIX1 INP1", "RX1", "SLIM RX1"},
{"RX2 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX2 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX2 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX2 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX2 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX2 MIX1 INP1", "IIR1", "IIR1"},
{"RX2 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX2 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX2 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX2 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX2 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX2 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX2 MIX1 INP2", "IIR1", "IIR1"},
{"RX3 MIX1 INP1", "RX1", "SLIM RX1"},
{"RX3 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX3 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX3 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX3 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX3 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX3 MIX1 INP1", "IIR1", "IIR1"},
{"RX3 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX3 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX3 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX3 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX3 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX3 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX3 MIX1 INP2", "IIR1", "IIR1"},
{"RX4 MIX1 INP1", "RX1", "SLIM RX1"},
{"RX4 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX4 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX4 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX4 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX4 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX4 MIX1 INP1", "IIR1", "IIR1"},
{"RX4 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX4 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX4 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX4 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX4 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX4 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX4 MIX1 INP2", "IIR1", "IIR1"},
{"RX5 MIX1 INP1", "RX1", "SLIM RX1"},
{"RX5 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX5 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX5 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX5 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX5 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX5 MIX1 INP1", "IIR1", "IIR1"},
{"RX5 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX5 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX5 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX5 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX5 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX5 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX5 MIX1 INP2", "IIR1", "IIR1"},
{"RX6 MIX1 INP1", "RX1", "SLIM RX1"},
{"RX6 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX6 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX6 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX6 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX6 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX6 MIX1 INP1", "IIR1", "IIR1"},
{"RX6 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX6 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX6 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX6 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX6 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX6 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX6 MIX1 INP2", "IIR1", "IIR1"},
{"RX7 MIX1 INP1", "RX1", "SLIM RX1"},
{"RX7 MIX1 INP1", "RX2", "SLIM RX2"},
{"RX7 MIX1 INP1", "RX3", "SLIM RX3"},
{"RX7 MIX1 INP1", "RX4", "SLIM RX4"},
+ {"RX7 MIX1 INP1", "RX6", "SLIM RX6"},
+ {"RX7 MIX1 INP1", "RX7", "SLIM RX7"},
{"RX7 MIX1 INP1", "IIR1", "IIR1"},
{"RX7 MIX1 INP2", "RX1", "SLIM RX1"},
{"RX7 MIX1 INP2", "RX2", "SLIM RX2"},
{"RX7 MIX1 INP2", "RX3", "SLIM RX3"},
{"RX7 MIX1 INP2", "RX4", "SLIM RX4"},
+ {"RX7 MIX1 INP2", "RX6", "SLIM RX6"},
+ {"RX7 MIX1 INP2", "RX7", "SLIM RX7"},
{"RX7 MIX1 INP2", "IIR1", "IIR1"},
/* Decimator Inputs */
@@ -2633,7 +2664,7 @@
}
pr_debug("%s: DAI-ID %x %d %d\n", __func__, dai->id, tx_num, rx_num);
- if (dai->id == AIF1_PB) {
+ if (dai->id == AIF1_PB || dai->id == AIF2_PB) {
for (i = 0; i < rx_num; i++) {
tabla->dai[dai->id - 1].ch_num[i] = rx_slot[i];
tabla->dai[dai->id - 1].ch_act = 0;
@@ -2681,6 +2712,12 @@
tx_slot[cnt] = tx_ch[6 + cnt];
cnt++;
}
+ } else if (dai->id == AIF2_PB) {
+ *rx_num = tabla_dai[dai->id - 1].playback.channels_max;
+ while (cnt < *rx_num) {
+ rx_slot[cnt] = rx_ch[5 + cnt];
+ cnt++;
+ }
}
return 0;
}
@@ -2778,7 +2815,7 @@
* If current dai is a rx dai, set sample rate to
* all the rx paths that are currently not active
*/
- if (dai->id == AIF1_PB) {
+ if (dai->id == AIF1_PB || dai->id == AIF2_PB) {
rx_state = snd_soc_read(codec,
TABLA_A_CDC_CLK_RX_B1_CTL);
@@ -2858,6 +2895,20 @@
},
.ops = &tabla_dai_ops,
},
+ {
+ .name = "tabla_rx2",
+ .id = AIF2_PB,
+ .playback = {
+ .stream_name = "AIF2 Playback",
+ .rates = WCD9310_RATES,
+ .formats = TABLA_FORMATS,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ .channels_min = 1,
+ .channels_max = 2,
+ },
+ .ops = &tabla_dai_ops,
+ },
};
static struct snd_soc_dai_driver tabla_i2s_dai[] = {
@@ -2963,7 +3014,8 @@
switch (event) {
case SND_SOC_DAPM_POST_PMU:
for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
- if (tabla_dai[j].id == AIF1_PB)
+ if (tabla_dai[j].id == AIF1_PB ||
+ tabla_dai[j].id == AIF2_PB)
continue;
if (!strncmp(w->sname,
tabla_dai[j].capture.stream_name, 13)) {
@@ -2979,7 +3031,8 @@
break;
case SND_SOC_DAPM_POST_PMD:
for (j = 0; j < ARRAY_SIZE(tabla_dai); j++) {
- if (tabla_dai[j].id == AIF1_PB)
+ if (tabla_dai[j].id == AIF1_PB ||
+ tabla_dai[j].id == AIF2_PB)
continue;
if (!strncmp(w->sname,
tabla_dai[j].capture.stream_name, 13)) {
@@ -3022,6 +3075,13 @@
SND_SOC_DAPM_AIF_IN("SLIM RX3", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("SLIM RX4", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0),
+ SND_SOC_DAPM_AIF_IN_E("SLIM RX6", "AIF2 Playback", 0, SND_SOC_NOPM, 0,
+ 0, tabla_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+ SND_SOC_DAPM_AIF_IN_E("SLIM RX7", "AIF2 Playback", 0, SND_SOC_NOPM, 0,
+ 0, tabla_codec_enable_slimrx,
+ SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
+
/* Headphone */
SND_SOC_DAPM_OUTPUT("HEADPHONE"),
SND_SOC_DAPM_PGA_E("HPHL", TABLA_A_RX_HPH_CNP_EN, 5, 0, NULL, 0,
@@ -3789,19 +3849,15 @@
struct tabla_mbhc_general_cfg *generic;
struct tabla_mbhc_btn_detect_cfg *btn_det;
int n;
- u8 tabla_ver;
u8 *n_cic, *gain;
+ struct tabla *tabla_core = dev_get_drvdata(codec->dev->parent);
tabla = snd_soc_codec_get_drvdata(codec);
generic = TABLA_MBHC_CAL_GENERAL_PTR(tabla->calibration);
btn_det = TABLA_MBHC_CAL_BTN_DET_PTR(tabla->calibration);
- tabla_ver = snd_soc_read(codec, TABLA_A_CHIP_VERSION);
- tabla_ver &= 0x1F;
-
for (n = 0; n < 8; n++) {
- if ((tabla_ver != TABLA_VERSION_1_0 &&
- tabla_ver != TABLA_VERSION_1_1) || n != 7) {
+ if ((!TABLA_IS_1_X(tabla_core->version)) || n != 7) {
snd_soc_update_bits(codec,
TABLA_A_CDC_MBHC_FEATURE_B1_CFG,
0x07, n);
@@ -5043,6 +5099,9 @@
case AIF1_CAP:
ch_cnt = tabla_dai[i].capture.channels_max;
break;
+ case AIF2_PB:
+ ch_cnt = tabla_dai[i].playback.channels_max;
+ break;
default:
continue;
}
@@ -5197,13 +5256,32 @@
},
};
+static struct platform_driver tabla1x_codec_driver = {
+ .probe = tabla_probe,
+ .remove = tabla_remove,
+ .driver = {
+ .name = "tabla1x_codec",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &tabla_pm_ops,
+#endif
+ },
+};
+
static int __init tabla_codec_init(void)
{
- return platform_driver_register(&tabla_codec_driver);
+ int rtn = platform_driver_register(&tabla_codec_driver);
+ if (rtn == 0) {
+ rtn = platform_driver_register(&tabla1x_codec_driver);
+ if (rtn != 0)
+ platform_driver_unregister(&tabla_codec_driver);
+ }
+ return rtn;
}
static void __exit tabla_codec_exit(void)
{
+ platform_driver_unregister(&tabla1x_codec_driver);
platform_driver_unregister(&tabla_codec_driver);
}
diff --git a/sound/soc/msm/Makefile b/sound/soc/msm/Makefile
index 1b3014e..6f2d651 100644
--- a/sound/soc/msm/Makefile
+++ b/sound/soc/msm/Makefile
@@ -56,7 +56,7 @@
obj-$(CONFIG_SND_SOC_MSM_QDSP6_INTF) += qdsp6/
-snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-multi-ch-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o msm-compr-q6.o
+snd-soc-qdsp6-objs := msm-dai-q6.o msm-pcm-q6.o msm-multi-ch-pcm-q6.o msm-pcm-routing.o msm-dai-fe.o msm-compr-q6.o msm-dai-stub.o
obj-$(CONFIG_SND_SOC_MSM_QDSP6_HDMI_AUDIO) += msm-dai-q6-hdmi.o
obj-$(CONFIG_SND_SOC_VOICE) += msm-pcm-voice.o msm-pcm-voip.o
snd-soc-qdsp6-objs += msm-pcm-lpa.o msm-pcm-afe.o
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index b515090..bcf6784 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -310,7 +310,6 @@
if (clk_users != 1)
return 0;
- codec_clk = clk_get(NULL, "i2s_spkr_osr_clk");
if (codec_clk) {
clk_set_rate(codec_clk, TABLA_EXT_CLK_RATE);
clk_enable(codec_clk);
@@ -329,7 +328,6 @@
pr_debug("%s: disabling MCLK. clk_users = %d\n",
__func__, clk_users);
clk_disable(codec_clk);
- clk_put(codec_clk);
tabla_mclk_enable(codec, 0);
}
}
@@ -350,7 +348,6 @@
if (clk_users != 1)
return 0;
- codec_clk = clk_get(NULL, "i2s_spkr_osr_clk");
if (codec_clk) {
clk_set_rate(codec_clk, 12288000);
clk_enable(codec_clk);
@@ -376,7 +373,6 @@
__func__, clk_users);
clk_disable(codec_clk);
- clk_put(codec_clk);
tabla_mclk_enable(w->codec, 0);
}
break;
@@ -736,8 +732,9 @@
int err;
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- pr_debug("%s()\n", __func__);
+ pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
/*if (machine_is_msm_liquid()) {
top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
@@ -779,6 +776,8 @@
return err;
}
+ codec_clk = clk_get(cpu_dai->dev, "osr_clk");
+
tabla_hs_detect(codec, &hs_jack, &button_jack, tabla_mbhc_cal,
TABLA_MICBIAS2, msm_enable_codec_ext_clk, 0,
TABLA_EXT_CLK_RATE);
@@ -865,6 +864,23 @@
return 0;
}
+static int msm_hdmi_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_interval *rate = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_RATE);
+
+ struct snd_interval *channels = hw_param_interval(params,
+ SNDRV_PCM_HW_PARAM_CHANNELS);
+
+ pr_debug("%s channels->min %u channels->max %u ()\n", __func__,
+ channels->min, channels->max);
+
+ rate->min = rate->max = 48000;
+
+ return 0;
+}
+
static int msm_btsco_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
struct snd_pcm_hw_params *params)
{
@@ -1084,6 +1100,17 @@
.platform_name = "msm-pcm-afe",
.ignore_suspend = 1,
},
+ {
+ .name = "Voice Stub",
+ .stream_name = "Voice Stub",
+ .cpu_dai_name = "VOICE_STUB",
+ .platform_name = "msm-pcm-hostless",
+ .dynamic = 1,
+ .dsp_link = &fe_media,
+ .no_host_mode = SND_SOC_DAI_LINK_NO_HOST,
+ .ignore_suspend = 1,
+ /* .be_id = do not care */
+ },
/* Backend DAI Links */
{
.name = LPASS_BE_SLIMBUS_0_RX,
@@ -1160,14 +1187,14 @@
{
.name = LPASS_BE_HDMI,
.stream_name = "HDMI Playback",
- .cpu_dai_name = "msm-dai-q6.8",
+ .cpu_dai_name = "msm-dai-q6-hdmi.8",
.platform_name = "msm-pcm-routing",
.codec_name = "msm-stub-codec.1",
.codec_dai_name = "msm-stub-rx",
.no_pcm = 1,
.no_codec = 1,
.be_id = MSM_BACKEND_DAI_HDMI_RX,
- .be_hw_params_fixup = msm_be_hw_params_fixup,
+ .be_hw_params_fixup = msm_hdmi_be_hw_params_fixup,
},
/* Backend AFE DAI Links */
{
@@ -1216,6 +1243,30 @@
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
},
+ {
+ .name = LPASS_BE_STUB_RX,
+ .stream_name = "Stub Playback",
+ .cpu_dai_name = "msm-dai-stub",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tabla_codec",
+ .codec_dai_name = "tabla_rx2",
+ .no_pcm = 1,
+ /* .be_id = do not care */
+ .be_hw_params_fixup = msm_slim_0_rx_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ },
+ {
+ .name = LPASS_BE_STUB_TX,
+ .stream_name = "Stub Capture",
+ .cpu_dai_name = "msm-dai-stub",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tabla_codec",
+ .codec_dai_name = "tabla_tx1",
+ .no_pcm = 1,
+ /* .be_id = do not care */
+ .be_hw_params_fixup = msm_slim_0_tx_be_hw_params_fixup,
+ .ops = &msm_be_ops,
+ },
};
struct snd_soc_card snd_soc_card_msm = {
diff --git a/sound/soc/msm/msm-dai-fe.c b/sound/soc/msm/msm-dai-fe.c
index 8f71e83..14d9adf 100644
--- a/sound/soc/msm/msm-dai-fe.c
+++ b/sound/soc/msm/msm-dai-fe.c
@@ -271,6 +271,28 @@
.ops = &msm_fe_dai_ops,
.name = "AUXPCM_HOSTLESS",
},
+ {
+ .playback = {
+ .stream_name = "Voice Stub Playback",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .stream_name = "Voice Stub Capture",
+ .rates = SNDRV_PCM_RATE_8000_48000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_fe_dai_ops,
+ .name = "VOICE_STUB",
+ },
};
static __devinit int msm_fe_dai_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/msm/msm-dai-q6.c b/sound/soc/msm/msm-dai-q6.c
index aff87ae..f23a6a0 100644
--- a/sound/soc/msm/msm-dai-q6.c
+++ b/sound/soc/msm/msm-dai-q6.c
@@ -618,7 +618,7 @@
* data to the cpu driver, since cpu drive is unaware of any
* boarc specific configuration.
*/
- pcm_clk = clk_get(NULL, auxpcm_pdata->clk);
+ pcm_clk = clk_get(dai->dev, auxpcm_pdata->clk);
if (IS_ERR(pcm_clk)) {
pr_err("%s: could not get pcm_clk\n", __func__);
return PTR_ERR(pcm_clk);
diff --git a/sound/soc/msm/msm-dai-stub.c b/sound/soc/msm/msm-dai-stub.c
new file mode 100644
index 0000000..b2bfa2c
--- /dev/null
+++ b/sound/soc/msm/msm-dai-stub.c
@@ -0,0 +1,102 @@
+/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+static int msm_dai_stub_set_channel_map(struct snd_soc_dai *dai,
+ unsigned int tx_num, unsigned int *tx_slot,
+ unsigned int rx_num, unsigned int *rx_slot)
+{
+ pr_debug("%s:\n", __func__);
+
+ return 0;
+}
+
+static struct snd_soc_dai_ops msm_dai_stub_ops = {
+ .set_channel_map = msm_dai_stub_set_channel_map,
+};
+
+static struct snd_soc_dai_driver msm_dai_stub_dai = {
+ .playback = {
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .capture = {
+ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_8000 |
+ SNDRV_PCM_RATE_16000,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE,
+ .channels_min = 1,
+ .channels_max = 2,
+ .rate_min = 8000,
+ .rate_max = 48000,
+ },
+ .ops = &msm_dai_stub_ops,
+};
+
+static __devinit int msm_dai_stub_dev_probe(struct platform_device *pdev)
+{
+ int rc = 0;
+
+ dev_dbg(&pdev->dev, "dev name %s\n", dev_name(&pdev->dev));
+
+ rc = snd_soc_register_dai(&pdev->dev, &msm_dai_stub_dai);
+
+ return rc;
+}
+
+static __devexit int msm_dai_stub_dev_remove(struct platform_device *pdev)
+{
+ pr_debug("%s:\n", __func__);
+
+ snd_soc_unregister_dai(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver msm_dai_stub_driver = {
+ .probe = msm_dai_stub_dev_probe,
+ .remove = msm_dai_stub_dev_remove,
+ .driver = {
+ .name = "msm-dai-stub",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init msm_dai_stub_init(void)
+{
+ pr_debug("%s:\n", __func__);
+
+ return platform_driver_register(&msm_dai_stub_driver);
+}
+module_init(msm_dai_stub_init);
+
+static void __exit msm_dai_stub_exit(void)
+{
+ pr_debug("%s:\n", __func__);
+
+ platform_driver_unregister(&msm_dai_stub_driver);
+}
+module_exit(msm_dai_stub_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("MSM Stub DSP DAI driver");
+MODULE_LICENSE("GPL v2");
diff --git a/sound/soc/msm/msm-pcm-lpa.c b/sound/soc/msm/msm-pcm-lpa.c
index 0a29016..83fd691 100644
--- a/sound/soc/msm/msm-pcm-lpa.c
+++ b/sound/soc/msm/msm-pcm-lpa.c
@@ -99,6 +99,8 @@
break;
} else
atomic_set(&prtd->pending_buffer, 0);
+ if (runtime->status->hw_ptr >= runtime->control->appl_ptr)
+ break;
pr_debug("%s:writing %d bytes of buffer to dsp 2\n",
__func__, prtd->pcm_count);
@@ -134,6 +136,9 @@
case ASM_SESSION_CMD_RUN: {
if (!atomic_read(&prtd->pending_buffer))
break;
+ if (runtime->status->hw_ptr >=
+ runtime->control->appl_ptr)
+ break;
pr_debug("%s:writing %d bytes"
" of buffer to dsp\n",
__func__, prtd->pcm_count);
@@ -340,8 +345,26 @@
struct snd_soc_pcm_runtime *soc_prtd = substream->private_data;
struct msm_audio *prtd = runtime->private_data;
int dir = 0;
+ int rc = 0;
- pr_debug("%s\n", __func__);
+ /*
+ If routing is still enabled, we need to issue EOS to
+ the DSP
+ To issue EOS to dsp, we need to be run state otherwise
+ EOS is not honored.
+ */
+ if (msm_routing_check_backend_enabled(soc_prtd->dai_link->be_id)) {
+ rc = q6asm_run(prtd->audio_client, 0, 0, 0);
+ atomic_set(&prtd->pending_buffer, 0);
+ prtd->cmd_ack = 0;
+ q6asm_cmd_nowait(prtd->audio_client, CMD_EOS);
+ pr_debug("%s\n", __func__);
+ rc = wait_event_timeout(the_locks.eos_wait,
+ prtd->cmd_ack, 5 * HZ);
+ if (rc < 0)
+ pr_err("EOS cmd timeout\n");
+ prtd->pcm_irq_pos = 0;
+ }
dir = IN;
atomic_set(&prtd->pending_buffer, 0);
@@ -462,6 +485,7 @@
switch (cmd) {
case SNDRV_PCM_IOCTL1_RESET:
+ prtd->cmd_ack = 0;
rc = q6asm_cmd(prtd->audio_client, CMD_FLUSH);
if (rc < 0)
pr_err("%s: flush cmd failed rc=%d\n", __func__, rc);
diff --git a/sound/soc/msm/msm-pcm-routing.c b/sound/soc/msm/msm-pcm-routing.c
index 8b6b5f1..b01c22c 100644
--- a/sound/soc/msm/msm-pcm-routing.c
+++ b/sound/soc/msm/msm-pcm-routing.c
@@ -46,6 +46,7 @@
static struct mutex routing_lock;
static int fm_switch_enable;
+
#define INT_FM_RX_VOL_MAX_STEPS 100
#define INT_FM_RX_VOL_GAIN 2000
@@ -1229,6 +1230,11 @@
0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("AUX_PCM_RX", "AUX PCM Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_IN("AUX_PCM_TX", "AUX PCM Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("VOICE_STUB_DL", "VOICE_STUB Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("VOICE_STUB_UL", "VOICE_STUB Capture", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("STUB_RX", "Stub Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_IN("STUB_TX", "Stub Capture", 0, 0, 0, 0),
+
/* Switch Definitions */
SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0,
&fm_switch_mixer_controls),
@@ -1432,6 +1438,8 @@
{"AUXPCM_RX Port Mixer", "AUX_PCM_UL_TX", "AUX_PCM_TX"},
{"AUXPCM_RX Port Mixer", "SLIM_0_TX", "SLIMBUS_0_TX"},
{"AUX_PCM_RX", NULL, "AUXPCM_RX Port Mixer"},
+ {"STUB_RX", NULL, "VOICE_STUB_DL"},
+ {"VOICE_STUB_UL", NULL, "STUB_TX"},
};
static int msm_pcm_routing_hw_params(struct snd_pcm_substream *substream,
@@ -1636,6 +1644,23 @@
.remove = __devexit_p(msm_routing_pcm_remove),
};
+int msm_routing_check_backend_enabled(int fedai_id)
+{
+ int i;
+ if (fedai_id >= MSM_FRONTEND_DAI_MM_MAX_ID) {
+ /* bad ID assigned in machine driver */
+ pr_err("%s: bad MM ID\n", __func__);
+ return 0;
+ }
+ for (i = 0; i < MSM_BACKEND_DAI_MAX; i++) {
+ if ((test_bit(fedai_id,
+ &msm_bedais[i].fe_sessions))) {
+ return msm_bedais[i].active;
+ }
+ }
+ return 0;
+}
+
static int __init msm_soc_routing_platform_init(void)
{
mutex_init(&routing_lock);
diff --git a/sound/soc/msm/msm-pcm-routing.h b/sound/soc/msm/msm-pcm-routing.h
index 25efb58..9515ab3 100644
--- a/sound/soc/msm/msm-pcm-routing.h
+++ b/sound/soc/msm/msm-pcm-routing.h
@@ -32,6 +32,8 @@
#define LPASS_BE_SEC_I2S_RX "(Backend) SECONDARY_I2S_RX"
#define LPASS_BE_MI2S_RX "(Backend) MI2S_RX"
+#define LPASS_BE_STUB_RX "(Backend) STUB_RX"
+#define LPASS_BE_STUB_TX "(Backend) STUB_TX"
/* For multimedia front-ends, asm session is allocated dynamically.
* Hence, asm session/multimedia front-end mapping has to be maintained.
@@ -85,4 +87,6 @@
void msm_pcm_routing_dereg_phy_stream(int fedai_id, int stream_type);
int lpa_set_volume(unsigned volume);
+
+int msm_routing_check_backend_enabled(int fedai_id);
#endif /*_MSM_PCM_H*/
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index bedfd68..eb363e7 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -309,7 +309,6 @@
if (clk_users != 1)
return 0;
- codec_clk = clk_get(NULL, "i2s_spkr_osr_clk");
if (codec_clk) {
clk_set_rate(codec_clk, TABLA_EXT_CLK_RATE);
clk_enable(codec_clk);
@@ -328,7 +327,6 @@
pr_debug("%s: disabling MCLK. clk_users = %d\n",
__func__, clk_users);
clk_disable(codec_clk);
- clk_put(codec_clk);
tabla_mclk_enable(codec, 0);
}
}
@@ -708,8 +706,9 @@
int err;
struct snd_soc_codec *codec = rtd->codec;
struct snd_soc_dapm_context *dapm = &codec->dapm;
+ struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
- pr_debug("%s()\n", __func__);
+ pr_debug("%s(), dev_name%s\n", __func__, dev_name(cpu_dai->dev));
if (machine_is_msm8960_liquid()) {
top_spk_pamp_gpio = (PM8921_GPIO_PM_TO_SYS(19));
@@ -752,6 +751,8 @@
return err;
}
+ codec_clk = clk_get(cpu_dai->dev, "osr_clk");
+
tabla_hs_detect(codec, &hs_jack, &button_jack, tabla_mbhc_cal,
TABLA_MICBIAS2, msm8960_enable_codec_ext_clk, 0,
TABLA_EXT_CLK_RATE);
@@ -984,7 +985,7 @@
};
/* Digital audio interface glue - connects codec <---> CPU */
-static struct snd_soc_dai_link msm8960_dai[] = {
+static struct snd_soc_dai_link msm8960_dai_common[] = {
/* FrontEnd DAI Links */
{
.name = "MSM8960 Media1",
@@ -1105,32 +1106,6 @@
.no_codec = 1,
.ignore_suspend = 1,
},
- /* Backend DAI Links */
- {
- .name = LPASS_BE_SLIMBUS_0_RX,
- .stream_name = "Slimbus Playback",
- .cpu_dai_name = "msm-dai-q6.16384",
- .platform_name = "msm-pcm-routing",
- .codec_name = "tabla_codec",
- .codec_dai_name = "tabla_rx1",
- .no_pcm = 1,
- .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
- .init = &msm8960_audrx_init,
- .be_hw_params_fixup = msm8960_slim_0_rx_be_hw_params_fixup,
- .ops = &msm8960_be_ops,
- },
- {
- .name = LPASS_BE_SLIMBUS_0_TX,
- .stream_name = "Slimbus Capture",
- .cpu_dai_name = "msm-dai-q6.16385",
- .platform_name = "msm-pcm-routing",
- .codec_name = "tabla_codec",
- .codec_dai_name = "tabla_tx1",
- .no_pcm = 1,
- .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
- .be_hw_params_fixup = msm8960_slim_0_tx_be_hw_params_fixup,
- .ops = &msm8960_be_ops,
- },
/* Backend BT/FM DAI Links */
{
.name = LPASS_BE_INT_BT_SCO_RX,
@@ -1278,13 +1253,88 @@
},
};
-struct snd_soc_card snd_soc_card_msm8960 = {
- .name = "msm8960-snd-card",
- .dai_link = msm8960_dai,
- .num_links = ARRAY_SIZE(msm8960_dai),
+static struct snd_soc_dai_link msm8960_dai_delta_tabla1x[] = {
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tabla1x_codec",
+ .codec_dai_name = "tabla_rx1",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm8960_audrx_init,
+ .be_hw_params_fixup = msm8960_slim_0_rx_be_hw_params_fixup,
+ .ops = &msm8960_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tabla1x_codec",
+ .codec_dai_name = "tabla_tx1",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm8960_slim_0_tx_be_hw_params_fixup,
+ .ops = &msm8960_be_ops,
+ },
+};
+
+
+static struct snd_soc_dai_link msm8960_dai_delta_tabla2x[] = {
+ /* Backend DAI Links */
+ {
+ .name = LPASS_BE_SLIMBUS_0_RX,
+ .stream_name = "Slimbus Playback",
+ .cpu_dai_name = "msm-dai-q6.16384",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tabla_codec",
+ .codec_dai_name = "tabla_rx1",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_RX,
+ .init = &msm8960_audrx_init,
+ .be_hw_params_fixup = msm8960_slim_0_rx_be_hw_params_fixup,
+ .ops = &msm8960_be_ops,
+ },
+ {
+ .name = LPASS_BE_SLIMBUS_0_TX,
+ .stream_name = "Slimbus Capture",
+ .cpu_dai_name = "msm-dai-q6.16385",
+ .platform_name = "msm-pcm-routing",
+ .codec_name = "tabla_codec",
+ .codec_dai_name = "tabla_tx1",
+ .no_pcm = 1,
+ .be_id = MSM_BACKEND_DAI_SLIMBUS_0_TX,
+ .be_hw_params_fixup = msm8960_slim_0_tx_be_hw_params_fixup,
+ .ops = &msm8960_be_ops,
+ },
+};
+
+static struct snd_soc_dai_link msm8960_tabla1x_dai[
+ ARRAY_SIZE(msm8960_dai_common) +
+ ARRAY_SIZE(msm8960_dai_delta_tabla1x)];
+
+
+static struct snd_soc_dai_link msm8960_dai[
+ ARRAY_SIZE(msm8960_dai_common) +
+ ARRAY_SIZE(msm8960_dai_delta_tabla2x)];
+
+static struct snd_soc_card snd_soc_tabla1x_card_msm8960 = {
+ .name = "msm8960-tabla1x-snd-card",
+ .dai_link = msm8960_tabla1x_dai,
+ .num_links = ARRAY_SIZE(msm8960_tabla1x_dai),
+};
+
+static struct snd_soc_card snd_soc_card_msm8960 = {
+ .name = "msm8960-snd-card",
+ .dai_link = msm8960_dai,
+ .num_links = ARRAY_SIZE(msm8960_dai),
};
static struct platform_device *msm8960_snd_device;
+static struct platform_device *msm8960_snd_tabla1x_device;
static int msm8960_configure_headset_mic_gpios(void)
{
@@ -1359,6 +1409,10 @@
return -ENOMEM;
}
+ memcpy(msm8960_dai, msm8960_dai_common, sizeof(msm8960_dai_common));
+ memcpy(msm8960_dai + ARRAY_SIZE(msm8960_dai_common),
+ msm8960_dai_delta_tabla2x, sizeof(msm8960_dai_delta_tabla2x));
+
platform_set_drvdata(msm8960_snd_device, &snd_soc_card_msm8960);
ret = platform_device_add(msm8960_snd_device);
if (ret) {
@@ -1367,6 +1421,27 @@
return ret;
}
+ msm8960_snd_tabla1x_device = platform_device_alloc("soc-audio", 1);
+ if (!msm8960_snd_tabla1x_device) {
+ pr_err("Platform device allocation failed\n");
+ kfree(tabla_mbhc_cal);
+ return -ENOMEM;
+ }
+
+ memcpy(msm8960_tabla1x_dai, msm8960_dai_common,
+ sizeof(msm8960_dai_common));
+ memcpy(msm8960_tabla1x_dai + ARRAY_SIZE(msm8960_dai_common),
+ msm8960_dai_delta_tabla1x, sizeof(msm8960_dai_delta_tabla1x));
+
+ platform_set_drvdata(msm8960_snd_tabla1x_device,
+ &snd_soc_tabla1x_card_msm8960);
+ ret = platform_device_add(msm8960_snd_tabla1x_device);
+ if (ret) {
+ platform_device_put(msm8960_snd_tabla1x_device);
+ kfree(tabla_mbhc_cal);
+ return ret;
+ }
+
if (msm8960_configure_headset_mic_gpios()) {
pr_err("%s Fail to configure headset mic gpios\n", __func__);
msm8960_headset_gpios_configured = 0;
@@ -1386,6 +1461,7 @@
}
msm8960_free_headset_mic_gpios();
platform_device_unregister(msm8960_snd_device);
+ platform_device_unregister(msm8960_snd_tabla1x_device);
kfree(tabla_mbhc_cal);
}
module_exit(msm8960_audio_exit);