== Changes to existing drivers ==

- Rename child driver [axp288_battery => axp288_fuel_gauge]; axp20x
    - Rename child driver [max77693-flash => max77693-led]; max77693
    - Error handling fixes; intel_soc_pmic
    - GPIO tweaking; intel_soc_pmic
    - Remove non-DT code; vexpress-sysreg, tc3589x
    - Remove unused/legacy code; ti_am335x_tscadc, rts5249, rtsx_gops, rtsx_pcr,
                                 rtc-s5m, sec-core, max77693, menelaus,
                                 wm5102-tables
    - Trivial fixups; rtsx_pci, da9150-core, sec-core, max7769, max77693,
                      mc13xxx-core, dln2, hi6421-pmic-core, rk808, twl4030-power,
                      lpc_ich, menelaus, twl6040
    - Update register/address values; rts5227, rts5249
    - DT and/or binding document fixups; arizona, da9150, mt6397, axp20x,
                                         qcom-rpm, qcom-spmi-pmic
    - Couple of trivial core Kconfig fixups
    - Remove use of seq_printf return value; ab8500-debugfs
    - Remove __exit markups; menelaus, tps65010
    - Fix platform-device name collisions; mfd-core
 
  == New drivers/supported devices ==
    - Add support for wm8280/wm8281 into arizona
    - Add support for COMe-cBL6 into kempld-core
    - Add support for rts524a and rts525a into rts5249
    - Add support for ipq8064 into qcom_rpm
    - Add support for extcon into axp20x
    - New MediaTek MT6397 PMIC driver
    - New Maxim MAX77843 PMIC dirver
    - New Intel Quark X1000 I2C-GPIO driver
    - New Skyworks SKY81452 driver
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJVLQlhAAoJEFGvii+H/HdhnSYP/i7h+0/uvI32+49XlQWO/zZv
 SIcnNcekSj/8MIIpSOZftY+ejdqyo8NHY0dvNTmxekY65ov/yXA6aJGDd5rr3xyL
 hd9E5e5nwxc4UTV2kJwPBgCIKIjx/idRgOMTEpIa1v4KY8Gn43xc81X4s+BusbCE
 WK8hPdBUePRDmMLrRzhkVHqrfeMSSLN5Z/fhmQehWqahE1asPZ2FOnTC6tFlGxgm
 I55FAMvWey+qv4g28+nQrC9RQMetCL2f/6o53jMEQoaRQdJbbrxMybBnNvpcXwbR
 JECPiV+2R0EqBd3xiT2gbPLAqmMDexIP1Cybh3BBRcFveJeJGqmMCFwMio6kotkA
 IIMlYNcwczufPVWIIqz3U2OtJ5EWzxPgco2aA4a1Ej1nbUC29o829fMahZY0SR8m
 O2zX/MpmYPZCg3mHOFQ4oPwalIM7oKv79NTV25Ks9r+rv+zNaBc8TPCE/Oxkxfj8
 IdJ/vKQaKMmMZA1THO8HMK9qAQV7vZL12XquVzrAgq40RZa+nOUXEk0J0rHI0VaO
 BHNMBv1D3iNQfR7cWAappDavhoZcFtIY/Z9x7OsLYm/W8+CxhdAafMNH0AJPlfts
 NR7RoNtStumXdq6QzDdA27Mp1sXkHz/kgGMVE4t9mdLVmD9C0MqVi8VPFUN+sST0
 vAKAhQ/cnXCKVxe6I9/3
 =QPNn
 -----END PGP SIGNATURE-----

Merge tag 'mfd-for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd

Pull MFD updates from Lee Jones:
 "Changes to existing drivers:

   - Rename child driver [axp288_battery => axp288_fuel_gauge]; axp20x
   - Rename child driver [max77693-flash => max77693-led]; max77693
   - Error handling fixes; intel_soc_pmic
   - GPIO tweaking; intel_soc_pmic
   - Remove non-DT code; vexpress-sysreg, tc3589x
   - Remove unused/legacy code; ti_am335x_tscadc, rts5249, rtsx_gops, rtsx_pcr,
                                rtc-s5m, sec-core, max77693, menelaus,
                                wm5102-tables
   - Trivial fixups; rtsx_pci, da9150-core, sec-core, max7769, max77693,
                     mc13xxx-core, dln2, hi6421-pmic-core, rk808, twl4030-power,
                     lpc_ich, menelaus, twl6040
   - Update register/address values; rts5227, rts5249
   - DT and/or binding document fixups; arizona, da9150, mt6397, axp20x,
                                        qcom-rpm, qcom-spmi-pmic
   - Couple of trivial core Kconfig fixups
   - Remove use of seq_printf return value; ab8500-debugfs
   - Remove __exit markups; menelaus, tps65010
   - Fix platform-device name collisions; mfd-core

  New drivers/supported devices:

   - Add support for wm8280/wm8281 into arizona
   - Add support for COMe-cBL6 into kempld-core
   - Add support for rts524a and rts525a into rts5249
   - Add support for ipq8064 into qcom_rpm
   - Add support for extcon into axp20x
   - New MediaTek MT6397 PMIC driver
   - New Maxim MAX77843 PMIC dirver
   - New Intel Quark X1000 I2C-GPIO driver
   - New Skyworks SKY81452 driver"

* tag 'mfd-for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (76 commits)
  mfd: sec: Fix RTC alarm interrupt number on S2MPS11
  mfd: wm5102: Remove registers for output 3R from readable list
  mfd: tps65010: Remove incorrect __exit markups
  mfd: devicetree: bindings: Add Qualcomm RPM regulator subnodes
  mfd: axp20x: Add support for extcon cell
  mfd: lpc_ich: Sort IDs
  mfd: twl6040: Remove wrong and unneeded "platform:twl6040" modalias
  mfd: qcom-spmi-pmic: Add specific compatible strings for Qualcomm's SPMI PMIC's
  mfd: axp20x: Fix duplicate const for model names
  mfd: menelaus: Use macro for magic number
  mfd: menelaus: Drop support for SW controller VCORE
  mfd: menelaus: Delete omap_has_menelaus
  mfd: arizona: Correct type of gpio_defaults
  mfd: lpc_ich: Sort IDs
  mfd: Fix a typo in Kconfig
  mfd: qcom_rpm: Add support for IPQ8064
  mfd: devicetree: qcom_rpm: Document IPQ8064 resources
  mfd: core: Fix platform-device name collisions
  mfd: intel_quark_i2c_gpio: Don't crash if !DMI
  dt-bindings: Add vendor-prefix for X-Powers
  ...
This commit is contained in:
Linus Torvalds 2015-04-14 17:29:55 -07:00
commit f0c1bc95a1
82 changed files with 4261 additions and 1190 deletions

View File

@ -89,6 +89,7 @@ ricoh,rv5c386 I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
ricoh,rv5c387a I2C bus SERIAL INTERFACE REAL-TIME CLOCK IC
samsung,24ad0xd1 S524AD0XF1 (128K/256K-bit Serial EEPROM for Low Power)
sii,s35390a 2-wire CMOS real-time clock
skyworks,sky81452 Skyworks SKY81452: Six-Channel White LED Driver with Touch Panel Bias Supply
st-micro,24c256 i2c serial eeprom (24cxx)
stm,m41t00 Serial Access TIMEKEEPER
stm,m41t62 Serial real-time clock (RTC) with alarm

View File

@ -8,6 +8,7 @@ Required properties:
- compatible : One of the following chip-specific strings:
"wlf,wm5102"
"wlf,wm5110"
"wlf,wm8280"
"wlf,wm8997"
- reg : I2C slave address when connected using I2C, chip select number when
using SPI.
@ -26,21 +27,27 @@ Required properties:
- #gpio-cells : Must be 2. The first cell is the pin number and the
second cell is used to specify optional parameters (currently unused).
- AVDD-supply, DBVDD1-supply, DBVDD2-supply, DBVDD3-supply (wm5102, wm5110),
CPVDD-supply, SPKVDDL-supply (wm5102, wm5110), SPKVDDR-supply (wm5102,
wm5110), SPKVDD-supply (wm8997) : Power supplies for the device, as covered
in Documentation/devicetree/bindings/regulator/regulator.txt
- AVDD-supply, DBVDD1-supply, CPVDD-supply : Power supplies for the device,
as covered in Documentation/devicetree/bindings/regulator/regulator.txt
- DBVDD2-supply, DBVDD3-supply : Additional databus power supplies (wm5102,
wm5110, wm8280)
- SPKVDDL-supply, SPKVDDR-supply : Speaker driver power supplies (wm5102,
wm5110, wm8280)
- SPKVDD-supply : Speaker driver power supply (wm8997)
Optional properties:
- wlf,reset : GPIO specifier for the GPIO controlling /RESET
- wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
- wlf,gpio-defaults : A list of GPIO configuration register values. If
absent, no configuration of these registers is performed. If any
entry has a value that is out of range for a 16 bit register then
the chip default will be used. If present exactly five values must
be specified.
- wlf,gpio-defaults : A list of GPIO configuration register values. Defines
for the appropriate values can found in <dt-bindings/mfd/arizona.txt>. If
absent, no configuration of these registers is performed. If any entry has
a value that is out of range for a 16 bit register then the chip default
will be used. If present exactly five values must be specified.
- wlf,inmode : A list of INn_MODE register values, where n is the number
of input signals. Valid values are 0 (Differential), 1 (Single-ended) and
@ -49,6 +56,12 @@ Optional properties:
input singals. If values less than the number of input signals, elements
that has not been specifed are set to 0 by default.
- wlf,dmic-ref : DMIC reference voltage source for each input, can be
selected from either MICVDD or one of the MICBIAS's, defines
(ARIZONA_DMIC_xxxx) are provided in <dt-bindings/mfd/arizona.txt>. If
present, the number of values should be less than or equal to the
number of inputs, unspecified inputs will use the chip default.
- DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
they are being externally supplied. As covered in
Documentation/devicetree/bindings/regulator/regulator.txt
@ -73,10 +86,10 @@ codec: wm5102@1a {
#gpio-cells = <2>;
wlf,gpio-defaults = <
0x00000000 /* AIF1TXLRCLK */
0xffffffff
0xffffffff
0xffffffff
0xffffffff
ARIZONA_GP_FN_TXLRCLK
ARIZONA_GP_DEFAULT
ARIZONA_GP_DEFAULT
ARIZONA_GP_DEFAULT
ARIZONA_GP_DEFAULT
>;
};

View File

@ -0,0 +1,96 @@
AXP202/AXP209 device tree bindings
The axp20x family current members :
axp202 (X-Powers)
axp209 (X-Powers)
Required properties:
- compatible: "x-powers,axp202" or "x-powers,axp209"
- reg: The I2C slave address for the AXP chip
- interrupt-parent: The parent interrupt controller
- interrupts: SoC NMI / GPIO interrupt connected to the PMIC's IRQ pin
- interrupt-controller: axp20x has its own internal IRQs
- #interrupt-cells: Should be set to 1
Optional properties:
- x-powers,dcdc-freq: defines the work frequency of DC-DC in KHz
(range: 750-1875). Default: 1.5MHz
- <input>-supply: a phandle to the regulator supply node. May be omitted if
inputs are unregulated, such as using the IPSOUT output
from the PMIC.
- regulators: A node that houses a sub-node for each regulator. Regulators
not used but preferred to be managed by the OS should be
listed as well.
See Documentation/devicetree/bindings/regulator/regulator.txt
for more information on standard regulator bindings.
Optional properties for DCDC regulators:
- x-powers,dcdc-workmode: 1 for PWM mode, 0 for AUTO (PWM/PFM) mode
Default: Current hardware setting
The DCDC regulators work in a mixed PWM/PFM mode,
using PFM under light loads and switching to PWM
for heavier loads. Forcing PWM mode trades efficiency
under light loads for lower output noise. This
probably makes sense for HiFi audio related
applications that aren't battery constrained.
AXP202/AXP209 regulators, type, and corresponding input supply names:
Regulator Type Supply Name Notes
--------- ---- ----------- -----
DCDC2 : DC-DC buck : vin2-supply
DCDC3 : DC-DC buck : vin3-supply
LDO1 : LDO : acin-supply : always on
LDO2 : LDO : ldo24in-supply : shared supply
LDO3 : LDO : ldo3in-supply
LDO4 : LDO : ldo24in-supply : shared supply
LDO5 : LDO : ldo5in-supply
Example:
axp209: pmic@34 {
compatible = "x-powers,axp209";
reg = <0x34>;
interrupt-parent = <&nmi_intc>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
#interrupt-cells = <1>;
regulators {
x-powers,dcdc-freq = <1500>;
vdd_cpu: dcdc2 {
regulator-always-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1450000>;
regulator-name = "vdd-cpu";
};
vdd_int_dll: dcdc3 {
regulator-always-on;
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1400000>;
regulator-name = "vdd-int-dll";
};
vdd_rtc: ldo1 {
regulator-always-on;
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1400000>;
regulator-name = "vdd-rtc";
};
avcc: ldo2 {
regulator-always-on;
regulator-min-microvolt = <2700000>;
regulator-max-microvolt = <3300000>;
regulator-name = "avcc";
};
ldo3 {
/* unused but preferred to be managed by OS */
};
};
};

View File

@ -0,0 +1,43 @@
Dialog Semiconductor DA9150 Combined Charger/Fuel-Gauge MFD bindings
DA9150 consists of a group of sub-devices:
Device Description
------ -----------
da9150-gpadc : General Purpose ADC
da9150-charger : Battery Charger
======
Required properties:
- compatible : Should be "dlg,da9150"
- reg: Specifies the I2C slave address
- interrupt-parent: Specifies the phandle of the interrupt controller to which
the IRQs from da9150 are delivered to.
- interrupts: IRQ line info for da9150 chip.
- interrupt-controller: da9150 has internal IRQs (own IRQ domain).
(See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
further information relating to interrupt properties)
Sub-devices:
- da9150-gpadc: See Documentation/devicetree/bindings/iio/adc/da9150-gpadc.txt
- da9150-charger: See Documentation/devicetree/bindings/power/da9150-charger.txt
Example:
charger_fg: da9150@58 {
compatible = "dlg,da9150";
reg = <0x58>;
interrupt-parent = <&gpio6>;
interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
interrupt-controller;
gpadc: da9150-gpadc {
...
};
da9150-charger {
...
};
};

View File

@ -0,0 +1,70 @@
MediaTek MT6397 Multifunction Device Driver
MT6397 is a multifunction device with the following sub modules:
- Regulator
- RTC
- Audio codec
- GPIO
- Clock
It is interfaced to host controller using SPI interface by a proprietary hardware
called PMIC wrapper or pwrap. MT6397 MFD is a child device of pwrap.
See the following for pwarp node definitions:
Documentation/devicetree/bindings/soc/pwrap.txt
This document describes the binding for MFD device and its sub module.
Required properties:
compatible: "mediatek,mt6397"
Optional subnodes:
- rtc
Required properties:
- compatible: "mediatek,mt6397-rtc"
- regulators
Required properties:
- compatible: "mediatek,mt6397-regulator"
see Documentation/devicetree/bindings/regulator/mt6397-regulator.txt
- codec
Required properties:
- compatible: "mediatek,mt6397-codec"
- clk
Required properties:
- compatible: "mediatek,mt6397-clk"
Example:
pwrap: pwrap@1000f000 {
compatible = "mediatek,mt8135-pwrap";
...
pmic {
compatible = "mediatek,mt6397";
codec: mt6397codec {
compatible = "mediatek,mt6397-codec";
};
regulators {
compatible = "mediatek,mt6397-regulator";
mt6397_vpca15_reg: buck_vpca15 {
regulator-compatible = "buck_vpca15";
regulator-name = "vpca15";
regulator-min-microvolt = <850000>;
regulator-max-microvolt = <1400000>;
regulator-ramp-delay = <12500>;
regulator-always-on;
};
mt6397_vgp4_reg: ldo_vgp4 {
regulator-compatible = "ldo_vgp4";
regulator-name = "vgp4";
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <3300000>;
regulator-enable-ramp-delay = <218>;
};
};
};
};

View File

@ -15,10 +15,21 @@ each. A function can consume one or more of these fixed-size register regions.
Required properties:
- compatible: Should contain one of:
"qcom,pm8941"
"qcom,pm8841"
"qcom,pma8084"
or generalized "qcom,spmi-pmic".
"qcom,pm8941",
"qcom,pm8841",
"qcom,pma8084",
"qcom,pm8019",
"qcom,pm8226",
"qcom,pm8110",
"qcom,pma8084",
"qcom,pmi8962",
"qcom,pmd9635",
"qcom,pm8994",
"qcom,pmi8994",
"qcom,pm8916",
"qcom,pm8004",
"qcom,pm8909",
or generalized "qcom,spmi-pmic".
- reg: Specifies the SPMI USID slave address for this device.
For more information see:
Documentation/devicetree/bindings/spmi/spmi.txt

View File

@ -12,6 +12,7 @@ frequencies.
"qcom,rpm-apq8064"
"qcom,rpm-msm8660"
"qcom,rpm-msm8960"
"qcom,rpm-ipq8064"
- reg:
Usage: required
@ -31,16 +32,6 @@ frequencies.
Value type: <string-array>
Definition: must be the three strings "ack", "err" and "wakeup", in order
- #address-cells:
Usage: required
Value type: <u32>
Definition: must be 1
- #size-cells:
Usage: required
Value type: <u32>
Definition: must be 0
- qcom,ipc:
Usage: required
Value type: <prop-encoded-array>
@ -52,6 +43,188 @@ frequencies.
- u32 representing the ipc bit within the register
= SUBNODES
The RPM exposes resources to its subnodes. The below bindings specify the set
of valid subnodes that can operate on these resources.
== Regulators
Regulator nodes are identified by their compatible:
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,rpm-pm8058-regulators"
"qcom,rpm-pm8901-regulators"
"qcom,rpm-pm8921-regulators"
- vdd_l0_l1_lvs-supply:
- vdd_l2_l11_l12-supply:
- vdd_l3_l4_l5-supply:
- vdd_l6_l7-supply:
- vdd_l8-supply:
- vdd_l9-supply:
- vdd_l10-supply:
- vdd_l13_l16-supply:
- vdd_l14_l15-supply:
- vdd_l17_l18-supply:
- vdd_l19_l20-supply:
- vdd_l21-supply:
- vdd_l22-supply:
- vdd_l23_l24_l25-supply:
- vdd_ncp-supply:
- vdd_s0-supply:
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
Usage: optional (pm8058 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- lvs0_in-supply:
- lvs1_in-supply:
- lvs2_in-supply:
- lvs3_in-supply:
- mvs_in-supply:
- vdd_l0-supply:
- vdd_l1-supply:
- vdd_l2-supply:
- vdd_l3-supply:
- vdd_l4-supply:
- vdd_l5-supply:
- vdd_l6-supply:
- vdd_s0-supply:
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s3-supply:
- vdd_s4-supply:
Usage: optional (pm8901 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
- vdd_l1_l2_l12_l18-supply:
- vdd_l3_l15_l17-supply:
- vdd_l4_l14-supply:
- vdd_l5_l8_l16-supply:
- vdd_l6_l7-supply:
- vdd_l9_l11-supply:
- vdd_l10_l22-supply:
- vdd_l21_l23_l29-supply:
- vdd_l24-supply:
- vdd_l25-supply:
- vdd_l26-supply:
- vdd_l27-supply:
- vdd_l28-supply:
- vdd_ncp-supply:
- vdd_s1-supply:
- vdd_s2-supply:
- vdd_s4-supply:
- vdd_s5-supply:
- vdd_s6-supply:
- vdd_s7-supply:
- vdd_s8-supply:
- vin_5vs-supply:
- vin_lvs1_3_6-supply:
- vin_lvs2-supply:
- vin_lvs4_5_7-supply:
Usage: optional (pm8921 only)
Value type: <phandle>
Definition: reference to regulator supplying the input pin, as
described in the data sheet
The regulator node houses sub-nodes for each regulator within the device. Each
sub-node is identified using the node's name, with valid values listed for each
of the pmics below.
pm8058:
l0, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14, l15,
l16, l17, l18, l19, l20, l21, l22, l23, l24, l25, s0, s1, s2, s3, s4,
lvs0, lvs1, ncp
pm8901:
l0, l1, l2, l3, l4, l5, l6, s0, s1, s2, s3, s4, lvs0, lvs1, lvs2, lvs3,
mvs
pm8921:
s1, s2, s3, s4, s7, s8, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11,
l12, l14, l15, l16, l17, l18, l21, l22, l23, l24, l25, l26, l27, l28,
l29, lvs1, lvs2, lvs3, lvs4, lvs5, lvs6, lvs7, usb-switch, hdmi-switch,
ncp
The content of each sub-node is defined by the standard binding for regulators -
see regulator.txt - with additional custom properties described below:
=== Switch-mode Power Supply regulator custom properties
- bias-pull-down:
Usage: optional
Value type: <empty>
Definition: enable pull down of the regulator when inactive
- qcom,switch-mode-frequency:
Usage: required
Value type: <u32>
Definition: Frequency (Hz) of the switch-mode power supply;
must be one of:
19200000, 9600000, 6400000, 4800000, 3840000, 3200000,
2740000, 2400000, 2130000, 1920000, 1750000, 1600000,
1480000, 1370000, 1280000, 1200000
- qcom,force-mode:
Usage: optional (default if no other qcom,force-mode is specified)
Value type: <u32>
Defintion: indicates that the regulator should be forced to a
particular mode, valid values are:
QCOM_RPM_FORCE_MODE_NONE - do not force any mode
QCOM_RPM_FORCE_MODE_LPM - force into low power mode
QCOM_RPM_FORCE_MODE_HPM - force into high power mode
QCOM_RPM_FORCE_MODE_AUTO - allow regulator to automatically
select its own mode based on
realtime current draw, only for:
pm8921 smps and ftsmps
- qcom,power-mode-hysteretic:
Usage: optional
Value type: <empty>
Definition: select that the power supply should operate in hysteretic
mode, instead of the default pwm mode
=== Low-dropout regulator custom properties
- bias-pull-down:
Usage: optional
Value type: <empty>
Definition: enable pull down of the regulator when inactive
- qcom,force-mode:
Usage: optional
Value type: <u32>
Defintion: indicates that the regulator should not be forced to any
particular mode, valid values are:
QCOM_RPM_FORCE_MODE_NONE - do not force any mode
QCOM_RPM_FORCE_MODE_LPM - force into low power mode
QCOM_RPM_FORCE_MODE_HPM - force into high power mode
QCOM_RPM_FORCE_MODE_BYPASS - set regulator to use bypass
mode, i.e. to act as a switch
and not regulate, only for:
pm8921 pldo, nldo and nldo1200
=== Negative Charge Pump custom properties
- qcom,switch-mode-frequency:
Usage: required
Value type: <u32>
Definition: Frequency (Hz) of the swith mode power supply;
must be one of:
19200000, 9600000, 6400000, 4800000, 3840000, 3200000,
2740000, 2400000, 2130000, 1920000, 1750000, 1600000,
1480000, 1370000, 1280000, 1200000
= EXAMPLE
#include <dt-bindings/mfd/qcom-rpm.h>
@ -64,7 +237,28 @@ frequencies.
interrupts = <0 19 0>, <0 21 0>, <0 22 0>;
interrupt-names = "ack", "err", "wakeup";
#address-cells = <1>;
#size-cells = <0>;
regulators {
compatible = "qcom,rpm-pm8921-regulators";
vdd_l1_l2_l12_l18-supply = <&pm8921_s4>;
s1 {
regulator-min-microvolt = <1225000>;
regulator-max-microvolt = <1225000>;
bias-pull-down;
qcom,switch-mode-frequency = <3200000>;
};
pm8921_s4: s4 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
qcom,switch-mode-frequency = <1600000>;
bias-pull-down;
qcom,force-mode = <QCOM_RPM_FORCE_MODE_AUTO>;
};
};
};

View File

@ -0,0 +1,35 @@
SKY81452 bindings
Required properties:
- compatible : Must be "skyworks,sky81452"
- reg : I2C slave address
Required child nodes:
- backlight : container node for backlight following the binding
in video/backlight/sky81452-backlight.txt
- regulator : container node for regulators following the binding
in regulator/sky81452-regulator.txt
Example:
sky81452@2c {
compatible = "skyworks,sky81452";
reg = <0x2c>;
backlight {
compatible = "skyworks,sky81452-backlight";
name = "pwm-backlight";
led-sources = <0 1 2 3 6>;
skyworks,ignore-pwm;
skyworks,phase-shift;
skyworks,current-limit = <2300>;
};
regulator {
lout {
regulator-name = "sky81452-lout";
regulator-min-microvolt = <4500000>;
regulator-max-microvolt = <8000000>;
};
};
};

View File

@ -167,6 +167,7 @@ sii Seiko Instruments, Inc.
silergy Silergy Corp.
sirf SiRF Technology, Inc.
sitronix Sitronix Technology Corporation
skyworks Skyworks Solutions, Inc.
smsc Standard Microsystems Corporation
snps Synopsys, Inc.
solidrun SolidRun
@ -194,6 +195,7 @@ voipac Voipac Technologies s.r.o.
winbond Winbond Electronics corp.
wlf Wolfson Microelectronics
wm Wondermedia Technologies, Inc.
x-powers X-Powers
xes Extreme Engineering Solutions (X-ES)
xillybus Xillybus Ltd.
xlnx Xilinx

View File

@ -0,0 +1,29 @@
SKY81452-backlight bindings
Required properties:
- compatible : Must be "skyworks,sky81452-backlight"
Optional properties:
- name : Name of backlight device. Default is 'lcd-backlight'.
- gpios : GPIO to use to EN pin.
See Documentation/devicetree/bindings/gpio/gpio.txt
- led-sources : List of enabled channels from 0 to 5.
See Documentation/devicetree/bindings/leds/common.txt
- skyworks,ignore-pwm : Ignore both PWM input
- skyworks,dpwm-mode : Enable DPWM dimming mode, otherwise Analog dimming.
- skyworks,phase-shift : Enable phase shift mode
- skyworks,short-detection-threshold-volt
: It should be one of 4, 5, 6 and 7V.
- skyworks,current-limit-mA
: It should be 2300mA or 2750mA.
Example:
backlight {
compatible = "skyworks,sky81452-backlight";
name = "pwm-backlight";
led-sources = <0 1 2 5>;
skyworks,ignore-pwm;
skyworks,phase-shift;
skyworks,current-limit-mA = <2300>;
};

View File

