From dc8383a32c75418b8ffd1fc29d77c94d89589711 Mon Sep 17 00:00:00 2001 From: Konstantin Makariev Date: Tue, 17 May 2022 18:35:36 -0500 Subject: [PATCH] drv8424_mmi: relative positions, gpio init and reset Fix for relative positions location. Peek position is farther from Extended than Compact. Init state can be defined in device tree to properly initialize GPIOs. Sensors data check became optionally configurable via device tree property. Change-Id: I7e31801d86e782e1ac7f5bdd3df0ef6cde7b6b0a Signed-off-by: Konstantin Makariev Reviewed-on: https://gerrit.mot.com/2271623 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Sridhar Vashist Reviewed-by: Qing Chang Submit-Approved: Jira Key --- Documentation/devicetree/bindings/drv8424.txt | 63 +++++++++++++ drivers/misc/drv8424/drv8424.c | 88 +++++++++++-------- 2 files changed, 114 insertions(+), 37 deletions(-) create mode 100644 Documentation/devicetree/bindings/drv8424.txt diff --git a/Documentation/devicetree/bindings/drv8424.txt b/Documentation/devicetree/bindings/drv8424.txt new file mode 100644 index 000000000000..37616237b8bf --- /dev/null +++ b/Documentation/devicetree/bindings/drv8424.txt @@ -0,0 +1,63 @@ +DRV8424 stepper motor driver from Texas Instruments + +Motor driver is a platform device. Motorola specific HW layout +allows for the following controllable GPIOs: + + - MOTOR_POWER_EN + - MOTOR_FAULT_INT + - MOTOR_STEP + - MOTOR_DIR + - MOTOR_EN + - MOTOR_SLEEP + - MOTOR_ACTIVE + +There is no kernel configuration option associated with DRV8424 DLKM + +Required properties: + - compatible: only one supported "moto,drv8424" + - drv8424-gpio-cells: number of elements allocated for gpio array in the driver + - MOTOR_POWER_EN-gpio: gpio enabling power to the motor + - MOTOR_FAULT_INT-gpio: gpio used as IRQ to indicate motor fault + - MOTOR_STEP-gpio: gpio used as input for pulse generator + - MOTOR_DIR-gpio: gpio to control motor direction + - MOTOR_EN-gpio: gpio to control drv8424 EN state + - MOTOR_SLEEP-gpio: gpio to control drv8424 SLEEP state + - MOTOR_ACTIVE-gpio: gpio to control hall effect sensor measurements + - pinctrl-names: pinctrl state "drv8424_int_default" required for motor fault IRQ + +Optional properties: + - pinctrl-names: list of pre-defined name (currently only "init_state" supported) + - power-default-off: keep power off when not in use + - support-mode: driver supports MODE0 and MODE1 setup + - support-torque: driver supports T0 and T1 setup + - no-sensors: ignore sensors data (mostly debug option) + +Note: +Only following pinctrl state names are valid!!! + "m0_low", "m0_high", "m0_disable", + "m1_low", "m1_high", "m1_disable", + "t0_low", "t0_high", "t0_disable", + "t1_low", "t1_high", "t1_disable", + "drv8424_int_default", + "drv8424_clk_active", + "drv8424_clk_sleep", + "init_state" + +Example: + + moto_drv8424_support { + compatible = "moto,drv8424"; + drv8424-gpios-cells = <11>; + pinctrl-names = "drv8424_int_default", "init_state"; + pinctrl-0 = <&drv8424_int_default>; + pinctrl-1 = <&drv8424_pwr_en_init &drv8424_step_init &drv8424_dir_init + &drv8424_sleep_init &drv8424_en_init &drv8424_step_init &drv8424_active_init>; + MOTOR_POWER_EN-gpio = <&tlmm 102>; + MOTOR_FAULT_INT-gpio = <&tlmm 112>; + MOTOR_STEP-gpio = <&tlmm 182>; + MOTOR_DIR-gpio = <&tlmm 183>; + MOTOR_SLEEP-gpio = <&tlmm 184>; + MOTOR_ACTIVE-gpio = <&tlmm 185>; + vdd-supply = <&S10B>; + power-default-off; + }; \ No newline at end of file diff --git a/drivers/misc/drv8424/drv8424.c b/drivers/misc/drv8424/drv8424.c index bafe9a8142fd..f0262c2dd03a 100644 --- a/drivers/misc/drv8424/drv8424.c +++ b/drivers/misc/drv8424/drv8424.c @@ -29,8 +29,6 @@ #include #include -#define DRV8424_INIT_DETECTION 1 - #define DEFAULT_STEP_FREQ 2400 #define MOTOR_CLASS_NAME "drv8424" #define MOTOR_CONTROL "control" @@ -39,15 +37,15 @@ #define MOTOR_DEFAULT_EXPIRE 3000 //3000ms timeout -#if defined(DRV8424_INIT_DETECTION) +#if 0 #define MOTOR_DETECT_EXPIRE 600000 //10min timeout #define POLL_INIT_INT 5000 //start polling sensor data in Xms #define POLL_NEXT_INT 1000 -#else +#endif + #define MOTOR_DETECT_EXPIRE 500 //500ms timeout #define POLL_INIT_INT 100 //start polling sensor data in Xms #define POLL_NEXT_INT 50 -#endif #define MOTOR_MODE_SPEED 0 #define MOTOR_MODE_STEP 1 @@ -222,7 +220,7 @@ static const char* const pins_state[] = { enum regime_idx { SQ_FULL, - SQ_SHORTENED, + SQ_PROLONGED, SQ_SHORT, SQ_TINY, SQ_MAX, @@ -231,7 +229,7 @@ enum regime_idx { static const char *regime_names[] = { "FULL", - "SHORTENED", + "PROLONGED", "SHORT", "TINY", "dummy", @@ -250,12 +248,12 @@ typedef struct { } motor_stage; static motor_stage initial_data[SQ_SLOWMO + 1][MAX_STAGE_LEGS] = { - { /* FULL 44mm */ - {400,24}, {1400,56}, {3000,6252}, {2000,12} - }, - { /* SHORTENED 39mm */ + { /* FULL 39mm */ {400,24}, {1400,56}, {3000,5530}, {2000,12} }, + { /* PROLONGED 44mm */ + {400,24}, {1400,56}, {3000,6252}, {2000,12} + }, { /* SHORT 5mm */ {400,24}, {1400,56}, {3000,630}, {2000,12} }, @@ -331,6 +329,7 @@ typedef struct motor_device { bool power_default_off; bool support_mode; bool support_torque; + bool sensors_off; int level:1; unsigned power_en:1; unsigned nsleep:1; @@ -458,6 +457,7 @@ static int set_pinctrl_state(motor_device* md, unsigned state_index) if(state_index >= PINS_END) { dev_err(md->dev, "Illegal pin index\n"); + ret = -EINVAL; goto err; } @@ -665,14 +665,20 @@ static void moto_drv8424_set_sensing(motor_device* md, bool en) { motor_control* mc = &md->mc; + if (md->sensors_off) + return; + if (en) { /* signal sensor hub to start/stop sampling hall effect */ GPIO_OUTPUT_DIR(mc->ptable[MOTOR_ACTIVE], 1); hrtimer_start(&md->timeout_timer, adapt_time_helper(md->time_out), HRTIMER_MODE_REL); moto_drv8424_cmd_push(md, CMD_POLL, msecs_to_jiffies(POLL_INIT_INT)); - /* declare sensor querying stage */ - atomic_set(&md->status, STATUS_QUERYING_POS); - moto_drv8424_cmd_push(md, CMD_STATUS, msecs_to_jiffies(POLL_INIT_INT)); + if (!md->power_en) { + /* declare sensor querying stage when powered off */ + /* when motor powered status will indicate direction */ + atomic_set(&md->status, STATUS_QUERYING_POS); + moto_drv8424_cmd_push(md, CMD_STATUS, msecs_to_jiffies(POLL_INIT_INT)); + } } else { hrtimer_try_to_cancel(&md->timeout_timer); GPIO_OUTPUT_DIR(mc->ptable[MOTOR_ACTIVE], 0); @@ -740,6 +746,8 @@ static void moto_drv8424_set_regime(motor_device *md, unsigned regime) md->max_stages = msn; md->time_out = timeoutMs[regime]; spin_unlock_irqrestore(&md->mlock, flags); + /* TODO: make time out based on sequence duration? */ + md->time_out = MOTOR_DEFAULT_EXPIRE; dev_info(md->dev, "Set active regime: %s, stages # %u\n", regime_names[md->regime], msn); @@ -979,21 +987,21 @@ static void motor_set_motion_params(motor_device *md, int start, int end) if (end == POS_COMPACT) regime = SQ_FULL; else // end == PEEK - regime = SQ_SHORTENED; + regime = SQ_PROLONGED; } else if (start == POS_COMPACT) { - md->dir = DIR_EXTEND; - if (end == POS_EXPANDED) - regime = SQ_FULL; - else // end == PEEK - regime = SQ_SHORT; - } else { // start == PEEK if (end == POS_EXPANDED) { md->dir = DIR_EXTEND; - regime = SQ_SHORTENED; - } else { // end == COMPACT + regime = SQ_FULL; + } else { // end == PEEK md->dir = DIR_WITHDRAW; regime = SQ_SHORT; } + } else { // start == PEEK + md->dir = DIR_EXTEND; + if (end == POS_EXPANDED) + regime = SQ_PROLONGED; + else // end == COMPACT + regime = SQ_SHORT; } moto_drv8424_set_motor_dir(md); @@ -1186,11 +1194,11 @@ static irqreturn_t motor_fault_irq(int irq, void *pdata) if(value) { dev_info(md->dev, "dummy motor irq event\n"); } -#if 0 + md->faulting = true; dev_err(md->dev, "Motor fault irq is happened\n"); moto_drv8424_cmd_push(md, CMD_FAULT, 0); -#endif + return IRQ_HANDLED; } @@ -1847,6 +1855,10 @@ static int moto_drv8424_init_from_dt(motor_device* md) if (md->support_torque) ATTR_ADD(torque); + md->sensors_off = of_property_read_bool(np, "no-sensors"); + if (md->sensors_off) + dev_info(pdev, "Ignore sensors data\n"); + md->power_default_off = of_property_read_bool(np, "power-default-off"); dev_info(pdev, "power is default off: %d\n", md->power_default_off); @@ -1994,18 +2006,20 @@ static int moto_drv8424_probe(struct platform_device *pdev) } RESET_SENSOR_DATA; -#if defined(DRV8424_INIT_DETECTION) - md->time_out = MOTOR_DETECT_EXPIRE; - atomic_set(&md->position, POS_UNKNOWN); - atomic_set(&md->destination, POS_UNKNOWN); - atomic_set(&md->status, STATUS_UNKNOWN); - /* run position detection */ - moto_drv8424_set_sensing(md, true); -#else - md->time_out = MOTOR_DEFAULT_EXPIRE; - atomic_set(&md->position, POS_COMPACT); - atomic_set(&md->status, STATUS_STOPPED_COMPACT); -#endif + if (!md->sensors_off) { + md->time_out = MOTOR_DETECT_EXPIRE; + atomic_set(&md->position, POS_UNKNOWN); + atomic_set(&md->status, STATUS_UNKNOWN); + atomic_set(&md->destination, POS_UNKNOWN); + /* run position detection */ + moto_drv8424_set_sensing(md, true); + } else { + md->time_out = MOTOR_DEFAULT_EXPIRE; + atomic_set(&md->position, POS_COMPACT); + atomic_set(&md->status, STATUS_STOPPED_COMPACT); + dev_info(dev, "Assume COMPACT position\n"); + } + dev_info(dev, "Success init device; running position detection...\n"); return 0;