diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-08 13:02:58 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-03-08 13:02:58 -0500 |
commit | cf2e8c544cd3b33e9e403b7b72404c221bf888d1 (patch) | |
tree | 21b46d362626562921df14d75ee106259b3fa936 | |
parent | 04e0361848afbe86fbf8b80945568df4c5bf6f07 (diff) | |
parent | d2d833e0bf2bad221a955626b942b38312630894 (diff) |
Merge tag 'mfd-next-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
Pull MFD updates from Lee Jones:
"New Drivers:
- Add STMPE ADC Input driver
- Add STMicroelectronics STPMIC1 Parent driver
- Add STMicroelectronics STPMIC1 OnKey Misc driver
- Add STMicroelectronics STPMIC1 Watchdog driver
- Add Cirrus Logic Lochnagar Parent driver
- Add TQ-Systems TQMX86 Parent driver
New Device Support:
- Add support for ADC to STMPE
New (or moved) Functionality:
- Move Lightbar functionality to its own driver; cros_ec_lightbar
- Move VBC functionality to its own driver; cros_ec_vbc
- Move VBC functionality to its own driver; cros_ec_vbc
- Move DebugFS functionality to its own driver; cros_ec_debugfs
- Move SYSFS functionality to its own driver; cros_ec_sysfs
- Add support for input voltage options; tps65218
Fixes:
- Use devm_* managed resources; cros_ec
- Device Tree documentation; stmpe, aspeed-lpc, lochnagar
- Trivial Clean-ups; stmpe
- Rip out broken modular code; aat2870-core, adp5520, as3711,
db8500-prcmu, htc-i2cpld, max8925-core, rc5t583, sta2x11-mfd,
syscon, tps65090, tps65910, tps68470 tps80031, wm831x-spi,
wm831x-i2c, wm831x-core, wm8350-i2c, wm8350-core, wm8400-core
- Kconfig fixups; INTEL_SOC_PMIC
- Improve error path; sm501, sec-core
- Use struct_size() helper; sm501
- Constify; at91-usart
- Use pointers instead of copying data; at91-usart
- Deliver proper return value; cros_ec_dev
- Trivial formatting/whitespace; sec-core"
* tag 'mfd-next-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd: (53 commits)
mfd: mxs-lradc: Mark expected switch fall-through
mfd: sec-core: Cleanup formatting to a consistent style
mfd: tqmx86: IO controller with I2C, Wachdog and GPIO
mfd: intel-lpss: Move linux/pm.h to the local header
mfd: cros_ec_dev: Return number of bytes read with CROS_EC_DEV_IOCRDMEM
mfd: tps68470: Drop unused MODULE_DEVICE_TABLE
mfd: at91-usart: No need to copy mfd_cell in probe
mfd: at91-usart: Constify at91_usart_spi_subdev and at91_usart_serial_subdev
mfd: lochnagar: Add support for the Cirrus Logic Lochnagar
mfd: lochnagar: Add initial binding documentation
dt-bindings: mfd: aspeed-lpc: Make parameter optional
mfd: sec-core: Return gracefully instead of BUG() if device cannot match
mfd: sm501: Use struct_size() in devm_kzalloc()
mfd: sm501: Fix potential NULL pointer dereference
mfd: Kconfig: Fix I2C_DESIGNWARE_PLATFORM dependencies
mfd: tps65218.c: Add input voltage options
mfd: wm8400-core: Make it explicitly non-modular
mfd: wm8350-core: Drop unused module infrastructure from non-modular code
mfd: wm8350-i2c: Make it explicitly non-modular
mfd: wm831x-core: Drop unused module infrastructure from non-modular code
...
79 files changed, 3571 insertions, 656 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-chromeos b/Documentation/ABI/testing/sysfs-class-chromeos new file mode 100644 index 000000000000..5819699d66ec --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-chromeos | |||
@@ -0,0 +1,32 @@ | |||
1 | What: /sys/class/chromeos/<ec-device-name>/flashinfo | ||
2 | Date: August 2015 | ||
3 | KernelVersion: 4.2 | ||
4 | Description: | ||
5 | Show the EC flash information. | ||
6 | |||
7 | What: /sys/class/chromeos/<ec-device-name>/kb_wake_angle | ||
8 | Date: March 2018 | ||
9 | KernelVersion: 4.17 | ||
10 | Description: | ||
11 | Control the keyboard wake lid angle. Values are between | ||
12 | 0 and 360. This file will also show the keyboard wake lid | ||
13 | angle by querying the hardware. | ||
14 | |||
15 | What: /sys/class/chromeos/<ec-device-name>/reboot | ||
16 | Date: August 2015 | ||
17 | KernelVersion: 4.2 | ||
18 | Description: | ||
19 | Tell the EC to reboot in various ways. Options are: | ||
20 | "cancel": Cancel a pending reboot. | ||
21 | "ro": Jump to RO without rebooting. | ||
22 | "rw": Jump to RW without rebooting. | ||
23 | "cold": Cold reboot. | ||
24 | "disable-jump": Disable jump until next reboot. | ||
25 | "hibernate": Hibernate the EC. | ||
26 | "at-shutdown": Reboot after an AP shutdown. | ||
27 | |||
28 | What: /sys/class/chromeos/<ec-device-name>/version | ||
29 | Date: August 2015 | ||
30 | KernelVersion: 4.2 | ||
31 | Description: | ||
32 | Show the information about the EC software and hardware. | ||
diff --git a/Documentation/ABI/testing/sysfs-class-chromeos-driver-cros-ec-lightbar b/Documentation/ABI/testing/sysfs-class-chromeos-driver-cros-ec-lightbar new file mode 100644 index 000000000000..57a037791403 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-chromeos-driver-cros-ec-lightbar | |||
@@ -0,0 +1,74 @@ | |||
1 | What: /sys/class/chromeos/<ec-device-name>/lightbar/brightness | ||
2 | Date: August 2015 | ||
3 | KernelVersion: 4.2 | ||
4 | Description: | ||
5 | Writing to this file adjusts the overall brightness of | ||
6 | the lightbar, separate from any color intensity. The | ||
7 | valid range is 0 (off) to 255 (maximum brightness). | ||
8 | |||
9 | What: /sys/class/chromeos/<ec-device-name>/lightbar/interval_msec | ||
10 | Date: August 2015 | ||
11 | KernelVersion: 4.2 | ||
12 | Description: | ||
13 | The lightbar is controlled by an embedded controller (EC), | ||
14 | which also manages the keyboard, battery charging, fans, | ||
15 | and other system hardware. To prevent unprivileged users | ||
16 | from interfering with the other EC functions, the rate at | ||
17 | which the lightbar control files can be read or written is | ||
18 | limited. | ||
19 | |||
20 | Reading this file will return the number of milliseconds | ||
21 | that must elapse between accessing any of the lightbar | ||
22 | functions through this interface. Going faster will simply | ||
23 | block until the necessary interval has lapsed. The interval | ||
24 | applies uniformly to all accesses of any kind by any user. | ||
25 | |||
26 | What: /sys/class/chromeos/<ec-device-name>/lightbar/led_rgb | ||
27 | Date: August 2015 | ||
28 | KernelVersion: 4.2 | ||
29 | Description: | ||
30 | This allows you to control each LED segment. If the | ||
31 | lightbar is already running one of the automatic | ||
32 | sequences, you probably won’t see anything change because | ||
33 | your color setting will be almost immediately replaced. | ||
34 | To get useful results, you should stop the lightbar | ||
35 | sequence first. | ||
36 | |||
37 | The values written to this file are sets of four integers, | ||
38 | indicating LED, RED, GREEN, BLUE. The LED number is 0 to 3 | ||
39 | to select a single segment, or 4 to set all four segments | ||
40 | to the same value at once. The RED, GREEN, and BLUE | ||
41 | numbers should be in the range 0 (off) to 255 (maximum). | ||
42 | You can update more than one segment at a time by writing | ||
43 | more than one set of four integers. | ||
44 | |||
45 | What: /sys/class/chromeos/<ec-device-name>/lightbar/program | ||
46 | Date: August 2015 | ||
47 | KernelVersion: 4.2 | ||
48 | Description: | ||
49 | This allows you to upload and run custom lightbar sequences. | ||
50 | |||
51 | What: /sys/class/chromeos/<ec-device-name>/lightbar/sequence | ||
52 | Date: August 2015 | ||
53 | KernelVersion: 4.2 | ||
54 | Description: | ||
55 | The Pixel lightbar has a number of built-in sequences | ||
56 | that it displays under various conditions, such as at | ||
57 | power on, shut down, or while running. Reading from this | ||
58 | file displays the current sequence that the lightbar is | ||
59 | displaying. Writing to this file allows you to change the | ||
60 | sequence. | ||
61 | |||
62 | What: /sys/class/chromeos/<ec-device-name>/lightbar/userspace_control | ||
63 | Date: August 2015 | ||
64 | KernelVersion: 4.2 | ||
65 | Description: | ||
66 | This allows you to take the control of the lightbar. This | ||
67 | prevents the kernel from going through its normal | ||
68 | sequences. | ||
69 | |||
70 | What: /sys/class/chromeos/<ec-device-name>/lightbar/version | ||
71 | Date: August 2015 | ||
72 | KernelVersion: 4.2 | ||
73 | Description: | ||
74 | Show the information about the lightbar version. | ||
diff --git a/Documentation/ABI/testing/sysfs-class-chromeos-driver-cros-ec-vbc b/Documentation/ABI/testing/sysfs-class-chromeos-driver-cros-ec-vbc new file mode 100644 index 000000000000..38c5aaaaa89a --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-chromeos-driver-cros-ec-vbc | |||
@@ -0,0 +1,6 @@ | |||
1 | What: /sys/class/chromeos/<ec-device-name>/vbc/vboot_context | ||
2 | Date: October 2015 | ||
3 | KernelVersion: 4.4 | ||
4 | Description: | ||
5 | Read/write the verified boot context data included on a | ||
6 | small nvram space on some EC implementations. | ||
diff --git a/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt new file mode 100644 index 000000000000..480e66422625 --- /dev/null +++ b/Documentation/devicetree/bindings/iio/adc/stmpe-adc.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | STMPE ADC driver | ||
2 | ---------------- | ||
3 | |||
4 | Required properties: | ||
5 | - compatible: "st,stmpe-adc" | ||
6 | |||
7 | Optional properties: | ||
8 | Note that the ADC is shared with the STMPE touchscreen. ADC related settings | ||
9 | have to be done in the mfd. | ||
10 | - st,norequest-mask: bitmask specifying which ADC channels should _not_ be | ||
11 | requestable due to different usage (e.g. touch) | ||
12 | |||
13 | Node name must be stmpe_adc and should be child node of stmpe node to | ||
14 | which it belongs. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | stmpe_adc { | ||
19 | compatible = "st,stmpe-adc"; | ||
20 | st,norequest-mask = <0x0F>; /* dont use ADC CH3-0 */ | ||
21 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt b/Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt new file mode 100644 index 000000000000..4494613ae7ad --- /dev/null +++ b/Documentation/devicetree/bindings/input/st,stpmic1-onkey.txt | |||
@@ -0,0 +1,28 @@ | |||
1 | STMicroelectronics STPMIC1 Onkey | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible = "st,stpmic1-onkey"; | ||
6 | - interrupts: interrupt line to use | ||
7 | - interrupt-names = "onkey-falling", "onkey-rising" | ||
8 | onkey-falling: happens when onkey is pressed; IT_PONKEY_F of pmic | ||
9 | onkey-rising: happens when onkey is released; IT_PONKEY_R of pmic | ||
10 | |||
11 | Optional properties: | ||
12 | |||
13 | - st,onkey-clear-cc-flag: onkey is able power on after an | ||
14 | over-current shutdown event. | ||
15 | - st,onkey-pu-inactive: onkey pull up is not active | ||
16 | - power-off-time-sec: Duration in seconds which the key should be kept | ||
17 | pressed for device to power off automatically (from 1 to 16 seconds). | ||
18 | see See Documentation/devicetree/bindings/input/keys.txt | ||
19 | |||
20 | Example: | ||
21 | |||
22 | onkey { | ||
23 | compatible = "st,stpmic1-onkey"; | ||
24 | interrupt-parent = <&pmic>; | ||
25 | interrupts = <IT_PONKEY_F 0>,<IT_PONKEY_R 1>; | ||
26 | interrupt-names = "onkey-falling", "onkey-rising"; | ||
27 | power-off-time-sec = <10>; | ||
28 | }; | ||
diff --git a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt index 127baa31a77a..c549924603d2 100644 --- a/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt +++ b/Documentation/devicetree/bindings/input/touchscreen/stmpe.txt | |||
@@ -5,39 +5,105 @@ Required properties: | |||
5 | - compatible: "st,stmpe-ts" | 5 | - compatible: "st,stmpe-ts" |
6 | 6 | ||
7 | Optional properties: | 7 | Optional properties: |
8 | - st,sample-time: ADC converstion time in number of clock. (0 -> 36 clocks, 1 -> | 8 | - st,ave-ctrl : Sample average control |
9 | 44 clocks, 2 -> 56 clocks, 3 -> 64 clocks, 4 -> 80 clocks, 5 -> 96 clocks, 6 | 9 | 0 -> 1 sample |
10 | -> 144 clocks), recommended is 4. | 10 | 1 -> 2 samples |
11 | - st,mod-12b: ADC Bit mode (0 -> 10bit ADC, 1 -> 12bit ADC) | 11 | 2 -> 4 samples |
12 | - st,ref-sel: ADC reference source (0 -> internal reference, 1 -> external | 12 | 3 -> 8 samples |
13 | reference) | 13 | - st,touch-det-delay : Touch detect interrupt delay (recommended is 3) |
14 | - st,adc-freq: ADC Clock speed (0 -> 1.625 MHz, 1 -> 3.25 MHz, 2 || 3 -> 6.5 MHz) | 14 | 0 -> 10 us |
15 | - st,ave-ctrl: Sample average control (0 -> 1 sample, 1 -> 2 samples, 2 -> 4 | 15 | 1 -> 50 us |
16 | samples, 3 -> 8 samples) | 16 | 2 -> 100 us |
17 | - st,touch-det-delay: Touch detect interrupt delay (0 -> 10 us, 1 -> 50 us, 2 -> | 17 | 3 -> 500 us |
18 | 100 us, 3 -> 500 us, 4-> 1 ms, 5 -> 5 ms, 6 -> 10 ms, 7 -> 50 ms) recommended | 18 | 4 -> 1 ms |
19 | is 3 | 19 | 5 -> 5 ms |
20 | - st,settling: Panel driver settling time (0 -> 10 us, 1 -> 100 us, 2 -> 500 us, 3 | 20 | 6 -> 10 ms |
21 | -> 1 ms, 4 -> 5 ms, 5 -> 10 ms, 6 for 50 ms, 7 -> 100 ms) recommended is 2 | 21 | 7 -> 50 ms |
22 | - st,fraction-z: Length of the fractional part in z (fraction-z ([0..7]) = Count of | 22 | - st,settling : Panel driver settling time (recommended is 2) |
23 | the fractional part) recommended is 7 | 23 | 0 -> 10 us |
24 | - st,i-drive: current limit value of the touchscreen drivers (0 -> 20 mA typical 35 | 24 | 1 -> 100 us |
25 | mA max, 1 -> 50 mA typical 80 mA max) | 25 | 2 -> 500 us |
26 | 3 -> 1 ms | ||
27 | 4 -> 5 ms | ||
28 | 5 -> 10 ms | ||
29 | 6 -> 50 ms | ||
30 | 7 -> 100 ms | ||
31 | - st,fraction-z : Length of the fractional part in z (recommended is 7) | ||
32 | (fraction-z ([0..7]) = Count of the fractional part) | ||
33 | - st,i-drive : current limit value of the touchscreen drivers | ||
34 | 0 -> 20 mA (typical 35mA max) | ||
35 | 1 -> 50 mA (typical 80 mA max) | ||
36 | |||
37 | Optional properties common with MFD (deprecated): | ||
38 | - st,sample-time : ADC conversion time in number of clock. | ||
39 | 0 -> 36 clocks | ||
40 | 1 -> 44 clocks | ||
41 | 2 -> 56 clocks | ||
42 | 3 -> 64 clocks | ||
43 | 4 -> 80 clocks (recommended) | ||
44 | 5 -> 96 clocks | ||
45 | 6 -> 124 clocks | ||
46 | - st,mod-12b : ADC Bit mode | ||
47 | 0 -> 10bit ADC | ||
48 | 1 -> 12bit ADC | ||
49 | - st,ref-sel : ADC reference source | ||
50 | 0 -> internal | ||
51 | 1 -> external | ||
52 | - st,adc-freq : ADC Clock speed | ||
53 | 0 -> 1.625 MHz | ||
54 | 1 -> 3.25 MHz | ||
55 | 2 || 3 -> 6.5 MHz | ||
26 | 56 | ||
27 | Node name must be stmpe_touchscreen and should be child node of stmpe node to | 57 | Node name must be stmpe_touchscreen and should be child node of stmpe node to |
28 | which it belongs. | 58 | which it belongs. |
29 | 59 | ||
60 | Note that common ADC settings of stmpe_touchscreen (child) will take precedence | ||
61 | over the settings done in MFD. | ||
62 | |||
30 | Example: | 63 | Example: |
31 | 64 | ||
65 | stmpe811@41 { | ||
66 | compatible = "st,stmpe811"; | ||
67 | pinctrl-names = "default"; | ||
68 | pinctrl-0 = <&pinctrl_touch_int>; | ||
69 | #address-cells = <1>; | ||
70 | #size-cells = <0>; | ||
71 | reg = <0x41>; | ||
72 | interrupts = <10 IRQ_TYPE_LEVEL_LOW>; | ||
73 | interrupt-parent = <&gpio4>; | ||
74 | interrupt-controller; | ||
75 | id = <0>; | ||
76 | blocks = <0x5>; | ||
77 | irq-trigger = <0x1>; | ||
78 | /* Common ADC settings */ | ||
79 | /* 3.25 MHz ADC clock speed */ | ||
80 | st,adc-freq = <1>; | ||
81 | /* 12-bit ADC */ | ||
82 | st,mod-12b = <1>; | ||
83 | /* internal ADC reference */ | ||
84 | st,ref-sel = <0>; | ||
85 | /* ADC converstion time: 80 clocks */ | ||
86 | st,sample-time = <4>; | ||
87 | |||
32 | stmpe_touchscreen { | 88 | stmpe_touchscreen { |
33 | compatible = "st,stmpe-ts"; | 89 | compatible = "st,stmpe-ts"; |
34 | st,sample-time = <4>; | 90 | reg = <0>; |
35 | st,mod-12b = <1>; | 91 | /* 8 sample average control */ |
36 | st,ref-sel = <0>; | 92 | st,ave-ctrl = <3>; |
37 | st,adc-freq = <1>; | 93 | /* 5 ms touch detect interrupt delay */ |
38 | st,ave-ctrl = <1>; | 94 | st,touch-det-delay = <5>; |
39 | st,touch-det-delay = <2>; | 95 | /* 1 ms panel driver settling time */ |
40 | st,settling = <2>; | 96 | st,settling = <3>; |
97 | /* 7 length fractional part in z */ | ||
41 | st,fraction-z = <7>; | 98 | st,fraction-z = <7>; |
99 | /* | ||
100 | * 50 mA typical 80 mA max touchscreen drivers | ||
101 | * current limit value | ||
102 | */ | ||
42 | st,i-drive = <1>; | 103 | st,i-drive = <1>; |
43 | }; | 104 | }; |
105 | stmpe_adc { | ||
106 | compatible = "st,stmpe-adc"; | ||
107 | st,norequest-mask = <0x0F>; | ||
108 | }; | ||
109 | }; | ||
diff --git a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt index 34dd89087cff..86446074e206 100644 --- a/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt +++ b/Documentation/devicetree/bindings/mfd/aspeed-lpc.txt | |||
@@ -135,6 +135,8 @@ Required properties: | |||
135 | - clocks: contains a phandle to the syscon node describing the clocks. | 135 | - clocks: contains a phandle to the syscon node describing the clocks. |
136 | There should then be one cell representing the clock to use | 136 | There should then be one cell representing the clock to use |
137 | 137 | ||
138 | Optional properties: | ||
139 | |||
138 | - memory-region: A phandle to a reserved_memory region to be used for the LPC | 140 | - memory-region: A phandle to a reserved_memory region to be used for the LPC |
139 | to AHB mapping | 141 | to AHB mapping |
140 | 142 | ||
diff --git a/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.txt b/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.txt new file mode 100644 index 000000000000..004b0158cf4d --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/cirrus,lochnagar.txt | |||
@@ -0,0 +1,68 @@ | |||
1 | Cirrus Logic Lochnagar Audio Development Board | ||
2 | |||
3 | Lochnagar is an evaluation and development board for Cirrus Logic | ||
4 | Smart CODEC and Amp devices. It allows the connection of most Cirrus | ||
5 | Logic devices on mini-cards, as well as allowing connection of | ||
6 | various application processor systems to provide a full evaluation | ||
7 | platform. Audio system topology, clocking and power can all be | ||
8 | controlled through the Lochnagar, allowing the device under test | ||
9 | to be used in a variety of possible use cases. | ||
10 | |||
11 | Also see these documents for generic binding information: | ||
12 | [1] GPIO : ../gpio/gpio.txt | ||
13 | |||
14 | And these for relevant defines: | ||
15 | [2] include/dt-bindings/pinctrl/lochnagar.h | ||
16 | [3] include/dt-bindings/clock/lochnagar.h | ||
17 | |||
18 | And these documents for the required sub-node binding details: | ||
19 | [4] Clock: ../clock/cirrus,lochnagar.txt | ||
20 | [5] Pinctrl: ../pinctrl/cirrus,lochnagar.txt | ||
21 | [6] Regulator: ../regulator/cirrus,lochnagar.txt | ||
22 | |||
23 | Required properties: | ||
24 | |||
25 | - compatible : One of the following strings: | ||
26 | "cirrus,lochnagar1" | ||
27 | "cirrus,lochnagar2" | ||
28 | |||
29 | - reg : I2C slave address | ||
30 | |||
31 | - reset-gpios : Reset line to the Lochnagar, see [1]. | ||
32 | |||
33 | Required sub-nodes: | ||
34 | |||
35 | - lochnagar-clk : Binding for the clocking components, see [4]. | ||
36 | |||
37 | - lochnagar-pinctrl : Binding for the pin control components, see [5]. | ||
38 | |||
39 | Optional sub-nodes: | ||
40 | |||
41 | - Bindings for the regulator components, see [6]. Only available on | ||
42 | Lochnagar 2. | ||
43 | |||
44 | Optional properties: | ||
45 | |||
46 | - present-gpios : Host present line, indicating the presence of a | ||
47 | host system, see [1]. This can be omitted if the present line is | ||
48 | tied in hardware. | ||
49 | |||
50 | Example: | ||
51 | |||
52 | lochnagar: lochnagar@22 { | ||
53 | compatible = "cirrus,lochnagar2"; | ||
54 | reg = <0x22>; | ||
55 | |||
56 | reset-gpios = <&gpio0 55 0>; | ||
57 | present-gpios = <&gpio0 60 0>; | ||
58 | |||
59 | lochnagar-clk { | ||
60 | compatible = "cirrus,lochnagar2-clk"; | ||
61 | ... | ||
62 | }; | ||
63 | |||
64 | lochnagar-pinctrl { | ||
65 | compatible = "cirrus,lochnagar-pinctrl"; | ||
66 | ... | ||
67 | }; | ||
68 | }; | ||
diff --git a/Documentation/devicetree/bindings/mfd/st,stpmic1.txt b/Documentation/devicetree/bindings/mfd/st,stpmic1.txt new file mode 100644 index 000000000000..afd45c089585 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/st,stpmic1.txt | |||
@@ -0,0 +1,61 @@ | |||
1 | * STMicroelectronics STPMIC1 Power Management IC | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: : "st,stpmic1" | ||
5 | - reg: : The I2C slave address for the STPMIC1 chip. | ||
6 | - interrupts: : The interrupt line the device is connected to. | ||
7 | - #interrupt-cells: : Should be 1. | ||
8 | - interrupt-controller: : Marks the device node as an interrupt controller. | ||
9 | Interrupt numbers are defined at | ||
10 | dt-bindings/mfd/st,stpmic1.h. | ||
11 | |||
12 | STPMIC1 consists in a varied group of sub-devices. | ||
13 | Each sub-device binding is be described in own documentation file. | ||
14 | |||
15 | Device Description | ||
16 | ------ ------------ | ||
17 | st,stpmic1-onkey : Power on key, see ../input/st,stpmic1-onkey.txt | ||
18 | st,stpmic1-regulators : Regulators, see ../regulator/st,stpmic1-regulator.txt | ||
19 | st,stpmic1-wdt : Watchdog, see ../watchdog/st,stpmic1-wdt.txt | ||
20 | |||
21 | Example: | ||
22 | |||
23 | #include <dt-bindings/mfd/st,stpmic1.h> | ||
24 | |||
25 | pmic: pmic@33 { | ||
26 | compatible = "st,stpmic1"; | ||
27 | reg = <0x33>; | ||
28 | interrupt-parent = <&gpioa>; | ||
29 | interrupts = <0 2>; | ||
30 | |||
31 | interrupt-controller; | ||
32 | #interrupt-cells = <2>; | ||
33 | |||
34 | onkey { | ||
35 | compatible = "st,stpmic1-onkey"; | ||
36 | interrupts = <IT_PONKEY_F 0>,<IT_PONKEY_R 1>; | ||
37 | interrupt-names = "onkey-falling", "onkey-rising"; | ||
38 | power-off-time-sec = <10>; | ||
39 | }; | ||
40 | |||
41 | watchdog { | ||
42 | compatible = "st,stpmic1-wdt"; | ||
43 | }; | ||
44 | |||
45 | regulators { | ||
46 | compatible = "st,stpmic1-regulators"; | ||
47 | |||
48 | vdd_core: buck1 { | ||
49 | regulator-name = "vdd_core"; | ||
50 | regulator-boot-on; | ||
51 | regulator-min-microvolt = <700000>; | ||
52 | regulator-max-microvolt = <1200000>; | ||
53 | }; | ||
54 | vdd: buck3 { | ||
55 | regulator-name = "vdd"; | ||
56 | regulator-min-microvolt = <3300000>; | ||
57 | regulator-max-microvolt = <3300000>; | ||
58 | regulator-boot-on; | ||
59 | regulator-pull-down; | ||
60 | }; | ||
61 | }; | ||
diff --git a/Documentation/devicetree/bindings/mfd/stmpe.txt b/Documentation/devicetree/bindings/mfd/stmpe.txt index c797c05cd3c2..d4408a417193 100644 --- a/Documentation/devicetree/bindings/mfd/stmpe.txt +++ b/Documentation/devicetree/bindings/mfd/stmpe.txt | |||
@@ -4,15 +4,29 @@ STMPE is an MFD device which may expose the following inbuilt devices: gpio, | |||
4 | keypad, touchscreen, adc, pwm, rotator. | 4 | keypad, touchscreen, adc, pwm, rotator. |
5 | 5 | ||
6 | Required properties: | 6 | Required properties: |
7 | - compatible : "st,stmpe[610|801|811|1600|1601|2401|2403]" | 7 | - compatible : "st,stmpe[610|801|811|1600|1601|2401|2403]" |
8 | - reg : I2C/SPI address of the device | 8 | - reg : I2C/SPI address of the device |
9 | 9 | ||
10 | Optional properties: | 10 | Optional properties: |
11 | - interrupts : The interrupt outputs from the controller | 11 | - interrupts : The interrupt outputs from the controller |
12 | - interrupt-controller : Marks the device node as an interrupt controller | 12 | - interrupt-controller : Marks the device node as an interrupt controller |
13 | - wakeup-source : Marks the input device as wakable | 13 | - wakeup-source : Marks the input device as wakable |
14 | - st,autosleep-timeout : Valid entries (ms); 4, 16, 32, 64, 128, 256, 512 and 1024 | 14 | - st,autosleep-timeout : Valid entries (ms); 4, 16, 32, 64, 128, 256, 512 and 1024 |
15 | - irq-gpio : If present, which GPIO to use for event IRQ | 15 | - irq-gpio : If present, which GPIO to use for event IRQ |
16 | |||
17 | Optional properties for devices with touch and ADC (STMPE811|STMPE610): | ||
18 | - st,sample-time : ADC conversion time in number of clock. | ||
19 | 0 -> 36 clocks 4 -> 80 clocks (recommended) | ||
20 | 1 -> 44 clocks 5 -> 96 clocks | ||
21 | 2 -> 56 clocks 6 -> 124 clocks | ||
22 | 3 -> 64 clocks | ||
23 | - st,mod-12b : ADC Bit mode | ||
24 | 0 -> 10bit ADC 1 -> 12bit ADC | ||
25 | - st,ref-sel : ADC reference source | ||
26 | 0 -> internal 1 -> external | ||
27 | - st,adc-freq : ADC Clock speed | ||
28 | 0 -> 1.625 MHz 2 || 3 -> 6.5 MHz | ||
29 | 1 -> 3.25 MHz | ||
16 | 30 | ||
17 | Example: | 31 | Example: |
18 | 32 | ||
diff --git a/Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt b/Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt new file mode 100644 index 000000000000..7cc1407f15cb --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/st,stpmic1-wdt.txt | |||
@@ -0,0 +1,11 @@ | |||
1 | STMicroelectronics STPMIC1 Watchdog | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible : should be "st,stpmic1-wdt" | ||
6 | |||
7 | Example: | ||
8 | |||
9 | watchdog { | ||
10 | compatible = "st,stpmic1-wdt"; | ||
11 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index cd4fd96a998a..e261ca14ebd0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -3777,6 +3777,23 @@ L: netdev@vger.kernel.org | |||
3777 | S: Maintained | 3777 | S: Maintained |
3778 | F: drivers/net/ethernet/cirrus/ep93xx_eth.c | 3778 | F: drivers/net/ethernet/cirrus/ep93xx_eth.c |
3779 | 3779 | ||
3780 | CIRRUS LOGIC LOCHNAGAR DRIVER | ||
3781 | M: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
3782 | M: Richard Fitzgerald <rf@opensource.cirrus.com> | ||
3783 | L: patches@opensource.cirrus.com | ||
3784 | S: Supported | ||
3785 | F: drivers/clk/clk-lochnagar.c | ||
3786 | F: drivers/mfd/lochnagar-i2c.c | ||
3787 | F: drivers/pinctrl/cirrus/pinctrl-lochnagar.c | ||
3788 | F: drivers/regulator/lochnagar-regulator.c | ||
3789 | F: include/dt-bindings/clk/lochnagar.h | ||
3790 | F: include/dt-bindings/pinctrl/lochnagar.h | ||
3791 | F: include/linux/mfd/lochnagar* | ||
3792 | F: Documentation/devicetree/bindings/mfd/cirrus,lochnagar.txt | ||
3793 | F: Documentation/devicetree/bindings/clock/cirrus,lochnagar.txt | ||
3794 | F: Documentation/devicetree/bindings/pinctrl/cirrus,lochnagar.txt | ||
3795 | F: Documentation/devicetree/bindings/regulator/cirrus,lochnagar.txt | ||
3796 | |||
3780 | CISCO FCOE HBA DRIVER | 3797 | CISCO FCOE HBA DRIVER |
3781 | M: Satish Kharat <satishkh@cisco.com> | 3798 | M: Satish Kharat <satishkh@cisco.com> |
3782 | M: Sesidhar Baddela <sebaddel@cisco.com> | 3799 | M: Sesidhar Baddela <sebaddel@cisco.com> |
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index 5debc67df70a..76db6e5cc296 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -817,6 +817,13 @@ config STM32_DFSDM_ADC | |||
817 | This driver can also be built as a module. If so, the module | 817 | This driver can also be built as a module. If so, the module |
818 | will be called stm32-dfsdm-adc. | 818 | will be called stm32-dfsdm-adc. |
819 | 819 | ||
820 | config STMPE_ADC | ||
821 | tristate "STMicroelectronics STMPE ADC driver" | ||
822 | depends on OF && MFD_STMPE | ||
823 | help | ||
824 | Say yes here to build support for ST Microelectronics STMPE | ||
825 | built-in ADC block (stmpe811). | ||
826 | |||
820 | config STX104 | 827 | config STX104 |
821 | tristate "Apex Embedded Systems STX104 driver" | 828 | tristate "Apex Embedded Systems STX104 driver" |
822 | depends on PC104 && X86 | 829 | depends on PC104 && X86 |
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile index d50eb47da484..6fcebd167524 100644 --- a/drivers/iio/adc/Makefile +++ b/drivers/iio/adc/Makefile | |||
@@ -77,6 +77,7 @@ obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o | |||
77 | obj-$(CONFIG_STM32_ADC) += stm32-adc.o | 77 | obj-$(CONFIG_STM32_ADC) += stm32-adc.o |
78 | obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o | 78 | obj-$(CONFIG_STM32_DFSDM_CORE) += stm32-dfsdm-core.o |
79 | obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o | 79 | obj-$(CONFIG_STM32_DFSDM_ADC) += stm32-dfsdm-adc.o |
80 | obj-$(CONFIG_STMPE_ADC) += stmpe-adc.o | ||
80 | obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o | 81 | obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o |
81 | obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o | 82 | obj-$(CONFIG_TI_ADC0832) += ti-adc0832.o |
82 | obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o | 83 | obj-$(CONFIG_TI_ADC084S021) += ti-adc084s021.o |
diff --git a/drivers/iio/adc/stmpe-adc.c b/drivers/iio/adc/stmpe-adc.c new file mode 100644 index 000000000000..37f4b74a5d32 --- /dev/null +++ b/drivers/iio/adc/stmpe-adc.c | |||
@@ -0,0 +1,363 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * STMicroelectronics STMPE811 IIO ADC Driver | ||
4 | * | ||
5 | * 4 channel, 10/12-bit ADC | ||
6 | * | ||
7 | * Copyright (C) 2013-2018 Toradex AG <stefan.agner@toradex.com> | ||
8 | */ | ||
9 | |||
10 | #include <linux/completion.h> | ||
11 | #include <linux/err.h> | ||
12 | #include <linux/iio/iio.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/mfd/stmpe.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/of_platform.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/device.h> | ||
20 | |||
21 | #define STMPE_REG_INT_STA 0x0B | ||
22 | #define STMPE_REG_ADC_INT_EN 0x0E | ||
23 | #define STMPE_REG_ADC_INT_STA 0x0F | ||
24 | |||
25 | #define STMPE_REG_ADC_CTRL1 0x20 | ||
26 | #define STMPE_REG_ADC_CTRL2 0x21 | ||
27 | #define STMPE_REG_ADC_CAPT 0x22 | ||
28 | #define STMPE_REG_ADC_DATA_CH(channel) (0x30 + 2 * (channel)) | ||
29 | |||
30 | #define STMPE_REG_TEMP_CTRL 0x60 | ||
31 | #define STMPE_TEMP_CTRL_ENABLE BIT(0) | ||
32 | #define STMPE_TEMP_CTRL_ACQ BIT(1) | ||
33 | #define STMPE_TEMP_CTRL_THRES_EN BIT(3) | ||
34 | #define STMPE_START_ONE_TEMP_CONV (STMPE_TEMP_CTRL_ENABLE | \ | ||
35 | STMPE_TEMP_CTRL_ACQ | \ | ||
36 | STMPE_TEMP_CTRL_THRES_EN) | ||
37 | #define STMPE_REG_TEMP_DATA 0x61 | ||
38 | #define STMPE_REG_TEMP_TH 0x63 | ||
39 | #define STMPE_ADC_LAST_NR 7 | ||
40 | #define STMPE_TEMP_CHANNEL (STMPE_ADC_LAST_NR + 1) | ||
41 | |||
42 | #define STMPE_ADC_CH(channel) ((1 << (channel)) & 0xff) | ||
43 | |||
44 | #define STMPE_ADC_TIMEOUT msecs_to_jiffies(1000) | ||
45 | |||
46 | struct stmpe_adc { | ||
47 | struct stmpe *stmpe; | ||
48 | struct clk *clk; | ||
49 | struct device *dev; | ||
50 | struct mutex lock; | ||
51 | |||
52 | /* We are allocating plus one for the temperature channel */ | ||
53 | struct iio_chan_spec stmpe_adc_iio_channels[STMPE_ADC_LAST_NR + 2]; | ||
54 | |||
55 | struct completion completion; | ||
56 | |||
57 | u8 channel; | ||
58 | u32 value; | ||
59 | }; | ||
60 | |||
61 | static int stmpe_read_voltage(struct stmpe_adc *info, | ||
62 | struct iio_chan_spec const *chan, int *val) | ||
63 | { | ||
64 | long ret; | ||
65 | |||
66 | mutex_lock(&info->lock); | ||
67 | |||
68 | info->channel = (u8)chan->channel; | ||
69 | |||
70 | if (info->channel > STMPE_ADC_LAST_NR) { | ||
71 | mutex_unlock(&info->lock); | ||
72 | return -EINVAL; | ||
73 | } | ||
74 | |||
75 | stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_EN, | ||
76 | STMPE_ADC_CH(info->channel)); | ||
77 | |||
78 | stmpe_reg_write(info->stmpe, STMPE_REG_ADC_CAPT, | ||
79 | STMPE_ADC_CH(info->channel)); | ||
80 | |||
81 | *val = info->value; | ||
82 | |||
83 | ret = wait_for_completion_interruptible_timeout | ||
84 | (&info->completion, STMPE_ADC_TIMEOUT); | ||
85 | |||
86 | if (ret <= 0) { | ||
87 | mutex_unlock(&info->lock); | ||
88 | if (ret == 0) | ||
89 | return -ETIMEDOUT; | ||
90 | else | ||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | *val = info->value; | ||
95 | |||
96 | mutex_unlock(&info->lock); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static int stmpe_read_temp(struct stmpe_adc *info, | ||
102 | struct iio_chan_spec const *chan, int *val) | ||
103 | { | ||
104 | long ret; | ||
105 | |||
106 | mutex_lock(&info->lock); | ||
107 | |||
108 | info->channel = (u8)chan->channel; | ||
109 | |||
110 | if (info->channel != STMPE_TEMP_CHANNEL) { | ||
111 | mutex_unlock(&info->lock); | ||
112 | return -EINVAL; | ||
113 | } | ||
114 | |||
115 | stmpe_reg_write(info->stmpe, STMPE_REG_TEMP_CTRL, | ||
116 | STMPE_START_ONE_TEMP_CONV); | ||
117 | |||
118 | ret = wait_for_completion_interruptible_timeout | ||
119 | (&info->completion, STMPE_ADC_TIMEOUT); | ||
120 | |||
121 | if (ret <= 0) { | ||
122 | mutex_unlock(&info->lock); | ||
123 | if (ret == 0) | ||
124 | return -ETIMEDOUT; | ||
125 | else | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | /* | ||
130 | * absolute temp = +V3.3 * value /7.51 [K] | ||
131 | * scale to [milli °C] | ||
132 | */ | ||
133 | *val = ((449960l * info->value) / 1024l) - 273150; | ||
134 | |||
135 | mutex_unlock(&info->lock); | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int stmpe_read_raw(struct iio_dev *indio_dev, | ||
141 | struct iio_chan_spec const *chan, | ||
142 | int *val, | ||
143 | int *val2, | ||
144 | long mask) | ||
145 | { | ||
146 | struct stmpe_adc *info = iio_priv(indio_dev); | ||
147 | long ret; | ||
148 | |||
149 | switch (mask) { | ||
150 | case IIO_CHAN_INFO_RAW: | ||
151 | case IIO_CHAN_INFO_PROCESSED: | ||
152 | |||
153 | switch (chan->type) { | ||
154 | case IIO_VOLTAGE: | ||
155 | ret = stmpe_read_voltage(info, chan, val); | ||
156 | break; | ||
157 | |||
158 | case IIO_TEMP: | ||
159 | ret = stmpe_read_temp(info, chan, val); | ||
160 | break; | ||
161 | default: | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | if (ret < 0) | ||
166 | return ret; | ||
167 | |||
168 | return IIO_VAL_INT; | ||
169 | |||
170 | case IIO_CHAN_INFO_SCALE: | ||
171 | *val = 3300; | ||
172 | *val2 = info->stmpe->mod_12b ? 12 : 10; | ||
173 | return IIO_VAL_FRACTIONAL_LOG2; | ||
174 | |||
175 | default: | ||
176 | break; | ||
177 | } | ||
178 | |||
179 | return -EINVAL; | ||
180 | } | ||
181 | |||
182 | static irqreturn_t stmpe_adc_isr(int irq, void *dev_id) | ||
183 | { | ||
184 | struct stmpe_adc *info = (struct stmpe_adc *)dev_id; | ||
185 | u16 data; | ||
186 | |||
187 | if (info->channel > STMPE_TEMP_CHANNEL) | ||
188 | return IRQ_NONE; | ||
189 | |||
190 | if (info->channel <= STMPE_ADC_LAST_NR) { | ||
191 | int int_sta; | ||
192 | |||
193 | int_sta = stmpe_reg_read(info->stmpe, STMPE_REG_ADC_INT_STA); | ||
194 | |||
195 | /* Is the interrupt relevant */ | ||
196 | if (!(int_sta & STMPE_ADC_CH(info->channel))) | ||
197 | return IRQ_NONE; | ||
198 | |||
199 | /* Read value */ | ||
200 | stmpe_block_read(info->stmpe, | ||
201 | STMPE_REG_ADC_DATA_CH(info->channel), 2, (u8 *) &data); | ||
202 | |||
203 | stmpe_reg_write(info->stmpe, STMPE_REG_ADC_INT_STA, int_sta); | ||
204 | } else if (info->channel == STMPE_TEMP_CHANNEL) { | ||
205 | /* Read value */ | ||
206 | stmpe_block_read(info->stmpe, STMPE_REG_TEMP_DATA, 2, | ||
207 | (u8 *) &data); | ||
208 | } | ||
209 | |||
210 | info->value = (u32) be16_to_cpu(data); | ||
211 | complete(&info->completion); | ||
212 | |||
213 | return IRQ_HANDLED; | ||
214 | } | ||
215 | |||
216 | static const struct iio_info stmpe_adc_iio_info = { | ||
217 | .read_raw = &stmpe_read_raw, | ||
218 | }; | ||
219 | |||
220 | static void stmpe_adc_voltage_chan(struct iio_chan_spec *ics, int chan) | ||
221 | { | ||
222 | ics->type = IIO_VOLTAGE; | ||
223 | ics->info_mask_separate = BIT(IIO_CHAN_INFO_RAW); | ||
224 | ics->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE); | ||
225 | ics->indexed = 1; | ||
226 | ics->channel = chan; | ||
227 | } | ||
228 | |||
229 | static void stmpe_adc_temp_chan(struct iio_chan_spec *ics, int chan) | ||
230 | { | ||
231 | ics->type = IIO_TEMP; | ||
232 | ics->info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED); | ||
233 | ics->indexed = 1; | ||
234 | ics->channel = chan; | ||
235 | } | ||
236 | |||
237 | static int stmpe_adc_init_hw(struct stmpe_adc *adc) | ||
238 | { | ||
239 | int ret; | ||
240 | struct stmpe *stmpe = adc->stmpe; | ||
241 | |||
242 | ret = stmpe_enable(stmpe, STMPE_BLOCK_ADC); | ||
243 | if (ret) { | ||
244 | dev_err(stmpe->dev, "Could not enable clock for ADC\n"); | ||
245 | return ret; | ||
246 | } | ||
247 | |||
248 | ret = stmpe811_adc_common_init(stmpe); | ||
249 | if (ret) { | ||
250 | stmpe_disable(stmpe, STMPE_BLOCK_ADC); | ||
251 | return ret; | ||
252 | } | ||
253 | |||
254 | /* use temp irq for each conversion completion */ | ||
255 | stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH, 0); | ||
256 | stmpe_reg_write(stmpe, STMPE_REG_TEMP_TH + 1, 0); | ||
257 | |||
258 | return 0; | ||
259 | } | ||
260 | |||
261 | static int stmpe_adc_probe(struct platform_device *pdev) | ||
262 | { | ||
263 | struct iio_dev *indio_dev; | ||
264 | struct stmpe_adc *info; | ||
265 | struct device_node *np; | ||
266 | u32 norequest_mask = 0; | ||
267 | int irq_temp, irq_adc; | ||
268 | int num_chan = 0; | ||
269 | int i = 0; | ||
270 | int ret; | ||
271 | |||
272 | irq_adc = platform_get_irq_byname(pdev, "STMPE_ADC"); | ||
273 | if (irq_adc < 0) | ||
274 | return irq_adc; | ||
275 | |||
276 | indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(struct stmpe_adc)); | ||
277 | if (!indio_dev) { | ||
278 | dev_err(&pdev->dev, "failed allocating iio device\n"); | ||
279 | return -ENOMEM; | ||
280 | } | ||
281 | |||
282 | info = iio_priv(indio_dev); | ||
283 | mutex_init(&info->lock); | ||
284 | |||
285 | init_completion(&info->completion); | ||
286 | ret = devm_request_threaded_irq(&pdev->dev, irq_adc, NULL, | ||
287 | stmpe_adc_isr, IRQF_ONESHOT, | ||
288 | "stmpe-adc", info); | ||
289 | if (ret < 0) { | ||
290 | dev_err(&pdev->dev, "failed requesting irq, irq = %d\n", | ||
291 | irq_adc); | ||
292 | return ret; | ||
293 | } | ||
294 | |||
295 | irq_temp = platform_get_irq_byname(pdev, "STMPE_TEMP_SENS"); | ||
296 | if (irq_temp >= 0) { | ||
297 | ret = devm_request_threaded_irq(&pdev->dev, irq_temp, NULL, | ||
298 | stmpe_adc_isr, IRQF_ONESHOT, | ||
299 | "stmpe-adc", info); | ||
300 | if (ret < 0) | ||
301 | dev_warn(&pdev->dev, "failed requesting irq for" | ||
302 | " temp sensor, irq = %d\n", irq_temp); | ||
303 | } | ||
304 | |||
305 | platform_set_drvdata(pdev, indio_dev); | ||
306 | |||
307 | indio_dev->name = dev_name(&pdev->dev); | ||
308 | indio_dev->dev.parent = &pdev->dev; | ||
309 | indio_dev->info = &stmpe_adc_iio_info; | ||
310 | indio_dev->modes = INDIO_DIRECT_MODE; | ||
311 | |||
312 | info->stmpe = dev_get_drvdata(pdev->dev.parent); | ||
313 | |||
314 | np = pdev->dev.of_node; | ||
315 | |||
316 | if (!np) | ||
317 | dev_err(&pdev->dev, "no device tree node found\n"); | ||
318 | |||
319 | of_property_read_u32(np, "st,norequest-mask", &norequest_mask); | ||
320 | |||
321 | for_each_clear_bit(i, (unsigned long *) &norequest_mask, | ||
322 | (STMPE_ADC_LAST_NR + 1)) { | ||
323 | stmpe_adc_voltage_chan(&info->stmpe_adc_iio_channels[num_chan], i); | ||
324 | num_chan++; | ||
325 | } | ||
326 | stmpe_adc_temp_chan(&info->stmpe_adc_iio_channels[num_chan], i); | ||
327 | num_chan++; | ||
328 | indio_dev->channels = info->stmpe_adc_iio_channels; | ||
329 | indio_dev->num_channels = num_chan; | ||
330 | |||
331 | ret = stmpe_adc_init_hw(info); | ||
332 | if (ret) | ||
333 | return ret; | ||
334 | |||
335 | return devm_iio_device_register(&pdev->dev, indio_dev); | ||
336 | } | ||
337 | |||
338 | static int __maybe_unused stmpe_adc_resume(struct device *dev) | ||
339 | { | ||
340 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | ||
341 | struct stmpe_adc *info = iio_priv(indio_dev); | ||
342 | |||
343 | stmpe_adc_init_hw(info); | ||
344 | |||
345 | return 0; | ||
346 | } | ||
347 | |||
348 | static SIMPLE_DEV_PM_OPS(stmpe_adc_pm_ops, NULL, stmpe_adc_resume); | ||
349 | |||
350 | static struct platform_driver stmpe_adc_driver = { | ||
351 | .probe = stmpe_adc_probe, | ||
352 | .driver = { | ||
353 | .name = "stmpe-adc", | ||
354 | .pm = &stmpe_adc_pm_ops, | ||
355 | }, | ||
356 | }; | ||
357 | |||
358 | module_platform_driver(stmpe_adc_driver); | ||
359 | |||
360 | MODULE_AUTHOR("Stefan Agner <stefan.agner@toradex.com>"); | ||
361 | MODULE_DESCRIPTION("STMPEXXX ADC driver"); | ||
362 | MODULE_LICENSE("GPL v2"); | ||
363 | MODULE_ALIAS("platform:stmpe-adc"); | ||
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index ca59a2be9bc5..279fb02a0f14 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -851,4 +851,15 @@ config INPUT_SC27XX_VIBRA | |||
851 | To compile this driver as a module, choose M here. The module will | 851 | To compile this driver as a module, choose M here. The module will |
852 | be called sc27xx_vibra. | 852 | be called sc27xx_vibra. |
853 | 853 | ||
854 | config INPUT_STPMIC1_ONKEY | ||
855 | tristate "STPMIC1 PMIC Onkey support" | ||
856 | depends on MFD_STPMIC1 | ||
857 | help | ||
858 | Say Y to enable support of onkey embedded into STPMIC1 PMIC. onkey | ||
859 | can be used to wakeup from low power modes and force a shut-down on | ||
860 | long press. | ||
861 | |||
862 | To compile this driver as a module, choose M here: the | ||
863 | module will be called stpmic1_onkey. | ||
864 | |||
854 | endif | 865 | endif |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index 9d0f9d1ff68f..1b44202ad8f7 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -71,6 +71,7 @@ obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o | |||
71 | obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o | 71 | obj-$(CONFIG_INPUT_SIRFSOC_ONKEY) += sirfsoc-onkey.o |
72 | obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o | 72 | obj-$(CONFIG_INPUT_SOC_BUTTON_ARRAY) += soc_button_array.o |
73 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o | 73 | obj-$(CONFIG_INPUT_SPARCSPKR) += sparcspkr.o |
74 | obj-$(CONFIG_INPUT_STPMIC1_ONKEY) += stpmic1_onkey.o | ||
74 | obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o | 75 | obj-$(CONFIG_INPUT_TPS65218_PWRBUTTON) += tps65218-pwrbutton.o |
75 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o | 76 | obj-$(CONFIG_INPUT_TWL4030_PWRBUTTON) += twl4030-pwrbutton.o |
76 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o | 77 | obj-$(CONFIG_INPUT_TWL4030_VIBRA) += twl4030-vibra.o |
@@ -81,3 +82,4 @@ obj-$(CONFIG_INPUT_WM831X_ON) += wm831x-on.o | |||
81 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o | 82 | obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND) += xen-kbdfront.o |
82 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o | 83 | obj-$(CONFIG_INPUT_YEALINK) += yealink.o |
83 | obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o | 84 | obj-$(CONFIG_INPUT_IDEAPAD_SLIDEBAR) += ideapad_slidebar.o |
85 | |||
diff --git a/drivers/input/misc/stpmic1_onkey.c b/drivers/input/misc/stpmic1_onkey.c new file mode 100644 index 000000000000..7b49c9997df7 --- /dev/null +++ b/drivers/input/misc/stpmic1_onkey.c | |||
@@ -0,0 +1,198 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (C) STMicroelectronics 2018 | ||
3 | // Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics. | ||
4 | |||
5 | #include <linux/input.h> | ||
6 | #include <linux/interrupt.h> | ||
7 | #include <linux/mfd/stpmic1.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/of.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/property.h> | ||
12 | #include <linux/regmap.h> | ||
13 | |||
14 | /** | ||
15 | * struct stpmic1_onkey - OnKey data | ||
16 | * @input_dev: pointer to input device | ||
17 | * @irq_falling: irq that we are hooked on to | ||
18 | * @irq_rising: irq that we are hooked on to | ||
19 | */ | ||
20 | struct stpmic1_onkey { | ||
21 | struct input_dev *input_dev; | ||
22 | int irq_falling; | ||
23 | int irq_rising; | ||
24 | }; | ||
25 | |||
26 | static irqreturn_t onkey_falling_irq(int irq, void *ponkey) | ||
27 | { | ||
28 | struct stpmic1_onkey *onkey = ponkey; | ||
29 | struct input_dev *input_dev = onkey->input_dev; | ||
30 | |||
31 | input_report_key(input_dev, KEY_POWER, 1); | ||
32 | pm_wakeup_event(input_dev->dev.parent, 0); | ||
33 | input_sync(input_dev); | ||
34 | |||
35 | return IRQ_HANDLED; | ||
36 | } | ||
37 | |||
38 | static irqreturn_t onkey_rising_irq(int irq, void *ponkey) | ||
39 | { | ||
40 | struct stpmic1_onkey *onkey = ponkey; | ||
41 | struct input_dev *input_dev = onkey->input_dev; | ||
42 | |||
43 | input_report_key(input_dev, KEY_POWER, 0); | ||
44 | pm_wakeup_event(input_dev->dev.parent, 0); | ||
45 | input_sync(input_dev); | ||
46 | |||
47 | return IRQ_HANDLED; | ||
48 | } | ||
49 | |||
50 | static int stpmic1_onkey_probe(struct platform_device *pdev) | ||
51 | { | ||
52 | struct stpmic1 *pmic = dev_get_drvdata(pdev->dev.parent); | ||
53 | struct device *dev = &pdev->dev; | ||
54 | struct input_dev *input_dev; | ||
55 | struct stpmic1_onkey *onkey; | ||
56 | unsigned int val, reg = 0; | ||
57 | int error; | ||
58 | |||
59 | onkey = devm_kzalloc(dev, sizeof(*onkey), GFP_KERNEL); | ||
60 | if (!onkey) | ||
61 | return -ENOMEM; | ||
62 | |||
63 | onkey->irq_falling = platform_get_irq_byname(pdev, "onkey-falling"); | ||
64 | if (onkey->irq_falling < 0) { | ||
65 | dev_err(dev, "failed: request IRQ onkey-falling %d\n", | ||
66 | onkey->irq_falling); | ||
67 | return onkey->irq_falling; | ||
68 | } | ||
69 | |||
70 | onkey->irq_rising = platform_get_irq_byname(pdev, "onkey-rising"); | ||
71 | if (onkey->irq_rising < 0) { | ||
72 | dev_err(dev, "failed: request IRQ onkey-rising %d\n", | ||
73 | onkey->irq_rising); | ||
74 | return onkey->irq_rising; | ||
75 | } | ||
76 | |||
77 | if (!device_property_read_u32(dev, "power-off-time-sec", &val)) { | ||
78 | if (val > 0 && val <= 16) { | ||
79 | dev_dbg(dev, "power-off-time=%d seconds\n", val); | ||
80 | reg |= PONKEY_PWR_OFF; | ||
81 | reg |= ((16 - val) & PONKEY_TURNOFF_TIMER_MASK); | ||
82 | } else { | ||
83 | dev_err(dev, "power-off-time-sec out of range\n"); | ||
84 | return -EINVAL; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | if (device_property_present(dev, "st,onkey-clear-cc-flag")) | ||
89 | reg |= PONKEY_CC_FLAG_CLEAR; | ||
90 | |||
91 | error = regmap_update_bits(pmic->regmap, PKEY_TURNOFF_CR, | ||
92 | PONKEY_TURNOFF_MASK, reg); | ||
93 | if (error) { | ||
94 | dev_err(dev, "PKEY_TURNOFF_CR write failed: %d\n", error); | ||
95 | return error; | ||
96 | } | ||
97 | |||
98 | if (device_property_present(dev, "st,onkey-pu-inactive")) { | ||
99 | error = regmap_update_bits(pmic->regmap, PADS_PULL_CR, | ||
100 | PONKEY_PU_INACTIVE, | ||
101 | PONKEY_PU_INACTIVE); | ||
102 | if (error) { | ||
103 | dev_err(dev, "ONKEY Pads configuration failed: %d\n", | ||
104 | error); | ||
105 | return error; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | input_dev = devm_input_allocate_device(dev); | ||
110 | if (!input_dev) { | ||
111 | dev_err(dev, "Can't allocate Pwr Onkey Input Device\n"); | ||
112 | return -ENOMEM; | ||
113 | } | ||
114 | |||
115 | input_dev->name = "pmic_onkey"; | ||
116 | input_dev->phys = "pmic_onkey/input0"; | ||
117 | |||
118 | input_set_capability(input_dev, EV_KEY, KEY_POWER); | ||
119 | |||
120 | onkey->input_dev = input_dev; | ||
121 | |||
122 | /* interrupt is nested in a thread */ | ||
123 | error = devm_request_threaded_irq(dev, onkey->irq_falling, NULL, | ||
124 | onkey_falling_irq, IRQF_ONESHOT, | ||
125 | dev_name(dev), onkey); | ||
126 | if (error) { | ||
127 | dev_err(dev, "Can't get IRQ Onkey Falling: %d\n", error); | ||
128 | return error; | ||
129 | } | ||
130 | |||
131 | error = devm_request_threaded_irq(dev, onkey->irq_rising, NULL, | ||
132 | onkey_rising_irq, IRQF_ONESHOT, | ||
133 | dev_name(dev), onkey); | ||
134 | if (error) { | ||
135 | dev_err(dev, "Can't get IRQ Onkey Rising: %d\n", error); | ||
136 | return error; | ||
137 | } | ||
138 | |||
139 | error = input_register_device(input_dev); | ||
140 | if (error) { | ||
141 | dev_err(dev, "Can't register power button: %d\n", error); | ||
142 | return error; | ||
143 | } | ||
144 | |||
145 | platform_set_drvdata(pdev, onkey); | ||
146 | device_init_wakeup(dev, true); | ||
147 | |||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static int __maybe_unused stpmic1_onkey_suspend(struct device *dev) | ||
152 | { | ||
153 | struct platform_device *pdev = to_platform_device(dev); | ||
154 | struct stpmic1_onkey *onkey = platform_get_drvdata(pdev); | ||
155 | |||
156 | if (device_may_wakeup(dev)) { | ||
157 | enable_irq_wake(onkey->irq_falling); | ||
158 | enable_irq_wake(onkey->irq_rising); | ||
159 | } | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int __maybe_unused stpmic1_onkey_resume(struct device *dev) | ||
164 | { | ||
165 | struct platform_device *pdev = to_platform_device(dev); | ||
166 | struct stpmic1_onkey *onkey = platform_get_drvdata(pdev); | ||
167 | |||
168 | if (device_may_wakeup(dev)) { | ||
169 | disable_irq_wake(onkey->irq_falling); | ||
170 | disable_irq_wake(onkey->irq_rising); | ||
171 | } | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static SIMPLE_DEV_PM_OPS(stpmic1_onkey_pm, | ||
176 | stpmic1_onkey_suspend, | ||
177 | stpmic1_onkey_resume); | ||
178 | |||
179 | static const struct of_device_id of_stpmic1_onkey_match[] = { | ||
180 | { .compatible = "st,stpmic1-onkey" }, | ||
181 | { }, | ||
182 | }; | ||
183 | |||
184 | MODULE_DEVICE_TABLE(of, of_stpmic1_onkey_match); | ||
185 | |||
186 | static struct platform_driver stpmic1_onkey_driver = { | ||
187 | .probe = stpmic1_onkey_probe, | ||
188 | .driver = { | ||
189 | .name = "stpmic1_onkey", | ||
190 | .of_match_table = of_match_ptr(of_stpmic1_onkey_match), | ||
191 | .pm = &stpmic1_onkey_pm, | ||
192 | }, | ||
193 | }; | ||
194 | module_platform_driver(stpmic1_onkey_driver); | ||
195 | |||
196 | MODULE_DESCRIPTION("Onkey driver for STPMIC1"); | ||
197 | MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>"); | ||
198 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/input/touchscreen/stmpe-ts.c b/drivers/input/touchscreen/stmpe-ts.c index 2a78e27b4495..cf9c9aa39f6e 100644 --- a/drivers/input/touchscreen/stmpe-ts.c +++ b/drivers/input/touchscreen/stmpe-ts.c | |||
@@ -30,8 +30,6 @@ | |||
30 | * with touchscreen controller | 30 | * with touchscreen controller |
31 | */ | 31 | */ |
32 | #define STMPE_REG_INT_STA 0x0B | 32 | #define STMPE_REG_INT_STA 0x0B |
33 | #define STMPE_REG_ADC_CTRL1 0x20 | ||
34 | #define STMPE_REG_ADC_CTRL2 0x21 | ||
35 | #define STMPE_REG_TSC_CTRL 0x40 | 33 | #define STMPE_REG_TSC_CTRL 0x40 |
36 | #define STMPE_REG_TSC_CFG 0x41 | 34 | #define STMPE_REG_TSC_CFG 0x41 |
37 | #define STMPE_REG_FIFO_TH 0x4A | 35 | #define STMPE_REG_FIFO_TH 0x4A |
@@ -49,17 +47,6 @@ | |||
49 | 47 | ||
50 | #define STMPE_IRQ_TOUCH_DET 0 | 48 | #define STMPE_IRQ_TOUCH_DET 0 |
51 | 49 | ||
52 | #define SAMPLE_TIME(x) ((x & 0xf) << 4) | ||
53 | #define MOD_12B(x) ((x & 0x1) << 3) | ||
54 | #define REF_SEL(x) ((x & 0x1) << 1) | ||
55 | #define ADC_FREQ(x) (x & 0x3) | ||
56 | #define AVE_CTRL(x) ((x & 0x3) << 6) | ||
57 | #define DET_DELAY(x) ((x & 0x7) << 3) | ||
58 | #define SETTLING(x) (x & 0x7) | ||
59 | #define FRACTION_Z(x) (x & 0x7) | ||
60 | #define I_DRIVE(x) (x & 0x1) | ||
61 | #define OP_MODE(x) ((x & 0x7) << 1) | ||
62 | |||
63 | #define STMPE_TS_NAME "stmpe-ts" | 50 | #define STMPE_TS_NAME "stmpe-ts" |
64 | #define XY_MASK 0xfff | 51 | #define XY_MASK 0xfff |
65 | 52 | ||
@@ -69,15 +56,6 @@ | |||
69 | * @idev: registered input device | 56 | * @idev: registered input device |
70 | * @work: a work item used to scan the device | 57 | * @work: a work item used to scan the device |
71 | * @dev: a pointer back to the MFD cell struct device* | 58 | * @dev: a pointer back to the MFD cell struct device* |
72 | * @sample_time: ADC converstion time in number of clock. | ||
73 | * (0 -> 36 clocks, 1 -> 44 clocks, 2 -> 56 clocks, 3 -> 64 clocks, | ||
74 | * 4 -> 80 clocks, 5 -> 96 clocks, 6 -> 144 clocks), | ||
75 | * recommended is 4. | ||
76 | * @mod_12b: ADC Bit mode (0 -> 10bit ADC, 1 -> 12bit ADC) | ||
77 | * @ref_sel: ADC reference source | ||
78 | * (0 -> internal reference, 1 -> external reference) | ||
79 | * @adc_freq: ADC Clock speed | ||
80 | * (0 -> 1.625 MHz, 1 -> 3.25 MHz, 2 || 3 -> 6.5 MHz) | ||
81 | * @ave_ctrl: Sample average control | 59 | * @ave_ctrl: Sample average control |
82 | * (0 -> 1 sample, 1 -> 2 samples, 2 -> 4 samples, 3 -> 8 samples) | 60 | * (0 -> 1 sample, 1 -> 2 samples, 2 -> 4 samples, 3 -> 8 samples) |
83 | * @touch_det_delay: Touch detect interrupt delay | 61 | * @touch_det_delay: Touch detect interrupt delay |
@@ -99,10 +77,6 @@ struct stmpe_touch { | |||
99 | struct input_dev *idev; | 77 | struct input_dev *idev; |
100 | struct delayed_work work; | 78 | struct delayed_work work; |
101 | struct device *dev; | 79 | struct device *dev; |
102 | u8 sample_time; | ||
103 | u8 mod_12b; | ||
104 | u8 ref_sel; | ||
105 | u8 adc_freq; | ||
106 | u8 ave_ctrl; | 80 | u8 ave_ctrl; |
107 | u8 touch_det_delay; | 81 | u8 touch_det_delay; |
108 | u8 settling; | 82 | u8 settling; |
@@ -203,7 +177,7 @@ static irqreturn_t stmpe_ts_handler(int irq, void *data) | |||
203 | static int stmpe_init_hw(struct stmpe_touch *ts) | 177 | static int stmpe_init_hw(struct stmpe_touch *ts) |
204 | { | 178 | { |
205 | int ret; | 179 | int ret; |
206 | u8 adc_ctrl1, adc_ctrl1_mask, tsc_cfg, tsc_cfg_mask; | 180 | u8 tsc_cfg, tsc_cfg_mask; |
207 | struct stmpe *stmpe = ts->stmpe; | 181 | struct stmpe *stmpe = ts->stmpe; |
208 | struct device *dev = ts->dev; | 182 | struct device *dev = ts->dev; |
209 | 183 | ||
@@ -213,27 +187,17 @@ static int stmpe_init_hw(struct stmpe_touch *ts) | |||
213 | return ret; | 187 | return ret; |
214 | } | 188 | } |
215 | 189 | ||
216 | adc_ctrl1 = SAMPLE_TIME(ts->sample_time) | MOD_12B(ts->mod_12b) | | 190 | ret = stmpe811_adc_common_init(stmpe); |
217 | REF_SEL(ts->ref_sel); | ||
218 | adc_ctrl1_mask = SAMPLE_TIME(0xff) | MOD_12B(0xff) | REF_SEL(0xff); | ||
219 | |||
220 | ret = stmpe_set_bits(stmpe, STMPE_REG_ADC_CTRL1, | ||
221 | adc_ctrl1_mask, adc_ctrl1); | ||
222 | if (ret) { | ||
223 | dev_err(dev, "Could not setup ADC\n"); | ||
224 | return ret; | ||
225 | } | ||
226 | |||
227 | ret = stmpe_set_bits(stmpe, STMPE_REG_ADC_CTRL2, | ||
228 | ADC_FREQ(0xff), ADC_FREQ(ts->adc_freq)); | ||
229 | if (ret) { | 191 | if (ret) { |
230 | dev_err(dev, "Could not setup ADC\n"); | 192 | stmpe_disable(stmpe, STMPE_BLOCK_TOUCHSCREEN | STMPE_BLOCK_ADC); |
231 | return ret; | 193 | return ret; |
232 | } | 194 | } |
233 | 195 | ||
234 | tsc_cfg = AVE_CTRL(ts->ave_ctrl) | DET_DELAY(ts->touch_det_delay) | | 196 | tsc_cfg = STMPE_AVE_CTRL(ts->ave_ctrl) | |
235 | SETTLING(ts->settling); | 197 | STMPE_DET_DELAY(ts->touch_det_delay) | |
236 | tsc_cfg_mask = AVE_CTRL(0xff) | DET_DELAY(0xff) | SETTLING(0xff); | 198 | STMPE_SETTLING(ts->settling); |
199 | tsc_cfg_mask = STMPE_AVE_CTRL(0xff) | STMPE_DET_DELAY(0xff) | | ||
200 | STMPE_SETTLING(0xff); | ||
237 | 201 | ||
238 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CFG, tsc_cfg_mask, tsc_cfg); | 202 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CFG, tsc_cfg_mask, tsc_cfg); |
239 | if (ret) { | 203 | if (ret) { |
@@ -242,14 +206,14 @@ static int stmpe_init_hw(struct stmpe_touch *ts) | |||
242 | } | 206 | } |
243 | 207 | ||
244 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_FRACTION_Z, | 208 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_FRACTION_Z, |
245 | FRACTION_Z(0xff), FRACTION_Z(ts->fraction_z)); | 209 | STMPE_FRACTION_Z(0xff), STMPE_FRACTION_Z(ts->fraction_z)); |
246 | if (ret) { | 210 | if (ret) { |
247 | dev_err(dev, "Could not config touch\n"); | 211 | dev_err(dev, "Could not config touch\n"); |
248 | return ret; | 212 | return ret; |
249 | } | 213 | } |
250 | 214 | ||
251 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_I_DRIVE, | 215 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_I_DRIVE, |
252 | I_DRIVE(0xff), I_DRIVE(ts->i_drive)); | 216 | STMPE_I_DRIVE(0xff), STMPE_I_DRIVE(ts->i_drive)); |
253 | if (ret) { | 217 | if (ret) { |
254 | dev_err(dev, "Could not config touch\n"); | 218 | dev_err(dev, "Could not config touch\n"); |
255 | return ret; | 219 | return ret; |
@@ -263,7 +227,7 @@ static int stmpe_init_hw(struct stmpe_touch *ts) | |||
263 | } | 227 | } |
264 | 228 | ||
265 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CTRL, | 229 | ret = stmpe_set_bits(stmpe, STMPE_REG_TSC_CTRL, |
266 | OP_MODE(0xff), OP_MODE(OP_MOD_XYZ)); | 230 | STMPE_OP_MODE(0xff), STMPE_OP_MODE(OP_MOD_XYZ)); |
267 | if (ret) { | 231 | if (ret) { |
268 | dev_err(dev, "Could not set mode\n"); | 232 | dev_err(dev, "Could not set mode\n"); |
269 | return ret; | 233 | return ret; |
@@ -303,13 +267,13 @@ static void stmpe_ts_get_platform_info(struct platform_device *pdev, | |||
303 | 267 | ||
304 | if (np) { | 268 | if (np) { |
305 | if (!of_property_read_u32(np, "st,sample-time", &val)) | 269 | if (!of_property_read_u32(np, "st,sample-time", &val)) |
306 | ts->sample_time = val; | 270 | ts->stmpe->sample_time = val; |
307 | if (!of_property_read_u32(np, "st,mod-12b", &val)) | 271 | if (!of_property_read_u32(np, "st,mod-12b", &val)) |
308 | ts->mod_12b = val; | 272 | ts->stmpe->mod_12b = val; |
309 | if (!of_property_read_u32(np, "st,ref-sel", &val)) | 273 | if (!of_property_read_u32(np, "st,ref-sel", &val)) |
310 | ts->ref_sel = val; | 274 | ts->stmpe->ref_sel = val; |
311 | if (!of_property_read_u32(np, "st,adc-freq", &val)) | 275 | if (!of_property_read_u32(np, "st,adc-freq", &val)) |
312 | ts->adc_freq = val; | 276 | ts->stmpe->adc_freq = val; |
313 | if (!of_property_read_u32(np, "st,ave-ctrl", &val)) | 277 | if (!of_property_read_u32(np, "st,ave-ctrl", &val)) |
314 | ts->ave_ctrl = val; | 278 | ts->ave_ctrl = val; |
315 | if (!of_property_read_u32(np, "st,touch-det-delay", &val)) | 279 | if (!of_property_read_u32(np, "st,touch-det-delay", &val)) |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 76f9909cf396..1b50fa955992 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -215,7 +215,6 @@ config MFD_CROS_EC | |||
215 | config MFD_CROS_EC_CHARDEV | 215 | config MFD_CROS_EC_CHARDEV |
216 | tristate "Chrome OS Embedded Controller userspace device interface" | 216 | tristate "Chrome OS Embedded Controller userspace device interface" |
217 | depends on MFD_CROS_EC | 217 | depends on MFD_CROS_EC |
218 | select CROS_EC_CTL | ||
219 | ---help--- | 218 | ---help--- |
220 | This driver adds support to talk with the ChromeOS EC from userspace. | 219 | This driver adds support to talk with the ChromeOS EC from userspace. |
221 | 220 | ||
@@ -519,10 +518,10 @@ config INTEL_SOC_PMIC | |||
519 | bool "Support for Crystal Cove PMIC" | 518 | bool "Support for Crystal Cove PMIC" |
520 | depends on ACPI && HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK | 519 | depends on ACPI && HAS_IOMEM && I2C=y && GPIOLIB && COMMON_CLK |
521 | depends on X86 || COMPILE_TEST | 520 | depends on X86 || COMPILE_TEST |
521 | depends on I2C_DESIGNWARE_PLATFORM=y | ||
522 | select MFD_CORE | 522 | select MFD_CORE |
523 | select REGMAP_I2C | 523 | select REGMAP_I2C |
524 | select REGMAP_IRQ | 524 | select REGMAP_IRQ |
525 | select I2C_DESIGNWARE_PLATFORM | ||
526 | help | 525 | help |
527 | Select this option to enable support for Crystal Cove PMIC | 526 | Select this option to enable support for Crystal Cove PMIC |
528 | on some Intel SoC systems. The PMIC provides ADC, GPIO, | 527 | on some Intel SoC systems. The PMIC provides ADC, GPIO, |
@@ -548,10 +547,10 @@ config INTEL_SOC_PMIC_CHTWC | |||
548 | bool "Support for Intel Cherry Trail Whiskey Cove PMIC" | 547 | bool "Support for Intel Cherry Trail Whiskey Cove PMIC" |
549 | depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK | 548 | depends on ACPI && HAS_IOMEM && I2C=y && COMMON_CLK |
550 | depends on X86 || COMPILE_TEST | 549 | depends on X86 || COMPILE_TEST |
550 | depends on I2C_DESIGNWARE_PLATFORM=y | ||
551 | select MFD_CORE | 551 | select MFD_CORE |
552 | select REGMAP_I2C | 552 | select REGMAP_I2C |
553 | select REGMAP_IRQ | 553 | select REGMAP_IRQ |
554 | select I2C_DESIGNWARE_PLATFORM | ||
555 | help | 554 | help |
556 | Select this option to enable support for the Intel Cherry Trail | 555 | Select this option to enable support for the Intel Cherry Trail |
557 | Whiskey Cove PMIC found on some Intel Cherry Trail systems. | 556 | Whiskey Cove PMIC found on some Intel Cherry Trail systems. |
@@ -1205,7 +1204,7 @@ config MFD_STMPE | |||
1205 | 1204 | ||
1206 | Currently supported devices are: | 1205 | Currently supported devices are: |
1207 | 1206 | ||
1208 | STMPE811: GPIO, Touchscreen | 1207 | STMPE811: GPIO, Touchscreen, ADC |
1209 | STMPE1601: GPIO, Keypad | 1208 | STMPE1601: GPIO, Keypad |
1210 | STMPE1801: GPIO, Keypad | 1209 | STMPE1801: GPIO, Keypad |
1211 | STMPE2401: GPIO, Keypad | 1210 | STMPE2401: GPIO, Keypad |
@@ -1218,6 +1217,7 @@ config MFD_STMPE | |||
1218 | GPIO: stmpe-gpio | 1217 | GPIO: stmpe-gpio |
1219 | Keypad: stmpe-keypad | 1218 | Keypad: stmpe-keypad |
1220 | Touchscreen: stmpe-ts | 1219 | Touchscreen: stmpe-ts |
1220 | ADC: stmpe-adc | ||
1221 | 1221 | ||
1222 | menu "STMicroelectronics STMPE Interface Drivers" | 1222 | menu "STMicroelectronics STMPE Interface Drivers" |
1223 | depends on MFD_STMPE | 1223 | depends on MFD_STMPE |
@@ -1420,9 +1420,9 @@ config MFD_TPS65217 | |||
1420 | config MFD_TPS68470 | 1420 | config MFD_TPS68470 |
1421 | bool "TI TPS68470 Power Management / LED chips" | 1421 | bool "TI TPS68470 Power Management / LED chips" |
1422 | depends on ACPI && PCI && I2C=y | 1422 | depends on ACPI && PCI && I2C=y |
1423 | depends on I2C_DESIGNWARE_PLATFORM=y | ||
1423 | select MFD_CORE | 1424 | select MFD_CORE |
1424 | select REGMAP_I2C | 1425 | select REGMAP_I2C |
1425 | select I2C_DESIGNWARE_PLATFORM | ||
1426 | help | 1426 | help |
1427 | If you say yes here you get support for the TPS68470 series of | 1427 | If you say yes here you get support for the TPS68470 series of |
1428 | Power Management / LED chips. | 1428 | Power Management / LED chips. |
@@ -1677,6 +1677,14 @@ config MFD_TC6393XB | |||
1677 | help | 1677 | help |
1678 | Support for Toshiba Mobile IO Controller TC6393XB | 1678 | Support for Toshiba Mobile IO Controller TC6393XB |
1679 | 1679 | ||
1680 | config MFD_TQMX86 | ||
1681 | tristate "TQ-Systems IO controller TQMX86" | ||
1682 | select MFD_CORE | ||
1683 | help | ||
1684 | Say yes here to enable support for various functions of the | ||
1685 | TQ-Systems IO controller and watchdog device, found on their | ||
1686 | ComExpress CPU modules. | ||
1687 | |||
1680 | config MFD_VX855 | 1688 | config MFD_VX855 |
1681 | tristate "VIA VX855/VX875 integrated south bridge" | 1689 | tristate "VIA VX855/VX875 integrated south bridge" |
1682 | depends on PCI | 1690 | depends on PCI |
@@ -1686,6 +1694,14 @@ config MFD_VX855 | |||
1686 | VIA VX855/VX875 south bridge. You will need to enable the vx855_spi | 1694 | VIA VX855/VX875 south bridge. You will need to enable the vx855_spi |
1687 | and/or vx855_gpio drivers for this to do anything useful. | 1695 | and/or vx855_gpio drivers for this to do anything useful. |
1688 | 1696 | ||
1697 | config MFD_LOCHNAGAR | ||
1698 | bool "Cirrus Logic Lochnagar Audio Development Board" | ||
1699 | select MFD_CORE | ||
1700 | select REGMAP_I2C | ||
1701 | depends on I2C=y && OF | ||
1702 | help | ||
1703 | Support for Cirrus Logic Lochnagar audio development board. | ||
1704 | |||
1689 | config MFD_ARIZONA | 1705 | config MFD_ARIZONA |
1690 | select REGMAP | 1706 | select REGMAP |
1691 | select REGMAP_IRQ | 1707 | select REGMAP_IRQ |
@@ -1872,6 +1888,22 @@ config MFD_STM32_TIMERS | |||
1872 | for PWM and IIO Timer. This driver allow to share the | 1888 | for PWM and IIO Timer. This driver allow to share the |
1873 | registers between the others drivers. | 1889 | registers between the others drivers. |
1874 | 1890 | ||
1891 | config MFD_STPMIC1 | ||
1892 | tristate "Support for STPMIC1 PMIC" | ||
1893 | depends on (I2C=y && OF) | ||
1894 | select REGMAP_I2C | ||
1895 | select REGMAP_IRQ | ||
1896 | select MFD_CORE | ||
1897 | help | ||
1898 | Support for ST Microelectronics STPMIC1 PMIC. STPMIC1 has power on | ||
1899 | key, watchdog and regulator functionalities which are supported via | ||
1900 | the relevant subsystems. This driver provides core support for the | ||
1901 | STPMIC1. In order to use the actual functionaltiy of the device other | ||
1902 | drivers must be enabled. | ||
1903 | |||
1904 | To compile this driver as a module, choose M here: the | ||
1905 | module will be called stpmic1. | ||
1906 | |||
1875 | menu "Multimedia Capabilities Port drivers" | 1907 | menu "Multimedia Capabilities Port drivers" |
1876 | depends on ARCH_SA1100 | 1908 | depends on ARCH_SA1100 |
1877 | 1909 | ||
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index ee6fb6af655e..b4569ed7f3f3 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -37,6 +37,9 @@ obj-$(CONFIG_MFD_TC3589X) += tc3589x.o | |||
37 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o | 37 | obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o |
38 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o | 38 | obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o |
39 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o | 39 | obj-$(CONFIG_MFD_TC6393XB) += tc6393xb.o tmio_core.o |
40 | obj-$(CONFIG_MFD_TQMX86) += tqmx86.o | ||
41 | |||
42 | obj-$(CONFIG_MFD_LOCHNAGAR) += lochnagar-i2c.o | ||
40 | 43 | ||
41 | obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o | 44 | obj-$(CONFIG_MFD_ARIZONA) += arizona-core.o |
42 | obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o | 45 | obj-$(CONFIG_MFD_ARIZONA) += arizona-irq.o |
@@ -234,6 +237,7 @@ obj-$(CONFIG_INTEL_SOC_PMIC_CHTDC_TI) += intel_soc_pmic_chtdc_ti.o | |||
234 | obj-$(CONFIG_MFD_MT6397) += mt6397-core.o | 237 | obj-$(CONFIG_MFD_MT6397) += mt6397-core.o |
235 | 238 | ||
236 | obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o | 239 | obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o |
240 | obj-$(CONFIG_MFD_STPMIC1) += stpmic1.o | ||
237 | obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o | 241 | obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o |
238 | 242 | ||
239 | obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o | 243 | obj-$(CONFIG_MFD_STM32_LPTIMER) += stm32-lptimer.o |
diff --git a/drivers/mfd/aat2870-core.c b/drivers/mfd/aat2870-core.c index 3ba19a45f199..9d3d90d386c2 100644 --- a/drivers/mfd/aat2870-core.c +++ b/drivers/mfd/aat2870-core.c | |||
@@ -20,7 +20,6 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | 23 | #include <linux/init.h> |
25 | #include <linux/debugfs.h> | 24 | #include <linux/debugfs.h> |
26 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
@@ -349,18 +348,10 @@ static void aat2870_init_debugfs(struct aat2870_data *aat2870) | |||
349 | "Failed to create debugfs register file\n"); | 348 | "Failed to create debugfs register file\n"); |
350 | } | 349 | } |
351 | 350 | ||
352 | static void aat2870_uninit_debugfs(struct aat2870_data *aat2870) | ||
353 | { | ||
354 | debugfs_remove_recursive(aat2870->dentry_root); | ||
355 | } | ||
356 | #else | 351 | #else |
357 | static inline void aat2870_init_debugfs(struct aat2870_data *aat2870) | 352 | static inline void aat2870_init_debugfs(struct aat2870_data *aat2870) |
358 | { | 353 | { |
359 | } | 354 | } |
360 | |||
361 | static inline void aat2870_uninit_debugfs(struct aat2870_data *aat2870) | ||
362 | { | ||
363 | } | ||
364 | #endif /* CONFIG_DEBUG_FS */ | 355 | #endif /* CONFIG_DEBUG_FS */ |
365 | 356 | ||
366 | static int aat2870_i2c_probe(struct i2c_client *client, | 357 | static int aat2870_i2c_probe(struct i2c_client *client, |
@@ -440,20 +431,6 @@ out_disable: | |||
440 | return ret; | 431 | return ret; |
441 | } | 432 | } |
442 | 433 | ||
443 | static int aat2870_i2c_remove(struct i2c_client *client) | ||
444 | { | ||
445 | struct aat2870_data *aat2870 = i2c_get_clientdata(client); | ||
446 | |||
447 | aat2870_uninit_debugfs(aat2870); | ||
448 | |||
449 | mfd_remove_devices(aat2870->dev); | ||
450 | aat2870_disable(aat2870); | ||
451 | if (aat2870->uninit) | ||
452 | aat2870->uninit(aat2870); | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | #ifdef CONFIG_PM_SLEEP | 434 | #ifdef CONFIG_PM_SLEEP |
458 | static int aat2870_i2c_suspend(struct device *dev) | 435 | static int aat2870_i2c_suspend(struct device *dev) |
459 | { | 436 | { |
@@ -492,15 +469,14 @@ static const struct i2c_device_id aat2870_i2c_id_table[] = { | |||
492 | { "aat2870", 0 }, | 469 | { "aat2870", 0 }, |
493 | { } | 470 | { } |
494 | }; | 471 | }; |
495 | MODULE_DEVICE_TABLE(i2c, aat2870_i2c_id_table); | ||
496 | 472 | ||
497 | static struct i2c_driver aat2870_i2c_driver = { | 473 | static struct i2c_driver aat2870_i2c_driver = { |
498 | .driver = { | 474 | .driver = { |
499 | .name = "aat2870", | 475 | .name = "aat2870", |
500 | .pm = &aat2870_pm_ops, | 476 | .pm = &aat2870_pm_ops, |
477 | .suppress_bind_attrs = true, | ||
501 | }, | 478 | }, |
502 | .probe = aat2870_i2c_probe, | 479 | .probe = aat2870_i2c_probe, |
503 | .remove = aat2870_i2c_remove, | ||
504 | .id_table = aat2870_i2c_id_table, | 480 | .id_table = aat2870_i2c_id_table, |
505 | }; | 481 | }; |
506 | 482 | ||
@@ -509,13 +485,3 @@ static int __init aat2870_init(void) | |||
509 | return i2c_add_driver(&aat2870_i2c_driver); | 485 | return i2c_add_driver(&aat2870_i2c_driver); |
510 | } | 486 | } |
511 | subsys_initcall(aat2870_init); | 487 | subsys_initcall(aat2870_init); |
512 | |||
513 | static void __exit aat2870_exit(void) | ||
514 | { | ||
515 | i2c_del_driver(&aat2870_i2c_driver); | ||
516 | } | ||
517 | module_exit(aat2870_exit); | ||
518 | |||
519 | MODULE_DESCRIPTION("Core support for the AnalogicTech AAT2870"); | ||
520 | MODULE_LICENSE("GPL"); | ||
521 | MODULE_AUTHOR("Jin Park <jinyoungp@nvidia.com>"); | ||
diff --git a/drivers/mfd/adp5520.c b/drivers/mfd/adp5520.c index be0497b96720..2cdd39cb8a18 100644 --- a/drivers/mfd/adp5520.c +++ b/drivers/mfd/adp5520.c | |||
@@ -7,6 +7,8 @@ | |||
7 | * | 7 | * |
8 | * Copyright 2009 Analog Devices Inc. | 8 | * Copyright 2009 Analog Devices Inc. |
9 | * | 9 | * |
10 | * Author: Michael Hennerich <michael.hennerich@analog.com> | ||
11 | * | ||
10 | * Derived from da903x: | 12 | * Derived from da903x: |
11 | * Copyright (C) 2008 Compulab, Ltd. | 13 | * Copyright (C) 2008 Compulab, Ltd. |
12 | * Mike Rapoport <mike@compulab.co.il> | 14 | * Mike Rapoport <mike@compulab.co.il> |
@@ -18,7 +20,7 @@ | |||
18 | */ | 20 | */ |
19 | 21 | ||
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 23 | #include <linux/init.h> |
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
24 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
@@ -304,18 +306,6 @@ out_free_irq: | |||
304 | return ret; | 306 | return ret; |
305 | } | 307 | } |
306 | 308 | ||
307 | static int adp5520_remove(struct i2c_client *client) | ||
308 | { | ||
309 | struct adp5520_chip *chip = dev_get_drvdata(&client->dev); | ||
310 | |||
311 | if (chip->irq) | ||
312 | free_irq(chip->irq, chip); | ||
313 | |||
314 | adp5520_remove_subdevs(chip); | ||
315 | adp5520_write(chip->dev, ADP5520_MODE_STATUS, 0); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
319 | #ifdef CONFIG_PM_SLEEP | 309 | #ifdef CONFIG_PM_SLEEP |
320 | static int adp5520_suspend(struct device *dev) | 310 | static int adp5520_suspend(struct device *dev) |
321 | { | 311 | { |
@@ -346,20 +336,14 @@ static const struct i2c_device_id adp5520_id[] = { | |||
346 | { "pmic-adp5501", ID_ADP5501 }, | 336 | { "pmic-adp5501", ID_ADP5501 }, |
347 | { } | 337 | { } |
348 | }; | 338 | }; |
349 | MODULE_DEVICE_TABLE(i2c, adp5520_id); | ||
350 | 339 | ||
351 | static struct i2c_driver adp5520_driver = { | 340 | static struct i2c_driver adp5520_driver = { |
352 | .driver = { | 341 | .driver = { |
353 | .name = "adp5520", | 342 | .name = "adp5520", |
354 | .pm = &adp5520_pm, | 343 | .pm = &adp5520_pm, |
344 | .suppress_bind_attrs = true, | ||
355 | }, | 345 | }, |
356 | .probe = adp5520_probe, | 346 | .probe = adp5520_probe, |
357 | .remove = adp5520_remove, | ||
358 | .id_table = adp5520_id, | 347 | .id_table = adp5520_id, |
359 | }; | 348 | }; |
360 | 349 | builtin_i2c_driver(adp5520_driver); | |
361 | module_i2c_driver(adp5520_driver); | ||
362 | |||
363 | MODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>"); | ||
364 | MODULE_DESCRIPTION("ADP5520(01) PMIC-MFD Driver"); | ||
365 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/as3711.c b/drivers/mfd/as3711.c index 67b12417585d..7a74a874b93c 100644 --- a/drivers/mfd/as3711.c +++ b/drivers/mfd/as3711.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/mfd/as3711.h> | 17 | #include <linux/mfd/as3711.h> |
18 | #include <linux/mfd/core.h> | 18 | #include <linux/mfd/core.h> |
19 | #include <linux/module.h> | ||
20 | #include <linux/of.h> | 19 | #include <linux/of.h> |
21 | #include <linux/regmap.h> | 20 | #include <linux/regmap.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
@@ -118,7 +117,6 @@ static const struct of_device_id as3711_of_match[] = { | |||
118 | {.compatible = "ams,as3711",}, | 117 | {.compatible = "ams,as3711",}, |
119 | {} | 118 | {} |
120 | }; | 119 | }; |
121 | MODULE_DEVICE_TABLE(of, as3711_of_match); | ||
122 | #endif | 120 | #endif |
123 | 121 | ||
124 | static int as3711_i2c_probe(struct i2c_client *client, | 122 | static int as3711_i2c_probe(struct i2c_client *client, |
@@ -202,8 +200,6 @@ static const struct i2c_device_id as3711_i2c_id[] = { | |||
202 | {} | 200 | {} |
203 | }; | 201 | }; |
204 | 202 | ||
205 | MODULE_DEVICE_TABLE(i2c, as3711_i2c_id); | ||
206 | |||
207 | static struct i2c_driver as3711_i2c_driver = { | 203 | static struct i2c_driver as3711_i2c_driver = { |
208 | .driver = { | 204 | .driver = { |
209 | .name = "as3711", | 205 | .name = "as3711", |
@@ -219,13 +215,3 @@ static int __init as3711_i2c_init(void) | |||
219 | } | 215 | } |
220 | /* Initialise early */ | 216 | /* Initialise early */ |
221 | subsys_initcall(as3711_i2c_init); | 217 | subsys_initcall(as3711_i2c_init); |
222 | |||
223 | static void __exit as3711_i2c_exit(void) | ||
224 | { | ||
225 | i2c_del_driver(&as3711_i2c_driver); | ||
226 | } | ||
227 | module_exit(as3711_i2c_exit); | ||
228 | |||
229 | MODULE_AUTHOR("Guennadi Liakhovetski <g.liakhovetski@gmx.de>"); | ||
230 | MODULE_DESCRIPTION("AS3711 PMIC driver"); | ||
231 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/at91-usart.c b/drivers/mfd/at91-usart.c index d20747f612c1..6a8351a4588e 100644 --- a/drivers/mfd/at91-usart.c +++ b/drivers/mfd/at91-usart.c | |||
@@ -15,29 +15,29 @@ | |||
15 | #include <linux/of.h> | 15 | #include <linux/of.h> |
16 | #include <linux/property.h> | 16 | #include <linux/property.h> |
17 | 17 | ||
18 | static struct mfd_cell at91_usart_spi_subdev = { | 18 | static const struct mfd_cell at91_usart_spi_subdev = { |
19 | .name = "at91_usart_spi", | 19 | .name = "at91_usart_spi", |
20 | .of_compatible = "microchip,at91sam9g45-usart-spi", | 20 | .of_compatible = "microchip,at91sam9g45-usart-spi", |
21 | }; | 21 | }; |
22 | 22 | ||
23 | static struct mfd_cell at91_usart_serial_subdev = { | 23 | static const struct mfd_cell at91_usart_serial_subdev = { |
24 | .name = "atmel_usart_serial", | 24 | .name = "atmel_usart_serial", |
25 | .of_compatible = "atmel,at91rm9200-usart-serial", | 25 | .of_compatible = "atmel,at91rm9200-usart-serial", |
26 | }; | 26 | }; |
27 | 27 | ||
28 | static int at91_usart_mode_probe(struct platform_device *pdev) | 28 | static int at91_usart_mode_probe(struct platform_device *pdev) |
29 | { | 29 | { |
30 | struct mfd_cell cell; | 30 | const struct mfd_cell *cell; |
31 | u32 opmode = AT91_USART_MODE_SERIAL; | 31 | u32 opmode = AT91_USART_MODE_SERIAL; |
32 | 32 | ||
33 | device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode); | 33 | device_property_read_u32(&pdev->dev, "atmel,usart-mode", &opmode); |
34 | 34 | ||
35 | switch (opmode) { | 35 | switch (opmode) { |
36 | case AT91_USART_MODE_SPI: | 36 | case AT91_USART_MODE_SPI: |
37 | cell = at91_usart_spi_subdev; | 37 | cell = &at91_usart_spi_subdev; |
38 | break; | 38 | break; |
39 | case AT91_USART_MODE_SERIAL: | 39 | case AT91_USART_MODE_SERIAL: |
40 | cell = at91_usart_serial_subdev; | 40 | cell = &at91_usart_serial_subdev; |
41 | break; | 41 | break; |
42 | default: | 42 | default: |
43 | dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n", | 43 | dev_err(&pdev->dev, "atmel,usart-mode has an invalid value %u\n", |
@@ -45,7 +45,7 @@ static int at91_usart_mode_probe(struct platform_device *pdev) | |||
45 | return -EINVAL; | 45 | return -EINVAL; |
46 | } | 46 | } |
47 | 47 | ||
48 | return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, &cell, 1, | 48 | return devm_mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, cell, 1, |
49 | NULL, 0, NULL); | 49 | NULL, 0, NULL); |
50 | } | 50 | } |
51 | 51 | ||
diff --git a/drivers/mfd/cros_ec.c b/drivers/mfd/cros_ec.c index fe6f83766144..6acfe036d522 100644 --- a/drivers/mfd/cros_ec.c +++ b/drivers/mfd/cros_ec.c | |||
@@ -129,8 +129,8 @@ int cros_ec_register(struct cros_ec_device *ec_dev) | |||
129 | } | 129 | } |
130 | } | 130 | } |
131 | 131 | ||
132 | err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1, | 132 | err = devm_mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, |
133 | NULL, ec_dev->irq, NULL); | 133 | 1, NULL, ec_dev->irq, NULL); |
134 | if (err) { | 134 | if (err) { |
135 | dev_err(dev, | 135 | dev_err(dev, |
136 | "Failed to register Embedded Controller subdevice %d\n", | 136 | "Failed to register Embedded Controller subdevice %d\n", |
@@ -147,7 +147,7 @@ int cros_ec_register(struct cros_ec_device *ec_dev) | |||
147 | * - the EC is responsive at init time (it is not true for a | 147 | * - the EC is responsive at init time (it is not true for a |
148 | * sensor hub. | 148 | * sensor hub. |
149 | */ | 149 | */ |
150 | err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, | 150 | err = devm_mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, |
151 | &ec_pd_cell, 1, NULL, ec_dev->irq, NULL); | 151 | &ec_pd_cell, 1, NULL, ec_dev->irq, NULL); |
152 | if (err) { | 152 | if (err) { |
153 | dev_err(dev, | 153 | dev_err(dev, |
@@ -181,14 +181,6 @@ int cros_ec_register(struct cros_ec_device *ec_dev) | |||
181 | } | 181 | } |
182 | EXPORT_SYMBOL(cros_ec_register); | 182 | EXPORT_SYMBOL(cros_ec_register); |
183 | 183 | ||
184 | int cros_ec_remove(struct cros_ec_device *ec_dev) | ||
185 | { | ||
186 | mfd_remove_devices(ec_dev->dev); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | EXPORT_SYMBOL(cros_ec_remove); | ||
191 | |||
192 | #ifdef CONFIG_PM_SLEEP | 184 | #ifdef CONFIG_PM_SLEEP |
193 | int cros_ec_suspend(struct cros_ec_device *ec_dev) | 185 | int cros_ec_suspend(struct cros_ec_device *ec_dev) |
194 | { | 186 | { |
diff --git a/drivers/mfd/cros_ec_dev.c b/drivers/mfd/cros_ec_dev.c index 2d0fee488c5a..d275deaecb12 100644 --- a/drivers/mfd/cros_ec_dev.c +++ b/drivers/mfd/cros_ec_dev.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/mfd/core.h> | 21 | #include <linux/mfd/core.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/mod_devicetable.h> | 23 | #include <linux/mod_devicetable.h> |
24 | #include <linux/of_platform.h> | ||
24 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
25 | #include <linux/pm.h> | 26 | #include <linux/pm.h> |
26 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
@@ -34,17 +35,9 @@ | |||
34 | #define CROS_MAX_DEV 128 | 35 | #define CROS_MAX_DEV 128 |
35 | static int ec_major; | 36 | static int ec_major; |
36 | 37 | ||
37 | static const struct attribute_group *cros_ec_groups[] = { | ||
38 | &cros_ec_attr_group, | ||
39 | &cros_ec_lightbar_attr_group, | ||
40 | &cros_ec_vbc_attr_group, | ||
41 | NULL, | ||
42 | }; | ||
43 | |||
44 | static struct class cros_class = { | 38 | static struct class cros_class = { |
45 | .owner = THIS_MODULE, | 39 | .owner = THIS_MODULE, |
46 | .name = "chromeos", | 40 | .name = "chromeos", |
47 | .dev_groups = cros_ec_groups, | ||
48 | }; | 41 | }; |
49 | 42 | ||
50 | /* Basic communication */ | 43 | /* Basic communication */ |
@@ -231,7 +224,7 @@ static long ec_device_ioctl_readmem(struct cros_ec_dev *ec, void __user *arg) | |||
231 | if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) | 224 | if (copy_to_user((void __user *)arg, &s_mem, sizeof(s_mem))) |
232 | return -EFAULT; | 225 | return -EFAULT; |
233 | 226 | ||
234 | return 0; | 227 | return num; |
235 | } | 228 | } |
236 | 229 | ||
237 | static long ec_device_ioctl(struct file *filp, unsigned int cmd, | 230 | static long ec_device_ioctl(struct file *filp, unsigned int cmd, |
@@ -395,9 +388,20 @@ static const struct mfd_cell cros_usbpd_charger_cells[] = { | |||
395 | { .name = "cros-usbpd-charger" } | 388 | { .name = "cros-usbpd-charger" } |
396 | }; | 389 | }; |
397 | 390 | ||
391 | static const struct mfd_cell cros_ec_platform_cells[] = { | ||
392 | { .name = "cros-ec-debugfs" }, | ||
393 | { .name = "cros-ec-lightbar" }, | ||
394 | { .name = "cros-ec-sysfs" }, | ||
395 | }; | ||
396 | |||
397 | static const struct mfd_cell cros_ec_vbc_cells[] = { | ||
398 | { .name = "cros-ec-vbc" } | ||
399 | }; | ||
400 | |||
398 | static int ec_device_probe(struct platform_device *pdev) | 401 | static int ec_device_probe(struct platform_device *pdev) |
399 | { | 402 | { |
400 | int retval = -ENOMEM; | 403 | int retval = -ENOMEM; |
404 | struct device_node *node; | ||
401 | struct device *dev = &pdev->dev; | 405 | struct device *dev = &pdev->dev; |
402 | struct cros_ec_platform *ec_platform = dev_get_platdata(dev); | 406 | struct cros_ec_platform *ec_platform = dev_get_platdata(dev); |
403 | struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); | 407 | struct cros_ec_dev *ec = kzalloc(sizeof(*ec), GFP_KERNEL); |
@@ -470,9 +474,6 @@ static int ec_device_probe(struct platform_device *pdev) | |||
470 | retval); | 474 | retval); |
471 | } | 475 | } |
472 | 476 | ||
473 | /* Take control of the lightbar from the EC. */ | ||
474 | lb_manual_suspend_ctrl(ec, 1); | ||
475 | |||
476 | /* We can now add the sysfs class, we know which parameter to show */ | 477 | /* We can now add the sysfs class, we know which parameter to show */ |
477 | retval = cdev_device_add(&ec->cdev, &ec->class_dev); | 478 | retval = cdev_device_add(&ec->cdev, &ec->class_dev); |
478 | if (retval) { | 479 | if (retval) { |
@@ -480,8 +481,26 @@ static int ec_device_probe(struct platform_device *pdev) | |||
480 | goto failed; | 481 | goto failed; |
481 | } | 482 | } |
482 | 483 | ||
483 | if (cros_ec_debugfs_init(ec)) | 484 | retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, |
484 | dev_warn(dev, "failed to create debugfs directory\n"); | 485 | cros_ec_platform_cells, |
486 | ARRAY_SIZE(cros_ec_platform_cells), | ||
487 | NULL, 0, NULL); | ||
488 | if (retval) | ||
489 | dev_warn(ec->dev, | ||
490 | "failed to add cros-ec platform devices: %d\n", | ||
491 | retval); | ||
492 | |||
493 | /* Check whether this EC instance has a VBC NVRAM */ | ||
494 | node = ec->ec_dev->dev->of_node; | ||
495 | if (of_property_read_bool(node, "google,has-vbc-nvram")) { | ||
496 | retval = mfd_add_devices(ec->dev, PLATFORM_DEVID_AUTO, | ||
497 | cros_ec_vbc_cells, | ||
498 | ARRAY_SIZE(cros_ec_vbc_cells), | ||
499 | NULL, 0, NULL); | ||
500 | if (retval) | ||
501 | dev_warn(ec->dev, "failed to add VBC devices: %d\n", | ||
502 | retval); | ||
503 | } | ||
485 | 504 | ||
486 | return 0; | 505 | return 0; |
487 | 506 | ||
@@ -494,69 +513,25 @@ static int ec_device_remove(struct platform_device *pdev) | |||
494 | { | 513 | { |
495 | struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); | 514 | struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); |
496 | 515 | ||
497 | /* Let the EC take over the lightbar again. */ | ||
498 | lb_manual_suspend_ctrl(ec, 0); | ||
499 | |||
500 | cros_ec_debugfs_remove(ec); | ||
501 | |||
502 | mfd_remove_devices(ec->dev); | 516 | mfd_remove_devices(ec->dev); |
503 | cdev_del(&ec->cdev); | 517 | cdev_del(&ec->cdev); |
504 | device_unregister(&ec->class_dev); | 518 | device_unregister(&ec->class_dev); |
505 | return 0; | 519 | return 0; |
506 | } | 520 | } |
507 | 521 | ||
508 | static void ec_device_shutdown(struct platform_device *pdev) | ||
509 | { | ||
510 | struct cros_ec_dev *ec = dev_get_drvdata(&pdev->dev); | ||
511 | |||
512 | /* Be sure to clear up debugfs delayed works */ | ||
513 | cros_ec_debugfs_remove(ec); | ||
514 | } | ||
515 | |||
516 | static const struct platform_device_id cros_ec_id[] = { | 522 | static const struct platform_device_id cros_ec_id[] = { |
517 | { DRV_NAME, 0 }, | 523 | { DRV_NAME, 0 }, |
518 | { /* sentinel */ } | 524 | { /* sentinel */ } |
519 | }; | 525 | }; |
520 | MODULE_DEVICE_TABLE(platform, cros_ec_id); | 526 | MODULE_DEVICE_TABLE(platform, cros_ec_id); |
521 | 527 | ||
522 | static __maybe_unused int ec_device_suspend(struct device *dev) | ||
523 | { | ||
524 | struct cros_ec_dev *ec = dev_get_drvdata(dev); | ||
525 | |||
526 | cros_ec_debugfs_suspend(ec); | ||
527 | |||
528 | lb_suspend(ec); | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | static __maybe_unused int ec_device_resume(struct device *dev) | ||
534 | { | ||
535 | struct cros_ec_dev *ec = dev_get_drvdata(dev); | ||
536 | |||
537 | cros_ec_debugfs_resume(ec); | ||
538 | |||
539 | lb_resume(ec); | ||
540 | |||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | static const struct dev_pm_ops cros_ec_dev_pm_ops = { | ||
545 | #ifdef CONFIG_PM_SLEEP | ||
546 | .suspend = ec_device_suspend, | ||
547 | .resume = ec_device_resume, | ||
548 | #endif | ||
549 | }; | ||
550 | |||
551 | static struct platform_driver cros_ec_dev_driver = { | 528 | static struct platform_driver cros_ec_dev_driver = { |
552 | .driver = { | 529 | .driver = { |
553 | .name = DRV_NAME, | 530 | .name = DRV_NAME, |
554 | .pm = &cros_ec_dev_pm_ops, | ||
555 | }, | 531 | }, |
556 | .id_table = cros_ec_id, | 532 | .id_table = cros_ec_id, |
557 | .probe = ec_device_probe, | 533 | .probe = ec_device_probe, |
558 | .remove = ec_device_remove, | 534 | .remove = ec_device_remove, |
559 | .shutdown = ec_device_shutdown, | ||
560 | }; | 535 | }; |
561 | 536 | ||
562 | static int __init cros_ec_dev_init(void) | 537 | static int __init cros_ec_dev_init(void) |
diff --git a/drivers/mfd/cros_ec_dev.h b/drivers/mfd/cros_ec_dev.h index 978d836a0248..ec750433455a 100644 --- a/drivers/mfd/cros_ec_dev.h +++ b/drivers/mfd/cros_ec_dev.h | |||
@@ -44,10 +44,4 @@ struct cros_ec_readmem { | |||
44 | #define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) | 44 | #define CROS_EC_DEV_IOCXCMD _IOWR(CROS_EC_DEV_IOC, 0, struct cros_ec_command) |
45 | #define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) | 45 | #define CROS_EC_DEV_IOCRDMEM _IOWR(CROS_EC_DEV_IOC, 1, struct cros_ec_readmem) |
46 | 46 | ||
47 | /* Lightbar utilities */ | ||
48 | extern bool ec_has_lightbar(struct cros_ec_dev *ec); | ||
49 | extern int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable); | ||
50 | extern int lb_suspend(struct cros_ec_dev *ec); | ||
51 | extern int lb_resume(struct cros_ec_dev *ec); | ||
52 | |||
53 | #endif /* _CROS_EC_DEV_H_ */ | 47 | #endif /* _CROS_EC_DEV_H_ */ |
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index aec20e1c7d3d..65666b624ae8 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c | |||
@@ -1,4 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * DB8500 PRCM Unit driver | ||
3 | * | ||
2 | * Copyright (C) STMicroelectronics 2009 | 4 | * Copyright (C) STMicroelectronics 2009 |
3 | * Copyright (C) ST-Ericsson SA 2010 | 5 | * Copyright (C) ST-Ericsson SA 2010 |
4 | * | 6 | * |
@@ -10,7 +12,8 @@ | |||
10 | * U8500 PRCM Unit interface driver | 12 | * U8500 PRCM Unit interface driver |
11 | * | 13 | * |
12 | */ | 14 | */ |
13 | #include <linux/module.h> | 15 | #include <linux/init.h> |
16 | #include <linux/export.h> | ||
14 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
15 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
16 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
@@ -3188,9 +3191,4 @@ static int __init db8500_prcmu_init(void) | |||
3188 | { | 3191 | { |
3189 | return platform_driver_register(&db8500_prcmu_driver); | 3192 | return platform_driver_register(&db8500_prcmu_driver); |
3190 | } | 3193 | } |
3191 | |||
3192 | core_initcall(db8500_prcmu_init); | 3194 | core_initcall(db8500_prcmu_init); |
3193 | |||
3194 | MODULE_AUTHOR("Mattias Nilsson <mattias.i.nilsson@stericsson.com>"); | ||
3195 | MODULE_DESCRIPTION("DB8500 PRCM Unit driver"); | ||
3196 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/htc-i2cpld.c b/drivers/mfd/htc-i2cpld.c index 01572b5e79e8..af3c66355270 100644 --- a/drivers/mfd/htc-i2cpld.c +++ b/drivers/mfd/htc-i2cpld.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/module.h> | ||
31 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
32 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
33 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
@@ -614,8 +613,6 @@ static const struct i2c_device_id htcpld_chip_id[] = { | |||
614 | { "htcpld-chip", 0 }, | 613 | { "htcpld-chip", 0 }, |
615 | { } | 614 | { } |
616 | }; | 615 | }; |
617 | MODULE_DEVICE_TABLE(i2c, htcpld_chip_id); | ||
618 | |||
619 | 616 | ||
620 | static struct i2c_driver htcpld_chip_driver = { | 617 | static struct i2c_driver htcpld_chip_driver = { |
621 | .driver = { | 618 | .driver = { |
@@ -643,17 +640,4 @@ static int __init htcpld_core_init(void) | |||
643 | /* Probe for our chips */ | 640 | /* Probe for our chips */ |
644 | return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe); | 641 | return platform_driver_probe(&htcpld_core_driver, htcpld_core_probe); |
645 | } | 642 | } |
646 | 643 | device_initcall(htcpld_core_init); | |
647 | static void __exit htcpld_core_exit(void) | ||
648 | { | ||
649 | i2c_del_driver(&htcpld_chip_driver); | ||
650 | platform_driver_unregister(&htcpld_core_driver); | ||
651 | } | ||
652 | |||
653 | module_init(htcpld_core_init); | ||
654 | module_exit(htcpld_core_exit); | ||
655 | |||
656 | MODULE_AUTHOR("Cory Maccarrone <darkstar6262@gmail.com>"); | ||
657 | MODULE_DESCRIPTION("I2C HTC PLD Driver"); | ||
658 | MODULE_LICENSE("GPL"); | ||
659 | |||
diff --git a/drivers/mfd/intel-lpss-acpi.c b/drivers/mfd/intel-lpss-acpi.c index 7911b0a14a6d..6d9f03363ee7 100644 --- a/drivers/mfd/intel-lpss-acpi.c +++ b/drivers/mfd/intel-lpss-acpi.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/pm.h> | ||
19 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
20 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
21 | #include <linux/property.h> | 20 | #include <linux/property.h> |
diff --git a/drivers/mfd/intel-lpss-pci.c b/drivers/mfd/intel-lpss-pci.c index 0e5282fc1467..cba2eb166650 100644 --- a/drivers/mfd/intel-lpss-pci.c +++ b/drivers/mfd/intel-lpss-pci.c | |||
@@ -15,7 +15,6 @@ | |||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/pci.h> | 17 | #include <linux/pci.h> |
18 | #include <linux/pm.h> | ||
19 | #include <linux/pm_runtime.h> | 18 | #include <linux/pm_runtime.h> |
20 | #include <linux/property.h> | 19 | #include <linux/property.h> |
21 | 20 | ||
diff --git a/drivers/mfd/intel-lpss.h b/drivers/mfd/intel-lpss.h index 865bbeaaf00c..3a120fecd2dc 100644 --- a/drivers/mfd/intel-lpss.h +++ b/drivers/mfd/intel-lpss.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #ifndef __MFD_INTEL_LPSS_H | 14 | #ifndef __MFD_INTEL_LPSS_H |
15 | #define __MFD_INTEL_LPSS_H | 15 | #define __MFD_INTEL_LPSS_H |
16 | 16 | ||
17 | #include <linux/pm.h> | ||
18 | |||
17 | struct device; | 19 | struct device; |
18 | struct resource; | 20 | struct resource; |
19 | struct property_entry; | 21 | struct property_entry; |
diff --git a/drivers/mfd/lochnagar-i2c.c b/drivers/mfd/lochnagar-i2c.c new file mode 100644 index 000000000000..3a65d9938902 --- /dev/null +++ b/drivers/mfd/lochnagar-i2c.c | |||
@@ -0,0 +1,398 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Lochnagar I2C bus interface | ||
4 | * | ||
5 | * Copyright (c) 2012-2018 Cirrus Logic, Inc. and | ||
6 | * Cirrus Logic International Semiconductor Ltd. | ||
7 | * | ||
8 | * Author: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
9 | */ | ||
10 | |||
11 | #include <linux/delay.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/gpio/consumer.h> | ||
15 | #include <linux/i2c.h> | ||
16 | #include <linux/lockdep.h> | ||
17 | #include <linux/mfd/core.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | #include <linux/regmap.h> | ||
22 | |||
23 | #include <linux/mfd/lochnagar.h> | ||
24 | #include <linux/mfd/lochnagar1_regs.h> | ||
25 | #include <linux/mfd/lochnagar2_regs.h> | ||
26 | |||
27 | #define LOCHNAGAR_BOOT_RETRIES 10 | ||
28 | #define LOCHNAGAR_BOOT_DELAY_MS 350 | ||
29 | |||
30 | #define LOCHNAGAR_CONFIG_POLL_US 10000 | ||
31 | |||
32 | static bool lochnagar1_readable_register(struct device *dev, unsigned int reg) | ||
33 | { | ||
34 | switch (reg) { | ||
35 | case LOCHNAGAR_SOFTWARE_RESET: | ||
36 | case LOCHNAGAR_FIRMWARE_ID1...LOCHNAGAR_FIRMWARE_ID2: | ||
37 | case LOCHNAGAR1_CDC_AIF1_SEL...LOCHNAGAR1_CDC_AIF3_SEL: | ||
38 | case LOCHNAGAR1_CDC_MCLK1_SEL...LOCHNAGAR1_CDC_MCLK2_SEL: | ||
39 | case LOCHNAGAR1_CDC_AIF_CTRL1...LOCHNAGAR1_CDC_AIF_CTRL2: | ||
40 | case LOCHNAGAR1_EXT_AIF_CTRL: | ||
41 | case LOCHNAGAR1_DSP_AIF1_SEL...LOCHNAGAR1_DSP_AIF2_SEL: | ||
42 | case LOCHNAGAR1_DSP_CLKIN_SEL: | ||
43 | case LOCHNAGAR1_DSP_AIF: | ||
44 | case LOCHNAGAR1_GF_AIF1...LOCHNAGAR1_GF_AIF2: | ||
45 | case LOCHNAGAR1_PSIA_AIF: | ||
46 | case LOCHNAGAR1_PSIA1_SEL...LOCHNAGAR1_PSIA2_SEL: | ||
47 | case LOCHNAGAR1_SPDIF_AIF_SEL: | ||
48 | case LOCHNAGAR1_GF_AIF3_SEL...LOCHNAGAR1_GF_AIF4_SEL: | ||
49 | case LOCHNAGAR1_GF_CLKOUT1_SEL: | ||
50 | case LOCHNAGAR1_GF_AIF1_SEL...LOCHNAGAR1_GF_AIF2_SEL: | ||
51 | case LOCHNAGAR1_GF_GPIO2...LOCHNAGAR1_GF_GPIO7: | ||
52 | case LOCHNAGAR1_RST: | ||
53 | case LOCHNAGAR1_LED1...LOCHNAGAR1_LED2: | ||
54 | case LOCHNAGAR1_I2C_CTRL: | ||
55 | return true; | ||
56 | default: | ||
57 | return false; | ||
58 | } | ||
59 | } | ||
60 | |||
61 | static const struct regmap_config lochnagar1_i2c_regmap = { | ||
62 | .reg_bits = 8, | ||
63 | .val_bits = 8, | ||
64 | .reg_format_endian = REGMAP_ENDIAN_BIG, | ||
65 | .val_format_endian = REGMAP_ENDIAN_BIG, | ||
66 | |||
67 | .max_register = 0x50, | ||
68 | .readable_reg = lochnagar1_readable_register, | ||
69 | |||
70 | .use_single_read = true, | ||
71 | .use_single_write = true, | ||
72 | |||
73 | .cache_type = REGCACHE_RBTREE, | ||
74 | }; | ||
75 | |||
76 | static const struct reg_sequence lochnagar1_patch[] = { | ||
77 | { 0x40, 0x0083 }, | ||
78 | { 0x47, 0x0018 }, | ||
79 | { 0x50, 0x0000 }, | ||
80 | }; | ||
81 | |||
82 | static bool lochnagar2_readable_register(struct device *dev, unsigned int reg) | ||
83 | { | ||
84 | switch (reg) { | ||
85 | case LOCHNAGAR_SOFTWARE_RESET: | ||
86 | case LOCHNAGAR_FIRMWARE_ID1...LOCHNAGAR_FIRMWARE_ID2: | ||
87 | case LOCHNAGAR2_CDC_AIF1_CTRL...LOCHNAGAR2_CDC_AIF3_CTRL: | ||
88 | case LOCHNAGAR2_DSP_AIF1_CTRL...LOCHNAGAR2_DSP_AIF2_CTRL: | ||
89 | case LOCHNAGAR2_PSIA1_CTRL...LOCHNAGAR2_PSIA2_CTRL: | ||
90 | case LOCHNAGAR2_GF_AIF3_CTRL...LOCHNAGAR2_GF_AIF4_CTRL: | ||
91 | case LOCHNAGAR2_GF_AIF1_CTRL...LOCHNAGAR2_GF_AIF2_CTRL: | ||
92 | case LOCHNAGAR2_SPDIF_AIF_CTRL: | ||
93 | case LOCHNAGAR2_USB_AIF1_CTRL...LOCHNAGAR2_USB_AIF2_CTRL: | ||
94 | case LOCHNAGAR2_ADAT_AIF_CTRL: | ||
95 | case LOCHNAGAR2_CDC_MCLK1_CTRL...LOCHNAGAR2_CDC_MCLK2_CTRL: | ||
96 | case LOCHNAGAR2_DSP_CLKIN_CTRL: | ||
97 | case LOCHNAGAR2_PSIA1_MCLK_CTRL...LOCHNAGAR2_PSIA2_MCLK_CTRL: | ||
98 | case LOCHNAGAR2_SPDIF_MCLK_CTRL: | ||
99 | case LOCHNAGAR2_GF_CLKOUT1_CTRL...LOCHNAGAR2_GF_CLKOUT2_CTRL: | ||
100 | case LOCHNAGAR2_ADAT_MCLK_CTRL: | ||
101 | case LOCHNAGAR2_SOUNDCARD_MCLK_CTRL: | ||
102 | case LOCHNAGAR2_GPIO_FPGA_GPIO1...LOCHNAGAR2_GPIO_FPGA_GPIO6: | ||
103 | case LOCHNAGAR2_GPIO_CDC_GPIO1...LOCHNAGAR2_GPIO_CDC_GPIO8: | ||
104 | case LOCHNAGAR2_GPIO_DSP_GPIO1...LOCHNAGAR2_GPIO_DSP_GPIO6: | ||
105 | case LOCHNAGAR2_GPIO_GF_GPIO2...LOCHNAGAR2_GPIO_GF_GPIO7: | ||
106 | case LOCHNAGAR2_GPIO_CDC_AIF1_BCLK...LOCHNAGAR2_GPIO_CDC_AIF3_TXDAT: | ||
107 | case LOCHNAGAR2_GPIO_DSP_AIF1_BCLK...LOCHNAGAR2_GPIO_DSP_AIF2_TXDAT: | ||
108 | case LOCHNAGAR2_GPIO_PSIA1_BCLK...LOCHNAGAR2_GPIO_PSIA2_TXDAT: | ||
109 | case LOCHNAGAR2_GPIO_GF_AIF3_BCLK...LOCHNAGAR2_GPIO_GF_AIF4_TXDAT: | ||
110 | case LOCHNAGAR2_GPIO_GF_AIF1_BCLK...LOCHNAGAR2_GPIO_GF_AIF2_TXDAT: | ||
111 | case LOCHNAGAR2_GPIO_DSP_UART1_RX...LOCHNAGAR2_GPIO_DSP_UART2_TX: | ||
112 | case LOCHNAGAR2_GPIO_GF_UART2_RX...LOCHNAGAR2_GPIO_GF_UART2_TX: | ||
113 | case LOCHNAGAR2_GPIO_USB_UART_RX: | ||
114 | case LOCHNAGAR2_GPIO_CDC_PDMCLK1...LOCHNAGAR2_GPIO_CDC_PDMDAT2: | ||
115 | case LOCHNAGAR2_GPIO_CDC_DMICCLK1...LOCHNAGAR2_GPIO_CDC_DMICDAT4: | ||
116 | case LOCHNAGAR2_GPIO_DSP_DMICCLK1...LOCHNAGAR2_GPIO_DSP_DMICDAT2: | ||
117 | case LOCHNAGAR2_GPIO_I2C2_SCL...LOCHNAGAR2_GPIO_I2C4_SDA: | ||
118 | case LOCHNAGAR2_GPIO_DSP_STANDBY: | ||
119 | case LOCHNAGAR2_GPIO_CDC_MCLK1...LOCHNAGAR2_GPIO_CDC_MCLK2: | ||
120 | case LOCHNAGAR2_GPIO_DSP_CLKIN: | ||
121 | case LOCHNAGAR2_GPIO_PSIA1_MCLK...LOCHNAGAR2_GPIO_PSIA2_MCLK: | ||
122 | case LOCHNAGAR2_GPIO_GF_GPIO1...LOCHNAGAR2_GPIO_GF_GPIO5: | ||
123 | case LOCHNAGAR2_GPIO_DSP_GPIO20: | ||
124 | case LOCHNAGAR2_GPIO_CHANNEL1...LOCHNAGAR2_GPIO_CHANNEL16: | ||
125 | case LOCHNAGAR2_MINICARD_RESETS: | ||
126 | case LOCHNAGAR2_ANALOGUE_PATH_CTRL1...LOCHNAGAR2_ANALOGUE_PATH_CTRL2: | ||
127 | case LOCHNAGAR2_COMMS_CTRL4: | ||
128 | case LOCHNAGAR2_SPDIF_CTRL: | ||
129 | case LOCHNAGAR2_IMON_CTRL1...LOCHNAGAR2_IMON_CTRL4: | ||
130 | case LOCHNAGAR2_IMON_DATA1...LOCHNAGAR2_IMON_DATA2: | ||
131 | case LOCHNAGAR2_POWER_CTRL: | ||
132 | case LOCHNAGAR2_MICVDD_CTRL1: | ||
133 | case LOCHNAGAR2_MICVDD_CTRL2: | ||
134 | case LOCHNAGAR2_VDDCORE_CDC_CTRL1: | ||
135 | case LOCHNAGAR2_VDDCORE_CDC_CTRL2: | ||
136 | case LOCHNAGAR2_SOUNDCARD_AIF_CTRL: | ||
137 | return true; | ||
138 | default: | ||
139 | return false; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | static bool lochnagar2_volatile_register(struct device *dev, unsigned int reg) | ||
144 | { | ||
145 | switch (reg) { | ||
146 | case LOCHNAGAR2_GPIO_CHANNEL1...LOCHNAGAR2_GPIO_CHANNEL16: | ||
147 | case LOCHNAGAR2_ANALOGUE_PATH_CTRL1: | ||
148 | case LOCHNAGAR2_IMON_CTRL3...LOCHNAGAR2_IMON_CTRL4: | ||
149 | case LOCHNAGAR2_IMON_DATA1...LOCHNAGAR2_IMON_DATA2: | ||
150 | return true; | ||
151 | default: | ||
152 | return false; | ||
153 | } | ||
154 | } | ||
155 | |||
156 | static const struct regmap_config lochnagar2_i2c_regmap = { | ||
157 | .reg_bits = 16, | ||
158 | .val_bits = 16, | ||
159 | .reg_format_endian = REGMAP_ENDIAN_BIG, | ||
160 | .val_format_endian = REGMAP_ENDIAN_BIG, | ||
161 | |||
162 | .max_register = 0x1F1F, | ||
163 | .readable_reg = lochnagar2_readable_register, | ||
164 | .volatile_reg = lochnagar2_volatile_register, | ||
165 | |||
166 | .cache_type = REGCACHE_RBTREE, | ||
167 | }; | ||
168 | |||
169 | static const struct reg_sequence lochnagar2_patch[] = { | ||
170 | { 0x00EE, 0x0000 }, | ||
171 | }; | ||
172 | |||
173 | struct lochnagar_config { | ||
174 | int id; | ||
175 | const char * const name; | ||
176 | enum lochnagar_type type; | ||
177 | const struct regmap_config *regmap; | ||
178 | const struct reg_sequence *patch; | ||
179 | int npatch; | ||
180 | }; | ||
181 | |||
182 | static struct lochnagar_config lochnagar_configs[] = { | ||
183 | { | ||
184 | .id = 0x50, | ||
185 | .name = "lochnagar1", | ||
186 | .type = LOCHNAGAR1, | ||
187 | .regmap = &lochnagar1_i2c_regmap, | ||
188 | .patch = lochnagar1_patch, | ||
189 | .npatch = ARRAY_SIZE(lochnagar1_patch), | ||
190 | }, | ||
191 | { | ||
192 | .id = 0xCB58, | ||
193 | .name = "lochnagar2", | ||
194 | .type = LOCHNAGAR2, | ||
195 | .regmap = &lochnagar2_i2c_regmap, | ||
196 | .patch = lochnagar2_patch, | ||
197 | .npatch = ARRAY_SIZE(lochnagar2_patch), | ||
198 | }, | ||
199 | }; | ||
200 | |||
201 | static const struct of_device_id lochnagar_of_match[] = { | ||
202 | { .compatible = "cirrus,lochnagar1", .data = &lochnagar_configs[0] }, | ||
203 | { .compatible = "cirrus,lochnagar2", .data = &lochnagar_configs[1] }, | ||
204 | {}, | ||
205 | }; | ||
206 | |||
207 | static int lochnagar_wait_for_boot(struct regmap *regmap, unsigned int *id) | ||
208 | { | ||
209 | int i, ret; | ||
210 | |||
211 | for (i = 0; i < LOCHNAGAR_BOOT_RETRIES; ++i) { | ||
212 | msleep(LOCHNAGAR_BOOT_DELAY_MS); | ||
213 | |||
214 | /* The reset register will return the device ID when read */ | ||
215 | ret = regmap_read(regmap, LOCHNAGAR_SOFTWARE_RESET, id); | ||
216 | if (!ret) | ||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | return -ETIMEDOUT; | ||
221 | } | ||
222 | |||
223 | /** | ||
224 | * lochnagar_update_config - Synchronise the boards analogue configuration to | ||
225 | * the hardware. | ||
226 | * | ||
227 | * @lochnagar: A pointer to the primary core data structure. | ||
228 | * | ||
229 | * Return: Zero on success or an appropriate negative error code on failure. | ||
230 | */ | ||
231 | int lochnagar_update_config(struct lochnagar *lochnagar) | ||
232 | { | ||
233 | struct regmap *regmap = lochnagar->regmap; | ||
234 | unsigned int done = LOCHNAGAR2_ANALOGUE_PATH_UPDATE_STS_MASK; | ||
235 | int timeout_ms = LOCHNAGAR_BOOT_DELAY_MS * LOCHNAGAR_BOOT_RETRIES; | ||
236 | unsigned int val = 0; | ||
237 | int ret; | ||
238 | |||
239 | lockdep_assert_held(&lochnagar->analogue_config_lock); | ||
240 | |||
241 | if (lochnagar->type != LOCHNAGAR2) | ||
242 | return 0; | ||
243 | |||
244 | /* | ||
245 | * Toggle the ANALOGUE_PATH_UPDATE bit and wait for the device to | ||
246 | * acknowledge that any outstanding changes to the analogue | ||
247 | * configuration have been applied. | ||
248 | */ | ||
249 | ret = regmap_write(regmap, LOCHNAGAR2_ANALOGUE_PATH_CTRL1, 0); | ||
250 | if (ret < 0) | ||
251 | return ret; | ||
252 | |||
253 | ret = regmap_write(regmap, LOCHNAGAR2_ANALOGUE_PATH_CTRL1, | ||
254 | LOCHNAGAR2_ANALOGUE_PATH_UPDATE_MASK); | ||
255 | if (ret < 0) | ||
256 | return ret; | ||
257 | |||
258 | ret = regmap_read_poll_timeout(regmap, | ||
259 | LOCHNAGAR2_ANALOGUE_PATH_CTRL1, val, | ||
260 | (val & done), LOCHNAGAR_CONFIG_POLL_US, | ||
261 | timeout_ms * 1000); | ||
262 | if (ret < 0) | ||
263 | return ret; | ||
264 | |||
265 | return 0; | ||
266 | } | ||
267 | EXPORT_SYMBOL_GPL(lochnagar_update_config); | ||
268 | |||
269 | static int lochnagar_i2c_probe(struct i2c_client *i2c) | ||
270 | { | ||
271 | struct device *dev = &i2c->dev; | ||
272 | const struct lochnagar_config *config = NULL; | ||
273 | const struct of_device_id *of_id; | ||
274 | struct lochnagar *lochnagar; | ||
275 | struct gpio_desc *reset, *present; | ||
276 | unsigned int val; | ||
277 | unsigned int firmwareid; | ||
278 | unsigned int devid, rev; | ||
279 | int ret; | ||
280 | |||
281 | lochnagar = devm_kzalloc(dev, sizeof(*lochnagar), GFP_KERNEL); | ||
282 | if (!lochnagar) | ||
283 | return -ENOMEM; | ||
284 | |||
285 | of_id = of_match_device(lochnagar_of_match, dev); | ||
286 | if (!of_id) | ||
287 | return -EINVAL; | ||
288 | |||
289 | config = of_id->data; | ||
290 | |||
291 | lochnagar->dev = dev; | ||
292 | mutex_init(&lochnagar->analogue_config_lock); | ||
293 | |||
294 | dev_set_drvdata(dev, lochnagar); | ||
295 | |||
296 | reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW); | ||
297 | if (IS_ERR(reset)) { | ||
298 | ret = PTR_ERR(reset); | ||
299 | dev_err(dev, "Failed to get reset GPIO: %d\n", ret); | ||
300 | return ret; | ||
301 | } | ||
302 | |||
303 | present = devm_gpiod_get_optional(dev, "present", GPIOD_OUT_HIGH); | ||
304 | if (IS_ERR(present)) { | ||
305 | ret = PTR_ERR(present); | ||
306 | dev_err(dev, "Failed to get present GPIO: %d\n", ret); | ||
307 | return ret; | ||
308 | } | ||
309 | |||
310 | /* Leave the Lochnagar in reset for a reasonable amount of time */ | ||
311 | msleep(20); | ||
312 | |||
313 | /* Bring Lochnagar out of reset */ | ||
314 | gpiod_set_value_cansleep(reset, 1); | ||
315 | |||
316 | /* Identify Lochnagar */ | ||
317 | lochnagar->type = config->type; | ||
318 | |||
319 | lochnagar->regmap = devm_regmap_init_i2c(i2c, config->regmap); | ||
320 | if (IS_ERR(lochnagar->regmap)) { | ||
321 | ret = PTR_ERR(lochnagar->regmap); | ||
322 | dev_err(dev, "Failed to allocate register map: %d\n", ret); | ||
323 | return ret; | ||
324 | } | ||
325 | |||
326 | /* Wait for Lochnagar to boot */ | ||
327 | ret = lochnagar_wait_for_boot(lochnagar->regmap, &val); | ||
328 | if (ret < 0) { | ||
329 | dev_err(dev, "Failed to read device ID: %d\n", ret); | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | devid = val & LOCHNAGAR_DEVICE_ID_MASK; | ||
334 | rev = val & LOCHNAGAR_REV_ID_MASK; | ||
335 | |||
336 | if (devid != config->id) { | ||
337 | dev_err(dev, | ||
338 | "ID does not match %s (expected 0x%x got 0x%x)\n", | ||
339 | config->name, config->id, devid); | ||
340 | return -ENODEV; | ||
341 | } | ||
342 | |||
343 | /* Identify firmware */ | ||
344 | ret = regmap_read(lochnagar->regmap, LOCHNAGAR_FIRMWARE_ID1, &val); | ||
345 | if (ret < 0) { | ||
346 | dev_err(dev, "Failed to read firmware id 1: %d\n", ret); | ||
347 | return ret; | ||
348 | } | ||
349 | |||
350 | firmwareid = val; | ||
351 | |||
352 | ret = regmap_read(lochnagar->regmap, LOCHNAGAR_FIRMWARE_ID2, &val); | ||
353 | if (ret < 0) { | ||
354 | dev_err(dev, "Failed to read firmware id 2: %d\n", ret); | ||
355 | return ret; | ||
356 | } | ||
357 | |||
358 | firmwareid |= (val << config->regmap->val_bits); | ||
359 | |||
360 | dev_info(dev, "Found %s (0x%x) revision %u firmware 0x%.6x\n", | ||
361 | config->name, devid, rev + 1, firmwareid); | ||
362 | |||
363 | ret = regmap_register_patch(lochnagar->regmap, config->patch, | ||
364 | config->npatch); | ||
365 | if (ret < 0) { | ||
366 | dev_err(dev, "Failed to register patch: %d\n", ret); | ||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | ret = devm_of_platform_populate(dev); | ||
371 | if (ret < 0) { | ||
372 | dev_err(dev, "Failed to populate child nodes: %d\n", ret); | ||
373 | return ret; | ||
374 | } | ||
375 | |||
376 | return ret; | ||
377 | } | ||
378 | |||
379 | static struct i2c_driver lochnagar_i2c_driver = { | ||
380 | .driver = { | ||
381 | .name = "lochnagar", | ||
382 | .of_match_table = of_match_ptr(lochnagar_of_match), | ||
383 | .suppress_bind_attrs = true, | ||
384 | }, | ||
385 | .probe_new = lochnagar_i2c_probe, | ||
386 | }; | ||
387 | |||
388 | static int __init lochnagar_i2c_init(void) | ||
389 | { | ||
390 | int ret; | ||
391 | |||
392 | ret = i2c_add_driver(&lochnagar_i2c_driver); | ||
393 | if (ret) | ||
394 | pr_err("Failed to register Lochnagar driver: %d\n", ret); | ||
395 | |||
396 | return ret; | ||
397 | } | ||
398 | subsys_initcall(lochnagar_i2c_init); | ||
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c index fd8b15cd84fd..87c724ba9793 100644 --- a/drivers/mfd/max8925-core.c +++ b/drivers/mfd/max8925-core.c | |||
@@ -10,7 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/module.h> | 13 | #include <linux/init.h> |
14 | #include <linux/i2c.h> | 14 | #include <linux/i2c.h> |
15 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
@@ -919,8 +919,3 @@ void max8925_device_exit(struct max8925_chip *chip) | |||
919 | free_irq(chip->tsc_irq, chip); | 919 | free_irq(chip->tsc_irq, chip); |
920 | mfd_remove_devices(chip->dev); | 920 | mfd_remove_devices(chip->dev); |
921 | } | 921 | } |
922 | |||
923 | |||
924 | MODULE_DESCRIPTION("PMIC Driver for Maxim MAX8925"); | ||
925 | MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com"); | ||
926 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/mxs-lradc.c b/drivers/mfd/mxs-lradc.c index 98e732a7ae96..a09a8d06302b 100644 --- a/drivers/mfd/mxs-lradc.c +++ b/drivers/mfd/mxs-lradc.c | |||
@@ -181,7 +181,7 @@ static int mxs_lradc_probe(struct platform_device *pdev) | |||
181 | MXS_LRADC_TOUCHSCREEN_5WIRE; | 181 | MXS_LRADC_TOUCHSCREEN_5WIRE; |
182 | break; | 182 | break; |
183 | } | 183 | } |
184 | /* fall through to an error message for i.MX23 */ | 184 | /* fall through - to an error message for i.MX23 */ |
185 | default: | 185 | default: |
186 | dev_err(&pdev->dev, | 186 | dev_err(&pdev->dev, |
187 | "Unsupported number of touchscreen wires (%d)\n" | 187 | "Unsupported number of touchscreen wires (%d)\n" |
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c index fd46de02b715..c5cc5cb3dde7 100644 --- a/drivers/mfd/rc5t583.c +++ b/drivers/mfd/rc5t583.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
26 | #include <linux/module.h> | ||
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
28 | #include <linux/err.h> | 27 | #include <linux/err.h> |
29 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
@@ -298,8 +297,6 @@ static const struct i2c_device_id rc5t583_i2c_id[] = { | |||
298 | {} | 297 | {} |
299 | }; | 298 | }; |
300 | 299 | ||
301 | MODULE_DEVICE_TABLE(i2c, rc5t583_i2c_id); | ||
302 | |||
303 | static struct i2c_driver rc5t583_i2c_driver = { | 300 | static struct i2c_driver rc5t583_i2c_driver = { |
304 | .driver = { | 301 | .driver = { |
305 | .name = "rc5t583", | 302 | .name = "rc5t583", |
@@ -313,14 +310,3 @@ static int __init rc5t583_i2c_init(void) | |||
313 | return i2c_add_driver(&rc5t583_i2c_driver); | 310 | return i2c_add_driver(&rc5t583_i2c_driver); |
314 | } | 311 | } |
315 | subsys_initcall(rc5t583_i2c_init); | 312 | subsys_initcall(rc5t583_i2c_init); |
316 | |||
317 | static void __exit rc5t583_i2c_exit(void) | ||
318 | { | ||
319 | i2c_del_driver(&rc5t583_i2c_driver); | ||
320 | } | ||
321 | |||
322 | module_exit(rc5t583_i2c_exit); | ||
323 | |||
324 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
325 | MODULE_DESCRIPTION("RICOH RC5T583 power management system device driver"); | ||
326 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/sec-core.c b/drivers/mfd/sec-core.c index e0835c9df7a1..521319086c81 100644 --- a/drivers/mfd/sec-core.c +++ b/drivers/mfd/sec-core.c | |||
@@ -114,7 +114,8 @@ static const struct mfd_cell s2mpu02_devs[] = { | |||
114 | 114 | ||
115 | #ifdef CONFIG_OF | 115 | #ifdef CONFIG_OF |
116 | static const struct of_device_id sec_dt_match[] = { | 116 | static const struct of_device_id sec_dt_match[] = { |
117 | { .compatible = "samsung,s5m8767-pmic", | 117 | { |
118 | .compatible = "samsung,s5m8767-pmic", | ||
118 | .data = (void *)S5M8767X, | 119 | .data = (void *)S5M8767X, |
119 | }, { | 120 | }, { |
120 | .compatible = "samsung,s2mps11-pmic", | 121 | .compatible = "samsung,s2mps11-pmic", |
@@ -309,8 +310,8 @@ static void sec_pmic_configure(struct sec_pmic_dev *sec_pmic) | |||
309 | * the sub-modules need not instantiate another instance while parsing their | 310 | * the sub-modules need not instantiate another instance while parsing their |
310 | * platform data. | 311 | * platform data. |
311 | */ | 312 | */ |
312 | static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( | 313 | static struct sec_platform_data * |
313 | struct device *dev) | 314 | sec_pmic_i2c_parse_dt_pdata(struct device *dev) |
314 | { | 315 | { |
315 | struct sec_platform_data *pd; | 316 | struct sec_platform_data *pd; |
316 | 317 | ||
@@ -331,8 +332,8 @@ static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( | |||
331 | return pd; | 332 | return pd; |
332 | } | 333 | } |
333 | #else | 334 | #else |
334 | static struct sec_platform_data *sec_pmic_i2c_parse_dt_pdata( | 335 | static struct sec_platform_data * |
335 | struct device *dev) | 336 | sec_pmic_i2c_parse_dt_pdata(struct device *dev) |
336 | { | 337 | { |
337 | return NULL; | 338 | return NULL; |
338 | } | 339 | } |
@@ -471,8 +472,9 @@ static int sec_pmic_probe(struct i2c_client *i2c, | |||
471 | num_sec_devs = ARRAY_SIZE(s2mpu02_devs); | 472 | num_sec_devs = ARRAY_SIZE(s2mpu02_devs); |
472 | break; | 473 | break; |
473 | default: | 474 | default: |
474 | /* If this happens the probe function is problem */ | 475 | dev_err(&i2c->dev, "Unsupported device type (%lu)\n", |
475 | BUG(); | 476 | sec_pmic->device_type); |
477 | return -ENODEV; | ||
476 | } | 478 | } |
477 | ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, | 479 | ret = devm_mfd_add_devices(sec_pmic->dev, -1, sec_devs, num_sec_devs, |
478 | NULL, 0, NULL); | 480 | NULL, 0, NULL); |
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index a530972c5a7e..d217debf382e 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -1142,9 +1142,11 @@ static int sm501_register_gpio_i2c_instance(struct sm501_devdata *sm, | |||
1142 | return -ENOMEM; | 1142 | return -ENOMEM; |
1143 | 1143 | ||
1144 | /* Create a gpiod lookup using gpiochip-local offsets */ | 1144 | /* Create a gpiod lookup using gpiochip-local offsets */ |
1145 | lookup = devm_kzalloc(&pdev->dev, | 1145 | lookup = devm_kzalloc(&pdev->dev, struct_size(lookup, table, 3), |
1146 | sizeof(*lookup) + 3 * sizeof(struct gpiod_lookup), | ||
1147 | GFP_KERNEL); | 1146 | GFP_KERNEL); |
1147 | if (!lookup) | ||
1148 | return -ENOMEM; | ||
1149 | |||
1148 | lookup->dev_id = "i2c-gpio"; | 1150 | lookup->dev_id = "i2c-gpio"; |
1149 | if (iic->pin_sda < 32) | 1151 | if (iic->pin_sda < 32) |
1150 | lookup->table[0].chip_label = "SM501-LOW"; | 1152 | lookup->table[0].chip_label = "SM501-LOW"; |
diff --git a/drivers/mfd/sta2x11-mfd.c b/drivers/mfd/sta2x11-mfd.c index 3aeafa228baf..cab9aabcaa1f 100644 --- a/drivers/mfd/sta2x11-mfd.c +++ b/drivers/mfd/sta2x11-mfd.c | |||
@@ -1,4 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * STA2x11 mfd for GPIO, SCTL and APBREG | ||
3 | * | ||
2 | * Copyright (c) 2009-2011 Wind River Systems, Inc. | 4 | * Copyright (c) 2009-2011 Wind River Systems, Inc. |
3 | * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi) | 5 | * Copyright (c) 2011 ST Microelectronics (Alessandro Rubini, Davide Ciminaghi) |
4 | * | 6 | * |
@@ -18,7 +20,8 @@ | |||
18 | */ | 20 | */ |
19 | 21 | ||
20 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 23 | #include <linux/init.h> |
24 | #include <linux/export.h> | ||
22 | #include <linux/spinlock.h> | 25 | #include <linux/spinlock.h> |
23 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
24 | #include <linux/device.h> | 27 | #include <linux/device.h> |
@@ -653,8 +656,3 @@ static int __init sta2x11_mfd_init(void) | |||
653 | */ | 656 | */ |
654 | subsys_initcall(sta2x11_drivers_init); | 657 | subsys_initcall(sta2x11_drivers_init); |
655 | rootfs_initcall(sta2x11_mfd_init); | 658 | rootfs_initcall(sta2x11_mfd_init); |
656 | |||
657 | MODULE_LICENSE("GPL v2"); | ||
658 | MODULE_AUTHOR("Wind River"); | ||
659 | MODULE_DESCRIPTION("STA2x11 mfd for GPIO, SCTL and APBREG"); | ||
660 | MODULE_DEVICE_TABLE(pci, sta2x11_mfd_tbl); | ||
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c index 7569a4be0608..f2acb1f6a29c 100644 --- a/drivers/mfd/stmpe.c +++ b/drivers/mfd/stmpe.c | |||
@@ -464,6 +464,28 @@ static const struct mfd_cell stmpe_ts_cell = { | |||
464 | }; | 464 | }; |
465 | 465 | ||
466 | /* | 466 | /* |
467 | * ADC (STMPE811) | ||
468 | */ | ||
469 | |||
470 | static struct resource stmpe_adc_resources[] = { | ||
471 | { | ||
472 | .name = "STMPE_TEMP_SENS", | ||
473 | .flags = IORESOURCE_IRQ, | ||
474 | }, | ||
475 | { | ||
476 | .name = "STMPE_ADC", | ||
477 | .flags = IORESOURCE_IRQ, | ||
478 | }, | ||
479 | }; | ||
480 | |||
481 | static const struct mfd_cell stmpe_adc_cell = { | ||
482 | .name = "stmpe-adc", | ||
483 | .of_compatible = "st,stmpe-adc", | ||
484 | .resources = stmpe_adc_resources, | ||
485 | .num_resources = ARRAY_SIZE(stmpe_adc_resources), | ||
486 | }; | ||
487 | |||
488 | /* | ||
467 | * STMPE811 or STMPE610 | 489 | * STMPE811 or STMPE610 |
468 | */ | 490 | */ |
469 | 491 | ||
@@ -497,6 +519,11 @@ static struct stmpe_variant_block stmpe811_blocks[] = { | |||
497 | .irq = STMPE811_IRQ_TOUCH_DET, | 519 | .irq = STMPE811_IRQ_TOUCH_DET, |
498 | .block = STMPE_BLOCK_TOUCHSCREEN, | 520 | .block = STMPE_BLOCK_TOUCHSCREEN, |
499 | }, | 521 | }, |
522 | { | ||
523 | .cell = &stmpe_adc_cell, | ||
524 | .irq = STMPE811_IRQ_TEMP_SENS, | ||
525 | .block = STMPE_BLOCK_ADC, | ||
526 | }, | ||
500 | }; | 527 | }; |
501 | 528 | ||
502 | static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, | 529 | static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, |
@@ -517,6 +544,35 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, | |||
517 | enable ? 0 : mask); | 544 | enable ? 0 : mask); |
518 | } | 545 | } |
519 | 546 | ||
547 | int stmpe811_adc_common_init(struct stmpe *stmpe) | ||
548 | { | ||
549 | int ret; | ||
550 | u8 adc_ctrl1, adc_ctrl1_mask; | ||
551 | |||
552 | adc_ctrl1 = STMPE_SAMPLE_TIME(stmpe->sample_time) | | ||
553 | STMPE_MOD_12B(stmpe->mod_12b) | | ||
554 | STMPE_REF_SEL(stmpe->ref_sel); | ||
555 | adc_ctrl1_mask = STMPE_SAMPLE_TIME(0xff) | STMPE_MOD_12B(0xff) | | ||
556 | STMPE_REF_SEL(0xff); | ||
557 | |||
558 | ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL1, | ||
559 | adc_ctrl1_mask, adc_ctrl1); | ||
560 | if (ret) { | ||
561 | dev_err(stmpe->dev, "Could not setup ADC\n"); | ||
562 | return ret; | ||
563 | } | ||
564 | |||
565 | ret = stmpe_set_bits(stmpe, STMPE811_REG_ADC_CTRL2, | ||
566 | STMPE_ADC_FREQ(0xff), STMPE_ADC_FREQ(stmpe->adc_freq)); | ||
567 | if (ret) { | ||
568 | dev_err(stmpe->dev, "Could not setup ADC\n"); | ||
569 | return ret; | ||
570 | } | ||
571 | |||
572 | return 0; | ||
573 | } | ||
574 | EXPORT_SYMBOL_GPL(stmpe811_adc_common_init); | ||
575 | |||
520 | static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) | 576 | static int stmpe811_get_altfunc(struct stmpe *stmpe, enum stmpe_block block) |
521 | { | 577 | { |
522 | /* 0 for touchscreen, 1 for GPIO */ | 578 | /* 0 for touchscreen, 1 for GPIO */ |
@@ -1325,6 +1381,7 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) | |||
1325 | struct device_node *np = ci->dev->of_node; | 1381 | struct device_node *np = ci->dev->of_node; |
1326 | struct stmpe *stmpe; | 1382 | struct stmpe *stmpe; |
1327 | int ret; | 1383 | int ret; |
1384 | u32 val; | ||
1328 | 1385 | ||
1329 | pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL); | 1386 | pdata = devm_kzalloc(ci->dev, sizeof(*pdata), GFP_KERNEL); |
1330 | if (!pdata) | 1387 | if (!pdata) |
@@ -1342,6 +1399,15 @@ int stmpe_probe(struct stmpe_client_info *ci, enum stmpe_partnum partnum) | |||
1342 | mutex_init(&stmpe->irq_lock); | 1399 | mutex_init(&stmpe->irq_lock); |
1343 | mutex_init(&stmpe->lock); | 1400 | mutex_init(&stmpe->lock); |
1344 | 1401 | ||
1402 | if (!of_property_read_u32(np, "st,sample-time", &val)) | ||
1403 | stmpe->sample_time = val; | ||
1404 | if (!of_property_read_u32(np, "st,mod-12b", &val)) | ||
1405 | stmpe->mod_12b = val; | ||
1406 | if (!of_property_read_u32(np, "st,ref-sel", &val)) | ||
1407 | stmpe->ref_sel = val; | ||
1408 | if (!of_property_read_u32(np, "st,adc-freq", &val)) | ||
1409 | stmpe->adc_freq = val; | ||
1410 | |||
1345 | stmpe->dev = ci->dev; | 1411 | stmpe->dev = ci->dev; |
1346 | stmpe->client = ci->client; | 1412 | stmpe->client = ci->client; |
1347 | stmpe->pdata = pdata; | 1413 | stmpe->pdata = pdata; |
@@ -1433,6 +1499,8 @@ int stmpe_remove(struct stmpe *stmpe) | |||
1433 | if (!IS_ERR(stmpe->vcc)) | 1499 | if (!IS_ERR(stmpe->vcc)) |
1434 | regulator_disable(stmpe->vcc); | 1500 | regulator_disable(stmpe->vcc); |
1435 | 1501 | ||
1502 | __stmpe_disable(stmpe, STMPE_BLOCK_ADC); | ||
1503 | |||
1436 | mfd_remove_devices(stmpe->dev); | 1504 | mfd_remove_devices(stmpe->dev); |
1437 | 1505 | ||
1438 | return 0; | 1506 | return 0; |
diff --git a/drivers/mfd/stpmic1.c b/drivers/mfd/stpmic1.c new file mode 100644 index 000000000000..7dfbe8906cb8 --- /dev/null +++ b/drivers/mfd/stpmic1.c | |||
@@ -0,0 +1,213 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (C) STMicroelectronics 2018 | ||
3 | // Author: Pascal Paillet <p.paillet@st.com> | ||
4 | |||
5 | #include <linux/i2c.h> | ||
6 | #include <linux/interrupt.h> | ||
7 | #include <linux/mfd/core.h> | ||
8 | #include <linux/mfd/stpmic1.h> | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/of.h> | ||
11 | #include <linux/of_irq.h> | ||
12 | #include <linux/of_platform.h> | ||
13 | #include <linux/pm_wakeirq.h> | ||
14 | #include <linux/regmap.h> | ||
15 | |||
16 | #include <dt-bindings/mfd/st,stpmic1.h> | ||
17 | |||
18 | #define STPMIC1_MAIN_IRQ 0 | ||
19 | |||
20 | static const struct regmap_range stpmic1_readable_ranges[] = { | ||
21 | regmap_reg_range(TURN_ON_SR, VERSION_SR), | ||
22 | regmap_reg_range(SWOFF_PWRCTRL_CR, LDO6_STDBY_CR), | ||
23 | regmap_reg_range(BST_SW_CR, BST_SW_CR), | ||
24 | regmap_reg_range(INT_PENDING_R1, INT_PENDING_R4), | ||
25 | regmap_reg_range(INT_CLEAR_R1, INT_CLEAR_R4), | ||
26 | regmap_reg_range(INT_MASK_R1, INT_MASK_R4), | ||
27 | regmap_reg_range(INT_SET_MASK_R1, INT_SET_MASK_R4), | ||
28 | regmap_reg_range(INT_CLEAR_MASK_R1, INT_CLEAR_MASK_R4), | ||
29 | regmap_reg_range(INT_SRC_R1, INT_SRC_R1), | ||
30 | }; | ||
31 | |||
32 | static const struct regmap_range stpmic1_writeable_ranges[] = { | ||
33 | regmap_reg_range(SWOFF_PWRCTRL_CR, LDO6_STDBY_CR), | ||
34 | regmap_reg_range(BST_SW_CR, BST_SW_CR), | ||
35 | regmap_reg_range(INT_CLEAR_R1, INT_CLEAR_R4), | ||
36 | regmap_reg_range(INT_SET_MASK_R1, INT_SET_MASK_R4), | ||
37 | regmap_reg_range(INT_CLEAR_MASK_R1, INT_CLEAR_MASK_R4), | ||
38 | }; | ||
39 | |||
40 | static const struct regmap_range stpmic1_volatile_ranges[] = { | ||
41 | regmap_reg_range(TURN_ON_SR, VERSION_SR), | ||
42 | regmap_reg_range(WCHDG_CR, WCHDG_CR), | ||
43 | regmap_reg_range(INT_PENDING_R1, INT_PENDING_R4), | ||
44 | regmap_reg_range(INT_SRC_R1, INT_SRC_R4), | ||
45 | }; | ||
46 | |||
47 | static const struct regmap_access_table stpmic1_readable_table = { | ||
48 | .yes_ranges = stpmic1_readable_ranges, | ||
49 | .n_yes_ranges = ARRAY_SIZE(stpmic1_readable_ranges), | ||
50 | }; | ||
51 | |||
52 | static const struct regmap_access_table stpmic1_writeable_table = { | ||
53 | .yes_ranges = stpmic1_writeable_ranges, | ||
54 | .n_yes_ranges = ARRAY_SIZE(stpmic1_writeable_ranges), | ||
55 | }; | ||
56 | |||
57 | static const struct regmap_access_table stpmic1_volatile_table = { | ||
58 | .yes_ranges = stpmic1_volatile_ranges, | ||
59 | .n_yes_ranges = ARRAY_SIZE(stpmic1_volatile_ranges), | ||
60 | }; | ||
61 | |||
62 | const struct regmap_config stpmic1_regmap_config = { | ||
63 | .reg_bits = 8, | ||
64 | .val_bits = 8, | ||
65 | .cache_type = REGCACHE_RBTREE, | ||
66 | .max_register = PMIC_MAX_REGISTER_ADDRESS, | ||
67 | .rd_table = &stpmic1_readable_table, | ||
68 | .wr_table = &stpmic1_writeable_table, | ||
69 | .volatile_table = &stpmic1_volatile_table, | ||
70 | }; | ||
71 | |||
72 | static const struct regmap_irq stpmic1_irqs[] = { | ||
73 | REGMAP_IRQ_REG(IT_PONKEY_F, 0, 0x01), | ||
74 | REGMAP_IRQ_REG(IT_PONKEY_R, 0, 0x02), | ||
75 | REGMAP_IRQ_REG(IT_WAKEUP_F, 0, 0x04), | ||
76 | REGMAP_IRQ_REG(IT_WAKEUP_R, 0, 0x08), | ||
77 | REGMAP_IRQ_REG(IT_VBUS_OTG_F, 0, 0x10), | ||
78 | REGMAP_IRQ_REG(IT_VBUS_OTG_R, 0, 0x20), | ||
79 | REGMAP_IRQ_REG(IT_SWOUT_F, 0, 0x40), | ||
80 | REGMAP_IRQ_REG(IT_SWOUT_R, 0, 0x80), | ||
81 | |||
82 | REGMAP_IRQ_REG(IT_CURLIM_BUCK1, 1, 0x01), | ||
83 | REGMAP_IRQ_REG(IT_CURLIM_BUCK2, 1, 0x02), | ||
84 | REGMAP_IRQ_REG(IT_CURLIM_BUCK3, 1, 0x04), | ||
85 | REGMAP_IRQ_REG(IT_CURLIM_BUCK4, 1, 0x08), | ||
86 | REGMAP_IRQ_REG(IT_OCP_OTG, 1, 0x10), | ||
87 | REGMAP_IRQ_REG(IT_OCP_SWOUT, 1, 0x20), | ||
88 | REGMAP_IRQ_REG(IT_OCP_BOOST, 1, 0x40), | ||
89 | REGMAP_IRQ_REG(IT_OVP_BOOST, 1, 0x80), | ||
90 | |||
91 | REGMAP_IRQ_REG(IT_CURLIM_LDO1, 2, 0x01), | ||
92 | REGMAP_IRQ_REG(IT_CURLIM_LDO2, 2, 0x02), | ||
93 | REGMAP_IRQ_REG(IT_CURLIM_LDO3, 2, 0x04), | ||
94 | REGMAP_IRQ_REG(IT_CURLIM_LDO4, 2, 0x08), | ||
95 | REGMAP_IRQ_REG(IT_CURLIM_LDO5, 2, 0x10), | ||
96 | REGMAP_IRQ_REG(IT_CURLIM_LDO6, 2, 0x20), | ||
97 | REGMAP_IRQ_REG(IT_SHORT_SWOTG, 2, 0x40), | ||
98 | REGMAP_IRQ_REG(IT_SHORT_SWOUT, 2, 0x80), | ||
99 | |||
100 | REGMAP_IRQ_REG(IT_TWARN_F, 3, 0x01), | ||
101 | REGMAP_IRQ_REG(IT_TWARN_R, 3, 0x02), | ||
102 | REGMAP_IRQ_REG(IT_VINLOW_F, 3, 0x04), | ||
103 | REGMAP_IRQ_REG(IT_VINLOW_R, 3, 0x08), | ||
104 | REGMAP_IRQ_REG(IT_SWIN_F, 3, 0x40), | ||
105 | REGMAP_IRQ_REG(IT_SWIN_R, 3, 0x80), | ||
106 | }; | ||
107 | |||
108 | static const struct regmap_irq_chip stpmic1_regmap_irq_chip = { | ||
109 | .name = "pmic_irq", | ||
110 | .status_base = INT_PENDING_R1, | ||
111 | .mask_base = INT_CLEAR_MASK_R1, | ||
112 | .unmask_base = INT_SET_MASK_R1, | ||
113 | .ack_base = INT_CLEAR_R1, | ||
114 | .num_regs = STPMIC1_PMIC_NUM_IRQ_REGS, | ||
115 | .irqs = stpmic1_irqs, | ||
116 | .num_irqs = ARRAY_SIZE(stpmic1_irqs), | ||
117 | }; | ||
118 | |||
119 | static int stpmic1_probe(struct i2c_client *i2c, | ||
120 | const struct i2c_device_id *id) | ||
121 | { | ||
122 | struct stpmic1 *ddata; | ||
123 | struct device *dev = &i2c->dev; | ||
124 | int ret; | ||
125 | struct device_node *np = dev->of_node; | ||
126 | u32 reg; | ||
127 | |||
128 | ddata = devm_kzalloc(dev, sizeof(struct stpmic1), GFP_KERNEL); | ||
129 | if (!ddata) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | i2c_set_clientdata(i2c, ddata); | ||
133 | ddata->dev = dev; | ||
134 | |||
135 | ddata->regmap = devm_regmap_init_i2c(i2c, &stpmic1_regmap_config); | ||
136 | if (IS_ERR(ddata->regmap)) | ||
137 | return PTR_ERR(ddata->regmap); | ||
138 | |||
139 | ddata->irq = of_irq_get(np, STPMIC1_MAIN_IRQ); | ||
140 | if (ddata->irq < 0) { | ||
141 | dev_err(dev, "Failed to get main IRQ: %d\n", ddata->irq); | ||
142 | return ddata->irq; | ||
143 | } | ||
144 | |||
145 | ret = regmap_read(ddata->regmap, VERSION_SR, ®); | ||
146 | if (ret) { | ||
147 | dev_err(dev, "Unable to read PMIC version\n"); | ||
148 | return ret; | ||
149 | } | ||
150 | dev_info(dev, "PMIC Chip Version: 0x%x\n", reg); | ||
151 | |||
152 | /* Initialize PMIC IRQ Chip & associated IRQ domains */ | ||
153 | ret = devm_regmap_add_irq_chip(dev, ddata->regmap, ddata->irq, | ||
154 | IRQF_ONESHOT | IRQF_SHARED, | ||
155 | 0, &stpmic1_regmap_irq_chip, | ||
156 | &ddata->irq_data); | ||
157 | if (ret) { | ||
158 | dev_err(dev, "IRQ Chip registration failed: %d\n", ret); | ||
159 | return ret; | ||
160 | } | ||
161 | |||
162 | return devm_of_platform_populate(dev); | ||
163 | } | ||
164 | |||
165 | #ifdef CONFIG_PM_SLEEP | ||
166 | static int stpmic1_suspend(struct device *dev) | ||
167 | { | ||
168 | struct i2c_client *i2c = to_i2c_client(dev); | ||
169 | struct stpmic1 *pmic_dev = i2c_get_clientdata(i2c); | ||
170 | |||
171 | disable_irq(pmic_dev->irq); | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | static int stpmic1_resume(struct device *dev) | ||
177 | { | ||
178 | struct i2c_client *i2c = to_i2c_client(dev); | ||
179 | struct stpmic1 *pmic_dev = i2c_get_clientdata(i2c); | ||
180 | int ret; | ||
181 | |||
182 | ret = regcache_sync(pmic_dev->regmap); | ||
183 | if (ret) | ||
184 | return ret; | ||
185 | |||
186 | enable_irq(pmic_dev->irq); | ||
187 | |||
188 | return 0; | ||
189 | } | ||
190 | #endif | ||
191 | |||
192 | static SIMPLE_DEV_PM_OPS(stpmic1_pm, stpmic1_suspend, stpmic1_resume); | ||
193 | |||
194 | static const struct of_device_id stpmic1_of_match[] = { | ||
195 | { .compatible = "st,stpmic1", }, | ||
196 | {}, | ||
197 | }; | ||
198 | MODULE_DEVICE_TABLE(of, stpmic1_of_match); | ||
199 | |||
200 | static struct i2c_driver stpmic1_driver = { | ||
201 | .driver = { | ||
202 | .name = "stpmic1", | ||
203 | .of_match_table = of_match_ptr(stpmic1_of_match), | ||
204 | .pm = &stpmic1_pm, | ||
205 | }, | ||
206 | .probe = stpmic1_probe, | ||
207 | }; | ||
208 | |||
209 | module_i2c_driver(stpmic1_driver); | ||
210 | |||
211 | MODULE_DESCRIPTION("STPMIC1 PMIC Driver"); | ||
212 | MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>"); | ||
213 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index b6d05cd934e6..0ecdffb3d967 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/err.h> | 15 | #include <linux/err.h> |
16 | #include <linux/hwspinlock.h> | 16 | #include <linux/hwspinlock.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | #include <linux/module.h> | 18 | #include <linux/init.h> |
19 | #include <linux/list.h> | 19 | #include <linux/list.h> |
20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
21 | #include <linux/of_address.h> | 21 | #include <linux/of_address.h> |
@@ -272,13 +272,3 @@ static int __init syscon_init(void) | |||
272 | return platform_driver_register(&syscon_driver); | 272 | return platform_driver_register(&syscon_driver); |
273 | } | 273 | } |
274 | postcore_initcall(syscon_init); | 274 | postcore_initcall(syscon_init); |
275 | |||
276 | static void __exit syscon_exit(void) | ||
277 | { | ||
278 | platform_driver_unregister(&syscon_driver); | ||
279 | } | ||
280 | module_exit(syscon_exit); | ||
281 | |||
282 | MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>"); | ||
283 | MODULE_DESCRIPTION("System Control driver"); | ||
284 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c index f13e4cd06e89..6968df4d7828 100644 --- a/drivers/mfd/tps65090.c +++ b/drivers/mfd/tps65090.c | |||
@@ -2,7 +2,9 @@ | |||
2 | * Core driver for TI TPS65090 PMIC family | 2 | * Core driver for TI TPS65090 PMIC family |
3 | * | 3 | * |
4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. | 4 | * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved. |
5 | 5 | * | |
6 | * Author: Venu Byravarasu <vbyravarasu@nvidia.com> | ||
7 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms and conditions of the GNU General Public License, | 9 | * under the terms and conditions of the GNU General Public License, |
8 | * version 2, as published by the Free Software Foundation. | 10 | * version 2, as published by the Free Software Foundation. |
@@ -19,7 +21,7 @@ | |||
19 | #include <linux/interrupt.h> | 21 | #include <linux/interrupt.h> |
20 | #include <linux/irq.h> | 22 | #include <linux/irq.h> |
21 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 24 | #include <linux/init.h> |
23 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
24 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
25 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
@@ -171,7 +173,6 @@ static const struct of_device_id tps65090_of_match[] = { | |||
171 | { .compatible = "ti,tps65090",}, | 173 | { .compatible = "ti,tps65090",}, |
172 | {}, | 174 | {}, |
173 | }; | 175 | }; |
174 | MODULE_DEVICE_TABLE(of, tps65090_of_match); | ||
175 | #endif | 176 | #endif |
176 | 177 | ||
177 | static int tps65090_i2c_probe(struct i2c_client *client, | 178 | static int tps65090_i2c_probe(struct i2c_client *client, |
@@ -236,30 +237,19 @@ err_irq_exit: | |||
236 | return ret; | 237 | return ret; |
237 | } | 238 | } |
238 | 239 | ||
239 | static int tps65090_i2c_remove(struct i2c_client *client) | ||
240 | { | ||
241 | struct tps65090 *tps65090 = i2c_get_clientdata(client); | ||
242 | |||
243 | mfd_remove_devices(tps65090->dev); | ||
244 | if (client->irq) | ||
245 | regmap_del_irq_chip(client->irq, tps65090->irq_data); | ||
246 | |||
247 | return 0; | ||
248 | } | ||
249 | 240 | ||
250 | static const struct i2c_device_id tps65090_id_table[] = { | 241 | static const struct i2c_device_id tps65090_id_table[] = { |
251 | { "tps65090", 0 }, | 242 | { "tps65090", 0 }, |
252 | { }, | 243 | { }, |
253 | }; | 244 | }; |
254 | MODULE_DEVICE_TABLE(i2c, tps65090_id_table); | ||
255 | 245 | ||
256 | static struct i2c_driver tps65090_driver = { | 246 | static struct i2c_driver tps65090_driver = { |
257 | .driver = { | 247 | .driver = { |
258 | .name = "tps65090", | 248 | .name = "tps65090", |
249 | .suppress_bind_attrs = true, | ||
259 | .of_match_table = of_match_ptr(tps65090_of_match), | 250 | .of_match_table = of_match_ptr(tps65090_of_match), |
260 | }, | 251 | }, |
261 | .probe = tps65090_i2c_probe, | 252 | .probe = tps65090_i2c_probe, |
262 | .remove = tps65090_i2c_remove, | ||
263 | .id_table = tps65090_id_table, | 253 | .id_table = tps65090_id_table, |
264 | }; | 254 | }; |
265 | 255 | ||
@@ -268,13 +258,3 @@ static int __init tps65090_init(void) | |||
268 | return i2c_add_driver(&tps65090_driver); | 258 | return i2c_add_driver(&tps65090_driver); |
269 | } | 259 | } |
270 | subsys_initcall(tps65090_init); | 260 | subsys_initcall(tps65090_init); |
271 | |||
272 | static void __exit tps65090_exit(void) | ||
273 | { | ||
274 | i2c_del_driver(&tps65090_driver); | ||
275 | } | ||
276 | module_exit(tps65090_exit); | ||
277 | |||
278 | MODULE_DESCRIPTION("TPS65090 core driver"); | ||
279 | MODULE_AUTHOR("Venu Byravarasu <vbyravarasu@nvidia.com>"); | ||
280 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/tps65218.c b/drivers/mfd/tps65218.c index 8bcdecf494d0..a62ea4cb8be7 100644 --- a/drivers/mfd/tps65218.c +++ b/drivers/mfd/tps65218.c | |||
@@ -211,6 +211,83 @@ static const struct of_device_id of_tps65218_match_table[] = { | |||
211 | }; | 211 | }; |
212 | MODULE_DEVICE_TABLE(of, of_tps65218_match_table); | 212 | MODULE_DEVICE_TABLE(of, of_tps65218_match_table); |
213 | 213 | ||
214 | static int tps65218_voltage_set_strict(struct tps65218 *tps) | ||
215 | { | ||
216 | u32 strict; | ||
217 | |||
218 | if (of_property_read_u32(tps->dev->of_node, | ||
219 | "ti,strict-supply-voltage-supervision", | ||
220 | &strict)) | ||
221 | return 0; | ||
222 | |||
223 | if (strict != 0 && strict != 1) { | ||
224 | dev_err(tps->dev, | ||
225 | "Invalid ti,strict-supply-voltage-supervision value\n"); | ||
226 | return -EINVAL; | ||
227 | } | ||
228 | |||
229 | tps65218_update_bits(tps, TPS65218_REG_CONFIG1, | ||
230 | TPS65218_CONFIG1_STRICT, | ||
231 | strict ? TPS65218_CONFIG1_STRICT : 0, | ||
232 | TPS65218_PROTECT_L1); | ||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static int tps65218_voltage_set_uv_hyst(struct tps65218 *tps) | ||
237 | { | ||
238 | u32 hyst; | ||
239 | |||
240 | if (of_property_read_u32(tps->dev->of_node, | ||
241 | "ti,under-voltage-hyst-microvolt", &hyst)) | ||
242 | return 0; | ||
243 | |||
244 | if (hyst != 400000 && hyst != 200000) { | ||
245 | dev_err(tps->dev, | ||
246 | "Invalid ti,under-voltage-hyst-microvolt value\n"); | ||
247 | return -EINVAL; | ||
248 | } | ||
249 | |||
250 | tps65218_update_bits(tps, TPS65218_REG_CONFIG2, | ||
251 | TPS65218_CONFIG2_UVLOHYS, | ||
252 | hyst == 400000 ? TPS65218_CONFIG2_UVLOHYS : 0, | ||
253 | TPS65218_PROTECT_L1); | ||
254 | return 0; | ||
255 | } | ||
256 | |||
257 | static int tps65218_voltage_set_uvlo(struct tps65218 *tps) | ||
258 | { | ||
259 | u32 uvlo; | ||
260 | int uvloval; | ||
261 | |||
262 | if (of_property_read_u32(tps->dev->of_node, | ||
263 | "ti,under-voltage-limit-microvolt", &uvlo)) | ||
264 | return 0; | ||
265 | |||
266 | switch (uvlo) { | ||
267 | case 2750000: | ||
268 | uvloval = TPS65218_CONFIG1_UVLO_2750000; | ||
269 | break; | ||
270 | case 2950000: | ||
271 | uvloval = TPS65218_CONFIG1_UVLO_2950000; | ||
272 | break; | ||
273 | case 3250000: | ||
274 | uvloval = TPS65218_CONFIG1_UVLO_3250000; | ||
275 | break; | ||
276 | case 3350000: | ||
277 | uvloval = TPS65218_CONFIG1_UVLO_3350000; | ||
278 | break; | ||
279 | default: | ||
280 | dev_err(tps->dev, | ||
281 | "Invalid ti,under-voltage-limit-microvolt value\n"); | ||
282 | return -EINVAL; | ||
283 | } | ||
284 | |||
285 | tps65218_update_bits(tps, TPS65218_REG_CONFIG1, | ||
286 | TPS65218_CONFIG1_UVLO_MASK, uvloval, | ||
287 | TPS65218_PROTECT_L1); | ||
288 | return 0; | ||
289 | } | ||
290 | |||
214 | static int tps65218_probe(struct i2c_client *client, | 291 | static int tps65218_probe(struct i2c_client *client, |
215 | const struct i2c_device_id *ids) | 292 | const struct i2c_device_id *ids) |
216 | { | 293 | { |
@@ -249,6 +326,18 @@ static int tps65218_probe(struct i2c_client *client, | |||
249 | 326 | ||
250 | tps->rev = chipid & TPS65218_CHIPID_REV_MASK; | 327 | tps->rev = chipid & TPS65218_CHIPID_REV_MASK; |
251 | 328 | ||
329 | ret = tps65218_voltage_set_strict(tps); | ||
330 | if (ret) | ||
331 | return ret; | ||
332 | |||
333 | ret = tps65218_voltage_set_uvlo(tps); | ||
334 | if (ret) | ||
335 | return ret; | ||
336 | |||
337 | ret = tps65218_voltage_set_uv_hyst(tps); | ||
338 | if (ret) | ||
339 | return ret; | ||
340 | |||
252 | ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells, | 341 | ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells, |
253 | ARRAY_SIZE(tps65218_cells), NULL, 0, | 342 | ARRAY_SIZE(tps65218_cells), NULL, 0, |
254 | regmap_irq_get_domain(tps->irq_data)); | 343 | regmap_irq_get_domain(tps->irq_data)); |
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c index bf16cbe6fd88..aa3d472a10ff 100644 --- a/drivers/mfd/tps65910.c +++ b/drivers/mfd/tps65910.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * tps65910.c -- TI TPS6591x | 2 | * tps65910.c -- TI TPS6591x chip family multi-function driver |
3 | * | 3 | * |
4 | * Copyright 2010 Texas Instruments Inc. | 4 | * Copyright 2010 Texas Instruments Inc. |
5 | * | 5 | * |
@@ -13,8 +13,6 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/moduleparam.h> | ||
18 | #include <linux/init.h> | 16 | #include <linux/init.h> |
19 | #include <linux/err.h> | 17 | #include <linux/err.h> |
20 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
@@ -374,7 +372,6 @@ static const struct of_device_id tps65910_of_match[] = { | |||
374 | { .compatible = "ti,tps65911", .data = (void *)TPS65911}, | 372 | { .compatible = "ti,tps65911", .data = (void *)TPS65911}, |
375 | { }, | 373 | { }, |
376 | }; | 374 | }; |
377 | MODULE_DEVICE_TABLE(of, tps65910_of_match); | ||
378 | 375 | ||
379 | static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, | 376 | static struct tps65910_board *tps65910_parse_dt(struct i2c_client *client, |
380 | unsigned long *chip_id) | 377 | unsigned long *chip_id) |
@@ -527,8 +524,6 @@ static const struct i2c_device_id tps65910_i2c_id[] = { | |||
527 | { "tps65911", TPS65911 }, | 524 | { "tps65911", TPS65911 }, |
528 | { } | 525 | { } |
529 | }; | 526 | }; |
530 | MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id); | ||
531 | |||
532 | 527 | ||
533 | static struct i2c_driver tps65910_i2c_driver = { | 528 | static struct i2c_driver tps65910_i2c_driver = { |
534 | .driver = { | 529 | .driver = { |
@@ -545,14 +540,3 @@ static int __init tps65910_i2c_init(void) | |||
545 | } | 540 | } |
546 | /* init early so consumer devices can complete system boot */ | 541 | /* init early so consumer devices can complete system boot */ |
547 | subsys_initcall(tps65910_i2c_init); | 542 | subsys_initcall(tps65910_i2c_init); |
548 | |||
549 | static void __exit tps65910_i2c_exit(void) | ||
550 | { | ||
551 | i2c_del_driver(&tps65910_i2c_driver); | ||
552 | } | ||
553 | module_exit(tps65910_i2c_exit); | ||
554 | |||
555 | MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>"); | ||
556 | MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>"); | ||
557 | MODULE_DESCRIPTION("TPS6591x chip family multi-function driver"); | ||
558 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/tps68470.c b/drivers/mfd/tps68470.c index a5981a79b29a..4a4df4ffd18c 100644 --- a/drivers/mfd/tps68470.c +++ b/drivers/mfd/tps68470.c | |||
@@ -86,7 +86,6 @@ static const struct acpi_device_id tps68470_acpi_ids[] = { | |||
86 | {"INT3472"}, | 86 | {"INT3472"}, |
87 | {}, | 87 | {}, |
88 | }; | 88 | }; |
89 | MODULE_DEVICE_TABLE(acpi, tps68470_acpi_ids); | ||
90 | 89 | ||
91 | static struct i2c_driver tps68470_driver = { | 90 | static struct i2c_driver tps68470_driver = { |
92 | .driver = { | 91 | .driver = { |
diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index 608c7f77830e..865257ade8ac 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c | |||
@@ -30,7 +30,6 @@ | |||
30 | #include <linux/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/mfd/core.h> | 31 | #include <linux/mfd/core.h> |
32 | #include <linux/mfd/tps80031.h> | 32 | #include <linux/mfd/tps80031.h> |
33 | #include <linux/module.h> | ||
34 | #include <linux/pm.h> | 33 | #include <linux/pm.h> |
35 | #include <linux/regmap.h> | 34 | #include <linux/regmap.h> |
36 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
@@ -516,40 +515,18 @@ fail_client_reg: | |||
516 | return ret; | 515 | return ret; |
517 | } | 516 | } |
518 | 517 | ||
519 | static int tps80031_remove(struct i2c_client *client) | ||
520 | { | ||
521 | struct tps80031 *tps80031 = i2c_get_clientdata(client); | ||
522 | int i; | ||
523 | |||
524 | if (tps80031_power_off_dev == tps80031) { | ||
525 | tps80031_power_off_dev = NULL; | ||
526 | pm_power_off = NULL; | ||
527 | } | ||
528 | |||
529 | mfd_remove_devices(tps80031->dev); | ||
530 | |||
531 | regmap_del_irq_chip(client->irq, tps80031->irq_data); | ||
532 | |||
533 | for (i = 0; i < TPS80031_NUM_SLAVES; i++) { | ||
534 | if (tps80031->clients[i] != client) | ||
535 | i2c_unregister_device(tps80031->clients[i]); | ||
536 | } | ||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | static const struct i2c_device_id tps80031_id_table[] = { | 518 | static const struct i2c_device_id tps80031_id_table[] = { |
541 | { "tps80031", TPS80031 }, | 519 | { "tps80031", TPS80031 }, |
542 | { "tps80032", TPS80032 }, | 520 | { "tps80032", TPS80032 }, |
543 | { } | 521 | { } |
544 | }; | 522 | }; |
545 | MODULE_DEVICE_TABLE(i2c, tps80031_id_table); | ||
546 | 523 | ||
547 | static struct i2c_driver tps80031_driver = { | 524 | static struct i2c_driver tps80031_driver = { |
548 | .driver = { | 525 | .driver = { |
549 | .name = "tps80031", | 526 | .name = "tps80031", |
527 | .suppress_bind_attrs = true, | ||
550 | }, | 528 | }, |
551 | .probe = tps80031_probe, | 529 | .probe = tps80031_probe, |
552 | .remove = tps80031_remove, | ||
553 | .id_table = tps80031_id_table, | 530 | .id_table = tps80031_id_table, |
554 | }; | 531 | }; |
555 | 532 | ||
@@ -558,13 +535,3 @@ static int __init tps80031_init(void) | |||
558 | return i2c_add_driver(&tps80031_driver); | 535 | return i2c_add_driver(&tps80031_driver); |
559 | } | 536 | } |
560 | subsys_initcall(tps80031_init); | 537 | subsys_initcall(tps80031_init); |
561 | |||
562 | static void __exit tps80031_exit(void) | ||
563 | { | ||
564 | i2c_del_driver(&tps80031_driver); | ||
565 | } | ||
566 | module_exit(tps80031_exit); | ||
567 | |||
568 | MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); | ||
569 | MODULE_DESCRIPTION("TPS80031 core driver"); | ||
570 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/tqmx86.c b/drivers/mfd/tqmx86.c new file mode 100644 index 000000000000..22d2f02d855c --- /dev/null +++ b/drivers/mfd/tqmx86.c | |||
@@ -0,0 +1,281 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0+ | ||
2 | /* | ||
3 | * TQ-Systems PLD MFD core driver, based on vendor driver by | ||
4 | * Vadim V.Vlasov <vvlasov@dev.rtsoft.ru> | ||
5 | * | ||
6 | * Copyright (c) 2015 TQ-Systems GmbH | ||
7 | * Copyright (c) 2019 Andrew Lunn <andrew@lunn.ch> | ||
8 | */ | ||
9 | |||
10 | #include <linux/delay.h> | ||
11 | #include <linux/dmi.h> | ||
12 | #include <linux/i2c.h> | ||
13 | #include <linux/io.h> | ||
14 | #include <linux/mfd/core.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/platform_data/i2c-ocores.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #define TQMX86_IOBASE 0x160 | ||
20 | #define TQMX86_IOSIZE 0x3f | ||
21 | #define TQMX86_IOBASE_I2C 0x1a0 | ||
22 | #define TQMX86_IOSIZE_I2C 0xa | ||
23 | #define TQMX86_IOBASE_WATCHDOG 0x18b | ||
24 | #define TQMX86_IOSIZE_WATCHDOG 0x2 | ||
25 | #define TQMX86_IOBASE_GPIO 0x18d | ||
26 | #define TQMX86_IOSIZE_GPIO 0x4 | ||
27 | |||
28 | #define TQMX86_REG_BOARD_ID 0x20 | ||
29 | #define TQMX86_REG_BOARD_ID_E38M 1 | ||
30 | #define TQMX86_REG_BOARD_ID_50UC 2 | ||
31 | #define TQMX86_REG_BOARD_ID_E38C 3 | ||
32 | #define TQMX86_REG_BOARD_ID_60EB 4 | ||
33 | #define TQMX86_REG_BOARD_ID_E39M 5 | ||
34 | #define TQMX86_REG_BOARD_ID_E39C 6 | ||
35 | #define TQMX86_REG_BOARD_ID_E39x 7 | ||
36 | #define TQMX86_REG_BOARD_ID_70EB 8 | ||
37 | #define TQMX86_REG_BOARD_ID_80UC 9 | ||
38 | #define TQMX86_REG_BOARD_ID_90UC 10 | ||
39 | #define TQMX86_REG_BOARD_REV 0x21 | ||
40 | #define TQMX86_REG_IO_EXT_INT 0x26 | ||
41 | #define TQMX86_REG_IO_EXT_INT_NONE 0 | ||
42 | #define TQMX86_REG_IO_EXT_INT_7 1 | ||
43 | #define TQMX86_REG_IO_EXT_INT_9 2 | ||
44 | #define TQMX86_REG_IO_EXT_INT_12 3 | ||
45 | #define TQMX86_REG_IO_EXT_INT_MASK 0x3 | ||
46 | #define TQMX86_REG_IO_EXT_INT_GPIO_SHIFT 4 | ||
47 | |||
48 | #define TQMX86_REG_I2C_DETECT 0x47 | ||
49 | #define TQMX86_REG_I2C_DETECT_SOFT 0xa5 | ||
50 | #define TQMX86_REG_I2C_INT_EN 0x49 | ||
51 | |||
52 | static uint gpio_irq; | ||
53 | module_param(gpio_irq, uint, 0); | ||
54 | MODULE_PARM_DESC(gpio_irq, "GPIO IRQ number (7, 9, 12)"); | ||
55 | |||
56 | static const struct resource tqmx_i2c_soft_resources[] = { | ||
57 | DEFINE_RES_IO(TQMX86_IOBASE_I2C, TQMX86_IOSIZE_I2C), | ||
58 | }; | ||
59 | |||
60 | static const struct resource tqmx_watchdog_resources[] = { | ||
61 | DEFINE_RES_IO(TQMX86_IOBASE_WATCHDOG, TQMX86_IOSIZE_WATCHDOG), | ||
62 | }; | ||
63 | |||
64 | /* | ||
65 | * The IRQ resource must be first, since it is updated with the | ||
66 | * configured IRQ in the probe function. | ||
67 | */ | ||
68 | static struct resource tqmx_gpio_resources[] = { | ||
69 | DEFINE_RES_IRQ(0), | ||
70 | DEFINE_RES_IO(TQMX86_IOBASE_GPIO, TQMX86_IOSIZE_GPIO), | ||
71 | }; | ||
72 | |||
73 | static struct i2c_board_info tqmx86_i2c_devices[] = { | ||
74 | { | ||
75 | /* 4K EEPROM at 0x50 */ | ||
76 | I2C_BOARD_INFO("24c32", 0x50), | ||
77 | }, | ||
78 | }; | ||
79 | |||
80 | static struct ocores_i2c_platform_data ocores_platfom_data = { | ||
81 | .num_devices = ARRAY_SIZE(tqmx86_i2c_devices), | ||
82 | .devices = tqmx86_i2c_devices, | ||
83 | }; | ||
84 | |||
85 | static const struct mfd_cell tqmx86_i2c_soft_dev[] = { | ||
86 | { | ||
87 | .name = "ocores-i2c", | ||
88 | .platform_data = &ocores_platfom_data, | ||
89 | .pdata_size = sizeof(ocores_platfom_data), | ||
90 | .resources = tqmx_i2c_soft_resources, | ||
91 | .num_resources = ARRAY_SIZE(tqmx_i2c_soft_resources), | ||
92 | }, | ||
93 | }; | ||
94 | |||
95 | static const struct mfd_cell tqmx86_devs[] = { | ||
96 | { | ||
97 | .name = "tqmx86-wdt", | ||
98 | .resources = tqmx_watchdog_resources, | ||
99 | .num_resources = ARRAY_SIZE(tqmx_watchdog_resources), | ||
100 | .ignore_resource_conflicts = true, | ||
101 | }, | ||
102 | { | ||
103 | .name = "tqmx86-gpio", | ||
104 | .resources = tqmx_gpio_resources, | ||
105 | .num_resources = ARRAY_SIZE(tqmx_gpio_resources), | ||
106 | .ignore_resource_conflicts = true, | ||
107 | }, | ||
108 | }; | ||
109 | |||
110 | static const char *tqmx86_board_id_to_name(u8 board_id) | ||
111 | { | ||
112 | switch (board_id) { | ||
113 | case TQMX86_REG_BOARD_ID_E38M: | ||
114 | return "TQMxE38M"; | ||
115 | case TQMX86_REG_BOARD_ID_50UC: | ||
116 | return "TQMx50UC"; | ||
117 | case TQMX86_REG_BOARD_ID_E38C: | ||
118 | return "TQMxE38C"; | ||
119 | case TQMX86_REG_BOARD_ID_60EB: | ||
120 | return "TQMx60EB"; | ||
121 | case TQMX86_REG_BOARD_ID_E39M: | ||
122 | return "TQMxE39M"; | ||
123 | case TQMX86_REG_BOARD_ID_E39C: | ||
124 | return "TQMxE39C"; | ||
125 | case TQMX86_REG_BOARD_ID_E39x: | ||
126 | return "TQMxE39x"; | ||
127 | case TQMX86_REG_BOARD_ID_70EB: | ||
128 | return "TQMx70EB"; | ||
129 | case TQMX86_REG_BOARD_ID_80UC: | ||
130 | return "TQMx80UC"; | ||
131 | case TQMX86_REG_BOARD_ID_90UC: | ||
132 | return "TQMx90UC"; | ||
133 | default: | ||
134 | return "Unknown"; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | static int tqmx86_board_id_to_clk_rate(u8 board_id) | ||
139 | { | ||
140 | switch (board_id) { | ||
141 | case TQMX86_REG_BOARD_ID_50UC: | ||
142 | case TQMX86_REG_BOARD_ID_60EB: | ||
143 | case TQMX86_REG_BOARD_ID_70EB: | ||
144 | case TQMX86_REG_BOARD_ID_80UC: | ||
145 | case TQMX86_REG_BOARD_ID_90UC: | ||
146 | return 24000; | ||
147 | case TQMX86_REG_BOARD_ID_E39M: | ||
148 | case TQMX86_REG_BOARD_ID_E39C: | ||
149 | case TQMX86_REG_BOARD_ID_E39x: | ||
150 | return 25000; | ||
151 | case TQMX86_REG_BOARD_ID_E38M: | ||
152 | case TQMX86_REG_BOARD_ID_E38C: | ||
153 | return 33000; | ||
154 | default: | ||
155 | return 0; | ||
156 | } | ||
157 | } | ||
158 | |||
159 | static int tqmx86_probe(struct platform_device *pdev) | ||
160 | { | ||
161 | u8 board_id, rev, i2c_det, i2c_ien, io_ext_int_val; | ||
162 | struct device *dev = &pdev->dev; | ||
163 | u8 gpio_irq_cfg, readback; | ||
164 | const char *board_name; | ||
165 | void __iomem *io_base; | ||
166 | int err; | ||
167 | |||
168 | switch (gpio_irq) { | ||
169 | case 0: | ||
170 | gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_NONE; | ||
171 | break; | ||
172 | case 7: | ||
173 | gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_7; | ||
174 | break; | ||
175 | case 9: | ||
176 | gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_9; | ||
177 | break; | ||
178 | case 12: | ||
179 | gpio_irq_cfg = TQMX86_REG_IO_EXT_INT_12; | ||
180 | break; | ||
181 | default: | ||
182 | pr_err("tqmx86: Invalid GPIO IRQ (%d)\n", gpio_irq); | ||
183 | return -EINVAL; | ||
184 | } | ||
185 | |||
186 | io_base = devm_ioport_map(dev, TQMX86_IOBASE, TQMX86_IOSIZE); | ||
187 | if (!io_base) | ||
188 | return -ENOMEM; | ||
189 | |||
190 | board_id = ioread8(io_base + TQMX86_REG_BOARD_ID); | ||
191 | board_name = tqmx86_board_id_to_name(board_id); | ||
192 | rev = ioread8(io_base + TQMX86_REG_BOARD_REV); | ||
193 | |||
194 | dev_info(dev, | ||
195 | "Found %s - Board ID %d, PCB Revision %d, PLD Revision %d\n", | ||
196 | board_name, board_id, rev >> 4, rev & 0xf); | ||
197 | |||
198 | i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT); | ||
199 | i2c_ien = ioread8(io_base + TQMX86_REG_I2C_INT_EN); | ||
200 | |||
201 | if (gpio_irq_cfg) { | ||
202 | io_ext_int_val = | ||
203 | gpio_irq_cfg << TQMX86_REG_IO_EXT_INT_GPIO_SHIFT; | ||
204 | iowrite8(io_ext_int_val, io_base + TQMX86_REG_IO_EXT_INT); | ||
205 | readback = ioread8(io_base + TQMX86_REG_IO_EXT_INT); | ||
206 | if (readback != io_ext_int_val) { | ||
207 | dev_warn(dev, "GPIO interrupts not supported.\n"); | ||
208 | return -EINVAL; | ||
209 | } | ||
210 | |||
211 | /* Assumes the IRQ resource is first. */ | ||
212 | tqmx_gpio_resources[0].start = gpio_irq; | ||
213 | } | ||
214 | |||
215 | ocores_platfom_data.clock_khz = tqmx86_board_id_to_clk_rate(board_id); | ||
216 | |||
217 | if (i2c_det == TQMX86_REG_I2C_DETECT_SOFT) { | ||
218 | err = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, | ||
219 | tqmx86_i2c_soft_dev, | ||
220 | ARRAY_SIZE(tqmx86_i2c_soft_dev), | ||
221 | NULL, 0, NULL); | ||
222 | if (err) | ||
223 | return err; | ||
224 | } | ||
225 | |||
226 | return devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, | ||
227 | tqmx86_devs, | ||
228 | ARRAY_SIZE(tqmx86_devs), | ||
229 | NULL, 0, NULL); | ||
230 | } | ||
231 | |||
232 | static int tqmx86_create_platform_device(const struct dmi_system_id *id) | ||
233 | { | ||
234 | struct platform_device *pdev; | ||
235 | int err; | ||
236 | |||
237 | pdev = platform_device_alloc("tqmx86", -1); | ||
238 | if (!pdev) | ||
239 | return -ENOMEM; | ||
240 | |||
241 | err = platform_device_add(pdev); | ||
242 | if (err) | ||
243 | platform_device_put(pdev); | ||
244 | |||
245 | return err; | ||
246 | } | ||
247 | |||
248 | static const struct dmi_system_id tqmx86_dmi_table[] __initconst = { | ||
249 | { | ||
250 | .ident = "TQMX86", | ||
251 | .matches = { | ||
252 | DMI_MATCH(DMI_SYS_VENDOR, "TQ-Group"), | ||
253 | DMI_MATCH(DMI_PRODUCT_NAME, "TQMx"), | ||
254 | }, | ||
255 | .callback = tqmx86_create_platform_device, | ||
256 | }, | ||
257 | {} | ||
258 | }; | ||
259 | MODULE_DEVICE_TABLE(dmi, tqmx86_dmi_table); | ||
260 | |||
261 | static struct platform_driver tqmx86_driver = { | ||
262 | .driver = { | ||
263 | .name = "tqmx86", | ||
264 | }, | ||
265 | .probe = tqmx86_probe, | ||
266 | }; | ||
267 | |||
268 | static int __init tqmx86_init(void) | ||
269 | { | ||
270 | if (!dmi_check_system(tqmx86_dmi_table)) | ||
271 | return -ENODEV; | ||
272 | |||
273 | return platform_driver_register(&tqmx86_driver); | ||
274 | } | ||
275 | |||
276 | module_init(tqmx86_init); | ||
277 | |||
278 | MODULE_DESCRIPTION("TQx86 PLD Core Driver"); | ||
279 | MODULE_AUTHOR("Andrew Lunn <andrew@lunn.ch>"); | ||
280 | MODULE_LICENSE("GPL"); | ||
281 | MODULE_ALIAS("platform:tqmx86"); | ||
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index e70d35ef5c6d..25fbbaf39cb9 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -13,7 +13,8 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/init.h> |
17 | #include <linux/export.h> | ||
17 | #include <linux/bcd.h> | 18 | #include <linux/bcd.h> |
18 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
19 | #include <linux/mfd/core.h> | 20 | #include <linux/mfd/core.h> |
@@ -1892,14 +1893,6 @@ err: | |||
1892 | return ret; | 1893 | return ret; |
1893 | } | 1894 | } |
1894 | 1895 | ||
1895 | void wm831x_device_exit(struct wm831x *wm831x) | ||
1896 | { | ||
1897 | wm831x_otp_exit(wm831x); | ||
1898 | mfd_remove_devices(wm831x->dev); | ||
1899 | free_irq(wm831x_irq(wm831x, WM831X_IRQ_AUXADC_DATA), wm831x); | ||
1900 | wm831x_irq_exit(wm831x); | ||
1901 | } | ||
1902 | |||
1903 | int wm831x_device_suspend(struct wm831x *wm831x) | 1896 | int wm831x_device_suspend(struct wm831x *wm831x) |
1904 | { | 1897 | { |
1905 | int reg, mask; | 1898 | int reg, mask; |
@@ -1944,7 +1937,3 @@ void wm831x_device_shutdown(struct wm831x *wm831x) | |||
1944 | } | 1937 | } |
1945 | } | 1938 | } |
1946 | EXPORT_SYMBOL_GPL(wm831x_device_shutdown); | 1939 | EXPORT_SYMBOL_GPL(wm831x_device_shutdown); |
1947 | |||
1948 | MODULE_DESCRIPTION("Core support for the WM831X AudioPlus PMIC"); | ||
1949 | MODULE_LICENSE("GPL"); | ||
1950 | MODULE_AUTHOR("Mark Brown"); | ||
diff --git a/drivers/mfd/wm831x-i2c.c b/drivers/mfd/wm831x-i2c.c index 22f7054d1b28..0f3af42f7268 100644 --- a/drivers/mfd/wm831x-i2c.c +++ b/drivers/mfd/wm831x-i2c.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/init.h> |
17 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
@@ -68,15 +68,6 @@ static int wm831x_i2c_probe(struct i2c_client *i2c, | |||
68 | return wm831x_device_init(wm831x, i2c->irq); | 68 | return wm831x_device_init(wm831x, i2c->irq); |
69 | } | 69 | } |
70 | 70 | ||
71 | static int wm831x_i2c_remove(struct i2c_client *i2c) | ||
72 | { | ||
73 | struct wm831x *wm831x = i2c_get_clientdata(i2c); | ||
74 | |||
75 | wm831x_device_exit(wm831x); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int wm831x_i2c_suspend(struct device *dev) | 71 | static int wm831x_i2c_suspend(struct device *dev) |
81 | { | 72 | { |
82 | struct wm831x *wm831x = dev_get_drvdata(dev); | 73 | struct wm831x *wm831x = dev_get_drvdata(dev); |
@@ -103,7 +94,6 @@ static const struct i2c_device_id wm831x_i2c_id[] = { | |||
103 | { "wm8326", WM8326 }, | 94 | { "wm8326", WM8326 }, |
104 | { } | 95 | { } |
105 | }; | 96 | }; |
106 | MODULE_DEVICE_TABLE(i2c, wm831x_i2c_id); | ||
107 | 97 | ||
108 | static const struct dev_pm_ops wm831x_pm_ops = { | 98 | static const struct dev_pm_ops wm831x_pm_ops = { |
109 | .suspend = wm831x_i2c_suspend, | 99 | .suspend = wm831x_i2c_suspend, |
@@ -115,9 +105,9 @@ static struct i2c_driver wm831x_i2c_driver = { | |||
115 | .name = "wm831x", | 105 | .name = "wm831x", |
116 | .pm = &wm831x_pm_ops, | 106 | .pm = &wm831x_pm_ops, |
117 | .of_match_table = of_match_ptr(wm831x_of_match), | 107 | .of_match_table = of_match_ptr(wm831x_of_match), |
108 | .suppress_bind_attrs = true, | ||
118 | }, | 109 | }, |
119 | .probe = wm831x_i2c_probe, | 110 | .probe = wm831x_i2c_probe, |
120 | .remove = wm831x_i2c_remove, | ||
121 | .id_table = wm831x_i2c_id, | 111 | .id_table = wm831x_i2c_id, |
122 | }; | 112 | }; |
123 | 113 | ||
@@ -132,9 +122,3 @@ static int __init wm831x_i2c_init(void) | |||
132 | return ret; | 122 | return ret; |
133 | } | 123 | } |
134 | subsys_initcall(wm831x_i2c_init); | 124 | subsys_initcall(wm831x_i2c_init); |
135 | |||
136 | static void __exit wm831x_i2c_exit(void) | ||
137 | { | ||
138 | i2c_del_driver(&wm831x_i2c_driver); | ||
139 | } | ||
140 | module_exit(wm831x_i2c_exit); | ||
diff --git a/drivers/mfd/wm831x-spi.c b/drivers/mfd/wm831x-spi.c index 018ce652ae57..dd4dab419940 100644 --- a/drivers/mfd/wm831x-spi.c +++ b/drivers/mfd/wm831x-spi.c | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/init.h> |
17 | #include <linux/of.h> | 17 | #include <linux/of.h> |
18 | #include <linux/of_device.h> | 18 | #include <linux/of_device.h> |
19 | #include <linux/pm.h> | 19 | #include <linux/pm.h> |
@@ -67,15 +67,6 @@ static int wm831x_spi_probe(struct spi_device *spi) | |||
67 | return wm831x_device_init(wm831x, spi->irq); | 67 | return wm831x_device_init(wm831x, spi->irq); |
68 | } | 68 | } |
69 | 69 | ||
70 | static int wm831x_spi_remove(struct spi_device *spi) | ||
71 | { | ||
72 | struct wm831x *wm831x = spi_get_drvdata(spi); | ||
73 | |||
74 | wm831x_device_exit(wm831x); | ||
75 | |||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static int wm831x_spi_suspend(struct device *dev) | 70 | static int wm831x_spi_suspend(struct device *dev) |
80 | { | 71 | { |
81 | struct wm831x *wm831x = dev_get_drvdata(dev); | 72 | struct wm831x *wm831x = dev_get_drvdata(dev); |
@@ -108,17 +99,16 @@ static const struct spi_device_id wm831x_spi_ids[] = { | |||
108 | { "wm8326", WM8326 }, | 99 | { "wm8326", WM8326 }, |
109 | { }, | 100 | { }, |
110 | }; | 101 | }; |
111 | MODULE_DEVICE_TABLE(spi, wm831x_spi_ids); | ||
112 | 102 | ||
113 | static struct spi_driver wm831x_spi_driver = { | 103 | static struct spi_driver wm831x_spi_driver = { |
114 | .driver = { | 104 | .driver = { |
115 | .name = "wm831x", | 105 | .name = "wm831x", |
116 | .pm = &wm831x_spi_pm, | 106 | .pm = &wm831x_spi_pm, |
117 | .of_match_table = of_match_ptr(wm831x_of_match), | 107 | .of_match_table = of_match_ptr(wm831x_of_match), |
108 | .suppress_bind_attrs = true, | ||
118 | }, | 109 | }, |
119 | .id_table = wm831x_spi_ids, | 110 | .id_table = wm831x_spi_ids, |
120 | .probe = wm831x_spi_probe, | 111 | .probe = wm831x_spi_probe, |
121 | .remove = wm831x_spi_remove, | ||
122 | }; | 112 | }; |
123 | 113 | ||
124 | static int __init wm831x_spi_init(void) | 114 | static int __init wm831x_spi_init(void) |
@@ -132,13 +122,3 @@ static int __init wm831x_spi_init(void) | |||
132 | return 0; | 122 | return 0; |
133 | } | 123 | } |
134 | subsys_initcall(wm831x_spi_init); | 124 | subsys_initcall(wm831x_spi_init); |
135 | |||
136 | static void __exit wm831x_spi_exit(void) | ||
137 | { | ||
138 | spi_unregister_driver(&wm831x_spi_driver); | ||
139 | } | ||
140 | module_exit(wm831x_spi_exit); | ||
141 | |||
142 | MODULE_DESCRIPTION("SPI support for WM831x/2x AudioPlus PMICs"); | ||
143 | MODULE_LICENSE("GPL"); | ||
144 | MODULE_AUTHOR("Mark Brown"); | ||
diff --git a/drivers/mfd/wm8350-core.c b/drivers/mfd/wm8350-core.c index 8a07c5634aee..9e1070f26b11 100644 --- a/drivers/mfd/wm8350-core.c +++ b/drivers/mfd/wm8350-core.c | |||
@@ -13,7 +13,8 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/module.h> | 16 | #include <linux/init.h> |
17 | #include <linux/export.h> | ||
17 | #include <linux/slab.h> | 18 | #include <linux/slab.h> |
18 | #include <linux/bug.h> | 19 | #include <linux/bug.h> |
19 | #include <linux/device.h> | 20 | #include <linux/device.h> |
@@ -442,30 +443,3 @@ err: | |||
442 | return ret; | 443 | return ret; |
443 | } | 444 | } |
444 | EXPORT_SYMBOL_GPL(wm8350_device_init); | 445 | EXPORT_SYMBOL_GPL(wm8350_device_init); |
445 | |||
446 | void wm8350_device_exit(struct wm8350 *wm8350) | ||
447 | { | ||
448 | int i; | ||
449 | |||
450 | for (i = 0; i < ARRAY_SIZE(wm8350->pmic.led); i++) | ||
451 | platform_device_unregister(wm8350->pmic.led[i].pdev); | ||
452 | |||
453 | for (i = 0; i < ARRAY_SIZE(wm8350->pmic.pdev); i++) | ||
454 | platform_device_unregister(wm8350->pmic.pdev[i]); | ||
455 | |||
456 | platform_device_unregister(wm8350->wdt.pdev); | ||
457 | platform_device_unregister(wm8350->rtc.pdev); | ||
458 | platform_device_unregister(wm8350->power.pdev); | ||
459 | platform_device_unregister(wm8350->hwmon.pdev); | ||
460 | platform_device_unregister(wm8350->gpio.pdev); | ||
461 | platform_device_unregister(wm8350->codec.pdev); | ||
462 | |||
463 | if (wm8350->irq_base) | ||
464 | free_irq(wm8350->irq_base + WM8350_IRQ_AUXADC_DATARDY, wm8350); | ||
465 | |||
466 | wm8350_irq_exit(wm8350); | ||
467 | } | ||
468 | EXPORT_SYMBOL_GPL(wm8350_device_exit); | ||
469 | |||
470 | MODULE_DESCRIPTION("WM8350 AudioPlus PMIC core driver"); | ||
471 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/wm8350-i2c.c b/drivers/mfd/wm8350-i2c.c index 9358f03b7938..b4194e068e1b 100644 --- a/drivers/mfd/wm8350-i2c.c +++ b/drivers/mfd/wm8350-i2c.c | |||
@@ -13,8 +13,6 @@ | |||
13 | * | 13 | * |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/moduleparam.h> | ||
18 | #include <linux/err.h> | 16 | #include <linux/err.h> |
19 | #include <linux/init.h> | 17 | #include <linux/init.h> |
20 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
@@ -48,30 +46,19 @@ static int wm8350_i2c_probe(struct i2c_client *i2c, | |||
48 | return wm8350_device_init(wm8350, i2c->irq, pdata); | 46 | return wm8350_device_init(wm8350, i2c->irq, pdata); |
49 | } | 47 | } |
50 | 48 | ||
51 | static int wm8350_i2c_remove(struct i2c_client *i2c) | ||
52 | { | ||
53 | struct wm8350 *wm8350 = i2c_get_clientdata(i2c); | ||
54 | |||
55 | wm8350_device_exit(wm8350); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static const struct i2c_device_id wm8350_i2c_id[] = { | 49 | static const struct i2c_device_id wm8350_i2c_id[] = { |
61 | { "wm8350", 0 }, | 50 | { "wm8350", 0 }, |
62 | { "wm8351", 0 }, | 51 | { "wm8351", 0 }, |
63 | { "wm8352", 0 }, | 52 | { "wm8352", 0 }, |
64 | { } | 53 | { } |
65 | }; | 54 | }; |
66 | MODULE_DEVICE_TABLE(i2c, wm8350_i2c_id); | ||
67 | |||
68 | 55 | ||
69 | static struct i2c_driver wm8350_i2c_driver = { | 56 | static struct i2c_driver wm8350_i2c_driver = { |
70 | .driver = { | 57 | .driver = { |
71 | .name = "wm8350", | 58 | .name = "wm8350", |
59 | .suppress_bind_attrs = true, | ||
72 | }, | 60 | }, |
73 | .probe = wm8350_i2c_probe, | 61 | .probe = wm8350_i2c_probe, |
74 | .remove = wm8350_i2c_remove, | ||
75 | .id_table = wm8350_i2c_id, | 62 | .id_table = wm8350_i2c_id, |
76 | }; | 63 | }; |
77 | 64 | ||
@@ -81,12 +68,3 @@ static int __init wm8350_i2c_init(void) | |||
81 | } | 68 | } |
82 | /* init early so consumer devices can complete system boot */ | 69 | /* init early so consumer devices can complete system boot */ |
83 | subsys_initcall(wm8350_i2c_init); | 70 | subsys_initcall(wm8350_i2c_init); |
84 | |||
85 | static void __exit wm8350_i2c_exit(void) | ||
86 | { | ||
87 | i2c_del_driver(&wm8350_i2c_driver); | ||
88 | } | ||
89 | module_exit(wm8350_i2c_exit); | ||
90 | |||
91 | MODULE_DESCRIPTION("I2C support for the WM8350 AudioPlus PMIC"); | ||
92 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mfd/wm8400-core.c b/drivers/mfd/wm8400-core.c index 8a98a2fc74e1..79756c83f5f0 100644 --- a/drivers/mfd/wm8400-core.c +++ b/drivers/mfd/wm8400-core.c | |||
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/module.h> | 15 | #include <linux/init.h> |
16 | #include <linux/bug.h> | 16 | #include <linux/bug.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/i2c.h> | 18 | #include <linux/i2c.h> |
@@ -150,7 +150,6 @@ static const struct i2c_device_id wm8400_i2c_id[] = { | |||
150 | { "wm8400", 0 }, | 150 | { "wm8400", 0 }, |
151 | { } | 151 | { } |
152 | }; | 152 | }; |
153 | MODULE_DEVICE_TABLE(i2c, wm8400_i2c_id); | ||
154 | 153 | ||
155 | static struct i2c_driver wm8400_i2c_driver = { | 154 | static struct i2c_driver wm8400_i2c_driver = { |
156 | .driver = { | 155 | .driver = { |
@@ -161,7 +160,7 @@ static struct i2c_driver wm8400_i2c_driver = { | |||
161 | }; | 160 | }; |
162 | #endif | 161 | #endif |
163 | 162 | ||
164 | static int __init wm8400_module_init(void) | 163 | static int __init wm8400_driver_init(void) |
165 | { | 164 | { |
166 | int ret = -ENODEV; | 165 | int ret = -ENODEV; |
167 | 166 | ||
@@ -173,15 +172,4 @@ static int __init wm8400_module_init(void) | |||
173 | 172 | ||
174 | return ret; | 173 | return ret; |
175 | } | 174 | } |
176 | subsys_initcall(wm8400_module_init); | 175 | subsys_initcall(wm8400_driver_init); |
177 | |||
178 | static void __exit wm8400_module_exit(void) | ||
179 | { | ||
180 | #if IS_ENABLED(CONFIG_I2C) | ||
181 | i2c_del_driver(&wm8400_i2c_driver); | ||
182 | #endif | ||
183 | } | ||
184 | module_exit(wm8400_module_exit); | ||
185 | |||
186 | MODULE_LICENSE("GPL"); | ||
187 | MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | ||
diff --git a/drivers/platform/chrome/Kconfig b/drivers/platform/chrome/Kconfig index 16b1615958aa..5e2fde5ff63d 100644 --- a/drivers/platform/chrome/Kconfig +++ b/drivers/platform/chrome/Kconfig | |||
@@ -49,9 +49,6 @@ config CHROMEOS_TBMC | |||
49 | To compile this driver as a module, choose M here: the | 49 | To compile this driver as a module, choose M here: the |
50 | module will be called chromeos_tbmc. | 50 | module will be called chromeos_tbmc. |
51 | 51 | ||
52 | config CROS_EC_CTL | ||
53 | tristate | ||
54 | |||
55 | config CROS_EC_I2C | 52 | config CROS_EC_I2C |
56 | tristate "ChromeOS Embedded Controller (I2C)" | 53 | tristate "ChromeOS Embedded Controller (I2C)" |
57 | depends on MFD_CROS_EC && I2C | 54 | depends on MFD_CROS_EC && I2C |
@@ -111,4 +108,48 @@ config CROS_KBD_LED_BACKLIGHT | |||
111 | To compile this driver as a module, choose M here: the | 108 | To compile this driver as a module, choose M here: the |
112 | module will be called cros_kbd_led_backlight. | 109 | module will be called cros_kbd_led_backlight. |
113 | 110 | ||
111 | config CROS_EC_LIGHTBAR | ||
112 | tristate "Chromebook Pixel's lightbar support" | ||
113 | depends on MFD_CROS_EC_CHARDEV | ||
114 | default MFD_CROS_EC_CHARDEV | ||
115 | help | ||
116 | This option exposes the Chromebook Pixel's lightbar to | ||
117 | userspace. | ||
118 | |||
119 | To compile this driver as a module, choose M here: the | ||
120 | module will be called cros_ec_lightbar. | ||
121 | |||
122 | config CROS_EC_VBC | ||
123 | tristate "ChromeOS EC vboot context support" | ||
124 | depends on MFD_CROS_EC_CHARDEV && OF | ||
125 | default MFD_CROS_EC_CHARDEV | ||
126 | help | ||
127 | This option exposes the ChromeOS EC vboot context nvram to | ||
128 | userspace. | ||
129 | |||
130 | To compile this driver as a module, choose M here: the | ||
131 | module will be called cros_ec_vbc. | ||
132 | |||
133 | config CROS_EC_DEBUGFS | ||
134 | tristate "Export ChromeOS EC internals in DebugFS" | ||
135 | depends on MFD_CROS_EC_CHARDEV && DEBUG_FS | ||
136 | default MFD_CROS_EC_CHARDEV | ||
137 | help | ||
138 | This option exposes the ChromeOS EC device internals to | ||
139 | userspace. | ||
140 | |||
141 | To compile this driver as a module, choose M here: the | ||
142 | module will be called cros_ec_debugfs. | ||
143 | |||
144 | config CROS_EC_SYSFS | ||
145 | tristate "ChromeOS EC control and information through sysfs" | ||
146 | depends on MFD_CROS_EC_CHARDEV && SYSFS | ||
147 | default MFD_CROS_EC_CHARDEV | ||
148 | help | ||
149 | This option exposes some sysfs attributes to control and get | ||
150 | information from ChromeOS EC. | ||
151 | |||
152 | To compile this driver as a module, choose M here: the | ||
153 | module will be called cros_ec_sysfs. | ||
154 | |||
114 | endif # CHROMEOS_PLATFORMS | 155 | endif # CHROMEOS_PLATFORMS |
diff --git a/drivers/platform/chrome/Makefile b/drivers/platform/chrome/Makefile index cd591bf872bb..fdbee501931b 100644 --- a/drivers/platform/chrome/Makefile +++ b/drivers/platform/chrome/Makefile | |||
@@ -3,9 +3,6 @@ | |||
3 | obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o | 3 | obj-$(CONFIG_CHROMEOS_LAPTOP) += chromeos_laptop.o |
4 | obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o | 4 | obj-$(CONFIG_CHROMEOS_PSTORE) += chromeos_pstore.o |
5 | obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o | 5 | obj-$(CONFIG_CHROMEOS_TBMC) += chromeos_tbmc.o |
6 | cros_ec_ctl-objs := cros_ec_sysfs.o cros_ec_lightbar.o \ | ||
7 | cros_ec_vbc.o cros_ec_debugfs.o | ||
8 | obj-$(CONFIG_CROS_EC_CTL) += cros_ec_ctl.o | ||
9 | obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o | 6 | obj-$(CONFIG_CROS_EC_I2C) += cros_ec_i2c.o |
10 | obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o | 7 | obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o |
11 | cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o | 8 | cros_ec_lpcs-objs := cros_ec_lpc.o cros_ec_lpc_reg.o |
@@ -13,3 +10,7 @@ cros_ec_lpcs-$(CONFIG_CROS_EC_LPC_MEC) += cros_ec_lpc_mec.o | |||
13 | obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o | 10 | obj-$(CONFIG_CROS_EC_LPC) += cros_ec_lpcs.o |
14 | obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o | 11 | obj-$(CONFIG_CROS_EC_PROTO) += cros_ec_proto.o |
15 | obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o | 12 | obj-$(CONFIG_CROS_KBD_LED_BACKLIGHT) += cros_kbd_led_backlight.o |
13 | obj-$(CONFIG_CROS_EC_LIGHTBAR) += cros_ec_lightbar.o | ||
14 | obj-$(CONFIG_CROS_EC_VBC) += cros_ec_vbc.o | ||
15 | obj-$(CONFIG_CROS_EC_DEBUGFS) += cros_ec_debugfs.o | ||
16 | obj-$(CONFIG_CROS_EC_SYSFS) += cros_ec_sysfs.o | ||
diff --git a/drivers/platform/chrome/cros_ec_debugfs.c b/drivers/platform/chrome/cros_ec_debugfs.c index c62ee8e610a0..6cacac53dfce 100644 --- a/drivers/platform/chrome/cros_ec_debugfs.c +++ b/drivers/platform/chrome/cros_ec_debugfs.c | |||
@@ -23,12 +23,16 @@ | |||
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/mfd/cros_ec.h> | 24 | #include <linux/mfd/cros_ec.h> |
25 | #include <linux/mfd/cros_ec_commands.h> | 25 | #include <linux/mfd/cros_ec_commands.h> |
26 | #include <linux/module.h> | ||
26 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/platform_device.h> | ||
27 | #include <linux/poll.h> | 29 | #include <linux/poll.h> |
28 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
29 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
30 | #include <linux/wait.h> | 32 | #include <linux/wait.h> |
31 | 33 | ||
34 | #define DRV_NAME "cros-ec-debugfs" | ||
35 | |||
32 | #define LOG_SHIFT 14 | 36 | #define LOG_SHIFT 14 |
33 | #define LOG_SIZE (1 << LOG_SHIFT) | 37 | #define LOG_SIZE (1 << LOG_SHIFT) |
34 | #define LOG_POLL_SEC 10 | 38 | #define LOG_POLL_SEC 10 |
@@ -423,8 +427,9 @@ static int cros_ec_create_pdinfo(struct cros_ec_debugfs *debug_info) | |||
423 | return 0; | 427 | return 0; |
424 | } | 428 | } |
425 | 429 | ||
426 | int cros_ec_debugfs_init(struct cros_ec_dev *ec) | 430 | static int cros_ec_debugfs_probe(struct platform_device *pd) |
427 | { | 431 | { |
432 | struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent); | ||
428 | struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev); | 433 | struct cros_ec_platform *ec_platform = dev_get_platdata(ec->dev); |
429 | const char *name = ec_platform->ec_name; | 434 | const char *name = ec_platform->ec_name; |
430 | struct cros_ec_debugfs *debug_info; | 435 | struct cros_ec_debugfs *debug_info; |
@@ -453,40 +458,57 @@ int cros_ec_debugfs_init(struct cros_ec_dev *ec) | |||
453 | 458 | ||
454 | ec->debug_info = debug_info; | 459 | ec->debug_info = debug_info; |
455 | 460 | ||
461 | dev_set_drvdata(&pd->dev, ec); | ||
462 | |||
456 | return 0; | 463 | return 0; |
457 | 464 | ||
458 | remove_debugfs: | 465 | remove_debugfs: |
459 | debugfs_remove_recursive(debug_info->dir); | 466 | debugfs_remove_recursive(debug_info->dir); |
460 | return ret; | 467 | return ret; |
461 | } | 468 | } |
462 | EXPORT_SYMBOL(cros_ec_debugfs_init); | ||
463 | 469 | ||
464 | void cros_ec_debugfs_remove(struct cros_ec_dev *ec) | 470 | static int cros_ec_debugfs_remove(struct platform_device *pd) |
465 | { | 471 | { |
466 | if (!ec->debug_info) | 472 | struct cros_ec_dev *ec = dev_get_drvdata(pd->dev.parent); |
467 | return; | ||
468 | 473 | ||
469 | debugfs_remove_recursive(ec->debug_info->dir); | 474 | debugfs_remove_recursive(ec->debug_info->dir); |
470 | cros_ec_cleanup_console_log(ec->debug_info); | 475 | cros_ec_cleanup_console_log(ec->debug_info); |
476 | |||
477 | return 0; | ||
471 | } | 478 | } |
472 | EXPORT_SYMBOL(cros_ec_debugfs_remove); | ||
473 | 479 | ||
474 | void cros_ec_debugfs_suspend(struct cros_ec_dev *ec) | 480 | static int __maybe_unused cros_ec_debugfs_suspend(struct device *dev) |
475 | { | 481 | { |
476 | /* | 482 | struct cros_ec_dev *ec = dev_get_drvdata(dev); |
477 | * cros_ec_debugfs_init() failures are non-fatal; it's also possible | 483 | |
478 | * that we initted things but decided that console log wasn't supported. | 484 | cancel_delayed_work_sync(&ec->debug_info->log_poll_work); |
479 | * We'll use the same set of checks that cros_ec_debugfs_remove() + | 485 | |
480 | * cros_ec_cleanup_console_log() end up using to handle those cases. | 486 | return 0; |
481 | */ | ||
482 | if (ec->debug_info && ec->debug_info->log_buffer.buf) | ||
483 | cancel_delayed_work_sync(&ec->debug_info->log_poll_work); | ||
484 | } | 487 | } |
485 | EXPORT_SYMBOL(cros_ec_debugfs_suspend); | ||
486 | 488 | ||
487 | void cros_ec_debugfs_resume(struct cros_ec_dev *ec) | 489 | static int __maybe_unused cros_ec_debugfs_resume(struct device *dev) |
488 | { | 490 | { |
489 | if (ec->debug_info && ec->debug_info->log_buffer.buf) | 491 | struct cros_ec_dev *ec = dev_get_drvdata(dev); |
490 | schedule_delayed_work(&ec->debug_info->log_poll_work, 0); | 492 | |
493 | schedule_delayed_work(&ec->debug_info->log_poll_work, 0); | ||
494 | |||
495 | return 0; | ||
491 | } | 496 | } |
492 | EXPORT_SYMBOL(cros_ec_debugfs_resume); | 497 | |
498 | static SIMPLE_DEV_PM_OPS(cros_ec_debugfs_pm_ops, | ||
499 | cros_ec_debugfs_suspend, cros_ec_debugfs_resume); | ||
500 | |||
501 | static struct platform_driver cros_ec_debugfs_driver = { | ||
502 | .driver = { | ||
503 | .name = DRV_NAME, | ||
504 | .pm = &cros_ec_debugfs_pm_ops, | ||
505 | }, | ||
506 | .probe = cros_ec_debugfs_probe, | ||
507 | .remove = cros_ec_debugfs_remove, | ||
508 | }; | ||
509 | |||
510 | module_platform_driver(cros_ec_debugfs_driver); | ||
511 | |||
512 | MODULE_LICENSE("GPL"); | ||
513 | MODULE_DESCRIPTION("Debug logs for ChromeOS EC"); | ||
514 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/platform/chrome/cros_ec_i2c.c b/drivers/platform/chrome/cros_ec_i2c.c index ef9b4763356f..9a009eaa4ada 100644 --- a/drivers/platform/chrome/cros_ec_i2c.c +++ b/drivers/platform/chrome/cros_ec_i2c.c | |||
@@ -317,15 +317,6 @@ static int cros_ec_i2c_probe(struct i2c_client *client, | |||
317 | return 0; | 317 | return 0; |
318 | } | 318 | } |
319 | 319 | ||
320 | static int cros_ec_i2c_remove(struct i2c_client *client) | ||
321 | { | ||
322 | struct cros_ec_device *ec_dev = i2c_get_clientdata(client); | ||
323 | |||
324 | cros_ec_remove(ec_dev); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | #ifdef CONFIG_PM_SLEEP | 320 | #ifdef CONFIG_PM_SLEEP |
330 | static int cros_ec_i2c_suspend(struct device *dev) | 321 | static int cros_ec_i2c_suspend(struct device *dev) |
331 | { | 322 | { |
@@ -376,7 +367,6 @@ static struct i2c_driver cros_ec_driver = { | |||
376 | .pm = &cros_ec_i2c_pm_ops, | 367 | .pm = &cros_ec_i2c_pm_ops, |
377 | }, | 368 | }, |
378 | .probe = cros_ec_i2c_probe, | 369 | .probe = cros_ec_i2c_probe, |
379 | .remove = cros_ec_i2c_remove, | ||
380 | .id_table = cros_ec_i2c_id, | 370 | .id_table = cros_ec_i2c_id, |
381 | }; | 371 | }; |
382 | 372 | ||
diff --git a/drivers/platform/chrome/cros_ec_lightbar.c b/drivers/platform/chrome/cros_ec_lightbar.c index 68193bb53383..c3e4e6e5211d 100644 --- a/drivers/platform/chrome/cros_ec_lightbar.c +++ b/drivers/platform/chrome/cros_ec_lightbar.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/uaccess.h> | 33 | #include <linux/uaccess.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | 35 | ||
36 | #define DRV_NAME "cros-ec-lightbar" | ||
37 | |||
36 | /* Rate-limit the lightbar interface to prevent DoS. */ | 38 | /* Rate-limit the lightbar interface to prevent DoS. */ |
37 | static unsigned long lb_interval_jiffies = 50 * HZ / 1000; | 39 | static unsigned long lb_interval_jiffies = 50 * HZ / 1000; |
38 | 40 | ||
@@ -41,7 +43,6 @@ static unsigned long lb_interval_jiffies = 50 * HZ / 1000; | |||
41 | * If this is true, we won't do anything during suspend/resume. | 43 | * If this is true, we won't do anything during suspend/resume. |
42 | */ | 44 | */ |
43 | static bool userspace_control; | 45 | static bool userspace_control; |
44 | static struct cros_ec_dev *ec_with_lightbar; | ||
45 | 46 | ||
46 | static ssize_t interval_msec_show(struct device *dev, | 47 | static ssize_t interval_msec_show(struct device *dev, |
47 | struct device_attribute *attr, char *buf) | 48 | struct device_attribute *attr, char *buf) |
@@ -373,15 +374,12 @@ error: | |||
373 | return ret; | 374 | return ret; |
374 | } | 375 | } |
375 | 376 | ||
376 | int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable) | 377 | static int lb_manual_suspend_ctrl(struct cros_ec_dev *ec, uint8_t enable) |
377 | { | 378 | { |
378 | struct ec_params_lightbar *param; | 379 | struct ec_params_lightbar *param; |
379 | struct cros_ec_command *msg; | 380 | struct cros_ec_command *msg; |
380 | int ret; | 381 | int ret; |
381 | 382 | ||
382 | if (ec != ec_with_lightbar) | ||
383 | return 0; | ||
384 | |||
385 | msg = alloc_lightbar_cmd_msg(ec); | 383 | msg = alloc_lightbar_cmd_msg(ec); |
386 | if (!msg) | 384 | if (!msg) |
387 | return -ENOMEM; | 385 | return -ENOMEM; |
@@ -408,25 +406,6 @@ error: | |||
408 | 406 | ||
409 | return ret; | 407 | return ret; |
410 | } | 408 | } |
411 | EXPORT_SYMBOL(lb_manual_suspend_ctrl); | ||
412 | |||
413 | int lb_suspend(struct cros_ec_dev *ec) | ||
414 | { | ||
415 | if (userspace_control || ec != ec_with_lightbar) | ||
416 | return 0; | ||
417 | |||
418 | return lb_send_empty_cmd(ec, LIGHTBAR_CMD_SUSPEND); | ||
419 | } | ||
420 | EXPORT_SYMBOL(lb_suspend); | ||
421 | |||
422 | int lb_resume(struct cros_ec_dev *ec) | ||
423 | { | ||
424 | if (userspace_control || ec != ec_with_lightbar) | ||
425 | return 0; | ||
426 | |||
427 | return lb_send_empty_cmd(ec, LIGHTBAR_CMD_RESUME); | ||
428 | } | ||
429 | EXPORT_SYMBOL(lb_resume); | ||
430 | 409 | ||
431 | static ssize_t sequence_store(struct device *dev, struct device_attribute *attr, | 410 | static ssize_t sequence_store(struct device *dev, struct device_attribute *attr, |
432 | const char *buf, size_t count) | 411 | const char *buf, size_t count) |
@@ -584,36 +563,91 @@ static struct attribute *__lb_cmds_attrs[] = { | |||
584 | NULL, | 563 | NULL, |
585 | }; | 564 | }; |
586 | 565 | ||
587 | bool ec_has_lightbar(struct cros_ec_dev *ec) | 566 | struct attribute_group cros_ec_lightbar_attr_group = { |
567 | .name = "lightbar", | ||
568 | .attrs = __lb_cmds_attrs, | ||
569 | }; | ||
570 | |||
571 | static int cros_ec_lightbar_probe(struct platform_device *pd) | ||
588 | { | 572 | { |
589 | return !!get_lightbar_version(ec, NULL, NULL); | 573 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); |
574 | struct cros_ec_platform *pdata = dev_get_platdata(ec_dev->dev); | ||
575 | struct device *dev = &pd->dev; | ||
576 | int ret; | ||
577 | |||
578 | /* | ||
579 | * Only instantiate the lightbar if the EC name is 'cros_ec'. Other EC | ||
580 | * devices like 'cros_pd' doesn't have a lightbar. | ||
581 | */ | ||
582 | if (strcmp(pdata->ec_name, CROS_EC_DEV_NAME) != 0) | ||
583 | return -ENODEV; | ||
584 | |||
585 | /* | ||
586 | * Ask then for the lightbar version, if it's 0 then the 'cros_ec' | ||
587 | * doesn't have a lightbar. | ||
588 | */ | ||
589 | if (!get_lightbar_version(ec_dev, NULL, NULL)) | ||
590 | return -ENODEV; | ||
591 | |||
592 | /* Take control of the lightbar from the EC. */ | ||
593 | lb_manual_suspend_ctrl(ec_dev, 1); | ||
594 | |||
595 | ret = sysfs_create_group(&ec_dev->class_dev.kobj, | ||
596 | &cros_ec_lightbar_attr_group); | ||
597 | if (ret < 0) | ||
598 | dev_err(dev, "failed to create %s attributes. err=%d\n", | ||
599 | cros_ec_lightbar_attr_group.name, ret); | ||
600 | |||
601 | return ret; | ||
590 | } | 602 | } |
591 | 603 | ||
592 | static umode_t cros_ec_lightbar_attrs_are_visible(struct kobject *kobj, | 604 | static int cros_ec_lightbar_remove(struct platform_device *pd) |
593 | struct attribute *a, int n) | ||
594 | { | 605 | { |
595 | struct device *dev = container_of(kobj, struct device, kobj); | 606 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); |
596 | struct cros_ec_dev *ec = to_cros_ec_dev(dev); | ||
597 | struct platform_device *pdev = to_platform_device(ec->dev); | ||
598 | struct cros_ec_platform *pdata = pdev->dev.platform_data; | ||
599 | int is_cros_ec; | ||
600 | 607 | ||
601 | is_cros_ec = strcmp(pdata->ec_name, CROS_EC_DEV_NAME); | 608 | sysfs_remove_group(&ec_dev->class_dev.kobj, |
609 | &cros_ec_lightbar_attr_group); | ||
602 | 610 | ||
603 | if (is_cros_ec != 0) | 611 | /* Let the EC take over the lightbar again. */ |
604 | return 0; | 612 | lb_manual_suspend_ctrl(ec_dev, 0); |
605 | 613 | ||
606 | /* Only instantiate this stuff if the EC has a lightbar */ | ||
607 | if (ec_has_lightbar(ec)) { | ||
608 | ec_with_lightbar = ec; | ||
609 | return a->mode; | ||
610 | } | ||
611 | return 0; | 614 | return 0; |
612 | } | 615 | } |
613 | 616 | ||
614 | struct attribute_group cros_ec_lightbar_attr_group = { | 617 | static int __maybe_unused cros_ec_lightbar_resume(struct device *dev) |
615 | .name = "lightbar", | 618 | { |
616 | .attrs = __lb_cmds_attrs, | 619 | struct cros_ec_dev *ec_dev = dev_get_drvdata(dev); |
617 | .is_visible = cros_ec_lightbar_attrs_are_visible, | 620 | |
621 | if (userspace_control) | ||
622 | return 0; | ||
623 | |||
624 | return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_RESUME); | ||
625 | } | ||
626 | |||
627 | static int __maybe_unused cros_ec_lightbar_suspend(struct device *dev) | ||
628 | { | ||
629 | struct cros_ec_dev *ec_dev = dev_get_drvdata(dev); | ||
630 | |||
631 | if (userspace_control) | ||
632 | return 0; | ||
633 | |||
634 | return lb_send_empty_cmd(ec_dev, LIGHTBAR_CMD_SUSPEND); | ||
635 | } | ||
636 | |||
637 | static SIMPLE_DEV_PM_OPS(cros_ec_lightbar_pm_ops, | ||
638 | cros_ec_lightbar_suspend, cros_ec_lightbar_resume); | ||
639 | |||
640 | static struct platform_driver cros_ec_lightbar_driver = { | ||
641 | .driver = { | ||
642 | .name = DRV_NAME, | ||
643 | .pm = &cros_ec_lightbar_pm_ops, | ||
644 | }, | ||
645 | .probe = cros_ec_lightbar_probe, | ||
646 | .remove = cros_ec_lightbar_remove, | ||
618 | }; | 647 | }; |
619 | EXPORT_SYMBOL(cros_ec_lightbar_attr_group); | 648 | |
649 | module_platform_driver(cros_ec_lightbar_driver); | ||
650 | |||
651 | MODULE_LICENSE("GPL"); | ||
652 | MODULE_DESCRIPTION("Expose the Chromebook Pixel's lightbar to userspace"); | ||
653 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/platform/chrome/cros_ec_lpc.c b/drivers/platform/chrome/cros_ec_lpc.c index e1b75775cd4a..14684a56e40f 100644 --- a/drivers/platform/chrome/cros_ec_lpc.c +++ b/drivers/platform/chrome/cros_ec_lpc.c | |||
@@ -327,7 +327,6 @@ static int cros_ec_lpc_probe(struct platform_device *pdev) | |||
327 | 327 | ||
328 | static int cros_ec_lpc_remove(struct platform_device *pdev) | 328 | static int cros_ec_lpc_remove(struct platform_device *pdev) |
329 | { | 329 | { |
330 | struct cros_ec_device *ec_dev; | ||
331 | struct acpi_device *adev; | 330 | struct acpi_device *adev; |
332 | 331 | ||
333 | adev = ACPI_COMPANION(&pdev->dev); | 332 | adev = ACPI_COMPANION(&pdev->dev); |
@@ -335,9 +334,6 @@ static int cros_ec_lpc_remove(struct platform_device *pdev) | |||
335 | acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY, | 334 | acpi_remove_notify_handler(adev->handle, ACPI_ALL_NOTIFY, |
336 | cros_ec_lpc_acpi_notify); | 335 | cros_ec_lpc_acpi_notify); |
337 | 336 | ||
338 | ec_dev = platform_get_drvdata(pdev); | ||
339 | cros_ec_remove(ec_dev); | ||
340 | |||
341 | return 0; | 337 | return 0; |
342 | } | 338 | } |
343 | 339 | ||
diff --git a/drivers/platform/chrome/cros_ec_spi.c b/drivers/platform/chrome/cros_ec_spi.c index 2060d1483043..6cfbc2835beb 100644 --- a/drivers/platform/chrome/cros_ec_spi.c +++ b/drivers/platform/chrome/cros_ec_spi.c | |||
@@ -685,16 +685,6 @@ static int cros_ec_spi_probe(struct spi_device *spi) | |||
685 | return 0; | 685 | return 0; |
686 | } | 686 | } |
687 | 687 | ||
688 | static int cros_ec_spi_remove(struct spi_device *spi) | ||
689 | { | ||
690 | struct cros_ec_device *ec_dev; | ||
691 | |||
692 | ec_dev = spi_get_drvdata(spi); | ||
693 | cros_ec_remove(ec_dev); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | #ifdef CONFIG_PM_SLEEP | 688 | #ifdef CONFIG_PM_SLEEP |
699 | static int cros_ec_spi_suspend(struct device *dev) | 689 | static int cros_ec_spi_suspend(struct device *dev) |
700 | { | 690 | { |
@@ -733,7 +723,6 @@ static struct spi_driver cros_ec_driver_spi = { | |||
733 | .pm = &cros_ec_spi_pm_ops, | 723 | .pm = &cros_ec_spi_pm_ops, |
734 | }, | 724 | }, |
735 | .probe = cros_ec_spi_probe, | 725 | .probe = cros_ec_spi_probe, |
736 | .remove = cros_ec_spi_remove, | ||
737 | .id_table = cros_ec_spi_id, | 726 | .id_table = cros_ec_spi_id, |
738 | }; | 727 | }; |
739 | 728 | ||
diff --git a/drivers/platform/chrome/cros_ec_sysfs.c b/drivers/platform/chrome/cros_ec_sysfs.c index f34a50121064..0ff5aa30c070 100644 --- a/drivers/platform/chrome/cros_ec_sysfs.c +++ b/drivers/platform/chrome/cros_ec_sysfs.c | |||
@@ -34,6 +34,8 @@ | |||
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | #include <linux/uaccess.h> | 35 | #include <linux/uaccess.h> |
36 | 36 | ||
37 | #define DRV_NAME "cros-ec-sysfs" | ||
38 | |||
37 | /* Accessor functions */ | 39 | /* Accessor functions */ |
38 | 40 | ||
39 | static ssize_t reboot_show(struct device *dev, | 41 | static ssize_t reboot_show(struct device *dev, |
@@ -353,7 +355,39 @@ struct attribute_group cros_ec_attr_group = { | |||
353 | .attrs = __ec_attrs, | 355 | .attrs = __ec_attrs, |
354 | .is_visible = cros_ec_ctrl_visible, | 356 | .is_visible = cros_ec_ctrl_visible, |
355 | }; | 357 | }; |
356 | EXPORT_SYMBOL(cros_ec_attr_group); | 358 | |
359 | static int cros_ec_sysfs_probe(struct platform_device *pd) | ||
360 | { | ||
361 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); | ||
362 | struct device *dev = &pd->dev; | ||
363 | int ret; | ||
364 | |||
365 | ret = sysfs_create_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group); | ||
366 | if (ret < 0) | ||
367 | dev_err(dev, "failed to create attributes. err=%d\n", ret); | ||
368 | |||
369 | return ret; | ||
370 | } | ||
371 | |||
372 | static int cros_ec_sysfs_remove(struct platform_device *pd) | ||
373 | { | ||
374 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); | ||
375 | |||
376 | sysfs_remove_group(&ec_dev->class_dev.kobj, &cros_ec_attr_group); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static struct platform_driver cros_ec_sysfs_driver = { | ||
382 | .driver = { | ||
383 | .name = DRV_NAME, | ||
384 | }, | ||
385 | .probe = cros_ec_sysfs_probe, | ||
386 | .remove = cros_ec_sysfs_remove, | ||
387 | }; | ||
388 | |||
389 | module_platform_driver(cros_ec_sysfs_driver); | ||
357 | 390 | ||
358 | MODULE_LICENSE("GPL"); | 391 | MODULE_LICENSE("GPL"); |
359 | MODULE_DESCRIPTION("ChromeOS EC control driver"); | 392 | MODULE_DESCRIPTION("ChromeOS EC control driver"); |
393 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/platform/chrome/cros_ec_vbc.c b/drivers/platform/chrome/cros_ec_vbc.c index 5356f26bc022..af9bfe6f385c 100644 --- a/drivers/platform/chrome/cros_ec_vbc.c +++ b/drivers/platform/chrome/cros_ec_vbc.c | |||
@@ -22,8 +22,11 @@ | |||
22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
23 | #include <linux/mfd/cros_ec.h> | 23 | #include <linux/mfd/cros_ec.h> |
24 | #include <linux/mfd/cros_ec_commands.h> | 24 | #include <linux/mfd/cros_ec_commands.h> |
25 | #include <linux/module.h> | ||
25 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
26 | 27 | ||
28 | #define DRV_NAME "cros-ec-vbc" | ||
29 | |||
27 | static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, | 30 | static ssize_t vboot_context_read(struct file *filp, struct kobject *kobj, |
28 | struct bin_attribute *att, char *buf, | 31 | struct bin_attribute *att, char *buf, |
29 | loff_t pos, size_t count) | 32 | loff_t pos, size_t count) |
@@ -105,21 +108,6 @@ static ssize_t vboot_context_write(struct file *filp, struct kobject *kobj, | |||
105 | return data_sz; | 108 | return data_sz; |
106 | } | 109 | } |
107 | 110 | ||
108 | static umode_t cros_ec_vbc_is_visible(struct kobject *kobj, | ||
109 | struct bin_attribute *a, int n) | ||
110 | { | ||
111 | struct device *dev = container_of(kobj, struct device, kobj); | ||
112 | struct cros_ec_dev *ec = to_cros_ec_dev(dev); | ||
113 | struct device_node *np = ec->ec_dev->dev->of_node; | ||
114 | |||
115 | if (IS_ENABLED(CONFIG_OF) && np) { | ||
116 | if (of_property_read_bool(np, "google,has-vbc-nvram")) | ||
117 | return a->attr.mode; | ||
118 | } | ||
119 | |||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | static BIN_ATTR_RW(vboot_context, 16); | 111 | static BIN_ATTR_RW(vboot_context, 16); |
124 | 112 | ||
125 | static struct bin_attribute *cros_ec_vbc_bin_attrs[] = { | 113 | static struct bin_attribute *cros_ec_vbc_bin_attrs[] = { |
@@ -130,6 +118,43 @@ static struct bin_attribute *cros_ec_vbc_bin_attrs[] = { | |||
130 | struct attribute_group cros_ec_vbc_attr_group = { | 118 | struct attribute_group cros_ec_vbc_attr_group = { |
131 | .name = "vbc", | 119 | .name = "vbc", |
132 | .bin_attrs = cros_ec_vbc_bin_attrs, | 120 | .bin_attrs = cros_ec_vbc_bin_attrs, |
133 | .is_bin_visible = cros_ec_vbc_is_visible, | ||
134 | }; | 121 | }; |
135 | EXPORT_SYMBOL(cros_ec_vbc_attr_group); | 122 | |
123 | static int cros_ec_vbc_probe(struct platform_device *pd) | ||
124 | { | ||
125 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); | ||
126 | struct device *dev = &pd->dev; | ||
127 | int ret; | ||
128 | |||
129 | ret = sysfs_create_group(&ec_dev->class_dev.kobj, | ||
130 | &cros_ec_vbc_attr_group); | ||
131 | if (ret < 0) | ||
132 | dev_err(dev, "failed to create %s attributes. err=%d\n", | ||
133 | cros_ec_vbc_attr_group.name, ret); | ||
134 | |||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | static int cros_ec_vbc_remove(struct platform_device *pd) | ||
139 | { | ||
140 | struct cros_ec_dev *ec_dev = dev_get_drvdata(pd->dev.parent); | ||
141 | |||
142 | sysfs_remove_group(&ec_dev->class_dev.kobj, | ||
143 | &cros_ec_vbc_attr_group); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static struct platform_driver cros_ec_vbc_driver = { | ||
149 | .driver = { | ||
150 | .name = DRV_NAME, | ||
151 | }, | ||
152 | .probe = cros_ec_vbc_probe, | ||
153 | .remove = cros_ec_vbc_remove, | ||
154 | }; | ||
155 | |||
156 | module_platform_driver(cros_ec_vbc_driver); | ||
157 | |||
158 | MODULE_LICENSE("GPL"); | ||
159 | MODULE_DESCRIPTION("Expose the vboot context nvram to userspace"); | ||
160 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 57f017d74a97..65c3c42b5e7c 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -817,6 +817,18 @@ config STM32_WATCHDOG | |||
817 | To compile this driver as a module, choose M here: the | 817 | To compile this driver as a module, choose M here: the |
818 | module will be called stm32_iwdg. | 818 | module will be called stm32_iwdg. |
819 | 819 | ||
820 | config STPMIC1_WATCHDOG | ||
821 | tristate "STPMIC1 PMIC watchdog support" | ||
822 | depends on MFD_STPMIC1 | ||
823 | select WATCHDOG_CORE | ||
824 | help | ||
825 | Say Y here to include watchdog support embedded into STPMIC1 PMIC. | ||
826 | If the watchdog timer expires, stpmic1 will shut down all its power | ||
827 | supplies. | ||
828 | |||
829 | To compile this driver as a module, choose M here: the | ||
830 | module will be called spmic1_wdt. | ||
831 | |||
820 | config UNIPHIER_WATCHDOG | 832 | config UNIPHIER_WATCHDOG |
821 | tristate "UniPhier watchdog support" | 833 | tristate "UniPhier watchdog support" |
822 | depends on ARCH_UNIPHIER || COMPILE_TEST | 834 | depends on ARCH_UNIPHIER || COMPILE_TEST |
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index a0917ef28e07..4e78a8c73f0c 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile | |||
@@ -220,3 +220,4 @@ obj-$(CONFIG_SOFT_WATCHDOG) += softdog.o | |||
220 | obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o | 220 | obj-$(CONFIG_MENF21BMC_WATCHDOG) += menf21bmc_wdt.o |
221 | obj-$(CONFIG_MENZ069_WATCHDOG) += menz69_wdt.o | 221 | obj-$(CONFIG_MENZ069_WATCHDOG) += menz69_wdt.o |
222 | obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o | 222 | obj-$(CONFIG_RAVE_SP_WATCHDOG) += rave-sp-wdt.o |
223 | obj-$(CONFIG_STPMIC1_WATCHDOG) += stpmic1_wdt.o | ||
diff --git a/drivers/watchdog/stpmic1_wdt.c b/drivers/watchdog/stpmic1_wdt.c new file mode 100644 index 000000000000..ad431d8ad95f --- /dev/null +++ b/drivers/watchdog/stpmic1_wdt.c | |||
@@ -0,0 +1,139 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (C) STMicroelectronics 2018 | ||
3 | // Author: Pascal Paillet <p.paillet@st.com> for STMicroelectronics. | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/mfd/stpmic1.h> | ||
7 | #include <linux/module.h> | ||
8 | #include <linux/platform_device.h> | ||
9 | #include <linux/of.h> | ||
10 | #include <linux/regmap.h> | ||
11 | #include <linux/slab.h> | ||
12 | #include <linux/watchdog.h> | ||
13 | |||
14 | /* WATCHDOG CONTROL REGISTER bit */ | ||
15 | #define WDT_START BIT(0) | ||
16 | #define WDT_PING BIT(1) | ||
17 | #define WDT_START_MASK BIT(0) | ||
18 | #define WDT_PING_MASK BIT(1) | ||
19 | #define WDT_STOP 0 | ||
20 | |||
21 | #define PMIC_WDT_MIN_TIMEOUT 1 | ||
22 | #define PMIC_WDT_MAX_TIMEOUT 256 | ||
23 | #define PMIC_WDT_DEFAULT_TIMEOUT 30 | ||
24 | |||
25 | static bool nowayout = WATCHDOG_NOWAYOUT; | ||
26 | module_param(nowayout, bool, 0); | ||
27 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" | ||
28 | __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); | ||
29 | |||
30 | struct stpmic1_wdt { | ||
31 | struct stpmic1 *pmic; | ||
32 | struct watchdog_device wdtdev; | ||
33 | }; | ||
34 | |||
35 | static int pmic_wdt_start(struct watchdog_device *wdd) | ||
36 | { | ||
37 | struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd); | ||
38 | |||
39 | return regmap_update_bits(wdt->pmic->regmap, | ||
40 | WCHDG_CR, WDT_START_MASK, WDT_START); | ||
41 | } | ||
42 | |||
43 | static int pmic_wdt_stop(struct watchdog_device *wdd) | ||
44 | { | ||
45 | struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd); | ||
46 | |||
47 | return regmap_update_bits(wdt->pmic->regmap, | ||
48 | WCHDG_CR, WDT_START_MASK, WDT_STOP); | ||
49 | } | ||
50 | |||
51 | static int pmic_wdt_ping(struct watchdog_device *wdd) | ||
52 | { | ||
53 | struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd); | ||
54 | |||
55 | return regmap_update_bits(wdt->pmic->regmap, | ||
56 | WCHDG_CR, WDT_PING_MASK, WDT_PING); | ||
57 | } | ||
58 | |||
59 | static int pmic_wdt_set_timeout(struct watchdog_device *wdd, | ||
60 | unsigned int timeout) | ||
61 | { | ||
62 | struct stpmic1_wdt *wdt = watchdog_get_drvdata(wdd); | ||
63 | |||
64 | wdd->timeout = timeout; | ||
65 | /* timeout is equal to register value + 1 */ | ||
66 | return regmap_write(wdt->pmic->regmap, WCHDG_TIMER_CR, timeout - 1); | ||
67 | } | ||
68 | |||
69 | static const struct watchdog_info pmic_watchdog_info = { | ||
70 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE, | ||
71 | .identity = "STPMIC1 PMIC Watchdog", | ||
72 | }; | ||
73 | |||
74 | static const struct watchdog_ops pmic_watchdog_ops = { | ||
75 | .owner = THIS_MODULE, | ||
76 | .start = pmic_wdt_start, | ||
77 | .stop = pmic_wdt_stop, | ||
78 | .ping = pmic_wdt_ping, | ||
79 | .set_timeout = pmic_wdt_set_timeout, | ||
80 | }; | ||
81 | |||
82 | static int pmic_wdt_probe(struct platform_device *pdev) | ||
83 | { | ||
84 | int ret; | ||
85 | struct stpmic1 *pmic; | ||
86 | struct stpmic1_wdt *wdt; | ||
87 | |||
88 | if (!pdev->dev.parent) | ||
89 | return -EINVAL; | ||
90 | |||
91 | pmic = dev_get_drvdata(pdev->dev.parent); | ||
92 | if (!pmic) | ||
93 | return -EINVAL; | ||
94 | |||
95 | wdt = devm_kzalloc(&pdev->dev, sizeof(struct stpmic1_wdt), GFP_KERNEL); | ||
96 | if (!wdt) | ||
97 | return -ENOMEM; | ||
98 | |||
99 | wdt->pmic = pmic; | ||
100 | |||
101 | wdt->wdtdev.info = &pmic_watchdog_info; | ||
102 | wdt->wdtdev.ops = &pmic_watchdog_ops; | ||
103 | wdt->wdtdev.min_timeout = PMIC_WDT_MIN_TIMEOUT; | ||
104 | wdt->wdtdev.max_timeout = PMIC_WDT_MAX_TIMEOUT; | ||
105 | wdt->wdtdev.parent = &pdev->dev; | ||
106 | |||
107 | wdt->wdtdev.timeout = PMIC_WDT_DEFAULT_TIMEOUT; | ||
108 | watchdog_init_timeout(&wdt->wdtdev, 0, &pdev->dev); | ||
109 | |||
110 | watchdog_set_nowayout(&wdt->wdtdev, nowayout); | ||
111 | watchdog_set_drvdata(&wdt->wdtdev, wdt); | ||
112 | |||
113 | ret = devm_watchdog_register_device(&pdev->dev, &wdt->wdtdev); | ||
114 | if (ret) | ||
115 | return ret; | ||
116 | |||
117 | dev_dbg(wdt->pmic->dev, "PMIC Watchdog driver probed\n"); | ||
118 | return 0; | ||
119 | } | ||
120 | |||
121 | static const struct of_device_id of_pmic_wdt_match[] = { | ||
122 | { .compatible = "st,stpmic1-wdt" }, | ||
123 | { }, | ||
124 | }; | ||
125 | |||
126 | MODULE_DEVICE_TABLE(of, of_pmic_wdt_match); | ||
127 | |||
128 | static struct platform_driver stpmic1_wdt_driver = { | ||
129 | .probe = pmic_wdt_probe, | ||
130 | .driver = { | ||
131 | .name = "stpmic1-wdt", | ||
132 | .of_match_table = of_pmic_wdt_match, | ||
133 | }, | ||
134 | }; | ||
135 | module_platform_driver(stpmic1_wdt_driver); | ||
136 | |||
137 | MODULE_DESCRIPTION("Watchdog driver for STPMIC1 device"); | ||
138 | MODULE_AUTHOR("Pascal Paillet <p.paillet@st.com>"); | ||
139 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/include/dt-bindings/clk/lochnagar.h b/include/dt-bindings/clk/lochnagar.h new file mode 100644 index 000000000000..8fa20551ff17 --- /dev/null +++ b/include/dt-bindings/clk/lochnagar.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Device Tree defines for Lochnagar clocking | ||
4 | * | ||
5 | * Copyright (c) 2017-2018 Cirrus Logic, Inc. and | ||
6 | * Cirrus Logic International Semiconductor Ltd. | ||
7 | * | ||
8 | * Author: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
9 | */ | ||
10 | |||
11 | #ifndef DT_BINDINGS_CLK_LOCHNAGAR_H | ||
12 | #define DT_BINDINGS_CLK_LOCHNAGAR_H | ||
13 | |||
14 | #define LOCHNAGAR_CDC_MCLK1 0 | ||
15 | #define LOCHNAGAR_CDC_MCLK2 1 | ||
16 | #define LOCHNAGAR_DSP_CLKIN 2 | ||
17 | #define LOCHNAGAR_GF_CLKOUT1 3 | ||
18 | #define LOCHNAGAR_GF_CLKOUT2 4 | ||
19 | #define LOCHNAGAR_PSIA1_MCLK 5 | ||
20 | #define LOCHNAGAR_PSIA2_MCLK 6 | ||
21 | #define LOCHNAGAR_SPDIF_MCLK 7 | ||
22 | #define LOCHNAGAR_ADAT_MCLK 8 | ||
23 | #define LOCHNAGAR_SOUNDCARD_MCLK 9 | ||
24 | #define LOCHNAGAR_SPDIF_CLKOUT 10 | ||
25 | |||
26 | #endif | ||
diff --git a/include/dt-bindings/mfd/st,stpmic1.h b/include/dt-bindings/mfd/st,stpmic1.h new file mode 100644 index 000000000000..321cd08797d9 --- /dev/null +++ b/include/dt-bindings/mfd/st,stpmic1.h | |||
@@ -0,0 +1,50 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) STMicroelectronics 2018 - All Rights Reserved | ||
4 | * Author: Philippe Peurichard <philippe.peurichard@st.com>, | ||
5 | * Pascal Paillet <p.paillet@st.com> for STMicroelectronics. | ||
6 | */ | ||
7 | |||
8 | #ifndef __DT_BINDINGS_STPMIC1_H__ | ||
9 | #define __DT_BINDINGS_STPMIC1_H__ | ||
10 | |||
11 | /* IRQ definitions */ | ||
12 | #define IT_PONKEY_F 0 | ||
13 | #define IT_PONKEY_R 1 | ||
14 | #define IT_WAKEUP_F 2 | ||
15 | #define IT_WAKEUP_R 3 | ||
16 | #define IT_VBUS_OTG_F 4 | ||
17 | #define IT_VBUS_OTG_R 5 | ||
18 | #define IT_SWOUT_F 6 | ||
19 | #define IT_SWOUT_R 7 | ||
20 | |||
21 | #define IT_CURLIM_BUCK1 8 | ||
22 | #define IT_CURLIM_BUCK2 9 | ||
23 | #define IT_CURLIM_BUCK3 10 | ||
24 | #define IT_CURLIM_BUCK4 11 | ||
25 | #define IT_OCP_OTG 12 | ||
26 | #define IT_OCP_SWOUT 13 | ||
27 | #define IT_OCP_BOOST 14 | ||
28 | #define IT_OVP_BOOST 15 | ||
29 | |||
30 | #define IT_CURLIM_LDO1 16 | ||
31 | #define IT_CURLIM_LDO2 17 | ||
32 | #define IT_CURLIM_LDO3 18 | ||
33 | #define IT_CURLIM_LDO4 19 | ||
34 | #define IT_CURLIM_LDO5 20 | ||
35 | #define IT_CURLIM_LDO6 21 | ||
36 | #define IT_SHORT_SWOTG 22 | ||
37 | #define IT_SHORT_SWOUT 23 | ||
38 | |||
39 | #define IT_TWARN_F 24 | ||
40 | #define IT_TWARN_R 25 | ||
41 | #define IT_VINLOW_F 26 | ||
42 | #define IT_VINLOW_R 27 | ||
43 | #define IT_SWIN_F 30 | ||
44 | #define IT_SWIN_R 31 | ||
45 | |||
46 | /* BUCK MODES definitions */ | ||
47 | #define STPMIC1_BUCK_MODE_NORMAL 0 | ||
48 | #define STPMIC1_BUCK_MODE_LP 2 | ||
49 | |||
50 | #endif /* __DT_BINDINGS_STPMIC1_H__ */ | ||
diff --git a/include/dt-bindings/pinctrl/lochnagar.h b/include/dt-bindings/pinctrl/lochnagar.h new file mode 100644 index 000000000000..644760bf5725 --- /dev/null +++ b/include/dt-bindings/pinctrl/lochnagar.h | |||
@@ -0,0 +1,132 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Device Tree defines for Lochnagar pinctrl | ||
4 | * | ||
5 | * Copyright (c) 2018 Cirrus Logic, Inc. and | ||
6 | * Cirrus Logic International Semiconductor Ltd. | ||
7 | * | ||
8 | * Author: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
9 | */ | ||
10 | |||
11 | #ifndef DT_BINDINGS_PINCTRL_LOCHNAGAR_H | ||
12 | #define DT_BINDINGS_PINCTRL_LOCHNAGAR_H | ||
13 | |||
14 | #define LOCHNAGAR1_PIN_CDC_RESET 0 | ||
15 | #define LOCHNAGAR1_PIN_DSP_RESET 1 | ||
16 | #define LOCHNAGAR1_PIN_CDC_CIF1MODE 2 | ||
17 | #define LOCHNAGAR1_PIN_NUM_GPIOS 3 | ||
18 | |||
19 | #define LOCHNAGAR2_PIN_CDC_RESET 0 | ||
20 | #define LOCHNAGAR2_PIN_DSP_RESET 1 | ||
21 | #define LOCHNAGAR2_PIN_CDC_CIF1MODE 2 | ||
22 | #define LOCHNAGAR2_PIN_CDC_LDOENA 3 | ||
23 | #define LOCHNAGAR2_PIN_SPDIF_HWMODE 4 | ||
24 | #define LOCHNAGAR2_PIN_SPDIF_RESET 5 | ||
25 | #define LOCHNAGAR2_PIN_FPGA_GPIO1 6 | ||
26 | #define LOCHNAGAR2_PIN_FPGA_GPIO2 7 | ||
27 | #define LOCHNAGAR2_PIN_FPGA_GPIO3 8 | ||
28 | #define LOCHNAGAR2_PIN_FPGA_GPIO4 9 | ||
29 | #define LOCHNAGAR2_PIN_FPGA_GPIO5 10 | ||
30 | #define LOCHNAGAR2_PIN_FPGA_GPIO6 11 | ||
31 | #define LOCHNAGAR2_PIN_CDC_GPIO1 12 | ||
32 | #define LOCHNAGAR2_PIN_CDC_GPIO2 13 | ||
33 | #define LOCHNAGAR2_PIN_CDC_GPIO3 14 | ||
34 | #define LOCHNAGAR2_PIN_CDC_GPIO4 15 | ||
35 | #define LOCHNAGAR2_PIN_CDC_GPIO5 16 | ||
36 | #define LOCHNAGAR2_PIN_CDC_GPIO6 17 | ||
37 | #define LOCHNAGAR2_PIN_CDC_GPIO7 18 | ||
38 | #define LOCHNAGAR2_PIN_CDC_GPIO8 19 | ||
39 | #define LOCHNAGAR2_PIN_DSP_GPIO1 20 | ||
40 | #define LOCHNAGAR2_PIN_DSP_GPIO2 21 | ||
41 | #define LOCHNAGAR2_PIN_DSP_GPIO3 22 | ||
42 | #define LOCHNAGAR2_PIN_DSP_GPIO4 23 | ||
43 | #define LOCHNAGAR2_PIN_DSP_GPIO5 24 | ||
44 | #define LOCHNAGAR2_PIN_DSP_GPIO6 25 | ||
45 | #define LOCHNAGAR2_PIN_GF_GPIO2 26 | ||
46 | #define LOCHNAGAR2_PIN_GF_GPIO3 27 | ||
47 | #define LOCHNAGAR2_PIN_GF_GPIO7 28 | ||
48 | #define LOCHNAGAR2_PIN_CDC_AIF1_BCLK 29 | ||
49 | #define LOCHNAGAR2_PIN_CDC_AIF1_RXDAT 30 | ||
50 | #define LOCHNAGAR2_PIN_CDC_AIF1_LRCLK 31 | ||
51 | #define LOCHNAGAR2_PIN_CDC_AIF1_TXDAT 32 | ||
52 | #define LOCHNAGAR2_PIN_CDC_AIF2_BCLK 33 | ||
53 | #define LOCHNAGAR2_PIN_CDC_AIF2_RXDAT 34 | ||
54 | #define LOCHNAGAR2_PIN_CDC_AIF2_LRCLK 35 | ||
55 | #define LOCHNAGAR2_PIN_CDC_AIF2_TXDAT 36 | ||
56 | #define LOCHNAGAR2_PIN_CDC_AIF3_BCLK 37 | ||
57 | #define LOCHNAGAR2_PIN_CDC_AIF3_RXDAT 38 | ||
58 | #define LOCHNAGAR2_PIN_CDC_AIF3_LRCLK 39 | ||
59 | #define LOCHNAGAR2_PIN_CDC_AIF3_TXDAT 40 | ||
60 | #define LOCHNAGAR2_PIN_DSP_AIF1_BCLK 41 | ||
61 | #define LOCHNAGAR2_PIN_DSP_AIF1_RXDAT 42 | ||
62 | #define LOCHNAGAR2_PIN_DSP_AIF1_LRCLK 43 | ||
63 | #define LOCHNAGAR2_PIN_DSP_AIF1_TXDAT 44 | ||
64 | #define LOCHNAGAR2_PIN_DSP_AIF2_BCLK 45 | ||
65 | #define LOCHNAGAR2_PIN_DSP_AIF2_RXDAT 46 | ||
66 | #define LOCHNAGAR2_PIN_DSP_AIF2_LRCLK 47 | ||
67 | #define LOCHNAGAR2_PIN_DSP_AIF2_TXDAT 48 | ||
68 | #define LOCHNAGAR2_PIN_PSIA1_BCLK 49 | ||
69 | #define LOCHNAGAR2_PIN_PSIA1_RXDAT 50 | ||
70 | #define LOCHNAGAR2_PIN_PSIA1_LRCLK 51 | ||
71 | #define LOCHNAGAR2_PIN_PSIA1_TXDAT 52 | ||
72 | #define LOCHNAGAR2_PIN_PSIA2_BCLK 53 | ||
73 | #define LOCHNAGAR2_PIN_PSIA2_RXDAT 54 | ||
74 | #define LOCHNAGAR2_PIN_PSIA2_LRCLK 55 | ||
75 | #define LOCHNAGAR2_PIN_PSIA2_TXDAT 56 | ||
76 | #define LOCHNAGAR2_PIN_GF_AIF3_BCLK 57 | ||
77 | #define LOCHNAGAR2_PIN_GF_AIF3_RXDAT 58 | ||
78 | #define LOCHNAGAR2_PIN_GF_AIF3_LRCLK 59 | ||
79 | #define LOCHNAGAR2_PIN_GF_AIF3_TXDAT 60 | ||
80 | #define LOCHNAGAR2_PIN_GF_AIF4_BCLK 61 | ||
81 | #define LOCHNAGAR2_PIN_GF_AIF4_RXDAT 62 | ||
82 | #define LOCHNAGAR2_PIN_GF_AIF4_LRCLK 63 | ||
83 | #define LOCHNAGAR2_PIN_GF_AIF4_TXDAT 64 | ||
84 | #define LOCHNAGAR2_PIN_GF_AIF1_BCLK 65 | ||
85 | #define LOCHNAGAR2_PIN_GF_AIF1_RXDAT 66 | ||
86 | #define LOCHNAGAR2_PIN_GF_AIF1_LRCLK 67 | ||
87 | #define LOCHNAGAR2_PIN_GF_AIF1_TXDAT 68 | ||
88 | #define LOCHNAGAR2_PIN_GF_AIF2_BCLK 69 | ||
89 | #define LOCHNAGAR2_PIN_GF_AIF2_RXDAT 70 | ||
90 | #define LOCHNAGAR2_PIN_GF_AIF2_LRCLK 71 | ||
91 | #define LOCHNAGAR2_PIN_GF_AIF2_TXDAT 72 | ||
92 | #define LOCHNAGAR2_PIN_DSP_UART1_RX 73 | ||
93 | #define LOCHNAGAR2_PIN_DSP_UART1_TX 74 | ||
94 | #define LOCHNAGAR2_PIN_DSP_UART2_RX 75 | ||
95 | #define LOCHNAGAR2_PIN_DSP_UART2_TX 76 | ||
96 | #define LOCHNAGAR2_PIN_GF_UART2_RX 77 | ||
97 | #define LOCHNAGAR2_PIN_GF_UART2_TX 78 | ||
98 | #define LOCHNAGAR2_PIN_USB_UART_RX 79 | ||
99 | #define LOCHNAGAR2_PIN_CDC_PDMCLK1 80 | ||
100 | #define LOCHNAGAR2_PIN_CDC_PDMDAT1 81 | ||
101 | #define LOCHNAGAR2_PIN_CDC_PDMCLK2 82 | ||
102 | #define LOCHNAGAR2_PIN_CDC_PDMDAT2 83 | ||
103 | #define LOCHNAGAR2_PIN_CDC_DMICCLK1 84 | ||
104 | #define LOCHNAGAR2_PIN_CDC_DMICDAT1 85 | ||
105 | #define LOCHNAGAR2_PIN_CDC_DMICCLK2 86 | ||
106 | #define LOCHNAGAR2_PIN_CDC_DMICDAT2 87 | ||
107 | #define LOCHNAGAR2_PIN_CDC_DMICCLK3 88 | ||
108 | #define LOCHNAGAR2_PIN_CDC_DMICDAT3 89 | ||
109 | #define LOCHNAGAR2_PIN_CDC_DMICCLK4 90 | ||
110 | #define LOCHNAGAR2_PIN_CDC_DMICDAT4 91 | ||
111 | #define LOCHNAGAR2_PIN_DSP_DMICCLK1 92 | ||
112 | #define LOCHNAGAR2_PIN_DSP_DMICDAT1 93 | ||
113 | #define LOCHNAGAR2_PIN_DSP_DMICCLK2 94 | ||
114 | #define LOCHNAGAR2_PIN_DSP_DMICDAT2 95 | ||
115 | #define LOCHNAGAR2_PIN_I2C2_SCL 96 | ||
116 | #define LOCHNAGAR2_PIN_I2C2_SDA 97 | ||
117 | #define LOCHNAGAR2_PIN_I2C3_SCL 98 | ||
118 | #define LOCHNAGAR2_PIN_I2C3_SDA 99 | ||
119 | #define LOCHNAGAR2_PIN_I2C4_SCL 100 | ||
120 | #define LOCHNAGAR2_PIN_I2C4_SDA 101 | ||
121 | #define LOCHNAGAR2_PIN_DSP_STANDBY 102 | ||
122 | #define LOCHNAGAR2_PIN_CDC_MCLK1 103 | ||
123 | #define LOCHNAGAR2_PIN_CDC_MCLK2 104 | ||
124 | #define LOCHNAGAR2_PIN_DSP_CLKIN 105 | ||
125 | #define LOCHNAGAR2_PIN_PSIA1_MCLK 106 | ||
126 | #define LOCHNAGAR2_PIN_PSIA2_MCLK 107 | ||
127 | #define LOCHNAGAR2_PIN_GF_GPIO1 108 | ||
128 | #define LOCHNAGAR2_PIN_GF_GPIO5 109 | ||
129 | #define LOCHNAGAR2_PIN_DSP_GPIO20 110 | ||
130 | #define LOCHNAGAR2_PIN_NUM_GPIOS 111 | ||
131 | |||
132 | #endif | ||
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h index de8b588c8776..8f2a8918bfa3 100644 --- a/include/linux/mfd/cros_ec.h +++ b/include/linux/mfd/cros_ec.h | |||
@@ -282,16 +282,6 @@ int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev, | |||
282 | struct cros_ec_command *msg); | 282 | struct cros_ec_command *msg); |
283 | 283 | ||
284 | /** | 284 | /** |
285 | * cros_ec_remove() - Remove a ChromeOS EC. | ||
286 | * @ec_dev: Device to register. | ||
287 | * | ||
288 | * Call this to deregister a ChromeOS EC, then clean up any private data. | ||
289 | * | ||
290 | * Return: 0 on success or negative error code. | ||
291 | */ | ||
292 | int cros_ec_remove(struct cros_ec_device *ec_dev); | ||
293 | |||
294 | /** | ||
295 | * cros_ec_register() - Register a new ChromeOS EC, using the provided info. | 285 | * cros_ec_register() - Register a new ChromeOS EC, using the provided info. |
296 | * @ec_dev: Device to register. | 286 | * @ec_dev: Device to register. |
297 | * | 287 | * |
@@ -335,15 +325,4 @@ int cros_ec_get_next_event(struct cros_ec_device *ec_dev, bool *wake_event); | |||
335 | */ | 325 | */ |
336 | u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); | 326 | u32 cros_ec_get_host_event(struct cros_ec_device *ec_dev); |
337 | 327 | ||
338 | /* sysfs stuff */ | ||
339 | extern struct attribute_group cros_ec_attr_group; | ||
340 | extern struct attribute_group cros_ec_lightbar_attr_group; | ||
341 | extern struct attribute_group cros_ec_vbc_attr_group; | ||
342 | |||
343 | /* debugfs stuff */ | ||
344 | int cros_ec_debugfs_init(struct cros_ec_dev *ec); | ||
345 | void cros_ec_debugfs_remove(struct cros_ec_dev *ec); | ||
346 | void cros_ec_debugfs_suspend(struct cros_ec_dev *ec); | ||
347 | void cros_ec_debugfs_resume(struct cros_ec_dev *ec); | ||
348 | |||
349 | #endif /* __LINUX_MFD_CROS_EC_H */ | 328 | #endif /* __LINUX_MFD_CROS_EC_H */ |
diff --git a/include/linux/mfd/lochnagar.h b/include/linux/mfd/lochnagar.h new file mode 100644 index 000000000000..ff9e64cfc9fb --- /dev/null +++ b/include/linux/mfd/lochnagar.h | |||
@@ -0,0 +1,55 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Lochnagar internals | ||
4 | * | ||
5 | * Copyright (c) 2013-2018 Cirrus Logic, Inc. and | ||
6 | * Cirrus Logic International Semiconductor Ltd. | ||
7 | * | ||
8 | * Author: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
9 | */ | ||
10 | |||
11 | #include <linux/device.h> | ||
12 | #include <linux/mutex.h> | ||
13 | #include <linux/regmap.h> | ||
14 | |||
15 | #ifndef CIRRUS_LOCHNAGAR_H | ||
16 | #define CIRRUS_LOCHNAGAR_H | ||
17 | |||
18 | enum lochnagar_type { | ||
19 | LOCHNAGAR1, | ||
20 | LOCHNAGAR2, | ||
21 | }; | ||
22 | |||
23 | /** | ||
24 | * struct lochnagar - Core data for the Lochnagar audio board driver. | ||
25 | * | ||
26 | * @type: The type of Lochnagar device connected. | ||
27 | * @dev: A pointer to the struct device for the main MFD. | ||
28 | * @regmap: The devices main register map. | ||
29 | * @analogue_config_lock: Lock used to protect updates in the analogue | ||
30 | * configuration as these must not be changed whilst the hardware is processing | ||
31 | * the last update. | ||
32 | */ | ||
33 | struct lochnagar { | ||
34 | enum lochnagar_type type; | ||
35 | struct device *dev; | ||
36 | struct regmap *regmap; | ||
37 | |||
38 | /* Lock to protect updates to the analogue configuration */ | ||
39 | struct mutex analogue_config_lock; | ||
40 | }; | ||
41 | |||
42 | /* Register Addresses */ | ||
43 | #define LOCHNAGAR_SOFTWARE_RESET 0x00 | ||
44 | #define LOCHNAGAR_FIRMWARE_ID1 0x01 | ||
45 | #define LOCHNAGAR_FIRMWARE_ID2 0x02 | ||
46 | |||
47 | /* (0x0000) Software Reset */ | ||
48 | #define LOCHNAGAR_DEVICE_ID_MASK 0xFFFC | ||
49 | #define LOCHNAGAR_DEVICE_ID_SHIFT 2 | ||
50 | #define LOCHNAGAR_REV_ID_MASK 0x0003 | ||
51 | #define LOCHNAGAR_REV_ID_SHIFT 0 | ||
52 | |||
53 | int lochnagar_update_config(struct lochnagar *lochnagar); | ||
54 | |||
55 | #endif | ||
diff --git a/include/linux/mfd/lochnagar1_regs.h b/include/linux/mfd/lochnagar1_regs.h new file mode 100644 index 000000000000..114b846245d9 --- /dev/null +++ b/include/linux/mfd/lochnagar1_regs.h | |||
@@ -0,0 +1,157 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Lochnagar1 register definitions | ||
4 | * | ||
5 | * Copyright (c) 2017-2018 Cirrus Logic, Inc. and | ||
6 | * Cirrus Logic International Semiconductor Ltd. | ||
7 | * | ||
8 | * Author: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
9 | */ | ||
10 | |||
11 | #ifndef LOCHNAGAR1_REGISTERS_H | ||
12 | #define LOCHNAGAR1_REGISTERS_H | ||
13 | |||
14 | /* Register Addresses */ | ||
15 | #define LOCHNAGAR1_CDC_AIF1_SEL 0x0008 | ||
16 | #define LOCHNAGAR1_CDC_AIF2_SEL 0x0009 | ||
17 | #define LOCHNAGAR1_CDC_AIF3_SEL 0x000A | ||
18 | #define LOCHNAGAR1_CDC_MCLK1_SEL 0x000B | ||
19 | #define LOCHNAGAR1_CDC_MCLK2_SEL 0x000C | ||
20 | #define LOCHNAGAR1_CDC_AIF_CTRL1 0x000D | ||
21 | #define LOCHNAGAR1_CDC_AIF_CTRL2 0x000E | ||
22 | #define LOCHNAGAR1_EXT_AIF_CTRL 0x000F | ||
23 | #define LOCHNAGAR1_DSP_AIF1_SEL 0x0010 | ||
24 | #define LOCHNAGAR1_DSP_AIF2_SEL 0x0011 | ||
25 | #define LOCHNAGAR1_DSP_CLKIN_SEL 0x0012 | ||
26 | #define LOCHNAGAR1_DSP_AIF 0x0013 | ||
27 | #define LOCHNAGAR1_GF_AIF1 0x0014 | ||
28 | #define LOCHNAGAR1_GF_AIF2 0x0015 | ||
29 | #define LOCHNAGAR1_PSIA_AIF 0x0016 | ||
30 | #define LOCHNAGAR1_PSIA1_SEL 0x0017 | ||
31 | #define LOCHNAGAR1_PSIA2_SEL 0x0018 | ||
32 | #define LOCHNAGAR1_SPDIF_AIF_SEL 0x0019 | ||
33 | #define LOCHNAGAR1_GF_AIF3_SEL 0x001C | ||
34 | #define LOCHNAGAR1_GF_AIF4_SEL 0x001D | ||
35 | #define LOCHNAGAR1_GF_CLKOUT1_SEL 0x001E | ||
36 | #define LOCHNAGAR1_GF_AIF1_SEL 0x001F | ||
37 | #define LOCHNAGAR1_GF_AIF2_SEL 0x0020 | ||
38 | #define LOCHNAGAR1_GF_GPIO2 0x0026 | ||
39 | #define LOCHNAGAR1_GF_GPIO3 0x0027 | ||
40 | #define LOCHNAGAR1_GF_GPIO7 0x0028 | ||
41 | #define LOCHNAGAR1_RST 0x0029 | ||
42 | #define LOCHNAGAR1_LED1 0x002A | ||
43 | #define LOCHNAGAR1_LED2 0x002B | ||
44 | #define LOCHNAGAR1_I2C_CTRL 0x0046 | ||
45 | |||
46 | /* | ||
47 | * (0x0008 - 0x000C, 0x0010 - 0x0012, 0x0017 - 0x0020) | ||
48 | * CDC_AIF1_SEL - GF_AIF2_SEL | ||
49 | */ | ||
50 | #define LOCHNAGAR1_SRC_MASK 0xFF | ||
51 | #define LOCHNAGAR1_SRC_SHIFT 0 | ||
52 | |||
53 | /* (0x000D) CDC_AIF_CTRL1 */ | ||
54 | #define LOCHNAGAR1_CDC_AIF2_LRCLK_DIR_MASK 0x40 | ||
55 | #define LOCHNAGAR1_CDC_AIF2_LRCLK_DIR_SHIFT 6 | ||
56 | #define LOCHNAGAR1_CDC_AIF2_BCLK_DIR_MASK 0x20 | ||
57 | #define LOCHNAGAR1_CDC_AIF2_BCLK_DIR_SHIFT 5 | ||
58 | #define LOCHNAGAR1_CDC_AIF2_ENA_MASK 0x10 | ||
59 | #define LOCHNAGAR1_CDC_AIF2_ENA_SHIFT 4 | ||
60 | #define LOCHNAGAR1_CDC_AIF1_LRCLK_DIR_MASK 0x04 | ||
61 | #define LOCHNAGAR1_CDC_AIF1_LRCLK_DIR_SHIFT 2 | ||
62 | #define LOCHNAGAR1_CDC_AIF1_BCLK_DIR_MASK 0x02 | ||
63 | #define LOCHNAGAR1_CDC_AIF1_BCLK_DIR_SHIFT 1 | ||
64 | #define LOCHNAGAR1_CDC_AIF1_ENA_MASK 0x01 | ||
65 | #define LOCHNAGAR1_CDC_AIF1_ENA_SHIFT 0 | ||
66 | |||
67 | /* (0x000E) CDC_AIF_CTRL2 */ | ||
68 | #define LOCHNAGAR1_CDC_AIF3_LRCLK_DIR_MASK 0x40 | ||
69 | #define LOCHNAGAR1_CDC_AIF3_LRCLK_DIR_SHIFT 6 | ||
70 | #define LOCHNAGAR1_CDC_AIF3_BCLK_DIR_MASK 0x20 | ||
71 | #define LOCHNAGAR1_CDC_AIF3_BCLK_DIR_SHIFT 5 | ||
72 | #define LOCHNAGAR1_CDC_AIF3_ENA_MASK 0x10 | ||
73 | #define LOCHNAGAR1_CDC_AIF3_ENA_SHIFT 4 | ||
74 | #define LOCHNAGAR1_CDC_MCLK1_ENA_MASK 0x02 | ||
75 | #define LOCHNAGAR1_CDC_MCLK1_ENA_SHIFT 1 | ||
76 | #define LOCHNAGAR1_CDC_MCLK2_ENA_MASK 0x01 | ||
77 | #define LOCHNAGAR1_CDC_MCLK2_ENA_SHIFT 0 | ||
78 | |||
79 | /* (0x000F) EXT_AIF_CTRL */ | ||
80 | #define LOCHNAGAR1_SPDIF_AIF_LRCLK_DIR_MASK 0x20 | ||
81 | #define LOCHNAGAR1_SPDIF_AIF_LRCLK_DIR_SHIFT 5 | ||
82 | #define LOCHNAGAR1_SPDIF_AIF_BCLK_DIR_MASK 0x10 | ||
83 | #define LOCHNAGAR1_SPDIF_AIF_BCLK_DIR_SHIFT 4 | ||
84 | #define LOCHNAGAR1_SPDIF_AIF_ENA_MASK 0x08 | ||
85 | #define LOCHNAGAR1_SPDIF_AIF_ENA_SHIFT 3 | ||
86 | |||
87 | /* (0x0013) DSP_AIF */ | ||
88 | #define LOCHNAGAR1_DSP_AIF2_LRCLK_DIR_MASK 0x40 | ||
89 | #define LOCHNAGAR1_DSP_AIF2_LRCLK_DIR_SHIFT 6 | ||
90 | #define LOCHNAGAR1_DSP_AIF2_BCLK_DIR_MASK 0x20 | ||
91 | #define LOCHNAGAR1_DSP_AIF2_BCLK_DIR_SHIFT 5 | ||
92 | #define LOCHNAGAR1_DSP_AIF2_ENA_MASK 0x10 | ||
93 | #define LOCHNAGAR1_DSP_AIF2_ENA_SHIFT 4 | ||
94 | #define LOCHNAGAR1_DSP_CLKIN_ENA_MASK 0x08 | ||
95 | #define LOCHNAGAR1_DSP_CLKIN_ENA_SHIFT 3 | ||
96 | #define LOCHNAGAR1_DSP_AIF1_LRCLK_DIR_MASK 0x04 | ||
97 | #define LOCHNAGAR1_DSP_AIF1_LRCLK_DIR_SHIFT 2 | ||
98 | #define LOCHNAGAR1_DSP_AIF1_BCLK_DIR_MASK 0x02 | ||
99 | #define LOCHNAGAR1_DSP_AIF1_BCLK_DIR_SHIFT 1 | ||
100 | #define LOCHNAGAR1_DSP_AIF1_ENA_MASK 0x01 | ||
101 | #define LOCHNAGAR1_DSP_AIF1_ENA_SHIFT 0 | ||
102 | |||
103 | /* (0x0014) GF_AIF1 */ | ||
104 | #define LOCHNAGAR1_GF_CLKOUT1_ENA_MASK 0x40 | ||
105 | #define LOCHNAGAR1_GF_CLKOUT1_ENA_SHIFT 6 | ||
106 | #define LOCHNAGAR1_GF_AIF3_LRCLK_DIR_MASK 0x20 | ||
107 | #define LOCHNAGAR1_GF_AIF3_LRCLK_DIR_SHIFT 5 | ||
108 | #define LOCHNAGAR1_GF_AIF3_BCLK_DIR_MASK 0x10 | ||
109 | #define LOCHNAGAR1_GF_AIF3_BCLK_DIR_SHIFT 4 | ||
110 | #define LOCHNAGAR1_GF_AIF3_ENA_MASK 0x08 | ||
111 | #define LOCHNAGAR1_GF_AIF3_ENA_SHIFT 3 | ||
112 | #define LOCHNAGAR1_GF_AIF1_LRCLK_DIR_MASK 0x04 | ||
113 | #define LOCHNAGAR1_GF_AIF1_LRCLK_DIR_SHIFT 2 | ||
114 | #define LOCHNAGAR1_GF_AIF1_BCLK_DIR_MASK 0x02 | ||
115 | #define LOCHNAGAR1_GF_AIF1_BCLK_DIR_SHIFT 1 | ||
116 | #define LOCHNAGAR1_GF_AIF1_ENA_MASK 0x01 | ||
117 | #define LOCHNAGAR1_GF_AIF1_ENA_SHIFT 0 | ||
118 | |||
119 | /* (0x0015) GF_AIF2 */ | ||
120 | #define LOCHNAGAR1_GF_AIF4_LRCLK_DIR_MASK 0x20 | ||
121 | #define LOCHNAGAR1_GF_AIF4_LRCLK_DIR_SHIFT 5 | ||
122 | #define LOCHNAGAR1_GF_AIF4_BCLK_DIR_MASK 0x10 | ||
123 | #define LOCHNAGAR1_GF_AIF4_BCLK_DIR_SHIFT 4 | ||
124 | #define LOCHNAGAR1_GF_AIF4_ENA_MASK 0x08 | ||
125 | #define LOCHNAGAR1_GF_AIF4_ENA_SHIFT 3 | ||
126 | #define LOCHNAGAR1_GF_AIF2_LRCLK_DIR_MASK 0x04 | ||
127 | #define LOCHNAGAR1_GF_AIF2_LRCLK_DIR_SHIFT 2 | ||
128 | #define LOCHNAGAR1_GF_AIF2_BCLK_DIR_MASK 0x02 | ||
129 | #define LOCHNAGAR1_GF_AIF2_BCLK_DIR_SHIFT 1 | ||
130 | #define LOCHNAGAR1_GF_AIF2_ENA_MASK 0x01 | ||
131 | #define LOCHNAGAR1_GF_AIF2_ENA_SHIFT 0 | ||
132 | |||
133 | /* (0x0016) PSIA_AIF */ | ||
134 | #define LOCHNAGAR1_PSIA2_LRCLK_DIR_MASK 0x40 | ||
135 | #define LOCHNAGAR1_PSIA2_LRCLK_DIR_SHIFT 6 | ||
136 | #define LOCHNAGAR1_PSIA2_BCLK_DIR_MASK 0x20 | ||
137 | #define LOCHNAGAR1_PSIA2_BCLK_DIR_SHIFT 5 | ||
138 | #define LOCHNAGAR1_PSIA2_ENA_MASK 0x10 | ||
139 | #define LOCHNAGAR1_PSIA2_ENA_SHIFT 4 | ||
140 | #define LOCHNAGAR1_PSIA1_LRCLK_DIR_MASK 0x04 | ||
141 | #define LOCHNAGAR1_PSIA1_LRCLK_DIR_SHIFT 2 | ||
142 | #define LOCHNAGAR1_PSIA1_BCLK_DIR_MASK 0x02 | ||
143 | #define LOCHNAGAR1_PSIA1_BCLK_DIR_SHIFT 1 | ||
144 | #define LOCHNAGAR1_PSIA1_ENA_MASK 0x01 | ||
145 | #define LOCHNAGAR1_PSIA1_ENA_SHIFT 0 | ||
146 | |||
147 | /* (0x0029) RST */ | ||
148 | #define LOCHNAGAR1_DSP_RESET_MASK 0x02 | ||
149 | #define LOCHNAGAR1_DSP_RESET_SHIFT 1 | ||
150 | #define LOCHNAGAR1_CDC_RESET_MASK 0x01 | ||
151 | #define LOCHNAGAR1_CDC_RESET_SHIFT 0 | ||
152 | |||
153 | /* (0x0046) I2C_CTRL */ | ||
154 | #define LOCHNAGAR1_CDC_CIF_MODE_MASK 0x01 | ||
155 | #define LOCHNAGAR1_CDC_CIF_MODE_SHIFT 0 | ||
156 | |||
157 | #endif | ||
diff --git a/include/linux/mfd/lochnagar2_regs.h b/include/linux/mfd/lochnagar2_regs.h new file mode 100644 index 000000000000..419b25a332fd --- /dev/null +++ b/include/linux/mfd/lochnagar2_regs.h | |||
@@ -0,0 +1,291 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Lochnagar2 register definitions | ||
4 | * | ||
5 | * Copyright (c) 2017-2018 Cirrus Logic, Inc. and | ||
6 | * Cirrus Logic International Semiconductor Ltd. | ||
7 | * | ||
8 | * Author: Charles Keepax <ckeepax@opensource.cirrus.com> | ||
9 | */ | ||
10 | |||
11 | #ifndef LOCHNAGAR2_REGISTERS_H | ||
12 | #define LOCHNAGAR2_REGISTERS_H | ||
13 | |||
14 | /* Register Addresses */ | ||
15 | #define LOCHNAGAR2_CDC_AIF1_CTRL 0x000D | ||
16 | #define LOCHNAGAR2_CDC_AIF2_CTRL 0x000E | ||
17 | #define LOCHNAGAR2_CDC_AIF3_CTRL 0x000F | ||
18 | #define LOCHNAGAR2_DSP_AIF1_CTRL 0x0010 | ||
19 | #define LOCHNAGAR2_DSP_AIF2_CTRL 0x0011 | ||
20 | #define LOCHNAGAR2_PSIA1_CTRL 0x0012 | ||
21 | #define LOCHNAGAR2_PSIA2_CTRL 0x0013 | ||
22 | #define LOCHNAGAR2_GF_AIF3_CTRL 0x0014 | ||
23 | #define LOCHNAGAR2_GF_AIF4_CTRL 0x0015 | ||
24 | #define LOCHNAGAR2_GF_AIF1_CTRL 0x0016 | ||
25 | #define LOCHNAGAR2_GF_AIF2_CTRL 0x0017 | ||
26 | #define LOCHNAGAR2_SPDIF_AIF_CTRL 0x0018 | ||
27 | #define LOCHNAGAR2_USB_AIF1_CTRL 0x0019 | ||
28 | #define LOCHNAGAR2_USB_AIF2_CTRL 0x001A | ||
29 | #define LOCHNAGAR2_ADAT_AIF_CTRL 0x001B | ||
30 | #define LOCHNAGAR2_CDC_MCLK1_CTRL 0x001E | ||
31 | #define LOCHNAGAR2_CDC_MCLK2_CTRL 0x001F | ||
32 | #define LOCHNAGAR2_DSP_CLKIN_CTRL 0x0020 | ||
33 | #define LOCHNAGAR2_PSIA1_MCLK_CTRL 0x0021 | ||
34 | #define LOCHNAGAR2_PSIA2_MCLK_CTRL 0x0022 | ||
35 | #define LOCHNAGAR2_SPDIF_MCLK_CTRL 0x0023 | ||
36 | #define LOCHNAGAR2_GF_CLKOUT1_CTRL 0x0024 | ||
37 | #define LOCHNAGAR2_GF_CLKOUT2_CTRL 0x0025 | ||
38 | #define LOCHNAGAR2_ADAT_MCLK_CTRL 0x0026 | ||
39 | #define LOCHNAGAR2_SOUNDCARD_MCLK_CTRL 0x0027 | ||
40 | #define LOCHNAGAR2_GPIO_FPGA_GPIO1 0x0031 | ||
41 | #define LOCHNAGAR2_GPIO_FPGA_GPIO2 0x0032 | ||
42 | #define LOCHNAGAR2_GPIO_FPGA_GPIO3 0x0033 | ||
43 | #define LOCHNAGAR2_GPIO_FPGA_GPIO4 0x0034 | ||
44 | #define LOCHNAGAR2_GPIO_FPGA_GPIO5 0x0035 | ||
45 | #define LOCHNAGAR2_GPIO_FPGA_GPIO6 0x0036 | ||
46 | #define LOCHNAGAR2_GPIO_CDC_GPIO1 0x0037 | ||
47 | #define LOCHNAGAR2_GPIO_CDC_GPIO2 0x0038 | ||
48 | #define LOCHNAGAR2_GPIO_CDC_GPIO3 0x0039 | ||
49 | #define LOCHNAGAR2_GPIO_CDC_GPIO4 0x003A | ||
50 | #define LOCHNAGAR2_GPIO_CDC_GPIO5 0x003B | ||
51 | #define LOCHNAGAR2_GPIO_CDC_GPIO6 0x003C | ||
52 | #define LOCHNAGAR2_GPIO_CDC_GPIO7 0x003D | ||
53 | #define LOCHNAGAR2_GPIO_CDC_GPIO8 0x003E | ||
54 | #define LOCHNAGAR2_GPIO_DSP_GPIO1 0x003F | ||
55 | #define LOCHNAGAR2_GPIO_DSP_GPIO2 0x0040 | ||
56 | #define LOCHNAGAR2_GPIO_DSP_GPIO3 0x0041 | ||
57 | #define LOCHNAGAR2_GPIO_DSP_GPIO4 0x0042 | ||
58 | #define LOCHNAGAR2_GPIO_DSP_GPIO5 0x0043 | ||
59 | #define LOCHNAGAR2_GPIO_DSP_GPIO6 0x0044 | ||
60 | #define LOCHNAGAR2_GPIO_GF_GPIO2 0x0045 | ||
61 | #define LOCHNAGAR2_GPIO_GF_GPIO3 0x0046 | ||
62 | #define LOCHNAGAR2_GPIO_GF_GPIO7 0x0047 | ||
63 | #define LOCHNAGAR2_GPIO_CDC_AIF1_BCLK 0x0048 | ||
64 | #define LOCHNAGAR2_GPIO_CDC_AIF1_RXDAT 0x0049 | ||
65 | #define LOCHNAGAR2_GPIO_CDC_AIF1_LRCLK 0x004A | ||
66 | #define LOCHNAGAR2_GPIO_CDC_AIF1_TXDAT 0x004B | ||
67 | #define LOCHNAGAR2_GPIO_CDC_AIF2_BCLK 0x004C | ||
68 | #define LOCHNAGAR2_GPIO_CDC_AIF2_RXDAT 0x004D | ||
69 | #define LOCHNAGAR2_GPIO_CDC_AIF2_LRCLK 0x004E | ||
70 | #define LOCHNAGAR2_GPIO_CDC_AIF2_TXDAT 0x004F | ||
71 | #define LOCHNAGAR2_GPIO_CDC_AIF3_BCLK 0x0050 | ||
72 | #define LOCHNAGAR2_GPIO_CDC_AIF3_RXDAT 0x0051 | ||
73 | #define LOCHNAGAR2_GPIO_CDC_AIF3_LRCLK 0x0052 | ||
74 | #define LOCHNAGAR2_GPIO_CDC_AIF3_TXDAT 0x0053 | ||
75 | #define LOCHNAGAR2_GPIO_DSP_AIF1_BCLK 0x0054 | ||
76 | #define LOCHNAGAR2_GPIO_DSP_AIF1_RXDAT 0x0055 | ||
77 | #define LOCHNAGAR2_GPIO_DSP_AIF1_LRCLK 0x0056 | ||
78 | #define LOCHNAGAR2_GPIO_DSP_AIF1_TXDAT 0x0057 | ||
79 | #define LOCHNAGAR2_GPIO_DSP_AIF2_BCLK 0x0058 | ||
80 | #define LOCHNAGAR2_GPIO_DSP_AIF2_RXDAT 0x0059 | ||
81 | #define LOCHNAGAR2_GPIO_DSP_AIF2_LRCLK 0x005A | ||
82 | #define LOCHNAGAR2_GPIO_DSP_AIF2_TXDAT 0x005B | ||
83 | #define LOCHNAGAR2_GPIO_PSIA1_BCLK 0x005C | ||
84 | #define LOCHNAGAR2_GPIO_PSIA1_RXDAT 0x005D | ||
85 | #define LOCHNAGAR2_GPIO_PSIA1_LRCLK 0x005E | ||
86 | #define LOCHNAGAR2_GPIO_PSIA1_TXDAT 0x005F | ||
87 | #define LOCHNAGAR2_GPIO_PSIA2_BCLK 0x0060 | ||
88 | #define LOCHNAGAR2_GPIO_PSIA2_RXDAT 0x0061 | ||
89 | #define LOCHNAGAR2_GPIO_PSIA2_LRCLK 0x0062 | ||
90 | #define LOCHNAGAR2_GPIO_PSIA2_TXDAT 0x0063 | ||
91 | #define LOCHNAGAR2_GPIO_GF_AIF3_BCLK 0x0064 | ||
92 | #define LOCHNAGAR2_GPIO_GF_AIF3_RXDAT 0x0065 | ||
93 | #define LOCHNAGAR2_GPIO_GF_AIF3_LRCLK 0x0066 | ||
94 | #define LOCHNAGAR2_GPIO_GF_AIF3_TXDAT 0x0067 | ||
95 | #define LOCHNAGAR2_GPIO_GF_AIF4_BCLK 0x0068 | ||
96 | #define LOCHNAGAR2_GPIO_GF_AIF4_RXDAT 0x0069 | ||
97 | #define LOCHNAGAR2_GPIO_GF_AIF4_LRCLK 0x006A | ||
98 | #define LOCHNAGAR2_GPIO_GF_AIF4_TXDAT 0x006B | ||
99 | #define LOCHNAGAR2_GPIO_GF_AIF1_BCLK 0x006C | ||
100 | #define LOCHNAGAR2_GPIO_GF_AIF1_RXDAT 0x006D | ||
101 | #define LOCHNAGAR2_GPIO_GF_AIF1_LRCLK 0x006E | ||
102 | #define LOCHNAGAR2_GPIO_GF_AIF1_TXDAT 0x006F | ||
103 | #define LOCHNAGAR2_GPIO_GF_AIF2_BCLK 0x0070 | ||
104 | #define LOCHNAGAR2_GPIO_GF_AIF2_RXDAT 0x0071 | ||
105 | #define LOCHNAGAR2_GPIO_GF_AIF2_LRCLK 0x0072 | ||
106 | #define LOCHNAGAR2_GPIO_GF_AIF2_TXDAT 0x0073 | ||
107 | #define LOCHNAGAR2_GPIO_DSP_UART1_RX 0x0074 | ||
108 | #define LOCHNAGAR2_GPIO_DSP_UART1_TX 0x0075 | ||
109 | #define LOCHNAGAR2_GPIO_DSP_UART2_RX 0x0076 | ||
110 | #define LOCHNAGAR2_GPIO_DSP_UART2_TX 0x0077 | ||
111 | #define LOCHNAGAR2_GPIO_GF_UART2_RX 0x0078 | ||
112 | #define LOCHNAGAR2_GPIO_GF_UART2_TX 0x0079 | ||
113 | #define LOCHNAGAR2_GPIO_USB_UART_RX 0x007A | ||
114 | #define LOCHNAGAR2_GPIO_CDC_PDMCLK1 0x007C | ||
115 | #define LOCHNAGAR2_GPIO_CDC_PDMDAT1 0x007D | ||
116 | #define LOCHNAGAR2_GPIO_CDC_PDMCLK2 0x007E | ||
117 | #define LOCHNAGAR2_GPIO_CDC_PDMDAT2 0x007F | ||
118 | #define LOCHNAGAR2_GPIO_CDC_DMICCLK1 0x0080 | ||
119 | #define LOCHNAGAR2_GPIO_CDC_DMICDAT1 0x0081 | ||
120 | #define LOCHNAGAR2_GPIO_CDC_DMICCLK2 0x0082 | ||
121 | #define LOCHNAGAR2_GPIO_CDC_DMICDAT2 0x0083 | ||
122 | #define LOCHNAGAR2_GPIO_CDC_DMICCLK3 0x0084 | ||
123 | #define LOCHNAGAR2_GPIO_CDC_DMICDAT3 0x0085 | ||
124 | #define LOCHNAGAR2_GPIO_CDC_DMICCLK4 0x0086 | ||
125 | #define LOCHNAGAR2_GPIO_CDC_DMICDAT4 0x0087 | ||
126 | #define LOCHNAGAR2_GPIO_DSP_DMICCLK1 0x0088 | ||
127 | #define LOCHNAGAR2_GPIO_DSP_DMICDAT1 0x0089 | ||
128 | #define LOCHNAGAR2_GPIO_DSP_DMICCLK2 0x008A | ||
129 | #define LOCHNAGAR2_GPIO_DSP_DMICDAT2 0x008B | ||
130 | #define LOCHNAGAR2_GPIO_I2C2_SCL 0x008C | ||
131 | #define LOCHNAGAR2_GPIO_I2C2_SDA 0x008D | ||
132 | #define LOCHNAGAR2_GPIO_I2C3_SCL 0x008E | ||
133 | #define LOCHNAGAR2_GPIO_I2C3_SDA 0x008F | ||
134 | #define LOCHNAGAR2_GPIO_I2C4_SCL 0x0090 | ||
135 | #define LOCHNAGAR2_GPIO_I2C4_SDA 0x0091 | ||
136 | #define LOCHNAGAR2_GPIO_DSP_STANDBY 0x0092 | ||
137 | #define LOCHNAGAR2_GPIO_CDC_MCLK1 0x0093 | ||
138 | #define LOCHNAGAR2_GPIO_CDC_MCLK2 0x0094 | ||
139 | #define LOCHNAGAR2_GPIO_DSP_CLKIN 0x0095 | ||
140 | #define LOCHNAGAR2_GPIO_PSIA1_MCLK 0x0096 | ||
141 | #define LOCHNAGAR2_GPIO_PSIA2_MCLK 0x0097 | ||
142 | #define LOCHNAGAR2_GPIO_GF_GPIO1 0x0098 | ||
143 | #define LOCHNAGAR2_GPIO_GF_GPIO5 0x0099 | ||
144 | #define LOCHNAGAR2_GPIO_DSP_GPIO20 0x009A | ||
145 | #define LOCHNAGAR2_GPIO_CHANNEL1 0x00B9 | ||
146 | #define LOCHNAGAR2_GPIO_CHANNEL2 0x00BA | ||
147 | #define LOCHNAGAR2_GPIO_CHANNEL3 0x00BB | ||
148 | #define LOCHNAGAR2_GPIO_CHANNEL4 0x00BC | ||
149 | #define LOCHNAGAR2_GPIO_CHANNEL5 0x00BD | ||
150 | #define LOCHNAGAR2_GPIO_CHANNEL6 0x00BE | ||
151 | #define LOCHNAGAR2_GPIO_CHANNEL7 0x00BF | ||
152 | #define LOCHNAGAR2_GPIO_CHANNEL8 0x00C0 | ||
153 | #define LOCHNAGAR2_GPIO_CHANNEL9 0x00C1 | ||
154 | #define LOCHNAGAR2_GPIO_CHANNEL10 0x00C2 | ||
155 | #define LOCHNAGAR2_GPIO_CHANNEL11 0x00C3 | ||
156 | #define LOCHNAGAR2_GPIO_CHANNEL12 0x00C4 | ||
157 | #define LOCHNAGAR2_GPIO_CHANNEL13 0x00C5 | ||
158 | #define LOCHNAGAR2_GPIO_CHANNEL14 0x00C6 | ||
159 | #define LOCHNAGAR2_GPIO_CHANNEL15 0x00C7 | ||
160 | #define LOCHNAGAR2_GPIO_CHANNEL16 0x00C8 | ||
161 | #define LOCHNAGAR2_MINICARD_RESETS 0x00DF | ||
162 | #define LOCHNAGAR2_ANALOGUE_PATH_CTRL1 0x00E3 | ||
163 | #define LOCHNAGAR2_ANALOGUE_PATH_CTRL2 0x00E4 | ||
164 | #define LOCHNAGAR2_COMMS_CTRL4 0x00F0 | ||
165 | #define LOCHNAGAR2_SPDIF_CTRL 0x00FE | ||
166 | #define LOCHNAGAR2_IMON_CTRL1 0x0108 | ||
167 | #define LOCHNAGAR2_IMON_CTRL2 0x0109 | ||
168 | #define LOCHNAGAR2_IMON_CTRL3 0x010A | ||
169 | #define LOCHNAGAR2_IMON_CTRL4 0x010B | ||
170 | #define LOCHNAGAR2_IMON_DATA1 0x010C | ||
171 | #define LOCHNAGAR2_IMON_DATA2 0x010D | ||
172 | #define LOCHNAGAR2_POWER_CTRL 0x0116 | ||
173 | #define LOCHNAGAR2_MICVDD_CTRL1 0x0119 | ||
174 | #define LOCHNAGAR2_MICVDD_CTRL2 0x011B | ||
175 | #define LOCHNAGAR2_VDDCORE_CDC_CTRL1 0x011E | ||
176 | #define LOCHNAGAR2_VDDCORE_CDC_CTRL2 0x0120 | ||
177 | #define LOCHNAGAR2_SOUNDCARD_AIF_CTRL 0x0180 | ||
178 | |||
179 | /* (0x000D-0x001B, 0x0180) CDC_AIF1_CTRL - SOUNCARD_AIF_CTRL */ | ||
180 | #define LOCHNAGAR2_AIF_ENA_MASK 0x8000 | ||
181 | #define LOCHNAGAR2_AIF_ENA_SHIFT 15 | ||
182 | #define LOCHNAGAR2_AIF_LRCLK_DIR_MASK 0x4000 | ||
183 | #define LOCHNAGAR2_AIF_LRCLK_DIR_SHIFT 14 | ||
184 | #define LOCHNAGAR2_AIF_BCLK_DIR_MASK 0x2000 | ||
185 | #define LOCHNAGAR2_AIF_BCLK_DIR_SHIFT 13 | ||
186 | #define LOCHNAGAR2_AIF_SRC_MASK 0x00FF | ||
187 | #define LOCHNAGAR2_AIF_SRC_SHIFT 0 | ||
188 | |||
189 | /* (0x001E - 0x0027) CDC_MCLK1_CTRL - SOUNDCARD_MCLK_CTRL */ | ||
190 | #define LOCHNAGAR2_CLK_ENA_MASK 0x8000 | ||
191 | #define LOCHNAGAR2_CLK_ENA_SHIFT 15 | ||
192 | #define LOCHNAGAR2_CLK_SRC_MASK 0x00FF | ||
193 | #define LOCHNAGAR2_CLK_SRC_SHIFT 0 | ||
194 | |||
195 | /* (0x0031 - 0x009A) GPIO_FPGA_GPIO1 - GPIO_DSP_GPIO20 */ | ||
196 | #define LOCHNAGAR2_GPIO_SRC_MASK 0x00FF | ||
197 | #define LOCHNAGAR2_GPIO_SRC_SHIFT 0 | ||
198 | |||
199 | /* (0x00B9 - 0x00C8) GPIO_CHANNEL1 - GPIO_CHANNEL16 */ | ||
200 | #define LOCHNAGAR2_GPIO_CHANNEL_STS_MASK 0x8000 | ||
201 | #define LOCHNAGAR2_GPIO_CHANNEL_STS_SHIFT 15 | ||
202 | #define LOCHNAGAR2_GPIO_CHANNEL_SRC_MASK 0x00FF | ||
203 | #define LOCHNAGAR2_GPIO_CHANNEL_SRC_SHIFT 0 | ||
204 | |||
205 | /* (0x00DF) MINICARD_RESETS */ | ||
206 | #define LOCHNAGAR2_DSP_RESET_MASK 0x0002 | ||
207 | #define LOCHNAGAR2_DSP_RESET_SHIFT 1 | ||
208 | #define LOCHNAGAR2_CDC_RESET_MASK 0x0001 | ||
209 | #define LOCHNAGAR2_CDC_RESET_SHIFT 0 | ||
210 | |||
211 | /* (0x00E3) ANALOGUE_PATH_CTRL1 */ | ||
212 | #define LOCHNAGAR2_ANALOGUE_PATH_UPDATE_MASK 0x8000 | ||
213 | #define LOCHNAGAR2_ANALOGUE_PATH_UPDATE_SHIFT 15 | ||
214 | #define LOCHNAGAR2_ANALOGUE_PATH_UPDATE_STS_MASK 0x4000 | ||
215 | #define LOCHNAGAR2_ANALOGUE_PATH_UPDATE_STS_SHIFT 14 | ||
216 | |||
217 | /* (0x00E4) ANALOGUE_PATH_CTRL2 */ | ||
218 | #define LOCHNAGAR2_P2_INPUT_BIAS_ENA_MASK 0x0080 | ||
219 | #define LOCHNAGAR2_P2_INPUT_BIAS_ENA_SHIFT 7 | ||
220 | #define LOCHNAGAR2_P1_INPUT_BIAS_ENA_MASK 0x0040 | ||
221 | #define LOCHNAGAR2_P1_INPUT_BIAS_ENA_SHIFT 6 | ||
222 | #define LOCHNAGAR2_P2_MICBIAS_SRC_MASK 0x0038 | ||
223 | #define LOCHNAGAR2_P2_MICBIAS_SRC_SHIFT 3 | ||
224 | #define LOCHNAGAR2_P1_MICBIAS_SRC_MASK 0x0007 | ||
225 | #define LOCHNAGAR2_P1_MICBIAS_SRC_SHIFT 0 | ||
226 | |||
227 | /* (0x00F0) COMMS_CTRL4 */ | ||
228 | #define LOCHNAGAR2_CDC_CIF1MODE_MASK 0x0001 | ||
229 | #define LOCHNAGAR2_CDC_CIF1MODE_SHIFT 0 | ||
230 | |||
231 | /* (0x00FE) SPDIF_CTRL */ | ||
232 | #define LOCHNAGAR2_SPDIF_HWMODE_MASK 0x0008 | ||
233 | #define LOCHNAGAR2_SPDIF_HWMODE_SHIFT 3 | ||
234 | #define LOCHNAGAR2_SPDIF_RESET_MASK 0x0001 | ||
235 | #define LOCHNAGAR2_SPDIF_RESET_SHIFT 0 | ||
236 | |||
237 | /* (0x0108) IMON_CTRL1 */ | ||
238 | #define LOCHNAGAR2_IMON_ENA_MASK 0x8000 | ||
239 | #define LOCHNAGAR2_IMON_ENA_SHIFT 15 | ||
240 | #define LOCHNAGAR2_IMON_MEASURED_CHANNELS_MASK 0x03FC | ||
241 | #define LOCHNAGAR2_IMON_MEASURED_CHANNELS_SHIFT 2 | ||
242 | #define LOCHNAGAR2_IMON_MODE_SEL_MASK 0x0003 | ||
243 | #define LOCHNAGAR2_IMON_MODE_SEL_SHIFT 0 | ||
244 | |||
245 | /* (0x0109) IMON_CTRL2 */ | ||
246 | #define LOCHNAGAR2_IMON_FSR_MASK 0x03FF | ||
247 | #define LOCHNAGAR2_IMON_FSR_SHIFT 0 | ||
248 | |||
249 | /* (0x010A) IMON_CTRL3 */ | ||
250 | #define LOCHNAGAR2_IMON_DONE_MASK 0x0004 | ||
251 | #define LOCHNAGAR2_IMON_DONE_SHIFT 2 | ||
252 | #define LOCHNAGAR2_IMON_CONFIGURE_MASK 0x0002 | ||
253 | #define LOCHNAGAR2_IMON_CONFIGURE_SHIFT 1 | ||
254 | #define LOCHNAGAR2_IMON_MEASURE_MASK 0x0001 | ||
255 | #define LOCHNAGAR2_IMON_MEASURE_SHIFT 0 | ||
256 | |||
257 | /* (0x010B) IMON_CTRL4 */ | ||
258 | #define LOCHNAGAR2_IMON_DATA_REQ_MASK 0x0080 | ||
259 | #define LOCHNAGAR2_IMON_DATA_REQ_SHIFT 7 | ||
260 | #define LOCHNAGAR2_IMON_CH_SEL_MASK 0x0070 | ||
261 | #define LOCHNAGAR2_IMON_CH_SEL_SHIFT 4 | ||
262 | #define LOCHNAGAR2_IMON_DATA_RDY_MASK 0x0008 | ||
263 | #define LOCHNAGAR2_IMON_DATA_RDY_SHIFT 3 | ||
264 | #define LOCHNAGAR2_IMON_CH_SRC_MASK 0x0007 | ||
265 | #define LOCHNAGAR2_IMON_CH_SRC_SHIFT 0 | ||
266 | |||
267 | /* (0x010C, 0x010D) IMON_DATA1, IMON_DATA2 */ | ||
268 | #define LOCHNAGAR2_IMON_DATA_MASK 0xFFFF | ||
269 | #define LOCHNAGAR2_IMON_DATA_SHIFT 0 | ||
270 | |||
271 | /* (0x0116) POWER_CTRL */ | ||
272 | #define LOCHNAGAR2_PWR_ENA_MASK 0x0001 | ||
273 | #define LOCHNAGAR2_PWR_ENA_SHIFT 0 | ||
274 | |||
275 | /* (0x0119) MICVDD_CTRL1 */ | ||
276 | #define LOCHNAGAR2_MICVDD_REG_ENA_MASK 0x8000 | ||
277 | #define LOCHNAGAR2_MICVDD_REG_ENA_SHIFT 15 | ||
278 | |||
279 | /* (0x011B) MICVDD_CTRL2 */ | ||
280 | #define LOCHNAGAR2_MICVDD_VSEL_MASK 0x001F | ||
281 | #define LOCHNAGAR2_MICVDD_VSEL_SHIFT 0 | ||
282 | |||
283 | /* (0x011E) VDDCORE_CDC_CTRL1 */ | ||
284 | #define LOCHNAGAR2_VDDCORE_CDC_REG_ENA_MASK 0x8000 | ||
285 | #define LOCHNAGAR2_VDDCORE_CDC_REG_ENA_SHIFT 15 | ||
286 | |||
287 | /* (0x0120) VDDCORE_CDC_CTRL2 */ | ||
288 | #define LOCHNAGAR2_VDDCORE_CDC_VSEL_MASK 0x007F | ||
289 | #define LOCHNAGAR2_VDDCORE_CDC_VSEL_SHIFT 0 | ||
290 | |||
291 | #endif | ||
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h index 4a827af17e59..07f55aac9390 100644 --- a/include/linux/mfd/stmpe.h +++ b/include/linux/mfd/stmpe.h | |||
@@ -10,6 +10,20 @@ | |||
10 | 10 | ||
11 | #include <linux/mutex.h> | 11 | #include <linux/mutex.h> |
12 | 12 | ||
13 | #define STMPE_SAMPLE_TIME(x) ((x & 0xf) << 4) | ||
14 | #define STMPE_MOD_12B(x) ((x & 0x1) << 3) | ||
15 | #define STMPE_REF_SEL(x) ((x & 0x1) << 1) | ||
16 | #define STMPE_ADC_FREQ(x) (x & 0x3) | ||
17 | #define STMPE_AVE_CTRL(x) ((x & 0x3) << 6) | ||
18 | #define STMPE_DET_DELAY(x) ((x & 0x7) << 3) | ||
19 | #define STMPE_SETTLING(x) (x & 0x7) | ||
20 | #define STMPE_FRACTION_Z(x) (x & 0x7) | ||
21 | #define STMPE_I_DRIVE(x) (x & 0x1) | ||
22 | #define STMPE_OP_MODE(x) ((x & 0x7) << 1) | ||
23 | |||
24 | #define STMPE811_REG_ADC_CTRL1 0x20 | ||
25 | #define STMPE811_REG_ADC_CTRL2 0x21 | ||
26 | |||
13 | struct device; | 27 | struct device; |
14 | struct regulator; | 28 | struct regulator; |
15 | 29 | ||
@@ -123,6 +137,12 @@ struct stmpe { | |||
123 | u8 ier[2]; | 137 | u8 ier[2]; |
124 | u8 oldier[2]; | 138 | u8 oldier[2]; |
125 | struct stmpe_platform_data *pdata; | 139 | struct stmpe_platform_data *pdata; |
140 | |||
141 | /* For devices that use an ADC */ | ||
142 | u8 sample_time; | ||
143 | u8 mod_12b; | ||
144 | u8 ref_sel; | ||
145 | u8 adc_freq; | ||
126 | }; | 146 | }; |
127 | 147 | ||
128 | extern int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 data); | 148 | extern int stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 data); |
@@ -136,6 +156,7 @@ extern int stmpe_set_altfunc(struct stmpe *stmpe, u32 pins, | |||
136 | enum stmpe_block block); | 156 | enum stmpe_block block); |
137 | extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks); | 157 | extern int stmpe_enable(struct stmpe *stmpe, unsigned int blocks); |
138 | extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks); | 158 | extern int stmpe_disable(struct stmpe *stmpe, unsigned int blocks); |
159 | extern int stmpe811_adc_common_init(struct stmpe *stmpe); | ||
139 | 160 | ||
140 | #define STMPE_GPIO_NOREQ_811_TOUCH (0xf0) | 161 | #define STMPE_GPIO_NOREQ_811_TOUCH (0xf0) |
141 | 162 | ||
diff --git a/include/linux/mfd/stpmic1.h b/include/linux/mfd/stpmic1.h new file mode 100644 index 000000000000..fa3f99f7e9a1 --- /dev/null +++ b/include/linux/mfd/stpmic1.h | |||
@@ -0,0 +1,212 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | /* | ||
3 | * Copyright (C) STMicroelectronics 2018 - All Rights Reserved | ||
4 | * Author: Philippe Peurichard <philippe.peurichard@st.com>, | ||
5 | * Pascal Paillet <p.paillet@st.com> for STMicroelectronics. | ||
6 | */ | ||
7 | |||
8 | #ifndef __LINUX_MFD_STPMIC1_H | ||
9 | #define __LINUX_MFD_STPMIC1_H | ||
10 | |||
11 | #define TURN_ON_SR 0x1 | ||
12 | #define TURN_OFF_SR 0x2 | ||
13 | #define ICC_LDO_TURN_OFF_SR 0x3 | ||
14 | #define ICC_BUCK_TURN_OFF_SR 0x4 | ||
15 | #define RREQ_STATE_SR 0x5 | ||
16 | #define VERSION_SR 0x6 | ||
17 | |||
18 | #define SWOFF_PWRCTRL_CR 0x10 | ||
19 | #define PADS_PULL_CR 0x11 | ||
20 | #define BUCKS_PD_CR 0x12 | ||
21 | #define LDO14_PD_CR 0x13 | ||
22 | #define LDO56_VREF_PD_CR 0x14 | ||
23 | #define VBUS_DET_VIN_CR 0x15 | ||
24 | #define PKEY_TURNOFF_CR 0x16 | ||
25 | #define BUCKS_MASK_RANK_CR 0x17 | ||
26 | #define BUCKS_MASK_RESET_CR 0x18 | ||
27 | #define LDOS_MASK_RANK_CR 0x19 | ||
28 | #define LDOS_MASK_RESET_CR 0x1A | ||
29 | #define WCHDG_CR 0x1B | ||
30 | #define WCHDG_TIMER_CR 0x1C | ||
31 | #define BUCKS_ICCTO_CR 0x1D | ||
32 | #define LDOS_ICCTO_CR 0x1E | ||
33 | |||
34 | #define BUCK1_ACTIVE_CR 0x20 | ||
35 | #define BUCK2_ACTIVE_CR 0x21 | ||
36 | #define BUCK3_ACTIVE_CR 0x22 | ||
37 | #define BUCK4_ACTIVE_CR 0x23 | ||
38 | #define VREF_DDR_ACTIVE_CR 0x24 | ||
39 | #define LDO1_ACTIVE_CR 0x25 | ||
40 | #define LDO2_ACTIVE_CR 0x26 | ||
41 | #define LDO3_ACTIVE_CR 0x27 | ||
42 | #define LDO4_ACTIVE_CR 0x28 | ||
43 | #define LDO5_ACTIVE_CR 0x29 | ||
44 | #define LDO6_ACTIVE_CR 0x2A | ||
45 | |||
46 | #define BUCK1_STDBY_CR 0x30 | ||
47 | #define BUCK2_STDBY_CR 0x31 | ||
48 | #define BUCK3_STDBY_CR 0x32 | ||
49 | #define BUCK4_STDBY_CR 0x33 | ||
50 | #define VREF_DDR_STDBY_CR 0x34 | ||
51 | #define LDO1_STDBY_CR 0x35 | ||
52 | #define LDO2_STDBY_CR 0x36 | ||
53 | #define LDO3_STDBY_CR 0x37 | ||
54 | #define LDO4_STDBY_CR 0x38 | ||
55 | #define LDO5_STDBY_CR 0x39 | ||
56 | #define LDO6_STDBY_CR 0x3A | ||
57 | |||
58 | #define BST_SW_CR 0x40 | ||
59 | |||
60 | #define INT_PENDING_R1 0x50 | ||
61 | #define INT_PENDING_R2 0x51 | ||
62 | #define INT_PENDING_R3 0x52 | ||
63 | #define INT_PENDING_R4 0x53 | ||
64 | |||
65 | #define INT_DBG_LATCH_R1 0x60 | ||
66 | #define INT_DBG_LATCH_R2 0x61 | ||
67 | #define INT_DBG_LATCH_R3 0x62 | ||
68 | #define INT_DBG_LATCH_R4 0x63 | ||
69 | |||
70 | #define INT_CLEAR_R1 0x70 | ||
71 | #define INT_CLEAR_R2 0x71 | ||
72 | #define INT_CLEAR_R3 0x72 | ||
73 | #define INT_CLEAR_R4 0x73 | ||
74 | |||
75 | #define INT_MASK_R1 0x80 | ||
76 | #define INT_MASK_R2 0x81 | ||
77 | #define INT_MASK_R3 0x82 | ||
78 | #define INT_MASK_R4 0x83 | ||
79 | |||
80 | #define INT_SET_MASK_R1 0x90 | ||
81 | #define INT_SET_MASK_R2 0x91 | ||
82 | #define INT_SET_MASK_R3 0x92 | ||
83 | #define INT_SET_MASK_R4 0x93 | ||
84 | |||
85 | #define INT_CLEAR_MASK_R1 0xA0 | ||
86 | #define INT_CLEAR_MASK_R2 0xA1 | ||
87 | #define INT_CLEAR_MASK_R3 0xA2 | ||
88 | #define INT_CLEAR_MASK_R4 0xA3 | ||
89 | |||
90 | #define INT_SRC_R1 0xB0 | ||
91 | #define INT_SRC_R2 0xB1 | ||
92 | #define INT_SRC_R3 0xB2 | ||
93 | #define INT_SRC_R4 0xB3 | ||
94 | |||
95 | #define PMIC_MAX_REGISTER_ADDRESS INT_SRC_R4 | ||
96 | |||
97 | #define STPMIC1_PMIC_NUM_IRQ_REGS 4 | ||
98 | |||
99 | #define TURN_OFF_SR_ICC_EVENT 0x08 | ||
100 | |||
101 | #define LDO_VOLTAGE_MASK GENMASK(6, 2) | ||
102 | #define BUCK_VOLTAGE_MASK GENMASK(7, 2) | ||
103 | #define LDO_BUCK_VOLTAGE_SHIFT 2 | ||
104 | |||
105 | #define LDO_ENABLE_MASK BIT(0) | ||
106 | #define BUCK_ENABLE_MASK BIT(0) | ||
107 | |||
108 | #define BUCK_HPLP_ENABLE_MASK BIT(1) | ||
109 | #define BUCK_HPLP_SHIFT 1 | ||
110 | |||
111 | #define STDBY_ENABLE_MASK BIT(0) | ||
112 | |||
113 | #define BUCKS_PD_CR_REG_MASK GENMASK(7, 0) | ||
114 | #define BUCK_MASK_RANK_REGISTER_MASK GENMASK(3, 0) | ||
115 | #define BUCK_MASK_RESET_REGISTER_MASK GENMASK(3, 0) | ||
116 | #define LDO1234_PULL_DOWN_REGISTER_MASK GENMASK(7, 0) | ||
117 | #define LDO56_VREF_PD_CR_REG_MASK GENMASK(5, 0) | ||
118 | #define LDO_MASK_RANK_REGISTER_MASK GENMASK(5, 0) | ||
119 | #define LDO_MASK_RESET_REGISTER_MASK GENMASK(5, 0) | ||
120 | |||
121 | #define BUCK1_PULL_DOWN_REG BUCKS_PD_CR | ||
122 | #define BUCK1_PULL_DOWN_MASK BIT(0) | ||
123 | #define BUCK2_PULL_DOWN_REG BUCKS_PD_CR | ||
124 | #define BUCK2_PULL_DOWN_MASK BIT(2) | ||
125 | #define BUCK3_PULL_DOWN_REG BUCKS_PD_CR | ||
126 | #define BUCK3_PULL_DOWN_MASK BIT(4) | ||
127 | #define BUCK4_PULL_DOWN_REG BUCKS_PD_CR | ||
128 | #define BUCK4_PULL_DOWN_MASK BIT(6) | ||
129 | |||
130 | #define LDO1_PULL_DOWN_REG LDO14_PD_CR | ||
131 | #define LDO1_PULL_DOWN_MASK BIT(0) | ||
132 | #define LDO2_PULL_DOWN_REG LDO14_PD_CR | ||
133 | #define LDO2_PULL_DOWN_MASK BIT(2) | ||
134 | #define LDO3_PULL_DOWN_REG LDO14_PD_CR | ||
135 | #define LDO3_PULL_DOWN_MASK BIT(4) | ||
136 | #define LDO4_PULL_DOWN_REG LDO14_PD_CR | ||
137 | #define LDO4_PULL_DOWN_MASK BIT(6) | ||
138 | #define LDO5_PULL_DOWN_REG LDO56_VREF_PD_CR | ||
139 | #define LDO5_PULL_DOWN_MASK BIT(0) | ||
140 | #define LDO6_PULL_DOWN_REG LDO56_VREF_PD_CR | ||
141 | #define LDO6_PULL_DOWN_MASK BIT(2) | ||
142 | #define VREF_DDR_PULL_DOWN_REG LDO56_VREF_PD_CR | ||
143 | #define VREF_DDR_PULL_DOWN_MASK BIT(4) | ||
144 | |||
145 | #define BUCKS_ICCTO_CR_REG_MASK GENMASK(6, 0) | ||
146 | #define LDOS_ICCTO_CR_REG_MASK GENMASK(5, 0) | ||
147 | |||
148 | #define LDO_BYPASS_MASK BIT(7) | ||
149 | |||
150 | /* Main PMIC Control Register | ||
151 | * SWOFF_PWRCTRL_CR | ||
152 | * Address : 0x10 | ||
153 | */ | ||
154 | #define ICC_EVENT_ENABLED BIT(4) | ||
155 | #define PWRCTRL_POLARITY_HIGH BIT(3) | ||
156 | #define PWRCTRL_PIN_VALID BIT(2) | ||
157 | #define RESTART_REQUEST_ENABLED BIT(1) | ||
158 | #define SOFTWARE_SWITCH_OFF_ENABLED BIT(0) | ||
159 | |||
160 | /* Main PMIC PADS Control Register | ||
161 | * PADS_PULL_CR | ||
162 | * Address : 0x11 | ||
163 | */ | ||
164 | #define WAKEUP_DETECTOR_DISABLED BIT(4) | ||
165 | #define PWRCTRL_PD_ACTIVE BIT(3) | ||
166 | #define PWRCTRL_PU_ACTIVE BIT(2) | ||
167 | #define WAKEUP_PD_ACTIVE BIT(1) | ||
168 | #define PONKEY_PU_INACTIVE BIT(0) | ||
169 | |||
170 | /* Main PMIC VINLOW Control Register | ||
171 | * VBUS_DET_VIN_CRC DMSC | ||
172 | * Address : 0x15 | ||
173 | */ | ||
174 | #define SWIN_DETECTOR_ENABLED BIT(7) | ||
175 | #define SWOUT_DETECTOR_ENABLED BIT(6) | ||
176 | #define VINLOW_ENABLED BIT(0) | ||
177 | #define VINLOW_CTRL_REG_MASK GENMASK(7, 0) | ||
178 | |||
179 | /* USB Control Register | ||
180 | * Address : 0x40 | ||
181 | */ | ||
182 | #define BOOST_OVP_DISABLED BIT(7) | ||
183 | #define VBUS_OTG_DETECTION_DISABLED BIT(6) | ||
184 | #define SW_OUT_DISCHARGE BIT(5) | ||
185 | #define VBUS_OTG_DISCHARGE BIT(4) | ||
186 | #define OCP_LIMIT_HIGH BIT(3) | ||
187 | #define SWIN_SWOUT_ENABLED BIT(2) | ||
188 | #define USBSW_OTG_SWITCH_ENABLED BIT(1) | ||
189 | #define BOOST_ENABLED BIT(0) | ||
190 | |||
191 | /* PKEY_TURNOFF_CR | ||
192 | * Address : 0x16 | ||
193 | */ | ||
194 | #define PONKEY_PWR_OFF BIT(7) | ||
195 | #define PONKEY_CC_FLAG_CLEAR BIT(6) | ||
196 | #define PONKEY_TURNOFF_TIMER_MASK GENMASK(3, 0) | ||
197 | #define PONKEY_TURNOFF_MASK GENMASK(7, 0) | ||
198 | |||
199 | /* | ||
200 | * struct stpmic1 - stpmic1 master device for sub-drivers | ||
201 | * @dev: master device of the chip (can be used to access platform data) | ||
202 | * @irq: main IRQ number | ||
203 | * @regmap_irq_chip_data: irq chip data | ||
204 | */ | ||
205 | struct stpmic1 { | ||
206 | struct device *dev; | ||
207 | struct regmap *regmap; | ||
208 | int irq; | ||
209 | struct regmap_irq_chip_data *irq_data; | ||
210 | }; | ||
211 | |||
212 | #endif /* __LINUX_MFD_STPMIC1_H */ | ||
diff --git a/include/linux/mfd/tps65218.h b/include/linux/mfd/tps65218.h index 45cdcd0fee53..b0470c35162d 100644 --- a/include/linux/mfd/tps65218.h +++ b/include/linux/mfd/tps65218.h | |||
@@ -137,6 +137,10 @@ | |||
137 | #define TPS65218_CONFIG1_PGDLY_MASK 0x18 | 137 | #define TPS65218_CONFIG1_PGDLY_MASK 0x18 |
138 | #define TPS65218_CONFIG1_STRICT BIT(2) | 138 | #define TPS65218_CONFIG1_STRICT BIT(2) |
139 | #define TPS65218_CONFIG1_UVLO_MASK 0x3 | 139 | #define TPS65218_CONFIG1_UVLO_MASK 0x3 |
140 | #define TPS65218_CONFIG1_UVLO_2750000 0x0 | ||
141 | #define TPS65218_CONFIG1_UVLO_2950000 0x1 | ||
142 | #define TPS65218_CONFIG1_UVLO_3250000 0x2 | ||
143 | #define TPS65218_CONFIG1_UVLO_3350000 0x3 | ||
140 | 144 | ||
141 | #define TPS65218_CONFIG2_DC12_RST BIT(7) | 145 | #define TPS65218_CONFIG2_DC12_RST BIT(7) |
142 | #define TPS65218_CONFIG2_UVLOHYS BIT(6) | 146 | #define TPS65218_CONFIG2_UVLOHYS BIT(6) |
diff --git a/include/linux/mfd/wm831x/core.h b/include/linux/mfd/wm831x/core.h index b49fa67612f1..6fcb8eb00282 100644 --- a/include/linux/mfd/wm831x/core.h +++ b/include/linux/mfd/wm831x/core.h | |||
@@ -418,7 +418,6 @@ int wm831x_bulk_read(struct wm831x *wm831x, unsigned short reg, | |||
418 | int count, u16 *buf); | 418 | int count, u16 *buf); |
419 | 419 | ||
420 | int wm831x_device_init(struct wm831x *wm831x, int irq); | 420 | int wm831x_device_init(struct wm831x *wm831x, int irq); |
421 | void wm831x_device_exit(struct wm831x *wm831x); | ||
422 | int wm831x_device_suspend(struct wm831x *wm831x); | 421 | int wm831x_device_suspend(struct wm831x *wm831x); |
423 | void wm831x_device_shutdown(struct wm831x *wm831x); | 422 | void wm831x_device_shutdown(struct wm831x *wm831x); |
424 | int wm831x_irq_init(struct wm831x *wm831x, int irq); | 423 | int wm831x_irq_init(struct wm831x *wm831x, int irq); |
diff --git a/include/linux/mfd/wm8350/core.h b/include/linux/mfd/wm8350/core.h index 509481d9cf19..202d9bde2c7c 100644 --- a/include/linux/mfd/wm8350/core.h +++ b/include/linux/mfd/wm8350/core.h | |||
@@ -643,7 +643,6 @@ struct wm8350_platform_data { | |||
643 | */ | 643 | */ |
644 | int wm8350_device_init(struct wm8350 *wm8350, int irq, | 644 | int wm8350_device_init(struct wm8350 *wm8350, int irq, |
645 | struct wm8350_platform_data *pdata); | 645 | struct wm8350_platform_data *pdata); |
646 | void wm8350_device_exit(struct wm8350 *wm8350); | ||
647 | 646 | ||
648 | /* | 647 | /* |
649 | * WM8350 device IO | 648 | * WM8350 device IO |