summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-iio8
-rw-r--r--Documentation/devicetree/bindings/gpio/gpio-twl4030.txt29
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt5
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt27
-rw-r--r--Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt39
-rw-r--r--Documentation/devicetree/bindings/input/twl4030-keypad.txt27
-rw-r--r--Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt21
-rw-r--r--Documentation/devicetree/bindings/media/si4713.txt30
-rw-r--r--Documentation/devicetree/bindings/mfd/twl-familly.txt47
-rw-r--r--Documentation/devicetree/bindings/mfd/twl-family.txt457
-rw-r--r--Documentation/devicetree/bindings/mfd/twl4030-audio.txt46
-rw-r--r--Documentation/devicetree/bindings/mfd/twl4030-power.txt28
-rw-r--r--Documentation/devicetree/bindings/misc/lis302.txt9
-rw-r--r--Documentation/devicetree/bindings/power/rx51-battery.txt25
-rw-r--r--Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt17
-rw-r--r--Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt17
-rw-r--r--Documentation/devicetree/bindings/regulator/twl-regulator.txt67
-rw-r--r--Documentation/devicetree/bindings/rtc/twl-rtc.txt12
-rw-r--r--Documentation/devicetree/bindings/sound/nokia,rx51.txt27
-rw-r--r--Documentation/devicetree/bindings/usb/twlxxxx-usb.txt40
-rw-r--r--Documentation/devicetree/bindings/watchdog/twl4030-wdt.txt10
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts253
-rw-r--r--arch/arm/boot/dts/omap3.dtsi4
-rw-r--r--arch/arm/boot/dts/twl4030.dtsi6
-rw-r--r--arch/arm/mach-omap2/board-rx51-peripherals.c67
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c12
-rw-r--r--drivers/iio/inkern.c18
-rw-r--r--drivers/input/input.c34
-rw-r--r--drivers/input/touchscreen/tsc2005.c130
-rw-r--r--drivers/media/radio/si4713/radio-platform-si4713.c28
-rw-r--r--drivers/media/radio/si4713/si4713.c166
-rw-r--r--drivers/media/radio/si4713/si4713.h15
-rw-r--r--drivers/media/rc/Kconfig2
-rw-r--r--drivers/media/rc/ir-rx51.c6
-rw-r--r--drivers/misc/lis3lv02d/lis3lv02d.c56
-rw-r--r--drivers/power/bq2415x_charger.c8
-rw-r--r--drivers/power/rx51_battery.c90
-rw-r--r--drivers/staging/media/bcm2048/radio-bcm2048.c18
-rw-r--r--include/dt-bindings/pinctrl/omap.h12
-rw-r--r--include/linux/iio/consumer.h13
-rw-r--r--include/linux/input.h8
-rw-r--r--include/linux/of.h7
-rw-r--r--include/media/radio-si4713.h30
-rw-r--r--include/media/si4713.h4
-rw-r--r--include/sound/rx51.h18
-rw-r--r--include/sound/soc.h13
-rw-r--r--sound/soc/codecs/tlv320aic3x.c9
-rw-r--r--sound/soc/omap/omap-mcbsp.c5
-rw-r--r--sound/soc/omap/omap-mcbsp.h2
-rw-r--r--sound/soc/omap/rx51.c248
-rw-r--r--sound/soc/soc-core.c68
51 files changed, 1532 insertions, 806 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-iio b/Documentation/ABI/testing/sysfs-bus-iio
index 6e02c5029152..58ba33300305 100644
--- a/Documentation/ABI/testing/sysfs-bus-iio
+++ b/Documentation/ABI/testing/sysfs-bus-iio
@@ -210,6 +210,14 @@ Contact: linux-iio@vger.kernel.org
Description:
Scaled humidity measurement in milli percent.
+What: /sys/bus/iio/devices/iio:deviceX/in_X_mean_raw
+KernelVersion: 3.5
+Contact: linux-iio@vger.kernel.org
+Description:
+ Averaged raw measurement from channel X. The number of values
+ used for averaging is device specific. The converting rules for
+ normal raw values also applies to the averaged raw values.
+
What: /sys/bus/iio/devices/iio:deviceX/in_accel_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_x_offset
What: /sys/bus/iio/devices/iio:deviceX/in_accel_y_offset
diff --git a/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt b/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
deleted file mode 100644
index 66788fda1db3..000000000000
--- a/Documentation/devicetree/bindings/gpio/gpio-twl4030.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-twl4030 GPIO controller bindings
-
-Required properties:
-- compatible:
- - "ti,twl4030-gpio" for twl4030 GPIO controller
-- #gpio-cells : Should be two.
- - first cell is the pin number
- - second cell is used to specify optional parameters (unused)
-- gpio-controller : Marks the device node as a GPIO controller.
-- #interrupt-cells : Should be 2.
-- interrupt-controller: Mark the device node as an interrupt controller
- The first cell is the GPIO number.
- The second cell is not used.
-- ti,use-leds : Enables LEDA and LEDB outputs if set
-- ti,debounce : if n-th bit is set, debounces GPIO-n
-- ti,mmc-cd : if n-th bit is set, GPIO-n controls VMMC(n+1)
-- ti,pullups : if n-th bit is set, set a pullup on GPIO-n
-- ti,pulldowns : if n-th bit is set, set a pulldown on GPIO-n
-
-Example:
-
-twl_gpio: gpio {
- compatible = "ti,twl4030-gpio";
- #gpio-cells = <2>;
- gpio-controller;
- #interrupt-cells = <2>;
- interrupt-controller;
- ti,use-leds;
-};
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index bef86e57c388..fc6a1ba5021c 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -81,7 +81,10 @@ stm,m41t00 Serial Access TIMEKEEPER
stm,m41t62 Serial real-time clock (RTC) with alarm
stm,m41t80 M41T80 - SERIAL ACCESS RTC WITH ALARMS
taos,tsl2550 Ambient Light Sensor with SMBUS/Two Wire Serial Interface
-ti,tsc2003 I2C Touch-Screen Controller
+ti,bq27200 Battery Monitor
+ti,bq27500 Battery Monitor
+ti,bq27425 Battery Monitor
ti,tmp102 Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
ti,tmp275 Digital Temperature Sensor
+ti,tsc2003 I2C Touch-Screen Controller
winbond,wpct301 i2c trusted platform module (TPM)
diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
new file mode 100644
index 000000000000..d8e06163c54e
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
@@ -0,0 +1,27 @@
+General Touchscreen Properties:
+
+Optional properties for Touchscreens:
+ - touchscreen-size-x : horizontal resolution of touchscreen
+ (in pixels)
+ - touchscreen-size-y : vertical resolution of touchscreen
+ (in pixels)
+ - touchscreen-max-pressure : maximum reported pressure (arbitrary range
+ dependent on the controller)
+ - touchscreen-fuzz-x : horizontal noise value of the absolute input
+ device (in pixels)
+ - touchscreen-fuzz-y : vertical noise value of the absolute input
+ device (in pixels)
+ - touchscreen-fuzz-pressure : pressure noise value of the absolute input
+ device (arbitrary range dependent on the
+ controller)
+ - touchscreen-inverted-x : X axis is inverted (boolean)
+ - touchscreen-inverted-y : Y axis is inverted (boolean)
+
+Deprecated properties for Touchscreens:
+ - x-size : deprecated name for touchscreen-size-x
+ - y-size : deprecated name for touchscreen-size-y
+ - moving-threshold : deprecated name for a combination of
+ touchscreen-fuzz-x and touchscreen-fuzz-y
+ - contact-threshold : deprecated name for touchscreen-fuzz-pressure
+ - x-invert : deprecated name for touchscreen-inverted-x
+ - y-invert : deprecated name for touchscreen-inverted-y
diff --git a/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt b/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt
new file mode 100644
index 000000000000..663f8ab96614
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/touchscreen/tsc2005.txt
@@ -0,0 +1,39 @@
+* Texas Instruments tsc2005 touchscreen controller
+
+Required properties:
+ - compatible : "ti,tsc2005"
+ - reg : SPI device address
+ - spi-max-frequency : Maximal SPI speed
+ - interrupts : IRQ specifier
+ - reset-gpios : GPIO specifier
+
+Optional properties:
+ - ti,x-plate-ohms : integer, resistance of the touchscreen's X plates
+ in ohm (defaults to 280)
+ - ti,esd-recovery-timeout-ms : integer, if the touchscreen does not respond after
+ the configured time (in milli seconds), the driver
+ will reset it. This is disabled by default.
+ - properties defined in touchscreen.txt
+
+Example:
+
+&mcspi1 {
+ tsc2005@0 {
+ compatible = "ti,tsc2005";
+ spi-max-frequency = <6000000>;
+ reg = <0>;
+
+ reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */
+ interrupts-extended = <&gpio4 4 IRQ_TYPE_NONE>; /* 100 */
+
+ touchscreen-fuzz-x = <4>;
+ touchscreen-fuzz-y = <7>;
+ touchscreen-fuzz-pressure = <2>;
+ touchscreen-max-x = <4096>;
+ touchscreen-max-y = <4096>;
+ touchscreen-max-pressure = <2048>;
+
+ ti,x-plate-ohms = <280>;
+ ti,esd-recovery-timeout-ms = <8000>;
+ };
+}
diff --git a/Documentation/devicetree/bindings/input/twl4030-keypad.txt b/Documentation/devicetree/bindings/input/twl4030-keypad.txt
deleted file mode 100644
index e4be2f76a717..000000000000
--- a/Documentation/devicetree/bindings/input/twl4030-keypad.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-* TWL4030's Keypad Controller device tree bindings
-
-TWL4030's Keypad controller is used to interface a SoC with a matrix-type
-keypad device. The keypad controller supports multiple row and column lines.
-A key can be placed at each intersection of a unique row and a unique column.
-The keypad controller can sense a key-press and key-release and report the
-event using a interrupt to the cpu.
-
-This binding is based on the matrix-keymap binding with the following
-changes:
-
- * keypad,num-rows and keypad,num-columns are required.
-
-Required SoC Specific Properties:
-- compatible: should be one of the following
- - "ti,twl4030-keypad": For controllers compatible with twl4030 keypad
- controller.
-- interrupt: should be one of the following
- - <1>: For controllers compatible with twl4030 keypad controller.
-
-Example:
- twl_keypad: keypad {
- compatible = "ti,twl4030-keypad";
- interrupts = <1>;
- keypad,num-rows = <8>;
- keypad,num-columns = <8>;
- };
diff --git a/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt b/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt
deleted file mode 100644
index c864a46cddcf..000000000000
--- a/Documentation/devicetree/bindings/input/twl4030-pwrbutton.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Texas Instruments TWL family (twl4030) pwrbutton module
-
-This module is part of the TWL4030. For more details about the whole
-chip see Documentation/devicetree/bindings/mfd/twl-familly.txt.
-
-This module provides a simple power button event via an Interrupt.
-
-Required properties:
-- compatible: should be one of the following
- - "ti,twl4030-pwrbutton": For controllers compatible with twl4030
-- interrupts: should be one of the following
- - <8>: For controllers compatible with twl4030
-
-Example:
-
-&twl {
- twl_pwrbutton: pwrbutton {
- compatible = "ti,twl4030-pwrbutton";
- interrupts = <8>;
- };
-};
diff --git a/Documentation/devicetree/bindings/media/si4713.txt b/Documentation/devicetree/bindings/media/si4713.txt
new file mode 100644
index 000000000000..5ee5552d3465
--- /dev/null
+++ b/Documentation/devicetree/bindings/media/si4713.txt
@@ -0,0 +1,30 @@
+* Silicon Labs FM Radio transmitter
+
+The Silicon Labs Si4713 is an FM radio transmitter with receive power scan
+supporting 76-108 MHz. It includes an RDS encoder and has both, a stereo-analog
+and a digital interface, which supports I2S, left-justified and a custom
+DSP-mode format. It is programmable through an I2C interface.
+
+Required Properties:
+- compatible: Should contain "silabs,si4713"
+- reg: the I2C address of the device
+
+Optional Properties:
+- interrupts-extended: Interrupt specifier for the chips interrupt
+- reset-gpios: GPIO specifier for the chips reset line
+- vdd-supply: phandle for Vdd regulator
+- vio-supply: phandle for Vio regulator
+
+Example:
+
+&i2c2 {
+ fmtx: si4713@63 {
+ compatible = "silabs,si4713";
+ reg = <0x63>;
+
+ interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */
+ reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */
+ vio-supply = <&vio>;
+ vdd-supply = <&vaux1>;
+ };
+};
diff --git a/Documentation/devicetree/bindings/mfd/twl-familly.txt b/Documentation/devicetree/bindings/mfd/twl-familly.txt
deleted file mode 100644
index a66fcf946759..000000000000
--- a/Documentation/devicetree/bindings/mfd/twl-familly.txt
+++ /dev/null
@@ -1,47 +0,0 @@
-Texas Instruments TWL family
-
-The TWLs are Integrated Power Management Chips.
-Some version might contain much more analog function like
-USB transceiver or Audio amplifier.
-These chips are connected to an i2c bus.
-
-
-Required properties:
-- compatible : Must be "ti,twl4030";
- For Integrated power-management/audio CODEC device used in OMAP3
- based boards
-- compatible : Must be "ti,twl6030";
- For Integrated power-management used in OMAP4 based boards
-- interrupts : This i2c device has an IRQ line connected to the main SoC
-- interrupt-controller : Since the twl support several interrupts internally,
- it is considered as an interrupt controller cascaded to the SoC one.
-- #interrupt-cells = <1>;
-- interrupt-parent : The parent interrupt controller.
-
-Optional node:
-- Child nodes contain in the twl. The twl family is made of several variants
- that support a different number of features.
- The children nodes will thus depend of the capability of the variant.
-
-
-Example:
-/*
- * Integrated Power Management Chip
- * http://www.ti.com/lit/ds/symlink/twl6030.pdf
- */
-twl@48 {
- compatible = "ti,twl6030";
- reg = <0x48>;
- interrupts = <39>; /* IRQ_SYS_1N cascaded to gic */
- interrupt-controller;
- #interrupt-cells = <1>;
- interrupt-parent = <&gic>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- twl_rtc {
- compatible = "ti,twl_rtc";
- interrupts = <11>;
- reg = <0>;
- };
-};
diff --git a/Documentation/devicetree/bindings/mfd/twl-family.txt b/Documentation/devicetree/bindings/mfd/twl-family.txt
new file mode 100644
index 000000000000..65f83ab86038
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl-family.txt
@@ -0,0 +1,457 @@
+Texas Instruments TWL family
+----------------------------
+
+The TWLs are i2c connected Integrated Power Management Chips.
+Some version contain much more analog function like
+USB transceiver or Audio amplifier.
+
+The TWL family provide have an integrated interrupt controller
+used by the internal subcomponents.
+
+Required properties:
+- compatible: Should contain:
+ * "ti,twl4030": For integrated power-management/audio CODEC device
+ used in OMAP3 boards.
+ * "ti,twl6030": For integrated power-management device used in OMAP4
+ based boards.
+- interrupts: interrupt-specifier for the sole interrupt generated by
+ the device.
+- interrupt-controller : Since the twl support several interrupts internally,
+ it is considered as an interrupt controller cascaded to the SoC one.
+- #interrupt-cells: must be <1>
+
+Optional properties:
+- interrupt-parent : The parent interrupt controller. This property is
+ optional if the implicit interrupt controller is correct.
+
+Optional nodes:
+- Child nodes contained in the twl. The twl family is made of several
+ variants that support a different number of features. The children
+ nodes will thus depend of the capability of the variant.
+
+TWL Regulator
+-------------
+
+Required properties:
+For twl6030 regulators/LDOs
+- compatible:
+ - "ti,twl6030-vaux1" for VAUX1 LDO
+ - "ti,twl6030-vaux2" for VAUX2 LDO
+ - "ti,twl6030-vaux3" for VAUX3 LDO
+ - "ti,twl6030-vmmc" for VMMC LDO
+ - "ti,twl6030-vpp" for VPP LDO
+ - "ti,twl6030-vusim" for VUSIM LDO
+ - "ti,twl6030-vana" for VANA LDO
+ - "ti,twl6030-vcxio" for VCXIO LDO
+ - "ti,twl6030-vdac" for VDAC LDO
+ - "ti,twl6030-vusb" for VUSB LDO
+ - "ti,twl6030-v1v8" for V1V8 LDO
+ - "ti,twl6030-v2v1" for V2V1 LDO
+ - "ti,twl6030-vdd1" for VDD1 SMPS
+ - "ti,twl6030-vdd2" for VDD2 SMPS
+ - "ti,twl6030-vdd3" for VDD3 SMPS
+For twl6032 regulators/LDOs
+- compatible:
+ - "ti,twl6032-ldo1" for LDO1 LDO
+ - "ti,twl6032-ldo2" for LDO2 LDO
+ - "ti,twl6032-ldo3" for LDO3 LDO
+ - "ti,twl6032-ldo4" for LDO4 LDO
+ - "ti,twl6032-ldo5" for LDO5 LDO
+ - "ti,twl6032-ldo6" for LDO6 LDO
+ - "ti,twl6032-ldo7" for LDO7 LDO
+ - "ti,twl6032-ldoln" for LDOLN LDO
+ - "ti,twl6032-ldousb" for LDOUSB LDO
+ - "ti,twl6032-smps3" for SMPS3 SMPS
+ - "ti,twl6032-smps4" for SMPS4 SMPS
+ - "ti,twl6032-vio" for VIO SMPS
+For twl4030 regulators/LDOs
+- compatible:
+ - "ti,twl4030-vaux1" for VAUX1 LDO
+ - "ti,twl4030-vaux2" for VAUX2 LDO
+ - "ti,twl5030-vaux2" for VAUX2 LDO
+ - "ti,twl4030-vaux3" for VAUX3 LDO
+ - "ti,twl4030-vaux4" for VAUX4 LDO
+ - "ti,twl4030-vmmc1" for VMMC1 LDO
+ - "ti,twl4030-vmmc2" for VMMC2 LDO
+ - "ti,twl4030-vpll1" for VPLL1 LDO
+ - "ti,twl4030-vpll2" for VPLL2 LDO
+ - "ti,twl4030-vsim" for VSIM LDO
+ - "ti,twl4030-vdac" for VDAC LDO
+ - "ti,twl4030-vintana2" for VINTANA2 LDO
+ - "ti,twl4030-vio" for VIO LDO
+ - "ti,twl4030-vdd1" for VDD1 SMPS
+ - "ti,twl4030-vdd2" for VDD2 SMPS
+ - "ti,twl4030-vintana1" for VINTANA1 LDO
+ - "ti,twl4030-vintdig" for VINTDIG LDO
+ - "ti,twl4030-vusb1v5" for VUSB1V5 LDO
+ - "ti,twl4030-vusb1v8" for VUSB1V8 LDO
+ - "ti,twl4030-vusb3v1" for VUSB3V1 LDO
+
+Optional properties:
+- Any optional property defined in bindings/regulator/regulator.txt
+
+TWL RTC
+-------
+
+Required properties:
+- compatible : Should be twl4030-rtc
+
+TWL PWM
+-------
+
+Supported PWMs:
+On TWL4030 series: PWM1 and PWM2
+On TWL6030 series: PWM0 and PWM1
+
+Required properties:
+- compatible: Should contain one of:
+ * "ti,twl4030-pwm"
+ * "ti,twl6030-pwm"
+- #pwm-cells: should be 2. See Documentation/devicetree/bindings/pwm/pwm.txt
+ for a description of the cells format. The binding follows the "typical"
+ encoding.
+
+TWL PWM LED
+-----------
+
+Supported PWMs:
+On TWL4030 series: PWMA and PWMB (connected to LEDA and LEDB terminals)
+On TWL6030 series: LED PWM (mainly used as charging indicator LED)
+
+Required properties:
+- compatible: Should contain one of:
+ * "ti,twl4030-pwmled"
+ * "ti,twl6030-pwmled"
+- #pwm-cells: should be 2. See Documentation/devicetree/bindings/pwm/pwm.txt
+ for a description of the cells format. The binding follows the "typical"
+ encoding.
+
+TWL4030 USB PHY AND COMPARATOR
+------------------------------
+
+Required properties:
+ - compatible : Should contain "ti,twl4030-usb"
+ - interrupts: A list of interrupt-specifiers:
+ [1] The OTG interrupt
+ [2] The VBUS interrupt (optional)
+ - vusb1v5-supply: phandle to the TWL's usb 1.5V regulator device
+ - vusb1v8-supply: phandle to the TWL's usb 1.8V regulator device
+ - vusb3v1-supply: phandle to the TWL's usb 3.1V regulator device
+ - usb_mode : The mode used by the phy to connect to the controller. <1>
+ specifies "ULPI" mode and <2> specifies "CEA2011_3PIN" mode.
+
+TWL6030 USB COMPARATOR
+----------------------
+
+Required properties:
+ - compatible : Should contain "ti,twl6030-usb"
+ - interrupts : Two interrupt numbers to the cpu should be specified. First
+ interrupt number is the otg interrupt number that raises ID interrupts when
+ the controller has to act as host and the second interrupt number is the
+ usb interrupt number that raises VBUS interrupts when the controller has to
+ act as device
+ - usb-supply : phandle to the regulator device tree node. It should be vusb
+ if it is twl6030 or ldousb if it is twl6032 subclass.
+
+TWL4030 GPIO Controller
+-----------------------
+
+Required properties:
+- compatible: Should contain "ti,twl4030-gpio"
+- #gpio-cells : Should be two.
+ - first cell is the pin number
+ - second cell is a bit field of flags, as defined in <dt-bindings/gpio/gpio.h>
+- gpio-controller : Marks the device node as a GPIO controller.
+- #interrupt-cells : Should be 2.
+ The first cell is the GPIO number.
+ The second cell is not used.
+- interrupt-controller: Mark the device node as an interrupt controller
+- ti,use-leds : Boolean; enables LEDA and LEDB outputs if set
+- ti,debounce : 32 Bit Unsigned; if n-th bit is set, debounces GPIO-n
+- ti,mmc-cd : 32 Bit Unsigned; if n-th bit is set, GPIO-n controls VMMC(n+1)
+- ti,pullups : 32 Bit Unsigned; if n-th bit is set, set a pullup on GPIO-n
+- ti,pulldowns : 32 Bit Unsigned; if n-th bit is set, set a pulldown on GPIO-n
+
+TWL4030 Audio
+-------------
+
+The audio module inside the TWL family consist of an audio codec and
+a vibrator driver.
+
+Required properties:
+- compatible : Should contain "ti,twl4030-audio"
+
+Optional properties:
+- ti,enable-vibra : Should be set to <1> if the vibra functionality is used.
+ if missing or it is 0, the vibra functionality is disabled.
+
+The node may contain a subnode named "codec", which may have the
+following properties:
+
+- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts
+ from the start of the recorded sample (in ms)
+- ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise
+- ti,hs_extmute: 32 Bit Unsigned; Use external mute for HS pop reduction
+- ti,hs_extmute_gpio: GPIO phandle; Use external GPIO to control the external mute
+- ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the
+ valid values.
+
+TWL4030 Power
+-------------
+
+The power management module inside the TWL family provides several facilities
+to control the power resources, including power scripts. For now, the binding
+only supports the complete shutdown of the system after poweroff.
+
+Required properties:
+- compatible : Should contain "ti,twl4030-power"
+
+Optional properties:
+- ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or
+ SLEEP-to-OFF transition when the system poweroffs.
+
+TWL4030 Watchdog
+----------------
+
+Required properties:
+- compatible: Should contain "ti,twl4030-wdt"
+
+TWL4030 Power Button
+--------------------
+
+This module provides a simple power button event via an Interrupt.
+
+Required properties:
+- compatible: Should contain "ti,twl4030-pwrbutton"
+- interrupts: Should be one of the following
+ - <8>: For controllers compatible with twl4030
+
+TWL4030 Keypad
+--------------
+
+TWL4030's Keypad controller is used to interface a SoC with a matrix-type
+keypad device. The keypad controller supports multiple row and column lines.
+A key can be placed at each intersection of a unique row and a unique column.
+The keypad controller can sense a key-press and key-release and report the
+event using a interrupt to the cpu.
+
+This binding is based on the matrix-keymap binding with the following
+changes:
+
+ * keypad,num-rows is required.
+ * keypad,num-columns is required.
+
+Required SoC Specific Properties:
+- compatible: Should contain "ti,twl4030-keypad"
+- interrupt: Should be one of the following
+ - <1>: For controllers compatible with twl4030 keypad controller.
+
+Example
+-------
+
+This is an example for TWL4030 binding (Nokia N900):
+
+&i2c {
+ twl@48 {
+ compatible = "ti,twl4030";
+
+ interrupt-controller;
+ #interrupt-cells = <1>;
+
+ reg = <0x48>;
+
+ interrupt-parent = <&intc>;
+ interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+
+ rtc {
+ compatible = "ti,twl4030-rtc";
+ interrupts = <11>;
+ };
+
+ watchdog {
+ compatible = "ti,twl4030-wdt";
+ };
+
+ vaux1: regulator-vaux1 {
+ compatible = "ti,twl4030-vaux1";
+
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on; /* due battery cover sensor */
+ };
+
+ vaux2: regulator-vaux2 {
+ compatible = "ti,twl4030-vaux2";
+
+ regulator-name = "VCSI";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vaux3: regulator-vaux3 {
+ compatible = "ti,twl4030-vaux3";
+
+ regulator-name = "VMMC2_30";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vaux4: regulator-vaux4 {
+ compatible = "ti,twl4030-vaux4";
+
+ regulator-name = "VCAM_ANA_28";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ vcc: regulator-vdd1 {
+ compatible = "ti,twl4030-vdd1";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1450000>;
+ };
+
+ vdac: regulator-vdac {
+ compatible = "ti,twl4030-vdac";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vio: regulator-vio {
+ compatible = "ti,twl4030-vio";
+
+ regulator-name = "VIO";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ vintana1: regulator-vintana1 {
+ compatible = "ti,twl4030-vintana1";
+
+ regulator-name = "VINTANA1";
+ /* fixed to 1500000 */
+ regulator-always-on;
+ };
+
+ vintana2: regulator-vintana2 {
+ compatible = "ti,twl4030-vintana2";
+
+ regulator-name = "VINTANA2";
+ regulator-min-microvolt = <2750000>;
+ regulator-max-microvolt = <2750000>;
+ regulator-always-on;
+ };
+
+ vintdig: regulator-vintdig {
+ compatible = "ti,twl4030-vintdig";
+
+ regulator-name = "VINTDIG";
+ /* fixed to 1500000 */
+ regulator-always-on;
+ };
+
+ vmmc1: regulator-vmmc1 {
+ compatible = "ti,twl4030-vmmc1";
+
+ regulator-name = "VMMC1";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vmmc2: regulator-vmmc2 {
+ compatible = "ti,twl4030-vmmc2";
+
+ regulator-name = "V28_A";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-always-on; /* due VIO leak to AIC34 VDDs */
+ };
+
+ vusb1v5: regulator-vusb1v5 {
+ compatible = "ti,twl4030-vusb1v5";
+ };
+
+ vusb1v8: regulator-vusb1v8 {
+ compatible = "ti,twl4030-vusb1v8";
+ };
+
+ vusb3v1: regulator-vusb3v1 {
+ compatible = "ti,twl4030-vusb3v1";
+ };
+
+ vpll1: regulator-vpll1 {
+ compatible = "ti,twl4030-vpll1";
+
+ regulator-name = "VPLL";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vpll2: regulator-vpll2 {
+ compatible = "ti,twl4030-vpll2";
+
+ regulator-name = "VSDI_CSI";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ vsim: regulator-vsim {
+ compatible = "ti,twl4030-vsim";
+
+ regulator-name = "VMMC2_IO_18";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ twl_gpio: gpio {
+ compatible = "ti,twl4030-gpio";
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ };
+
+ usb2_phy: twl4030-usb {
+ compatible = "ti,twl4030-usb";
+ interrupts = <10>, <4>;
+ usb1v5-supply = <&vusb1v5>;
+ usb1v8-supply = <&vusb1v8>;
+ usb3v1-supply = <&vusb3v1>;
+ usb_mode = <1>;
+ };
+
+ twl_pwm: pwm {
+ compatible = "ti,twl4030-pwm";
+ #pwm-cells = <2>;
+ };
+
+ twl_pwmled: pwmled {
+ compatible = "ti,twl4030-pwmled";
+ #pwm-cells = <2>;
+ };
+
+ twl_keypad: keypad {
+ compatible = "ti,twl4030-keypad";
+ interrupts = <1>;
+ keypad,num-rows = <8>;
+ keypad,num-columns = <8>;
+
+ linux,keymap = < 0x00000010 /* KEY_Q */
+ 0x00010018 /* KEY_O */
+ 0x00020019 /* KEY_P */
+ /* ... */
+ >;
+ };
+
+ twl_pwrbutton: pwrbutton {
+ compatible = "ti,twl4030-pwrbutton";
+ interrupts = <8>;
+ };
+
+ twl_audio: audio {
+ compatible = "ti,twl4030-audio";
+ ti,enable-vibra = <1>;
+ };
+ };
+};
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
deleted file mode 100644
index 414d2ae0adf6..000000000000
--- a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
+++ /dev/null
@@ -1,46 +0,0 @@
-Texas Instruments TWL family (twl4030) audio module
-
-The audio module inside the TWL family consist of an audio codec and a vibra
-driver.
-
-Required properties:
-- compatible : must be "ti,twl4030-audio"
-
-Optional properties, nodes:
-
-Audio functionality:
-- codec { }: Need to be present if the audio functionality is used. Within this
- section the following options can be used:
-- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts
- from the start of the recorded sample (in ms)
--ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise
--ti,hs_extmute: Use external mute for HS pop reduction
--ti,hs_extmute_gpio: Use external GPIO to control the external mute
--ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the
- valid values.
-
-Vibra functionality
-- ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if
- missing or it is 0, the vibra functionality is disabled.
-
-Example:
-&i2c1 {
- clock-frequency = <2600000>;
-
- twl: twl@48 {
- reg = <0x48>;
- interrupts = <7>; /* SYS_NIRQ cascaded to intc */
- interrupt-parent = <&intc>;
-
- twl_audio: audio {
- compatible = "ti,twl4030-audio";
-
- ti,enable-vibra = <1>;
-
- codec {
- ti,ramp_delay_value = <3>;
- };
-
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-power.txt b/Documentation/devicetree/bindings/mfd/twl4030-power.txt
deleted file mode 100644
index 8e15ec35ac99..000000000000
--- a/Documentation/devicetree/bindings/mfd/twl4030-power.txt
+++ /dev/null
@@ -1,28 +0,0 @@
-Texas Instruments TWL family (twl4030) reset and power management module
-
-The power management module inside the TWL family provides several facilities
-to control the power resources, including power scripts. For now, the
-binding only supports the complete shutdown of the system after poweroff.
-
-Required properties:
-- compatible : must be "ti,twl4030-power"
-
-Optional properties:
-- ti,use_poweroff: With this flag, the chip will initiates an ACTIVE-to-OFF or
- SLEEP-to-OFF transition when the system poweroffs.
-
-Example:
-&i2c1 {
- clock-frequency = <2600000>;
-
- twl: twl@48 {
- reg = <0x48>;
- interrupts = <7>; /* SYS_NIRQ cascaded to intc */
- interrupt-parent = <&intc>;
-
- twl_power: power {
- compatible = "ti,twl4030-power";
- ti,use_poweroff;
- };
- };
-};
diff --git a/Documentation/devicetree/bindings/misc/lis302.txt b/Documentation/devicetree/bindings/misc/lis302.txt
index 6def86f6b053..2a19bff9693f 100644
--- a/Documentation/devicetree/bindings/misc/lis302.txt
+++ b/Documentation/devicetree/bindings/misc/lis302.txt
@@ -46,11 +46,18 @@ Optional properties for all bus drivers:
interrupt 2
- st,wakeup-{x,y,z}-{lo,hi}: set wakeup condition on x/y/z axis for
upper/lower limit
+ - st,wakeup-threshold: set wakeup threshold
+ - st,wakeup2-{x,y,z}-{lo,hi}: set wakeup condition on x/y/z axis for
+ upper/lower limit for second wakeup
+ engine.
+ - st,wakeup2-threshold: set wakeup threshold for second wakeup
+ engine.
- st,highpass-cutoff-hz=: 1, 2, 4 or 8 for 1Hz, 2Hz, 4Hz or 8Hz of
highpass cut-off frequency
- st,hipass{1,2}-disable: disable highpass 1/2.
- st,default-rate=: set the default rate
- - st,axis-{x,y,z}=: set the axis to map to the three coordinates
+ - st,axis-{x,y,z}=: set the axis to map to the three coordinates.
+ Negative values can be used for inverted axis.
- st,{min,max}-limit-{x,y,z} set the min/max limits for x/y/z axis
(used by self-test)
diff --git a/Documentation/devicetree/bindings/power/rx51-battery.txt b/Documentation/devicetree/bindings/power/rx51-battery.txt
new file mode 100644
index 000000000000..90438453db58
--- /dev/null
+++ b/Documentation/devicetree/bindings/power/rx51-battery.txt
@@ -0,0 +1,25 @@
+Binding for Nokia N900 battery
+
+The Nokia N900 battery status can be read via the TWL4030's A/D converter.
+
+Required properties:
+- compatible: Should contain one of the following:
+ * "nokia,n900-battery"
+- io-channels: Should contain IIO channel specifiers
+ for each element in io-channel-names.
+- io-channel-names: Should contain the following values:
+ * "temp" - The ADC channel for temperature reading
+ * "bsi" - The ADC channel for battery size identification
+ * "vbat" - The ADC channel to measure the battery voltage
+
+Example from Nokia N900:
+
+battery: n900-battery {
+ compatible = "nokia,n900-battery";
+ io-channels = <&twl4030_madc 0>,
+ <&twl4030_madc 4>,
+ <&twl4030_madc 12>;
+ io-channel-names = "temp",
+ "bsi",
+ "vbat";
+};
diff --git a/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt b/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt
deleted file mode 100644
index 4e32bee11201..000000000000
--- a/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Texas Instruments TWL series PWM drivers
-
-Supported PWMs:
-On TWL4030 series: PWM1 and PWM2
-On TWL6030 series: PWM0 and PWM1
-
-Required properties:
-- compatible: "ti,twl4030-pwm" or "ti,twl6030-pwm"
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
- the cells format.
-
-Example:
-
-twl_pwm: pwm {
- compatible = "ti,twl6030-pwm";
- #pwm-cells = <2>;
-};
diff --git a/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt b/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt
deleted file mode 100644
index 9f4b46090782..000000000000
--- a/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Texas Instruments TWL series PWM drivers connected to LED terminals
-
-Supported PWMs:
-On TWL4030 series: PWMA and PWMB (connected to LEDA and LEDB terminals)
-On TWL6030 series: LED PWM (mainly used as charging indicator LED)
-
-Required properties:
-- compatible: "ti,twl4030-pwmled" or "ti,twl6030-pwmled"
-- #pwm-cells: should be 2. See pwm.txt in this directory for a description of
- the cells format.
-
-Example:
-
-twl_pwmled: pwmled {
- compatible = "ti,twl6030-pwmled";
- #pwm-cells = <2>;
-};
diff --git a/Documentation/devicetree/bindings/regulator/twl-regulator.txt b/Documentation/devicetree/bindings/regulator/twl-regulator.txt
deleted file mode 100644
index 75b0c1669504..000000000000
--- a/Documentation/devicetree/bindings/regulator/twl-regulator.txt
+++ /dev/null
@@ -1,67 +0,0 @@
-TWL family of regulators
-
-Required properties:
-For twl6030 regulators/LDOs
-- compatible:
- - "ti,twl6030-vaux1" for VAUX1 LDO
- - "ti,twl6030-vaux2" for VAUX2 LDO
- - "ti,twl6030-vaux3" for VAUX3 LDO
- - "ti,twl6030-vmmc" for VMMC LDO
- - "ti,twl6030-vpp" for VPP LDO
- - "ti,twl6030-vusim" for VUSIM LDO
- - "ti,twl6030-vana" for VANA LDO
- - "ti,twl6030-vcxio" for VCXIO LDO
- - "ti,twl6030-vdac" for VDAC LDO
- - "ti,twl6030-vusb" for VUSB LDO
- - "ti,twl6030-v1v8" for V1V8 LDO
- - "ti,twl6030-v2v1" for V2V1 LDO
- - "ti,twl6030-vdd1" for VDD1 SMPS
- - "ti,twl6030-vdd2" for VDD2 SMPS
- - "ti,twl6030-vdd3" for VDD3 SMPS
-For twl6032 regulators/LDOs
-- compatible:
- - "ti,twl6032-ldo1" for LDO1 LDO
- - "ti,twl6032-ldo2" for LDO2 LDO
- - "ti,twl6032-ldo3" for LDO3 LDO
- - "ti,twl6032-ldo4" for LDO4 LDO
- - "ti,twl6032-ldo5" for LDO5 LDO
- - "ti,twl6032-ldo6" for LDO6 LDO
- - "ti,twl6032-ldo7" for LDO7 LDO
- - "ti,twl6032-ldoln" for LDOLN LDO
- - "ti,twl6032-ldousb" for LDOUSB LDO
- - "ti,twl6032-smps3" for SMPS3 SMPS
- - "ti,twl6032-smps4" for SMPS4 SMPS
- - "ti,twl6032-vio" for VIO SMPS
-For twl4030 regulators/LDOs
-- compatible:
- - "ti,twl4030-vaux1" for VAUX1 LDO
- - "ti,twl4030-vaux2" for VAUX2 LDO
- - "ti,twl5030-vaux2" for VAUX2 LDO
- - "ti,twl4030-vaux3" for VAUX3 LDO
- - "ti,twl4030-vaux4" for VAUX4 LDO
- - "ti,twl4030-vmmc1" for VMMC1 LDO
- - "ti,twl4030-vmmc2" for VMMC2 LDO
- - "ti,twl4030-vpll1" for VPLL1 LDO
- - "ti,twl4030-vpll2" for VPLL2 LDO
- - "ti,twl4030-vsim" for VSIM LDO
- - "ti,twl4030-vdac" for VDAC LDO
- - "ti,twl4030-vintana2" for VINTANA2 LDO
- - "ti,twl4030-vio" for VIO LDO
- - "ti,twl4030-vdd1" for VDD1 SMPS
- - "ti,twl4030-vdd2" for VDD2 SMPS
- - "ti,twl4030-vintana1" for VINTANA1 LDO
- - "ti,twl4030-vintdig" for VINTDIG LDO
- - "ti,twl4030-vusb1v5" for VUSB1V5 LDO
- - "ti,twl4030-vusb1v8" for VUSB1V8 LDO
- - "ti,twl4030-vusb3v1" for VUSB3V1 LDO
-
-Optional properties:
-- Any optional property defined in bindings/regulator/regulator.txt
-
-Example:
-
- xyz: regulator@0 {
- compatible = "ti,twl6030-vaux1";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <3000000>;
- };
diff --git a/Documentation/devicetree/bindings/rtc/twl-rtc.txt b/Documentation/devicetree/bindings/rtc/twl-rtc.txt
deleted file mode 100644
index 596e0c97be7a..000000000000
--- a/Documentation/devicetree/bindings/rtc/twl-rtc.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-* TI twl RTC
-
-The TWL family (twl4030/6030) contains a RTC.
-
-Required properties:
-- compatible : Should be twl4030-rtc
-
-Examples:
-
-rtc@0 {
- compatible = "ti,twl4030-rtc";
-};
diff --git a/Documentation/devicetree/bindings/sound/nokia,rx51.txt b/Documentation/devicetree/bindings/sound/nokia,rx51.txt
new file mode 100644
index 000000000000..72f93d996273
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/nokia,rx51.txt
@@ -0,0 +1,27 @@
+* Nokia N900 audio setup
+
+Required properties:
+- compatible: Should contain "nokia,n900-audio"
+- nokia,cpu-dai: phandle for the McBSP node
+- nokia,audio-codec: phandles for the main TLV320AIC3X node and the
+ auxiliary TLV320AIC3X node (in this order)
+- nokia,headphone-amplifier: phandle for the TPA6130A2 node
+- tvout-selection-gpios: GPIO for tvout selection
+- jack-detection-gpios: GPIO for jack detection
+- eci-switch-gpios: GPIO for ECI (Enhancement Control Interface) switch
+- speaker-amplifier-gpios: GPIO for speaker amplifier
+
+Example:
+
+sound {
+ compatible = "nokia,n900-audio";
+
+ nokia,cpu-dai = <&mcbsp2>;
+ nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>;
+ nokia,headphone-amplifier = <&tpa6130a2>;
+
+ tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */
+ jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */
+ eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */
+ speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
+};
diff --git a/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt b/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt
deleted file mode 100644
index 0aee0ad3f035..000000000000
--- a/Documentation/devicetree/bindings/usb/twlxxxx-usb.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-USB COMPARATOR OF TWL CHIPS
-
-TWL6030 USB COMPARATOR
- - compatible : Should be "ti,twl6030-usb"
- - interrupts : Two interrupt numbers to the cpu should be specified. First
- interrupt number is the otg interrupt number that raises ID interrupts when
- the controller has to act as host and the second interrupt number is the
- usb interrupt number that raises VBUS interrupts when the controller has to
- act as device
- - usb-supply : phandle to the regulator device tree node. It should be vusb
- if it is twl6030 or ldousb if it is twl6032 subclass.
-
-twl6030-usb {
- compatible = "ti,twl6030-usb";
- interrupts = < 4 10 >;
-};
-
-Board specific device node entry
-&twl6030-usb {
- usb-supply = <&vusb>;
-};
-
-TWL4030 USB PHY AND COMPARATOR
- - compatible : Should be "ti,twl4030-usb"
- - interrupts : The interrupt numbers to the cpu should be specified. First
- interrupt number is the otg interrupt number that raises ID interrupts
- and VBUS interrupts. The second interrupt number is optional.
- - <supply-name>-supply : phandle to the regulator device tree node.
- <supply-name> should be vusb1v5, vusb1v8 and vusb3v1
- - usb_mode : The mode used by the phy to connect to the controller. "1"
- specifies "ULPI" mode and "2" specifies "CEA2011_3PIN" mode.
-
-twl4030-usb {
- compatible = "ti,twl4030-usb";
- interrupts = < 10 4 >;
- usb1v5-supply = <&vusb1v5>;
- usb1v8-supply = <&vusb1v8>;
- usb3v1-supply = <&vusb3v1>;
- usb_mode = <1>;
-};
diff --git a/Documentation/devicetree/bindings/watchdog/twl4030-wdt.txt b/Documentation/devicetree/bindings/watchdog/twl4030-wdt.txt
deleted file mode 100644
index 80a37193c0b8..000000000000
--- a/Documentation/devicetree/bindings/watchdog/twl4030-wdt.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Device tree bindings for twl4030-wdt driver (TWL4030 watchdog)
-
-Required properties:
- compatible = "ti,twl4030-wdt";
-
-Example:
-
-watchdog {
- compatible = "ti,twl4030-wdt";
-};
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index 3cd899dbd546..01c55354f613 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -10,6 +10,7 @@
/dts-v1/;
#include "omap34xx-hs.dtsi"
+#include <dt-bindings/input/input.h>
/ {
model = "Nokia N900";
@@ -90,6 +91,25 @@
};
};
};
+
+ sound: n900-audio {
+ compatible = "nokia,n900-audio";
+
+ nokia,cpu-dai = <&mcbsp2>;
+ nokia,audio-codec = <&tlv320aic3x>, <&tlv320aic3x_aux>;
+ nokia,headphone-amplifier = <&tpa6130a2>;
+
+ tvout-selection-gpios = <&gpio2 8 GPIO_ACTIVE_HIGH>; /* 40 */
+ jack-detection-gpios = <&gpio6 17 GPIO_ACTIVE_HIGH>; /* 177 */
+ eci-switch-gpios = <&gpio6 22 GPIO_ACTIVE_HIGH>; /* 182 */
+ speaker-amplifier-gpios = <&twl_gpio 7 GPIO_ACTIVE_HIGH>;
+ };
+
+ battery: n900-battery {
+ compatible = "nokia,n900-battery";
+ io-channels = <&twl_madc 0>, <&twl_madc 4>, <&twl_madc 12>;
+ io-channel-names = "temp", "bsi", "vbat";
+ };
};
&omap3_pmx_core {
@@ -130,6 +150,15 @@
>;
};
+ mcspi4_pins: pinmux_mcspi4_pins {
+ pinctrl-single,pins = <
+ 0x15c (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_clk */
+ 0x162 (PIN_INPUT_PULLDOWN | MUX_MODE1) /* mcspi4_somi */
+ 0x160 (PIN_OUTPUT | MUX_MODE1) /* mcspi4_simo */
+ 0x166 (PIN_OUTPUT | MUX_MODE1) /* mcspi4_cs0 */
+ >;
+ };
+
mmc1_pins: pinmux_mmc1_pins {
pinctrl-single,pins = <
0x114 (PIN_INPUT_PULLUP | MUX_MODE0) /* sdmmc1_clk */
@@ -174,6 +203,20 @@
>;
};
+ wl1251_pins: pinmux_wl1251 {
+ pinctrl-single,pins = <
+ 0x0ce (PIN_OUTPUT | MUX_MODE4) /* gpio 87 => wl1251 enable */
+ 0x05a (PIN_INPUT | MUX_MODE4) /* gpio 42 => wl1251 irq */
+ >;
+ };
+
+ fmtx_pins: pinmux_fmtx {
+ pinctrl-single,pins = <
+ 0x082 (PIN_INPUT | MUX_MODE4) /* 53 => fmtx irq */
+ 0x16a (PIN_OUTPUT | MUX_MODE4) /* 163 => fmtx reset */
+ >;
+ };
+
ssi_pins: pinmux_ssi {
pinctrl-single,pins = <
0x150 (PIN_INPUT_PULLUP | MUX_MODE1) /* ssi1_rdy_tx */
@@ -307,57 +350,57 @@
};
&twl_keypad {
- linux,keymap = < 0x00000010 /* KEY_Q */
- 0x00010018 /* KEY_O */
- 0x00020019 /* KEY_P */
- 0x00030033 /* KEY_COMMA */
- 0x0004000e /* KEY_BACKSPACE */
- 0x0006001e /* KEY_A */
- 0x0007001f /* KEY_S */
-
- 0x01000011 /* KEY_W */
- 0x01010020 /* KEY_D */
- 0x01020021 /* KEY_F */
- 0x01030022 /* KEY_G */
- 0x01040023 /* KEY_H */
- 0x01050024 /* KEY_J */
- 0x01060025 /* KEY_K */
- 0x01070026 /* KEY_L */
-
- 0x02000012 /* KEY_E */
- 0x02010034 /* KEY_DOT */
- 0x02020067 /* KEY_UP */
- 0x0203001c /* KEY_ENTER */
- 0x0205002c /* KEY_Z */
- 0x0206002d /* KEY_X */
- 0x0207002e /* KEY_C */
- 0x02080043 /* KEY_F9 */
-
- 0x03000013 /* KEY_R */
- 0x0301002f /* KEY_V */
- 0x03020030 /* KEY_B */
- 0x03030031 /* KEY_N */
- 0x03040032 /* KEY_M */
- 0x03050039 /* KEY_SPACE */
- 0x03060039 /* KEY_SPACE */
- 0x03070069 /* KEY_LEFT */
-
- 0x04000014 /* KEY_T */
- 0x0401006c /* KEY_DOWN */
- 0x0402006a /* KEY_RIGHT */
- 0x0404001d /* KEY_LEFTCTRL */
- 0x04050064 /* KEY_RIGHTALT */
- 0x0406002a /* KEY_LEFTSHIFT */
- 0x04080044 /* KEY_F10 */
-
- 0x05000015 /* KEY_Y */
- 0x05080057 /* KEY_F11 */
-
- 0x06000016 /* KEY_U */
-
- 0x07000017 /* KEY_I */
- 0x07010041 /* KEY_F7 */
- 0x07020042 /* KEY_F8 */
+ linux,keymap = < MATRIX_KEY(0x00, 0x00, KEY_Q)
+ MATRIX_KEY(0x00, 0x01, KEY_O)
+ MATRIX_KEY(0x00, 0x02, KEY_P)
+ MATRIX_KEY(0x00, 0x03, KEY_COMMA)
+ MATRIX_KEY(0x00, 0x04, KEY_BACKSPACE)
+ MATRIX_KEY(0x00, 0x06, KEY_A)
+ MATRIX_KEY(0x00, 0x07, KEY_S)
+
+ MATRIX_KEY(0x01, 0x00, KEY_W)
+ MATRIX_KEY(0x01, 0x01, KEY_D)
+ MATRIX_KEY(0x01, 0x02, KEY_F)
+ MATRIX_KEY(0x01, 0x03, KEY_G)
+ MATRIX_KEY(0x01, 0x04, KEY_H)
+ MATRIX_KEY(0x01, 0x05, KEY_J)
+ MATRIX_KEY(0x01, 0x06, KEY_K)
+ MATRIX_KEY(0x01, 0x07, KEY_L)
+
+ MATRIX_KEY(0x02, 0x00, KEY_E)
+ MATRIX_KEY(0x02, 0x01, KEY_DOT)
+ MATRIX_KEY(0x02, 0x02, KEY_UP)
+ MATRIX_KEY(0x02, 0x03, KEY_ENTER)
+ MATRIX_KEY(0x02, 0x05, KEY_Z)
+ MATRIX_KEY(0x02, 0x06, KEY_X)
+ MATRIX_KEY(0x02, 0x07, KEY_C)
+ MATRIX_KEY(0x02, 0x08, KEY_F9)
+
+ MATRIX_KEY(0x03, 0x00, KEY_R)
+ MATRIX_KEY(0x03, 0x01, KEY_V)
+ MATRIX_KEY(0x03, 0x02, KEY_B)
+ MATRIX_KEY(0x03, 0x03, KEY_N)
+ MATRIX_KEY(0x03, 0x04, KEY_M)
+ MATRIX_KEY(0x03, 0x05, KEY_SPACE)
+ MATRIX_KEY(0x03, 0x06, KEY_SPACE)
+ MATRIX_KEY(0x03, 0x07, KEY_LEFT)
+
+ MATRIX_KEY(0x04, 0x00, KEY_T)
+ MATRIX_KEY(0x04, 0x01, KEY_DOWN)
+ MATRIX_KEY(0x04, 0x02, KEY_RIGHT)
+ MATRIX_KEY(0x04, 0x04, KEY_LEFTCTRL)
+ MATRIX_KEY(0x04, 0x05, KEY_RIGHTALT)
+ MATRIX_KEY(0x04, 0x06, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x04, 0x08, KEY_F10)
+
+ MATRIX_KEY(0x05, 0x00, KEY_Y)
+ MATRIX_KEY(0x05, 0x08, KEY_F11)
+
+ MATRIX_KEY(0x06, 0x00, KEY_U)
+
+ MATRIX_KEY(0x07, 0x00, KEY_I)
+ MATRIX_KEY(0x07, 0x01, KEY_F7)
+ MATRIX_KEY(0x07, 0x02, KEY_F8)
>;
};
@@ -480,6 +523,19 @@
power-gpio = <&gpio4 2 GPIO_ACTIVE_HIGH>; /* 98 */
};
+ fmtx: si4713@63 {
+ compatible = "silabs,si4713";
+ reg = <0x63>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&fmtx_pins>;
+
+ interrupts-extended = <&gpio2 21 IRQ_TYPE_EDGE_FALLING>; /* 53 */
+ reset-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>; /* 163 */
+ vio-supply = <&vio>;
+ vdd-supply = <&vaux1>;
+ };
+
bq24150a: bq24150a@6b {
compatible = "ti,bq24150a";
reg = <0x6b>;
@@ -500,6 +556,58 @@
pinctrl-0 = <&i2c3_pins>;
clock-frequency = <400000>;
+
+ lis302dl: lis3lv02d@1d {
+ compatible = "st,lis3lv02d";
+ reg = <0x1d>;
+
+ Vdd-supply = <&vaux1>;
+ Vdd_IO-supply = <&vio>;
+
+ interrupt-parent = <&gpio6>;
+ interrupts = <21 20>; /* 181 and 180 */
+
+ /* click flags */
+ st,click-single-x;
+ st,click-single-y;
+ st,click-single-z;
+
+ /* Limits are 0.5g * value */
+ st,click-threshold-x = <8>;
+ st,click-threshold-y = <8>;
+ st,click-threshold-z = <10>;
+
+ /* Click must be longer than time limit */
+ st,click-time-limit = <9>;
+
+ /* Kind of debounce filter */
+ st,click-latency = <50>;
+
+ /* Interrupt line 2 for click detection */
+ st,irq2-click;
+
+ st,wakeup-x-hi;
+ st,wakeup-y-hi;
+ st,wakeup-threshold = <(800/18)>; /* millig-value / 18 to get HW values */
+
+ st,wakeup2-z-hi;
+ st,wakeup2-threshold = <(900/18)>; /* millig-value / 18 to get HW values */
+
+ st,hipass1-disable;
+ st,hipass2-disable;
+
+ st,axis-x = <1>; /* LIS3_DEV_X */
+ st,axis-y = <(-2)>; /* LIS3_INV_DEV_Y */
+ st,axis-z = <(-3)>; /* LIS3_INV_DEV_Z */
+
+ st,min-limit-x = <(-32)>;
+ st,min-limit-y = <3>;
+ st,min-limit-z = <3>;
+
+ st,max-limit-x = <(-3)>;
+ st,max-limit-y = <32>;
+ st,max-limit-z = <32>;
+ };
};
&mmc1 {
@@ -507,7 +615,7 @@
pinctrl-0 = <&mmc1_pins>;
vmmc-supply = <&vmmc1>;
bus-width = <4>;
- cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; /* 160 */
+ /* cd-gpios = <&gpio6 0 GPIO_ACTIVE_HIGH>; */ /* 160 */
};
/* most boards use vaux3, only some old versions use vmmc2 instead */
@@ -604,9 +712,22 @@
* Also... order in the device tree actually matters here.
*/
tsc2005@0 {
- compatible = "tsc2005";
+ compatible = "ti,tsc2005";
spi-max-frequency = <6000000>;
reg = <0>;
+
+ reset-gpios = <&gpio4 8 GPIO_ACTIVE_HIGH>; /* 104 */
+ interrupts-extended = <&gpio4 4 IRQ_TYPE_NONE>; /* 100 */
+
+ touchscreen-fuzz-x = <4>;
+ touchscreen-fuzz-y = <7>;
+ touchscreen-fuzz-pressure = <2>;
+ touchscreen-max-x = <4096>;
+ touchscreen-max-y = <4096>;
+ touchscreen-max-pressure = <2048>;
+
+ ti,x-plate-ohms = <280>;
+ ti,esd-recovery-timeout-ms = <8000>;
};
acx565akm@2 {
@@ -628,6 +749,30 @@
};
};
+&mcspi4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&mcspi4_pins>;
+
+ wl1251@0 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&wl1251_pins>;
+
+ vio-supply = <&vio>;
+
+ compatible = "ti,wl1251";
+ reg = <0>;
+ spi-max-frequency = <48000000>;
+
+ spi-cpol;
+ spi-cpha;
+
+ ti,power-gpio = <&gpio3 23 GPIO_ACTIVE_HIGH>; /* 87 */
+
+ interrupt-parent = <&gpio2>;
+ interrupts = <10 IRQ_TYPE_NONE>; /* gpio line 42 */
+ };
+};
+
&usb_otg_hs {
interface-type = <0>;
usb-phy = <&usb2_phy>;
@@ -644,11 +789,13 @@
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&uart2_pins>;
+ interrupts-extended = <&intc 73 &omap3_pmx_core OMAP3_UART2_RX>;
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&uart3_pins>;
+ interrupts-extended = <&intc 74 &omap3_pmx_core OMAP3_UART3_RX>;
};
&dss {
diff --git a/arch/arm/boot/dts/omap3.dtsi b/arch/arm/boot/dts/omap3.dtsi
index b8cd2d78347b..3ac5ba7154a4 100644
--- a/arch/arm/boot/dts/omap3.dtsi
+++ b/arch/arm/boot/dts/omap3.dtsi
@@ -277,7 +277,7 @@
uart2: serial@4806c000 {
compatible = "ti,omap3-uart";
reg = <0x4806c000 0x400>;
- interrupts = <73>;
+ interrupts-extended = <&intc 73>;
dmas = <&sdma 51 &sdma 52>;
dma-names = "tx", "rx";
ti,hwmods = "uart2";
@@ -287,7 +287,7 @@
uart3: serial@49020000 {
compatible = "ti,omap3-uart";
reg = <0x49020000 0x400>;
- interrupts = <74>;
+ interrupts-extended = <&intc 74>;
dmas = <&sdma 53 &sdma 54>;
dma-names = "tx", "rx";
ti,hwmods = "uart3";
diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi
index 86cfc7d15ca7..36ae9160b558 100644
--- a/arch/arm/boot/dts/twl4030.dtsi
+++ b/arch/arm/boot/dts/twl4030.dtsi
@@ -152,4 +152,10 @@
keypad,num-rows = <8>;
keypad,num-columns = <8>;
};
+
+ twl_madc: madc {
+ compatible = "ti,twl4030-madc";
+ interrupts = <3>;
+ #io-channel-cells = <1>;
+ };
};
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c
index ddfc8df83c6a..6f950e37b158 100644
--- a/arch/arm/mach-omap2/board-rx51-peripherals.c
+++ b/arch/arm/mach-omap2/board-rx51-peripherals.c
@@ -23,6 +23,7 @@
#include <linux/regulator/machine.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
+#include <linux/gpio/driver.h>
#include <linux/mmc/host.h>
#include <linux/power/isp1704_charger.h>
#include <linux/platform_data/spi-omap2-mcspi.h>
@@ -38,7 +39,6 @@
#include <sound/tlv320aic3x.h>
#include <sound/tpa6130a2-plat.h>
-#include <media/radio-si4713.h>
#include <media/si4713.h>
#include <linux/platform_data/leds-lp55xx.h>
@@ -760,46 +760,17 @@ static struct regulator_init_data rx51_vintdig = {
},
};
-static const char * const si4713_supply_names[] = {
- "vio",
- "vdd",
-};
-
-static struct si4713_platform_data rx51_si4713_i2c_data __initdata_or_module = {
- .supplies = ARRAY_SIZE(si4713_supply_names),
- .supply_names = si4713_supply_names,
- .gpio_reset = RX51_FMTX_RESET_GPIO,
-};
-
-static struct i2c_board_info rx51_si4713_board_info __initdata_or_module = {
- I2C_BOARD_INFO("si4713", SI4713_I2C_ADDR_BUSEN_HIGH),
- .platform_data = &rx51_si4713_i2c_data,
-};
-
-static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = {
- .i2c_bus = 2,
- .subdev_board_info = &rx51_si4713_board_info,
-};
-
-static struct platform_device rx51_si4713_dev __initdata_or_module = {
- .name = "radio-si4713",
- .id = -1,
- .dev = {
- .platform_data = &rx51_si4713_data,
+static struct gpiod_lookup_table rx51_fmtx_gpios_table = {
+ .dev_id = "2-0063",
+ .table = {
+ GPIO_LOOKUP("gpio.6", 3, "reset", GPIO_ACTIVE_HIGH), /* 163 */
+ { },
},
};
-static __init void rx51_init_si4713(void)
+static __init void rx51_gpio_init(void)
{
- int err;
-
- err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
- if (err) {
- printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
- return;
- }
- rx51_si4713_board_info.irq = gpio_to_irq(RX51_FMTX_IRQ);
- platform_device_register(&rx51_si4713_dev);
+ gpiod_add_lookup_table(&rx51_fmtx_gpios_table);
}
static int rx51_twlgpio_setup(struct device *dev, unsigned gpio, unsigned n)
@@ -1029,7 +1000,17 @@ static struct aic3x_pdata rx51_aic3x_data2 = {
.gpio_reset = 60,
};
+static struct si4713_platform_data rx51_si4713_platform_data = {
+ .is_platform_device = true
+};
+
static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_2[] = {
+#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+ {
+ I2C_BOARD_INFO("si4713", 0x63),
+ .platform_data = &rx51_si4713_platform_data,
+ },
+#endif
{
I2C_BOARD_INFO("tlv320aic3x", 0x18),
.platform_data = &rx51_aic3x_data,
@@ -1070,6 +1051,8 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_3[] = {
static int __init rx51_i2c_init(void)
{
+ int err;
+
if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
system_rev >= SYSTEM_REV_B_USES_VAUX3) {
rx51_twldata.vaux3 = &rx51_vaux3_mmc;
@@ -1087,6 +1070,14 @@ static int __init rx51_i2c_init(void)
rx51_twldata.vdac->constraints.name = "VDAC";
omap_pmic_init(1, 2200, "twl5030", 7 + OMAP_INTC_START, &rx51_twldata);
+#if IS_ENABLED(CONFIG_I2C_SI4713) && IS_ENABLED(CONFIG_PLATFORM_SI4713)
+ err = gpio_request_one(RX51_FMTX_IRQ, GPIOF_DIR_IN, "si4713 irq");
+ if (err) {
+ printk(KERN_ERR "Cannot request si4713 irq gpio. %d\n", err);
+ return err;
+ }
+ rx51_peripherals_i2c_board_info_2[0].irq = gpio_to_irq(RX51_FMTX_IRQ);
+#endif
omap_register_i2c_bus(2, 100, rx51_peripherals_i2c_board_info_2,
ARRAY_SIZE(rx51_peripherals_i2c_board_info_2));
#if defined(CONFIG_SENSORS_LIS3_I2C) || defined(CONFIG_SENSORS_LIS3_I2C_MODULE)
@@ -1300,6 +1291,7 @@ static void __init rx51_init_omap3_rom_rng(void)
void __init rx51_peripherals_init(void)
{
+ rx51_gpio_init();
rx51_i2c_init();
regulator_has_full_constraints();
gpmc_onenand_init(board_onenand_data);
@@ -1307,7 +1299,6 @@ void __init rx51_peripherals_init(void)
rx51_add_gpio_keys();
rx51_init_wl1251();
rx51_init_tsc2005();
- rx51_init_si4713();
rx51_init_lirc();
spi_register_board_info(rx51_peripherals_spi_board_info,
ARRAY_SIZE(rx51_peripherals_spi_board_info));
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index c3b73351cb7a..fa298bd2476e 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -226,6 +226,14 @@ static void __init am3517_evm_legacy_init(void)
am35xx_emac_reset();
}
+static struct platform_device omap3_rom_rng_device = {
+ .name = "omap3-rom-rng",
+ .id = -1,
+ .dev = {
+ .platform_data = rx51_secure_rng_call,
+ },
+};
+
static void __init nokia_n900_legacy_init(void)
{
hsmmc2_internal_input_clk();
@@ -239,6 +247,10 @@ static void __init nokia_n900_legacy_init(void)
pr_warning("RX-51: Not enabling ARM errata 430973 workaround\n");
pr_warning("Thumb binaries may crash randomly without this workaround\n");
}
+
+ pr_info("RX-51: Registring OMAP3 HWRNG device\n");
+ platform_device_register(&omap3_rom_rng_device);
+
}
}
#endif /* CONFIG_ARCH_OMAP3 */
diff --git a/drivers/iio/inkern.c b/drivers/iio/inkern.c
index 0cf5f8e06cfc..adeba5a0ecf7 100644
--- a/drivers/iio/inkern.c
+++ b/drivers/iio/inkern.c
@@ -443,6 +443,24 @@ err_unlock:
}
EXPORT_SYMBOL_GPL(iio_read_channel_raw);
+int iio_read_channel_average_raw(struct iio_channel *chan, int *val)
+{
+ int ret;
+
+ mutex_lock(&chan->indio_dev->info_exist_lock);
+ if (chan->indio_dev->info == NULL) {
+ ret = -ENODEV;
+ goto err_unlock;
+ }
+
+ ret = iio_channel_read(chan, val, NULL, IIO_CHAN_INFO_AVERAGE_RAW);
+err_unlock:
+ mutex_unlock(&chan->indio_dev->info_exist_lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(iio_read_channel_average_raw);
+
static int iio_convert_raw_to_processed_unlocked(struct iio_channel *chan,
int raw, int *processed, unsigned int scale)
{
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 1c4c0db05550..97966d93e1f3 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -27,6 +27,7 @@
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/rcupdate.h>
+#include <linux/of.h>
#include "input-compat.h"
MODULE_AUTHOR("Vojtech Pavlik <vojtech@suse.cz>");
@@ -2398,6 +2399,39 @@ void input_free_minor(unsigned int minor)
}
EXPORT_SYMBOL(input_free_minor);
+#if defined(CONFIG_OF)
+/**
+ * input_parse_touchscreen_of_params - parse common touchscreen DT properties
+ * @dev: device that should be parsed
+ *
+ * This function parses common DT properties for touchscreens and setups the
+ * input device accordingly. The function keeps previously setuped default
+ * values if no value is specified via DT.
+ */
+void input_parse_touchscreen_of_params(struct input_dev *dev)
+{
+ struct device_node *np = dev->dev.parent->of_node;
+ struct input_absinfo *absinfo;
+
+ input_alloc_absinfo(dev);
+ if (!dev->absinfo)
+ return;
+
+ absinfo = &dev->absinfo[ABS_X];
+ of_property_read_u32(np, "touchscreen-size-x", &absinfo->maximum);
+ of_property_read_u32(np, "touchscreen-fuzz-x", &absinfo->fuzz);
+
+ absinfo = &dev->absinfo[ABS_Y];
+ of_property_read_u32(np, "touchscreen-size-y", &absinfo->maximum);
+ of_property_read_u32(np, "touchscreen-fuzz-y", &absinfo->fuzz);
+
+ absinfo = &dev->absinfo[ABS_PRESSURE];
+ of_property_read_u32(np, "touchscreen-max-pressure", &absinfo->maximum);
+ of_property_read_u32(np, "touchscreen-fuzz-pressure", &absinfo->fuzz);
+}
+EXPORT_SYMBOL(input_parse_touchscreen_of_params);
+#endif
+
static int __init input_init(void)
{
int err;
diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c
index 550adcbbfc23..a83d1beb2750 100644
--- a/drivers/input/touchscreen/tsc2005.c
+++ b/drivers/input/touchscreen/tsc2005.c
@@ -28,6 +28,8 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/pm.h>
+#include <linux/of.h>
+#include <linux/of_gpio.h>
#include <linux/spi/spi.h>
#include <linux/spi/tsc2005.h>
@@ -100,6 +102,11 @@
TSC2005_CFR2_AVG_7)
#define MAX_12BIT 0xfff
+#define TSC2005_DEF_X_FUZZ 4
+#define TSC2005_DEF_Y_FUZZ 8
+#define TSC2005_DEF_P_FUZZ 2
+#define TSC2005_DEF_RESISTOR 280
+
#define TSC2005_SPI_MAX_SPEED_HZ 10000000
#define TSC2005_PENUP_TIME_MS 40
@@ -143,6 +150,7 @@ struct tsc2005 {
bool pen_down;
+ int reset_gpio;
void (*set_reset)(bool enable);
};
@@ -337,6 +345,14 @@ static void tsc2005_stop_scan(struct tsc2005 *ts)
tsc2005_cmd(ts, TSC2005_CMD_STOP);
}
+static void tsc2005_set_reset(struct tsc2005 *ts, bool enable)
+{
+ if (ts->reset_gpio >= 0)
+ gpio_set_value(ts->reset_gpio, enable);
+ else if (ts->set_reset)
+ ts->set_reset(enable);
+}
+
/* must be called with ts->mutex held */
static void __tsc2005_disable(struct tsc2005 *ts)
{
@@ -355,7 +371,7 @@ static void __tsc2005_enable(struct tsc2005 *ts)
{
tsc2005_start_scan(ts);
- if (ts->esd_timeout && ts->set_reset) {
+ if (ts->esd_timeout && (ts->set_reset || ts->reset_gpio)) {
ts->last_valid_interrupt = jiffies;
schedule_delayed_work(&ts->esd_work,
round_jiffies_relative(
@@ -414,9 +430,9 @@ static ssize_t tsc2005_selftest_show(struct device *dev,
}
/* hardware reset */
- ts->set_reset(false);
+ tsc2005_set_reset(ts, false);
usleep_range(100, 500); /* only 10us required */
- ts->set_reset(true);
+ tsc2005_set_reset(ts, true);
if (!success)
goto out;
@@ -459,7 +475,7 @@ static umode_t tsc2005_attr_is_visible(struct kobject *kobj,
umode_t mode = attr->mode;
if (attr == &dev_attr_selftest.attr) {
- if (!ts->set_reset)
+ if (!ts->set_reset && !ts->reset_gpio)
mode = 0;
}
@@ -509,9 +525,9 @@ static void tsc2005_esd_work(struct work_struct *work)
tsc2005_update_pen_state(ts, 0, 0, 0);
- ts->set_reset(false);
+ tsc2005_set_reset(ts, false);
usleep_range(100, 500); /* only 10us required */
- ts->set_reset(true);
+ tsc2005_set_reset(ts, true);
enable_irq(ts->spi->irq);
tsc2005_start_scan(ts);
@@ -572,29 +588,47 @@ static void tsc2005_setup_spi_xfer(struct tsc2005 *ts)
static int tsc2005_probe(struct spi_device *spi)
{
const struct tsc2005_platform_data *pdata = dev_get_platdata(&spi->dev);
+ struct device_node *np = spi->dev.of_node;
+
struct tsc2005 *ts;
struct input_dev *input_dev;
- unsigned int max_x, max_y, max_p;
- unsigned int fudge_x, fudge_y, fudge_p;
+ unsigned int max_x = MAX_12BIT;
+ unsigned int max_y = MAX_12BIT;
+ unsigned int max_p = MAX_12BIT;
+ unsigned int fudge_x = TSC2005_DEF_X_FUZZ;
+ unsigned int fudge_y = TSC2005_DEF_Y_FUZZ;
+ unsigned int fudge_p = TSC2005_DEF_P_FUZZ;
+ unsigned int x_plate_ohm = TSC2005_DEF_RESISTOR;
+ unsigned int esd_timeout;
int error;
- if (!pdata) {
- dev_dbg(&spi->dev, "no platform data\n");
+ if (!np && !pdata) {
+ dev_err(&spi->dev, "no platform data\n");
return -ENODEV;
}
- fudge_x = pdata->ts_x_fudge ? : 4;
- fudge_y = pdata->ts_y_fudge ? : 8;
- fudge_p = pdata->ts_pressure_fudge ? : 2;
- max_x = pdata->ts_x_max ? : MAX_12BIT;
- max_y = pdata->ts_y_max ? : MAX_12BIT;
- max_p = pdata->ts_pressure_max ? : MAX_12BIT;
-
if (spi->irq <= 0) {
- dev_dbg(&spi->dev, "no irq\n");
+ dev_err(&spi->dev, "no irq\n");
return -ENODEV;
}
+ if (pdata) {
+ fudge_x = pdata->ts_x_fudge;
+ fudge_y = pdata->ts_y_fudge;
+ fudge_p = pdata->ts_pressure_fudge;
+ max_x = pdata->ts_x_max;
+ max_y = pdata->ts_y_max;
+ max_p = pdata->ts_pressure_max;
+ x_plate_ohm = pdata->ts_x_plate_ohm;
+ esd_timeout = pdata->esd_timeout_ms;
+ } else {
+ x_plate_ohm = TSC2005_DEF_RESISTOR;
+ of_property_read_u32(np, "ti,x-plate-ohms", &x_plate_ohm);
+ esd_timeout = 0;
+ of_property_read_u32(np, "ti,esd-recovery-timeout-ms",
+ &esd_timeout);
+ }
+
spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
if (!spi->max_speed_hz)
@@ -604,19 +638,38 @@ static int tsc2005_probe(struct spi_device *spi)
if (error)
return error;
- ts = kzalloc(sizeof(*ts), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ts || !input_dev) {
- error = -ENOMEM;
- goto err_free_mem;
- }
+ ts = devm_kzalloc(&spi->dev, sizeof(*ts), GFP_KERNEL);
+ input_dev = devm_input_allocate_device(&spi->dev);
+ if (!ts || !input_dev)
+ return -ENOMEM;
ts->spi = spi;
ts->idev = input_dev;
- ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280;
- ts->esd_timeout = pdata->esd_timeout_ms;
- ts->set_reset = pdata->set_reset;
+ ts->x_plate_ohm = x_plate_ohm;
+ ts->esd_timeout = esd_timeout;
+
+ if (np) {
+ ts->reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
+ if (ts->reset_gpio == -EPROBE_DEFER)
+ return ts->reset_gpio;
+ if (ts->reset_gpio < 0) {
+ dev_err(&spi->dev, "error acquiring reset gpio: %d\n",
+ ts->reset_gpio);
+ return ts->reset_gpio;
+ }
+
+ error = devm_gpio_request_one(&spi->dev, ts->reset_gpio, 0,
+ "reset-gpios");
+ if (error) {
+ dev_err(&spi->dev, "error requesting reset gpio: %d\n",
+ error);
+ return error;
+ }
+ } else {
+ ts->reset_gpio = -1;
+ ts->set_reset = pdata->set_reset;
+ }
mutex_init(&ts->mutex);
@@ -641,6 +694,9 @@ static int tsc2005_probe(struct spi_device *spi)
input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);
input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);
+ if (np)
+ input_parse_touchscreen_of_params(input_dev);
+
input_dev->open = tsc2005_open;
input_dev->close = tsc2005_close;
@@ -649,12 +705,13 @@ static int tsc2005_probe(struct spi_device *spi)
/* Ensure the touchscreen is off */
tsc2005_stop_scan(ts);
- error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread,
- IRQF_TRIGGER_RISING | IRQF_ONESHOT,
- "tsc2005", ts);
+ error = devm_request_threaded_irq(&spi->dev, spi->irq, NULL,
+ tsc2005_irq_thread,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ "tsc2005", ts);
if (error) {
dev_err(&spi->dev, "Failed to request irq, err: %d\n", error);
- goto err_free_mem;
+ return error;
}
spi_set_drvdata(spi, ts);
@@ -662,7 +719,7 @@ static int tsc2005_probe(struct spi_device *spi)
if (error) {
dev_err(&spi->dev,
"Failed to create sysfs attributes, err: %d\n", error);
- goto err_clear_drvdata;
+ return error;
}
error = input_register_device(ts->idev);
@@ -677,11 +734,6 @@ static int tsc2005_probe(struct spi_device *spi)
err_remove_sysfs:
sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group);
-err_clear_drvdata:
- free_irq(spi->irq, ts);
-err_free_mem:
- input_free_device(input_dev);
- kfree(ts);
return error;
}
@@ -691,10 +743,6 @@ static int tsc2005_remove(struct spi_device *spi)
sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group);
- free_irq(ts->spi->irq, ts);
- input_unregister_device(ts->idev);
- kfree(ts);
-
return 0;
}
diff --git a/drivers/media/radio/si4713/radio-platform-si4713.c b/drivers/media/radio/si4713/radio-platform-si4713.c
index ba4cfc946868..27f1ffb47b4c 100644
--- a/drivers/media/radio/si4713/radio-platform-si4713.c
+++ b/drivers/media/radio/si4713/radio-platform-si4713.c
@@ -34,7 +34,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-event.h>
-#include <media/radio-si4713.h>
+#include "si4713.h"
/* module parameters */
static int radio_nr = -1; /* radio device minor (-1 ==> auto assign) */
@@ -153,7 +153,6 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
{
struct radio_si4713_platform_data *pdata = pdev->dev.platform_data;
struct radio_si4713_device *rsdev;
- struct i2c_adapter *adapter;
struct v4l2_subdev *sd;
int rval = 0;
@@ -177,20 +176,11 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
goto exit;
}
- adapter = i2c_get_adapter(pdata->i2c_bus);
- if (!adapter) {
- dev_err(&pdev->dev, "Cannot get i2c adapter %d\n",
- pdata->i2c_bus);
- rval = -ENODEV;
- goto unregister_v4l2_dev;
- }
-
- sd = v4l2_i2c_new_subdev_board(&rsdev->v4l2_dev, adapter,
- pdata->subdev_board_info, NULL);
- if (!sd) {
+ sd = i2c_get_clientdata(pdata->subdev);
+ rval = v4l2_device_register_subdev(&rsdev->v4l2_dev, sd);
+ if (rval) {
dev_err(&pdev->dev, "Cannot get v4l2 subdevice\n");
- rval = -ENODEV;
- goto put_adapter;
+ goto unregister_v4l2_dev;
}
rsdev->radio_dev = radio_si4713_vdev_template;
@@ -203,14 +193,12 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
if (video_register_device(&rsdev->radio_dev, VFL_TYPE_RADIO, radio_nr)) {
dev_err(&pdev->dev, "Could not register video device.\n");
rval = -EIO;
- goto put_adapter;
+ goto unregister_v4l2_dev;
}
dev_info(&pdev->dev, "New device successfully probed\n");
goto exit;
-put_adapter:
- i2c_put_adapter(adapter);
unregister_v4l2_dev:
v4l2_device_unregister(&rsdev->v4l2_dev);
exit:
@@ -221,14 +209,10 @@ exit:
static int radio_si4713_pdriver_remove(struct platform_device *pdev)
{
struct v4l2_device *v4l2_dev = platform_get_drvdata(pdev);
- struct v4l2_subdev *sd = list_entry(v4l2_dev->subdevs.next,
- struct v4l2_subdev, list);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
struct radio_si4713_device *rsdev;
rsdev = container_of(v4l2_dev, struct radio_si4713_device, v4l2_dev);
video_unregister_device(&rsdev->radio_dev);
- i2c_put_adapter(client->adapter);
v4l2_device_unregister(&rsdev->v4l2_dev);
return 0;
diff --git a/drivers/media/radio/si4713/si4713.c b/drivers/media/radio/si4713/si4713.c
index 07d5153811e8..c12d3f9fc56a 100644
--- a/drivers/media/radio/si4713/si4713.c
+++ b/drivers/media/radio/si4713/si4713.c
@@ -23,6 +23,7 @@
#include <linux/completion.h>
#include <linux/delay.h>
+#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/slab.h>
@@ -366,16 +367,25 @@ static int si4713_powerup(struct si4713_device *sdev)
if (sdev->power_state)
return 0;
- if (sdev->supplies) {
- err = regulator_bulk_enable(sdev->supplies, sdev->supply_data);
+ if (sdev->vdd) {
+ err = regulator_enable(sdev->vdd);
if (err) {
- v4l2_err(&sdev->sd, "Failed to enable supplies: %d\n", err);
+ v4l2_err(&sdev->sd, "Failed to enable vdd: %d\n", err);
return err;
}
}
- if (gpio_is_valid(sdev->gpio_reset)) {
+
+ if (sdev->vio) {
+ err = regulator_enable(sdev->vio);
+ if (err) {
+ v4l2_err(&sdev->sd, "Failed to enable vio: %d\n", err);
+ return err;
+ }
+ }
+
+ if (!IS_ERR(sdev->gpio_reset)) {
udelay(50);
- gpio_set_value(sdev->gpio_reset, 1);
+ gpiod_set_value(sdev->gpio_reset, 1);
}
if (client->irq)
@@ -397,13 +407,20 @@ static int si4713_powerup(struct si4713_device *sdev)
SI4713_STC_INT | SI4713_CTS);
return err;
}
- if (gpio_is_valid(sdev->gpio_reset))
- gpio_set_value(sdev->gpio_reset, 0);
- if (sdev->supplies) {
- err = regulator_bulk_disable(sdev->supplies, sdev->supply_data);
+ if (!IS_ERR(sdev->gpio_reset))
+ gpiod_set_value(sdev->gpio_reset, 0);
+
+
+ if (sdev->vdd) {
+ err = regulator_disable(sdev->vdd);
if (err)
- v4l2_err(&sdev->sd,
- "Failed to disable supplies: %d\n", err);
+ v4l2_err(&sdev->sd, "Failed to disable vdd: %d\n", err);
+ }
+
+ if (sdev->vio) {
+ err = regulator_disable(sdev->vio);
+ if (err)
+ v4l2_err(&sdev->sd, "Failed to disable vio: %d\n", err);
}
return err;
@@ -430,15 +447,25 @@ static int si4713_powerdown(struct si4713_device *sdev)
v4l2_dbg(1, debug, &sdev->sd, "Power down response: 0x%02x\n",
resp[0]);
v4l2_dbg(1, debug, &sdev->sd, "Device in reset mode\n");
- if (gpio_is_valid(sdev->gpio_reset))
- gpio_set_value(sdev->gpio_reset, 0);
- if (sdev->supplies) {
- err = regulator_bulk_disable(sdev->supplies,
- sdev->supply_data);
- if (err)
+ if (!IS_ERR(sdev->gpio_reset))
+ gpiod_set_value(sdev->gpio_reset, 0);
+
+ if (sdev->vdd) {
+ err = regulator_disable(sdev->vdd);
+ if (err) {
+ v4l2_err(&sdev->sd,
+ "Failed to disable vdd: %d\n", err);
+ }
+ }
+
+ if (sdev->vio) {
+ err = regulator_disable(sdev->vio);
+ if (err) {
v4l2_err(&sdev->sd,
- "Failed to disable supplies: %d\n", err);
+ "Failed to disable vio: %d\n", err);
+ }
}
+
sdev->power_state = POWER_OFF;
}
@@ -1363,38 +1390,50 @@ static int si4713_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct si4713_device *sdev;
- struct si4713_platform_data *pdata = client->dev.platform_data;
struct v4l2_ctrl_handler *hdl;
- int rval, i;
+ struct si4713_platform_data *pdata = client->dev.platform_data;
+ struct device_node *np = client->dev.of_node;
+ int rval;
+
+ struct radio_si4713_platform_data si4713_pdev_pdata;
+ struct platform_device *si4713_pdev;
- sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
+ sdev = devm_kzalloc(&client->dev, sizeof(*sdev), GFP_KERNEL);
if (!sdev) {
dev_err(&client->dev, "Failed to alloc video device.\n");
rval = -ENOMEM;
goto exit;
}
- sdev->gpio_reset = -1;
- if (pdata && gpio_is_valid(pdata->gpio_reset)) {
- rval = gpio_request(pdata->gpio_reset, "si4713 reset");
- if (rval) {
- dev_err(&client->dev,
- "Failed to request gpio: %d\n", rval);
- goto free_sdev;
- }
- sdev->gpio_reset = pdata->gpio_reset;
- gpio_direction_output(sdev->gpio_reset, 0);
- sdev->supplies = pdata->supplies;
+ sdev->gpio_reset = devm_gpiod_get(&client->dev, "reset");
+ if (!IS_ERR(sdev->gpio_reset)) {
+ gpiod_direction_output(sdev->gpio_reset, 0);
+ } else if (PTR_ERR(sdev->gpio_reset) == -ENOENT) {
+ dev_dbg(&client->dev, "No reset GPIO assigned\n");
+ } else {
+ rval = PTR_ERR(sdev->gpio_reset);
+ dev_err(&client->dev, "Failed to request gpio: %d\n", rval);
+ goto exit;
}
- for (i = 0; i < sdev->supplies; i++)
- sdev->supply_data[i].supply = pdata->supply_names[i];
+ sdev->vdd = devm_regulator_get_optional(&client->dev, "vdd");
+ if (IS_ERR(sdev->vdd)) {
+ rval = PTR_ERR(sdev->vdd);
+ if (rval == -EPROBE_DEFER)
+ goto exit;
- rval = regulator_bulk_get(&client->dev, sdev->supplies,
- sdev->supply_data);
- if (rval) {
- dev_err(&client->dev, "Cannot get regulators: %d\n", rval);
- goto free_gpio;
+ dev_info(&client->dev, "no vdd regulator found: %d\n", rval);
+ sdev->vdd = NULL;
+ }
+
+ sdev->vio = devm_regulator_get_optional(&client->dev, "vio");
+ if (IS_ERR(sdev->vio)) {
+ rval = PTR_ERR(sdev->vio);
+ if (rval == -EPROBE_DEFER)
+ goto exit;
+
+ dev_info(&client->dev, "no vio regulator found: %d\n", rval);
+ sdev->vio = NULL;
}
v4l2_i2c_subdev_init(&sdev->sd, client, &si4713_subdev_ops);
@@ -1480,12 +1519,12 @@ static int si4713_probe(struct i2c_client *client,
sdev->sd.ctrl_handler = hdl;
if (client->irq) {
- rval = request_irq(client->irq,
+ rval = devm_request_irq(&client->dev, client->irq,
si4713_handler, IRQF_TRIGGER_FALLING,
client->name, sdev);
if (rval < 0) {
v4l2_err(&sdev->sd, "Could not request IRQ\n");
- goto put_reg;
+ goto free_ctrls;
}
v4l2_dbg(1, debug, &sdev->sd, "IRQ requested.\n");
} else {
@@ -1495,23 +1534,36 @@ static int si4713_probe(struct i2c_client *client,
rval = si4713_initialize(sdev);
if (rval < 0) {
v4l2_err(&sdev->sd, "Failed to probe device information.\n");
- goto free_irq;
+ goto free_ctrls;
+ }
+
+ if ((pdata && pdata->is_platform_device) || np) {
+ si4713_pdev = platform_device_alloc("radio-si4713", -1);
+ if (!si4713_pdev)
+ goto put_main_pdev;
+
+ si4713_pdev_pdata.subdev = client;
+ rval = platform_device_add_data(si4713_pdev, &si4713_pdev_pdata,
+ sizeof(si4713_pdev_pdata));
+ if (rval)
+ goto put_main_pdev;
+
+ rval = platform_device_add(si4713_pdev);
+ if (rval)
+ goto put_main_pdev;
+
+ sdev->pd = si4713_pdev;
+ } else {
+ sdev->pd = NULL;
}
return 0;
-free_irq:
- if (client->irq)
- free_irq(client->irq, sdev);
+put_main_pdev:
+ platform_device_put(si4713_pdev);
+ v4l2_device_unregister_subdev(&sdev->sd);
free_ctrls:
v4l2_ctrl_handler_free(hdl);
-put_reg:
- regulator_bulk_free(sdev->supplies, sdev->supply_data);
-free_gpio:
- if (gpio_is_valid(sdev->gpio_reset))
- gpio_free(sdev->gpio_reset);
-free_sdev:
- kfree(sdev);
exit:
return rval;
}
@@ -1522,18 +1574,14 @@ static int si4713_remove(struct i2c_client *client)
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct si4713_device *sdev = to_si4713_device(sd);
+ if (sdev->pd)
+ platform_device_unregister(sdev->pd);
+
if (sdev->power_state)
si4713_set_power_state(sdev, POWER_DOWN);
- if (client->irq > 0)
- free_irq(client->irq, sdev);
-
v4l2_device_unregister_subdev(sd);
v4l2_ctrl_handler_free(sd->ctrl_handler);
- regulator_bulk_free(sdev->supplies, sdev->supply_data);
- if (gpio_is_valid(sdev->gpio_reset))
- gpio_free(sdev->gpio_reset);
- kfree(sdev);
return 0;
}
diff --git a/drivers/media/radio/si4713/si4713.h b/drivers/media/radio/si4713/si4713.h
index 4837cf6e0e1b..2ff772e75887 100644
--- a/drivers/media/radio/si4713/si4713.h
+++ b/drivers/media/radio/si4713/si4713.h
@@ -15,7 +15,9 @@
#ifndef SI4713_I2C_H
#define SI4713_I2C_H
+#include <linux/platform_device.h>
#include <linux/regulator/consumer.h>
+#include <linux/gpio/consumer.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-ctrls.h>
#include <media/si4713.h>
@@ -190,8 +192,6 @@
#define MIN_ACOMP_THRESHOLD (-40)
#define MAX_ACOMP_GAIN 20
-#define SI4713_NUM_SUPPLIES 2
-
/*
* si4713_device - private data
*/
@@ -227,9 +227,10 @@ struct si4713_device {
struct v4l2_ctrl *tune_ant_cap;
};
struct completion work;
- unsigned supplies;
- struct regulator_bulk_data supply_data[SI4713_NUM_SUPPLIES];
- int gpio_reset;
+ struct regulator *vdd;
+ struct regulator *vio;
+ struct gpio_desc *gpio_reset;
+ struct platform_device *pd;
u32 power_state;
u32 rds_enabled;
u32 frequency;
@@ -237,4 +238,8 @@ struct si4713_device {
u32 stereo;
u32 tune_rnl;
};
+
+struct radio_si4713_platform_data {
+ struct i2c_client *subdev;
+};
#endif /* ifndef SI4713_I2C_H */
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 8fbd377e6311..1cc2f77678d4 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -301,7 +301,7 @@ config IR_TTUSBIR
config IR_RX51
tristate "Nokia N900 IR transmitter diode"
- depends on OMAP_DM_TIMER && ARCH_OMAP2PLUS && LIRC && !ARCH_MULTIPLATFORM
+ depends on OMAP_DM_TIMER && ARCH_OMAP2PLUS && LIRC
---help---
Say Y or M here if you want to enable support for the IR
transmitter diode built in the Nokia N900 (RX51) device.
diff --git a/drivers/media/rc/ir-rx51.c b/drivers/media/rc/ir-rx51.c
index b1e19a26208d..be29bd0901f1 100644
--- a/drivers/media/rc/ir-rx51.c
+++ b/drivers/media/rc/ir-rx51.c
@@ -25,9 +25,9 @@
#include <linux/platform_device.h>
#include <linux/sched.h>
#include <linux/wait.h>
+#include <linux/clk.h>
-#include <plat/dmtimer.h>
-#include <plat/clock.h>
+#include "../../../arch/arm/plat-omap/include/plat/dmtimer.h"
#include <media/lirc.h>
#include <media/lirc_dev.h>
@@ -208,7 +208,7 @@ static int lirc_rx51_init_port(struct lirc_rx51 *lirc_rx51)
}
clk_fclk = omap_dm_timer_get_fclk(lirc_rx51->pwm_timer);
- lirc_rx51->fclk_khz = clk_fclk->rate / 1000;
+ lirc_rx51->fclk_khz = clk_get_rate(clk_fclk) / 1000;
return 0;
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c
index 3ef4627f9cb1..4739689d23ad 100644
--- a/drivers/misc/lis3lv02d/lis3lv02d.c
+++ b/drivers/misc/lis3lv02d/lis3lv02d.c
@@ -950,6 +950,7 @@ int lis3lv02d_init_dt(struct lis3lv02d *lis3)
struct lis3lv02d_platform_data *pdata;
struct device_node *np = lis3->of_node;
u32 val;
+ s32 sval;
if (!lis3->of_node)
return 0;
@@ -1031,6 +1032,23 @@ int lis3lv02d_init_dt(struct lis3lv02d *lis3)
pdata->wakeup_flags |= LIS3_WAKEUP_Z_LO;
if (of_get_property(np, "st,wakeup-z-hi", NULL))
pdata->wakeup_flags |= LIS3_WAKEUP_Z_HI;
+ if (of_get_property(np, "st,wakeup-threshold", &val))
+ pdata->wakeup_thresh = val;
+
+ if (of_get_property(np, "st,wakeup2-x-lo", NULL))
+ pdata->wakeup_flags2 |= LIS3_WAKEUP_X_LO;
+ if (of_get_property(np, "st,wakeup2-x-hi", NULL))
+ pdata->wakeup_flags2 |= LIS3_WAKEUP_X_HI;
+ if (of_get_property(np, "st,wakeup2-y-lo", NULL))
+ pdata->wakeup_flags2 |= LIS3_WAKEUP_Y_LO;
+ if (of_get_property(np, "st,wakeup2-y-hi", NULL))
+ pdata->wakeup_flags2 |= LIS3_WAKEUP_Y_HI;
+ if (of_get_property(np, "st,wakeup2-z-lo", NULL))
+ pdata->wakeup_flags2 |= LIS3_WAKEUP_Z_LO;
+ if (of_get_property(np, "st,wakeup2-z-hi", NULL))
+ pdata->wakeup_flags2 |= LIS3_WAKEUP_Z_HI;
+ if (of_get_property(np, "st,wakeup2-threshold", &val))
+ pdata->wakeup_thresh2 = val;
if (!of_property_read_u32(np, "st,highpass-cutoff-hz", &val)) {
switch (val) {
@@ -1054,29 +1072,29 @@ int lis3lv02d_init_dt(struct lis3lv02d *lis3)
if (of_get_property(np, "st,hipass2-disable", NULL))
pdata->hipass_ctrl |= LIS3_HIPASS2_DISABLE;
- if (of_get_property(np, "st,axis-x", &val))
- pdata->axis_x = val;
- if (of_get_property(np, "st,axis-y", &val))
- pdata->axis_y = val;
- if (of_get_property(np, "st,axis-z", &val))
- pdata->axis_z = val;
+ if (of_property_read_s32(np, "st,axis-x", &sval) == 0)
+ pdata->axis_x = sval;
+ if (of_property_read_s32(np, "st,axis-y", &sval) == 0)
+ pdata->axis_y = sval;
+ if (of_property_read_s32(np, "st,axis-z", &sval) == 0)
+ pdata->axis_z = sval;
if (of_get_property(np, "st,default-rate", NULL))
pdata->default_rate = val;
- if (of_get_property(np, "st,min-limit-x", &val))
- pdata->st_min_limits[0] = val;
- if (of_get_property(np, "st,min-limit-y", &val))
- pdata->st_min_limits[1] = val;
- if (of_get_property(np, "st,min-limit-z", &val))
- pdata->st_min_limits[2] = val;
-
- if (of_get_property(np, "st,max-limit-x", &val))
- pdata->st_max_limits[0] = val;
- if (of_get_property(np, "st,max-limit-y", &val))
- pdata->st_max_limits[1] = val;
- if (of_get_property(np, "st,max-limit-z", &val))
- pdata->st_max_limits[2] = val;
+ if (of_property_read_s32(np, "st,min-limit-x", &sval) == 0)
+ pdata->st_min_limits[0] = sval;
+ if (of_property_read_s32(np, "st,min-limit-y", &sval) == 0)
+ pdata->st_min_limits[1] = sval;
+ if (of_property_read_s32(np, "st,min-limit-z", &sval) == 0)
+ pdata->st_min_limits[2] = sval;
+
+ if (of_property_read_s32(np, "st,max-limit-x", &sval) == 0)
+ pdata->st_max_limits[0] = sval;
+ if (of_property_read_s32(np, "st,max-limit-y", &sval) == 0)
+ pdata->st_max_limits[1] = sval;
+ if (of_property_read_s32(np, "st,max-limit-z", &sval) == 0)
+ pdata->st_max_limits[2] = sval;
lis3->pdata = pdata;
diff --git a/drivers/power/bq2415x_charger.c b/drivers/power/bq2415x_charger.c
index 79a37f6d3307..e384844a1ae1 100644
--- a/drivers/power/bq2415x_charger.c
+++ b/drivers/power/bq2415x_charger.c
@@ -840,8 +840,7 @@ static int bq2415x_notifier_call(struct notifier_block *nb,
if (bq->automode < 1)
return NOTIFY_OK;
- sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
- bq2415x_set_mode(bq, bq->reported_mode);
+ schedule_delayed_work(&bq->work, 0);
return NOTIFY_OK;
}
@@ -892,6 +891,11 @@ static void bq2415x_timer_work(struct work_struct *work)
int error;
int boost;
+ if (bq->automode > 0 && (bq->reported_mode != bq->mode)) {
+ sysfs_notify(&bq->charger.dev->kobj, NULL, "reported_mode");
+ bq2415x_set_mode(bq, bq->reported_mode);
+ }
+
if (!bq->autotimer)
return;
diff --git a/drivers/power/rx51_battery.c b/drivers/power/rx51_battery.c
index 1bc5857b8bd5..d5a2acfb8821 100644
--- a/drivers/power/rx51_battery.c
+++ b/drivers/power/rx51_battery.c
@@ -24,34 +24,27 @@
#include <linux/power_supply.h>
#include <linux/slab.h>
#include <linux/i2c/twl4030-madc.h>
-
-/* RX51 specific channels */
-#define TWL4030_MADC_BTEMP_RX51 TWL4030_MADC_ADCIN0
-#define TWL4030_MADC_BCI_RX51 TWL4030_MADC_ADCIN4
+#include <linux/iio/consumer.h>
+#include <linux/of.h>
struct rx51_device_info {
struct device *dev;
struct power_supply bat;
+ struct iio_channel *channel_temp;
+ struct iio_channel *channel_bsi;
+ struct iio_channel *channel_vbat;
};
/*
* Read ADCIN channel value, code copied from maemo kernel
*/
-static int rx51_battery_read_adc(int channel)
+static int rx51_battery_read_adc(struct iio_channel *channel)
{
- struct twl4030_madc_request req;
-
- req.channels = channel;
- req.do_avg = 1;
- req.method = TWL4030_MADC_SW1;
- req.func_cb = NULL;
- req.type = TWL4030_MADC_WAIT;
- req.raw = true;
-
- if (twl4030_madc_conversion(&req) <= 0)
- return -ENODATA;
-
- return req.rbuf[ffs(channel) - 1];
+ int val, err;
+ err = iio_read_channel_average_raw(channel, &val);
+ if (err < 0)
+ return err;
+ return val;
}
/*
@@ -60,10 +53,12 @@ static int rx51_battery_read_adc(int channel)
*/
static int rx51_battery_read_voltage(struct rx51_device_info *di)
{
- int voltage = rx51_battery_read_adc(TWL4030_MADC_VBAT);
+ int voltage = rx51_battery_read_adc(di->channel_vbat);
- if (voltage < 0)
+ if (voltage < 0) {
+ dev_err(di->dev, "Could not read ADC: %d\n", voltage);
return voltage;
+ }
return 1000 * (10000 * voltage / 1705);
}
@@ -112,7 +107,10 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di)
{
int min = 0;
int max = ARRAY_SIZE(rx51_temp_table2) - 1;
- int raw = rx51_battery_read_adc(TWL4030_MADC_BTEMP_RX51);
+ int raw = rx51_battery_read_adc(di->channel_temp);
+
+ if (raw < 0)
+ dev_err(di->dev, "Could not read ADC: %d\n", raw);
/* Zero and negative values are undefined */
if (raw <= 0)
@@ -146,10 +144,12 @@ static int rx51_battery_read_temperature(struct rx51_device_info *di)
*/
static int rx51_battery_read_capacity(struct rx51_device_info *di)
{
- int capacity = rx51_battery_read_adc(TWL4030_MADC_BCI_RX51);
+ int capacity = rx51_battery_read_adc(di->channel_bsi);
- if (capacity < 0)
+ if (capacity < 0) {
+ dev_err(di->dev, "Could not read ADC: %d\n", capacity);
return capacity;
+ }
return 1280 * (1200 * capacity)/(1024 - capacity);
}
@@ -213,17 +213,46 @@ static int rx51_battery_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, di);
+ di->dev = &pdev->dev;
di->bat.name = dev_name(&pdev->dev);
di->bat.type = POWER_SUPPLY_TYPE_BATTERY;
di->bat.properties = rx51_battery_props;
di->bat.num_properties = ARRAY_SIZE(rx51_battery_props);
di->bat.get_property = rx51_battery_get_property;
+ di->channel_temp = iio_channel_get(di->dev, "temp");
+ if (IS_ERR(di->channel_temp)) {
+ ret = PTR_ERR(di->channel_temp);
+ goto error;
+ }
+
+ di->channel_bsi = iio_channel_get(di->dev, "bsi");
+ if (IS_ERR(di->channel_bsi)) {
+ ret = PTR_ERR(di->channel_bsi);
+ goto error_channel_temp;
+ }
+
+ di->channel_vbat = iio_channel_get(di->dev, "vbat");
+ if (IS_ERR(di->channel_vbat)) {
+ ret = PTR_ERR(di->channel_vbat);
+ goto error_channel_bsi;
+ }
+
ret = power_supply_register(di->dev, &di->bat);
if (ret)
- return ret;
+ goto error_channel_vbat;
return 0;
+
+error_channel_vbat:
+ iio_channel_release(di->channel_vbat);
+error_channel_bsi:
+ iio_channel_release(di->channel_bsi);
+error_channel_temp:
+ iio_channel_release(di->channel_temp);
+error:
+
+ return ret;
}
static int rx51_battery_remove(struct platform_device *pdev)
@@ -232,15 +261,28 @@ static int rx51_battery_remove(struct platform_device *pdev)
power_supply_unregister(&di->bat);
+ iio_channel_release(di->channel_vbat);
+ iio_channel_release(di->channel_bsi);
+ iio_channel_release(di->channel_temp);
+
return 0;
}
+#ifdef CONFIG_OF
+static const struct of_device_id n900_battery_of_match[] = {
+ {.compatible = "nokia,n900-battery", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, n900_battery_of_match);
+#endif
+
static struct platform_driver rx51_battery_driver = {
.probe = rx51_battery_probe,
.remove = rx51_battery_remove,
.driver = {
.name = "rx51-battery",
.owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(n900_battery_of_match),
},
};
module_platform_driver(rx51_battery_driver);
diff --git a/drivers/staging/media/bcm2048/radio-bcm2048.c b/drivers/staging/media/bcm2048/radio-bcm2048.c
index b2cd3a85166d..311be1cfea8a 100644
--- a/drivers/staging/media/bcm2048/radio-bcm2048.c
+++ b/drivers/staging/media/bcm2048/radio-bcm2048.c
@@ -2720,23 +2720,7 @@ static struct i2c_driver bcm2048_i2c_driver = {
.remove = __exit_p(bcm2048_i2c_driver_remove),
.id_table = bcm2048_id,
};
-
-/*
- * Module Interface
- */
-static int __init bcm2048_module_init(void)
-{
- pr_info(BCM2048_DRIVER_DESC "\n");
-
- return i2c_add_driver(&bcm2048_i2c_driver);
-}
-module_init(bcm2048_module_init);
-
-static void __exit bcm2048_module_exit(void)
-{
- i2c_del_driver(&bcm2048_i2c_driver);
-}
-module_exit(bcm2048_module_exit);
+module_i2c_driver(bcm2048_i2c_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR(BCM2048_DRIVER_AUTHOR);
diff --git a/include/dt-bindings/pinctrl/omap.h b/include/dt-bindings/pinctrl/omap.h
index b04528cd033c..c4038fffee33 100644
--- a/include/dt-bindings/pinctrl/omap.h
+++ b/include/dt-bindings/pinctrl/omap.h
@@ -69,5 +69,17 @@
#define OMAP5_WKUP_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0xc840) (val)
#define DRA7XX_CORE_IOPAD(pa, val) OMAP_IOPAD_OFFSET((pa), 0x3400) (val)
+/*
+ * Define some commonly used pins configured by the boards.
+ * Note that some boards use alternative pins, so check
+ * the schematics before using these.
+ */
+#define OMAP3_UART1_RX 0x152
+#define OMAP3_UART2_RX 0x14a
+#define OMAP3_UART3_RX 0x16e
+#define OMAP4_UART2_RX 0xdc
+#define OMAP4_UART3_RX 0x104
+#define OMAP4_UART4_RX 0x11c
+
#endif
diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h
index 2752b1fd12be..651f9a0e2765 100644
--- a/include/linux/iio/consumer.h
+++ b/include/linux/iio/consumer.h
@@ -123,6 +123,19 @@ int iio_read_channel_raw(struct iio_channel *chan,
int *val);
/**
+ * iio_read_channel_average_raw() - read from a given channel
+ * @chan: The channel being queried.
+ * @val: Value read back.
+ *
+ * Note raw reads from iio channels are in adc counts and hence
+ * scale will need to be applied if standard units required.
+ *
+ * In opposit to the normal iio_read_channel_raw this function
+ * returns the average of multiple reads.
+ */
+int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
+
+/**
* iio_read_channel_processed() - read processed value from a given channel
* @chan: The channel being queried.
* @val: Value read back.
diff --git a/include/linux/input.h b/include/linux/input.h
index 82ce323b9986..3dc3b1edc2af 100644
--- a/include/linux/input.h
+++ b/include/linux/input.h
@@ -531,4 +531,12 @@ int input_ff_erase(struct input_dev *dev, int effect_id, struct file *file);
int input_ff_create_memless(struct input_dev *dev, void *data,
int (*play_effect)(struct input_dev *, void *, struct ff_effect *));
+#if defined(CONFIG_OF)
+void input_parse_touchscreen_of_params(struct input_dev *dev);
+#else
+static inline void input_parse_touchscreen_of_params(struct input_dev *dev) {
+ return;
+}
+#endif
+
#endif
diff --git a/include/linux/of.h b/include/linux/of.h
index 3bad8d106e0e..ba18f08aedd8 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -696,6 +696,13 @@ static inline int of_property_read_u32(const struct device_node *np,
return of_property_read_u32_array(np, propname, out_value, 1);
}
+static inline int of_property_read_s32(const struct device_node *np,
+ const char *propname,
+ s32 *out_value)
+{
+ return of_property_read_u32(np, propname, (u32*) out_value);
+}
+
#define of_property_for_each_u32(np, propname, prop, p, u) \
for (prop = of_find_property(np, propname, NULL), \
p = of_prop_next_u32(prop, NULL, &u); \
diff --git a/include/media/radio-si4713.h b/include/media/radio-si4713.h
deleted file mode 100644
index f6aae29c7741..000000000000
--- a/include/media/radio-si4713.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * include/media/radio-si4713.h
- *
- * Board related data definitions for Si4713 radio transmitter chip.
- *
- * Copyright (c) 2009 Nokia Corporation
- * Contact: Eduardo Valentin <eduardo.valentin@nokia.com>
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- *
- */
-
-#ifndef RADIO_SI4713_H
-#define RADIO_SI4713_H
-
-#include <linux/i2c.h>
-
-#define SI4713_NAME "radio-si4713"
-
-/*
- * Platform dependent definition
- */
-struct radio_si4713_platform_data {
- int i2c_bus;
- struct i2c_board_info *subdev_board_info;
-};
-
-#endif /* ifndef RADIO_SI4713_H*/
diff --git a/include/media/si4713.h b/include/media/si4713.h
index f98a0a7af61c..be4f58e2440b 100644
--- a/include/media/si4713.h
+++ b/include/media/si4713.h
@@ -23,9 +23,7 @@
* Platform dependent definition
*/
struct si4713_platform_data {
- const char * const *supply_names;
- unsigned supplies;
- int gpio_reset; /* < 0 if not used */
+ bool is_platform_device;
};
/*
diff --git a/include/sound/rx51.h b/include/sound/rx51.h
new file mode 100644
index 000000000000..190d745a106b
--- /dev/null
+++ b/include/sound/rx51.h
@@ -0,0 +1,18 @@
+/*
+ * Platform data for Nokia RX-51 SoC audio
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __RX51_AUDIO_H__
+#define __RX51_AUDIO_H__
+
+struct rx51_audio_pdata {
+ int tvout_selection_gpio;
+ int jack_detection_gpio;
+ int eci_sw_gpio;
+ int speaker_amp_gpio;
+};
+
+#endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 0b83168d8ff4..d371ae1c7279 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -931,7 +931,12 @@ struct snd_soc_dai_link {
};
struct snd_soc_codec_conf {
+ /*
+ * specify device either by device name, or by
+ * DT/OF node, but not both.
+ */
const char *dev_name;
+ const struct device_node *of_node;
/*
* optional map of kcontrol, widget and path name prefixes that are
@@ -942,7 +947,13 @@ struct snd_soc_codec_conf {
struct snd_soc_aux_dev {
const char *name; /* Codec name */
- const char *codec_name; /* for multi-codec */
+
+ /*
+ * specify multi-codec either by device name, or by
+ * DT/OF node, but not both.
+ */
+ const char *codec_name;
+ const struct device_node *codec_of_node;
/* codec/machine specific init - e.g. add machine controls */
int (*init)(struct snd_soc_dapm_context *dapm);
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c
index b1835103e9b4..d7349bc89ad3 100644
--- a/sound/soc/codecs/tlv320aic3x.c
+++ b/sound/soc/codecs/tlv320aic3x.c
@@ -1399,7 +1399,6 @@ static int aic3x_probe(struct snd_soc_codec *codec)
}
aic3x_add_widgets(codec);
- list_add(&aic3x->list, &reset_list);
return 0;
@@ -1569,7 +1568,13 @@ static int aic3x_i2c_probe(struct i2c_client *i2c,
ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_aic3x, &aic3x_dai, 1);
- return ret;
+
+ if (ret != 0)
+ goto err_gpio;
+
+ list_add(&aic3x->list, &reset_list);
+
+ return 0;
err_gpio:
if (gpio_is_valid(aic3x->gpio_reset) &&
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c
index 6c19bba23570..f88e31e28836 100644
--- a/sound/soc/omap/omap-mcbsp.c
+++ b/sound/soc/omap/omap-mcbsp.c
@@ -691,7 +691,7 @@ OMAP_MCBSP_SOC_SINGLE_S16_EXT("McBSP" #port " Sidetone Channel 1 Volume", \
OMAP_MCBSP_ST_CONTROLS(2);
OMAP_MCBSP_ST_CONTROLS(3);
-int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
+int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id)
{
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
struct omap_mcbsp *mcbsp = snd_soc_dai_get_drvdata(cpu_dai);
@@ -701,7 +701,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
return 0;
}
- switch (mcbsp->id) {
+ switch (port_id) {
case 2: /* McBSP 2 */
return snd_soc_add_dai_controls(cpu_dai,
omap_mcbsp2_st_controls,
@@ -711,6 +711,7 @@ int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd)
omap_mcbsp3_st_controls,
ARRAY_SIZE(omap_mcbsp3_st_controls));
default:
+ dev_err(mcbsp->dev, "Port %d not supported\n", port_id);
break;
}
diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h
index ba8386a0d8dc..2e3369c27be3 100644
--- a/sound/soc/omap/omap-mcbsp.h
+++ b/sound/soc/omap/omap-mcbsp.h
@@ -39,6 +39,6 @@ enum omap_mcbsp_div {
OMAP_MCBSP_CLKGDV, /* Sample rate generator divider */
};
-int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd);
+int omap_mcbsp_st_add_controls(struct snd_soc_pcm_runtime *rtd, int port_id);
#endif
diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c
index 7fb3d4b10370..418bd4105d0c 100644
--- a/sound/soc/omap/rx51.c
+++ b/sound/soc/omap/rx51.c
@@ -26,11 +26,13 @@
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
+#include <linux/of_gpio.h>
#include <linux/module.h>
#include <sound/core.h>
#include <sound/jack.h>
#include <sound/pcm.h>
#include <sound/soc.h>
+#include <sound/rx51.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include "../codecs/tpa6130a2.h"
@@ -38,15 +40,6 @@
#include "omap-mcbsp.h"
-#define RX51_TVOUT_SEL_GPIO 40
-#define RX51_JACK_DETECT_GPIO 177
-#define RX51_ECI_SW_GPIO 182
-/*
- * REVISIT: TWL4030 GPIO base in RX-51. Now statically defined to 192. This
- * gpio is reserved in arch/arm/mach-omap2/board-rx51-peripherals.c
- */
-#define RX51_SPEAKER_AMP_TWL_GPIO (192 + 7)
-
enum {
RX51_JACK_DISABLED,
RX51_JACK_TVOUT, /* tv-out with stereo output */
@@ -60,6 +53,8 @@ static int rx51_jack_func;
static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
{
+ struct snd_soc_card *card = dapm->card;
+ struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
int hp = 0, hs = 0, tvout = 0;
switch (rx51_jack_func) {
@@ -93,7 +88,7 @@ static void rx51_ext_control(struct snd_soc_dapm_context *dapm)
else
snd_soc_dapm_disable_pin_unlocked(dapm, "HS Mic");
- gpio_set_value(RX51_TVOUT_SEL_GPIO, tvout);
+ gpio_set_value(pdata->tvout_selection_gpio, tvout);
snd_soc_dapm_sync_unlocked(dapm);
@@ -154,10 +149,12 @@ static int rx51_set_spk(struct snd_kcontrol *kcontrol,
static int rx51_spk_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *k, int event)
{
- if (SND_SOC_DAPM_EVENT_ON(event))
- gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 1);
- else
- gpio_set_value_cansleep(RX51_SPEAKER_AMP_TWL_GPIO, 0);
+ struct snd_soc_dapm_context *dapm = w->dapm;
+ struct snd_soc_card *card = dapm->card;
+ struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
+
+ gpio_set_value_cansleep(pdata->speaker_amp_gpio,
+ !!SND_SOC_DAPM_EVENT_ON(event));
return 0;
}
@@ -223,7 +220,6 @@ static struct snd_soc_jack rx51_av_jack;
static struct snd_soc_jack_gpio rx51_av_jack_gpios[] = {
{
- .gpio = RX51_JACK_DETECT_GPIO,
.name = "avdet-gpio",
.report = SND_JACK_HEADSET,
.invert = 1,
@@ -237,9 +233,6 @@ static const struct snd_soc_dapm_widget aic34_dapm_widgets[] = {
SND_SOC_DAPM_HP("Headphone Jack", rx51_hp_event),
SND_SOC_DAPM_MIC("HS Mic", NULL),
SND_SOC_DAPM_LINE("FM Transmitter", NULL),
-};
-
-static const struct snd_soc_dapm_widget aic34_dapm_widgetsb[] = {
SND_SOC_DAPM_SPK("Earphone", NULL),
};
@@ -253,9 +246,7 @@ static const struct snd_soc_dapm_route audio_map[] = {
{"DMic Rate 64", NULL, "Mic Bias"},
{"Mic Bias", NULL, "DMic"},
-};
-static const struct snd_soc_dapm_route audio_mapb[] = {
{"b LINE2R", NULL, "MONO_LOUT"},
{"Earphone", NULL, "b HPLOUT"},
@@ -281,15 +272,15 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = {
SOC_ENUM_EXT("Jack Function", rx51_enum[2],
rx51_get_jack, rx51_set_jack),
SOC_DAPM_PIN_SWITCH("FM Transmitter"),
-};
-
-static const struct snd_kcontrol_new aic34_rx51_controlsb[] = {
SOC_DAPM_PIN_SWITCH("Earphone"),
};
static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
{
struct snd_soc_codec *codec = rtd->codec;
+ struct snd_soc_card *card = codec->card;
+ struct rx51_audio_pdata *pdata = snd_soc_card_get_drvdata(card);
+
struct snd_soc_dapm_context *dapm = &codec->dapm;
int err;
@@ -298,57 +289,40 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd)
snd_soc_dapm_nc_pin(dapm, "MIC3R");
snd_soc_dapm_nc_pin(dapm, "LINE1R");
- /* Add RX-51 specific controls */
- err = snd_soc_add_card_controls(rtd->card, aic34_rx51_controls,
- ARRAY_SIZE(aic34_rx51_controls));
- if (err < 0)
- return err;
-
- /* Add RX-51 specific widgets */
- snd_soc_dapm_new_controls(dapm, aic34_dapm_widgets,
- ARRAY_SIZE(aic34_dapm_widgets));
-
- /* Set up RX-51 specific audio path audio_map */
- snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map));
-
err = tpa6130a2_add_controls(codec);
- if (err < 0)
+ if (err < 0) {
+ dev_err(card->dev, "Failed to add TPA6130A2 controls\n");
return err;
+ }
snd_soc_limit_volume(codec, "TPA6130A2 Headphone Playback Volume", 42);
- err = omap_mcbsp_st_add_controls(rtd);
- if (err < 0)
+ err = omap_mcbsp_st_add_controls(rtd, 2);
+ if (err < 0) {
+ dev_err(card->dev, "Failed to add MCBSP controls\n");
return err;
+ }
/* AV jack detection */
err = snd_soc_jack_new(codec, "AV Jack",
SND_JACK_HEADSET | SND_JACK_VIDEOOUT,
&rx51_av_jack);
- if (err)
+ if (err) {
+ dev_err(card->dev, "Failed to add AV Jack\n");
return err;
- err = snd_soc_jack_add_gpios(&rx51_av_jack,
- ARRAY_SIZE(rx51_av_jack_gpios),
- rx51_av_jack_gpios);
- return err;
-}
+ }
-static int rx51_aic34b_init(struct snd_soc_dapm_context *dapm)
-{
- int err;
+ rx51_av_jack_gpios[0].gpio = pdata->jack_detection_gpio;
- err = snd_soc_add_card_controls(dapm->card, aic34_rx51_controlsb,
- ARRAY_SIZE(aic34_rx51_controlsb));
- if (err < 0)
+ err = snd_soc_jack_add_gpios(&rx51_av_jack,
+ ARRAY_SIZE(rx51_av_jack_gpios),
+ rx51_av_jack_gpios);
+ if (err) {
+ dev_err(card->dev, "Failed to add GPIOs\n");
return err;
+ }
- err = snd_soc_dapm_new_controls(dapm, aic34_dapm_widgetsb,
- ARRAY_SIZE(aic34_dapm_widgetsb));
- if (err < 0)
- return 0;
-
- return snd_soc_dapm_add_routes(dapm, audio_mapb,
- ARRAY_SIZE(audio_mapb));
+ return 0;
}
/* Digital audio interface glue - connects codec <--> CPU */
@@ -371,7 +345,6 @@ static struct snd_soc_aux_dev rx51_aux_dev[] = {
{
.name = "TLV320AIC34b",
.codec_name = "tlv320aic3x-codec.2-0019",
- .init = rx51_aic34b_init,
},
};
@@ -392,63 +365,154 @@ static struct snd_soc_card rx51_sound_card = {
.num_aux_devs = ARRAY_SIZE(rx51_aux_dev),
.codec_conf = rx51_codec_conf,
.num_configs = ARRAY_SIZE(rx51_codec_conf),
+ .dapm_widgets = aic34_dapm_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(aic34_dapm_widgets),
+ .controls = aic34_rx51_controls,
+ .num_controls = ARRAY_SIZE(aic34_rx51_controls),
+ .dapm_routes = audio_map,
+ .num_dapm_routes = ARRAY_SIZE(audio_map),
};
-static struct platform_device *rx51_snd_device;
-
-static int __init rx51_soc_init(void)
+static int rx51_soc_probe(struct platform_device *pdev)
{
+ struct rx51_audio_pdata *pdata = pdev->dev.platform_data;
+ struct device_node *np = pdev->dev.of_node;
+ struct snd_soc_card *card = &rx51_sound_card;
int err;
if (!machine_is_nokia_rx51() && !of_machine_is_compatible("nokia,omap3-n900"))
return -ENODEV;
- err = gpio_request_one(RX51_TVOUT_SEL_GPIO,
+ card->dev = &pdev->dev;
+
+ if (np) {
+ struct device_node *dai_node;
+
+ pdata = devm_kzalloc(&pdev->dev,
+ sizeof(struct rx51_audio_pdata), GFP_KERNEL);
+
+ if (pdata == NULL) {
+ dev_err(card->dev, "failed to create private data\n");
+ return -ENOMEM;
+ }
+
+ pdata->tvout_selection_gpio =
+ of_get_named_gpio(np, "tvout-selection-gpios", 0);
+ pdata->jack_detection_gpio =
+ of_get_named_gpio(np, "jack-detection-gpios", 0);
+ pdata->eci_sw_gpio =
+ of_get_named_gpio(np, "eci-switch-gpios", 0);
+ pdata->speaker_amp_gpio =
+ of_get_named_gpio(np, "speaker-amplifier-gpios", 0);
+
+ dai_node = of_parse_phandle(np, "nokia,cpu-dai", 0);
+ if (!dai_node) {
+ dev_err(&pdev->dev, "McBSP node is not provided\n");
+ return -EINVAL;
+ }
+ rx51_dai[0].cpu_dai_name = NULL;
+ rx51_dai[0].cpu_of_node = dai_node;
+
+ dai_node = of_parse_phandle(np, "nokia,audio-codec", 0);
+ if (!dai_node) {
+ dev_err(&pdev->dev, "Codec node is not provided\n");
+ return -EINVAL;
+ }
+ rx51_dai[0].codec_name = NULL;
+ rx51_dai[0].codec_of_node = dai_node;
+
+ dai_node = of_parse_phandle(np, "nokia,audio-codec", 1);
+ if (!dai_node) {
+ dev_err(&pdev->dev, "Auxiliary Codec node is not provided\n");
+ return -EINVAL;
+ }
+ rx51_aux_dev[0].codec_name = NULL;
+ rx51_aux_dev[0].codec_of_node = dai_node;
+ rx51_codec_conf[0].dev_name = NULL;
+ rx51_codec_conf[0].of_node = dai_node;
+
+ if (pdata->tvout_selection_gpio == -EPROBE_DEFER ||
+ pdata->jack_detection_gpio == -EPROBE_DEFER ||
+ pdata->eci_sw_gpio == -EPROBE_DEFER ||
+ pdata->speaker_amp_gpio == -EPROBE_DEFER) {
+ devm_kfree(card->dev, pdata);
+ pdev->dev.platform_data = NULL;
+ return -EPROBE_DEFER;
+ }
+
+ pdev->dev.platform_data = pdata;
+ } else if (!pdata) {
+ dev_err(card->dev, "platform data missing");
+ err = -ENODEV;
+ goto error;
+ }
+
+ err = devm_gpio_request_one(card->dev, pdata->tvout_selection_gpio,
GPIOF_DIR_OUT | GPIOF_INIT_LOW, "tvout_sel");
- if (err)
- goto err_gpio_tvout_sel;
- err = gpio_request_one(RX51_ECI_SW_GPIO,
+ if (err) {
+ dev_err(card->dev, "could not setup tvout_sel\n");
+ goto error;
+ }
+ err = devm_gpio_request_one(card->dev, pdata->eci_sw_gpio,
GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "eci_sw");
- if (err)
- goto err_gpio_eci_sw;
-
- rx51_snd_device = platform_device_alloc("soc-audio", -1);
- if (!rx51_snd_device) {
- err = -ENOMEM;
- goto err1;
+ if (err) {
+ dev_err(card->dev, "could not setup eci_sw\n");
+ goto error;
+ }
+ err = devm_gpio_request_one(card->dev, pdata->speaker_amp_gpio,
+ GPIOF_DIR_OUT | GPIOF_INIT_LOW, "speaker_en");
+ if (err) {
+ dev_err(card->dev, "could not setup speaker_en\n");
+ goto error;
}
- platform_set_drvdata(rx51_snd_device, &rx51_sound_card);
-
- err = platform_device_add(rx51_snd_device);
- if (err)
- goto err2;
+ snd_soc_card_set_drvdata(card, pdata);
+ err = devm_snd_soc_register_card(card->dev, card);
+ if (err) {
+ dev_err(card->dev, "snd_soc_register_card failed (%d)\n", err);
+ goto error;
+ }
return 0;
-err2:
- platform_device_put(rx51_snd_device);
-err1:
- gpio_free(RX51_ECI_SW_GPIO);
-err_gpio_eci_sw:
- gpio_free(RX51_TVOUT_SEL_GPIO);
-err_gpio_tvout_sel:
-
+error:
+ card->dev = NULL;
return err;
}
-static void __exit rx51_soc_exit(void)
+static int rx51_soc_remove(struct platform_device *pdev)
{
+ struct snd_soc_card *card = platform_get_drvdata(pdev);
+
snd_soc_jack_free_gpios(&rx51_av_jack, ARRAY_SIZE(rx51_av_jack_gpios),
rx51_av_jack_gpios);
- platform_device_unregister(rx51_snd_device);
- gpio_free(RX51_ECI_SW_GPIO);
- gpio_free(RX51_TVOUT_SEL_GPIO);
+ card->dev = NULL;
+
+ return 0;
}
-module_init(rx51_soc_init);
-module_exit(rx51_soc_exit);
+#if defined(CONFIG_OF)
+static const struct of_device_id rx51_audio_of_match[] = {
+ { .compatible = "nokia,n900-audio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, rx51_audio_of_match);
+#endif
+
+
+static struct platform_driver rx51_soc_driver = {
+ .driver = {
+ .name = "rx51-audio",
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(rx51_audio_of_match),
+ },
+ .probe = rx51_soc_probe,
+ .remove = rx51_soc_remove,
+};
+
+module_platform_driver(rx51_soc_driver);
MODULE_AUTHOR("Nokia Corporation");
MODULE_DESCRIPTION("ALSA SoC Nokia RX-51");
MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rx51-audio");
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 051c006281f5..448a60748523 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1104,10 +1104,12 @@ static void soc_set_name_prefix(struct snd_soc_card *card,
for (i = 0; i < card->num_configs; i++) {
struct snd_soc_codec_conf *map = &card->codec_conf[i];
- if (map->dev_name && !strcmp(codec->name, map->dev_name)) {
- codec->name_prefix = map->name_prefix;
- break;
- }
+ if (map->of_node && codec->dev->of_node != map->of_node)
+ continue;
+ if (map->dev_name && strcmp(codec->name, map->dev_name))
+ continue;
+ codec->name_prefix = map->name_prefix;
+ break;
}
}
@@ -1541,52 +1543,66 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec)
}
#endif
-static int soc_check_aux_dev(struct snd_soc_card *card, int num)
+struct snd_soc_codec *soc_find_matching_codec(struct snd_soc_card *card, int num)
{
struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
struct snd_soc_codec *codec;
- /* find CODEC from registered CODECs*/
+ /* find CODEC from registered CODECs */
list_for_each_entry(codec, &codec_list, list) {
- if (!strcmp(codec->name, aux_dev->codec_name))
- return 0;
+ if (aux_dev->codec_of_node &&
+ (codec->dev->of_node != aux_dev->codec_of_node))
+ continue;
+ if (aux_dev->codec_name && strcmp(codec->name, aux_dev->codec_name))
+ continue;
+ return codec;
}
- dev_err(card->dev, "ASoC: %s not registered\n", aux_dev->codec_name);
+ return NULL;
+}
+
+static int soc_check_aux_dev(struct snd_soc_card *card, int num)
+{
+ struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
+ const char *codecname = aux_dev->codec_name;
+ struct snd_soc_codec *codec = soc_find_matching_codec(card, num);
+ if (codec)
+ return 0;
+ if (aux_dev->codec_of_node)
+ codecname = of_node_full_name(aux_dev->codec_of_node);
+
+ dev_err(card->dev, "ASoC: %s not registered\n", codecname);
return -EPROBE_DEFER;
}
static int soc_probe_aux_dev(struct snd_soc_card *card, int num)
{
struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num];
- struct snd_soc_codec *codec;
+ const char *codecname = aux_dev->codec_name;
int ret = -ENODEV;
+ struct snd_soc_codec *codec = soc_find_matching_codec(card, num);
- /* find CODEC from registered CODECs*/
- list_for_each_entry(codec, &codec_list, list) {
- if (!strcmp(codec->name, aux_dev->codec_name)) {
- if (codec->probed) {
- dev_err(codec->dev,
- "ASoC: codec already probed");
- ret = -EBUSY;
- goto out;
- }
- goto found;
- }
+ if (!codec) {
+ if (aux_dev->codec_of_node)
+ codecname = of_node_full_name(aux_dev->codec_of_node);
+
+ /* codec not found */
+ dev_err(card->dev, "ASoC: codec %s not found", codecname);
+ return -EPROBE_DEFER;
+ }
+
+ if (codec->probed) {
+ dev_err(codec->dev, "ASoC: codec already probed");
+ return -EBUSY;
}
- /* codec not found */
- dev_err(card->dev, "ASoC: codec %s not found", aux_dev->codec_name);
- return -EPROBE_DEFER;
-found:
ret = soc_probe_codec(card, codec);
if (ret < 0)
return ret;
ret = soc_post_component_init(card, codec, num, 1);
-out:
return ret;
}