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;