* [PATCH v7 2/8] MFD: add STM32 Timers driver
From: Benjamin Gaignard @ 2017-01-05 9:25 UTC (permalink / raw)
To: lee.jones, robh+dt, mark.rutland, alexandre.torgue, devicetree,
linux-kernel, thierry.reding, linux-pwm, jic23, knaack.h, lars,
pmeerw, linux-iio, linux-arm-kernel
Cc: linaro-kernel, Benjamin Gaignard, linus.walleij, arnaud.pouliquen,
benjamin.gaignard, gerald.baeza, fabrice.gasnier
In-Reply-To: <1483608344-9012-1-git-send-email-benjamin.gaignard@st.com>
This hardware block could at used at same time for PWM generation
and IIO timers.
PWM and IIO timer configuration are mixed in the same registers
so we need a multi fonction driver to be able to share those registers.
version 7:
- rebase on v4.10-rc2
version 6:
- rename files to stm32-timers
- rename functions to stm32_timers_xxx
version 5:
- fix Lee comments about detect function
- add missing dependency on REGMAP_MMIO
version 4:
- add a function to detect Auto Reload Register (ARR) size
- rename the structure shared with other drivers
version 2:
- rename driver "stm32-gptimer" to be align with SoC documentation
- only keep one compatible
- use of_platform_populate() instead of devm_mfd_add_devices()
Signed-off-by: Benjamin Gaignard <benjamin.gaignard@st.com>
---
.../devicetree/bindings/mfd/stm32-timers.txt | 2 +-
drivers/mfd/Kconfig | 11 +++
drivers/mfd/Makefile | 2 +
drivers/mfd/stm32-timers.c | 80 ++++++++++++++++++++++
include/linux/mfd/stm32-timers.h | 71 +++++++++++++++++++
5 files changed, 165 insertions(+), 1 deletion(-)
create mode 100644 drivers/mfd/stm32-timers.c
create mode 100644 include/linux/mfd/stm32-timers.h
diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
index a73301d..897e7c2 100644
--- a/Documentation/devicetree/bindings/mfd/stm32-timers.txt
+++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
@@ -12,7 +12,7 @@ Required parameters:
- reg: Physical base address and length of the controller's
registers.
-- clock-names: Set to "int".
+- clock-names: Set to "int".
- clocks: Phandle to the clock used by the timer module.
For Clk properties, please refer to ../clock/clock-bindings.txt
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4ce3b6f..d0c14b8 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1621,6 +1621,17 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.
+config MFD_STM32_TIMERS
+ tristate "Support for STM32 Timers"
+ depends on (ARCH_STM32 && OF) || COMPILE_TEST
+ select MFD_CORE
+ select REGMAP
+ select REGMAP_MMIO
+ help
+ Select this option to enable STM32 timers driver used
+ for PWM and IIO Timer. This driver allow to share the
+ registers between the others drivers.
+
menu "Multimedia Capabilities Port drivers"
depends on ARCH_SA1100
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index dda4d4f..876ca86 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -212,3 +212,5 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o
obj-$(CONFIG_MFD_SUN4I_GPADC) += sun4i-gpadc.o
+
+obj-$(CONFIG_MFD_STM32_TIMERS) += stm32-timers.o
diff --git a/drivers/mfd/stm32-timers.c b/drivers/mfd/stm32-timers.c
new file mode 100644
index 0000000..41bd901
--- /dev/null
+++ b/drivers/mfd/stm32-timers.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) STMicroelectronics 2016
+ *
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/mfd/stm32-timers.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/reset.h>
+
+static const struct regmap_config stm32_timers_regmap_cfg = {
+ .reg_bits = 32,
+ .val_bits = 32,
+ .reg_stride = sizeof(u32),
+ .max_register = 0x400,
+};
+
+static void stm32_timers_get_arr_size(struct stm32_timers *ddata)
+{
+ /*
+ * Only the available bits will be written so when readback
+ * we get the maximum value of auto reload register
+ */
+ regmap_write(ddata->regmap, TIM_ARR, ~0L);
+ regmap_read(ddata->regmap, TIM_ARR, &ddata->max_arr);
+ regmap_write(ddata->regmap, TIM_ARR, 0x0);
+}
+
+static int stm32_timers_probe(struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+ struct stm32_timers *ddata;
+ struct resource *res;
+ void __iomem *mmio;
+
+ ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+ if (!ddata)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ mmio = devm_ioremap_resource(dev, res);
+ if (IS_ERR(mmio))
+ return PTR_ERR(mmio);
+
+ ddata->regmap = devm_regmap_init_mmio_clk(dev, "int", mmio,
+ &stm32_timers_regmap_cfg);
+ if (IS_ERR(ddata->regmap))
+ return PTR_ERR(ddata->regmap);
+
+ ddata->clk = devm_clk_get(dev, NULL);
+ if (IS_ERR(ddata->clk))
+ return PTR_ERR(ddata->clk);
+
+ stm32_timers_get_arr_size(ddata);
+
+ platform_set_drvdata(pdev, ddata);
+
+ return of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+}
+
+static const struct of_device_id stm32_timers_of_match[] = {
+ { .compatible = "st,stm32-timers", },
+ { /* end node */ },
+};
+MODULE_DEVICE_TABLE(of, stm32_timers_of_match);
+
+static struct platform_driver stm32_timers_driver = {
+ .probe = stm32_timers_probe,
+ .driver = {
+ .name = "stm32-timers",
+ .of_match_table = stm32_timers_of_match,
+ },
+};
+module_platform_driver(stm32_timers_driver);
+
+MODULE_DESCRIPTION("STMicroelectronics STM32 Timers");
+MODULE_LICENSE("GPL v2");
diff --git a/include/linux/mfd/stm32-timers.h b/include/linux/mfd/stm32-timers.h
new file mode 100644
index 0000000..d030004
--- /dev/null
+++ b/include/linux/mfd/stm32-timers.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) STMicroelectronics 2016
+ *
+ * Author: Benjamin Gaignard <benjamin.gaignard@st.com>
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#ifndef _LINUX_STM32_GPTIMER_H_
+#define _LINUX_STM32_GPTIMER_H_
+
+#include <linux/clk.h>
+#include <linux/regmap.h>
+
+#define TIM_CR1 0x00 /* Control Register 1 */
+#define TIM_CR2 0x04 /* Control Register 2 */
+#define TIM_SMCR 0x08 /* Slave mode control reg */
+#define TIM_DIER 0x0C /* DMA/interrupt register */
+#define TIM_SR 0x10 /* Status register */
+#define TIM_EGR 0x14 /* Event Generation Reg */
+#define TIM_CCMR1 0x18 /* Capt/Comp 1 Mode Reg */
+#define TIM_CCMR2 0x1C /* Capt/Comp 2 Mode Reg */
+#define TIM_CCER 0x20 /* Capt/Comp Enable Reg */
+#define TIM_PSC 0x28 /* Prescaler */
+#define TIM_ARR 0x2c /* Auto-Reload Register */
+#define TIM_CCR1 0x34 /* Capt/Comp Register 1 */
+#define TIM_CCR2 0x38 /* Capt/Comp Register 2 */
+#define TIM_CCR3 0x3C /* Capt/Comp Register 3 */
+#define TIM_CCR4 0x40 /* Capt/Comp Register 4 */
+#define TIM_BDTR 0x44 /* Break and Dead-Time Reg */
+
+#define TIM_CR1_CEN BIT(0) /* Counter Enable */
+#define TIM_CR1_ARPE BIT(7) /* Auto-reload Preload Ena */
+#define TIM_CR2_MMS (BIT(4) | BIT(5) | BIT(6)) /* Master mode selection */
+#define TIM_SMCR_SMS (BIT(0) | BIT(1) | BIT(2)) /* Slave mode selection */
+#define TIM_SMCR_TS (BIT(4) | BIT(5) | BIT(6)) /* Trigger selection */
+#define TIM_DIER_UIE BIT(0) /* Update interrupt */
+#define TIM_SR_UIF BIT(0) /* Update interrupt flag */
+#define TIM_EGR_UG BIT(0) /* Update Generation */
+#define TIM_CCMR_PE BIT(3) /* Channel Preload Enable */
+#define TIM_CCMR_M1 (BIT(6) | BIT(5)) /* Channel PWM Mode 1 */
+#define TIM_CCER_CC1E BIT(0) /* Capt/Comp 1 out Ena */
+#define TIM_CCER_CC1P BIT(1) /* Capt/Comp 1 Polarity */
+#define TIM_CCER_CC1NE BIT(2) /* Capt/Comp 1N out Ena */
+#define TIM_CCER_CC1NP BIT(3) /* Capt/Comp 1N Polarity */
+#define TIM_CCER_CC2E BIT(4) /* Capt/Comp 2 out Ena */
+#define TIM_CCER_CC3E BIT(8) /* Capt/Comp 3 out Ena */
+#define TIM_CCER_CC4E BIT(12) /* Capt/Comp 4 out Ena */
+#define TIM_CCER_CCXE (BIT(0) | BIT(4) | BIT(8) | BIT(12))
+#define TIM_BDTR_BKE BIT(12) /* Break input enable */
+#define TIM_BDTR_BKP BIT(13) /* Break input polarity */
+#define TIM_BDTR_AOE BIT(14) /* Automatic Output Enable */
+#define TIM_BDTR_MOE BIT(15) /* Main Output Enable */
+#define TIM_BDTR_BKF (BIT(16) | BIT(17) | BIT(18) | BIT(19))
+#define TIM_BDTR_BK2F (BIT(20) | BIT(21) | BIT(22) | BIT(23))
+#define TIM_BDTR_BK2E BIT(24) /* Break 2 input enable */
+#define TIM_BDTR_BK2P BIT(25) /* Break 2 input polarity */
+
+#define MAX_TIM_PSC 0xFFFF
+#define TIM_CR2_MMS_SHIFT 4
+#define TIM_SMCR_TS_SHIFT 4
+#define TIM_BDTR_BKF_MASK 0xF
+#define TIM_BDTR_BKF_SHIFT 16
+#define TIM_BDTR_BK2F_SHIFT 20
+
+struct stm32_timers {
+ struct clk *clk;
+ struct regmap *regmap;
+ u32 max_arr;
+};
+#endif
--
1.9.1
^ permalink raw reply related
* [PATCH v7 1/8] MFD: add bindings for STM32 Timers driver
From: Benjamin Gaignard @ 2017-01-05 9:25 UTC (permalink / raw)
To: lee.jones-QSEj5FYQhm4dnm+yROfE0A, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, alexandre.torgue-qxv4g6HH51o,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
thierry.reding-Re5JQEeQqe8AvxtiuMwx3w,
linux-pwm-u79uwXL29TY76Z2rM5mHXA, jic23-DgEjT+Ai2ygdnm+yROfE0A,
knaack.h-Mmb7MZpHnFY, lars-Qo5EllUWu/uELgA04lAiVw,
pmeerw-jW+XmwGofnusTnJN9+BGXg, linux-iio-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
Cc: fabrice.gasnier-qxv4g6HH51o, gerald.baeza-qxv4g6HH51o,
arnaud.pouliquen-qxv4g6HH51o,
linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
linaro-kernel-cunTk1MwBs8s++Sfvej+rw,
benjamin.gaignard-QSEj5FYQhm4dnm+yROfE0A, Benjamin Gaignard
In-Reply-To: <1483608344-9012-1-git-send-email-benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
Add bindings information for STM32 Timers
version 6:
- rename stm32-gtimer to stm32-timers
- change compatible
- add description about the IPs
version 2:
- rename stm32-mfd-timer to stm32-gptimer
- only keep one compatible string
Signed-off-by: Benjamin Gaignard <benjamin.gaignard-qxv4g6HH51o@public.gmane.org>
---
.../devicetree/bindings/mfd/stm32-timers.txt | 46 ++++++++++++++++++++++
1 file changed, 46 insertions(+)
create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
diff --git a/Documentation/devicetree/bindings/mfd/stm32-timers.txt b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
new file mode 100644
index 0000000..a73301d
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/stm32-timers.txt
@@ -0,0 +1,46 @@
+STM32 Timers driver bindings
+
+This IP provides 3 types of timer along with PWM functionality:
+- advanced-control timers consist of a 16-bit auto-reload counter driven by a programmable
+ prescaler, break input feature, PWM outputs and complementary PWM ouputs channels.
+- general-purpose timers consist of a 16-bit or 32-bit auto-reload counter driven by a
+ programmable prescaler and PWM outputs.
+- basic timers consist of a 16-bit auto-reload counter driven by a programmable prescaler.
+
+Required parameters:
+- compatible: must be "st,stm32-timers"
+
+- reg: Physical base address and length of the controller's
+ registers.
+- clock-names: Set to "int".
+- clocks: Phandle to the clock used by the timer module.
+ For Clk properties, please refer to ../clock/clock-bindings.txt
+
+Optional parameters:
+- resets: Phandle to the parent reset controller.
+ See ../reset/st,stm32-rcc.txt
+
+Optional subnodes:
+- pwm: See ../pwm/pwm-stm32.txt
+- timer: See ../iio/timer/stm32-timer-trigger.txt
+
+Example:
+ timers@40010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "st,stm32-timers";
+ reg = <0x40010000 0x400>;
+ clocks = <&rcc 0 160>;
+ clock-names = "clk_int";
+
+ pwm {
+ compatible = "st,stm32-pwm";
+ pinctrl-0 = <&pwm1_pins>;
+ pinctrl-names = "default";
+ };
+
+ timer {
+ compatible = "st,stm32-timer-trigger";
+ reg = <0>;
+ };
+ };
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v7 0/8] Add PWM and IIO timer drivers for STM32
From: Benjamin Gaignard @ 2017-01-05 9:25 UTC (permalink / raw)
To: lee.jones, robh+dt, mark.rutland, alexandre.torgue, devicetree,
linux-kernel, thierry.reding, linux-pwm, jic23, knaack.h, lars,
pmeerw, linux-iio, linux-arm-kernel
Cc: fabrice.gasnier, gerald.baeza, arnaud.pouliquen, linus.walleij,
linaro-kernel, benjamin.gaignard, Benjamin Gaignard
version 7:
- rebase on v4.10-rc2
- remove iio_device code from driver and keep only the trigger part
version 6:
- rename stm32-gptimer in stm32-timers.
- change "st,stm32-gptimer" compatible to "st,stm32-timers".
- modify "st,breakinput" parameter in pwm part.
- split DT patch in 2
version 5:
- fix comments done on version 4
- rebased on kernel 4.9-rc8
- change nodes names and re-order then by addresses
version 4:
- fix comments done on version 3
- don't use interrupts anymore in IIO timer
- detect hardware capabilities at probe time to simplify binding
version 3:
- no change on mfd and pwm divers patches
- add cross reference between bindings
- change compatible to "st,stm32-timer-trigger"
- fix attributes access rights
- use string instead of int for master_mode and slave_mode
- document device attributes in sysfs-bus-iio-timer-stm32
- update DT with the new compatible
version 2:
- keep only one compatible per driver
- use DT parameters to describe hardware block configuration:
- pwm channels, complementary output, counter size, break input
- triggers accepted and create by IIO timers
- change DT to limite use of reference to the node
- interrupt is now in IIO timer driver
- rename stm32-mfd-timer to stm32-timers (for general purpose timer)
The following patches enable PWM and IIO Timer features for STM32 platforms.
Those two features are mixed into the registers of the same hardware block
(named general purpose timer) which lead to introduce a multifunctions driver
on the top of them to be able to share the registers.
In STM32f4 14 instances of timer hardware block exist, even if they all have
the same register mapping they could have a different number of pwm channels
and/or different triggers capabilities. We use various parameters in DT to
describe the differences between hardware blocks
The MFD (stm32-timers.c) takes care of clock and register mapping
by using regmap. stm32_timers structure is provided to its sub-node to
share those information.
PWM driver is implemented into pwm-stm32.c. Depending of the instance we may
have up to 4 channels, sometime with complementary outputs or 32 bits counter
instead of 16 bits. Some hardware blocks may also have a break input function
which allows to stop pwm depending of a level, defined in devicetree, on an
external pin.
IIO timer driver (stm32-timer-trigger.c and stm32-timer-trigger.h) define a list
of hardware triggers usable by hardware blocks like ADC, DAC or other timers.
The matrix of possible connections between blocks is quite complex so we use
trigger names and is_stm32_iio_timer_trigger() function to be sure that
triggers are valid and configure the IPs.
At run time IIO timer hardware blocks can configure (through "master_mode"
IIO device attribute) which internal signal (counter enable, reset,
comparison block, etc...) is used to generate the trigger.
Benjamin Gaignard (8):
MFD: add bindings for STM32 Timers driver
MFD: add STM32 Timers driver
PWM: add pwm-stm32 DT bindings
PWM: add PWM driver for STM32 plaftorm
IIO: add bindings for STM32 timer trigger driver
IIO: add STM32 timer trigger driver
ARM: dts: stm32: add Timers driver for stm32f429 MCU
ARM: dts: stm32: Enable pwm1 and pwm3 for stm32f469-disco
.../ABI/testing/sysfs-bus-iio-timer-stm32 | 29 ++
.../bindings/iio/timer/stm32-timer-trigger.txt | 23 ++
.../devicetree/bindings/mfd/stm32-timers.txt | 46 +++
.../devicetree/bindings/pwm/pwm-stm32.txt | 33 ++
arch/arm/boot/dts/stm32f429.dtsi | 275 +++++++++++++
arch/arm/boot/dts/stm32f469-disco.dts | 28 ++
drivers/iio/Kconfig | 1 -
drivers/iio/trigger/Kconfig | 10 +
drivers/iio/trigger/Makefile | 1 +
drivers/iio/trigger/stm32-timer-trigger.c | 340 ++++++++++++++++
drivers/mfd/Kconfig | 11 +
drivers/mfd/Makefile | 2 +
drivers/mfd/stm32-timers.c | 80 ++++
drivers/pwm/Kconfig | 9 +
drivers/pwm/Makefile | 1 +
drivers/pwm/pwm-stm32.c | 434 +++++++++++++++++++++
include/linux/iio/timer/stm32-timer-trigger.h | 62 +++
include/linux/mfd/stm32-timers.h | 71 ++++
18 files changed, 1455 insertions(+), 1 deletion(-)
create mode 100644 Documentation/ABI/testing/sysfs-bus-iio-timer-stm32
create mode 100644 Documentation/devicetree/bindings/iio/timer/stm32-timer-trigger.txt
create mode 100644 Documentation/devicetree/bindings/mfd/stm32-timers.txt
create mode 100644 Documentation/devicetree/bindings/pwm/pwm-stm32.txt
create mode 100644 drivers/iio/trigger/stm32-timer-trigger.c
create mode 100644 drivers/mfd/stm32-timers.c
create mode 100644 drivers/pwm/pwm-stm32.c
create mode 100644 include/linux/iio/timer/stm32-timer-trigger.h
create mode 100644 include/linux/mfd/stm32-timers.h
--
1.9.1
^ permalink raw reply
* Re: [PATCH v2 3/4] arm64: dts: exynos: make tm2 and tm2e independent from each other
From: Andi Shyti @ 2017-01-05 9:23 UTC (permalink / raw)
To: Chanwoo Choi
Cc: Mark Rutland, devicetree, linux-samsung-soc, Dmitry Torokhov,
Catalin Marinas, Jaechul Lee, Will Deacon, linux-kernel,
Krzysztof Kozlowski, Javier Martinez Canillas, Rob Herring,
Kukjin Kim, linux-input, galaxyra, beomho.seo, linux-arm-kernel
In-Reply-To: <586E0E56.6050608@samsung.com>
Hi Chanwoo,
> I add the some comment as following:
> - ldo23/25/31/38 have the different value between tm2 and tm2e.
Thanks for pointing this out. I planned to do this already in a
following patch as for now I think it's out from the scope of this
particular patch.
> - The patch[1] was alread posted. I think you better to rebase this patch on patch[1].
> [1] https://patchwork.kernel.org/patch/9491769/
> - ("ARM64: dts: TM2: comply to the samsung pinctrl naming convention")
Yes, I also thought about this, but I didn't know whether it was
already picked by anyone. I didn't want to stop Jaechul that's
why I was planning to rebase the other rather than this.
But you are right, because some bits of the other patches I know
that have been merged. Thank you!
Krzysztof, do you mind if I send patch 3 as a reply to this
e-mail? The changes should not affect patch 4, anyway.
Thanks,
Andi
^ permalink raw reply
* Re: [PATCH 1/1] iio: adc: tlc4541: add support for TI tlc4541 adc
From: Peter Meerwald-Stadler @ 2017-01-05 9:21 UTC (permalink / raw)
To: Phil Reid
Cc: jic23-DgEjT+Ai2ygdnm+yROfE0A, lars-Qo5EllUWu/uELgA04lAiVw,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1483606546-13629-1-git-send-email-preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
> This adds TI's tlc4541 16-bit ADC driver. Which is a single channel
> ADC. Supports raw and trigger buffer access.
comments below
> Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
> ---
> .../devicetree/bindings/iio/adc/ti-tlc4541.txt | 16 ++
> drivers/iio/adc/Kconfig | 11 +
> drivers/iio/adc/Makefile | 1 +
> drivers/iio/adc/ti-tlc4541.c | 266 +++++++++++++++++++++
> 4 files changed, 294 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt
> create mode 100644 drivers/iio/adc/ti-tlc4541.c
>
> diff --git a/Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt b/Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt
> new file mode 100644
> index 0000000..67caccd
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt
> @@ -0,0 +1,16 @@
> +* Texas Instruments' TLC4541
> +
> +Required properties:
> + - compatible: Should be one of
> + * "ti,tlc4541"
> + - reg: spi chip select number for the device
SPI
> + - vref-supply: The regulator supply for ADC reference voltage
> + - spi-max-frequency: Max SPI frequency to use (<= 200000)
> +
> +Example:
> +adc@0 {
> + compatible = "ti,adc0832";
> + reg = <0>;
> + vref-supply = <&vdd_supply>;
> + spi-max-frequency = <200000>;
> +};
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 99c0514..4dda3f0 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -525,6 +525,17 @@ config TI_AM335X_ADC
> To compile this driver as a module, choose M here: the module will be
> called ti_am335x_adc.
>
> +config TI_TLC4541
> + tristate "Texas Instruments TLC4541 ADC driver"
> + depends on SPI
> + select IIO_BUFFER
> + select IIO_TRIGGERED_BUFFER
> + help
> + Say yes here to build support for Texas Instruments TLC4541 ADC chip.
> +
> + This driver can also be built as a module. If so, the module will be
> + called ti-tlc4541.
> +
> config TWL4030_MADC
> tristate "TWL4030 MADC (Monitoring A/D Converter)"
> depends on TWL4030_CORE
> diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
> index 7a40c04..9bf2377 100644
> --- a/drivers/iio/adc/Makefile
> +++ b/drivers/iio/adc/Makefile
> @@ -49,6 +49,7 @@ obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
> obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
> obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
> obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
> +obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o
> obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
> obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
> obj-$(CONFIG_VF610_ADC) += vf610_adc.o
> diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c
> new file mode 100644
> index 0000000..a767707
> --- /dev/null
> +++ b/drivers/iio/adc/ti-tlc4541.c
> @@ -0,0 +1,266 @@
> +/*
> + * TI tlc4541 ADC Driver
> + *
> + * Copyright (C) 2017 Phil Reid
> + *
> + * Datasheets can be found here:
> + * http://www.ti.com/lit/gpn/tlc4541
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * The tlc4541 requires 24 clock cycles to start a transfer.
> + * Conversion then takes 2.94us to complete before data is ready
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/interrupt.h>
> +#include <linux/iio/iio.h>
> +#include <linux/iio/sysfs.h>
> +#include <linux/iio/buffer.h>
> +#include <linux/iio/trigger_consumer.h>
> +#include <linux/iio/triggered_buffer.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/regulator/consumer.h>
> +#include <linux/slab.h>
> +#include <linux/spi/spi.h>
> +#include <linux/sysfs.h>
> +
> +struct tlc4541_state {
> + struct spi_device *spi;
> + struct regulator *reg;
> + struct spi_transfer scan_single_xfer[3];
> + struct spi_message scan_single_msg;
> +
> + /*
> + * DMA (thus cache coherency maintenance) requires the
> + * transfer buffers to live in their own cache lines.
> + */
> + __be16 rx_buf[2] ____cacheline_aligned;
> +};
> +
> +struct tlc4541_chip_info {
> + const struct iio_chan_spec *channels;
> + unsigned int num_channels;
> +};
> +
> +enum tlc4541_id {
> + TLC4541,
> +};
> +
> +#define TLC4541_V_CHAN(index, bits) { \
> + .type = IIO_VOLTAGE, \
> + .indexed = 1, \
no need if there is just one channel
> + .channel = index, \
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
> + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
> + .address = index, \
.address not needed
> + .scan_index = index, \
> + .scan_type = { \
> + .sign = 'u', \
> + .realbits = (bits), \
> + .storagebits = 16, \
> + .endianness = IIO_BE, \
> + }, \
> + }
> +
> +#define DECLARE_TLC4541_CHANNELS(name, bits) \
this flexibility is only needed when further chips are added; maybe start
simple and only implement what is needed at first
> +const struct iio_chan_spec name ## _channels[] = { \
> + TLC4541_V_CHAN(0, bits), \
> + IIO_CHAN_SOFT_TIMESTAMP(1), \
> +}
> +
> +static DECLARE_TLC4541_CHANNELS(tlc4541, 16);
> +
> +static const struct tlc4541_chip_info tlc4541_chip_info[] = {
> + [TLC4541] = {
> + .channels = tlc4541_channels,
> + .num_channels = ARRAY_SIZE(tlc4541_channels),
> + },
> +};
> +
> +static irqreturn_t tlc4541_trigger_handler(int irq, void *p)
> +{
> + struct iio_poll_func *pf = p;
> + struct iio_dev *indio_dev = pf->indio_dev;
> + struct tlc4541_state *st = iio_priv(indio_dev);
> + u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */
> + int ret;
> +
> + ret = spi_sync(st->spi, &st->scan_single_msg);
> + if (ret < 0)
> + goto done;
> +
> + buf[0] = be16_to_cpu(st->rx_buf[0]);
endianness is set to IIO_BE in scan_type, so this conversion is not needed
and maybe also buf and the copy can be avoided if rx_buf is large enough
> + iio_push_to_buffers_with_timestamp(indio_dev, buf,
> + iio_get_time_ns(indio_dev));
> +
> +done:
> + iio_trigger_notify_done(indio_dev->trig);
> + return IRQ_HANDLED;
> +}
> +
> +static int tlc4541_get_range(struct tlc4541_state *st)
> +{
> + int vref;
> +
> + vref = regulator_get_voltage(st->reg);
> + if (vref < 0)
> + return vref;
> +
> + vref /= 1000;
> +
> + return vref;
> +}
> +
> +static int tlc4541_read_raw(struct iio_dev *indio_dev,
> + struct iio_chan_spec const *chan,
> + int *val,
> + int *val2,
> + long m)
> +{
> + int ret = 0;
> + struct tlc4541_state *st = iio_priv(indio_dev);
> +
> + switch (m) {
> + case IIO_CHAN_INFO_RAW:
> + ret = iio_device_claim_direct_mode(indio_dev);
> + if (ret)
> + return ret;
> + ret = spi_sync(st->spi, &st->scan_single_msg);
> + iio_device_release_direct_mode(indio_dev);
> + if (ret < 0)
> + return ret;
> + *val = be16_to_cpu(st->rx_buf[0]);
on page 12 of the datasheet, the conversion results is in two registers?
and rx_buf has two elements?
haven't investigated in detail -- maybe a comment would be good to detail
operation?
> + return IIO_VAL_INT;
> + case IIO_CHAN_INFO_SCALE:
> + ret = tlc4541_get_range(st);
> + if (ret < 0)
> + return ret;
> + *val = ret;
> + *val2 = chan->scan_type.realbits;
> + return IIO_VAL_FRACTIONAL_LOG2;
> + }
> + return -EINVAL;
> +}
> +
> +static const struct iio_info tlc4541_info = {
> + .read_raw = &tlc4541_read_raw,
> + .driver_module = THIS_MODULE,
> +};
> +
> +static int tlc4541_probe(struct spi_device *spi)
> +{
> + struct tlc4541_state *st;
> + struct iio_dev *indio_dev;
> + const struct tlc4541_chip_info *info;
> + int ret;
> + int8_t device_init = 0;
> +
> + indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
> + if (indio_dev == NULL)
> + return -ENOMEM;
> +
> + st = iio_priv(indio_dev);
> +
> + spi_set_drvdata(spi, indio_dev);
> +
> + st->spi = spi;
> +
> + info = &tlc4541_chip_info[spi_get_device_id(spi)->driver_data];
> +
> + indio_dev->name = spi_get_device_id(spi)->name;
> + indio_dev->dev.parent = &spi->dev;
> + indio_dev->modes = INDIO_DIRECT_MODE;
> + indio_dev->channels = info->channels;
> + indio_dev->num_channels = info->num_channels;
> + indio_dev->info = &tlc4541_info;
> +
> + /* perform reset */
> + spi_write(spi, &device_init, 1);
> +
> + /* Setup default message */
> + st->scan_single_xfer[0].rx_buf = &st->rx_buf[0];
> + st->scan_single_xfer[0].len = 3;
> + st->scan_single_xfer[1].delay_usecs = 3;
> + st->scan_single_xfer[2].rx_buf = &st->rx_buf[0];
> + st->scan_single_xfer[2].len = 2;
> +
> + spi_message_init(&st->scan_single_msg);
> + spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
> + spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
> + spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg);
> +
> + st->reg = devm_regulator_get(&spi->dev, "vref");
> + if (IS_ERR(st->reg))
> + return PTR_ERR(st->reg);
> +
> + ret = regulator_enable(st->reg);
> + if (ret)
> + return ret;
> +
> + ret = iio_triggered_buffer_setup(indio_dev, NULL,
> + &tlc4541_trigger_handler, NULL);
> + if (ret)
> + goto error_disable_reg;
> +
> + ret = iio_device_register(indio_dev);
> + if (ret)
> + goto error_cleanup_buffer;
> +
> + return 0;
> +
> +error_cleanup_buffer:
> + iio_triggered_buffer_cleanup(indio_dev);
> +error_disable_reg:
> + regulator_disable(st->reg);
> +
> + return ret;
> +}
> +
> +static int tlc4541_remove(struct spi_device *spi)
> +{
> + struct iio_dev *indio_dev = spi_get_drvdata(spi);
> + struct tlc4541_state *st = iio_priv(indio_dev);
> +
> + iio_device_unregister(indio_dev);
> + iio_triggered_buffer_cleanup(indio_dev);
> + regulator_disable(st->reg);
> +
> + return 0;
> +}
> +
> +#ifdef CONFIG_OF
> +
> +static const struct of_device_id tlc4541_dt_ids[] = {
> + { .compatible = "ti,tlc4541", },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, tlc4541_dt_ids);
> +
> +#endif
> +
> +static const struct spi_device_id tlc4541_id[] = {
> + {"tlc4541", TLC4541},
> + {}
> +};
> +MODULE_DEVICE_TABLE(spi, tlc4541_id);
> +
> +static struct spi_driver tlc4541_driver = {
> + .driver = {
> + .name = "tlc4541",
> + .of_match_table = of_match_ptr(tlc4541_dt_ids),
> + },
> + .probe = tlc4541_probe,
> + .remove = tlc4541_remove,
> + .id_table = tlc4541_id,
> +};
> +module_spi_driver(tlc4541_driver);
> +
> +MODULE_AUTHOR("Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>");
> +MODULE_DESCRIPTION("Texas Instruments TLC4541 ADC");
> +MODULE_LICENSE("GPL v2");
>
--
Peter Meerwald-Stadler
+43-664-2444418 (mobile)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* RE: [RFC PATCH] usb: dwc3: add support for OTG driver compilation
From: Felipe Balbi @ 2017-01-05 9:20 UTC (permalink / raw)
To: Manish Narani, robh+dt@kernel.org, mark.rutland@arm.com,
catalin.marinas@arm.com, will.deacon@arm.com,
michal.simek@xilinx.com, Soren Brinkmann,
gregkh@linuxfoundation.org, mathias.nyman@intel.com,
agraf@suse.de, Bharat Kumar Gogada, Punnaiah Choudary Kalluri,
dhdang@apm.com, marc.zyngier@arm.com, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, linux-usb
Cc: Anurag Kumar Vulisha, Anirudha Sarangi
In-Reply-To: <B2EF86ADE403CA4A85AF1BE1D3A22A06DB2CED@XAP-PVEXMBX01.xlnx.xilinx.com>
[-- Attachment #1.1: Type: text/plain, Size: 1700 bytes --]
Hi,
Manish Narani <manish.narani@xilinx.com> writes:
> Hi Felipe,
>
>
>> From: Felipe Balbi [mailto:balbi@kernel.org]
>> Sent: Wednesday, January 04, 2017 7:01 PM
>> Hi,
>>
>> Manish Narani <manish.narani@xilinx.com> writes:
>> > This patch adds support for OTG driver compilation and object file
>> > creation
>> >
>> > Signed-off-by: Manish Narani <mnarani@xilinx.com>
>> > ---
>> > drivers/usb/dwc3/Makefile | 4 ++++
>> > 1 file changed, 4 insertions(+)
>> >
>> > diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
>> > index ffca340..2d269ad 100644
>> > --- a/drivers/usb/dwc3/Makefile
>> > +++ b/drivers/usb/dwc3/Makefile
>> > @@ -17,6 +17,10 @@ ifneq ($(filter y,$(CONFIG_USB_DWC3_GADGET)
>> $(CONFIG_USB_DWC3_DUAL_ROLE)),)
>> > dwc3-y += gadget.o ep0.o
>> > endif
>> >
>> > +ifneq ($(CONFIG_USB_DWC3_DUAL_ROLE),)
>> > + dwc3-y += otg.o
>> > +endif
>>
>> you just broke compilation
>
> Should I add new USB_DWC3_OTG macro in Kconfig?
No, no. Reset your tree to this commit and try to compile it. Problem
should be clear.
> This email and any attachments are intended for the sole use of the
> named recipient(s) and contain(s) confidential information that may be
> proprietary, privileged or copyrighted under applicable law. If you
> are not the intended recipient, do not read, copy, or forward this
> email message or any attachments. Delete this email message and any
> attachments immediately.
you should make sure these notes aren't sent to public mailing
lists. I'll delete this email of yours and stop reading them until this
is sorted out.
--
balbi
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v2 3/4] arm64: dts: exynos: make tm2 and tm2e independent from each other
From: Chanwoo Choi @ 2017-01-05 9:13 UTC (permalink / raw)
To: Jaechul Lee, Dmitry Torokhov, Rob Herring, Mark Rutland,
Catalin Marinas, Will Deacon, Kukjin Kim, Krzysztof Kozlowski,
Javier Martinez Canillas
Cc: devicetree, linux-samsung-soc, linux-kernel, Andi Shyti,
beomho.seo, linux-input, galaxyra, linux-arm-kernel
In-Reply-To: <1483604833-29746-4-git-send-email-jcsing.lee@samsung.com>
[-- Attachment #1: Type: text/plain, Size: 19424 bytes --]
Hi,
I add the some comment as following:
- ldo23/25/31/38 have the different value between tm2 and tm2e.
- The patch[1] was alread posted. I think you better to rebase this patch on patch[1].
[1] https://patchwork.kernel.org/patch/9491769/
- ("ARM64: dts: TM2: comply to the samsung pinctrl naming convention")
I add detailed comments on below.
On 2017년 01월 05일 17:27, Jaechul Lee wrote:
> From: Andi Shyti <andi.shyti@samsung.com>
>
> Currently tm2e dts includes tm2 but there are some differences
> between the two boards and tm2 has some properties that tm2e
> doesn't have.
>
> That's why it's important to keep the two dts files independent
> and put all the commonalities in a tm2-common.dtsi file.
>
> Signed-off-by: Andi Shyti <andi.shyti@samsung.com>
> Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
> ---
> .../boot/dts/exynos/exynos5433-tm2-common.dtsi | 1116 +++++++++++++++++++
> arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 1138 +-------------------
> arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 2 +-
> 3 files changed, 1136 insertions(+), 1120 deletions(-)
> create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
> rewrite arch/arm64/boot/dts/exynos/exynos5433-tm2.dts (98%)
>
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
> new file mode 100644
> index 0000000..7ad0019
> --- /dev/null
> +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
> @@ -0,0 +1,1116 @@
> +/*
> + * SAMSUNG Exynos5433 TM2 board device tree source
> + *
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + *
> + * Device tree source file for Samsung's TM2 board which is based on
> + * Samsung Exynos5433 SoC.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +/dts-v1/;
> +#include "exynos5433.dtsi"
> +#include <dt-bindings/clock/samsung,s2mps11.h>
> +#include <dt-bindings/gpio/gpio.h>
> +#include <dt-bindings/input/input.h>
> +#include <dt-bindings/interrupt-controller/irq.h>
> +
[snip]
> +&hsi2c_0 {
> + status = "okay";
> + clock-frequency = <2500000>;
> +
> + s2mps13-pmic@66 {
> + compatible = "samsung,s2mps13-pmic";
> + interrupt-parent = <&gpa0>;
> + interrupts = <7 IRQ_TYPE_NONE>;
> + reg = <0x66>;
> + samsung,s2mps11-wrstbi-ground;
> +
> + s2mps13_osc: clocks {
> + compatible = "samsung,s2mps13-clk";
> + #clock-cells = <1>;
> + clock-output-names = "s2mps13_ap", "s2mps13_cp",
> + "s2mps13_bt";
> + };
> +
> + regulators {
> + ldo1_reg: LDO1 {
> + regulator-name = "VDD_ALIVE_0.9V_AP";
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <900000>;
> + regulator-always-on;
> + };
> +
> + ldo2_reg: LDO2 {
> + regulator-name = "VDDQ_MMC2_2.8V_AP";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo3_reg: LDO3 {
> + regulator-name = "VDD1_E_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + };
> +
> + ldo4_reg: LDO4 {
> + regulator-name = "VDD10_MIF_PLL_1.0V_AP";
> + regulator-min-microvolt = <1300000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo5_reg: LDO5 {
> + regulator-name = "VDD10_DPLL_1.0V_AP";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo6_reg: LDO6 {
> + regulator-name = "VDD10_MIPI2L_1.0V_AP";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo7_reg: LDO7 {
> + regulator-name = "VDD18_MIPI2L_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo8_reg: LDO8 {
> + regulator-name = "VDD18_LLI_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo9_reg: LDO9 {
> + regulator-name = "VDD18_ABB_ETC_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo10_reg: LDO10 {
> + regulator-name = "VDD33_USB30_3.0V_AP";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3000000>;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo11_reg: LDO11 {
> + regulator-name = "VDD_INT_M_1.0V_AP";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo12_reg: LDO12 {
> + regulator-name = "VDD_KFC_M_1.1V_AP";
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1350000>;
> + regulator-always-on;
> + };
> +
> + ldo13_reg: LDO13 {
> + regulator-name = "VDD_G3D_M_0.95V_AP";
> + regulator-min-microvolt = <950000>;
> + regulator-max-microvolt = <950000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo14_reg: LDO14 {
> + regulator-name = "VDDQ_M1_LDO_1.2V_AP";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo15_reg: LDO15 {
> + regulator-name = "VDDQ_M2_LDO_1.2V_AP";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + ldo16_reg: LDO16 {
> + regulator-name = "VDDQ_EFUSE";
> + regulator-min-microvolt = <1400000>;
> + regulator-max-microvolt = <3400000>;
> + regulator-always-on;
> + };
> +
> + ldo17_reg: LDO17 {
> + regulator-name = "V_TFLASH_2.8V_AP";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + };
> +
> + ldo18_reg: LDO18 {
> + regulator-name = "V_CODEC_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo19_reg: LDO19 {
> + regulator-name = "VDDA_1.8V_COMP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + regulator-always-on;
> + };
> +
> + ldo20_reg: LDO20 {
> + regulator-name = "VCC_2.8V_AP";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + regulator-always-on;
> + };
> +
> + ldo21_reg: LDO21 {
> + regulator-name = "VT_CAM_1.8V";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo22_reg: LDO22 {
> + regulator-name = "CAM_IO_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo23_reg: LDO23 {
> + regulator-name = "CAM_SEN_CORE_1.2V_AP";
> + regulator-min-microvolt = <1050000>;
> + regulator-max-microvolt = <1200000>;
ldo23_reg has the different value between tm2 and tm2e.
- tm2 : name - CAM_SEN_CORE_1.2V_AP, max-microvolt :1200000
- tm2e : name - CAM_SEN_CORE_1.025V_AP, max-microvolt :1050000
> + };
> +
> + ldo24_reg: LDO24 {
> + regulator-name = "VT_CAM_1.2V";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + };
> +
> + ldo25_reg: LDO25 {
> + regulator-name = "CAM_SEN_A2.8V_AP";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + };
ldo25 is only used on TM2 and has the different name between tm2 and tm2e.
- tm2 : name - CAM_SEN_A2.8V_AP
- tm2e : name - UNUSED_LDO15
> +
> + ldo26_reg: LDO26 {
> + regulator-name = "CAM_AF_2.8V_AP";
> + regulator-min-microvolt = <2800000>;
> + regulator-max-microvolt = <2800000>;
> + };
> +
> + ldo27_reg: LDO27 {
> + regulator-name = "VCC_3.0V_LCD_AP";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3000000>;
> + };
> +
> + ldo28_reg: LDO28 {
> + regulator-name = "VCC_1.8V_LCD_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo29_reg: LDO29 {
> + regulator-name = "VT_CAM_2.8V";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3000000>;
> + };
> +
> + ldo30_reg: LDO30 {
> + regulator-name = "TSP_AVDD_3.3V_AP";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + ldo31_reg: LDO31 {
> + regulator-name = "TSP_VDD_1.85V_AP";
> + regulator-min-microvolt = <1850000>;
> + regulator-max-microvolt = <1850000>;
> + };
ldo31_reg has the different value between tm2 and tm2e.
- tm2 : name - TSP_VDD_1.85V_AP, min/max-microvolt :1850000
- tm2e : name - TSP_VDD_1.8V_AP, min/max-microvolt :1800000
> +
> + ldo32_reg: LDO32 {
> + regulator-name = "VTOUCH_1.8V_AP";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo33_reg: LDO33 {
> + regulator-name = "VTOUCH_LED_3.3V";
> + regulator-min-microvolt = <2500000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-ramp-delay = <12500>;
> + };
> +
> + ldo34_reg: LDO34 {
> + regulator-name = "VCC_1.8V_MHL_AP";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <2100000>;
> + };
> +
> + ldo35_reg: LDO35 {
> + regulator-name = "OIS_VM_2.8V";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <2800000>;
> + };
> +
> + ldo36_reg: LDO36 {
> + regulator-name = "VSIL_1.0V";
> + regulator-min-microvolt = <1000000>;
> + regulator-max-microvolt = <1000000>;
> + };
> +
> + ldo37_reg: LDO37 {
> + regulator-name = "VF_1.8V";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + ldo38_reg: LDO38 {
> + regulator-name = "VCC_3.0V_MOTOR_AP";
> + regulator-min-microvolt = <3000000>;
> + regulator-max-microvolt = <3000000>;
> + };
ldo38_reg has the different value between tm2 and tm2e.
- tm2 : name - VCC_3.0V_MOTOR_AP, min/max-microvolt :3000000
- tm2e : name - VCC_3.3V_MOTOR_AP, min/max-microvolt :3300000
> + regulator-off-in-suspend;
> + };
> + };
> +
> + buck2_reg: BUCK2 {
> + regulator-name = "VDD_EGL_1.0V_AP";
> + regulator-min-microvolt = <900000>;
> + regulator-max-microvolt = <1300000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + buck3_reg: BUCK3 {
> + regulator-name = "VDD_KFC_1.0V_AP";
> + regulator-min-microvolt = <800000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + buck4_reg: BUCK4 {
> + regulator-name = "VDD_INT_0.95V_AP";
> + regulator-min-microvolt = <600000>;
> + regulator-max-microvolt = <1500000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + buck5_reg: BUCK5 {
> + regulator-name = "VDD_DISP_CAM0_0.9V_AP";
> + regulator-min-microvolt = <600000>;
> + regulator-max-microvolt = <1500000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + buck6_reg: BUCK6 {
> + regulator-name = "VDD_G3D_0.9V_AP";
> + regulator-min-microvolt = <600000>;
> + regulator-max-microvolt = <1500000>;
> + regulator-always-on;
> + regulator-state-mem {
> + regulator-off-in-suspend;
> + };
> + };
> +
> + buck7_reg: BUCK7 {
> + regulator-name = "VDD_MEM1_1.2V_AP";
> + regulator-min-microvolt = <1200000>;
> + regulator-max-microvolt = <1200000>;
> + regulator-always-on;
> + };
> +
> + buck8_reg: BUCK8 {
> + regulator-name = "VDD_LLDO_1.35V_AP";
> + regulator-min-microvolt = <1350000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> +
> + buck9_reg: BUCK9 {
> + regulator-name = "VDD_MLDO_2.0V_AP";
> + regulator-min-microvolt = <1350000>;
> + regulator-max-microvolt = <3300000>;
> + regulator-always-on;
> + };
> +
> + buck10_reg: BUCK10 {
> + regulator-name = "vdd_mem2";
> + regulator-min-microvolt = <550000>;
> + regulator-max-microvolt = <1500000>;
> + regulator-always-on;
> + };
> + };
> + };
> +};
> +
> +&hsi2c_8 {
> + status = "okay";
> +
> + max77843@66 {
> + compatible = "maxim,max77843";
> + interrupt-parent = <&gpa1>;
> + interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
> + reg = <0x66>;
> +
> + muic: max77843-muic {
> + compatible = "maxim,max77843-muic";
> + };
> +
> + regulators {
> + compatible = "maxim,max77843-regulator";
> + safeout1_reg: SAFEOUT1 {
> + regulator-name = "SAFEOUT1";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <4950000>;
> + };
> +
> + safeout2_reg: SAFEOUT2 {
> + regulator-name = "SAFEOUT2";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <4950000>;
> + };
> +
> + charger_reg: CHARGER {
> + regulator-name = "CHARGER";
> + regulator-min-microamp = <100000>;
> + regulator-max-microamp = <3150000>;
> + };
> + };
> +
> + haptic: max77843-haptic {
> + compatible = "maxim,max77843-haptic";
> + haptic-supply = <&ldo38_reg>;
> + pwms = <&pwm 0 33670 0>;
> + pwm-names = "haptic";
> + };
> + };
> +};
> +
> +&i2s0 {
> + status = "okay";
> +};
> +
> +&mshc_0 {
> + status = "okay";
> + num-slots = <1>;
> + mmc-hs200-1_8v;
> + mmc-hs400-1_8v;
> + cap-mmc-highspeed;
> + non-removable;
> + card-detect-delay = <200>;
> + samsung,dw-mshc-ciu-div = <3>;
> + samsung,dw-mshc-sdr-timing = <0 4>;
> + samsung,dw-mshc-ddr-timing = <0 2>;
> + samsung,dw-mshc-hs400-timing = <0 3>;
> + samsung,read-strobe-delay = <90>;
> + fifo-depth = <0x80>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4
> + &sd0_bus8 &sd0_rdqs>;
> + bus-width = <8>;
> + assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>;
> + assigned-clock-rates = <800000000>;
> +};
> +
> +&mshc_2 {
> + status = "okay";
> + num-slots = <1>;
> + cap-sd-highspeed;
> + disable-wp;
> + cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
> + cd-inverted;
> + card-detect-delay = <200>;
> + samsung,dw-mshc-ciu-div = <3>;
> + samsung,dw-mshc-sdr-timing = <0 4>;
> + samsung,dw-mshc-ddr-timing = <0 2>;
> + fifo-depth = <0x80>;
> + pinctrl-names = "default";
> + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
> + bus-width = <4>;
> +};
> +
> +&ppmu_d0_general {
> + status = "okay";
> + events {
> + ppmu_event0_d0_general: ppmu-event0-d0-general {
> + event-name = "ppmu-event0-d0-general";
> + };
> + };
> +};
> +
> +&ppmu_d1_general {
> + status = "okay";
> + events {
> + ppmu_event0_d1_general: ppmu-event0-d1-general {
> + event-name = "ppmu-event0-d1-general";
> + };
> + };
> +};
> +
> +&pinctrl_alive {
> + pinctrl-names = "default";
> + pinctrl-0 = <&initial_alive>;
> +
The following patches[1] touch the tm2.dts file about pinctrl naming convention.
So, I recommend that this patch shoud be rebased on patch[1] to prevent the merge conflict.
[1] https://patchwork.kernel.org/patch/9491769/
- ("ARM64: dts: TM2: comply to the samsung pinctrl naming convention")
> + initial_alive: initial-state {
> + PIN(IN, gpa0-0, DOWN, LV1);
> + PIN(IN, gpa0-1, NONE, LV1);
> + PIN(IN, gpa0-2, DOWN, LV1);
> + PIN(IN, gpa0-3, NONE, LV1);
> + PIN(IN, gpa0-4, NONE, LV1);
> + PIN(IN, gpa0-5, DOWN, LV1);
> + PIN(IN, gpa0-6, NONE, LV1);
> + PIN(IN, gpa0-7, NONE, LV1);
> +
> + PIN(IN, gpa1-0, UP, LV1);
> + PIN(IN, gpa1-1, NONE, LV1);
> + PIN(IN, gpa1-2, NONE, LV1);
> + PIN(IN, gpa1-3, DOWN, LV1);
> + PIN(IN, gpa1-4, DOWN, LV1);
> + PIN(IN, gpa1-5, NONE, LV1);
> + PIN(IN, gpa1-6, NONE, LV1);
> + PIN(IN, gpa1-7, NONE, LV1);
> +
> + PIN(IN, gpa2-0, NONE, LV1);
> + PIN(IN, gpa2-1, NONE, LV1);
> + PIN(IN, gpa2-2, NONE, LV1);
> + PIN(IN, gpa2-3, DOWN, LV1);
> + PIN(IN, gpa2-4, NONE, LV1);
> + PIN(IN, gpa2-5, DOWN, LV1);
> + PIN(IN, gpa2-6, DOWN, LV1);
> + PIN(IN, gpa2-7, NONE, LV1);
> +
> + PIN(IN, gpa3-0, DOWN, LV1);
> + PIN(IN, gpa3-1, DOWN, LV1);
> + PIN(IN, gpa3-2, NONE, LV1);
> + PIN(IN, gpa3-3, DOWN, LV1);
> + PIN(IN, gpa3-4, NONE, LV1);
> + PIN(IN, gpa3-5, DOWN, LV1);
> + PIN(IN, gpa3-6, DOWN, LV1);
> + PIN(IN, gpa3-7, DOWN, LV1);
> +
> + PIN(IN, gpf1-0, NONE, LV1);
> + PIN(IN, gpf1-1, NONE, LV1);
> + PIN(IN, gpf1-2, DOWN, LV1);
> + PIN(IN, gpf1-4, UP, LV1);
> + PIN(OUT, gpf1-5, NONE, LV1);
> + PIN(IN, gpf1-6, DOWN, LV1);
> + PIN(IN, gpf1-7, DOWN, LV1);
> +
> + PIN(IN, gpf2-0, DOWN, LV1);
> + PIN(IN, gpf2-1, DOWN, LV1);
> + PIN(IN, gpf2-2, DOWN, LV1);
> + PIN(IN, gpf2-3, DOWN, LV1);
> +
> + PIN(IN, gpf3-0, DOWN, LV1);
> + PIN(IN, gpf3-1, DOWN, LV1);
> + PIN(IN, gpf3-2, NONE, LV1);
> + PIN(IN, gpf3-3, DOWN, LV1);
> +
> + PIN(IN, gpf4-0, DOWN, LV1);
> + PIN(IN, gpf4-1, DOWN, LV1);
> + PIN(IN, gpf4-2, DOWN, LV1);
> + PIN(IN, gpf4-3, DOWN, LV1);
> + PIN(IN, gpf4-4, DOWN, LV1);
> + PIN(IN, gpf4-5, DOWN, LV1);
> + PIN(IN, gpf4-6, DOWN, LV1);
> + PIN(IN, gpf4-7, DOWN, LV1);
> +
> + PIN(IN, gpf5-0, DOWN, LV1);
> + PIN(IN, gpf5-1, DOWN, LV1);
> + PIN(IN, gpf5-2, DOWN, LV1);
> + PIN(IN, gpf5-3, DOWN, LV1);
> + PIN(OUT, gpf5-4, NONE, LV1);
> + PIN(IN, gpf5-5, DOWN, LV1);
> + PIN(IN, gpf5-6, DOWN, LV1);
> + PIN(IN, gpf5-7, DOWN, LV1);
> + };
[snip]
> +/*
> + * SAMSUNG Exynos5433 TM2 board device tree source
> + *
> + * Copyright (c) 2016 Samsung Electronics Co., Ltd.
> + *
> + * Device tree source file for Samsung's TM2 board which is based on
> + * Samsung Exynos5433 SoC.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +
> +#include "exynos5433-tm2-common.dtsi"
> +
> +/ {
> + model = "Samsung TM2 board";
> + compatible = "samsung,tm2", "samsung,exynos5433";
> +};
> diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
> index 1db4e7f..81fdbef 100644
> --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
> +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
> @@ -11,7 +11,7 @@
> * published by the Free Software Foundation.
> */
>
> -#include "exynos5433-tm2.dts"
> +#include "exynos5433-tm2-common.dtsi"
>
> / {
> model = "Samsung TM2E board";
>
--
Best Regards,
Chanwoo Choi
Samsung Electronics
[-- Attachment #2: cw00_choi.vcf --]
[-- Type: text/x-vcard, Size: 6 bytes --]
null
[-- Attachment #3: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply
* Re: [PATCH v3 4/4] phy: qcom-qmp: new qmp phy driver for qcom-chipsets
From: Vivek Gautam @ 2017-01-05 9:13 UTC (permalink / raw)
To: Bjorn Andersson
Cc: Stephen Boyd, robh+dt, kishon,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Mark Rutland,
Srinivas Kandagatla, linux-arm-msm-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20170103192429.GL10531@minitux>
Hi,
On Wed, Jan 4, 2017 at 12:54 AM, Bjorn Andersson
<bjorn.andersson-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org> wrote:
> On Wed 28 Dec 23:39 PST 2016, Vivek Gautam wrote:
>
>> >> + *
>> >> + */
>> >> +static int phy_pipe_clk_register(struct qcom_qmp_phy *qphy, int id)
>> >> +{
>> >> + char clk_name[MAX_PROP_NAME];
>> >
>> > I'm not sure MAX_PROP_NAME is the same as some max clk name but
>> > ok. We should be able to calculate that the maximum is length of
>> > usb3_phy_pipe_clk_src for now though?
>>
>> Yea, i thought of using the same macro, considering that it provides
>> 32 characters :-)
>> Will rather use the length of usb3_phy_pipe_clk_src for now. May be
>> #define MAX_CLK_NAME 24
>>
>
> Using a macro indicates that the size have some global meaning, but as
> far as I can see it doesn't. Just write 24 and you will have enough
> space for 100k pcie pipe clocks. And then use sizeof(clk_name) below.
Sure, will do as suggested.
>
>> >
>> >> + struct clk *clk;
>> >> +
>> >> + memset(&clk_name, 0, sizeof(clk_name));
>
> There's no point in clearing clk_name, as it will be overwritten
> and null-terminated below.
Right. Will remove this.
>
>> >> + switch (qphy->cfg->type) {
>> >> + case PHY_TYPE_USB3:
>> >> + snprintf(clk_name, MAX_PROP_NAME, "usb3_phy_pipe_clk_src");
>> >> + break;
>> >> + case PHY_TYPE_PCIE:
>> >> + snprintf(clk_name, MAX_PROP_NAME, "pcie_%d_pipe_clk_src", id);
>> >> + break;
>> >> + default:
>> >> + return -EINVAL;
>> >> + }
>> >> +
>> >> + /* controllers using QMP phys use 125MHz pipe clock interface */
>> >> + clk = clk_register_fixed_rate(qphy->dev, clk_name, NULL, 0, 125000000);
>
> Regards,
> Bjorn
> --
> To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
Regards
Vivek
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH v8 5/5] ARM: configs: stm32: Add I2C support for STM32 defconfig
From: M'boumba Cedric Madianga @ 2017-01-05 9:07 UTC (permalink / raw)
To: wsa, robh+dt, mcoquelin.stm32, alexandre.torgue, linus.walleij,
patrice.chotard, linux, linux-i2c, devicetree, linux-arm-kernel,
linux-kernel, u.kleine-koenig
Cc: M'boumba Cedric Madianga
In-Reply-To: <1483607246-14771-1-git-send-email-cedric.madianga@gmail.com>
This patch adds I2C support for STM32 default configuration
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
arch/arm/configs/stm32_defconfig | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/configs/stm32_defconfig b/arch/arm/configs/stm32_defconfig
index 5a72d69..323d2a3 100644
--- a/arch/arm/configs/stm32_defconfig
+++ b/arch/arm/configs/stm32_defconfig
@@ -47,6 +47,9 @@ CONFIG_SERIAL_NONSTANDARD=y
CONFIG_SERIAL_STM32=y
CONFIG_SERIAL_STM32_CONSOLE=y
# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_STM32F4=y
# CONFIG_HWMON is not set
# CONFIG_USB_SUPPORT is not set
CONFIG_NEW_LEDS=y
--
1.9.1
^ permalink raw reply related
* [PATCH v8 4/5] ARM: dts: stm32: Add I2C1 support for STM32429 eval board
From: M'boumba Cedric Madianga @ 2017-01-05 9:07 UTC (permalink / raw)
To: wsa, robh+dt, mcoquelin.stm32, alexandre.torgue, linus.walleij,
patrice.chotard, linux, linux-i2c, devicetree, linux-arm-kernel,
linux-kernel, u.kleine-koenig
Cc: M'boumba Cedric Madianga
In-Reply-To: <1483607246-14771-1-git-send-email-cedric.madianga@gmail.com>
This patch adds I2C1 instance support for STM32x9I-Eval board.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
arch/arm/boot/dts/stm32429i-eval.dts | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/arm/boot/dts/stm32429i-eval.dts b/arch/arm/boot/dts/stm32429i-eval.dts
index 76f7206..c943539 100644
--- a/arch/arm/boot/dts/stm32429i-eval.dts
+++ b/arch/arm/boot/dts/stm32429i-eval.dts
@@ -146,3 +146,9 @@
pinctrl-names = "default";
status = "okay";
};
+
+&i2c1 {
+ pinctrl-0 = <&i2c1_pins_b>;
+ pinctrl-names = "default";
+ status = "okay";
+};
--
1.9.1
^ permalink raw reply related
* [PATCH v8 3/5] ARM: dts: stm32: Add I2C1 support for STM32F429 SoC
From: M'boumba Cedric Madianga @ 2017-01-05 9:07 UTC (permalink / raw)
To: wsa, robh+dt, mcoquelin.stm32, alexandre.torgue, linus.walleij,
patrice.chotard, linux, linux-i2c, devicetree, linux-arm-kernel,
linux-kernel, u.kleine-koenig
Cc: M'boumba Cedric Madianga
In-Reply-To: <1483607246-14771-1-git-send-email-cedric.madianga@gmail.com>
This patch adds I2C1 support for STM32F429 SoC
Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
arch/arm/boot/dts/stm32f429.dtsi | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/arch/arm/boot/dts/stm32f429.dtsi b/arch/arm/boot/dts/stm32f429.dtsi
index e4dae0e..5b063e9 100644
--- a/arch/arm/boot/dts/stm32f429.dtsi
+++ b/arch/arm/boot/dts/stm32f429.dtsi
@@ -48,6 +48,7 @@
#include "skeleton.dtsi"
#include "armv7-m.dtsi"
#include <dt-bindings/pinctrl/stm32f429-pinfunc.h>
+#include <dt-bindings/mfd/stm32f4-rcc.h>
/ {
clocks {
@@ -153,6 +154,18 @@
status = "disabled";
};
+ i2c1: i2c@40005400 {
+ compatible = "st,stm32f4-i2c";
+ reg = <0x40005400 0x400>;
+ interrupts = <31>,
+ <32>;
+ resets = <&rcc STM32F4_APB1_RESET(I2C1)>;
+ clocks = <&rcc 0 STM32F4_APB1_CLOCK(I2C1)>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "disabled";
+ };
+
usart7: serial@40007800 {
compatible = "st,stm32-usart", "st,stm32-uart";
reg = <0x40007800 0x400>;
@@ -355,6 +368,16 @@
slew-rate = <2>;
};
};
+
+ i2c1_pins_b: i2c1@0 {
+ pins {
+ pinmux = <STM32F429_PB9_FUNC_I2C1_SDA>,
+ <STM32F429_PB6_FUNC_I2C1_SCL>;
+ bias-disable;
+ drive-open-drain;
+ slew-rate = <3>;
+ };
+ };
};
rcc: rcc@40023810 {
--
1.9.1
^ permalink raw reply related
* [PATCH v8 2/5] i2c: Add STM32F4 I2C driver
From: M'boumba Cedric Madianga @ 2017-01-05 9:07 UTC (permalink / raw)
To: wsa, robh+dt, mcoquelin.stm32, alexandre.torgue, linus.walleij,
patrice.chotard, linux, linux-i2c, devicetree, linux-arm-kernel,
linux-kernel, u.kleine-koenig
Cc: M'boumba Cedric Madianga
In-Reply-To: <1483607246-14771-1-git-send-email-cedric.madianga@gmail.com>
This patch adds support for the STM32F4 I2C controller.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
---
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-stm32f4.c | 866 +++++++++++++++++++++++++++++++++++++++
3 files changed, 877 insertions(+)
create mode 100644 drivers/i2c/busses/i2c-stm32f4.c
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index 0cdc844..2719208 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -886,6 +886,16 @@ config I2C_ST
This driver can also be built as module. If so, the module
will be called i2c-st.
+config I2C_STM32F4
+ tristate "STMicroelectronics STM32F4 I2C support"
+ depends on ARCH_STM32 || COMPILE_TEST
+ help
+ Enable this option to add support for STM32 I2C controller embedded
+ in STM32F4 SoCs.
+
+ This driver can also be built as module. If so, the module
+ will be called i2c-stm32f4.
+
config I2C_STU300
tristate "ST Microelectronics DDC I2C interface"
depends on MACH_U300
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 1c1bac8..a2c6ff5 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o
obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
obj-$(CONFIG_I2C_SIRF) += i2c-sirf.o
obj-$(CONFIG_I2C_ST) += i2c-st.o
+obj-$(CONFIG_I2C_STM32F4) += i2c-stm32f4.o
obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
obj-$(CONFIG_I2C_SUN6I_P2WI) += i2c-sun6i-p2wi.o
obj-$(CONFIG_I2C_TEGRA) += i2c-tegra.o
diff --git a/drivers/i2c/busses/i2c-stm32f4.c b/drivers/i2c/busses/i2c-stm32f4.c
new file mode 100644
index 0000000..23e5757
--- /dev/null
+++ b/drivers/i2c/busses/i2c-stm32f4.c
@@ -0,0 +1,866 @@
+/*
+ * Driver for STMicroelectronics STM32 I2C controller
+ *
+ * This I2C controller is described in the STM32F429/439 Soc reference manual.
+ * Please see below a link to the documentation:
+ * http://www.st.com/resource/en/reference_manual/DM00031020.pdf
+ *
+ * Copyright (C) M'boumba Cedric Madianga 2016
+ * Author: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
+ *
+ * This driver is based on i2c-st.c
+ *
+ * License terms: GNU General Public License (GPL), version 2
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset.h>
+
+/* STM32F4 I2C offset registers */
+#define STM32F4_I2C_CR1 0x00
+#define STM32F4_I2C_CR2 0x04
+#define STM32F4_I2C_DR 0x10
+#define STM32F4_I2C_SR1 0x14
+#define STM32F4_I2C_SR2 0x18
+#define STM32F4_I2C_CCR 0x1C
+#define STM32F4_I2C_TRISE 0x20
+#define STM32F4_I2C_FLTR 0x24
+
+/* STM32F4 I2C control 1*/
+#define STM32F4_I2C_CR1_POS BIT(11)
+#define STM32F4_I2C_CR1_ACK BIT(10)
+#define STM32F4_I2C_CR1_STOP BIT(9)
+#define STM32F4_I2C_CR1_START BIT(8)
+#define STM32F4_I2C_CR1_PE BIT(0)
+
+/* STM32F4 I2C control 2 */
+#define STM32F4_I2C_CR2_FREQ_MASK GENMASK(5, 0)
+#define STM32F4_I2C_CR2_FREQ(n) ((n) & STM32F4_I2C_CR2_FREQ_MASK)
+#define STM32F4_I2C_CR2_ITBUFEN BIT(10)
+#define STM32F4_I2C_CR2_ITEVTEN BIT(9)
+#define STM32F4_I2C_CR2_ITERREN BIT(8)
+#define STM32F4_I2C_CR2_IRQ_MASK (STM32F4_I2C_CR2_ITBUFEN | \
+ STM32F4_I2C_CR2_ITEVTEN | \
+ STM32F4_I2C_CR2_ITERREN)
+
+/* STM32F4 I2C Status 1 */
+#define STM32F4_I2C_SR1_AF BIT(10)
+#define STM32F4_I2C_SR1_ARLO BIT(9)
+#define STM32F4_I2C_SR1_BERR BIT(8)
+#define STM32F4_I2C_SR1_TXE BIT(7)
+#define STM32F4_I2C_SR1_RXNE BIT(6)
+#define STM32F4_I2C_SR1_BTF BIT(2)
+#define STM32F4_I2C_SR1_ADDR BIT(1)
+#define STM32F4_I2C_SR1_SB BIT(0)
+#define STM32F4_I2C_SR1_ITEVTEN_MASK (STM32F4_I2C_SR1_BTF | \
+ STM32F4_I2C_SR1_ADDR | \
+ STM32F4_I2C_SR1_SB)
+#define STM32F4_I2C_SR1_ITBUFEN_MASK (STM32F4_I2C_SR1_TXE | \
+ STM32F4_I2C_SR1_RXNE)
+#define STM32F4_I2C_SR1_ITERREN_MASK (STM32F4_I2C_SR1_AF | \
+ STM32F4_I2C_SR1_ARLO | \
+ STM32F4_I2C_SR1_BERR)
+
+/* STM32F4 I2C Status 2 */
+#define STM32F4_I2C_SR2_BUSY BIT(1)
+
+/* STM32F4 I2C Control Clock */
+#define STM32F4_I2C_CCR_CCR_MASK GENMASK(11, 0)
+#define STM32F4_I2C_CCR_CCR(n) ((n) & STM32F4_I2C_CCR_CCR_MASK)
+#define STM32F4_I2C_CCR_FS BIT(15)
+#define STM32F4_I2C_CCR_DUTY BIT(14)
+
+/* STM32F4 I2C Trise */
+#define STM32F4_I2C_TRISE_VALUE_MASK GENMASK(5, 0)
+#define STM32F4_I2C_TRISE_VALUE(n) ((n) & STM32F4_I2C_TRISE_VALUE_MASK)
+
+/* STM32F4 I2C Filter */
+#define STM32F4_I2C_FLTR_DNF_MASK GENMASK(3, 0)
+#define STM32F4_I2C_FLTR_DNF(n) ((n) & STM32F4_I2C_FLTR_DNF_MASK)
+#define STM32F4_I2C_FLTR_ANOFF BIT(4)
+
+#define STM32F4_I2C_MIN_FREQ 2U
+#define STM32F4_I2C_MAX_FREQ 46U
+#define HZ_TO_MHZ 1000000
+
+enum stm32f4_i2c_speed {
+ STM32F4_I2C_SPEED_STANDARD, /* 100 kHz */
+ STM32F4_I2C_SPEED_FAST, /* 400 kHz */
+ STM32F4_I2C_SPEED_END,
+};
+
+/**
+ * struct stm32f4_i2c_timings - per-Mode tuning parameters
+ * @duty: Fast mode duty cycle
+ * @scl_period: SCL period in microsecond to reach 100kHz/400kHz SCL frequency
+ */
+struct stm32f4_i2c_timings {
+ u32 duty;
+ u32 scl_period;
+};
+
+/**
+ * struct stm32f4_i2c_msg - client specific data
+ * @addr: 8-bit slave addr, including r/w bit
+ * @count: number of bytes to be transferred
+ * @buf: data buffer
+ * @result: result of the transfer
+ * @stop: last I2C msg to be sent, i.e. STOP to be generated
+ */
+struct stm32f4_i2c_msg {
+ u8 addr;
+ u32 count;
+ u8 *buf;
+ int result;
+ bool stop;
+};
+
+/**
+ * struct stm32f4_i2c_dev - private data of the controller
+ * @adap: I2C adapter for this controller
+ * @dev: device for this controller
+ * @base: virtual memory area
+ * @complete: completion of I2C message
+ * @clk: hw i2c clock
+ * speed: I2C clock frequency of the controller. Standard or Fast only supported
+ * @msg: I2C transfer information
+ */
+struct stm32f4_i2c_dev {
+ struct i2c_adapter adap;
+ struct device *dev;
+ void __iomem *base;
+ struct completion complete;
+ struct clk *clk;
+ int speed;
+ struct stm32f4_i2c_msg msg;
+};
+
+/*
+ * In standard mode:
+ * SCL period = SCL high period = SCL low period = CCR * I2C parent clk period
+ *
+ * In fast mode:
+ * If Duty = 0; SCL high period = 1 * CCR * I2C parent clk period
+ * SCL low period = 2 * CCR * I2C parent clk period
+ * If Duty = 1; SCL high period = 9 * CCR * I2C parent clk period
+ * SCL low period = 16 * CCR * I2C parent clk period
+ * In order to reach 400 kHz with lower I2C parent clk frequencies we always set
+ * Duty = 1
+ *
+ * For both modes, we have CCR = SCL period * I2C parent clk frequency
+ * with scl_period = 5 microseconds in Standard mode and scl_period = 1
+ * microsecond in Fast Mode in order to satisfy scl_high and scl_low periods
+ * constraints defined by i2c bus specification
+ */
+static struct stm32f4_i2c_timings i2c_timings[] = {
+ [STM32F4_I2C_SPEED_STANDARD] = {
+ .duty = 0,
+ .scl_period = 5,
+ },
+ [STM32F4_I2C_SPEED_FAST] = {
+ .duty = 1,
+ .scl_period = 1,
+ },
+};
+
+static inline void stm32f4_i2c_set_bits(void __iomem *reg, u32 mask)
+{
+ writel_relaxed(readl_relaxed(reg) | mask, reg);
+}
+
+static inline void stm32f4_i2c_clr_bits(void __iomem *reg, u32 mask)
+{
+ writel_relaxed(readl_relaxed(reg) & ~mask, reg);
+}
+
+static void stm32f4_i2c_disable_irq(struct stm32f4_i2c_dev *i2c_dev)
+{
+ void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
+
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR2_IRQ_MASK);
+}
+
+static int stm32f4_i2c_set_periph_clk_freq(struct stm32f4_i2c_dev *i2c_dev)
+{
+ u32 clk_rate, cr2, freq;
+
+ /*
+ * The minimum allowed frequency is 2MHz, the maximum APB frequency is
+ * limited by an intrinsic value of 46 MHz
+ */
+ clk_rate = clk_get_rate(i2c_dev->clk);
+ freq = DIV_ROUND_UP(clk_rate, HZ_TO_MHZ);
+ if (freq < STM32F4_I2C_MIN_FREQ || freq > STM32F4_I2C_MAX_FREQ) {
+ dev_err(i2c_dev->dev, "out of scope parent clk freq at %dMHz\n",
+ freq);
+ return -EINVAL;
+ }
+
+ cr2 = readl_relaxed(i2c_dev->base + STM32F4_I2C_CR2);
+ cr2 &= ~STM32F4_I2C_CR2_FREQ_MASK;
+ cr2 |= STM32F4_I2C_CR2_FREQ(freq);
+ writel_relaxed(cr2, i2c_dev->base + STM32F4_I2C_CR2);
+
+ return 0;
+}
+
+static void stm32f4_i2c_set_rise_time(struct stm32f4_i2c_dev *i2c_dev)
+{
+ u32 trise, freq, cr2;
+
+ /*
+ * These bits must be programmed with the maximum SCL rise time given in
+ * the I2C bus specification, incremented by 1.
+ *
+ * In standard mode, the maximum allowed SCL rise time is 1000 ns.
+ * If, in the I2C_CR2 register, the value of FREQ[5:0] bits is equal to
+ * 0x08 so period = 125 ns therefore the TRISE[5:0] bits must be
+ * programmed with 09h.(1000 ns / 125 ns = 8 + 1)
+ * So, for I2C standard mode TRISE = FREQ[5:0] + 1
+ *
+ * In fast mode, the maximum allowed SCL rise time is 300 ns.
+ * If, in the I2C_CR2 register, the value of FREQ[5:0] bits is equal to
+ * 0x08 so period = 125 ns therefore the TRISE[5:0] bits must be
+ * programmed with 03h.(300 ns / 125 ns = 2 + 1)
+ * So, for I2C fast mode TRISE = FREQ[5:0] * 300 / 1000 + 1
+ */
+
+ cr2 = readl_relaxed(i2c_dev->base + STM32F4_I2C_CR2);
+ freq = cr2 & STM32F4_I2C_CR2_FREQ_MASK;
+
+ if (i2c_dev->speed == STM32F4_I2C_SPEED_STANDARD)
+ trise = freq + 1;
+ else
+ trise = freq * 300 / 1000 + 1;
+
+ writel_relaxed(STM32F4_I2C_TRISE_VALUE(trise),
+ i2c_dev->base + STM32F4_I2C_TRISE);
+}
+
+static void stm32f4_i2c_set_speed_mode(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_timings *t = &i2c_timings[i2c_dev->speed];
+ u32 cr2, ccr, freq, val;
+
+ ccr = readl_relaxed(i2c_dev->base + STM32F4_I2C_CCR);
+ ccr &= ~(STM32F4_I2C_CCR_FS | STM32F4_I2C_CCR_DUTY |
+ STM32F4_I2C_CCR_CCR_MASK);
+
+ /*
+ * Please see the comments above regarding i2c_timings[] declaration
+ * to understand the below calculation
+ */
+ cr2 = readl_relaxed(i2c_dev->base + STM32F4_I2C_CR2);
+ freq = cr2 & STM32F4_I2C_CR2_FREQ_MASK;
+ val = freq * t->scl_period;
+ ccr |= STM32F4_I2C_CCR_CCR(val);
+
+ if (t->duty)
+ ccr |= STM32F4_I2C_CCR_FS | STM32F4_I2C_CCR_DUTY;
+
+ writel_relaxed(ccr, i2c_dev->base + STM32F4_I2C_CCR);
+}
+
+static void stm32f4_i2c_set_filter(struct stm32f4_i2c_dev *i2c_dev)
+{
+ u32 filter;
+
+ /* Enable analog noise filter and disable digital noise filter */
+ filter = readl_relaxed(i2c_dev->base + STM32F4_I2C_FLTR);
+ filter &= ~(STM32F4_I2C_FLTR_ANOFF | STM32F4_I2C_FLTR_DNF_MASK);
+ writel_relaxed(filter, i2c_dev->base + STM32F4_I2C_FLTR);
+}
+
+/**
+ * stm32f4_i2c_hw_config() - Prepare I2C block
+ * @i2c_dev: Controller's private data
+ */
+static int stm32f4_i2c_hw_config(struct stm32f4_i2c_dev *i2c_dev)
+{
+ void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR1;
+ int ret = 0;
+
+ /* Disable I2C */
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_PE);
+
+ ret = stm32f4_i2c_set_periph_clk_freq(i2c_dev);
+ if (ret)
+ return ret;
+
+ stm32f4_i2c_set_rise_time(i2c_dev);
+
+ stm32f4_i2c_set_speed_mode(i2c_dev);
+
+ stm32f4_i2c_set_filter(i2c_dev);
+
+ /* Enable I2C */
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_PE);
+
+ return ret;
+}
+
+static int stm32f4_i2c_wait_free_bus(struct stm32f4_i2c_dev *i2c_dev)
+{
+ u32 status;
+ int ret;
+
+ ret = readl_relaxed_poll_timeout(i2c_dev->base + STM32F4_I2C_SR2,
+ status,
+ !(status & STM32F4_I2C_SR2_BUSY),
+ 10, 1000);
+ if (ret) {
+ dev_dbg(i2c_dev->dev, "bus not free\n");
+ ret = -EBUSY;
+ }
+
+ return ret;
+}
+
+/**
+ * stm32f4_i2c_write_ byte() - Write a byte in the data register
+ * @i2c_dev: Controller's private data
+ * @byte: Data to write in the register
+ */
+static void stm32f4_i2c_write_byte(struct stm32f4_i2c_dev *i2c_dev, u8 byte)
+{
+ writel_relaxed(byte, i2c_dev->base + STM32F4_I2C_DR);
+}
+
+/**
+ * stm32f4_i2c_write_msg() - Fill the data register in write mode
+ * @i2c_dev: Controller's private data
+ *
+ * This function fills the data register with I2C transfer buffer
+ */
+static void stm32f4_i2c_write_msg(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+
+ stm32f4_i2c_write_byte(i2c_dev, *msg->buf++);
+ msg->count--;
+}
+
+static void stm32f4_i2c_read_msg(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ u32 rbuf;
+
+ rbuf = readl_relaxed(i2c_dev->base + STM32F4_I2C_DR);
+ *msg->buf++ = rbuf & 0xff;
+ msg->count--;
+}
+
+static void stm32f4_i2c_terminate_xfer(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
+
+ stm32f4_i2c_disable_irq(i2c_dev);
+
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ if (msg->stop)
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
+ else
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
+
+ complete(&i2c_dev->complete);
+}
+
+/**
+ * stm32f4_i2c_handle_write() - Handle FIFO empty interrupt in case of write
+ * @i2c_dev: Controller's private data
+ */
+static void stm32f4_i2c_handle_write(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
+
+ if (msg->count) {
+ stm32f4_i2c_write_msg(i2c_dev);
+ if (!msg->count) {
+ /* Disable buffer interrupts for RXNE/TXE events */
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR2_ITBUFEN);
+ }
+ } else {
+ stm32f4_i2c_terminate_xfer(i2c_dev);
+ }
+}
+
+/**
+ * stm32f4_i2c_handle_read() - Handle FIFO empty interrupt in case of read
+ * @i2c_dev: Controller's private data
+ */
+static void stm32f4_i2c_handle_read(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR2;
+
+ switch (msg->count) {
+ case 1:
+ stm32f4_i2c_disable_irq(i2c_dev);
+ stm32f4_i2c_read_msg(i2c_dev);
+ complete(&i2c_dev->complete);
+ break;
+ /*
+ * For 2 or 3-byte reception, we do not have to read the data register
+ * when RXNE occurs as we have to wait for byte transferred finished
+ * event before reading data. So, here we just disable buffer
+ * interrupt in order to avoid another system preemption due to RXNE
+ * event
+ */
+ case 2:
+ case 3:
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR2_ITBUFEN);
+ break;
+ /* For N byte reception with N > 3 we directly read data register */
+ default:
+ stm32f4_i2c_read_msg(i2c_dev);
+ }
+}
+
+/**
+ * stm32f4_i2c_handle_rx_btf() - Handle byte transfer finished interrupt
+ * in case of read
+ * @i2c_dev: Controller's private data
+ */
+static void stm32f4_i2c_handle_rx_btf(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ void __iomem *reg;
+ u32 mask;
+ int i;
+
+ switch (msg->count) {
+ case 2:
+ /*
+ * In order to correctly send the Stop or Repeated Start
+ * condition on the I2C bus, the STOP/START bit has to be set
+ * before reading the last two bytes.
+ * After that, we could read the last two bytes, disable
+ * remaining interrupts and notify the end of xfer to the
+ * client
+ */
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ if (msg->stop)
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
+ else
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
+
+ for (i = 2; i > 0; i--)
+ stm32f4_i2c_read_msg(i2c_dev);
+
+ reg = i2c_dev->base + STM32F4_I2C_CR2;
+ mask = STM32F4_I2C_CR2_ITEVTEN | STM32F4_I2C_CR2_ITERREN;
+ stm32f4_i2c_clr_bits(reg, mask);
+
+ complete(&i2c_dev->complete);
+ break;
+ case 3:
+ /*
+ * In order to correctly send the ACK on the I2C bus for the
+ * last two bytes, we have to set ACK bit before reading the
+ * third last data byte
+ */
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
+ stm32f4_i2c_read_msg(i2c_dev);
+ break;
+ default:
+ stm32f4_i2c_read_msg(i2c_dev);
+ }
+}
+
+/**
+ * stm32f4_i2c_handle_rx_addr() - Handle address matched interrupt in case of
+ * master receiver
+ * @i2c_dev: Controller's private data
+ */
+static void stm32f4_i2c_handle_rx_addr(struct stm32f4_i2c_dev *i2c_dev)
+{
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ void __iomem *reg;
+
+ switch (msg->count) {
+ case 0:
+ stm32f4_i2c_terminate_xfer(i2c_dev);
+ /* Clear ADDR flag */
+ readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
+ break;
+ case 1:
+ /*
+ * Single byte reception:
+ * Enable NACK, clear ADDR flag and generate STOP or RepSTART
+ */
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
+ readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
+ if (msg->stop)
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
+ else
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
+ break;
+ case 2:
+ /*
+ * 2-byte reception:
+ * Enable NACK and set POS
+ */
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_ACK);
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_POS);
+ readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
+ break;
+
+ default:
+ /* N-byte reception: Enable ACK */
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_ACK);
+ readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
+ break;
+ }
+}
+
+/**
+ * stm32f4_i2c_isr_event() - Interrupt routine for I2C bus event
+ * @irq: interrupt number
+ * @data: Controller's private data
+ */
+static irqreturn_t stm32f4_i2c_isr_event(int irq, void *data)
+{
+ struct stm32f4_i2c_dev *i2c_dev = data;
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ u32 possible_status = STM32F4_I2C_SR1_ITEVTEN_MASK;
+ void __iomem *reg;
+ u32 status, ien, event;
+
+ ien = readl_relaxed(i2c_dev->base + STM32F4_I2C_CR2);
+ ien &= STM32F4_I2C_CR2_IRQ_MASK;
+
+ /* Update possible_status if buffer interrupt is enabled */
+ if (ien & STM32F4_I2C_CR2_ITBUFEN)
+ possible_status |= STM32F4_I2C_SR1_ITBUFEN_MASK;
+
+ status = readl_relaxed(i2c_dev->base + STM32F4_I2C_SR1);
+ event = status & possible_status;
+ if (!event) {
+ dev_dbg(i2c_dev->dev,
+ "spurious evt irq (status=0x%08x, ien=0x%08x)\n",
+ status, ien);
+ return IRQ_NONE;
+ }
+
+ if (event & STM32F4_I2C_SR1_SB)
+ stm32f4_i2c_write_byte(i2c_dev, msg->addr);
+
+ if (event & STM32F4_I2C_SR1_ADDR) {
+ if (msg->addr & I2C_M_RD)
+ stm32f4_i2c_handle_rx_addr(i2c_dev);
+ else
+ readl_relaxed(i2c_dev->base + STM32F4_I2C_SR2);
+
+ /* Enable buffer interrupts for RXNE/TXE events */
+ reg = i2c_dev->base + STM32F4_I2C_CR2;
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR2_ITBUFEN);
+ }
+
+ if ((event & STM32F4_I2C_SR1_TXE) && !(msg->addr & I2C_M_RD))
+ stm32f4_i2c_handle_write(i2c_dev);
+
+ if ((event & STM32F4_I2C_SR1_RXNE) && (msg->addr & I2C_M_RD))
+ stm32f4_i2c_handle_read(i2c_dev);
+
+ if (event & STM32F4_I2C_SR1_BTF) {
+ if (msg->addr & I2C_M_RD)
+ stm32f4_i2c_handle_rx_btf(i2c_dev);
+ else
+ stm32f4_i2c_handle_write(i2c_dev);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * stm32f4_i2c_isr_error() - Interrupt routine for I2C bus error
+ * @irq: interrupt number
+ * @data: Controller's private data
+ */
+static irqreturn_t stm32f4_i2c_isr_error(int irq, void *data)
+{
+ struct stm32f4_i2c_dev *i2c_dev = data;
+ struct stm32f4_i2c_msg *msg = &i2c_dev->msg;
+ void __iomem *reg;
+ u32 status;
+
+ status = readl_relaxed(i2c_dev->base + STM32F4_I2C_SR1);
+
+ /* Arbitration lost */
+ if (status & STM32F4_I2C_SR1_ARLO) {
+ reg = i2c_dev->base + STM32F4_I2C_SR1;
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_SR1_ARLO);
+ msg->result = -EAGAIN;
+ }
+
+ /*
+ * Acknowledge failure:
+ * In master transmitter mode a Stop must be generated by software
+ */
+ if (status & STM32F4_I2C_SR1_AF) {
+ if (!(msg->addr & I2C_M_RD)) {
+ reg = i2c_dev->base + STM32F4_I2C_CR1;
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_STOP);
+ }
+ reg = i2c_dev->base + STM32F4_I2C_SR1;
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_SR1_AF);
+ msg->result = -EIO;
+ }
+
+ /* Bus error */
+ if (status & STM32F4_I2C_SR1_BERR) {
+ reg = i2c_dev->base + STM32F4_I2C_SR1;
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_SR1_BERR);
+ msg->result = -EIO;
+ }
+
+ stm32f4_i2c_disable_irq(i2c_dev);
+ complete(&i2c_dev->complete);
+
+ return IRQ_HANDLED;
+}
+
+/**
+ * stm32f4_i2c_xfer_msg() - Transfer a single I2C message
+ * @i2c_dev: Controller's private data
+ * @msg: I2C message to transfer
+ * @is_first: first message of the sequence
+ * @is_last: last message of the sequence
+ */
+static int stm32f4_i2c_xfer_msg(struct stm32f4_i2c_dev *i2c_dev,
+ struct i2c_msg *msg, bool is_first,
+ bool is_last)
+{
+ struct stm32f4_i2c_msg *f4_msg = &i2c_dev->msg;
+ void __iomem *reg = i2c_dev->base + STM32F4_I2C_CR1;
+ unsigned long timeout;
+ u32 mask;
+ int ret;
+
+ f4_msg->addr = i2c_8bit_addr_from_msg(msg);
+ f4_msg->buf = msg->buf;
+ f4_msg->count = msg->len;
+ f4_msg->result = 0;
+ f4_msg->stop = is_last;
+
+ reinit_completion(&i2c_dev->complete);
+
+ /* Enable events and errors interrupts */
+ mask = STM32F4_I2C_CR2_ITEVTEN | STM32F4_I2C_CR2_ITERREN;
+ stm32f4_i2c_set_bits(i2c_dev->base + STM32F4_I2C_CR2, mask);
+
+ if (is_first) {
+ ret = stm32f4_i2c_wait_free_bus(i2c_dev);
+ if (ret)
+ return ret;
+
+ /* START generation */
+ stm32f4_i2c_set_bits(reg, STM32F4_I2C_CR1_START);
+ }
+
+ timeout = wait_for_completion_timeout(&i2c_dev->complete,
+ i2c_dev->adap.timeout);
+ ret = f4_msg->result;
+
+ /* Disable POS position Ack */
+ stm32f4_i2c_clr_bits(reg, STM32F4_I2C_CR1_POS);
+
+ if (!timeout)
+ ret = -ETIMEDOUT;
+
+ return ret;
+}
+
+/**
+ * stm32f4_i2c_xfer() - Transfer combined I2C message
+ * @i2c_adap: Adapter pointer to the controller
+ * @msgs: Pointer to data to be written.
+ * @num: Number of messages to be executed
+ */
+static int stm32f4_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[],
+ int num)
+{
+ struct stm32f4_i2c_dev *i2c_dev = i2c_get_adapdata(i2c_adap);
+ int ret, i;
+
+ ret = clk_enable(i2c_dev->clk);
+ if (ret) {
+ dev_err(i2c_dev->dev, "Failed to enable clock\n");
+ return ret;
+ }
+
+ for (i = 0; i < num && !ret; i++)
+ ret = stm32f4_i2c_xfer_msg(i2c_dev, &msgs[i], i == 0,
+ i == num - 1);
+
+ clk_disable(i2c_dev->clk);
+
+ return (ret < 0) ? ret : num;
+}
+
+static u32 stm32f4_i2c_func(struct i2c_adapter *adap)
+{
+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static struct i2c_algorithm stm32f4_i2c_algo = {
+ .master_xfer = stm32f4_i2c_xfer,
+ .functionality = stm32f4_i2c_func,
+};
+
+static int stm32f4_i2c_probe(struct platform_device *pdev)
+{
+ struct device_node *np = pdev->dev.of_node;
+ struct stm32f4_i2c_dev *i2c_dev;
+ struct resource *res;
+ u32 irq_event, irq_error, clk_rate;
+ struct i2c_adapter *adap;
+ struct reset_control *rst;
+ int ret;
+
+ i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
+ if (!i2c_dev)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ i2c_dev->base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(i2c_dev->base))
+ return PTR_ERR(i2c_dev->base);
+
+ irq_event = irq_of_parse_and_map(np, 0);
+ if (!irq_event) {
+ dev_err(&pdev->dev, "IRQ event missing or invalid\n");
+ return -EINVAL;
+ }
+
+ irq_error = irq_of_parse_and_map(np, 1);
+ if (!irq_error) {
+ dev_err(&pdev->dev, "IRQ error missing or invalid\n");
+ return -EINVAL;
+ }
+
+ i2c_dev->clk = devm_clk_get(&pdev->dev, NULL);
+ if (IS_ERR(i2c_dev->clk)) {
+ dev_err(&pdev->dev, "Error: Missing controller clock\n");
+ return PTR_ERR(i2c_dev->clk);
+ }
+ ret = clk_prepare_enable(i2c_dev->clk);
+ if (ret) {
+ dev_err(i2c_dev->dev, "Failed to prepare_enable clock\n");
+ return ret;
+ }
+
+ rst = devm_reset_control_get(&pdev->dev, NULL);
+ if (IS_ERR(rst)) {
+ dev_err(&pdev->dev, "Error: Missing controller reset\n");
+ ret = PTR_ERR(rst);
+ goto clk_free;
+ }
+ reset_control_assert(rst);
+ udelay(2);
+ reset_control_deassert(rst);
+
+ i2c_dev->speed = STM32F4_I2C_SPEED_STANDARD;
+ ret = of_property_read_u32(np, "clock-frequency", &clk_rate);
+ if (!ret && clk_rate >= 40000)
+ i2c_dev->speed = STM32F4_I2C_SPEED_FAST;
+
+ i2c_dev->dev = &pdev->dev;
+
+ ret = devm_request_irq(&pdev->dev, irq_event, stm32f4_i2c_isr_event, 0,
+ pdev->name, i2c_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request irq event %i\n",
+ irq_event);
+ goto clk_free;
+ }
+
+ ret = devm_request_irq(&pdev->dev, irq_error, stm32f4_i2c_isr_error, 0,
+ pdev->name, i2c_dev);
+ if (ret) {
+ dev_err(&pdev->dev, "Failed to request irq error %i\n",
+ irq_error);
+ goto clk_free;
+ }
+
+ ret = stm32f4_i2c_hw_config(i2c_dev);
+ if (ret)
+ goto clk_free;
+
+ adap = &i2c_dev->adap;
+ i2c_set_adapdata(adap, i2c_dev);
+ snprintf(adap->name, sizeof(adap->name), "STM32 I2C(%pa)", &res->start);
+ adap->owner = THIS_MODULE;
+ adap->timeout = 2 * HZ;
+ adap->retries = 0;
+ adap->algo = &stm32f4_i2c_algo;
+ adap->dev.parent = &pdev->dev;
+ adap->dev.of_node = pdev->dev.of_node;
+
+ init_completion(&i2c_dev->complete);
+
+ ret = i2c_add_adapter(adap);
+ if (ret)
+ goto clk_free;
+
+ platform_set_drvdata(pdev, i2c_dev);
+
+ clk_disable(i2c_dev->clk);
+
+ dev_info(i2c_dev->dev, "STM32F4 I2C driver registered\n");
+
+ return 0;
+
+clk_free:
+ clk_disable_unprepare(i2c_dev->clk);
+ return ret;
+}
+
+static int stm32f4_i2c_remove(struct platform_device *pdev)
+{
+ struct stm32f4_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
+
+ i2c_del_adapter(&i2c_dev->adap);
+
+ clk_unprepare(i2c_dev->clk);
+
+ return 0;
+}
+
+static const struct of_device_id stm32f4_i2c_match[] = {
+ { .compatible = "st,stm32f4-i2c", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, stm32f4_i2c_match);
+
+static struct platform_driver stm32f4_i2c_driver = {
+ .driver = {
+ .name = "stm32f4-i2c",
+ .of_match_table = stm32f4_i2c_match,
+ },
+ .probe = stm32f4_i2c_probe,
+ .remove = stm32f4_i2c_remove,
+};
+
+module_platform_driver(stm32f4_i2c_driver);
+
+MODULE_AUTHOR("M'boumba Cedric Madianga <cedric.madianga@gmail.com>");
+MODULE_DESCRIPTION("STMicroelectronics STM32F4 I2C driver");
+MODULE_LICENSE("GPL v2");
--
1.9.1
^ permalink raw reply related
* [PATCH v8 1/5] dt-bindings: Document the STM32 I2C bindings
From: M'boumba Cedric Madianga @ 2017-01-05 9:07 UTC (permalink / raw)
To: wsa, robh+dt, mcoquelin.stm32, alexandre.torgue, linus.walleij,
patrice.chotard, linux, linux-i2c, devicetree, linux-arm-kernel,
linux-kernel, u.kleine-koenig
Cc: M'boumba Cedric Madianga
In-Reply-To: <1483607246-14771-1-git-send-email-cedric.madianga@gmail.com>
This patch adds documentation of device tree bindings for the STM32 I2C
controller.
Signed-off-by: M'boumba Cedric Madianga <cedric.madianga@gmail.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../devicetree/bindings/i2c/i2c-stm32.txt | 33 ++++++++++++++++++++++
1 file changed, 33 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-stm32.txt
diff --git a/Documentation/devicetree/bindings/i2c/i2c-stm32.txt b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt
new file mode 100644
index 0000000..78eaf7b
--- /dev/null
+++ b/Documentation/devicetree/bindings/i2c/i2c-stm32.txt
@@ -0,0 +1,33 @@
+* I2C controller embedded in STMicroelectronics STM32 I2C platform
+
+Required properties :
+- compatible : Must be "st,stm32f4-i2c"
+- reg : Offset and length of the register set for the device
+- interrupts : Must contain the interrupt id for I2C event and then the
+ interrupt id for I2C error.
+- resets: Must contain the phandle to the reset controller.
+- clocks: Must contain the input clock of the I2C instance.
+- A pinctrl state named "default" must be defined to set pins in mode of
+ operation for I2C transfer
+- #address-cells = <1>;
+- #size-cells = <0>;
+
+Optional properties :
+- clock-frequency : Desired I2C bus clock frequency in Hz. If not specified,
+ the default 100 kHz frequency will be used. As only Normal and Fast modes
+ are supported, possible values are 100000 and 400000.
+
+Example :
+
+ i2c@40005400 {
+ compatible = "st,stm32f4-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x40005400 0x400>;
+ interrupts = <31>,
+ <32>;
+ resets = <&rcc 277>;
+ clocks = <&rcc 0 149>;
+ pinctrl-0 = <&i2c1_sda_pin>, <&i2c1_scl_pin>;
+ pinctrl-names = "default";
+ };
--
1.9.1
^ permalink raw reply related
* [PATCH v8 0/5] Add support for the STM32F4 I2C
From: M'boumba Cedric Madianga @ 2017-01-05 9:07 UTC (permalink / raw)
To: wsa, robh+dt, mcoquelin.stm32, alexandre.torgue, linus.walleij,
patrice.chotard, linux, linux-i2c, devicetree, linux-arm-kernel,
linux-kernel, u.kleine-koenig
Cc: M'boumba Cedric Madianga
This patchset adds support for the I2C controller embedded in STM32F4xx SoC.
It enables I2C transfer in interrupt mode with Standard-mode and Fast-mode bus
speed.
Changes since v7:
- Remove unneeded parenthesis in some macro definitions (Uwe)
- Fix some typo (s/KhzkHZ, s/PEC/POC) (Uwe)
- Fix alignment issues in some structures declaration (Uwe)
- Clarify comments to argue i2c_timing values chosen (Uwe)
- Raise an error if parent clk rate is out of scope during I2C hw config (Uwe)
- Use dev_dbg instead of dev_err message when I2C bus is busy (Uwe)
- Add more comments about stuff done by stm32f4_i2c_handle_rx_btf() (Uwe)
- Simplify stm32f4_i2c_isr_error() routine implementation by removing possible
status checking (Uwe)
- Rework stm32f4_i2c_isr_error() routine by removing the loop to check which status occured (Uwe)
- Add open-drain property for SCL pins (Uwe)
- Rework unneeded mul_ccr field from i2c_timing structure
- Remove min_ccr field from i2c_timing structure as default scl_period is chosen
to have a correct minimal ccr value
- Execute hw_config once during probe
- Remove soft_reset after an I2C error as all errors are now handled and
hw_config is done once during probe
- Generate STOP by software when Acknowledge failure occurs
- Set the max speed mode for I2C pins
- Add bias-disable property for I2C pins
- Use intrinsic limitation of APB bus to set I2C max input clk
M'boumba Cedric Madianga (5):
dt-bindings: Document the STM32 I2C bindings
i2c: Add STM32F4 I2C driver
ARM: dts: stm32: Add I2C1 support for STM32F429 SoC
ARM: dts: stm32: Add I2C1 support for STM32429 eval board
ARM: configs: stm32: Add I2C support for STM32 defconfig
.../devicetree/bindings/i2c/i2c-stm32.txt | 33 +
arch/arm/boot/dts/stm32429i-eval.dts | 6 +
arch/arm/boot/dts/stm32f429.dtsi | 23 +
arch/arm/configs/stm32_defconfig | 3 +
drivers/i2c/busses/Kconfig | 10 +
drivers/i2c/busses/Makefile | 1 +
drivers/i2c/busses/i2c-stm32f4.c | 866 +++++++++++++++++++++
7 files changed, 942 insertions(+)
create mode 100644 Documentation/devicetree/bindings/i2c/i2c-stm32.txt
create mode 100644 drivers/i2c/busses/i2c-stm32f4.c
--
1.9.1
^ permalink raw reply
* Re: [PATCH v2 4/4] ARM: dts: keystone: Add "ti, da830-uart" compatible string
From: Sekhar Nori @ 2017-01-05 9:04 UTC (permalink / raw)
To: Santosh Shilimkar, David Lechner, Greg Kroah-Hartman,
Santosh Shilimkar
Cc: Mark Rutland, devicetree, Axel Haslam, Kevin Hilman, linux-kernel,
Bartosz Golaszewski, Rob Herring, Alexandre Bailon, linux-serial,
Jiri Slaby, Franklin S Cooper Jr, linux-arm-kernel
In-Reply-To: <93c4aed0-6faa-2c27-7931-454fc1f48e79@oracle.com>
Hi Santosh,
On Thursday 05 January 2017 03:30 AM, Santosh Shilimkar wrote:
> On 1/4/2017 12:30 PM, David Lechner wrote:
>> The TI Keystone SoCs have extra UART registers beyond the standard 8250
>> registers, so we need a new compatible string to indicate this. Also, at
>> least one of these registers uses the full 32 bits, so we need to specify
>> reg-io-width in addition to reg-shift.
>>
>> "ns16550a" is left in the compatible specification since it does work as
>> long as the bootloader configures the SoC UART power management
>> registers.
>>
> NAK!!
> We can't break the booting boards with existing boot loaders.
Sorry, but it not clear to me how this breaks booting with older
bootloaders? If older DTB is ROM'ed, it will continue to work because of
match with ns16550a.
I just verified boot on K2E with these patches applied and using 2016.05
based U-Boot from a TI release.
http://pastebin.ubuntu.com/23744719/
> I suggest you to first get the driver updated to take care of
> the UART PM register and then enable the support for it.
Isn't that what patch 2/4 is doing?
Thanks,
Sekhar
^ permalink raw reply
* Re: [PATCH V2 5/5] ARM: dts: exynos5440: support the phy-pcie node for pcie
From: pankaj.dubey @ 2017-01-05 9:04 UTC (permalink / raw)
To: Jaehoon Chung, linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, kishon, jingoohan1, vivek.gautam,
alim.akhtar, cpgs
In-Reply-To: <20170104123435.30740-6-jh80.chung@samsung.com>
Hi Jaehoon,
On Wednesday 04 January 2017 06:04 PM, Jaehoon Chung wrote:
> Add phy-pcie node for using Exynos5440 pcie.
> And use the reg-names as "elbi" and "config".
> Because the getting configuratioin space address from ranges is old way.
> It also is helpful to distinguish more clearly.
>
> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
> ---
> Changelog on V2:
> - Removes the child-node
> - Fixes the typo
> - Removes the unnecessary comments
>
> arch/arm/boot/dts/exynos5440.dtsi | 34 ++++++++++++++++++++++------------
> 1 file changed, 22 insertions(+), 12 deletions(-)
>
Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Thanks,
Pankaj Dubey
^ permalink raw reply
* Re: [PATCH V2 4/5] PCI: exynos: support the using PHY generic framework
From: pankaj.dubey @ 2017-01-05 9:01 UTC (permalink / raw)
To: Jaehoon Chung, linux-pci
Cc: devicetree, linux-kernel, linux-samsung-soc, bhelgaas, robh+dt,
mark.rutland, kgene, krzk, kishon, jingoohan1, vivek.gautam,
alim.akhtar, cpgs
In-Reply-To: <20170104123435.30740-5-jh80.chung@samsung.com>
Hi Jaehoon,
On Wednesday 04 January 2017 06:04 PM, Jaehoon Chung wrote:
> This patch is for using PHY generic framework.
> To maintain backward compatibility, check whether phy is supported or
> not with 'using_phy'.
>
> And if someone use the old dt-file, display the "deprecated" message.
> But it's still working fine with it.
>
> Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
> ---
> Changelog on V2:
> - This patch is split from previous PATCH[1/4]
> - Maintain the backward compatibility
> - Adds 'using_phy' for cheching whether phy framework is used or not
> - Adds 'DEPRECATED' message for old dt-binding way
>
Reviewed-by: Pankaj Dubey <pankaj.dubey@samsung.com>
Thanks,
Pankaj Dubey
^ permalink raw reply
* Re: [PATCH 08/12] ARM: dts: socfpga: Add NAND device tree for Arria10
From: Steffen Trumtrar @ 2017-01-05 8:55 UTC (permalink / raw)
To: Dinh Nguyen; +Cc: devicetree, dinguyen, linux-arm-kernel, Graham Moore
In-Reply-To: <1483575694-29599-9-git-send-email-dinguyen@kernel.org>
Hi!
Dinh Nguyen <dinguyen@kernel.org> writes:
> From: Graham Moore <grmoore@opensource.altera.com>
>
> Add socfpga_arria10_socdk_nand.dts board file for supporting NAND.
>
> Signed-off-by: Graham Moore <grmoore@opensource.altera.com>
> Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
> ---
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts | 44 ++++++++++++++++++++++++
> 2 files changed, 45 insertions(+)
> create mode 100644 arch/arm/boot/dts/socfpga_arria10_socdk_nand.dts
>
(...)
> +#include "socfpga_arria10_socdk.dtsi"
> +
> +/ {
> + soc {
> + nand: nand@ffb90000 {
> + #address-cells = <1>;
> + #size-cells = <1>;
> + status = "okay";
> +
> + compatible = "denali,denali-nand-dt", "altr,socfpga-denali-nand";
> + reg = <0xffb90000 0x72000>, <0xffb80000 0x10000>;
> + reg-names = "nand_data", "denali_reg";
> + interrupts = <0 99 4>;
> + dma-mask = <0xffffffff>;
> + clocks = <&nand_clk>;
This belongs into the socfpga_arria10.dtsi.
Regards,
Steffen
--
Pengutronix e.K. | Steffen Trumtrar |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
^ permalink raw reply
* [PATCH 1/1] iio: adc: tlc4541: add support for TI tlc4541 adc
From: Phil Reid @ 2017-01-05 8:55 UTC (permalink / raw)
To: jic23-DgEjT+Ai2ygdnm+yROfE0A, knaack.h-Mmb7MZpHnFY,
lars-Qo5EllUWu/uELgA04lAiVw, pmeerw-jW+XmwGofnusTnJN9+BGXg,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO,
linux-iio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
This adds TI's tlc4541 16-bit ADC driver. Which is a single channel
ADC. Supports raw and trigger buffer access.
Signed-off-by: Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>
---
.../devicetree/bindings/iio/adc/ti-tlc4541.txt | 16 ++
drivers/iio/adc/Kconfig | 11 +
drivers/iio/adc/Makefile | 1 +
drivers/iio/adc/ti-tlc4541.c | 266 +++++++++++++++++++++
4 files changed, 294 insertions(+)
create mode 100644 Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt
create mode 100644 drivers/iio/adc/ti-tlc4541.c
diff --git a/Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt b/Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt
new file mode 100644
index 0000000..67caccd
--- /dev/null
+++ b/Documentation/devicetree/bindings/iio/adc/ti-tlc4541.txt
@@ -0,0 +1,16 @@
+* Texas Instruments' TLC4541
+
+Required properties:
+ - compatible: Should be one of
+ * "ti,tlc4541"
+ - reg: spi chip select number for the device
+ - vref-supply: The regulator supply for ADC reference voltage
+ - spi-max-frequency: Max SPI frequency to use (<= 200000)
+
+Example:
+adc@0 {
+ compatible = "ti,adc0832";
+ reg = <0>;
+ vref-supply = <&vdd_supply>;
+ spi-max-frequency = <200000>;
+};
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 99c0514..4dda3f0 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -525,6 +525,17 @@ config TI_AM335X_ADC
To compile this driver as a module, choose M here: the module will be
called ti_am335x_adc.
+config TI_TLC4541
+ tristate "Texas Instruments TLC4541 ADC driver"
+ depends on SPI
+ select IIO_BUFFER
+ select IIO_TRIGGERED_BUFFER
+ help
+ Say yes here to build support for Texas Instruments TLC4541 ADC chip.
+
+ This driver can also be built as a module. If so, the module will be
+ called ti-tlc4541.
+
config TWL4030_MADC
tristate "TWL4030 MADC (Monitoring A/D Converter)"
depends on TWL4030_CORE
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 7a40c04..9bf2377 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -49,6 +49,7 @@ obj-$(CONFIG_TI_ADC161S626) += ti-adc161s626.o
obj-$(CONFIG_TI_ADS1015) += ti-ads1015.o
obj-$(CONFIG_TI_ADS8688) += ti-ads8688.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
+obj-$(CONFIG_TI_TLC4541) += ti-tlc4541.o
obj-$(CONFIG_TWL4030_MADC) += twl4030-madc.o
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
obj-$(CONFIG_VF610_ADC) += vf610_adc.o
diff --git a/drivers/iio/adc/ti-tlc4541.c b/drivers/iio/adc/ti-tlc4541.c
new file mode 100644
index 0000000..a767707
--- /dev/null
+++ b/drivers/iio/adc/ti-tlc4541.c
@@ -0,0 +1,266 @@
+/*
+ * TI tlc4541 ADC Driver
+ *
+ * Copyright (C) 2017 Phil Reid
+ *
+ * Datasheets can be found here:
+ * http://www.ti.com/lit/gpn/tlc4541
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * The tlc4541 requires 24 clock cycles to start a transfer.
+ * Conversion then takes 2.94us to complete before data is ready
+ */
+
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/iio/iio.h>
+#include <linux/iio/sysfs.h>
+#include <linux/iio/buffer.h>
+#include <linux/iio/trigger_consumer.h>
+#include <linux/iio/triggered_buffer.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/spi/spi.h>
+#include <linux/sysfs.h>
+
+struct tlc4541_state {
+ struct spi_device *spi;
+ struct regulator *reg;
+ struct spi_transfer scan_single_xfer[3];
+ struct spi_message scan_single_msg;
+
+ /*
+ * DMA (thus cache coherency maintenance) requires the
+ * transfer buffers to live in their own cache lines.
+ */
+ __be16 rx_buf[2] ____cacheline_aligned;
+};
+
+struct tlc4541_chip_info {
+ const struct iio_chan_spec *channels;
+ unsigned int num_channels;
+};
+
+enum tlc4541_id {
+ TLC4541,
+};
+
+#define TLC4541_V_CHAN(index, bits) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = index, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
+ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
+ .address = index, \
+ .scan_index = index, \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (bits), \
+ .storagebits = 16, \
+ .endianness = IIO_BE, \
+ }, \
+ }
+
+#define DECLARE_TLC4541_CHANNELS(name, bits) \
+const struct iio_chan_spec name ## _channels[] = { \
+ TLC4541_V_CHAN(0, bits), \
+ IIO_CHAN_SOFT_TIMESTAMP(1), \
+}
+
+static DECLARE_TLC4541_CHANNELS(tlc4541, 16);
+
+static const struct tlc4541_chip_info tlc4541_chip_info[] = {
+ [TLC4541] = {
+ .channels = tlc4541_channels,
+ .num_channels = ARRAY_SIZE(tlc4541_channels),
+ },
+};
+
+static irqreturn_t tlc4541_trigger_handler(int irq, void *p)
+{
+ struct iio_poll_func *pf = p;
+ struct iio_dev *indio_dev = pf->indio_dev;
+ struct tlc4541_state *st = iio_priv(indio_dev);
+ u16 buf[8]; /* 2 bytes data + 6 bytes padding + 8 bytes timestamp */
+ int ret;
+
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ if (ret < 0)
+ goto done;
+
+ buf[0] = be16_to_cpu(st->rx_buf[0]);
+ iio_push_to_buffers_with_timestamp(indio_dev, buf,
+ iio_get_time_ns(indio_dev));
+
+done:
+ iio_trigger_notify_done(indio_dev->trig);
+ return IRQ_HANDLED;
+}
+
+static int tlc4541_get_range(struct tlc4541_state *st)
+{
+ int vref;
+
+ vref = regulator_get_voltage(st->reg);
+ if (vref < 0)
+ return vref;
+
+ vref /= 1000;
+
+ return vref;
+}
+
+static int tlc4541_read_raw(struct iio_dev *indio_dev,
+ struct iio_chan_spec const *chan,
+ int *val,
+ int *val2,
+ long m)
+{
+ int ret = 0;
+ struct tlc4541_state *st = iio_priv(indio_dev);
+
+ switch (m) {
+ case IIO_CHAN_INFO_RAW:
+ ret = iio_device_claim_direct_mode(indio_dev);
+ if (ret)
+ return ret;
+ ret = spi_sync(st->spi, &st->scan_single_msg);
+ iio_device_release_direct_mode(indio_dev);
+ if (ret < 0)
+ return ret;
+ *val = be16_to_cpu(st->rx_buf[0]);
+ return IIO_VAL_INT;
+ case IIO_CHAN_INFO_SCALE:
+ ret = tlc4541_get_range(st);
+ if (ret < 0)
+ return ret;
+ *val = ret;
+ *val2 = chan->scan_type.realbits;
+ return IIO_VAL_FRACTIONAL_LOG2;
+ }
+ return -EINVAL;
+}
+
+static const struct iio_info tlc4541_info = {
+ .read_raw = &tlc4541_read_raw,
+ .driver_module = THIS_MODULE,
+};
+
+static int tlc4541_probe(struct spi_device *spi)
+{
+ struct tlc4541_state *st;
+ struct iio_dev *indio_dev;
+ const struct tlc4541_chip_info *info;
+ int ret;
+ int8_t device_init = 0;
+
+ indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
+ if (indio_dev == NULL)
+ return -ENOMEM;
+
+ st = iio_priv(indio_dev);
+
+ spi_set_drvdata(spi, indio_dev);
+
+ st->spi = spi;
+
+ info = &tlc4541_chip_info[spi_get_device_id(spi)->driver_data];
+
+ indio_dev->name = spi_get_device_id(spi)->name;
+ indio_dev->dev.parent = &spi->dev;
+ indio_dev->modes = INDIO_DIRECT_MODE;
+ indio_dev->channels = info->channels;
+ indio_dev->num_channels = info->num_channels;
+ indio_dev->info = &tlc4541_info;
+
+ /* perform reset */
+ spi_write(spi, &device_init, 1);
+
+ /* Setup default message */
+ st->scan_single_xfer[0].rx_buf = &st->rx_buf[0];
+ st->scan_single_xfer[0].len = 3;
+ st->scan_single_xfer[1].delay_usecs = 3;
+ st->scan_single_xfer[2].rx_buf = &st->rx_buf[0];
+ st->scan_single_xfer[2].len = 2;
+
+ spi_message_init(&st->scan_single_msg);
+ spi_message_add_tail(&st->scan_single_xfer[0], &st->scan_single_msg);
+ spi_message_add_tail(&st->scan_single_xfer[1], &st->scan_single_msg);
+ spi_message_add_tail(&st->scan_single_xfer[2], &st->scan_single_msg);
+
+ st->reg = devm_regulator_get(&spi->dev, "vref");
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+
+ ret = regulator_enable(st->reg);
+ if (ret)
+ return ret;
+
+ ret = iio_triggered_buffer_setup(indio_dev, NULL,
+ &tlc4541_trigger_handler, NULL);
+ if (ret)
+ goto error_disable_reg;
+
+ ret = iio_device_register(indio_dev);
+ if (ret)
+ goto error_cleanup_buffer;
+
+ return 0;
+
+error_cleanup_buffer:
+ iio_triggered_buffer_cleanup(indio_dev);
+error_disable_reg:
+ regulator_disable(st->reg);
+
+ return ret;
+}
+
+static int tlc4541_remove(struct spi_device *spi)
+{
+ struct iio_dev *indio_dev = spi_get_drvdata(spi);
+ struct tlc4541_state *st = iio_priv(indio_dev);
+
+ iio_device_unregister(indio_dev);
+ iio_triggered_buffer_cleanup(indio_dev);
+ regulator_disable(st->reg);
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+
+static const struct of_device_id tlc4541_dt_ids[] = {
+ { .compatible = "ti,tlc4541", },
+ {}
+};
+MODULE_DEVICE_TABLE(of, tlc4541_dt_ids);
+
+#endif
+
+static const struct spi_device_id tlc4541_id[] = {
+ {"tlc4541", TLC4541},
+ {}
+};
+MODULE_DEVICE_TABLE(spi, tlc4541_id);
+
+static struct spi_driver tlc4541_driver = {
+ .driver = {
+ .name = "tlc4541",
+ .of_match_table = of_match_ptr(tlc4541_dt_ids),
+ },
+ .probe = tlc4541_probe,
+ .remove = tlc4541_remove,
+ .id_table = tlc4541_id,
+};
+module_spi_driver(tlc4541_driver);
+
+MODULE_AUTHOR("Phil Reid <preid-qgqNFa1JUf/o2iN0hyhwsIdd74u8MsAO@public.gmane.org>");
+MODULE_DESCRIPTION("Texas Instruments TLC4541 ADC");
+MODULE_LICENSE("GPL v2");
--
1.8.3.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* Re: [PATCH 03/22] iio: adc: add support for X-Powers AXP20X and AXP22X PMICs ADCs
From: Chen-Yu Tsai @ 2017-01-05 8:27 UTC (permalink / raw)
To: Quentin Schulz
Cc: Mark Rutland, devicetree, Lars-Peter Clausen, open list:THERMAL,
linux-iio, linux-kernel, Sebastian Reichel, Russell King,
Chen-Yu Tsai, Rob Herring, linux-arm-kernel,
Peter Meerwald-Stadler, knaack.h, Maxime Ripard,
Bruno Prémont, Lee Jones, Thomas Petazzoni, Jonathan Cameron,
Icenowy Zheng
In-Reply-To: <9acfe5e0-dc56-bd63-02b4-7bf34d49d62c@free-electrons.com>
On Thu, Jan 5, 2017 at 4:06 PM, Quentin Schulz
<quentin.schulz@free-electrons.com> wrote:
> Hi Chen-Yu,
>
> On 05/01/2017 06:42, Chen-Yu Tsai wrote:
>> On Tue, Jan 3, 2017 at 12:37 AM, Quentin Schulz
>> <quentin.schulz@free-electrons.com> wrote:
> [...]
>>> +
>>> +#define AXP20X_ADC_RATE_MASK (3 << 6)
>>> +#define AXP20X_ADC_RATE_25HZ (0 << 6)
>>> +#define AXP20X_ADC_RATE_50HZ BIT(6)
>>
>> Please be consistent with the format.
>>
>>> +#define AXP20X_ADC_RATE_100HZ (2 << 6)
>>> +#define AXP20X_ADC_RATE_200HZ (3 << 6)
>>> +
>>> +#define AXP22X_ADC_RATE_100HZ (0 << 6)
>>> +#define AXP22X_ADC_RATE_200HZ BIT(6)
>>> +#define AXP22X_ADC_RATE_400HZ (2 << 6)
>>> +#define AXP22X_ADC_RATE_800HZ (3 << 6)
>>
>> These are power-of-2 multiples of some base rate. May I suggest
>> a formula macro instead. Either way, you seem to be using only
>> one value. Will this be made configurable in the future?
>>
>
> Yes, I could use a formula macro instead. No plan to make it
> configurable, should I make it configurable?
I don't see a use case for that atm.
>>> +
>>> +#define AXP20X_ADC_CHANNEL(_channel, _name, _type, _reg) \
>>> + { \
>>> + .type = _type, \
>>> + .indexed = 1, \
>>> + .channel = _channel, \
>>> + .address = _reg, \
>>> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
>>> + BIT(IIO_CHAN_INFO_SCALE), \
>>> + .datasheet_name = _name, \
>>> + }
>>> +
>>> +#define AXP20X_ADC_CHANNEL_OFFSET(_channel, _name, _type, _reg) \
>>> + { \
>>> + .type = _type, \
>>> + .indexed = 1, \
>>> + .channel = _channel, \
>>> + .address = _reg, \
>>> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
>>> + BIT(IIO_CHAN_INFO_SCALE) |\
>>> + BIT(IIO_CHAN_INFO_OFFSET),\
>>> + .datasheet_name = _name, \
>>> + }
>>> +
>>> +struct axp20x_adc_iio {
>>> + struct iio_dev *indio_dev;
>>> + struct regmap *regmap;
>>> +};
>>> +
>>> +enum axp20x_adc_channel {
>>> + AXP20X_ACIN_V = 0,
>>> + AXP20X_ACIN_I,
>>> + AXP20X_VBUS_V,
>>> + AXP20X_VBUS_I,
>>> + AXP20X_TEMP_ADC,
>>
>> PMIC_TEMP would be better. And please save a slot for TS input.
>>
>
> ACK.
>
> Hum.. I'm wondering what should be the IIO type of the TS input channel
> then? The TS Pin can be used in two modes: either to monitor the
> temperature of the battery or as an external ADC, at least that's what I
> understand from the datasheet.
AFAIK the battery charge/discharge high/low temperature threshold
registers take values in terms of voltage, not actual temperature.
And the temperature readout kind of depends on the thermoresistor
one is using. So I think "voltage" would be the proper type.
>
>>> + AXP20X_GPIO0_V,
>>> + AXP20X_GPIO1_V,
>>
>> Please skip a slot for "battery instantaneous power".
>>
>>> + AXP20X_BATT_V,
>>> + AXP20X_BATT_CHRG_I,
>>> + AXP20X_BATT_DISCHRG_I,
>>> + AXP20X_IPSOUT_V,
>>> +};
>>> +
>>> +enum axp22x_adc_channel {
>>> + AXP22X_TEMP_ADC = 0,
>>
>> Same comments as AXP20X_TEMP_ADC.
>>
>>> + AXP22X_BATT_V,
>>> + AXP22X_BATT_CHRG_I,
>>> + AXP22X_BATT_DISCHRG_I,
>>> +};
>>
>> Shouldn't these channel numbers be exported as part of the device tree
>> bindings? At the very least, they shouldn't be changed.
>>
>
> I don't understand what you mean by that. Do you mean you want a
> consistent numbering between the AXP20X and the AXP22X, so that
> AXP22X_BATT_V would have the same channel number than AXP20X_BATT_V?
>
> Could you explain a bit more your thoughts on the channel numbers being
> exported as part of the device tree bindings?
What I meant was that, since you are referencing the channels in the
device tree, the numbering scheme would be part of the device tree
binding, and should never be changed. So either these would be macros
in include/dt-bindings/, or a big warning should be put before it.
But see my reply on patch 7, about do we actually need to expose this
in the device tree.
>> Also please add a comment saying that the channels are numbered
>> in the order of their respective registers, and not the table
>> describing the ADCs in the datasheet (9.7 Signal Capture for AXP209
>> and 9.5 E-Gauge for AXP221).
>>
>
> Yes I can.
>
> What about Rob wanting channel numbers to start at zero for each
> different IIO type (i.e., today we have AXP22X_BATT_CHRG_I being
> exported as in_current1_raw whereas he wants in_current0_raw).
Hmm... I missed this. Are you talking about IIO or hwmon? IIRC
hwmon numbers things starting at 1.
> [...]
>>> +static int axp22x_adc_read_raw(struct iio_dev *indio_dev,
>>> + struct iio_chan_spec const *channel, int *val,
>>> + int *val2)
>>> +{
>>> + struct axp20x_adc_iio *info = iio_priv(indio_dev);
>>> + int size = 12, ret;
>>> +
>>> + switch (channel->channel) {
>>> + case AXP22X_BATT_DISCHRG_I:
>>> + size = 13;
>>> + case AXP22X_TEMP_ADC:
>>> + case AXP22X_BATT_V:
>>> + case AXP22X_BATT_CHRG_I:
>>
>> According to the datasheet, AXP22X_BATT_CHRG_I is also 13 bits wide.
>>
>
> Where did you get that?
>
> Also, the datasheet is inconsistent:
> - 9.5 E-Gauge Fuel Gauge system => the min value is at 0x0 and the max
> value at 0xfff for all channels, that's 12 bits.
> - 10.1.4 ADC Data => all channels except battery discharge current are
> on 12 bits (8 high, 4 low).
My datasheets (AXP221 v1.6, AXP221s v1.2, AXP223 v1.1, all Chinese) say
in 10.1.4:
- 7A: battery charge current high 5 bits
- 7B: battery charge current low 8 bits
- 7C: battery discharge current high 5 bits
- 7D: battery discharge current low 8 bits
>
> [...]
>>> +static int axp22x_read_raw(struct iio_dev *indio_dev,
>>> + struct iio_chan_spec const *chan, int *val,
>>> + int *val2, long mask)
>>> +{
>>> + switch (mask) {
>>> + case IIO_CHAN_INFO_OFFSET:
>>> + *val = -2667;
>>
>> Datasheet says -267.7 C, or -2677 here.
>>
>
> The formula in the datasheet is (in milli Celsius):
> processed = raw * 100 - 266700;
>
> while the IIO framework asks for a scale and an offset which are then
> applied as:
> processed = (raw + offset) * scale;
>
> Thus by factorizing, we get:
> processed = (raw - 2667) * 100;
What I meant was that your lower end value is off by one degree,
-266.7 in your code vs -267.7 in the datasheet.
>
> [...]
>>> +static int axp20x_remove(struct platform_device *pdev)
>>> +{
>>> + struct axp20x_adc_iio *info;
>>> + struct iio_dev *indio_dev = platform_get_drvdata(pdev);
>>> +
>>> + info = iio_priv(indio_dev);
>>
>> Nit: you could just reverse the 2 declarations above and join this
>> line after struct axp20x_adc_iio *info;
>>
>>> + regmap_write(info->regmap, AXP20X_ADC_EN1, 0);
>>> + regmap_write(info->regmap, AXP20X_ADC_EN2, 0);
>>
>> The existing VBUS power supply driver enables the VBUS ADC bits itself,
>> and does not check them later on. This means if one were to remove this
>> axp20x-adc module, the voltage/current readings in the VBUS power supply
>> would be invalid. Some sort of workaround would be needed here in this
>> driver of the VBUS driver.
>>
>
> That would be one reason to migrate the VBUS driver to use the IIO
> channels, wouldn't it?
It is, preferably without changing the device tree.
Regards
ChenYu
>
> But ACK, I'll think about something to work around this issue.
>
>>> +
>>> + return 0;
>>> +}
>>> +
>>> +static struct platform_driver axp20x_adc_driver = {
>>> + .driver = {
>>> + .name = "axp20x-adc",
>>> + .of_match_table = axp20x_adc_of_match,
>>> + },
>>> + .probe = axp20x_probe,
>>> + .remove = axp20x_remove,
>>> +};
>>> +
>>> +module_platform_driver(axp20x_adc_driver);
>>> +
>>> +MODULE_DESCRIPTION("ADC driver for AXP20X and AXP22X PMICs");
>>> +MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
>>> +MODULE_LICENSE("GPL");
>>> diff --git a/include/linux/mfd/axp20x.h b/include/linux/mfd/axp20x.h
>>> index a4860bc..650c6f6 100644
>>> --- a/include/linux/mfd/axp20x.h
>>> +++ b/include/linux/mfd/axp20x.h
>>> @@ -150,6 +150,10 @@ enum {
>>> #define AXP20X_VBUS_I_ADC_L 0x5d
>>> #define AXP20X_TEMP_ADC_H 0x5e
>>> #define AXP20X_TEMP_ADC_L 0x5f
>>> +
>>> +#define AXP22X_TEMP_ADC_H 0x56
>>> +#define AXP22X_TEMP_ADC_L 0x57
>>> +
>>
>> This is in the wrong patch. Also we already have
>>
>> /* AXP22X specific registers */
>> #define AXP22X_PMIC_ADC_H 0x56
>> #define AXP22X_PMIC_ADC_L 0x57
>> #define AXP22X_TS_ADC_H 0x58
>> #define AXP22X_TS_ADC_L 0x59
>>
>> If you want, you could just rename them to be consistent.
>>
>
> ACK.
>
> Thanks,
> Quentin
>
> --
> Quentin Schulz, Free Electrons
> Embedded Linux and Kernel engineering
> http://free-electrons.com
^ permalink raw reply
* [PATCH v2 4/4] arm64: dts: exynos: Add tm2 touchkey node
From: Jaechul Lee @ 2017-01-05 8:27 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Mark Rutland, Catalin Marinas,
Will Deacon, Kukjin Kim, Krzysztof Kozlowski,
Javier Martinez Canillas
Cc: Jaechul Lee, Andi Shyti, Chanwoo Choi, beomho.seo, galaxyra,
linux-arm-kernel, linux-input, devicetree, linux-kernel,
linux-samsung-soc
In-Reply-To: <1483604833-29746-1-git-send-email-jcsing.lee@samsung.com>
Add DT node support for TM2 touchkey device.
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Signed-off-by: Andi Shyti <andi.shyti@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzk@kernel.org>
---
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
index aa8584a..dad6fb8 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -17,3 +17,16 @@
model = "Samsung TM2 board";
compatible = "samsung,tm2", "samsung,exynos5433";
};
+
+&hsi2c_9 {
+ status = "okay";
+
+ touchkey@20 {
+ compatible = "samsung,tm2-touchkey";
+ reg = <0x20>;
+ interrupt-parent = <&gpa3>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+ vcc-supply = <&ldo32_reg>;
+ vdd-supply = <&ldo33_reg>;
+ };
+};
--
2.7.4
^ permalink raw reply related
* [PATCH v2 3/4] arm64: dts: exynos: make tm2 and tm2e independent from each other
From: Jaechul Lee @ 2017-01-05 8:27 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Mark Rutland, Catalin Marinas,
Will Deacon, Kukjin Kim, Krzysztof Kozlowski,
Javier Martinez Canillas
Cc: devicetree, linux-samsung-soc, Jaechul Lee, linux-kernel,
Andi Shyti, Chanwoo Choi, beomho.seo, linux-input, galaxyra,
linux-arm-kernel
In-Reply-To: <1483604833-29746-1-git-send-email-jcsing.lee@samsung.com>
From: Andi Shyti <andi.shyti@samsung.com>
Currently tm2e dts includes tm2 but there are some differences
between the two boards and tm2 has some properties that tm2e
doesn't have.
That's why it's important to keep the two dts files independent
and put all the commonalities in a tm2-common.dtsi file.
Signed-off-by: Andi Shyti <andi.shyti@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
---
.../boot/dts/exynos/exynos5433-tm2-common.dtsi | 1116 +++++++++++++++++++
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 1138 +-------------------
arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 2 +-
3 files changed, 1136 insertions(+), 1120 deletions(-)
create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
rewrite arch/arm64/boot/dts/exynos/exynos5433-tm2.dts (98%)
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
new file mode 100644
index 0000000..7ad0019
--- /dev/null
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -0,0 +1,1116 @@
+/*
+ * SAMSUNG Exynos5433 TM2 board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Device tree source file for Samsung's TM2 board which is based on
+ * Samsung Exynos5433 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+/dts-v1/;
+#include "exynos5433.dtsi"
+#include <dt-bindings/clock/samsung,s2mps11.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/ {
+ aliases {
+ gsc0 = &gsc_0;
+ gsc1 = &gsc_1;
+ gsc2 = &gsc_2;
+ pinctrl0 = &pinctrl_alive;
+ pinctrl1 = &pinctrl_aud;
+ pinctrl2 = &pinctrl_cpif;
+ pinctrl3 = &pinctrl_ese;
+ pinctrl4 = &pinctrl_finger;
+ pinctrl5 = &pinctrl_fsys;
+ pinctrl6 = &pinctrl_imem;
+ pinctrl7 = &pinctrl_nfc;
+ pinctrl8 = &pinctrl_peric;
+ pinctrl9 = &pinctrl_touch;
+ serial0 = &serial_0;
+ serial1 = &serial_1;
+ serial2 = &serial_2;
+ serial3 = &serial_3;
+ spi0 = &spi_0;
+ spi1 = &spi_1;
+ spi2 = &spi_2;
+ spi3 = &spi_3;
+ spi4 = &spi_4;
+ mshc0 = &mshc_0;
+ mshc2 = &mshc_2;
+ };
+
+ chosen {
+ stdout-path = &serial_1;
+ };
+
+ memory@20000000 {
+ device_type = "memory";
+ reg = <0x0 0x20000000 0x0 0xc0000000>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power-key {
+ gpios = <&gpa2 7 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_POWER>;
+ label = "power key";
+ debounce-interval = <10>;
+ };
+
+ volume-up-key {
+ gpios = <&gpa2 0 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEUP>;
+ label = "volume-up key";
+ debounce-interval = <10>;
+ };
+
+ volume-down-key {
+ gpios = <&gpa2 1 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_VOLUMEDOWN>;
+ label = "volume-down key";
+ debounce-interval = <10>;
+ };
+
+ homepage-key {
+ gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
+ linux,code = <KEY_MENU>;
+ label = "homepage key";
+ debounce-interval = <10>;
+ };
+ };
+
+ i2c_max98504: i2c-gpio-0 {
+ compatible = "i2c-gpio";
+ gpios = <&gpd0 1 GPIO_ACTIVE_HIGH /* SPK_AMP_SDA */
+ &gpd0 0 GPIO_ACTIVE_HIGH /* SPK_AMP_SCL */ >;
+ i2c-gpio,delay-us = <2>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ status = "okay";
+
+ max98504: max98504@31 {
+ compatible = "maxim,max98504";
+ reg = <0x31>;
+ maxim,rx-path = <1>;
+ maxim,tx-path = <1>;
+ maxim,tx-channel-mask = <3>;
+ maxim,tx-channel-source = <2>;
+ };
+ };
+
+ sound {
+ compatible = "samsung,tm2-audio";
+ audio-codec = <&wm5110>;
+ i2s-controller = <&i2s0>;
+ audio-amplifier = <&max98504>;
+ mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
+ model = "wm5110";
+ samsung,audio-routing =
+ /* Headphone */
+ "HP", "HPOUT1L",
+ "HP", "HPOUT1R",
+
+ /* Speaker */
+ "SPK", "SPKOUT",
+ "SPKOUT", "HPOUT2L",
+ "SPKOUT", "HPOUT2R",
+
+ /* Receiver */
+ "RCV", "HPOUT3L",
+ "RCV", "HPOUT3R";
+ status = "okay";
+ };
+};
+
+&adc {
+ vdd-supply = <&ldo3_reg>;
+ status = "okay";
+
+ thermistor-ap {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 0>;
+ };
+
+ thermistor-battery {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 1>;
+ #thermal-sensor-cells = <0>;
+ };
+
+ thermistor-charger {
+ compatible = "murata,ncp03wf104";
+ pullup-uv = <1800000>;
+ pullup-ohm = <100000>;
+ pulldown-ohm = <0>;
+ io-channels = <&adc 2>;
+ };
+};
+
+&bus_g2d_400 {
+ devfreq-events = <&ppmu_event0_d0_general>, <&ppmu_event0_d1_general>;
+ vdd-supply = <&buck4_reg>;
+ exynos,saturation-ratio = <10>;
+ status = "okay";
+};
+
+&bus_g2d_266 {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_gscl {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_hevc {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_jpeg {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_mfc {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_mscl {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_noc0 {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_noc1 {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&bus_noc2 {
+ devfreq = <&bus_g2d_400>;
+ status = "okay";
+};
+
+&cmu_aud {
+ assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>;
+ assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>;
+};
+
+&cmu_fsys {
+ assigned-clocks = <&cmu_top CLK_MOUT_SCLK_USBDRD30>,
+ <&cmu_top CLK_MOUT_SCLK_USBHOST30>,
+ <&cmu_fsys CLK_MOUT_SCLK_USBDRD30_USER>,
+ <&cmu_fsys CLK_MOUT_SCLK_USBHOST30_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER>,
+ <&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER>,
+ <&cmu_top CLK_DIV_SCLK_USBDRD30>,
+ <&cmu_top CLK_DIV_SCLK_USBHOST30>;
+ assigned-clock-parents = <&cmu_top CLK_MOUT_BUS_PLL_USER>,
+ <&cmu_top CLK_MOUT_BUS_PLL_USER>,
+ <&cmu_top CLK_SCLK_USBDRD30_FSYS>,
+ <&cmu_top CLK_SCLK_USBHOST30_FSYS>,
+ <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY>,
+ <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY>,
+ <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY>,
+ <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY>;
+ assigned-clock-rates = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>,
+ <66700000>, <66700000>;
+};
+
+&cmu_gscl {
+ assigned-clocks = <&cmu_gscl CLK_MOUT_ACLK_GSCL_111_USER>,
+ <&cmu_gscl CLK_MOUT_ACLK_GSCL_333_USER>;
+ assigned-clock-parents = <&cmu_top CLK_ACLK_GSCL_111>,
+ <&cmu_top CLK_ACLK_GSCL_333>;
+};
+
+&cmu_mfc {
+ assigned-clocks = <&cmu_mfc CLK_MOUT_ACLK_MFC_400_USER>;
+ assigned-clock-parents = <&cmu_top CLK_ACLK_MFC_400>;
+};
+
+&cmu_mscl {
+ assigned-clocks = <&cmu_mscl CLK_MOUT_ACLK_MSCL_400_USER>,
+ <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
+ <&cmu_mscl CLK_MOUT_SCLK_JPEG>,
+ <&cmu_top CLK_MOUT_SCLK_JPEG_A>;
+ assigned-clock-parents = <&cmu_top CLK_ACLK_MSCL_400>,
+ <&cmu_top CLK_SCLK_JPEG_MSCL>,
+ <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
+ <&cmu_top CLK_MOUT_BUS_PLL_USER>;
+};
+
+&cpu0 {
+ cpu-supply = <&buck3_reg>;
+};
+
+&cpu4 {
+ cpu-supply = <&buck2_reg>;
+};
+
+&decon {
+ status = "okay";
+
+ i80-if-timings {
+ };
+};
+
+&dsi {
+ status = "okay";
+ vddcore-supply = <&ldo6_reg>;
+ vddio-supply = <&ldo7_reg>;
+ samsung,pll-clock-frequency = <24000000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&te_irq>;
+
+ ports {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ port@1 {
+ reg = <1>;
+
+ dsi_out: endpoint {
+ samsung,burst-clock-frequency = <512000000>;
+ samsung,esc-clock-frequency = <16000000>;
+ };
+ };
+ };
+};
+
+&hsi2c_0 {
+ status = "okay";
+ clock-frequency = <2500000>;
+
+ s2mps13-pmic@66 {
+ compatible = "samsung,s2mps13-pmic";
+ interrupt-parent = <&gpa0>;
+ interrupts = <7 IRQ_TYPE_NONE>;
+ reg = <0x66>;
+ samsung,s2mps11-wrstbi-ground;
+
+ s2mps13_osc: clocks {
+ compatible = "samsung,s2mps13-clk";
+ #clock-cells = <1>;
+ clock-output-names = "s2mps13_ap", "s2mps13_cp",
+ "s2mps13_bt";
+ };
+
+ regulators {
+ ldo1_reg: LDO1 {
+ regulator-name = "VDD_ALIVE_0.9V_AP";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <900000>;
+ regulator-always-on;
+ };
+
+ ldo2_reg: LDO2 {
+ regulator-name = "VDDQ_MMC2_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo3_reg: LDO3 {
+ regulator-name = "VDD1_E_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo4_reg: LDO4 {
+ regulator-name = "VDD10_MIF_PLL_1.0V_AP";
+ regulator-min-microvolt = <1300000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo5_reg: LDO5 {
+ regulator-name = "VDD10_DPLL_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo6_reg: LDO6 {
+ regulator-name = "VDD10_MIPI2L_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo7_reg: LDO7 {
+ regulator-name = "VDD18_MIPI2L_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo8_reg: LDO8 {
+ regulator-name = "VDD18_LLI_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo9_reg: LDO9 {
+ regulator-name = "VDD18_ABB_ETC_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo10_reg: LDO10 {
+ regulator-name = "VDD33_USB30_3.0V_AP";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo11_reg: LDO11 {
+ regulator-name = "VDD_INT_M_1.0V_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo12_reg: LDO12 {
+ regulator-name = "VDD_KFC_M_1.1V_AP";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1350000>;
+ regulator-always-on;
+ };
+
+ ldo13_reg: LDO13 {
+ regulator-name = "VDD_G3D_M_0.95V_AP";
+ regulator-min-microvolt = <950000>;
+ regulator-max-microvolt = <950000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo14_reg: LDO14 {
+ regulator-name = "VDDQ_M1_LDO_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo15_reg: LDO15 {
+ regulator-name = "VDDQ_M2_LDO_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ ldo16_reg: LDO16 {
+ regulator-name = "VDDQ_EFUSE";
+ regulator-min-microvolt = <1400000>;
+ regulator-max-microvolt = <3400000>;
+ regulator-always-on;
+ };
+
+ ldo17_reg: LDO17 {
+ regulator-name = "V_TFLASH_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo18_reg: LDO18 {
+ regulator-name = "V_CODEC_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo19_reg: LDO19 {
+ regulator-name = "VDDA_1.8V_COMP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-always-on;
+ };
+
+ ldo20_reg: LDO20 {
+ regulator-name = "VCC_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ regulator-always-on;
+ };
+
+ ldo21_reg: LDO21 {
+ regulator-name = "VT_CAM_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo22_reg: LDO22 {
+ regulator-name = "CAM_IO_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo23_reg: LDO23 {
+ regulator-name = "CAM_SEN_CORE_1.2V_AP";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo24_reg: LDO24 {
+ regulator-name = "VT_CAM_1.2V";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ ldo25_reg: LDO25 {
+ regulator-name = "CAM_SEN_A2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo26_reg: LDO26 {
+ regulator-name = "CAM_AF_2.8V_AP";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo27_reg: LDO27 {
+ regulator-name = "VCC_3.0V_LCD_AP";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo28_reg: LDO28 {
+ regulator-name = "VCC_1.8V_LCD_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo29_reg: LDO29 {
+ regulator-name = "VT_CAM_2.8V";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo30_reg: LDO30 {
+ regulator-name = "TSP_AVDD_3.3V_AP";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ ldo31_reg: LDO31 {
+ regulator-name = "TSP_VDD_1.85V_AP";
+ regulator-min-microvolt = <1850000>;
+ regulator-max-microvolt = <1850000>;
+ };
+
+ ldo32_reg: LDO32 {
+ regulator-name = "VTOUCH_1.8V_AP";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo33_reg: LDO33 {
+ regulator-name = "VTOUCH_LED_3.3V";
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-ramp-delay = <12500>;
+ };
+
+ ldo34_reg: LDO34 {
+ regulator-name = "VCC_1.8V_MHL_AP";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <2100000>;
+ };
+
+ ldo35_reg: LDO35 {
+ regulator-name = "OIS_VM_2.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2800000>;
+ };
+
+ ldo36_reg: LDO36 {
+ regulator-name = "VSIL_1.0V";
+ regulator-min-microvolt = <1000000>;
+ regulator-max-microvolt = <1000000>;
+ };
+
+ ldo37_reg: LDO37 {
+ regulator-name = "VF_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo38_reg: LDO38 {
+ regulator-name = "VCC_3.0V_MOTOR_AP";
+ regulator-min-microvolt = <3000000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ ldo39_reg: LDO39 {
+ regulator-name = "V_HRM_1.8V";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+
+ ldo40_reg: LDO40 {
+ regulator-name = "V_HRM_3.3V";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ };
+
+ buck1_reg: BUCK1 {
+ regulator-name = "VDD_MIF_0.9V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck2_reg: BUCK2 {
+ regulator-name = "VDD_EGL_1.0V_AP";
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1300000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck3_reg: BUCK3 {
+ regulator-name = "VDD_KFC_1.0V_AP";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck4_reg: BUCK4 {
+ regulator-name = "VDD_INT_0.95V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck5_reg: BUCK5 {
+ regulator-name = "VDD_DISP_CAM0_0.9V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck6_reg: BUCK6 {
+ regulator-name = "VDD_G3D_0.9V_AP";
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ regulator-state-mem {
+ regulator-off-in-suspend;
+ };
+ };
+
+ buck7_reg: BUCK7 {
+ regulator-name = "VDD_MEM1_1.2V_AP";
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ regulator-always-on;
+ };
+
+ buck8_reg: BUCK8 {
+ regulator-name = "VDD_LLDO_1.35V_AP";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ buck9_reg: BUCK9 {
+ regulator-name = "VDD_MLDO_2.0V_AP";
+ regulator-min-microvolt = <1350000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ };
+
+ buck10_reg: BUCK10 {
+ regulator-name = "vdd_mem2";
+ regulator-min-microvolt = <550000>;
+ regulator-max-microvolt = <1500000>;
+ regulator-always-on;
+ };
+ };
+ };
+};
+
+&hsi2c_8 {
+ status = "okay";
+
+ max77843@66 {
+ compatible = "maxim,max77843";
+ interrupt-parent = <&gpa1>;
+ interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
+ reg = <0x66>;
+
+ muic: max77843-muic {
+ compatible = "maxim,max77843-muic";
+ };
+
+ regulators {
+ compatible = "maxim,max77843-regulator";
+ safeout1_reg: SAFEOUT1 {
+ regulator-name = "SAFEOUT1";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <4950000>;
+ };
+
+ safeout2_reg: SAFEOUT2 {
+ regulator-name = "SAFEOUT2";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <4950000>;
+ };
+
+ charger_reg: CHARGER {
+ regulator-name = "CHARGER";
+ regulator-min-microamp = <100000>;
+ regulator-max-microamp = <3150000>;
+ };
+ };
+
+ haptic: max77843-haptic {
+ compatible = "maxim,max77843-haptic";
+ haptic-supply = <&ldo38_reg>;
+ pwms = <&pwm 0 33670 0>;
+ pwm-names = "haptic";
+ };
+ };
+};
+
+&i2s0 {
+ status = "okay";
+};
+
+&mshc_0 {
+ status = "okay";
+ num-slots = <1>;
+ mmc-hs200-1_8v;
+ mmc-hs400-1_8v;
+ cap-mmc-highspeed;
+ non-removable;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ samsung,dw-mshc-hs400-timing = <0 3>;
+ samsung,read-strobe-delay = <90>;
+ fifo-depth = <0x80>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4
+ &sd0_bus8 &sd0_rdqs>;
+ bus-width = <8>;
+ assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>;
+ assigned-clock-rates = <800000000>;
+};
+
+&mshc_2 {
+ status = "okay";
+ num-slots = <1>;
+ cap-sd-highspeed;
+ disable-wp;
+ cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
+ cd-inverted;
+ card-detect-delay = <200>;
+ samsung,dw-mshc-ciu-div = <3>;
+ samsung,dw-mshc-sdr-timing = <0 4>;
+ samsung,dw-mshc-ddr-timing = <0 2>;
+ fifo-depth = <0x80>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
+ bus-width = <4>;
+};
+
+&ppmu_d0_general {
+ status = "okay";
+ events {
+ ppmu_event0_d0_general: ppmu-event0-d0-general {
+ event-name = "ppmu-event0-d0-general";
+ };
+ };
+};
+
+&ppmu_d1_general {
+ status = "okay";
+ events {
+ ppmu_event0_d1_general: ppmu-event0-d1-general {
+ event-name = "ppmu-event0-d1-general";
+ };
+ };
+};
+
+&pinctrl_alive {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_alive>;
+
+ initial_alive: initial-state {
+ PIN(IN, gpa0-0, DOWN, LV1);
+ PIN(IN, gpa0-1, NONE, LV1);
+ PIN(IN, gpa0-2, DOWN, LV1);
+ PIN(IN, gpa0-3, NONE, LV1);
+ PIN(IN, gpa0-4, NONE, LV1);
+ PIN(IN, gpa0-5, DOWN, LV1);
+ PIN(IN, gpa0-6, NONE, LV1);
+ PIN(IN, gpa0-7, NONE, LV1);
+
+ PIN(IN, gpa1-0, UP, LV1);
+ PIN(IN, gpa1-1, NONE, LV1);
+ PIN(IN, gpa1-2, NONE, LV1);
+ PIN(IN, gpa1-3, DOWN, LV1);
+ PIN(IN, gpa1-4, DOWN, LV1);
+ PIN(IN, gpa1-5, NONE, LV1);
+ PIN(IN, gpa1-6, NONE, LV1);
+ PIN(IN, gpa1-7, NONE, LV1);
+
+ PIN(IN, gpa2-0, NONE, LV1);
+ PIN(IN, gpa2-1, NONE, LV1);
+ PIN(IN, gpa2-2, NONE, LV1);
+ PIN(IN, gpa2-3, DOWN, LV1);
+ PIN(IN, gpa2-4, NONE, LV1);
+ PIN(IN, gpa2-5, DOWN, LV1);
+ PIN(IN, gpa2-6, DOWN, LV1);
+ PIN(IN, gpa2-7, NONE, LV1);
+
+ PIN(IN, gpa3-0, DOWN, LV1);
+ PIN(IN, gpa3-1, DOWN, LV1);
+ PIN(IN, gpa3-2, NONE, LV1);
+ PIN(IN, gpa3-3, DOWN, LV1);
+ PIN(IN, gpa3-4, NONE, LV1);
+ PIN(IN, gpa3-5, DOWN, LV1);
+ PIN(IN, gpa3-6, DOWN, LV1);
+ PIN(IN, gpa3-7, DOWN, LV1);
+
+ PIN(IN, gpf1-0, NONE, LV1);
+ PIN(IN, gpf1-1, NONE, LV1);
+ PIN(IN, gpf1-2, DOWN, LV1);
+ PIN(IN, gpf1-4, UP, LV1);
+ PIN(OUT, gpf1-5, NONE, LV1);
+ PIN(IN, gpf1-6, DOWN, LV1);
+ PIN(IN, gpf1-7, DOWN, LV1);
+
+ PIN(IN, gpf2-0, DOWN, LV1);
+ PIN(IN, gpf2-1, DOWN, LV1);
+ PIN(IN, gpf2-2, DOWN, LV1);
+ PIN(IN, gpf2-3, DOWN, LV1);
+
+ PIN(IN, gpf3-0, DOWN, LV1);
+ PIN(IN, gpf3-1, DOWN, LV1);
+ PIN(IN, gpf3-2, NONE, LV1);
+ PIN(IN, gpf3-3, DOWN, LV1);
+
+ PIN(IN, gpf4-0, DOWN, LV1);
+ PIN(IN, gpf4-1, DOWN, LV1);
+ PIN(IN, gpf4-2, DOWN, LV1);
+ PIN(IN, gpf4-3, DOWN, LV1);
+ PIN(IN, gpf4-4, DOWN, LV1);
+ PIN(IN, gpf4-5, DOWN, LV1);
+ PIN(IN, gpf4-6, DOWN, LV1);
+ PIN(IN, gpf4-7, DOWN, LV1);
+
+ PIN(IN, gpf5-0, DOWN, LV1);
+ PIN(IN, gpf5-1, DOWN, LV1);
+ PIN(IN, gpf5-2, DOWN, LV1);
+ PIN(IN, gpf5-3, DOWN, LV1);
+ PIN(OUT, gpf5-4, NONE, LV1);
+ PIN(IN, gpf5-5, DOWN, LV1);
+ PIN(IN, gpf5-6, DOWN, LV1);
+ PIN(IN, gpf5-7, DOWN, LV1);
+ };
+
+ te_irq: te_irq {
+ samsung,pins = "gpf1-3";
+ samsung,pin-function = <0xf>;
+ };
+};
+
+&pinctrl_cpif {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_cpif>;
+
+ initial_cpif: initial-state {
+ PIN(IN, gpv6-0, DOWN, LV1);
+ PIN(IN, gpv6-1, DOWN, LV1);
+ };
+};
+
+&pinctrl_ese {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_ese>;
+
+ initial_ese: initial-state {
+ PIN(IN, gpj2-0, DOWN, LV1);
+ PIN(IN, gpj2-1, DOWN, LV1);
+ PIN(IN, gpj2-2, DOWN, LV1);
+ };
+};
+
+&pinctrl_fsys {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_fsys>;
+
+ initial_fsys: initial-state {
+ PIN(IN, gpr3-0, NONE, LV1);
+ PIN(IN, gpr3-1, DOWN, LV1);
+ PIN(IN, gpr3-2, DOWN, LV1);
+ PIN(IN, gpr3-3, DOWN, LV1);
+ PIN(IN, gpr3-7, NONE, LV1);
+ };
+};
+
+&pinctrl_imem {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_imem>;
+
+ initial_imem: initial-state {
+ PIN(IN, gpf0-0, UP, LV1);
+ PIN(IN, gpf0-1, UP, LV1);
+ PIN(IN, gpf0-2, DOWN, LV1);
+ PIN(IN, gpf0-3, UP, LV1);
+ PIN(IN, gpf0-4, DOWN, LV1);
+ PIN(IN, gpf0-5, NONE, LV1);
+ PIN(IN, gpf0-6, DOWN, LV1);
+ PIN(IN, gpf0-7, UP, LV1);
+ };
+};
+
+&pinctrl_nfc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_nfc>;
+
+ initial_nfc: initial-state {
+ PIN(IN, gpj0-2, DOWN, LV1);
+ };
+};
+
+&pinctrl_peric {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_peric>;
+
+ initial_peric: initial-state {
+ PIN(IN, gpv7-0, DOWN, LV1);
+ PIN(IN, gpv7-1, DOWN, LV1);
+ PIN(IN, gpv7-2, NONE, LV1);
+ PIN(IN, gpv7-3, DOWN, LV1);
+ PIN(IN, gpv7-4, DOWN, LV1);
+ PIN(IN, gpv7-5, DOWN, LV1);
+
+ PIN(IN, gpb0-4, DOWN, LV1);
+
+ PIN(IN, gpc0-2, DOWN, LV1);
+ PIN(IN, gpc0-5, DOWN, LV1);
+ PIN(IN, gpc0-7, DOWN, LV1);
+
+ PIN(IN, gpc1-1, DOWN, LV1);
+
+ PIN(IN, gpc3-4, NONE, LV1);
+ PIN(IN, gpc3-5, NONE, LV1);
+ PIN(IN, gpc3-6, NONE, LV1);
+ PIN(IN, gpc3-7, NONE, LV1);
+
+ PIN(OUT, gpg0-0, NONE, LV1);
+ PIN(FUNC1, gpg0-1, DOWN, LV1);
+
+ PIN(IN, gpd2-5, DOWN, LV1);
+
+ PIN(IN, gpd4-0, NONE, LV1);
+ PIN(IN, gpd4-1, DOWN, LV1);
+ PIN(IN, gpd4-2, DOWN, LV1);
+ PIN(IN, gpd4-3, DOWN, LV1);
+ PIN(IN, gpd4-4, DOWN, LV1);
+
+ PIN(IN, gpd6-3, DOWN, LV1);
+
+ PIN(IN, gpd8-1, UP, LV1);
+
+ PIN(IN, gpg1-0, DOWN, LV1);
+ PIN(IN, gpg1-1, DOWN, LV1);
+ PIN(IN, gpg1-2, DOWN, LV1);
+ PIN(IN, gpg1-3, DOWN, LV1);
+ PIN(IN, gpg1-4, DOWN, LV1);
+
+ PIN(IN, gpg2-0, DOWN, LV1);
+ PIN(IN, gpg2-1, DOWN, LV1);
+
+ PIN(IN, gpg3-0, DOWN, LV1);
+ PIN(IN, gpg3-1, DOWN, LV1);
+ PIN(IN, gpg3-5, DOWN, LV1);
+ PIN(IN, gpg3-7, DOWN, LV1);
+ };
+};
+
+&pinctrl_touch {
+ pinctrl-names = "default";
+ pinctrl-0 = <&initial_touch>;
+
+ initial_touch: initial-state {
+ PIN(IN, gpj1-2, DOWN, LV1);
+ };
+};
+
+&pwm {
+ pinctrl-0 = <&pwm0_out>;
+ pinctrl-names = "default";
+ status = "okay";
+};
+
+&mic {
+ status = "okay";
+
+ i80-if-timings {
+ };
+};
+
+&pmu_system_controller {
+ assigned-clocks = <&pmu_system_controller 0>;
+ assigned-clock-parents = <&xxti>;
+};
+
+&serial_1 {
+ status = "okay";
+};
+
+&spi_1 {
+ cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
+ status = "okay";
+
+ wm5110: wm5110-codec@0 {
+ compatible = "wlf,wm5110";
+ reg = <0x0>;
+ spi-max-frequency = <20000000>;
+ interrupt-parent = <&gpa0>;
+ interrupts = <4 IRQ_TYPE_NONE>;
+ clocks = <&pmu_system_controller 0>,
+ <&s2mps13_osc S2MPS11_CLK_BT>;
+ clock-names = "mclk1", "mclk2";
+
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ wlf,micd-detect-debounce = <300>;
+ wlf,micd-bias-start-time = <0x1>;
+ wlf,micd-rate = <0x7>;
+ wlf,micd-dbtime = <0x1>;
+ wlf,micd-force-micbias;
+ wlf,micd-configs = <0x0 1 0>;
+ wlf,hpdet-channel = <1>;
+ wlf,gpsw = <0x1>;
+ wlf,inmode = <2 0 2 0>;
+
+ wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
+ wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
+
+ /* core supplies */
+ AVDD-supply = <&ldo18_reg>;
+ DBVDD1-supply = <&ldo18_reg>;
+ CPVDD-supply = <&ldo18_reg>;
+ DBVDD2-supply = <&ldo18_reg>;
+ DBVDD3-supply = <&ldo18_reg>;
+
+ controller-data {
+ samsung,spi-feedback-delay = <0>;
+ };
+ };
+};
+
+&timer {
+ clock-frequency = <24000000>;
+};
+
+&tmu_atlas0 {
+ vtmu-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&tmu_apollo {
+ vtmu-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&tmu_g3d {
+ vtmu-supply = <&ldo3_reg>;
+ status = "okay";
+};
+
+&usbdrd30 {
+ vdd33-supply = <&ldo10_reg>;
+ vdd10-supply = <&ldo6_reg>;
+ status = "okay";
+};
+
+&usbdrd_dwc3_0 {
+ dr_mode = "otg";
+};
+
+&usbdrd30_phy {
+ vbus-supply = <&safeout1_reg>;
+ status = "okay";
+};
+
+&xxti {
+ clock-frequency = <24000000>;
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
dissimilarity index 98%
index 4e6619c..aa8584a 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
@@ -1,1119 +1,19 @@
-/*
- * SAMSUNG Exynos5433 TM2 board device tree source
- *
- * Copyright (c) 2016 Samsung Electronics Co., Ltd.
- *
- * Device tree source file for Samsung's TM2 board which is based on
- * Samsung Exynos5433 SoC.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-/dts-v1/;
-#include "exynos5433.dtsi"
-#include <dt-bindings/clock/samsung,s2mps11.h>
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/input/input.h>
-#include <dt-bindings/interrupt-controller/irq.h>
-
-/ {
- model = "Samsung TM2 board";
- compatible = "samsung,tm2", "samsung,exynos5433";
-
- aliases {
- gsc0 = &gsc_0;
- gsc1 = &gsc_1;
- gsc2 = &gsc_2;
- pinctrl0 = &pinctrl_alive;
- pinctrl1 = &pinctrl_aud;
- pinctrl2 = &pinctrl_cpif;
- pinctrl3 = &pinctrl_ese;
- pinctrl4 = &pinctrl_finger;
- pinctrl5 = &pinctrl_fsys;
- pinctrl6 = &pinctrl_imem;
- pinctrl7 = &pinctrl_nfc;
- pinctrl8 = &pinctrl_peric;
- pinctrl9 = &pinctrl_touch;
- serial0 = &serial_0;
- serial1 = &serial_1;
- serial2 = &serial_2;
- serial3 = &serial_3;
- spi0 = &spi_0;
- spi1 = &spi_1;
- spi2 = &spi_2;
- spi3 = &spi_3;
- spi4 = &spi_4;
- mshc0 = &mshc_0;
- mshc2 = &mshc_2;
- };
-
- chosen {
- stdout-path = &serial_1;
- };
-
- memory@20000000 {
- device_type = "memory";
- reg = <0x0 0x20000000 0x0 0xc0000000>;
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- power-key {
- gpios = <&gpa2 7 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_POWER>;
- label = "power key";
- debounce-interval = <10>;
- };
-
- volume-up-key {
- gpios = <&gpa2 0 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_VOLUMEUP>;
- label = "volume-up key";
- debounce-interval = <10>;
- };
-
- volume-down-key {
- gpios = <&gpa2 1 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_VOLUMEDOWN>;
- label = "volume-down key";
- debounce-interval = <10>;
- };
-
- homepage-key {
- gpios = <&gpa0 3 GPIO_ACTIVE_LOW>;
- linux,code = <KEY_MENU>;
- label = "homepage key";
- debounce-interval = <10>;
- };
- };
-
- i2c_max98504: i2c-gpio-0 {
- compatible = "i2c-gpio";
- gpios = <&gpd0 1 GPIO_ACTIVE_HIGH /* SPK_AMP_SDA */
- &gpd0 0 GPIO_ACTIVE_HIGH /* SPK_AMP_SCL */ >;
- i2c-gpio,delay-us = <2>;
- #address-cells = <1>;
- #size-cells = <0>;
- status = "okay";
-
- max98504: max98504@31 {
- compatible = "maxim,max98504";
- reg = <0x31>;
- maxim,rx-path = <1>;
- maxim,tx-path = <1>;
- maxim,tx-channel-mask = <3>;
- maxim,tx-channel-source = <2>;
- };
- };
-
- sound {
- compatible = "samsung,tm2-audio";
- audio-codec = <&wm5110>;
- i2s-controller = <&i2s0>;
- audio-amplifier = <&max98504>;
- mic-bias-gpios = <&gpr3 2 GPIO_ACTIVE_HIGH>;
- model = "wm5110";
- samsung,audio-routing =
- /* Headphone */
- "HP", "HPOUT1L",
- "HP", "HPOUT1R",
-
- /* Speaker */
- "SPK", "SPKOUT",
- "SPKOUT", "HPOUT2L",
- "SPKOUT", "HPOUT2R",
-
- /* Receiver */
- "RCV", "HPOUT3L",
- "RCV", "HPOUT3R";
- status = "okay";
- };
-};
-
-&adc {
- vdd-supply = <&ldo3_reg>;
- status = "okay";
-
- thermistor-ap {
- compatible = "murata,ncp03wf104";
- pullup-uv = <1800000>;
- pullup-ohm = <100000>;
- pulldown-ohm = <0>;
- io-channels = <&adc 0>;
- };
-
- thermistor-battery {
- compatible = "murata,ncp03wf104";
- pullup-uv = <1800000>;
- pullup-ohm = <100000>;
- pulldown-ohm = <0>;
- io-channels = <&adc 1>;
- #thermal-sensor-cells = <0>;
- };
-
- thermistor-charger {
- compatible = "murata,ncp03wf104";
- pullup-uv = <1800000>;
- pullup-ohm = <100000>;
- pulldown-ohm = <0>;
- io-channels = <&adc 2>;
- };
-};
-
-&bus_g2d_400 {
- devfreq-events = <&ppmu_event0_d0_general>, <&ppmu_event0_d1_general>;
- vdd-supply = <&buck4_reg>;
- exynos,saturation-ratio = <10>;
- status = "okay";
-};
-
-&bus_g2d_266 {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_gscl {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_hevc {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_jpeg {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_mfc {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_mscl {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_noc0 {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_noc1 {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&bus_noc2 {
- devfreq = <&bus_g2d_400>;
- status = "okay";
-};
-
-&cmu_aud {
- assigned-clocks = <&cmu_aud CLK_MOUT_AUD_PLL_USER>;
- assigned-clock-parents = <&cmu_top CLK_FOUT_AUD_PLL>;
-};
-
-&cmu_fsys {
- assigned-clocks = <&cmu_top CLK_MOUT_SCLK_USBDRD30>,
- <&cmu_top CLK_MOUT_SCLK_USBHOST30>,
- <&cmu_fsys CLK_MOUT_SCLK_USBDRD30_USER>,
- <&cmu_fsys CLK_MOUT_SCLK_USBHOST30_USER>,
- <&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_USER>,
- <&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_USER>,
- <&cmu_fsys CLK_MOUT_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_USER>,
- <&cmu_fsys CLK_MOUT_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_USER>,
- <&cmu_top CLK_DIV_SCLK_USBDRD30>,
- <&cmu_top CLK_DIV_SCLK_USBHOST30>;
- assigned-clock-parents = <&cmu_top CLK_MOUT_BUS_PLL_USER>,
- <&cmu_top CLK_MOUT_BUS_PLL_USER>,
- <&cmu_top CLK_SCLK_USBDRD30_FSYS>,
- <&cmu_top CLK_SCLK_USBHOST30_FSYS>,
- <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PIPE_PCLK_PHY>,
- <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PIPE_PCLK_PHY>,
- <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK_PHY>,
- <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK_PHY>;
- assigned-clock-rates = <0>, <0>, <0>, <0>, <0>, <0>, <0>, <0>,
- <66700000>, <66700000>;
-};
-
-&cmu_gscl {
- assigned-clocks = <&cmu_gscl CLK_MOUT_ACLK_GSCL_111_USER>,
- <&cmu_gscl CLK_MOUT_ACLK_GSCL_333_USER>;
- assigned-clock-parents = <&cmu_top CLK_ACLK_GSCL_111>,
- <&cmu_top CLK_ACLK_GSCL_333>;
-};
-
-&cmu_mfc {
- assigned-clocks = <&cmu_mfc CLK_MOUT_ACLK_MFC_400_USER>;
- assigned-clock-parents = <&cmu_top CLK_ACLK_MFC_400>;
-};
-
-&cmu_mscl {
- assigned-clocks = <&cmu_mscl CLK_MOUT_ACLK_MSCL_400_USER>,
- <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
- <&cmu_mscl CLK_MOUT_SCLK_JPEG>,
- <&cmu_top CLK_MOUT_SCLK_JPEG_A>;
- assigned-clock-parents = <&cmu_top CLK_ACLK_MSCL_400>,
- <&cmu_top CLK_SCLK_JPEG_MSCL>,
- <&cmu_mscl CLK_MOUT_SCLK_JPEG_USER>,
- <&cmu_top CLK_MOUT_BUS_PLL_USER>;
-};
-
-&cpu0 {
- cpu-supply = <&buck3_reg>;
-};
-
-&cpu4 {
- cpu-supply = <&buck2_reg>;
-};
-
-&decon {
- status = "okay";
-
- i80-if-timings {
- };
-};
-
-&dsi {
- status = "okay";
- vddcore-supply = <&ldo6_reg>;
- vddio-supply = <&ldo7_reg>;
- samsung,pll-clock-frequency = <24000000>;
- pinctrl-names = "default";
- pinctrl-0 = <&te_irq>;
-
- ports {
- #address-cells = <1>;
- #size-cells = <0>;
-
- port@1 {
- reg = <1>;
-
- dsi_out: endpoint {
- samsung,burst-clock-frequency = <512000000>;
- samsung,esc-clock-frequency = <16000000>;
- };
- };
- };
-};
-
-&hsi2c_0 {
- status = "okay";
- clock-frequency = <2500000>;
-
- s2mps13-pmic@66 {
- compatible = "samsung,s2mps13-pmic";
- interrupt-parent = <&gpa0>;
- interrupts = <7 IRQ_TYPE_NONE>;
- reg = <0x66>;
- samsung,s2mps11-wrstbi-ground;
-
- s2mps13_osc: clocks {
- compatible = "samsung,s2mps13-clk";
- #clock-cells = <1>;
- clock-output-names = "s2mps13_ap", "s2mps13_cp",
- "s2mps13_bt";
- };
-
- regulators {
- ldo1_reg: LDO1 {
- regulator-name = "VDD_ALIVE_0.9V_AP";
- regulator-min-microvolt = <900000>;
- regulator-max-microvolt = <900000>;
- regulator-always-on;
- };
-
- ldo2_reg: LDO2 {
- regulator-name = "VDDQ_MMC2_2.8V_AP";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo3_reg: LDO3 {
- regulator-name = "VDD1_E_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- };
-
- ldo4_reg: LDO4 {
- regulator-name = "VDD10_MIF_PLL_1.0V_AP";
- regulator-min-microvolt = <1300000>;
- regulator-max-microvolt = <1300000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo5_reg: LDO5 {
- regulator-name = "VDD10_DPLL_1.0V_AP";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo6_reg: LDO6 {
- regulator-name = "VDD10_MIPI2L_1.0V_AP";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo7_reg: LDO7 {
- regulator-name = "VDD18_MIPI2L_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo8_reg: LDO8 {
- regulator-name = "VDD18_LLI_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo9_reg: LDO9 {
- regulator-name = "VDD18_ABB_ETC_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo10_reg: LDO10 {
- regulator-name = "VDD33_USB30_3.0V_AP";
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo11_reg: LDO11 {
- regulator-name = "VDD_INT_M_1.0V_AP";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo12_reg: LDO12 {
- regulator-name = "VDD_KFC_M_1.1V_AP";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1350000>;
- regulator-always-on;
- };
-
- ldo13_reg: LDO13 {
- regulator-name = "VDD_G3D_M_0.95V_AP";
- regulator-min-microvolt = <950000>;
- regulator-max-microvolt = <950000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo14_reg: LDO14 {
- regulator-name = "VDDQ_M1_LDO_1.2V_AP";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo15_reg: LDO15 {
- regulator-name = "VDDQ_M2_LDO_1.2V_AP";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- ldo16_reg: LDO16 {
- regulator-name = "VDDQ_EFUSE";
- regulator-min-microvolt = <1400000>;
- regulator-max-microvolt = <3400000>;
- regulator-always-on;
- };
-
- ldo17_reg: LDO17 {
- regulator-name = "V_TFLASH_2.8V_AP";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- ldo18_reg: LDO18 {
- regulator-name = "V_CODEC_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo19_reg: LDO19 {
- regulator-name = "VDDA_1.8V_COMP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-always-on;
- };
-
- ldo20_reg: LDO20 {
- regulator-name = "VCC_2.8V_AP";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- regulator-always-on;
- };
-
- ldo21_reg: LDO21 {
- regulator-name = "VT_CAM_1.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo22_reg: LDO22 {
- regulator-name = "CAM_IO_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo23_reg: LDO23 {
- regulator-name = "CAM_SEN_CORE_1.2V_AP";
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1200000>;
- };
-
- ldo24_reg: LDO24 {
- regulator-name = "VT_CAM_1.2V";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- ldo25_reg: LDO25 {
- regulator-name = "CAM_SEN_A2.8V_AP";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- ldo26_reg: LDO26 {
- regulator-name = "CAM_AF_2.8V_AP";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- ldo27_reg: LDO27 {
- regulator-name = "VCC_3.0V_LCD_AP";
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- };
-
- ldo28_reg: LDO28 {
- regulator-name = "VCC_1.8V_LCD_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo29_reg: LDO29 {
- regulator-name = "VT_CAM_2.8V";
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- };
-
- ldo30_reg: LDO30 {
- regulator-name = "TSP_AVDD_3.3V_AP";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo31_reg: LDO31 {
- regulator-name = "TSP_VDD_1.85V_AP";
- regulator-min-microvolt = <1850000>;
- regulator-max-microvolt = <1850000>;
- };
-
- ldo32_reg: LDO32 {
- regulator-name = "VTOUCH_1.8V_AP";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo33_reg: LDO33 {
- regulator-name = "VTOUCH_LED_3.3V";
- regulator-min-microvolt = <2500000>;
- regulator-max-microvolt = <3300000>;
- regulator-ramp-delay = <12500>;
- };
-
- ldo34_reg: LDO34 {
- regulator-name = "VCC_1.8V_MHL_AP";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <2100000>;
- };
-
- ldo35_reg: LDO35 {
- regulator-name = "OIS_VM_2.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- ldo36_reg: LDO36 {
- regulator-name = "VSIL_1.0V";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- };
-
- ldo37_reg: LDO37 {
- regulator-name = "VF_1.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo38_reg: LDO38 {
- regulator-name = "VCC_3.0V_MOTOR_AP";
- regulator-min-microvolt = <3000000>;
- regulator-max-microvolt = <3000000>;
- };
-
- ldo39_reg: LDO39 {
- regulator-name = "V_HRM_1.8V";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo40_reg: LDO40 {
- regulator-name = "V_HRM_3.3V";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- };
-
- buck1_reg: BUCK1 {
- regulator-name = "VDD_MIF_0.9V_AP";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1500000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- buck2_reg: BUCK2 {
- regulator-name = "VDD_EGL_1.0V_AP";
- regulator-min-microvolt = <900000>;
- regulator-max-microvolt = <1300000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- buck3_reg: BUCK3 {
- regulator-name = "VDD_KFC_1.0V_AP";
- regulator-min-microvolt = <800000>;
- regulator-max-microvolt = <1200000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- buck4_reg: BUCK4 {
- regulator-name = "VDD_INT_0.95V_AP";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1500000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- buck5_reg: BUCK5 {
- regulator-name = "VDD_DISP_CAM0_0.9V_AP";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1500000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- buck6_reg: BUCK6 {
- regulator-name = "VDD_G3D_0.9V_AP";
- regulator-min-microvolt = <600000>;
- regulator-max-microvolt = <1500000>;
- regulator-always-on;
- regulator-state-mem {
- regulator-off-in-suspend;
- };
- };
-
- buck7_reg: BUCK7 {
- regulator-name = "VDD_MEM1_1.2V_AP";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-always-on;
- };
-
- buck8_reg: BUCK8 {
- regulator-name = "VDD_LLDO_1.35V_AP";
- regulator-min-microvolt = <1350000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
-
- buck9_reg: BUCK9 {
- regulator-name = "VDD_MLDO_2.0V_AP";
- regulator-min-microvolt = <1350000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- };
-
- buck10_reg: BUCK10 {
- regulator-name = "vdd_mem2";
- regulator-min-microvolt = <550000>;
- regulator-max-microvolt = <1500000>;
- regulator-always-on;
- };
- };
- };
-};
-
-&hsi2c_8 {
- status = "okay";
-
- max77843@66 {
- compatible = "maxim,max77843";
- interrupt-parent = <&gpa1>;
- interrupts = <5 IRQ_TYPE_EDGE_FALLING>;
- reg = <0x66>;
-
- muic: max77843-muic {
- compatible = "maxim,max77843-muic";
- };
-
- regulators {
- compatible = "maxim,max77843-regulator";
- safeout1_reg: SAFEOUT1 {
- regulator-name = "SAFEOUT1";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <4950000>;
- };
-
- safeout2_reg: SAFEOUT2 {
- regulator-name = "SAFEOUT2";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <4950000>;
- };
-
- charger_reg: CHARGER {
- regulator-name = "CHARGER";
- regulator-min-microamp = <100000>;
- regulator-max-microamp = <3150000>;
- };
- };
-
- haptic: max77843-haptic {
- compatible = "maxim,max77843-haptic";
- haptic-supply = <&ldo38_reg>;
- pwms = <&pwm 0 33670 0>;
- pwm-names = "haptic";
- };
- };
-};
-
-&i2s0 {
- status = "okay";
-};
-
-&mshc_0 {
- status = "okay";
- num-slots = <1>;
- mmc-hs200-1_8v;
- mmc-hs400-1_8v;
- cap-mmc-highspeed;
- non-removable;
- card-detect-delay = <200>;
- samsung,dw-mshc-ciu-div = <3>;
- samsung,dw-mshc-sdr-timing = <0 4>;
- samsung,dw-mshc-ddr-timing = <0 2>;
- samsung,dw-mshc-hs400-timing = <0 3>;
- samsung,read-strobe-delay = <90>;
- fifo-depth = <0x80>;
- pinctrl-names = "default";
- pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4
- &sd0_bus8 &sd0_rdqs>;
- bus-width = <8>;
- assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>;
- assigned-clock-rates = <800000000>;
-};
-
-&mshc_2 {
- status = "okay";
- num-slots = <1>;
- cap-sd-highspeed;
- disable-wp;
- cd-gpios = <&gpa2 4 GPIO_ACTIVE_HIGH>;
- cd-inverted;
- card-detect-delay = <200>;
- samsung,dw-mshc-ciu-div = <3>;
- samsung,dw-mshc-sdr-timing = <0 4>;
- samsung,dw-mshc-ddr-timing = <0 2>;
- fifo-depth = <0x80>;
- pinctrl-names = "default";
- pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>;
- bus-width = <4>;
-};
-
-&ppmu_d0_general {
- status = "okay";
- events {
- ppmu_event0_d0_general: ppmu-event0-d0-general {
- event-name = "ppmu-event0-d0-general";
- };
- };
-};
-
-&ppmu_d1_general {
- status = "okay";
- events {
- ppmu_event0_d1_general: ppmu-event0-d1-general {
- event-name = "ppmu-event0-d1-general";
- };
- };
-};
-
-&pinctrl_alive {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_alive>;
-
- initial_alive: initial-state {
- PIN(IN, gpa0-0, DOWN, LV1);
- PIN(IN, gpa0-1, NONE, LV1);
- PIN(IN, gpa0-2, DOWN, LV1);
- PIN(IN, gpa0-3, NONE, LV1);
- PIN(IN, gpa0-4, NONE, LV1);
- PIN(IN, gpa0-5, DOWN, LV1);
- PIN(IN, gpa0-6, NONE, LV1);
- PIN(IN, gpa0-7, NONE, LV1);
-
- PIN(IN, gpa1-0, UP, LV1);
- PIN(IN, gpa1-1, NONE, LV1);
- PIN(IN, gpa1-2, NONE, LV1);
- PIN(IN, gpa1-3, DOWN, LV1);
- PIN(IN, gpa1-4, DOWN, LV1);
- PIN(IN, gpa1-5, NONE, LV1);
- PIN(IN, gpa1-6, NONE, LV1);
- PIN(IN, gpa1-7, NONE, LV1);
-
- PIN(IN, gpa2-0, NONE, LV1);
- PIN(IN, gpa2-1, NONE, LV1);
- PIN(IN, gpa2-2, NONE, LV1);
- PIN(IN, gpa2-3, DOWN, LV1);
- PIN(IN, gpa2-4, NONE, LV1);
- PIN(IN, gpa2-5, DOWN, LV1);
- PIN(IN, gpa2-6, DOWN, LV1);
- PIN(IN, gpa2-7, NONE, LV1);
-
- PIN(IN, gpa3-0, DOWN, LV1);
- PIN(IN, gpa3-1, DOWN, LV1);
- PIN(IN, gpa3-2, NONE, LV1);
- PIN(IN, gpa3-3, DOWN, LV1);
- PIN(IN, gpa3-4, NONE, LV1);
- PIN(IN, gpa3-5, DOWN, LV1);
- PIN(IN, gpa3-6, DOWN, LV1);
- PIN(IN, gpa3-7, DOWN, LV1);
-
- PIN(IN, gpf1-0, NONE, LV1);
- PIN(IN, gpf1-1, NONE, LV1);
- PIN(IN, gpf1-2, DOWN, LV1);
- PIN(IN, gpf1-4, UP, LV1);
- PIN(OUT, gpf1-5, NONE, LV1);
- PIN(IN, gpf1-6, DOWN, LV1);
- PIN(IN, gpf1-7, DOWN, LV1);
-
- PIN(IN, gpf2-0, DOWN, LV1);
- PIN(IN, gpf2-1, DOWN, LV1);
- PIN(IN, gpf2-2, DOWN, LV1);
- PIN(IN, gpf2-3, DOWN, LV1);
-
- PIN(IN, gpf3-0, DOWN, LV1);
- PIN(IN, gpf3-1, DOWN, LV1);
- PIN(IN, gpf3-2, NONE, LV1);
- PIN(IN, gpf3-3, DOWN, LV1);
-
- PIN(IN, gpf4-0, DOWN, LV1);
- PIN(IN, gpf4-1, DOWN, LV1);
- PIN(IN, gpf4-2, DOWN, LV1);
- PIN(IN, gpf4-3, DOWN, LV1);
- PIN(IN, gpf4-4, DOWN, LV1);
- PIN(IN, gpf4-5, DOWN, LV1);
- PIN(IN, gpf4-6, DOWN, LV1);
- PIN(IN, gpf4-7, DOWN, LV1);
-
- PIN(IN, gpf5-0, DOWN, LV1);
- PIN(IN, gpf5-1, DOWN, LV1);
- PIN(IN, gpf5-2, DOWN, LV1);
- PIN(IN, gpf5-3, DOWN, LV1);
- PIN(OUT, gpf5-4, NONE, LV1);
- PIN(IN, gpf5-5, DOWN, LV1);
- PIN(IN, gpf5-6, DOWN, LV1);
- PIN(IN, gpf5-7, DOWN, LV1);
- };
-
- te_irq: te_irq {
- samsung,pins = "gpf1-3";
- samsung,pin-function = <0xf>;
- };
-};
-
-&pinctrl_cpif {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_cpif>;
-
- initial_cpif: initial-state {
- PIN(IN, gpv6-0, DOWN, LV1);
- PIN(IN, gpv6-1, DOWN, LV1);
- };
-};
-
-&pinctrl_ese {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_ese>;
-
- initial_ese: initial-state {
- PIN(IN, gpj2-0, DOWN, LV1);
- PIN(IN, gpj2-1, DOWN, LV1);
- PIN(IN, gpj2-2, DOWN, LV1);
- };
-};
-
-&pinctrl_fsys {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_fsys>;
-
- initial_fsys: initial-state {
- PIN(IN, gpr3-0, NONE, LV1);
- PIN(IN, gpr3-1, DOWN, LV1);
- PIN(IN, gpr3-2, DOWN, LV1);
- PIN(IN, gpr3-3, DOWN, LV1);
- PIN(IN, gpr3-7, NONE, LV1);
- };
-};
-
-&pinctrl_imem {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_imem>;
-
- initial_imem: initial-state {
- PIN(IN, gpf0-0, UP, LV1);
- PIN(IN, gpf0-1, UP, LV1);
- PIN(IN, gpf0-2, DOWN, LV1);
- PIN(IN, gpf0-3, UP, LV1);
- PIN(IN, gpf0-4, DOWN, LV1);
- PIN(IN, gpf0-5, NONE, LV1);
- PIN(IN, gpf0-6, DOWN, LV1);
- PIN(IN, gpf0-7, UP, LV1);
- };
-};
-
-&pinctrl_nfc {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_nfc>;
-
- initial_nfc: initial-state {
- PIN(IN, gpj0-2, DOWN, LV1);
- };
-};
-
-&pinctrl_peric {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_peric>;
-
- initial_peric: initial-state {
- PIN(IN, gpv7-0, DOWN, LV1);
- PIN(IN, gpv7-1, DOWN, LV1);
- PIN(IN, gpv7-2, NONE, LV1);
- PIN(IN, gpv7-3, DOWN, LV1);
- PIN(IN, gpv7-4, DOWN, LV1);
- PIN(IN, gpv7-5, DOWN, LV1);
-
- PIN(IN, gpb0-4, DOWN, LV1);
-
- PIN(IN, gpc0-2, DOWN, LV1);
- PIN(IN, gpc0-5, DOWN, LV1);
- PIN(IN, gpc0-7, DOWN, LV1);
-
- PIN(IN, gpc1-1, DOWN, LV1);
-
- PIN(IN, gpc3-4, NONE, LV1);
- PIN(IN, gpc3-5, NONE, LV1);
- PIN(IN, gpc3-6, NONE, LV1);
- PIN(IN, gpc3-7, NONE, LV1);
-
- PIN(OUT, gpg0-0, NONE, LV1);
- PIN(FUNC1, gpg0-1, DOWN, LV1);
-
- PIN(IN, gpd2-5, DOWN, LV1);
-
- PIN(IN, gpd4-0, NONE, LV1);
- PIN(IN, gpd4-1, DOWN, LV1);
- PIN(IN, gpd4-2, DOWN, LV1);
- PIN(IN, gpd4-3, DOWN, LV1);
- PIN(IN, gpd4-4, DOWN, LV1);
-
- PIN(IN, gpd6-3, DOWN, LV1);
-
- PIN(IN, gpd8-1, UP, LV1);
-
- PIN(IN, gpg1-0, DOWN, LV1);
- PIN(IN, gpg1-1, DOWN, LV1);
- PIN(IN, gpg1-2, DOWN, LV1);
- PIN(IN, gpg1-3, DOWN, LV1);
- PIN(IN, gpg1-4, DOWN, LV1);
-
- PIN(IN, gpg2-0, DOWN, LV1);
- PIN(IN, gpg2-1, DOWN, LV1);
-
- PIN(IN, gpg3-0, DOWN, LV1);
- PIN(IN, gpg3-1, DOWN, LV1);
- PIN(IN, gpg3-5, DOWN, LV1);
- PIN(IN, gpg3-7, DOWN, LV1);
- };
-};
-
-&pinctrl_touch {
- pinctrl-names = "default";
- pinctrl-0 = <&initial_touch>;
-
- initial_touch: initial-state {
- PIN(IN, gpj1-2, DOWN, LV1);
- };
-};
-
-&pwm {
- pinctrl-0 = <&pwm0_out>;
- pinctrl-names = "default";
- status = "okay";
-};
-
-&mic {
- status = "okay";
-
- i80-if-timings {
- };
-};
-
-&pmu_system_controller {
- assigned-clocks = <&pmu_system_controller 0>;
- assigned-clock-parents = <&xxti>;
-};
-
-&serial_1 {
- status = "okay";
-};
-
-&spi_1 {
- cs-gpios = <&gpd6 3 GPIO_ACTIVE_HIGH>;
- status = "okay";
-
- wm5110: wm5110-codec@0 {
- compatible = "wlf,wm5110";
- reg = <0x0>;
- spi-max-frequency = <20000000>;
- interrupt-parent = <&gpa0>;
- interrupts = <4 IRQ_TYPE_NONE>;
- clocks = <&pmu_system_controller 0>,
- <&s2mps13_osc S2MPS11_CLK_BT>;
- clock-names = "mclk1", "mclk2";
-
- gpio-controller;
- #gpio-cells = <2>;
-
- wlf,micd-detect-debounce = <300>;
- wlf,micd-bias-start-time = <0x1>;
- wlf,micd-rate = <0x7>;
- wlf,micd-dbtime = <0x1>;
- wlf,micd-force-micbias;
- wlf,micd-configs = <0x0 1 0>;
- wlf,hpdet-channel = <1>;
- wlf,gpsw = <0x1>;
- wlf,inmode = <2 0 2 0>;
-
- wlf,reset = <&gpc0 7 GPIO_ACTIVE_HIGH>;
- wlf,ldoena = <&gpf0 0 GPIO_ACTIVE_HIGH>;
-
- /* core supplies */
- AVDD-supply = <&ldo18_reg>;
- DBVDD1-supply = <&ldo18_reg>;
- CPVDD-supply = <&ldo18_reg>;
- DBVDD2-supply = <&ldo18_reg>;
- DBVDD3-supply = <&ldo18_reg>;
-
- controller-data {
- samsung,spi-feedback-delay = <0>;
- };
- };
-};
-
-&timer {
- clock-frequency = <24000000>;
-};
-
-&tmu_atlas0 {
- vtmu-supply = <&ldo3_reg>;
- status = "okay";
-};
-
-&tmu_apollo {
- vtmu-supply = <&ldo3_reg>;
- status = "okay";
-};
-
-&tmu_g3d {
- vtmu-supply = <&ldo3_reg>;
- status = "okay";
-};
-
-&usbdrd30 {
- vdd33-supply = <&ldo10_reg>;
- vdd10-supply = <&ldo6_reg>;
- status = "okay";
-};
-
-&usbdrd_dwc3_0 {
- dr_mode = "otg";
-};
-
-&usbdrd30_phy {
- vbus-supply = <&safeout1_reg>;
- status = "okay";
-};
-
-&xxti {
- clock-frequency = <24000000>;
-};
+/*
+ * SAMSUNG Exynos5433 TM2 board device tree source
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Device tree source file for Samsung's TM2 board which is based on
+ * Samsung Exynos5433 SoC.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "exynos5433-tm2-common.dtsi"
+
+/ {
+ model = "Samsung TM2 board";
+ compatible = "samsung,tm2", "samsung,exynos5433";
+};
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
index 1db4e7f..81fdbef 100644
--- a/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
+++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
@@ -11,7 +11,7 @@
* published by the Free Software Foundation.
*/
-#include "exynos5433-tm2.dts"
+#include "exynos5433-tm2-common.dtsi"
/ {
model = "Samsung TM2E board";
--
2.7.4
^ permalink raw reply related
* [PATCH v2 2/4] input: tm2-touchkey: Add touchkey driver support for TM2
From: Jaechul Lee @ 2017-01-05 8:27 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Mark Rutland, Catalin Marinas,
Will Deacon, Kukjin Kim, Krzysztof Kozlowski,
Javier Martinez Canillas
Cc: devicetree, linux-samsung-soc, Jaechul Lee, linux-kernel,
Andi Shyti, Chanwoo Choi, beomho.seo, linux-input, galaxyra,
linux-arm-kernel
In-Reply-To: <1483604833-29746-1-git-send-email-jcsing.lee@samsung.com>
This patch adds support for the TM2 touch key and led
functionality.
The driver interfaces with userspace through an input device and
reports KEY_PHONE and KEY_BACK event types. LED brightness can be
controlled by "/sys/class/leds/tm2-touchkey/brightness".
Signed-off-by: Beomho Seo <beomho.seo@samsung.com>
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Andi Shyti <andi.shyti@samsung.com>
---
drivers/input/keyboard/Kconfig | 11 ++
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/tm2-touchkey.c | 280 ++++++++++++++++++++++++++++++++++
3 files changed, 292 insertions(+)
create mode 100644 drivers/input/keyboard/tm2-touchkey.c
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index cbd75cf..e6e9858 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -666,6 +666,17 @@ config KEYBOARD_TC3589X
To compile this driver as a module, choose M here: the
module will be called tc3589x-keypad.
+config KEYBOARD_TM2_TOUCHKEY
+ tristate "tm2-touchkey support"
+ depends on I2C
+ depends on LEDS_CLASS
+ help
+ Say Y here to enable device driver for tm2-touchkey with
+ LED control for the Exynos5433 TM2 board.
+
+ To compile this driver as a module, choose M here.
+ module will be called tm2-touchkey.
+
config KEYBOARD_TWL4030
tristate "TI TWL4030/TWL5030/TPS659x0 keypad support"
depends on TWL4030_CORE
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile
index d9f4cfc..7d9acff 100644
--- a/drivers/input/keyboard/Makefile
+++ b/drivers/input/keyboard/Makefile
@@ -61,6 +61,7 @@ obj-$(CONFIG_KEYBOARD_SUN4I_LRADC) += sun4i-lradc-keys.o
obj-$(CONFIG_KEYBOARD_SUNKBD) += sunkbd.o
obj-$(CONFIG_KEYBOARD_TC3589X) += tc3589x-keypad.o
obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
+obj-$(CONFIG_KEYBOARD_TM2_TOUCHKEY) += tm2-touchkey.o
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
diff --git a/drivers/input/keyboard/tm2-touchkey.c b/drivers/input/keyboard/tm2-touchkey.c
new file mode 100644
index 0000000..92eacb6
--- /dev/null
+++ b/drivers/input/keyboard/tm2-touchkey.c
@@ -0,0 +1,280 @@
+/*
+ * TM2 touchkey device driver
+ *
+ * Copyright 2005 Phil Blundell
+ * Copyright 2016 Samsung Electronics Co., Ltd.
+ *
+ * Author: Beomho Seo <beomho.seo@samsung.com>
+ * Author: Jaechul Lee <jcsing.lee@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/pm.h>
+#include <linux/regulator/consumer.h>
+
+#define TM2_TOUCHKEY_DEV_NAME "tm2-touchkey"
+#define TM2_TOUCHKEY_KEYCODE_REG 0x03
+#define TM2_TOUCHKEY_BASE_REG 0x00
+#define TM2_TOUCHKEY_CMD_LED_ON 0x10
+#define TM2_TOUCHKEY_CMD_LED_OFF 0x20
+#define TM2_TOUCHKEY_BIT_PRESS_EV BIT(3)
+#define TM2_TOUCHKEY_BIT_KEYCODE GENMASK(2, 0)
+#define TM2_TOUCHKEY_LED_VOLTAGE_MIN 2500000
+#define TM2_TOUCHKEY_LED_VOLTAGE_MAX 3300000
+
+enum {
+ TM2_TOUCHKEY_KEY_MENU = 0x1,
+ TM2_TOUCHKEY_KEY_BACK,
+};
+
+struct tm2_touchkey_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct led_classdev led_dev;
+ struct regulator_bulk_data regulators[2];
+
+ u8 keycode_type;
+ u8 pressed;
+};
+
+static void tm2_touchkey_led_brightness_set(struct led_classdev *led_dev,
+ enum led_brightness brightness)
+{
+ struct tm2_touchkey_data *touchkey =
+ container_of(led_dev, struct tm2_touchkey_data, led_dev);
+ u32 volt;
+ u8 data;
+
+ if (brightness == LED_OFF) {
+ volt = TM2_TOUCHKEY_LED_VOLTAGE_MIN;
+ data = TM2_TOUCHKEY_CMD_LED_OFF;
+ } else {
+ volt = TM2_TOUCHKEY_LED_VOLTAGE_MAX;
+ data = TM2_TOUCHKEY_CMD_LED_ON;
+ }
+
+ regulator_set_voltage(touchkey->regulators[1].consumer, volt, volt);
+ i2c_smbus_write_byte_data(touchkey->client,
+ TM2_TOUCHKEY_BASE_REG, data);
+}
+
+static int tm2_touchkey_power_enable(struct tm2_touchkey_data *touchkey)
+{
+ int ret = 0;
+
+ ret = regulator_bulk_enable(ARRAY_SIZE(touchkey->regulators),
+ touchkey->regulators);
+ if (ret)
+ return ret;
+
+ /* waiting for device initialization, at least 150ms */
+ msleep(150);
+
+ return 0;
+}
+
+static void tm2_touchkey_power_disable(void *data)
+{
+ struct tm2_touchkey_data *touchkey = data;
+
+ regulator_bulk_disable(ARRAY_SIZE(touchkey->regulators),
+ touchkey->regulators);
+}
+
+static irqreturn_t tm2_touchkey_irq_handler(int irq, void *devid)
+{
+ struct tm2_touchkey_data *touchkey = devid;
+ u32 data;
+
+ data = i2c_smbus_read_byte_data(touchkey->client,
+ TM2_TOUCHKEY_KEYCODE_REG);
+
+ if (data < 0) {
+ dev_err(&touchkey->client->dev, "Failed to read i2c data\n");
+ return IRQ_HANDLED;
+ }
+
+ touchkey->keycode_type = data & TM2_TOUCHKEY_BIT_KEYCODE;
+ touchkey->pressed = !(data & TM2_TOUCHKEY_BIT_PRESS_EV);
+
+ if (touchkey->keycode_type != TM2_TOUCHKEY_KEY_MENU &&
+ touchkey->keycode_type != TM2_TOUCHKEY_KEY_BACK) {
+ dev_warn(&touchkey->client->dev, "Skip unhandled keycode(%d)\n",
+ touchkey->keycode_type);
+ return IRQ_HANDLED;
+ }
+
+ if (!touchkey->pressed) {
+ input_report_key(touchkey->input_dev, KEY_PHONE, 0);
+ input_report_key(touchkey->input_dev, KEY_BACK, 0);
+ } else {
+ if (touchkey->keycode_type == TM2_TOUCHKEY_KEY_MENU)
+ input_report_key(touchkey->input_dev,
+ KEY_PHONE, 1);
+ else
+ input_report_key(touchkey->input_dev,
+ KEY_BACK, 1);
+ }
+ input_sync(touchkey->input_dev);
+
+ return IRQ_HANDLED;
+}
+
+static int tm2_touchkey_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct tm2_touchkey_data *touchkey;
+ int ret;
+
+ ret = i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE |
+ I2C_FUNC_SMBUS_BYTE_DATA);
+ if (!ret) {
+ dev_err(&client->dev, "No I2C functionality found\n");
+ return -ENODEV;
+ }
+
+ touchkey = devm_kzalloc(&client->dev, sizeof(*touchkey), GFP_KERNEL);
+ if (!touchkey)
+ return -ENOMEM;
+
+ touchkey->client = client;
+ i2c_set_clientdata(client, touchkey);
+
+ /* regulators */
+ touchkey->regulators[0].supply = "vcc";
+ touchkey->regulators[1].supply = "vdd";
+ ret = devm_regulator_bulk_get(&client->dev,
+ ARRAY_SIZE(touchkey->regulators),
+ touchkey->regulators);
+ if (ret) {
+ dev_err(&client->dev, "Failed to get regulators\n");
+ return ret;
+ }
+
+ /* power */
+ ret = tm2_touchkey_power_enable(touchkey);
+ if (ret) {
+ dev_err(&client->dev, "Failed to enable power\n");
+ return ret;
+ }
+
+ ret = devm_add_action_or_reset(&client->dev,
+ tm2_touchkey_power_disable, touchkey);
+ if (ret)
+ return ret;
+
+ /* input device */
+ touchkey->input_dev = devm_input_allocate_device(&client->dev);
+ if (!touchkey->input_dev) {
+ dev_err(&client->dev, "Failed to alloc input device\n");
+ return -ENOMEM;
+ }
+ touchkey->input_dev->name = TM2_TOUCHKEY_DEV_NAME;
+ touchkey->input_dev->id.bustype = BUS_I2C;
+
+ set_bit(EV_KEY, touchkey->input_dev->evbit);
+ input_set_capability(touchkey->input_dev, EV_KEY, KEY_PHONE);
+ input_set_capability(touchkey->input_dev, EV_KEY, KEY_BACK);
+
+ input_set_drvdata(touchkey->input_dev, touchkey);
+
+ ret = input_register_device(touchkey->input_dev);
+ if (ret) {
+ dev_err(&client->dev, "Failed to register input device\n");
+ return ret;
+ }
+
+ /* irq */
+ ret = devm_request_threaded_irq(&client->dev,
+ client->irq, NULL,
+ tm2_touchkey_irq_handler,
+ IRQF_ONESHOT, TM2_TOUCHKEY_DEV_NAME,
+ touchkey);
+ if (ret) {
+ dev_err(&client->dev, "Failed to request threaded irq\n");
+ return ret;
+ }
+
+ /* led device */
+ touchkey->led_dev.name = TM2_TOUCHKEY_DEV_NAME;
+ touchkey->led_dev.brightness = LED_FULL;
+ touchkey->led_dev.max_brightness = LED_FULL;
+ touchkey->led_dev.brightness_set = tm2_touchkey_led_brightness_set;
+
+ ret = devm_led_classdev_register(&client->dev, &touchkey->led_dev);
+ if (ret < 0) {
+ dev_err(&client->dev, "Failed to register touchkey led\n");
+ return ret;
+ }
+
+ return 0;
+}
+
+static int __maybe_unused tm2_touchkey_suspend(struct device *dev)
+{
+ struct tm2_touchkey_data *touchkey = dev_get_drvdata(dev);
+
+ disable_irq(touchkey->client->irq);
+ tm2_touchkey_power_disable(touchkey);
+
+ return 0;
+}
+
+static int __maybe_unused tm2_touchkey_resume(struct device *dev)
+{
+ struct tm2_touchkey_data *touchkey = dev_get_drvdata(dev);
+ int ret;
+
+ enable_irq(touchkey->client->irq);
+ ret = tm2_touchkey_power_enable(touchkey);
+ if (ret)
+ dev_err(dev, "Failed to enable power\n");
+
+ return ret;
+}
+
+static SIMPLE_DEV_PM_OPS(tm2_touchkey_pm_ops, tm2_touchkey_suspend,
+ tm2_touchkey_resume);
+
+static const struct i2c_device_id tm2_touchkey_id_table[] = {
+ {TM2_TOUCHKEY_DEV_NAME, 0},
+ {},
+};
+MODULE_DEVICE_TABLE(i2c, tm2_touchkey_id_table);
+
+static const struct of_device_id tm2_touchkey_of_match[] = {
+ {.compatible = "samsung,tm2-touchkey",},
+ {},
+};
+MODULE_DEVICE_TABLE(of, tm2_touchkey_of_match);
+
+static struct i2c_driver tm2_touchkey_driver = {
+ .driver = {
+ .name = TM2_TOUCHKEY_DEV_NAME,
+ .pm = &tm2_touchkey_pm_ops,
+ .of_match_table = of_match_ptr(tm2_touchkey_of_match),
+ },
+ .probe = tm2_touchkey_probe,
+ .id_table = tm2_touchkey_id_table,
+};
+
+module_i2c_driver(tm2_touchkey_driver);
+
+MODULE_AUTHOR("Beomho Seo <beomho.seo@samsung.com>");
+MODULE_AUTHOR("Jaechul Lee <jcsing.lee@samsung.com>");
+MODULE_DESCRIPTION("Samsung touchkey driver");
+MODULE_LICENSE("GPL v2");
--
2.7.4
^ permalink raw reply related
* [PATCH v2 1/4] input: Add support for the tm2 touchkey device driver
From: Jaechul Lee @ 2017-01-05 8:27 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Mark Rutland, Catalin Marinas,
Will Deacon, Kukjin Kim, Krzysztof Kozlowski,
Javier Martinez Canillas
Cc: devicetree, linux-samsung-soc, Jaechul Lee, linux-kernel,
Andi Shyti, Chanwoo Choi, beomho.seo, linux-input, galaxyra,
linux-arm-kernel
In-Reply-To: <1483604833-29746-1-git-send-email-jcsing.lee@samsung.com>
This patch adds the binding description of the tm2 touchkey
device driver.
Signed-off-by: Jaechul Lee <jcsing.lee@samsung.com>
Reviewed-by: Javier Martinez Canillas <javier@osg.samsung.com>
Reviewed-by: Andi Shyti <andi.shyti@samsung.com>
Acked-by: Rob Herring <robh@kernel.org>
---
.../bindings/input/samsung,tm2-touchkey.txt | 27 ++++++++++++++++++++++
1 file changed, 27 insertions(+)
create mode 100644 Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
diff --git a/Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt b/Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
new file mode 100644
index 0000000..4de1af0
--- /dev/null
+++ b/Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
@@ -0,0 +1,27 @@
+Samsung tm2-touchkey
+
+Required properties:
+- compatible: must be "samsung,tm2-touchkey"
+- reg: I2C address of the chip.
+- interrupt-parent: a phandle for the interrupt controller (see interrupt
+ binding[0]).
+- interrupts: interrupt to which the chip is connected (see interrupt
+ binding[0]).
+- vcc-supply : internal regulator output. 1.8V
+- vdd-supply : power supply for IC 3.3V
+
+[0]: Documentation/devicetree/bindings/interrupt-controller/interrupts.txt
+
+Example:
+ &i2c0 {
+ /* ... */
+
+ touchkey@20 {
+ compatible = "samsung,tm2-touchkey";
+ reg = <0x20>;
+ interrupt-parent = <&gpa3>;
+ interrupts = <2 IRQ_TYPE_EDGE_FALLING>;
+ vcc-supply=<&ldo32_reg>;
+ vdd-supply=<&ldo33_reg>;
+ };
+ };
--
2.7.4
^ permalink raw reply related
* [PATCH v2 0/4] Add touch key driver support for TM2
From: Jaechul Lee @ 2017-01-05 8:27 UTC (permalink / raw)
To: Dmitry Torokhov, Rob Herring, Mark Rutland, Catalin Marinas,
Will Deacon, Kukjin Kim, Krzysztof Kozlowski,
Javier Martinez Canillas
Cc: Jaechul Lee, Andi Shyti, Chanwoo Choi,
beomho.seo-Sze3O3UU22JBDgjK7y7TUQ,
galaxyra-Re5JQEeQqe8AvxtiuMwx3w,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-input-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-samsung-soc-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <CGME20170105082715epcas1p10e0820a792ba9d89cd165299d6602654@epcas1p1.samsung.com>
Hi,
This patchset adds support for the tm2 touchkey device.
The driver has been ported from Tizen Kernel, originally written
by Beomho. I ported it to the latest mainline Kernel.
The patchset applies on next-20170105.
Changes in v2:
- fixed reviews from Javier, Dmitry
- refactored power enable/disable functions.
- reordered signed-offs in patch 2, while patch 4 is left as it
was as Andi copy pasted the node to the new tm2.dts file
- added Jarvier's (patch 1,2,4) and Krzysztof's (patch 4) reviews
and Rob's Ack
- patch 3 diff has been generated with -B50%
Best Regards,
Jaechul
Andi Shyti (1):
arm64: dts: exynos: make tm2 and tm2e independent from each other
Jaechul Lee (3):
input: Add support for the tm2 touchkey device driver
input: tm2-touchkey: Add touchkey driver support for TM2
arm64: dts: exynos: Add tm2 touchkey node
.../bindings/input/samsung,tm2-touchkey.txt | 27 +
.../boot/dts/exynos/exynos5433-tm2-common.dtsi | 1116 ++++++++++++++++++++
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts | 1105 +------------------
arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts | 2 +-
drivers/input/keyboard/Kconfig | 11 +
drivers/input/keyboard/Makefile | 1 +
drivers/input/keyboard/tm2-touchkey.c | 280 +++++
7 files changed, 1445 insertions(+), 1097 deletions(-)
create mode 100644 Documentation/devicetree/bindings/input/samsung,tm2-touchkey.txt
create mode 100644 arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
create mode 100644 drivers/input/keyboard/tm2-touchkey.c
--
2.7.4
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox