mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-04 04:02:26 +00:00
- New Drivers
- RK805 Power Management IC (PMIC) - ROHM BD9571MWV-M MFD Power Management IC (PMIC) - Texas Instruments TPS68470 Power Management IC (PMIC) & LEDs - New Device Support - Add support for HiSilicon Hi6421v530 to hi6421-pmic-core - Add support for X-Powers AXP806 to axp20x - Add support for X-Powers AXP813 to axp20x - Add support for Intel Sunrise Point LPSS to intel-lpss-pci - New Functionality - Amend API to provide register layout; atmel-smc - Fix-ups - DT re-work; omap, nokia - Header file location change {I2C => MFD}; dm355evm_msp, tps65010 - Fix chip ID formatting issue(s); rk808 - Optionally register touchscreen devices; da9052-core - Documentation improvements; twl-core - Constification; rtsx_pcr, ab8500-core, da9055-i2c, da9052-spi - Drop unnecessary static declaration; max8925-i2c - Kconfig changes (missing deps and remove module support) - Slim down oversized licence statement; hi6421-pmic-core - Use managed resources (devm_*); lp87565 - Supply proper error checking/handling; t7l66xb - Bug Fixes - Fix counter duplication issue; da9052-core - Fix potential NULL deference issue; max8998 - Leave SPI-NOR write-protection bit alone; lpc_ich - Ensure device is put into reset during suspend; intel-lpss - Correct register offset variable size; omap-usb-tll -----BEGIN PGP SIGNATURE----- iQIcBAABCAAGBQJZsP0YAAoJEFGvii+H/HdhrJUP/RB6BTCDMf3WCi5e6PN8IFST JspCcf4bwKVc5lDvORQglVRfBhKY/uSr7F9xlfXtHx8V60ZNo1VOQcyJBTKIz+IJ +FQQgM3lEMKIn3QCcu9lKSRomJx55YDnF5SrZ8FzkC8pGLrCYEru5HfqFqOTfPqq OH2wZSqiX4H/jYdfVzp3bgqXkDff/nSEGTeFankFkv4wRvLGRxlpVuqkRJcvEJA3 d8N9MoBBxkZAtAn2j1H5cHyPx5NrBEM2gkXpDfdd+kJNnFzjL72xsXd6rp+N6rcm d20eL+1fyJVyvGhGiDOhFwqRAZEqvjPSI4k5kQdRk8IdioGgbmaI74eUbv+rGAKp P9QdR7n1ctYyVgwnawIwKTPMzdZo5+9kdagCtu8IBVT02zQqVSDKZM7dAYo2rJuF yw24jONcwHFrKA25n1pLJmMbJGHq83kqqw3q5kl17nyArvOOcyspCTODIL9iskhZ L0IoIMwQYEj/pnI+iuXl9bJ30v2FIJxyCzUR2u7OJnrH7G27rsoOL0WDqxbp3Dp9 7tD+6OzMiyIEDxtcd74kjg7g9p5HCmcY3FiDWirmQuZIR3abSET4ap+cTYPdFqVZ widS5Pi4PP40ZFN6+4lbBHLlh6MgpHpig9M03kFAr1SyZnH8nf4TnCsFV+wYPyTb LR3cKpFeTY8IyFWaLoSg =TKIm -----END PGP SIGNATURE----- Merge tag 'mfd-next-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd Pull MFD updates from Lee Jones: "New Drivers - RK805 Power Management IC (PMIC) - ROHM BD9571MWV-M MFD Power Management IC (PMIC) - Texas Instruments TPS68470 Power Management IC (PMIC) & LEDs New Device Support: - Add support for HiSilicon Hi6421v530 to hi6421-pmic-core - Add support for X-Powers AXP806 to axp20x - Add support for X-Powers AXP813 to axp20x - Add support for Intel Sunrise Point LPSS to intel-lpss-pci New Functionality: - Amend API to provide register layout; atmel-smc Fix-ups: - DT re-work; omap, nokia - Header file location change {I2C => MFD}; dm355evm_msp, tps65010 - Fix chip ID formatting issue(s); rk808 - Optionally register touchscreen devices; da9052-core - Documentation improvements; twl-core - Constification; rtsx_pcr, ab8500-core, da9055-i2c, da9052-spi - Drop unnecessary static declaration; max8925-i2c - Kconfig changes (missing deps and remove module support) - Slim down oversized licence statement; hi6421-pmic-core - Use managed resources (devm_*); lp87565 - Supply proper error checking/handling; t7l66xb Bug Fixes: - Fix counter duplication issue; da9052-core - Fix potential NULL deference issue; max8998 - Leave SPI-NOR write-protection bit alone; lpc_ich - Ensure device is put into reset during suspend; intel-lpss - Correct register offset variable size; omap-usb-tll" * tag 'mfd-next-4.14' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (61 commits) mfd: intel_soc_pmic: Differentiate between Bay and Cherry Trail CRC variants mfd: intel_soc_pmic: Export separate mfd-cell configs for BYT and CHT dt-bindings: mfd: Add bindings for ZII RAVE devices mfd: omap-usb-tll: Fix register offsets mfd: da9052: Constify spi_device_id mfd: intel-lpss: Put I2C and SPI controllers into reset state on suspend mfd: da9055: Constify i2c_device_id mfd: intel-lpss: Add missing PCI ID for Intel Sunrise Point LPSS devices mfd: t7l66xb: Handle return value of clk_prepare_enable mfd: Add ROHM BD9571MWV-M PMIC DT bindings mfd: intel_soc_pmic_chtwc: Turn Kconfig option into a bool mfd: lp87565: Convert to use devm_mfd_add_devices() mfd: Add support for TPS68470 device mfd: lpc_ich: Do not touch SPI-NOR write protection bit on Haswell/Broadwell mfd: syscon: atmel-smc: Add helper to retrieve register layout mfd: axp20x: Use correct platform device ID for many PEK dt-bindings: mfd: axp20x: Introduce bindings for AXP813 mfd: axp20x: Add support for AXP813 PMIC dt-bindings: mfd: axp20x: Add AXP806 to supported list of chips mfd: Add ROHM BD9571MWV-M MFD PMIC driver ...
This commit is contained in:
commit
968c61f7da
57
Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32
Normal file
57
Documentation/ABI/testing/sysfs-bus-iio-lptimer-stm32
Normal file
@ -0,0 +1,57 @@
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count0_preset
|
||||
KernelVersion: 4.13
|
||||
Contact: fabrice.gasnier@st.com
|
||||
Description:
|
||||
Reading returns the current preset value. Writing sets the
|
||||
preset value. Encoder counts continuously from 0 to preset
|
||||
value, depending on direction (up/down).
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count_quadrature_mode_available
|
||||
KernelVersion: 4.13
|
||||
Contact: fabrice.gasnier@st.com
|
||||
Description:
|
||||
Reading returns the list possible quadrature modes.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count0_quadrature_mode
|
||||
KernelVersion: 4.13
|
||||
Contact: fabrice.gasnier@st.com
|
||||
Description:
|
||||
Configure the device counter quadrature modes:
|
||||
- non-quadrature:
|
||||
Encoder IN1 input servers as the count input (up
|
||||
direction).
|
||||
- quadrature:
|
||||
Encoder IN1 and IN2 inputs are mixed to get direction
|
||||
and count.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count_polarity_available
|
||||
KernelVersion: 4.13
|
||||
Contact: fabrice.gasnier@st.com
|
||||
Description:
|
||||
Reading returns the list possible active edges.
|
||||
|
||||
What: /sys/bus/iio/devices/iio:deviceX/in_count0_polarity
|
||||
KernelVersion: 4.13
|
||||
Contact: fabrice.gasnier@st.com
|
||||
Description:
|
||||
Configure the device encoder/counter active edge:
|
||||
- rising-edge
|
||||
- falling-edge
|
||||
- both-edges
|
||||
|
||||
In non-quadrature mode, device counts up on active edge.
|
||||
In quadrature mode, encoder counting scenarios are as follows:
|
||||
----------------------------------------------------------------
|
||||
| Active | Level on | IN1 signal | IN2 signal |
|
||||
| edge | opposite |------------------------------------------
|
||||
| | signal | Rising | Falling | Rising | Falling |
|
||||
----------------------------------------------------------------
|
||||
| Rising | High -> | Down | - | Up | - |
|
||||
| edge | Low -> | Up | - | Down | - |
|
||||
----------------------------------------------------------------
|
||||
| Falling | High -> | - | Up | - | Down |
|
||||
| edge | Low -> | - | Down | - | Up |
|
||||
----------------------------------------------------------------
|
||||
| Both | High -> | Down | Up | Up | Down |
|
||||
| edges | Low -> | Up | Down | Down | Up |
|
||||
----------------------------------------------------------------
|
@ -20,8 +20,8 @@ i2c@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
retu-mfd: retu@1 {
|
||||
compatible = "retu-mfd";
|
||||
retu: retu@1 {
|
||||
compatible = "nokia,retu";
|
||||
reg = <0x1>;
|
||||
};
|
||||
};
|
||||
|
@ -0,0 +1,27 @@
|
||||
STMicroelectronics STM32 Low-Power Timer quadrature encoder and counter
|
||||
|
||||
STM32 Low-Power Timer provides several counter modes. It can be used as:
|
||||
- quadrature encoder to detect angular position and direction of rotary
|
||||
elements, from IN1 and IN2 input signals.
|
||||
- simple counter from IN1 input signal.
|
||||
|
||||
Must be a sub-node of an STM32 Low-Power Timer device tree node.
|
||||
See ../mfd/stm32-lptimer.txt for details about the parent node.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "st,stm32-lptimer-counter".
|
||||
- pinctrl-names: Set to "default".
|
||||
- pinctrl-0: List of phandles pointing to pin configuration nodes,
|
||||
to set IN1/IN2 pins in mode of operation for Low-Power
|
||||
Timer input on external pin.
|
||||
|
||||
Example:
|
||||
timer@40002400 {
|
||||
compatible = "st,stm32-lptimer";
|
||||
...
|
||||
counter {
|
||||
compatible = "st,stm32-lptimer-counter";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&lptim1_in_pins>;
|
||||
};
|
||||
};
|
@ -0,0 +1,23 @@
|
||||
STMicroelectronics STM32 Low-Power Timer Trigger
|
||||
|
||||
STM32 Low-Power Timer provides trigger source (LPTIM output) that can be used
|
||||
by STM32 internal ADC and/or DAC.
|
||||
|
||||
Must be a sub-node of an STM32 Low-Power Timer device tree node.
|
||||
See ../mfd/stm32-lptimer.txt for details about the parent node.
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "st,stm32-lptimer-trigger".
|
||||
- reg: Identify trigger hardware block. Must be 0, 1 or 2
|
||||
respectively for lptimer1, lptimer2 or lptimer3
|
||||
trigger output.
|
||||
|
||||
Example:
|
||||
timer@40002400 {
|
||||
compatible = "st,stm32-lptimer";
|
||||
...
|
||||
trigger@0 {
|
||||
compatible = "st,stm32-lptimer-trigger";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
@ -8,6 +8,7 @@ Required properties:
|
||||
- compatible: Should be one of the following
|
||||
"atmel,at91sam9260-smc", "syscon"
|
||||
"atmel,sama5d3-smc", "syscon"
|
||||
"atmel,sama5d2-smc", "syscon"
|
||||
- reg: Contains offset/length value of the SMC memory
|
||||
region.
|
||||
|
||||
|
@ -7,7 +7,14 @@ axp209 (X-Powers)
|
||||
axp221 (X-Powers)
|
||||
axp223 (X-Powers)
|
||||
axp803 (X-Powers)
|
||||
axp806 (X-Powers)
|
||||
axp809 (X-Powers)
|
||||
axp813 (X-Powers)
|
||||
|
||||
The AXP813 is 2 chips packaged into 1. The 2 chips do not share anything
|
||||
other than the packaging. Pins are routed separately. As such they should
|
||||
be treated as separate entities. The other half is an AC100 RTC/codec
|
||||
combo chip. Please see ./ac100.txt for its bindings.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be one of:
|
||||
@ -19,6 +26,7 @@ Required properties:
|
||||
* "x-powers,axp803"
|
||||
* "x-powers,axp806"
|
||||
* "x-powers,axp809"
|
||||
* "x-powers,axp813"
|
||||
- reg: The I2C slave address or RSB hardware address for the AXP chip
|
||||
- interrupt-parent: The parent interrupt controller
|
||||
- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
|
||||
@ -28,12 +36,14 @@ Required properties:
|
||||
Optional properties:
|
||||
- x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz
|
||||
AXP152/20X: range: 750-1875, Default: 1.5 MHz
|
||||
AXP22X/80X: range: 1800-4050, Default: 3 MHz
|
||||
AXP22X/8XX: range: 1800-4050, Default: 3 MHz
|
||||
|
||||
- x-powers,drive-vbus-en: axp221 / axp223 only boolean, set this when the
|
||||
N_VBUSEN pin is used as an output pin to control an external
|
||||
regulator to drive the OTG VBus, rather then as an input pin
|
||||
which signals whether the board is driving OTG VBus or not.
|
||||
- x-powers,drive-vbus-en: boolean, set this when the N_VBUSEN pin is
|
||||
used as an output pin to control an external
|
||||
regulator to drive the OTG VBus, rather then
|
||||
as an input pin which signals whether the
|
||||
board is driving OTG VBus or not.
|
||||
(axp221 / axp223 / axp813 only)
|
||||
|
||||
- x-powers,master-mode: Boolean (axp806 only). Set this when the PMIC is
|
||||
wired for master mode. The default is slave mode.
|
||||
@ -171,6 +181,36 @@ LDO_IO1 : LDO : ips-supply : GPIO 1
|
||||
RTC_LDO : LDO : ips-supply : always on
|
||||
SW : On/Off Switch : swin-supply
|
||||
|
||||
AXP813 regulators, type, and corresponding input supply names:
|
||||
|
||||
Regulator Type Supply Name Notes
|
||||
--------- ---- ----------- -----
|
||||
DCDC1 : DC-DC buck : vin1-supply
|
||||
DCDC2 : DC-DC buck : vin2-supply : poly-phase capable
|
||||
DCDC3 : DC-DC buck : vin3-supply : poly-phase capable
|
||||
DCDC4 : DC-DC buck : vin4-supply
|
||||
DCDC5 : DC-DC buck : vin5-supply : poly-phase capable
|
||||
DCDC6 : DC-DC buck : vin6-supply : poly-phase capable
|
||||
DCDC7 : DC-DC buck : vin7-supply
|
||||
ALDO1 : LDO : aldoin-supply : shared supply
|
||||
ALDO2 : LDO : aldoin-supply : shared supply
|
||||
ALDO3 : LDO : aldoin-supply : shared supply
|
||||
DLDO1 : LDO : dldoin-supply : shared supply
|
||||
DLDO2 : LDO : dldoin-supply : shared supply
|
||||
DLDO3 : LDO : dldoin-supply : shared supply
|
||||
DLDO4 : LDO : dldoin-supply : shared supply
|
||||
ELDO1 : LDO : eldoin-supply : shared supply
|
||||
ELDO2 : LDO : eldoin-supply : shared supply
|
||||
ELDO3 : LDO : eldoin-supply : shared supply
|
||||
FLDO1 : LDO : fldoin-supply : shared supply
|
||||
FLDO2 : LDO : fldoin-supply : shared supply
|
||||
FLDO3 : LDO : fldoin-supply : shared supply
|
||||
LDO_IO0 : LDO : ips-supply : GPIO 0
|
||||
LDO_IO1 : LDO : ips-supply : GPIO 1
|
||||
RTC_LDO : LDO : ips-supply : always on
|
||||
SW : On/Off Switch : swin-supply
|
||||
DRIVEVBUS : Enable output : drivevbus-supply : external regulator
|
||||
|
||||
Example:
|
||||
|
||||
axp209: pmic@34 {
|
||||
|
49
Documentation/devicetree/bindings/mfd/bd9571mwv.txt
Normal file
49
Documentation/devicetree/bindings/mfd/bd9571mwv.txt
Normal file
@ -0,0 +1,49 @@
|
||||
* ROHM BD9571MWV Power Management Integrated Circuit (PMIC) bindings
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be "rohm,bd9571mwv".
|
||||
- reg : I2C slave address.
|
||||
- interrupt-parent : Phandle to the parent interrupt controller.
|
||||
- interrupts : The interrupt line the device is connected to.
|
||||
- interrupt-controller : Marks the device node as an interrupt controller.
|
||||
- #interrupt-cells : The number of cells to describe an IRQ, should be 2.
|
||||
The first cell is the IRQ number.
|
||||
The second cell is the flags, encoded as trigger
|
||||
masks from ../interrupt-controller/interrupts.txt.
|
||||
- gpio-controller : Marks the device node as a GPIO Controller.
|
||||
- #gpio-cells : Should be two. The first cell is the pin number and
|
||||
the second cell is used to specify flags.
|
||||
See ../gpio/gpio.txt for more information.
|
||||
- regulators: : List of child nodes that specify the regulator
|
||||
initialization data. Child nodes must be named
|
||||
after their hardware counterparts:
|
||||
- vd09
|
||||
- vd18
|
||||
- vd25
|
||||
- vd33
|
||||
- dvfs
|
||||
Each child node is defined using the standard
|
||||
binding for regulators.
|
||||
|
||||
Example:
|
||||
|
||||
pmic: pmic@30 {
|
||||
compatible = "rohm,bd9571mwv";
|
||||
reg = <0x30>;
|
||||
interrupt-parent = <&gpio2>;
|
||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <2>;
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
regulators {
|
||||
dvfs: dvfs {
|
||||
regulator-name = "dvfs";
|
||||
regulator-min-microvolt = <750000>;
|
||||
regulator-max-microvolt = <1030000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
};
|
@ -4,6 +4,14 @@ Required properties:
|
||||
- compatible : Should be "dlg,da9052", "dlg,da9053-aa",
|
||||
"dlg,da9053-ab", or "dlg,da9053-bb"
|
||||
|
||||
Optional properties:
|
||||
- dlg,tsi-as-adc : Boolean, if set the X+, X-, Y+, Y- touchscreen
|
||||
input lines are used as general purpose analogue
|
||||
input.
|
||||
- tsiref-supply: Phandle to the regulator, which provides the reference
|
||||
voltage for the TSIREF pin. Must be provided when the
|
||||
touchscreen pins are used for ADC purposes.
|
||||
|
||||
Sub-nodes:
|
||||
- regulators : Contain the regulator nodes. The DA9052/53 regulators are
|
||||
bound using their names as listed below:
|
||||
|
25
Documentation/devicetree/bindings/mfd/retu.txt
Normal file
25
Documentation/devicetree/bindings/mfd/retu.txt
Normal file
@ -0,0 +1,25 @@
|
||||
* Device tree bindings for Nokia Retu and Tahvo multi-function device
|
||||
|
||||
Retu and Tahvo are a multi-function devices found on Nokia Internet
|
||||
Tablets (770, N800 and N810). The Retu chip provides watchdog timer
|
||||
and power button control functionalities while Tahvo chip provides
|
||||
USB transceiver functionality.
|
||||
|
||||
Required properties:
|
||||
- compatible: "nokia,retu" or "nokia,tahvo"
|
||||
- reg: Specifies the CBUS slave address of the ASIC chip
|
||||
- interrupts: The interrupt line the device is connected to
|
||||
- interrupt-parent: The parent interrupt controller
|
||||
|
||||
Example:
|
||||
|
||||
cbus0 {
|
||||
compatible = "i2c-cbus-gpio";
|
||||
...
|
||||
retu: retu@1 {
|
||||
compatible = "nokia,retu";
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0x1>;
|
||||
};
|
||||
};
|
@ -1,11 +1,14 @@
|
||||
RK8XX Power Management Integrated Circuit
|
||||
|
||||
The rk8xx family current members:
|
||||
rk805
|
||||
rk808
|
||||
rk818
|
||||
|
||||
Required properties:
|
||||
- compatible: "rockchip,rk808", "rockchip,rk818"
|
||||
- compatible: "rockchip,rk805"
|
||||
- compatible: "rockchip,rk808"
|
||||
- compatible: "rockchip,rk818"
|
||||
- reg: I2C slave address
|
||||
- interrupt-parent: The parent interrupt controller.
|
||||
- interrupts: the interrupt outputs of the controller.
|
||||
@ -18,6 +21,14 @@ Optional properties:
|
||||
- rockchip,system-power-controller: Telling whether or not this pmic is controlling
|
||||
the system power.
|
||||
|
||||
Optional RK805 properties:
|
||||
- vcc1-supply: The input supply for DCDC_REG1
|
||||
- vcc2-supply: The input supply for DCDC_REG2
|
||||
- vcc3-supply: The input supply for DCDC_REG3
|
||||
- vcc4-supply: The input supply for DCDC_REG4
|
||||
- vcc5-supply: The input supply for LDO_REG1 and LDO_REG2
|
||||
- vcc6-supply: The input supply for LDO_REG3
|
||||
|
||||
Optional RK808 properties:
|
||||
- vcc1-supply: The input supply for DCDC_REG1
|
||||
- vcc2-supply: The input supply for DCDC_REG2
|
||||
@ -56,6 +67,15 @@ by a child node of the 'regulators' node.
|
||||
/* standard regulator bindings here */
|
||||
};
|
||||
|
||||
Following regulators of the RK805 PMIC regulators are supported. Note that
|
||||
the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
|
||||
number as described in RK805 datasheet.
|
||||
|
||||
- DCDC_REGn
|
||||
- valid values for n are 1 to 4.
|
||||
- LDO_REGn
|
||||
- valid values for n are 1 to 3
|
||||
|
||||
Following regulators of the RK808 PMIC block are supported. Note that
|
||||
the 'n' in regulator name, as in DCDC_REGn or LDOn, represents the DCDC or LDO
|
||||
number as described in RK808 datasheet.
|
||||
|
48
Documentation/devicetree/bindings/mfd/stm32-lptimer.txt
Normal file
48
Documentation/devicetree/bindings/mfd/stm32-lptimer.txt
Normal file
@ -0,0 +1,48 @@
|
||||
STMicroelectronics STM32 Low-Power Timer
|
||||
|
||||
The STM32 Low-Power Timer (LPTIM) is a 16-bit timer that provides several
|
||||
functions:
|
||||
- PWM output (with programmable prescaler, configurable polarity)
|
||||
- Quadrature encoder, counter
|
||||
- Trigger source for STM32 ADC/DAC (LPTIM_OUT)
|
||||
|
||||
Required properties:
|
||||
- compatible: Must be "st,stm32-lptimer".
|
||||
- reg: Offset and length of the device's register set.
|
||||
- clocks: Phandle to the clock used by the LP Timer module.
|
||||
- clock-names: Must be "mux".
|
||||
- #address-cells: Should be '<1>'.
|
||||
- #size-cells: Should be '<0>'.
|
||||
|
||||
Optional subnodes:
|
||||
- pwm: See ../pwm/pwm-stm32-lp.txt
|
||||
- counter: See ../iio/timer/stm32-lptimer-cnt.txt
|
||||
- trigger: See ../iio/timer/stm32-lptimer-trigger.txt
|
||||
|
||||
Example:
|
||||
|
||||
timer@40002400 {
|
||||
compatible = "st,stm32-lptimer";
|
||||
reg = <0x40002400 0x400>;
|
||||
clocks = <&timer_clk>;
|
||||
clock-names = "mux";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
pwm {
|
||||
compatible = "st,stm32-pwm-lp";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&lppwm1_pins>;
|
||||
};
|
||||
|
||||
trigger@0 {
|
||||
compatible = "st,stm32-lptimer-trigger";
|
||||
reg = <0>;
|
||||
};
|
||||
|
||||
counter {
|
||||
compatible = "st,stm32-lptimer-counter";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&lptim1_in_pins>;
|
||||
};
|
||||
};
|
17
Documentation/devicetree/bindings/mfd/tps6105x.txt
Normal file
17
Documentation/devicetree/bindings/mfd/tps6105x.txt
Normal file
@ -0,0 +1,17 @@
|
||||
* Device tree bindings for TI TPS61050/61052 Boost Converters
|
||||
|
||||
The TP61050/TPS61052 is a high-power "white LED driver". The
|
||||
device provides LED, GPIO and regulator functionalities.
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,tps61050" or "ti,tps61052"
|
||||
- reg: Specifies the I2C slave address
|
||||
|
||||
Example:
|
||||
|
||||
i2c0 {
|
||||
tps61052@33 {
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
};
|
||||
};
|
39
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt
Normal file
39
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt
Normal file
@ -0,0 +1,39 @@
|
||||
Zodiac Inflight Innovations RAVE Supervisory Processor
|
||||
|
||||
RAVE Supervisory Processor communicates with SoC over UART. It is
|
||||
expected that its Device Tree node is specified as a child of a node
|
||||
corresponding to UART controller used for communication.
|
||||
|
||||
Required parent device properties:
|
||||
|
||||
- compatible: Should be one of:
|
||||
- "zii,rave-sp-niu"
|
||||
- "zii,rave-sp-mezz"
|
||||
- "zii,rave-sp-esb"
|
||||
- "zii,rave-sp-rdu1"
|
||||
- "zii,rave-sp-rdu2"
|
||||
|
||||
- current-speed: Should be set to baud rate SP device is using
|
||||
|
||||
RAVE SP consists of the following sub-devices:
|
||||
|
||||
Device Description
|
||||
------ -----------
|
||||
rave-sp-wdt : Watchdog
|
||||
rave-sp-nvmem : Interface to onborad EEPROM
|
||||
rave-sp-backlight : Display backlight
|
||||
rave-sp-hwmon : Interface to onboard hardware sensors
|
||||
rave-sp-leds : Interface to onboard LEDs
|
||||
rave-sp-input : Interface to onboard power button
|
||||
|
||||
Example of usage:
|
||||
|
||||
rdu {
|
||||
compatible = "zii,rave-sp-rdu2";
|
||||
current-speed = <1000000>;
|
||||
|
||||
watchdog {
|
||||
compatible = "zii,rave-sp-watchdog";
|
||||
};
|
||||
};
|
||||
|
63
Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt
Normal file
63
Documentation/devicetree/bindings/pinctrl/pinctrl-rk805.txt
Normal file
@ -0,0 +1,63 @@
|
||||
Pincontrol driver for RK805 Power management IC.
|
||||
|
||||
RK805 has 2 pins which can be configured as GPIO output only.
|
||||
|
||||
Please refer file <devicetree/bindings/pinctrl/pinctrl-bindings.txt>
|
||||
for details of the common pinctrl bindings used by client devices,
|
||||
including the meaning of the phrase "pin configuration node".
|
||||
|
||||
Optional Pinmux properties:
|
||||
--------------------------
|
||||
Following properties are required if default setting of pins are required
|
||||
at boot.
|
||||
- pinctrl-names: A pinctrl state named per <pinctrl-binding.txt>.
|
||||
- pinctrl[0...n]: Properties to contain the phandle for pinctrl states per
|
||||
<pinctrl-binding.txt>.
|
||||
|
||||
The pin configurations are defined as child of the pinctrl states node. Each
|
||||
sub-node have following properties:
|
||||
|
||||
Required properties:
|
||||
------------------
|
||||
- #gpio-cells: Should be two. The first cell is the pin number and the
|
||||
second is the GPIO flags.
|
||||
|
||||
- gpio-controller: Marks the device node as a GPIO controller.
|
||||
|
||||
- pins: List of pins. Valid values of pins properties are: gpio0, gpio1.
|
||||
|
||||
First 2 properties must be added in the RK805 PMIC node, documented in
|
||||
Documentation/devicetree/bindings/mfd/rk808.txt
|
||||
|
||||
Optional properties:
|
||||
-------------------
|
||||
Following are optional properties defined as pinmux DT binding document
|
||||
<pinctrl-bindings.txt>. Absence of properties will leave the configuration
|
||||
on default.
|
||||
function,
|
||||
output-low,
|
||||
output-high.
|
||||
|
||||
Valid values for function properties are: gpio.
|
||||
|
||||
Theres is also not customised properties for any GPIO.
|
||||
|
||||
Example:
|
||||
--------
|
||||
rk805: rk805@18 {
|
||||
compatible = "rockchip,rk805";
|
||||
...
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pmic_int_l>, <&rk805_default>;
|
||||
|
||||
rk805_default: pinmux {
|
||||
gpio01 {
|
||||
pins = "gpio0", "gpio1";
|
||||
function = "gpio";
|
||||
output-high;
|
||||
};
|
||||
};
|
||||
};
|
24
Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt
Normal file
24
Documentation/devicetree/bindings/pwm/pwm-stm32-lp.txt
Normal file
@ -0,0 +1,24 @@
|
||||
STMicroelectronics STM32 Low-Power Timer PWM
|
||||
|
||||
STM32 Low-Power Timer provides single channel PWM.
|
||||
|
||||
Must be a sub-node of an STM32 Low-Power Timer device tree node.
|
||||
See ../mfd/stm32-lptimer.txt for details about the parent node.
|
||||
|
||||
Required parameters:
|
||||
- compatible: Must be "st,stm32-pwm-lp".
|
||||
|
||||
Optional properties:
|
||||
- pinctrl-names: Set to "default".
|
||||
- pinctrl-0: Phandle pointing to pin configuration node for PWM.
|
||||
|
||||
Example:
|
||||
timer@40002400 {
|
||||
compatible = "st,stm32-lptimer";
|
||||
...
|
||||
pwm {
|
||||
compatible = "st,stm32-pwm-lp";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&lppwm1_pins>;
|
||||
};
|
||||
};
|
11
MAINTAINERS
11
MAINTAINERS
@ -11432,6 +11432,17 @@ L: linux-serial@vger.kernel.org
|
||||
S: Odd Fixes
|
||||
F: drivers/tty/serial/rp2.*
|
||||
|
||||
ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS
|
||||
M: Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||
L: linux-kernel@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/mfd/bd9571mwv.c
|
||||
F: drivers/regulator/bd9571mwv-regulator.c
|
||||
F: drivers/gpio/gpio-bd9571mwv.c
|
||||
F: include/linux/mfd/bd9571mwv.h
|
||||
F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt
|
||||
|
||||
ROSE NETWORK LAYER
|
||||
M: Ralf Baechle <ralf@linux-mips.org>
|
||||
L: linux-hams@vger.kernel.org
|
||||
|
@ -15,8 +15,8 @@ &gpio3 0 GPIO_ACTIVE_HIGH /* gpio64 sel */
|
||||
>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
retu_mfd: retu@1 {
|
||||
compatible = "retu-mfd";
|
||||
retu: retu@1 {
|
||||
compatible = "nokia,retu";
|
||||
interrupt-parent = <&gpio4>;
|
||||
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
|
||||
reg = <0x1>;
|
||||
|
@ -30,7 +30,7 @@ uart@80121000 {
|
||||
|
||||
i2c@80004000 {
|
||||
tps61052@33 {
|
||||
compatible = "tps61052";
|
||||
compatible = "ti,tps61052";
|
||||
reg = <0x33>;
|
||||
};
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/platform_data/gpio-omap.h>
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
|
||||
#include "board-h2.h"
|
||||
#include "mmc.h"
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
#include <linux/smc91x.h>
|
||||
#include <linux/omapfb.h>
|
||||
#include <linux/platform_data/gpio-omap.h>
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "board-h3.h"
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
#include <linux/smc91x.h>
|
||||
#include <linux/omapfb.h>
|
||||
#include <linux/platform_data/gpio-omap.h>
|
||||
|
@ -233,10 +233,10 @@ static struct platform_device nokia770_cbus_device = {
|
||||
|
||||
static struct i2c_board_info nokia770_i2c_board_info_2[] __initdata = {
|
||||
{
|
||||
I2C_BOARD_INFO("retu-mfd", 0x01),
|
||||
I2C_BOARD_INFO("retu", 0x01),
|
||||
},
|
||||
{
|
||||
I2C_BOARD_INFO("tahvo-mfd", 0x02),
|
||||
I2C_BOARD_INFO("tahvo", 0x02),
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
#include <linux/mtd/physmap.h>
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
#include <linux/platform_data/gpio-omap.h>
|
||||
#include <linux/platform_data/omap1_bl.h>
|
||||
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/i2c-omap.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/irqchip/irq-omap-intc.h>
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "voltage.h"
|
||||
|
@ -17,7 +17,7 @@
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
|
||||
#include <plat/cpu-freq.h>
|
||||
#include <mach/gpio-samsung.h>
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/mach/arch.h>
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/irqdomain.h>
|
||||
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
|
||||
/*
|
||||
* The GPIO "subchip" supports 18 GPIOs which can be configured as
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <linux/dmaengine.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/buffer.h>
|
||||
#include <linux/iio/timer/stm32-lptim-trigger.h>
|
||||
#include <linux/iio/timer/stm32-timer-trigger.h>
|
||||
#include <linux/iio/trigger.h>
|
||||
#include <linux/iio/trigger_consumer.h>
|
||||
@ -185,6 +186,11 @@ enum stm32_adc_extsel {
|
||||
STM32_EXT13,
|
||||
STM32_EXT14,
|
||||
STM32_EXT15,
|
||||
STM32_EXT16,
|
||||
STM32_EXT17,
|
||||
STM32_EXT18,
|
||||
STM32_EXT19,
|
||||
STM32_EXT20,
|
||||
};
|
||||
|
||||
/**
|
||||
@ -526,6 +532,9 @@ static struct stm32_adc_trig_info stm32h7_adc_trigs[] = {
|
||||
{ TIM4_TRGO, STM32_EXT12 },
|
||||
{ TIM6_TRGO, STM32_EXT13 },
|
||||
{ TIM3_CH4, STM32_EXT15 },
|
||||
{ LPTIM1_OUT, STM32_EXT18 },
|
||||
{ LPTIM2_OUT, STM32_EXT19 },
|
||||
{ LPTIM3_OUT, STM32_EXT20 },
|
||||
{},
|
||||
};
|
||||
|
||||
@ -1082,7 +1091,8 @@ static int stm32_adc_get_trig_extsel(struct iio_dev *indio_dev,
|
||||
* Checking both stm32 timer trigger type and trig name
|
||||
* should be safe against arbitrary trigger names.
|
||||
*/
|
||||
if (is_stm32_timer_trigger(trig) &&
|
||||
if ((is_stm32_timer_trigger(trig) ||
|
||||
is_stm32_lptim_trigger(trig)) &&
|
||||
!strcmp(adc->cfg->trigs[i].name, trig->name)) {
|
||||
return adc->cfg->trigs[i].extsel;
|
||||
}
|
||||
@ -1764,7 +1774,7 @@ static int stm32_adc_probe(struct platform_device *pdev)
|
||||
indio_dev->dev.parent = &pdev->dev;
|
||||
indio_dev->dev.of_node = pdev->dev.of_node;
|
||||
indio_dev->info = &stm32_adc_iio_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE | INDIO_HARDWARE_TRIGGERED;
|
||||
|
||||
platform_set_drvdata(pdev, adc);
|
||||
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/mutex.h>
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
|
||||
|
@ -21,4 +21,13 @@ config 104_QUAD_8
|
||||
The base port addresses for the devices may be configured via the base
|
||||
array module parameter.
|
||||
|
||||
config STM32_LPTIMER_CNT
|
||||
tristate "STM32 LP Timer encoder counter driver"
|
||||
depends on MFD_STM32_LPTIMER || COMPILE_TEST
|
||||
help
|
||||
Select this option to enable STM32 Low-Power Timer quadrature encoder
|
||||
and counter driver.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stm32-lptimer-cnt.
|
||||
endmenu
|
||||
|
@ -5,3 +5,4 @@
|
||||
# When adding new entries keep the list in alphabetical order
|
||||
|
||||
obj-$(CONFIG_104_QUAD_8) += 104-quad-8.o
|
||||
obj-$(CONFIG_STM32_LPTIMER_CNT) += stm32-lptimer-cnt.o
|
||||
|
383
drivers/iio/counter/stm32-lptimer-cnt.c
Normal file
383
drivers/iio/counter/stm32-lptimer-cnt.c
Normal file
@ -0,0 +1,383 @@
|
||||
/*
|
||||
* STM32 Low-Power Timer Encoder and Counter driver
|
||||
*
|
||||
* Copyright (C) STMicroelectronics 2017
|
||||
*
|
||||
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||
*
|
||||
* Inspired by 104-quad-8 and stm32-timer-trigger drivers.
|
||||
*
|
||||
* License terms: GNU General Public License (GPL), version 2
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/mfd/stm32-lptimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
struct stm32_lptim_cnt {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
u32 preset;
|
||||
u32 polarity;
|
||||
u32 quadrature_mode;
|
||||
};
|
||||
|
||||
static int stm32_lptim_is_enabled(struct stm32_lptim_cnt *priv)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return FIELD_GET(STM32_LPTIM_ENABLE, val);
|
||||
}
|
||||
|
||||
static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
|
||||
int enable)
|
||||
{
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
val = FIELD_PREP(STM32_LPTIM_ENABLE, enable);
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CR, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!enable) {
|
||||
clk_disable(priv->clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* LP timer must be enabled before writing CMP & ARR */
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->preset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* ensure CMP & ARR registers are properly written */
|
||||
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
|
||||
(val & STM32_LPTIM_CMPOK_ARROK),
|
||||
100, 1000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
|
||||
STM32_LPTIM_CMPOKCF_ARROKCF);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_enable(priv->clk);
|
||||
if (ret) {
|
||||
regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Start LP timer in continuous mode */
|
||||
return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
|
||||
STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
|
||||
}
|
||||
|
||||
static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
|
||||
{
|
||||
u32 mask = STM32_LPTIM_ENC | STM32_LPTIM_COUNTMODE |
|
||||
STM32_LPTIM_CKPOL | STM32_LPTIM_PRESC;
|
||||
u32 val;
|
||||
|
||||
/* Setup LP timer encoder/counter and polarity, without prescaler */
|
||||
if (priv->quadrature_mode)
|
||||
val = enable ? STM32_LPTIM_ENC : 0;
|
||||
else
|
||||
val = enable ? STM32_LPTIM_COUNTMODE : 0;
|
||||
val |= FIELD_PREP(STM32_LPTIM_CKPOL, enable ? priv->polarity : 0);
|
||||
|
||||
return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
|
||||
}
|
||||
|
||||
static int stm32_lptim_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int val, int val2, long mask)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_ENABLE:
|
||||
if (val < 0 || val > 1)
|
||||
return -EINVAL;
|
||||
|
||||
/* Check nobody uses the timer, or already disabled/enabled */
|
||||
ret = stm32_lptim_is_enabled(priv);
|
||||
if ((ret < 0) || (!ret && !val))
|
||||
return ret;
|
||||
if (val && ret)
|
||||
return -EBUSY;
|
||||
|
||||
ret = stm32_lptim_setup(priv, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
return stm32_lptim_set_enable_state(priv, val);
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int stm32_lptim_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val, int *val2, long mask)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
u32 dat;
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &dat);
|
||||
if (ret)
|
||||
return ret;
|
||||
*val = dat;
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_CHAN_INFO_ENABLE:
|
||||
ret = stm32_lptim_is_enabled(priv);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
*val = ret;
|
||||
return IIO_VAL_INT;
|
||||
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
/* Non-quadrature mode: scale = 1 */
|
||||
*val = 1;
|
||||
*val2 = 0;
|
||||
if (priv->quadrature_mode) {
|
||||
/*
|
||||
* Quadrature encoder mode:
|
||||
* - both edges, quarter cycle, scale is 0.25
|
||||
* - either rising/falling edge scale is 0.5
|
||||
*/
|
||||
if (priv->polarity > 1)
|
||||
*val2 = 2;
|
||||
else
|
||||
*val2 = 1;
|
||||
}
|
||||
return IIO_VAL_FRACTIONAL_LOG2;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct iio_info stm32_lptim_cnt_iio_info = {
|
||||
.read_raw = stm32_lptim_read_raw,
|
||||
.write_raw = stm32_lptim_write_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const char *const stm32_lptim_quadrature_modes[] = {
|
||||
"non-quadrature",
|
||||
"quadrature",
|
||||
};
|
||||
|
||||
static int stm32_lptim_get_quadrature_mode(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
|
||||
return priv->quadrature_mode;
|
||||
}
|
||||
|
||||
static int stm32_lptim_set_quadrature_mode(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan,
|
||||
unsigned int type)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
|
||||
if (stm32_lptim_is_enabled(priv))
|
||||
return -EBUSY;
|
||||
|
||||
priv->quadrature_mode = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct iio_enum stm32_lptim_quadrature_mode_en = {
|
||||
.items = stm32_lptim_quadrature_modes,
|
||||
.num_items = ARRAY_SIZE(stm32_lptim_quadrature_modes),
|
||||
.get = stm32_lptim_get_quadrature_mode,
|
||||
.set = stm32_lptim_set_quadrature_mode,
|
||||
};
|
||||
|
||||
static const char * const stm32_lptim_cnt_polarity[] = {
|
||||
"rising-edge", "falling-edge", "both-edges",
|
||||
};
|
||||
|
||||
static int stm32_lptim_cnt_get_polarity(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
|
||||
return priv->polarity;
|
||||
}
|
||||
|
||||
static int stm32_lptim_cnt_set_polarity(struct iio_dev *indio_dev,
|
||||
const struct iio_chan_spec *chan,
|
||||
unsigned int type)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
|
||||
if (stm32_lptim_is_enabled(priv))
|
||||
return -EBUSY;
|
||||
|
||||
priv->polarity = type;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct iio_enum stm32_lptim_cnt_polarity_en = {
|
||||
.items = stm32_lptim_cnt_polarity,
|
||||
.num_items = ARRAY_SIZE(stm32_lptim_cnt_polarity),
|
||||
.get = stm32_lptim_cnt_get_polarity,
|
||||
.set = stm32_lptim_cnt_set_polarity,
|
||||
};
|
||||
|
||||
static ssize_t stm32_lptim_cnt_get_preset(struct iio_dev *indio_dev,
|
||||
uintptr_t private,
|
||||
const struct iio_chan_spec *chan,
|
||||
char *buf)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u\n", priv->preset);
|
||||
}
|
||||
|
||||
static ssize_t stm32_lptim_cnt_set_preset(struct iio_dev *indio_dev,
|
||||
uintptr_t private,
|
||||
const struct iio_chan_spec *chan,
|
||||
const char *buf, size_t len)
|
||||
{
|
||||
struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
if (stm32_lptim_is_enabled(priv))
|
||||
return -EBUSY;
|
||||
|
||||
ret = kstrtouint(buf, 0, &priv->preset);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (priv->preset > STM32_LPTIM_MAX_ARR)
|
||||
return -EINVAL;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* LP timer with encoder */
|
||||
static const struct iio_chan_spec_ext_info stm32_lptim_enc_ext_info[] = {
|
||||
{
|
||||
.name = "preset",
|
||||
.shared = IIO_SEPARATE,
|
||||
.read = stm32_lptim_cnt_get_preset,
|
||||
.write = stm32_lptim_cnt_set_preset,
|
||||
},
|
||||
IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
|
||||
IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
|
||||
IIO_ENUM("quadrature_mode", IIO_SEPARATE,
|
||||
&stm32_lptim_quadrature_mode_en),
|
||||
IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_lptim_quadrature_mode_en),
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec stm32_lptim_enc_channels = {
|
||||
.type = IIO_COUNT,
|
||||
.channel = 0,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_ENABLE) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.ext_info = stm32_lptim_enc_ext_info,
|
||||
.indexed = 1,
|
||||
};
|
||||
|
||||
/* LP timer without encoder (counter only) */
|
||||
static const struct iio_chan_spec_ext_info stm32_lptim_cnt_ext_info[] = {
|
||||
{
|
||||
.name = "preset",
|
||||
.shared = IIO_SEPARATE,
|
||||
.read = stm32_lptim_cnt_get_preset,
|
||||
.write = stm32_lptim_cnt_set_preset,
|
||||
},
|
||||
IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
|
||||
IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec stm32_lptim_cnt_channels = {
|
||||
.type = IIO_COUNT,
|
||||
.channel = 0,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_ENABLE) |
|
||||
BIT(IIO_CHAN_INFO_SCALE),
|
||||
.ext_info = stm32_lptim_cnt_ext_info,
|
||||
.indexed = 1,
|
||||
};
|
||||
|
||||
static int stm32_lptim_cnt_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
|
||||
struct stm32_lptim_cnt *priv;
|
||||
struct iio_dev *indio_dev;
|
||||
|
||||
if (IS_ERR_OR_NULL(ddata))
|
||||
return -EINVAL;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
priv = iio_priv(indio_dev);
|
||||
priv->dev = &pdev->dev;
|
||||
priv->regmap = ddata->regmap;
|
||||
priv->clk = ddata->clk;
|
||||
priv->preset = STM32_LPTIM_MAX_ARR;
|
||||
|
||||
indio_dev->name = dev_name(&pdev->dev);
|
||||
indio_dev->dev.parent = &pdev->dev;
|
||||
indio_dev->dev.of_node = pdev->dev.of_node;
|
||||
indio_dev->info = &stm32_lptim_cnt_iio_info;
|
||||
if (ddata->has_encoder)
|
||||
indio_dev->channels = &stm32_lptim_enc_channels;
|
||||
else
|
||||
indio_dev->channels = &stm32_lptim_cnt_channels;
|
||||
indio_dev->num_channels = 1;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return devm_iio_device_register(&pdev->dev, indio_dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_lptim_cnt_of_match[] = {
|
||||
{ .compatible = "st,stm32-lptimer-counter", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_lptim_cnt_of_match);
|
||||
|
||||
static struct platform_driver stm32_lptim_cnt_driver = {
|
||||
.probe = stm32_lptim_cnt_probe,
|
||||
.driver = {
|
||||
.name = "stm32-lptimer-counter",
|
||||
.of_match_table = stm32_lptim_cnt_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(stm32_lptim_cnt_driver);
|
||||
|
||||
MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
|
||||
MODULE_ALIAS("platform:stm32-lptimer-counter");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM counter driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -24,6 +24,17 @@ config IIO_INTERRUPT_TRIGGER
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called iio-trig-interrupt.
|
||||
|
||||
config IIO_STM32_LPTIMER_TRIGGER
|
||||
tristate "STM32 Low-Power Timer Trigger"
|
||||
depends on MFD_STM32_LPTIMER || COMPILE_TEST
|
||||
help
|
||||
Select this option to enable STM32 Low-Power Timer Trigger.
|
||||
This can be used as trigger source for STM32 internal ADC
|
||||
and/or DAC.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stm32-lptimer-trigger.
|
||||
|
||||
config IIO_STM32_TIMER_TRIGGER
|
||||
tristate "STM32 Timer Trigger"
|
||||
depends on (ARCH_STM32 && OF && MFD_STM32_TIMERS) || COMPILE_TEST
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
obj-$(CONFIG_IIO_HRTIMER_TRIGGER) += iio-trig-hrtimer.o
|
||||
obj-$(CONFIG_IIO_INTERRUPT_TRIGGER) += iio-trig-interrupt.o
|
||||
obj-$(CONFIG_IIO_STM32_LPTIMER_TRIGGER) += stm32-lptimer-trigger.o
|
||||
obj-$(CONFIG_IIO_STM32_TIMER_TRIGGER) += stm32-timer-trigger.o
|
||||
obj-$(CONFIG_IIO_SYSFS_TRIGGER) += iio-trig-sysfs.o
|
||||
obj-$(CONFIG_IIO_TIGHTLOOP_TRIGGER) += iio-trig-loop.o
|
||||
|
118
drivers/iio/trigger/stm32-lptimer-trigger.c
Normal file
118
drivers/iio/trigger/stm32-lptimer-trigger.c
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* STM32 Low-Power Timer Trigger driver
|
||||
*
|
||||
* Copyright (C) STMicroelectronics 2017
|
||||
*
|
||||
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>.
|
||||
*
|
||||
* License terms: GNU General Public License (GPL), version 2
|
||||
*
|
||||
* Inspired by Benjamin Gaignard's stm32-timer-trigger driver
|
||||
*/
|
||||
|
||||
#include <linux/iio/timer/stm32-lptim-trigger.h>
|
||||
#include <linux/mfd/stm32-lptimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
/* List Low-Power Timer triggers */
|
||||
static const char * const stm32_lptim_triggers[] = {
|
||||
LPTIM1_OUT,
|
||||
LPTIM2_OUT,
|
||||
LPTIM3_OUT,
|
||||
};
|
||||
|
||||
struct stm32_lptim_trigger {
|
||||
struct device *dev;
|
||||
const char *trg;
|
||||
};
|
||||
|
||||
static int stm32_lptim_validate_device(struct iio_trigger *trig,
|
||||
struct iio_dev *indio_dev)
|
||||
{
|
||||
if (indio_dev->modes & INDIO_HARDWARE_TRIGGERED)
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct iio_trigger_ops stm32_lptim_trigger_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.validate_device = stm32_lptim_validate_device,
|
||||
};
|
||||
|
||||
/**
|
||||
* is_stm32_lptim_trigger
|
||||
* @trig: trigger to be checked
|
||||
*
|
||||
* return true if the trigger is a valid STM32 IIO Low-Power Timer Trigger
|
||||
* either return false
|
||||
*/
|
||||
bool is_stm32_lptim_trigger(struct iio_trigger *trig)
|
||||
{
|
||||
return (trig->ops == &stm32_lptim_trigger_ops);
|
||||
}
|
||||
EXPORT_SYMBOL(is_stm32_lptim_trigger);
|
||||
|
||||
static int stm32_lptim_setup_trig(struct stm32_lptim_trigger *priv)
|
||||
{
|
||||
struct iio_trigger *trig;
|
||||
|
||||
trig = devm_iio_trigger_alloc(priv->dev, "%s", priv->trg);
|
||||
if (!trig)
|
||||
return -ENOMEM;
|
||||
|
||||
trig->dev.parent = priv->dev->parent;
|
||||
trig->ops = &stm32_lptim_trigger_ops;
|
||||
iio_trigger_set_drvdata(trig, priv);
|
||||
|
||||
return devm_iio_trigger_register(priv->dev, trig);
|
||||
}
|
||||
|
||||
static int stm32_lptim_trigger_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_lptim_trigger *priv;
|
||||
u32 index;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_property_read_u32(pdev->dev.of_node, "reg", &index))
|
||||
return -EINVAL;
|
||||
|
||||
if (index >= ARRAY_SIZE(stm32_lptim_triggers))
|
||||
return -EINVAL;
|
||||
|
||||
priv->dev = &pdev->dev;
|
||||
priv->trg = stm32_lptim_triggers[index];
|
||||
|
||||
ret = stm32_lptim_setup_trig(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_lptim_trig_of_match[] = {
|
||||
{ .compatible = "st,stm32-lptimer-trigger", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_lptim_trig_of_match);
|
||||
|
||||
static struct platform_driver stm32_lptim_trigger_driver = {
|
||||
.probe = stm32_lptim_trigger_probe,
|
||||
.driver = {
|
||||
.name = "stm32-lptimer-trigger",
|
||||
.of_match_table = stm32_lptim_trig_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(stm32_lptim_trigger_driver);
|
||||
|
||||
MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
|
||||
MODULE_ALIAS("platform:stm32-lptimer-trigger");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM trigger driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -30,7 +30,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <linux/i2c/dm355evm_msp.h>
|
||||
#include <linux/mfd/dm355evm_msp.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
|
||||
#define PWR_PWRON_IRQ (1 << 0)
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/mfd/twl4030-audio.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -51,6 +51,7 @@ struct atmel_ebi {
|
||||
struct {
|
||||
struct regmap *regmap;
|
||||
struct clk *clk;
|
||||
const struct atmel_hsmc_reg_layout *layout;
|
||||
} smc;
|
||||
|
||||
struct device *dev;
|
||||
@ -84,8 +85,8 @@ static void at91sam9_ebi_get_config(struct atmel_ebi_dev *ebid,
|
||||
static void sama5_ebi_get_config(struct atmel_ebi_dev *ebid,
|
||||
struct atmel_ebi_dev_config *conf)
|
||||
{
|
||||
atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, conf->cs,
|
||||
&conf->smcconf);
|
||||
atmel_hsmc_cs_conf_get(ebid->ebi->smc.regmap, ebid->ebi->smc.layout,
|
||||
conf->cs, &conf->smcconf);
|
||||
}
|
||||
|
||||
static const struct atmel_smc_timing_xlate timings_xlate_table[] = {
|
||||
@ -287,8 +288,8 @@ static void at91sam9_ebi_apply_config(struct atmel_ebi_dev *ebid,
|
||||
static void sama5_ebi_apply_config(struct atmel_ebi_dev *ebid,
|
||||
struct atmel_ebi_dev_config *conf)
|
||||
{
|
||||
atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, conf->cs,
|
||||
&conf->smcconf);
|
||||
atmel_hsmc_cs_conf_apply(ebid->ebi->smc.regmap, ebid->ebi->smc.layout,
|
||||
conf->cs, &conf->smcconf);
|
||||
}
|
||||
|
||||
static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np,
|
||||
@ -527,6 +528,10 @@ static int atmel_ebi_probe(struct platform_device *pdev)
|
||||
if (IS_ERR(ebi->smc.regmap))
|
||||
return PTR_ERR(ebi->smc.regmap);
|
||||
|
||||
ebi->smc.layout = atmel_hsmc_get_reg_layout(smc_np);
|
||||
if (IS_ERR(ebi->smc.layout))
|
||||
return PTR_ERR(ebi->smc.layout);
|
||||
|
||||
ebi->smc.clk = of_clk_get(smc_np, 0);
|
||||
if (IS_ERR(ebi->smc.clk)) {
|
||||
if (PTR_ERR(ebi->smc.clk) != -ENOENT)
|
||||
|
@ -133,6 +133,20 @@ config MFD_BCM590XX
|
||||
help
|
||||
Support for the BCM590xx PMUs from Broadcom
|
||||
|
||||
config MFD_BD9571MWV
|
||||
tristate "ROHM BD9571MWV PMIC"
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
depends on I2C
|
||||
help
|
||||
Support for the ROHM BD9571MWV PMIC, which contains single
|
||||
voltage regulator, voltage sampling units, GPIO block and
|
||||
watchdog block.
|
||||
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called bd9571mwv.
|
||||
|
||||
config MFD_AC100
|
||||
tristate "X-Powers AC100"
|
||||
select MFD_CORE
|
||||
@ -453,12 +467,12 @@ config LPC_SCH
|
||||
|
||||
config INTEL_SOC_PMIC
|
||||
bool "Support for Crystal Cove PMIC"
|
||||
depends on HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK
|
||||
depends on ACPI && HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK
|
||||
depends on X86 || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
select I2C_DESIGNWARE_PLATFORM if ACPI
|
||||
select I2C_DESIGNWARE_PLATFORM
|
||||
help
|
||||
Select this option to enable support for Crystal Cove PMIC
|
||||
on some Intel SoC systems. The PMIC provides ADC, GPIO,
|
||||
@ -481,7 +495,7 @@ config INTEL_SOC_PMIC_BXTWC
|
||||
on these systems.
|
||||
|
||||
config INTEL_SOC_PMIC_CHTWC
|
||||
tristate "Support for Intel Cherry Trail Whiskey Cove PMIC"
|
||||
bool "Support for Intel Cherry Trail Whiskey Cove PMIC"
|
||||
depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK
|
||||
depends on X86 || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
@ -951,13 +965,13 @@ config MFD_RC5T583
|
||||
different functionality of the device.
|
||||
|
||||
config MFD_RK808
|
||||
tristate "Rockchip RK808/RK818 Power Management Chip"
|
||||
tristate "Rockchip RK805/RK808/RK818 Power Management Chip"
|
||||
depends on I2C && OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select REGMAP_IRQ
|
||||
help
|
||||
If you say yes here you get support for the RK808 and RK818
|
||||
If you say yes here you get support for the RK805, RK808 and RK818
|
||||
Power Management chips.
|
||||
This driver provides common support for accessing the device
|
||||
through I2C interface. The device supports multiple sub-devices
|
||||
@ -1294,6 +1308,7 @@ config TPS6507X
|
||||
|
||||
config MFD_TPS65086
|
||||
tristate "TI TPS65086 Power Management Integrated Chips (PMICs)"
|
||||
select MFD_CORE
|
||||
select REGMAP
|
||||
select REGMAP_IRQ
|
||||
select REGMAP_I2C
|
||||
@ -1337,6 +1352,24 @@ config MFD_TPS65217
|
||||
This driver can also be built as a module. If so, the module
|
||||
will be called tps65217.
|
||||
|
||||
config MFD_TPS68470
|
||||
bool "TI TPS68470 Power Management / LED chips"
|
||||
depends on ACPI && I2C=y
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
select I2C_DESIGNWARE_PLATFORM
|
||||
help
|
||||
If you say yes here you get support for the TPS68470 series of
|
||||
Power Management / LED chips.
|
||||
|
||||
These include voltage regulators, LEDs and other features
|
||||
that are often used in portable devices.
|
||||
|
||||
This option is a bool as it provides an ACPI operation
|
||||
region, which must be available before any of the devices
|
||||
using this are probed. This option also configures the
|
||||
designware-i2c driver to be built-in, for the same reason.
|
||||
|
||||
config MFD_TI_LP873X
|
||||
tristate "TI LP873X Power Management IC"
|
||||
depends on I2C
|
||||
@ -1723,6 +1756,20 @@ config MFD_STW481X
|
||||
in various ST Microelectronics and ST-Ericsson embedded
|
||||
Nomadik series.
|
||||
|
||||
config MFD_STM32_LPTIMER
|
||||
tristate "Support for STM32 Low-Power Timer"
|
||||
depends on (ARCH_STM32 && OF) || COMPILE_TEST
|
||||
select MFD_CORE
|
||||
select REGMAP
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Select this option to enable STM32 Low-Power Timer driver
|
||||
used for PWM, IIO Trigger, IIO Encoder and Counter. Shared
|
||||
resources are also dealt with here.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called stm32-lptimer.
|
||||
|
||||
config MFD_STM32_TIMERS
|
||||
tristate "Support for STM32 Timers"
|
||||
depends on (ARCH_STM32 && OF) || COMPILE_TEST
|
||||
|
@ -10,6 +10,7 @@ obj-$(CONFIG_MFD_ACT8945A) += act8945a.o
|
||||
obj-$(CONFIG_MFD_SM501) += sm501.o
|
||||
obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o
|
||||
obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o
|
||||
obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o
|
||||
cros_ec_core-objs := cros_ec.o
|
||||
cros_ec_core-$(CONFIG_ACPI) += cros_ec_acpi_gpe.o
|
||||
obj-$(CONFIG_MFD_CROS_EC) += cros_ec_core.o
|
||||
@ -83,6 +84,7 @@ obj-$(CONFIG_MFD_TPS65910) += tps65910.o
|
||||
obj-$(CONFIG_MFD_TPS65912) += tps65912-core.o
|
||||
obj-$(CONFIG_MFD_TPS65912_I2C) += tps65912-i2c.o
|
||||
obj-$(CONFIG_MFD_TPS65912_SPI) += tps65912-spi.o
|
||||
obj-$(CONFIG_MFD_TPS68470) += tps68470.o
|
||||
obj-$(CONFIG_MFD_TPS80031) += tps80031.o
|
||||
obj-$(CONFIG_MENELAUS) += menelaus.o
|
||||
|
||||
@ -221,5 +223,6 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
|
||||
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
|
||||
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
|
||||
|
||||
obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o
|
||||
obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
|
||||
obj-$(CONFIG_MFD_MXS_LRADC) += mxs-lradc.o
|
||||
|
@ -1059,15 +1059,15 @@ static struct attribute *ab9540_sysfs_entries[] = {
|
||||
NULL,
|
||||
};
|
||||
|
||||
static struct attribute_group ab8500_attr_group = {
|
||||
static const struct attribute_group ab8500_attr_group = {
|
||||
.attrs = ab8500_sysfs_entries,
|
||||
};
|
||||
|
||||
static struct attribute_group ab8505_attr_group = {
|
||||
static const struct attribute_group ab8505_attr_group = {
|
||||
.attrs = ab8505_sysfs_entries,
|
||||
};
|
||||
|
||||
static struct attribute_group ab9540_attr_group = {
|
||||
static const struct attribute_group ab9540_attr_group = {
|
||||
.attrs = ab9540_sysfs_entries,
|
||||
};
|
||||
|
||||
|
@ -258,19 +258,21 @@ EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_apply);
|
||||
* atmel_hsmc_cs_conf_apply - apply an SMC CS conf
|
||||
* @regmap: the HSMC regmap
|
||||
* @cs: the CS id
|
||||
* @layout: the layout of registers
|
||||
* @conf the SMC CS conf to apply
|
||||
*
|
||||
* Applies an SMC CS configuration.
|
||||
* Only valid on post-sama5 SoCs.
|
||||
*/
|
||||
void atmel_hsmc_cs_conf_apply(struct regmap *regmap, int cs,
|
||||
const struct atmel_smc_cs_conf *conf)
|
||||
void atmel_hsmc_cs_conf_apply(struct regmap *regmap,
|
||||
const struct atmel_hsmc_reg_layout *layout,
|
||||
int cs, const struct atmel_smc_cs_conf *conf)
|
||||
{
|
||||
regmap_write(regmap, ATMEL_HSMC_SETUP(cs), conf->setup);
|
||||
regmap_write(regmap, ATMEL_HSMC_PULSE(cs), conf->pulse);
|
||||
regmap_write(regmap, ATMEL_HSMC_CYCLE(cs), conf->cycle);
|
||||
regmap_write(regmap, ATMEL_HSMC_TIMINGS(cs), conf->timings);
|
||||
regmap_write(regmap, ATMEL_HSMC_MODE(cs), conf->mode);
|
||||
regmap_write(regmap, ATMEL_HSMC_SETUP(layout, cs), conf->setup);
|
||||
regmap_write(regmap, ATMEL_HSMC_PULSE(layout, cs), conf->pulse);
|
||||
regmap_write(regmap, ATMEL_HSMC_CYCLE(layout, cs), conf->cycle);
|
||||
regmap_write(regmap, ATMEL_HSMC_TIMINGS(layout, cs), conf->timings);
|
||||
regmap_write(regmap, ATMEL_HSMC_MODE(layout, cs), conf->mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_hsmc_cs_conf_apply);
|
||||
|
||||
@ -297,18 +299,55 @@ EXPORT_SYMBOL_GPL(atmel_smc_cs_conf_get);
|
||||
* atmel_hsmc_cs_conf_get - retrieve the current SMC CS conf
|
||||
* @regmap: the HSMC regmap
|
||||
* @cs: the CS id
|
||||
* @layout: the layout of registers
|
||||
* @conf: the SMC CS conf object to store the current conf
|
||||
*
|
||||
* Retrieve the SMC CS configuration.
|
||||
* Only valid on post-sama5 SoCs.
|
||||
*/
|
||||
void atmel_hsmc_cs_conf_get(struct regmap *regmap, int cs,
|
||||
struct atmel_smc_cs_conf *conf)
|
||||
void atmel_hsmc_cs_conf_get(struct regmap *regmap,
|
||||
const struct atmel_hsmc_reg_layout *layout,
|
||||
int cs, struct atmel_smc_cs_conf *conf)
|
||||
{
|
||||
regmap_read(regmap, ATMEL_HSMC_SETUP(cs), &conf->setup);
|
||||
regmap_read(regmap, ATMEL_HSMC_PULSE(cs), &conf->pulse);
|
||||
regmap_read(regmap, ATMEL_HSMC_CYCLE(cs), &conf->cycle);
|
||||
regmap_read(regmap, ATMEL_HSMC_TIMINGS(cs), &conf->timings);
|
||||
regmap_read(regmap, ATMEL_HSMC_MODE(cs), &conf->mode);
|
||||
regmap_read(regmap, ATMEL_HSMC_SETUP(layout, cs), &conf->setup);
|
||||
regmap_read(regmap, ATMEL_HSMC_PULSE(layout, cs), &conf->pulse);
|
||||
regmap_read(regmap, ATMEL_HSMC_CYCLE(layout, cs), &conf->cycle);
|
||||
regmap_read(regmap, ATMEL_HSMC_TIMINGS(layout, cs), &conf->timings);
|
||||
regmap_read(regmap, ATMEL_HSMC_MODE(layout, cs), &conf->mode);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_hsmc_cs_conf_get);
|
||||
|
||||
static const struct atmel_hsmc_reg_layout sama5d3_reg_layout = {
|
||||
.timing_regs_offset = 0x600,
|
||||
};
|
||||
|
||||
static const struct atmel_hsmc_reg_layout sama5d2_reg_layout = {
|
||||
.timing_regs_offset = 0x700,
|
||||
};
|
||||
|
||||
static const struct of_device_id atmel_smc_ids[] = {
|
||||
{ .compatible = "atmel,at91sam9260-smc", .data = NULL },
|
||||
{ .compatible = "atmel,sama5d3-smc", .data = &sama5d3_reg_layout },
|
||||
{ .compatible = "atmel,sama5d2-smc", .data = &sama5d2_reg_layout },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
/**
|
||||
* atmel_hsmc_get_reg_layout - retrieve the layout of HSMC registers
|
||||
* @np: the HSMC regmap
|
||||
*
|
||||
* Retrieve the layout of HSMC registers.
|
||||
*
|
||||
* Returns NULL in case of SMC, a struct atmel_hsmc_reg_layout pointer
|
||||
* in HSMC case, otherwise ERR_PTR(-EINVAL).
|
||||
*/
|
||||
const struct atmel_hsmc_reg_layout *
|
||||
atmel_hsmc_get_reg_layout(struct device_node *np)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
|
||||
match = of_match_node(atmel_smc_ids, np);
|
||||
|
||||
return match ? match->data : ERR_PTR(-EINVAL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(atmel_hsmc_get_reg_layout);
|
||||
|
@ -64,6 +64,7 @@ static const struct of_device_id axp20x_rsb_of_match[] = {
|
||||
{ .compatible = "x-powers,axp803", .data = (void *)AXP803_ID },
|
||||
{ .compatible = "x-powers,axp806", .data = (void *)AXP806_ID },
|
||||
{ .compatible = "x-powers,axp809", .data = (void *)AXP809_ID },
|
||||
{ .compatible = "x-powers,axp813", .data = (void *)AXP813_ID },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, axp20x_rsb_of_match);
|
||||
|
@ -44,6 +44,7 @@ static const char * const axp20x_model_names[] = {
|
||||
"AXP803",
|
||||
"AXP806",
|
||||
"AXP809",
|
||||
"AXP813",
|
||||
};
|
||||
|
||||
static const struct regmap_range axp152_writeable_ranges[] = {
|
||||
@ -676,7 +677,7 @@ static struct mfd_cell axp20x_cells[] = {
|
||||
|
||||
static struct mfd_cell axp221_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp22x_pek_resources),
|
||||
.resources = axp22x_pek_resources,
|
||||
}, {
|
||||
@ -701,7 +702,7 @@ static struct mfd_cell axp221_cells[] = {
|
||||
|
||||
static struct mfd_cell axp223_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp22x_pek_resources),
|
||||
.resources = axp22x_pek_resources,
|
||||
}, {
|
||||
@ -834,7 +835,7 @@ static struct mfd_cell axp288_cells[] = {
|
||||
.resources = axp288_fuel_gauge_resources,
|
||||
},
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp288_power_button_resources),
|
||||
.resources = axp288_power_button_resources,
|
||||
},
|
||||
@ -845,7 +846,7 @@ static struct mfd_cell axp288_cells[] = {
|
||||
|
||||
static struct mfd_cell axp803_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp803_pek_resources),
|
||||
.resources = axp803_pek_resources,
|
||||
},
|
||||
@ -861,7 +862,7 @@ static struct mfd_cell axp806_cells[] = {
|
||||
|
||||
static struct mfd_cell axp809_cells[] = {
|
||||
{
|
||||
.name = "axp20x-pek",
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp809_pek_resources),
|
||||
.resources = axp809_pek_resources,
|
||||
}, {
|
||||
@ -870,6 +871,14 @@ static struct mfd_cell axp809_cells[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell axp813_cells[] = {
|
||||
{
|
||||
.name = "axp221-pek",
|
||||
.num_resources = ARRAY_SIZE(axp803_pek_resources),
|
||||
.resources = axp803_pek_resources,
|
||||
}
|
||||
};
|
||||
|
||||
static struct axp20x_dev *axp20x_pm_power_off;
|
||||
static void axp20x_power_off(void)
|
||||
{
|
||||
@ -956,6 +965,19 @@ int axp20x_match_device(struct axp20x_dev *axp20x)
|
||||
axp20x->regmap_cfg = &axp22x_regmap_config;
|
||||
axp20x->regmap_irq_chip = &axp809_regmap_irq_chip;
|
||||
break;
|
||||
case AXP813_ID:
|
||||
axp20x->nr_cells = ARRAY_SIZE(axp813_cells);
|
||||
axp20x->cells = axp813_cells;
|
||||
axp20x->regmap_cfg = &axp288_regmap_config;
|
||||
/*
|
||||
* The IRQ table given in the datasheet is incorrect.
|
||||
* In IRQ enable/status registers 1, there are separate
|
||||
* IRQs for ACIN and VBUS, instead of bits [7:5] being
|
||||
* the same as bits [4:2]. So it shares the same IRQs
|
||||
* as the AXP803, rather than the AXP288.
|
||||
*/
|
||||
axp20x->regmap_irq_chip = &axp803_regmap_irq_chip;
|
||||
break;
|
||||
default:
|
||||
dev_err(dev, "unsupported AXP20X ID %lu\n", axp20x->variant);
|
||||
return -EINVAL;
|
||||
|
230
drivers/mfd/bd9571mwv.c
Normal file
230
drivers/mfd/bd9571mwv.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* ROHM BD9571MWV-M MFD driver
|
||||
*
|
||||
* Copyright (C) 2017 Marek Vasut <marek.vasut+renesas@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether expressed or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License version 2 for more details.
|
||||
*
|
||||
* Based on the TPS65086 driver
|
||||
*/
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/mfd/bd9571mwv.h>
|
||||
|
||||
static const struct mfd_cell bd9571mwv_cells[] = {
|
||||
{ .name = "bd9571mwv-regulator", },
|
||||
{ .name = "bd9571mwv-gpio", },
|
||||
};
|
||||
|
||||
static const struct regmap_range bd9571mwv_readable_yes_ranges[] = {
|
||||
regmap_reg_range(BD9571MWV_VENDOR_CODE, BD9571MWV_PRODUCT_REVISION),
|
||||
regmap_reg_range(BD9571MWV_AVS_SET_MONI, BD9571MWV_AVS_DVFS_VID(3)),
|
||||
regmap_reg_range(BD9571MWV_VD18_VID, BD9571MWV_VD33_VID),
|
||||
regmap_reg_range(BD9571MWV_DVFS_VINIT, BD9571MWV_DVFS_VINIT),
|
||||
regmap_reg_range(BD9571MWV_DVFS_SETVMAX, BD9571MWV_DVFS_MONIVDAC),
|
||||
regmap_reg_range(BD9571MWV_GPIO_IN, BD9571MWV_GPIO_IN),
|
||||
regmap_reg_range(BD9571MWV_GPIO_INT, BD9571MWV_GPIO_INTMASK),
|
||||
regmap_reg_range(BD9571MWV_INT_INTREQ, BD9571MWV_INT_INTMASK),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table bd9571mwv_readable_table = {
|
||||
.yes_ranges = bd9571mwv_readable_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(bd9571mwv_readable_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range bd9571mwv_writable_yes_ranges[] = {
|
||||
regmap_reg_range(BD9571MWV_AVS_VD09_VID(0), BD9571MWV_AVS_VD09_VID(3)),
|
||||
regmap_reg_range(BD9571MWV_DVFS_SETVID, BD9571MWV_DVFS_SETVID),
|
||||
regmap_reg_range(BD9571MWV_GPIO_DIR, BD9571MWV_GPIO_OUT),
|
||||
regmap_reg_range(BD9571MWV_GPIO_INT_SET, BD9571MWV_GPIO_INTMASK),
|
||||
regmap_reg_range(BD9571MWV_INT_INTREQ, BD9571MWV_INT_INTMASK),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table bd9571mwv_writable_table = {
|
||||
.yes_ranges = bd9571mwv_writable_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(bd9571mwv_writable_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_range bd9571mwv_volatile_yes_ranges[] = {
|
||||
regmap_reg_range(BD9571MWV_GPIO_IN, BD9571MWV_GPIO_IN),
|
||||
regmap_reg_range(BD9571MWV_GPIO_INT, BD9571MWV_GPIO_INT),
|
||||
regmap_reg_range(BD9571MWV_INT_INTREQ, BD9571MWV_INT_INTREQ),
|
||||
};
|
||||
|
||||
static const struct regmap_access_table bd9571mwv_volatile_table = {
|
||||
.yes_ranges = bd9571mwv_volatile_yes_ranges,
|
||||
.n_yes_ranges = ARRAY_SIZE(bd9571mwv_volatile_yes_ranges),
|
||||
};
|
||||
|
||||
static const struct regmap_config bd9571mwv_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.rd_table = &bd9571mwv_readable_table,
|
||||
.wr_table = &bd9571mwv_writable_table,
|
||||
.volatile_table = &bd9571mwv_volatile_table,
|
||||
.max_register = 0xff,
|
||||
};
|
||||
|
||||
static const struct regmap_irq bd9571mwv_irqs[] = {
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_MD1, 0,
|
||||
BD9571MWV_INT_INTREQ_MD1_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_MD2_E1, 0,
|
||||
BD9571MWV_INT_INTREQ_MD2_E1_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_MD2_E2, 0,
|
||||
BD9571MWV_INT_INTREQ_MD2_E2_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_PROT_ERR, 0,
|
||||
BD9571MWV_INT_INTREQ_PROT_ERR_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_GP, 0,
|
||||
BD9571MWV_INT_INTREQ_GP_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_128H_OF, 0,
|
||||
BD9571MWV_INT_INTREQ_128H_OF_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_WDT_OF, 0,
|
||||
BD9571MWV_INT_INTREQ_WDT_OF_INT),
|
||||
REGMAP_IRQ_REG(BD9571MWV_IRQ_BKUP_TRG, 0,
|
||||
BD9571MWV_INT_INTREQ_BKUP_TRG_INT),
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip bd9571mwv_irq_chip = {
|
||||
.name = "bd9571mwv",
|
||||
.status_base = BD9571MWV_INT_INTREQ,
|
||||
.mask_base = BD9571MWV_INT_INTMASK,
|
||||
.ack_base = BD9571MWV_INT_INTREQ,
|
||||
.init_ack_masked = true,
|
||||
.num_regs = 1,
|
||||
.irqs = bd9571mwv_irqs,
|
||||
.num_irqs = ARRAY_SIZE(bd9571mwv_irqs),
|
||||
};
|
||||
|
||||
static int bd9571mwv_identify(struct bd9571mwv *bd)
|
||||
{
|
||||
struct device *dev = bd->dev;
|
||||
unsigned int value;
|
||||
int ret;
|
||||
|
||||
ret = regmap_read(bd->regmap, BD9571MWV_VENDOR_CODE, &value);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read vendor code register (ret=%i)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (value != BD9571MWV_VENDOR_CODE_VAL) {
|
||||
dev_err(dev, "Invalid vendor code ID %02x (expected %02x)\n",
|
||||
value, BD9571MWV_VENDOR_CODE_VAL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_read(bd->regmap, BD9571MWV_PRODUCT_CODE, &value);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read product code register (ret=%i)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (value != BD9571MWV_PRODUCT_CODE_VAL) {
|
||||
dev_err(dev, "Invalid product code ID %02x (expected %02x)\n",
|
||||
value, BD9571MWV_PRODUCT_CODE_VAL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = regmap_read(bd->regmap, BD9571MWV_PRODUCT_REVISION, &value);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read revision register (ret=%i)\n",
|
||||
ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(dev, "Device: BD9571MWV rev. %d\n", value & 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd9571mwv_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *ids)
|
||||
{
|
||||
struct bd9571mwv *bd;
|
||||
int ret;
|
||||
|
||||
bd = devm_kzalloc(&client->dev, sizeof(*bd), GFP_KERNEL);
|
||||
if (!bd)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(client, bd);
|
||||
bd->dev = &client->dev;
|
||||
bd->irq = client->irq;
|
||||
|
||||
bd->regmap = devm_regmap_init_i2c(client, &bd9571mwv_regmap_config);
|
||||
if (IS_ERR(bd->regmap)) {
|
||||
dev_err(bd->dev, "Failed to initialize register map\n");
|
||||
return PTR_ERR(bd->regmap);
|
||||
}
|
||||
|
||||
ret = bd9571mwv_identify(bd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_add_irq_chip(bd->regmap, bd->irq, IRQF_ONESHOT, 0,
|
||||
&bd9571mwv_irq_chip, &bd->irq_data);
|
||||
if (ret) {
|
||||
dev_err(bd->dev, "Failed to register IRQ chip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(bd->dev, PLATFORM_DEVID_AUTO, bd9571mwv_cells,
|
||||
ARRAY_SIZE(bd9571mwv_cells), NULL, 0,
|
||||
regmap_irq_get_domain(bd->irq_data));
|
||||
if (ret) {
|
||||
regmap_del_irq_chip(bd->irq, bd->irq_data);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bd9571mwv_remove(struct i2c_client *client)
|
||||
{
|
||||
struct bd9571mwv *bd = i2c_get_clientdata(client);
|
||||
|
||||
regmap_del_irq_chip(bd->irq, bd->irq_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id bd9571mwv_of_match_table[] = {
|
||||
{ .compatible = "rohm,bd9571mwv", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bd9571mwv_of_match_table);
|
||||
|
||||
static const struct i2c_device_id bd9571mwv_id_table[] = {
|
||||
{ "bd9571mwv", 0 },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bd9571mwv_id_table);
|
||||
|
||||
static struct i2c_driver bd9571mwv_driver = {
|
||||
.driver = {
|
||||
.name = "bd9571mwv",
|
||||
.of_match_table = bd9571mwv_of_match_table,
|
||||
},
|
||||
.probe = bd9571mwv_probe,
|
||||
.remove = bd9571mwv_remove,
|
||||
.id_table = bd9571mwv_id_table,
|
||||
};
|
||||
module_i2c_driver(bd9571mwv_driver);
|
||||
|
||||
MODULE_AUTHOR("Marek Vasut <marek.vasut+renesas@gmail.com>");
|
||||
MODULE_DESCRIPTION("BD9571MWV PMIC Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -387,6 +387,8 @@ int da9052_adc_manual_read(struct da9052 *da9052, unsigned char channel)
|
||||
|
||||
mutex_lock(&da9052->auxadc_lock);
|
||||
|
||||
reinit_completion(&da9052->done);
|
||||
|
||||
/* Channel gets activated on enabling the Conversion bit */
|
||||
mux_sel = chan_mux[channel] | DA9052_ADC_MAN_MAN_CONV;
|
||||
|
||||
|
@ -67,7 +67,7 @@ static int da9052_spi_remove(struct spi_device *spi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct spi_device_id da9052_spi_id[] = {
|
||||
static const struct spi_device_id da9052_spi_id[] = {
|
||||
{"da9052", DA9052},
|
||||
{"da9053-aa", DA9053_AA},
|
||||
{"da9053-ba", DA9053_BA},
|
||||
|
@ -62,7 +62,7 @@ static int da9055_i2c_remove(struct i2c_client *i2c)
|
||||
* purposes separate). As a result there are specific DA9055 ids for PMIC
|
||||
* and CODEC, which must be different to operate together.
|
||||
*/
|
||||
static struct i2c_device_id da9055_i2c_id[] = {
|
||||
static const struct i2c_device_id da9055_i2c_id[] = {
|
||||
{"da9055-pmic", 0},
|
||||
{ }
|
||||
};
|
||||
|
@ -18,7 +18,7 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/leds.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/dm355evm_msp.h>
|
||||
#include <linux/mfd/dm355evm_msp.h>
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1,40 +1,35 @@
|
||||
/*
|
||||
* Device driver for Hi6421 IC
|
||||
* Device driver for Hi6421 PMIC
|
||||
*
|
||||
* Copyright (c) <2011-2014> HiSilicon Technologies Co., Ltd.
|
||||
* http://www.hisilicon.com
|
||||
* Copyright (c) <2013-2014> Linaro Ltd.
|
||||
* Copyright (c) <2013-2017> Linaro Ltd.
|
||||
* http://www.linaro.org
|
||||
*
|
||||
* Author: Guodong Xu <guodong.xu@linaro.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/hi6421-pmic.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/hi6421-pmic.h>
|
||||
|
||||
static const struct mfd_cell hi6421_devs[] = {
|
||||
{ .name = "hi6421-regulator", },
|
||||
};
|
||||
|
||||
static const struct mfd_cell hi6421v530_devs[] = {
|
||||
{ .name = "hi6421v530-regulator", },
|
||||
};
|
||||
|
||||
static const struct regmap_config hi6421_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
@ -42,12 +37,33 @@ static const struct regmap_config hi6421_regmap_config = {
|
||||
.max_register = HI6421_REG_TO_BUS_ADDR(HI6421_REG_MAX),
|
||||
};
|
||||
|
||||
static const struct of_device_id of_hi6421_pmic_match[] = {
|
||||
{
|
||||
.compatible = "hisilicon,hi6421-pmic",
|
||||
.data = (void *)HI6421
|
||||
},
|
||||
{
|
||||
.compatible = "hisilicon,hi6421v530-pmic",
|
||||
.data = (void *)HI6421_V530
|
||||
},
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match);
|
||||
|
||||
static int hi6421_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct hi6421_pmic *pmic;
|
||||
struct resource *res;
|
||||
const struct of_device_id *id;
|
||||
const struct mfd_cell *subdevs;
|
||||
enum hi6421_type type;
|
||||
void __iomem *base;
|
||||
int ret;
|
||||
int n_subdevs, ret;
|
||||
|
||||
id = of_match_device(of_hi6421_pmic_match, &pdev->dev);
|
||||
if (!id)
|
||||
return -EINVAL;
|
||||
type = (enum hi6421_type)id->data;
|
||||
|
||||
pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
@ -61,41 +77,50 @@ static int hi6421_pmic_probe(struct platform_device *pdev)
|
||||
pmic->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
|
||||
&hi6421_regmap_config);
|
||||
if (IS_ERR(pmic->regmap)) {
|
||||
dev_err(&pdev->dev,
|
||||
"regmap init failed: %ld\n", PTR_ERR(pmic->regmap));
|
||||
dev_err(&pdev->dev, "Failed to initialise Regmap: %ld\n",
|
||||
PTR_ERR(pmic->regmap));
|
||||
return PTR_ERR(pmic->regmap);
|
||||
}
|
||||
|
||||
/* set over-current protection debounce 8ms */
|
||||
regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
|
||||
switch (type) {
|
||||
case HI6421:
|
||||
/* set over-current protection debounce 8ms */
|
||||
regmap_update_bits(pmic->regmap, HI6421_OCP_DEB_CTRL_REG,
|
||||
(HI6421_OCP_DEB_SEL_MASK
|
||||
| HI6421_OCP_EN_DEBOUNCE_MASK
|
||||
| HI6421_OCP_AUTO_STOP_MASK),
|
||||
(HI6421_OCP_DEB_SEL_8MS
|
||||
| HI6421_OCP_EN_DEBOUNCE_ENABLE));
|
||||
|
||||
platform_set_drvdata(pdev, pmic);
|
||||
subdevs = hi6421_devs;
|
||||
n_subdevs = ARRAY_SIZE(hi6421_devs);
|
||||
break;
|
||||
case HI6421_V530:
|
||||
subdevs = hi6421v530_devs;
|
||||
n_subdevs = ARRAY_SIZE(hi6421v530_devs);
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "Unknown device type %d\n",
|
||||
(unsigned int)type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(&pdev->dev, 0, hi6421_devs,
|
||||
ARRAY_SIZE(hi6421_devs), NULL, 0, NULL);
|
||||
ret = devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_NONE,
|
||||
subdevs, n_subdevs, NULL, 0, NULL);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "add mfd devices failed: %d\n", ret);
|
||||
dev_err(&pdev->dev, "Failed to add child devices: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id of_hi6421_pmic_match_tbl[] = {
|
||||
{ .compatible = "hisilicon,hi6421-pmic", },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, of_hi6421_pmic_match_tbl);
|
||||
|
||||
static struct platform_driver hi6421_pmic_driver = {
|
||||
.driver = {
|
||||
.name = "hi6421_pmic",
|
||||
.of_match_table = of_hi6421_pmic_match_tbl,
|
||||
.name = "hi6421_pmic",
|
||||
.of_match_table = of_hi6421_pmic_match,
|
||||
},
|
||||
.probe = hi6421_pmic_probe,
|
||||
};
|
||||
|
@ -221,6 +221,7 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
|
||||
{ PCI_VDEVICE(INTEL, 0xa12a), (kernel_ulong_t)&spt_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa160), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa161), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa162), (kernel_ulong_t)&spt_i2c_info },
|
||||
{ PCI_VDEVICE(INTEL, 0xa166), (kernel_ulong_t)&spt_uart_info },
|
||||
/* KBL-H */
|
||||
{ PCI_VDEVICE(INTEL, 0xa2a7), (kernel_ulong_t)&spt_uart_info },
|
||||
|
@ -502,6 +502,14 @@ int intel_lpss_suspend(struct device *dev)
|
||||
for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
|
||||
lpss->priv_ctx[i] = readl(lpss->priv + i * 4);
|
||||
|
||||
/*
|
||||
* If the device type is not UART, then put the controller into
|
||||
* reset. UART cannot be put into reset since S3/S0ix fail when
|
||||
* no_console_suspend flag is enabled.
|
||||
*/
|
||||
if (lpss->type != LPSS_DEV_UART)
|
||||
writel(0, lpss->priv + LPSS_PRIV_RESETS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(intel_lpss_suspend);
|
||||
|
@ -16,6 +16,7 @@
|
||||
* Author: Zhu, Lejun <lejun.zhu@linux.intel.com>
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/i2c.h>
|
||||
@ -28,6 +29,10 @@
|
||||
#include <linux/pwm.h>
|
||||
#include "intel_soc_pmic_core.h"
|
||||
|
||||
/* Crystal Cove PMIC shares same ACPI ID between different platforms */
|
||||
#define BYT_CRC_HRV 2
|
||||
#define CHT_CRC_HRV 3
|
||||
|
||||
/* Lookup table for the Panel Enable/Disable line as GPIO signals */
|
||||
static struct gpiod_lookup_table panel_gpio_table = {
|
||||
/* Intel GFX is consumer */
|
||||
@ -48,16 +53,33 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *i2c_id)
|
||||
{
|
||||
struct device *dev = &i2c->dev;
|
||||
const struct acpi_device_id *id;
|
||||
struct intel_soc_pmic_config *config;
|
||||
struct intel_soc_pmic *pmic;
|
||||
unsigned long long hrv;
|
||||
acpi_status status;
|
||||
int ret;
|
||||
|
||||
id = acpi_match_device(dev->driver->acpi_match_table, dev);
|
||||
if (!id || !id->driver_data)
|
||||
/*
|
||||
* There are 2 different Crystal Cove PMICs a Bay Trail and Cherry
|
||||
* Trail version, use _HRV to differentiate between the 2.
|
||||
*/
|
||||
status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
dev_err(dev, "Failed to get PMIC hardware revision\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
config = (struct intel_soc_pmic_config *)id->driver_data;
|
||||
switch (hrv) {
|
||||
case BYT_CRC_HRV:
|
||||
config = &intel_soc_pmic_config_byt_crc;
|
||||
break;
|
||||
case CHT_CRC_HRV:
|
||||
config = &intel_soc_pmic_config_cht_crc;
|
||||
break;
|
||||
default:
|
||||
dev_warn(dev, "Unknown hardware rev %llu, assuming BYT\n", hrv);
|
||||
config = &intel_soc_pmic_config_byt_crc;
|
||||
}
|
||||
|
||||
pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL);
|
||||
if (!pmic)
|
||||
@ -157,7 +179,7 @@ MODULE_DEVICE_TABLE(i2c, intel_soc_pmic_i2c_id);
|
||||
|
||||
#if defined(CONFIG_ACPI)
|
||||
static const struct acpi_device_id intel_soc_pmic_acpi_match[] = {
|
||||
{"INT33FD", (kernel_ulong_t)&intel_soc_pmic_config_crc},
|
||||
{ "INT33FD" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, intel_soc_pmic_acpi_match);
|
||||
|
@ -27,6 +27,7 @@ struct intel_soc_pmic_config {
|
||||
const struct regmap_irq_chip *irq_chip;
|
||||
};
|
||||
|
||||
extern struct intel_soc_pmic_config intel_soc_pmic_config_crc;
|
||||
extern struct intel_soc_pmic_config intel_soc_pmic_config_byt_crc;
|
||||
extern struct intel_soc_pmic_config intel_soc_pmic_config_cht_crc;
|
||||
|
||||
#endif /* __INTEL_SOC_PMIC_CORE_H__ */
|
||||
|
@ -80,7 +80,7 @@ static struct resource bcu_resources[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell crystal_cove_dev[] = {
|
||||
static struct mfd_cell crystal_cove_byt_dev[] = {
|
||||
{
|
||||
.name = "crystal_cove_pwrsrc",
|
||||
.num_resources = ARRAY_SIZE(pwrsrc_resources),
|
||||
@ -114,6 +114,17 @@ static struct mfd_cell crystal_cove_dev[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct mfd_cell crystal_cove_cht_dev[] = {
|
||||
{
|
||||
.name = "crystal_cove_gpio",
|
||||
.num_resources = ARRAY_SIZE(gpio_resources),
|
||||
.resources = gpio_resources,
|
||||
},
|
||||
{
|
||||
.name = "crystal_cove_pwm",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_config crystal_cove_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -155,10 +166,18 @@ static const struct regmap_irq_chip crystal_cove_irq_chip = {
|
||||
.mask_base = CRYSTAL_COVE_REG_MIRQLVL1,
|
||||
};
|
||||
|
||||
struct intel_soc_pmic_config intel_soc_pmic_config_crc = {
|
||||
struct intel_soc_pmic_config intel_soc_pmic_config_byt_crc = {
|
||||
.irq_flags = IRQF_TRIGGER_RISING,
|
||||
.cell_dev = crystal_cove_dev,
|
||||
.n_cell_devs = ARRAY_SIZE(crystal_cove_dev),
|
||||
.cell_dev = crystal_cove_byt_dev,
|
||||
.n_cell_devs = ARRAY_SIZE(crystal_cove_byt_dev),
|
||||
.regmap_config = &crystal_cove_regmap_config,
|
||||
.irq_chip = &crystal_cove_irq_chip,
|
||||
};
|
||||
|
||||
struct intel_soc_pmic_config intel_soc_pmic_config_cht_crc = {
|
||||
.irq_flags = IRQF_TRIGGER_RISING,
|
||||
.cell_dev = crystal_cove_cht_dev,
|
||||
.n_cell_devs = ARRAY_SIZE(crystal_cove_cht_dev),
|
||||
.regmap_config = &crystal_cove_regmap_config,
|
||||
.irq_chip = &crystal_cove_irq_chip,
|
||||
};
|
||||
|
@ -73,10 +73,9 @@ static int lp87565_probe(struct i2c_client *client,
|
||||
|
||||
i2c_set_clientdata(client, lp87565);
|
||||
|
||||
ret = mfd_add_devices(lp87565->dev, PLATFORM_DEVID_AUTO, lp87565_cells,
|
||||
ARRAY_SIZE(lp87565_cells), NULL, 0, NULL);
|
||||
|
||||
return ret;
|
||||
return devm_mfd_add_devices(lp87565->dev, PLATFORM_DEVID_AUTO,
|
||||
lp87565_cells, ARRAY_SIZE(lp87565_cells),
|
||||
NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static const struct i2c_device_id lp87565_id_table[] = {
|
||||
|
@ -1119,17 +1119,7 @@ static int lpc_ich_init_spi(struct pci_dev *dev)
|
||||
res->start = spi_base + SPIBASE_LPT;
|
||||
res->end = res->start + SPIBASE_LPT_SZ - 1;
|
||||
|
||||
/*
|
||||
* Try to make the flash chip writeable now by
|
||||
* setting BCR_WPD. It it fails we tell the driver
|
||||
* that it can only read the chip.
|
||||
*/
|
||||
pci_read_config_dword(dev, BCR, &bcr);
|
||||
if (!(bcr & BCR_WPD)) {
|
||||
bcr |= BCR_WPD;
|
||||
pci_write_config_dword(dev, BCR, bcr);
|
||||
pci_read_config_dword(dev, BCR, &bcr);
|
||||
}
|
||||
info->writeable = !!(bcr & BCR_WPD);
|
||||
}
|
||||
break;
|
||||
|
@ -151,7 +151,7 @@ static int max8925_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct max8925_platform_data *pdata = dev_get_platdata(&client->dev);
|
||||
static struct max8925_chip *chip;
|
||||
struct max8925_chip *chip;
|
||||
struct device_node *node = client->dev.of_node;
|
||||
|
||||
if (node && !pdata) {
|
||||
|
@ -192,10 +192,8 @@ static int max8998_i2c_probe(struct i2c_client *i2c,
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) {
|
||||
pdata = max8998_i2c_parse_dt_pdata(&i2c->dev);
|
||||
if (IS_ERR(pdata)) {
|
||||
ret = PTR_ERR(pdata);
|
||||
goto err;
|
||||
}
|
||||
if (IS_ERR(pdata))
|
||||
return PTR_ERR(pdata);
|
||||
}
|
||||
|
||||
i2c_set_clientdata(i2c, max8998);
|
||||
|
@ -131,12 +131,12 @@ static inline u32 usbtll_read(void __iomem *base, u32 reg)
|
||||
return readl_relaxed(base + reg);
|
||||
}
|
||||
|
||||
static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
|
||||
static inline void usbtll_writeb(void __iomem *base, u32 reg, u8 val)
|
||||
{
|
||||
writeb_relaxed(val, base + reg);
|
||||
}
|
||||
|
||||
static inline u8 usbtll_readb(void __iomem *base, u8 reg)
|
||||
static inline u8 usbtll_readb(void __iomem *base, u32 reg)
|
||||
{
|
||||
return readb_relaxed(base + reg);
|
||||
}
|
||||
|
@ -302,15 +302,23 @@ static int retu_remove(struct i2c_client *i2c)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id retu_id[] = {
|
||||
{ "retu-mfd", 0 },
|
||||
{ "tahvo-mfd", 0 },
|
||||
{ "retu", 0 },
|
||||
{ "tahvo", 0 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, retu_id);
|
||||
|
||||
static const struct of_device_id retu_of_match[] = {
|
||||
{ .compatible = "nokia,retu" },
|
||||
{ .compatible = "nokia,tahvo" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, retu_of_match);
|
||||
|
||||
static struct i2c_driver retu_driver = {
|
||||
.driver = {
|
||||
.name = "retu-mfd",
|
||||
.of_match_table = retu_of_match,
|
||||
},
|
||||
.probe = retu_probe,
|
||||
.remove = retu_remove,
|
||||
|
@ -70,6 +70,14 @@ static const struct regmap_config rk818_regmap_config = {
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk805_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = RK805_OFF_SOURCE_REG,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
.volatile_reg = rk808_is_volatile_reg,
|
||||
};
|
||||
|
||||
static const struct regmap_config rk808_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
@ -86,6 +94,34 @@ static struct resource rtc_resources[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static struct resource rk805_key_resources[] = {
|
||||
{
|
||||
.start = RK805_IRQ_PWRON_FALL,
|
||||
.end = RK805_IRQ_PWRON_FALL,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
{
|
||||
.start = RK805_IRQ_PWRON_RISE,
|
||||
.end = RK805_IRQ_PWRON_RISE,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
}
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk805s[] = {
|
||||
{ .name = "rk808-clkout", },
|
||||
{ .name = "rk808-regulator", },
|
||||
{ .name = "rk805-pinctrl", },
|
||||
{
|
||||
.name = "rk808-rtc",
|
||||
.num_resources = ARRAY_SIZE(rtc_resources),
|
||||
.resources = &rtc_resources[0],
|
||||
},
|
||||
{ .name = "rk805-pwrkey",
|
||||
.num_resources = ARRAY_SIZE(rk805_key_resources),
|
||||
.resources = &rk805_key_resources[0],
|
||||
},
|
||||
};
|
||||
|
||||
static const struct mfd_cell rk808s[] = {
|
||||
{ .name = "rk808-clkout", },
|
||||
{ .name = "rk808-regulator", },
|
||||
@ -106,6 +142,20 @@ static const struct mfd_cell rk818s[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk808_reg_data rk805_pre_init_reg[] = {
|
||||
{RK805_BUCK1_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
|
||||
RK805_BUCK1_2_ILMAX_4000MA},
|
||||
{RK805_BUCK2_CONFIG_REG, RK805_BUCK1_2_ILMAX_MASK,
|
||||
RK805_BUCK1_2_ILMAX_4000MA},
|
||||
{RK805_BUCK3_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
|
||||
RK805_BUCK3_ILMAX_3000MA},
|
||||
{RK805_BUCK4_CONFIG_REG, RK805_BUCK3_4_ILMAX_MASK,
|
||||
RK805_BUCK4_ILMAX_3500MA},
|
||||
{RK805_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_400MA},
|
||||
{RK805_GPIO_IO_POL_REG, SLP_SD_MSK, SLEEP_FUN},
|
||||
{RK805_THERMAL_REG, TEMP_HOTDIE_MSK, TEMP115C},
|
||||
};
|
||||
|
||||
static const struct rk808_reg_data rk808_pre_init_reg[] = {
|
||||
{ RK808_BUCK3_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_150MA },
|
||||
{ RK808_BUCK4_CONFIG_REG, BUCK_ILMIN_MASK, BUCK_ILMIN_200MA },
|
||||
@ -135,6 +185,41 @@ static const struct rk808_reg_data rk818_pre_init_reg[] = {
|
||||
VB_LO_SEL_3500MV },
|
||||
};
|
||||
|
||||
static const struct regmap_irq rk805_irqs[] = {
|
||||
[RK805_IRQ_PWRON_RISE] = {
|
||||
.mask = RK805_IRQ_PWRON_RISE_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_VB_LOW] = {
|
||||
.mask = RK805_IRQ_VB_LOW_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_PWRON] = {
|
||||
.mask = RK805_IRQ_PWRON_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_PWRON_LP] = {
|
||||
.mask = RK805_IRQ_PWRON_LP_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_HOTDIE] = {
|
||||
.mask = RK805_IRQ_HOTDIE_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_RTC_ALARM] = {
|
||||
.mask = RK805_IRQ_RTC_ALARM_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_RTC_PERIOD] = {
|
||||
.mask = RK805_IRQ_RTC_PERIOD_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
[RK805_IRQ_PWRON_FALL] = {
|
||||
.mask = RK805_IRQ_PWRON_FALL_MSK,
|
||||
.reg_offset = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_irq rk808_irqs[] = {
|
||||
/* INT_STS */
|
||||
[RK808_IRQ_VOUT_LO] = {
|
||||
@ -247,6 +332,17 @@ static const struct regmap_irq rk818_irqs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct regmap_irq_chip rk805_irq_chip = {
|
||||
.name = "rk805",
|
||||
.irqs = rk805_irqs,
|
||||
.num_irqs = ARRAY_SIZE(rk805_irqs),
|
||||
.num_regs = 1,
|
||||
.status_base = RK805_INT_STS_REG,
|
||||
.mask_base = RK805_INT_STS_MSK_REG,
|
||||
.ack_base = RK805_INT_STS_REG,
|
||||
.init_ack_masked = true,
|
||||
};
|
||||
|
||||
static const struct regmap_irq_chip rk808_irq_chip = {
|
||||
.name = "rk808",
|
||||
.irqs = rk808_irqs,
|
||||
@ -272,6 +368,25 @@ static const struct regmap_irq_chip rk818_irq_chip = {
|
||||
};
|
||||
|
||||
static struct i2c_client *rk808_i2c_client;
|
||||
|
||||
static void rk805_device_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client);
|
||||
|
||||
if (!rk808) {
|
||||
dev_warn(&rk808_i2c_client->dev,
|
||||
"have no rk805, so do nothing here\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = regmap_update_bits(rk808->regmap,
|
||||
RK805_DEV_CTRL_REG,
|
||||
DEV_OFF, DEV_OFF);
|
||||
if (ret)
|
||||
dev_err(&rk808_i2c_client->dev, "power off error!\n");
|
||||
}
|
||||
|
||||
static void rk808_device_shutdown(void)
|
||||
{
|
||||
int ret;
|
||||
@ -309,6 +424,7 @@ static void rk818_device_shutdown(void)
|
||||
}
|
||||
|
||||
static const struct of_device_id rk808_of_match[] = {
|
||||
{ .compatible = "rockchip,rk805" },
|
||||
{ .compatible = "rockchip,rk808" },
|
||||
{ .compatible = "rockchip,rk818" },
|
||||
{ },
|
||||
@ -325,7 +441,7 @@ static int rk808_probe(struct i2c_client *client,
|
||||
void (*pm_pwroff_fn)(void);
|
||||
int nr_pre_init_regs;
|
||||
int nr_cells;
|
||||
int pm_off = 0;
|
||||
int pm_off = 0, msb, lsb;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
@ -333,16 +449,34 @@ static int rk808_probe(struct i2c_client *client,
|
||||
if (!rk808)
|
||||
return -ENOMEM;
|
||||
|
||||
rk808->variant = i2c_smbus_read_word_data(client, RK808_ID_MSB);
|
||||
if (rk808->variant < 0) {
|
||||
dev_err(&client->dev, "Failed to read the chip id at 0x%02x\n",
|
||||
/* Read chip variant */
|
||||
msb = i2c_smbus_read_byte_data(client, RK808_ID_MSB);
|
||||
if (msb < 0) {
|
||||
dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
|
||||
RK808_ID_MSB);
|
||||
return rk808->variant;
|
||||
return msb;
|
||||
}
|
||||
|
||||
dev_dbg(&client->dev, "Chip id: 0x%x\n", (unsigned int)rk808->variant);
|
||||
lsb = i2c_smbus_read_byte_data(client, RK808_ID_LSB);
|
||||
if (lsb < 0) {
|
||||
dev_err(&client->dev, "failed to read the chip id at 0x%x\n",
|
||||
RK808_ID_LSB);
|
||||
return lsb;
|
||||
}
|
||||
|
||||
rk808->variant = ((msb << 8) | lsb) & RK8XX_ID_MSK;
|
||||
dev_info(&client->dev, "chip id: 0x%x\n", (unsigned int)rk808->variant);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK805_ID:
|
||||
rk808->regmap_cfg = &rk805_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk805_irq_chip;
|
||||
pre_init_reg = rk805_pre_init_reg;
|
||||
nr_pre_init_regs = ARRAY_SIZE(rk805_pre_init_reg);
|
||||
cells = rk805s;
|
||||
nr_cells = ARRAY_SIZE(rk805s);
|
||||
pm_pwroff_fn = rk805_device_shutdown;
|
||||
break;
|
||||
case RK808_ID:
|
||||
rk808->regmap_cfg = &rk808_regmap_config;
|
||||
rk808->regmap_irq_chip = &rk808_irq_chip;
|
||||
@ -435,6 +569,7 @@ static int rk808_remove(struct i2c_client *client)
|
||||
}
|
||||
|
||||
static const struct i2c_device_id rk808_ids[] = {
|
||||
{ "rk805" },
|
||||
{ "rk808" },
|
||||
{ "rk818" },
|
||||
{ },
|
||||
|
@ -644,7 +644,7 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
|
||||
{
|
||||
int err, clk;
|
||||
u8 n, clk_divider, mcu_cnt, div;
|
||||
u8 depth[] = {
|
||||
static const u8 depth[] = {
|
||||
[RTSX_SSC_DEPTH_4M] = SSC_DEPTH_4M,
|
||||
[RTSX_SSC_DEPTH_2M] = SSC_DEPTH_2M,
|
||||
[RTSX_SSC_DEPTH_1M] = SSC_DEPTH_1M,
|
||||
@ -768,7 +768,7 @@ EXPORT_SYMBOL_GPL(rtsx_pci_card_power_off);
|
||||
|
||||
int rtsx_pci_card_exclusive_check(struct rtsx_pcr *pcr, int card)
|
||||
{
|
||||
unsigned int cd_mask[] = {
|
||||
static const unsigned int cd_mask[] = {
|
||||
[RTSX_SD_CARD] = SD_EXIST,
|
||||
[RTSX_MS_CARD] = MS_EXIST
|
||||
};
|
||||
|
107
drivers/mfd/stm32-lptimer.c
Normal file
107
drivers/mfd/stm32-lptimer.c
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* STM32 Low-Power Timer parent driver.
|
||||
*
|
||||
* Copyright (C) STMicroelectronics 2017
|
||||
*
|
||||
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
|
||||
*
|
||||
* Inspired by Benjamin Gaignard's stm32-timers driver
|
||||
*
|
||||
* License terms: GNU General Public License (GPL), version 2
|
||||
*/
|
||||
|
||||
#include <linux/mfd/stm32-lptimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_platform.h>
|
||||
|
||||
#define STM32_LPTIM_MAX_REGISTER 0x3fc
|
||||
|
||||
static const struct regmap_config stm32_lptimer_regmap_cfg = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = sizeof(u32),
|
||||
.max_register = STM32_LPTIM_MAX_REGISTER,
|
||||
};
|
||||
|
||||
static int stm32_lptimer_detect_encoder(struct stm32_lptimer *ddata)
|
||||
{
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Quadrature encoder mode bit can only be written and read back when
|
||||
* Low-Power Timer supports it.
|
||||
*/
|
||||
ret = regmap_update_bits(ddata->regmap, STM32_LPTIM_CFGR,
|
||||
STM32_LPTIM_ENC, STM32_LPTIM_ENC);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(ddata->regmap, STM32_LPTIM_CFGR, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_update_bits(ddata->regmap, STM32_LPTIM_CFGR,
|
||||
STM32_LPTIM_ENC, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ddata->has_encoder = !!(val & STM32_LPTIM_ENC);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_lptimer_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct stm32_lptimer *ddata;
|
||||
struct resource *res;
|
||||
void __iomem *mmio;
|
||||
int ret;
|
||||
|
||||
ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
|
||||
if (!ddata)
|
||||
return -ENOMEM;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
mmio = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(mmio))
|
||||
return PTR_ERR(mmio);
|
||||
|
||||
ddata->regmap = devm_regmap_init_mmio_clk(dev, "mux", mmio,
|
||||
&stm32_lptimer_regmap_cfg);
|
||||
if (IS_ERR(ddata->regmap))
|
||||
return PTR_ERR(ddata->regmap);
|
||||
|
||||
ddata->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(ddata->clk))
|
||||
return PTR_ERR(ddata->clk);
|
||||
|
||||
ret = stm32_lptimer_detect_encoder(ddata);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, ddata);
|
||||
|
||||
return devm_of_platform_populate(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_lptimer_of_match[] = {
|
||||
{ .compatible = "st,stm32-lptimer", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_lptimer_of_match);
|
||||
|
||||
static struct platform_driver stm32_lptimer_driver = {
|
||||
.probe = stm32_lptimer_probe,
|
||||
.driver = {
|
||||
.name = "stm32-lptimer",
|
||||
.of_match_table = stm32_lptimer_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(stm32_lptimer_driver);
|
||||
|
||||
MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 Low-Power Timer");
|
||||
MODULE_ALIAS("platform:stm32-lptimer");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -86,8 +86,11 @@ static int t7l66xb_mmc_enable(struct platform_device *mmc)
|
||||
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
|
||||
unsigned long flags;
|
||||
u8 dev_ctl;
|
||||
int ret;
|
||||
|
||||
clk_prepare_enable(t7l66xb->clk32k);
|
||||
ret = clk_prepare_enable(t7l66xb->clk32k);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
raw_spin_lock_irqsave(&t7l66xb->lock, flags);
|
||||
|
||||
@ -286,8 +289,12 @@ static int t7l66xb_resume(struct platform_device *dev)
|
||||
{
|
||||
struct t7l66xb *t7l66xb = platform_get_drvdata(dev);
|
||||
struct t7l66xb_platform_data *pdata = dev_get_platdata(&dev->dev);
|
||||
int ret;
|
||||
|
||||
ret = clk_prepare_enable(t7l66xb->clk48m);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
clk_prepare_enable(t7l66xb->clk48m);
|
||||
if (pdata && pdata->resume)
|
||||
pdata->resume(dev);
|
||||
|
||||
@ -361,7 +368,9 @@ static int t7l66xb_probe(struct platform_device *dev)
|
||||
goto err_ioremap;
|
||||
}
|
||||
|
||||
clk_prepare_enable(t7l66xb->clk48m);
|
||||
ret = clk_prepare_enable(t7l66xb->clk48m);
|
||||
if (ret)
|
||||
goto err_clk_enable;
|
||||
|
||||
if (pdata->enable)
|
||||
pdata->enable(dev);
|
||||
@ -386,6 +395,8 @@ static int t7l66xb_probe(struct platform_device *dev)
|
||||
return 0;
|
||||
|
||||
t7l66xb_detach_irq(dev);
|
||||
clk_disable_unprepare(t7l66xb->clk48m);
|
||||
err_clk_enable:
|
||||
iounmap(t7l66xb->scr);
|
||||
err_ioremap:
|
||||
release_resource(&t7l66xb->rscr);
|
||||
|
@ -173,9 +173,17 @@ static const struct i2c_device_id tps6105x_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tps6105x_id);
|
||||
|
||||
static const struct of_device_id tps6105x_of_match[] = {
|
||||
{ .compatible = "ti,tps61050" },
|
||||
{ .compatible = "ti,tps61052" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tps6105x_of_match);
|
||||
|
||||
static struct i2c_driver tps6105x_driver = {
|
||||
.driver = {
|
||||
.name = "tps6105x",
|
||||
.of_match_table = tps6105x_of_match,
|
||||
},
|
||||
.probe = tps6105x_probe,
|
||||
.remove = tps6105x_remove,
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
|
||||
|
106
drivers/mfd/tps68470.c
Normal file
106
drivers/mfd/tps68470.c
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* TPS68470 chip Parent driver
|
||||
*
|
||||
* Copyright (C) 2017 Intel Corporation
|
||||
*
|
||||
* Authors:
|
||||
* Rajmohan Mani <rajmohan.mani@intel.com>
|
||||
* Tianshu Qiu <tian.shu.qiu@intel.com>
|
||||
* Jian Xu Zheng <jian.xu.zheng@intel.com>
|
||||
* Yuning Pu <yuning.pu@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as
|
||||
* published by the Free Software Foundation version 2.
|
||||
*
|
||||
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
|
||||
* kind, whether express or implied; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/tps68470.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell tps68470s[] = {
|
||||
{ .name = "tps68470-gpio" },
|
||||
{ .name = "tps68470_pmic_opregion" },
|
||||
};
|
||||
|
||||
static const struct regmap_config tps68470_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = TPS68470_REG_MAX,
|
||||
};
|
||||
|
||||
static int tps68470_chip_init(struct device *dev, struct regmap *regmap)
|
||||
{
|
||||
unsigned int version;
|
||||
int ret;
|
||||
|
||||
/* Force software reset */
|
||||
ret = regmap_write(regmap, TPS68470_REG_RESET, TPS68470_REG_RESET_MASK);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(regmap, TPS68470_REG_REVID, &version);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to read revision register: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dev_info(dev, "TPS68470 REVID: 0x%x\n", version);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tps68470_probe(struct i2c_client *client)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
regmap = devm_regmap_init_i2c(client, &tps68470_regmap_config);
|
||||
if (IS_ERR(regmap)) {
|
||||
dev_err(dev, "devm_regmap_init_i2c Error %ld\n",
|
||||
PTR_ERR(regmap));
|
||||
return PTR_ERR(regmap);
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, regmap);
|
||||
|
||||
ret = tps68470_chip_init(dev, regmap);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "TPS68470 Init Error %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, tps68470s,
|
||||
ARRAY_SIZE(tps68470s), NULL, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "devm_mfd_add_devices failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct acpi_device_id tps68470_acpi_ids[] = {
|
||||
{"INT3472"},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(acpi, tps68470_acpi_ids);
|
||||
|
||||
static struct i2c_driver tps68470_driver = {
|
||||
.driver = {
|
||||
.name = "tps68470",
|
||||
.acpi_match_table = tps68470_acpi_ids,
|
||||
},
|
||||
.probe_new = tps68470_probe,
|
||||
};
|
||||
builtin_i2c_driver(tps68470_driver);
|
@ -44,7 +44,7 @@
|
||||
#include <linux/regulator/machine.h>
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
|
||||
/* Register descriptions for audio */
|
||||
#include <linux/mfd/twl4030-audio.h>
|
||||
@ -173,7 +173,7 @@ static struct twl_private *twl_priv;
|
||||
static struct twl_mapping twl4030_map[] = {
|
||||
/*
|
||||
* NOTE: don't change this table without updating the
|
||||
* <linux/i2c/twl.h> defines for TWL4030_MODULE_*
|
||||
* <linux/mfd/twl.h> defines for TWL4030_MODULE_*
|
||||
* so they continue to match the order in this table.
|
||||
*/
|
||||
|
||||
@ -344,7 +344,7 @@ static const struct regmap_config twl4030_regmap_config[4] = {
|
||||
static struct twl_mapping twl6030_map[] = {
|
||||
/*
|
||||
* NOTE: don't change this table without updating the
|
||||
* <linux/i2c/twl.h> defines for TWL4030_MODULE_*
|
||||
* <linux/mfd/twl.h> defines for TWL4030_MODULE_*
|
||||
* so they continue to match the order in this table.
|
||||
*/
|
||||
|
||||
@ -448,7 +448,7 @@ static struct regmap *twl_get_regmap(u8 mod_no)
|
||||
* @reg: register address (just offset will do)
|
||||
* @num_bytes: number of bytes to transfer
|
||||
*
|
||||
* Returns the result of operation - 0 is success
|
||||
* Returns 0 on success or else a negative error code.
|
||||
*/
|
||||
int twl_i2c_write(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
||||
{
|
||||
@ -476,7 +476,7 @@ EXPORT_SYMBOL(twl_i2c_write);
|
||||
* @reg: register address (just offset will do)
|
||||
* @num_bytes: number of bytes to transfer
|
||||
*
|
||||
* Returns result of operation - num_bytes is success else failure.
|
||||
* Returns 0 on success or else a negative error code.
|
||||
*/
|
||||
int twl_i2c_read(u8 mod_no, u8 *value, u8 reg, unsigned num_bytes)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/twl4030-audio.h>
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/irqdomain.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
|
||||
#include "twl-core.h"
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/suspend.h>
|
||||
#include <linux/of.h>
|
||||
|
@ -247,6 +247,7 @@ struct atmel_hsmc_nand_controller {
|
||||
void __iomem *virt;
|
||||
dma_addr_t dma;
|
||||
} sram;
|
||||
const struct atmel_hsmc_reg_layout *hsmc_layout;
|
||||
struct regmap *io;
|
||||
struct atmel_nfc_op op;
|
||||
struct completion complete;
|
||||
@ -1442,12 +1443,12 @@ static int atmel_hsmc_nand_setup_data_interface(struct atmel_nand *nand,
|
||||
int csline,
|
||||
const struct nand_data_interface *conf)
|
||||
{
|
||||
struct atmel_nand_controller *nc;
|
||||
struct atmel_hsmc_nand_controller *nc;
|
||||
struct atmel_smc_cs_conf smcconf;
|
||||
struct atmel_nand_cs *cs;
|
||||
int ret;
|
||||
|
||||
nc = to_nand_controller(nand->base.controller);
|
||||
nc = to_hsmc_nand_controller(nand->base.controller);
|
||||
|
||||
ret = atmel_smc_nand_prepare_smcconf(nand, conf, &smcconf);
|
||||
if (ret)
|
||||
@ -1462,7 +1463,8 @@ static int atmel_hsmc_nand_setup_data_interface(struct atmel_nand *nand,
|
||||
if (cs->rb.type == ATMEL_NAND_NATIVE_RB)
|
||||
cs->smcconf.timings |= ATMEL_HSMC_TIMINGS_RBNSEL(cs->rb.id);
|
||||
|
||||
atmel_hsmc_cs_conf_apply(nc->smc, cs->id, &cs->smcconf);
|
||||
atmel_hsmc_cs_conf_apply(nc->base.smc, nc->hsmc_layout, cs->id,
|
||||
&cs->smcconf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2177,6 +2179,8 @@ atmel_hsmc_nand_controller_init(struct atmel_hsmc_nand_controller *nc)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nc->hsmc_layout = atmel_hsmc_get_reg_layout(np);
|
||||
|
||||
nc->irq = of_irq_get(np, 0);
|
||||
of_node_put(np);
|
||||
if (nc->irq < 0) {
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/usb/musb.h>
|
||||
#include <linux/usb/ulpi.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -338,6 +338,15 @@ config PINCTRL_INGENIC
|
||||
select GENERIC_PINMUX_FUNCTIONS
|
||||
select REGMAP_MMIO
|
||||
|
||||
config PINCTRL_RK805
|
||||
tristate "Pinctrl and GPIO driver for RK805 PMIC"
|
||||
depends on MFD_RK808
|
||||
select GPIOLIB
|
||||
select PINMUX
|
||||
select GENERIC_PINCONF
|
||||
help
|
||||
This selects the pinctrl driver for RK805.
|
||||
|
||||
source "drivers/pinctrl/aspeed/Kconfig"
|
||||
source "drivers/pinctrl/bcm/Kconfig"
|
||||
source "drivers/pinctrl/berlin/Kconfig"
|
||||
|
@ -43,6 +43,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
|
||||
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
|
||||
obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o
|
||||
obj-$(CONFIG_PINCTRL_INGENIC) += pinctrl-ingenic.o
|
||||
obj-$(CONFIG_PINCTRL_RK805) += pinctrl-rk805.o
|
||||
|
||||
obj-$(CONFIG_ARCH_ASPEED) += aspeed/
|
||||
obj-y += bcm/
|
||||
|
493
drivers/pinctrl/pinctrl-rk805.c
Normal file
493
drivers/pinctrl/pinctrl-rk805.c
Normal file
@ -0,0 +1,493 @@
|
||||
/*
|
||||
* Pinctrl driver for Rockchip RK805 PMIC
|
||||
*
|
||||
* Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd
|
||||
*
|
||||
* Author: Joseph Chen <chenjh@rock-chips.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* Based on the pinctrl-as3722 driver
|
||||
*/
|
||||
|
||||
#include <linux/gpio/driver.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mfd/rk808.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/pinctrl/machine.h>
|
||||
#include <linux/pinctrl/pinctrl.h>
|
||||
#include <linux/pinctrl/pinconf-generic.h>
|
||||
#include <linux/pinctrl/pinconf.h>
|
||||
#include <linux/pinctrl/pinmux.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "core.h"
|
||||
#include "pinconf.h"
|
||||
#include "pinctrl-utils.h"
|
||||
|
||||
struct rk805_pin_function {
|
||||
const char *name;
|
||||
const char *const *groups;
|
||||
unsigned int ngroups;
|
||||
int mux_option;
|
||||
};
|
||||
|
||||
struct rk805_pin_group {
|
||||
const char *name;
|
||||
const unsigned int pins[1];
|
||||
unsigned int npins;
|
||||
};
|
||||
|
||||
/*
|
||||
* @reg: gpio setting register;
|
||||
* @fun_mask: functions select mask value, when set is gpio;
|
||||
* @dir_mask: input or output mask value, when set is output, otherwise input;
|
||||
* @val_mask: gpio set value, when set is level high, otherwise low;
|
||||
*
|
||||
* Different PMIC has different pin features, belowing 3 mask members are not
|
||||
* all necessary for every PMIC. For example, RK805 has 2 pins that can be used
|
||||
* as output only GPIOs, so func_mask and dir_mask are not needed. RK816 has 1
|
||||
* pin that can be used as TS/GPIO, so fun_mask, dir_mask and val_mask are all
|
||||
* necessary.
|
||||
*/
|
||||
struct rk805_pin_config {
|
||||
u8 reg;
|
||||
u8 fun_msk;
|
||||
u8 dir_msk;
|
||||
u8 val_msk;
|
||||
};
|
||||
|
||||
struct rk805_pctrl_info {
|
||||
struct rk808 *rk808;
|
||||
struct device *dev;
|
||||
struct pinctrl_dev *pctl;
|
||||
struct gpio_chip gpio_chip;
|
||||
struct pinctrl_desc pinctrl_desc;
|
||||
const struct rk805_pin_function *functions;
|
||||
unsigned int num_functions;
|
||||
const struct rk805_pin_group *groups;
|
||||
int num_pin_groups;
|
||||
const struct pinctrl_pin_desc *pins;
|
||||
unsigned int num_pins;
|
||||
struct rk805_pin_config *pin_cfg;
|
||||
};
|
||||
|
||||
enum rk805_pinmux_option {
|
||||
RK805_PINMUX_GPIO,
|
||||
};
|
||||
|
||||
enum {
|
||||
RK805_GPIO0,
|
||||
RK805_GPIO1,
|
||||
};
|
||||
|
||||
static const char *const rk805_gpio_groups[] = {
|
||||
"gpio0",
|
||||
"gpio1",
|
||||
};
|
||||
|
||||
/* RK805: 2 output only GPIOs */
|
||||
static const struct pinctrl_pin_desc rk805_pins_desc[] = {
|
||||
PINCTRL_PIN(RK805_GPIO0, "gpio0"),
|
||||
PINCTRL_PIN(RK805_GPIO1, "gpio1"),
|
||||
};
|
||||
|
||||
static const struct rk805_pin_function rk805_pin_functions[] = {
|
||||
{
|
||||
.name = "gpio",
|
||||
.groups = rk805_gpio_groups,
|
||||
.ngroups = ARRAY_SIZE(rk805_gpio_groups),
|
||||
.mux_option = RK805_PINMUX_GPIO,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct rk805_pin_group rk805_pin_groups[] = {
|
||||
{
|
||||
.name = "gpio0",
|
||||
.pins = { RK805_GPIO0 },
|
||||
.npins = 1,
|
||||
},
|
||||
{
|
||||
.name = "gpio1",
|
||||
.pins = { RK805_GPIO1 },
|
||||
.npins = 1,
|
||||
},
|
||||
};
|
||||
|
||||
#define RK805_GPIO0_VAL_MSK BIT(0)
|
||||
#define RK805_GPIO1_VAL_MSK BIT(1)
|
||||
|
||||
static struct rk805_pin_config rk805_gpio_cfgs[] = {
|
||||
{
|
||||
.reg = RK805_OUT_REG,
|
||||
.val_msk = RK805_GPIO0_VAL_MSK,
|
||||
},
|
||||
{
|
||||
.reg = RK805_OUT_REG,
|
||||
.val_msk = RK805_GPIO1_VAL_MSK,
|
||||
},
|
||||
};
|
||||
|
||||
/* generic gpio chip */
|
||||
static int rk805_gpio_get(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = gpiochip_get_data(chip);
|
||||
int ret, val;
|
||||
|
||||
ret = regmap_read(pci->rk808->regmap, pci->pin_cfg[offset].reg, &val);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "get gpio%d value failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return !!(val & pci->pin_cfg[offset].val_msk);
|
||||
}
|
||||
|
||||
static void rk805_gpio_set(struct gpio_chip *chip,
|
||||
unsigned int offset,
|
||||
int value)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = gpiochip_get_data(chip);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(pci->rk808->regmap,
|
||||
pci->pin_cfg[offset].reg,
|
||||
pci->pin_cfg[offset].val_msk,
|
||||
value ? pci->pin_cfg[offset].val_msk : 0);
|
||||
if (ret)
|
||||
dev_err(pci->dev, "set gpio%d value %d failed\n",
|
||||
offset, value);
|
||||
}
|
||||
|
||||
static int rk805_gpio_direction_input(struct gpio_chip *chip,
|
||||
unsigned int offset)
|
||||
{
|
||||
return pinctrl_gpio_direction_input(chip->base + offset);
|
||||
}
|
||||
|
||||
static int rk805_gpio_direction_output(struct gpio_chip *chip,
|
||||
unsigned int offset, int value)
|
||||
{
|
||||
rk805_gpio_set(chip, offset, value);
|
||||
return pinctrl_gpio_direction_output(chip->base + offset);
|
||||
}
|
||||
|
||||
static int rk805_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = gpiochip_get_data(chip);
|
||||
unsigned int val;
|
||||
int ret;
|
||||
|
||||
/* default output*/
|
||||
if (!pci->pin_cfg[offset].dir_msk)
|
||||
return 0;
|
||||
|
||||
ret = regmap_read(pci->rk808->regmap,
|
||||
pci->pin_cfg[offset].reg,
|
||||
&val);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "get gpio%d direction failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return !(val & pci->pin_cfg[offset].dir_msk);
|
||||
}
|
||||
|
||||
static struct gpio_chip rk805_gpio_chip = {
|
||||
.label = "rk805-gpio",
|
||||
.request = gpiochip_generic_request,
|
||||
.free = gpiochip_generic_free,
|
||||
.get_direction = rk805_gpio_get_direction,
|
||||
.get = rk805_gpio_get,
|
||||
.set = rk805_gpio_set,
|
||||
.direction_input = rk805_gpio_direction_input,
|
||||
.direction_output = rk805_gpio_direction_output,
|
||||
.can_sleep = true,
|
||||
.base = -1,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
/* generic pinctrl */
|
||||
static int rk805_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pci->num_pin_groups;
|
||||
}
|
||||
|
||||
static const char *rk805_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
|
||||
unsigned int group)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pci->groups[group].name;
|
||||
}
|
||||
|
||||
static int rk805_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
|
||||
unsigned int group,
|
||||
const unsigned int **pins,
|
||||
unsigned int *num_pins)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*pins = pci->groups[group].pins;
|
||||
*num_pins = pci->groups[group].npins;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinctrl_ops rk805_pinctrl_ops = {
|
||||
.get_groups_count = rk805_pinctrl_get_groups_count,
|
||||
.get_group_name = rk805_pinctrl_get_group_name,
|
||||
.get_group_pins = rk805_pinctrl_get_group_pins,
|
||||
.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
|
||||
.dt_free_map = pinctrl_utils_free_map,
|
||||
};
|
||||
|
||||
static int rk805_pinctrl_get_funcs_count(struct pinctrl_dev *pctldev)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pci->num_functions;
|
||||
}
|
||||
|
||||
static const char *rk805_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
|
||||
unsigned int function)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
return pci->functions[function].name;
|
||||
}
|
||||
|
||||
static int rk805_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
|
||||
unsigned int function,
|
||||
const char *const **groups,
|
||||
unsigned int *const num_groups)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
|
||||
*groups = pci->functions[function].groups;
|
||||
*num_groups = pci->functions[function].ngroups;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
|
||||
unsigned int offset,
|
||||
int mux)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
int ret;
|
||||
|
||||
if (!pci->pin_cfg[offset].fun_msk)
|
||||
return 0;
|
||||
|
||||
if (mux == RK805_PINMUX_GPIO) {
|
||||
ret = regmap_update_bits(pci->rk808->regmap,
|
||||
pci->pin_cfg[offset].reg,
|
||||
pci->pin_cfg[offset].fun_msk,
|
||||
pci->pin_cfg[offset].fun_msk);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "set gpio%d GPIO failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
dev_err(pci->dev, "Couldn't find function mux %d\n", mux);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk805_pinctrl_set_mux(struct pinctrl_dev *pctldev,
|
||||
unsigned int function,
|
||||
unsigned int group)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
int mux = pci->functions[function].mux_option;
|
||||
int offset = group;
|
||||
|
||||
return _rk805_pinctrl_set_mux(pctldev, offset, mux);
|
||||
}
|
||||
|
||||
static int rk805_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
|
||||
struct pinctrl_gpio_range *range,
|
||||
unsigned int offset, bool input)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
int ret;
|
||||
|
||||
/* switch to gpio function */
|
||||
ret = _rk805_pinctrl_set_mux(pctldev, offset, RK805_PINMUX_GPIO);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "set gpio%d mux failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* set direction */
|
||||
if (!pci->pin_cfg[offset].dir_msk)
|
||||
return 0;
|
||||
|
||||
ret = regmap_update_bits(pci->rk808->regmap,
|
||||
pci->pin_cfg[offset].reg,
|
||||
pci->pin_cfg[offset].dir_msk,
|
||||
input ? 0 : pci->pin_cfg[offset].dir_msk);
|
||||
if (ret) {
|
||||
dev_err(pci->dev, "set gpio%d direction failed\n", offset);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct pinmux_ops rk805_pinmux_ops = {
|
||||
.get_functions_count = rk805_pinctrl_get_funcs_count,
|
||||
.get_function_name = rk805_pinctrl_get_func_name,
|
||||
.get_function_groups = rk805_pinctrl_get_func_groups,
|
||||
.set_mux = rk805_pinctrl_set_mux,
|
||||
.gpio_set_direction = rk805_pmx_gpio_set_direction,
|
||||
};
|
||||
|
||||
static int rk805_pinconf_get(struct pinctrl_dev *pctldev,
|
||||
unsigned int pin, unsigned long *config)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
enum pin_config_param param = pinconf_to_config_param(*config);
|
||||
u32 arg = 0;
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
arg = rk805_gpio_get(&pci->gpio_chip, pin);
|
||||
break;
|
||||
default:
|
||||
dev_err(pci->dev, "Properties not supported\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
*config = pinconf_to_config_packed(param, (u16)arg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rk805_pinconf_set(struct pinctrl_dev *pctldev,
|
||||
unsigned int pin, unsigned long *configs,
|
||||
unsigned int num_configs)
|
||||
{
|
||||
struct rk805_pctrl_info *pci = pinctrl_dev_get_drvdata(pctldev);
|
||||
enum pin_config_param param;
|
||||
u32 i, arg = 0;
|
||||
|
||||
for (i = 0; i < num_configs; i++) {
|
||||
param = pinconf_to_config_param(configs[i]);
|
||||
arg = pinconf_to_config_argument(configs[i]);
|
||||
|
||||
switch (param) {
|
||||
case PIN_CONFIG_OUTPUT:
|
||||
rk805_gpio_set(&pci->gpio_chip, pin, arg);
|
||||
rk805_pmx_gpio_set_direction(pctldev, NULL, pin, false);
|
||||
break;
|
||||
default:
|
||||
dev_err(pci->dev, "Properties not supported\n");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct pinconf_ops rk805_pinconf_ops = {
|
||||
.pin_config_get = rk805_pinconf_get,
|
||||
.pin_config_set = rk805_pinconf_set,
|
||||
};
|
||||
|
||||
static struct pinctrl_desc rk805_pinctrl_desc = {
|
||||
.name = "rk805-pinctrl",
|
||||
.pctlops = &rk805_pinctrl_ops,
|
||||
.pmxops = &rk805_pinmux_ops,
|
||||
.confops = &rk805_pinconf_ops,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static int rk805_pinctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk805_pctrl_info *pci;
|
||||
int ret;
|
||||
|
||||
pci = devm_kzalloc(&pdev->dev, sizeof(*pci), GFP_KERNEL);
|
||||
if (!pci)
|
||||
return -ENOMEM;
|
||||
|
||||
pci->dev = &pdev->dev;
|
||||
pci->dev->of_node = pdev->dev.parent->of_node;
|
||||
pci->rk808 = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
pci->pinctrl_desc = rk805_pinctrl_desc;
|
||||
pci->gpio_chip = rk805_gpio_chip;
|
||||
pci->gpio_chip.parent = &pdev->dev;
|
||||
pci->gpio_chip.of_node = pdev->dev.parent->of_node;
|
||||
|
||||
platform_set_drvdata(pdev, pci);
|
||||
|
||||
switch (pci->rk808->variant) {
|
||||
case RK805_ID:
|
||||
pci->pins = rk805_pins_desc;
|
||||
pci->num_pins = ARRAY_SIZE(rk805_pins_desc);
|
||||
pci->functions = rk805_pin_functions;
|
||||
pci->num_functions = ARRAY_SIZE(rk805_pin_functions);
|
||||
pci->groups = rk805_pin_groups;
|
||||
pci->num_pin_groups = ARRAY_SIZE(rk805_pin_groups);
|
||||
pci->pinctrl_desc.pins = rk805_pins_desc;
|
||||
pci->pinctrl_desc.npins = ARRAY_SIZE(rk805_pins_desc);
|
||||
pci->pin_cfg = rk805_gpio_cfgs;
|
||||
pci->gpio_chip.ngpio = ARRAY_SIZE(rk805_gpio_cfgs);
|
||||
break;
|
||||
default:
|
||||
dev_err(&pdev->dev, "unsupported RK805 ID %lu\n",
|
||||
pci->rk808->variant);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Add gpio chip */
|
||||
ret = devm_gpiochip_add_data(&pdev->dev, &pci->gpio_chip, pci);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Couldn't add gpiochip\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Add pinctrl */
|
||||
pci->pctl = devm_pinctrl_register(&pdev->dev, &pci->pinctrl_desc, pci);
|
||||
if (IS_ERR(pci->pctl)) {
|
||||
dev_err(&pdev->dev, "Couldn't add pinctrl\n");
|
||||
return PTR_ERR(pci->pctl);
|
||||
}
|
||||
|
||||
/* Add pin range */
|
||||
ret = gpiochip_add_pin_range(&pci->gpio_chip, dev_name(&pdev->dev),
|
||||
0, 0, pci->gpio_chip.ngpio);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Couldn't add gpiochip pin range\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver rk805_pinctrl_driver = {
|
||||
.probe = rk805_pinctrl_probe,
|
||||
.driver = {
|
||||
.name = "rk805-pinctrl",
|
||||
},
|
||||
};
|
||||
module_platform_driver(rk805_pinctrl_driver);
|
||||
|
||||
MODULE_DESCRIPTION("RK805 pin control and GPIO driver");
|
||||
MODULE_AUTHOR("Joseph Chen <chenjh@rock-chips.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -18,7 +18,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/usb/otg.h>
|
||||
|
@ -417,6 +417,16 @@ config PWM_STM32
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-stm32.
|
||||
|
||||
config PWM_STM32_LP
|
||||
tristate "STMicroelectronics STM32 PWM LP"
|
||||
depends on MFD_STM32_LPTIMER || COMPILE_TEST
|
||||
help
|
||||
Generic PWM framework driver for STMicroelectronics STM32 SoCs
|
||||
with Low-Power Timer (LPTIM).
|
||||
|
||||
To compile this driver as a module, choose M here: the module
|
||||
will be called pwm-stm32-lp.
|
||||
|
||||
config PWM_STMPE
|
||||
bool "STMPE expander PWM export"
|
||||
depends on MFD_STMPE
|
||||
|
@ -40,6 +40,7 @@ obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o
|
||||
obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o
|
||||
obj-$(CONFIG_PWM_STI) += pwm-sti.o
|
||||
obj-$(CONFIG_PWM_STM32) += pwm-stm32.o
|
||||
obj-$(CONFIG_PWM_STM32_LP) += pwm-stm32-lp.o
|
||||
obj-$(CONFIG_PWM_STMPE) += pwm-stmpe.o
|
||||
obj-$(CONFIG_PWM_SUN4I) += pwm-sun4i.o
|
||||
obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o
|
||||
|
246
drivers/pwm/pwm-stm32-lp.c
Normal file
246
drivers/pwm/pwm-stm32-lp.c
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* STM32 Low-Power Timer PWM driver
|
||||
*
|
||||
* Copyright (C) STMicroelectronics 2017
|
||||
*
|
||||
* Author: Gerald Baeza <gerald.baeza@st.com>
|
||||
*
|
||||
* License terms: GNU General Public License (GPL), version 2
|
||||
*
|
||||
* Inspired by Gerald Baeza's pwm-stm32 driver
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/mfd/stm32-lptimer.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
|
||||
struct stm32_pwm_lp {
|
||||
struct pwm_chip chip;
|
||||
struct clk *clk;
|
||||
struct regmap *regmap;
|
||||
};
|
||||
|
||||
static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip)
|
||||
{
|
||||
return container_of(chip, struct stm32_pwm_lp, chip);
|
||||
}
|
||||
|
||||
/* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */
|
||||
#define STM32_LPTIM_MAX_PRESCALER 128
|
||||
|
||||
static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
|
||||
unsigned long long prd, div, dty;
|
||||
struct pwm_state cstate;
|
||||
u32 val, mask, cfgr, presc = 0;
|
||||
bool reenable;
|
||||
int ret;
|
||||
|
||||
pwm_get_state(pwm, &cstate);
|
||||
reenable = !cstate.enabled;
|
||||
|
||||
if (!state->enabled) {
|
||||
if (cstate.enabled) {
|
||||
/* Disable LP timer */
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* disable clock to PWM counter */
|
||||
clk_disable(priv->clk);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Calculate the period and prescaler value */
|
||||
div = (unsigned long long)clk_get_rate(priv->clk) * state->period;
|
||||
do_div(div, NSEC_PER_SEC);
|
||||
prd = div;
|
||||
while (div > STM32_LPTIM_MAX_ARR) {
|
||||
presc++;
|
||||
if ((1 << presc) > STM32_LPTIM_MAX_PRESCALER) {
|
||||
dev_err(priv->chip.dev, "max prescaler exceeded\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
div = prd >> presc;
|
||||
}
|
||||
prd = div;
|
||||
|
||||
/* Calculate the duty cycle */
|
||||
dty = prd * state->duty_cycle;
|
||||
do_div(dty, state->period);
|
||||
|
||||
if (!cstate.enabled) {
|
||||
/* enable clock to drive PWM counter */
|
||||
ret = clk_enable(priv->clk);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) ||
|
||||
(FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity)) {
|
||||
val = FIELD_PREP(STM32_LPTIM_PRESC, presc);
|
||||
val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity);
|
||||
mask = STM32_LPTIM_PRESC | STM32_LPTIM_WAVPOL;
|
||||
|
||||
/* Must disable LP timer to modify CFGR */
|
||||
reenable = true;
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask,
|
||||
val);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (reenable) {
|
||||
/* Must (re)enable LP timer to modify CMP & ARR */
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CR,
|
||||
STM32_LPTIM_ENABLE);
|
||||
if (ret)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, prd - 1);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, prd - (1 + dty));
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
/* ensure CMP & ARR registers are properly written */
|
||||
ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
|
||||
(val & STM32_LPTIM_CMPOK_ARROK),
|
||||
100, 1000);
|
||||
if (ret) {
|
||||
dev_err(priv->chip.dev, "ARR/CMP registers write issue\n");
|
||||
goto err;
|
||||
}
|
||||
ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
|
||||
STM32_LPTIM_CMPOKCF_ARROKCF);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
if (reenable) {
|
||||
/* Start LP timer in continuous mode */
|
||||
ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
|
||||
STM32_LPTIM_CNTSTRT,
|
||||
STM32_LPTIM_CNTSTRT);
|
||||
if (ret) {
|
||||
regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (!cstate.enabled)
|
||||
clk_disable(priv->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void stm32_pwm_lp_get_state(struct pwm_chip *chip,
|
||||
struct pwm_device *pwm,
|
||||
struct pwm_state *state)
|
||||
{
|
||||
struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip);
|
||||
unsigned long rate = clk_get_rate(priv->clk);
|
||||
u32 val, presc, prd;
|
||||
u64 tmp;
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
|
||||
state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val);
|
||||
/* Keep PWM counter clock refcount in sync with PWM initial state */
|
||||
if (state->enabled)
|
||||
clk_enable(priv->clk);
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val);
|
||||
presc = FIELD_GET(STM32_LPTIM_PRESC, val);
|
||||
state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val);
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_ARR, &prd);
|
||||
tmp = prd + 1;
|
||||
tmp = (tmp << presc) * NSEC_PER_SEC;
|
||||
state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate);
|
||||
|
||||
regmap_read(priv->regmap, STM32_LPTIM_CMP, &val);
|
||||
tmp = prd - val;
|
||||
tmp = (tmp << presc) * NSEC_PER_SEC;
|
||||
state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate);
|
||||
}
|
||||
|
||||
static const struct pwm_ops stm32_pwm_lp_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.apply = stm32_pwm_lp_apply,
|
||||
.get_state = stm32_pwm_lp_get_state,
|
||||
};
|
||||
|
||||
static int stm32_pwm_lp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
|
||||
struct stm32_pwm_lp *priv;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->regmap = ddata->regmap;
|
||||
priv->clk = ddata->clk;
|
||||
priv->chip.base = -1;
|
||||
priv->chip.dev = &pdev->dev;
|
||||
priv->chip.ops = &stm32_pwm_lp_ops;
|
||||
priv->chip.npwm = 1;
|
||||
|
||||
ret = pwmchip_add(&priv->chip);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
platform_set_drvdata(pdev, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stm32_pwm_lp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct stm32_pwm_lp *priv = platform_get_drvdata(pdev);
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < priv->chip.npwm; i++)
|
||||
if (pwm_is_enabled(&priv->chip.pwms[i]))
|
||||
pwm_disable(&priv->chip.pwms[i]);
|
||||
|
||||
return pwmchip_remove(&priv->chip);
|
||||
}
|
||||
|
||||
static const struct of_device_id stm32_pwm_lp_of_match[] = {
|
||||
{ .compatible = "st,stm32-pwm-lp", },
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, stm32_pwm_lp_of_match);
|
||||
|
||||
static struct platform_driver stm32_pwm_lp_driver = {
|
||||
.probe = stm32_pwm_lp_probe,
|
||||
.remove = stm32_pwm_lp_remove,
|
||||
.driver = {
|
||||
.name = "stm32-pwm-lp",
|
||||
.of_match_table = of_match_ptr(stm32_pwm_lp_of_match),
|
||||
},
|
||||
};
|
||||
module_platform_driver(stm32_pwm_lp_driver);
|
||||
|
||||
MODULE_ALIAS("platform:stm32-pwm-lp");
|
||||
MODULE_DESCRIPTION("STMicroelectronics STM32 PWM LP driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -24,7 +24,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/*
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pwm.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/*
|
||||
|
@ -696,11 +696,11 @@ config REGULATOR_RC5T583
|
||||
outputs which can be controlled by i2c communication.
|
||||
|
||||
config REGULATOR_RK808
|
||||
tristate "Rockchip RK808/RK818 Power regulators"
|
||||
tristate "Rockchip RK805/RK808/RK818 Power regulators"
|
||||
depends on MFD_RK808
|
||||
help
|
||||
Select this option to enable the power regulator of ROCKCHIP
|
||||
PMIC RK808 and RK818.
|
||||
PMIC RK805,RK808 and RK818.
|
||||
This driver supports the control of different power rails of device
|
||||
through regulator interface. The device supports multiple DCDC/LDO
|
||||
outputs which can be controlled by i2c communication.
|
||||
|
@ -65,6 +65,27 @@
|
||||
/* max steps for increase voltage of Buck1/2, equal 100mv*/
|
||||
#define MAX_STEPS_ONE_TIME 8
|
||||
|
||||
#define RK805_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _etime) \
|
||||
[_id] = { \
|
||||
.name = (_match), \
|
||||
.supply_name = (_supply), \
|
||||
.of_match = of_match_ptr(_match), \
|
||||
.regulators_node = of_match_ptr("regulators"), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = (_id), \
|
||||
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (_min) * 1000, \
|
||||
.uV_step = (_step) * 1000, \
|
||||
.vsel_reg = (_vreg), \
|
||||
.vsel_mask = (_vmask), \
|
||||
.enable_reg = (_ereg), \
|
||||
.enable_mask = (_emask), \
|
||||
.enable_time = (_etime), \
|
||||
.ops = &rk805_reg_ops, \
|
||||
}
|
||||
|
||||
#define RK8XX_DESC(_id, _match, _supply, _min, _max, _step, _vreg, \
|
||||
_vmask, _ereg, _emask, _etime) \
|
||||
[_id] = { \
|
||||
@ -298,6 +319,28 @@ static int rk808_set_suspend_voltage_range(struct regulator_dev *rdev, int uv)
|
||||
sel);
|
||||
}
|
||||
|
||||
static int rk805_set_suspend_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
rdev->desc->enable_mask,
|
||||
rdev->desc->enable_mask);
|
||||
}
|
||||
|
||||
static int rk805_set_suspend_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = rdev->desc->enable_reg + RK808_SLP_SET_OFF_REG_OFFSET;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, reg,
|
||||
rdev->desc->enable_mask,
|
||||
0);
|
||||
}
|
||||
|
||||
static int rk808_set_suspend_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
unsigned int reg;
|
||||
@ -320,6 +363,27 @@ static int rk808_set_suspend_disable(struct regulator_dev *rdev)
|
||||
rdev->desc->enable_mask);
|
||||
}
|
||||
|
||||
static struct regulator_ops rk805_reg_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_voltage = rk808_set_suspend_voltage,
|
||||
.set_suspend_enable = rk805_set_suspend_enable,
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk805_switch_ops = {
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.set_suspend_enable = rk805_set_suspend_enable,
|
||||
.set_suspend_disable = rk805_set_suspend_disable,
|
||||
};
|
||||
|
||||
static struct regulator_ops rk808_buck1_2_ops = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.map_voltage = regulator_map_voltage_linear,
|
||||
@ -369,6 +433,68 @@ static struct regulator_ops rk808_switch_ops = {
|
||||
.set_suspend_disable = rk808_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_desc rk805_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
.supply_name = "vcc1",
|
||||
.of_match = of_match_ptr("DCDC_REG1"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK805_ID_DCDC1,
|
||||
.ops = &rk805_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 712500,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.vsel_reg = RK805_BUCK1_ON_VSEL_REG,
|
||||
.vsel_mask = RK818_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK805_DCDC_EN_REG,
|
||||
.enable_mask = BIT(0),
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "DCDC_REG2",
|
||||
.supply_name = "vcc2",
|
||||
.of_match = of_match_ptr("DCDC_REG2"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK805_ID_DCDC2,
|
||||
.ops = &rk805_reg_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.min_uV = 712500,
|
||||
.uV_step = 12500,
|
||||
.n_voltages = 64,
|
||||
.vsel_reg = RK805_BUCK2_ON_VSEL_REG,
|
||||
.vsel_mask = RK818_BUCK_VSEL_MASK,
|
||||
.enable_reg = RK805_DCDC_EN_REG,
|
||||
.enable_mask = BIT(1),
|
||||
.owner = THIS_MODULE,
|
||||
}, {
|
||||
.name = "DCDC_REG3",
|
||||
.supply_name = "vcc3",
|
||||
.of_match = of_match_ptr("DCDC_REG3"),
|
||||
.regulators_node = of_match_ptr("regulators"),
|
||||
.id = RK805_ID_DCDC3,
|
||||
.ops = &rk805_switch_ops,
|
||||
.type = REGULATOR_VOLTAGE,
|
||||
.n_voltages = 1,
|
||||
.enable_reg = RK805_DCDC_EN_REG,
|
||||
.enable_mask = BIT(2),
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
|
||||
RK805_DESC(RK805_ID_DCDC4, "DCDC_REG4", "vcc4", 800, 3400, 100,
|
||||
RK805_BUCK4_ON_VSEL_REG, RK818_BUCK4_VSEL_MASK,
|
||||
RK805_DCDC_EN_REG, BIT(3), 0),
|
||||
|
||||
RK805_DESC(RK805_ID_LDO1, "LDO_REG1", "vcc5", 800, 3400, 100,
|
||||
RK805_LDO1_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
|
||||
BIT(0), 400),
|
||||
RK805_DESC(RK805_ID_LDO2, "LDO_REG2", "vcc5", 800, 3400, 100,
|
||||
RK805_LDO2_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
|
||||
BIT(1), 400),
|
||||
RK805_DESC(RK805_ID_LDO3, "LDO_REG3", "vcc6", 800, 3400, 100,
|
||||
RK805_LDO3_ON_VSEL_REG, RK818_LDO_VSEL_MASK, RK805_LDO_EN_REG,
|
||||
BIT(2), 400),
|
||||
};
|
||||
|
||||
static const struct regulator_desc rk808_reg[] = {
|
||||
{
|
||||
.name = "DCDC_REG1",
|
||||
@ -625,6 +751,10 @@ static int rk808_regulator_probe(struct platform_device *pdev)
|
||||
platform_set_drvdata(pdev, pdata);
|
||||
|
||||
switch (rk808->variant) {
|
||||
case RK805_ID:
|
||||
regulators = rk805_reg;
|
||||
nregulators = RK805_NUM_REGULATORS;
|
||||
break;
|
||||
case RK808_ID:
|
||||
regulators = rk808_reg;
|
||||
nregulators = RK808_NUM_REGULATORS;
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
/*
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
struct twlreg_info {
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <linux/i2c/dm355evm_msp.h>
|
||||
#include <linux/mfd/dm355evm_msp.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
|
||||
enum twl_class {
|
||||
TWL_4030 = 0,
|
||||
|
@ -53,7 +53,7 @@
|
||||
#define DRIVER_DESC "OHCI OMAP driver"
|
||||
|
||||
#ifdef CONFIG_TPS65010
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
#else
|
||||
|
||||
#define LOW 0
|
||||
|
@ -96,7 +96,7 @@ struct isp1301 {
|
||||
|
||||
#if IS_REACHABLE(CONFIG_TPS65010)
|
||||
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
|
||||
#else
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <linux/usb/musb.h>
|
||||
#include <linux/usb/phy_companion.h>
|
||||
#include <linux/phy/omap_usb.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/i2c/twl.h>
|
||||
#include <linux/mfd/twl.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
#define TWL_PWM0_ON 0x00
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/i2c/tps65010.h>
|
||||
#include <linux/mfd/tps65010.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include "omapfb.h"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user