@ -1149,6 +1149,7 @@ static int arizona_extcon_probe(struct platform_device *pdev)
}
break;
case WM5110:
case WM8280:
switch (arizona->rev) {
case 0 ... 2:
break;

View File

@ -669,6 +669,7 @@ config GPIO_STP_XWAY
config GPIO_TC3589X
bool "TC3589X GPIOs"
depends on MFD_TC3589X
depends on OF_GPIO
select GPIOLIB_IRQCHIP
help
This enables support for the GPIOs found on the TC3589X

View File

@ -116,6 +116,7 @@ static int arizona_gpio_probe(struct platform_device *pdev)
switch (arizona->type) {
case WM5102:
case WM5110:
case WM8280:
case WM8997:
arizona_gpio->gpio_chip.ngpio = 5;
break;

View File

@ -260,10 +260,7 @@ static int tc3589x_gpio_probe(struct platform_device *pdev)
tc3589x_gpio->chip.ngpio = tc3589x->num_gpio;
tc3589x_gpio->chip.dev = &pdev->dev;
tc3589x_gpio->chip.base = -1;
#ifdef CONFIG_OF_GPIO
tc3589x_gpio->chip.of_node = np;
#endif
/* Bring the GPIO module out of reset */
ret = tc3589x_set_bits(tc3589x, TC3589x_RSTCTRL,

View File

@ -296,7 +296,6 @@ static void tc3589x_keypad_close(struct input_dev *input)
tc3589x_keypad_disable(keypad);
}
#ifdef CONFIG_OF
static const struct tc3589x_keypad_platform_data *
tc3589x_keypad_of_probe(struct device *dev)
{
@ -346,14 +345,6 @@ tc3589x_keypad_of_probe(struct device *dev)
return plat;
}
#else
static inline const struct tc3589x_keypad_platform_data *
tc3589x_keypad_of_probe(struct device *dev)
{
return ERR_PTR(-ENODEV);
}
#endif
static int tc3589x_keypad_probe(struct platform_device *pdev)
{

View File

@ -283,6 +283,18 @@ config HTC_I2CPLD
This device provides input and output GPIOs through an I2C
interface to one or more sub-chips.
config MFD_INTEL_QUARK_I2C_GPIO
tristate "Intel Quark MFD I2C GPIO"
depends on PCI
depends on X86
depends on COMMON_CLK
select MFD_CORE
help
This MFD provides support for I2C and GPIO that exist only
in a single PCI device. It splits the 2 IO devices to
their respective IO driver.
The GPIO exports a total amount of 8 interrupt-capable GPIOs.
config LPC_ICH
tristate "Intel ICH LPC"
depends on PCI
@ -364,6 +376,7 @@ config MFD_KEMPLD
* COMe-bIP#
* COMe-bPC2 (ETXexpress-PC)
* COMe-bSC# (ETXexpress-SC T#)
* COMe-cBL6
* COMe-cBT6
* COMe-cCT6
* COMe-cDC2 (microETXexpress-DC)
@ -455,6 +468,20 @@ config MFD_MAX77693
additional drivers must be enabled in order to use the functionality
of the device.
config MFD_MAX77843
bool "Maxim Semiconductor MAX77843 PMIC Support"
depends on I2C=y
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
Say yes here to add support for Maxim Semiconductor MAX77843.
This is companion Power Management IC with LEDs, Haptic, Charger,
Fuel Gauge, MUIC(Micro USB Interface Controller) controls on chip.
This driver provides common support for accessing the device;
additional drivers must be enabled in order to use the functionality
of the device.
config MFD_MAX8907
tristate "Maxim Semiconductor MAX8907 PMIC Support"
select MFD_CORE
@ -502,6 +529,16 @@ config MFD_MAX8998
additional drivers must be enabled in order to use the functionality
of the device.
config MFD_MT6397
tristate "MediaTek MT6397 PMIC Support"
select MFD_CORE
select IRQ_DOMAIN
help
Say yes here to add support for MediaTek MT6397 PMIC. This is
a Power Management IC. This driver provides common support for
accessing the device; additional drivers must be enabled in order
to use the functionality of the device.
config MFD_MENF21BMC
tristate "MEN 14F021P00 Board Management Controller Support"
depends on I2C
@ -655,6 +692,7 @@ config MFD_RT5033
depends on I2C=y
select MFD_CORE
select REGMAP_I2C
select REGMAP_IRQ
help
This driver provides for the Richtek RT5033 Power Management IC,
which includes the I2C driver and the Core APIs. This driver provides
@ -753,6 +791,18 @@ config MFD_SM501_GPIO
lines on the SM501. The platform data is used to supply the
base number for the first GPIO line to register.
config MFD_SKY81452
tristate "Skyworks Solutions SKY81452"
select MFD_CORE
select REGMAP_I2C
depends on I2C
help
This is the core driver for the Skyworks SKY81452 backlight and
voltage regulator device.
This driver can also be built as a module. If so, the module
will be called sky81452.
config MFD_SMSC
bool "SMSC ECE1099 series chips"
depends on I2C=y
@ -1210,6 +1260,7 @@ config MFD_TIMBERDALE
config MFD_TC3589X
bool "Toshiba TC35892 and variants"
depends on I2C=y
depends on OF
select MFD_CORE
help
Support for the Toshiba TC35892 and variants I/O Expander.
@ -1289,10 +1340,11 @@ config MFD_WM5102
Support for Wolfson Microelectronics WM5102 low power audio SoC
config MFD_WM5110
bool "Wolfson Microelectronics WM5110"
bool "Wolfson Microelectronics WM5110 and WM8280/WM8281"
depends on MFD_ARIZONA
help
Support for Wolfson Microelectronics WM5110 low power audio SoC
Support for Wolfson Microelectronics WM5110 and WM8280/WM8281
low power audio SoC
config MFD_WM8997
bool "Wolfson Microelectronics WM8997"
@ -1362,7 +1414,7 @@ config MFD_WM8994
depends on I2C
help
The WM8994 is a highly integrated hi-fi CODEC designed for
smartphone applicatiosn. As well as audio functionality it
smartphone applications. As well as audio functionality it
has on board GPIO and regulator functionality which is
supported via the relevant subsystems. This driver provides
core support for the WM8994, in order to use the actual

View File

@ -13,7 +13,7 @@ obj-$(CONFIG_MFD_CROS_EC) += cros_ec.o
obj-$(CONFIG_MFD_CROS_EC_I2C) += cros_ec_i2c.o
obj-$(CONFIG_MFD_CROS_EC_SPI) += cros_ec_spi.o
rtsx_pci-objs := rtsx_pcr.o rtsx_gops.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
rtsx_pci-objs := rtsx_pcr.o rts5209.o rts5229.o rtl8411.o rts5227.o rts5249.o
obj-$(CONFIG_MFD_RTSX_PCI) += rtsx_pci.o
obj-$(CONFIG_MFD_RTSX_USB) += rtsx_usb.o
@ -117,6 +117,7 @@ obj-$(CONFIG_MFD_DA9150) += da9150-core.o
obj-$(CONFIG_MFD_MAX14577) += max14577.o
obj-$(CONFIG_MFD_MAX77686) += max77686.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o
obj-$(CONFIG_MFD_MAX77843) += max77843.o
obj-$(CONFIG_MFD_MAX8907) += max8907.o
max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o
@ -138,6 +139,7 @@ obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
obj-$(CONFIG_MFD_KEMPLD) += kempld-core.o
obj-$(CONFIG_MFD_INTEL_QUARK_I2C_GPIO) += intel_quark_i2c_gpio.o
obj-$(CONFIG_LPC_SCH) += lpc_sch.o
obj-$(CONFIG_LPC_ICH) += lpc_ich.o
obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
@ -178,6 +180,8 @@ obj-$(CONFIG_MFD_MENF21BMC) += menf21bmc.o
obj-$(CONFIG_MFD_HI6421_PMIC) += hi6421-pmic-core.o
obj-$(CONFIG_MFD_DLN2) += dln2.o
obj-$(CONFIG_MFD_RT5033) += rt5033.o
obj-$(CONFIG_MFD_SKY81452) += sky81452.o
intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o
obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o
obj-$(CONFIG_MFD_MT6397) += mt6397-core.o

View File

@ -1283,7 +1283,7 @@ static irqreturn_t ab8500_debug_handler(int irq, void *data)
/* Prints to seq_file or log_buf */
static int ab8500_registers_print(struct device *dev, u32 bank,
struct seq_file *s)
struct seq_file *s)
{
unsigned int i;
@ -1304,20 +1304,19 @@ static int ab8500_registers_print(struct device *dev, u32 bank,
}
if (s) {
err = seq_printf(s,
" [0x%02X/0x%02X]: 0x%02X\n",
bank, reg, value);
if (err < 0) {
/* Error is not returned here since
* the output is wanted in any case */
seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
bank, reg, value);
/* Error is not returned here since
* the output is wanted in any case */
if (seq_has_overflowed(s))
return 0;
}
} else {
dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n",
bank, reg, value);
}
}
}
return 0;
}
@ -1330,8 +1329,7 @@ static int ab8500_print_bank_registers(struct seq_file *s, void *p)
seq_printf(s, " bank 0x%02X:\n", bank);
ab8500_registers_print(dev, bank, s);
return 0;
return ab8500_registers_print(dev, bank, s);
}
static int ab8500_registers_open(struct inode *inode, struct file *file)
@ -1355,9 +1353,12 @@ static int ab8500_print_all_banks(struct seq_file *s, void *p)
seq_puts(s, AB8500_NAME_STRING " register values:\n");
for (i = 0; i < AB8500_NUM_BANKS; i++) {
seq_printf(s, " bank 0x%02X:\n", i);
int err;
ab8500_registers_print(dev, i, s);
seq_printf(s, " bank 0x%02X:\n", i);
err = ab8500_registers_print(dev, i, s);
if (err)
return err;
}
return 0;
}
@ -1458,7 +1459,8 @@ static const struct file_operations ab8500_all_banks_fops = {
static int ab8500_bank_print(struct seq_file *s, void *p)
{
return seq_printf(s, "0x%02X\n", debug_bank);
seq_printf(s, "0x%02X\n", debug_bank);
return 0;
}
static int ab8500_bank_open(struct inode *inode, struct file *file)
@ -1490,7 +1492,8 @@ static ssize_t ab8500_bank_write(struct file *file,
static int ab8500_address_print(struct seq_file *s, void *p)
{
return seq_printf(s, "0x%02X\n", debug_address);
seq_printf(s, "0x%02X\n", debug_address);
return 0;
}
static int ab8500_address_open(struct inode *inode, struct file *file)
@ -1598,7 +1601,8 @@ static int ab8500_interrupts_print(struct seq_file *s, void *p)
for (line = 0; line < num_interrupt_lines; line++) {
struct irq_desc *desc = irq_to_desc(line + irq_first);
seq_printf(s, "%3i: %6i %4i", line,
seq_printf(s, "%3i: %6i %4i",
line,
num_interrupts[line],
num_wake_interrupts[line]);
@ -1705,8 +1709,7 @@ static int ab8500_print_modem_registers(struct seq_file *s, void *p)
dev_err(dev, "ab->read fail %d\n", err);
return err;
}
err = seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n",
bank, reg, value);
seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value);
}
err = abx500_set_register_interruptible(dev,
AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value);
@ -1743,8 +1746,9 @@ static int ab8500_gpadc_bat_ctrl_print(struct seq_file *s, void *p)
bat_ctrl_convert = ab8500_gpadc_ad_to_voltage(gpadc,
BAT_CTRL, bat_ctrl_raw);
return seq_printf(s, "%d,0x%X\n",
bat_ctrl_convert, bat_ctrl_raw);
seq_printf(s, "%d,0x%X\n", bat_ctrl_convert, bat_ctrl_raw);
return 0;
}
static int ab8500_gpadc_bat_ctrl_open(struct inode *inode, struct file *file)
@ -1773,8 +1777,9 @@ static int ab8500_gpadc_btemp_ball_print(struct seq_file *s, void *p)
btemp_ball_convert = ab8500_gpadc_ad_to_voltage(gpadc, BTEMP_BALL,
btemp_ball_raw);
return seq_printf(s,
"%d,0x%X\n", btemp_ball_convert, btemp_ball_raw);
seq_printf(s, "%d,0x%X\n", btemp_ball_convert, btemp_ball_raw);
return 0;
}
static int ab8500_gpadc_btemp_ball_open(struct inode *inode,
@ -1804,8 +1809,9 @@ static int ab8500_gpadc_main_charger_v_print(struct seq_file *s, void *p)
main_charger_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
MAIN_CHARGER_V, main_charger_v_raw);
return seq_printf(s, "%d,0x%X\n",
main_charger_v_convert, main_charger_v_raw);
seq_printf(s, "%d,0x%X\n", main_charger_v_convert, main_charger_v_raw);
return 0;
}
static int ab8500_gpadc_main_charger_v_open(struct inode *inode,
@ -1835,8 +1841,9 @@ static int ab8500_gpadc_acc_detect1_print(struct seq_file *s, void *p)
acc_detect1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ACC_DETECT1,
acc_detect1_raw);
return seq_printf(s, "%d,0x%X\n",
acc_detect1_convert, acc_detect1_raw);
seq_printf(s, "%d,0x%X\n", acc_detect1_convert, acc_detect1_raw);
return 0;
}
static int ab8500_gpadc_acc_detect1_open(struct inode *inode,
@ -1866,8 +1873,9 @@ static int ab8500_gpadc_acc_detect2_print(struct seq_file *s, void *p)
acc_detect2_convert = ab8500_gpadc_ad_to_voltage(gpadc,
ACC_DETECT2, acc_detect2_raw);
return seq_printf(s, "%d,0x%X\n",
acc_detect2_convert, acc_detect2_raw);
seq_printf(s, "%d,0x%X\n", acc_detect2_convert, acc_detect2_raw);
return 0;
}
static int ab8500_gpadc_acc_detect2_open(struct inode *inode,
@ -1897,8 +1905,9 @@ static int ab8500_gpadc_aux1_print(struct seq_file *s, void *p)
aux1_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX1,
aux1_raw);
return seq_printf(s, "%d,0x%X\n",
aux1_convert, aux1_raw);
seq_printf(s, "%d,0x%X\n", aux1_convert, aux1_raw);
return 0;
}
static int ab8500_gpadc_aux1_open(struct inode *inode, struct file *file)
@ -1926,8 +1935,9 @@ static int ab8500_gpadc_aux2_print(struct seq_file *s, void *p)
aux2_convert = ab8500_gpadc_ad_to_voltage(gpadc, ADC_AUX2,
aux2_raw);
return seq_printf(s, "%d,0x%X\n",
aux2_convert, aux2_raw);
seq_printf(s, "%d,0x%X\n", aux2_convert, aux2_raw);
return 0;
}
static int ab8500_gpadc_aux2_open(struct inode *inode, struct file *file)
@ -1955,8 +1965,9 @@ static int ab8500_gpadc_main_bat_v_print(struct seq_file *s, void *p)
main_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, MAIN_BAT_V,
main_bat_v_raw);
return seq_printf(s, "%d,0x%X\n",
main_bat_v_convert, main_bat_v_raw);
seq_printf(s, "%d,0x%X\n", main_bat_v_convert, main_bat_v_raw);
return 0;
}
static int ab8500_gpadc_main_bat_v_open(struct inode *inode,
@ -1986,8 +1997,9 @@ static int ab8500_gpadc_vbus_v_print(struct seq_file *s, void *p)
vbus_v_convert = ab8500_gpadc_ad_to_voltage(gpadc, VBUS_V,
vbus_v_raw);
return seq_printf(s, "%d,0x%X\n",
vbus_v_convert, vbus_v_raw);
seq_printf(s, "%d,0x%X\n", vbus_v_convert, vbus_v_raw);
return 0;
}
static int ab8500_gpadc_vbus_v_open(struct inode *inode, struct file *file)
@ -2015,8 +2027,9 @@ static int ab8500_gpadc_main_charger_c_print(struct seq_file *s, void *p)
main_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
MAIN_CHARGER_C, main_charger_c_raw);
return seq_printf(s, "%d,0x%X\n",
main_charger_c_convert, main_charger_c_raw);
seq_printf(s, "%d,0x%X\n", main_charger_c_convert, main_charger_c_raw);
return 0;
}
static int ab8500_gpadc_main_charger_c_open(struct inode *inode,
@ -2046,8 +2059,9 @@ static int ab8500_gpadc_usb_charger_c_print(struct seq_file *s, void *p)
usb_charger_c_convert = ab8500_gpadc_ad_to_voltage(gpadc,
USB_CHARGER_C, usb_charger_c_raw);
return seq_printf(s, "%d,0x%X\n",
usb_charger_c_convert, usb_charger_c_raw);
seq_printf(s, "%d,0x%X\n", usb_charger_c_convert, usb_charger_c_raw);
return 0;
}
static int ab8500_gpadc_usb_charger_c_open(struct inode *inode,
@ -2077,8 +2091,9 @@ static int ab8500_gpadc_bk_bat_v_print(struct seq_file *s, void *p)
bk_bat_v_convert = ab8500_gpadc_ad_to_voltage(gpadc,
BK_BAT_V, bk_bat_v_raw);
return seq_printf(s, "%d,0x%X\n",
bk_bat_v_convert, bk_bat_v_raw);
seq_printf(s, "%d,0x%X\n", bk_bat_v_convert, bk_bat_v_raw);
return 0;
}
static int ab8500_gpadc_bk_bat_v_open(struct inode *inode, struct file *file)
@ -2107,8 +2122,9 @@ static int ab8500_gpadc_die_temp_print(struct seq_file *s, void *p)
die_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, DIE_TEMP,
die_temp_raw);
return seq_printf(s, "%d,0x%X\n",
die_temp_convert, die_temp_raw);
seq_printf(s, "%d,0x%X\n", die_temp_convert, die_temp_raw);
return 0;
}
static int ab8500_gpadc_die_temp_open(struct inode *inode, struct file *file)
@ -2137,8 +2153,9 @@ static int ab8500_gpadc_usb_id_print(struct seq_file *s, void *p)
usb_id_convert = ab8500_gpadc_ad_to_voltage(gpadc, USB_ID,
usb_id_raw);
return seq_printf(s, "%d,0x%X\n",
usb_id_convert, usb_id_raw);
seq_printf(s, "%d,0x%X\n", usb_id_convert, usb_id_raw);
return 0;
}
static int ab8500_gpadc_usb_id_open(struct inode *inode, struct file *file)
@ -2166,8 +2183,9 @@ static int ab8540_gpadc_xtal_temp_print(struct seq_file *s, void *p)
xtal_temp_convert = ab8500_gpadc_ad_to_voltage(gpadc, XTAL_TEMP,
xtal_temp_raw);
return seq_printf(s, "%d,0x%X\n",
xtal_temp_convert, xtal_temp_raw);
seq_printf(s, "%d,0x%X\n", xtal_temp_convert, xtal_temp_raw);
return 0;
}
static int ab8540_gpadc_xtal_temp_open(struct inode *inode, struct file *file)
@ -2197,8 +2215,9 @@ static int ab8540_gpadc_vbat_true_meas_print(struct seq_file *s, void *p)
ab8500_gpadc_ad_to_voltage(gpadc, VBAT_TRUE_MEAS,
vbat_true_meas_raw);
return seq_printf(s, "%d,0x%X\n",
vbat_true_meas_convert, vbat_true_meas_raw);
seq_printf(s, "%d,0x%X\n", vbat_true_meas_convert, vbat_true_meas_raw);
return 0;
}
static int ab8540_gpadc_vbat_true_meas_open(struct inode *inode,
@ -2233,9 +2252,13 @@ static int ab8540_gpadc_bat_ctrl_and_ibat_print(struct seq_file *s, void *p)
ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
ibat_raw);
return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
bat_ctrl_convert, bat_ctrl_raw,
ibat_convert, ibat_raw);
seq_printf(s,
"%d,0x%X\n"
"%d,0x%X\n",
bat_ctrl_convert, bat_ctrl_raw,
ibat_convert, ibat_raw);
return 0;
}
static int ab8540_gpadc_bat_ctrl_and_ibat_open(struct inode *inode,
@ -2269,9 +2292,13 @@ static int ab8540_gpadc_vbat_meas_and_ibat_print(struct seq_file *s, void *p)
ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
ibat_raw);
return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
vbat_meas_convert, vbat_meas_raw,
ibat_convert, ibat_raw);
seq_printf(s,
"%d,0x%X\n"
"%d,0x%X\n",
vbat_meas_convert, vbat_meas_raw,
ibat_convert, ibat_raw);
return 0;
}
static int ab8540_gpadc_vbat_meas_and_ibat_open(struct inode *inode,
@ -2307,9 +2334,13 @@ static int ab8540_gpadc_vbat_true_meas_and_ibat_print(struct seq_file *s,
ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
ibat_raw);
return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
vbat_true_meas_convert, vbat_true_meas_raw,
ibat_convert, ibat_raw);
seq_printf(s,
"%d,0x%X\n"
"%d,0x%X\n",
vbat_true_meas_convert, vbat_true_meas_raw,
ibat_convert, ibat_raw);
return 0;
}
static int ab8540_gpadc_vbat_true_meas_and_ibat_open(struct inode *inode,
@ -2344,9 +2375,13 @@ static int ab8540_gpadc_bat_temp_and_ibat_print(struct seq_file *s, void *p)
ibat_convert = ab8500_gpadc_ad_to_voltage(gpadc, IBAT_VIRTUAL_CHANNEL,
ibat_raw);
return seq_printf(s, "%d,0x%X\n" "%d,0x%X\n",
bat_temp_convert, bat_temp_raw,
ibat_convert, ibat_raw);
seq_printf(s,
"%d,0x%X\n"
"%d,0x%X\n",
bat_temp_convert, bat_temp_raw,
ibat_convert, ibat_raw);
return 0;
}
static int ab8540_gpadc_bat_temp_and_ibat_open(struct inode *inode,
@ -2373,16 +2408,19 @@ static int ab8540_gpadc_otp_cal_print(struct seq_file *s, void *p)
gpadc = ab8500_gpadc_get("ab8500-gpadc.0");
ab8540_gpadc_get_otp(gpadc, &vmain_l, &vmain_h, &btemp_l, &btemp_h,
&vbat_l, &vbat_h, &ibat_l, &ibat_h);
return seq_printf(s, "VMAIN_L:0x%X\n"
"VMAIN_H:0x%X\n"
"BTEMP_L:0x%X\n"
"BTEMP_H:0x%X\n"
"VBAT_L:0x%X\n"
"VBAT_H:0x%X\n"
"IBAT_L:0x%X\n"
"IBAT_H:0x%X\n",
vmain_l, vmain_h, btemp_l, btemp_h,
vbat_l, vbat_h, ibat_l, ibat_h);
seq_printf(s,
"VMAIN_L:0x%X\n"
"VMAIN_H:0x%X\n"
"BTEMP_L:0x%X\n"
"BTEMP_H:0x%X\n"
"VBAT_L:0x%X\n"
"VBAT_H:0x%X\n"
"IBAT_L:0x%X\n"
"IBAT_H:0x%X\n",
vmain_l, vmain_h, btemp_l, btemp_h,
vbat_l, vbat_h, ibat_l, ibat_h);
return 0;
}
static int ab8540_gpadc_otp_cal_open(struct inode *inode, struct file *file)
@ -2400,7 +2438,9 @@ static const struct file_operations ab8540_gpadc_otp_calib_fops = {
static int ab8500_gpadc_avg_sample_print(struct seq_file *s, void *p)
{
return seq_printf(s, "%d\n", avg_sample);
seq_printf(s, "%d\n", avg_sample);
return 0;
}
static int ab8500_gpadc_avg_sample_open(struct inode *inode, struct file *file)
@ -2445,7 +2485,9 @@ static const struct file_operations ab8500_gpadc_avg_sample_fops = {
static int ab8500_gpadc_trig_edge_print(struct seq_file *s, void *p)
{
return seq_printf(s, "%d\n", trig_edge);
seq_printf(s, "%d\n", trig_edge);
return 0;
}
static int ab8500_gpadc_trig_edge_open(struct inode *inode, struct file *file)
@ -2490,7 +2532,9 @@ static const struct file_operations ab8500_gpadc_trig_edge_fops = {
static int ab8500_gpadc_trig_timer_print(struct seq_file *s, void *p)
{
return seq_printf(s, "%d\n", trig_timer);
seq_printf(s, "%d\n", trig_timer);
return 0;
}
static int ab8500_gpadc_trig_timer_open(struct inode *inode, struct file *file)
@ -2533,7 +2577,9 @@ static const struct file_operations ab8500_gpadc_trig_timer_fops = {
static int ab8500_gpadc_conv_type_print(struct seq_file *s, void *p)
{
return seq_printf(s, "%d\n", conv_type);
seq_printf(s, "%d\n", conv_type);
return 0;
}
static int ab8500_gpadc_conv_type_open(struct inode *inode, struct file *file)

View File

@ -561,12 +561,23 @@ static int arizona_of_get_core_pdata(struct arizona *arizona)
count++;
}
count = 0;
of_property_for_each_u32(arizona->dev->of_node, "wlf,dmic-ref", prop,
cur, val) {
if (count == ARRAY_SIZE(arizona->pdata.dmic_ref))
break;
arizona->pdata.dmic_ref[count] = val;
count++;
}
return 0;
}
const struct of_device_id arizona_of_match[] = {
{ .compatible = "wlf,wm5102", .data = (void *)WM5102 },
{ .compatible = "wlf,wm5110", .data = (void *)WM5110 },
{ .compatible = "wlf,wm8280", .data = (void *)WM8280 },
{ .compatible = "wlf,wm8997", .data = (void *)WM8997 },
{},
};
@ -671,6 +682,7 @@ int arizona_dev_init(struct arizona *arizona)
switch (arizona->type) {
case WM5102:
case WM5110:
case WM8280:
case WM8997:
for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++)
arizona->core_supplies[i].supply
@ -834,11 +846,19 @@ int arizona_dev_init(struct arizona *arizona)
#endif
#ifdef CONFIG_MFD_WM5110
case 0x5110:
type_name = "WM5110";
if (arizona->type != WM5110) {
switch (arizona->type) {
case WM5110:
type_name = "WM5110";
break;
case WM8280:
type_name = "WM8280";
break;
default:
type_name = "WM5110";
dev_err(arizona->dev, "WM5110 registered as %d\n",
arizona->type);
arizona->type = WM5110;
break;
}
apply_patch = wm5110_patch;
break;
@ -1010,6 +1030,7 @@ int arizona_dev_init(struct arizona *arizona)
ARRAY_SIZE(wm5102_devs), NULL, 0, NULL);
break;
case WM5110:
case WM8280:
ret = mfd_add_devices(arizona->dev, -1, wm5110_devs,
ARRAY_SIZE(wm5110_devs), NULL, 0, NULL);
break;

View File

@ -44,6 +44,7 @@ static int arizona_i2c_probe(struct i2c_client *i2c,
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
case WM8280:
regmap_config = &wm5110_i2c_regmap;
break;
#endif
@ -87,6 +88,7 @@ static int arizona_i2c_remove(struct i2c_client *i2c)
static const struct i2c_device_id arizona_i2c_id[] = {
{ "wm5102", WM5102 },
{ "wm5110", WM5110 },
{ "wm8280", WM8280 },
{ "wm8997", WM8997 },
{ }
};

View File

@ -211,6 +211,7 @@ int arizona_irq_init(struct arizona *arizona)
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
case WM8280:
aod = &wm5110_aod;
switch (arizona->rev) {

View File

@ -44,6 +44,7 @@ static int arizona_spi_probe(struct spi_device *spi)
#endif
#ifdef CONFIG_MFD_WM5110
case WM5110:
case WM8280:
regmap_config = &wm5110_spi_regmap;
break;
#endif
@ -84,6 +85,7 @@ static int arizona_spi_remove(struct spi_device *spi)
static const struct spi_device_id arizona_spi_ids[] = {
{ "wm5102", WM5102 },
{ "wm5110", WM5110 },
{ "wm8280", WM8280 },
{ },
};
MODULE_DEVICE_TABLE(spi, arizona_spi_ids);

View File

@ -29,7 +29,7 @@
#define AXP20X_OFF 0x80
static const char const *axp20x_model_names[] = {
static const char * const axp20x_model_names[] = {
"AXP202",
"AXP209",
"AXP288",
@ -290,6 +290,29 @@ static struct resource axp288_adc_resources[] = {
},
};
static struct resource axp288_extcon_resources[] = {
{
.start = AXP288_IRQ_VBUS_FALL,
.end = AXP288_IRQ_VBUS_FALL,
.flags = IORESOURCE_IRQ,
},
{
.start = AXP288_IRQ_VBUS_RISE,
.end = AXP288_IRQ_VBUS_RISE,
.flags = IORESOURCE_IRQ,
},
{
.start = AXP288_IRQ_MV_CHNG,
.end = AXP288_IRQ_MV_CHNG,
.flags = IORESOURCE_IRQ,
},
{
.start = AXP288_IRQ_BC_USB_CHNG,
.end = AXP288_IRQ_BC_USB_CHNG,
.flags = IORESOURCE_IRQ,
},
};
static struct resource axp288_charger_resources[] = {
{
.start = AXP288_IRQ_OV,
@ -344,6 +367,11 @@ static struct mfd_cell axp288_cells[] = {
.num_resources = ARRAY_SIZE(axp288_adc_resources),
.resources = axp288_adc_resources,
},
{
.name = "axp288_extcon",
.num_resources = ARRAY_SIZE(axp288_extcon_resources),
.resources = axp288_extcon_resources,
},
{
.name = "axp288_charger",
.num_resources = ARRAY_SIZE(axp288_charger_resources),

View File

@ -262,6 +262,8 @@ int da9052_irq_init(struct da9052 *da9052)
goto regmap_err;
}
enable_irq_wake(da9052->chip_irq);
ret = da9052_request_irq(da9052, DA9052_IRQ_ADC_EOM, "adc-irq",
da9052_auxadc_irq, da9052);

View File

@ -32,7 +32,7 @@ static int da9052_spi_probe(struct spi_device *spi)
if (!da9052)
return -ENOMEM;
spi->mode = SPI_MODE_0 | SPI_CPOL;
spi->mode = SPI_MODE_0;
spi->bits_per_word = 8;
spi_setup(spi);
@ -43,6 +43,10 @@ static int da9052_spi_probe(struct spi_device *spi)
config = da9052_regmap_config;
config.read_flag_mask = 1;
config.reg_bits = 7;
config.pad_bits = 1;
config.val_bits = 8;
config.use_single_rw = 1;
da9052->regmap = devm_regmap_init_spi(spi, &config);
if (IS_ERR(da9052->regmap)) {

View File

@ -95,7 +95,7 @@ static const struct regmap_range_cfg da9150_range_cfg[] = {
},
};
static struct regmap_config da9150_regmap_config = {
static const struct regmap_config da9150_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.ranges = da9150_range_cfg,

View File

@ -435,7 +435,7 @@ static int _dln2_transfer(struct dln2_dev *dln2, u16 handle, u16 cmd,
struct dln2_response *rsp;
struct dln2_rx_context *rxc;
struct device *dev = &dln2->interface->dev;
const unsigned long timeout = DLN2_USB_TIMEOUT * HZ / 1000;
const unsigned long timeout = msecs_to_jiffies(DLN2_USB_TIMEOUT);
struct dln2_mod_rx_slots *rxs = &dln2->mod_rx_slots[handle];
int size;

View File

@ -93,7 +93,7 @@ static int hi6421_pmic_remove(struct platform_device *pdev)
return 0;
}
static struct of_device_id of_hi6421_pmic_match_tbl[] = {
static const struct of_device_id of_hi6421_pmic_match_tbl[] = {
{ .compatible = "hisilicon,hi6421-pmic", },
{ },
};

View File

@ -0,0 +1,282 @@
/*
* Intel Quark MFD PCI driver for I2C & GPIO
*
* Copyright(c) 2014 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* 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.
*
* Intel Quark PCI device for I2C and GPIO controller sharing the same
* PCI function. This PCI driver will split the 2 devices into their
* respective drivers.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/mfd/core.h>
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/dmi.h>
#include <linux/platform_data/gpio-dwapb.h>
#include <linux/platform_data/i2c-designware.h>
/* PCI BAR for register base address */
#define MFD_I2C_BAR 0
#define MFD_GPIO_BAR 1
/* The base GPIO number under GPIOLIB framework */
#define INTEL_QUARK_MFD_GPIO_BASE 8
/* The default number of South-Cluster GPIO on Quark. */
#define INTEL_QUARK_MFD_NGPIO 8
/* The DesignWare GPIO ports on Quark. */
#define INTEL_QUARK_GPIO_NPORTS 1
#define INTEL_QUARK_IORES_MEM 0
#define INTEL_QUARK_IORES_IRQ 1
#define INTEL_QUARK_I2C_CONTROLLER_CLK "i2c_designware.0"
/* The Quark I2C controller source clock */
#define INTEL_QUARK_I2C_CLK_HZ 33000000
#define INTEL_QUARK_I2C_NCLK 1
struct intel_quark_mfd {
struct pci_dev *pdev;
struct clk *i2c_clk;
struct clk_lookup *i2c_clk_lookup;
};
struct i2c_mode_info {
const char *name;
unsigned int i2c_scl_freq;
};
static const struct i2c_mode_info platform_i2c_mode_info[] = {
{
.name = "Galileo",
.i2c_scl_freq = 100000,
},
{
.name = "GalileoGen2",
.i2c_scl_freq = 400000,
},
{}
};
static struct resource intel_quark_i2c_res[] = {
[INTEL_QUARK_IORES_MEM] = {
.flags = IORESOURCE_MEM,
},
[INTEL_QUARK_IORES_IRQ] = {
.flags = IORESOURCE_IRQ,
},
};
static struct resource intel_quark_gpio_res[] = {
[INTEL_QUARK_IORES_MEM] = {
.flags = IORESOURCE_MEM,
},
};
static struct mfd_cell intel_quark_mfd_cells[] = {
{
.id = MFD_I2C_BAR,
.name = "i2c_designware",
.num_resources = ARRAY_SIZE(intel_quark_i2c_res),
.resources = intel_quark_i2c_res,
.ignore_resource_conflicts = true,
},
{
.id = MFD_GPIO_BAR,
.name = "gpio-dwapb",
.num_resources = ARRAY_SIZE(intel_quark_gpio_res),
.resources = intel_quark_gpio_res,
.ignore_resource_conflicts = true,
},
};
static const struct pci_device_id intel_quark_mfd_ids[] = {
{ PCI_VDEVICE(INTEL, 0x0934), },
{},
};
MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
{
struct pci_dev *pdev = quark_mfd->pdev;
struct clk_lookup *i2c_clk_lookup;
struct clk *i2c_clk;
int ret;
i2c_clk_lookup = devm_kcalloc(&pdev->dev, INTEL_QUARK_I2C_NCLK,
sizeof(*i2c_clk_lookup), GFP_KERNEL);
if (!i2c_clk_lookup)
return -ENOMEM;
i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
i2c_clk = clk_register_fixed_rate(&pdev->dev,
INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
quark_mfd->i2c_clk = i2c_clk;
ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
INTEL_QUARK_I2C_NCLK);
if (ret)
dev_err(&pdev->dev, "Fixed clk register failed: %d\n", ret);
return ret;
}
static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
{
struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev);
if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup)
return;
clkdev_drop(quark_mfd->i2c_clk_lookup);
clk_unregister(quark_mfd->i2c_clk);
}
static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell)
{
const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
const struct i2c_mode_info *info;
struct dw_i2c_platform_data *pdata;
struct resource *res = (struct resource *)cell->resources;
struct device *dev = &pdev->dev;
res[INTEL_QUARK_IORES_MEM].start =
pci_resource_start(pdev, MFD_I2C_BAR);
res[INTEL_QUARK_IORES_MEM].end =
pci_resource_end(pdev, MFD_I2C_BAR);
res[INTEL_QUARK_IORES_IRQ].start = pdev->irq;
res[INTEL_QUARK_IORES_IRQ].end = pdev->irq;
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
/* Normal mode by default */
pdata->i2c_scl_freq = 100000;
if (board_name) {
for (info = platform_i2c_mode_info; info->name; info++) {
if (!strcmp(board_name, info->name)) {
pdata->i2c_scl_freq = info->i2c_scl_freq;
break;
}
}
}
cell->platform_data = pdata;
cell->pdata_size = sizeof(*pdata);
return 0;
}
static int intel_quark_gpio_setup(struct pci_dev *pdev, struct mfd_cell *cell)
{
struct dwapb_platform_data *pdata;
struct resource *res = (struct resource *)cell->resources;
struct device *dev = &pdev->dev;
res[INTEL_QUARK_IORES_MEM].start =
pci_resource_start(pdev, MFD_GPIO_BAR);
res[INTEL_QUARK_IORES_MEM].end =
pci_resource_end(pdev, MFD_GPIO_BAR);
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
/* For intel quark x1000, it has only one port: portA */
pdata->nports = INTEL_QUARK_GPIO_NPORTS;
pdata->properties = devm_kcalloc(dev, pdata->nports,
sizeof(*pdata->properties),
GFP_KERNEL);
if (!pdata->properties)
return -ENOMEM;
/* Set the properties for portA */
pdata->properties->node = NULL;
pdata->properties->name = "intel-quark-x1000-gpio-portA";
pdata->properties->idx = 0;
pdata->properties->ngpio = INTEL_QUARK_MFD_NGPIO;
pdata->properties->gpio_base = INTEL_QUARK_MFD_GPIO_BASE;
pdata->properties->irq = pdev->irq;
pdata->properties->irq_shared = true;
cell->platform_data = pdata;
cell->pdata_size = sizeof(*pdata);
return 0;
}
static int intel_quark_mfd_probe(struct pci_dev *pdev,
const struct pci_device_id *id)
{
struct intel_quark_mfd *quark_mfd;
int ret;
ret = pcim_enable_device(pdev);
if (ret)
return ret;
quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
if (!quark_mfd)
return -ENOMEM;
quark_mfd->pdev = pdev;
ret = intel_quark_register_i2c_clk(quark_mfd);
if (ret)
return ret;
dev_set_drvdata(&pdev->dev, quark_mfd);
ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[MFD_I2C_BAR]);
if (ret)
return ret;
ret = intel_quark_gpio_setup(pdev,
&intel_quark_mfd_cells[MFD_GPIO_BAR]);
if (ret)
return ret;
return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
NULL);
}
static void intel_quark_mfd_remove(struct pci_dev *pdev)
{
intel_quark_unregister_i2c_clk(pdev);
mfd_remove_devices(&pdev->dev);
}
static struct pci_driver intel_quark_mfd_driver = {
.name = "intel_quark_mfd_i2c_gpio",
.id_table = intel_quark_mfd_ids,
.probe = intel_quark_mfd_probe,
.remove = intel_quark_mfd_remove,
};
module_pci_driver(intel_quark_mfd_driver);
MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
MODULE_DESCRIPTION("Intel Quark MFD PCI driver for I2C & GPIO");
MODULE_LICENSE("GPL v2");

View File

@ -26,19 +26,14 @@
#include <linux/mfd/intel_soc_pmic.h>
#include "intel_soc_pmic_core.h"
/*
* On some boards the PMIC interrupt may come from a GPIO line.
* Try to lookup the ACPI table and see if such connection exists. If not,
* return -ENOENT and use the IRQ provided by I2C.
*/
static int intel_soc_pmic_find_gpio_irq(struct device *dev)
{
struct gpio_desc *desc;
int irq;
desc = devm_gpiod_get_index(dev, "intel_soc_pmic", 0);
desc = devm_gpiod_get_index(dev, "intel_soc_pmic", 0, GPIOD_IN);
if (IS_ERR(desc))
return -ENOENT;
return PTR_ERR(desc);
irq = gpiod_to_irq(desc);
if (irq < 0)
@ -71,6 +66,11 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c,
pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config);
/*
* On some boards the PMIC interrupt may come from a GPIO line. Try to
* lookup the ACPI table for a such connection and setup a GPIO
* interrupt if it exists. Otherwise use the IRQ provided by I2C
*/
irq = intel_soc_pmic_find_gpio_irq(dev);
pmic->irq = (irq < 0) ? i2c->irq : irq;

View File

@ -508,8 +508,15 @@ static struct dmi_system_id kempld_dmi_table[] __initdata = {
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
},
{
}, {
.ident = "CBL6",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),
DMI_MATCH(DMI_BOARD_NAME, "COMe-cBL6"),
},
.driver_data = (void *)&kempld_platform_data_generic,
.callback = kempld_create_platform_device,
}, {
.ident = "CCR2",
.matches = {
DMI_MATCH(DMI_BOARD_VENDOR, "Kontron"),

View File

@ -539,72 +539,7 @@ static struct lpc_ich_info lpc_chipset_info[] = {
* functions that probably will be registered by other drivers.
*/
static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x2410), LPC_ICH},
{ PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0},
{ PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2},
{ PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M},
{ PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3},
{ PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M},
{ PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4},
{ PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M},
{ PCI_VDEVICE(INTEL, 0x2450), LPC_CICH},
{ PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5},
{ PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB},
{ PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6},
{ PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M},
{ PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W},
{ PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7},
{ PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH},
{ PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M},
{ PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH},
{ PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10},
{ PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8},
{ PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH},
{ PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO},
{ PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M},
{ PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME},
{ PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9},
{ PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R},
{ PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH},
{ PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO},
{ PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M},
{ PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME},
{ PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10},
{ PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R},
{ PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D},
{ PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO},
{ PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH},
{ PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM},
{ PCI_VDEVICE(INTEL, 0x3b02), LPC_P55},
{ PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55},
{ PCI_VDEVICE(INTEL, 0x3b06), LPC_H55},
{ PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57},
{ PCI_VDEVICE(INTEL, 0x3b08), LPC_H57},
{ PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55},
{ PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57},
{ PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57},
{ PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF},
{ PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57},
{ PCI_VDEVICE(INTEL, 0x3b12), LPC_3400},
{ PCI_VDEVICE(INTEL, 0x3b14), LPC_3420},
{ PCI_VDEVICE(INTEL, 0x3b16), LPC_3450},
{ PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579},
{ PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL},
{ PCI_VDEVICE(INTEL, 0x1c41), LPC_CPT},
{ PCI_VDEVICE(INTEL, 0x1c42), LPC_CPTD},
{ PCI_VDEVICE(INTEL, 0x1c43), LPC_CPTM},
@ -638,7 +573,6 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x1c5f), LPC_CPT},
{ PCI_VDEVICE(INTEL, 0x1d40), LPC_PBG},
{ PCI_VDEVICE(INTEL, 0x1d41), LPC_PBG},
{ PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC},
{ PCI_VDEVICE(INTEL, 0x1e40), LPC_PPT},
{ PCI_VDEVICE(INTEL, 0x1e41), LPC_PPT},
{ PCI_VDEVICE(INTEL, 0x1e42), LPC_PPT},
@ -671,6 +605,79 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x1e5d), LPC_PPT},
{ PCI_VDEVICE(INTEL, 0x1e5e), LPC_PPT},
{ PCI_VDEVICE(INTEL, 0x1e5f), LPC_PPT},
{ PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL},
{ PCI_VDEVICE(INTEL, 0x2310), LPC_DH89XXCC},
{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
{ PCI_VDEVICE(INTEL, 0x2410), LPC_ICH},
{ PCI_VDEVICE(INTEL, 0x2420), LPC_ICH0},
{ PCI_VDEVICE(INTEL, 0x2440), LPC_ICH2},
{ PCI_VDEVICE(INTEL, 0x244c), LPC_ICH2M},
{ PCI_VDEVICE(INTEL, 0x2450), LPC_CICH},
{ PCI_VDEVICE(INTEL, 0x2480), LPC_ICH3},
{ PCI_VDEVICE(INTEL, 0x248c), LPC_ICH3M},
{ PCI_VDEVICE(INTEL, 0x24c0), LPC_ICH4},
{ PCI_VDEVICE(INTEL, 0x24cc), LPC_ICH4M},
{ PCI_VDEVICE(INTEL, 0x24d0), LPC_ICH5},
{ PCI_VDEVICE(INTEL, 0x25a1), LPC_6300ESB},
{ PCI_VDEVICE(INTEL, 0x2640), LPC_ICH6},
{ PCI_VDEVICE(INTEL, 0x2641), LPC_ICH6M},
{ PCI_VDEVICE(INTEL, 0x2642), LPC_ICH6W},
{ PCI_VDEVICE(INTEL, 0x2670), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2671), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2672), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2673), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2674), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2675), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2676), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2677), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2678), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x2679), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267a), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267b), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267c), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267d), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267e), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x267f), LPC_631XESB},
{ PCI_VDEVICE(INTEL, 0x27b0), LPC_ICH7DH},
{ PCI_VDEVICE(INTEL, 0x27b8), LPC_ICH7},
{ PCI_VDEVICE(INTEL, 0x27b9), LPC_ICH7M},
{ PCI_VDEVICE(INTEL, 0x27bc), LPC_NM10},
{ PCI_VDEVICE(INTEL, 0x27bd), LPC_ICH7MDH},
{ PCI_VDEVICE(INTEL, 0x2810), LPC_ICH8},
{ PCI_VDEVICE(INTEL, 0x2811), LPC_ICH8ME},
{ PCI_VDEVICE(INTEL, 0x2812), LPC_ICH8DH},
{ PCI_VDEVICE(INTEL, 0x2814), LPC_ICH8DO},
{ PCI_VDEVICE(INTEL, 0x2815), LPC_ICH8M},
{ PCI_VDEVICE(INTEL, 0x2912), LPC_ICH9DH},
{ PCI_VDEVICE(INTEL, 0x2914), LPC_ICH9DO},
{ PCI_VDEVICE(INTEL, 0x2916), LPC_ICH9R},
{ PCI_VDEVICE(INTEL, 0x2917), LPC_ICH9ME},
{ PCI_VDEVICE(INTEL, 0x2918), LPC_ICH9},
{ PCI_VDEVICE(INTEL, 0x2919), LPC_ICH9M},
{ PCI_VDEVICE(INTEL, 0x3a14), LPC_ICH10DO},
{ PCI_VDEVICE(INTEL, 0x3a16), LPC_ICH10R},
{ PCI_VDEVICE(INTEL, 0x3a18), LPC_ICH10},
{ PCI_VDEVICE(INTEL, 0x3a1a), LPC_ICH10D},
{ PCI_VDEVICE(INTEL, 0x3b00), LPC_PCH},
{ PCI_VDEVICE(INTEL, 0x3b01), LPC_PCHM},
{ PCI_VDEVICE(INTEL, 0x3b02), LPC_P55},
{ PCI_VDEVICE(INTEL, 0x3b03), LPC_PM55},
{ PCI_VDEVICE(INTEL, 0x3b06), LPC_H55},
{ PCI_VDEVICE(INTEL, 0x3b07), LPC_QM57},
{ PCI_VDEVICE(INTEL, 0x3b08), LPC_H57},
{ PCI_VDEVICE(INTEL, 0x3b09), LPC_HM55},
{ PCI_VDEVICE(INTEL, 0x3b0a), LPC_Q57},
{ PCI_VDEVICE(INTEL, 0x3b0b), LPC_HM57},
{ PCI_VDEVICE(INTEL, 0x3b0d), LPC_PCHMSFF},
{ PCI_VDEVICE(INTEL, 0x3b0f), LPC_QS57},
{ PCI_VDEVICE(INTEL, 0x3b12), LPC_3400},
{ PCI_VDEVICE(INTEL, 0x3b14), LPC_3420},
{ PCI_VDEVICE(INTEL, 0x3b16), LPC_3450},
{ PCI_VDEVICE(INTEL, 0x5031), LPC_EP80579},
{ PCI_VDEVICE(INTEL, 0x8c40), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c41), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c42), LPC_LPT},
@ -703,14 +710,11 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT},
{ PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8d40), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x8d41), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x8d42), LPC_WBG},
@ -743,12 +747,14 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x8d5d), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x8d5e), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x8d5f), LPC_WBG},
{ PCI_VDEVICE(INTEL, 0x1f38), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f39), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f3a), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x1f3b), LPC_AVN},
{ PCI_VDEVICE(INTEL, 0x0f1c), LPC_BAYTRAIL},
{ PCI_VDEVICE(INTEL, 0x2390), LPC_COLETO},
{ PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc1), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc2), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc3), LPC_WPT_LP},
@ -756,12 +762,6 @@ static const struct pci_device_id lpc_ich_ids[] = {
{ PCI_VDEVICE(INTEL, 0x9cc6), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc7), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x9cc9), LPC_WPT_LP},
{ PCI_VDEVICE(INTEL, 0x229c), LPC_BRASWELL},
{ PCI_VDEVICE(INTEL, 0x8cc1), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc2), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc3), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc4), LPC_9S},
{ PCI_VDEVICE(INTEL, 0x8cc6), LPC_9S},
{ 0, }, /* End of list */
};
MODULE_DEVICE_TABLE(pci, lpc_ich_ids);

