summaryrefslogtreecommitdiffstats
path: root/drivers/counter/ti-eqep.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-11-04 16:21:47 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2021-11-04 16:21:47 +0100
commit5c904c66ed4e86c31ac7c033b64274cebed04e0e (patch)
tree769d366c5e61ffa45d5d8a99c61ae9d5ea39a0a0 /drivers/counter/ti-eqep.c
parentMerge tag 'staging-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff)
parentcomedi: dt9812: fix DMA buffers on stack (diff)
downloadlinux-5c904c66ed4e86c31ac7c033b64274cebed04e0e.tar.xz
linux-5c904c66ed4e86c31ac7c033b64274cebed04e0e.zip
Merge tag 'char-misc-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the big set of char and misc and other tiny driver subsystem updates for 5.16-rc1. Loads of things in here, all of which have been in linux-next for a while with no reported problems (except for one called out below.) Included are: - habanana labs driver updates, including dma_buf usage, reviewed and acked by the dma_buf maintainers - iio driver update (going through this tree not staging as they really do not belong going through that tree anymore) - counter driver updates - hwmon driver updates that the counter drivers needed, acked by the hwmon maintainer - xillybus driver updates - binder driver updates - extcon driver updates - dma_buf module namespaces added (will cause a build error in arm64 for allmodconfig, but that change is on its way through the drm tree) - lkdtm driver updates - pvpanic driver updates - phy driver updates - virt acrn and nitr_enclaves driver updates - smaller char and misc driver updates" * tag 'char-misc-5.16-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (386 commits) comedi: dt9812: fix DMA buffers on stack comedi: ni_usb6501: fix NULL-deref in command paths arm64: errata: Enable TRBE workaround for write to out-of-range address arm64: errata: Enable workaround for TRBE overwrite in FILL mode coresight: trbe: Work around write to out of range coresight: trbe: Make sure we have enough space coresight: trbe: Add a helper to determine the minimum buffer size coresight: trbe: Workaround TRBE errata overwrite in FILL mode coresight: trbe: Add infrastructure for Errata handling coresight: trbe: Allow driver to choose a different alignment coresight: trbe: Decouple buffer base from the hardware base coresight: trbe: Add a helper to pad a given buffer area coresight: trbe: Add a helper to calculate the trace generated coresight: trbe: Defer the probe on offline CPUs coresight: trbe: Fix incorrect access of the sink specific data coresight: etm4x: Add ETM PID for Kryo-5XX coresight: trbe: Prohibit trace before disabling TRBE coresight: trbe: End the AUX handle on truncation coresight: trbe: Do not truncate buffer on IRQ coresight: trbe: Fix handling of spurious interrupts ...
Diffstat (limited to 'drivers/counter/ti-eqep.c')
-rw-r--r--drivers/counter/ti-eqep.c180
1 files changed, 98 insertions, 82 deletions
diff --git a/drivers/counter/ti-eqep.c b/drivers/counter/ti-eqep.c
index 94fe58bb3eab..09817c953f9a 100644
--- a/drivers/counter/ti-eqep.c
+++ b/drivers/counter/ti-eqep.c
@@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/types.h>
/* 32-bit registers */
#define QPOSCNT 0x0
@@ -73,19 +74,13 @@ enum {
};
/* Position Counter Input Modes */
-enum {
+enum ti_eqep_count_func {
TI_EQEP_COUNT_FUNC_QUAD_COUNT,
TI_EQEP_COUNT_FUNC_DIR_COUNT,
TI_EQEP_COUNT_FUNC_UP_COUNT,
TI_EQEP_COUNT_FUNC_DOWN_COUNT,
};
-enum {
- TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES,
- TI_EQEP_SYNAPSE_ACTION_RISING_EDGE,
- TI_EQEP_SYNAPSE_ACTION_NONE,
-};
-
struct ti_eqep_cnt {
struct counter_device counter;
struct regmap *regmap32;
@@ -93,7 +88,7 @@ struct ti_eqep_cnt {
};
static int ti_eqep_count_read(struct counter_device *counter,
- struct counter_count *count, unsigned long *val)
+ struct counter_count *count, u64 *val)
{
struct ti_eqep_cnt *priv = counter->priv;
u32 cnt;
@@ -105,7 +100,7 @@ static int ti_eqep_count_read(struct counter_device *counter,
}
static int ti_eqep_count_write(struct counter_device *counter,
- struct counter_count *count, unsigned long val)
+ struct counter_count *count, u64 val)
{
struct ti_eqep_cnt *priv = counter->priv;
u32 max;
@@ -117,64 +112,100 @@ static int ti_eqep_count_write(struct counter_device *counter,
return regmap_write(priv->regmap32, QPOSCNT, val);
}
-static int ti_eqep_function_get(struct counter_device *counter,
- struct counter_count *count, size_t *function)
+static int ti_eqep_function_read(struct counter_device *counter,
+ struct counter_count *count,
+ enum counter_function *function)
{
struct ti_eqep_cnt *priv = counter->priv;
u32 qdecctl;
regmap_read(priv->regmap16, QDECCTL, &qdecctl);
- *function = (qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT;
+
+ switch ((qdecctl & QDECCTL_QSRC) >> QDECCTL_QSRC_SHIFT) {
+ case TI_EQEP_COUNT_FUNC_QUAD_COUNT:
+ *function = COUNTER_FUNCTION_QUADRATURE_X4;
+ break;
+ case TI_EQEP_COUNT_FUNC_DIR_COUNT:
+ *function = COUNTER_FUNCTION_PULSE_DIRECTION;
+ break;
+ case TI_EQEP_COUNT_FUNC_UP_COUNT:
+ *function = COUNTER_FUNCTION_INCREASE;
+ break;
+ case TI_EQEP_COUNT_FUNC_DOWN_COUNT:
+ *function = COUNTER_FUNCTION_DECREASE;
+ break;
+ }
return 0;
}
-static int ti_eqep_function_set(struct counter_device *counter,
- struct counter_count *count, size_t function)
+static int ti_eqep_function_write(struct counter_device *counter,
+ struct counter_count *count,
+ enum counter_function function)
{
struct ti_eqep_cnt *priv = counter->priv;
+ enum ti_eqep_count_func qsrc;
+
+ switch (function) {
+ case COUNTER_FUNCTION_QUADRATURE_X4:
+ qsrc = TI_EQEP_COUNT_FUNC_QUAD_COUNT;
+ break;
+ case COUNTER_FUNCTION_PULSE_DIRECTION:
+ qsrc = TI_EQEP_COUNT_FUNC_DIR_COUNT;
+ break;
+ case COUNTER_FUNCTION_INCREASE:
+ qsrc = TI_EQEP_COUNT_FUNC_UP_COUNT;
+ break;
+ case COUNTER_FUNCTION_DECREASE:
+ qsrc = TI_EQEP_COUNT_FUNC_DOWN_COUNT;
+ break;
+ default:
+ /* should never reach this path */
+ return -EINVAL;
+ }
return regmap_write_bits(priv->regmap16, QDECCTL, QDECCTL_QSRC,
- function << QDECCTL_QSRC_SHIFT);
+ qsrc << QDECCTL_QSRC_SHIFT);
}
-static int ti_eqep_action_get(struct counter_device *counter,
- struct counter_count *count,
- struct counter_synapse *synapse, size_t *action)
+static int ti_eqep_action_read(struct counter_device *counter,
+ struct counter_count *count,
+ struct counter_synapse *synapse,
+ enum counter_synapse_action *action)
{
struct ti_eqep_cnt *priv = counter->priv;
- size_t function;
+ enum counter_function function;
u32 qdecctl;
int err;
- err = ti_eqep_function_get(counter, count, &function);
+ err = ti_eqep_function_read(counter, count, &function);
if (err)
return err;
switch (function) {
- case TI_EQEP_COUNT_FUNC_QUAD_COUNT:
+ case COUNTER_FUNCTION_QUADRATURE_X4:
/* In quadrature mode, the rising and falling edge of both
* QEPA and QEPB trigger QCLK.
*/
- *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
+ *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
return 0;
- case TI_EQEP_COUNT_FUNC_DIR_COUNT:
+ case COUNTER_FUNCTION_PULSE_DIRECTION:
/* In direction-count mode only rising edge of QEPA is counted
* and QEPB gives direction.
*/
switch (synapse->signal->id) {
case TI_EQEP_SIGNAL_QEPA:
- *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
+ *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
return 0;
case TI_EQEP_SIGNAL_QEPB:
- *action = TI_EQEP_SYNAPSE_ACTION_NONE;
+ *action = COUNTER_SYNAPSE_ACTION_NONE;
return 0;
default:
/* should never reach this path */
return -EINVAL;
}
- case TI_EQEP_COUNT_FUNC_UP_COUNT:
- case TI_EQEP_COUNT_FUNC_DOWN_COUNT:
+ case COUNTER_FUNCTION_INCREASE:
+ case COUNTER_FUNCTION_DECREASE:
/* In up/down-count modes only QEPA is counted and QEPB is not
* used.
*/
@@ -185,12 +216,12 @@ static int ti_eqep_action_get(struct counter_device *counter,
return err;
if (qdecctl & QDECCTL_XCR)
- *action = TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES;
+ *action = COUNTER_SYNAPSE_ACTION_BOTH_EDGES;
else
- *action = TI_EQEP_SYNAPSE_ACTION_RISING_EDGE;
+ *action = COUNTER_SYNAPSE_ACTION_RISING_EDGE;
return 0;
case TI_EQEP_SIGNAL_QEPB:
- *action = TI_EQEP_SYNAPSE_ACTION_NONE;
+ *action = COUNTER_SYNAPSE_ACTION_NONE;
return 0;
default:
/* should never reach this path */
@@ -205,82 +236,67 @@ static int ti_eqep_action_get(struct counter_device *counter,
static const struct counter_ops ti_eqep_counter_ops = {
.count_read = ti_eqep_count_read,
.count_write = ti_eqep_count_write,
- .function_get = ti_eqep_function_get,
- .function_set = ti_eqep_function_set,
- .action_get = ti_eqep_action_get,
+ .function_read = ti_eqep_function_read,
+ .function_write = ti_eqep_function_write,
+ .action_read = ti_eqep_action_read,
};
-static ssize_t ti_eqep_position_ceiling_read(struct counter_device *counter,
- struct counter_count *count,
- void *ext_priv, char *buf)
+static int ti_eqep_position_ceiling_read(struct counter_device *counter,
+ struct counter_count *count,
+ u64 *ceiling)
{
struct ti_eqep_cnt *priv = counter->priv;
u32 qposmax;
regmap_read(priv->regmap32, QPOSMAX, &qposmax);
- return sprintf(buf, "%u\n", qposmax);
+ *ceiling = qposmax;
+
+ return 0;
}
-static ssize_t ti_eqep_position_ceiling_write(struct counter_device *counter,
- struct counter_count *count,
- void *ext_priv, const char *buf,
- size_t len)
+static int ti_eqep_position_ceiling_write(struct counter_device *counter,
+ struct counter_count *count,
+ u64 ceiling)
{
struct ti_eqep_cnt *priv = counter->priv;
- int err;
- u32 res;
- err = kstrtouint(buf, 0, &res);
- if (err < 0)
- return err;
+ if (ceiling != (u32)ceiling)
+ return -ERANGE;
- regmap_write(priv->regmap32, QPOSMAX, res);
+ regmap_write(priv->regmap32, QPOSMAX, ceiling);
- return len;
+ return 0;
}
-static ssize_t ti_eqep_position_enable_read(struct counter_device *counter,
- struct counter_count *count,
- void *ext_priv, char *buf)
+static int ti_eqep_position_enable_read(struct counter_device *counter,
+ struct counter_count *count, u8 *enable)
{
struct ti_eqep_cnt *priv = counter->priv;
u32 qepctl;
regmap_read(priv->regmap16, QEPCTL, &qepctl);
- return sprintf(buf, "%u\n", !!(qepctl & QEPCTL_PHEN));
+ *enable = !!(qepctl & QEPCTL_PHEN);
+
+ return 0;
}
-static ssize_t ti_eqep_position_enable_write(struct counter_device *counter,
- struct counter_count *count,
- void *ext_priv, const char *buf,
- size_t len)
+static int ti_eqep_position_enable_write(struct counter_device *counter,
+ struct counter_count *count, u8 enable)
{
struct ti_eqep_cnt *priv = counter->priv;
- int err;
- bool res;
-
- err = kstrtobool(buf, &res);
- if (err < 0)
- return err;
- regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, res ? -1 : 0);
+ regmap_write_bits(priv->regmap16, QEPCTL, QEPCTL_PHEN, enable ? -1 : 0);
- return len;
+ return 0;
}
-static struct counter_count_ext ti_eqep_position_ext[] = {
- {
- .name = "ceiling",
- .read = ti_eqep_position_ceiling_read,
- .write = ti_eqep_position_ceiling_write,
- },
- {
- .name = "enable",
- .read = ti_eqep_position_enable_read,
- .write = ti_eqep_position_enable_write,
- },
+static struct counter_comp ti_eqep_position_ext[] = {
+ COUNTER_COMP_CEILING(ti_eqep_position_ceiling_read,
+ ti_eqep_position_ceiling_write),
+ COUNTER_COMP_ENABLE(ti_eqep_position_enable_read,
+ ti_eqep_position_enable_write),
};
static struct counter_signal ti_eqep_signals[] = {
@@ -295,16 +311,16 @@ static struct counter_signal ti_eqep_signals[] = {
};
static const enum counter_function ti_eqep_position_functions[] = {
- [TI_EQEP_COUNT_FUNC_QUAD_COUNT] = COUNTER_FUNCTION_QUADRATURE_X4,
- [TI_EQEP_COUNT_FUNC_DIR_COUNT] = COUNTER_FUNCTION_PULSE_DIRECTION,
- [TI_EQEP_COUNT_FUNC_UP_COUNT] = COUNTER_FUNCTION_INCREASE,
- [TI_EQEP_COUNT_FUNC_DOWN_COUNT] = COUNTER_FUNCTION_DECREASE,
+ COUNTER_FUNCTION_QUADRATURE_X4,
+ COUNTER_FUNCTION_PULSE_DIRECTION,
+ COUNTER_FUNCTION_INCREASE,
+ COUNTER_FUNCTION_DECREASE,
};
static const enum counter_synapse_action ti_eqep_position_synapse_actions[] = {
- [TI_EQEP_SYNAPSE_ACTION_BOTH_EDGES] = COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
- [TI_EQEP_SYNAPSE_ACTION_RISING_EDGE] = COUNTER_SYNAPSE_ACTION_RISING_EDGE,
- [TI_EQEP_SYNAPSE_ACTION_NONE] = COUNTER_SYNAPSE_ACTION_NONE,
+ COUNTER_SYNAPSE_ACTION_BOTH_EDGES,
+ COUNTER_SYNAPSE_ACTION_RISING_EDGE,
+ COUNTER_SYNAPSE_ACTION_NONE,
};
static struct counter_synapse ti_eqep_position_synapses[] = {