linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* (no subject)
@ 2012-08-06 16:59 anish kumar
  2012-08-06 17:05 ` Maarten Lankhorst
                   ` (2 more replies)
  0 siblings, 3 replies; 11+ messages in thread
From: anish kumar @ 2012-08-06 16:59 UTC (permalink / raw)
  To: cw00.choi, myungjoo.ham, jic23
  Cc: linux-kernel, linux-iio, anish kumar, anish kumar

From: anish kumar <anish198519851985@gmail.com>

External connector devices that decides connection information based on
ADC values may use adc-jack device driver. The user simply needs to
provide a table of adc range and connection states. Then, extcon
framework will automatically notify others.

Changes in this version:
added Lars-Peter Clausen suggested changes:
Using macros to get rid of boiler plate code such as devm_kzalloc
and module_platform_driver.Other changes suggested are related to
coding guidelines.

Signed-off-by: anish kumar <anish.singh@samsung.com>
Signed-off-by: MyungJoo Ham <myungjoo.ham@samsung.com>
---
 drivers/extcon/Kconfig          |    5 +
 drivers/extcon/Makefile         |    1 +
 drivers/extcon/adc_jack.c       |  193 +++++++++++++++++++++++++++++++++++++++
 include/linux/extcon/adc_jack.h |   77 ++++++++++++++++
 4 files changed, 276 insertions(+), 0 deletions(-)
 create mode 100644 drivers/extcon/adc_jack.c
 create mode 100644 include/linux/extcon/adc_jack.h

diff --git a/drivers/extcon/Kconfig b/drivers/extcon/Kconfig
index e175c8e..596e277 100644
--- a/drivers/extcon/Kconfig
+++ b/drivers/extcon/Kconfig
@@ -21,6 +21,11 @@ config EXTCON_GPIO
 	  Say Y here to enable GPIO based extcon support. Note that GPIO
 	  extcon supports single state per extcon instance.
 
+config EXTCON_ADC_JACK
+        tristate "ADC Jack extcon support"
+        help
+          Say Y here to enable extcon device driver based on ADC values.
+
 config EXTCON_MAX77693
 	tristate "MAX77693 EXTCON Support"
 	depends on MFD_MAX77693
diff --git a/drivers/extcon/Makefile b/drivers/extcon/Makefile
index 88961b3..d95c5ea 100644
--- a/drivers/extcon/Makefile
+++ b/drivers/extcon/Makefile
@@ -4,6 +4,7 @@
 
 obj-$(CONFIG_EXTCON)		+= extcon_class.o
 obj-$(CONFIG_EXTCON_GPIO)	+= extcon_gpio.o
+obj-$(CONFIG_EXTCON_ADC_JACK)   += adc_jack.o
 obj-$(CONFIG_EXTCON_MAX77693)	+= extcon-max77693.o
 obj-$(CONFIG_EXTCON_MAX8997)	+= extcon-max8997.o
 obj-$(CONFIG_EXTCON_ARIZONA)	+= extcon-arizona.o
