All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
@ 2017-05-17 17:13 ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-iio, linux-arm-kernel, Hartley Sweeten, Ryan Mallon
  Cc: Alexander Sverdlin, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler

This series prepares the necessary infrastructure for ADC platform device on
Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device using
IIO subsystem.

Changelog
v4:
  Spelling improvements
  sign_extend32() usage
v3:
  Rebased to the current master
  sizeof(struct foo) -> sizeof(*bar)
v2:
  Added Documentation/iio/ep93xx_adc.txt
  Removed extend_name
  Added timeout to the status polling loop
  Used iio_device_register() instead of devm_iio_device_register()

Alexander Sverdlin (5):
  clk: ep93xx: Implement clk_get_parent()
  clk: ep93xx: Add ADC clock
  ep93xx: Add ADC platform device support to core
  edb93xx: Add ADC platform device
  iio: adc: New driver for Cirrus Logic EP93xx ADC

 Documentation/iio/ep93xx_adc.txt             |  29 +++
 arch/arm/mach-ep93xx/clock.c                 |  14 ++
 arch/arm/mach-ep93xx/core.c                  |  24 +++
 arch/arm/mach-ep93xx/edb93xx.c               |   1 +
 arch/arm/mach-ep93xx/include/mach/platform.h |   1 +
 arch/arm/mach-ep93xx/soc.h                   |   1 +
 drivers/iio/adc/Kconfig                      |  11 ++
 drivers/iio/adc/Makefile                     |   1 +
 drivers/iio/adc/ep93xx_adc.c                 | 255 +++++++++++++++++++++++++++
 9 files changed, 337 insertions(+)
 create mode 100644 Documentation/iio/ep93xx_adc.txt
 create mode 100644 drivers/iio/adc/ep93xx_adc.c

-- 
2.12.2


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
@ 2017-05-17 17:13 ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

This series prepares the necessary infrastructure for ADC platform device on
Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device using
IIO subsystem.

Changelog
v4:
  Spelling improvements
  sign_extend32() usage
v3:
  Rebased to the current master
  sizeof(struct foo) -> sizeof(*bar)
v2:
  Added Documentation/iio/ep93xx_adc.txt
  Removed extend_name
  Added timeout to the status polling loop
  Used iio_device_register() instead of devm_iio_device_register()

Alexander Sverdlin (5):
  clk: ep93xx: Implement clk_get_parent()
  clk: ep93xx: Add ADC clock
  ep93xx: Add ADC platform device support to core
  edb93xx: Add ADC platform device
  iio: adc: New driver for Cirrus Logic EP93xx ADC

 Documentation/iio/ep93xx_adc.txt             |  29 +++
 arch/arm/mach-ep93xx/clock.c                 |  14 ++
 arch/arm/mach-ep93xx/core.c                  |  24 +++
 arch/arm/mach-ep93xx/edb93xx.c               |   1 +
 arch/arm/mach-ep93xx/include/mach/platform.h |   1 +
 arch/arm/mach-ep93xx/soc.h                   |   1 +
 drivers/iio/adc/Kconfig                      |  11 ++
 drivers/iio/adc/Makefile                     |   1 +
 drivers/iio/adc/ep93xx_adc.c                 | 255 +++++++++++++++++++++++++++
 9 files changed, 337 insertions(+)
 create mode 100644 Documentation/iio/ep93xx_adc.txt
 create mode 100644 drivers/iio/adc/ep93xx_adc.c

-- 
2.12.2

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 1/5] clk: ep93xx: Implement clk_get_parent()
  2017-05-17 17:13 ` Alexander Sverdlin
@ 2017-05-17 17:13   ` Alexander Sverdlin
  -1 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-iio, linux-arm-kernel, Hartley Sweeten, Ryan Mallon
  Cc: Alexander Sverdlin, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler

Trivial implementation of clk_get_parent(), but necessary for some drivers,
such as ADC.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/clock.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 39ef3b613912..b9cd9d7da14d 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -475,6 +475,12 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
 
 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
-- 
2.12.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 1/5] clk: ep93xx: Implement clk_get_parent()
@ 2017-05-17 17:13   ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

Trivial implementation of clk_get_parent(), but necessary for some drivers,
such as ADC.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/clock.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 39ef3b613912..b9cd9d7da14d 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -475,6 +475,12 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
 }
 EXPORT_SYMBOL(clk_set_rate);
 
+struct clk *clk_get_parent(struct clk *clk)
+{
+	return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
+
 
 static char fclk_divisors[] = { 1, 2, 4, 8, 16, 1, 1, 1 };
 static char hclk_divisors[] = { 1, 2, 4, 5, 6, 8, 16, 32 };
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 2/5] clk: ep93xx: Add ADC clock
  2017-05-17 17:13 ` Alexander Sverdlin
@ 2017-05-17 17:13   ` Alexander Sverdlin
  -1 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-iio, linux-arm-kernel, Hartley Sweeten, Ryan Mallon
  Cc: Alexander Sverdlin, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler, Alexander Sverdlin

From: Alexander Sverdlin <alexander.sverdlin@gmx.de>

ADC and keypad controller clocks share the same control register, so use the
existing infrastructure to add ADC clock support for Cirrus Logic EP93xx SoCs.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/clock.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index b9cd9d7da14d..425342637e47 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -98,6 +98,13 @@ static struct clk clk_keypad = {
 	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
 	.set_rate	= set_keytchclk_rate,
 };
