counter: Internalize sysfs interface code
[linux-2.6-microblaze.git] / drivers / counter / ti-eqep.c
index 94fe58b..09817c9 100644 (file)
@@ -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[] = {