View File

@ -53,8 +53,8 @@ static const struct mfd_cell max77693_devs[] = {
.of_compatible = "maxim,max77693-haptic",
},
{
.name = "max77693-flash",
.of_compatible = "maxim,max77693-flash",
.name = "max77693-led",
.of_compatible = "maxim,max77693-led",
},
};

243
drivers/mfd/max77843.c Normal file
View File

@ -0,0 +1,243 @@
/*
* MFD core driver for the Maxim MAX77843
*
* Copyright (C) 2015 Samsung Electronics
* Author: Jaewon Kim <jaewon02.kim@samsung.com>
* Author: Beomho Seo <beomho.seo@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77843-private.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
static const struct mfd_cell max77843_devs[] = {
{
.name = "max77843-muic",
.of_compatible = "maxim,max77843-muic",
}, {
.name = "max77843-regulator",
.of_compatible = "maxim,max77843-regulator",
}, {
.name = "max77843-charger",
.of_compatible = "maxim,max77843-charger"
}, {
.name = "max77843-fuelgauge",
.of_compatible = "maxim,max77843-fuelgauge",
}, {
.name = "max77843-haptic",
.of_compatible = "maxim,max77843-haptic",
},
};
static const struct regmap_config max77843_charger_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX77843_CHG_REG_END,
};
static const struct regmap_config max77843_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX77843_SYS_REG_END,
};
static const struct regmap_irq max77843_irqs[] = {
/* TOPSYS interrupts */
{ .reg_offset = 0, .mask = MAX77843_SYS_IRQ_SYSUVLO_INT, },
{ .reg_offset = 0, .mask = MAX77843_SYS_IRQ_SYSOVLO_INT, },
{ .reg_offset = 0, .mask = MAX77843_SYS_IRQ_TSHDN_INT, },
{ .reg_offset = 0, .mask = MAX77843_SYS_IRQ_TM_INT, },
};
static const struct regmap_irq_chip max77843_irq_chip = {
.name = "max77843",
.status_base = MAX77843_SYS_REG_SYSINTSRC,
.mask_base = MAX77843_SYS_REG_SYSINTMASK,
.mask_invert = false,
.num_regs = 1,
.irqs = max77843_irqs,
.num_irqs = ARRAY_SIZE(max77843_irqs),
};
/* Charger and Charger regulator use same regmap. */
static int max77843_chg_init(struct max77843 *max77843)
{
int ret;
max77843->i2c_chg = i2c_new_dummy(max77843->i2c->adapter, I2C_ADDR_CHG);
if (!max77843->i2c_chg) {
dev_err(&max77843->i2c->dev,
"Cannot allocate I2C device for Charger\n");
return PTR_ERR(max77843->i2c_chg);
}
i2c_set_clientdata(max77843->i2c_chg, max77843);
max77843->regmap_chg = devm_regmap_init_i2c(max77843->i2c_chg,
&max77843_charger_regmap_config);
if (IS_ERR(max77843->regmap_chg)) {
ret = PTR_ERR(max77843->regmap_chg);
goto err_chg_i2c;
}
return 0;
err_chg_i2c:
i2c_unregister_device(max77843->i2c_chg);
return ret;
}
static int max77843_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max77843 *max77843;
unsigned int reg_data;
int ret;
max77843 = devm_kzalloc(&i2c->dev, sizeof(*max77843), GFP_KERNEL);
if (!max77843)
return -ENOMEM;
i2c_set_clientdata(i2c, max77843);
max77843->dev = &i2c->dev;
max77843->i2c = i2c;
max77843->irq = i2c->irq;
max77843->regmap = devm_regmap_init_i2c(i2c,
&max77843_regmap_config);
if (IS_ERR(max77843->regmap)) {
dev_err(&i2c->dev, "Failed to allocate topsys register map\n");
return PTR_ERR(max77843->regmap);
}
ret = regmap_add_irq_chip(max77843->regmap, max77843->irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
0, &max77843_irq_chip, &max77843->irq_data);
if (ret) {
dev_err(&i2c->dev, "Failed to add TOPSYS IRQ chip\n");
return ret;
}
ret = regmap_read(max77843->regmap,
MAX77843_SYS_REG_PMICID, &reg_data);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read PMIC ID\n");
goto err_pmic_id;
}
dev_info(&i2c->dev, "device ID: 0x%x\n", reg_data);
ret = max77843_chg_init(max77843);
if (ret) {
dev_err(&i2c->dev, "Failed to init Charger\n");
goto err_pmic_id;
}
ret = regmap_update_bits(max77843->regmap,
MAX77843_SYS_REG_INTSRCMASK,
MAX77843_INTSRC_MASK_MASK,
(unsigned int)~MAX77843_INTSRC_MASK_MASK);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to unmask interrupt source\n");
goto err_pmic_id;
}
ret = mfd_add_devices(max77843->dev, -1, max77843_devs,
ARRAY_SIZE(max77843_devs), NULL, 0, NULL);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to add mfd device\n");
goto err_pmic_id;
}
device_init_wakeup(max77843->dev, true);
return 0;
err_pmic_id:
regmap_del_irq_chip(max77843->irq, max77843->irq_data);
return ret;
}
static int max77843_remove(struct i2c_client *i2c)
{
struct max77843 *max77843 = i2c_get_clientdata(i2c);
mfd_remove_devices(max77843->dev);
regmap_del_irq_chip(max77843->irq, max77843->irq_data);
i2c_unregister_device(max77843->i2c_chg);
return 0;
}
static const struct of_device_id max77843_dt_match[] = {
{ .compatible = "maxim,max77843", },
{ },
};
static const struct i2c_device_id max77843_id[] = {
{ "max77843", },
{ },
};
MODULE_DEVICE_TABLE(i2c, max77843_id);
static int __maybe_unused max77843_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max77843 *max77843 = i2c_get_clientdata(i2c);
disable_irq(max77843->irq);
if (device_may_wakeup(dev))
enable_irq_wake(max77843->irq);
return 0;
}
static int __maybe_unused max77843_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max77843 *max77843 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
disable_irq_wake(max77843->irq);
enable_irq(max77843->irq);
return 0;
}
static SIMPLE_DEV_PM_OPS(max77843_pm, max77843_suspend, max77843_resume);
static struct i2c_driver max77843_i2c_driver = {
.driver = {
.name = "max77843",
.pm = &max77843_pm,
.of_match_table = max77843_dt_match,
},
.probe = max77843_probe,
.remove = max77843_remove,
.id_table = max77843_id,
};
static int __init max77843_i2c_init(void)
{
return i2c_add_driver(&max77843_i2c_driver);
}
subsys_initcall(max77843_i2c_init);
static void __exit max77843_i2c_exit(void)
{
i2c_del_driver(&max77843_i2c_driver);
}
module_exit(max77843_i2c_exit);

View File