+static struct clk clk_adc = {
+	.parent		= &clk_xtali,
+	.sw_locked	= 1,
+	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
+	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
+	.set_rate	= set_keytchclk_rate,
+};
 static struct clk clk_spi = {
 	.parent		= &clk_xtali,
 	.rate		= EP93XX_EXT_CLK_RATE,
@@ -214,6 +221,7 @@ static struct clk_lookup clocks[] = {
 	INIT_CK(NULL,			"pll2",		&clk_pll2),
 	INIT_CK("ohci-platform",	NULL,		&clk_usb_host),
 	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
+	INIT_CK("ep93xx-adc",		NULL,		&clk_adc),
 	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
 	INIT_CK("ep93xx-spi.0",		NULL,		&clk_spi),
 	INIT_CK("ep93xx-i2s",		"mclk",		&clk_i2s_mclk),
-- 
2.12.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 2/5] clk: ep93xx: Add ADC clock
@ 2017-05-17 17:13   ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

From: Alexander Sverdlin <alexander.sverdlin@gmx.de>

ADC and keypad controller clocks share the same control register, so use the
existing infrastructure to add ADC clock support for Cirrus Logic EP93xx SoCs.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/clock.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index b9cd9d7da14d..425342637e47 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -98,6 +98,13 @@ static struct clk clk_keypad = {
 	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
 	.set_rate	= set_keytchclk_rate,
 };
+static struct clk clk_adc = {
+	.parent		= &clk_xtali,
+	.sw_locked	= 1,
+	.enable_reg	= EP93XX_SYSCON_KEYTCHCLKDIV,
+	.enable_mask	= EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
+	.set_rate	= set_keytchclk_rate,
+};
 static struct clk clk_spi = {
 	.parent		= &clk_xtali,
 	.rate		= EP93XX_EXT_CLK_RATE,
@@ -214,6 +221,7 @@ static struct clk_lookup clocks[] = {
 	INIT_CK(NULL,			"pll2",		&clk_pll2),
 	INIT_CK("ohci-platform",	NULL,		&clk_usb_host),
 	INIT_CK("ep93xx-keypad",	NULL,		&clk_keypad),
+	INIT_CK("ep93xx-adc",		NULL,		&clk_adc),
 	INIT_CK("ep93xx-fb",		NULL,		&clk_video),
 	INIT_CK("ep93xx-spi.0",		NULL,		&clk_spi),
 	INIT_CK("ep93xx-i2s",		"mclk",		&clk_i2s_mclk),
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 3/5] ep93xx: Add ADC platform device support to core
  2017-05-17 17:13 ` Alexander Sverdlin
@ 2017-05-17 17:13   ` Alexander Sverdlin
  -1 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-iio, linux-arm-kernel, Hartley Sweeten, Ryan Mallon
  Cc: Alexander Sverdlin, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler

Newly provided ep93xx_register_adc() could be used by machine-specific code
to create ADC platform device on Cirrus Logic EP93xx SoC-based machines.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/core.c                  | 24 ++++++++++++++++++++++++
 arch/arm/mach-ep93xx/include/mach/platform.h |  1 +
 arch/arm/mach-ep93xx/soc.h                   |  1 +
 3 files changed, 26 insertions(+)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index c393b1b0310d..f53c61813998 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -821,6 +821,30 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev)
 EXPORT_SYMBOL(ep93xx_ide_release_gpio);
 
 /*************************************************************************
+ * EP93xx ADC
+ *************************************************************************/
+static struct resource ep93xx_adc_resources[] = {
+	DEFINE_RES_MEM(EP93XX_ADC_PHYS_BASE, 0x28),
+	DEFINE_RES_IRQ(IRQ_EP93XX_TOUCH),
+};
+
+static struct platform_device ep93xx_adc_device = {
+	.name		= "ep93xx-adc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(ep93xx_adc_resources),
+	.resource	= ep93xx_adc_resources,
+};
+
+void __init ep93xx_register_adc(void)
+{
+	/* Power up ADC, deactivate Touch Screen Controller */
+	ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_TIN,
+				EP93XX_SYSCON_DEVCFG_ADCPD);
+
+	platform_device_register(&ep93xx_adc_device);
+}
+
+/*************************************************************************
  * EP93xx Security peripheral
  *************************************************************************/
 
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 4c0bbd97f741..db0839691ef5 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -52,6 +52,7 @@ int ep93xx_i2s_acquire(void);
 void ep93xx_i2s_release(void);
 void ep93xx_register_ac97(void);
 void ep93xx_register_ide(void);
+void ep93xx_register_adc(void);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
 void ep93xx_ide_release_gpio(struct platform_device *pdev);
 
diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
index 7bf7ff8beae7..d20e631164cf 100644
--- a/arch/arm/mach-ep93xx/soc.h
+++ b/arch/arm/mach-ep93xx/soc.h
@@ -95,6 +95,7 @@
 #define EP93XX_KEY_MATRIX_PHYS_BASE	EP93XX_APB_PHYS(0x000f0000)
 #define EP93XX_KEY_MATRIX_BASE		EP93XX_APB_IOMEM(0x000f0000)
 
+#define EP93XX_ADC_PHYS_BASE		EP93XX_APB_PHYS(0x00100000)
 #define EP93XX_ADC_BASE			EP93XX_APB_IOMEM(0x00100000)
 #define EP93XX_TOUCHSCREEN_BASE		EP93XX_APB_IOMEM(0x00100000)
 
-- 
2.12.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 3/5] ep93xx: Add ADC platform device support to core
@ 2017-05-17 17:13   ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

Newly provided ep93xx_register_adc() could be used by machine-specific code
to create ADC platform device on Cirrus Logic EP93xx SoC-based machines.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/core.c                  | 24 ++++++++++++++++++++++++
 arch/arm/mach-ep93xx/include/mach/platform.h |  1 +
 arch/arm/mach-ep93xx/soc.h                   |  1 +
 3 files changed, 26 insertions(+)

diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index c393b1b0310d..f53c61813998 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -821,6 +821,30 @@ void ep93xx_ide_release_gpio(struct platform_device *pdev)
 EXPORT_SYMBOL(ep93xx_ide_release_gpio);
 
 /*************************************************************************
+ * EP93xx ADC
+ *************************************************************************/
+static struct resource ep93xx_adc_resources[] = {
+	DEFINE_RES_MEM(EP93XX_ADC_PHYS_BASE, 0x28),
+	DEFINE_RES_IRQ(IRQ_EP93XX_TOUCH),
+};
+
+static struct platform_device ep93xx_adc_device = {
+	.name		= "ep93xx-adc",
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(ep93xx_adc_resources),
+	.resource	= ep93xx_adc_resources,
+};
+
+void __init ep93xx_register_adc(void)
+{
+	/* Power up ADC, deactivate Touch Screen Controller */
+	ep93xx_devcfg_set_clear(EP93XX_SYSCON_DEVCFG_TIN,
+				EP93XX_SYSCON_DEVCFG_ADCPD);
+
+	platform_device_register(&ep93xx_adc_device);
+}
+
+/*************************************************************************
  * EP93xx Security peripheral
  *************************************************************************/
 
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 4c0bbd97f741..db0839691ef5 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -52,6 +52,7 @@ int ep93xx_i2s_acquire(void);
 void ep93xx_i2s_release(void);
 void ep93xx_register_ac97(void);
 void ep93xx_register_ide(void);
+void ep93xx_register_adc(void);
 int ep93xx_ide_acquire_gpio(struct platform_device *pdev);
 void ep93xx_ide_release_gpio(struct platform_device *pdev);
 
diff --git a/arch/arm/mach-ep93xx/soc.h b/arch/arm/mach-ep93xx/soc.h
index 7bf7ff8beae7..d20e631164cf 100644
--- a/arch/arm/mach-ep93xx/soc.h
+++ b/arch/arm/mach-ep93xx/soc.h
@@ -95,6 +95,7 @@
 #define EP93XX_KEY_MATRIX_PHYS_BASE	EP93XX_APB_PHYS(0x000f0000)
 #define EP93XX_KEY_MATRIX_BASE		EP93XX_APB_IOMEM(0x000f0000)
 
+#define EP93XX_ADC_PHYS_BASE		EP93XX_APB_PHYS(0x00100000)
 #define EP93XX_ADC_BASE			EP93XX_APB_IOMEM(0x00100000)
 #define EP93XX_TOUCHSCREEN_BASE		EP93XX_APB_IOMEM(0x00100000)
 
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 4/5] edb93xx: Add ADC platform device
  2017-05-17 17:13 ` Alexander Sverdlin
@ 2017-05-17 17:13   ` Alexander Sverdlin
  -1 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-iio, linux-arm-kernel, Hartley Sweeten, Ryan Mallon
  Cc: Alexander Sverdlin, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler

This enables the creation of ADC platform device on EDB93xx series of Cirrus
Logic evaluation boards. The driver for this device must be enabled separately,
either as built-in, or a module.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/edb93xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 0ac176386789..7a7f280b07d7 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -245,6 +245,7 @@ static void __init edb93xx_init_machine(void)
 	edb93xx_register_pwm();
 	edb93xx_register_fb();
 	edb93xx_register_ide();
+	ep93xx_register_adc();
 }
 
 
-- 
2.12.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 4/5] edb93xx: Add ADC platform device
@ 2017-05-17 17:13   ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

This enables the creation of ADC platform device on EDB93xx series of Cirrus
Logic evaluation boards. The driver for this device must be enabled separately,
either as built-in, or a module.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
---
 arch/arm/mach-ep93xx/edb93xx.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/mach-ep93xx/edb93xx.c b/arch/arm/mach-ep93xx/edb93xx.c
index 0ac176386789..7a7f280b07d7 100644
--- a/arch/arm/mach-ep93xx/edb93xx.c
+++ b/arch/arm/mach-ep93xx/edb93xx.c
@@ -245,6 +245,7 @@ static void __init edb93xx_init_machine(void)
 	edb93xx_register_pwm();
 	edb93xx_register_fb();
 	edb93xx_register_ide();
+	ep93xx_register_adc();
 }
 
 
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 5/5] iio: adc: New driver for Cirrus Logic EP93xx ADC
  2017-05-17 17:13 ` Alexander Sverdlin
@ 2017-05-17 17:13   ` Alexander Sverdlin
  -1 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-iio, linux-arm-kernel, Hartley Sweeten, Ryan Mallon
  Cc: Alexander Sverdlin, Jonathan Cameron, Hartmut Knaack,
	Lars-Peter Clausen, Peter Meerwald-Stadler

New driver adding support for ADC found on Cirrus Logic EP93xx series of SoCs.
Board specific code must take care to create plaform device with all necessary
resources.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
---
 Documentation/iio/ep93xx_adc.txt |  29 +++++
 drivers/iio/adc/Kconfig          |  11 ++
 drivers/iio/adc/Makefile         |   1 +
 drivers/iio/adc/ep93xx_adc.c     | 255 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 296 insertions(+)
 create mode 100644 Documentation/iio/ep93xx_adc.txt
 create mode 100644 drivers/iio/adc/ep93xx_adc.c

diff --git a/Documentation/iio/ep93xx_adc.txt b/Documentation/iio/ep93xx_adc.txt
new file mode 100644
index 000000000000..23053e7817bd
--- /dev/null
+++ b/Documentation/iio/ep93xx_adc.txt
@@ -0,0 +1,29 @@
+Cirrus Logic EP93xx ADC driver.
+
+1. Overview
+
+The driver is intended to work on both low-end (EP9301, EP9302) devices with
+5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel
+touchscreen/ADC module.
+
+2. Channel numbering
+
+Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
+EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
+not defined. So the last three are numbered randomly, let's say.
+
+Assuming ep93xx_adc is IIO device0, you'd find the following entries under
+/sys/bus/iio/devices/iio:device0/:
+
+  +-----------------+---------------+
+  | sysfs entry     | ball/pin name |
+  +-----------------+---------------+
+  | in_voltage0_raw | YM            |
+  | in_voltage1_raw | SXP           |
+  | in_voltage2_raw | SXM           |
+  | in_voltage3_raw | SYP           |
+  | in_voltage4_raw | SYM           |
+  | in_voltage5_raw | XP            |
+  | in_voltage6_raw | XM            |
+  | in_voltage7_raw | YP            |
+  +-----------------+---------------+
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 401f47b51d83..a3eba810292a 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -249,6 +249,17 @@ config ENVELOPE_DETECTOR
 	  To compile this driver as a module, choose M here: the module will be
 	  called envelope-detector.
 
+config EP93XX_ADC
+	tristate "Cirrus Logic EP93XX ADC driver"
+	depends on ARCH_EP93XX
+	help
+	  Driver for the ADC module on the EP93XX series of SoC from Cirrus Logic.
+	  It's recommended to switch on CONFIG_HIGH_RES_TIMERS option, in this
+	  case driver will reduce its CPU usage by 90% in some use cases.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ep93xx_adc.
+
 config EXYNOS_ADC
 	tristate "Exynos ADC driver support"
 	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9339bec4babe..d1a036d38486 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
 obj-$(CONFIG_CPCAP_ADC) += cpcap-adc.o
 obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
 obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o
+obj-$(CONFIG_EP93XX_ADC) += ep93xx_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
 obj-$(CONFIG_HI8435) += hi8435.o
diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c
new file mode 100644
index 000000000000..a179ac476c6d
--- /dev/null
+++ b/drivers/iio/adc/ep93xx_adc.c
@@ -0,0 +1,255 @@
+/*
+ * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs
+ *
+ * Copyright (C) 2015 Alexander Sverdlin
+ *
+ * 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 driver uses polling to get the conversion status. According to EP93xx
+ * datasheets, reading ADCResult register starts the conversion, but user is also
+ * responsible for ensuring that delay between adjacent conversion triggers is
+ * long enough so that maximum allowed conversion rate is not exceeded. This
+ * basically renders IRQ mode unusable.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/io.h>
+#include <linux/irqflags.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+/*
+ * This code could benefit from real HR Timers, but jiffy granularity would
+ * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait
+ * in such case.
+ *
+ * HR Timers-based version loads CPU only up to 10% during back to back ADC
+ * conversion, while busy wait-based version consumes whole CPU power.
+ */
+#ifdef CONFIG_HIGH_RES_TIMERS
+#define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax)
+#else
+#define ep93xx_adc_delay(usmin, usmax) udelay(usmin)
+#endif
+
+#define EP93XX_ADC_RESULT	0x08
+#define   EP93XX_ADC_SDR	BIT(31)
+#define EP93XX_ADC_SWITCH	0x18
+#define EP93XX_ADC_SW_LOCK	0x20
+
+struct ep93xx_adc_priv {
+	struct clk *clk;
+	void __iomem *base;
+	int lastch;
+	struct mutex lock;
+};
+
+#define EP93XX_ADC_CH(index, dname, swcfg) {			\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.channel = index,					\
+	.address = swcfg,					\
+	.datasheet_name = dname,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) |	\
+				   BIT(IIO_CHAN_INFO_OFFSET),	\
+}
+
+/*
+ * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
+ * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
+ * not defined. So the last three are numbered randomly, let's say.
+ */
+static const struct iio_chan_spec ep93xx_adc_channels[8] = {
+	EP93XX_ADC_CH(0, "YM",	0x608),
+	EP93XX_ADC_CH(1, "SXP",	0x680),
+	EP93XX_ADC_CH(2, "SXM",	0x640),
+	EP93XX_ADC_CH(3, "SYP",	0x620),
+	EP93XX_ADC_CH(4, "SYM",	0x610),
+	EP93XX_ADC_CH(5, "XP",	0x601),
+	EP93XX_ADC_CH(6, "XM",	0x602),
+	EP93XX_ADC_CH(7, "YP",	0x604),
+};
+
+static int ep93xx_read_raw(struct iio_dev *iiodev,
+			   struct iio_chan_spec const *channel, int *value,
+			   int *shift, long mask)
+{
+	struct ep93xx_adc_priv *priv = iio_priv(iiodev);
+	unsigned long timeout;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&priv->lock);
+		if (priv->lastch != channel->channel) {
+			priv->lastch = channel->channel;
+			/*
+			 * Switch register is software-locked, unlocking must be
+			 * immediately followed by write
+			 */
+			local_irq_disable();
+			writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK);
+			writel_relaxed(channel->address,
+				       priv->base + EP93XX_ADC_SWITCH);
+			local_irq_enable();
+			/*
+			 * Settling delay depends on module clock and could be
+			 * 2ms or 500us
+			 */
+			ep93xx_adc_delay(2000, 2000);
+		}
+		/* Start the conversion, eventually discarding old result */
+		readl_relaxed(priv->base + EP93XX_ADC_RESULT);
+		/* Ensure maximum conversion rate is not exceeded */
+		ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925),
+				 DIV_ROUND_UP(1000000, 925));
+		/* At this point conversion must be completed, but anyway... */
+		ret = IIO_VAL_INT;
+		timeout = jiffies + msecs_to_jiffies(1) + 1;
+		while (1) {
+			u32 t;
+
+			t = readl_relaxed(priv->base + EP93XX_ADC_RESULT);
+			if (t & EP93XX_ADC_SDR) {
+				*value = sign_extend32(t, 15);
+				break;
+			}
+
+			if (time_after(jiffies, timeout)) {
+				dev_err(&iiodev->dev, "Conversion timeout\n");
+				ret = -ETIMEDOUT;
+				break;
+			}
+
+			cpu_relax();
+		}
+		mutex_unlock(&priv->lock);
+		return ret;
+
+	case IIO_CHAN_INFO_OFFSET:
+		/* According to datasheet, range is -25000..25000 */
+		*value = 25000;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		/* Typical supply voltage is 3.3v */
+		*value = (1ULL << 32) * 3300 / 50000;
+		*shift = 32;
+		return IIO_VAL_FRACTIONAL_LOG2;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_info ep93xx_adc_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = ep93xx_read_raw,
+};
+
+static int ep93xx_adc_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct iio_dev *iiodev;
+	struct ep93xx_adc_priv *priv;
+	struct clk *pclk;
+	struct resource *res;
+
+	iiodev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
+	if (!iiodev)
+		return -ENOMEM;
+	priv = iio_priv(iiodev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Cannot obtain memory resource\n");
+		return -ENXIO;
+	}
+	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->base)) {
+		dev_err(&pdev->dev, "Cannot map memory resource\n");
+		return PTR_ERR(priv->base);
+	}
+
+	iiodev->dev.parent = &pdev->dev;
+	iiodev->name = dev_name(&pdev->dev);
+	iiodev->modes = INDIO_DIRECT_MODE;
+	iiodev->info = &ep93xx_adc_info;
+	iiodev->num_channels = ARRAY_SIZE(ep93xx_adc_channels);
+	iiodev->channels = ep93xx_adc_channels;
+
+	priv->lastch = -1;
+	mutex_init(&priv->lock);
+
+	platform_set_drvdata(pdev, iiodev);
+
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(&pdev->dev, "Cannot obtain clock\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	pclk = clk_get_parent(priv->clk);
+	if (!pclk) {
+		dev_warn(&pdev->dev, "Cannot obtain parent clock\n");
+	} else {
+		/*
+		 * This is actually a place for improvement:
+		 * EP93xx ADC supports two clock divisors -- 4 and 16,
+		 * resulting in conversion rates 3750 and 925 samples per second
+		 * with 500us or 2ms settling time respectively.
+		 * One might find this interesting enough to be configurable.
+		 */
+		ret = clk_set_rate(priv->clk, clk_get_rate(pclk) / 16);
+		if (ret)
+			dev_warn(&pdev->dev, "Cannot set clock rate\n");
+		/*
+		 * We can tolerate rate setting failure because the module should
+		 * work in any case.
+		 */
+	}
+
+	ret = clk_enable(priv->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot enable clock\n");
+		return ret;
+	}
+
+	ret = iio_device_register(iiodev);
+	if (ret)
+		clk_disable(priv->clk);
+
+	return ret;
+}
+
+static int ep93xx_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *iiodev = platform_get_drvdata(pdev);
+	struct ep93xx_adc_priv *priv = iio_priv(iiodev);
+
+	iio_device_unregister(iiodev);
+	clk_disable(priv->clk);
+
+	return 0;
+}
+
+static struct platform_driver ep93xx_adc_driver = {
+	.driver = {
+		.name = "ep93xx-adc",
+	},
+	.probe = ep93xx_adc_probe,
+	.remove = ep93xx_adc_remove,
+};
+module_platform_driver(ep93xx_adc_driver);
+
+MODULE_AUTHOR("Alexander Sverdlin <alexander.sverdlin@gmail.com>");
+MODULE_DESCRIPTION("Cirrus Logic EP93XX ADC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ep93xx-adc");
-- 
2.12.2


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v4 5/5] iio: adc: New driver for Cirrus Logic EP93xx ADC
@ 2017-05-17 17:13   ` Alexander Sverdlin
  0 siblings, 0 replies; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-17 17:13 UTC (permalink / raw)
  To: linux-arm-kernel

New driver adding support for ADC found on Cirrus Logic EP93xx series of SoCs.
Board specific code must take care to create plaform device with all necessary
resources.

Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Acked-by: Jonathan Cameron <jic23@kernel.org>
---
 Documentation/iio/ep93xx_adc.txt |  29 +++++
 drivers/iio/adc/Kconfig          |  11 ++
 drivers/iio/adc/Makefile         |   1 +
 drivers/iio/adc/ep93xx_adc.c     | 255 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 296 insertions(+)
 create mode 100644 Documentation/iio/ep93xx_adc.txt
 create mode 100644 drivers/iio/adc/ep93xx_adc.c

diff --git a/Documentation/iio/ep93xx_adc.txt b/Documentation/iio/ep93xx_adc.txt
new file mode 100644
index 000000000000..23053e7817bd
--- /dev/null
+++ b/Documentation/iio/ep93xx_adc.txt
@@ -0,0 +1,29 @@
+Cirrus Logic EP93xx ADC driver.
+
+1. Overview
+
+The driver is intended to work on both low-end (EP9301, EP9302) devices with
+5-channel ADC and high-end (EP9307, EP9312, EP9315) devices with 10-channel
+touchscreen/ADC module.
+
+2. Channel numbering
+
+Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
+EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
+not defined. So the last three are numbered randomly, let's say.
+
+Assuming ep93xx_adc is IIO device0, you'd find the following entries under
+/sys/bus/iio/devices/iio:device0/:
+
+  +-----------------+---------------+
+  | sysfs entry     | ball/pin name |
+  +-----------------+---------------+
+  | in_voltage0_raw | YM            |
+  | in_voltage1_raw | SXP           |
+  | in_voltage2_raw | SXM           |
+  | in_voltage3_raw | SYP           |
+  | in_voltage4_raw | SYM           |
+  | in_voltage5_raw | XP            |
+  | in_voltage6_raw | XM            |
+  | in_voltage7_raw | YP            |
+  +-----------------+---------------+
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
index 401f47b51d83..a3eba810292a 100644
--- a/drivers/iio/adc/Kconfig
+++ b/drivers/iio/adc/Kconfig
@@ -249,6 +249,17 @@ config ENVELOPE_DETECTOR
 	  To compile this driver as a module, choose M here: the module will be
 	  called envelope-detector.
 
+config EP93XX_ADC
+	tristate "Cirrus Logic EP93XX ADC driver"
+	depends on ARCH_EP93XX
+	help
+	  Driver for the ADC module on the EP93XX series of SoC from Cirrus Logic.
+	  It's recommended to switch on CONFIG_HIGH_RES_TIMERS option, in this
+	  case driver will reduce its CPU usage by 90% in some use cases.
+
+	  To compile this driver as a module, choose M here: the module will be
+	  called ep93xx_adc.
+
 config EXYNOS_ADC
 	tristate "Exynos ADC driver support"
 	depends on ARCH_EXYNOS || ARCH_S3C24XX || ARCH_S3C64XX || (OF && COMPILE_TEST)
diff --git a/drivers/iio/adc/Makefile b/drivers/iio/adc/Makefile
index 9339bec4babe..d1a036d38486 100644
--- a/drivers/iio/adc/Makefile
+++ b/drivers/iio/adc/Makefile
@@ -25,6 +25,7 @@ obj-$(CONFIG_CC10001_ADC) += cc10001_adc.o
 obj-$(CONFIG_CPCAP_ADC) += cpcap-adc.o
 obj-$(CONFIG_DA9150_GPADC) += da9150-gpadc.o
 obj-$(CONFIG_ENVELOPE_DETECTOR) += envelope-detector.o
+obj-$(CONFIG_EP93XX_ADC) += ep93xx_adc.o
 obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
 obj-$(CONFIG_FSL_MX25_ADC) += fsl-imx25-gcq.o
 obj-$(CONFIG_HI8435) += hi8435.o
diff --git a/drivers/iio/adc/ep93xx_adc.c b/drivers/iio/adc/ep93xx_adc.c
new file mode 100644
index 000000000000..a179ac476c6d
--- /dev/null
+++ b/drivers/iio/adc/ep93xx_adc.c
@@ -0,0 +1,255 @@
+/*
+ * Driver for ADC module on the Cirrus Logic EP93xx series of SoCs
+ *
+ * Copyright (C) 2015 Alexander Sverdlin
+ *
+ * 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 driver uses polling to get the conversion status. According to EP93xx
+ * datasheets, reading ADCResult register starts the conversion, but user is also
+ * responsible for ensuring that delay between adjacent conversion triggers is
+ * long enough so that maximum allowed conversion rate is not exceeded. This
+ * basically renders IRQ mode unusable.
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/iio/iio.h>
+#include <linux/io.h>
+#include <linux/irqflags.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+
+/*
+ * This code could benefit from real HR Timers, but jiffy granularity would
+ * lower ADC conversion rate down to CONFIG_HZ, so we fallback to busy wait
+ * in such case.
+ *
+ * HR Timers-based version loads CPU only up to 10% during back to back ADC
+ * conversion, while busy wait-based version consumes whole CPU power.
+ */
+#ifdef CONFIG_HIGH_RES_TIMERS
+#define ep93xx_adc_delay(usmin, usmax) usleep_range(usmin, usmax)
+#else
+#define ep93xx_adc_delay(usmin, usmax) udelay(usmin)
+#endif
+
+#define EP93XX_ADC_RESULT	0x08
+#define   EP93XX_ADC_SDR	BIT(31)
+#define EP93XX_ADC_SWITCH	0x18
+#define EP93XX_ADC_SW_LOCK	0x20
+
+struct ep93xx_adc_priv {
+	struct clk *clk;
+	void __iomem *base;
+	int lastch;
+	struct mutex lock;
+};
+
+#define EP93XX_ADC_CH(index, dname, swcfg) {			\
+	.type = IIO_VOLTAGE,					\
+	.indexed = 1,						\
+	.channel = index,					\
+	.address = swcfg,					\
+	.datasheet_name = dname,				\
+	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
+	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) |	\
+				   BIT(IIO_CHAN_INFO_OFFSET),	\
+}
+
+/*
+ * Numbering scheme for channels 0..4 is defined in EP9301 and EP9302 datasheets.
+ * EP9307, EP9312 and EP9312 have 3 channels more (total 8), but the numbering is
+ * not defined. So the last three are numbered randomly, let's say.
+ */
+static const struct iio_chan_spec ep93xx_adc_channels[8] = {
+	EP93XX_ADC_CH(0, "YM",	0x608),
+	EP93XX_ADC_CH(1, "SXP",	0x680),
+	EP93XX_ADC_CH(2, "SXM",	0x640),
+	EP93XX_ADC_CH(3, "SYP",	0x620),
+	EP93XX_ADC_CH(4, "SYM",	0x610),
+	EP93XX_ADC_CH(5, "XP",	0x601),
+	EP93XX_ADC_CH(6, "XM",	0x602),
+	EP93XX_ADC_CH(7, "YP",	0x604),
+};
+
+static int ep93xx_read_raw(struct iio_dev *iiodev,
+			   struct iio_chan_spec const *channel, int *value,
+			   int *shift, long mask)
+{
+	struct ep93xx_adc_priv *priv = iio_priv(iiodev);
+	unsigned long timeout;
+	int ret;
+
+	switch (mask) {
+	case IIO_CHAN_INFO_RAW:
+		mutex_lock(&priv->lock);
+		if (priv->lastch != channel->channel) {
+			priv->lastch = channel->channel;
+			/*
+			 * Switch register is software-locked, unlocking must be
+			 * immediately followed by write
+			 */
+			local_irq_disable();
+			writel_relaxed(0xAA, priv->base + EP93XX_ADC_SW_LOCK);
+			writel_relaxed(channel->address,
+				       priv->base + EP93XX_ADC_SWITCH);
+			local_irq_enable();
+			/*
+			 * Settling delay depends on module clock and could be
+			 * 2ms or 500us
+			 */
+			ep93xx_adc_delay(2000, 2000);
+		}
+		/* Start the conversion, eventually discarding old result */
+		readl_relaxed(priv->base + EP93XX_ADC_RESULT);
+		/* Ensure maximum conversion rate is not exceeded */
+		ep93xx_adc_delay(DIV_ROUND_UP(1000000, 925),
+				 DIV_ROUND_UP(1000000, 925));
+		/* At this point conversion must be completed, but anyway... */
+		ret = IIO_VAL_INT;
+		timeout = jiffies + msecs_to_jiffies(1) + 1;
+		while (1) {
+			u32 t;
+
+			t = readl_relaxed(priv->base + EP93XX_ADC_RESULT);
+			if (t & EP93XX_ADC_SDR) {
+				*value = sign_extend32(t, 15);
+				break;
+			}
+
+			if (time_after(jiffies, timeout)) {
+				dev_err(&iiodev->dev, "Conversion timeout\n");
+				ret = -ETIMEDOUT;
+				break;
+			}
+
+			cpu_relax();
+		}
+		mutex_unlock(&priv->lock);
+		return ret;
+
+	case IIO_CHAN_INFO_OFFSET:
+		/* According to datasheet, range is -25000..25000 */
+		*value = 25000;
+		return IIO_VAL_INT;
+
+	case IIO_CHAN_INFO_SCALE:
+		/* Typical supply voltage is 3.3v */
+		*value = (1ULL << 32) * 3300 / 50000;
+		*shift = 32;
+		return IIO_VAL_FRACTIONAL_LOG2;
+	}
+
+	return -EINVAL;
+}
+
+static const struct iio_info ep93xx_adc_info = {
+	.driver_module = THIS_MODULE,
+	.read_raw = ep93xx_read_raw,
+};
+
+static int ep93xx_adc_probe(struct platform_device *pdev)
+{
+	int ret;
+	struct iio_dev *iiodev;
+	struct ep93xx_adc_priv *priv;
+	struct clk *pclk;
+	struct resource *res;
+
+	iiodev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
+	if (!iiodev)
+		return -ENOMEM;
+	priv = iio_priv(iiodev);
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "Cannot obtain memory resource\n");
+		return -ENXIO;
+	}
+	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(priv->base)) {
+		dev_err(&pdev->dev, "Cannot map memory resource\n");
+		return PTR_ERR(priv->base);
+	}
+
+	iiodev->dev.parent = &pdev->dev;
+	iiodev->name = dev_name(&pdev->dev);
+	iiodev->modes = INDIO_DIRECT_MODE;
+	iiodev->info = &ep93xx_adc_info;
+	iiodev->num_channels = ARRAY_SIZE(ep93xx_adc_channels);
+	iiodev->channels = ep93xx_adc_channels;
+
+	priv->lastch = -1;
+	mutex_init(&priv->lock);
+
+	platform_set_drvdata(pdev, iiodev);
+
+	priv->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(priv->clk)) {
+		dev_err(&pdev->dev, "Cannot obtain clock\n");
+		return PTR_ERR(priv->clk);
+	}
+
+	pclk = clk_get_parent(priv->clk);
+	if (!pclk) {
+		dev_warn(&pdev->dev, "Cannot obtain parent clock\n");
+	} else {
+		/*
+		 * This is actually a place for improvement:
+		 * EP93xx ADC supports two clock divisors -- 4 and 16,
+		 * resulting in conversion rates 3750 and 925 samples per second
+		 * with 500us or 2ms settling time respectively.
+		 * One might find this interesting enough to be configurable.
+		 */
+		ret = clk_set_rate(priv->clk, clk_get_rate(pclk) / 16);
+		if (ret)
+			dev_warn(&pdev->dev, "Cannot set clock rate\n");
+		/*
+		 * We can tolerate rate setting failure because the module should
+		 * work in any case.
+		 */
+	}
+
+	ret = clk_enable(priv->clk);
+	if (ret) {
+		dev_err(&pdev->dev, "Cannot enable clock\n");
+		return ret;
+	}
+
+	ret = iio_device_register(iiodev);
+	if (ret)
+		clk_disable(priv->clk);
+
+	return ret;
+}
+
+static int ep93xx_adc_remove(struct platform_device *pdev)
+{
+	struct iio_dev *iiodev = platform_get_drvdata(pdev);
+	struct ep93xx_adc_priv *priv = iio_priv(iiodev);
+
+	iio_device_unregister(iiodev);
+	clk_disable(priv->clk);
+
+	return 0;
+}
+
+static struct platform_driver ep93xx_adc_driver = {
+	.driver = {
+		.name = "ep93xx-adc",
+	},
+	.probe = ep93xx_adc_probe,
+	.remove = ep93xx_adc_remove,
+};
+module_platform_driver(ep93xx_adc_driver);
+
+MODULE_AUTHOR("Alexander Sverdlin <alexander.sverdlin@gmail.com>");
+MODULE_DESCRIPTION("Cirrus Logic EP93XX ADC driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ep93xx-adc");
-- 
2.12.2

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
  2017-05-17 17:13 ` Alexander Sverdlin
