Pull MFD updates from Lee Jones: "New Drivers: - Add support for Maxim MAX77714 PMIC Removed Drivers: - Remove support for ST-Ericsson AB8500 DebugFS New Device Support: - Add support for Silergy SY7636A to Simple MFD I2C - Add support for MediaTek MT6366 PMIC to MT6358 IRQ - Add support for Charger to Intel PMIC CRC - Add support for Raptor Lake to Intel LPSS PCI New Functionality: - Add support for Reboot to Rockchip RK808 Fix-ups: - Device Tree changes (includcing YAML conversion) for silergy,sy7636a, maxim,max77843, google,cros-ec, maxim,max14577, maxim,max77802, maxim,max77714, qcom,tcsr, qcom,spmi-pmic, stericsson,ab8500, stericsson,db8500-prcmu, samsung,exynos5433-lpass, mt6397, syscon, brcm,cru - Visible to menuconfig; simple-mfd-i2c - Clean-up or clarify code; max77686, intel_soc_pmic_crc - Improve error handling; mc13xxx-core, stmfx, asic3 - Pass device information to child devices; iqs62x, intel-lpss-acpi - Individually identify IRQ domains; intel_soc_pmic_core - Remove superfluous code; dbx500-prcmu, exynos-lpass - Staticify and constify; arizona-i2c - Mark sometimes used data as __maybe_unused; atmel-flexcom - Account for different ACPI tables on AOSP/Windows platforms; arizona-spi - Use provided (platform) APIs; ab8500-core - Trivial (whitespace, spelling); rohm-bd9576" * tag 'mfd-next-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (50 commits) dt-bindings: mfd: syscon: Add microchip,lan966x-cpu-syscon compatible mfd: bd9576: fix typos in comments mfd: Use platform_get_irq() to get the interrupt mfd: db8500-prcmu: Remove unused inline function mfd: arizona-spi: Add Android board ACPI table handling mfd: arizona-spi: Split Windows ACPI init code into its own function mfd: asic3: Add missing iounmap() on error asic3_mfd_probe MAINTAINERS: Rectify entry for ROHM MULTIFUNCTION BD9571MWV-M PMIC DEVICE DRIVERS mfd: intel-lpss: Provide an SSP type to the driver dt-bindings: mfd: brcm,cru: Rename pinctrl node dt-bindings: Add compatibles for undocumented trivial syscons mfd: atmel-flexcom: Fix compilation warning dt-bindings: mfd: Add compatible for the MediaTek MT6366 PMIC dt-bindings: mfd: samsung,exynos5433-lpass: Convert to dtschema mfd: exynos-lpass: Drop unneeded syscon.h include mfd: intel-lpss: Add Intel Raptor Lake PCH-S PCI IDs mfd: ab8500: Drop debugfs module mfd: sta2x11: Use GFP_KERNEL instead of GFP_ATOMIC mfd: ab8500: Rewrite bindings in YAML mfd: qcom-spmi-pmic: Add pm8953 compatible ...
Unified · Split
| @@ -0,0 +1,105 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/leds/maxim,max77693.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Maxim MAX77693 MicroUSB and Companion Power Management IC LEDs | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated | ||
| 14 | Circuit (MUIC). | ||
| 15 | |||
| 16 | There are two LED outputs available - FLED1 and FLED2. Each of them can | ||
| 17 | control a separate LED or they can be connected together to double the | ||
| 18 | maximum current for a single connected LED. One LED is represented by one | ||
| 19 | child node. | ||
| 20 | |||
| 21 | See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for | ||
| 22 | additional information and example. | ||
| 23 | |||
| 24 | properties: | ||
| 25 | compatible: | ||
| 26 | const: maxim,max77693-led | ||
| 27 | |||
| 28 | maxim,boost-mode: | ||
| 29 | description: | ||
| 30 | In boost mode the device can produce up to 1.2A of total current on both | ||
| 31 | outputs. The maximum current on each output is reduced to 625mA then. If | ||
| 32 | not enabled explicitly, boost setting defaults to LEDS_BOOST_FIXED in | ||
| 33 | case both current sources are used. | ||
| 34 | See LEDS_BOOST_* in include/dt-bindings/leds/common.h. | ||
| 35 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 36 | enum: [0, 1, 2] | ||
| 37 | |||
| 38 | maxim,boost-mvout: | ||
| 39 | description: | | ||
| 40 | Output voltage of the boost module in millivolts. | ||
| 41 | Valid values: 3300 - 5500, step by 25 (rounded down) | ||
| 42 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 43 | minimum: 3300 | ||
| 44 | maximum: 5500 | ||
| 45 | default: 3300 | ||
| 46 | |||
| 47 | maxim,mvsys-min: | ||
| 48 | description: | | ||
| 49 | Low input voltage level in millivolts. Flash is not fired if chip | ||
| 50 | estimates that system voltage could drop below this level due to flash | ||
| 51 | power consumption. | ||
| 52 | Valid values: 2400 - 3400, step by 33 (rounded down) | ||
| 53 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 54 | minimum: 2400 | ||
| 55 | maximum: 3400 | ||
| 56 | default: 2400 | ||
| 57 | |||
| 58 | patternProperties: | ||
| 59 | "^([a-z]+-)?led[01]?$": | ||
| 60 | type: object | ||
| 61 | $ref: common.yaml# | ||
| 62 | unevaluatedProperties: false | ||
| 63 | |||
| 64 | properties: | ||
| 65 | led-sources: | ||
| 66 | allOf: | ||
| 67 | - minItems: 1 | ||
| 68 | maxItems: 2 | ||
| 69 | items: | ||
| 70 | minimum: 0 | ||
| 71 | maximum: 1 | ||
| 72 | |||
| 73 | led-max-microamp: | ||
| 74 | description: | | ||
| 75 | Valid values for a LED connected to one FLED output: | ||
| 76 | 15625 - 250000, step by 15625 (rounded down) | ||
| 77 | Valid values for a LED connected to both FLED outputs: | ||
| 78 | 15625 - 500000, step by 15625 (rounded down) | ||
| 79 | |||
| 80 | flash-max-microamp: | ||
| 81 | description: | | ||
| 82 | Valid values for a single LED connected to one FLED output | ||
| 83 | (boost mode must be turned off): | ||
| 84 | 15625 - 1000000, step by 15625 (rounded down) | ||
| 85 | Valid values for a single LED connected to both FLED outputs: | ||
| 86 | 15625 - 1250000, step by 15625 (rounded down) | ||
| 87 | Valid values for two LEDs case: | ||
| 88 | 15625 - 625000, step by 15625 (rounded down) | ||
| 89 | |||
| 90 | flash-max-timeout-us: | ||
| 91 | description: | | ||
| 92 | Valid values: 62500 - 1000000, step by 62500 (rounded down) | ||
| 93 | minimum: 62500 | ||
| 94 | maximum: 1000000 | ||
| 95 | |||
| 96 | required: | ||
| 97 | - flash-max-microamp | ||
| 98 | - flash-max-timeout-us | ||
| 99 | - led-max-microamp | ||
| 100 | - led-sources | ||
| 101 | |||
| 102 | required: | ||
| 103 | - compatible | ||
| 104 | |||
| 105 | additionalProperties: false | ||
| @@ -1,282 +0,0 @@ | |||
| 1 | * AB8500 Multi-Functional Device (MFD) | ||
| 2 | |||
| 3 | Required parent device properties: | ||
| 4 | - compatible : contains "stericsson,ab8500" or "stericsson,ab8505"; | ||
| 5 | - interrupts : contains the IRQ line for the AB8500 | ||
| 6 | - interrupt-controller : describes the AB8500 as an Interrupt Controller (has its own domain) | ||
| 7 | - #interrupt-cells : should be 2, for 2-cell format | ||
| 8 | - The first cell is the AB8500 local IRQ number | ||
| 9 | - The second cell is used to specify optional parameters | ||
| 10 | - bits[3:0] trigger type and level flags: | ||
| 11 | 1 = low-to-high edge triggered | ||
| 12 | 2 = high-to-low edge triggered | ||
| 13 | 4 = active high level-sensitive | ||
| 14 | 8 = active low level-sensitive | ||
| 15 | |||
| 16 | The AB8500 consists of a large and varied group of sub-devices: | ||
| 17 | |||
| 18 | Device IRQ Names Supply Names Description | ||
| 19 | ------ --------- ------------ ----------- | ||
| 20 | ab8500-bm : : : Battery Manager | ||
| 21 | ab8500-btemp : : : Battery Temperature | ||
| 22 | ab8500-charger : : : Battery Charger | ||
| 23 | ab8500-codec : : : Audio Codec | ||
| 24 | ab8500-fg : : vddadc : Fuel Gauge | ||
| 25 | : NCONV_ACCU : : Accumulate N Sample Conversion | ||
| 26 | : BATT_OVV : : Battery Over Voltage | ||
| 27 | : LOW_BAT_F : : LOW threshold battery voltage | ||
| 28 | : CC_INT_CALIB : : Coulomb Counter Internal Calibration | ||
| 29 | : CCEOC : : Coulomb Counter End of Conversion | ||
| 30 | ab8500-btemp : : vtvout : Battery Temperature | ||
| 31 | : BAT_CTRL_INDB : : Battery Removal Indicator | ||
| 32 | : BTEMP_LOW : : Btemp < BtempLow, if battery temperature is lower than -10°C | ||
| 33 | : BTEMP_LOW_MEDIUM : : BtempLow < Btemp < BtempMedium,if battery temperature is between -10 and 0°C | ||
| 34 | : BTEMP_MEDIUM_HIGH : : BtempMedium < Btemp < BtempHigh,if battery temperature is between 0°C and MaxTemp | ||
| 35 | : BTEMP_HIGH : : Btemp > BtempHigh, if battery temperature is higher than MaxTemp | ||
| 36 | ab8500-charger : : vddadc : Charger interface | ||
| 37 | : MAIN_CH_UNPLUG_DET : : main charger unplug detection management (not in 8505) | ||
| 38 | : MAIN_CHARGE_PLUG_DET : : main charger plug detection management (not in 8505) | ||
| 39 | : MAIN_EXT_CH_NOT_OK : : main charger not OK | ||
| 40 | : MAIN_CH_TH_PROT_R : : Die temp is above main charger | ||
| 41 | : MAIN_CH_TH_PROT_F : : Die temp is below main charger | ||
| 42 | : VBUS_DET_F : : VBUS falling detected | ||
| 43 | : VBUS_DET_R : : VBUS rising detected | ||
| 44 | : USB_LINK_STATUS : : USB link status has changed | ||
| 45 | : USB_CH_TH_PROT_R : : Die temp is above usb charger | ||
| 46 | : USB_CH_TH_PROT_F : : Die temp is below usb charger | ||
| 47 | : USB_CHARGER_NOT_OKR : : allowed USB charger not ok detection | ||
| 48 | : VBUS_OVV : : Overvoltage on Vbus ball detected (USB charge is stopped) | ||
| 49 | : CH_WD_EXP : : Charger watchdog detected | ||
| 50 | ab8500-gpadc : HW_CONV_END : vddadc : Analogue to Digital Converter | ||
| 51 | SW_CONV_END : : | ||
| 52 | ab8500-gpio : : : GPIO Controller (AB8500) | ||
| 53 | ab8505-gpio : : : GPIO Controller (AB8505) | ||
| 54 | ab8500-ponkey : ONKEY_DBF : : Power-on Key | ||
| 55 | ONKEY_DBR : : | ||
| 56 | ab8500-pwm : : : Pulse Width Modulator | ||
| 57 | ab8500-regulator : : : Regulators (AB8500) | ||
| 58 | ab8505-regulator : : : Regulators (AB8505) | ||
| 59 | ab8500-rtc : 60S : : Real Time Clock | ||
| 60 | : ALARM : : | ||
| 61 | ab8500-sysctrl : : : System Control | ||
| 62 | ab8500-usb : ID_WAKEUP_R : vddulpivio18 : Universal Serial Bus | ||
| 63 | : ID_WAKEUP_F : v-ape : | ||
| 64 | : VBUS_DET_F : musb_1v8 : | ||
| 65 | : VBUS_DET_R : : | ||
| 66 | : USB_LINK_STATUS : : | ||
| 67 | : USB_ADP_PROBE_PLUG : : | ||
| 68 | : USB_ADP_PROBE_UNPLUG : : | ||
| 69 | |||
| 70 | Required child device properties: | ||
| 71 | - compatible : "stericsson,ab8500-[bm|btemp|charger|fg|gpadc|gpio|ponkey| | ||
| 72 | pwm|regulator|rtc|sysctrl|usb]"; | ||
| 73 | |||
| 74 | A few child devices require ADC channels from the GPADC node. Those follow the | ||
| 75 | standard bindings from | ||
| 76 | https://github.com/devicetree-org/dt-schema/blob/master/schemas/iio/iio-consumer.yaml | ||
| 77 | and Documentation/devicetree/bindings/iio/adc/adc.yaml | ||
| 78 | |||
| 79 | abx500-temp : io-channels "aux1" and "aux2" for measuring external | ||
| 80 | temperatures. | ||
| 81 | ab8500-fg : io-channel "main_bat_v" for measuring main battery voltage, | ||
| 82 | ab8500-btemp : io-channels "btemp_ball" and "bat_ctrl" for measuring the | ||
| 83 | battery voltage. | ||
| 84 | ab8500-charger : io-channels "main_charger_v", "main_charger_c", "vbus_v", | ||
| 85 | "usb_charger_c" for measuring voltage and current of the | ||
| 86 | different charging supplies. | ||
| 87 | |||
| 88 | Optional child device properties: | ||
| 89 | - interrupts : contains the device IRQ(s) using the 2-cell format (see above) | ||
| 90 | - interrupt-names : contains names of IRQ resource in the order in which they were | ||
| 91 | supplied in the interrupts property | ||
| 92 | - <supply_name>-supply : contains a phandle to the regulator supply node in Device Tree | ||
| 93 | |||
| 94 | Non-standard child device properties: | ||
| 95 | - Audio CODEC: | ||
| 96 | - stericsson,amic[1|2]-type-single-ended : Single-ended Analoge Mic (default: differential) | ||
| 97 | - stericsson,amic1a-bias-vamic2 : Analoge Mic wishes to use a non-standard Vamic | ||
| 98 | - stericsson,amic1b-bias-vamic2 : Analoge Mic wishes to use a non-standard Vamic | ||
| 99 | - stericsson,amic2-bias-vamic1 : Analoge Mic wishes to use a non-standard Vamic | ||
| 100 | - stericsson,earpeice-cmv : Earpeice voltage (only: 950 | 1100 | 1270 | 1580) | ||
| 101 | |||
| 102 | ab8500 { | ||
| 103 | compatible = "stericsson,ab8500"; | ||
| 104 | interrupts = <0 40 0x4>; | ||
| 105 | interrupt-controller; | ||
| 106 | #interrupt-cells = <2>; | ||
| 107 | |||
| 108 | ab8500-rtc { | ||
| 109 | compatible = "stericsson,ab8500-rtc"; | ||
| 110 | interrupts = <17 0x4 | ||
| 111 | 18 0x4>; | ||
| 112 | interrupt-names = "60S", "ALARM"; | ||
| 113 | }; | ||
| 114 | |||
| 115 | ab8500-gpadc { | ||
| 116 | compatible = "stericsson,ab8500-gpadc"; | ||
| 117 | interrupts = <32 0x4 | ||
| 118 | 39 0x4>; | ||
| 119 | interrupt-names = "HW_CONV_END", "SW_CONV_END"; | ||
| 120 | vddadc-supply = <&ab8500_ldo_tvout_reg>; | ||
| 121 | #address-cells = <1>; | ||
| 122 | #size-cells = <0>; | ||
| 123 | #io-channel-cells = <1>; | ||
| 124 | |||
| 125 | /* GPADC channels */ | ||
| 126 | bat_ctrl: channel@1 { | ||
| 127 | reg = <0x01>; | ||
| 128 | }; | ||
| 129 | btemp_ball: channel@2 { | ||
| 130 | reg = <0x02>; | ||
| 131 | }; | ||
| 132 | main_charger_v: channel@3 { | ||
| 133 | reg = <0x03>; | ||
| 134 | }; | ||
| 135 | acc_detect1: channel@4 { | ||
| 136 | reg = <0x04>; | ||
| 137 | }; | ||
| 138 | acc_detect2: channel@5 { | ||
| 139 | reg = <0x05>; | ||
| 140 | }; | ||
| 141 | adc_aux1: channel@6 { | ||
| 142 | reg = <0x06>; | ||
| 143 | }; | ||
| 144 | adc_aux2: channel@7 { | ||
| 145 | reg = <0x07>; | ||
| 146 | }; | ||
| 147 | main_batt_v: channel@8 { | ||
| 148 | reg = <0x08>; | ||
| 149 | }; | ||
| 150 | vbus_v: channel@9 { | ||
| 151 | reg = <0x09>; | ||
| 152 | }; | ||
| 153 | main_charger_c: channel@a { | ||
| 154 | reg = <0x0a>; | ||
| 155 | }; | ||
| 156 | usb_charger_c: channel@b { | ||
| 157 | reg = <0x0b>; | ||
| 158 | }; | ||
| 159 | bk_bat_v: channel@c { | ||
| 160 | reg = <0x0c>; | ||
| 161 | }; | ||
| 162 | die_temp: channel@d { | ||
| 163 | reg = <0x0d>; | ||
| 164 | }; | ||
| 165 | usb_id: channel@e { | ||
| 166 | reg = <0x0e>; | ||
| 167 | }; | ||
| 168 | xtal_temp: channel@12 { | ||
| 169 | reg = <0x12>; | ||
| 170 | }; | ||
| 171 | vbat_true_meas: channel@13 { | ||
| 172 | reg = <0x13>; | ||
| 173 | }; | ||
| 174 | bat_ctrl_and_ibat: channel@1c { | ||
| 175 | reg = <0x1c>; | ||
| 176 | }; | ||
| 177 | vbat_meas_and_ibat: channel@1d { | ||
| 178 | reg = <0x1d>; | ||
| 179 | }; | ||
| 180 | vbat_true_meas_and_ibat: channel@1e { | ||
| 181 | reg = <0x1e>; | ||
| 182 | }; | ||
| 183 | bat_temp_and_ibat: channel@1f { | ||
| 184 | reg = <0x1f>; | ||
| 185 | }; | ||
| 186 | }; | ||
| 187 | |||
| 188 | ab8500_temp { | ||
| 189 | compatible = "stericsson,abx500-temp"; | ||
| 190 | io-channels = <&gpadc 0x06>, | ||
| 191 | <&gpadc 0x07>; | ||
| 192 | io-channel-name = "aux1", "aux2"; | ||
| 193 | }; | ||
| 194 | |||
| 195 | ab8500_battery: ab8500_battery { | ||
| 196 | stericsson,battery-type = "LIPO"; | ||
| 197 | thermistor-on-batctrl; | ||
| 198 | }; | ||
| 199 | |||
| 200 | ab8500_fg { | ||
| 201 | compatible = "stericsson,ab8500-fg"; | ||
| 202 | battery = <&ab8500_battery>; | ||
| 203 | io-channels = <&gpadc 0x08>; | ||
| 204 | io-channel-name = "main_bat_v"; | ||
| 205 | }; | ||
| 206 | |||
| 207 | ab8500_btemp { | ||
| 208 | compatible = "stericsson,ab8500-btemp"; | ||
| 209 | battery = <&ab8500_battery>; | ||
| 210 | io-channels = <&gpadc 0x02>, | ||
| 211 | <&gpadc 0x01>; | ||
| 212 | io-channel-name = "btemp_ball", | ||
| 213 | "bat_ctrl"; | ||
| 214 | }; | ||
| 215 | |||
| 216 | ab8500_charger { | ||
| 217 | compatible = "stericsson,ab8500-charger"; | ||
| 218 | battery = <&ab8500_battery>; | ||
| 219 | vddadc-supply = <&ab8500_ldo_tvout_reg>; | ||
| 220 | io-channels = <&gpadc 0x03>, | ||
| 221 | <&gpadc 0x0a>, | ||
| 222 | <&gpadc 0x09>, | ||
| 223 | <&gpadc 0x0b>; | ||
| 224 | io-channel-name = "main_charger_v", | ||
| 225 | "main_charger_c", | ||
| 226 | "vbus_v", | ||
| 227 | "usb_charger_c"; | ||
| 228 | }; | ||
| 229 | |||
| 230 | ab8500-usb { | ||
| 231 | compatible = "stericsson,ab8500-usb"; | ||
| 232 | interrupts = < 90 0x4 | ||
| 233 | 96 0x4 | ||
| 234 | 14 0x4 | ||
| 235 | 15 0x4 | ||
| 236 | 79 0x4 | ||
| 237 | 74 0x4 | ||
| 238 | 75 0x4>; | ||
| 239 | interrupt-names = "ID_WAKEUP_R", | ||
| 240 | "ID_WAKEUP_F", | ||
| 241 | "VBUS_DET_F", | ||
| 242 | "VBUS_DET_R", | ||
| 243 | "USB_LINK_STATUS", | ||
| 244 | "USB_ADP_PROBE_PLUG", | ||
| 245 | "USB_ADP_PROBE_UNPLUG"; | ||
| 246 | vddulpivio18-supply = <&ab8500_ldo_intcore_reg>; | ||
| 247 | v-ape-supply = <&db8500_vape_reg>; | ||
| 248 | musb_1v8-supply = <&db8500_vsmps2_reg>; | ||
| 249 | }; | ||
| 250 | |||
| 251 | ab8500-ponkey { | ||
| 252 | compatible = "stericsson,ab8500-ponkey"; | ||
| 253 | interrupts = <6 0x4 | ||
| 254 | 7 0x4>; | ||
| 255 | interrupt-names = "ONKEY_DBF", "ONKEY_DBR"; | ||
| 256 | }; | ||
| 257 | |||
| 258 | ab8500-sysctrl { | ||
| 259 | compatible = "stericsson,ab8500-sysctrl"; | ||
| 260 | }; | ||
| 261 | |||
| 262 | ab8500-pwm { | ||
| 263 | compatible = "stericsson,ab8500-pwm"; | ||
| 264 | }; | ||
| 265 | |||
| 266 | codec: ab8500-codec { | ||
| 267 | compatible = "stericsson,ab8500-codec"; | ||
| 268 | |||
| 269 | stericsson,earpeice-cmv = <950>; /* Units in mV. */ | ||
| 270 | }; | ||
| 271 | |||
| 272 | ab8500-regulators { | ||
| 273 | compatible = "stericsson,ab8500-regulator"; | ||
| 274 | |||
| 275 | ab8500_ldo_aux1_reg: ab8500_ldo_aux1 { | ||
| 276 | /* | ||
| 277 | * See: Documentation/devicetree/bindings/regulator/regulator.txt | ||
| 278 | * for more information on regulators | ||
| 279 | */ | ||
| 280 | }; | ||
| 281 | }; | ||
| 282 | }; | ||
| @@ -1,194 +0,0 @@ | |||
| 1 | Maxim MAX77693 multi-function device | ||
| 2 | |||
| 3 | MAX77693 is a Multifunction device with the following submodules: | ||
| 4 | - PMIC, | ||
| 5 | - CHARGER, | ||
| 6 | - LED, | ||
| 7 | - MUIC, | ||
| 8 | - HAPTIC | ||
| 9 | |||
| 10 | It is interfaced to host controller using i2c. | ||
| 11 | This document describes the bindings for the mfd device. | ||
| 12 | |||
| 13 | Required properties: | ||
| 14 | - compatible : Must be "maxim,max77693". | ||
| 15 | - reg : Specifies the i2c slave address of PMIC block. | ||
| 16 | - interrupts : This i2c device has an IRQ line connected to the main SoC. | ||
| 17 | |||
| 18 | Optional properties: | ||
| 19 | - regulators : The regulators of max77693 have to be instantiated under subnode | ||
| 20 | named "regulators" using the following format. | ||
| 21 | |||
| 22 | regulators { | ||
| 23 | regulator-compatible = ESAFEOUT1/ESAFEOUT2/CHARGER | ||
| 24 | standard regulator constraints[*]. | ||
| 25 | }; | ||
| 26 | |||
| 27 | [*] refer Documentation/devicetree/bindings/regulator/regulator.txt | ||
| 28 | |||
| 29 | - haptic : The MAX77693 haptic device utilises a PWM controlled motor to provide | ||
| 30 | users with tactile feedback. PWM period and duty-cycle are varied in | ||
| 31 | order to provide the appropriate level of feedback. | ||
| 32 | |||
| 33 | Required properties: | ||
| 34 | - compatible : Must be "maxim,max77693-haptic" | ||
| 35 | - haptic-supply : power supply for the haptic motor | ||
| 36 | [*] refer Documentation/devicetree/bindings/regulator/regulator.txt | ||
| 37 | - pwms : phandle to the physical PWM(Pulse Width Modulation) device. | ||
| 38 | PWM properties should be named "pwms". And number of cell is different | ||
| 39 | for each pwm device. | ||
| 40 | To get more information, please refer to documentation. | ||
| 41 | [*] refer Documentation/devicetree/bindings/pwm/pwm.txt | ||
| 42 | |||
| 43 | - charger : Node configuring the charger driver. | ||
| 44 | If present, required properties: | ||
| 45 | - compatible : Must be "maxim,max77693-charger". | ||
| 46 | |||
| 47 | Optional properties (if not set, defaults will be used): | ||
| 48 | - maxim,constant-microvolt : Battery constant voltage in uV. The charger | ||
| 49 | will operate in fast charge constant current mode till battery voltage | ||
| 50 | reaches this level. Then the charger will switch to fast charge constant | ||
| 51 | voltage mode. Also vsys (system voltage) will be set to this value when | ||
| 52 | DC power is supplied but charger is not enabled. | ||
| 53 | Valid values: 3650000 - 4400000, step by 25000 (rounded down) | ||
| 54 | Default: 4200000 | ||
| 55 | |||
| 56 | - maxim,min-system-microvolt : Minimal system voltage in uV. | ||
| 57 | Valid values: 3000000 - 3700000, step by 100000 (rounded down) | ||
| 58 | Default: 3600000 | ||
| 59 | |||
| 60 | - maxim,thermal-regulation-celsius : Temperature in Celsius for entering | ||
| 61 | high temperature charging mode. If die temperature exceeds this value | ||
| 62 | the charging current will be reduced by 105 mA/Celsius. | ||
| 63 | Valid values: 70, 85, 100, 115 | ||
| 64 | Default: 100 | ||
| 65 | |||
| 66 | - maxim,battery-overcurrent-microamp : Overcurrent protection threshold | ||
| 67 | in uA (current from battery to system). | ||
| 68 | Valid values: 2000000 - 3500000, step by 250000 (rounded down) | ||
| 69 | Default: 3500000 | ||
| 70 | |||
| 71 | - maxim,charge-input-threshold-microvolt : Threshold voltage in uV for | ||
| 72 | triggering input voltage regulation loop. If input voltage decreases | ||
| 73 | below this value, the input current will be reduced to reach the | ||
| 74 | threshold voltage. | ||
| 75 | Valid values: 4300000, 4700000, 4800000, 4900000 | ||
| 76 | Default: 4300000 | ||
| 77 | |||
| 78 | - led : the LED submodule device node | ||
| 79 | |||
| 80 | There are two LED outputs available - FLED1 and FLED2. Each of them can | ||
| 81 | control a separate LED or they can be connected together to double | ||
| 82 | the maximum current for a single connected LED. One LED is represented | ||
| 83 | by one child node. | ||
| 84 | |||
| 85 | Required properties: | ||
| 86 | - compatible : Must be "maxim,max77693-led". | ||
| 87 | |||
| 88 | Optional properties: | ||
| 89 | - maxim,boost-mode : | ||
| 90 | In boost mode the device can produce up to 1.2A of total current | ||
| 91 | on both outputs. The maximum current on each output is reduced | ||
| 92 | to 625mA then. If not enabled explicitly, boost setting defaults to | ||
| 93 | LEDS_BOOST_FIXED in case both current sources are used. | ||
| 94 | Possible values: | ||
| 95 | LEDS_BOOST_OFF (0) - no boost, | ||
| 96 | LEDS_BOOST_ADAPTIVE (1) - adaptive mode, | ||
| 97 | LEDS_BOOST_FIXED (2) - fixed mode. | ||
| 98 | - maxim,boost-mvout : Output voltage of the boost module in millivolts. | ||
| 99 | Valid values: 3300 - 5500, step by 25 (rounded down) | ||
| 100 | Default: 3300 | ||
| 101 | - maxim,mvsys-min : Low input voltage level in millivolts. Flash is not fired | ||
| 102 | if chip estimates that system voltage could drop below this level due | ||
| 103 | to flash power consumption. | ||
| 104 | Valid values: 2400 - 3400, step by 33 (rounded down) | ||
| 105 | Default: 2400 | ||
| 106 | |||
| 107 | Required properties for the LED child node: | ||
| 108 | - led-sources : see Documentation/devicetree/bindings/leds/common.txt; | ||
| 109 | device current output identifiers: 0 - FLED1, 1 - FLED2 | ||
| 110 | - led-max-microamp : see Documentation/devicetree/bindings/leds/common.txt | ||
| 111 | Valid values for a LED connected to one FLED output: | ||
| 112 | 15625 - 250000, step by 15625 (rounded down) | ||
| 113 | Valid values for a LED connected to both FLED outputs: | ||
| 114 | 15625 - 500000, step by 15625 (rounded down) | ||
| 115 | - flash-max-microamp : see Documentation/devicetree/bindings/leds/common.txt | ||
| 116 | Valid values for a single LED connected to one FLED output | ||
| 117 | (boost mode must be turned off): | ||
| 118 | 15625 - 1000000, step by 15625 (rounded down) | ||
| 119 | Valid values for a single LED connected to both FLED outputs: | ||
| 120 | 15625 - 1250000, step by 15625 (rounded down) | ||
| 121 | Valid values for two LEDs case: | ||
| 122 | 15625 - 625000, step by 15625 (rounded down) | ||
| 123 | - flash-max-timeout-us : see Documentation/devicetree/bindings/leds/common.txt | ||
| 124 | Valid values: 62500 - 1000000, step by 62500 (rounded down) | ||
| 125 | |||
| 126 | Optional properties for the LED child node: | ||
| 127 | - label : see Documentation/devicetree/bindings/leds/common.txt | ||
| 128 | |||
| 129 | Optional nodes: | ||
| 130 | - max77693-muic : | ||
| 131 | Node used only by extcon consumers. | ||
| 132 | Required properties: | ||
| 133 | - compatible : "maxim,max77693-muic" | ||
| 134 | |||
| 135 | Example: | ||
| 136 | #include <dt-bindings/leds/common.h> | ||
| 137 | |||
| 138 | max77693@66 { | ||
| 139 | compatible = "maxim,max77693"; | ||
| 140 | reg = <0x66>; | ||
| 141 | interrupt-parent = <&gpx1>; | ||
| 142 | interrupts = <5 IRQ_TYPE_LEVEL_LOW>; | ||
| 143 | |||
| 144 | regulators { | ||
| 145 | esafeout@1 { | ||
| 146 | regulator-compatible = "ESAFEOUT1"; | ||
| 147 | regulator-name = "ESAFEOUT1"; | ||
| 148 | regulator-boot-on; | ||
| 149 | }; | ||
| 150 | esafeout@2 { | ||
| 151 | regulator-compatible = "ESAFEOUT2"; | ||
| 152 | regulator-name = "ESAFEOUT2"; | ||
| 153 | }; | ||
| 154 | charger@0 { | ||
| 155 | regulator-compatible = "CHARGER"; | ||
| 156 | regulator-name = "CHARGER"; | ||
| 157 | regulator-min-microamp = <60000>; | ||
| 158 | regulator-max-microamp = <2580000>; | ||
| 159 | regulator-boot-on; | ||
| 160 | }; | ||
| 161 | }; | ||
| 162 | |||
| 163 | haptic { | ||
| 164 | compatible = "maxim,max77693-haptic"; | ||
| 165 | haptic-supply = <&haptic_supply>; | ||
| 166 | pwms = <&pwm 0 40000 0>; | ||
| 167 | pwm-names = "haptic"; | ||
| 168 | }; | ||
| 169 | |||
| 170 | charger { | ||
| 171 | compatible = "maxim,max77693-charger"; | ||
| 172 | |||
| 173 | maxim,constant-microvolt = <4200000>; | ||
| 174 | maxim,min-system-microvolt = <3600000>; | ||
| 175 | maxim,thermal-regulation-celsius = <75>; | ||
| 176 | maxim,battery-overcurrent-microamp = <3000000>; | ||
| 177 | maxim,charge-input-threshold-microvolt = <4300000>; | ||
| 178 | }; | ||
| 179 | |||
| 180 | led { | ||
| 181 | compatible = "maxim,max77693-led"; | ||
| 182 | maxim,boost-mode = <LEDS_BOOST_FIXED>; | ||
| 183 | maxim,boost-mvout = <5000>; | ||
| 184 | maxim,mvsys-min = <2400>; | ||
| 185 | |||
| 186 | camera_flash: flash-led { | ||
| 187 | label = "max77693-flash"; | ||
| 188 | led-sources = <0>, <1>; | ||
| 189 | led-max-microamp = <500000>; | ||
| 190 | flash-max-microamp = <1250000>; | ||
| 191 | flash-max-timeout-us = <1000000>; | ||
| 192 | }; | ||
| 193 | }; | ||
| 194 | }; | ||
| @@ -0,0 +1,143 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/mfd/maxim,max77693.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Maxim MAX77693 MicroUSB and Companion Power Management IC | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Chanwoo Choi <cw00.choi@samsung.com> | ||
| 11 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 12 | |||
| 13 | description: | | ||
| 14 | This is a part of device tree bindings for Maxim MAX77693 MicroUSB | ||
| 15 | Integrated Circuit (MUIC). | ||
| 16 | |||
| 17 | The Maxim MAX77693 is a MicroUSB and Companion Power Management IC which | ||
| 18 | includes voltage current regulators, charger, LED/flash, haptic motor driver | ||
| 19 | and MicroUSB management IC. | ||
| 20 | |||
| 21 | properties: | ||
| 22 | compatible: | ||
| 23 | const: maxim,max77693 | ||
| 24 | |||
| 25 | interrupts: | ||
| 26 | maxItems: 1 | ||
| 27 | |||
| 28 | reg: | ||
| 29 | maxItems: 1 | ||
| 30 | |||
| 31 | charger: | ||
| 32 | $ref: /schemas/power/supply/maxim,max77693.yaml | ||
| 33 | |||
| 34 | led: | ||
| 35 | $ref: /schemas/leds/maxim,max77693.yaml | ||
| 36 | |||
| 37 | max77693-muic: | ||
| 38 | type: object | ||
| 39 | additionalProperties: false | ||
| 40 | |||
| 41 | properties: | ||
| 42 | compatible: | ||
| 43 | const: maxim,max77693-muic | ||
| 44 | |||
| 45 | required: | ||
| 46 | - compatible | ||
| 47 | |||
| 48 | motor-driver: | ||
| 49 | type: object | ||
| 50 | additionalProperties: false | ||
| 51 | |||
| 52 | properties: | ||
| 53 | compatible: | ||
| 54 | const: maxim,max77693-haptic | ||
| 55 | |||
| 56 | haptic-supply: | ||
| 57 | description: Power supply to the haptic motor | ||
| 58 | |||
| 59 | pwms: | ||
| 60 | maxItems: 1 | ||
| 61 | |||
| 62 | required: | ||
| 63 | - compatible | ||
| 64 | - haptic-supply | ||
| 65 | - pwms | ||
| 66 | |||
| 67 | regulators: | ||
| 68 | $ref: ../regulator/maxim,max77693.yaml | ||
| 69 | description: | ||
| 70 | List of child nodes that specify the regulators. | ||
| 71 | |||
| 72 | required: | ||
| 73 | - compatible | ||
| 74 | - interrupts | ||
| 75 | - reg | ||
| 76 | |||
| 77 | additionalProperties: false | ||
| 78 | |||
| 79 | examples: | ||
| 80 | - | | ||
| 81 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 82 | #include <dt-bindings/leds/common.h> | ||
| 83 | |||
| 84 | i2c { | ||
| 85 | #address-cells = <1>; | ||
| 86 | #size-cells = <0>; | ||
| 87 | |||
| 88 | pmic@66 { | ||
| 89 | compatible = "maxim,max77693"; | ||
| 90 | reg = <0x66>; | ||
| 91 | interrupt-parent = <&gpx1>; | ||
| 92 | interrupts = <5 IRQ_TYPE_LEVEL_LOW>; | ||
| 93 | |||
| 94 | regulators { | ||
| 95 | ESAFEOUT1 { | ||
| 96 | regulator-name = "ESAFEOUT1"; | ||
| 97 | }; | ||
| 98 | |||
| 99 | ESAFEOUT2 { | ||
| 100 | regulator-name = "ESAFEOUT2"; | ||
| 101 | }; | ||
| 102 | |||
| 103 | CHARGER { | ||
| 104 | regulator-name = "CHARGER"; | ||
| 105 | regulator-min-microamp = <60000>; | ||
| 106 | regulator-max-microamp = <2580000>; | ||
| 107 | }; | ||
| 108 | }; | ||
| 109 | |||
| 110 | motor-driver { | ||
| 111 | compatible = "maxim,max77693-haptic"; | ||
| 112 | haptic-supply = <&ldo26_reg>; | ||
| 113 | pwms = <&pwm 0 38022 0>; | ||
| 114 | }; | ||
| 115 | |||
| 116 | charger { | ||
| 117 | compatible = "maxim,max77693-charger"; | ||
| 118 | |||
| 119 | maxim,constant-microvolt = <4350000>; | ||
| 120 | maxim,min-system-microvolt = <3600000>; | ||
| 121 | maxim,thermal-regulation-celsius = <100>; | ||
| 122 | maxim,battery-overcurrent-microamp = <3500000>; | ||
| 123 | maxim,charge-input-threshold-microvolt = <4300000>; | ||
| 124 | }; | ||
| 125 | |||
| 126 | led { | ||
| 127 | compatible = "maxim,max77693-led"; | ||
| 128 | maxim,boost-mode = <LEDS_BOOST_FIXED>; | ||
| 129 | maxim,boost-mvout = <5000>; | ||
| 130 | maxim,mvsys-min = <2400>; | ||
| 131 | |||
| 132 | flash-led { | ||
| 133 | label = "max77693-flash"; | ||
| 134 | function = LED_FUNCTION_FLASH; | ||
| 135 | color = <LED_COLOR_ID_WHITE>; | ||
| 136 | led-sources = <0>, <1>; | ||
| 137 | led-max-microamp = <500000>; | ||
| 138 | flash-max-microamp = <1250000>; | ||
| 139 | flash-max-timeout-us = <1000000>; | ||
| 140 | }; | ||
| 141 | }; | ||
| 142 | }; | ||
| 143 | }; | ||
| @@ -0,0 +1,68 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/mfd/maxim,max77714.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: MAX77714 PMIC with GPIO, RTC and watchdog from Maxim Integrated. | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Luca Ceresoli <luca@lucaceresoli.net> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | MAX77714 is a Power Management IC with 4 buck regulators, 9 | ||
| 14 | low-dropout regulators, 8 GPIOs, RTC and watchdog. | ||
| 15 | |||
| 16 | properties: | ||
| 17 | compatible: | ||
| 18 | const: maxim,max77714 | ||
| 19 | |||
| 20 | reg: | ||
| 21 | maxItems: 1 | ||
| 22 | |||
| 23 | interrupts: | ||
| 24 | maxItems: 1 | ||
| 25 | |||
| 26 | interrupt-controller: true | ||
| 27 | |||
| 28 | "#interrupt-cells": | ||
| 29 | const: 2 | ||
| 30 | description: | ||
| 31 | The first cell is the IRQ number, the second cell is the trigger type. | ||
| 32 | |||
| 33 | regulators: | ||
| 34 | type: object | ||
| 35 | additionalProperties: false | ||
| 36 | |||
| 37 | patternProperties: | ||
| 38 | '^(buck[0-3]|ldo[0-8])$': | ||
| 39 | type: object | ||
| 40 | unevaluatedProperties: false | ||
| 41 | $ref: /schemas/regulator/regulator.yaml# | ||
| 42 | |||
| 43 | required: | ||
| 44 | - compatible | ||
| 45 | - reg | ||
| 46 | - interrupts | ||
| 47 | - interrupt-controller | ||
| 48 | - "#interrupt-cells" | ||
| 49 | |||
| 50 | additionalProperties: false | ||
| 51 | |||
| 52 | examples: | ||
| 53 | - | | ||
| 54 | #include <dt-bindings/interrupt-controller/irq.h> | ||
| 55 | i2c { | ||
| 56 | #address-cells = <1>; | ||
| 57 | #size-cells = <0>; | ||
| 58 | |||
| 59 | pmic@1c { | ||
| 60 | compatible = "maxim,max77714"; | ||
| 61 | reg = <0x1c>; | ||
| 62 | interrupt-parent = <&gpio2>; | ||
| 63 | interrupts = <3 IRQ_TYPE_LEVEL_LOW>; | ||
| 64 | |||
| 65 | interrupt-controller; | ||
| 66 | #interrupt-cells = <2>; | ||
| 67 | }; | ||
| 68 | }; | ||
| @@ -20,7 +20,7 @@ This document describes the binding for MFD device and its sub module. · 19 unmodified lines | |||
| 20 | Required properties: | 20 | Required properties: |
| 21 | compatible: | 21 | compatible: |
| 22 | "mediatek,mt6323" for PMIC MT6323 | 22 | "mediatek,mt6323" for PMIC MT6323 |
| 23 | "mediatek,mt6358" for PMIC MT6358 | 23 | "mediatek,mt6358" for PMIC MT6358 and MT6366 |
| 24 | "mediatek,mt6359" for PMIC MT6359 | 24 | "mediatek,mt6359" for PMIC MT6359 |
| 25 | "mediatek,mt6397" for PMIC MT6397 | 25 | "mediatek,mt6397" for PMIC MT6397 |
| 26 | 26 | ||
| @@ -35,6 +35,7 @@ Required properties: · 34 unmodified lines | |||
| 35 | "qcom,pm8916", | 35 | "qcom,pm8916", |
| 36 | "qcom,pm8941", | 36 | "qcom,pm8941", |
| 37 | "qcom,pm8950", | 37 | "qcom,pm8950", |
| 38 | "qcom,pm8953", | ||
| 38 | "qcom,pm8994", | 39 | "qcom,pm8994", |
| 39 | "qcom,pm8998", | 40 | "qcom,pm8998", |
| 40 | "qcom,pma8084", | 41 | "qcom,pma8084", |
| @@ -10,6 +10,7 @@ Required properties: · 9 unmodified lines | |||
| 10 | "qcom,tcsr-ipq8064", "syscon" for IPQ8064 | 10 | "qcom,tcsr-ipq8064", "syscon" for IPQ8064 |
| 11 | "qcom,tcsr-apq8064", "syscon" for APQ8064 | 11 | "qcom,tcsr-apq8064", "syscon" for APQ8064 |
| 12 | "qcom,tcsr-msm8660", "syscon" for MSM8660 | 12 | "qcom,tcsr-msm8660", "syscon" for MSM8660 |
| 13 | "qcom,tcsr-msm8953", "syscon" for MSM8953 | ||
| 13 | "qcom,tcsr-msm8960", "syscon" for MSM8960 | 14 | "qcom,tcsr-msm8960", "syscon" for MSM8960 |
| 14 | "qcom,tcsr-msm8974", "syscon" for MSM8974 | 15 | "qcom,tcsr-msm8974", "syscon" for MSM8974 |
| 15 | "qcom,tcsr-apq8084", "syscon" for APQ8084 | 16 | "qcom,tcsr-apq8084", "syscon" for APQ8084 |
| @@ -1,72 +0,0 @@ | |||
| 1 | Samsung Exynos SoC Low Power Audio Subsystem (LPASS) | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | |||
| 5 | - compatible : "samsung,exynos5433-lpass" | ||
| 6 | - reg : should contain the LPASS top SFR region location | ||
| 7 | and size | ||
| 8 | - clock-names : should contain following required clocks: "sfr0_ctrl" | ||
| 9 | - clocks : should contain clock specifiers of all clocks, which | ||
| 10 | input names have been specified in clock-names | ||
| 11 | property, in same order. | ||
| 12 | - #address-cells : should be 1 | ||
| 13 | - #size-cells : should be 1 | ||
| 14 | - ranges : must be present | ||
| 15 | |||
| 16 | Each IP block of the Low Power Audio Subsystem should be specified as | ||
| 17 | an optional sub-node. For "samsung,exynos5433-lpass" compatible this includes: | ||
| 18 | UART, SLIMBUS, PCM, I2S, DMAC, Timers 0...4, VIC, WDT 0...1 devices. | ||
| 19 | |||
| 20 | Bindings of the sub-nodes are described in: | ||
| 21 | ../serial/samsung_uart.yaml | ||
| 22 | ../sound/samsung-i2s.txt | ||
| 23 | ../dma/arm-pl330.txt | ||
| 24 | |||
| 25 | |||
| 26 | Example: | ||
| 27 | |||
| 28 | audio-subsystem { | ||
| 29 | compatible = "samsung,exynos5433-lpass"; | ||
| 30 | reg = <0x11400000 0x100>, <0x11500000 0x08>; | ||
| 31 | clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>; | ||
| 32 | clock-names = "sfr0_ctrl"; | ||
| 33 | #address-cells = <1>; | ||
| 34 | #size-cells = <1>; | ||
| 35 | ranges; | ||
| 36 | |||
| 37 | adma: adma@11420000 { | ||
| 38 | compatible = "arm,pl330", "arm,primecell"; | ||
| 39 | reg = <0x11420000 0x1000>; | ||
| 40 | interrupts = <0 73 0>; | ||
| 41 | clocks = <&cmu_aud CLK_ACLK_DMAC>; | ||
| 42 | clock-names = "apb_pclk"; | ||
| 43 | #dma-cells = <1>; | ||
| 44 | #dma-channels = <8>; | ||
| 45 | #dma-requests = <32>; | ||
| 46 | }; | ||
| 47 | |||
| 48 | i2s0: i2s0@11440000 { | ||
| 49 | compatible = "samsung,exynos7-i2s"; | ||
| 50 | reg = <0x11440000 0x100>; | ||
| 51 | dmas = <&adma 0 &adma 2>; | ||
| 52 | dma-names = "tx", "rx"; | ||
| 53 | interrupts = <0 70 0>; | ||
| 54 | clocks = <&cmu_aud CLK_PCLK_AUD_I2S>, | ||
| 55 | <&cmu_aud CLK_SCLK_AUD_I2S>, | ||
| 56 | <&cmu_aud CLK_SCLK_I2S_BCLK>; | ||
| 57 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; | ||
| 58 | pinctrl-names = "default"; | ||
| 59 | pinctrl-0 = <&i2s0_bus>; | ||
| 60 | }; | ||
| 61 | |||
| 62 | serial_3: serial@11460000 { | ||
| 63 | compatible = "samsung,exynos5433-uart"; | ||
| 64 | reg = <0x11460000 0x100>; | ||
| 65 | interrupts = <0 67 0>; | ||
| 66 | clocks = <&cmu_aud CLK_PCLK_AUD_UART>, | ||
| 67 | <&cmu_aud CLK_SCLK_AUD_UART>; | ||
| 68 | clock-names = "uart", "clk_uart_baud0"; | ||
| 69 | pinctrl-names = "default"; | ||
| 70 | pinctrl-0 = <&uart_aud_bus>; | ||
| 71 | }; | ||
| 72 | }; | ||
| @@ -0,0 +1,117 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/mfd/samsung,exynos5433-lpass.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Samsung Exynos SoC Low Power Audio Subsystem (LPASS) | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 11 | - Sylwester Nawrocki <s.nawrocki@samsung.com> | ||
| 12 | |||
| 13 | properties: | ||
| 14 | compatible: | ||
| 15 | const: samsung,exynos5433-lpass | ||
| 16 | |||
| 17 | '#address-cells': | ||
| 18 | const: 1 | ||
| 19 | |||
| 20 | clocks: | ||
| 21 | maxItems: 1 | ||
| 22 | |||
| 23 | clock-names: | ||
| 24 | items: | ||
| 25 | - const: sfr0_ctrl | ||
| 26 | |||
| 27 | power-domains: | ||
| 28 | maxItems: 1 | ||
| 29 | |||
| 30 | ranges: true | ||
| 31 | |||
| 32 | reg: | ||
| 33 | minItems: 2 | ||
| 34 | maxItems: 2 | ||
| 35 | |||
| 36 | '#size-cells': | ||
| 37 | const: 1 | ||
| 38 | |||
| 39 | patternProperties: | ||
| 40 | "^dma-controller@[0-9a-f]+$": | ||
| 41 | $ref: /schemas/dma/arm,pl330.yaml | ||
| 42 | |||
| 43 | "^i2s@[0-9a-f]+$": | ||
| 44 | $ref: /schemas/sound/samsung-i2s.yaml | ||
| 45 | |||
| 46 | "^serial@[0-9a-f]+$": | ||
| 47 | $ref: /schemas/serial/samsung_uart.yaml | ||
| 48 | |||
| 49 | required: | ||
| 50 | - compatible | ||
| 51 | - '#address-cells' | ||
| 52 | - clocks | ||
| 53 | - clock-names | ||
| 54 | - ranges | ||
| 55 | - reg | ||
| 56 | - '#size-cells' | ||
| 57 | |||
| 58 | additionalProperties: false | ||
| 59 | |||
| 60 | examples: | ||
| 61 | - | | ||
| 62 | #include <dt-bindings/clock/exynos5433.h> | ||
| 63 | #include <dt-bindings/interrupt-controller/arm-gic.h> | ||
| 64 | |||
| 65 | audio-subsystem@11400000 { | ||
| 66 | compatible = "samsung,exynos5433-lpass"; | ||
| 67 | reg = <0x11400000 0x100>, <0x11500000 0x08>; | ||
| 68 | clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>; | ||
| 69 | clock-names = "sfr0_ctrl"; | ||
| 70 | power-domains = <&pd_aud>; | ||
| 71 | #address-cells = <1>; | ||
| 72 | #size-cells = <1>; | ||
| 73 | ranges; | ||
| 74 | |||
| 75 | dma-controller@11420000 { | ||
| 76 | compatible = "arm,pl330", "arm,primecell"; | ||
| 77 | reg = <0x11420000 0x1000>; | ||
| 78 | interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; | ||
| 79 | clocks = <&cmu_aud CLK_ACLK_DMAC>; | ||
| 80 | clock-names = "apb_pclk"; | ||
| 81 | #dma-cells = <1>; | ||
| 82 | #dma-channels = <8>; | ||
| 83 | #dma-requests = <32>; | ||
| 84 | power-domains = <&pd_aud>; | ||
| 85 | }; | ||
| 86 | |||
| 87 | i2s@11440000 { | ||
| 88 | compatible = "samsung,exynos7-i2s"; | ||
| 89 | reg = <0x11440000 0x100>; | ||
| 90 | dmas = <&adma 0>, <&adma 2>; | ||
| 91 | dma-names = "tx", "rx"; | ||
| 92 | interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; | ||
| 93 | #address-cells = <1>; | ||
| 94 | #size-cells = <0>; | ||
| 95 | clocks = <&cmu_aud CLK_PCLK_AUD_I2S>, | ||
| 96 | <&cmu_aud CLK_SCLK_AUD_I2S>, | ||
| 97 | <&cmu_aud CLK_SCLK_I2S_BCLK>; | ||
| 98 | clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; | ||
| 99 | #clock-cells = <1>; | ||
| 100 | pinctrl-names = "default"; | ||
| 101 | pinctrl-0 = <&i2s0_bus>; | ||
| 102 | power-domains = <&pd_aud>; | ||
| 103 | #sound-dai-cells = <1>; | ||
| 104 | }; | ||
| 105 | |||
| 106 | serial@11460000 { | ||
| 107 | compatible = "samsung,exynos5433-uart"; | ||
| 108 | reg = <0x11460000 0x100>; | ||
| 109 | interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; | ||
| 110 | clocks = <&cmu_aud CLK_PCLK_AUD_UART>, | ||
| 111 | <&cmu_aud CLK_SCLK_AUD_UART>; | ||
| 112 | clock-names = "uart", "clk_uart_baud0"; | ||
| 113 | pinctrl-names = "default"; | ||
| 114 | pinctrl-0 = <&uart_aud_bus>; | ||
| 115 | power-domains = <&pd_aud>; | ||
| 116 | }; | ||
| 117 | }; | ||
| @@ -0,0 +1,82 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/mfd/silergy,sy7636a.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: silergy sy7636a PMIC | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Alistair Francis <alistair@alistair23.me> | ||
| 11 | |||
| 12 | properties: | ||
| 13 | compatible: | ||
| 14 | const: silergy,sy7636a | ||
| 15 | |||
| 16 | reg: | ||
| 17 | description: | ||
| 18 | I2C device address. | ||
| 19 | maxItems: 1 | ||
| 20 | |||
| 21 | "#address-cells": | ||
| 22 | const: 1 | ||
| 23 | |||
| 24 | "#size-cells": | ||
| 25 | const: 0 | ||
| 26 | |||
| 27 | '#thermal-sensor-cells': | ||
| 28 | const: 0 | ||
| 29 | |||
| 30 | epd-pwr-good-gpios: | ||
| 31 | description: | ||
| 32 | Specifying the power good GPIOs. | ||
| 33 | maxItems: 1 | ||
| 34 | |||
| 35 | regulators: | ||
| 36 | type: object | ||
| 37 | |||
| 38 | properties: | ||
| 39 | compatible: | ||
| 40 | const: silergy,sy7636a-regulator | ||
| 41 | |||
| 42 | vcom: | ||
| 43 | type: object | ||
| 44 | $ref: /schemas/regulator/regulator.yaml# | ||
| 45 | description: | ||
| 46 | The regulator for the compenstation voltage. Enabling/disabling this | ||
| 47 | enables/disables the entire device. | ||
| 48 | properties: | ||
| 49 | regulator-name: | ||
| 50 | const: vcom | ||
| 51 | |||
| 52 | additionalProperties: false | ||
| 53 | |||
| 54 | required: | ||
| 55 | - compatible | ||
| 56 | - reg | ||
| 57 | - '#thermal-sensor-cells' | ||
| 58 | |||
| 59 | additionalProperties: false | ||
| 60 | |||
| 61 | examples: | ||
| 62 | - | | ||
| 63 | i2c { | ||
| 64 | #address-cells = <1>; | ||
| 65 | #size-cells = <0>; | ||
| 66 | |||
| 67 | pmic@62 { | ||
| 68 | compatible = "silergy,sy7636a"; | ||
| 69 | reg = <0x62>; | ||
| 70 | pinctrl-names = "default"; | ||
| 71 | pinctrl-0 = <&pinctrl_epdpmic>; | ||
| 72 | #thermal-sensor-cells = <0>; | ||
| 73 | |||
| 74 | regulators { | ||
| 75 | reg_epdpmic: vcom { | ||
| 76 | regulator-name = "vcom"; | ||
| 77 | regulator-boot-on; | ||
| 78 | }; | ||
| 79 | }; | ||
| 80 | }; | ||
| 81 | }; | ||
| 82 | ... | ||
| @@ -0,0 +1,500 @@ | |||
| 1 | # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/mfd/stericsson,ab8500.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: ST-Ericsson Analog Baseband AB8500 and AB8505 | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Linus Walleij <linus.walleij@linaro.org> | ||
| 11 | |||
| 12 | description: | ||
| 13 | the AB8500 "Analog Baseband" is the mixed-signals integrated circuit | ||
| 14 | handling power management (regulators), analog-to-digital conversion | ||
| 15 | (ADC), battery charging, fuel gauging of the battery, battery-backed | ||
| 16 | RTC, PWM, USB PHY and some GPIO lines in the ST-Ericsson U8500 platforms | ||
| 17 | in connection with the DB8500 digital baseband. The DB8500 PRCMU | ||
| 18 | communicates directly and autonomously with the AB8500 and thus it | ||
| 19 | appears as a subnode of the DB8500 PRCMU. An altered version called | ||
| 20 | AB8505 also exist, the difference in AB8505 is that some of the USB and | ||
| 21 | USB charging handling has changed, and it has an embedded USB-to-serial | ||
| 22 | converter. Most subblocks takes their interrupts directly from the | ||
| 23 | AB8500 embedded interrupt controller. | ||
| 24 | |||
| 25 | properties: | ||
| 26 | $nodename: | ||
| 27 | pattern: '^ab850[05]$' | ||
| 28 | |||
| 29 | compatible: | ||
| 30 | enum: | ||
| 31 | - stericsson,ab8500 | ||
| 32 | - stericsson,ab8505 | ||
| 33 | |||
| 34 | interrupts: | ||
| 35 | maxItems: 1 | ||
| 36 | |||
| 37 | interrupt-controller: true | ||
| 38 | |||
| 39 | '#interrupt-cells': | ||
| 40 | const: 2 | ||
| 41 | |||
| 42 | # Some subnodes use a reg, some don't. Those that do use a single cell. | ||
| 43 | '#address-cells': | ||
| 44 | const: 1 | ||
| 45 | |||
| 46 | '#size-cells': | ||
| 47 | const: 0 | ||
| 48 | |||
| 49 | clock-controller: | ||
| 50 | description: Node describing the AB8500 clock controller. This | ||
| 51 | provides the reference clock for the entire U8500 system and | ||
| 52 | the DB8500 counterpart. | ||
| 53 | type: object | ||
| 54 | |||
| 55 | properties: | ||
| 56 | compatible: | ||
| 57 | const: stericsson,ab8500-clk | ||
| 58 | |||
| 59 | '#clock-cells': | ||
| 60 | const: 1 | ||
| 61 | |||
| 62 | gpio: | ||
| 63 | description: Node describing the AB8500 GPIO controller. A few | ||
| 64 | GPIO pins available for misc usage. | ||
| 65 | type: object | ||
| 66 | |||
| 67 | properties: | ||
| 68 | compatible: | ||
| 69 | enum: | ||
| 70 | - stericsson,ab8500-gpio | ||
| 71 | - stericsson,ab8505-gpio | ||
| 72 | |||
| 73 | gpio-controller: true | ||
| 74 | |||
| 75 | '#gpio-cells': | ||
| 76 | const: 2 | ||
| 77 | |||
| 78 | rtc: | ||
| 79 | description: Node describing the AB8500 battery-backed RTC. | ||
| 80 | type: object | ||
| 81 | |||
| 82 | properties: | ||
| 83 | compatible: | ||
| 84 | const: stericsson,ab8500-rtc | ||
| 85 | |||
| 86 | interrupts: | ||
| 87 | items: | ||
| 88 | - description: 60 second interval alarm interrupt | ||
| 89 | - description: RTC alarm | ||
| 90 | |||
| 91 | interrupt-names: | ||
| 92 | items: | ||
| 93 | - const: 60S | ||
| 94 | - const: ALARM | ||
| 95 | |||
| 96 | adc: | ||
| 97 | description: Node describing the AB8500 general purpose analog to digital | ||
| 98 | converter, GPADC. | ||
| 99 | type: object | ||
| 100 | |||
| 101 | properties: | ||
| 102 | compatible: | ||
| 103 | const: stericsson,ab8500-gpadc | ||
| 104 | |||
| 105 | # AB8505 only supports one (software) EOC interrupt | ||
| 106 | interrupts: | ||
| 107 | minItems: 1 | ||
| 108 | maxItems: 2 | ||
| 109 | |||
| 110 | interrupt-names: true | ||
| 111 | |||
| 112 | vddadc-supply: true | ||
| 113 | |||
| 114 | '#address-cells': | ||
| 115 | const: 1 | ||
| 116 | |||
| 117 | '#size-cells': | ||
| 118 | const: 0 | ||
| 119 | |||
| 120 | '#io-channel-cells': | ||
| 121 | const: 1 | ||
| 122 | |||
| 123 | patternProperties: | ||
| 124 | "^channel@[0-9a-f]+$": | ||
| 125 | type: object | ||
| 126 | $ref: ../iio/adc/adc.yaml# | ||
| 127 | description: Represents each of the external channels which are | ||
| 128 | connected to the ADC. | ||
| 129 | |||
| 130 | properties: | ||
| 131 | reg: | ||
| 132 | items: | ||
| 133 | minimum: 1 | ||
| 134 | maximum: 31 | ||
| 135 | |||
| 136 | required: | ||
| 137 | - reg | ||
| 138 | |||
| 139 | additionalProperties: false | ||
| 140 | |||
| 141 | required: | ||
| 142 | - compatible | ||
| 143 | - interrupts | ||
| 144 | - interrupt-names | ||
| 145 | - vddadc-supply | ||
| 146 | - '#address-cells' | ||
| 147 | - '#size-cells' | ||
| 148 | - '#io-channel-cells' | ||
| 149 | |||
| 150 | additionalProperties: false | ||
| 151 | |||
| 152 | thermal: | ||
| 153 | description: Node describing the AB8500 thermal control block. All this block | ||
| 154 | really does is to fire an interrupt when the die becomes 130 degrees Celsius | ||
| 155 | in temperature. | ||
| 156 | type: object | ||
| 157 | |||
| 158 | properties: | ||
| 159 | compatible: | ||
| 160 | const: stericsson,abx500-temp | ||
| 161 | |||
| 162 | interrupts: | ||
| 163 | items: | ||
| 164 | - description: Thermal warm warning interrupt | ||
| 165 | |||
| 166 | interrupt-names: | ||
| 167 | items: | ||
| 168 | - const: ABX500_TEMP_WARM | ||
| 169 | |||
| 170 | required: | ||
| 171 | - compatible | ||
| 172 | - interrupts | ||
| 173 | - interrupt-names | ||
| 174 | |||
| 175 | additionalProperties: false | ||
| 176 | |||
| 177 | ab8500_fg: | ||
| 178 | description: Node describing the AB8500 fuel gauge control block. | ||
| 179 | type: object | ||
| 180 | $ref: ../power/supply/stericsson,ab8500-fg.yaml | ||
| 181 | |||
| 182 | ab8500_btemp: | ||
| 183 | description: Node describing the AB8500 battery temperature control block. | ||
| 184 | type: object | ||
| 185 | $ref: ../power/supply/stericsson,ab8500-btemp.yaml | ||
| 186 | |||
| 187 | ab8500_charger: | ||
| 188 | description: Node describing the AB8500 battery charger control block. | ||
| 189 | type: object | ||
| 190 | $ref: ../power/supply/stericsson,ab8500-charger.yaml | ||
| 191 | |||
| 192 | ab8500_chargalg: | ||
| 193 | description: Node describing the AB8500 battery charger algorithm. | ||
| 194 | type: object | ||
| 195 | $ref: ../power/supply/stericsson,ab8500-chargalg.yaml | ||
| 196 | |||
| 197 | phy: | ||
| 198 | description: Node describing the AB8500 USB PHY control block. | ||
| 199 | type: object | ||
| 200 | |||
| 201 | properties: | ||
| 202 | compatible: | ||
| 203 | const: stericsson,ab8500-usb | ||
| 204 | |||
| 205 | interrupts: | ||
| 206 | items: | ||
| 207 | - description: ID wakeup rising IRQ | ||
| 208 | - description: ID wakeup falling IRQ | ||
| 209 | - description: VBUS detection falling IRQ | ||
| 210 | - description: VBUS detection rising IRQ | ||
| 211 | - description: USB link status change IRQ | ||
| 212 | - description: ADP probe plug IRQ | ||
| 213 | - description: ADP probe unplug IRQ | ||
| 214 | |||
| 215 | interrupt-names: | ||
| 216 | items: | ||
| 217 | - const: ID_WAKEUP_R | ||
| 218 | - const: ID_WAKEUP_F | ||
| 219 | - const: VBUS_DET_F | ||
| 220 | - const: VBUS_DET_R | ||
| 221 | - const: USB_LINK_STATUS | ||
| 222 | - const: USB_ADP_PROBE_PLUG | ||
| 223 | - const: USB_ADP_PROBE_UNPLUG | ||
| 224 | |||
| 225 | vddulpivio18-supply: true | ||
| 226 | v-ape-supply: true | ||
| 227 | musb_1v8-supply: true | ||
| 228 | |||
| 229 | clocks: | ||
| 230 | items: | ||
| 231 | - description: PRCMY system clock | ||
| 232 | |||
| 233 | clock-names: | ||
| 234 | items: | ||
| 235 | - const: sysclk | ||
| 236 | |||
| 237 | '#phy-cells': | ||
| 238 | const: 0 | ||
| 239 | |||
| 240 | required: | ||
| 241 | - compatible | ||
| 242 | - interrupts | ||
| 243 | - interrupt-names | ||
| 244 | - vddulpivio18-supply | ||
| 245 | - v-ape-supply | ||
| 246 | - musb_1v8-supply | ||
| 247 | - clocks | ||
| 248 | - clock-names | ||
| 249 | - '#phy-cells' | ||
| 250 | |||
| 251 | additionalProperties: false | ||
| 252 | |||
| 253 | key: | ||
| 254 | description: Node describing the AB8500 power-on key control block. | ||
| 255 | type: object | ||
| 256 | |||
| 257 | properties: | ||
| 258 | compatible: | ||
| 259 | const: stericsson,ab8500-poweron-key | ||
| 260 | |||
| 261 | interrupts: | ||
| 262 | items: | ||
| 263 | - description: ON key falling IRQ | ||
| 264 | - description: ON key rising IRQ | ||
| 265 | |||
| 266 | interrupt-names: | ||
| 267 | items: | ||
| 268 | - const: ONKEY_DBF | ||
| 269 | - const: ONKEY_DBR | ||
| 270 | |||
| 271 | required: | ||
| 272 | - compatible | ||
| 273 | - interrupts | ||
| 274 | - interrupt-names | ||
| 275 | |||
| 276 | additionalProperties: false | ||
| 277 | |||
| 278 | ab8500-sysctrl: | ||
| 279 | description: Node describing the AB8500 system control block. | ||
| 280 | type: object | ||
| 281 | |||
| 282 | properties: | ||
| 283 | compatible: | ||
| 284 | const: stericsson,ab8500-sysctrl | ||
| 285 | |||
| 286 | required: | ||
| 287 | - compatible | ||
| 288 | |||
| 289 | additionalProperties: false | ||
| 290 | |||
| 291 | codec: | ||
| 292 | description: Node describing the AB8500 audio codec block. | ||
| 293 | type: object | ||
| 294 | |||
| 295 | properties: | ||
| 296 | compatible: | ||
| 297 | const: stericsson,ab8500-codec | ||
| 298 | |||
| 299 | V-AUD-supply: true | ||
| 300 | V-AMIC1-supply: true | ||
| 301 | V-AMIC2-supply: true | ||
| 302 | V-DMIC-supply: true | ||
| 303 | |||
| 304 | clocks: | ||
| 305 | items: | ||
| 306 | - description: Audio system clock | ||
| 307 | |||
| 308 | clock-names: | ||
| 309 | items: | ||
| 310 | - const: audioclk | ||
| 311 | |||
| 312 | stericsson,earpeice-cmv: | ||
| 313 | description: Earpeice voltage | ||
| 314 | $ref: /schemas/types.yaml#/definitions/uint32 | ||
| 315 | enum: [ 950, 1100, 1270, 1580 ] | ||
| 316 | |||
| 317 | required: | ||
| 318 | - compatible | ||
| 319 | |||
| 320 | additionalProperties: false | ||
| 321 | |||
| 322 | regulator: | ||
| 323 | description: Node describing the AB8500 internal regulators. | ||
| 324 | type: object | ||
| 325 | |||
| 326 | properties: | ||
| 327 | compatible: | ||
| 328 | enum: | ||
| 329 | - stericsson,ab8500-regulator | ||
| 330 | - stericsson,ab8505-regulator | ||
| 331 | |||
| 332 | vin-supply: | ||
| 333 | description: The regulator supplying all of the internal regulators | ||
| 334 | with power. | ||
| 335 | |||
| 336 | ab8500_ldo_aux1: | ||
| 337 | description: The voltage for the auxilary LDO regulator 1 | ||
| 338 | type: object | ||
| 339 | $ref: ../regulator/regulator.yaml# | ||
| 340 | |||
| 341 | ab8500_ldo_aux2: | ||
| 342 | description: The voltage for the auxilary LDO regulator 2 | ||
| 343 | type: object | ||
| 344 | $ref: ../regulator/regulator.yaml# | ||
| 345 | |||
| 346 | ab8500_ldo_aux3: | ||
| 347 | description: The voltage for the auxilary LDO regulator 3 | ||
| 348 | type: object | ||
| 349 | $ref: ../regulator/regulator.yaml# | ||
| 350 | |||
| 351 | ab8500_ldo_aux4: | ||
| 352 | description: The voltage for the auxilary LDO regulator 4 | ||
| 353 | only present on AB8505 | ||
| 354 | type: object | ||
| 355 | $ref: ../regulator/regulator.yaml# | ||
| 356 | |||
| 357 | ab8500_ldo_aux5: | ||
| 358 | description: The voltage for the auxilary LDO regulator 5 | ||
| 359 | only present on AB8505 | ||
| 360 | type: object | ||
| 361 | $ref: ../regulator/regulator.yaml# | ||
| 362 | |||
| 363 | ab8500_ldo_aux6: | ||
| 364 | description: The voltage for the auxilary LDO regulator 6 | ||
| 365 | only present on AB8505 | ||
| 366 | type: object | ||
| 367 | $ref: ../regulator/regulator.yaml# | ||
| 368 | |||
| 369 | # There is never any AUX7 regulator which is confusing | ||
| 370 | |||
| 371 | ab8500_ldo_aux8: | ||
| 372 | description: The voltage for the auxilary LDO regulator 8 | ||
| 373 | only present on AB8505 | ||
| 374 | type: object | ||
| 375 | $ref: ../regulator/regulator.yaml# | ||
| 376 | |||
| 377 | ab8500_ldo_intcore: | ||
| 378 | description: The LDO regulator for the internal core voltage | ||
| 379 | of the AB8500 | ||
| 380 | type: object | ||
| 381 | $ref: ../regulator/regulator.yaml# | ||
| 382 | |||
| 383 | ab8500_ldo_adc: | ||
| 384 | description: Analog power regulator for the analog to digital converter | ||
| 385 | ADC, only present on AB8505 | ||
| 386 | type: object | ||
| 387 | $ref: ../regulator/regulator.yaml# | ||
| 388 | |||
| 389 | ab8500_ldo_tvout: | ||
| 390 | description: The voltage for the TV output regulator, incidentally | ||
| 391 | this voltage is also used for other purposes such as measuring | ||
| 392 | the temperature of the NTC thermistor on the battery. | ||
| 393 | Only present on AB8500. | ||
| 394 | type: object | ||
| 395 | $ref: ../regulator/regulator.yaml# | ||
| 396 | |||
| 397 | ab8500_ldo_audio: | ||
| 398 | description: The LDO regulator for the audio codec output | ||
| 399 | type: object | ||
| 400 | $ref: ../regulator/regulator.yaml# | ||
| 401 | |||
| 402 | ab8500_ldo_anamic1: | ||
| 403 | description: The LDO regulator for the analog microphone 1 | ||
| 404 | type: object | ||
| 405 | $ref: ../regulator/regulator.yaml# | ||
| 406 | |||
| 407 | ab8500_ldo_anamic2: | ||
| 408 | description: The LDO regulator for the analog microphone 2 | ||
| 409 | type: object | ||
| 410 | $ref: ../regulator/regulator.yaml# | ||
| 411 | |||
| 412 | ab8500_ldo_dmic: | ||
| 413 | description: The LDO regulator for the digital microphone | ||
| 414 | only present on AB8500 | ||
| 415 | type: object | ||
| 416 | $ref: ../regulator/regulator.yaml# | ||
| 417 | |||
| 418 | ab8500_ldo_ana: | ||
| 419 | description: Analog power regulator for CSI and DSI interfaces, | ||
| 420 | Camera Serial Interface CSI and Display Serial Interface DSI. | ||
| 421 | type: object | ||
| 422 | $ref: ../regulator/regulator.yaml# | ||
| 423 | |||
| 424 | required: | ||
| 425 | - compatible | ||
| 426 | |||
| 427 | additionalProperties: false | ||
| 428 | |||
| 429 | |||
| 430 | regulator-external: | ||
| 431 | description: Node describing the AB8500 external regulators. This | ||
| 432 | concerns the autonomous regulators VSMPS1, VSMPS2 and VSMPS3 | ||
| 433 | that are normally controlled by external electronics but also | ||
| 434 | sometimes need to be explicitly controlled by software. | ||
| 435 | type: object | ||
| 436 | |||
| 437 | properties: | ||
| 438 | compatible: | ||
| 439 | const: stericsson,ab8500-ext-regulator | ||
| 440 | |||
| 441 | ab8500_ext1: | ||
| 442 | description: The voltage for the VSMPS1 external regulator | ||
| 443 | type: object | ||
| 444 | $ref: ../regulator/regulator.yaml# | ||
| 445 | |||
| 446 | ab8500_ext2: | ||
| 447 | description: The voltage for the VSMPS2 external regulator | ||
| 448 | type: object | ||
| 449 | $ref: ../regulator/regulator.yaml# | ||
| 450 | |||
| 451 | ab8500_ext3: | ||
| 452 | description: The voltage for the VSMPS3 external regulator | ||
| 453 | type: object | ||
| 454 | $ref: ../regulator/regulator.yaml# | ||
| 455 | |||
| 456 | required: | ||
| 457 | - compatible | ||
| 458 | |||
| 459 | additionalProperties: false | ||
| 460 | |||
| 461 | patternProperties: | ||
| 462 | "^pwm@[1-9]+?$": | ||
| 463 | type: object | ||
| 464 | $ref: ../pwm/pwm.yaml# | ||
| 465 | description: Represents each of the PWM blocks in the AB8500 | ||
| 466 | |||
| 467 | properties: | ||
| 468 | compatible: | ||
| 469 | const: stericsson,ab8500-pwm | ||
| 470 | |||
| 471 | reg: true | ||
| 472 | |||
| 473 | clocks: | ||
| 474 | items: | ||
| 475 | - description: internal clock | ||
| 476 | |||
| 477 | clock-names: | ||
| 478 | items: | ||
| 479 | - const: intclk | ||
| 480 | |||
| 481 | required: | ||
| 482 | - compatible | ||
| 483 | - reg | ||
| 484 | |||
| 485 | required: | ||
| 486 | - compatible | ||
| 487 | - clock-controller | ||
| 488 | - gpio | ||
| 489 | - rtc | ||
| 490 | - adc | ||
| 491 | - thermal | ||
| 492 | - ab8500_fg | ||
| 493 | - ab8500_btemp | ||
| 494 | - ab8500_charger | ||
| 495 | - ab8500_chargalg | ||
| 496 | - phy | ||
| 497 | - key | ||
| 498 | - regulator | ||
| 499 | |||
| 500 | additionalProperties: false | ||
| @@ -263,6 +263,7 @@ patternProperties: · 262 unmodified lines | |||
| 263 | set of devicetree bindings. The AB8505 is a newer version of the | 263 | set of devicetree bindings. The AB8505 is a newer version of the |
| 264 | same ASIC. | 264 | same ASIC. |
| 265 | type: object | 265 | type: object |
| 266 | $ref: stericsson,ab8500.yaml# | ||
| 266 | 267 | ||
| 267 | required: | 268 | required: |
| 268 | - compatible | 269 | - compatible |
| @@ -44,6 +44,11 @@ properties: · 43 unmodified lines | |||
| 44 | - hisilicon,hi6220-sramctrl | 44 | - hisilicon,hi6220-sramctrl |
| 45 | - hisilicon,pcie-sas-subctrl | 45 | - hisilicon,pcie-sas-subctrl |
| 46 | - hisilicon,peri-subctrl | 46 | - hisilicon,peri-subctrl |
| 47 | - intel,lgm-syscon | ||
| 48 | - marvell,armada-3700-usb2-host-misc | ||
| 49 | - mediatek,mt8135-pctl-a-syscfg | ||
| 50 | - mediatek,mt8135-pctl-b-syscfg | ||
| 51 | - microchip,lan966x-cpu-syscon | ||
| 47 | - microchip,sparx5-cpu-syscon | 52 | - microchip,sparx5-cpu-syscon |
| 48 | - mstar,msc313-pmsleep | 53 | - mstar,msc313-pmsleep |
| 49 | - rockchip,px30-qos | 54 | - rockchip,px30-qos |
| @@ -0,0 +1,70 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/power/supply/maxim,max77693.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Maxim MAX77693 MicroUSB and Companion Power Management IC Charger | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 11 | |||
| 12 | description: | | ||
| 13 | This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated | ||
| 14 | Circuit (MUIC). | ||
| 15 | |||
| 16 | See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for | ||
| 17 | additional information and example. | ||
| 18 | |||
| 19 | properties: | ||
| 20 | compatible: | ||
| 21 | const: maxim,max77693-charger | ||
| 22 | |||
| 23 | maxim,constant-microvolt: | ||
| 24 | description: | | ||
| 25 | Battery constant voltage in uV. The charger will operate in fast | ||
| 26 | charge constant current mode till battery voltage reaches this level. | ||
| 27 | Then the charger will switch to fast charge constant voltage mode. | ||
| 28 | Also vsys (system voltage) will be set to this value when DC power is | ||
| 29 | supplied but charger is not enabled. | ||
| 30 | Valid values: 3650000 - 4400000, step by 25000 (rounded down) | ||
| 31 | minimum: 3650000 | ||
| 32 | maximum: 4400000 | ||
| 33 | default: 4200000 | ||
| 34 | |||
| 35 | maxim,min-system-microvolt: | ||
| 36 | description: | | ||
| 37 | Minimal system voltage in uV. | ||
| 38 | enum: [3000000, 3100000, 3200000, 3300000, 3400000, 3500000, | ||
| 39 | 3600000, 3700000] | ||
| 40 | default: 3600000 | ||
| 41 | |||
| 42 | maxim,thermal-regulation-celsius: | ||
| 43 | description: | | ||
| 44 | Temperature in Celsius for entering high temperature charging mode. | ||
| 45 | If die temperature exceeds this value the charging current will be | ||
| 46 | reduced by 105 mA/Celsius. | ||
| 47 | enum: [70, 85, 100, 115] | ||
| 48 | default: 100 | ||
| 49 | |||
| 50 | maxim,battery-overcurrent-microamp: | ||
| 51 | description: | | ||
| 52 | Overcurrent protection threshold in uA (current from battery to | ||
| 53 | system). | ||
| 54 | Valid values: 2000000 - 3500000, step by 250000 (rounded down) | ||
| 55 | minimum: 2000000 | ||
| 56 | maximum: 3500000 | ||
| 57 | default: 3500000 | ||
| 58 | |||
| 59 | maxim,charge-input-threshold-microvolt: | ||
| 60 | description: | | ||
| 61 | Threshold voltage in uV for triggering input voltage regulation loop. | ||
| 62 | If input voltage decreases below this value, the input current will | ||
| 63 | be reduced to reach the threshold voltage. | ||
| 64 | enum: [4300000, 4700000, 4800000, 4900000] | ||
| 65 | default: 4300000 | ||
| 66 | |||
| 67 | required: | ||
| 68 | - compatible | ||
| 69 | |||
| 70 | additionalProperties: false | ||
| @@ -0,0 +1,60 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause | ||
| 2 | %YAML 1.2 | ||
| 3 | --- | ||
| 4 | $id: http://devicetree.org/schemas/regulator/maxim,max77693.yaml# | ||
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
| 6 | |||
| 7 | title: Maxim MAX77693 MicroUSB and Companion Power Management IC regulators | ||
| 8 | |||
| 9 | maintainers: | ||
| 10 | - Chanwoo Choi <cw00.choi@samsung.com> | ||
| 11 | - Krzysztof Kozlowski <krzysztof.kozlowski@canonical.com> | ||
| 12 | |||
| 13 | description: | | ||
| 14 | This is a part of device tree bindings for Maxim MAX77693 MicroUSB Integrated | ||
| 15 | Circuit (MUIC). | ||
| 16 | |||
| 17 | See also Documentation/devicetree/bindings/mfd/maxim,max77693.yaml for | ||
| 18 | additional information and example. | ||
| 19 | |||
| 20 | properties: | ||
| 21 | CHARGER: | ||
| 22 | type: object | ||
| 23 | $ref: regulator.yaml# | ||
| 24 | additionalProperties: false | ||
| 25 | description: | | ||
| 26 | Current regulator. | ||
| 27 | |||
| 28 | properties: | ||
| 29 | regulator-name: true | ||
| 30 | regulator-always-on: true | ||
| 31 | regulator-boot-on: true | ||
| 32 | regulator-min-microamp: | ||
| 33 | minimum: 60000 | ||
| 34 | regulator-max-microamp: | ||
| 35 | maximum: 2580000 | ||
| 36 | |||
| 37 | required: | ||
| 38 | - regulator-name | ||
| 39 | |||
| 40 | patternProperties: | ||
| 41 | "^ESAFEOUT[12]$": | ||
| 42 | type: object | ||
| 43 | $ref: regulator.yaml# | ||
| 44 | additionalProperties: false | ||
| 45 | description: | | ||
| 46 | Safeout LDO regulator. | ||
| 47 | |||
| 48 | properties: | ||
| 49 | regulator-name: true | ||
| 50 | regulator-always-on: true | ||
| 51 | regulator-boot-on: true | ||
| 52 | regulator-min-microvolt: | ||
| 53 | minimum: 3300000 | ||
| 54 | regulator-max-microvolt: | ||
| 55 | maximum: 4950000 | ||
| 56 | |||
| 57 | required: | ||
| 58 | - regulator-name | ||
| 59 | |||
| 60 | additionalProperties: false | ||
| @@ -187,6 +187,7 @@ Hardware Monitoring Kernel Drivers · 186 unmodified lines | |||
| 187 | smsc47m1 | 187 | smsc47m1 |
| 188 | sparx5-temp | 188 | sparx5-temp |
| 189 | stpddc60 | 189 | stpddc60 |
| 190 | sy7636a-hwmon | ||
| 190 | tc654 | 191 | tc654 |
| 191 | tc74 | 192 | tc74 |
| 192 | thmc50 | 193 | thmc50 |
| @@ -0,0 +1,26 @@ | |||
| 1 | .. SPDX-License-Identifier: GPL-2.0-or-later | ||
| 2 | |||
| 3 | Kernel driver sy7636a-hwmon | ||
| 4 | =========================== | ||
| 5 | |||
| 6 | Supported chips: | ||
| 7 | |||
| 8 | * Silergy SY7636A PMIC | ||
| 9 | |||
| 10 | |||
| 11 | Description | ||
| 12 | ----------- | ||
| 13 | |||
| 14 | This driver adds hardware temperature reading support for | ||
| 15 | the Silergy SY7636A PMIC. | ||
| 16 | |||
| 17 | The following sensors are supported | ||
| 18 | |||
| 19 | * Temperature | ||
| 20 | - SoC on-die temperature in milli-degree C | ||
| 21 | |||
| 22 | sysfs-Interface | ||
| 23 | --------------- | ||
| 24 | |||
| 25 | temp0_input | ||
| 26 | - SoC on-die temperature (milli-degree C) | ||
| @@ -11824,6 +11824,13 @@ F: drivers/power/supply/max77650-charger.c · 11823 unmodified lines | |||
| 11824 | F: drivers/regulator/max77650-regulator.c | 11824 | F: drivers/regulator/max77650-regulator.c |
| 11825 | F: include/linux/mfd/max77650.h | 11825 | F: include/linux/mfd/max77650.h |
| 11826 | 11826 | ||
| 11827 | MAXIM MAX77714 PMIC MFD DRIVER | ||
| 11828 | M: Luca Ceresoli <luca@lucaceresoli.net> | ||
| 11829 | S: Maintained | ||
| 11830 | F: Documentation/devicetree/bindings/mfd/maxim,max77714.yaml | ||
| 11831 | F: drivers/mfd/max77714.c | ||
| 11832 | F: include/linux/mfd/max77714.h | ||
| 11833 | |||
| 11827 | MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER | 11834 | MAXIM MAX77802 PMIC REGULATOR DEVICE DRIVER |
| 11828 | M: Javier Martinez Canillas <javier@dowhile0.org> | 11835 | M: Javier Martinez Canillas <javier@dowhile0.org> |
| 11829 | L: linux-kernel@vger.kernel.org | 11836 | L: linux-kernel@vger.kernel.org |
| @@ -11844,6 +11851,7 @@ M: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> · 14 unmodified lines | |||
| 11844 | L: linux-pm@vger.kernel.org | 11851 | L: linux-pm@vger.kernel.org |
| 11845 | S: Supported | 11852 | S: Supported |
| 11846 | F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml | 11853 | F: Documentation/devicetree/bindings/power/supply/maxim,max14577.yaml |
| 11854 | F: Documentation/devicetree/bindings/power/supply/maxim,max77693.yaml | ||
| 11847 | F: drivers/power/supply/max14577_charger.c | 11855 | F: drivers/power/supply/max14577_charger.c |
| 11848 | F: drivers/power/supply/max77693_charger.c | 11856 | F: drivers/power/supply/max77693_charger.c |
| 11849 | 11857 | ||
| @@ -11855,6 +11863,7 @@ L: linux-kernel@vger.kernel.org · 5 unmodified lines | |||
| 11855 | S: Supported | 11863 | S: Supported |
| 11856 | F: Documentation/devicetree/bindings/*/maxim,max14577.yaml | 11864 | F: Documentation/devicetree/bindings/*/maxim,max14577.yaml |
| 11857 | F: Documentation/devicetree/bindings/*/maxim,max77686.yaml | 11865 | F: Documentation/devicetree/bindings/*/maxim,max77686.yaml |
| 11866 | F: Documentation/devicetree/bindings/*/maxim,max77693.yaml | ||
| 11858 | F: Documentation/devicetree/bindings/*/maxim,max77843.yaml | 11867 | F: Documentation/devicetree/bindings/*/maxim,max77843.yaml |
| 11859 | F: Documentation/devicetree/bindings/clock/maxim,max77686.txt | 11868 | F: Documentation/devicetree/bindings/clock/maxim,max77686.txt |
| 11860 | F: Documentation/devicetree/bindings/mfd/max77693.txt | 11869 | F: Documentation/devicetree/bindings/mfd/max77693.txt |
| @@ -16842,7 +16851,7 @@ M: Marek Vasut <marek.vasut+renesas@gmail.com> · 4981 unmodified lines | |||
| 16842 | L: linux-kernel@vger.kernel.org | 16851 | L: linux-kernel@vger.kernel.org |
| 16843 | L: linux-renesas-soc@vger.kernel.org | 16852 | L: linux-renesas-soc@vger.kernel.org |
| 16844 | S: Supported | 16853 | S: Supported |
| 16845 | F: Documentation/devicetree/bindings/mfd/bd9571mwv.txt | 16854 | F: Documentation/devicetree/bindings/mfd/rohm,bd9571mwv.yaml |
| 16846 | F: drivers/gpio/gpio-bd9571mwv.c | 16855 | F: drivers/gpio/gpio-bd9571mwv.c |
| 16847 | F: drivers/mfd/bd9571mwv.c | 16856 | F: drivers/mfd/bd9571mwv.c |
| 16848 | F: drivers/regulator/bd9571mwv-regulator.c | 16857 | F: drivers/regulator/bd9571mwv-regulator.c |
| @@ -1689,6 +1689,15 @@ config SENSORS_SIS5595 · 1688 unmodified lines | |||
| 1689 | This driver can also be built as a module. If so, the module | 1689 | This driver can also be built as a module. If so, the module |
| 1690 | will be called sis5595. | 1690 | will be called sis5595. |
| 1691 | 1691 | ||
| 1692 | config SENSORS_SY7636A | ||
| 1693 | tristate "Silergy SY7636A" | ||
| 1694 | help | ||
| 1695 | If you say yes here you get support for the thermistor readout of | ||
| 1696 | the Silergy SY7636A PMIC. | ||
| 1697 | |||
| 1698 | This driver can also be built as a module. If so, the module | ||
| 1699 | will be called sy7636a-hwmon. | ||
| 1700 | |||
| 1692 | config SENSORS_DME1737 | 1701 | config SENSORS_DME1737 |
| 1693 | tristate "SMSC DME1737, SCH311x and compatibles" | 1702 | tristate "SMSC DME1737, SCH311x and compatibles" |
| 1694 | depends on I2C && !PPC | 1703 | depends on I2C && !PPC |
| @@ -187,6 +187,7 @@ obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o · 186 unmodified lines | |||
| 187 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o | 187 | obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o |
| 188 | obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o | 188 | obj-$(CONFIG_SENSORS_SPARX5) += sparx5-temp.o |
| 189 | obj-$(CONFIG_SENSORS_STTS751) += stts751.o | 189 | obj-$(CONFIG_SENSORS_STTS751) += stts751.o |
| 190 | obj-$(CONFIG_SENSORS_SY7636A) += sy7636a-hwmon.o | ||
| 190 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o | 191 | obj-$(CONFIG_SENSORS_AMC6821) += amc6821.o |
| 191 | obj-$(CONFIG_SENSORS_TC74) += tc74.o | 192 | obj-$(CONFIG_SENSORS_TC74) += tc74.o |
| 192 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o | 193 | obj-$(CONFIG_SENSORS_THMC50) += thmc50.o |
| @@ -0,0 +1,106 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0+ | ||
| 2 | /* | ||
| 3 | * Functions to access SY3686A power management chip temperature | ||
| 4 | * | ||
| 5 | * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/ | ||
| 6 | * | ||
| 7 | * Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com> | ||
| 8 | * Alistair Francis <alistair@alistair23.me> | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/err.h> | ||
| 12 | #include <linux/hwmon.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/module.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/regmap.h> | ||
| 17 | #include <linux/regulator/machine.h> | ||
| 18 | |||
| 19 | #include <linux/mfd/sy7636a.h> | ||
| 20 | |||
| 21 | static int sy7636a_read(struct device *dev, enum hwmon_sensor_types type, | ||
| 22 | u32 attr, int channel, long *temp) | ||
| 23 | { | ||
| 24 | struct regmap *regmap = dev_get_drvdata(dev); | ||
| 25 | int ret, reg_val; | ||
| 26 | |||
| 27 | ret = regmap_read(regmap, | ||
| 28 | SY7636A_REG_TERMISTOR_READOUT, ®_val); | ||
| 29 | if (ret) | ||
| 30 | return ret; | ||
| 31 | |||
| 32 | *temp = reg_val * 1000; | ||
| 33 | |||
| 34 | return 0; | ||
| 35 | } | ||
| 36 | |||
| 37 | static umode_t sy7636a_is_visible(const void *data, | ||
| 38 | enum hwmon_sensor_types type, | ||
| 39 | u32 attr, int channel) | ||
| 40 | { | ||
| 41 | if (type != hwmon_temp) | ||
| 42 | return 0; | ||
| 43 | |||
| 44 | if (attr != hwmon_temp_input) | ||
| 45 | return 0; | ||
| 46 | |||
| 47 | return 0444; | ||
| 48 | } | ||
| 49 | |||
| 50 | static const struct hwmon_ops sy7636a_hwmon_ops = { | ||
| 51 | .is_visible = sy7636a_is_visible, | ||
| 52 | .read = sy7636a_read, | ||
| 53 | }; | ||
| 54 | |||
| 55 | static const struct hwmon_channel_info *sy7636a_info[] = { | ||
| 56 | HWMON_CHANNEL_INFO(chip, HWMON_C_REGISTER_TZ), | ||
| 57 | HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), | ||
| 58 | NULL | ||
| 59 | }; | ||
| 60 | |||
| 61 | static const struct hwmon_chip_info sy7636a_chip_info = { | ||
| 62 | .ops = &sy7636a_hwmon_ops, | ||
| 63 | .info = sy7636a_info, | ||
| 64 | }; | ||
| 65 | |||
| 66 | static int sy7636a_sensor_probe(struct platform_device *pdev) | ||
| 67 | { | ||
| 68 | struct regmap *regmap = dev_get_regmap(pdev->dev.parent, NULL); | ||
| 69 | struct regulator *regulator; | ||
| 70 | struct device *hwmon_dev; | ||
| 71 | int err; | ||
| 72 | |||
| 73 | if (!regmap) | ||
| 74 | return -EPROBE_DEFER; | ||
| 75 | |||
| 76 | regulator = devm_regulator_get(&pdev->dev, "vcom"); | ||
| 77 | if (IS_ERR(regulator)) | ||
| 78 | return PTR_ERR(regulator); | ||
| 79 | |||
| 80 | err = regulator_enable(regulator); | ||
| 81 | if (err) | ||
| 82 | return err; | ||
| 83 | |||
| 84 | hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, | ||
| 85 | "sy7636a_temperature", regmap, | ||
| 86 | &sy7636a_chip_info, NULL); | ||
| 87 | |||
| 88 | if (IS_ERR(hwmon_dev)) { | ||
| 89 | err = PTR_ERR(hwmon_dev); | ||
| 90 | dev_err(&pdev->dev, "Unable to register hwmon device, returned %d\n", err); | ||
| 91 | return err; | ||
| 92 | } | ||
| 93 | |||
| 94 | return 0; | ||
| 95 | } | ||
| 96 | |||
| 97 | static struct platform_driver sy7636a_sensor_driver = { | ||
| 98 | .probe = sy7636a_sensor_probe, | ||
| 99 | .driver = { | ||
| 100 | .name = "sy7636a-temperature", | ||
| 101 | }, | ||
| 102 | }; | ||
| 103 | module_platform_driver(sy7636a_sensor_driver); | ||
| 104 | |||
| 105 | MODULE_DESCRIPTION("SY7636A sensor driver"); | ||
| 106 | MODULE_LICENSE("GPL"); | ||
| @@ -17,6 +17,7 @@ · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | #define IQS620_TEMP_SCALE 1000 | 18 | #define IQS620_TEMP_SCALE 1000 |
| 19 | #define IQS620_TEMP_OFFSET (-100) | 19 | #define IQS620_TEMP_OFFSET (-100) |
| 20 | #define IQS620_TEMP_OFFSET_V3 (-40) | ||
| 20 | 21 | ||
| 21 | static int iqs620_temp_read_raw(struct iio_dev *indio_dev, | 22 | static int iqs620_temp_read_raw(struct iio_dev *indio_dev, |
| 22 | struct iio_chan_spec const *chan, | 23 | struct iio_chan_spec const *chan, |
| @@ -41,7 +42,8 @@ static int iqs620_temp_read_raw(struct iio_dev *indio_dev, · 18 unmodified lines | |||
| 41 | return IIO_VAL_INT; | 42 | return IIO_VAL_INT; |
| 42 | 43 | ||
| 43 | case IIO_CHAN_INFO_OFFSET: | 44 | case IIO_CHAN_INFO_OFFSET: |
| 44 | *val = IQS620_TEMP_OFFSET; | 45 | *val = iqs62x->hw_num < IQS620_HW_NUM_V3 ? IQS620_TEMP_OFFSET |
| 46 | : IQS620_TEMP_OFFSET_V3; | ||
| 45 | return IIO_VAL_INT; | 47 | return IIO_VAL_INT; |
| 46 | 48 | ||
| 47 | default: | 49 | default: |
| @@ -849,6 +849,20 @@ config MFD_MAX77693 · 848 unmodified lines | |||
| 849 | additional drivers must be enabled in order to use the functionality | 849 | additional drivers must be enabled in order to use the functionality |
| 850 | of the device. | 850 | of the device. |
| 851 | 851 | ||
| 852 | config MFD_MAX77714 | ||
| 853 | tristate "Maxim Semiconductor MAX77714 PMIC Support" | ||
| 854 | depends on I2C | ||
| 855 | depends on OF || COMPILE_TEST | ||
| 856 | select MFD_CORE | ||
| 857 | select REGMAP_I2C | ||
| 858 | help | ||
| 859 | Say yes here to add support for Maxim Semiconductor MAX77714. | ||
| 860 | This is a Power Management IC with 4 buck regulators, 9 | ||
| 861 | low-dropout regulators, 8 GPIOs, RTC, watchdog etc. This driver | ||
| 862 | provides common support for accessing the device; additional | ||
| 863 | drivers must be enabled in order to use each functionality of the | ||
| 864 | device. | ||
| 865 | |||
| 852 | config MFD_MAX77843 | 866 | config MFD_MAX77843 |
| 853 | bool "Maxim Semiconductor MAX77843 PMIC Support" | 867 | bool "Maxim Semiconductor MAX77843 PMIC Support" |
| 854 | depends on I2C=y | 868 | depends on I2C=y |
| @@ -1188,7 +1202,7 @@ config MFD_SI476X_CORE · 333 unmodified lines | |||
| 1188 | module will be called si476x-core. | 1202 | module will be called si476x-core. |
| 1189 | 1203 | ||
| 1190 | config MFD_SIMPLE_MFD_I2C | 1204 | config MFD_SIMPLE_MFD_I2C |
| 1191 | tristate | 1205 | tristate "Simple Multi-Functional Device support (I2C)" |
| 1192 | depends on I2C | 1206 | depends on I2C |
| 1193 | select MFD_CORE | 1207 | select MFD_CORE |
| 1194 | select REGMAP_I2C | 1208 | select REGMAP_I2C |
| @@ -1283,14 +1297,6 @@ config AB8500_CORE · 88 unmodified lines | |||
| 1283 | the irq_chip parts for handling the Mixed Signal chip events. | 1297 | the irq_chip parts for handling the Mixed Signal chip events. |
| 1284 | This chip embeds various other multimedia functionalities as well. | 1298 | This chip embeds various other multimedia functionalities as well. |
| 1285 | 1299 | ||
| 1286 | config AB8500_DEBUG | ||
| 1287 | bool "Enable debug info via debugfs" | ||
| 1288 | depends on AB8500_GPADC && DEBUG_FS | ||
| 1289 | default y if DEBUG_FS | ||
| 1290 | help | ||
| 1291 | Select this option if you want debug information using the debug | ||
| 1292 | filesystem, debugfs. | ||
| 1293 | |||
| 1294 | config MFD_DB8500_PRCMU | 1300 | config MFD_DB8500_PRCMU |
| 1295 | bool "ST-Ericsson DB8500 Power Reset Control Management Unit" | 1301 | bool "ST-Ericsson DB8500 Power Reset Control Management Unit" |
| 1296 | depends on UX500_SOC_DB8500 | 1302 | depends on UX500_SOC_DB8500 |
| @@ -162,6 +162,7 @@ obj-$(CONFIG_MFD_MAX77620) += max77620.o · 161 unmodified lines | |||
| 162 | obj-$(CONFIG_MFD_MAX77650) += max77650.o | 162 | obj-$(CONFIG_MFD_MAX77650) += max77650.o |
| 163 | obj-$(CONFIG_MFD_MAX77686) += max77686.o | 163 | obj-$(CONFIG_MFD_MAX77686) += max77686.o |
| 164 | obj-$(CONFIG_MFD_MAX77693) += max77693.o | 164 | obj-$(CONFIG_MFD_MAX77693) += max77693.o |
| 165 | obj-$(CONFIG_MFD_MAX77714) += max77714.o | ||
| 165 | obj-$(CONFIG_MFD_MAX77843) += max77843.o | 166 | obj-$(CONFIG_MFD_MAX77843) += max77843.o |
| 166 | obj-$(CONFIG_MFD_MAX8907) += max8907.o | 167 | obj-$(CONFIG_MFD_MAX8907) += max8907.o |
| 167 | max8925-objs := max8925-core.o max8925-i2c.o | 168 | max8925-objs := max8925-core.o max8925-i2c.o |
| @@ -176,7 +177,6 @@ obj-$(CONFIG_MFD_PCF50633) += pcf50633.o · 8 unmodified lines | |||
| 176 | obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o | 177 | obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o |
| 177 | obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o | 178 | obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o |
| 178 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o | 179 | obj-$(CONFIG_ABX500_CORE) += abx500-core.o |
| 179 | obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o | ||
| 180 | obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o | 180 | obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o |
| 181 | # ab8500-core need to come after db8500-prcmu (which provides the channel) | 181 | # ab8500-core need to come after db8500-prcmu (which provides the channel) |
| 182 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o | 182 | obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o |
| @@ -613,10 +613,6 @@ static const struct mfd_cell ab8500_bm_devs[] = { · 612 unmodified lines | |||
| 613 | }; | 613 | }; |
| 614 | 614 | ||
| 615 | static const struct mfd_cell ab8500_devs[] = { | 615 | static const struct mfd_cell ab8500_devs[] = { |
| 616 | #ifdef CONFIG_DEBUG_FS | ||
| 617 | MFD_CELL_OF("ab8500-debug", | ||
| 618 | NULL, NULL, 0, 0, "stericsson,ab8500-debug"), | ||
| 619 | #endif | ||
| 620 | MFD_CELL_OF("ab8500-sysctrl", | 616 | MFD_CELL_OF("ab8500-sysctrl", |
| 621 | NULL, NULL, 0, 0, "stericsson,ab8500-sysctrl"), | 617 | NULL, NULL, 0, 0, "stericsson,ab8500-sysctrl"), |
| 622 | MFD_CELL_OF("ab8500-ext-regulator", | 618 | MFD_CELL_OF("ab8500-ext-regulator", |
| @@ -652,11 +648,6 @@ static const struct mfd_cell ab8500_devs[] = { · 29 unmodified lines | |||
| 652 | }; | 648 | }; |
| 653 | 649 | ||
| 654 | static const struct mfd_cell ab9540_devs[] = { | 650 | static const struct mfd_cell ab9540_devs[] = { |
| 655 | #ifdef CONFIG_DEBUG_FS | ||
| 656 | { | ||
| 657 | .name = "ab8500-debug", | ||
| 658 | }, | ||
| 659 | #endif | ||
| 660 | { | 651 | { |
| 661 | .name = "ab8500-sysctrl", | 652 | .name = "ab8500-sysctrl", |
| 662 | }, | 653 | }, |
| @@ -707,12 +698,6 @@ static const struct mfd_cell ab9540_devs[] = { · 44 unmodified lines | |||
| 707 | 698 | ||
| 708 | /* Device list for ab8505 */ | 699 | /* Device list for ab8505 */ |
| 709 | static const struct mfd_cell ab8505_devs[] = { | 700 | static const struct mfd_cell ab8505_devs[] = { |
| 710 | #ifdef CONFIG_DEBUG_FS | ||
| 711 | { | ||
| 712 | .name = "ab8500-debug", | ||
| 713 | .of_compatible = "stericsson,ab8500-debug", | ||
| 714 | }, | ||
| 715 | #endif | ||
| 716 | { | 701 | { |
| 717 | .name = "ab8500-sysctrl", | 702 | .name = "ab8500-sysctrl", |
| 718 | .of_compatible = "stericsson,ab8500-sysctrl", | 703 | .of_compatible = "stericsson,ab8500-sysctrl", |
| @@ -764,11 +749,6 @@ static const struct mfd_cell ab8505_devs[] = { · 45 unmodified lines | |||
| 764 | }; | 749 | }; |
| 765 | 750 | ||
| 766 | static const struct mfd_cell ab8540_devs[] = { | 751 | static const struct mfd_cell ab8540_devs[] = { |
| 767 | #ifdef CONFIG_DEBUG_FS | ||
| 768 | { | ||
| 769 | .name = "ab8500-debug", | ||
| 770 | }, | ||
| 771 | #endif | ||
| 772 | { | 752 | { |
| 773 | .name = "ab8500-sysctrl", | 753 | .name = "ab8500-sysctrl", |
| 774 | }, | 754 | }, |
| @@ -1042,9 +1022,9 @@ static int ab8500_probe(struct platform_device *pdev) · 267 unmodified lines | |||
| 1042 | enum ab8500_version version = AB8500_VERSION_UNDEFINED; | 1022 | enum ab8500_version version = AB8500_VERSION_UNDEFINED; |
| 1043 | struct device_node *np = pdev->dev.of_node; | 1023 | struct device_node *np = pdev->dev.of_node; |
| 1044 | struct ab8500 *ab8500; | 1024 | struct ab8500 *ab8500; |
| 1045 | struct resource *resource; | ||
| 1046 | int ret; | 1025 | int ret; |
| 1047 | int i; | 1026 | int i; |
| 1027 | int irq; | ||
| 1048 | u8 value; | 1028 | u8 value; |
| 1049 | 1029 | ||
| 1050 | ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); | 1030 | ab8500 = devm_kzalloc(&pdev->dev, sizeof(*ab8500), GFP_KERNEL); |
| @@ -1053,13 +1033,11 @@ static int ab8500_probe(struct platform_device *pdev) · 2 unmodified lines | |||
| 1053 | 1033 | ||
| 1054 | ab8500->dev = &pdev->dev; | 1034 | ab8500->dev = &pdev->dev; |
| 1055 | 1035 | ||
| 1056 | resource = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 1036 | irq = platform_get_irq(pdev, 0); |
| 1057 | if (!resource) { | 1037 | if (irq < 0) |
| 1058 | dev_err(&pdev->dev, "no IRQ resource\n"); | 1038 | return irq; |
| 1059 | return -ENODEV; | ||
| 1060 | } | ||
| 1061 | 1039 | ||
| 1062 | ab8500->irq = resource->start; | 1040 | ab8500->irq = irq; |
| 1063 | 1041 | ||
| 1064 | ab8500->read = ab8500_prcmu_read; | 1042 | ab8500->read = ab8500_prcmu_read; |
| 1065 | ab8500->write = ab8500_prcmu_write; | 1043 | ab8500->write = ab8500_prcmu_write; |
| @@ -1,2096 +0,0 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Copyright (C) ST-Ericsson SA 2010 | ||
| 4 | * | ||
| 5 | * Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson. | ||
| 6 | */ | ||
| 7 | /* | ||
| 8 | * AB8500 register access | ||
| 9 | * ====================== | ||
| 10 | * | ||
| 11 | * read: | ||
| 12 | * # echo BANK > <debugfs>/ab8500/register-bank | ||
| 13 | * # echo ADDR > <debugfs>/ab8500/register-address | ||
| 14 | * # cat <debugfs>/ab8500/register-value | ||
| 15 | * | ||
| 16 | * write: | ||
| 17 | * # echo BANK > <debugfs>/ab8500/register-bank | ||
| 18 | * # echo ADDR > <debugfs>/ab8500/register-address | ||
| 19 | * # echo VALUE > <debugfs>/ab8500/register-value | ||
| 20 | * | ||
| 21 | * read all registers from a bank: | ||
| 22 | * # echo BANK > <debugfs>/ab8500/register-bank | ||
| 23 | * # cat <debugfs>/ab8500/all-bank-register | ||
| 24 | * | ||
| 25 | * BANK target AB8500 register bank | ||
| 26 | * ADDR target AB8500 register address | ||
| 27 | * VALUE decimal or 0x-prefixed hexadecimal | ||
| 28 | * | ||
| 29 | * | ||
| 30 | * User Space notification on AB8500 IRQ | ||
| 31 | * ===================================== | ||
| 32 | * | ||
| 33 | * Allows user space entity to be notified when target AB8500 IRQ occurs. | ||
| 34 | * When subscribed, a sysfs entry is created in ab8500.i2c platform device. | ||
| 35 | * One can pool this file to get target IRQ occurence information. | ||
| 36 | * | ||
| 37 | * subscribe to an AB8500 IRQ: | ||
| 38 | * # echo IRQ > <debugfs>/ab8500/irq-subscribe | ||
| 39 | * | ||
| 40 | * unsubscribe from an AB8500 IRQ: | ||
| 41 | * # echo IRQ > <debugfs>/ab8500/irq-unsubscribe | ||
| 42 | * | ||
| 43 | * | ||
| 44 | * AB8500 register formated read/write access | ||
| 45 | * ========================================== | ||
| 46 | * | ||
| 47 | * Read: read data, data>>SHIFT, data&=MASK, output data | ||
| 48 | * [0xABCDEF98] shift=12 mask=0xFFF => 0x00000CDE | ||
| 49 | * Write: read data, data &= ~(MASK<<SHIFT), data |= (VALUE<<SHIFT), write data | ||
| 50 | * [0xABCDEF98] shift=12 mask=0xFFF value=0x123 => [0xAB123F98] | ||
| 51 | * | ||
| 52 | * Usage: | ||
| 53 | * # echo "CMD [OPTIONS] BANK ADRESS [VALUE]" > $debugfs/ab8500/hwreg | ||
| 54 | * | ||
| 55 | * CMD read read access | ||
| 56 | * write write access | ||
| 57 | * | ||
| 58 | * BANK target reg bank | ||
| 59 | * ADDRESS target reg address | ||
| 60 | * VALUE (write) value to be updated | ||
| 61 | * | ||
| 62 | * OPTIONS | ||
| 63 | * -d|-dec (read) output in decimal | ||
| 64 | * -h|-hexa (read) output in 0x-hexa (default) | ||
| 65 | * -l|-w|-b 32bit (default), 16bit or 8bit reg access | ||
| 66 | * -m|-mask MASK 0x-hexa mask (default 0xFFFFFFFF) | ||
| 67 | * -s|-shift SHIFT bit shift value (read:left, write:right) | ||
| 68 | * -o|-offset OFFSET address offset to add to ADDRESS value | ||
| 69 | * | ||
| 70 | * Warning: bit shift operation is applied to bit-mask. | ||
| 71 | * Warning: bit shift direction depends on read or right command. | ||
| 72 | */ | ||
| 73 | |||
| 74 | #include <linux/seq_file.h> | ||
| 75 | #include <linux/uaccess.h> | ||
| 76 | #include <linux/fs.h> | ||
| 77 | #include <linux/init.h> | ||
| 78 | #include <linux/debugfs.h> | ||
| 79 | #include <linux/platform_device.h> | ||
| 80 | #include <linux/interrupt.h> | ||
| 81 | #include <linux/kobject.h> | ||
| 82 | #include <linux/slab.h> | ||
| 83 | #include <linux/irq.h> | ||
| 84 | |||
| 85 | #include <linux/mfd/abx500.h> | ||
| 86 | #include <linux/mfd/abx500/ab8500.h> | ||
| 87 | |||
| 88 | #ifdef CONFIG_DEBUG_FS | ||
| 89 | #include <linux/string.h> | ||
| 90 | #include <linux/ctype.h> | ||
| 91 | #endif | ||
| 92 | |||
| 93 | static u32 debug_bank; | ||
| 94 | static u32 debug_address; | ||
| 95 | |||
| 96 | static int irq_ab8500; | ||
| 97 | static int irq_first; | ||
| 98 | static int irq_last; | ||
| 99 | static u32 *irq_count; | ||
| 100 | static int num_irqs; | ||
| 101 | |||
| 102 | static struct device_attribute **dev_attr; | ||
| 103 | static char **event_name; | ||
| 104 | |||
| 105 | /** | ||
| 106 | * struct ab8500_reg_range | ||
| 107 | * @first: the first address of the range | ||
| 108 | * @last: the last address of the range | ||
| 109 | * @perm: access permissions for the range | ||
| 110 | */ | ||
| 111 | struct ab8500_reg_range { | ||
| 112 | u8 first; | ||
| 113 | u8 last; | ||
| 114 | u8 perm; | ||
| 115 | }; | ||
| 116 | |||
| 117 | /** | ||
| 118 | * struct ab8500_prcmu_ranges | ||
| 119 | * @num_ranges: the number of ranges in the list | ||
| 120 | * @bankid: bank identifier | ||
| 121 | * @range: the list of register ranges | ||
| 122 | */ | ||
| 123 | struct ab8500_prcmu_ranges { | ||
| 124 | u8 num_ranges; | ||
| 125 | u8 bankid; | ||
| 126 | const struct ab8500_reg_range *range; | ||
| 127 | }; | ||
| 128 | |||
| 129 | /* hwreg- "mask" and "shift" entries ressources */ | ||
| 130 | struct hwreg_cfg { | ||
| 131 | u32 bank; /* target bank */ | ||
| 132 | unsigned long addr; /* target address */ | ||
| 133 | uint fmt; /* format */ | ||
| 134 | unsigned long mask; /* read/write mask, applied before any bit shift */ | ||
| 135 | long shift; /* bit shift (read:right shift, write:left shift */ | ||
| 136 | }; | ||
| 137 | /* fmt bit #0: 0=hexa, 1=dec */ | ||
| 138 | #define REG_FMT_DEC(c) ((c)->fmt & 0x1) | ||
| 139 | #define REG_FMT_HEX(c) (!REG_FMT_DEC(c)) | ||
| 140 | |||
| 141 | static struct hwreg_cfg hwreg_cfg = { | ||
| 142 | .addr = 0, /* default: invalid phys addr */ | ||
| 143 | .fmt = 0, /* default: 32bit access, hex output */ | ||
| 144 | .mask = 0xFFFFFFFF, /* default: no mask */ | ||
| 145 | .shift = 0, /* default: no bit shift */ | ||
| 146 | }; | ||
| 147 | |||
| 148 | #define AB8500_NAME_STRING "ab8500" | ||
| 149 | #define AB8500_NUM_BANKS AB8500_DEBUG_FIELD_LAST | ||
| 150 | |||
| 151 | #define AB8500_REV_REG 0x80 | ||
| 152 | |||
| 153 | static struct ab8500_prcmu_ranges *debug_ranges; | ||
| 154 | |||
| 155 | static struct ab8500_prcmu_ranges ab8500_debug_ranges[AB8500_NUM_BANKS] = { | ||
| 156 | [AB8500_M_FSM_RANK] = { | ||
| 157 | .num_ranges = 0, | ||
| 158 | .range = NULL, | ||
| 159 | }, | ||
| 160 | [AB8500_SYS_CTRL1_BLOCK] = { | ||
| 161 | .num_ranges = 3, | ||
| 162 | .range = (struct ab8500_reg_range[]) { | ||
| 163 | { | ||
| 164 | .first = 0x00, | ||
| 165 | .last = 0x02, | ||
| 166 | }, | ||
| 167 | { | ||
| 168 | .first = 0x42, | ||
| 169 | .last = 0x42, | ||
| 170 | }, | ||
| 171 | { | ||
| 172 | .first = 0x80, | ||
| 173 | .last = 0x81, | ||
| 174 | }, | ||
| 175 | }, | ||
| 176 | }, | ||
| 177 | [AB8500_SYS_CTRL2_BLOCK] = { | ||
| 178 | .num_ranges = 4, | ||
| 179 | .range = (struct ab8500_reg_range[]) { | ||
| 180 | { | ||
| 181 | .first = 0x00, | ||
| 182 | .last = 0x0D, | ||
| 183 | }, | ||
| 184 | { | ||
| 185 | .first = 0x0F, | ||
| 186 | .last = 0x17, | ||
| 187 | }, | ||
| 188 | { | ||
| 189 | .first = 0x30, | ||
| 190 | .last = 0x30, | ||
| 191 | }, | ||
| 192 | { | ||
| 193 | .first = 0x32, | ||
| 194 | .last = 0x33, | ||
| 195 | }, | ||
| 196 | }, | ||
| 197 | }, | ||
| 198 | [AB8500_REGU_CTRL1] = { | ||
| 199 | .num_ranges = 3, | ||
| 200 | .range = (struct ab8500_reg_range[]) { | ||
| 201 | { | ||
| 202 | .first = 0x00, | ||
| 203 | .last = 0x00, | ||
| 204 | }, | ||
| 205 | { | ||
| 206 | .first = 0x03, | ||
| 207 | .last = 0x10, | ||
| 208 | }, | ||
| 209 | { | ||
| 210 | .first = 0x80, | ||
| 211 | .last = 0x84, | ||
| 212 | }, | ||
| 213 | }, | ||
| 214 | }, | ||
| 215 | [AB8500_REGU_CTRL2] = { | ||
| 216 | .num_ranges = 5, | ||
| 217 | .range = (struct ab8500_reg_range[]) { | ||
| 218 | { | ||
| 219 | .first = 0x00, | ||
| 220 | .last = 0x15, | ||
| 221 | }, | ||
| 222 | { | ||
| 223 | .first = 0x17, | ||
| 224 | .last = 0x19, | ||
| 225 | }, | ||
| 226 | { | ||
| 227 | .first = 0x1B, | ||
| 228 | .last = 0x1D, | ||
| 229 | }, | ||
| 230 | { | ||
| 231 | .first = 0x1F, | ||
| 232 | .last = 0x22, | ||
| 233 | }, | ||
| 234 | { | ||
| 235 | .first = 0x40, | ||
| 236 | .last = 0x44, | ||
| 237 | }, | ||
| 238 | /* | ||
| 239 | * 0x80-0x8B are SIM registers and should | ||
| 240 | * not be accessed from here | ||
| 241 | */ | ||
| 242 | }, | ||
| 243 | }, | ||
| 244 | [AB8500_USB] = { | ||
| 245 | .num_ranges = 2, | ||
| 246 | .range = (struct ab8500_reg_range[]) { | ||
| 247 | { | ||
| 248 | .first = 0x80, | ||
| 249 | .last = 0x83, | ||
| 250 | }, | ||
| 251 | { | ||
| 252 | .first = 0x87, | ||
| 253 | .last = 0x8A, | ||
| 254 | }, | ||
| 255 | }, | ||
| 256 | }, | ||
| 257 | [AB8500_TVOUT] = { | ||
| 258 | .num_ranges = 9, | ||
| 259 | .range = (struct ab8500_reg_range[]) { | ||
| 260 | { | ||
| 261 | .first = 0x00, | ||
| 262 | .last = 0x12, | ||
| 263 | }, | ||
| 264 | { | ||
| 265 | .first = 0x15, | ||
| 266 | .last = 0x17, | ||
| 267 | }, | ||
| 268 | { | ||
| 269 | .first = 0x19, | ||
| 270 | .last = 0x21, | ||
| 271 | }, | ||
| 272 | { | ||
| 273 | .first = 0x27, | ||
| 274 | .last = 0x2C, | ||
| 275 | }, | ||
| 276 | { | ||
| 277 | .first = 0x41, | ||
| 278 | .last = 0x41, | ||
| 279 | }, | ||
| 280 | { | ||
| 281 | .first = 0x45, | ||
| 282 | .last = 0x5B, | ||
| 283 | }, | ||
| 284 | { | ||
| 285 | .first = 0x5D, | ||
| 286 | .last = 0x5D, | ||
| 287 | }, | ||
| 288 | { | ||
| 289 | .first = 0x69, | ||
| 290 | .last = 0x69, | ||
| 291 | }, | ||
| 292 | { | ||
| 293 | .first = 0x80, | ||
| 294 | .last = 0x81, | ||
| 295 | }, | ||
| 296 | }, | ||
| 297 | }, | ||
| 298 | [AB8500_DBI] = { | ||
| 299 | .num_ranges = 0, | ||
| 300 | .range = NULL, | ||
| 301 | }, | ||
| 302 | [AB8500_ECI_AV_ACC] = { | ||
| 303 | .num_ranges = 1, | ||
| 304 | .range = (struct ab8500_reg_range[]) { | ||
| 305 | { | ||
| 306 | .first = 0x80, | ||
| 307 | .last = 0x82, | ||
| 308 | }, | ||
| 309 | }, | ||
| 310 | }, | ||
| 311 | [AB8500_RESERVED] = { | ||
| 312 | .num_ranges = 0, | ||
| 313 | .range = NULL, | ||
| 314 | }, | ||
| 315 | [AB8500_GPADC] = { | ||
| 316 | .num_ranges = 1, | ||
| 317 | .range = (struct ab8500_reg_range[]) { | ||
| 318 | { | ||
| 319 | .first = 0x00, | ||
| 320 | .last = 0x08, | ||
| 321 | }, | ||
| 322 | }, | ||
| 323 | }, | ||
| 324 | [AB8500_CHARGER] = { | ||
| 325 | .num_ranges = 9, | ||
| 326 | .range = (struct ab8500_reg_range[]) { | ||
| 327 | { | ||
| 328 | .first = 0x00, | ||
| 329 | .last = 0x03, | ||
| 330 | }, | ||
| 331 | { | ||
| 332 | .first = 0x05, | ||
| 333 | .last = 0x05, | ||
| 334 | }, | ||
| 335 | { | ||
| 336 | .first = 0x40, | ||
| 337 | .last = 0x40, | ||
| 338 | }, | ||
| 339 | { | ||
| 340 | .first = 0x42, | ||
| 341 | .last = 0x42, | ||
| 342 | }, | ||
| 343 | { | ||
| 344 | .first = 0x44, | ||
| 345 | .last = 0x44, | ||
| 346 | }, | ||
| 347 | { | ||
| 348 | .first = 0x50, | ||
| 349 | .last = 0x55, | ||
| 350 | }, | ||
| 351 | { | ||
| 352 | .first = 0x80, | ||
| 353 | .last = 0x82, | ||
| 354 | }, | ||
| 355 | { | ||
| 356 | .first = 0xC0, | ||
| 357 | .last = 0xC2, | ||
| 358 | }, | ||
| 359 | { | ||
| 360 | .first = 0xf5, | ||
| 361 | .last = 0xf6, | ||
| 362 | }, | ||
| 363 | }, | ||
| 364 | }, | ||
| 365 | [AB8500_GAS_GAUGE] = { | ||
| 366 | .num_ranges = 3, | ||
| 367 | .range = (struct ab8500_reg_range[]) { | ||
| 368 | { | ||
| 369 | .first = 0x00, | ||
| 370 | .last = 0x00, | ||
| 371 | }, | ||
| 372 | { | ||
| 373 | .first = 0x07, | ||
| 374 | .last = 0x0A, | ||
| 375 | }, | ||
| 376 | { | ||
| 377 | .first = 0x10, | ||
| 378 | .last = 0x14, | ||
| 379 | }, | ||
| 380 | }, | ||
| 381 | }, | ||
| 382 | [AB8500_AUDIO] = { | ||
| 383 | .num_ranges = 1, | ||
| 384 | .range = (struct ab8500_reg_range[]) { | ||
| 385 | { | ||
| 386 | .first = 0x00, | ||
| 387 | .last = 0x6F, | ||
| 388 | }, | ||
| 389 | }, | ||
| 390 | }, | ||
| 391 | [AB8500_INTERRUPT] = { | ||
| 392 | .num_ranges = 0, | ||
| 393 | .range = NULL, | ||
| 394 | }, | ||
| 395 | [AB8500_RTC] = { | ||
| 396 | .num_ranges = 1, | ||
| 397 | .range = (struct ab8500_reg_range[]) { | ||
| 398 | { | ||
| 399 | .first = 0x00, | ||
| 400 | .last = 0x0F, | ||
| 401 | }, | ||
| 402 | }, | ||
| 403 | }, | ||
| 404 | [AB8500_MISC] = { | ||
| 405 | .num_ranges = 8, | ||
| 406 | .range = (struct ab8500_reg_range[]) { | ||
| 407 | { | ||
| 408 | .first = 0x00, | ||
| 409 | .last = 0x05, | ||
| 410 | }, | ||
| 411 | { | ||
| 412 | .first = 0x10, | ||
| 413 | .last = 0x15, | ||
| 414 | }, | ||
| 415 | { | ||
| 416 | .first = 0x20, | ||
| 417 | .last = 0x25, | ||
| 418 | }, | ||
| 419 | { | ||
| 420 | .first = 0x30, | ||
| 421 | .last = 0x35, | ||
| 422 | }, | ||
| 423 | { | ||
| 424 | .first = 0x40, | ||
| 425 | .last = 0x45, | ||
| 426 | }, | ||
| 427 | { | ||
| 428 | .first = 0x50, | ||
| 429 | .last = 0x50, | ||
| 430 | }, | ||
| 431 | { | ||
| 432 | .first = 0x60, | ||
| 433 | .last = 0x67, | ||
| 434 | }, | ||
| 435 | { | ||
| 436 | .first = 0x80, | ||
| 437 | .last = 0x80, | ||
| 438 | }, | ||
| 439 | }, | ||
| 440 | }, | ||
| 441 | [AB8500_DEVELOPMENT] = { | ||
| 442 | .num_ranges = 1, | ||
| 443 | .range = (struct ab8500_reg_range[]) { | ||
| 444 | { | ||
| 445 | .first = 0x00, | ||
| 446 | .last = 0x00, | ||
| 447 | }, | ||
| 448 | }, | ||
| 449 | }, | ||
| 450 | [AB8500_DEBUG] = { | ||
| 451 | .num_ranges = 1, | ||
| 452 | .range = (struct ab8500_reg_range[]) { | ||
| 453 | { | ||
| 454 | .first = 0x05, | ||
| 455 | .last = 0x07, | ||
| 456 | }, | ||
| 457 | }, | ||
| 458 | }, | ||
| 459 | [AB8500_PROD_TEST] = { | ||
| 460 | .num_ranges = 0, | ||
| 461 | .range = NULL, | ||
| 462 | }, | ||
| 463 | [AB8500_STE_TEST] = { | ||
| 464 | .num_ranges = 0, | ||
| 465 | .range = NULL, | ||
| 466 | }, | ||
| 467 | [AB8500_OTP_EMUL] = { | ||
| 468 | .num_ranges = 1, | ||
| 469 | .range = (struct ab8500_reg_range[]) { | ||
| 470 | { | ||
| 471 | .first = 0x01, | ||
| 472 | .last = 0x0F, | ||
| 473 | }, | ||
| 474 | }, | ||
| 475 | }, | ||
| 476 | }; | ||
| 477 | |||
| 478 | static struct ab8500_prcmu_ranges ab8505_debug_ranges[AB8500_NUM_BANKS] = { | ||
| 479 | [0x0] = { | ||
| 480 | .num_ranges = 0, | ||
| 481 | .range = NULL, | ||
| 482 | }, | ||
| 483 | [AB8500_SYS_CTRL1_BLOCK] = { | ||
| 484 | .num_ranges = 5, | ||
| 485 | .range = (struct ab8500_reg_range[]) { | ||
| 486 | { | ||
| 487 | .first = 0x00, | ||
| 488 | .last = 0x04, | ||
| 489 | }, | ||
| 490 | { | ||
| 491 | .first = 0x42, | ||
| 492 | .last = 0x42, | ||
| 493 | }, | ||
| 494 | { | ||
| 495 | .first = 0x52, | ||
| 496 | .last = 0x52, | ||
| 497 | }, | ||
| 498 | { | ||
| 499 | .first = 0x54, | ||
| 500 | .last = 0x57, | ||
| 501 | }, | ||
| 502 | { | ||
| 503 | .first = 0x80, | ||
| 504 | .last = 0x83, | ||
| 505 | }, | ||
| 506 | }, | ||
| 507 | }, | ||
| 508 | [AB8500_SYS_CTRL2_BLOCK] = { | ||
| 509 | .num_ranges = 5, | ||
| 510 | .range = (struct ab8500_reg_range[]) { | ||
| 511 | { | ||
| 512 | .first = 0x00, | ||
| 513 | .last = 0x0D, | ||
| 514 | }, | ||
| 515 | { | ||
| 516 | .first = 0x0F, | ||
| 517 | .last = 0x17, | ||
| 518 | }, | ||
| 519 | { | ||
| 520 | .first = 0x20, | ||
| 521 | .last = 0x20, | ||
| 522 | }, | ||
| 523 | { | ||
| 524 | .first = 0x30, | ||
| 525 | .last = 0x30, | ||
| 526 | }, | ||
| 527 | { | ||
| 528 | .first = 0x32, | ||
| 529 | .last = 0x3A, | ||
| 530 | }, | ||
| 531 | }, | ||
| 532 | }, | ||
| 533 | [AB8500_REGU_CTRL1] = { | ||
| 534 | .num_ranges = 3, | ||
| 535 | .range = (struct ab8500_reg_range[]) { | ||
| 536 | { | ||
| 537 | .first = 0x00, | ||
| 538 | .last = 0x00, | ||
| 539 | }, | ||
| 540 | { | ||
| 541 | .first = 0x03, | ||
| 542 | .last = 0x11, | ||
| 543 | }, | ||
| 544 | { | ||
| 545 | .first = 0x80, | ||
| 546 | .last = 0x86, | ||
| 547 | }, | ||
| 548 | }, | ||
| 549 | }, | ||
| 550 | [AB8500_REGU_CTRL2] = { | ||
| 551 | .num_ranges = 6, | ||
| 552 | .range = (struct ab8500_reg_range[]) { | ||
| 553 | { | ||
| 554 | .first = 0x00, | ||
| 555 | .last = 0x06, | ||
| 556 | }, | ||
| 557 | { | ||
| 558 | .first = 0x08, | ||
| 559 | .last = 0x15, | ||
| 560 | }, | ||
| 561 | { | ||
| 562 | .first = 0x17, | ||
| 563 | .last = 0x19, | ||
| 564 | }, | ||
| 565 | { | ||
| 566 | .first = 0x1B, | ||
| 567 | .last = 0x1D, | ||
| 568 | }, | ||
| 569 | { | ||
| 570 | .first = 0x1F, | ||
| 571 | .last = 0x30, | ||
| 572 | }, | ||
| 573 | { | ||
| 574 | .first = 0x40, | ||
| 575 | .last = 0x48, | ||
| 576 | }, | ||
| 577 | /* | ||
| 578 | * 0x80-0x8B are SIM registers and should | ||
| 579 | * not be accessed from here | ||
| 580 | */ | ||
| 581 | }, | ||
| 582 | }, | ||
| 583 | [AB8500_USB] = { | ||
| 584 | .num_ranges = 3, | ||
| 585 | .range = (struct ab8500_reg_range[]) { | ||
| 586 | { | ||
| 587 | .first = 0x80, | ||
| 588 | .last = 0x83, | ||
| 589 | }, | ||
| 590 | { | ||
| 591 | .first = 0x87, | ||
| 592 | .last = 0x8A, | ||
| 593 | }, | ||
| 594 | { | ||
| 595 | .first = 0x91, | ||
| 596 | .last = 0x94, | ||
| 597 | }, | ||
| 598 | }, | ||
| 599 | }, | ||
| 600 | [AB8500_TVOUT] = { | ||
| 601 | .num_ranges = 0, | ||
| 602 | .range = NULL, | ||
| 603 | }, | ||
| 604 | [AB8500_DBI] = { | ||
| 605 | .num_ranges = 0, | ||
| 606 | .range = NULL, | ||
| 607 | }, | ||
| 608 | [AB8500_ECI_AV_ACC] = { | ||
| 609 | .num_ranges = 1, | ||
| 610 | .range = (struct ab8500_reg_range[]) { | ||
| 611 | { | ||
| 612 | .first = 0x80, | ||
| 613 | .last = 0x82, | ||
| 614 | }, | ||
| 615 | }, | ||
| 616 | }, | ||
| 617 | [AB8500_RESERVED] = { | ||
| 618 | .num_ranges = 0, | ||
| 619 | .range = NULL, | ||
| 620 | }, | ||
| 621 | [AB8500_GPADC] = { | ||
| 622 | .num_ranges = 1, | ||
| 623 | .range = (struct ab8500_reg_range[]) { | ||
| 624 | { | ||
| 625 | .first = 0x00, | ||
| 626 | .last = 0x08, | ||
| 627 | }, | ||
| 628 | }, | ||
| 629 | }, | ||
| 630 | [AB8500_CHARGER] = { | ||
| 631 | .num_ranges = 9, | ||
| 632 | .range = (struct ab8500_reg_range[]) { | ||
| 633 | { | ||
| 634 | .first = 0x02, | ||
| 635 | .last = 0x03, | ||
| 636 | }, | ||
| 637 | { | ||
| 638 | .first = 0x05, | ||
| 639 | .last = 0x05, | ||
| 640 | }, | ||
| 641 | { | ||
| 642 | .first = 0x40, | ||
| 643 | .last = 0x44, | ||
| 644 | }, | ||
| 645 | { | ||
| 646 | .first = 0x50, | ||
| 647 | .last = 0x57, | ||
| 648 | }, | ||
| 649 | { | ||
| 650 | .first = 0x60, | ||
| 651 | .last = 0x60, | ||
| 652 | }, | ||
| 653 | { | ||
| 654 | .first = 0xA0, | ||
| 655 | .last = 0xA7, | ||
| 656 | }, | ||
| 657 | { | ||
| 658 | .first = 0xAF, | ||
| 659 | .last = 0xB2, | ||
| 660 | }, | ||
| 661 | { | ||
| 662 | .first = 0xC0, | ||
| 663 | .last = 0xC2, | ||
| 664 | }, | ||
| 665 | { | ||
| 666 | .first = 0xF5, | ||
| 667 | .last = 0xF5, | ||
| 668 | }, | ||
| 669 | }, | ||
| 670 | }, | ||
| 671 | [AB8500_GAS_GAUGE] = { | ||
| 672 | .num_ranges = 3, | ||
| 673 | .range = (struct ab8500_reg_range[]) { | ||
| 674 | { | ||
| 675 | .first = 0x00, | ||
| 676 | .last = 0x00, | ||
| 677 | }, | ||
| 678 | { | ||
| 679 | .first = 0x07, | ||
| 680 | .last = 0x0A, | ||
| 681 | }, | ||
| 682 | { | ||
| 683 | .first = 0x10, | ||
| 684 | .last = 0x14, | ||
| 685 | }, | ||
| 686 | }, | ||
| 687 | }, | ||
| 688 | [AB8500_AUDIO] = { | ||
| 689 | .num_ranges = 1, | ||
| 690 | .range = (struct ab8500_reg_range[]) { | ||
| 691 | { | ||
| 692 | .first = 0x00, | ||
| 693 | .last = 0x83, | ||
| 694 | }, | ||
| 695 | }, | ||
| 696 | }, | ||
| 697 | [AB8500_INTERRUPT] = { | ||
| 698 | .num_ranges = 11, | ||
| 699 | .range = (struct ab8500_reg_range[]) { | ||
| 700 | { | ||
| 701 | .first = 0x00, | ||
| 702 | .last = 0x04, | ||
| 703 | }, | ||
| 704 | { | ||
| 705 | .first = 0x06, | ||
| 706 | .last = 0x07, | ||
| 707 | }, | ||
| 708 | { | ||
| 709 | .first = 0x09, | ||
| 710 | .last = 0x09, | ||
| 711 | }, | ||
| 712 | { | ||
| 713 | .first = 0x0B, | ||
| 714 | .last = 0x0C, | ||
| 715 | }, | ||
| 716 | { | ||
| 717 | .first = 0x12, | ||
| 718 | .last = 0x15, | ||
| 719 | }, | ||
| 720 | { | ||
| 721 | .first = 0x18, | ||
| 722 | .last = 0x18, | ||
| 723 | }, | ||
| 724 | /* Latch registers should not be read here */ | ||
| 725 | { | ||
| 726 | .first = 0x40, | ||
| 727 | .last = 0x44, | ||
| 728 | }, | ||
| 729 | { | ||
| 730 | .first = 0x46, | ||
| 731 | .last = 0x49, | ||
| 732 | }, | ||
| 733 | { | ||
| 734 | .first = 0x4B, | ||
| 735 | .last = 0x4D, | ||
| 736 | }, | ||
| 737 | { | ||
| 738 | .first = 0x52, | ||
| 739 | .last = 0x55, | ||
| 740 | }, | ||
| 741 | { | ||
| 742 | .first = 0x58, | ||
| 743 | .last = 0x58, | ||
| 744 | }, | ||
| 745 | /* LatchHier registers should not be read here */ | ||
| 746 | }, | ||
| 747 | }, | ||
| 748 | [AB8500_RTC] = { | ||
| 749 | .num_ranges = 2, | ||
| 750 | .range = (struct ab8500_reg_range[]) { | ||
| 751 | { | ||
| 752 | .first = 0x00, | ||
| 753 | .last = 0x14, | ||
| 754 | }, | ||
| 755 | { | ||
| 756 | .first = 0x16, | ||
| 757 | .last = 0x17, | ||
| 758 | }, | ||
| 759 | }, | ||
| 760 | }, | ||
| 761 | [AB8500_MISC] = { | ||
| 762 | .num_ranges = 8, | ||
| 763 | .range = (struct ab8500_reg_range[]) { | ||
| 764 | { | ||
| 765 | .first = 0x00, | ||
| 766 | .last = 0x06, | ||
| 767 | }, | ||
| 768 | { | ||
| 769 | .first = 0x10, | ||
| 770 | .last = 0x16, | ||
| 771 | }, | ||
| 772 | { | ||
| 773 | .first = 0x20, | ||
| 774 | .last = 0x26, | ||
| 775 | }, | ||
| 776 | { | ||
| 777 | .first = 0x30, | ||
| 778 | .last = 0x36, | ||
| 779 | }, | ||
| 780 | { | ||
| 781 | .first = 0x40, | ||
| 782 | .last = 0x46, | ||
| 783 | }, | ||
| 784 | { | ||
| 785 | .first = 0x50, | ||
| 786 | .last = 0x50, | ||
| 787 | }, | ||
| 788 | { | ||
| 789 | .first = 0x60, | ||
| 790 | .last = 0x6B, | ||
| 791 | }, | ||
| 792 | { | ||
| 793 | .first = 0x80, | ||
| 794 | .last = 0x82, | ||
| 795 | }, | ||
| 796 | }, | ||
| 797 | }, | ||
| 798 | [AB8500_DEVELOPMENT] = { | ||
| 799 | .num_ranges = 2, | ||
| 800 | .range = (struct ab8500_reg_range[]) { | ||
| 801 | { | ||
| 802 | .first = 0x00, | ||
| 803 | .last = 0x00, | ||
| 804 | }, | ||
| 805 | { | ||
| 806 | .first = 0x05, | ||
| 807 | .last = 0x05, | ||
| 808 | }, | ||
| 809 | }, | ||
| 810 | }, | ||
| 811 | [AB8500_DEBUG] = { | ||
| 812 | .num_ranges = 1, | ||
| 813 | .range = (struct ab8500_reg_range[]) { | ||
| 814 | { | ||
| 815 | .first = 0x05, | ||
| 816 | .last = 0x07, | ||
| 817 | }, | ||
| 818 | }, | ||
| 819 | }, | ||
| 820 | [AB8500_PROD_TEST] = { | ||
| 821 | .num_ranges = 0, | ||
| 822 | .range = NULL, | ||
| 823 | }, | ||
| 824 | [AB8500_STE_TEST] = { | ||
| 825 | .num_ranges = 0, | ||
| 826 | .range = NULL, | ||
| 827 | }, | ||
| 828 | [AB8500_OTP_EMUL] = { | ||
| 829 | .num_ranges = 1, | ||
| 830 | .range = (struct ab8500_reg_range[]) { | ||
| 831 | { | ||
| 832 | .first = 0x01, | ||
| 833 | .last = 0x15, | ||
| 834 | }, | ||
| 835 | }, | ||
| 836 | }, | ||
| 837 | }; | ||
| 838 | |||
| 839 | static struct ab8500_prcmu_ranges ab8540_debug_ranges[AB8500_NUM_BANKS] = { | ||
| 840 | [AB8500_M_FSM_RANK] = { | ||
| 841 | .num_ranges = 1, | ||
| 842 | .range = (struct ab8500_reg_range[]) { | ||
| 843 | { | ||
| 844 | .first = 0x00, | ||
| 845 | .last = 0x0B, | ||
| 846 | }, | ||
| 847 | }, | ||
| 848 | }, | ||
| 849 | [AB8500_SYS_CTRL1_BLOCK] = { | ||
| 850 | .num_ranges = 6, | ||
| 851 | .range = (struct ab8500_reg_range[]) { | ||
| 852 | { | ||
| 853 | .first = 0x00, | ||
| 854 | .last = 0x04, | ||
| 855 | }, | ||
| 856 | { | ||
| 857 | .first = 0x42, | ||
| 858 | .last = 0x42, | ||
| 859 | }, | ||
| 860 | { | ||
| 861 | .first = 0x50, | ||
| 862 | .last = 0x54, | ||
| 863 | }, | ||
| 864 | { | ||
| 865 | .first = 0x57, | ||
| 866 | .last = 0x57, | ||
| 867 | }, | ||
| 868 | { | ||
| 869 | .first = 0x80, | ||
| 870 | .last = 0x83, | ||
| 871 | }, | ||
| 872 | { | ||
| 873 | .first = 0x90, | ||
| 874 | .last = 0x90, | ||
| 875 | }, | ||
| 876 | }, | ||
| 877 | }, | ||
| 878 | [AB8500_SYS_CTRL2_BLOCK] = { | ||
| 879 | .num_ranges = 5, | ||
| 880 | .range = (struct ab8500_reg_range[]) { | ||
| 881 | { | ||
| 882 | .first = 0x00, | ||
| 883 | .last = 0x0D, | ||
| 884 | }, | ||
| 885 | { | ||
| 886 | .first = 0x0F, | ||
| 887 | .last = 0x10, | ||
| 888 | }, | ||
| 889 | { | ||
| 890 | .first = 0x20, | ||
| 891 | .last = 0x21, | ||
| 892 | }, | ||
| 893 | { | ||
| 894 | .first = 0x32, | ||
| 895 | .last = 0x3C, | ||
| 896 | }, | ||
| 897 | { | ||
| 898 | .first = 0x40, | ||
| 899 | .last = 0x42, | ||
| 900 | }, | ||
| 901 | }, | ||
| 902 | }, | ||
| 903 | [AB8500_REGU_CTRL1] = { | ||
| 904 | .num_ranges = 4, | ||
| 905 | .range = (struct ab8500_reg_range[]) { | ||
| 906 | { | ||
| 907 | .first = 0x03, | ||
| 908 | .last = 0x15, | ||
| 909 | }, | ||
| 910 | { | ||
| 911 | .first = 0x20, | ||
| 912 | .last = 0x20, | ||
| 913 | }, | ||
| 914 | { | ||
| 915 | .first = 0x80, | ||
| 916 | .last = 0x85, | ||
| 917 | }, | ||
| 918 | { | ||
| 919 | .first = 0x87, | ||
| 920 | .last = 0x88, | ||
| 921 | }, | ||
| 922 | }, | ||
| 923 | }, | ||
| 924 | [AB8500_REGU_CTRL2] = { | ||
| 925 | .num_ranges = 8, | ||
| 926 | .range = (struct ab8500_reg_range[]) { | ||
| 927 | { | ||
| 928 | .first = 0x00, | ||
| 929 | .last = 0x06, | ||
| 930 | }, | ||
| 931 | { | ||
| 932 | .first = 0x08, | ||
| 933 | .last = 0x15, | ||
| 934 | }, | ||
| 935 | { | ||
| 936 | .first = 0x17, | ||
| 937 | .last = 0x19, | ||
| 938 | }, | ||
| 939 | { | ||
| 940 | .first = 0x1B, | ||
| 941 | .last = 0x1D, | ||
| 942 | }, | ||
| 943 | { | ||
| 944 | .first = 0x1F, | ||
| 945 | .last = 0x2F, | ||
| 946 | }, | ||
| 947 | { | ||
| 948 | .first = 0x31, | ||
| 949 | .last = 0x3A, | ||
| 950 | }, | ||
| 951 | { | ||
| 952 | .first = 0x43, | ||
| 953 | .last = 0x44, | ||
| 954 | }, | ||
| 955 | { | ||
| 956 | .first = 0x48, | ||
| 957 | .last = 0x49, | ||
| 958 | }, | ||
| 959 | }, | ||
| 960 | }, | ||
| 961 | [AB8500_USB] = { | ||
| 962 | .num_ranges = 3, | ||
| 963 | .range = (struct ab8500_reg_range[]) { | ||
| 964 | { | ||
| 965 | .first = 0x80, | ||
| 966 | .last = 0x83, | ||
| 967 | }, | ||
| 968 | { | ||
| 969 | .first = 0x87, | ||
| 970 | .last = 0x8A, | ||
| 971 | }, | ||
| 972 | { | ||
| 973 | .first = 0x91, | ||
| 974 | .last = 0x94, | ||
| 975 | }, | ||
| 976 | }, | ||
| 977 | }, | ||
| 978 | [AB8500_TVOUT] = { | ||
| 979 | .num_ranges = 0, | ||
| 980 | .range = NULL | ||
| 981 | }, | ||
| 982 | [AB8500_DBI] = { | ||
| 983 | .num_ranges = 4, | ||
| 984 | .range = (struct ab8500_reg_range[]) { | ||
| 985 | { | ||
| 986 | .first = 0x00, | ||
| 987 | .last = 0x07, | ||
| 988 | }, | ||
| 989 | { | ||
| 990 | .first = 0x10, | ||
| 991 | .last = 0x11, | ||
| 992 | }, | ||
| 993 | { | ||
| 994 | .first = 0x20, | ||
| 995 | .last = 0x21, | ||
| 996 | }, | ||
| 997 | { | ||
| 998 | .first = 0x30, | ||
| 999 | .last = 0x43, | ||
| 1000 | }, | ||
| 1001 | }, | ||
| 1002 | }, | ||
| 1003 | [AB8500_ECI_AV_ACC] = { | ||
| 1004 | .num_ranges = 2, | ||
| 1005 | .range = (struct ab8500_reg_range[]) { | ||
| 1006 | { | ||
| 1007 | .first = 0x00, | ||
| 1008 | .last = 0x03, | ||
| 1009 | }, | ||
| 1010 | { | ||
| 1011 | .first = 0x80, | ||
| 1012 | .last = 0x82, | ||
| 1013 | }, | ||
| 1014 | }, | ||
| 1015 | }, | ||
| 1016 | [AB8500_RESERVED] = { | ||
| 1017 | .num_ranges = 0, | ||
| 1018 | .range = NULL, | ||
| 1019 | }, | ||
| 1020 | [AB8500_GPADC] = { | ||
| 1021 | .num_ranges = 4, | ||
| 1022 | .range = (struct ab8500_reg_range[]) { | ||
| 1023 | { | ||
| 1024 | .first = 0x00, | ||
| 1025 | .last = 0x01, | ||
| 1026 | }, | ||
| 1027 | { | ||
| 1028 | .first = 0x04, | ||
| 1029 | .last = 0x06, | ||
| 1030 | }, | ||
| 1031 | { | ||
| 1032 | .first = 0x09, | ||
| 1033 | .last = 0x0A, | ||
| 1034 | }, | ||
| 1035 | { | ||
| 1036 | .first = 0x10, | ||
| 1037 | .last = 0x14, | ||
| 1038 | }, | ||
| 1039 | }, | ||
| 1040 | }, | ||
| 1041 | [AB8500_CHARGER] = { | ||
| 1042 | .num_ranges = 10, | ||
| 1043 | .range = (struct ab8500_reg_range[]) { | ||
| 1044 | { | ||
| 1045 | .first = 0x00, | ||
| 1046 | .last = 0x00, | ||
| 1047 | }, | ||
| 1048 | { | ||
| 1049 | .first = 0x02, | ||
| 1050 | .last = 0x05, | ||
| 1051 | }, | ||
| 1052 | { | ||
| 1053 | .first = 0x40, | ||
| 1054 | .last = 0x44, | ||
| 1055 | }, | ||
| 1056 | { | ||
| 1057 | .first = 0x50, | ||
| 1058 | .last = 0x57, | ||
| 1059 | }, | ||
| 1060 | { | ||
| 1061 | .first = 0x60, | ||
| 1062 | .last = 0x60, | ||
| 1063 | }, | ||
| 1064 | { | ||
| 1065 | .first = 0x70, | ||
| 1066 | .last = 0x70, | ||
| 1067 | }, | ||
| 1068 | { | ||
| 1069 | .first = 0xA0, | ||
| 1070 | .last = 0xA9, | ||
| 1071 | }, | ||
| 1072 | { | ||
| 1073 | .first = 0xAF, | ||
| 1074 | .last = 0xB2, | ||
| 1075 | }, | ||
| 1076 | { | ||
| 1077 | .first = 0xC0, | ||
| 1078 | .last = 0xC6, | ||
| 1079 | }, | ||
| 1080 | { | ||
| 1081 | .first = 0xF5, | ||
| 1082 | .last = 0xF5, | ||
| 1083 | }, | ||
| 1084 | }, | ||
| 1085 | }, | ||
| 1086 | [AB8500_GAS_GAUGE] = { | ||
| 1087 | .num_ranges = 3, | ||
| 1088 | .range = (struct ab8500_reg_range[]) { | ||
| 1089 | { | ||
| 1090 | .first = 0x00, | ||
| 1091 | .last = 0x00, | ||
| 1092 | }, | ||
| 1093 | { | ||
| 1094 | .first = 0x07, | ||
| 1095 | .last = 0x0A, | ||
| 1096 | }, | ||
| 1097 | { | ||
| 1098 | .first = 0x10, | ||
| 1099 | .last = 0x14, | ||
| 1100 | }, | ||
| 1101 | }, | ||
| 1102 | }, | ||
| 1103 | [AB8500_AUDIO] = { | ||
| 1104 | .num_ranges = 1, | ||
| 1105 | .range = (struct ab8500_reg_range[]) { | ||
| 1106 | { | ||
| 1107 | .first = 0x00, | ||
| 1108 | .last = 0x9f, | ||
| 1109 | }, | ||
| 1110 | }, | ||
| 1111 | }, | ||
| 1112 | [AB8500_INTERRUPT] = { | ||
| 1113 | .num_ranges = 6, | ||
| 1114 | .range = (struct ab8500_reg_range[]) { | ||
| 1115 | { | ||
| 1116 | .first = 0x00, | ||
| 1117 | .last = 0x05, | ||
| 1118 | }, | ||
| 1119 | { | ||
| 1120 | .first = 0x0B, | ||
| 1121 | .last = 0x0D, | ||
| 1122 | }, | ||
| 1123 | { | ||
| 1124 | .first = 0x12, | ||
| 1125 | .last = 0x20, | ||
| 1126 | }, | ||
| 1127 | /* Latch registers should not be read here */ | ||
| 1128 | { | ||
| 1129 | .first = 0x40, | ||
| 1130 | .last = 0x45, | ||
| 1131 | }, | ||
| 1132 | { | ||
| 1133 | .first = 0x4B, | ||
| 1134 | .last = 0x4D, | ||
| 1135 | }, | ||
| 1136 | { | ||
| 1137 | .first = 0x52, | ||
| 1138 | .last = 0x60, | ||
| 1139 | }, | ||
| 1140 | /* LatchHier registers should not be read here */ | ||
| 1141 | }, | ||
| 1142 | }, | ||
| 1143 | [AB8500_RTC] = { | ||
| 1144 | .num_ranges = 3, | ||
| 1145 | .range = (struct ab8500_reg_range[]) { | ||
| 1146 | { | ||
| 1147 | .first = 0x00, | ||
| 1148 | .last = 0x07, | ||
| 1149 | }, | ||
| 1150 | { | ||
| 1151 | .first = 0x0B, | ||
| 1152 | .last = 0x18, | ||
| 1153 | }, | ||
| 1154 | { | ||
| 1155 | .first = 0x20, | ||
| 1156 | .last = 0x25, | ||
| 1157 | }, | ||
| 1158 | }, | ||
| 1159 | }, | ||
| 1160 | [AB8500_MISC] = { | ||
| 1161 | .num_ranges = 9, | ||
| 1162 | .range = (struct ab8500_reg_range[]) { | ||
| 1163 | { | ||
| 1164 | .first = 0x00, | ||
| 1165 | .last = 0x06, | ||
| 1166 | }, | ||
| 1167 | { | ||
| 1168 | .first = 0x10, | ||
| 1169 | .last = 0x16, | ||
| 1170 | }, | ||
| 1171 | { | ||
| 1172 | .first = 0x20, | ||
| 1173 | .last = 0x26, | ||
| 1174 | }, | ||
| 1175 | { | ||
| 1176 | .first = 0x30, | ||
| 1177 | .last = 0x36, | ||
| 1178 | }, | ||
| 1179 | { | ||
| 1180 | .first = 0x40, | ||
| 1181 | .last = 0x49, | ||
| 1182 | }, | ||
| 1183 | { | ||
| 1184 | .first = 0x50, | ||
| 1185 | .last = 0x50, | ||
| 1186 | }, | ||
| 1187 | { | ||
| 1188 | .first = 0x60, | ||
| 1189 | .last = 0x6B, | ||
| 1190 | }, | ||
| 1191 | { | ||
| 1192 | .first = 0x70, | ||
| 1193 | .last = 0x74, | ||
| 1194 | }, | ||
| 1195 | { | ||
| 1196 | .first = 0x80, | ||
| 1197 | .last = 0x82, | ||
| 1198 | }, | ||
| 1199 | }, | ||
| 1200 | }, | ||
| 1201 | [AB8500_DEVELOPMENT] = { | ||
| 1202 | .num_ranges = 3, | ||
| 1203 | .range = (struct ab8500_reg_range[]) { | ||
| 1204 | { | ||
| 1205 | .first = 0x00, | ||
| 1206 | .last = 0x01, | ||
| 1207 | }, | ||
| 1208 | { | ||
| 1209 | .first = 0x06, | ||
| 1210 | .last = 0x06, | ||
| 1211 | }, | ||
| 1212 | { | ||
| 1213 | .first = 0x10, | ||
| 1214 | .last = 0x21, | ||
| 1215 | }, | ||
| 1216 | }, | ||
| 1217 | }, | ||
| 1218 | [AB8500_DEBUG] = { | ||
| 1219 | .num_ranges = 3, | ||
| 1220 | .range = (struct ab8500_reg_range[]) { | ||
| 1221 | { | ||
| 1222 | .first = 0x01, | ||
| 1223 | .last = 0x0C, | ||
| 1224 | }, | ||
| 1225 | { | ||
| 1226 | .first = 0x0E, | ||
| 1227 | .last = 0x11, | ||
| 1228 | }, | ||
| 1229 | { | ||
| 1230 | .first = 0x80, | ||
| 1231 | .last = 0x81, | ||
| 1232 | }, | ||
| 1233 | }, | ||
| 1234 | }, | ||
| 1235 | [AB8500_PROD_TEST] = { | ||
| 1236 | .num_ranges = 0, | ||
| 1237 | .range = NULL, | ||
| 1238 | }, | ||
| 1239 | [AB8500_STE_TEST] = { | ||
| 1240 | .num_ranges = 0, | ||
| 1241 | .range = NULL, | ||
| 1242 | }, | ||
| 1243 | [AB8500_OTP_EMUL] = { | ||
| 1244 | .num_ranges = 1, | ||
| 1245 | .range = (struct ab8500_reg_range[]) { | ||
| 1246 | { | ||
| 1247 | .first = 0x00, | ||
| 1248 | .last = 0x3F, | ||
| 1249 | }, | ||
| 1250 | }, | ||
| 1251 | }, | ||
| 1252 | }; | ||
| 1253 | |||
| 1254 | static irqreturn_t ab8500_debug_handler(int irq, void *data) | ||
| 1255 | { | ||
| 1256 | char buf[16]; | ||
| 1257 | struct kobject *kobj = (struct kobject *)data; | ||
| 1258 | unsigned int irq_abb = irq - irq_first; | ||
| 1259 | |||
| 1260 | if (irq_abb < num_irqs) | ||
| 1261 | irq_count[irq_abb]++; | ||
| 1262 | /* | ||
| 1263 | * This makes it possible to use poll for events (EPOLLPRI | EPOLLERR) | ||
| 1264 | * from userspace on sysfs file named <irq-nr> | ||
| 1265 | */ | ||
| 1266 | sprintf(buf, "%d", irq); | ||
| 1267 | sysfs_notify(kobj, NULL, buf); | ||
| 1268 | |||
| 1269 | return IRQ_HANDLED; | ||
| 1270 | } | ||
| 1271 | |||
| 1272 | /* Prints to seq_file or log_buf */ | ||
| 1273 | static int ab8500_registers_print(struct device *dev, u32 bank, | ||
| 1274 | struct seq_file *s) | ||
| 1275 | { | ||
| 1276 | unsigned int i; | ||
| 1277 | |||
| 1278 | for (i = 0; i < debug_ranges[bank].num_ranges; i++) { | ||
| 1279 | u32 reg; | ||
| 1280 | |||
| 1281 | for (reg = debug_ranges[bank].range[i].first; | ||
| 1282 | reg <= debug_ranges[bank].range[i].last; | ||
| 1283 | reg++) { | ||
| 1284 | u8 value; | ||
| 1285 | int err; | ||
| 1286 | |||
| 1287 | err = abx500_get_register_interruptible(dev, | ||
| 1288 | (u8)bank, (u8)reg, &value); | ||
| 1289 | if (err < 0) { | ||
| 1290 | dev_err(dev, "ab->read fail %d\n", err); | ||
| 1291 | return err; | ||
| 1292 | } | ||
| 1293 | |||
| 1294 | if (s) { | ||
| 1295 | seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", | ||
| 1296 | bank, reg, value); | ||
| 1297 | /* | ||
| 1298 | * Error is not returned here since | ||
| 1299 | * the output is wanted in any case | ||
| 1300 | */ | ||
| 1301 | if (seq_has_overflowed(s)) | ||
| 1302 | return 0; | ||
| 1303 | } else { | ||
| 1304 | dev_info(dev, " [0x%02X/0x%02X]: 0x%02X\n", | ||
| 1305 | bank, reg, value); | ||
| 1306 | } | ||
| 1307 | } | ||
| 1308 | } | ||
| 1309 | |||
| 1310 | return 0; | ||
| 1311 | } | ||
| 1312 | |||
| 1313 | static int ab8500_bank_registers_show(struct seq_file *s, void *p) | ||
| 1314 | { | ||
| 1315 | struct device *dev = s->private; | ||
| 1316 | u32 bank = debug_bank; | ||
| 1317 | |||
| 1318 | seq_puts(s, AB8500_NAME_STRING " register values:\n"); | ||
| 1319 | |||
| 1320 | seq_printf(s, " bank 0x%02X:\n", bank); | ||
| 1321 | |||
| 1322 | return ab8500_registers_print(dev, bank, s); | ||
| 1323 | } | ||
| 1324 | |||
| 1325 | DEFINE_SHOW_ATTRIBUTE(ab8500_bank_registers); | ||
| 1326 | |||
| 1327 | static int ab8500_print_all_banks(struct seq_file *s, void *p) | ||
| 1328 | { | ||
| 1329 | struct device *dev = s->private; | ||
| 1330 | unsigned int i; | ||
| 1331 | |||
| 1332 | seq_puts(s, AB8500_NAME_STRING " register values:\n"); | ||
| 1333 | |||
| 1334 | for (i = 0; i < AB8500_NUM_BANKS; i++) { | ||
| 1335 | int err; | ||
| 1336 | |||
| 1337 | seq_printf(s, " bank 0x%02X:\n", i); | ||
| 1338 | err = ab8500_registers_print(dev, i, s); | ||
| 1339 | if (err) | ||
| 1340 | return err; | ||
| 1341 | } | ||
| 1342 | return 0; | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | /* Dump registers to kernel log */ | ||
| 1346 | void ab8500_dump_all_banks(struct device *dev) | ||
| 1347 | { | ||
| 1348 | unsigned int i; | ||
| 1349 | |||
| 1350 | dev_info(dev, "ab8500 register values:\n"); | ||
| 1351 | |||
| 1352 | for (i = 1; i < AB8500_NUM_BANKS; i++) { | ||
| 1353 | dev_info(dev, " bank 0x%02X:\n", i); | ||
| 1354 | ab8500_registers_print(dev, i, NULL); | ||
| 1355 | } | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | static int ab8500_all_banks_open(struct inode *inode, struct file *file) | ||
| 1359 | { | ||
| 1360 | struct seq_file *s; | ||
| 1361 | int err; | ||
| 1362 | |||
| 1363 | err = single_open(file, ab8500_print_all_banks, inode->i_private); | ||
| 1364 | if (!err) { | ||
| 1365 | /* Default buf size in seq_read is not enough */ | ||
| 1366 | s = (struct seq_file *)file->private_data; | ||
| 1367 | s->size = (PAGE_SIZE * 2); | ||
| 1368 | s->buf = kmalloc(s->size, GFP_KERNEL); | ||
| 1369 | if (!s->buf) { | ||
| 1370 | single_release(inode, file); | ||
| 1371 | err = -ENOMEM; | ||
| 1372 | } | ||
| 1373 | } | ||
| 1374 | return err; | ||
| 1375 | } | ||
| 1376 | |||
| 1377 | static const struct file_operations ab8500_all_banks_fops = { | ||
| 1378 | .open = ab8500_all_banks_open, | ||
| 1379 | .read = seq_read, | ||
| 1380 | .llseek = seq_lseek, | ||
| 1381 | .release = single_release, | ||
| 1382 | .owner = THIS_MODULE, | ||
| 1383 | }; | ||
| 1384 | |||
| 1385 | static int ab8500_bank_print(struct seq_file *s, void *p) | ||
| 1386 | { | ||
| 1387 | seq_printf(s, "0x%02X\n", debug_bank); | ||
| 1388 | return 0; | ||
| 1389 | } | ||
| 1390 | |||
| 1391 | static int ab8500_bank_open(struct inode *inode, struct file *file) | ||
| 1392 | { | ||
| 1393 | return single_open(file, ab8500_bank_print, inode->i_private); | ||
| 1394 | } | ||
| 1395 | |||
| 1396 | static ssize_t ab8500_bank_write(struct file *file, | ||
| 1397 | const char __user *user_buf, | ||
| 1398 | size_t count, loff_t *ppos) | ||
| 1399 | { | ||
| 1400 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | ||
| 1401 | unsigned long user_bank; | ||
| 1402 | int err; | ||
| 1403 | |||
| 1404 | err = kstrtoul_from_user(user_buf, count, 0, &user_bank); | ||
| 1405 | if (err) | ||
| 1406 | return err; | ||
| 1407 | |||
| 1408 | if (user_bank >= AB8500_NUM_BANKS) { | ||
| 1409 | dev_err(dev, "debugfs error input > number of banks\n"); | ||
| 1410 | return -EINVAL; | ||
| 1411 | } | ||
| 1412 | |||
| 1413 | debug_bank = user_bank; | ||
| 1414 | |||
| 1415 | return count; | ||
| 1416 | } | ||
| 1417 | |||
| 1418 | static int ab8500_address_print(struct seq_file *s, void *p) | ||
| 1419 | { | ||
| 1420 | seq_printf(s, "0x%02X\n", debug_address); | ||
| 1421 | return 0; | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | static int ab8500_address_open(struct inode *inode, struct file *file) | ||
| 1425 | { | ||
| 1426 | return single_open(file, ab8500_address_print, inode->i_private); | ||
| 1427 | } | ||
| 1428 | |||
| 1429 | static ssize_t ab8500_address_write(struct file *file, | ||
| 1430 | const char __user *user_buf, | ||
| 1431 | size_t count, loff_t *ppos) | ||
| 1432 | { | ||
| 1433 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | ||
| 1434 | unsigned long user_address; | ||
| 1435 | int err; | ||
| 1436 | |||
| 1437 | err = kstrtoul_from_user(user_buf, count, 0, &user_address); | ||
| 1438 | if (err) | ||
| 1439 | return err; | ||
| 1440 | |||
| 1441 | if (user_address > 0xff) { | ||
| 1442 | dev_err(dev, "debugfs error input > 0xff\n"); | ||
| 1443 | return -EINVAL; | ||
| 1444 | } | ||
| 1445 | debug_address = user_address; | ||
| 1446 | |||
| 1447 | return count; | ||
| 1448 | } | ||
| 1449 | |||
| 1450 | static int ab8500_val_print(struct seq_file *s, void *p) | ||
| 1451 | { | ||
| 1452 | struct device *dev = s->private; | ||
| 1453 | int ret; | ||
| 1454 | u8 regvalue; | ||
| 1455 | |||
| 1456 | ret = abx500_get_register_interruptible(dev, | ||
| 1457 | (u8)debug_bank, (u8)debug_address, ®value); | ||
| 1458 | if (ret < 0) { | ||
| 1459 | dev_err(dev, "abx500_get_reg fail %d, %d\n", | ||
| 1460 | ret, __LINE__); | ||
| 1461 | return -EINVAL; | ||
| 1462 | } | ||
| 1463 | seq_printf(s, "0x%02X\n", regvalue); | ||
| 1464 | |||
| 1465 | return 0; | ||
| 1466 | } | ||
| 1467 | |||
| 1468 | static int ab8500_val_open(struct inode *inode, struct file *file) | ||
| 1469 | { | ||
| 1470 | return single_open(file, ab8500_val_print, inode->i_private); | ||
| 1471 | } | ||
| 1472 | |||
| 1473 | static ssize_t ab8500_val_write(struct file *file, | ||
| 1474 | const char __user *user_buf, | ||
| 1475 | size_t count, loff_t *ppos) | ||
| 1476 | { | ||
| 1477 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | ||
| 1478 | unsigned long user_val; | ||
| 1479 | int err; | ||
| 1480 | |||
| 1481 | err = kstrtoul_from_user(user_buf, count, 0, &user_val); | ||
| 1482 | if (err) | ||
| 1483 | return err; | ||
| 1484 | |||
| 1485 | if (user_val > 0xff) { | ||
| 1486 | dev_err(dev, "debugfs error input > 0xff\n"); | ||
| 1487 | return -EINVAL; | ||
| 1488 | } | ||
| 1489 | err = abx500_set_register_interruptible(dev, | ||
| 1490 | (u8)debug_bank, debug_address, (u8)user_val); | ||
| 1491 | if (err < 0) { | ||
| 1492 | pr_err("abx500_set_reg failed %d, %d", err, __LINE__); | ||
| 1493 | return -EINVAL; | ||
| 1494 | } | ||
| 1495 | |||
| 1496 | return count; | ||
| 1497 | } | ||
| 1498 | |||
| 1499 | /* | ||
| 1500 | * Interrupt status | ||
| 1501 | */ | ||
| 1502 | static u32 num_interrupts[AB8500_MAX_NR_IRQS]; | ||
| 1503 | static u32 num_wake_interrupts[AB8500_MAX_NR_IRQS]; | ||
| 1504 | static int num_interrupt_lines; | ||
| 1505 | |||
| 1506 | void ab8500_debug_register_interrupt(int line) | ||
| 1507 | { | ||
| 1508 | if (line < num_interrupt_lines) | ||
| 1509 | num_interrupts[line]++; | ||
| 1510 | } | ||
| 1511 | |||
| 1512 | static int ab8500_interrupts_show(struct seq_file *s, void *p) | ||
| 1513 | { | ||
| 1514 | int line; | ||
| 1515 | |||
| 1516 | seq_puts(s, "name: number: irq: number of: wake:\n"); | ||
| 1517 | |||
| 1518 | for (line = 0; line < num_interrupt_lines; line++) { | ||
| 1519 | seq_printf(s, "%3i: %4i %6i %4i\n", | ||
| 1520 | line, | ||
| 1521 | line + irq_first, | ||
| 1522 | num_interrupts[line], | ||
| 1523 | num_wake_interrupts[line]); | ||
| 1524 | } | ||
| 1525 | |||
| 1526 | return 0; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | DEFINE_SHOW_ATTRIBUTE(ab8500_interrupts); | ||
| 1530 | |||
| 1531 | /* | ||
| 1532 | * - HWREG DB8500 formated routines | ||
| 1533 | */ | ||
| 1534 | static int ab8500_hwreg_print(struct seq_file *s, void *d) | ||
| 1535 | { | ||
| 1536 | struct device *dev = s->private; | ||
| 1537 | int ret; | ||
| 1538 | u8 regvalue; | ||
| 1539 | |||
| 1540 | ret = abx500_get_register_interruptible(dev, | ||
| 1541 | (u8)hwreg_cfg.bank, (u8)hwreg_cfg.addr, ®value); | ||
| 1542 | if (ret < 0) { | ||
| 1543 | dev_err(dev, "abx500_get_reg fail %d, %d\n", | ||
| 1544 | ret, __LINE__); | ||
| 1545 | return -EINVAL; | ||
| 1546 | } | ||
| 1547 | |||
| 1548 | if (hwreg_cfg.shift >= 0) | ||
| 1549 | regvalue >>= hwreg_cfg.shift; | ||
| 1550 | else | ||
| 1551 | regvalue <<= -hwreg_cfg.shift; | ||
| 1552 | regvalue &= hwreg_cfg.mask; | ||
| 1553 | |||
| 1554 | if (REG_FMT_DEC(&hwreg_cfg)) | ||
| 1555 | seq_printf(s, "%d\n", regvalue); | ||
| 1556 | else | ||
| 1557 | seq_printf(s, "0x%02X\n", regvalue); | ||
| 1558 | return 0; | ||
| 1559 | } | ||
| 1560 | |||
| 1561 | static int ab8500_hwreg_open(struct inode *inode, struct file *file) | ||
| 1562 | { | ||
| 1563 | return single_open(file, ab8500_hwreg_print, inode->i_private); | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | #define AB8500_SUPPLY_CONTROL_CONFIG_1 0x01 | ||
| 1567 | #define AB8500_SUPPLY_CONTROL_REG 0x00 | ||
| 1568 | #define AB8500_FIRST_SIM_REG 0x80 | ||
| 1569 | #define AB8500_LAST_SIM_REG 0x8B | ||
| 1570 | #define AB8505_LAST_SIM_REG 0x8C | ||
| 1571 | |||
| 1572 | static int ab8500_modem_show(struct seq_file *s, void *p) | ||
| 1573 | { | ||
| 1574 | struct device *dev = s->private; | ||
| 1575 | struct ab8500 *ab8500; | ||
| 1576 | int err; | ||
| 1577 | u8 value; | ||
| 1578 | u8 orig_value; | ||
| 1579 | u32 bank = AB8500_REGU_CTRL2; | ||
| 1580 | u32 last_sim_reg = AB8500_LAST_SIM_REG; | ||
| 1581 | u32 reg; | ||
| 1582 | |||
| 1583 | ab8500 = dev_get_drvdata(dev->parent); | ||
| 1584 | dev_warn(dev, "WARNING! This operation can interfer with modem side\n" | ||
| 1585 | "and should only be done with care\n"); | ||
| 1586 | |||
| 1587 | err = abx500_get_register_interruptible(dev, | ||
| 1588 | AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, &orig_value); | ||
| 1589 | if (err < 0) | ||
| 1590 | goto report_read_failure; | ||
| 1591 | |||
| 1592 | /* Config 1 will allow APE side to read SIM registers */ | ||
| 1593 | err = abx500_set_register_interruptible(dev, | ||
| 1594 | AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, | ||
| 1595 | AB8500_SUPPLY_CONTROL_CONFIG_1); | ||
| 1596 | if (err < 0) | ||
| 1597 | goto report_write_failure; | ||
| 1598 | |||
| 1599 | seq_printf(s, " bank 0x%02X:\n", bank); | ||
| 1600 | |||
| 1601 | if (is_ab9540(ab8500) || is_ab8505(ab8500)) | ||
| 1602 | last_sim_reg = AB8505_LAST_SIM_REG; | ||
| 1603 | |||
| 1604 | for (reg = AB8500_FIRST_SIM_REG; reg <= last_sim_reg; reg++) { | ||
| 1605 | err = abx500_get_register_interruptible(dev, | ||
| 1606 | bank, reg, &value); | ||
| 1607 | if (err < 0) | ||
| 1608 | goto report_read_failure; | ||
| 1609 | |||
| 1610 | seq_printf(s, " [0x%02X/0x%02X]: 0x%02X\n", bank, reg, value); | ||
| 1611 | } | ||
| 1612 | err = abx500_set_register_interruptible(dev, | ||
| 1613 | AB8500_REGU_CTRL1, AB8500_SUPPLY_CONTROL_REG, orig_value); | ||
| 1614 | if (err < 0) | ||
| 1615 | goto report_write_failure; | ||
| 1616 | |||
| 1617 | return 0; | ||
| 1618 | |||
| 1619 | report_read_failure: | ||
| 1620 | dev_err(dev, "ab->read fail %d\n", err); | ||
| 1621 | return err; | ||
| 1622 | |||
| 1623 | report_write_failure: | ||
| 1624 | dev_err(dev, "ab->write fail %d\n", err); | ||
| 1625 | return err; | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | DEFINE_SHOW_ATTRIBUTE(ab8500_modem); | ||
| 1629 | |||
| 1630 | /* | ||
| 1631 | * return length of an ASCII numerical value, 0 is string is not a | ||
| 1632 | * numerical value. | ||
| 1633 | * string shall start at value 1st char. | ||
| 1634 | * string can be tailed with \0 or space or newline chars only. | ||
| 1635 | * value can be decimal or hexadecimal (prefixed 0x or 0X). | ||
| 1636 | */ | ||
| 1637 | static int strval_len(char *b) | ||
| 1638 | { | ||
| 1639 | char *s = b; | ||
| 1640 | |||
| 1641 | if ((*s == '0') && ((*(s+1) == 'x') || (*(s+1) == 'X'))) { | ||
| 1642 | s += 2; | ||
| 1643 | for (; *s && (*s != ' ') && (*s != '\n'); s++) { | ||
| 1644 | if (!isxdigit(*s)) | ||
| 1645 | return 0; | ||
| 1646 | } | ||
| 1647 | } else { | ||
| 1648 | if (*s == '-') | ||
| 1649 | s++; | ||
| 1650 | for (; *s && (*s != ' ') && (*s != '\n'); s++) { | ||
| 1651 | if (!isdigit(*s)) | ||
| 1652 | return 0; | ||
| 1653 | } | ||
| 1654 | } | ||
| 1655 | return (int) (s-b); | ||
| 1656 | } | ||
| 1657 | |||
| 1658 | /* | ||
| 1659 | * parse hwreg input data. | ||
| 1660 | * update global hwreg_cfg only if input data syntax is ok. | ||
| 1661 | */ | ||
| 1662 | static ssize_t hwreg_common_write(char *b, struct hwreg_cfg *cfg, | ||
| 1663 | struct device *dev) | ||
| 1664 | { | ||
| 1665 | uint write, val = 0; | ||
| 1666 | u8 regvalue; | ||
| 1667 | int ret; | ||
| 1668 | struct hwreg_cfg loc = { | ||
| 1669 | .bank = 0, /* default: invalid phys addr */ | ||
| 1670 | .addr = 0, /* default: invalid phys addr */ | ||
| 1671 | .fmt = 0, /* default: 32bit access, hex output */ | ||
| 1672 | .mask = 0xFFFFFFFF, /* default: no mask */ | ||
| 1673 | .shift = 0, /* default: no bit shift */ | ||
| 1674 | }; | ||
| 1675 | |||
| 1676 | /* read or write ? */ | ||
| 1677 | if (!strncmp(b, "read ", 5)) { | ||
| 1678 | write = 0; | ||
| 1679 | b += 5; | ||
| 1680 | } else if (!strncmp(b, "write ", 6)) { | ||
| 1681 | write = 1; | ||
| 1682 | b += 6; | ||
| 1683 | } else | ||
| 1684 | return -EINVAL; | ||
| 1685 | |||
| 1686 | /* OPTIONS -l|-w|-b -s -m -o */ | ||
| 1687 | while ((*b == ' ') || (*b == '-')) { | ||
| 1688 | if (*(b-1) != ' ') { | ||
| 1689 | b++; | ||
| 1690 | continue; | ||
| 1691 | } | ||
| 1692 | if ((!strncmp(b, "-d ", 3)) || | ||
| 1693 | (!strncmp(b, "-dec ", 5))) { | ||
| 1694 | b += (*(b+2) == ' ') ? 3 : 5; | ||
| 1695 | loc.fmt |= (1<<0); | ||
| 1696 | } else if ((!strncmp(b, "-h ", 3)) || | ||
| 1697 | (!strncmp(b, "-hex ", 5))) { | ||
| 1698 | b += (*(b+2) == ' ') ? 3 : 5; | ||
| 1699 | loc.fmt &= ~(1<<0); | ||
| 1700 | } else if ((!strncmp(b, "-m ", 3)) || | ||
| 1701 | (!strncmp(b, "-mask ", 6))) { | ||
| 1702 | b += (*(b+2) == ' ') ? 3 : 6; | ||
| 1703 | if (strval_len(b) == 0) | ||
| 1704 | return -EINVAL; | ||
| 1705 | ret = kstrtoul(b, 0, &loc.mask); | ||
| 1706 | if (ret) | ||
| 1707 | return ret; | ||
| 1708 | } else if ((!strncmp(b, "-s ", 3)) || | ||
| 1709 | (!strncmp(b, "-shift ", 7))) { | ||
| 1710 | b += (*(b+2) == ' ') ? 3 : 7; | ||
| 1711 | if (strval_len(b) == 0) | ||
| 1712 | return -EINVAL; | ||
| 1713 | ret = kstrtol(b, 0, &loc.shift); | ||
| 1714 | if (ret) | ||
| 1715 | return ret; | ||
| 1716 | } else { | ||
| 1717 | return -EINVAL; | ||
| 1718 | } | ||
| 1719 | } | ||
| 1720 | /* get arg BANK and ADDRESS */ | ||
| 1721 | if (strval_len(b) == 0) | ||
| 1722 | return -EINVAL; | ||
| 1723 | ret = kstrtouint(b, 0, &loc.bank); | ||
| 1724 | if (ret) | ||
| 1725 | return ret; | ||
| 1726 | while (*b == ' ') | ||
| 1727 | b++; | ||
| 1728 | if (strval_len(b) == 0) | ||
| 1729 | return -EINVAL; | ||
| 1730 | ret = kstrtoul(b, 0, &loc.addr); | ||
| 1731 | if (ret) | ||
| 1732 | return ret; | ||
| 1733 | |||
| 1734 | if (write) { | ||
| 1735 | while (*b == ' ') | ||
| 1736 | b++; | ||
| 1737 | if (strval_len(b) == 0) | ||
| 1738 | return -EINVAL; | ||
| 1739 | ret = kstrtouint(b, 0, &val); | ||
| 1740 | if (ret) | ||
| 1741 | return ret; | ||
| 1742 | } | ||
| 1743 | |||
| 1744 | /* args are ok, update target cfg (mainly for read) */ | ||
| 1745 | *cfg = loc; | ||
| 1746 | |||
| 1747 | #ifdef ABB_HWREG_DEBUG | ||
| 1748 | pr_warn("HWREG request: %s, %s,\n", (write) ? "write" : "read", | ||
| 1749 | REG_FMT_DEC(cfg) ? "decimal" : "hexa"); | ||
| 1750 | pr_warn(" addr=0x%08X, mask=0x%X, shift=%d" "value=0x%X\n", | ||
| 1751 | cfg->addr, cfg->mask, cfg->shift, val); | ||
| 1752 | #endif | ||
| 1753 | |||
| 1754 | if (!write) | ||
| 1755 | return 0; | ||
| 1756 | |||
| 1757 | ret = abx500_get_register_interruptible(dev, | ||
| 1758 | (u8)cfg->bank, (u8)cfg->addr, ®value); | ||
| 1759 | if (ret < 0) { | ||
| 1760 | dev_err(dev, "abx500_get_reg fail %d, %d\n", | ||
| 1761 | ret, __LINE__); | ||
| 1762 | return -EINVAL; | ||
| 1763 | } | ||
| 1764 | |||
| 1765 | if (cfg->shift >= 0) { | ||
| 1766 | regvalue &= ~(cfg->mask << (cfg->shift)); | ||
| 1767 | val = (val & cfg->mask) << (cfg->shift); | ||
| 1768 | } else { | ||
| 1769 | regvalue &= ~(cfg->mask >> (-cfg->shift)); | ||
| 1770 | val = (val & cfg->mask) >> (-cfg->shift); | ||
| 1771 | } | ||
| 1772 | val = val | regvalue; | ||
| 1773 | |||
| 1774 | ret = abx500_set_register_interruptible(dev, | ||
| 1775 | (u8)cfg->bank, (u8)cfg->addr, (u8)val); | ||
| 1776 | if (ret < 0) { | ||
| 1777 | pr_err("abx500_set_reg failed %d, %d", ret, __LINE__); | ||
| 1778 | return -EINVAL; | ||
| 1779 | } | ||
| 1780 | |||
| 1781 | return 0; | ||
| 1782 | } | ||
| 1783 | |||
| 1784 | static ssize_t ab8500_hwreg_write(struct file *file, | ||
| 1785 | const char __user *user_buf, size_t count, loff_t *ppos) | ||
| 1786 | { | ||
| 1787 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | ||
| 1788 | char buf[128]; | ||
| 1789 | int buf_size, ret; | ||
| 1790 | |||
| 1791 | /* Get userspace string and assure termination */ | ||
| 1792 | buf_size = min((int)count, (int)(sizeof(buf)-1)); | ||
| 1793 | if (copy_from_user(buf, user_buf, buf_size)) | ||
| 1794 | return -EFAULT; | ||
| 1795 | buf[buf_size] = 0; | ||
| 1796 | |||
| 1797 | /* get args and process */ | ||
| 1798 | ret = hwreg_common_write(buf, &hwreg_cfg, dev); | ||
| 1799 | return (ret) ? ret : buf_size; | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | /* | ||
| 1803 | * - irq subscribe/unsubscribe stuff | ||
| 1804 | */ | ||
| 1805 | static int ab8500_subscribe_unsubscribe_print(struct seq_file *s, void *p) | ||
| 1806 | { | ||
| 1807 | seq_printf(s, "%d\n", irq_first); | ||
| 1808 | |||
| 1809 | return 0; | ||
| 1810 | } | ||
| 1811 | |||
| 1812 | static int ab8500_subscribe_unsubscribe_open(struct inode *inode, | ||
| 1813 | struct file *file) | ||
| 1814 | { | ||
| 1815 | return single_open(file, ab8500_subscribe_unsubscribe_print, | ||
| 1816 | inode->i_private); | ||
| 1817 | } | ||
| 1818 | |||
| 1819 | /* | ||
| 1820 | * Userspace should use poll() on this file. When an event occur | ||
| 1821 | * the blocking poll will be released. | ||
| 1822 | */ | ||
| 1823 | static ssize_t show_irq(struct device *dev, | ||
| 1824 | struct device_attribute *attr, char *buf) | ||
| 1825 | { | ||
| 1826 | unsigned long name; | ||
| 1827 | unsigned int irq_index; | ||
| 1828 | int err; | ||
| 1829 | |||
| 1830 | err = kstrtoul(attr->attr.name, 0, &name); | ||
| 1831 | if (err) | ||
| 1832 | return err; | ||
| 1833 | |||
| 1834 | irq_index = name - irq_first; | ||
| 1835 | if (irq_index >= num_irqs) | ||
| 1836 | return -EINVAL; | ||
| 1837 | |||
| 1838 | return sprintf(buf, "%u\n", irq_count[irq_index]); | ||
| 1839 | } | ||
| 1840 | |||
| 1841 | static ssize_t ab8500_subscribe_write(struct file *file, | ||
| 1842 | const char __user *user_buf, | ||
| 1843 | size_t count, loff_t *ppos) | ||
| 1844 | { | ||
| 1845 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | ||
| 1846 | unsigned long user_val; | ||
| 1847 | int err; | ||
| 1848 | unsigned int irq_index; | ||
| 1849 | |||
| 1850 | err = kstrtoul_from_user(user_buf, count, 0, &user_val); | ||
| 1851 | if (err) | ||
| 1852 | return err; | ||
| 1853 | |||
| 1854 | if (user_val < irq_first) { | ||
| 1855 | dev_err(dev, "debugfs error input < %d\n", irq_first); | ||
| 1856 | return -EINVAL; | ||
| 1857 | } | ||
| 1858 | if (user_val > irq_last) { | ||
| 1859 | dev_err(dev, "debugfs error input > %d\n", irq_last); | ||
| 1860 | return -EINVAL; | ||
| 1861 | } | ||
| 1862 | |||
| 1863 | irq_index = user_val - irq_first; | ||
| 1864 | if (irq_index >= num_irqs) | ||
| 1865 | return -EINVAL; | ||
| 1866 | |||
| 1867 | /* | ||
| 1868 | * This will create a sysfs file named <irq-nr> which userspace can | ||
| 1869 | * use to select or poll and get the AB8500 events | ||
| 1870 | */ | ||
| 1871 | dev_attr[irq_index] = kmalloc(sizeof(struct device_attribute), | ||
| 1872 | GFP_KERNEL); | ||
| 1873 | if (!dev_attr[irq_index]) | ||
| 1874 | return -ENOMEM; | ||
| 1875 | |||
| 1876 | event_name[irq_index] = kasprintf(GFP_KERNEL, "%lu", user_val); | ||
| 1877 | if (!event_name[irq_index]) | ||
| 1878 | return -ENOMEM; | ||
| 1879 | |||
| 1880 | dev_attr[irq_index]->show = show_irq; | ||
| 1881 | dev_attr[irq_index]->store = NULL; | ||
| 1882 | dev_attr[irq_index]->attr.name = event_name[irq_index]; | ||
| 1883 | dev_attr[irq_index]->attr.mode = S_IRUGO; | ||
| 1884 | err = sysfs_create_file(&dev->kobj, &dev_attr[irq_index]->attr); | ||
| 1885 | if (err < 0) { | ||
| 1886 | pr_info("sysfs_create_file failed %d\n", err); | ||
| 1887 | return err; | ||
| 1888 | } | ||
| 1889 | |||
| 1890 | err = request_threaded_irq(user_val, NULL, ab8500_debug_handler, | ||
| 1891 | IRQF_SHARED | IRQF_NO_SUSPEND | IRQF_ONESHOT, | ||
| 1892 | "ab8500-debug", &dev->kobj); | ||
| 1893 | if (err < 0) { | ||
| 1894 | pr_info("request_threaded_irq failed %d, %lu\n", | ||
| 1895 | err, user_val); | ||
| 1896 | sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr); | ||
| 1897 | return err; | ||
| 1898 | } | ||
| 1899 | |||
| 1900 | return count; | ||
| 1901 | } | ||
| 1902 | |||
| 1903 | static ssize_t ab8500_unsubscribe_write(struct file *file, | ||
| 1904 | const char __user *user_buf, | ||
| 1905 | size_t count, loff_t *ppos) | ||
| 1906 | { | ||
| 1907 | struct device *dev = ((struct seq_file *)(file->private_data))->private; | ||
| 1908 | unsigned long user_val; | ||
| 1909 | int err; | ||
| 1910 | unsigned int irq_index; | ||
| 1911 | |||
| 1912 | err = kstrtoul_from_user(user_buf, count, 0, &user_val); | ||
| 1913 | if (err) | ||
| 1914 | return err; | ||
| 1915 | |||
| 1916 | if (user_val < irq_first) { | ||
| 1917 | dev_err(dev, "debugfs error input < %d\n", irq_first); | ||
| 1918 | return -EINVAL; | ||
| 1919 | } | ||
| 1920 | if (user_val > irq_last) { | ||
| 1921 | dev_err(dev, "debugfs error input > %d\n", irq_last); | ||
| 1922 | return -EINVAL; | ||
| 1923 | } | ||
| 1924 | |||
| 1925 | irq_index = user_val - irq_first; | ||
| 1926 | if (irq_index >= num_irqs) | ||
| 1927 | return -EINVAL; | ||
| 1928 | |||
| 1929 | /* Set irq count to 0 when unsubscribe */ | ||
| 1930 | irq_count[irq_index] = 0; | ||
| 1931 | |||
| 1932 | if (dev_attr[irq_index]) | ||
| 1933 | sysfs_remove_file(&dev->kobj, &dev_attr[irq_index]->attr); | ||
| 1934 | |||
| 1935 | |||
| 1936 | free_irq(user_val, &dev->kobj); | ||
| 1937 | kfree(event_name[irq_index]); | ||
| 1938 | kfree(dev_attr[irq_index]); | ||
| 1939 | |||
| 1940 | return count; | ||
| 1941 | } | ||
| 1942 | |||
| 1943 | /* | ||
| 1944 | * - several debugfs nodes fops | ||
| 1945 | */ | ||
| 1946 | |||
| 1947 | static const struct file_operations ab8500_bank_fops = { | ||
| 1948 | .open = ab8500_bank_open, | ||
| 1949 | .write = ab8500_bank_write, | ||
| 1950 | .read = seq_read, | ||
| 1951 | .llseek = seq_lseek, | ||
| 1952 | .release = single_release, | ||
| 1953 | .owner = THIS_MODULE, | ||
| 1954 | }; | ||
| 1955 | |||
| 1956 | static const struct file_operations ab8500_address_fops = { | ||
| 1957 | .open = ab8500_address_open, | ||
| 1958 | .write = ab8500_address_write, | ||
| 1959 | .read = seq_read, | ||
| 1960 | .llseek = seq_lseek, | ||
| 1961 | .release = single_release, | ||
| 1962 | .owner = THIS_MODULE, | ||
| 1963 | }; | ||
| 1964 | |||
| 1965 | static const struct file_operations ab8500_val_fops = { | ||
| 1966 | .open = ab8500_val_open, | ||
| 1967 | .write = ab8500_val_write, | ||
| 1968 | .read = seq_read, | ||
| 1969 | .llseek = seq_lseek, | ||
| 1970 | .release = single_release, | ||
| 1971 | .owner = THIS_MODULE, | ||
| 1972 | }; | ||
| 1973 | |||
| 1974 | static const struct file_operations ab8500_subscribe_fops = { | ||
| 1975 | .open = ab8500_subscribe_unsubscribe_open, | ||
| 1976 | .write = ab8500_subscribe_write, | ||
| 1977 | .read = seq_read, | ||
| 1978 | .llseek = seq_lseek, | ||
| 1979 | .release = single_release, | ||
| 1980 | .owner = THIS_MODULE, | ||
| 1981 | }; | ||
| 1982 | |||
| 1983 | static const struct file_operations ab8500_unsubscribe_fops = { | ||
| 1984 | .open = ab8500_subscribe_unsubscribe_open, | ||
| 1985 | .write = ab8500_unsubscribe_write, | ||
| 1986 | .read = seq_read, | ||
| 1987 | .llseek = seq_lseek, | ||
| 1988 | .release = single_release, | ||
| 1989 | .owner = THIS_MODULE, | ||
| 1990 | }; | ||
| 1991 | |||
| 1992 | static const struct file_operations ab8500_hwreg_fops = { | ||
| 1993 | .open = ab8500_hwreg_open, | ||
| 1994 | .write = ab8500_hwreg_write, | ||
| 1995 | .read = seq_read, | ||
| 1996 | .llseek = seq_lseek, | ||
| 1997 | .release = single_release, | ||
| 1998 | .owner = THIS_MODULE, | ||
| 1999 | }; | ||
| 2000 | |||
| 2001 | static int ab8500_debug_probe(struct platform_device *plf) | ||
| 2002 | { | ||
| 2003 | struct dentry *ab8500_dir; | ||
| 2004 | struct ab8500 *ab8500; | ||
| 2005 | struct resource *res; | ||
| 2006 | |||
| 2007 | debug_bank = AB8500_MISC; | ||
| 2008 | debug_address = AB8500_REV_REG & 0x00FF; | ||
| 2009 | |||
| 2010 | ab8500 = dev_get_drvdata(plf->dev.parent); | ||
| 2011 | num_irqs = ab8500->mask_size; | ||
| 2012 | |||
| 2013 | irq_count = devm_kcalloc(&plf->dev, | ||
| 2014 | num_irqs, sizeof(*irq_count), GFP_KERNEL); | ||
| 2015 | if (!irq_count) | ||
| 2016 | return -ENOMEM; | ||
| 2017 | |||
| 2018 | dev_attr = devm_kcalloc(&plf->dev, | ||
| 2019 | num_irqs, sizeof(*dev_attr), GFP_KERNEL); | ||
| 2020 | if (!dev_attr) | ||
| 2021 | return -ENOMEM; | ||
| 2022 | |||
| 2023 | event_name = devm_kcalloc(&plf->dev, | ||
| 2024 | num_irqs, sizeof(*event_name), GFP_KERNEL); | ||
| 2025 | if (!event_name) | ||
| 2026 | return -ENOMEM; | ||
| 2027 | |||
| 2028 | res = platform_get_resource_byname(plf, 0, "IRQ_AB8500"); | ||
| 2029 | if (!res) { | ||
| 2030 | dev_err(&plf->dev, "AB8500 irq not found, err %d\n", irq_first); | ||
| 2031 | return -ENXIO; | ||
| 2032 | } | ||
| 2033 | irq_ab8500 = res->start; | ||
| 2034 | |||
| 2035 | irq_first = platform_get_irq_byname(plf, "IRQ_FIRST"); | ||
| 2036 | if (irq_first < 0) | ||
| 2037 | return irq_first; | ||
| 2038 | |||
| 2039 | irq_last = platform_get_irq_byname(plf, "IRQ_LAST"); | ||
| 2040 | if (irq_last < 0) | ||
| 2041 | return irq_last; | ||
| 2042 | |||
| 2043 | ab8500_dir = debugfs_create_dir(AB8500_NAME_STRING, NULL); | ||
| 2044 | |||
| 2045 | debugfs_create_file("all-bank-registers", S_IRUGO, ab8500_dir, | ||
| 2046 | &plf->dev, &ab8500_bank_registers_fops); | ||
| 2047 | debugfs_create_file("all-banks", S_IRUGO, ab8500_dir, | ||
| 2048 | &plf->dev, &ab8500_all_banks_fops); | ||
| 2049 | debugfs_create_file("register-bank", (S_IRUGO | S_IWUSR | S_IWGRP), | ||
| 2050 | ab8500_dir, &plf->dev, &ab8500_bank_fops); | ||
| 2051 | debugfs_create_file("register-address", (S_IRUGO | S_IWUSR | S_IWGRP), | ||
| 2052 | ab8500_dir, &plf->dev, &ab8500_address_fops); | ||
| 2053 | debugfs_create_file("register-value", (S_IRUGO | S_IWUSR | S_IWGRP), | ||
| 2054 | ab8500_dir, &plf->dev, &ab8500_val_fops); | ||
| 2055 | debugfs_create_file("irq-subscribe", (S_IRUGO | S_IWUSR | S_IWGRP), | ||
| 2056 | ab8500_dir, &plf->dev, &ab8500_subscribe_fops); | ||
| 2057 | |||
| 2058 | if (is_ab8500(ab8500)) { | ||
| 2059 | debug_ranges = ab8500_debug_ranges; | ||
| 2060 | num_interrupt_lines = AB8500_NR_IRQS; | ||
| 2061 | } else if (is_ab8505(ab8500)) { | ||
| 2062 | debug_ranges = ab8505_debug_ranges; | ||
| 2063 | num_interrupt_lines = AB8505_NR_IRQS; | ||
| 2064 | } else if (is_ab9540(ab8500)) { | ||
| 2065 | debug_ranges = ab8505_debug_ranges; | ||
| 2066 | num_interrupt_lines = AB9540_NR_IRQS; | ||
| 2067 | } else if (is_ab8540(ab8500)) { | ||
| 2068 | debug_ranges = ab8540_debug_ranges; | ||
| 2069 | num_interrupt_lines = AB8540_NR_IRQS; | ||
| 2070 | } | ||
| 2071 | |||
| 2072 | debugfs_create_file("interrupts", (S_IRUGO), ab8500_dir, &plf->dev, | ||
| 2073 | &ab8500_interrupts_fops); | ||
| 2074 | debugfs_create_file("irq-unsubscribe", (S_IRUGO | S_IWUSR | S_IWGRP), | ||
| 2075 | ab8500_dir, &plf->dev, &ab8500_unsubscribe_fops); | ||
| 2076 | debugfs_create_file("hwreg", (S_IRUGO | S_IWUSR | S_IWGRP), ab8500_dir, | ||
| 2077 | &plf->dev, &ab8500_hwreg_fops); | ||
| 2078 | debugfs_create_file("all-modem-registers", (S_IRUGO | S_IWUSR | S_IWGRP), | ||
| 2079 | ab8500_dir, &plf->dev, &ab8500_modem_fops); | ||
| 2080 | |||
| 2081 | return 0; | ||
| 2082 | } | ||
| 2083 | |||
| 2084 | static struct platform_driver ab8500_debug_driver = { | ||
| 2085 | .driver = { | ||
| 2086 | .name = "ab8500-debug", | ||
| 2087 | .suppress_bind_attrs = true, | ||
| 2088 | }, | ||
| 2089 | .probe = ab8500_debug_probe, | ||
| 2090 | }; | ||
| 2091 | |||
| 2092 | static int __init ab8500_debug_init(void) | ||
| 2093 | { | ||
| 2094 | return platform_driver_register(&ab8500_debug_driver); | ||
| 2095 | } | ||
| 2096 | subsys_initcall(ab8500_debug_init); | ||
| @@ -105,7 +105,7 @@ static const struct i2c_device_id arizona_i2c_id[] = { · 104 unmodified lines | |||
| 105 | MODULE_DEVICE_TABLE(i2c, arizona_i2c_id); | 105 | MODULE_DEVICE_TABLE(i2c, arizona_i2c_id); |
| 106 | 106 | ||
| 107 | #ifdef CONFIG_OF | 107 | #ifdef CONFIG_OF |
| 108 | const struct of_device_id arizona_i2c_of_match[] = { | 108 | static const struct of_device_id arizona_i2c_of_match[] = { |
| 109 | { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, | 109 | { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, |
| 110 | { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, | 110 | { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, |
| 111 | { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, | 111 | { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, |
| @@ -43,31 +43,13 @@ static const struct gpiod_lookup arizona_soc_gpios[] = { · 42 unmodified lines | |||
| 43 | { "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW }, | 43 | { "arizona", 4, "wlf,micd-pol", 0, GPIO_ACTIVE_LOW }, |
| 44 | }; | 44 | }; |
| 45 | 45 | ||
| 46 | /* | ||
| 47 | * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: | ||
| 48 | * Function A Play/Pause: 0 ohm | ||
| 49 | * Function D Voice assistant: 135 ohm | ||
| 50 | * Function B Volume Up 240 ohm | ||
| 51 | * Function C Volume Down 470 ohm | ||
| 52 | * Minimum Mic DC resistance 1000 ohm | ||
| 53 | * Minimum Ear speaker impedance 16 ohm | ||
| 54 | * Note the first max value below must be less then the min. speaker impedance, | ||
| 55 | * to allow CTIA/OMTP detection to work. The other max values are the closest | ||
| 56 | * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. | ||
| 57 | */ | ||
| 58 | static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { | ||
| 59 | { .max = 11, .key = KEY_PLAYPAUSE }, | ||
| 60 | { .max = 186, .key = KEY_VOICECOMMAND }, | ||
| 61 | { .max = 348, .key = KEY_VOLUMEUP }, | ||
| 62 | { .max = 752, .key = KEY_VOLUMEDOWN }, | ||
| 63 | }; | ||
| 64 | |||
| 65 | static void arizona_spi_acpi_remove_lookup(void *lookup) | 46 | static void arizona_spi_acpi_remove_lookup(void *lookup) |
| 66 | { | 47 | { |
| 67 | gpiod_remove_lookup_table(lookup); | 48 | gpiod_remove_lookup_table(lookup); |
| 68 | } | 49 | } |
| 69 | 50 | ||
| 70 | static int arizona_spi_acpi_probe(struct arizona *arizona) | 51 | /* For ACPI tables from boards which ship with Windows as factory OS */ |
| 52 | static int arizona_spi_acpi_windows_probe(struct arizona *arizona) | ||
| 71 | { | 53 | { |
| 72 | struct gpiod_lookup_table *lookup; | 54 | struct gpiod_lookup_table *lookup; |
| 73 | acpi_status status; | 55 | acpi_status status; |
| @@ -96,6 +78,65 @@ static int arizona_spi_acpi_probe(struct arizona *arizona) · 22 unmodified lines | |||
| 96 | if (ACPI_FAILURE(status)) | 78 | if (ACPI_FAILURE(status)) |
| 97 | dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status); | 79 | dev_warn(arizona->dev, "Failed to enable 32KHz clk ACPI error %d\n", status); |
| 98 | 80 | ||
| 81 | return 0; | ||
| 82 | } | ||
| 83 | |||
| 84 | /* For ACPI tables from boards which ship with Android as factory OS */ | ||
| 85 | static int arizona_spi_acpi_android_probe(struct arizona *arizona) | ||
| 86 | { | ||
| 87 | int ret; | ||
| 88 | |||
| 89 | /* | ||
| 90 | * Get the reset GPIO, treating -ENOENT as -EPROBE_DEFER to wait for | ||
| 91 | * the x86-android-tablets module to register the board specific GPIO | ||
| 92 | * lookup table. | ||
| 93 | */ | ||
| 94 | arizona->pdata.reset = devm_gpiod_get(arizona->dev, "reset", GPIOD_OUT_LOW); | ||
| 95 | if (IS_ERR(arizona->pdata.reset)) { | ||
| 96 | ret = PTR_ERR(arizona->pdata.reset); | ||
| 97 | if (ret == -ENOENT) { | ||
| 98 | dev_info_once(arizona->dev, | ||
| 99 | "Deferring probe till GPIO lookup is registered\n"); | ||
| 100 | ret = -EPROBE_DEFER; | ||
| 101 | } | ||
| 102 | return dev_err_probe(arizona->dev, ret, "getting reset GPIO\n"); | ||
| 103 | } | ||
| 104 | |||
| 105 | return 0; | ||
| 106 | } | ||
| 107 | |||
| 108 | /* | ||
| 109 | * The AOSP 3.5 mm Headset: Accessory Specification gives the following values: | ||
| 110 | * Function A Play/Pause: 0 ohm | ||
| 111 | * Function D Voice assistant: 135 ohm | ||
| 112 | * Function B Volume Up 240 ohm | ||
| 113 | * Function C Volume Down 470 ohm | ||
| 114 | * Minimum Mic DC resistance 1000 ohm | ||
| 115 | * Minimum Ear speaker impedance 16 ohm | ||
| 116 | * Note the first max value below must be less then the min. speaker impedance, | ||
| 117 | * to allow CTIA/OMTP detection to work. The other max values are the closest | ||
| 118 | * value from extcon-arizona.c:arizona_micd_levels halfway 2 button resistances. | ||
| 119 | */ | ||
| 120 | static const struct arizona_micd_range arizona_micd_aosp_ranges[] = { | ||
| 121 | { .max = 11, .key = KEY_PLAYPAUSE }, | ||
| 122 | { .max = 186, .key = KEY_VOICECOMMAND }, | ||
| 123 | { .max = 348, .key = KEY_VOLUMEUP }, | ||
| 124 | { .max = 752, .key = KEY_VOLUMEDOWN }, | ||
| 125 | }; | ||
| 126 | |||
| 127 | static int arizona_spi_acpi_probe(struct arizona *arizona) | ||
| 128 | { | ||
| 129 | struct acpi_device *adev = ACPI_COMPANION(arizona->dev); | ||
| 130 | int ret; | ||
| 131 | |||
| 132 | if (acpi_dev_hid_uid_match(adev, "10WM5102", NULL)) | ||
| 133 | ret = arizona_spi_acpi_android_probe(arizona); | ||
| 134 | else | ||
| 135 | ret = arizona_spi_acpi_windows_probe(arizona); | ||
| 136 | |||
| 137 | if (ret) | ||
| 138 | return ret; | ||
| 139 | |||
| 99 | /* | 140 | /* |
| 100 | * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING | 141 | * Some DSDTs wrongly declare the IRQ trigger-type as IRQF_TRIGGER_FALLING |
| 101 | * The IRQ line will stay low when a new IRQ event happens between reading | 142 | * The IRQ line will stay low when a new IRQ event happens between reading |
| @@ -130,6 +171,10 @@ static const struct acpi_device_id arizona_acpi_match[] = { · 28 unmodified lines | |||
| 130 | .id = "WM510205", | 171 | .id = "WM510205", |
| 131 | .driver_data = WM5102, | 172 | .driver_data = WM5102, |
| 132 | }, | 173 | }, |
| 174 | { | ||
| 175 | .id = "10WM5102", | ||
| 176 | .driver_data = WM5102, | ||
| 177 | }, | ||
| 133 | { } | 178 | { } |
| 134 | }; | 179 | }; |
| 135 | MODULE_DEVICE_TABLE(acpi, arizona_acpi_match); | 180 | MODULE_DEVICE_TABLE(acpi, arizona_acpi_match); |
| @@ -224,7 +269,7 @@ static const struct spi_device_id arizona_spi_ids[] = { · 88 unmodified lines | |||
| 224 | MODULE_DEVICE_TABLE(spi, arizona_spi_ids); | 269 | MODULE_DEVICE_TABLE(spi, arizona_spi_ids); |
| 225 | 270 | ||
| 226 | #ifdef CONFIG_OF | 271 | #ifdef CONFIG_OF |
| 227 | const struct of_device_id arizona_spi_of_match[] = { | 272 | static const struct of_device_id arizona_spi_of_match[] = { |
| 228 | { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, | 273 | { .compatible = "wlf,wm5102", .data = (void *)WM5102 }, |
| 229 | { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, | 274 | { .compatible = "wlf,wm5110", .data = (void *)WM5110 }, |
| 230 | { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, | 275 | { .compatible = "wlf,wm8280", .data = (void *)WM8280 }, |
| @@ -906,14 +906,14 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, · 905 unmodified lines | |||
| 906 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 906 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
| 907 | &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); | 907 | &asic3_cell_ds1wm, 1, mem, asic->irq_base, NULL); |
| 908 | if (ret < 0) | 908 | if (ret < 0) |
| 909 | goto out; | 909 | goto out_unmap; |
| 910 | } | 910 | } |
| 911 | 911 | ||
| 912 | if (mem_sdio && (irq >= 0)) { | 912 | if (mem_sdio && (irq >= 0)) { |
| 913 | ret = mfd_add_devices(&pdev->dev, pdev->id, | 913 | ret = mfd_add_devices(&pdev->dev, pdev->id, |
| 914 | &asic3_cell_mmc, 1, mem_sdio, irq, NULL); | 914 | &asic3_cell_mmc, 1, mem_sdio, irq, NULL); |
| 915 | if (ret < 0) | 915 | if (ret < 0) |
| 916 | goto out; | 916 | goto out_unmap; |
| 917 | } | 917 | } |
| 918 | 918 | ||
| 919 | ret = 0; | 919 | ret = 0; |
| @@ -927,8 +927,12 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, · 7 unmodified lines | |||
| 927 | ret = mfd_add_devices(&pdev->dev, 0, | 927 | ret = mfd_add_devices(&pdev->dev, 0, |
| 928 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); | 928 | asic3_cell_leds, ASIC3_NUM_LEDS, NULL, 0, NULL); |
| 929 | } | 929 | } |
| 930 | return ret; | ||
| 930 | 931 | ||
| 931 | out: | 932 | out_unmap: |
| 933 | if (asic->tmio_cnf) | ||
| 934 | iounmap(asic->tmio_cnf); | ||
| 935 | out: | ||
| 932 | return ret; | 936 | return ret; |
| 933 | } | 937 | } |
| 934 | 938 | ||
| @@ -105,7 +105,7 @@ static int __maybe_unused atmel_flexcom_resume_noirq(struct device *dev) · 104 unmodified lines | |||
| 105 | return 0; | 105 | return 0; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static const struct dev_pm_ops atmel_flexcom_pm_ops = { | 108 | static const struct dev_pm_ops __maybe_unused atmel_flexcom_pm_ops = { |
| 109 | .resume_noirq = atmel_flexcom_resume_noirq, | 109 | .resume_noirq = atmel_flexcom_resume_noirq, |
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| @@ -15,7 +15,6 @@ · 14 unmodified lines | |||
| 15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
| 16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
| 17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 18 | #include <linux/mfd/syscon.h> | ||
| 19 | #include <linux/of.h> | 18 | #include <linux/of.h> |
| 20 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
| 21 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
| @@ -15,11 +15,22 @@ · 14 unmodified lines | |||
| 15 | #include <linux/pm_runtime.h> | 15 | #include <linux/pm_runtime.h> |
| 16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/property.h> | 17 | #include <linux/property.h> |
| 18 | #include <linux/pxa2xx_ssp.h> | ||
| 18 | 19 | ||
| 19 | #include "intel-lpss.h" | 20 | #include "intel-lpss.h" |
| 20 | 21 | ||
| 22 | static const struct property_entry spt_spi_properties[] = { | ||
| 23 | PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_SPT_SSP), | ||
| 24 | { } | ||
| 25 | }; | ||
| 26 | |||
| 27 | static const struct software_node spt_spi_node = { | ||
| 28 | .properties = spt_spi_properties, | ||
| 29 | }; | ||
| 30 | |||
| 21 | static const struct intel_lpss_platform_info spt_info = { | 31 | static const struct intel_lpss_platform_info spt_info = { |
| 22 | .clk_rate = 120000000, | 32 | .clk_rate = 120000000, |
| 33 | .swnode = &spt_spi_node, | ||
| 23 | }; | 34 | }; |
| 24 | 35 | ||
| 25 | static const struct property_entry spt_i2c_properties[] = { | 36 | static const struct property_entry spt_i2c_properties[] = { |
| @@ -53,8 +64,18 @@ static const struct intel_lpss_platform_info spt_uart_info = { · 27 unmodified lines | |||
| 53 | .swnode = &uart_node, | 64 | .swnode = &uart_node, |
| 54 | }; | 65 | }; |
| 55 | 66 | ||
| 67 | static const struct property_entry bxt_spi_properties[] = { | ||
| 68 | PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_BXT_SSP), | ||
| 69 | { } | ||
| 70 | }; | ||
| 71 | |||
| 72 | static const struct software_node bxt_spi_node = { | ||
| 73 | .properties = bxt_spi_properties, | ||
| 74 | }; | ||
| 75 | |||
| 56 | static const struct intel_lpss_platform_info bxt_info = { | 76 | static const struct intel_lpss_platform_info bxt_info = { |
| 57 | .clk_rate = 100000000, | 77 | .clk_rate = 100000000, |
| 78 | .swnode = &bxt_spi_node, | ||
| 58 | }; | 79 | }; |
| 59 | 80 | ||
| 60 | static const struct property_entry bxt_i2c_properties[] = { | 81 | static const struct property_entry bxt_i2c_properties[] = { |
| @@ -89,6 +110,20 @@ static const struct intel_lpss_platform_info apl_i2c_info = { · 28 unmodified lines | |||
| 89 | .swnode = &apl_i2c_node, | 110 | .swnode = &apl_i2c_node, |
| 90 | }; | 111 | }; |
| 91 | 112 | ||
| 113 | static const struct property_entry cnl_spi_properties[] = { | ||
| 114 | PROPERTY_ENTRY_U32("intel,spi-pxa2xx-type", LPSS_CNL_SSP), | ||
| 115 | { } | ||
| 116 | }; | ||
| 117 | |||
| 118 | static const struct software_node cnl_spi_node = { | ||
| 119 | .properties = cnl_spi_properties, | ||
| 120 | }; | ||
| 121 | |||
| 122 | static const struct intel_lpss_platform_info cnl_info = { | ||
| 123 | .clk_rate = 120000000, | ||
| 124 | .swnode = &cnl_spi_node, | ||
| 125 | }; | ||
| 126 | |||
| 92 | static const struct intel_lpss_platform_info cnl_i2c_info = { | 127 | static const struct intel_lpss_platform_info cnl_i2c_info = { |
| 93 | .clk_rate = 216000000, | 128 | .clk_rate = 216000000, |
| 94 | .swnode = &spt_i2c_node, | 129 | .swnode = &spt_i2c_node, |
| @@ -108,8 +143,8 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = { · 13 unmodified lines | |||
| 108 | { "INT3449", (kernel_ulong_t)&spt_uart_info }, | 143 | { "INT3449", (kernel_ulong_t)&spt_uart_info }, |
| 109 | { "INT344A", (kernel_ulong_t)&spt_uart_info }, | 144 | { "INT344A", (kernel_ulong_t)&spt_uart_info }, |
| 110 | /* CNL */ | 145 | /* CNL */ |
| 111 | { "INT34B0", (kernel_ulong_t)&spt_info }, | 146 | { "INT34B0", (kernel_ulong_t)&cnl_info }, |
| 112 | { "INT34B1", (kernel_ulong_t)&spt_info }, | 147 | { "INT34B1", (kernel_ulong_t)&cnl_info }, |
| 113 | { "INT34B2", (kernel_ulong_t)&cnl_i2c_info }, | 148 | { "INT34B2", (kernel_ulong_t)&cnl_i2c_info }, |
| 114 | { "INT34B3", (kernel_ulong_t)&cnl_i2c_info }, | 149 | { "INT34B3", (kernel_ulong_t)&cnl_i2c_info }, |
| 115 | { "INT34B4", (kernel_ulong_t)&cnl_i2c_info }, | 150 | { "INT34B4", (kernel_ulong_t)&cnl_i2c_info }, |
| @@ -119,7 +154,7 @@ static const struct acpi_device_id intel_lpss_acpi_ids[] = { · 3 unmodified lines | |||
| 119 | { "INT34B8", (kernel_ulong_t)&spt_uart_info }, | 154 | { "INT34B8", (kernel_ulong_t)&spt_uart_info }, |
| 120 | { "INT34B9", (kernel_ulong_t)&spt_uart_info }, | 155 | { "INT34B9", (kernel_ulong_t)&spt_uart_info }, |
| 121 | { "INT34BA", (kernel_ulong_t)&spt_uart_info }, | 156 | { "INT34BA", (kernel_ulong_t)&spt_uart_info }, |
| 122 | { "INT34BC", (kernel_ulong_t)&spt_info }, | 157 | { "INT34BC", (kernel_ulong_t)&cnl_info }, |
| 123 | /* BXT */ | 158 | /* BXT */ |
| 124 | { "80860AAC", (kernel_ulong_t)&bxt_i2c_info }, | 159 | { "80860AAC", (kernel_ulong_t)&bxt_i2c_info }, |
| 125 | { "80860ABC", (kernel_ulong_t)&bxt_info }, | 160 | { "80860ABC", (kernel_ulong_t)&bxt_info }, |
| @@ -353,6 +353,21 @@ static const struct pci_device_id intel_lpss_pci_ids[] = { · 352 unmodified lines | |||
| 353 | { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info }, | 353 | { PCI_VDEVICE(INTEL, 0x5ac4), (kernel_ulong_t)&bxt_info }, |
| 354 | { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info }, | 354 | { PCI_VDEVICE(INTEL, 0x5ac6), (kernel_ulong_t)&bxt_info }, |
| 355 | { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, | 355 | { PCI_VDEVICE(INTEL, 0x5aee), (kernel_ulong_t)&bxt_uart_info }, |
| 356 | /* RPL-S */ | ||
| 357 | { PCI_VDEVICE(INTEL, 0x7a28), (kernel_ulong_t)&bxt_uart_info }, | ||
| 358 | { PCI_VDEVICE(INTEL, 0x7a29), (kernel_ulong_t)&bxt_uart_info }, | ||
| 359 | { PCI_VDEVICE(INTEL, 0x7a2a), (kernel_ulong_t)&bxt_info }, | ||
| 360 | { PCI_VDEVICE(INTEL, 0x7a2b), (kernel_ulong_t)&bxt_info }, | ||
| 361 | { PCI_VDEVICE(INTEL, 0x7a4c), (kernel_ulong_t)&bxt_i2c_info }, | ||
| 362 | { PCI_VDEVICE(INTEL, 0x7a4d), (kernel_ulong_t)&bxt_i2c_info }, | ||
| 363 | { PCI_VDEVICE(INTEL, 0x7a4e), (kernel_ulong_t)&bxt_i2c_info }, | ||
| 364 | { PCI_VDEVICE(INTEL, 0x7a4f), (kernel_ulong_t)&bxt_i2c_info }, | ||
| 365 | { PCI_VDEVICE(INTEL, 0x7a5c), (kernel_ulong_t)&bxt_uart_info }, | ||
| 366 | { PCI_VDEVICE(INTEL, 0x7a79), (kernel_ulong_t)&bxt_info }, | ||
| 367 | { PCI_VDEVICE(INTEL, 0x7a7b), (kernel_ulong_t)&bxt_info }, | ||
| 368 | { PCI_VDEVICE(INTEL, 0x7a7c), (kernel_ulong_t)&bxt_i2c_info }, | ||
| 369 | { PCI_VDEVICE(INTEL, 0x7a7d), (kernel_ulong_t)&bxt_i2c_info }, | ||
| 370 | { PCI_VDEVICE(INTEL, 0x7a7e), (kernel_ulong_t)&bxt_uart_info }, | ||
| 356 | /* ADL-S */ | 371 | /* ADL-S */ |
| 357 | { PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info }, | 372 | { PCI_VDEVICE(INTEL, 0x7aa8), (kernel_ulong_t)&bxt_uart_info }, |
| 358 | { PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info }, | 373 | { PCI_VDEVICE(INTEL, 0x7aa9), (kernel_ulong_t)&bxt_uart_info }, |
| @@ -64,6 +64,10 @@ static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, · 63 unmodified lines | |||
| 64 | /* Add lookup table for crc-pwm */ | 64 | /* Add lookup table for crc-pwm */ |
| 65 | pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); | 65 | pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); |
| 66 | 66 | ||
| 67 | /* To distuingish this domain from the GPIO/charger's irqchip domains */ | ||
| 68 | irq_domain_update_bus_token(regmap_irq_get_domain(pmic->irq_chip_data), | ||
| 69 | DOMAIN_BUS_NEXUS); | ||
| 70 | |||
| 67 | ret = mfd_add_devices(dev, -1, config->cell_dev, | 71 | ret = mfd_add_devices(dev, -1, config->cell_dev, |
| 68 | config->n_cell_devs, NULL, 0, | 72 | config->n_cell_devs, NULL, 0, |
| 69 | regmap_irq_get_domain(pmic->irq_chip_data)); | 73 | regmap_irq_get_domain(pmic->irq_chip_data)); |
| @@ -28,18 +28,10 @@ · 27 unmodified lines | |||
| 28 | #define CRYSTAL_COVE_IRQ_GPIO 5 | 28 | #define CRYSTAL_COVE_IRQ_GPIO 5 |
| 29 | #define CRYSTAL_COVE_IRQ_VHDMIOCP 6 | 29 | #define CRYSTAL_COVE_IRQ_VHDMIOCP 6 |
| 30 | 30 | ||
| 31 | static const struct resource gpio_resources[] = { | ||
| 32 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"), | ||
| 33 | }; | ||
| 34 | |||
| 35 | static const struct resource pwrsrc_resources[] = { | 31 | static const struct resource pwrsrc_resources[] = { |
| 36 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_PWRSRC, "PWRSRC"), | 32 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_PWRSRC, "PWRSRC"), |
| 37 | }; | 33 | }; |
| 38 | 34 | ||
| 39 | static const struct resource adc_resources[] = { | ||
| 40 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"), | ||
| 41 | }; | ||
| 42 | |||
| 43 | static const struct resource thermal_resources[] = { | 35 | static const struct resource thermal_resources[] = { |
| 44 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_THRM, "THERMAL"), | 36 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_THRM, "THERMAL"), |
| 45 | }; | 37 | }; |
| @@ -48,17 +40,24 @@ static const struct resource bcu_resources[] = { · 2 unmodified lines | |||
| 48 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_BCU, "BCU"), | 40 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_BCU, "BCU"), |
| 49 | }; | 41 | }; |
| 50 | 42 | ||
| 43 | static const struct resource adc_resources[] = { | ||
| 44 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_ADC, "ADC"), | ||
| 45 | }; | ||
| 46 | |||
| 47 | static const struct resource charger_resources[] = { | ||
| 48 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_CHGR, "CHGR"), | ||
| 49 | }; | ||
| 50 | |||
| 51 | static const struct resource gpio_resources[] = { | ||
| 52 | DEFINE_RES_IRQ_NAMED(CRYSTAL_COVE_IRQ_GPIO, "GPIO"), | ||
| 53 | }; | ||
| 54 | |||
| 51 | static struct mfd_cell crystal_cove_byt_dev[] = { | 55 | static struct mfd_cell crystal_cove_byt_dev[] = { |
| 52 | { | 56 | { |
| 53 | .name = "crystal_cove_pwrsrc", | 57 | .name = "crystal_cove_pwrsrc", |
| 54 | .num_resources = ARRAY_SIZE(pwrsrc_resources), | 58 | .num_resources = ARRAY_SIZE(pwrsrc_resources), |
| 55 | .resources = pwrsrc_resources, | 59 | .resources = pwrsrc_resources, |
| 56 | }, | 60 | }, |
| 57 | { | ||
| 58 | .name = "crystal_cove_adc", | ||
| 59 | .num_resources = ARRAY_SIZE(adc_resources), | ||
| 60 | .resources = adc_resources, | ||
| 61 | }, | ||
| 62 | { | 61 | { |
| 63 | .name = "crystal_cove_thermal", | 62 | .name = "crystal_cove_thermal", |
| 64 | .num_resources = ARRAY_SIZE(thermal_resources), | 63 | .num_resources = ARRAY_SIZE(thermal_resources), |
| @@ -69,6 +68,16 @@ static struct mfd_cell crystal_cove_byt_dev[] = { · 4 unmodified lines | |||
| 69 | .num_resources = ARRAY_SIZE(bcu_resources), | 68 | .num_resources = ARRAY_SIZE(bcu_resources), |
| 70 | .resources = bcu_resources, | 69 | .resources = bcu_resources, |
| 71 | }, | 70 | }, |
| 71 | { | ||
| 72 | .name = "crystal_cove_adc", | ||
| 73 | .num_resources = ARRAY_SIZE(adc_resources), | ||
| 74 | .resources = adc_resources, | ||
| 75 | }, | ||
| 76 | { | ||
| 77 | .name = "crystal_cove_charger", | ||
| 78 | .num_resources = ARRAY_SIZE(charger_resources), | ||
| 79 | .resources = charger_resources, | ||
| 80 | }, | ||
| 72 | { | 81 | { |
| 73 | .name = "crystal_cove_gpio", | 82 | .name = "crystal_cove_gpio", |
| 74 | .num_resources = ARRAY_SIZE(gpio_resources), | 83 | .num_resources = ARRAY_SIZE(gpio_resources), |
| @@ -898,7 +898,6 @@ static int iqs62x_probe(struct i2c_client *client) · 897 unmodified lines | |||
| 898 | struct iqs62x_info info; | 898 | struct iqs62x_info info; |
| 899 | unsigned int val; | 899 | unsigned int val; |
| 900 | int ret, i, j; | 900 | int ret, i, j; |
| 901 | u8 sw_num = 0; | ||
| 902 | const char *fw_name = NULL; | 901 | const char *fw_name = NULL; |
| 903 | 902 | ||
| 904 | iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL); | 903 | iqs62x = devm_kzalloc(&client->dev, sizeof(*iqs62x), GFP_KERNEL); |
| @@ -949,7 +948,8 @@ static int iqs62x_probe(struct i2c_client *client) · 44 unmodified lines | |||
| 949 | if (info.sw_num < iqs62x->dev_desc->sw_num) | 948 | if (info.sw_num < iqs62x->dev_desc->sw_num) |
| 950 | continue; | 949 | continue; |
| 951 | 950 | ||
| 952 | sw_num = info.sw_num; | 951 | iqs62x->sw_num = info.sw_num; |
| 952 | iqs62x->hw_num = info.hw_num; | ||
| 953 | 953 | ||
| 954 | /* | 954 | /* |
| 955 | * Read each of the device's designated calibration registers, | 955 | * Read each of the device's designated calibration registers, |
| @@ -985,7 +985,7 @@ static int iqs62x_probe(struct i2c_client *client) · 29 unmodified lines | |||
| 985 | return -EINVAL; | 985 | return -EINVAL; |
| 986 | } | 986 | } |
| 987 | 987 | ||
| 988 | if (!sw_num) { | 988 | if (!iqs62x->sw_num) { |
| 989 | dev_err(&client->dev, "Unrecognized software number: 0x%02X\n", | 989 | dev_err(&client->dev, "Unrecognized software number: 0x%02X\n", |
| 990 | info.sw_num); | 990 | info.sw_num); |
| 991 | return -EINVAL; | 991 | return -EINVAL; |
| @@ -87,7 +87,7 @@ static bool max77802_rtc_is_volatile_reg(struct device *dev, unsigned int reg) · 86 unmodified lines | |||
| 87 | reg == MAX77802_RTC_WEEKDAY || | 87 | reg == MAX77802_RTC_WEEKDAY || |
| 88 | reg == MAX77802_RTC_MONTH || | 88 | reg == MAX77802_RTC_MONTH || |
| 89 | reg == MAX77802_RTC_YEAR || | 89 | reg == MAX77802_RTC_YEAR || |
| 90 | reg == MAX77802_RTC_DATE); | 90 | reg == MAX77802_RTC_MONTHDAY); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg) | 93 | static bool max77802_is_volatile_reg(struct device *dev, unsigned int reg) |
| @@ -0,0 +1,152 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | ||
| 2 | /* | ||
| 3 | * Maxim MAX77714 Core Driver | ||
| 4 | * | ||
| 5 | * Copyright (C) 2022 Luca Ceresoli | ||
| 6 | * Author: Luca Ceresoli <luca@lucaceresoli.net> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #include <linux/i2c.h> | ||
| 10 | #include <linux/interrupt.h> | ||
| 11 | #include <linux/mfd/core.h> | ||
| 12 | #include <linux/mfd/max77714.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/of.h> | ||
| 15 | #include <linux/regmap.h> | ||
| 16 | |||
| 17 | static const struct mfd_cell max77714_cells[] = { | ||
| 18 | { .name = "max77714-watchdog" }, | ||
| 19 | { .name = "max77714-rtc" }, | ||
| 20 | }; | ||
| 21 | |||
| 22 | static const struct regmap_range max77714_readable_ranges[] = { | ||
| 23 | regmap_reg_range(MAX77714_INT_TOP, MAX77714_INT_TOP), | ||
| 24 | regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM), | ||
| 25 | regmap_reg_range(MAX77714_32K_STATUS, MAX77714_32K_CONFIG), | ||
| 26 | regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF), | ||
| 27 | }; | ||
| 28 | |||
| 29 | static const struct regmap_range max77714_writable_ranges[] = { | ||
| 30 | regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM), | ||
| 31 | regmap_reg_range(MAX77714_32K_CONFIG, MAX77714_32K_CONFIG), | ||
| 32 | regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF), | ||
| 33 | }; | ||
| 34 | |||
| 35 | static const struct regmap_access_table max77714_readable_table = { | ||
| 36 | .yes_ranges = max77714_readable_ranges, | ||
| 37 | .n_yes_ranges = ARRAY_SIZE(max77714_readable_ranges), | ||
| 38 | }; | ||
| 39 | |||
| 40 | static const struct regmap_access_table max77714_writable_table = { | ||
| 41 | .yes_ranges = max77714_writable_ranges, | ||
| 42 | .n_yes_ranges = ARRAY_SIZE(max77714_writable_ranges), | ||
| 43 | }; | ||
| 44 | |||
| 45 | static const struct regmap_config max77714_regmap_config = { | ||
| 46 | .reg_bits = 8, | ||
| 47 | .val_bits = 8, | ||
| 48 | .max_register = MAX77714_CNFG2_ONOFF, | ||
| 49 | .rd_table = &max77714_readable_table, | ||
| 50 | .wr_table = &max77714_writable_table, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static const struct regmap_irq max77714_top_irqs[] = { | ||
| 54 | REGMAP_IRQ_REG(MAX77714_IRQ_TOP_ONOFF, 0, MAX77714_INT_TOP_ONOFF), | ||
| 55 | REGMAP_IRQ_REG(MAX77714_IRQ_TOP_RTC, 0, MAX77714_INT_TOP_RTC), | ||
| 56 | REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GPIO, 0, MAX77714_INT_TOP_GPIO), | ||
| 57 | REGMAP_IRQ_REG(MAX77714_IRQ_TOP_LDO, 0, MAX77714_INT_TOP_LDO), | ||
| 58 | REGMAP_IRQ_REG(MAX77714_IRQ_TOP_SD, 0, MAX77714_INT_TOP_SD), | ||
| 59 | REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GLBL, 0, MAX77714_INT_TOP_GLBL), | ||
| 60 | }; | ||
| 61 | |||
| 62 | static const struct regmap_irq_chip max77714_irq_chip = { | ||
| 63 | .name = "max77714-pmic", | ||
| 64 | .status_base = MAX77714_INT_TOP, | ||
| 65 | .mask_base = MAX77714_INT_TOPM, | ||
| 66 | .num_regs = 1, | ||
| 67 | .irqs = max77714_top_irqs, | ||
| 68 | .num_irqs = ARRAY_SIZE(max77714_top_irqs), | ||
| 69 | }; | ||
| 70 | |||
| 71 | /* | ||
| 72 | * MAX77714 initially uses the internal, low precision oscillator. Enable | ||
| 73 | * the external oscillator by setting the XOSC_RETRY bit. If the external | ||
| 74 | * oscillator is not OK (probably not installed) this has no effect. | ||
| 75 | */ | ||
| 76 | static int max77714_setup_xosc(struct device *dev, struct regmap *regmap) | ||
| 77 | { | ||
| 78 | /* Internal Crystal Load Capacitance, indexed by value of 32KLOAD bits */ | ||
| 79 | static const unsigned int load_cap[4] = {0, 10, 12, 22}; /* pF */ | ||
| 80 | unsigned int load_cap_idx; | ||
| 81 | unsigned int status; | ||
| 82 | int err; | ||
| 83 | |||
| 84 | err = regmap_update_bits(regmap, MAX77714_32K_CONFIG, | ||
| 85 | MAX77714_32K_CONFIG_XOSC_RETRY, | ||
| 86 | MAX77714_32K_CONFIG_XOSC_RETRY); | ||
| 87 | if (err) | ||
| 88 | return dev_err_probe(dev, err, "Failed to configure the external oscillator\n"); | ||
| 89 | |||
| 90 | err = regmap_read(regmap, MAX77714_32K_STATUS, &status); | ||
| 91 | if (err) | ||
| 92 | return dev_err_probe(dev, err, "Failed to read external oscillator status\n"); | ||
| 93 | |||
| 94 | load_cap_idx = (status >> MAX77714_32K_STATUS_32KLOAD_SHF) | ||
| 95 | & MAX77714_32K_STATUS_32KLOAD_MSK; | ||
| 96 | |||
| 97 | dev_info(dev, "Using %s oscillator, %d pF load cap\n", | ||
| 98 | status & MAX77714_32K_STATUS_32KSOURCE ? "internal" : "external", | ||
| 99 | load_cap[load_cap_idx]); | ||
| 100 | |||
| 101 | return 0; | ||
| 102 | } | ||
| 103 | |||
| 104 | static int max77714_probe(struct i2c_client *client) | ||
| 105 | { | ||
| 106 | struct device *dev = &client->dev; | ||
| 107 | struct regmap *regmap; | ||
| 108 | struct regmap_irq_chip_data *irq_data; | ||
| 109 | int err; | ||
| 110 | |||
| 111 | regmap = devm_regmap_init_i2c(client, &max77714_regmap_config); | ||
| 112 | if (IS_ERR(regmap)) | ||
| 113 | return dev_err_probe(dev, PTR_ERR(regmap), | ||
| 114 | "Failed to initialise regmap\n"); | ||
| 115 | |||
| 116 | err = max77714_setup_xosc(dev, regmap); | ||
| 117 | if (err) | ||
| 118 | return err; | ||
| 119 | |||
| 120 | err = devm_regmap_add_irq_chip(dev, regmap, client->irq, | ||
| 121 | IRQF_ONESHOT | IRQF_SHARED, 0, | ||
| 122 | &max77714_irq_chip, &irq_data); | ||
| 123 | if (err) | ||
| 124 | return dev_err_probe(dev, err, "Failed to add PMIC IRQ chip\n"); | ||
| 125 | |||
| 126 | err = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, | ||
| 127 | max77714_cells, ARRAY_SIZE(max77714_cells), | ||
| 128 | NULL, 0, NULL); | ||
| 129 | if (err) | ||
| 130 | return dev_err_probe(dev, err, "Failed to register child devices\n"); | ||
| 131 | |||
| 132 | return 0; | ||
| 133 | } | ||
| 134 | |||
| 135 | static const struct of_device_id max77714_dt_match[] = { | ||
| 136 | { .compatible = "maxim,max77714" }, | ||
| 137 | {}, | ||
| 138 | }; | ||
| 139 | MODULE_DEVICE_TABLE(of, max77714_dt_match); | ||
| 140 | |||
| 141 | static struct i2c_driver max77714_driver = { | ||
| 142 | .driver = { | ||
| 143 | .name = "max77714", | ||
| 144 | .of_match_table = max77714_dt_match, | ||
| 145 | }, | ||
| 146 | .probe_new = max77714_probe, | ||
| 147 | }; | ||
| 148 | module_i2c_driver(max77714_driver); | ||
| 149 | |||
| 150 | MODULE_DESCRIPTION("Maxim MAX77714 MFD core driver"); | ||
| 151 | MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>"); | ||
| 152 | MODULE_LICENSE("GPL"); | ||
| @@ -323,8 +323,10 @@ int mc13xxx_adc_do_conversion(struct mc13xxx *mc13xxx, unsigned int mode, · 322 unmodified lines | |||
| 323 | adc1 |= MC13783_ADC1_ATOX; | 323 | adc1 |= MC13783_ADC1_ATOX; |
| 324 | 324 | ||
| 325 | dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); | 325 | dev_dbg(mc13xxx->dev, "%s: request irq\n", __func__); |
| 326 | mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, | 326 | ret = mc13xxx_irq_request(mc13xxx, MC13XXX_IRQ_ADCDONE, |
| 327 | mc13xxx_handler_adcdone, __func__, &adcdone_data); | 327 | mc13xxx_handler_adcdone, __func__, &adcdone_data); |
| 328 | if (ret) | ||
| 329 | goto out; | ||
| 328 | 330 | ||
| 329 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); | 331 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC0, adc0); |
| 330 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); | 332 | mc13xxx_reg_write(mc13xxx, MC13XXX_ADC1, adc1); |
| @@ -212,6 +212,7 @@ int mt6358_irq_init(struct mt6397_chip *chip) · 211 unmodified lines | |||
| 212 | 212 | ||
| 213 | switch (chip->chip_id) { | 213 | switch (chip->chip_id) { |
| 214 | case MT6358_CHIP_ID: | 214 | case MT6358_CHIP_ID: |
| 215 | case MT6366_CHIP_ID: | ||
| 215 | chip->irq_data = &mt6358_irqd; | 216 | chip->irq_data = &mt6358_irqd; |
| 216 | break; | 217 | break; |
| 217 | 218 | ||
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/of_device.h> | 20 | #include <linux/of_device.h> |
| 21 | #include <linux/regmap.h> | 21 | #include <linux/regmap.h> |
| 22 | #include <linux/reboot.h> | ||
| 22 | 23 | ||
| 23 | struct rk808_reg_data { | 24 | struct rk808_reg_data { |
| 24 | int addr; | 25 | int addr; |
| @@ -543,6 +544,7 @@ static void rk808_pm_power_off(void) · 518 unmodified lines | |||
| 543 | reg = RK808_DEVCTRL_REG, | 544 | reg = RK808_DEVCTRL_REG, |
| 544 | bit = DEV_OFF_RST; | 545 | bit = DEV_OFF_RST; |
| 545 | break; | 546 | break; |
| 547 | case RK809_ID: | ||
| 546 | case RK817_ID: | 548 | case RK817_ID: |
| 547 | reg = RK817_SYS_CFG(3); | 549 | reg = RK817_SYS_CFG(3); |
| 548 | bit = DEV_OFF; | 550 | bit = DEV_OFF; |
| @@ -559,6 +561,34 @@ static void rk808_pm_power_off(void) · 10 unmodified lines | |||
| 559 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); | 561 | dev_err(&rk808_i2c_client->dev, "Failed to shutdown device!\n"); |
| 560 | } | 562 | } |
| 561 | 563 | ||
| 564 | static int rk808_restart_notify(struct notifier_block *this, unsigned long mode, void *cmd) | ||
| 565 | { | ||
| 566 | struct rk808 *rk808 = i2c_get_clientdata(rk808_i2c_client); | ||
| 567 | unsigned int reg, bit; | ||
| 568 | int ret; | ||
| 569 | |||
| 570 | switch (rk808->variant) { | ||
| 571 | case RK809_ID: | ||
| 572 | case RK817_ID: | ||
| 573 | reg = RK817_SYS_CFG(3); | ||
| 574 | bit = DEV_RST; | ||
| 575 | break; | ||
| 576 | |||
| 577 | default: | ||
| 578 | return NOTIFY_DONE; | ||
| 579 | } | ||
| 580 | ret = regmap_update_bits(rk808->regmap, reg, bit, bit); | ||
| 581 | if (ret) | ||
| 582 | dev_err(&rk808_i2c_client->dev, "Failed to restart device!\n"); | ||
| 583 | |||
| 584 | return NOTIFY_DONE; | ||
| 585 | } | ||
| 586 | |||
| 587 | static struct notifier_block rk808_restart_handler = { | ||
| 588 | .notifier_call = rk808_restart_notify, | ||
| 589 | .priority = 192, | ||
| 590 | }; | ||
| 591 | |||
| 562 | static void rk8xx_shutdown(struct i2c_client *client) | 592 | static void rk8xx_shutdown(struct i2c_client *client) |
| 563 | { | 593 | { |
| 564 | struct rk808 *rk808 = i2c_get_clientdata(client); | 594 | struct rk808 *rk808 = i2c_get_clientdata(client); |
| @@ -727,6 +757,18 @@ static int rk808_probe(struct i2c_client *client, · 162 unmodified lines | |||
| 727 | if (of_property_read_bool(np, "rockchip,system-power-controller")) { | 757 | if (of_property_read_bool(np, "rockchip,system-power-controller")) { |
| 728 | rk808_i2c_client = client; | 758 | rk808_i2c_client = client; |
| 729 | pm_power_off = rk808_pm_power_off; | 759 | pm_power_off = rk808_pm_power_off; |
| 760 | |||
| 761 | switch (rk808->variant) { | ||
| 762 | case RK809_ID: | ||
| 763 | case RK817_ID: | ||
| 764 | ret = register_restart_handler(&rk808_restart_handler); | ||
| 765 | if (ret) | ||
| 766 | dev_warn(&client->dev, "failed to register rst handler, %d\n", ret); | ||
| 767 | break; | ||
| 768 | default: | ||
| 769 | dev_dbg(&client->dev, "pmic controlled board reset not supported\n"); | ||
| 770 | break; | ||
| 771 | } | ||
| 730 | } | 772 | } |
| 731 | 773 | ||
| 732 | return 0; | 774 | return 0; |
| @@ -749,6 +791,8 @@ static int rk808_remove(struct i2c_client *client) · 16 unmodified lines | |||
| 749 | if (pm_power_off == rk808_pm_power_off) | 791 | if (pm_power_off == rk808_pm_power_off) |
| 750 | pm_power_off = NULL; | 792 | pm_power_off = NULL; |
| 751 | 793 | ||
| 794 | unregister_restart_handler(&rk808_restart_handler); | ||
| 795 | |||
| 752 | return 0; | 796 | return 0; |
| 753 | } | 797 | } |
| 754 | 798 | ||
| @@ -23,7 +23,7 @@ enum { · 22 unmodified lines | |||
| 23 | }; | 23 | }; |
| 24 | 24 | ||
| 25 | /* | 25 | /* |
| 26 | * Due to the BD9576MUF nasty IRQ behaiour we don't always populate IRQs. | 26 | * Due to the BD9576MUF nasty IRQ behaviour we don't always populate IRQs. |
| 27 | * These will be added to regulator resources only if IRQ information for the | 27 | * These will be added to regulator resources only if IRQ information for the |
| 28 | * PMIC is populated in device-tree. | 28 | * PMIC is populated in device-tree. |
| 29 | */ | 29 | */ |
| @@ -62,8 +62,19 @@ static int simple_mfd_i2c_probe(struct i2c_client *i2c) · 61 unmodified lines | |||
| 62 | return ret; | 62 | return ret; |
| 63 | } | 63 | } |
| 64 | 64 | ||
| 65 | static const struct mfd_cell sy7636a_cells[] = { | ||
| 66 | { .name = "sy7636a-regulator", }, | ||
| 67 | { .name = "sy7636a-temperature", }, | ||
| 68 | }; | ||
| 69 | |||
| 70 | static const struct simple_mfd_data silergy_sy7636a = { | ||
| 71 | .mfd_cell = sy7636a_cells, | ||
| 72 | .mfd_cell_size = ARRAY_SIZE(sy7636a_cells), | ||
| 73 | }; | ||
| 74 | |||
| 65 | static const struct of_device_id simple_mfd_i2c_of_match[] = { | 75 | static const struct of_device_id simple_mfd_i2c_of_match[] = { |
| 66 | { .compatible = "kontron,sl28cpld" }, | 76 | { .compatible = "kontron,sl28cpld" }, |
| 77 | { .compatible = "silergy,sy7636a", .data = &silergy_sy7636a}, | ||
| 67 | {} | 78 | {} |
| 68 | }; | 79 | }; |
| 69 | MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); | 80 | MODULE_DEVICE_TABLE(of, simple_mfd_i2c_of_match); |
| @@ -590,7 +590,7 @@ static int sta2x11_mfd_probe(struct pci_dev *pdev, · 589 unmodified lines | |||
| 590 | 590 | ||
| 591 | /* Record this pdev before mfd_add_devices: their probe looks for it */ | 591 | /* Record this pdev before mfd_add_devices: their probe looks for it */ |
| 592 | if (!sta2x11_mfd_find(pdev)) | 592 | if (!sta2x11_mfd_find(pdev)) |
| 593 | sta2x11_mfd_add(pdev, GFP_ATOMIC); | 593 | sta2x11_mfd_add(pdev, GFP_KERNEL); |
| 594 | 594 | ||
| 595 | /* Just 2 bars for all mfd's at present */ | 595 | /* Just 2 bars for all mfd's at present */ |
| 596 | for (i = 0; i < 2; i++) { | 596 | for (i = 0; i < 2; i++) { |
| @@ -392,17 +392,22 @@ err: · 391 unmodified lines | |||
| 392 | return ret; | 392 | return ret; |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | static int stmfx_chip_exit(struct i2c_client *client) | 395 | static void stmfx_chip_exit(struct i2c_client *client) |
| 396 | { | 396 | { |
| 397 | struct stmfx *stmfx = i2c_get_clientdata(client); | 397 | struct stmfx *stmfx = i2c_get_clientdata(client); |
| 398 | 398 | ||
| 399 | regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0); | 399 | regmap_write(stmfx->map, STMFX_REG_IRQ_SRC_EN, 0); |
| 400 | regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0); | 400 | regmap_write(stmfx->map, STMFX_REG_SYS_CTRL, 0); |
| 401 | 401 | ||
| 402 | if (stmfx->vdd) | 402 | if (stmfx->vdd) { |
| 403 | return regulator_disable(stmfx->vdd); | 403 | int ret; |
| 404 | 404 | ||
| 405 | return 0; | 405 | ret = regulator_disable(stmfx->vdd); |
| 406 | if (ret) | ||
| 407 | dev_err(&client->dev, | ||
| 408 | "Failed to disable vdd regulator: %pe\n", | ||
| 409 | ERR_PTR(ret)); | ||
| 410 | } | ||
| 406 | } | 411 | } |
| 407 | 412 | ||
| 408 | static int stmfx_probe(struct i2c_client *client, | 413 | static int stmfx_probe(struct i2c_client *client, |
| @@ -466,7 +471,9 @@ static int stmfx_remove(struct i2c_client *client) · 57 unmodified lines | |||
| 466 | { | 471 | { |
| 467 | stmfx_irq_exit(client); | 472 | stmfx_irq_exit(client); |
| 468 | 473 | ||
| 469 | return stmfx_chip_exit(client); | 474 | stmfx_chip_exit(client); |
| 475 | |||
| 476 | return 0; | ||
| 470 | } | 477 | } |
| 471 | 478 | ||
| 472 | #ifdef CONFIG_PM_SLEEP | 479 | #ifdef CONFIG_PM_SLEEP |
| @@ -1219,7 +1219,6 @@ config REGULATOR_STW481X_VMMC · 1218 unmodified lines | |||
| 1219 | 1219 | ||
| 1220 | config REGULATOR_SY7636A | 1220 | config REGULATOR_SY7636A |
| 1221 | tristate "Silergy SY7636A voltage regulator" | 1221 | tristate "Silergy SY7636A voltage regulator" |
| 1222 | depends on MFD_SY7636A | ||
| 1223 | help | 1222 | help |
| 1224 | This driver supports Silergy SY3686A voltage regulator. | 1223 | This driver supports Silergy SY3686A voltage regulator. |
| 1225 | 1224 | ||
| @@ -7,11 +7,14 @@ · 6 unmodified lines | |||
| 7 | // Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com> | 7 | // Authors: Lars Ivar Miljeteig <lars.ivar.miljeteig@remarkable.com> |
| 8 | // Alistair Francis <alistair@alistair23.me> | 8 | // Alistair Francis <alistair@alistair23.me> |
| 9 | 9 | ||
| 10 | #include <linux/gpio/consumer.h> | ||
| 11 | #include <linux/i2c.h> | ||
| 12 | #include <linux/mfd/sy7636a.h> | ||
| 10 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 11 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
| 15 | #include <linux/regulator/driver.h> | ||
| 16 | #include <linux/regulator/machine.h> | ||
| 12 | #include <linux/regmap.h> | 17 | #include <linux/regmap.h> |
| 13 | #include <linux/gpio/consumer.h> | ||
| 14 | #include <linux/mfd/sy7636a.h> | ||
| 15 | 18 | ||
| 16 | struct sy7636a_data { | 19 | struct sy7636a_data { |
| 17 | struct regmap *regmap; | 20 | struct regmap *regmap; |
| @@ -375,7 +375,7 @@ config RTC_DRV_MAX8997 · 374 unmodified lines | |||
| 375 | 375 | ||
| 376 | config RTC_DRV_MAX77686 | 376 | config RTC_DRV_MAX77686 |
| 377 | tristate "Maxim MAX77686" | 377 | tristate "Maxim MAX77686" |
| 378 | depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST | 378 | depends on MFD_MAX77686 || MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST |
| 379 | help | 379 | help |
| 380 | If you say yes here you will get support for the | 380 | If you say yes here you will get support for the |
| 381 | RTC of Maxim MAX77686/MAX77620/MAX77802 PMIC. | 381 | RTC of Maxim MAX77686/MAX77620/MAX77802 PMIC. |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #define MAX77686_I2C_ADDR_RTC (0x0C >> 1) | 20 | #define MAX77686_I2C_ADDR_RTC (0x0C >> 1) |
| 21 | #define MAX77620_I2C_ADDR_RTC 0x68 | 21 | #define MAX77620_I2C_ADDR_RTC 0x68 |
| 22 | #define MAX77714_I2C_ADDR_RTC 0x48 | ||
| 22 | #define MAX77686_INVALID_I2C_ADDR (-1) | 23 | #define MAX77686_INVALID_I2C_ADDR (-1) |
| 23 | 24 | ||
| 24 | /* Define non existing register */ | 25 | /* Define non existing register */ |
| @@ -34,9 +35,6 @@ · 9 unmodified lines | |||
| 34 | #define RTC_UDR_MASK BIT(RTC_UDR_SHIFT) | 35 | #define RTC_UDR_MASK BIT(RTC_UDR_SHIFT) |
| 35 | #define RTC_RBUDR_SHIFT 4 | 36 | #define RTC_RBUDR_SHIFT 4 |
| 36 | #define RTC_RBUDR_MASK BIT(RTC_RBUDR_SHIFT) | 37 | #define RTC_RBUDR_MASK BIT(RTC_RBUDR_SHIFT) |
| 37 | /* RTC Hour register */ | ||
| 38 | #define HOUR_PM_SHIFT 6 | ||
| 39 | #define HOUR_PM_MASK BIT(HOUR_PM_SHIFT) | ||
| 40 | /* RTC Alarm Enable */ | 38 | /* RTC Alarm Enable */ |
| 41 | #define ALARM_ENABLE_SHIFT 7 | 39 | #define ALARM_ENABLE_SHIFT 7 |
| 42 | #define ALARM_ENABLE_MASK BIT(ALARM_ENABLE_SHIFT) | 40 | #define ALARM_ENABLE_MASK BIT(ALARM_ENABLE_SHIFT) |
| @@ -57,28 +55,31 @@ enum { · 14 unmodified lines | |||
| 57 | RTC_WEEKDAY, | 55 | RTC_WEEKDAY, |
| 58 | RTC_MONTH, | 56 | RTC_MONTH, |
| 59 | RTC_YEAR, | 57 | RTC_YEAR, |
| 60 | RTC_DATE, | 58 | RTC_MONTHDAY, |
| 61 | RTC_NR_TIME | 59 | RTC_NR_TIME |
| 62 | }; | 60 | }; |
| 63 | 61 | ||
| 62 | /** | ||
| 63 | * struct max77686_rtc_driver_data - model-specific configuration | ||
| 64 | * @delay: Minimum usecs needed for a RTC update | ||
| 65 | * @mask: Mask used to read RTC registers value | ||
| 66 | * @map: Registers offset to I2C addresses map | ||
| 67 | * @alarm_enable_reg: Has a separate alarm enable register? | ||
| 68 | * @rtc_i2c_addr: I2C address for RTC block | ||
| 69 | * @rtc_irq_from_platform: RTC interrupt via platform resource | ||
| 70 | * @alarm_pending_status_reg: Pending alarm status register | ||
| 71 | * @rtc_irq_chip: RTC IRQ CHIP for regmap | ||
| 72 | * @regmap_config: regmap configuration for the chip | ||
| 73 | */ | ||
| 64 | struct max77686_rtc_driver_data { | 74 | struct max77686_rtc_driver_data { |
| 65 | /* Minimum usecs needed for a RTC update */ | ||
| 66 | unsigned long delay; | 75 | unsigned long delay; |
| 67 | /* Mask used to read RTC registers value */ | ||
| 68 | u8 mask; | 76 | u8 mask; |
| 69 | /* Registers offset to I2C addresses map */ | ||
| 70 | const unsigned int *map; | 77 | const unsigned int *map; |
| 71 | /* Has a separate alarm enable register? */ | ||
| 72 | bool alarm_enable_reg; | 78 | bool alarm_enable_reg; |
| 73 | /* I2C address for RTC block */ | ||
| 74 | int rtc_i2c_addr; | 79 | int rtc_i2c_addr; |
| 75 | /* RTC interrupt via platform resource */ | ||
| 76 | bool rtc_irq_from_platform; | 80 | bool rtc_irq_from_platform; |
| 77 | /* Pending alarm status register */ | ||
| 78 | int alarm_pending_status_reg; | 81 | int alarm_pending_status_reg; |
| 79 | /* RTC IRQ CHIP for regmap */ | ||
| 80 | const struct regmap_irq_chip *rtc_irq_chip; | 82 | const struct regmap_irq_chip *rtc_irq_chip; |
| 81 | /* regmap configuration for the chip */ | ||
| 82 | const struct regmap_config *regmap_config; | 83 | const struct regmap_config *regmap_config; |
| 83 | }; | 84 | }; |
| 84 | 85 | ||
| @@ -96,7 +97,6 @@ struct max77686_rtc_info { · 11 unmodified lines | |||
| 96 | 97 | ||
| 97 | int rtc_irq; | 98 | int rtc_irq; |
| 98 | int virq; | 99 | int virq; |
| 99 | int rtc_24hr_mode; | ||
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | enum MAX77686_RTC_OP { | 102 | enum MAX77686_RTC_OP { |
| @@ -116,7 +116,7 @@ enum max77686_rtc_reg_offset { · 13 unmodified lines | |||
| 116 | REG_RTC_WEEKDAY, | 116 | REG_RTC_WEEKDAY, |
| 117 | REG_RTC_MONTH, | 117 | REG_RTC_MONTH, |
| 118 | REG_RTC_YEAR, | 118 | REG_RTC_YEAR, |
| 119 | REG_RTC_DATE, | 119 | REG_RTC_MONTHDAY, |
| 120 | REG_ALARM1_SEC, | 120 | REG_ALARM1_SEC, |
| 121 | REG_ALARM1_MIN, | 121 | REG_ALARM1_MIN, |
| 122 | REG_ALARM1_HOUR, | 122 | REG_ALARM1_HOUR, |
| @@ -147,7 +147,7 @@ static const unsigned int max77686_map[REG_RTC_END] = { · 24 unmodified lines | |||
| 147 | [REG_RTC_WEEKDAY] = MAX77686_RTC_WEEKDAY, | 147 | [REG_RTC_WEEKDAY] = MAX77686_RTC_WEEKDAY, |
| 148 | [REG_RTC_MONTH] = MAX77686_RTC_MONTH, | 148 | [REG_RTC_MONTH] = MAX77686_RTC_MONTH, |
| 149 | [REG_RTC_YEAR] = MAX77686_RTC_YEAR, | 149 | [REG_RTC_YEAR] = MAX77686_RTC_YEAR, |
| 150 | [REG_RTC_DATE] = MAX77686_RTC_DATE, | 150 | [REG_RTC_MONTHDAY] = MAX77686_RTC_MONTHDAY, |
| 151 | [REG_ALARM1_SEC] = MAX77686_ALARM1_SEC, | 151 | [REG_ALARM1_SEC] = MAX77686_ALARM1_SEC, |
| 152 | [REG_ALARM1_MIN] = MAX77686_ALARM1_MIN, | 152 | [REG_ALARM1_MIN] = MAX77686_ALARM1_MIN, |
| 153 | [REG_ALARM1_HOUR] = MAX77686_ALARM1_HOUR, | 153 | [REG_ALARM1_HOUR] = MAX77686_ALARM1_HOUR, |
| @@ -201,6 +201,28 @@ static const struct max77686_rtc_driver_data max77686_drv_data = { · 47 unmodified lines | |||
| 201 | .regmap_config = &max77686_rtc_regmap_config, | 201 | .regmap_config = &max77686_rtc_regmap_config, |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| 204 | static const struct regmap_irq_chip max77714_rtc_irq_chip = { | ||
| 205 | .name = "max77714-rtc", | ||
| 206 | .status_base = MAX77686_RTC_INT, | ||
| 207 | .mask_base = MAX77686_RTC_INTM, | ||
| 208 | .num_regs = 1, | ||
| 209 | .irqs = max77686_rtc_irqs, | ||
| 210 | .num_irqs = ARRAY_SIZE(max77686_rtc_irqs) - 1, /* no WTSR on 77714 */ | ||
| 211 | }; | ||
| 212 | |||
| 213 | static const struct max77686_rtc_driver_data max77714_drv_data = { | ||
| 214 | .delay = 16000, | ||
| 215 | .mask = 0x7f, | ||
| 216 | .map = max77686_map, | ||
| 217 | .alarm_enable_reg = false, | ||
| 218 | .rtc_irq_from_platform = false, | ||
| 219 | /* On MAX77714 RTCA1 is BIT 1 of RTCINT (0x00). Not supported by this driver. */ | ||
| 220 | .alarm_pending_status_reg = MAX77686_INVALID_REG, | ||
| 221 | .rtc_i2c_addr = MAX77714_I2C_ADDR_RTC, | ||
| 222 | .rtc_irq_chip = &max77714_rtc_irq_chip, | ||
| 223 | .regmap_config = &max77686_rtc_regmap_config, | ||
| 224 | }; | ||
| 225 | |||
| 204 | static const struct regmap_config max77620_rtc_regmap_config = { | 226 | static const struct regmap_config max77620_rtc_regmap_config = { |
| 205 | .reg_bits = 8, | 227 | .reg_bits = 8, |
| 206 | .val_bits = 8, | 228 | .val_bits = 8, |
| @@ -230,7 +252,7 @@ static const unsigned int max77802_map[REG_RTC_END] = { · 23 unmodified lines | |||
| 230 | [REG_RTC_WEEKDAY] = MAX77802_RTC_WEEKDAY, | 252 | [REG_RTC_WEEKDAY] = MAX77802_RTC_WEEKDAY, |
| 231 | [REG_RTC_MONTH] = MAX77802_RTC_MONTH, | 253 | [REG_RTC_MONTH] = MAX77802_RTC_MONTH, |
| 232 | [REG_RTC_YEAR] = MAX77802_RTC_YEAR, | 254 | [REG_RTC_YEAR] = MAX77802_RTC_YEAR, |
| 233 | [REG_RTC_DATE] = MAX77802_RTC_DATE, | 255 | [REG_RTC_MONTHDAY] = MAX77802_RTC_MONTHDAY, |
| 234 | [REG_ALARM1_SEC] = MAX77802_ALARM1_SEC, | 256 | [REG_ALARM1_SEC] = MAX77802_ALARM1_SEC, |
| 235 | [REG_ALARM1_MIN] = MAX77802_ALARM1_MIN, | 257 | [REG_ALARM1_MIN] = MAX77802_ALARM1_MIN, |
| 236 | [REG_ALARM1_HOUR] = MAX77802_ALARM1_HOUR, | 258 | [REG_ALARM1_HOUR] = MAX77802_ALARM1_HOUR, |
| @@ -275,17 +297,11 @@ static void max77686_rtc_data_to_tm(u8 *data, struct rtc_time *tm, · 38 unmodified lines | |||
| 275 | 297 | ||
| 276 | tm->tm_sec = data[RTC_SEC] & mask; | 298 | tm->tm_sec = data[RTC_SEC] & mask; |
| 277 | tm->tm_min = data[RTC_MIN] & mask; | 299 | tm->tm_min = data[RTC_MIN] & mask; |
| 278 | if (info->rtc_24hr_mode) { | 300 | tm->tm_hour = data[RTC_HOUR] & 0x1f; |
| 279 | tm->tm_hour = data[RTC_HOUR] & 0x1f; | ||
| 280 | } else { | ||
| 281 | tm->tm_hour = data[RTC_HOUR] & 0x0f; | ||
| 282 | if (data[RTC_HOUR] & HOUR_PM_MASK) | ||
| 283 | tm->tm_hour += 12; | ||
| 284 | } | ||
| 285 | 301 | ||
| 286 | /* Only a single bit is set in data[], so fls() would be equivalent */ | 302 | /* Only a single bit is set in data[], so fls() would be equivalent */ |
| 287 | tm->tm_wday = ffs(data[RTC_WEEKDAY] & mask) - 1; | 303 | tm->tm_wday = ffs(data[RTC_WEEKDAY] & mask) - 1; |
| 288 | tm->tm_mday = data[RTC_DATE] & 0x1f; | 304 | tm->tm_mday = data[RTC_MONTHDAY] & 0x1f; |
| 289 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; | 305 | tm->tm_mon = (data[RTC_MONTH] & 0x0f) - 1; |
| 290 | tm->tm_year = data[RTC_YEAR] & mask; | 306 | tm->tm_year = data[RTC_YEAR] & mask; |
| 291 | tm->tm_yday = 0; | 307 | tm->tm_yday = 0; |
| @@ -306,7 +322,7 @@ static int max77686_rtc_tm_to_data(struct rtc_time *tm, u8 *data, · 14 unmodified lines | |||
| 306 | data[RTC_MIN] = tm->tm_min; | 322 | data[RTC_MIN] = tm->tm_min; |
| 307 | data[RTC_HOUR] = tm->tm_hour; | 323 | data[RTC_HOUR] = tm->tm_hour; |
| 308 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; | 324 | data[RTC_WEEKDAY] = 1 << tm->tm_wday; |
| 309 | data[RTC_DATE] = tm->tm_mday; | 325 | data[RTC_MONTHDAY] = tm->tm_mday; |
| 310 | data[RTC_MONTH] = tm->tm_mon + 1; | 326 | data[RTC_MONTH] = tm->tm_mon + 1; |
| 311 | 327 | ||
| 312 | if (info->drv_data->alarm_enable_reg) { | 328 | if (info->drv_data->alarm_enable_reg) { |
| @@ -562,8 +578,8 @@ static int max77686_rtc_start_alarm(struct max77686_rtc_info *info) · 249 unmodified lines | |||
| 562 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); | 578 | data[RTC_MONTH] |= (1 << ALARM_ENABLE_SHIFT); |
| 563 | if (data[RTC_YEAR] & info->drv_data->mask) | 579 | if (data[RTC_YEAR] & info->drv_data->mask) |
| 564 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); | 580 | data[RTC_YEAR] |= (1 << ALARM_ENABLE_SHIFT); |
| 565 | if (data[RTC_DATE] & 0x1f) | 581 | if (data[RTC_MONTHDAY] & 0x1f) |
| 566 | data[RTC_DATE] |= (1 << ALARM_ENABLE_SHIFT); | 582 | data[RTC_MONTHDAY] |= (1 << ALARM_ENABLE_SHIFT); |
| 567 | 583 | ||
| 568 | ret = regmap_bulk_write(info->rtc_regmap, map[REG_ALARM1_SEC], | 584 | ret = regmap_bulk_write(info->rtc_regmap, map[REG_ALARM1_SEC], |
| 569 | data, ARRAY_SIZE(data)); | 585 | data, ARRAY_SIZE(data)); |
| @@ -659,8 +675,6 @@ static int max77686_rtc_init_reg(struct max77686_rtc_info *info) · 89 unmodified lines | |||
| 659 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | 675 | data[0] = (1 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
| 660 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); | 676 | data[1] = (0 << BCD_EN_SHIFT) | (1 << MODEL24_SHIFT); |
| 661 | 677 | ||
| 662 | info->rtc_24hr_mode = 1; | ||
| 663 | |||
| 664 | ret = regmap_bulk_write(info->rtc_regmap, | 678 | ret = regmap_bulk_write(info->rtc_regmap, |
| 665 | info->drv_data->map[REG_RTC_CONTROLM], | 679 | info->drv_data->map[REG_RTC_CONTROLM], |
| 666 | data, ARRAY_SIZE(data)); | 680 | data, ARRAY_SIZE(data)); |
| @@ -852,6 +866,7 @@ static const struct platform_device_id rtc_id[] = { · 185 unmodified lines | |||
| 852 | { "max77686-rtc", .driver_data = (kernel_ulong_t)&max77686_drv_data, }, | 866 | { "max77686-rtc", .driver_data = (kernel_ulong_t)&max77686_drv_data, }, |
| 853 | { "max77802-rtc", .driver_data = (kernel_ulong_t)&max77802_drv_data, }, | 867 | { "max77802-rtc", .driver_data = (kernel_ulong_t)&max77802_drv_data, }, |
| 854 | { "max77620-rtc", .driver_data = (kernel_ulong_t)&max77620_drv_data, }, | 868 | { "max77620-rtc", .driver_data = (kernel_ulong_t)&max77620_drv_data, }, |
| 869 | { "max77714-rtc", .driver_data = (kernel_ulong_t)&max77714_drv_data, }, | ||
| 855 | {}, | 870 | {}, |
| 856 | }; | 871 | }; |
| 857 | MODULE_DEVICE_TABLE(platform, rtc_id); | 872 | MODULE_DEVICE_TABLE(platform, rtc_id); |
| @@ -678,7 +678,7 @@ config MAX63XX_WATCHDOG · 677 unmodified lines | |||
| 678 | 678 | ||
| 679 | config MAX77620_WATCHDOG | 679 | config MAX77620_WATCHDOG |
| 680 | tristate "Maxim Max77620 Watchdog Timer" | 680 | tristate "Maxim Max77620 Watchdog Timer" |
| 681 | depends on MFD_MAX77620 || COMPILE_TEST | 681 | depends on MFD_MAX77620 || MFD_MAX77714 || COMPILE_TEST |
| 682 | select WATCHDOG_CORE | 682 | select WATCHDOG_CORE |
| 683 | help | 683 | help |
| 684 | This is the driver for the Max77620 watchdog timer. | 684 | This is the driver for the Max77620 watchdog timer. |
| @@ -3,8 +3,10 @@ · 2 unmodified lines | |||
| 3 | * Maxim MAX77620 Watchdog Driver | 3 | * Maxim MAX77620 Watchdog Driver |
| 4 | * | 4 | * |
| 5 | * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. | 5 | * Copyright (C) 2016 NVIDIA CORPORATION. All rights reserved. |
| 6 | * Copyright (C) 2022 Luca Ceresoli | ||
| 6 | * | 7 | * |
| 7 | * Author: Laxman Dewangan <ldewangan@nvidia.com> | 8 | * Author: Laxman Dewangan <ldewangan@nvidia.com> |
| 9 | * Author: Luca Ceresoli <luca@lucaceresoli.net> | ||
| 8 | */ | 10 | */ |
| 9 | 11 | ||
| 10 | #include <linux/err.h> | 12 | #include <linux/err.h> |
| @@ -13,6 +15,7 @@ · 2 unmodified lines | |||
| 13 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 14 | #include <linux/mod_devicetable.h> | 16 | #include <linux/mod_devicetable.h> |
| 15 | #include <linux/mfd/max77620.h> | 17 | #include <linux/mfd/max77620.h> |
| 18 | #include <linux/mfd/max77714.h> | ||
| 16 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
| 17 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
| 18 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| @@ -20,17 +23,57 @@ · 1 unmodified line | |||
| 20 | 23 | ||
| 21 | static bool nowayout = WATCHDOG_NOWAYOUT; | 24 | static bool nowayout = WATCHDOG_NOWAYOUT; |
| 22 | 25 | ||
| 26 | /** | ||
| 27 | * struct max77620_variant - Data specific to a chip variant | ||
| 28 | * @wdt_info: watchdog descriptor | ||
| 29 | * @reg_onoff_cnfg2: ONOFF_CNFG2 register offset | ||
| 30 | * @reg_cnfg_glbl2: CNFG_GLBL2 register offset | ||
| 31 | * @reg_cnfg_glbl3: CNFG_GLBL3 register offset | ||
| 32 | * @wdtc_mask: WDTC bit mask in CNFG_GLBL3 (=bits to update to ping the watchdog) | ||
| 33 | * @bit_wd_rst_wk: WD_RST_WK bit offset within ONOFF_CNFG2 | ||
| 34 | * @cnfg_glbl2_cfg_bits: configuration bits to enable in CNFG_GLBL2 register | ||
| 35 | */ | ||
| 36 | struct max77620_variant { | ||
| 37 | u8 reg_onoff_cnfg2; | ||
| 38 | u8 reg_cnfg_glbl2; | ||
| 39 | u8 reg_cnfg_glbl3; | ||
| 40 | u8 wdtc_mask; | ||
| 41 | u8 bit_wd_rst_wk; | ||
| 42 | u8 cnfg_glbl2_cfg_bits; | ||
| 43 | }; | ||
| 44 | |||
| 23 | struct max77620_wdt { | 45 | struct max77620_wdt { |
| 24 | struct device *dev; | 46 | struct device *dev; |
| 25 | struct regmap *rmap; | 47 | struct regmap *rmap; |
| 48 | const struct max77620_variant *drv_data; | ||
| 26 | struct watchdog_device wdt_dev; | 49 | struct watchdog_device wdt_dev; |
| 27 | }; | 50 | }; |
| 28 | 51 | ||
| 52 | static const struct max77620_variant max77620_wdt_data = { | ||
| 53 | .reg_onoff_cnfg2 = MAX77620_REG_ONOFFCNFG2, | ||
| 54 | .reg_cnfg_glbl2 = MAX77620_REG_CNFGGLBL2, | ||
| 55 | .reg_cnfg_glbl3 = MAX77620_REG_CNFGGLBL3, | ||
| 56 | .wdtc_mask = MAX77620_WDTC_MASK, | ||
| 57 | .bit_wd_rst_wk = MAX77620_ONOFFCNFG2_WD_RST_WK, | ||
| 58 | /* Set WDT clear in OFF and sleep mode */ | ||
| 59 | .cnfg_glbl2_cfg_bits = MAX77620_WDTSLPC | MAX77620_WDTOFFC, | ||
| 60 | }; | ||
| 61 | |||
| 62 | static const struct max77620_variant max77714_wdt_data = { | ||
| 63 | .reg_onoff_cnfg2 = MAX77714_CNFG2_ONOFF, | ||
| 64 | .reg_cnfg_glbl2 = MAX77714_CNFG_GLBL2, | ||
| 65 | .reg_cnfg_glbl3 = MAX77714_CNFG_GLBL3, | ||
| 66 | .wdtc_mask = MAX77714_WDTC, | ||
| 67 | .bit_wd_rst_wk = MAX77714_WD_RST_WK, | ||
| 68 | /* Set WDT clear in sleep mode (there is no WDTOFFC on MAX77714) */ | ||
| 69 | .cnfg_glbl2_cfg_bits = MAX77714_WDTSLPC, | ||
| 70 | }; | ||
| 71 | |||
| 29 | static int max77620_wdt_start(struct watchdog_device *wdt_dev) | 72 | static int max77620_wdt_start(struct watchdog_device *wdt_dev) |
| 30 | { | 73 | { |
| 31 | struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); | 74 | struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); |
| 32 | 75 | ||
| 33 | return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, | 76 | return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, |
| 34 | MAX77620_WDTEN, MAX77620_WDTEN); | 77 | MAX77620_WDTEN, MAX77620_WDTEN); |
| 35 | } | 78 | } |
| 36 | 79 | ||
| @@ -38,7 +81,7 @@ static int max77620_wdt_stop(struct watchdog_device *wdt_dev) · 1 unmodified line | |||
| 38 | { | 81 | { |
| 39 | struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); | 82 | struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); |
| 40 | 83 | ||
| 41 | return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, | 84 | return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, |
| 42 | MAX77620_WDTEN, 0); | 85 | MAX77620_WDTEN, 0); |
| 43 | } | 86 | } |
| 44 | 87 | ||
| @@ -46,8 +89,8 @@ static int max77620_wdt_ping(struct watchdog_device *wdt_dev) · 1 unmodified line | |||
| 46 | { | 89 | { |
| 47 | struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); | 90 | struct max77620_wdt *wdt = watchdog_get_drvdata(wdt_dev); |
| 48 | 91 | ||
| 49 | return regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3, | 92 | return regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, |
| 50 | MAX77620_WDTC_MASK, 0x1); | 93 | wdt->drv_data->wdtc_mask, 0x1); |
| 51 | } | 94 | } |
| 52 | 95 | ||
| 53 | static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, | 96 | static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, |
| @@ -80,12 +123,17 @@ static int max77620_wdt_set_timeout(struct watchdog_device *wdt_dev, · 26 unmodified lines | |||
| 80 | break; | 123 | break; |
| 81 | } | 124 | } |
| 82 | 125 | ||
| 83 | ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL3, | 126 | /* |
| 84 | MAX77620_WDTC_MASK, 0x1); | 127 | * "If the value of TWD needs to be changed, clear the system |
| 128 | * watchdog timer first [...], then change the value of TWD." | ||
| 129 | * (MAX77714 datasheet but applies to MAX77620 too) | ||
| 130 | */ | ||
| 131 | ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl3, | ||
| 132 | wdt->drv_data->wdtc_mask, 0x1); | ||
| 85 | if (ret < 0) | 133 | if (ret < 0) |
| 86 | return ret; | 134 | return ret; |
| 87 | 135 | ||
| 88 | ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, | 136 | ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, |
| 89 | MAX77620_TWD_MASK, regval); | 137 | MAX77620_TWD_MASK, regval); |
| 90 | if (ret < 0) | 138 | if (ret < 0) |
| 91 | return ret; | 139 | return ret; |
| @@ -109,6 +157,7 @@ static const struct watchdog_ops max77620_wdt_ops = { · 17 unmodified lines | |||
| 109 | 157 | ||
| 110 | static int max77620_wdt_probe(struct platform_device *pdev) | 158 | static int max77620_wdt_probe(struct platform_device *pdev) |
| 111 | { | 159 | { |
| 160 | const struct platform_device_id *id = platform_get_device_id(pdev); | ||
| 112 | struct device *dev = &pdev->dev; | 161 | struct device *dev = &pdev->dev; |
| 113 | struct max77620_wdt *wdt; | 162 | struct max77620_wdt *wdt; |
| 114 | struct watchdog_device *wdt_dev; | 163 | struct watchdog_device *wdt_dev; |
| @@ -120,6 +169,8 @@ static int max77620_wdt_probe(struct platform_device *pdev) · 5 unmodified lines | |||
| 120 | return -ENOMEM; | 169 | return -ENOMEM; |
| 121 | 170 | ||
| 122 | wdt->dev = dev; | 171 | wdt->dev = dev; |
| 172 | wdt->drv_data = (const struct max77620_variant *) id->driver_data; | ||
| 173 | |||
| 123 | wdt->rmap = dev_get_regmap(dev->parent, NULL); | 174 | wdt->rmap = dev_get_regmap(dev->parent, NULL); |
| 124 | if (!wdt->rmap) { | 175 | if (!wdt->rmap) { |
| 125 | dev_err(wdt->dev, "Failed to get parent regmap\n"); | 176 | dev_err(wdt->dev, "Failed to get parent regmap\n"); |
| @@ -136,25 +187,25 @@ static int max77620_wdt_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 136 | platform_set_drvdata(pdev, wdt); | 187 | platform_set_drvdata(pdev, wdt); |
| 137 | 188 | ||
| 138 | /* Enable WD_RST_WK - WDT expire results in a restart */ | 189 | /* Enable WD_RST_WK - WDT expire results in a restart */ |
| 139 | ret = regmap_update_bits(wdt->rmap, MAX77620_REG_ONOFFCNFG2, | 190 | ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_onoff_cnfg2, |
| 140 | MAX77620_ONOFFCNFG2_WD_RST_WK, | 191 | wdt->drv_data->bit_wd_rst_wk, |
| 141 | MAX77620_ONOFFCNFG2_WD_RST_WK); | 192 | wdt->drv_data->bit_wd_rst_wk); |
| 142 | if (ret < 0) { | 193 | if (ret < 0) { |
| 143 | dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret); | 194 | dev_err(wdt->dev, "Failed to set WD_RST_WK: %d\n", ret); |
| 144 | return ret; | 195 | return ret; |
| 145 | } | 196 | } |
| 146 | 197 | ||
| 147 | /* Set WDT clear in OFF and sleep mode */ | 198 | /* Set the "auto WDT clear" bits available on the chip */ |
| 148 | ret = regmap_update_bits(wdt->rmap, MAX77620_REG_CNFGGLBL2, | 199 | ret = regmap_update_bits(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, |
| 149 | MAX77620_WDTOFFC | MAX77620_WDTSLPC, | 200 | wdt->drv_data->cnfg_glbl2_cfg_bits, |
| 150 | MAX77620_WDTOFFC | MAX77620_WDTSLPC); | 201 | wdt->drv_data->cnfg_glbl2_cfg_bits); |
| 151 | if (ret < 0) { | 202 | if (ret < 0) { |
| 152 | dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret); | 203 | dev_err(wdt->dev, "Failed to set WDT OFF mode: %d\n", ret); |
| 153 | return ret; | 204 | return ret; |
| 154 | } | 205 | } |
| 155 | 206 | ||
| 156 | /* Check if WDT running and if yes then set flags properly */ | 207 | /* Check if WDT running and if yes then set flags properly */ |
| 157 | ret = regmap_read(wdt->rmap, MAX77620_REG_CNFGGLBL2, ®val); | 208 | ret = regmap_read(wdt->rmap, wdt->drv_data->reg_cnfg_glbl2, ®val); |
| 158 | if (ret < 0) { | 209 | if (ret < 0) { |
| 159 | dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret); | 210 | dev_err(wdt->dev, "Failed to read WDT CFG register: %d\n", ret); |
| 160 | return ret; | 211 | return ret; |
| @@ -186,7 +237,8 @@ static int max77620_wdt_probe(struct platform_device *pdev) · 25 unmodified lines | |||
| 186 | } | 237 | } |
| 187 | 238 | ||
| 188 | static const struct platform_device_id max77620_wdt_devtype[] = { | 239 | static const struct platform_device_id max77620_wdt_devtype[] = { |
| 189 | { .name = "max77620-watchdog", }, | 240 | { "max77620-watchdog", (kernel_ulong_t)&max77620_wdt_data }, |
| 241 | { "max77714-watchdog", (kernel_ulong_t)&max77714_wdt_data }, | ||
| 190 | { }, | 242 | { }, |
| 191 | }; | 243 | }; |
| 192 | MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype); | 244 | MODULE_DEVICE_TABLE(platform, max77620_wdt_devtype); |
| @@ -208,4 +260,5 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " · 15 unmodified lines | |||
| 208 | "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | 260 | "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); |
| 209 | 261 | ||
| 210 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | 262 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); |
| 263 | MODULE_AUTHOR("Luca Ceresoli <luca@lucaceresoli.net>"); | ||
| 211 | MODULE_LICENSE("GPL v2"); | 264 | MODULE_LICENSE("GPL v2"); |
| @@ -556,31 +556,11 @@ static inline void prcmu_clear(unsigned int reg, u32 bits) · 555 unmodified lines | |||
| 556 | #define PRCMU_QOS_ARM_OPP 3 | 556 | #define PRCMU_QOS_ARM_OPP 3 |
| 557 | #define PRCMU_QOS_DEFAULT_VALUE -1 | 557 | #define PRCMU_QOS_DEFAULT_VALUE -1 |
| 558 | 558 | ||
| 559 | #ifdef CONFIG_DBX500_PRCMU_QOS_POWER | ||
| 560 | |||
| 561 | unsigned long prcmu_qos_get_cpufreq_opp_delay(void); | ||
| 562 | void prcmu_qos_set_cpufreq_opp_delay(unsigned long); | ||
| 563 | void prcmu_qos_force_opp(int, s32); | ||
| 564 | int prcmu_qos_requirement(int pm_qos_class); | ||
| 565 | int prcmu_qos_add_requirement(int pm_qos_class, char *name, s32 value); | ||
| 566 | int prcmu_qos_update_requirement(int pm_qos_class, char *name, s32 new_value); | ||
| 567 | void prcmu_qos_remove_requirement(int pm_qos_class, char *name); | ||
| 568 | int prcmu_qos_add_notifier(int prcmu_qos_class, | ||
| 569 | struct notifier_block *notifier); | ||
| 570 | int prcmu_qos_remove_notifier(int prcmu_qos_class, | ||
| 571 | struct notifier_block *notifier); | ||
| 572 | |||
| 573 | #else | ||
| 574 | |||
| 575 | static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) | 559 | static inline unsigned long prcmu_qos_get_cpufreq_opp_delay(void) |
| 576 | { | 560 | { |
| 577 | return 0; | 561 | return 0; |
| 578 | } | 562 | } |
| 579 | 563 | ||
| 580 | static inline void prcmu_qos_set_cpufreq_opp_delay(unsigned long n) {} | ||
| 581 | |||
| 582 | static inline void prcmu_qos_force_opp(int prcmu_qos_class, s32 i) {} | ||
| 583 | |||
| 584 | static inline int prcmu_qos_requirement(int prcmu_qos_class) | 564 | static inline int prcmu_qos_requirement(int prcmu_qos_class) |
| 585 | { | 565 | { |
| 586 | return 0; | 566 | return 0; |
| @@ -613,6 +593,4 @@ static inline int prcmu_qos_remove_notifier(int prcmu_qos_class, · 26 unmodified lines | |||
| 613 | return 0; | 593 | return 0; |
| 614 | } | 594 | } |
| 615 | 595 | ||
| 616 | #endif | ||
| 617 | |||
| 618 | #endif /* __MACH_PRCMU_H */ | 596 | #endif /* __MACH_PRCMU_H */ |
| @@ -14,6 +14,11 @@ · 13 unmodified lines | |||
| 14 | #define IQS624_PROD_NUM 0x43 | 14 | #define IQS624_PROD_NUM 0x43 |
| 15 | #define IQS625_PROD_NUM 0x4E | 15 | #define IQS625_PROD_NUM 0x4E |
| 16 | 16 | ||
| 17 | #define IQS620_HW_NUM_V0 0x82 | ||
| 18 | #define IQS620_HW_NUM_V1 IQS620_HW_NUM_V0 | ||
| 19 | #define IQS620_HW_NUM_V2 IQS620_HW_NUM_V0 | ||
| 20 | #define IQS620_HW_NUM_V3 0x92 | ||
| 21 | |||
| 17 | #define IQS621_ALS_FLAGS 0x16 | 22 | #define IQS621_ALS_FLAGS 0x16 |
| 18 | #define IQS622_ALS_FLAGS 0x14 | 23 | #define IQS622_ALS_FLAGS 0x14 |
| 19 | 24 | ||
| @@ -129,6 +134,8 @@ struct iqs62x_core { · 109 unmodified lines | |||
| 129 | struct completion fw_done; | 134 | struct completion fw_done; |
| 130 | enum iqs62x_ui_sel ui_sel; | 135 | enum iqs62x_ui_sel ui_sel; |
| 131 | unsigned long event_cache; | 136 | unsigned long event_cache; |
| 137 | u8 sw_num; | ||
| 138 | u8 hw_num; | ||
| 132 | }; | 139 | }; |
| 133 | 140 | ||
| 134 | extern const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS]; | 141 | extern const struct iqs62x_event_desc iqs62x_events[IQS62X_NUM_EVENTS]; |
| @@ -152,7 +152,7 @@ enum max77686_rtc_reg { · 151 unmodified lines | |||
| 152 | MAX77686_RTC_WEEKDAY = 0x0A, | 152 | MAX77686_RTC_WEEKDAY = 0x0A, |
| 153 | MAX77686_RTC_MONTH = 0x0B, | 153 | MAX77686_RTC_MONTH = 0x0B, |
| 154 | MAX77686_RTC_YEAR = 0x0C, | 154 | MAX77686_RTC_YEAR = 0x0C, |
| 155 | MAX77686_RTC_DATE = 0x0D, | 155 | MAX77686_RTC_MONTHDAY = 0x0D, |
| 156 | MAX77686_ALARM1_SEC = 0x0E, | 156 | MAX77686_ALARM1_SEC = 0x0E, |
| 157 | MAX77686_ALARM1_MIN = 0x0F, | 157 | MAX77686_ALARM1_MIN = 0x0F, |
| 158 | MAX77686_ALARM1_HOUR = 0x10, | 158 | MAX77686_ALARM1_HOUR = 0x10, |
| @@ -352,7 +352,7 @@ enum max77802_rtc_reg { · 193 unmodified lines | |||
| 352 | MAX77802_RTC_WEEKDAY = 0xCA, | 352 | MAX77802_RTC_WEEKDAY = 0xCA, |
| 353 | MAX77802_RTC_MONTH = 0xCB, | 353 | MAX77802_RTC_MONTH = 0xCB, |
| 354 | MAX77802_RTC_YEAR = 0xCC, | 354 | MAX77802_RTC_YEAR = 0xCC, |
| 355 | MAX77802_RTC_DATE = 0xCD, | 355 | MAX77802_RTC_MONTHDAY = 0xCD, |
| 356 | MAX77802_RTC_AE1 = 0xCE, | 356 | MAX77802_RTC_AE1 = 0xCE, |
| 357 | MAX77802_ALARM1_SEC = 0xCF, | 357 | MAX77802_ALARM1_SEC = 0xCF, |
| 358 | MAX77802_ALARM1_MIN = 0xD0, | 358 | MAX77802_ALARM1_MIN = 0xD0, |
| @@ -0,0 +1,60 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Maxim MAX77714 Register and data structures definition. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2022 Luca Ceresoli | ||
| 6 | * Author: Luca Ceresoli <luca@lucaceresoli.net> | ||
| 7 | */ | ||
| 8 | |||
| 9 | #ifndef __LINUX_MFD_MAX77714_H_ | ||
| 10 | #define __LINUX_MFD_MAX77714_H_ | ||
| 11 | |||
| 12 | #include <linux/bits.h> | ||
| 13 | |||
| 14 | #define MAX77714_INT_TOP 0x00 | ||
| 15 | #define MAX77714_INT_TOPM 0x07 /* Datasheet says "read only", but it is RW */ | ||
| 16 | |||
| 17 | #define MAX77714_INT_TOP_ONOFF BIT(1) | ||
| 18 | #define MAX77714_INT_TOP_RTC BIT(3) | ||
| 19 | #define MAX77714_INT_TOP_GPIO BIT(4) | ||
| 20 | #define MAX77714_INT_TOP_LDO BIT(5) | ||
| 21 | #define MAX77714_INT_TOP_SD BIT(6) | ||
| 22 | #define MAX77714_INT_TOP_GLBL BIT(7) | ||
| 23 | |||
| 24 | #define MAX77714_32K_STATUS 0x30 | ||
| 25 | #define MAX77714_32K_STATUS_SIOSCOK BIT(5) | ||
| 26 | #define MAX77714_32K_STATUS_XOSCOK BIT(4) | ||
| 27 | #define MAX77714_32K_STATUS_32KSOURCE BIT(3) | ||
| 28 | #define MAX77714_32K_STATUS_32KLOAD_MSK 0x3 | ||
| 29 | #define MAX77714_32K_STATUS_32KLOAD_SHF 1 | ||
| 30 | #define MAX77714_32K_STATUS_CRYSTAL_CFG BIT(0) | ||
| 31 | |||
| 32 | #define MAX77714_32K_CONFIG 0x31 | ||
| 33 | #define MAX77714_32K_CONFIG_XOSC_RETRY BIT(4) | ||
| 34 | |||
| 35 | #define MAX77714_CNFG_GLBL2 0x91 | ||
| 36 | #define MAX77714_WDTEN BIT(2) | ||
| 37 | #define MAX77714_WDTSLPC BIT(3) | ||
| 38 | #define MAX77714_TWD_MASK 0x3 | ||
| 39 | #define MAX77714_TWD_2s 0x0 | ||
| 40 | #define MAX77714_TWD_16s 0x1 | ||
| 41 | #define MAX77714_TWD_64s 0x2 | ||
| 42 | #define MAX77714_TWD_128s 0x3 | ||
| 43 | |||
| 44 | #define MAX77714_CNFG_GLBL3 0x92 | ||
| 45 | #define MAX77714_WDTC BIT(0) | ||
| 46 | |||
| 47 | #define MAX77714_CNFG2_ONOFF 0x94 | ||
| 48 | #define MAX77714_WD_RST_WK BIT(5) | ||
| 49 | |||
| 50 | /* Interrupts */ | ||
| 51 | enum { | ||
| 52 | MAX77714_IRQ_TOP_ONOFF, | ||
| 53 | MAX77714_IRQ_TOP_RTC, /* Real-time clock */ | ||
| 54 | MAX77714_IRQ_TOP_GPIO, /* GPIOs */ | ||
| 55 | MAX77714_IRQ_TOP_LDO, /* Low-dropout regulators */ | ||
| 56 | MAX77714_IRQ_TOP_SD, /* Step-down regulators */ | ||
| 57 | MAX77714_IRQ_TOP_GLBL, /* "Global resources": Low-Battery, overtemp... */ | ||
| 58 | }; | ||
| 59 | |||
| 60 | #endif /* __LINUX_MFD_MAX77714_H_ */ | ||
| @@ -94,6 +94,10 @@ · 93 unmodified lines | |||
| 94 | #define MT6358_BUCK_VCORE_CON0 0x1488 | 94 | #define MT6358_BUCK_VCORE_CON0 0x1488 |
| 95 | #define MT6358_BUCK_VCORE_DBG0 0x149e | 95 | #define MT6358_BUCK_VCORE_DBG0 0x149e |
| 96 | #define MT6358_BUCK_VCORE_DBG1 0x14a0 | 96 | #define MT6358_BUCK_VCORE_DBG1 0x14a0 |
| 97 | #define MT6358_BUCK_VCORE_SSHUB_CON0 0x14a4 | ||
| 98 | #define MT6358_BUCK_VCORE_SSHUB_CON1 0x14a6 | ||
| 99 | #define MT6358_BUCK_VCORE_SSHUB_ELR0 MT6358_BUCK_VCORE_SSHUB_CON1 | ||
| 100 | #define MT6358_BUCK_VCORE_SSHUB_DBG1 MT6358_BUCK_VCORE_DBG1 | ||
| 97 | #define MT6358_BUCK_VCORE_ELR0 0x14aa | 101 | #define MT6358_BUCK_VCORE_ELR0 0x14aa |
| 98 | #define MT6358_BUCK_VGPU_CON0 0x1508 | 102 | #define MT6358_BUCK_VGPU_CON0 0x1508 |
| 99 | #define MT6358_BUCK_VGPU_DBG0 0x151e | 103 | #define MT6358_BUCK_VGPU_DBG0 0x151e |
| @@ -169,6 +173,9 @@ · 69 unmodified lines | |||
| 169 | #define MT6358_LDO_VSRAM_OTHERS_CON0 0x1ba6 | 173 | #define MT6358_LDO_VSRAM_OTHERS_CON0 0x1ba6 |
| 170 | #define MT6358_LDO_VSRAM_OTHERS_DBG0 0x1bc0 | 174 | #define MT6358_LDO_VSRAM_OTHERS_DBG0 0x1bc0 |
| 171 | #define MT6358_LDO_VSRAM_OTHERS_DBG1 0x1bc2 | 175 | #define MT6358_LDO_VSRAM_OTHERS_DBG1 0x1bc2 |
| 176 | #define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON0 0x1bc4 | ||
| 177 | #define MT6358_LDO_VSRAM_OTHERS_SSHUB_CON1 0x1bc6 | ||
| 178 | #define MT6358_LDO_VSRAM_OTHERS_SSHUB_DBG1 MT6358_LDO_VSRAM_OTHERS_DBG1 | ||
| 172 | #define MT6358_LDO_VSRAM_GPU_CON0 0x1bc8 | 179 | #define MT6358_LDO_VSRAM_GPU_CON0 0x1bc8 |
| 173 | #define MT6358_LDO_VSRAM_GPU_DBG0 0x1be2 | 180 | #define MT6358_LDO_VSRAM_GPU_DBG0 0x1be2 |
| 174 | #define MT6358_LDO_VSRAM_GPU_DBG1 0x1be4 | 181 | #define MT6358_LDO_VSRAM_GPU_DBG1 0x1be4 |
| @@ -14,6 +14,7 @@ enum chip_id { · 13 unmodified lines | |||
| 14 | MT6323_CHIP_ID = 0x23, | 14 | MT6323_CHIP_ID = 0x23, |
| 15 | MT6358_CHIP_ID = 0x58, | 15 | MT6358_CHIP_ID = 0x58, |
| 16 | MT6359_CHIP_ID = 0x59, | 16 | MT6359_CHIP_ID = 0x59, |
| 17 | MT6366_CHIP_ID = 0x66, | ||
| 17 | MT6391_CHIP_ID = 0x91, | 18 | MT6391_CHIP_ID = 0x91, |
| 18 | MT6397_CHIP_ID = 0x97, | 19 | MT6397_CHIP_ID = 0x97, |
| 19 | }; | 20 | }; |
| @@ -373,6 +373,7 @@ enum rk805_reg { · 372 unmodified lines | |||
| 373 | #define SWITCH2_EN BIT(6) | 373 | #define SWITCH2_EN BIT(6) |
| 374 | #define SWITCH1_EN BIT(5) | 374 | #define SWITCH1_EN BIT(5) |
| 375 | #define DEV_OFF_RST BIT(3) | 375 | #define DEV_OFF_RST BIT(3) |
| 376 | #define DEV_RST BIT(2) | ||
| 376 | #define DEV_OFF BIT(0) | 377 | #define DEV_OFF BIT(0) |
| 377 | #define RTC_STOP BIT(0) | 378 | #define RTC_STOP BIT(0) |
| 378 | 379 | ||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | ||
| 2 | /* | ||
| 3 | * Functions to access SY3686A power management chip. | ||
| 4 | * | ||
| 5 | * Copyright (C) 2021 reMarkable AS - http://www.remarkable.com/ | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef __MFD_SY7636A_H | ||
| 9 | #define __MFD_SY7636A_H | ||
| 10 | |||
| 11 | #define SY7636A_REG_OPERATION_MODE_CRL 0x00 | ||
| 12 | /* It is set if a gpio is used to control the regulator */ | ||
| 13 | #define SY7636A_OPERATION_MODE_CRL_VCOMCTL BIT(6) | ||
| 14 | #define SY7636A_OPERATION_MODE_CRL_ONOFF BIT(7) | ||
| 15 | #define SY7636A_REG_VCOM_ADJUST_CTRL_L 0x01 | ||
| 16 | #define SY7636A_REG_VCOM_ADJUST_CTRL_H 0x02 | ||
| 17 | #define SY7636A_REG_VCOM_ADJUST_CTRL_MASK 0x01ff | ||
| 18 | #define SY7636A_REG_VLDO_VOLTAGE_ADJULST_CTRL 0x03 | ||
| 19 | #define SY7636A_REG_POWER_ON_DELAY_TIME 0x06 | ||
| 20 | #define SY7636A_REG_FAULT_FLAG 0x07 | ||
| 21 | #define SY7636A_FAULT_FLAG_PG BIT(0) | ||
| 22 | #define SY7636A_REG_TERMISTOR_READOUT 0x08 | ||
| 23 | |||
| 24 | #define SY7636A_REG_MAX 0x08 | ||
| 25 | |||
| 26 | #define VCOM_ADJUST_CTRL_MASK 0x1ff | ||
| 27 | // Used to shift the high byte | ||
| 28 | #define VCOM_ADJUST_CTRL_SHIFT 8 | ||
| 29 | // Used to scale from VCOM_ADJUST_CTRL to mv | ||
| 30 | #define VCOM_ADJUST_CTRL_SCAL 10000 | ||
| 31 | |||
| 32 | #define FAULT_FLAG_SHIFT 1 | ||
| 33 | |||
| 34 | #endif /* __LINUX_MFD_SY7636A_H */ | ||