diff --git a/drivers/extcon/adc_jack.c b/drivers/extcon/adc_jack.c
new file mode 100644
index 0000000..8b80af0
--- /dev/null
+++ b/drivers/extcon/adc_jack.c
@@ -0,0 +1,193 @@
+/*
+ * drivers/extcon/adc_jack.c
+ *
+ * Analog Jack extcon driver with ADC-based detection capability.
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * MyungJoo Ham <myungjoo.ham@samsung.com>
+ *
+ * Modified for calling to IIO to get adc by <anish.singh@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/slab.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/iio/consumer.h>
+#include <linux/extcon/adc_jack.h>
+#include <linux/extcon.h>
+
+/**
+ * struct adc_jack_data - internal data for adc_jack device driver
+ * @edev        - extcon device.
+ * @cable_names - list of supported cables.
+ * @num_cables  - size of cable_names.
+ * @adc_condition       - list of adc value conditions.
+ * @num_condition       - size of adc_condition.
+ * @irq         - irq number of attach/detach event (0 if not exist).
+ * @handling_delay      - interrupt handler will schedule extcon event
+ *                      handling at handling_delay jiffies.
+ * @handler     - extcon event handler called by interrupt handler.
+ * @get_adc     - a callback to get ADC value to identify state.
+ */
+struct adc_jack_data {
+	struct extcon_dev edev;
+
+	const char **cable_names;
+	int num_cables;
+	struct adc_jack_cond *adc_condition;
+	int num_conditions;
+
+	int irq;
+	unsigned long handling_delay; /* in jiffies */
+	struct delayed_work handler;
+
+	struct iio_channel *chan;
+};
+
+static void adc_jack_handler(struct work_struct *work)
+{
+	struct adc_jack_data *data = container_of(to_delayed_work(work),
+						  struct adc_jack_data,
+						  handler);
+	u32 state = 0;
+	int ret, adc_val;
+	int i;
+
+	ret = iio_read_channel_raw(data->chan, &adc_val);
+	if (ret < 0) {
+		dev_err(data->edev.dev, "read channel() error: %d\n", ret);
+		return;
+	}
+
+	/* Get state from adc value with adc_condition */
+	for (i = 0; i < data->num_conditions; i++) {
+		struct adc_jack_cond *def = &data->adc_condition[i];
+		if (!def->state)
+			break;
+		if (def->min_adc <= adc_val && def->max_adc >= adc_val) {
+			state = def->state;
+			break;
+		}
+	}
+	/* if no def has met, it means state = 0 (no cables attached) */
+
+	extcon_set_state(&data->edev, state);
+}
+
+static irqreturn_t adc_jack_irq_thread(int irq, void *_data)
+{
+	struct adc_jack_data *data = _data;
+
+	schedule_delayed_work(&data->handler, data->handling_delay);
+	return IRQ_HANDLED;
+}
+
+static int adc_jack_probe(struct platform_device *pdev)
+{
+	struct adc_jack_data *data;
+	struct adc_jack_pdata *pdata = pdev->dev.platform_data;
+	int i, err = 0;
+
+	data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	data->edev.name = pdata->name;
+
+	if (pdata->cable_names)
+		data->edev.supported_cable = pdata->cable_names;
+	else
+		data->edev.supported_cable = extcon_cable_name;
+
+	/* Check the length of array and set num_cables */
+	for (i = 0; data->edev.supported_cable[i]; i++)
+		;
+	if (i == 0 || i > SUPPORTED_CABLE_MAX) {
+		err = -EINVAL;
+		dev_err(&pdev->dev, "error: pdata->cable_names size = %d\n",
+			i - 1);
+		goto err_alloc;
+	}
+	data->num_cables = i;
+
+	if (!pdata->adc_condition ||
+	    !pdata->adc_condition[0].state) {
+		err = -EINVAL;
+		dev_err(&pdev->dev, "error: adc_condition not defined.\n");
+		goto err_alloc;
+	}
+	data->adc_condition = pdata->adc_condition;
+
+	/* Check the length of array and set num_conditions */
+	for (i = 0; data->adc_condition[i].state; i++)
+		;
+	data->num_conditions = i;
+
+	data->chan = iio_channel_get(dev_name(&pdev->dev),
+						pdata->consumer_channel);
+	if (IS_ERR(data->chan)) {
+		err = PTR_ERR(data->chan);
+		goto err_alloc;
+	}
+
+	data->handling_delay = msecs_to_jiffies(pdata->handling_delay_ms);
+
+	INIT_DELAYED_WORK_DEFERRABLE(&data->handler, adc_jack_handler);
+
+	platform_set_drvdata(pdev, data);
+
+	err = extcon_dev_register(&data->edev, &pdev->dev);
+	if (err)
+		goto err_initwork;
+
+	data->irq = platform_get_irq(pdev, 0);
+
+	err = request_any_context_irq(data->irq, adc_jack_irq_thread,
+				pdata->irq_flags, pdata->name, data);
+
+	if (err) {
+		dev_err(&pdev->dev, "error: irq %d\n", data->irq);
+		err = -EINVAL;
+		goto err_irq;
+	}
+
+	goto out;
+
+err_irq:
+	extcon_dev_unregister(&data->edev);
+err_initwork:
+	cancel_delayed_work_sync(&data->handler);
+err_alloc:
+	kfree(data);
+out:
+	return err;
+}
+
+static int __devexit adc_jack_remove(struct platform_device *pdev)
+{
+	struct adc_jack_data *data = platform_get_drvdata(pdev);
+
+	extcon_dev_unregister(&data->edev);
+	if (data->irq)
+		free_irq(data->irq, data);
+
+	return 0;
+}
+
+static struct platform_driver adc_jack_driver = {
+	.probe		= adc_jack_probe,
+	.remove		= __devexit_p(adc_jack_remove),
+	.driver		= {
+		.name	= "adc-jack",
+		.owner	= THIS_MODULE,
+	},
+};
+
+module_platform_driver(adc_jack_driver);
diff --git a/include/linux/extcon/adc_jack.h b/include/linux/extcon/adc_jack.h
new file mode 100644
index 0000000..ca4d1cd
--- /dev/null
+++ b/include/linux/extcon/adc_jack.h
@@ -0,0 +1,77 @@
+/*
+ * include/linux/extcon/adc_jack.h
+ *
+ * Analog Jack extcon driver with ADC-based detection capability.
+ *
+ * Copyright (C) 2012 Samsung Electronics
+ * MyungJoo Ham <myungjoo.ham@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.
+ *
+ */
+
+#ifndef _EXTCON_ADC_JACK_H_
+#define _EXTCON_ADC_JACK_H_ __FILE__
+
+#include <linux/module.h>
+#include <linux/extcon.h>
+
+/**
+ * struct adc_jack_cond - condition to use an extcon state
+ * @state	- the corresponding extcon state (if 0, this struct denotes
+ *		the last adc_jack_cond element among the array)
+ * @min_adc	- min adc value for this condition
+ * @max_adc	- max adc value for this condition
+ *
+ * For example, if { .state = 0x3, .min_adc = 100, .max_adc = 200}, it means
+ * that if ADC value is between (inclusive) 100 and 200, than the cable 0 and
+ * 1 are attached (1<<0 | 1<<1 == 0x3)
+ *
+ * Note that you don't need to describe condition for "no cable attached"
+ * because when no adc_jack_cond is met, state = 0 is automatically chosen.
+ */
+struct adc_jack_cond {
+	u32 state; /* extcon state value. 0 if invalid */
+	u32 min_adc;
+	u32 max_adc;
+};
+
+/**
+ * struct adc_jack_pdata - platform data for adc jack device.
+ * @name	- name of the extcon device. If null, "adc-jack" is used.
+ * @cable_names	- array of cable names ending with null. If the array itself
+ *		if null, extcon standard cable names are chosen.
+ * @adc_contition	- array of struct adc_jack_cond conditions ending
+ *			with .state = 0 entry. This describes how to decode
+ *			adc values into extcon state.
+ * @irq		- IRQ number that is triggerred by cable attach/detach
+ *		events. If irq = 0, use should manually update extcon state
+ *		with extcon APIs.
+ * @irq_flags	- irq flags used for the @irq
+ * @handling_delay_ms	- in some devices, we need to read ADC value some
+ *			milli-seconds after the interrupt occurs. You may
+ *			describe such delays with @handling_delay_ms, which
+ *			is rounded-off by jiffies.
+ * @get_adc	- the callback to read ADC value to identify cable states.
+ */
+struct adc_jack_pdata {
+	const char *name;
+	const char *consumer_channel;
+	/*
+	 * NULL if standard extcon names are used.
+	 * The last entry should be NULL
+	 */
+	const char **cable_names;
+	/* The last entry's state should be 0 */
+	struct adc_jack_cond *adc_condition;
+
+	unsigned long irq_flags;
+	unsigned long handling_delay_ms; /* in ms */
+
+	/* When we have ADC subsystem, this can be generalized. */
+	int (*get_adc)(u32 *value);
+};
+
+#endif /* _EXTCON_ADC_JACK_H */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 11+ messages in thread
* (no subject)
@ 2015-02-28 11:21 Jonathan Cameron
  2015-02-28 11:22 ` Jonathan Cameron
  0 siblings, 1 reply; 11+ messages in thread
From: Jonathan Cameron @ 2015-02-28 11:21 UTC (permalink / raw)
  To: Greg KH, linux-iio@vger.kernel.org

The following changes since commit 8ecb55b849b74dff026681b41266970072b207dd:

  Merge tag 'iio-fixes-for-3.19a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-linus (2015-01-08 17:59:04 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git tags/iio-fixes-for-4.0a

for you to fetch changes up to e01becbad300712a28f29b666e685536f45e83bc:

  IIO: si7020: Allocate correct amount of memory in devm_iio_device_alloc (2015-02-14 11:35:12 +0000)

----------------------------------------------------------------
First round of fixes for IIO in the 4.0 cycle. Note a followup
set dependent on patches in the recent merge windows will follow shortly.

* dht11 - fix a read off the end of an array, add some locking to prevent
          the read function being interrupted and make sure gpio/irq lines
	  are not enabled for irqs during output.
* iadc - timeout should be in jiffies not msecs
* mpu6050 - avoid a null id from ACPI emumeration being dereferenced.
* mxs-lradc - fix up some interaction issues between the touchscreen driver
              and iio driver.  Mostly about making sure that the adc driver
              only affects channels that are not being used for the
              touchscreen.
* ad2s1200 - sign extension fix for a result of c type promotion.
* adis16400 - sign extension fix for a result of c type promotion.
* mcp3422 - scale table was transposed.
* ad5686 - use _optional regulator get to avoid a dummy reg being allocate
           which would cause the driver to fail to initialize.
* gp2ap020a00f - select REGMAP_I2C
* si7020 - revert an incorrect cleanup up and then fix the issue that made
           that cleanup seem like a good idea.

----------------------------------------------------------------
Andrey Smirnov (1):
      IIO: si7020: Allocate correct amount of memory in devm_iio_device_alloc

Angelo Compagnucci (1):
      iio:adc:mcp3422 Fix incorrect scales table

Jonathan Cameron (1):
      Revert "iio:humidity:si7020: fix pointer to i2c client"

Kristina Martšenko (4):
      iio: mxs-lradc: separate touchscreen and buffer virtual channels
      iio: mxs-lradc: make ADC reads not disable touchscreen interrupts
      iio: mxs-lradc: make ADC reads not unschedule touchscreen conversions
      iio: mxs-lradc: only update the buffer when its conversions have finished

Nicholas Mc Guire (1):
      iio: iadc: wait_for_completion_timeout time in jiffies

Rasmus Villemoes (2):
      staging: iio: ad2s1200: Fix sign extension
      iio: imu: adis16400: Fix sign extension

Richard Weinberger (3):
      iio: dht11: Fix out-of-bounds read
      iio: dht11: Add locking
      iio: dht11: IRQ fixes

Roberta Dobrescu (1):
      iio: light: gp2ap020a00f: Select REGMAP_I2C

Srinivas Pandruvada (1):
      iio: imu: inv_mpu6050: Prevent dereferencing NULL

Stefan Wahren (1):
      iio: mxs-lradc: fix iio channel map regression

Urs Fässler (1):
      iio: ad5686: fix optional reference voltage declaration

 drivers/iio/adc/mcp3422.c                  |  17 +--
 drivers/iio/adc/qcom-spmi-iadc.c           |   3 +-
 drivers/iio/dac/ad5686.c                   |   2 +-
 drivers/iio/humidity/dht11.c               |  69 ++++++----
 drivers/iio/humidity/si7020.c              |   6 +-
 drivers/iio/imu/adis16400_core.c           |   3 +-
 drivers/iio/imu/inv_mpu6050/inv_mpu_core.c |   6 +-
 drivers/iio/light/Kconfig                  |   1 +
 drivers/staging/iio/adc/mxs-lradc.c        | 207 +++++++++++++++--------------
 drivers/staging/iio/resolver/ad2s1200.c    |   3 +-
 10 files changed, 166 insertions(+), 151 deletions(-)

^ permalink raw reply	[flat|nested] 11+ messages in thread
[parent not found: <DM5PR19MB165765D43BE979AB51A9897E9EEB0@DM5PR19MB1657.namprd19.prod.outlook.com>]
[parent not found: <CADU64hCr7mshqfBRE2Wp8zf4BHBdJoLLH=VJt2MrHeR+zHOV4w@mail.gmail.com>]
* [PATCH] counter: microchip-tcb-capture: Allow shared IRQ for multi-channel TCBs
@ 2025-10-06 10:51 Dharma Balasubiramani
  2025-10-08  7:06 ` Kamel Bouhara
  0 siblings, 1 reply; 11+ messages in thread