@ -51,19 +51,19 @@
void mc13xxx_lock(struct mc13xxx *mc13xxx)
{
if (!mutex_trylock(&mc13xxx->lock)) {
dev_dbg(mc13xxx->dev, "wait for %s from %pf\n",
dev_dbg(mc13xxx->dev, "wait for %s from %ps\n",
__func__, __builtin_return_address(0));
mutex_lock(&mc13xxx->lock);
}
dev_dbg(mc13xxx->dev, "%s from %pf\n",
dev_dbg(mc13xxx->dev, "%s from %ps\n",
__func__, __builtin_return_address(0));
}
EXPORT_SYMBOL(mc13xxx_lock);
void mc13xxx_unlock(struct mc13xxx *mc13xxx)
{
dev_dbg(mc13xxx->dev, "%s from %pf\n",
dev_dbg(mc13xxx->dev, "%s from %ps\n",
__func__, __builtin_return_address(0));
mutex_unlock(&mc13xxx->lock);
}

View File

@ -532,29 +532,6 @@ static const struct menelaus_vtg_value vcore_values[] = {
{ 1450, 18 },
};
int menelaus_set_vcore_sw(unsigned int mV)
{
int val, ret;
struct i2c_client *c = the_menelaus->client;
val = menelaus_get_vtg_value(mV, vcore_values,
ARRAY_SIZE(vcore_values));
if (val < 0)
return -EINVAL;
dev_dbg(&c->dev, "Setting VCORE to %d mV (val 0x%02x)\n", mV, val);
/* Set SW mode and the voltage in one go. */
mutex_lock(&the_menelaus->lock);
ret = menelaus_write_reg(MENELAUS_VCORE_CTRL1, val);
if (ret == 0)
the_menelaus->vcore_hw_mode = 0;
mutex_unlock(&the_menelaus->lock);
msleep(1);
return ret;
}
int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV)
{
int fval, rval, val, ret;
@ -1239,7 +1216,7 @@ static int menelaus_probe(struct i2c_client *client,
err = menelaus_read_reg(MENELAUS_VCORE_CTRL1);
if (err < 0)
goto fail;
if (err & BIT(7))
if (err & VCORE_CTRL1_HW_NSW)
menelaus->vcore_hw_mode = 1;
else
menelaus->vcore_hw_mode = 0;
@ -1259,7 +1236,7 @@ fail:
return err;
}
static int __exit menelaus_remove(struct i2c_client *client)
static int menelaus_remove(struct i2c_client *client)
{
struct menelaus_chip *menelaus = i2c_get_clientdata(client);
@ -1280,7 +1257,7 @@ static struct i2c_driver menelaus_i2c_driver = {
.name = DRIVER_NAME,
},
.probe = menelaus_probe,
.remove = __exit_p(menelaus_remove),
.remove = menelaus_remove,
.id_table = menelaus_id,
};

View File

@ -128,7 +128,7 @@ static int mfd_add_device(struct device *parent, int id,
int platform_id;
int r;
if (id < 0)
if (id == PLATFORM_DEVID_AUTO)
platform_id = id;
else
platform_id = id + cell->id;

227
drivers/mfd/mt6397-core.c Normal file
View File

@ -0,0 +1,227 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Flora Fu, MediaTek
*
* 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 in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/mfd/mt6397/core.h>
#include <linux/mfd/mt6397/registers.h>
static const struct mfd_cell mt6397_devs[] = {
{
.name = "mt6397-rtc",
.of_compatible = "mediatek,mt6397-rtc",
}, {
.name = "mt6397-regulator",
.of_compatible = "mediatek,mt6397-regulator",
}, {
.name = "mt6397-codec",
.of_compatible = "mediatek,mt6397-codec",
}, {
.name = "mt6397-clk",
.of_compatible = "mediatek,mt6397-clk",
},
};
static void mt6397_irq_lock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq);
mutex_lock(&mt6397->irqlock);
}
static void mt6397_irq_sync_unlock(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq);
regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]);
regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]);
mutex_unlock(&mt6397->irqlock);
}
static void mt6397_irq_disable(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq);
int shift = data->hwirq & 0xf;
int reg = data->hwirq >> 4;
mt6397->irq_masks_cur[reg] &= ~BIT(shift);
}
static void mt6397_irq_enable(struct irq_data *data)
{
struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq);
int shift = data->hwirq & 0xf;
int reg = data->hwirq >> 4;
mt6397->irq_masks_cur[reg] |= BIT(shift);
}
static struct irq_chip mt6397_irq_chip = {
.name = "mt6397-irq",
.irq_bus_lock = mt6397_irq_lock,
.irq_bus_sync_unlock = mt6397_irq_sync_unlock,
.irq_enable = mt6397_irq_enable,
.irq_disable = mt6397_irq_disable,
};
static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg,
int irqbase)
{
unsigned int status;
int i, irq, ret;
ret = regmap_read(mt6397->regmap, reg, &status);
if (ret) {
dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret);
return;
}
for (i = 0; i < 16; i++) {
if (status & BIT(i)) {
irq = irq_find_mapping(mt6397->irq_domain, irqbase + i);
if (irq)
handle_nested_irq(irq);
}
}
regmap_write(mt6397->regmap, reg, status);
}
static irqreturn_t mt6397_irq_thread(int irq, void *data)
{
struct mt6397_chip *mt6397 = data;
mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0);
mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16);
return IRQ_HANDLED;
}
static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
struct mt6397_chip *mt6397 = d->host_data;
irq_set_chip_data(irq, mt6397);
irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq);
irq_set_nested_thread(irq, 1);
#ifdef CONFIG_ARM
set_irq_flags(irq, IRQF_VALID);
#else
irq_set_noprobe(irq);
#endif
return 0;
}
static struct irq_domain_ops mt6397_irq_domain_ops = {
.map = mt6397_irq_domain_map,
};
static int mt6397_irq_init(struct mt6397_chip *mt6397)
{
int ret;
mutex_init(&mt6397->irqlock);
/* Mask all interrupt sources */
regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0);
regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0);
mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node,
MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397);
if (!mt6397->irq_domain) {
dev_err(mt6397->dev, "could not create irq domain\n");
return -ENOMEM;
}
ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL,
mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397);
if (ret) {
dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n",
mt6397->irq, ret);
return ret;
}
return 0;
}
static int mt6397_probe(struct platform_device *pdev)
{
int ret;
struct mt6397_chip *mt6397;
mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL);
if (!mt6397)
return -ENOMEM;
mt6397->dev = &pdev->dev;
/*
* mt6397 MFD is child device of soc pmic wrapper.
* Regmap is set from its parent.
*/
mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!mt6397->regmap)
return -ENODEV;
platform_set_drvdata(pdev, mt6397);
mt6397->irq = platform_get_irq(pdev, 0);
if (mt6397->irq > 0) {
ret = mt6397_irq_init(mt6397);
if (ret)
return ret;
}
ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs,
ARRAY_SIZE(mt6397_devs), NULL, 0, NULL);
if (ret)
dev_err(&pdev->dev, "failed to add child devices: %d\n", ret);
return ret;
}
static int mt6397_remove(struct platform_device *pdev)
{
mfd_remove_devices(&pdev->dev);
return 0;
}
static const struct of_device_id mt6397_of_match[] = {
{ .compatible = "mediatek,mt6397" },
{ }
};
MODULE_DEVICE_TABLE(of, mt6397_of_match);
static struct platform_driver mt6397_driver = {
.probe = mt6397_probe,
.remove = mt6397_remove,
.driver = {
.name = "mt6397",
.of_match_table = of_match_ptr(mt6397_of_match),
},
};
module_platform_driver(mt6397_driver);
MODULE_AUTHOR("Flora Fu, MediaTek");
MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:mt6397");

View File

@ -17,6 +17,100 @@
#include <linux/regmap.h>
#include <linux/of_platform.h>
#define PMIC_REV2 0x101
#define PMIC_REV3 0x102
#define PMIC_REV4 0x103
#define PMIC_TYPE 0x104
#define PMIC_SUBTYPE 0x105
#define PMIC_TYPE_VALUE 0x51
#define COMMON_SUBTYPE 0x00
#define PM8941_SUBTYPE 0x01
#define PM8841_SUBTYPE 0x02
#define PM8019_SUBTYPE 0x03
#define PM8226_SUBTYPE 0x04
#define PM8110_SUBTYPE 0x05
#define PMA8084_SUBTYPE 0x06
#define PMI8962_SUBTYPE 0x07
#define PMD9635_SUBTYPE 0x08
#define PM8994_SUBTYPE 0x09
#define PMI8994_SUBTYPE 0x0a
#define PM8916_SUBTYPE 0x0b
#define PM8004_SUBTYPE 0x0c
#define PM8909_SUBTYPE 0x0d
static const struct of_device_id pmic_spmi_id_table[] = {
{ .compatible = "qcom,spmi-pmic", .data = (void *)COMMON_SUBTYPE },
{ .compatible = "qcom,pm8941", .data = (void *)PM8941_SUBTYPE },
{ .compatible = "qcom,pm8841", .data = (void *)PM8841_SUBTYPE },
{ .compatible = "qcom,pm8019", .data = (void *)PM8019_SUBTYPE },
{ .compatible = "qcom,pm8226", .data = (void *)PM8226_SUBTYPE },
{ .compatible = "qcom,pm8110", .data = (void *)PM8110_SUBTYPE },
{ .compatible = "qcom,pma8084", .data = (void *)PMA8084_SUBTYPE },
{ .compatible = "qcom,pmi8962", .data = (void *)PMI8962_SUBTYPE },
{ .compatible = "qcom,pmd9635", .data = (void *)PMD9635_SUBTYPE },
{ .compatible = "qcom,pm8994", .data = (void *)PM8994_SUBTYPE },
{ .compatible = "qcom,pmi8994", .data = (void *)PMI8994_SUBTYPE },
{ .compatible = "qcom,pm8916", .data = (void *)PM8916_SUBTYPE },
{ .compatible = "qcom,pm8004", .data = (void *)PM8004_SUBTYPE },
{ .compatible = "qcom,pm8909", .data = (void *)PM8909_SUBTYPE },
{ }
};
static void pmic_spmi_show_revid(struct regmap *map, struct device *dev)
{
unsigned int rev2, minor, major, type, subtype;
const char *name = "unknown";
int ret, i;
ret = regmap_read(map, PMIC_TYPE, &type);
if (ret < 0)
return;
if (type != PMIC_TYPE_VALUE)
return;
ret = regmap_read(map, PMIC_SUBTYPE, &subtype);
if (ret < 0)
return;
for (i = 0; i < ARRAY_SIZE(pmic_spmi_id_table); i++) {
if (subtype == (unsigned long)pmic_spmi_id_table[i].data)
break;
}
if (i != ARRAY_SIZE(pmic_spmi_id_table))
name = pmic_spmi_id_table[i].compatible;
ret = regmap_read(map, PMIC_REV2, &rev2);
if (ret < 0)
return;
ret = regmap_read(map, PMIC_REV3, &minor);
if (ret < 0)
return;
ret = regmap_read(map, PMIC_REV4, &major);
if (ret < 0)
return;
/*
* In early versions of PM8941 and PM8226, the major revision number
* started incrementing from 0 (eg 0 = v1.0, 1 = v2.0).
* Increment the major revision number here if the chip is an early
* version of PM8941 or PM8226.
*/
if ((subtype == PM8941_SUBTYPE || subtype == PM8226_SUBTYPE) &&
major < 0x02)
major++;
if (subtype == PM8110_SUBTYPE)
minor = rev2;
dev_dbg(dev, "%x: %s v%d.%d\n", subtype, name, major, minor);
}
static const struct regmap_config spmi_regmap_config = {
.reg_bits = 16,
.val_bits = 8,
@ -33,6 +127,8 @@ static int pmic_spmi_probe(struct spmi_device *sdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
pmic_spmi_show_revid(regmap, &sdev->dev);
return of_platform_populate(root, NULL, NULL, &sdev->dev);
}
@ -41,13 +137,6 @@ static void pmic_spmi_remove(struct spmi_device *sdev)
of_platform_depopulate(&sdev->dev);
}
static const struct of_device_id pmic_spmi_id_table[] = {
{ .compatible = "qcom,spmi-pmic" },
{ .compatible = "qcom,pm8941" },
{ .compatible = "qcom,pm8841" },
{ .compatible = "qcom,pma8084" },
{ }
};
MODULE_DEVICE_TABLE(of, pmic_spmi_id_table);
static struct spmi_driver pmic_spmi_driver = {

View File

@ -323,10 +323,51 @@ static const struct qcom_rpm_data msm8960_template = {
.n_resources = ARRAY_SIZE(msm8960_rpm_resource_table),
};
static const struct qcom_rpm_resource ipq806x_rpm_resource_table[] = {
[QCOM_RPM_CXO_CLK] = { 25, 9, 5, 1 },
[QCOM_RPM_PXO_CLK] = { 26, 10, 6, 1 },
[QCOM_RPM_APPS_FABRIC_CLK] = { 27, 11, 8, 1 },
[QCOM_RPM_SYS_FABRIC_CLK] = { 28, 12, 9, 1 },
[QCOM_RPM_NSS_FABRIC_0_CLK] = { 29, 13, 10, 1 },
[QCOM_RPM_DAYTONA_FABRIC_CLK] = { 30, 14, 11, 1 },
[QCOM_RPM_SFPB_CLK] = { 31, 15, 12, 1 },
[QCOM_RPM_CFPB_CLK] = { 32, 16, 13, 1 },
[QCOM_RPM_NSS_FABRIC_1_CLK] = { 33, 17, 14, 1 },
[QCOM_RPM_EBI1_CLK] = { 34, 18, 16, 1 },
[QCOM_RPM_APPS_FABRIC_HALT] = { 35, 19, 18, 2 },
[QCOM_RPM_APPS_FABRIC_MODE] = { 37, 20, 19, 3 },
[QCOM_RPM_APPS_FABRIC_IOCTL] = { 40, 21, 20, 1 },
[QCOM_RPM_APPS_FABRIC_ARB] = { 41, 22, 21, 12 },
[QCOM_RPM_SYS_FABRIC_HALT] = { 53, 23, 22, 2 },
[QCOM_RPM_SYS_FABRIC_MODE] = { 55, 24, 23, 3 },
[QCOM_RPM_SYS_FABRIC_IOCTL] = { 58, 25, 24, 1 },
[QCOM_RPM_SYS_FABRIC_ARB] = { 59, 26, 25, 30 },
[QCOM_RPM_MM_FABRIC_HALT] = { 89, 27, 26, 2 },
[QCOM_RPM_MM_FABRIC_MODE] = { 91, 28, 27, 3 },
[QCOM_RPM_MM_FABRIC_IOCTL] = { 94, 29, 28, 1 },
[QCOM_RPM_MM_FABRIC_ARB] = { 95, 30, 29, 2 },
[QCOM_RPM_CXO_BUFFERS] = { 209, 33, 31, 1 },
[QCOM_RPM_USB_OTG_SWITCH] = { 210, 34, 32, 1 },
[QCOM_RPM_HDMI_SWITCH] = { 211, 35, 33, 1 },
[QCOM_RPM_DDR_DMM] = { 212, 36, 34, 2 },
[QCOM_RPM_VDDMIN_GPIO] = { 215, 40, 39, 1 },
[QCOM_RPM_SMB208_S1a] = { 216, 41, 90, 2 },
[QCOM_RPM_SMB208_S1b] = { 218, 43, 91, 2 },
[QCOM_RPM_SMB208_S2a] = { 220, 45, 92, 2 },
[QCOM_RPM_SMB208_S2b] = { 222, 47, 93, 2 },
};
static const struct qcom_rpm_data ipq806x_template = {
.version = 3,
.resource_table = ipq806x_rpm_resource_table,
.n_resources = ARRAY_SIZE(ipq806x_rpm_resource_table),
};
static const struct of_device_id qcom_rpm_of_match[] = {
{ .compatible = "qcom,rpm-apq8064", .data = &apq8064_template },
{ .compatible = "qcom,rpm-msm8660", .data = &msm8660_template },
{ .compatible = "qcom,rpm-msm8960", .data = &msm8960_template },
{ .compatible = "qcom,rpm-ipq8064", .data = &ipq806x_template },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_rpm_of_match);

View File

@ -89,6 +89,7 @@ static const struct rk808_reg_data pre_init_reg[] = {
{ RK808_BOOST_CONFIG_REG, BOOST_ILMIN_MASK, BOOST_ILMIN_100MA },
{ RK808_BUCK1_CONFIG_REG, BUCK1_RATE_MASK, BUCK_ILMIN_200MA },
{ RK808_BUCK2_CONFIG_REG, BUCK2_RATE_MASK, BUCK_ILMIN_200MA },
{ RK808_DCDC_UV_ACT_REG, BUCK_UV_ACT_MASK, BUCK_UV_ACT_DISABLE},
{ RK808_VB_MON_REG, MASK_ALL, VB_LO_ACT |
VB_LO_SEL_3500MV },
};
@ -245,7 +246,7 @@ static int rk808_remove(struct i2c_client *client)
return 0;
}
static struct of_device_id rk808_of_match[] = {
static const struct of_device_id rk808_of_match[] = {
{ .compatible = "rockchip,rk808" },
{ },
};

View File

@ -53,7 +53,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
u8 reg3 = 0;
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg1);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg1);
if (!rtsx_vendor_setting_valid(reg1))
return;
@ -65,7 +65,7 @@ static void rtl8411_fetch_vendor_settings(struct rtsx_pcr *pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg1);
rtsx_pci_read_config_byte(pcr, PCR_SETTING_REG3, &reg3);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG3, reg3);
pcr->sd30_drive_sel_3v3 = rtl8411_reg_to_sd30_drive_sel_3v3(reg3);
}
@ -74,7 +74,7 @@ static void rtl8411b_fetch_vendor_settings(struct rtsx_pcr *pcr)
u32 reg = 0;
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
if (!rtsx_vendor_setting_valid(reg))
return;
@ -260,9 +260,8 @@ static unsigned int rtl8411_cd_deglitch(struct rtsx_pcr *pcr)
rtsx_pci_write_register(pcr, CARD_PWR_CTL,
BPP_POWER_MASK, BPP_POWER_OFF);
dev_dbg(&(pcr->pci->dev),
"After CD deglitch, card_exist = 0x%x\n",
card_exist);
pcr_dbg(pcr, "After CD deglitch, card_exist = 0x%x\n",
card_exist);
}
if (card_exist & MS_EXIST) {

View File

@ -38,7 +38,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
u32 reg;
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
if (rts5209_vendor_setting1_valid(reg)) {
if (rts5209_reg_check_ms_pmos(reg))
@ -47,7 +47,7 @@ static void rts5209_fetch_vendor_settings(struct rtsx_pcr *pcr)
}
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
if (rts5209_vendor_setting2_valid(reg)) {
pcr->sd30_drive_sel_1v8 =

View File

@ -63,7 +63,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
u32 reg;
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
if (!rtsx_vendor_setting_valid(reg))
return;
@ -74,7 +74,7 @@ static void rts5227_fetch_vendor_settings(struct rtsx_pcr *pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
if (rtsx_reg_check_reverse_socket(reg))
pcr->flags |= PCR_REVERSE_SOCKET;
@ -118,11 +118,9 @@ static int rts5227_extra_init_hw(struct rtsx_pcr *pcr)
rts5227_fill_driving(pcr, OUTPUT_3V3);
/* Configure force_clock_req */
if (pcr->flags & PCR_REVERSE_SOCKET)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
AUTOLOAD_CFG_BASE + 3, 0xB8, 0xB8);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0xB8);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
AUTOLOAD_CFG_BASE + 3, 0xB8, 0x88);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB8, 0x88);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
return rtsx_pci_send_cmd(pcr, 100);
@ -132,7 +130,7 @@ static int rts5227_optimize_phy(struct rtsx_pcr *pcr)
{
int err;
err = rtsx_gops_pm_reset(pcr);
err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;

View File

@ -38,7 +38,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
u32 reg;
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
if (!rtsx_vendor_setting_valid(reg))
return;
@ -50,7 +50,7 @@ static void rts5229_fetch_vendor_settings(struct rtsx_pcr *pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr->sd30_drive_sel_3v3 =
map_sd_drive(rtsx_reg_to_sd30_drive_sel_3v3(reg));
}

View File

@ -36,16 +36,16 @@ static u8 rts5249_get_ic_version(struct rtsx_pcr *pcr)
static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
{
u8 driving_3v3[4][3] = {
{0x11, 0x11, 0x11},
{0x11, 0x11, 0x18},
{0x55, 0x55, 0x5C},
{0x99, 0x99, 0x92},
{0x99, 0x99, 0x92},
{0xFF, 0xFF, 0xFF},
{0x96, 0x96, 0x96},
};
u8 driving_1v8[4][3] = {
{0x3C, 0x3C, 0x3C},
{0xB3, 0xB3, 0xB3},
{0xFE, 0xFE, 0xFE},
{0xC4, 0xC4, 0xC4},
{0x3C, 0x3C, 0x3C},
{0xFE, 0xFE, 0xFE},
{0xB3, 0xB3, 0xB3},
};
u8 (*driving)[3], drive_sel;
@ -65,15 +65,17 @@ static void rts5249_fill_driving(struct rtsx_pcr *pcr, u8 voltage)
0xFF, driving[drive_sel][2]);
}
static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
static void rtsx_base_fetch_vendor_settings(struct rtsx_pcr *pcr)
{
u32 reg;
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG1, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG1, reg);
if (!rtsx_vendor_setting_valid(reg))
if (!rtsx_vendor_setting_valid(reg)) {
pcr_dbg(pcr, "skip fetch vendor setting\n");
return;
}
pcr->aspm_en = rtsx_reg_to_aspm(reg);
pcr->sd30_drive_sel_1v8 = rtsx_reg_to_sd30_drive_sel_1v8(reg);
@ -81,13 +83,13 @@ static void rts5249_fetch_vendor_settings(struct rtsx_pcr *pcr)
pcr->card_drive_sel |= rtsx_reg_to_card_drive_sel(reg);
rtsx_pci_read_config_dword(pcr, PCR_SETTING_REG2, &reg);
dev_dbg(&(pcr->pci->dev), "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr_dbg(pcr, "Cfg 0x%x: 0x%x\n", PCR_SETTING_REG2, reg);
pcr->sd30_drive_sel_3v3 = rtsx_reg_to_sd30_drive_sel_3v3(reg);
if (rtsx_reg_check_reverse_socket(reg))
pcr->flags |= PCR_REVERSE_SOCKET;
}
static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
static void rtsx_base_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
{
/* Set relink_time to 0 */
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 1, 0xFF, 0);
@ -95,7 +97,8 @@ static void rts5249_force_power_down(struct rtsx_pcr *pcr, u8 pm_state)
rtsx_pci_write_register(pcr, AUTOLOAD_CFG_BASE + 3, 0x01, 0);
if (pm_state == HOST_ENTER_S3)
rtsx_pci_write_register(pcr, PM_CTRL3, 0x10, 0x10);
rtsx_pci_write_register(pcr, pcr->reg_pm_ctrl3,
D3_DELINK_MODE_EN, D3_DELINK_MODE_EN);
rtsx_pci_write_register(pcr, FPDCTL, 0x03, 0x03);
}
@ -104,6 +107,8 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
{
rtsx_pci_init_cmd(pcr);
/* Rest L1SUB Config */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, L1SUB_CONFIG3, 0xFF, 0x00);
/* Configure GPIO as output */
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, GPIO_CTL, 0x02, 0x02);
/* Reset ASPM state to default value */
@ -116,12 +121,9 @@ static int rts5249_extra_init_hw(struct rtsx_pcr *pcr)
/* Configure driving */
rts5249_fill_driving(pcr, OUTPUT_3V3);
if (pcr->flags & PCR_REVERSE_SOCKET)
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
AUTOLOAD_CFG_BASE + 3, 0xB0, 0xB0);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0xB0);
else
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD,
AUTOLOAD_CFG_BASE + 3, 0xB0, 0x80);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PM_CTRL3, 0x10, 0x00);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, PETXCFG, 0xB0, 0x80);
return rtsx_pci_send_cmd(pcr, 100);
}
@ -130,15 +132,16 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
{
int err;
err = rtsx_gops_pm_reset(pcr);
err = rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_REG_REV,
PHY_REG_REV_RESV | PHY_REG_REV_RXIDLE_LATCHED |
PHY_REG_REV_P1_EN | PHY_REG_REV_RXIDLE_EN |
PHY_REG_REV_RX_PWST | PHY_REG_REV_CLKREQ_DLY_TIMER_1_0 |
PHY_REG_REV_STOP_CLKRD | PHY_REG_REV_STOP_CLKWR);
err = rtsx_pci_write_phy_register(pcr, PHY_REV,
PHY_REV_RESV | PHY_REV_RXIDLE_LATCHED |
PHY_REV_P1_EN | PHY_REV_RXIDLE_EN |
PHY_REV_CLKREQ_TX_EN | PHY_REV_RX_PWST |
PHY_REV_CLKREQ_DT_1_0 | PHY_REV_STOP_CLKRD |
PHY_REV_STOP_CLKWR);
if (err < 0)
return err;
@ -149,19 +152,21 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
PHY_BPCR_IB_FILTER | PHY_BPCR_CMIRROR_EN);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_PCR,
PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 |
PHY_PCR_RSSI_EN);
PHY_PCR_RSSI_EN | PHY_PCR_RX10K);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RCR2,
PHY_RCR2_EMPHASE_EN | PHY_RCR2_NADJR |
PHY_RCR2_CDR_CP_10 | PHY_RCR2_CDR_SR_2 |
PHY_RCR2_FREQSEL_12 | PHY_RCR2_CPADJEN |
PHY_RCR2_CDR_SC_8 | PHY_RCR2_CALIB_LATE);
PHY_RCR2_CDR_SR_2 | PHY_RCR2_FREQSEL_12 |
PHY_RCR2_CDR_SC_12P | PHY_RCR2_CALIB_LATE);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_FLD4,
PHY_FLD4_FLDEN_SEL | PHY_FLD4_REQ_REF |
PHY_FLD4_RXAMP_OFF | PHY_FLD4_REQ_ADDA |
@ -169,11 +174,12 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
PHY_FLD4_BER_CHK_EN);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RDR, PHY_RDR_RXDSEL_1_9);
err = rtsx_pci_write_phy_register(pcr, PHY_RDR,
PHY_RDR_RXDSEL_1_9 | PHY_SSC_AUTO_PWD);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_RCR1,
PHY_RCR1_ADP_TIME | PHY_RCR1_VCO_COARSE);
PHY_RCR1_ADP_TIME_4 | PHY_RCR1_VCO_COARSE);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_FLD3,
@ -181,33 +187,34 @@ static int rts5249_optimize_phy(struct rtsx_pcr *pcr)
PHY_FLD3_RXDELINK);
if (err < 0)
return err;
return rtsx_pci_write_phy_register(pcr, PHY_TUNE,
PHY_TUNE_TUNEREF_1_0 | PHY_TUNE_VBGSEL_1252 |
PHY_TUNE_SDBUS_33 | PHY_TUNE_TUNED18 |
PHY_TUNE_TUNED12);
PHY_TUNE_TUNED12 | PHY_TUNE_TUNEA12);
}
static int rts5249_turn_on_led(struct rtsx_pcr *pcr)
static int rtsx_base_turn_on_led(struct rtsx_pcr *pcr)
{
return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x02);
}
static int rts5249_turn_off_led(struct rtsx_pcr *pcr)
static int rtsx_base_turn_off_led(struct rtsx_pcr *pcr)
{
return rtsx_pci_write_register(pcr, GPIO_CTL, 0x02, 0x00);
}
static int rts5249_enable_auto_blink(struct rtsx_pcr *pcr)
static int rtsx_base_enable_auto_blink(struct rtsx_pcr *pcr)
{
return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x08);
}
static int rts5249_disable_auto_blink(struct rtsx_pcr *pcr)
static int rtsx_base_disable_auto_blink(struct rtsx_pcr *pcr)
{
return rtsx_pci_write_register(pcr, OLT_LED_CTL, 0x08, 0x00);
}
static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card)
static int rtsx_base_card_power_on(struct rtsx_pcr *pcr, int card)
{
int err;
@ -234,7 +241,7 @@ static int rts5249_card_power_on(struct rtsx_pcr *pcr, int card)
return 0;
}
static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card)
static int rtsx_base_card_power_off(struct rtsx_pcr *pcr, int card)
{
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CARD_PWR_CTL,
@ -244,22 +251,35 @@ static int rts5249_card_power_off(struct rtsx_pcr *pcr, int card)
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
static int rtsx_base_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
int err;
u16 append;
if (voltage == OUTPUT_3V3) {
err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4FC0 | 0x24);
switch (voltage) {
case OUTPUT_3V3:
err = rtsx_pci_update_phy(pcr, PHY_TUNE, PHY_TUNE_VOLTAGE_MASK,
PHY_TUNE_VOLTAGE_3V3);
if (err < 0)
return err;
} else if (voltage == OUTPUT_1V8) {
err = rtsx_pci_write_phy_register(pcr, PHY_BACR, 0x3C02);
break;
case OUTPUT_1V8:
append = PHY_TUNE_D18_1V8;
if (CHK_PCI_PID(pcr, 0x5249)) {
err = rtsx_pci_update_phy(pcr, PHY_BACR,
PHY_BACR_BASIC_MASK, 0);
if (err < 0)
return err;
append = PHY_TUNE_D18_1V7;
}
err = rtsx_pci_update_phy(pcr, PHY_TUNE, PHY_TUNE_VOLTAGE_MASK,
append);
if (err < 0)
return err;
err = rtsx_pci_write_phy_register(pcr, PHY_TUNE, 0x4C40 | 0x24);
if (err < 0)
return err;
} else {
break;
default:
pcr_dbg(pcr, "unknown output voltage %d\n", voltage);
return -EINVAL;
}
@ -270,17 +290,17 @@ static int rts5249_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
}
static const struct pcr_ops rts5249_pcr_ops = {
.fetch_vendor_settings = rts5249_fetch_vendor_settings,
.fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
.extra_init_hw = rts5249_extra_init_hw,
.optimize_phy = rts5249_optimize_phy,
.turn_on_led = rts5249_turn_on_led,
.turn_off_led = rts5249_turn_off_led,
.enable_auto_blink = rts5249_enable_auto_blink,
.disable_auto_blink = rts5249_disable_auto_blink,
.card_power_on = rts5249_card_power_on,
.card_power_off = rts5249_card_power_off,
.switch_output_voltage = rts5249_switch_output_voltage,
.force_power_down = rts5249_force_power_down,
.turn_on_led = rtsx_base_turn_on_led,
.turn_off_led = rtsx_base_turn_off_led,
.enable_auto_blink = rtsx_base_enable_auto_blink,
.disable_auto_blink = rtsx_base_disable_auto_blink,
.card_power_on = rtsx_base_card_power_on,
.card_power_off = rtsx_base_card_power_off,
.switch_output_voltage = rtsx_base_switch_output_voltage,
.force_power_down = rtsx_base_force_power_down,
};
/* SD Pull Control Enable:
@ -343,7 +363,7 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
pcr->flags = 0;
pcr->card_drive_sel = RTSX_CARD_DRIVE_DEFAULT;
pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_C;
pcr->sd30_drive_sel_1v8 = CFG_DRIVER_TYPE_B;
pcr->sd30_drive_sel_3v3 = CFG_DRIVER_TYPE_B;
pcr->aspm_en = ASPM_L1_EN;
pcr->tx_initial_phase = SET_CLOCK_PHASE(1, 29, 16);
@ -354,4 +374,219 @@ void rts5249_init_params(struct rtsx_pcr *pcr)
pcr->sd_pull_ctl_disable_tbl = rts5249_sd_pull_ctl_disable_tbl;
pcr->ms_pull_ctl_enable_tbl = rts5249_ms_pull_ctl_enable_tbl;
pcr->ms_pull_ctl_disable_tbl = rts5249_ms_pull_ctl_disable_tbl;
pcr->reg_pm_ctrl3 = PM_CTRL3;
}
static int rts524a_write_phy(struct rtsx_pcr *pcr, u8 addr, u16 val)
{
addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr;
return __rtsx_pci_write_phy_register(pcr, addr, val);
}
static int rts524a_read_phy(struct rtsx_pcr *pcr, u8 addr, u16 *val)
{
addr = addr & 0x80 ? (addr & 0x7F) | 0x40 : addr;
return __rtsx_pci_read_phy_register(pcr, addr, val);
}
static int rts524a_optimize_phy(struct rtsx_pcr *pcr)
{
int err;
err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
rtsx_pci_write_phy_register(pcr, PHY_PCR,
PHY_PCR_FORCE_CODE | PHY_PCR_OOBS_CALI_50 |
PHY_PCR_OOBS_VCM_08 | PHY_PCR_OOBS_SEN_90 | PHY_PCR_RSSI_EN);
rtsx_pci_write_phy_register(pcr, PHY_SSCCR3,
PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY);
if (is_version(pcr, 0x524A, IC_VER_A)) {
rtsx_pci_write_phy_register(pcr, PHY_SSCCR3,
PHY_SSCCR3_STEP_IN | PHY_SSCCR3_CHECK_DELAY);
rtsx_pci_write_phy_register(pcr, PHY_SSCCR2,
PHY_SSCCR2_PLL_NCODE | PHY_SSCCR2_TIME0 |
PHY_SSCCR2_TIME2_WIDTH);
rtsx_pci_write_phy_register(pcr, PHY_ANA1A,
PHY_ANA1A_TXR_LOOPBACK | PHY_ANA1A_RXT_BIST |
PHY_ANA1A_TXR_BIST | PHY_ANA1A_REV);
rtsx_pci_write_phy_register(pcr, PHY_ANA1D,
PHY_ANA1D_DEBUG_ADDR);
rtsx_pci_write_phy_register(pcr, PHY_DIG1E,
PHY_DIG1E_REV | PHY_DIG1E_D0_X_D1 |
PHY_DIG1E_RX_ON_HOST | PHY_DIG1E_RCLK_REF_HOST |
PHY_DIG1E_RCLK_TX_EN_KEEP |
PHY_DIG1E_RCLK_TX_TERM_KEEP |
PHY_DIG1E_RCLK_RX_EIDLE_ON | PHY_DIG1E_TX_TERM_KEEP |
PHY_DIG1E_RX_TERM_KEEP | PHY_DIG1E_TX_EN_KEEP |
PHY_DIG1E_RX_EN_KEEP);
}
rtsx_pci_write_phy_register(pcr, PHY_ANA08,
PHY_ANA08_RX_EQ_DCGAIN | PHY_ANA08_SEL_RX_EN |
PHY_ANA08_RX_EQ_VAL | PHY_ANA08_SCP | PHY_ANA08_SEL_IPI);
return 0;
}
static int rts524a_extra_init_hw(struct rtsx_pcr *pcr)
{
rts5249_extra_init_hw(pcr);
rtsx_pci_write_register(pcr, FUNC_FORCE_CTL,
FORCE_ASPM_L1_EN, FORCE_ASPM_L1_EN);
rtsx_pci_write_register(pcr, PM_EVENT_DEBUG, PME_DEBUG_0, PME_DEBUG_0);
rtsx_pci_write_register(pcr, LDO_VCC_CFG1, LDO_VCC_LMT_EN,
LDO_VCC_LMT_EN);
rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
if (is_version(pcr, 0x524A, IC_VER_A)) {
rtsx_pci_write_register(pcr, LDO_DV18_CFG,
LDO_DV18_SR_MASK, LDO_DV18_SR_DF);
rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
LDO_VCC_REF_TUNE_MASK, LDO_VCC_REF_1V2);
rtsx_pci_write_register(pcr, LDO_VIO_CFG,
LDO_VIO_REF_TUNE_MASK, LDO_VIO_REF_1V2);
rtsx_pci_write_register(pcr, LDO_VIO_CFG,
LDO_VIO_SR_MASK, LDO_VIO_SR_DF);
rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
LDO_REF12_TUNE_MASK, LDO_REF12_TUNE_DF);
rtsx_pci_write_register(pcr, SD40_LDO_CTL1,
SD40_VIO_TUNE_MASK, SD40_VIO_TUNE_1V7);
}
return 0;
}
static const struct pcr_ops rts524a_pcr_ops = {
.write_phy = rts524a_write_phy,
.read_phy = rts524a_read_phy,
.fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
.extra_init_hw = rts524a_extra_init_hw,
.optimize_phy = rts524a_optimize_phy,
.turn_on_led = rtsx_base_turn_on_led,
.turn_off_led = rtsx_base_turn_off_led,
.enable_auto_blink = rtsx_base_enable_auto_blink,
.disable_auto_blink = rtsx_base_disable_auto_blink,
.card_power_on = rtsx_base_card_power_on,
.card_power_off = rtsx_base_card_power_off,
.switch_output_voltage = rtsx_base_switch_output_voltage,
.force_power_down = rtsx_base_force_power_down,
};
void rts524a_init_params(struct rtsx_pcr *pcr)
{
rts5249_init_params(pcr);
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
pcr->ops = &rts524a_pcr_ops;
}
static int rts525a_card_power_on(struct rtsx_pcr *pcr, int card)
{
rtsx_pci_write_register(pcr, LDO_VCC_CFG1,
LDO_VCC_TUNE_MASK, LDO_VCC_3V3);
return rtsx_base_card_power_on(pcr, card);
}
static int rts525a_switch_output_voltage(struct rtsx_pcr *pcr, u8 voltage)
{
switch (voltage) {
case OUTPUT_3V3:
rtsx_pci_write_register(pcr, LDO_CONFIG2,
LDO_D3318_MASK, LDO_D3318_33V);
rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8, 0);
break;
case OUTPUT_1V8:
rtsx_pci_write_register(pcr, LDO_CONFIG2,
LDO_D3318_MASK, LDO_D3318_18V);
rtsx_pci_write_register(pcr, SD_PAD_CTL, SD_IO_USING_1V8,
SD_IO_USING_1V8);
break;
default:
return -EINVAL;
}
rtsx_pci_init_cmd(pcr);
rts5249_fill_driving(pcr, voltage);
return rtsx_pci_send_cmd(pcr, 100);
}
static int rts525a_optimize_phy(struct rtsx_pcr *pcr)
{
int err;
err = rtsx_pci_write_register(pcr, RTS524A_PM_CTRL3,
D3_DELINK_MODE_EN, 0x00);
if (err < 0)
return err;
rtsx_pci_write_phy_register(pcr, _PHY_FLD0,
_PHY_FLD0_CLK_REQ_20C | _PHY_FLD0_RX_IDLE_EN |
_PHY_FLD0_BIT_ERR_RSTN | _PHY_FLD0_BER_COUNT |
_PHY_FLD0_BER_TIMER | _PHY_FLD0_CHECK_EN);
rtsx_pci_write_phy_register(pcr, _PHY_ANA03,
_PHY_ANA03_TIMER_MAX | _PHY_ANA03_OOBS_DEB_EN |
_PHY_CMU_DEBUG_EN);
if (is_version(pcr, 0x525A, IC_VER_A))
rtsx_pci_write_phy_register(pcr, _PHY_REV0,
_PHY_REV0_FILTER_OUT | _PHY_REV0_CDR_BYPASS_PFD |
_PHY_REV0_CDR_RX_IDLE_BYPASS);
return 0;
}
static int rts525a_extra_init_hw(struct rtsx_pcr *pcr)
{
rts5249_extra_init_hw(pcr);
rtsx_pci_write_register(pcr, PCLK_CTL, PCLK_MODE_SEL, PCLK_MODE_SEL);
if (is_version(pcr, 0x525A, IC_VER_A)) {
rtsx_pci_write_register(pcr, L1SUB_CONFIG2,
L1SUB_AUTO_CFG, L1SUB_AUTO_CFG);
rtsx_pci_write_register(pcr, RREF_CFG,
RREF_VBGSEL_MASK, RREF_VBGSEL_1V25);
rtsx_pci_write_register(pcr, LDO_VIO_CFG,
LDO_VIO_TUNE_MASK, LDO_VIO_1V7);
rtsx_pci_write_register(pcr, LDO_DV12S_CFG,
LDO_D12_TUNE_MASK, LDO_D12_TUNE_DF);
rtsx_pci_write_register(pcr, LDO_AV12S_CFG,
LDO_AV12S_TUNE_MASK, LDO_AV12S_TUNE_DF);
rtsx_pci_write_register(pcr, LDO_VCC_CFG0,
LDO_VCC_LMTVTH_MASK, LDO_VCC_LMTVTH_2A);
rtsx_pci_write_register(pcr, OOBS_CONFIG,
OOBS_AUTOK_DIS | OOBS_VAL_MASK, 0x89);
}
return 0;
}
static const struct pcr_ops rts525a_pcr_ops = {
.fetch_vendor_settings = rtsx_base_fetch_vendor_settings,
.extra_init_hw = rts525a_extra_init_hw,
.optimize_phy = rts525a_optimize_phy,
.turn_on_led = rtsx_base_turn_on_led,
.turn_off_led = rtsx_base_turn_off_led,
.enable_auto_blink = rtsx_base_enable_auto_blink,
.disable_auto_blink = rtsx_base_disable_auto_blink,
.card_power_on = rts525a_card_power_on,
.card_power_off = rtsx_base_card_power_off,
.switch_output_voltage = rts525a_switch_output_voltage,
.force_power_down = rtsx_base_force_power_down,
};
void rts525a_init_params(struct rtsx_pcr *pcr)
{
rts5249_init_params(pcr);
pcr->reg_pm_ctrl3 = RTS524A_PM_CTRL3;
pcr->ops = &rts525a_pcr_ops;
}

View File

@ -1,37 +0,0 @@
/* Driver for Realtek PCI-Express card reader
*
* Copyright(c) 2009-2013 Realtek Semiconductor Corp. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*
* Author:
* Micky Ching <micky_ching@realsil.com.cn>
*/
#include <linux/mfd/rtsx_pci.h>
#include "rtsx_pcr.h"
int rtsx_gops_pm_reset(struct rtsx_pcr *pcr)
{
int err;
/* init aspm */
rtsx_pci_write_register(pcr, ASPM_FORCE_CTL, 0xFF, 0x00);
err = rtsx_pci_update_cfg_byte(pcr, LCTLR, ~LCTLR_ASPM_CTL_MASK, 0x00);
if (err < 0)
return err;
/* reset PM_CTRL3 before send buffer cmd */
return rtsx_pci_write_register(pcr, PM_CTRL3, D3_DELINK_MODE_EN, 0x00);
}

View File

@ -58,11 +58,25 @@ static const struct pci_device_id rtsx_pci_ids[] = {
{ PCI_DEVICE(0x10EC, 0x5249), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5287), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x5286), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x524A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ PCI_DEVICE(0x10EC, 0x525A), PCI_CLASS_OTHERS << 16, 0xFF0000 },
{ 0, }
};
MODULE_DEVICE_TABLE(pci, rtsx_pci_ids);
static inline void rtsx_pci_enable_aspm(struct rtsx_pcr *pcr)
{
rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
0xFC, pcr->aspm_en);
}
static inline void rtsx_pci_disable_aspm(struct rtsx_pcr *pcr)
{
rtsx_pci_update_cfg_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL,
0xFC, 0);
}
void rtsx_pci_start_run(struct rtsx_pcr *pcr)
{
/* If pci device removed, don't queue idle work any more */
@ -75,7 +89,7 @@ void rtsx_pci_start_run(struct rtsx_pcr *pcr)
pcr->ops->enable_auto_blink(pcr);
if (pcr->aspm_en)
rtsx_pci_write_config_byte(pcr, LCTLR, 0);
rtsx_pci_disable_aspm(pcr);
}
mod_delayed_work(system_wq, &pcr->idle_work, msecs_to_jiffies(200));
@ -130,7 +144,7 @@ int rtsx_pci_read_register(struct rtsx_pcr *pcr, u16 addr, u8 *data)
}
EXPORT_SYMBOL_GPL(rtsx_pci_read_register);
int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val)
int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val)
{
int err, i, finished = 0;
u8 tmp;
@ -162,9 +176,17 @@ int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val)
return 0;
}
int rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val)
{
if (pcr->ops->write_phy)
return pcr->ops->write_phy(pcr, addr, val);
return __rtsx_pci_write_phy_register(pcr, addr, val);
}
EXPORT_SYMBOL_GPL(rtsx_pci_write_phy_register);
int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
{
int err, i, finished = 0;
u16 data;
@ -210,6 +232,14 @@ int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
return 0;
}
int rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val)
{
if (pcr->ops->read_phy)
return pcr->ops->read_phy(pcr, addr, val);
return __rtsx_pci_read_phy_register(pcr, addr, val);
}
EXPORT_SYMBOL_GPL(rtsx_pci_read_phy_register);
void rtsx_pci_stop_cmd(struct rtsx_pcr *pcr)
@ -286,8 +316,7 @@ int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout)
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, msecs_to_jiffies(timeout));
if (timeleft <= 0) {
dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n",
__func__, __LINE__);
pcr_dbg(pcr, "Timeout (%s %d)\n", __func__, __LINE__);
err = -ETIMEDOUT;
goto finish_send_cmd;
}
@ -323,8 +352,7 @@ static void rtsx_pci_add_sg_tbl(struct rtsx_pcr *pcr,
u64 val;
u8 option = SG_VALID | SG_TRANS_DATA;
dev_dbg(&(pcr->pci->dev), "DMA addr: 0x%x, Len: 0x%x\n",
(unsigned int)addr, len);
pcr_dbg(pcr, "DMA addr: 0x%x, Len: 0x%x\n", (unsigned int)addr, len);
if (end)
option |= SG_END;
@ -339,11 +367,11 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist,
{
int err = 0, count;
dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg);
pcr_dbg(pcr, "--> %s: num_sg = %d\n", __func__, num_sg);
count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read);
if (count < 1)
return -EINVAL;
dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count);
pcr_dbg(pcr, "DMA mapping count: %d\n", count);
err = rtsx_pci_dma_transfer(pcr, sglist, count, read, timeout);
@ -417,8 +445,7 @@ int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist,
timeleft = wait_for_completion_interruptible_timeout(
&trans_done, msecs_to_jiffies(timeout));
if (timeleft <= 0) {
dev_dbg(&(pcr->pci->dev), "Timeout (%s %d)\n",
__func__, __LINE__);
pcr_dbg(pcr, "Timeout (%s %d)\n", __func__, __LINE__);
err = -ETIMEDOUT;
goto out;
}
@ -592,7 +619,7 @@ static void rtsx_pci_enable_bus_int(struct rtsx_pcr *pcr)
/* Enable Bus Interrupt */
rtsx_pci_writel(pcr, RTSX_BIER, pcr->bier);
dev_dbg(&(pcr->pci->dev), "RTSX_BIER: 0x%08x\n", pcr->bier);
pcr_dbg(pcr, "RTSX_BIER: 0x%08x\n", pcr->bier);
}
static inline u8 double_ssc_depth(u8 depth)
@ -638,14 +665,13 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
return err;
card_clock /= 1000000;
dev_dbg(&(pcr->pci->dev), "Switch card clock to %dMHz\n", card_clock);
pcr_dbg(pcr, "Switch card clock to %dMHz\n", card_clock);
clk = card_clock;
if (!initial_mode && double_clk)
clk = card_clock * 2;
dev_dbg(&(pcr->pci->dev),
"Internal SSC clock: %dMHz (cur_clock = %d)\n",
clk, pcr->cur_clock);
pcr_dbg(pcr, "Internal SSC clock: %dMHz (cur_clock = %d)\n",
clk, pcr->cur_clock);
if (clk == pcr->cur_clock)
return 0;
@ -674,14 +700,14 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
}
div++;
}
dev_dbg(&(pcr->pci->dev), "n = %d, div = %d\n", n, div);
pcr_dbg(pcr, "n = %d, div = %d\n", n, div);
ssc_depth = depth[ssc_depth];
if (double_clk)
ssc_depth = double_ssc_depth(ssc_depth);
ssc_depth = revise_ssc_depth(ssc_depth, div);
dev_dbg(&(pcr->pci->dev), "ssc_depth = %d\n", ssc_depth);
pcr_dbg(pcr, "ssc_depth = %d\n", ssc_depth);
rtsx_pci_init_cmd(pcr);
rtsx_pci_add_cmd(pcr, WRITE_REG_CMD, CLK_CTL,
@ -803,13 +829,13 @@ static void rtsx_pci_card_detect(struct work_struct *work)
dwork = to_delayed_work(work);
pcr = container_of(dwork, struct rtsx_pcr, carddet_work);
dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
pcr_dbg(pcr, "--> %s\n", __func__);
mutex_lock(&pcr->pcr_mutex);
spin_lock_irqsave(&pcr->lock, flags);
irq_status = rtsx_pci_readl(pcr, RTSX_BIPR);
dev_dbg(&(pcr->pci->dev), "irq_status: 0x%08x\n", irq_status);
pcr_dbg(pcr, "irq_status: 0x%08x\n", irq_status);
irq_status &= CARD_EXIST;
card_inserted = pcr->card_inserted & irq_status;
@ -820,9 +846,8 @@ static void rtsx_pci_card_detect(struct work_struct *work)
spin_unlock_irqrestore(&pcr->lock, flags);
if (card_inserted || card_removed) {
dev_dbg(&(pcr->pci->dev),
"card_inserted: 0x%x, card_removed: 0x%x\n",
card_inserted, card_removed);
pcr_dbg(pcr, "card_inserted: 0x%x, card_removed: 0x%x\n",
card_inserted, card_removed);
if (pcr->ops->cd_deglitch)
card_inserted = pcr->ops->cd_deglitch(pcr);
@ -930,7 +955,7 @@ static void rtsx_pci_idle_work(struct work_struct *work)
struct delayed_work *dwork = to_delayed_work(work);
struct rtsx_pcr *pcr = container_of(dwork, struct rtsx_pcr, idle_work);
dev_dbg(&(pcr->pci->dev), "--> %s\n", __func__);
pcr_dbg(pcr, "--> %s\n", __func__);
mutex_lock(&pcr->pcr_mutex);
@ -942,7 +967,7 @@ static void rtsx_pci_idle_work(struct work_struct *work)
pcr->ops->turn_off_led(pcr);
if (pcr->aspm_en)
rtsx_pci_write_config_byte(pcr, LCTLR, pcr->aspm_en);
rtsx_pci_enable_aspm(pcr);
mutex_unlock(&pcr->pcr_mutex);
}
@ -968,6 +993,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
{
int err;
pcr->pcie_cap = pci_find_capability(pcr->pci, PCI_CAP_ID_EXP);
rtsx_pci_writel(pcr, RTSX_HCBAR, pcr->host_cmds_addr);
rtsx_pci_enable_bus_int(pcr);
@ -980,6 +1006,7 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
/* Wait SSC power stable */
udelay(200);
rtsx_pci_disable_aspm(pcr);
if (pcr->ops->optimize_phy) {
err = pcr->ops->optimize_phy(pcr);
if (err < 0)
@ -1028,10 +1055,8 @@ static int rtsx_pci_init_hw(struct rtsx_pcr *pcr)
if (err < 0)
return err;
rtsx_pci_write_config_byte(pcr, LCTLR, 0);
/* Enable clk_request_n to enable clock power management */
rtsx_pci_write_config_byte(pcr, 0x81, 1);
rtsx_pci_write_config_byte(pcr, pcr->pcie_cap + PCI_EXP_LNKCTL + 1, 1);
/* Enter L1 when host tx idle */
rtsx_pci_write_config_byte(pcr, 0x70F, 0x5B);
@ -1081,6 +1106,14 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
rts5249_init_params(pcr);
break;
case 0x524A:
rts524a_init_params(pcr);
break;
case 0x525A:
rts525a_init_params(pcr);
break;
case 0x5287:
rtl8411b_init_params(pcr);
break;
@ -1090,7 +1123,7 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
break;
}
dev_dbg(&(pcr->pci->dev), "PID: 0x%04x, IC version: 0x%02x\n",
pcr_dbg(pcr, "PID: 0x%04x, IC version: 0x%02x\n",
PCI_PID(pcr), pcr->ic_version);
pcr->slots = kcalloc(pcr->num_slots, sizeof(struct rtsx_slot),
@ -1101,14 +1134,14 @@ static int rtsx_pci_init_chip(struct rtsx_pcr *pcr)
if (pcr->ops->fetch_vendor_settings)
pcr->ops->fetch_vendor_settings(pcr);
dev_dbg(&(pcr->pci->dev), "pcr->aspm_en = 0x%x\n", pcr->aspm_en);
dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_1v8 = 0x%x\n",
pcr_dbg(pcr, "pcr->aspm_en = 0x%x\n", pcr->aspm_en);
pcr_dbg(pcr, "pcr->sd30_drive_sel_1v8 = 0x%x\n",
pcr->sd30_drive_sel_1v8);
dev_dbg(&(pcr->pci->dev), "pcr->sd30_drive_sel_3v3 = 0x%x\n",
pcr_dbg(pcr, "pcr->sd30_drive_sel_3v3 = 0x%x\n",
pcr->sd30_drive_sel_3v3);
dev_dbg(&(pcr->pci->dev), "pcr->card_drive_sel = 0x%x\n",
pcr_dbg(pcr, "pcr->card_drive_sel = 0x%x\n",
pcr->card_drive_sel);
dev_dbg(&(pcr->pci->dev), "pcr->flags = 0x%x\n", pcr->flags);
pcr_dbg(pcr, "pcr->flags = 0x%x\n", pcr->flags);
pcr->state = PDEV_STAT_IDLE;
err = rtsx_pci_init_hw(pcr);
@ -1126,7 +1159,7 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
struct rtsx_pcr *pcr;
struct pcr_handle *handle;
u32 base, len;
int ret, i;
int ret, i, bar = 0;
dev_dbg(&(pcidev->dev),
": Realtek PCI-E Card Reader found at %s [%04x:%04x] (rev %x)\n",
@ -1171,8 +1204,10 @@ static int rtsx_pci_probe(struct pci_dev *pcidev,
pcr->pci = pcidev;
dev_set_drvdata(&pcidev->dev, handle);
len = pci_resource_len(pcidev, 0);
base = pci_resource_start(pcidev, 0);
if (CHK_PCI_PID(pcr, 0x525A))
bar = 1;
len = pci_resource_len(pcidev, bar);
base = pci_resource_start(pcidev, bar);
pcr->remap_addr = ioremap_nocache(base, len);
if (!pcr->remap_addr) {
ret = -ENOMEM;

View File

@ -27,12 +27,20 @@
#define MIN_DIV_N_PCR 80
#define MAX_DIV_N_PCR 208
#define RTS524A_PME_FORCE_CTL 0xFF78
#define RTS524A_PM_CTRL3 0xFF7E
int __rtsx_pci_write_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 val);
int __rtsx_pci_read_phy_register(struct rtsx_pcr *pcr, u8 addr, u16 *val);
void rts5209_init_params(struct rtsx_pcr *pcr);
void rts5229_init_params(struct rtsx_pcr *pcr);
void rtl8411_init_params(struct rtsx_pcr *pcr);
void rtl8402_init_params(struct rtsx_pcr *pcr);
void rts5227_init_params(struct rtsx_pcr *pcr);
void rts5249_init_params(struct rtsx_pcr *pcr);
void rts524a_init_params(struct rtsx_pcr *pcr);
void rts525a_init_params(struct rtsx_pcr *pcr);
void rtl8411b_init_params(struct rtsx_pcr *pcr);
static inline u8 map_sd_drive(int idx)

View File

@ -68,6 +68,8 @@ static const struct mfd_cell s5m8767_devs[] = {
static const struct mfd_cell s2mps11_devs[] = {
{
.name = "s2mps11-pmic",
}, {
.name = "s2mps14-rtc",
}, {
.name = "s2mps11-clk",
.of_compatible = "samsung,s2mps11-clk",
@ -267,10 +269,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata(
struct sec_platform_data *pd;
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd) {
dev_err(dev, "could not allocate memory for pdata\n");
if (!pd)
return ERR_PTR(-ENOMEM);
}
/*
* ToDo: the 'wakeup' member in the platform data is more of a linux
@ -333,7 +333,6 @@ static int sec_pmic_probe(struct i2c_client *i2c,
}
if (pdata) {
sec_pmic->device_type = pdata->device_type;
sec_pmic->ono = pdata->ono;
sec_pmic->irq_base = pdata->irq_base;
sec_pmic->wakeup = pdata->wakeup;
sec_pmic->pdata = pdata;

View File

@ -61,14 +61,14 @@ static const struct regmap_irq s2mps11_irqs[] = {
.reg_offset = 1,
.mask = S2MPS11_IRQ_RTC60S_MASK,
},
[S2MPS11_IRQ_RTCA0] = {
.reg_offset = 1,
.mask = S2MPS11_IRQ_RTCA0_MASK,
},
[S2MPS11_IRQ_RTCA1] = {
.reg_offset = 1,
.mask = S2MPS11_IRQ_RTCA1_MASK,
},
[S2MPS11_IRQ_RTCA0] = {
.reg_offset = 1,
.mask = S2MPS11_IRQ_RTCA0_MASK,
},
[S2MPS11_IRQ_SMPL] = {
.reg_offset = 1,
.mask = S2MPS11_IRQ_SMPL_MASK,
@ -484,6 +484,12 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic)
return ret;
}
/*
* The rtc-s5m driver requests S2MPS14_IRQ_RTCA0 also for S2MPS11
* so the interrupt number must be consistent.
*/
BUILD_BUG_ON(((enum s2mps14_irq)S2MPS11_IRQ_RTCA0) != S2MPS14_IRQ_RTCA0);
return 0;
}

108
drivers/mfd/sky81452.c Normal file
View File

@ -0,0 +1,108 @@
/*
* sky81452.c SKY81452 MFD driver
*
* Copyright 2014 Skyworks Solutions Inc.
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.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 in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/mfd/core.h>
#include <linux/mfd/sky81452.h>
static const struct regmap_config sky81452_config = {
.reg_bits = 8,
.val_bits = 8,
};
static int sky81452_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct device *dev = &client->dev;
const struct sky81452_platform_data *pdata = dev_get_platdata(dev);
struct mfd_cell cells[2];
struct regmap *regmap;
int ret;
if (!pdata) {
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
return -ENOMEM;
}
regmap = devm_regmap_init_i2c(client, &sky81452_config);
if (IS_ERR(regmap)) {
dev_err(dev, "failed to initialize.err=%ld\n", PTR_ERR(regmap));
return PTR_ERR(regmap);
}
i2c_set_clientdata(client, regmap);
memset(cells, 0, sizeof(cells));
cells[0].name = "sky81452-backlight";
cells[0].of_compatible = "skyworks,sky81452-backlight";
cells[0].platform_data = pdata->bl_pdata;
cells[0].pdata_size = sizeof(*pdata->bl_pdata);
cells[1].name = "sky81452-regulator";
cells[1].platform_data = pdata->regulator_init_data;
cells[1].pdata_size = sizeof(*pdata->regulator_init_data);
ret = mfd_add_devices(dev, -1, cells, ARRAY_SIZE(cells), NULL, 0, NULL);
if (ret)
dev_err(dev, "failed to add child devices. err=%d\n", ret);
return ret;
}
static int sky81452_remove(struct i2c_client *client)
{
mfd_remove_devices(&client->dev);
return 0;
}
static const struct i2c_device_id sky81452_ids[] = {
{ "sky81452" },
{ }
};
MODULE_DEVICE_TABLE(i2c, sky81452_ids);
#ifdef CONFIG_OF
static const struct of_device_id sky81452_of_match[] = {
{ .compatible = "skyworks,sky81452", },
{ }
};
MODULE_DEVICE_TABLE(of, sky81452_of_match);
#endif
static struct i2c_driver sky81452_driver = {
.driver = {
.name = "sky81452",
.of_match_table = of_match_ptr(sky81452_of_match),
},
.probe = sky81452_probe,
.remove = sky81452_remove,
.id_table = sky81452_ids,
};
module_i2c_driver(sky81452_driver);
MODULE_DESCRIPTION("Skyworks SKY81452 MFD driver");
MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>");
MODULE_LICENSE("GPL v2");

View File

@ -318,7 +318,6 @@ static int tc3589x_device_init(struct tc3589x *tc3589x)
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id tc3589x_match[] = {
/* Legacy compatible string */
{ .compatible = "tc3589x", .data = (void *) TC3589X_UNKNOWN },
@ -359,14 +358,6 @@ tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
return pdata;
}
#else
static inline struct tc3589x_platform_data *
tc3589x_of_probe(struct device *dev, enum tc3589x_version *version)
{
dev_err(dev, "no device tree support\n");
return ERR_PTR(-ENODEV);
}
#endif
static int tc3589x_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)

View File

@ -68,12 +68,6 @@ static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc)
DEFINE_WAIT(wait);
u32 reg;
/*
* disable TSC steps so it does not run while the ADC is using it. If
* write 0 while it is running (it just started or was already running)
* then it completes all steps that were enabled and stops then.
*/
tscadc_writel(tsadc, REG_SE, 0);
reg = tscadc_readl(tsadc, REG_ADCFSM);
if (reg & SEQ_STATUS) {
tsadc->adc_waiting = true;
@ -86,8 +80,12 @@ static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc)
spin_lock_irq(&tsadc->reg_lock);
finish_wait(&tsadc->reg_se_wait, &wait);
/*
* Sequencer should either be idle or
* busy applying the charge step.
*/
reg = tscadc_readl(tsadc, REG_ADCFSM);
WARN_ON(reg & SEQ_STATUS);
WARN_ON((reg & SEQ_STATUS) && !(reg & CHARGE_STEP));
tsadc->adc_waiting = false;
}
tsadc->adc_in_use = true;
@ -96,7 +94,6 @@ static void am335x_tscadc_need_adc(struct ti_tscadc_dev *tsadc)
void am335x_tsc_se_set_once(struct ti_tscadc_dev *tsadc, u32 val)
{
spin_lock_irq(&tsadc->reg_lock);
tsadc->reg_se_cache |= val;
am335x_tscadc_need_adc(tsadc);
tscadc_writel(tsadc, REG_SE, val);

View File

@ -515,7 +515,7 @@ static int tps65010_gpio_get(struct gpio_chip *chip, unsigned offset)
static struct tps65010 *the_tps;
static int __exit tps65010_remove(struct i2c_client *client)
static int tps65010_remove(struct i2c_client *client)
{
struct tps65010 *tps = i2c_get_clientdata(client);
struct tps65010_board *board = dev_get_platdata(&client->dev);
@ -684,7 +684,7 @@ static struct i2c_driver tps65010_driver = {
.name = "tps65010",
},
.probe = tps65010_probe,
.remove = __exit_p(tps65010_remove),
.remove = tps65010_remove,
.id_table = tps65010_id,
};

View File

@ -829,7 +829,7 @@ static struct twl4030_power_data osc_off_idle = {
.board_config = osc_off_rconfig,
};
static struct of_device_id twl4030_power_of_match[] = {
static const struct of_device_id twl4030_power_of_match[] = {
{
.compatible = "ti,twl4030-power",
},

View File

@ -814,4 +814,3 @@ MODULE_DESCRIPTION("TWL6040 MFD");
MODULE_AUTHOR("Misael Lopez Cruz <misael.lopez@ti.com>");
MODULE_AUTHOR("Jorge Eduardo Candelaria <jorge.candelaria@ti.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:twl6040");

View File

@ -47,71 +47,26 @@
#define SYS_HBI_MASK 0xfff
#define SYS_PROCIDx_HBI_SHIFT 0
#define SYS_MCI_CARDIN (1 << 0)
#define SYS_MCI_WPROT (1 << 1)
#define SYS_MISC_MASTERSITE (1 << 14)
static void __iomem *__vexpress_sysreg_base;
static void __iomem *vexpress_sysreg_base(void)
{
if (!__vexpress_sysreg_base) {
struct device_node *node = of_find_compatible_node(NULL, NULL,
"arm,vexpress-sysreg");
__vexpress_sysreg_base = of_iomap(node, 0);
}
WARN_ON(!__vexpress_sysreg_base);
return __vexpress_sysreg_base;
}
static int vexpress_sysreg_get_master(void)
{
if (readl(vexpress_sysreg_base() + SYS_MISC) & SYS_MISC_MASTERSITE)
return VEXPRESS_SITE_DB2;
return VEXPRESS_SITE_DB1;
}
void vexpress_flags_set(u32 data)
{
writel(~0, vexpress_sysreg_base() + SYS_FLAGSCLR);
writel(data, vexpress_sysreg_base() + SYS_FLAGSSET);
static void __iomem *base;
if (!base) {
struct device_node *node = of_find_compatible_node(NULL, NULL,
"arm,vexpress-sysreg");
base = of_iomap(node, 0);
}
if (WARN_ON(!base))
return;
writel(~0, base + SYS_FLAGSCLR);
writel(data, base + SYS_FLAGSSET);
}
unsigned int vexpress_get_mci_cardin(struct device *dev)
{
return readl(vexpress_sysreg_base() + SYS_MCI) & SYS_MCI_CARDIN;
}
u32 vexpress_get_procid(int site)
{
if (site == VEXPRESS_SITE_MASTER)
site = vexpress_sysreg_get_master();
return readl(vexpress_sysreg_base() + (site == VEXPRESS_SITE_DB1 ?
SYS_PROCID0 : SYS_PROCID1));
}
void __iomem *vexpress_get_24mhz_clock_base(void)
{
return vexpress_sysreg_base() + SYS_24MHZ;
}
void __init vexpress_sysreg_early_init(void __iomem *base)
{
__vexpress_sysreg_base = base;
vexpress_config_set_master(vexpress_sysreg_get_master());
}
/* The sysreg block is just a random collection of various functions... */
static struct syscon_platform_data vexpress_sysreg_sys_id_pdata = {
@ -210,6 +165,7 @@ static int vexpress_sysreg_probe(struct platform_device *pdev)
struct resource *mem;
void __iomem *base;
struct bgpio_chip *mmc_gpio_chip;
int master;
u32 dt_hbi;
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@ -220,11 +176,14 @@ static int vexpress_sysreg_probe(struct platform_device *pdev)
if (!base)
return -ENOMEM;
vexpress_config_set_master(vexpress_sysreg_get_master());
master = readl(base + SYS_MISC) & SYS_MISC_MASTERSITE ?
VEXPRESS_SITE_DB2 : VEXPRESS_SITE_DB1;
vexpress_config_set_master(master);
/* Confirm board type against DT property, if available */
if (of_property_read_u32(of_root, "arm,hbi", &dt_hbi) == 0) {
u32 id = vexpress_get_procid(VEXPRESS_SITE_MASTER);
u32 id = readl(base + (master == VEXPRESS_SITE_DB1 ?
SYS_PROCID0 : SYS_PROCID1));
u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK;
if (WARN_ON(dt_hbi != hbi))

View File

@ -1172,9 +1172,6 @@ static bool wm5102_readable_register(struct device *dev, unsigned int reg)
case ARIZONA_DAC_DIGITAL_VOLUME_3L:
case ARIZONA_DAC_VOLUME_LIMIT_3L:
case ARIZONA_NOISE_GATE_SELECT_3L:
case ARIZONA_OUTPUT_PATH_CONFIG_3R:
case ARIZONA_DAC_DIGITAL_VOLUME_3R:
case ARIZONA_DAC_VOLUME_LIMIT_3R:
case ARIZONA_OUTPUT_PATH_CONFIG_4L:
case ARIZONA_DAC_DIGITAL_VOLUME_4L:
case ARIZONA_OUT_VOLUME_4L:

View File

@ -246,6 +246,7 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
*/
switch (arizona->type) {
case WM5110:
case WM8280:
desc = &arizona_micsupp_ext;
micsupp->init_data = arizona_micsupp_ext_default;
break;

View File

@ -48,8 +48,6 @@ struct s5m_rtc_reg_config {
unsigned int alarm0;
/* First register for alarm 1, seconds */
unsigned int alarm1;
/* SMPL/WTSR register */
unsigned int smpl_wtsr;
/*
* Register for update flag (UDR). Typically setting UDR field to 1
* will enable update of time or alarm register. Then it will be
@ -67,7 +65,6 @@ static const struct s5m_rtc_reg_config s5m_rtc_regs = {
.ctrl = S5M_ALARM1_CONF,
.alarm0 = S5M_ALARM0_SEC,
.alarm1 = S5M_ALARM1_SEC,
.smpl_wtsr = S5M_WTSR_SMPL_CNTL,
.rtc_udr_update = S5M_RTC_UDR_CON,
.rtc_udr_mask = S5M_RTC_UDR_MASK,
};
@ -82,7 +79,6 @@ static const struct s5m_rtc_reg_config s2mps_rtc_regs = {
.ctrl = S2MPS_RTC_CTRL,
.alarm0 = S2MPS_ALARM0_SEC,
.alarm1 = S2MPS_ALARM1_SEC,
.smpl_wtsr = S2MPS_WTSR_SMPL_CNTL,
.rtc_udr_update = S2MPS_RTC_UDR_CON,
.rtc_udr_mask = S2MPS_RTC_WUDR_MASK,
};
@ -96,7 +92,6 @@ struct s5m_rtc_info {
int irq;
int device_type;
int rtc_24hr_mode;
bool wtsr_smpl;
const struct s5m_rtc_reg_config *regs;
};
@ -597,28 +592,6 @@ static const struct rtc_class_ops s5m_rtc_ops = {
.alarm_irq_enable = s5m_rtc_alarm_irq_enable,
};
static void s5m_rtc_enable_wtsr(struct s5m_rtc_info *info, bool enable)
{
int ret;
ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
WTSR_ENABLE_MASK,
enable ? WTSR_ENABLE_MASK : 0);
if (ret < 0)
dev_err(info->dev, "%s: fail to update WTSR reg(%d)\n",
__func__, ret);
}
static void s5m_rtc_enable_smpl(struct s5m_rtc_info *info, bool enable)
{
int ret;
ret = regmap_update_bits(info->regmap, info->regs->smpl_wtsr,
SMPL_ENABLE_MASK,
enable ? SMPL_ENABLE_MASK : 0);
if (ret < 0)
dev_err(info->dev, "%s: fail to update SMPL reg(%d)\n",
__func__, ret);
}
static int s5m8767_rtc_init_reg(struct s5m_rtc_info *info)
{
u8 data[2];
@ -715,7 +688,6 @@ static int s5m_rtc_probe(struct platform_device *pdev)
info->dev = &pdev->dev;
info->s5m87xx = s5m87xx;
info->device_type = s5m87xx->device_type;
info->wtsr_smpl = s5m87xx->wtsr_smpl;
if (s5m87xx->irq_data) {
info->irq = regmap_irq_get_virq(s5m87xx->irq_data, alarm_irq);
@ -731,11 +703,6 @@ static int s5m_rtc_probe(struct platform_device *pdev)
ret = s5m8767_rtc_init_reg(info);
if (info->wtsr_smpl) {
s5m_rtc_enable_wtsr(info, true);
s5m_rtc_enable_smpl(info, true);
}
device_init_wakeup(&pdev->dev, 1);
info->rtc_dev = devm_rtc_device_register(&pdev->dev, "s5m-rtc",
@ -768,36 +735,10 @@ err:
return ret;
}
static void s5m_rtc_shutdown(struct platform_device *pdev)
{
struct s5m_rtc_info *info = platform_get_drvdata(pdev);
int i;
unsigned int val = 0;
if (info->wtsr_smpl) {
for (i = 0; i < 3; i++) {
s5m_rtc_enable_wtsr(info, false);
regmap_read(info->regmap, info->regs->smpl_wtsr, &val);
pr_debug("%s: WTSR_SMPL reg(0x%02x)\n", __func__, val);
if (val & WTSR_ENABLE_MASK)
pr_emerg("%s: fail to disable WTSR\n",
__func__);
else {
pr_info("%s: success to disable WTSR\n",
__func__);
break;
}
}
}
/* Disable SMPL when power off */
s5m_rtc_enable_smpl(info, false);
}
static int s5m_rtc_remove(struct platform_device *pdev)
{
struct s5m_rtc_info *info = platform_get_drvdata(pdev);
/* Perform also all shutdown steps when removing */
s5m_rtc_shutdown(pdev);
i2c_unregister_device(info->i2c);
return 0;
@ -842,7 +783,6 @@ static struct platform_driver s5m_rtc_driver = {
},
.probe = s5m_rtc_probe,
.remove = s5m_rtc_remove,
.shutdown = s5m_rtc_shutdown,
.id_table = s5m_rtc_id,
};

View File

@ -408,6 +408,16 @@ config BACKLIGHT_PANDORA
If you have a Pandora console, say Y to enable the
backlight driver.
config BACKLIGHT_SKY81452
tristate "Backlight driver for SKY81452"
depends on BACKLIGHT_CLASS_DEVICE && MFD_SKY81452
help
If you have a Skyworks SKY81452, say Y to enable the
backlight driver.
To compile this driver as a module, choose M here: the module will
be called sky81452-backlight
config BACKLIGHT_TPS65217
tristate "TPS65217 Backlight"
depends on BACKLIGHT_CLASS_DEVICE && MFD_TPS65217

View File

@ -50,6 +50,7 @@ obj-$(CONFIG_BACKLIGHT_PANDORA) += pandora_bl.o
obj-$(CONFIG_BACKLIGHT_PCF50633) += pcf50633-backlight.o
obj-$(CONFIG_BACKLIGHT_PWM) += pwm_bl.o
obj-$(CONFIG_BACKLIGHT_SAHARA) += kb3886_bl.o
obj-$(CONFIG_BACKLIGHT_SKY81452) += sky81452-backlight.o
obj-$(CONFIG_BACKLIGHT_TOSA) += tosa_bl.o
obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
obj-$(CONFIG_BACKLIGHT_WM831X) += wm831x_bl.o

View File

@ -0,0 +1,353 @@
/*
* sky81452-backlight.c SKY81452 backlight driver
*
* Copyright 2014 Skyworks Solutions Inc.
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.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 in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/backlight.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/platform_data/sky81452-backlight.h>
#include <linux/slab.h>
/* registers */
#define SKY81452_REG0 0x00
#define SKY81452_REG1 0x01
#define SKY81452_REG2 0x02
#define SKY81452_REG4 0x04
#define SKY81452_REG5 0x05
/* bit mask */
#define SKY81452_CS 0xFF
#define SKY81452_EN 0x3F
#define SKY81452_IGPW 0x20
#define SKY81452_PWMMD 0x10
#define SKY81452_PHASE 0x08
#define SKY81452_ILIM 0x04
#define SKY81452_VSHRT 0x03
#define SKY81452_OCP 0x80
#define SKY81452_OTMP 0x40
#define SKY81452_SHRT 0x3F
#define SKY81452_OPN 0x3F
#define SKY81452_DEFAULT_NAME "lcd-backlight"
#define SKY81452_MAX_BRIGHTNESS (SKY81452_CS + 1)
#define CTZ(b) __builtin_ctz(b)
static int sky81452_bl_update_status(struct backlight_device *bd)
{
const struct sky81452_bl_platform_data *pdata =
dev_get_platdata(bd->dev.parent);
const unsigned int brightness = (unsigned int)bd->props.brightness;
struct regmap *regmap = bl_get_data(bd);
int ret;
if (brightness > 0) {
ret = regmap_write(regmap, SKY81452_REG0, brightness - 1);
if (IS_ERR_VALUE(ret))
return ret;
return regmap_update_bits(regmap, SKY81452_REG1, SKY81452_EN,
pdata->enable << CTZ(SKY81452_EN));
}
return regmap_update_bits(regmap, SKY81452_REG1, SKY81452_EN, 0);
}
static const struct backlight_ops sky81452_bl_ops = {
.update_status = sky81452_bl_update_status,
};
static ssize_t sky81452_bl_store_enable(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct regmap *regmap = bl_get_data(to_backlight_device(dev));
unsigned long value;
int ret;
ret = kstrtoul(buf, 16, &value);
if (IS_ERR_VALUE(ret))
return ret;
ret = regmap_update_bits(regmap, SKY81452_REG1, SKY81452_EN,
value << CTZ(SKY81452_EN));
if (IS_ERR_VALUE(ret))
return ret;
return count;
}
static ssize_t sky81452_bl_show_open_short(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regmap *regmap = bl_get_data(to_backlight_device(dev));
unsigned int reg, value = 0;
char tmp[3];
int i, ret;
reg = !strcmp(attr->attr.name, "open") ? SKY81452_REG5 : SKY81452_REG4;
ret = regmap_read(regmap, reg, &value);
if (IS_ERR_VALUE(ret))
return ret;
if (value & SKY81452_SHRT) {
*buf = 0;
for (i = 0; i < 6; i++) {
if (value & 0x01) {
sprintf(tmp, "%d ", i + 1);
strcat(buf, tmp);
}
value >>= 1;
}
strcat(buf, "\n");
} else {
strcpy(buf, "none\n");
}
return strlen(buf);
}
static ssize_t sky81452_bl_show_fault(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct regmap *regmap = bl_get_data(to_backlight_device(dev));
unsigned int value = 0;
int ret;
ret = regmap_read(regmap, SKY81452_REG4, &value);
if (IS_ERR_VALUE(ret))
return ret;
*buf = 0;
if (value & SKY81452_OCP)
strcat(buf, "over-current ");
if (value & SKY81452_OTMP)
strcat(buf, "over-temperature");
strcat(buf, "\n");
return strlen(buf);
}
static DEVICE_ATTR(enable, S_IWGRP | S_IWUSR, NULL, sky81452_bl_store_enable);
static DEVICE_ATTR(open, S_IRUGO, sky81452_bl_show_open_short, NULL);
static DEVICE_ATTR(short, S_IRUGO, sky81452_bl_show_open_short, NULL);
static DEVICE_ATTR(fault, S_IRUGO, sky81452_bl_show_fault, NULL);
static struct attribute *sky81452_bl_attribute[] = {
&dev_attr_enable.attr,
&dev_attr_open.attr,
&dev_attr_short.attr,
&dev_attr_fault.attr,
NULL
};
static const struct attribute_group sky81452_bl_attr_group = {
.attrs = sky81452_bl_attribute,
};
#ifdef CONFIG_OF
static struct sky81452_bl_platform_data *sky81452_bl_parse_dt(
struct device *dev)
{
struct device_node *np = of_node_get(dev->of_node);
struct sky81452_bl_platform_data *pdata;
int num_entry;
unsigned int sources[6];
int ret;
if (!np) {
dev_err(dev, "backlight node not found.\n");
return ERR_PTR(-ENODATA);
}
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata) {
of_node_put(np);
return ERR_PTR(-ENOMEM);
}
of_property_read_string(np, "name", &pdata->name);
pdata->ignore_pwm = of_property_read_bool(np, "skyworks,ignore-pwm");
pdata->dpwm_mode = of_property_read_bool(np, "skyworks,dpwm-mode");
pdata->phase_shift = of_property_read_bool(np, "skyworks,phase-shift");
pdata->gpio_enable = of_get_gpio(np, 0);
ret = of_property_count_u32_elems(np, "led-sources");
if (IS_ERR_VALUE(ret)) {
pdata->enable = SKY81452_EN >> CTZ(SKY81452_EN);
} else {
num_entry = ret;
if (num_entry > 6)
num_entry = 6;
ret = of_property_read_u32_array(np, "led-sources", sources,
num_entry);
if (IS_ERR_VALUE(ret)) {
dev_err(dev, "led-sources node is invalid.\n");
return ERR_PTR(-EINVAL);
}
pdata->enable = 0;
while (--num_entry)
pdata->enable |= (1 << sources[num_entry]);
}
ret = of_property_read_u32(np,
"skyworks,short-detection-threshold-volt",
&pdata->short_detection_threshold);
if (IS_ERR_VALUE(ret))
pdata->short_detection_threshold = 7;
ret = of_property_read_u32(np, "skyworks,current-limit-mA",
&pdata->boost_current_limit);
if (IS_ERR_VALUE(ret))
pdata->boost_current_limit = 2750;
of_node_put(np);
return pdata;
}
#else
static struct sky81452_bl_platform_data *sky81452_bl_parse_dt(
struct device *dev)
{
return ERR_PTR(-EINVAL);
}
#endif
static int sky81452_bl_init_device(struct regmap *regmap,
struct sky81452_bl_platform_data *pdata)
{
unsigned int value;
value = pdata->ignore_pwm ? SKY81452_IGPW : 0;
value |= pdata->dpwm_mode ? SKY81452_PWMMD : 0;
value |= pdata->phase_shift ? 0 : SKY81452_PHASE;
if (pdata->boost_current_limit == 2300)
value |= SKY81452_ILIM;
else if (pdata->boost_current_limit != 2750)
return -EINVAL;
if (pdata->short_detection_threshold < 4 ||
pdata->short_detection_threshold > 7)
return -EINVAL;
value |= (7 - pdata->short_detection_threshold) << CTZ(SKY81452_VSHRT);
return regmap_write(regmap, SKY81452_REG2, value);
}
static int sky81452_bl_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regmap *regmap = dev_get_drvdata(dev->parent);
struct sky81452_bl_platform_data *pdata = dev_get_platdata(dev);
struct backlight_device *bd;
struct backlight_properties props;
const char *name;
int ret;
if (!pdata) {
pdata = sky81452_bl_parse_dt(dev);
if (IS_ERR(pdata))
return PTR_ERR(pdata);
}
if (gpio_is_valid(pdata->gpio_enable)) {
ret = devm_gpio_request_one(dev, pdata->gpio_enable,
GPIOF_OUT_INIT_HIGH, "sky81452-en");
if (IS_ERR_VALUE(ret)) {
dev_err(dev, "failed to request GPIO. err=%d\n", ret);
return ret;
}
}
ret = sky81452_bl_init_device(regmap, pdata);
if (IS_ERR_VALUE(ret)) {
dev_err(dev, "failed to initialize. err=%d\n", ret);
return ret;
}
memset(&props, 0, sizeof(props));
props.max_brightness = SKY81452_MAX_BRIGHTNESS,
name = pdata->name ? pdata->name : SKY81452_DEFAULT_NAME;
bd = devm_backlight_device_register(dev, name, dev, regmap,
&sky81452_bl_ops, &props);
if (IS_ERR(bd)) {
dev_err(dev, "failed to register. err=%ld\n", PTR_ERR(bd));
return PTR_ERR(bd);
}
platform_set_drvdata(pdev, bd);
ret = sysfs_create_group(&bd->dev.kobj, &sky81452_bl_attr_group);
if (IS_ERR_VALUE(ret)) {
dev_err(dev, "failed to create attribute. err=%d\n", ret);
return ret;
}
return ret;
}
static int sky81452_bl_remove(struct platform_device *pdev)
{
const struct sky81452_bl_platform_data *pdata =
dev_get_platdata(&pdev->dev);
struct backlight_device *bd = platform_get_drvdata(pdev);
sysfs_remove_group(&bd->dev.kobj, &sky81452_bl_attr_group);
bd->props.power = FB_BLANK_UNBLANK;
bd->props.brightness = 0;
backlight_update_status(bd);
if (gpio_is_valid(pdata->gpio_enable))
gpio_set_value_cansleep(pdata->gpio_enable, 0);
return 0;
}
#ifdef CONFIG_OF
static const struct of_device_id sky81452_bl_of_match[] = {
{ .compatible = "skyworks,sky81452-backlight", },
{ }
};
MODULE_DEVICE_TABLE(of, sky81452_bl_of_match);
#endif
static struct platform_driver sky81452_bl_driver = {
.driver = {
.name = "sky81452-backlight",
.of_match_table = of_match_ptr(sky81452_bl_of_match),
},
.probe = sky81452_bl_probe,
.remove = sky81452_bl_remove,
};
module_platform_driver(sky81452_bl_driver);
MODULE_DESCRIPTION("Skyworks SKY81452 backlight driver");
MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@skyworksinc.com>");
MODULE_LICENSE("GPL v2");

View File

@ -1,7 +1,7 @@
/*
* GPIO configuration for Arizona devices
* Device Tree defines for Arizona devices
*
* Copyright 2013 Wolfson Microelectronics. PLC.
* Copyright 2015 Cirrus Logic Inc.
*
* Author: Charles Keepax <ckeepax@opensource.wolfsonmicro.com>
*
@ -10,9 +10,10 @@
* published by the Free Software Foundation.
*/
#ifndef _ARIZONA_GPIO_H
#define _ARIZONA_GPIO_H
#ifndef _DT_BINDINGS_MFD_ARIZONA_H
#define _DT_BINDINGS_MFD_ARIZONA_H
/* GPIO Function Definitions */
#define ARIZONA_GP_FN_TXLRCLK 0x00
#define ARIZONA_GP_FN_GPIO 0x01
#define ARIZONA_GP_FN_IRQ1 0x02
@ -61,36 +62,32 @@
#define ARIZONA_GP_FN_SYSCLK_ENA_STATUS 0x4B
#define ARIZONA_GP_FN_ASYNCCLK_ENA_STATUS 0x4C
#define ARIZONA_GPN_DIR 0x8000 /* GPN_DIR */
#define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */
#define ARIZONA_GPN_DIR_SHIFT 15 /* GPN_DIR */
#define ARIZONA_GPN_DIR_WIDTH 1 /* GPN_DIR */
#define ARIZONA_GPN_PU 0x4000 /* GPN_PU */
#define ARIZONA_GPN_PU_MASK 0x4000 /* GPN_PU */
#define ARIZONA_GPN_PU_SHIFT 14 /* GPN_PU */
#define ARIZONA_GPN_PU_WIDTH 1 /* GPN_PU */
#define ARIZONA_GPN_PD 0x2000 /* GPN_PD */
#define ARIZONA_GPN_PD_MASK 0x2000 /* GPN_PD */
#define ARIZONA_GPN_PD_SHIFT 13 /* GPN_PD */
#define ARIZONA_GPN_PD_WIDTH 1 /* GPN_PD */
#define ARIZONA_GPN_LVL 0x0800 /* GPN_LVL */
#define ARIZONA_GPN_LVL_MASK 0x0800 /* GPN_LVL */
#define ARIZONA_GPN_LVL_SHIFT 11 /* GPN_LVL */
#define ARIZONA_GPN_LVL_WIDTH 1 /* GPN_LVL */
#define ARIZONA_GPN_POL 0x0400 /* GPN_POL */
#define ARIZONA_GPN_POL_MASK 0x0400 /* GPN_POL */
#define ARIZONA_GPN_POL_SHIFT 10 /* GPN_POL */
#define ARIZONA_GPN_POL_WIDTH 1 /* GPN_POL */
#define ARIZONA_GPN_OP_CFG 0x0200 /* GPN_OP_CFG */
#define ARIZONA_GPN_OP_CFG_MASK 0x0200 /* GPN_OP_CFG */
#define ARIZONA_GPN_OP_CFG_SHIFT 9 /* GPN_OP_CFG */
#define ARIZONA_GPN_OP_CFG_WIDTH 1 /* GPN_OP_CFG */
#define ARIZONA_GPN_DB 0x0100 /* GPN_DB */
#define ARIZONA_GPN_DB_MASK 0x0100 /* GPN_DB */
#define ARIZONA_GPN_DB_SHIFT 8 /* GPN_DB */
#define ARIZONA_GPN_DB_WIDTH 1 /* GPN_DB */
#define ARIZONA_GPN_FN_MASK 0x007F /* GPN_DB */
#define ARIZONA_GPN_FN_SHIFT 0 /* GPN_DB */
#define ARIZONA_GPN_FN_WIDTH 7 /* GPN_DB */
/* GPIO Configuration Bits */
#define ARIZONA_GPN_DIR 0x8000
#define ARIZONA_GPN_PU 0x4000
#define ARIZONA_GPN_PD 0x2000
#define ARIZONA_GPN_LVL 0x0800
#define ARIZONA_GPN_POL 0x0400
#define ARIZONA_GPN_OP_CFG 0x0200
#define ARIZONA_GPN_DB 0x0100
/* Provide some defines for the most common configs */
#define ARIZONA_GP_DEFAULT 0xffffffff
#define ARIZONA_GP_OUTPUT (ARIZONA_GP_FN_GPIO)
#define ARIZONA_GP_INPUT (ARIZONA_GP_FN_GPIO | \
ARIZONA_GPN_DIR)
#define ARIZONA_32KZ_MCLK1 1
#define ARIZONA_32KZ_MCLK2 2
#define ARIZONA_32KZ_NONE 3
#define ARIZONA_DMIC_MICVDD 0
#define ARIZONA_DMIC_MICBIAS1 1
#define ARIZONA_DMIC_MICBIAS2 2
#define ARIZONA_DMIC_MICBIAS3 3
#define ARIZONA_INMODE_DIFF 0
#define ARIZONA_INMODE_SE 1
#define ARIZONA_INMODE_DMIC 2
#endif

View File

@ -141,6 +141,12 @@
#define QCOM_RPM_SYS_FABRIC_MODE 131
#define QCOM_RPM_USB_OTG_SWITCH 132
#define QCOM_RPM_VDDMIN_GPIO 133
#define QCOM_RPM_NSS_FABRIC_0_CLK 134
#define QCOM_RPM_NSS_FABRIC_1_CLK 135
#define QCOM_RPM_SMB208_S1a 136
#define QCOM_RPM_SMB208_S1b 137
#define QCOM_RPM_SMB208_S2a 138
#define QCOM_RPM_SMB208_S2b 139
/*
* Constants used to select force mode for regulators.

View File

@ -24,6 +24,7 @@ enum arizona_type {
WM5102 = 1,
WM5110 = 2,
WM8997 = 3,
WM8280 = 4,
};
#define ARIZONA_IRQ_GP1 0

View File

@ -11,31 +11,26 @@
#ifndef _ARIZONA_PDATA_H
#define _ARIZONA_PDATA_H
#define ARIZONA_GPN_DIR 0x8000 /* GPN_DIR */
#include <dt-bindings/mfd/arizona.h>
#define ARIZONA_GPN_DIR_MASK 0x8000 /* GPN_DIR */
#define ARIZONA_GPN_DIR_SHIFT 15 /* GPN_DIR */
#define ARIZONA_GPN_DIR_WIDTH 1 /* GPN_DIR */
#define ARIZONA_GPN_PU 0x4000 /* GPN_PU */
#define ARIZONA_GPN_PU_MASK 0x4000 /* GPN_PU */
#define ARIZONA_GPN_PU_SHIFT 14 /* GPN_PU */
#define ARIZONA_GPN_PU_WIDTH 1 /* GPN_PU */
#define ARIZONA_GPN_PD 0x2000 /* GPN_PD */
#define ARIZONA_GPN_PD_MASK 0x2000 /* GPN_PD */
#define ARIZONA_GPN_PD_SHIFT 13 /* GPN_PD */
#define ARIZONA_GPN_PD_WIDTH 1 /* GPN_PD */
#define ARIZONA_GPN_LVL 0x0800 /* GPN_LVL */
#define ARIZONA_GPN_LVL_MASK 0x0800 /* GPN_LVL */
#define ARIZONA_GPN_LVL_SHIFT 11 /* GPN_LVL */
#define ARIZONA_GPN_LVL_WIDTH 1 /* GPN_LVL */
#define ARIZONA_GPN_POL 0x0400 /* GPN_POL */
#define ARIZONA_GPN_POL_MASK 0x0400 /* GPN_POL */
#define ARIZONA_GPN_POL_SHIFT 10 /* GPN_POL */
#define ARIZONA_GPN_POL_WIDTH 1 /* GPN_POL */
#define ARIZONA_GPN_OP_CFG 0x0200 /* GPN_OP_CFG */
#define ARIZONA_GPN_OP_CFG_MASK 0x0200 /* GPN_OP_CFG */
#define ARIZONA_GPN_OP_CFG_SHIFT 9 /* GPN_OP_CFG */
#define ARIZONA_GPN_OP_CFG_WIDTH 1 /* GPN_OP_CFG */
#define ARIZONA_GPN_DB 0x0100 /* GPN_DB */
#define ARIZONA_GPN_DB_MASK 0x0100 /* GPN_DB */
#define ARIZONA_GPN_DB_SHIFT 8 /* GPN_DB */
#define ARIZONA_GPN_DB_WIDTH 1 /* GPN_DB */
@ -45,23 +40,10 @@
#define ARIZONA_MAX_GPIO 5
#define ARIZONA_32KZ_MCLK1 1
#define ARIZONA_32KZ_MCLK2 2
#define ARIZONA_32KZ_NONE 3
#define ARIZONA_MAX_INPUT 4
#define ARIZONA_DMIC_MICVDD 0
#define ARIZONA_DMIC_MICBIAS1 1
#define ARIZONA_DMIC_MICBIAS2 2
#define ARIZONA_DMIC_MICBIAS3 3
#define ARIZONA_MAX_MICBIAS 3
#define ARIZONA_INMODE_DIFF 0
#define ARIZONA_INMODE_SE 1
#define ARIZONA_INMODE_DMIC 2
#define ARIZONA_MAX_OUTPUT 6
#define ARIZONA_MAX_AIF 3
@ -112,7 +94,7 @@ struct arizona_pdata {
int gpio_base;
/** Pin state for GPIO pins */
int gpio_defaults[ARIZONA_MAX_GPIO];
unsigned int gpio_defaults[ARIZONA_MAX_GPIO];
/**
* Maximum number of channels clocks will be generated for,

View File

@ -87,6 +87,7 @@ enum max77693_pmic_reg {
/* MAX77693 ITORCH register */
#define TORCH_IOUT1_SHIFT 0
#define TORCH_IOUT2_SHIFT 4
#define TORCH_IOUT_MASK(x) (0xf << (x))
#define TORCH_IOUT_MIN 15625
#define TORCH_IOUT_MAX 250000
#define TORCH_IOUT_STEP 15625
@ -113,8 +114,8 @@ enum max77693_pmic_reg {
#define FLASH_EN_FLASH 0x1
#define FLASH_EN_TORCH 0x2
#define FLASH_EN_ON 0x3
#define FLASH_EN_SHIFT(x) (6 - ((x) - 1) * 2)
#define TORCH_EN_SHIFT(x) (2 - ((x) - 1) * 2)
#define FLASH_EN_SHIFT(x) (6 - (x) * 2)
#define TORCH_EN_SHIFT(x) (2 - (x) * 2)
/* MAX77693 MAX_FLASH1 register */
#define MAX_FLASH1_MAX_FL_EN 0x80

View File

@ -81,19 +81,6 @@ enum max77693_led_boost_mode {
MAX77693_LED_BOOST_FIXED,
};
struct max77693_led_platform_data {
u32 fleds[2];
u32 iout_torch[2];
u32 iout_flash[2];
u32 trigger[2];
u32 trigger_type[2];
u32 num_leds;
u32 boost_mode;
u32 flash_timeout;
u32 boost_vout;
u32 low_vsys;
};
/* MAX77693 */
struct max77693_platform_data {

View File

@ -0,0 +1,454 @@
/*
* Common variables for the Maxim MAX77843 driver
*
* Copyright (C) 2015 Samsung Electronics
* Author: Jaewon Kim <jaewon02.kim@samsung.com>
* Author: Beomho Seo <beomho.seo@samsung.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.
*/
#ifndef __MAX77843_PRIVATE_H_
#define __MAX77843_PRIVATE_H_
#include <linux/i2c.h>
#include <linux/regmap.h>
#define I2C_ADDR_TOPSYS (0xCC >> 1)
#define I2C_ADDR_CHG (0xD2 >> 1)
#define I2C_ADDR_FG (0x6C >> 1)
#define I2C_ADDR_MUIC (0x4A >> 1)
/* Topsys, Haptic and LED registers */
enum max77843_sys_reg {
MAX77843_SYS_REG_PMICID = 0x00,
MAX77843_SYS_REG_PMICREV = 0x01,
MAX77843_SYS_REG_MAINCTRL1 = 0x02,
MAX77843_SYS_REG_INTSRC = 0x22,
MAX77843_SYS_REG_INTSRCMASK = 0x23,
MAX77843_SYS_REG_SYSINTSRC = 0x24,
MAX77843_SYS_REG_SYSINTMASK = 0x26,
MAX77843_SYS_REG_TOPSYS_STAT = 0x28,
MAX77843_SYS_REG_SAFEOUTCTRL = 0xC6,
MAX77843_SYS_REG_END,
};
enum max77843_haptic_reg {
MAX77843_HAP_REG_MCONFIG = 0x10,
MAX77843_HAP_REG_END,
};
enum max77843_led_reg {
MAX77843_LED_REG_LEDEN = 0x30,
MAX77843_LED_REG_LED0BRT = 0x31,
MAX77843_LED_REG_LED1BRT = 0x32,
MAX77843_LED_REG_LED2BRT = 0x33,
MAX77843_LED_REG_LED3BRT = 0x34,
MAX77843_LED_REG_LEDBLNK = 0x38,
MAX77843_LED_REG_LEDRAMP = 0x36,
MAX77843_LED_REG_END,
};
/* Charger registers */
enum max77843_charger_reg {
MAX77843_CHG_REG_CHG_INT = 0xB0,
MAX77843_CHG_REG_CHG_INT_MASK = 0xB1,
MAX77843_CHG_REG_CHG_INT_OK = 0xB2,
MAX77843_CHG_REG_CHG_DTLS_00 = 0xB3,
MAX77843_CHG_REG_CHG_DTLS_01 = 0xB4,
MAX77843_CHG_REG_CHG_DTLS_02 = 0xB5,
MAX77843_CHG_REG_CHG_CNFG_00 = 0xB7,
MAX77843_CHG_REG_CHG_CNFG_01 = 0xB8,
MAX77843_CHG_REG_CHG_CNFG_02 = 0xB9,
MAX77843_CHG_REG_CHG_CNFG_03 = 0xBA,
MAX77843_CHG_REG_CHG_CNFG_04 = 0xBB,
MAX77843_CHG_REG_CHG_CNFG_06 = 0xBD,
MAX77843_CHG_REG_CHG_CNFG_07 = 0xBE,
MAX77843_CHG_REG_CHG_CNFG_09 = 0xC0,
MAX77843_CHG_REG_CHG_CNFG_10 = 0xC1,
MAX77843_CHG_REG_CHG_CNFG_11 = 0xC2,
MAX77843_CHG_REG_CHG_CNFG_12 = 0xC3,
MAX77843_CHG_REG_END,
};
/* Fuel gauge registers */
enum max77843_fuelgauge {
MAX77843_FG_REG_STATUS = 0x00,
MAX77843_FG_REG_VALRT_TH = 0x01,
MAX77843_FG_REG_TALRT_TH = 0x02,
MAX77843_FG_REG_SALRT_TH = 0x03,
MAX77843_FG_RATE_AT_RATE = 0x04,
MAX77843_FG_REG_REMCAP_REP = 0x05,
MAX77843_FG_REG_SOCREP = 0x06,
MAX77843_FG_REG_AGE = 0x07,
MAX77843_FG_REG_TEMP = 0x08,
MAX77843_FG_REG_VCELL = 0x09,
MAX77843_FG_REG_CURRENT = 0x0A,
MAX77843_FG_REG_AVG_CURRENT = 0x0B,
MAX77843_FG_REG_SOCMIX = 0x0D,
MAX77843_FG_REG_SOCAV = 0x0E,
MAX77843_FG_REG_REMCAP_MIX = 0x0F,
MAX77843_FG_REG_FULLCAP = 0x10,
MAX77843_FG_REG_AVG_TEMP = 0x16,
MAX77843_FG_REG_CYCLES = 0x17,
MAX77843_FG_REG_AVG_VCELL = 0x19,
MAX77843_FG_REG_CONFIG = 0x1D,
MAX77843_FG_REG_REMCAP_AV = 0x1F,
MAX77843_FG_REG_FULLCAP_NOM = 0x23,
MAX77843_FG_REG_MISCCFG = 0x2B,
MAX77843_FG_REG_RCOMP = 0x38,
MAX77843_FG_REG_FSTAT = 0x3D,
MAX77843_FG_REG_DQACC = 0x45,
MAX77843_FG_REG_DPACC = 0x46,
MAX77843_FG_REG_OCV = 0xEE,
MAX77843_FG_REG_VFOCV = 0xFB,
MAX77843_FG_SOCVF = 0xFF,
MAX77843_FG_END,
};
/* MUIC registers */
enum max77843_muic_reg {
MAX77843_MUIC_REG_ID = 0x00,
MAX77843_MUIC_REG_INT1 = 0x01,
MAX77843_MUIC_REG_INT2 = 0x02,
MAX77843_MUIC_REG_INT3 = 0x03,
MAX77843_MUIC_REG_STATUS1 = 0x04,
MAX77843_MUIC_REG_STATUS2 = 0x05,
MAX77843_MUIC_REG_STATUS3 = 0x06,
MAX77843_MUIC_REG_INTMASK1 = 0x07,
MAX77843_MUIC_REG_INTMASK2 = 0x08,
MAX77843_MUIC_REG_INTMASK3 = 0x09,
MAX77843_MUIC_REG_CDETCTRL1 = 0x0A,
MAX77843_MUIC_REG_CDETCTRL2 = 0x0B,
MAX77843_MUIC_REG_CONTROL1 = 0x0C,
MAX77843_MUIC_REG_CONTROL2 = 0x0D,
MAX77843_MUIC_REG_CONTROL3 = 0x0E,
MAX77843_MUIC_REG_CONTROL4 = 0x16,
MAX77843_MUIC_REG_HVCONTROL1 = 0x17,
MAX77843_MUIC_REG_HVCONTROL2 = 0x18,
MAX77843_MUIC_REG_END,
};
enum max77843_irq {
/* Topsys: SYSTEM */
MAX77843_SYS_IRQ_SYSINTSRC_SYSUVLO_INT,
MAX77843_SYS_IRQ_SYSINTSRC_SYSOVLO_INT,
MAX77843_SYS_IRQ_SYSINTSRC_TSHDN_INT,
MAX77843_SYS_IRQ_SYSINTSRC_TM_INT,
/* Charger: CHG_INT */
MAX77843_CHG_IRQ_CHG_INT_BYP_I,
MAX77843_CHG_IRQ_CHG_INT_BATP_I,
MAX77843_CHG_IRQ_CHG_INT_BAT_I,
MAX77843_CHG_IRQ_CHG_INT_CHG_I,
MAX77843_CHG_IRQ_CHG_INT_WCIN_I,
MAX77843_CHG_IRQ_CHG_INT_CHGIN_I,
MAX77843_CHG_IRQ_CHG_INT_AICL_I,
MAX77843_IRQ_NUM,
};
enum max77843_irq_muic {
/* MUIC: INT1 */
MAX77843_MUIC_IRQ_INT1_ADC,
MAX77843_MUIC_IRQ_INT1_ADCERROR,
MAX77843_MUIC_IRQ_INT1_ADC1K,
/* MUIC: INT2 */
MAX77843_MUIC_IRQ_INT2_CHGTYP,
MAX77843_MUIC_IRQ_INT2_CHGDETRUN,
MAX77843_MUIC_IRQ_INT2_DCDTMR,
MAX77843_MUIC_IRQ_INT2_DXOVP,
MAX77843_MUIC_IRQ_INT2_VBVOLT,
/* MUIC: INT3 */
MAX77843_MUIC_IRQ_INT3_VBADC,
MAX77843_MUIC_IRQ_INT3_VDNMON,
MAX77843_MUIC_IRQ_INT3_DNRES,
MAX77843_MUIC_IRQ_INT3_MPNACK,
MAX77843_MUIC_IRQ_INT3_MRXBUFOW,
MAX77843_MUIC_IRQ_INT3_MRXTRF,
MAX77843_MUIC_IRQ_INT3_MRXPERR,
MAX77843_MUIC_IRQ_INT3_MRXRDY,
MAX77843_MUIC_IRQ_NUM,
};
/* MAX77843 interrupts */
#define MAX77843_SYS_IRQ_SYSUVLO_INT BIT(0)
#define MAX77843_SYS_IRQ_SYSOVLO_INT BIT(1)
#define MAX77843_SYS_IRQ_TSHDN_INT BIT(2)
#define MAX77843_SYS_IRQ_TM_INT BIT(3)
/* MAX77843 MAINCTRL1 register */
#define MAINCTRL1_BIASEN_SHIFT 7
#define MAX77843_MAINCTRL1_BIASEN_MASK BIT(MAINCTRL1_BIASEN_SHIFT)
/* MAX77843 MCONFIG register */
#define MCONFIG_MODE_SHIFT 7
#define MCONFIG_MEN_SHIFT 6
#define MCONFIG_PDIV_SHIFT 0
#define MAX77843_MCONFIG_MODE_MASK BIT(MCONFIG_MODE_SHIFT)
#define MAX77843_MCONFIG_MEN_MASK BIT(MCONFIG_MEN_SHIFT)
#define MAX77843_MCONFIG_PDIV_MASK (0x3 << MCONFIG_PDIV_SHIFT)
/* Max77843 charger insterrupts */
#define MAX77843_CHG_BYP_I BIT(0)
#define MAX77843_CHG_BATP_I BIT(2)
#define MAX77843_CHG_BAT_I BIT(3)
#define MAX77843_CHG_CHG_I BIT(4)
#define MAX77843_CHG_WCIN_I BIT(5)
#define MAX77843_CHG_CHGIN_I BIT(6)
#define MAX77843_CHG_AICL_I BIT(7)
/* MAX77843 CHG_INT_OK register */
#define MAX77843_CHG_BYP_OK BIT(0)
#define MAX77843_CHG_BATP_OK BIT(2)
#define MAX77843_CHG_BAT_OK BIT(3)
#define MAX77843_CHG_CHG_OK BIT(4)
#define MAX77843_CHG_WCIN_OK BIT(5)
#define MAX77843_CHG_CHGIN_OK BIT(6)
#define MAX77843_CHG_AICL_OK BIT(7)
/* MAX77843 CHG_DETAILS_00 register */
#define MAX77843_CHG_BAT_DTLS BIT(0)
/* MAX77843 CHG_DETAILS_01 register */
#define MAX77843_CHG_DTLS_MASK 0x0f
#define MAX77843_CHG_PQ_MODE 0x00
#define MAX77843_CHG_CC_MODE 0x01
#define MAX77843_CHG_CV_MODE 0x02
#define MAX77843_CHG_TO_MODE 0x03
#define MAX77843_CHG_DO_MODE 0x04
#define MAX77843_CHG_HT_MODE 0x05
#define MAX77843_CHG_TF_MODE 0x06
#define MAX77843_CHG_TS_MODE 0x07
#define MAX77843_CHG_OFF_MODE 0x08
#define MAX77843_CHG_BAT_DTLS_MASK 0xf0
#define MAX77843_CHG_NO_BAT (0x00 << 4)
#define MAX77843_CHG_LOW_VOLT_BAT (0x01 << 4)
#define MAX77843_CHG_LONG_BAT_TIME (0x02 << 4)
#define MAX77843_CHG_OK_BAT (0x03 << 4)
#define MAX77843_CHG_OK_LOW_VOLT_BAT (0x04 << 4)
#define MAX77843_CHG_OVER_VOLT_BAT (0x05 << 4)
#define MAX77843_CHG_OVER_CURRENT_BAT (0x06 << 4)
/* MAX77843 CHG_CNFG_00 register */
#define MAX77843_CHG_DISABLE 0x00
#define MAX77843_CHG_ENABLE 0x05
#define MAX77843_CHG_MASK 0x01
#define MAX77843_CHG_BUCK_MASK 0x04
/* MAX77843 CHG_CNFG_01 register */
#define MAX77843_CHG_RESTART_THRESHOLD_100 0x00
#define MAX77843_CHG_RESTART_THRESHOLD_150 0x10
#define MAX77843_CHG_RESTART_THRESHOLD_200 0x20
#define MAX77843_CHG_RESTART_THRESHOLD_DISABLE 0x30
/* MAX77843 CHG_CNFG_02 register */
#define MAX77843_CHG_FAST_CHG_CURRENT_MIN 100000
#define MAX77843_CHG_FAST_CHG_CURRENT_MAX 3150000
#define MAX77843_CHG_FAST_CHG_CURRENT_STEP 50000
#define MAX77843_CHG_FAST_CHG_CURRENT_MASK 0x3f
#define MAX77843_CHG_OTG_ILIMIT_500 (0x00 << 6)
#define MAX77843_CHG_OTG_ILIMIT_900 (0x01 << 6)
#define MAX77843_CHG_OTG_ILIMIT_1200 (0x02 << 6)
#define MAX77843_CHG_OTG_ILIMIT_1500 (0x03 << 6)
#define MAX77843_CHG_OTG_ILIMIT_MASK 0xc0
/* MAX77843 CHG_CNFG_03 register */
#define MAX77843_CHG_TOP_OFF_CURRENT_MIN 125000
#define MAX77843_CHG_TOP_OFF_CURRENT_MAX 650000
#define MAX77843_CHG_TOP_OFF_CURRENT_STEP 75000
#define MAX77843_CHG_TOP_OFF_CURRENT_MASK 0x07
/* MAX77843 CHG_CNFG_06 register */
#define MAX77843_CHG_WRITE_CAP_BLOCK 0x10
#define MAX77843_CHG_WRITE_CAP_UNBLOCK 0x0C
/* MAX77843_CHG_CNFG_09_register */
#define MAX77843_CHG_INPUT_CURRENT_LIMIT_MIN 100000
#define MAX77843_CHG_INPUT_CURRENT_LIMIT_MAX 4000000
#define MAX77843_CHG_INPUT_CURRENT_LIMIT_REF 3367000
#define MAX77843_CHG_INPUT_CURRENT_LIMIT_STEP 33000
#define MAX77843_MUIC_ADC BIT(0)
#define MAX77843_MUIC_ADCERROR BIT(2)
#define MAX77843_MUIC_ADC1K BIT(3)
#define MAX77843_MUIC_CHGTYP BIT(0)
#define MAX77843_MUIC_CHGDETRUN BIT(1)
#define MAX77843_MUIC_DCDTMR BIT(2)
#define MAX77843_MUIC_DXOVP BIT(3)
#define MAX77843_MUIC_VBVOLT BIT(4)
#define MAX77843_MUIC_VBADC BIT(0)
#define MAX77843_MUIC_VDNMON BIT(1)
#define MAX77843_MUIC_DNRES BIT(2)
#define MAX77843_MUIC_MPNACK BIT(3)
#define MAX77843_MUIC_MRXBUFOW BIT(4)
#define MAX77843_MUIC_MRXTRF BIT(5)
#define MAX77843_MUIC_MRXPERR BIT(6)
#define MAX77843_MUIC_MRXRDY BIT(7)
/* MAX77843 INTSRCMASK register */
#define MAX77843_INTSRCMASK_CHGR 0
#define MAX77843_INTSRCMASK_SYS 1
#define MAX77843_INTSRCMASK_FG 2
#define MAX77843_INTSRCMASK_MUIC 3
#define MAX77843_INTSRCMASK_CHGR_MASK BIT(MAX77843_INTSRCMASK_CHGR)
#define MAX77843_INTSRCMASK_SYS_MASK BIT(MAX77843_INTSRCMASK_SYS)
#define MAX77843_INTSRCMASK_FG_MASK BIT(MAX77843_INTSRCMASK_FG)
#define MAX77843_INTSRCMASK_MUIC_MASK BIT(MAX77843_INTSRCMASK_MUIC)
#define MAX77843_INTSRC_MASK_MASK \
(MAX77843_INTSRCMASK_MUIC_MASK | MAX77843_INTSRCMASK_FG_MASK | \
MAX77843_INTSRCMASK_SYS_MASK | MAX77843_INTSRCMASK_CHGR_MASK)
/* MAX77843 STATUS register*/
#define STATUS1_ADC_SHIFT 0
#define STATUS1_ADCERROR_SHIFT 6
#define STATUS1_ADC1K_SHIFT 7
#define STATUS2_CHGTYP_SHIFT 0
#define STATUS2_CHGDETRUN_SHIFT 3
#define STATUS2_DCDTMR_SHIFT 4
#define STATUS2_DXOVP_SHIFT 5
#define STATUS2_VBVOLT_SHIFT 6
#define STATUS3_VBADC_SHIFT 0
#define STATUS3_VDNMON_SHIFT 4
#define STATUS3_DNRES_SHIFT 5
#define STATUS3_MPNACK_SHIFT 6
#define MAX77843_MUIC_STATUS1_ADC_MASK (0x1f << STATUS1_ADC_SHIFT)
#define MAX77843_MUIC_STATUS1_ADCERROR_MASK BIT(STATUS1_ADCERROR_SHIFT)
#define MAX77843_MUIC_STATUS1_ADC1K_MASK BIT(STATUS1_ADC1K_SHIFT)
#define MAX77843_MUIC_STATUS2_CHGTYP_MASK (0x7 << STATUS2_CHGTYP_SHIFT)
#define MAX77843_MUIC_STATUS2_CHGDETRUN_MASK BIT(STATUS2_CHGDETRUN_SHIFT)
#define MAX77843_MUIC_STATUS2_DCDTMR_MASK BIT(STATUS2_DCDTMR_SHIFT)
#define MAX77843_MUIC_STATUS2_DXOVP_MASK BIT(STATUS2_DXOVP_SHIFT)
#define MAX77843_MUIC_STATUS2_VBVOLT_MASK BIT(STATUS2_VBVOLT_SHIFT)
#define MAX77843_MUIC_STATUS3_VBADC_MASK (0xf << STATUS3_VBADC_SHIFT)
#define MAX77843_MUIC_STATUS3_VDNMON_MASK BIT(STATUS3_VDNMON_SHIFT)
#define MAX77843_MUIC_STATUS3_DNRES_MASK BIT(STATUS3_DNRES_SHIFT)
#define MAX77843_MUIC_STATUS3_MPNACK_MASK BIT(STATUS3_MPNACK_SHIFT)
/* MAX77843 CONTROL register */
#define CONTROL1_COMP1SW_SHIFT 0
#define CONTROL1_COMP2SW_SHIFT 3
#define CONTROL1_IDBEN_SHIFT 7
#define CONTROL2_LOWPWR_SHIFT 0
#define CONTROL2_ADCEN_SHIFT 1
#define CONTROL2_CPEN_SHIFT 2
#define CONTROL2_ACC_DET_SHIFT 5
#define CONTROL2_USBCPINT_SHIFT 6
#define CONTROL2_RCPS_SHIFT 7
#define CONTROL3_JIGSET_SHIFT 0
#define CONTROL4_ADCDBSET_SHIFT 0
#define CONTROL4_USBAUTO_SHIFT 4
#define CONTROL4_FCTAUTO_SHIFT 5
#define CONTROL4_ADCMODE_SHIFT 6
#define MAX77843_MUIC_CONTROL1_COMP1SW_MASK (0x7 << CONTROL1_COMP1SW_SHIFT)
#define MAX77843_MUIC_CONTROL1_COMP2SW_MASK (0x7 << CONTROL1_COMP2SW_SHIFT)
#define MAX77843_MUIC_CONTROL1_IDBEN_MASK BIT(CONTROL1_IDBEN_SHIFT)
#define MAX77843_MUIC_CONTROL2_LOWPWR_MASK BIT(CONTROL2_LOWPWR_SHIFT)
#define MAX77843_MUIC_CONTROL2_ADCEN_MASK BIT(CONTROL2_ADCEN_SHIFT)
#define MAX77843_MUIC_CONTROL2_CPEN_MASK BIT(CONTROL2_CPEN_SHIFT)
#define MAX77843_MUIC_CONTROL2_ACC_DET_MASK BIT(CONTROL2_ACC_DET_SHIFT)
#define MAX77843_MUIC_CONTROL2_USBCPINT_MASK BIT(CONTROL2_USBCPINT_SHIFT)
#define MAX77843_MUIC_CONTROL2_RCPS_MASK BIT(CONTROL2_RCPS_SHIFT)
#define MAX77843_MUIC_CONTROL3_JIGSET_MASK (0x3 << CONTROL3_JIGSET_SHIFT)
#define MAX77843_MUIC_CONTROL4_ADCDBSET_MASK (0x3 << CONTROL4_ADCDBSET_SHIFT)
#define MAX77843_MUIC_CONTROL4_USBAUTO_MASK BIT(CONTROL4_USBAUTO_SHIFT)
#define MAX77843_MUIC_CONTROL4_FCTAUTO_MASK BIT(CONTROL4_FCTAUTO_SHIFT)
#define MAX77843_MUIC_CONTROL4_ADCMODE_MASK (0x3 << CONTROL4_ADCMODE_SHIFT)
/* MAX77843 switch port */
#define COM_OPEN 0
#define COM_USB 1
#define COM_AUDIO 2
#define COM_UART 3
#define COM_AUX_USB 4
#define COM_AUX_UART 5
#define CONTROL1_COM_SW \
((MAX77843_MUIC_CONTROL1_COMP1SW_MASK | \
MAX77843_MUIC_CONTROL1_COMP2SW_MASK))
#define CONTROL1_SW_OPEN \
((COM_OPEN << CONTROL1_COMP1SW_SHIFT | \
COM_OPEN << CONTROL1_COMP2SW_SHIFT))
#define CONTROL1_SW_USB \
((COM_USB << CONTROL1_COMP1SW_SHIFT | \
COM_USB << CONTROL1_COMP2SW_SHIFT))
#define CONTROL1_SW_AUDIO \
((COM_AUDIO << CONTROL1_COMP1SW_SHIFT | \
COM_AUDIO << CONTROL1_COMP2SW_SHIFT))
#define CONTROL1_SW_UART \
((COM_UART << CONTROL1_COMP1SW_SHIFT | \
COM_UART << CONTROL1_COMP2SW_SHIFT))
#define CONTROL1_SW_AUX_USB \
((COM_AUX_USB << CONTROL1_COMP1SW_SHIFT | \
COM_AUX_USB << CONTROL1_COMP2SW_SHIFT))
#define CONTROL1_SW_AUX_UART \
((COM_AUX_UART << CONTROL1_COMP1SW_SHIFT | \
COM_AUX_UART << CONTROL1_COMP2SW_SHIFT))
#define MAX77843_DISABLE 0
#define MAX77843_ENABLE 1
#define CONTROL4_AUTO_DISABLE \
((MAX77843_DISABLE << CONTROL4_USBAUTO_SHIFT) | \
(MAX77843_DISABLE << CONTROL4_FCTAUTO_SHIFT))
#define CONTROL4_AUTO_ENABLE \
((MAX77843_ENABLE << CONTROL4_USBAUTO_SHIFT) | \
(MAX77843_ENABLE << CONTROL4_FCTAUTO_SHIFT))
/* MAX77843 SAFEOUT LDO Control register */
#define SAFEOUTCTRL_SAFEOUT1_SHIFT 0
#define SAFEOUTCTRL_SAFEOUT2_SHIFT 2
#define SAFEOUTCTRL_ENSAFEOUT1_SHIFT 6
#define SAFEOUTCTRL_ENSAFEOUT2_SHIFT 7
#define MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT1 \
BIT(SAFEOUTCTRL_ENSAFEOUT1_SHIFT)
#define MAX77843_REG_SAFEOUTCTRL_ENSAFEOUT2 \
BIT(SAFEOUTCTRL_ENSAFEOUT2_SHIFT)
#define MAX77843_REG_SAFEOUTCTRL_SAFEOUT1_MASK \
(0x3 << SAFEOUTCTRL_SAFEOUT1_SHIFT)
#define MAX77843_REG_SAFEOUTCTRL_SAFEOUT2_MASK \
(0x3 << SAFEOUTCTRL_SAFEOUT2_SHIFT)
struct max77843 {
struct device *dev;
struct i2c_client *i2c;
struct i2c_client *i2c_chg;
struct i2c_client *i2c_fuel;
struct i2c_client *i2c_muic;
struct regmap *regmap;
struct regmap *regmap_chg;
struct regmap *regmap_fuel;
struct regmap *regmap_muic;
struct regmap_irq_chip_data *irq_data;
struct regmap_irq_chip_data *irq_data_chg;
struct regmap_irq_chip_data *irq_data_fuel;
struct regmap_irq_chip_data *irq_data_muic;
int irq;
};
#endif /* __MAX77843_H__ */

View File

@ -24,7 +24,6 @@ extern int menelaus_set_vaux(unsigned int mV);
extern int menelaus_set_vdcdc(int dcdc, unsigned int mV);
extern int menelaus_set_slot_sel(int enable);
extern int menelaus_get_slot_pin_states(void);
extern int menelaus_set_vcore_sw(unsigned int mV);
extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
#define EN_VPLL_SLEEP (1 << 7)
@ -38,10 +37,4 @@ extern int menelaus_set_vcore_hw(unsigned int roof_mV, unsigned int floor_mV);
extern int menelaus_set_regulator_sleep(int enable, u32 val);
#if defined(CONFIG_ARCH_OMAP2) && defined(CONFIG_MENELAUS)
#define omap_has_menelaus() 1
#else
#define omap_has_menelaus() 0
#endif
#endif

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Flora Fu, MediaTek
*
* 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 in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MFD_MT6397_CORE_H__
#define __MFD_MT6397_CORE_H__
enum mt6397_irq_numbers {
MT6397_IRQ_SPKL_AB = 0,
MT6397_IRQ_SPKR_AB,
MT6397_IRQ_SPKL,
MT6397_IRQ_SPKR,
MT6397_IRQ_BAT_L,
MT6397_IRQ_BAT_H,
MT6397_IRQ_FG_BAT_L,
MT6397_IRQ_FG_BAT_H,
MT6397_IRQ_WATCHDOG,
MT6397_IRQ_PWRKEY,
MT6397_IRQ_THR_L,
MT6397_IRQ_THR_H,
MT6397_IRQ_VBATON_UNDET,
MT6397_IRQ_BVALID_DET,
MT6397_IRQ_CHRDET,
MT6397_IRQ_OV,
MT6397_IRQ_LDO,
MT6397_IRQ_HOMEKEY,
MT6397_IRQ_ACCDET,
MT6397_IRQ_AUDIO,
MT6397_IRQ_RTC,
MT6397_IRQ_PWRKEY_RSTB,
MT6397_IRQ_HDMI_SIFM,
MT6397_IRQ_HDMI_CEC,
MT6397_IRQ_VCA15,
MT6397_IRQ_VSRMCA15,
MT6397_IRQ_VCORE,
MT6397_IRQ_VGPU,
MT6397_IRQ_VIO18,
MT6397_IRQ_VPCA7,
MT6397_IRQ_VSRMCA7,
MT6397_IRQ_VDRM,
MT6397_IRQ_NR,
};
struct mt6397_chip {
struct device *dev;
struct regmap *regmap;
int irq;
struct irq_domain *irq_domain;
struct mutex irqlock;
u16 irq_masks_cur[2];
u16 irq_masks_cache[2];
};
#endif /* __MFD_MT6397_CORE_H__ */

View File

@ -0,0 +1,362 @@
/*
* Copyright (c) 2014 MediaTek Inc.
* Author: Flora Fu, MediaTek
*
* 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 in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __MFD_MT6397_REGISTERS_H__
#define __MFD_MT6397_REGISTERS_H__
/* PMIC Registers */
#define MT6397_CID 0x0100
#define MT6397_TOP_CKPDN 0x0102
#define MT6397_TOP_CKPDN_SET 0x0104
#define MT6397_TOP_CKPDN_CLR 0x0106
#define MT6397_TOP_CKPDN2 0x0108
#define MT6397_TOP_CKPDN2_SET 0x010A
#define MT6397_TOP_CKPDN2_CLR 0x010C
#define MT6397_TOP_GPIO_CKPDN 0x010E
#define MT6397_TOP_RST_CON 0x0114
#define MT6397_WRP_CKPDN 0x011A
#define MT6397_WRP_RST_CON 0x0120
#define MT6397_TOP_RST_MISC 0x0126
#define MT6397_TOP_CKCON1 0x0128
#define MT6397_TOP_CKCON2 0x012A
#define MT6397_TOP_CKTST1 0x012C
#define MT6397_TOP_CKTST2 0x012E
#define MT6397_OC_DEG_EN 0x0130
#define MT6397_OC_CTL0 0x0132
#define MT6397_OC_CTL1 0x0134
#define MT6397_OC_CTL2 0x0136
#define MT6397_INT_RSV 0x0138
#define MT6397_TEST_CON0 0x013A
#define MT6397_TEST_CON1 0x013C
#define MT6397_STATUS0 0x013E
#define MT6397_STATUS1 0x0140
#define MT6397_PGSTATUS 0x0142
#define MT6397_CHRSTATUS 0x0144
#define MT6397_OCSTATUS0 0x0146
#define MT6397_OCSTATUS1 0x0148
#define MT6397_OCSTATUS2 0x014A
#define MT6397_HDMI_PAD_IE 0x014C
#define MT6397_TEST_OUT_L 0x014E
#define MT6397_TEST_OUT_H 0x0150
#define MT6397_TDSEL_CON 0x0152
#define MT6397_RDSEL_CON 0x0154
#define MT6397_GPIO_SMT_CON0 0x0156
#define MT6397_GPIO_SMT_CON1 0x0158
#define MT6397_GPIO_SMT_CON2 0x015A
#define MT6397_GPIO_SMT_CON3 0x015C
#define MT6397_DRV_CON0 0x015E
#define MT6397_DRV_CON1 0x0160
#define MT6397_DRV_CON2 0x0162
#define MT6397_DRV_CON3 0x0164
#define MT6397_DRV_CON4 0x0166
#define MT6397_DRV_CON5 0x0168
#define MT6397_DRV_CON6 0x016A
#define MT6397_DRV_CON7 0x016C
#define MT6397_DRV_CON8 0x016E
#define MT6397_DRV_CON9 0x0170
#define MT6397_DRV_CON10 0x0172
#define MT6397_DRV_CON11 0x0174
#define MT6397_DRV_CON12 0x0176
#define MT6397_INT_CON0 0x0178
#define MT6397_INT_CON1 0x017E
#define MT6397_INT_STATUS0 0x0184
#define MT6397_INT_STATUS1 0x0186
#define MT6397_FQMTR_CON0 0x0188
#define MT6397_FQMTR_CON1 0x018A
#define MT6397_FQMTR_CON2 0x018C
#define MT6397_EFUSE_DOUT_0_15 0x01C4
#define MT6397_EFUSE_DOUT_16_31 0x01C6
#define MT6397_EFUSE_DOUT_32_47 0x01C8
#define MT6397_EFUSE_DOUT_48_63 0x01CA
#define MT6397_SPI_CON 0x01CC
#define MT6397_TOP_CKPDN3 0x01CE
#define MT6397_TOP_CKCON3 0x01D4
#define MT6397_EFUSE_DOUT_64_79 0x01D6
#define MT6397_EFUSE_DOUT_80_95 0x01D8
#define MT6397_EFUSE_DOUT_96_111 0x01DA
#define MT6397_EFUSE_DOUT_112_127 0x01DC
#define MT6397_EFUSE_DOUT_128_143 0x01DE
#define MT6397_EFUSE_DOUT_144_159 0x01E0
#define MT6397_EFUSE_DOUT_160_175 0x01E2
#define MT6397_EFUSE_DOUT_176_191 0x01E4
#define MT6397_EFUSE_DOUT_192_207 0x01E6
#define MT6397_EFUSE_DOUT_208_223 0x01E8
#define MT6397_EFUSE_DOUT_224_239 0x01EA
#define MT6397_EFUSE_DOUT_240_255 0x01EC
#define MT6397_EFUSE_DOUT_256_271 0x01EE
#define MT6397_EFUSE_DOUT_272_287 0x01F0
#define MT6397_EFUSE_DOUT_288_300 0x01F2
#define MT6397_EFUSE_DOUT_304_319 0x01F4
#define MT6397_BUCK_CON0 0x0200
#define MT6397_BUCK_CON1 0x0202
#define MT6397_BUCK_CON2 0x0204
#define MT6397_BUCK_CON3 0x0206
#define MT6397_BUCK_CON4 0x0208
#define MT6397_BUCK_CON5 0x020A
#define MT6397_BUCK_CON6 0x020C
#define MT6397_BUCK_CON7 0x020E
#define MT6397_BUCK_CON8 0x0210
#define MT6397_BUCK_CON9 0x0212
#define MT6397_VCA15_CON0 0x0214
#define MT6397_VCA15_CON1 0x0216
#define MT6397_VCA15_CON2 0x0218
#define MT6397_VCA15_CON3 0x021A
#define MT6397_VCA15_CON4 0x021C
#define MT6397_VCA15_CON5 0x021E
#define MT6397_VCA15_CON6 0x0220
#define MT6397_VCA15_CON7 0x0222
#define MT6397_VCA15_CON8 0x0224
#define MT6397_VCA15_CON9 0x0226
#define MT6397_VCA15_CON10 0x0228
#define MT6397_VCA15_CON11 0x022A
#define MT6397_VCA15_CON12 0x022C
#define MT6397_VCA15_CON13 0x022E
#define MT6397_VCA15_CON14 0x0230
#define MT6397_VCA15_CON15 0x0232
#define MT6397_VCA15_CON16 0x0234
#define MT6397_VCA15_CON17 0x0236
#define MT6397_VCA15_CON18 0x0238
#define MT6397_VSRMCA15_CON0 0x023A
#define MT6397_VSRMCA15_CON1 0x023C
#define MT6397_VSRMCA15_CON2 0x023E
#define MT6397_VSRMCA15_CON3 0x0240
#define MT6397_VSRMCA15_CON4 0x0242
#define MT6397_VSRMCA15_CON5 0x0244
#define MT6397_VSRMCA15_CON6 0x0246
#define MT6397_VSRMCA15_CON7 0x0248
#define MT6397_VSRMCA15_CON8 0x024A
#define MT6397_VSRMCA15_CON9 0x024C
#define MT6397_VSRMCA15_CON10 0x024E
#define MT6397_VSRMCA15_CON11 0x0250
#define MT6397_VSRMCA15_CON12 0x0252
#define MT6397_VSRMCA15_CON13 0x0254
#define MT6397_VSRMCA15_CON14 0x0256
#define MT6397_VSRMCA15_CON15 0x0258
#define MT6397_VSRMCA15_CON16 0x025A
#define MT6397_VSRMCA15_CON17 0x025C
#define MT6397_VSRMCA15_CON18 0x025E
#define MT6397_VSRMCA15_CON19 0x0260
#define MT6397_VSRMCA15_CON20 0x0262
#define MT6397_VSRMCA15_CON21 0x0264
#define MT6397_VCORE_CON0 0x0266
#define MT6397_VCORE_CON1 0x0268
#define MT6397_VCORE_CON2 0x026A
#define MT6397_VCORE_CON3 0x026C
#define MT6397_VCORE_CON4 0x026E
#define MT6397_VCORE_CON5 0x0270
#define MT6397_VCORE_CON6 0x0272
#define MT6397_VCORE_CON7 0x0274
#define MT6397_VCORE_CON8 0x0276
#define MT6397_VCORE_CON9 0x0278
#define MT6397_VCORE_CON10 0x027A
#define MT6397_VCORE_CON11 0x027C
#define MT6397_VCORE_CON12 0x027E
#define MT6397_VCORE_CON13 0x0280
#define MT6397_VCORE_CON14 0x0282
#define MT6397_VCORE_CON15 0x0284
#define MT6397_VCORE_CON16 0x0286
#define MT6397_VCORE_CON17 0x0288
#define MT6397_VCORE_CON18 0x028A
#define MT6397_VGPU_CON0 0x028C
#define MT6397_VGPU_CON1 0x028E
#define MT6397_VGPU_CON2 0x0290
#define MT6397_VGPU_CON3 0x0292
#define MT6397_VGPU_CON4 0x0294
#define MT6397_VGPU_CON5 0x0296
#define MT6397_VGPU_CON6 0x0298
#define MT6397_VGPU_CON7 0x029A
#define MT6397_VGPU_CON8 0x029C
#define MT6397_VGPU_CON9 0x029E
#define MT6397_VGPU_CON10 0x02A0
#define MT6397_VGPU_CON11 0x02A2
#define MT6397_VGPU_CON12 0x02A4
#define MT6397_VGPU_CON13 0x02A6
#define MT6397_VGPU_CON14 0x02A8
#define MT6397_VGPU_CON15 0x02AA
#define MT6397_VGPU_CON16 0x02AC
#define MT6397_VGPU_CON17 0x02AE
#define MT6397_VGPU_CON18 0x02B0
#define MT6397_VIO18_CON0 0x0300
#define MT6397_VIO18_CON1 0x0302
#define MT6397_VIO18_CON2 0x0304
#define MT6397_VIO18_CON3 0x0306
#define MT6397_VIO18_CON4 0x0308
#define MT6397_VIO18_CON5 0x030A
#define MT6397_VIO18_CON6 0x030C
#define MT6397_VIO18_CON7 0x030E
#define MT6397_VIO18_CON8 0x0310
#define MT6397_VIO18_CON9 0x0312
#define MT6397_VIO18_CON10 0x0314
#define MT6397_VIO18_CON11 0x0316
#define MT6397_VIO18_CON12 0x0318
#define MT6397_VIO18_CON13 0x031A
#define MT6397_VIO18_CON14 0x031C
#define MT6397_VIO18_CON15 0x031E
#define MT6397_VIO18_CON16 0x0320
#define MT6397_VIO18_CON17 0x0322
#define MT6397_VIO18_CON18 0x0324
#define MT6397_VPCA7_CON0 0x0326
#define MT6397_VPCA7_CON1 0x0328
#define MT6397_VPCA7_CON2 0x032A
#define MT6397_VPCA7_CON3 0x032C
#define MT6397_VPCA7_CON4 0x032E
#define MT6397_VPCA7_CON5 0x0330
#define MT6397_VPCA7_CON6 0x0332
#define MT6397_VPCA7_CON7 0x0334
#define MT6397_VPCA7_CON8 0x0336
#define MT6397_VPCA7_CON9 0x0338
#define MT6397_VPCA7_CON10 0x033A
#define MT6397_VPCA7_CON11 0x033C
#define MT6397_VPCA7_CON12 0x033E
#define MT6397_VPCA7_CON13 0x0340
#define MT6397_VPCA7_CON14 0x0342
#define MT6397_VPCA7_CON15 0x0344
#define MT6397_VPCA7_CON16 0x0346
#define MT6397_VPCA7_CON17 0x0348
#define MT6397_VPCA7_CON18 0x034A
#define MT6397_VSRMCA7_CON0 0x034C
#define MT6397_VSRMCA7_CON1 0x034E
#define MT6397_VSRMCA7_CON2 0x0350
#define MT6397_VSRMCA7_CON3 0x0352
#define MT6397_VSRMCA7_CON4 0x0354
#define MT6397_VSRMCA7_CON5 0x0356
#define MT6397_VSRMCA7_CON6 0x0358
#define MT6397_VSRMCA7_CON7 0x035A
#define MT6397_VSRMCA7_CON8 0x035C
#define MT6397_VSRMCA7_CON9 0x035E
#define MT6397_VSRMCA7_CON10 0x0360
#define MT6397_VSRMCA7_CON11 0x0362
#define MT6397_VSRMCA7_CON12 0x0364
#define MT6397_VSRMCA7_CON13 0x0366
#define MT6397_VSRMCA7_CON14 0x0368
#define MT6397_VSRMCA7_CON15 0x036A
#define MT6397_VSRMCA7_CON16 0x036C
#define MT6397_VSRMCA7_CON17 0x036E
#define MT6397_VSRMCA7_CON18 0x0370
#define MT6397_VSRMCA7_CON19 0x0372
#define MT6397_VSRMCA7_CON20 0x0374
#define MT6397_VSRMCA7_CON21 0x0376
#define MT6397_VDRM_CON0 0x0378
#define MT6397_VDRM_CON1 0x037A
#define MT6397_VDRM_CON2 0x037C
#define MT6397_VDRM_CON3 0x037E
#define MT6397_VDRM_CON4 0x0380
#define MT6397_VDRM_CON5 0x0382
#define MT6397_VDRM_CON6 0x0384
#define MT6397_VDRM_CON7 0x0386
#define MT6397_VDRM_CON8 0x0388
#define MT6397_VDRM_CON9 0x038A
#define MT6397_VDRM_CON10 0x038C
#define MT6397_VDRM_CON11 0x038E
#define MT6397_VDRM_CON12 0x0390
#define MT6397_VDRM_CON13 0x0392
#define MT6397_VDRM_CON14 0x0394
#define MT6397_VDRM_CON15 0x0396
#define MT6397_VDRM_CON16 0x0398
#define MT6397_VDRM_CON17 0x039A
#define MT6397_VDRM_CON18 0x039C
#define MT6397_BUCK_K_CON0 0x039E
#define MT6397_BUCK_K_CON1 0x03A0
#define MT6397_ANALDO_CON0 0x0400
#define MT6397_ANALDO_CON1 0x0402
#define MT6397_ANALDO_CON2 0x0404
#define MT6397_ANALDO_CON3 0x0406
#define MT6397_ANALDO_CON4 0x0408
#define MT6397_ANALDO_CON5 0x040A
#define MT6397_ANALDO_CON6 0x040C
#define MT6397_ANALDO_CON7 0x040E
#define MT6397_DIGLDO_CON0 0x0410
#define MT6397_DIGLDO_CON1 0x0412
#define MT6397_DIGLDO_CON2 0x0414
#define MT6397_DIGLDO_CON3 0x0416
#define MT6397_DIGLDO_CON4 0x0418
#define MT6397_DIGLDO_CON5 0x041A
#define MT6397_DIGLDO_CON6 0x041C
#define MT6397_DIGLDO_CON7 0x041E
#define MT6397_DIGLDO_CON8 0x0420
#define MT6397_DIGLDO_CON9 0x0422
#define MT6397_DIGLDO_CON10 0x0424
#define MT6397_DIGLDO_CON11 0x0426
#define MT6397_DIGLDO_CON12 0x0428
#define MT6397_DIGLDO_CON13 0x042A
#define MT6397_DIGLDO_CON14 0x042C
#define MT6397_DIGLDO_CON15 0x042E
#define MT6397_DIGLDO_CON16 0x0430
#define MT6397_DIGLDO_CON17 0x0432
#define MT6397_DIGLDO_CON18 0x0434
#define MT6397_DIGLDO_CON19 0x0436
#define MT6397_DIGLDO_CON20 0x0438
#define MT6397_DIGLDO_CON21 0x043A
#define MT6397_DIGLDO_CON22 0x043C
#define MT6397_DIGLDO_CON23 0x043E
#define MT6397_DIGLDO_CON24 0x0440
#define MT6397_DIGLDO_CON25 0x0442
#define MT6397_DIGLDO_CON26 0x0444
#define MT6397_DIGLDO_CON27 0x0446
#define MT6397_DIGLDO_CON28 0x0448
#define MT6397_DIGLDO_CON29 0x044A
#define MT6397_DIGLDO_CON30 0x044C
#define MT6397_DIGLDO_CON31 0x044E
#define MT6397_DIGLDO_CON32 0x0450
#define MT6397_DIGLDO_CON33 0x045A
#define MT6397_SPK_CON0 0x0600
#define MT6397_SPK_CON1 0x0602
#define MT6397_SPK_CON2 0x0604
#define MT6397_SPK_CON3 0x0606
#define MT6397_SPK_CON4 0x0608
#define MT6397_SPK_CON5 0x060A
#define MT6397_SPK_CON6 0x060C
#define MT6397_SPK_CON7 0x060E
#define MT6397_SPK_CON8 0x0610
#define MT6397_SPK_CON9 0x0612
#define MT6397_SPK_CON10 0x0614
#define MT6397_SPK_CON11 0x0616
#define MT6397_AUDDAC_CON0 0x0700
#define MT6397_AUDBUF_CFG0 0x0702
#define MT6397_AUDBUF_CFG1 0x0704
#define MT6397_AUDBUF_CFG2 0x0706
#define MT6397_AUDBUF_CFG3 0x0708
#define MT6397_AUDBUF_CFG4 0x070A
#define MT6397_IBIASDIST_CFG0 0x070C
#define MT6397_AUDACCDEPOP_CFG0 0x070E
#define MT6397_AUD_IV_CFG0 0x0710
#define MT6397_AUDCLKGEN_CFG0 0x0712
#define MT6397_AUDLDO_CFG0 0x0714
#define MT6397_AUDLDO_CFG1 0x0716
#define MT6397_AUDNVREGGLB_CFG0 0x0718
#define MT6397_AUD_NCP0 0x071A
#define MT6397_AUDPREAMP_CON0 0x071C
#define MT6397_AUDADC_CON0 0x071E
#define MT6397_AUDADC_CON1 0x0720
#define MT6397_AUDADC_CON2 0x0722
#define MT6397_AUDADC_CON3 0x0724
#define MT6397_AUDADC_CON4 0x0726
#define MT6397_AUDADC_CON5 0x0728
#define MT6397_AUDADC_CON6 0x072A
#define MT6397_AUDDIGMI_CON0 0x072C
#define MT6397_AUDLSBUF_CON0 0x072E
#define MT6397_AUDLSBUF_CON1 0x0730
#define MT6397_AUDENCSPARE_CON0 0x0732
#define MT6397_AUDENCCLKSQ_CON0 0x0734
#define MT6397_AUDPREAMPGAIN_CON0 0x0736
#define MT6397_ZCD_CON0 0x0738
#define MT6397_ZCD_CON1 0x073A
#define MT6397_ZCD_CON2 0x073C
#define MT6397_ZCD_CON3 0x073E
#define MT6397_ZCD_CON4 0x0740
#define MT6397_ZCD_CON5 0x0742
#define MT6397_NCP_CLKDIV_CON0 0x0744
#define MT6397_NCP_CLKDIV_CON1 0x0746
#endif /* __MFD_MT6397_REGISTERS_H__ */

View File

@ -156,6 +156,9 @@ enum rk808_reg {
#define BUCK2_RATE_MASK (3 << 3)
#define MASK_ALL 0xff
#define BUCK_UV_ACT_MASK 0x0f
#define BUCK_UV_ACT_DISABLE 0
#define SWITCH2_EN BIT(6)
#define SWITCH1_EN BIT(5)
#define DEV_OFF_RST BIT(3)

File diff suppressed because it is too large Load Diff

View File

@ -58,13 +58,7 @@ enum sec_device_type {
* @irq_base: Base IRQ number for device, required for IRQs
* @irq: Generic IRQ number for device
* @irq_data: Runtime data structure for IRQ controller
* @ono: Power onoff IRQ number for s5m87xx
* @wakeup: Whether or not this is a wakeup device
* @wtsr_smpl: Whether or not to enable in RTC driver the Watchdog
* Timer Software Reset (registers set to default value
* after PWRHOLD falling) and Sudden Momentary Power Loss
* (PMIC will enter power on sequence after short drop in
* VBATT voltage).
*/
struct sec_pmic_dev {
struct device *dev;
@ -77,9 +71,7 @@ struct sec_pmic_dev {
int irq;
struct regmap_irq_chip_data *irq_data;
int ono;
bool wakeup;
bool wtsr_smpl;
};
int sec_irq_init(struct sec_pmic_dev *sec_pmic);
@ -95,7 +87,6 @@ struct sec_platform_data {
int irq_base;
int (*cfg_pmic_irq)(void);
int ono;
bool wakeup;
bool buck_voltage_lock;

View File

@ -74,8 +74,8 @@ enum s2mps11_irq {
S2MPS11_IRQ_MRB,
S2MPS11_IRQ_RTC60S,
S2MPS11_IRQ_RTCA0,
S2MPS11_IRQ_RTCA1,
S2MPS11_IRQ_RTCA0,
S2MPS11_IRQ_SMPL,
S2MPS11_IRQ_RTC1S,
S2MPS11_IRQ_WTSR,

View File

@ -0,0 +1,31 @@
/*
* sky81452.h SKY81452 MFD driver
*
* Copyright 2014 Skyworks Solutions Inc.
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.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 in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SKY81452_H
#define _SKY81452_H
#include <linux/platform_data/sky81452-backlight.h>
#include <linux/regulator/machine.h>
struct sky81452_platform_data {
struct sky81452_bl_platform_data *bl_pdata;
struct regulator_init_data *regulator_init_data;
};
#endif

View File

@ -128,6 +128,7 @@
/* Sequencer Status */
#define SEQ_STATUS BIT(5)
#define CHARGE_STEP 0x11
#define ADC_CLK 3000000
#define TOTAL_STEPS 16

View File

@ -0,0 +1,46 @@
/*
* sky81452.h SKY81452 backlight driver
*
* Copyright 2014 Skyworks Solutions Inc.
* Author : Gyungoh Yoo <jack.yoo@skyworksinc.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 in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _SKY81452_BACKLIGHT_H
#define _SKY81452_BACKLIGHT_H
/**
* struct sky81452_platform_data
* @name: backlight driver name.
If it is not defined, default name is lcd-backlight.
* @gpio_enable:GPIO number which control EN pin
* @enable: Enable mask for current sink channel 1, 2, 3, 4, 5 and 6.
* @ignore_pwm: true if DPWMI should be ignored.
* @dpwm_mode: true is DPWM dimming mode, otherwise Analog dimming mode.
* @phase_shift:true is phase shift mode.
* @short_detecion_threshold: It should be one of 4, 5, 6 and 7V.
* @boost_current_limit: It should be one of 2300, 2750mA.
*/
struct sky81452_bl_platform_data {
const char *name;
int gpio_enable;
unsigned int enable;
bool ignore_pwm;
bool dpwm_mode;
bool phase_shift;
unsigned int short_detection_threshold;
unsigned int boost_current_limit;
};
#endif

View File

@ -19,7 +19,6 @@
#include <sound/tlv.h>
#include <linux/mfd/arizona/core.h>
#include <linux/mfd/arizona/gpio.h>
#include <linux/mfd/arizona/registers.h>
#include "arizona.h"
@ -281,6 +280,7 @@ int arizona_init_gpio(struct snd_soc_codec *codec)
switch (arizona->type) {
case WM5110:
case WM8280:
snd_soc_dapm_disable_pin(&codec->dapm, "DRC2 Signal Activity");
break;
default:
@ -1729,6 +1729,7 @@ static int arizona_calc_fratio(struct arizona_fll *fll,
switch (fll->arizona->type) {
case WM5110:
case WM8280:
if (fll->arizona->rev < 3 || sync)
return init_ratio;
break;