@ 2017-05-21 14:03   ` Jonathan Cameron
  -1 siblings, 0 replies; 20+ messages in thread
From: Jonathan Cameron @ 2017-05-21 14:03 UTC (permalink / raw)
  To: Alexander Sverdlin, linux-iio, linux-arm-kernel, Hartley Sweeten,
	Ryan Mallon
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler

On 17/05/17 18:13, Alexander Sverdlin wrote:
> This series prepares the necessary infrastructure for ADC platform device on
> Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device using
> IIO subsystem.
Hartley, Ryan,

How do you want to handle taking this series forward.
Clearly we have a few arch specific bits and then the driver which
is dependent on some of them.

I'm happy to take the lot through the IIO tree, but will be wanting
a few acks.

I'm interested to note how few implementations there are of clk_get_parent
in tree.  Any comments on that little bit of the code would be
particularly welcome.

Thanks,

Jonathan
> 
> Changelog
> v4:
>    Spelling improvements
>    sign_extend32() usage
> v3:
>    Rebased to the current master
>    sizeof(struct foo) -> sizeof(*bar)
> v2:
>    Added Documentation/iio/ep93xx_adc.txt
>    Removed extend_name
>    Added timeout to the status polling loop
>    Used iio_device_register() instead of devm_iio_device_register()
> 
> Alexander Sverdlin (5):
>    clk: ep93xx: Implement clk_get_parent()
>    clk: ep93xx: Add ADC clock
>    ep93xx: Add ADC platform device support to core
>    edb93xx: Add ADC platform device
>    iio: adc: New driver for Cirrus Logic EP93xx ADC
> 
>   Documentation/iio/ep93xx_adc.txt             |  29 +++
>   arch/arm/mach-ep93xx/clock.c                 |  14 ++
>   arch/arm/mach-ep93xx/core.c                  |  24 +++
>   arch/arm/mach-ep93xx/edb93xx.c               |   1 +
>   arch/arm/mach-ep93xx/include/mach/platform.h |   1 +
>   arch/arm/mach-ep93xx/soc.h                   |   1 +
>   drivers/iio/adc/Kconfig                      |  11 ++
>   drivers/iio/adc/Makefile                     |   1 +
>   drivers/iio/adc/ep93xx_adc.c                 | 255 +++++++++++++++++++++++++++
>   9 files changed, 337 insertions(+)
>   create mode 100644 Documentation/iio/ep93xx_adc.txt
>   create mode 100644 drivers/iio/adc/ep93xx_adc.c
> 


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
@ 2017-05-21 14:03   ` Jonathan Cameron
  0 siblings, 0 replies; 20+ messages in thread
From: Jonathan Cameron @ 2017-05-21 14:03 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/05/17 18:13, Alexander Sverdlin wrote:
> This series prepares the necessary infrastructure for ADC platform device on
> Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device using
> IIO subsystem.
Hartley, Ryan,

How do you want to handle taking this series forward.
Clearly we have a few arch specific bits and then the driver which
is dependent on some of them.

I'm happy to take the lot through the IIO tree, but will be wanting
a few acks.

I'm interested to note how few implementations there are of clk_get_parent
in tree.  Any comments on that little bit of the code would be
particularly welcome.

Thanks,

Jonathan
> 
> Changelog
> v4:
>    Spelling improvements
>    sign_extend32() usage
> v3:
>    Rebased to the current master
>    sizeof(struct foo) -> sizeof(*bar)
> v2:
>    Added Documentation/iio/ep93xx_adc.txt
>    Removed extend_name
>    Added timeout to the status polling loop
>    Used iio_device_register() instead of devm_iio_device_register()
> 
> Alexander Sverdlin (5):
>    clk: ep93xx: Implement clk_get_parent()
>    clk: ep93xx: Add ADC clock
>    ep93xx: Add ADC platform device support to core
>    edb93xx: Add ADC platform device
>    iio: adc: New driver for Cirrus Logic EP93xx ADC
> 
>   Documentation/iio/ep93xx_adc.txt             |  29 +++
>   arch/arm/mach-ep93xx/clock.c                 |  14 ++
>   arch/arm/mach-ep93xx/core.c                  |  24 +++
>   arch/arm/mach-ep93xx/edb93xx.c               |   1 +
>   arch/arm/mach-ep93xx/include/mach/platform.h |   1 +
>   arch/arm/mach-ep93xx/soc.h                   |   1 +
>   drivers/iio/adc/Kconfig                      |  11 ++
>   drivers/iio/adc/Makefile                     |   1 +
>   drivers/iio/adc/ep93xx_adc.c                 | 255 +++++++++++++++++++++++++++
>   9 files changed, 337 insertions(+)
>   create mode 100644 Documentation/iio/ep93xx_adc.txt
>   create mode 100644 drivers/iio/adc/ep93xx_adc.c
> 

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
  2017-05-21 14:03   ` Jonathan Cameron
@ 2017-05-21 20:29     ` Ryan Mallon
  -1 siblings, 0 replies; 20+ messages in thread
From: Ryan Mallon @ 2017-05-21 20:29 UTC (permalink / raw)
  To: Jonathan Cameron, Alexander Sverdlin, linux-iio,
	linux-arm-kernel, Hartley Sweeten
  Cc: Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler

On 22/05/17 00:03, Jonathan Cameron wrote:
> On 17/05/17 18:13, Alexander Sverdlin wrote:
>> This series prepares the necessary infrastructure for ADC platform
>> device on
>> Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device
>> using
>> IIO subsystem.
> Hartley, Ryan,
> 
> How do you want to handle taking this series forward.
> Clearly we have a few arch specific bits and then the driver which
> is dependent on some of them.

I no longer maintain an ep93xx tree because the architecture gets very
few patches now. Patches should go via the arm-soc tree, which is
maintained by (I believe) Arnd and Olaf.

> 
> I'm happy to take the lot through the IIO tree, but will be wanting
> a few acks.

Sure, the series looks fine to me. For the ep93xx specific bits:

Acked-by: Ryan Mallon <rmallon@gmail.com>

> I'm interested to note how few implementations there are of clk_get_parent
> in tree.  Any comments on that little bit of the code would be
> particularly welcome.

The ep93xx architecture is old and obsolete. Because of this, and the
relatively few number of people developing for it and with hardware to
test, it hasn't gotten upgraded to some of the more modern kernel apis
like the common clock framework.

It probably isn't too difficult to move ep93xx to the common clock
framework, but it is a separate change and I don't think Alexander
should have to do it as a prerequisite to getting this adc support merged.

~Ryan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
@ 2017-05-21 20:29     ` Ryan Mallon
  0 siblings, 0 replies; 20+ messages in thread
From: Ryan Mallon @ 2017-05-21 20:29 UTC (permalink / raw)
  To: linux-arm-kernel

On 22/05/17 00:03, Jonathan Cameron wrote:
> On 17/05/17 18:13, Alexander Sverdlin wrote:
>> This series prepares the necessary infrastructure for ADC platform
>> device on
>> Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device
>> using
>> IIO subsystem.
> Hartley, Ryan,
> 
> How do you want to handle taking this series forward.
> Clearly we have a few arch specific bits and then the driver which
> is dependent on some of them.

I no longer maintain an ep93xx tree because the architecture gets very
few patches now. Patches should go via the arm-soc tree, which is
maintained by (I believe) Arnd and Olaf.

> 
> I'm happy to take the lot through the IIO tree, but will be wanting
> a few acks.

Sure, the series looks fine to me. For the ep93xx specific bits:

Acked-by: Ryan Mallon <rmallon@gmail.com>

> I'm interested to note how few implementations there are of clk_get_parent
> in tree.  Any comments on that little bit of the code would be
> particularly welcome.

The ep93xx architecture is old and obsolete. Because of this, and the
relatively few number of people developing for it and with hardware to
test, it hasn't gotten upgraded to some of the more modern kernel apis
like the common clock framework.

It probably isn't too difficult to move ep93xx to the common clock
framework, but it is a separate change and I don't think Alexander
should have to do it as a prerequisite to getting this adc support merged.

~Ryan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
  2017-05-21 20:29     ` Ryan Mallon
  (?)
@ 2017-05-22  5:41     ` Alexander Sverdlin
  2017-05-22  6:51       ` Ryan Mallon
  -1 siblings, 1 reply; 20+ messages in thread
From: Alexander Sverdlin @ 2017-05-22  5:41 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Ryan!

On 21/05/17 22:29, Ryan Mallon wrote:
>> How do you want to handle taking this series forward.
>> Clearly we have a few arch specific bits and then the driver which
>> is dependent on some of them.
> I no longer maintain an ep93xx tree because the architecture gets very
> few patches now. Patches should go via the arm-soc tree, which is
> maintained by (I believe) Arnd and Olaf.

This probably should be reflected in MAINTAINERS file?
Do you want to drop EP93xx maintenance?
In this case I can volunteer myself as a maintainer for the platform.

--
Best regards,
Alexander.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
  2017-05-22  5:41     ` Alexander Sverdlin
@ 2017-05-22  6:51       ` Ryan Mallon
  0 siblings, 0 replies; 20+ messages in thread
From: Ryan Mallon @ 2017-05-22  6:51 UTC (permalink / raw)
  To: linux-arm-kernel