From: Dharma Balasubiramani @ 2025-10-06 10:51 UTC (permalink / raw)
  To: Kamel Bouhara, William Breathitt Gray, Bence Csókás
  Cc: linux-arm-kernel, linux-iio, linux-kernel, Dharma Balasubiramani

Mark the interrupt as IRQF_SHARED to permit multiple counter channels to
share the same TCB IRQ line.

Each Timer/Counter Block (TCB) instance shares a single IRQ line among its
three internal channels. When multiple counter channels (e.g., counter@0
and counter@1) within the same TCB are enabled, the second call to
devm_request_irq() fails because the IRQ line is already requested by the
first channel.

Fixes: e5d581396821 ("counter: microchip-tcb-capture: Add IRQ handling")
Signed-off-by: Dharma Balasubiramani <dharma.b@microchip.com>
---
 drivers/counter/microchip-tcb-capture.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/counter/microchip-tcb-capture.c b/drivers/counter/microchip-tcb-capture.c
index 1a299d1f350b..19d457ae4c3b 100644
--- a/drivers/counter/microchip-tcb-capture.c
+++ b/drivers/counter/microchip-tcb-capture.c
@@ -451,7 +451,7 @@ static void mchp_tc_irq_remove(void *ptr)
 static int mchp_tc_irq_enable(struct counter_device *const counter, int irq)
 {
 	struct mchp_tc_data *const priv = counter_priv(counter);
-	int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, 0,
+	int ret = devm_request_irq(counter->parent, irq, mchp_tc_isr, IRQF_SHARED,
 				   dev_name(counter->parent), counter);
 
 	if (ret < 0)

---
base-commit: fd94619c43360eb44d28bd3ef326a4f85c600a07
change-id: 20251006-microchip-tcb-edd8aeae36c4

Best regards,
-- 
Dharma Balasubiramani <dharma.b@microchip.com>


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

end of thread, other threads:[~2025-10-08 20:46 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-06 16:59 anish kumar
2012-08-06 17:05 ` Maarten Lankhorst
2012-08-06 17:06 ` [PATCH V1]Extcon: adc_jack: adc-jack driver to support 3.5 pi or simliar devices anish kumar
2012-08-06 17:45 ` Extcon: " Lars-Peter Clausen
  -- strict thread matches above, loose matches on Subject: below --
2015-02-28 11:21 Jonathan Cameron
2015-02-28 11:22 ` Jonathan Cameron
     [not found] <DM5PR19MB165765D43BE979AB51A9897E9EEB0@DM5PR19MB1657.namprd19.prod.outlook.com>
2019-06-18  9:41 ` Re: Enrico Weigelt, metux IT consult
     [not found] <CADU64hCr7mshqfBRE2Wp8zf4BHBdJoLLH=VJt2MrHeR+zHOV4w@mail.gmail.com>
2025-07-20 18:26 ` >
2025-07-20 19:30   ` David Lechner
2025-07-21  6:52     ` Re: Krzysztof Kozlowski
     [not found]       ` <CADU64hDZeyaCpHXBmSG1rtHjpxmjejT7asK9oGBUMF55eYeh4w@mail.gmail.com>
2025-07-21 14:09         ` Re: David Lechner
2025-07-21  7:52   ` Re: Andy Shevchenko
2025-10-06 10:51 [PATCH] counter: microchip-tcb-capture: Allow shared IRQ for multi-channel TCBs Dharma Balasubiramani
2025-10-08  7:06 ` Kamel Bouhara
2025-10-08 20:46   ` Bence Csókás

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).