> On 22 May 2017, at 3:41 pm, Alexander Sverdlin <alexander.sverdlin@gmail.com> wrote:
> 
> Hello Ryan!
> 
> On 21/05/17 22:29, Ryan Mallon wrote:
>>> How do you want to handle taking this series forward.
>>> Clearly we have a few arch specific bits and then the driver which
>>> is dependent on some of them.
>> I no longer maintain an ep93xx tree because the architecture gets very
>> few patches now. Patches should go via the arm-soc tree, which is
>> maintained by (I believe) Arnd and Olaf.
> 
> This probably should be reflected in MAINTAINERS file?
> Do you want to drop EP93xx maintenance?
> In this case I can volunteer myself as a maintainer for the platform.

Sure. Sounds good. Send a patch changing the maintainer and I can ack it.

~Ryan

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
  2017-05-21 20:29     ` Ryan Mallon
@ 2017-06-03  9:14       ` Jonathan Cameron
  -1 siblings, 0 replies; 20+ messages in thread
From: Jonathan Cameron @ 2017-06-03  9:14 UTC (permalink / raw)
  To: Ryan Mallon
  Cc: Alexander Sverdlin, linux-iio, linux-arm-kernel, Hartley Sweeten,
	Hartmut Knaack, Lars-Peter Clausen, Peter Meerwald-Stadler,
	linux-arm-kernel

On Mon, 22 May 2017 06:29:08 +1000
Ryan Mallon <rmallon@gmail.com> wrote:

> On 22/05/17 00:03, Jonathan Cameron wrote:
> > On 17/05/17 18:13, Alexander Sverdlin wrote:  
> >> This series prepares the necessary infrastructure for ADC platform
> >> device on
> >> Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device
> >> using
> >> IIO subsystem.  
> > Hartley, Ryan,
> > 
> > How do you want to handle taking this series forward.
> > Clearly we have a few arch specific bits and then the driver which
> > is dependent on some of them.  
> 
> I no longer maintain an ep93xx tree because the architecture gets very
> few patches now. Patches should go via the arm-soc tree, which is
> maintained by (I believe) Arnd and Olaf.
> 
> > 
> > I'm happy to take the lot through the IIO tree, but will be wanting
> > a few acks.  
> 
> Sure, the series looks fine to me. For the ep93xx specific bits:
> 
> Acked-by: Ryan Mallon <rmallon@gmail.com>
> 
> > I'm interested to note how few implementations there are of clk_get_parent
> > in tree.  Any comments on that little bit of the code would be
> > particularly welcome.  
> 
> The ep93xx architecture is old and obsolete. Because of this, and the
> relatively few number of people developing for it and with hardware to
> test, it hasn't gotten upgraded to some of the more modern kernel apis
> like the common clock framework.
> 
> It probably isn't too difficult to move ep93xx to the common clock
> framework, but it is a separate change and I don't think Alexander
> should have to do it as a prerequisite to getting this adc support merged.
Agreed entirely!

Alexander, would you mind reposting the whole series, with
the linux-arm-kernel@lists.infrared.org cc'd.

I've cc'd it to this email to provide a bit of background to
the maintainers, but please add a note to the cover letter
highlighting what Ryan has covered here.

Thanks,

Jonathan

> 
> ~Ryan


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v4 0/5] iio: ADC driver for EP93xx SoC
@ 2017-06-03  9:14       ` Jonathan Cameron
  0 siblings, 0 replies; 20+ messages in thread
From: Jonathan Cameron @ 2017-06-03  9:14 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, 22 May 2017 06:29:08 +1000
Ryan Mallon <rmallon@gmail.com> wrote:

> On 22/05/17 00:03, Jonathan Cameron wrote:
> > On 17/05/17 18:13, Alexander Sverdlin wrote:  
> >> This series prepares the necessary infrastructure for ADC platform
> >> device on
> >> Cirrus Logic EP93xx family of SoCs and adds the driver for ADC device
> >> using
> >> IIO subsystem.  
> > Hartley, Ryan,
> > 
> > How do you want to handle taking this series forward.
> > Clearly we have a few arch specific bits and then the driver which
> > is dependent on some of them.  
> 
> I no longer maintain an ep93xx tree because the architecture gets very
> few patches now. Patches should go via the arm-soc tree, which is
> maintained by (I believe) Arnd and Olaf.
> 
> > 
> > I'm happy to take the lot through the IIO tree, but will be wanting
> > a few acks.  
> 
> Sure, the series looks fine to me. For the ep93xx specific bits:
> 
> Acked-by: Ryan Mallon <rmallon@gmail.com>
> 
> > I'm interested to note how few implementations there are of clk_get_parent
> > in tree.  Any comments on that little bit of the code would be
> > particularly welcome.  
> 
> The ep93xx architecture is old and obsolete. Because of this, and the
> relatively few number of people developing for it and with hardware to
> test, it hasn't gotten upgraded to some of the more modern kernel apis
> like the common clock framework.
> 
> It probably isn't too difficult to move ep93xx to the common clock
> framework, but it is a separate change and I don't think Alexander
> should have to do it as a prerequisite to getting this adc support merged.
Agreed entirely!

Alexander, would you mind reposting the whole series, with
the linux-arm-kernel at lists.infrared.org cc'd.

I've cc'd it to this email to provide a bit of background to
the maintainers, but please add a note to the cover letter
highlighting what Ryan has covered here.

Thanks,

Jonathan

> 
> ~Ryan

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-06-03  9:14 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-17 17:13 [PATCH v4 0/5] iio: ADC driver for EP93xx SoC Alexander Sverdlin
2017-05-17 17:13 ` Alexander Sverdlin
2017-05-17 17:13 ` [PATCH v4 1/5] clk: ep93xx: Implement clk_get_parent() Alexander Sverdlin
2017-05-17 17:13   ` Alexander Sverdlin
2017-05-17 17:13 ` [PATCH v4 2/5] clk: ep93xx: Add ADC clock Alexander Sverdlin
2017-05-17 17:13   ` Alexander Sverdlin
2017-05-17 17:13 ` [PATCH v4 3/5] ep93xx: Add ADC platform device support to core Alexander Sverdlin
2017-05-17 17:13   ` Alexander Sverdlin
2017-05-17 17:13 ` [PATCH v4 4/5] edb93xx: Add ADC platform device Alexander Sverdlin
2017-05-17 17:13   ` Alexander Sverdlin
2017-05-17 17:13 ` [PATCH v4 5/5] iio: adc: New driver for Cirrus Logic EP93xx ADC Alexander Sverdlin
2017-05-17 17:13   ` Alexander Sverdlin
2017-05-21 14:03 ` [PATCH v4 0/5] iio: ADC driver for EP93xx SoC Jonathan Cameron
2017-05-21 14:03   ` Jonathan Cameron
2017-05-21 20:29   ` Ryan Mallon
2017-05-21 20:29     ` Ryan Mallon
2017-05-22  5:41     ` Alexander Sverdlin
2017-05-22  6:51       ` Ryan Mallon
2017-06-03  9:14     ` Jonathan Cameron
2017-06-03  9:14       ` Jonathan Cameron

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.