diff mbox

[v2,2/3] Input: rotary-encoder - move configuration data to driver data

Message ID 1454408678-6011-3-git-send-email-u.kleine-koenig@pengutronix.de (mailing list archive)
State New, archived
Headers show

Commit Message

Uwe Kleine-König Feb. 2, 2016, 10:24 a.m. UTC
This is a preparation for the next patche. There is no change in
behaviour intended.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
---
 drivers/input/misc/rotary_encoder.c | 166 ++++++++++++++++++++----------------
 1 file changed, 94 insertions(+), 72 deletions(-)

Comments

Daniel Mack Feb. 2, 2016, 12:10 p.m. UTC | #1
On 02/02/2016 11:24 AM, Uwe Kleine-König wrote:
> This is a preparation for the next patche. There is no change in
> behaviour intended.

This one looks good to me, but it clashes with Dmitry's latest patch
sets (which I haven't found the time to test yet, sorry!).

> Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>

 Acked-by: Daniel Mack <daniel@zonque.org>




Thanks,
Daniel


> ---
>  drivers/input/misc/rotary_encoder.c | 166 ++++++++++++++++++++----------------
>  1 file changed, 94 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
> index 386bdb5314e6..0582e851993f 100644
> --- a/drivers/input/misc/rotary_encoder.c
> +++ b/drivers/input/misc/rotary_encoder.c
> @@ -32,58 +32,65 @@
>  
>  struct rotary_encoder {
>  	struct input_dev *input;
> -	const struct rotary_encoder_platform_data *pdata;
>  
> +	/* configuration */
> +	unsigned int steps;
>  	unsigned int axis;
> -	unsigned int pos;
> +	unsigned int gpio_a;
> +	unsigned int gpio_b;
> +	unsigned int inverted_a;
> +	unsigned int inverted_b;
> +	unsigned int steps_per_period;
> +	bool relative_axis;
> +	bool rollover;
> +	bool wakeup_source;
>  
>  	unsigned int irq_a;
>  	unsigned int irq_b;
>  
> +	/* state */
> +	unsigned int pos;
>  	bool armed;
>  	unsigned char dir;	/* 0 - clockwise, 1 - CCW */
> -
>  	char last_stable;
>  };
>  
> -static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata)
> +static int rotary_encoder_get_state(const struct rotary_encoder *encoder)
>  {
> -	int a = !!gpio_get_value(pdata->gpio_a);
> -	int b = !!gpio_get_value(pdata->gpio_b);
> +	int a = !!gpio_get_value(encoder->gpio_a);
> +	int b = !!gpio_get_value(encoder->gpio_b);
>  
> -	a ^= pdata->inverted_a;
> -	b ^= pdata->inverted_b;
> +	a ^= encoder->inverted_a;
> +	b ^= encoder->inverted_b;
>  
>  	return ((a << 1) | b);
>  }
>  
>  static void rotary_encoder_report_event(struct rotary_encoder *encoder)
>  {
> -	const struct rotary_encoder_platform_data *pdata = encoder->pdata;
> -
> -	if (pdata->relative_axis) {
> +	if (encoder->relative_axis) {
>  		input_report_rel(encoder->input,
> -				 pdata->axis, encoder->dir ? -1 : 1);
> +				 encoder->axis, encoder->dir ? -1 : 1);
>  	} else {
>  		unsigned int pos = encoder->pos;
>  
>  		if (encoder->dir) {
>  			/* turning counter-clockwise */
> -			if (pdata->rollover)
> -				pos += pdata->steps;
> +			if (encoder->rollover)
> +				pos += encoder->steps;
>  			if (pos)
>  				pos--;
>  		} else {
>  			/* turning clockwise */
> -			if (pdata->rollover || pos < pdata->steps)
> +			if (encoder->rollover || pos < encoder->steps)
>  				pos++;
>  		}
>  
> -		if (pdata->rollover)
> -			pos %= pdata->steps;
> +		if (encoder->rollover)
> +			pos %= encoder->steps;
>  
>  		encoder->pos = pos;
> -		input_report_abs(encoder->input, pdata->axis, encoder->pos);
> +		input_report_abs(encoder->input, encoder->axis, encoder->pos);
>  	}
>  
>  	input_sync(encoder->input);
> @@ -94,7 +101,7 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
>  	struct rotary_encoder *encoder = dev_id;
>  	int state;
>  
> -	state = rotary_encoder_get_state(encoder->pdata);
> +	state = rotary_encoder_get_state(encoder);
>  
>  	switch (state) {
>  	case 0x0:
> @@ -123,7 +130,7 @@ static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
>  	struct rotary_encoder *encoder = dev_id;
>  	int state;
>  
> -	state = rotary_encoder_get_state(encoder->pdata);
> +	state = rotary_encoder_get_state(encoder);
>  
>  	switch (state) {
>  	case 0x00:
> @@ -149,7 +156,7 @@ static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
>  	unsigned char sum;
>  	int state;
>  
> -	state = rotary_encoder_get_state(encoder->pdata);
> +	state = rotary_encoder_get_state(encoder);
>  
>  	/*
>  	 * We encode the previous and the current state using a byte.
> @@ -199,38 +206,34 @@ static const struct of_device_id rotary_encoder_of_match[] = {
>  };
>  MODULE_DEVICE_TABLE(of, rotary_encoder_of_match);
>  
> -static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct device *dev)
> +static int rotary_encoder_parse_dt(struct device *dev,
> +				   struct rotary_encoder *encoder)
>  {
>  	const struct of_device_id *of_id =
>  				of_match_device(rotary_encoder_of_match, dev);
>  	struct device_node *np = dev->of_node;
> -	struct rotary_encoder_platform_data *pdata;
>  	enum of_gpio_flags flags;
>  	int error;
>  
>  	if (!of_id || !np)
> -		return NULL;
> -
> -	pdata = devm_kzalloc(dev, sizeof(struct rotary_encoder_platform_data),
> -			     GFP_KERNEL);
> -	if (!pdata)
> -		return ERR_PTR(-ENOMEM);
> +		return 1;
>  
> -	of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps);
> -	of_property_read_u32(np, "linux,axis", &pdata->axis);
> +	of_property_read_u32(np, "rotary-encoder,steps", &encoder->steps);
> +	of_property_read_u32(np, "linux,axis", &encoder->axis);
>  
> -	pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
> -	pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
> +	encoder->gpio_a = of_get_gpio_flags(np, 0, &flags);
> +	encoder->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
>  
> -	pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
> -	pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
> +	encoder->gpio_b = of_get_gpio_flags(np, 1, &flags);
> +	encoder->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
>  
> -	pdata->relative_axis =
> +	encoder->relative_axis =
>  		of_property_read_bool(np, "rotary-encoder,relative-axis");
> -	pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
> +	encoder->rollover =
> +		of_property_read_bool(np, "rotary-encoder,rollover");
>  
>  	error = of_property_read_u32(np, "rotary-encoder,steps-per-period",
> -				     &pdata->steps_per_period);
> +				     &encoder->steps_per_period);
>  	if (error) {
>  		/*
>  		 * The 'half-period' property has been deprecated, you must use
> @@ -238,45 +241,57 @@ static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
>  		 * need to parse it to maintain compatibility.
>  		 */
>  		if (of_property_read_bool(np, "rotary-encoder,half-period")) {
> -			pdata->steps_per_period = 2;
> +			encoder->steps_per_period = 2;
>  		} else {
>  			/* Fallback to one step per period behavior */
> -			pdata->steps_per_period = 1;
> +			encoder->steps_per_period = 1;
>  		}
>  	}
>  
> -	pdata->wakeup_source = of_property_read_bool(np, "wakeup-source");
> +	encoder->wakeup_source = of_property_read_bool(np, "wakeup-source");
>  
> -	return pdata;
> +	return 0;
>  }
>  #else
> -static inline struct rotary_encoder_platform_data *
> -rotary_encoder_parse_dt(struct device *dev)
> +static inline int rotary_encoder_parse_dt(struct device *dev,
> +					  struct rotary_encoder *encoder)
>  {
> -	return NULL;
> +	return 1;
>  }
>  #endif
>  
> +static int rotary_encoder_parse_pdata(struct device *dev,
> +				      struct rotary_encoder *encoder)
> +{
> +	const struct rotary_encoder_platform_data *pdata;
> +
> +	pdata = dev_get_platdata(dev);
> +	if (!pdata) {
> +		dev_err(dev, "missing platform data\n");
> +		return -EINVAL;
> +	}
> +
> +	encoder->steps = pdata->steps;
> +	encoder->axis = pdata->axis;
> +	encoder->gpio_a = pdata->gpio_a;
> +	encoder->gpio_b = pdata->gpio_b;
> +	encoder->inverted_a = pdata->inverted_a;
> +	encoder->inverted_b = pdata->inverted_b;
> +	encoder->steps_per_period = pdata->steps_per_period;
> +	encoder->relative_axis = pdata->relative_axis;
> +	encoder->rollover = pdata->rollover;
> +
> +	return 0;
> +}
> +
>  static int rotary_encoder_probe(struct platform_device *pdev)
>  {
>  	struct device *dev = &pdev->dev;
> -	const struct rotary_encoder_platform_data *pdata = dev_get_platdata(dev);
>  	struct rotary_encoder *encoder;
>  	struct input_dev *input;
>  	irq_handler_t handler;
>  	int err;
>  
> -	if (!pdata) {
> -		pdata = rotary_encoder_parse_dt(dev);
> -		if (IS_ERR(pdata))
> -			return PTR_ERR(pdata);
> -
> -		if (!pdata) {
> -			dev_err(dev, "missing platform data\n");
> -			return -EINVAL;
> -		}
> -	}
> -
>  	encoder = devm_kzalloc(dev, sizeof(struct rotary_encoder), GFP_KERNEL);
>  	input = devm_input_allocate_device(&pdev->dev);
>  	if (!encoder || !input) {
> @@ -284,55 +299,62 @@ static int rotary_encoder_probe(struct platform_device *pdev)
>  		return -ENOMEM;
>  	}
>  
> +	err = rotary_encoder_parse_dt(dev, encoder);
> +	if (err > 0)
> +		/* not instatiated by dt */
> +		err = rotary_encoder_parse_pdata(dev, encoder);
> +
> +	if (err < 0)
> +		return err;
> +
>  	encoder->input = input;
> -	encoder->pdata = pdata;
>  
>  	input->name = pdev->name;
>  	input->id.bustype = BUS_HOST;
>  	input->dev.parent = dev;
>  
> -	if (pdata->relative_axis) {
> +	if (encoder->relative_axis) {
>  		input->evbit[0] = BIT_MASK(EV_REL);
> -		input->relbit[0] = BIT_MASK(pdata->axis);
> +		input->relbit[0] = BIT_MASK(encoder->axis);
>  	} else {
>  		input->evbit[0] = BIT_MASK(EV_ABS);
>  		input_set_abs_params(encoder->input,
> -				     pdata->axis, 0, pdata->steps, 0, 1);
> +				     encoder->axis, 0, encoder->steps, 0, 1);
>  	}
>  
>  	/* request the GPIOs */
> -	err = devm_gpio_request_one(dev, pdata->gpio_a,
> +	err = devm_gpio_request_one(dev, encoder->gpio_a,
>  				    GPIOF_IN, dev_name(dev));
>  	if (err) {
> -		dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a);
> +		dev_err(dev, "unable to request GPIO %d\n", encoder->gpio_a);
>  		return err;
>  	}
>  
> -	err = devm_gpio_request_one(dev, pdata->gpio_b,
> +	err = devm_gpio_request_one(dev, encoder->gpio_b,
>  				    GPIOF_IN, dev_name(dev));
>  	if (err) {
> -		dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_b);
> +		dev_err(dev, "unable to request GPIO %d\n", encoder->gpio_b);
>  		return err;
>  	}
>  
> -	encoder->irq_a = gpio_to_irq(pdata->gpio_a);
> -	encoder->irq_b = gpio_to_irq(pdata->gpio_b);
> +	encoder->irq_a = gpio_to_irq(encoder->gpio_a);
> +	encoder->irq_b = gpio_to_irq(encoder->gpio_b);
>  
> -	switch (pdata->steps_per_period) {
> +	switch (encoder->steps_per_period) {
>  	case 4:
>  		handler = &rotary_encoder_quarter_period_irq;
> -		encoder->last_stable = rotary_encoder_get_state(pdata);
> +		encoder->last_stable = rotary_encoder_get_state(encoder);
>  		break;
>  	case 2:
>  		handler = &rotary_encoder_half_period_irq;
> -		encoder->last_stable = rotary_encoder_get_state(pdata);
> +		encoder->last_stable = rotary_encoder_get_state(encoder);
>  		break;
>  	case 1:
>  		handler = &rotary_encoder_irq;
>  		break;
>  	default:
>  		dev_err(dev, "'%d' is not a valid steps-per-period value\n",
> -			pdata->steps_per_period);
> +			encoder->steps_per_period);
>  		return -EINVAL;
>  	}
>  
> @@ -358,7 +380,7 @@ static int rotary_encoder_probe(struct platform_device *pdev)
>  		return err;
>  	}
>  
> -	device_init_wakeup(&pdev->dev, pdata->wakeup_source);
> +	device_init_wakeup(&pdev->dev, encoder->wakeup_source);
>  
>  	platform_set_drvdata(pdev, encoder);
>  
>
Uwe Kleine-König Feb. 3, 2016, 9:35 a.m. UTC | #2
Hello,

On Tue, Feb 02, 2016 at 01:10:19PM +0100, Daniel Mack wrote:
> On 02/02/2016 11:24 AM, Uwe Kleine-König wrote:
> > This is a preparation for the next patche. There is no change in
> > behaviour intended.
> 
> This one looks good to me, but it clashes with Dmitry's latest patch
> sets (which I haven't found the time to test yet, sorry!).

There is nothing in next-20160203, so I assume Dmitry either fixes this
up when applying my patches or tells me when I should rebase.

> > Signed-off-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> 
>  Acked-by: Daniel Mack <daniel@zonque.org>

Thanks
Uwe
Dmitry Torokhov Feb. 4, 2016, 9:18 p.m. UTC | #3
On Wed, Feb 03, 2016 at 10:35:27AM +0100, Uwe Kleine-König wrote:
> Hello,
> 
> On Tue, Feb 02, 2016 at 01:10:19PM +0100, Daniel Mack wrote:
> > On 02/02/2016 11:24 AM, Uwe Kleine-König wrote:
> > > This is a preparation for the next patche. There is no change in
> > > behaviour intended.
> > 
> > This one looks good to me, but it clashes with Dmitry's latest patch
> > sets (which I haven't found the time to test yet, sorry!).
> 
> There is nothing in next-20160203, so I assume Dmitry either fixes this
> up when applying my patches or tells me when I should rebase.

Please take a look at my rotary-encoder branch. I am waiting to merge it
into next until I can get some testers. If you have raumfild device that
would be awesome.

Thanks.
Uwe Kleine-König Feb. 5, 2016, 9:05 a.m. UTC | #4
Hello Dmitry,

On Thu, Feb 04, 2016 at 01:18:42PM -0800, Dmitry Torokhov wrote:
> On Wed, Feb 03, 2016 at 10:35:27AM +0100, Uwe Kleine-König wrote:
> > Hello,
> > 
> > On Tue, Feb 02, 2016 at 01:10:19PM +0100, Daniel Mack wrote:
> > > On 02/02/2016 11:24 AM, Uwe Kleine-König wrote:
> > > > This is a preparation for the next patche. There is no change in
> > > > behaviour intended.
> > > 
> > > This one looks good to me, but it clashes with Dmitry's latest patch
> > > sets (which I haven't found the time to test yet, sorry!).
> > 
> > There is nothing in next-20160203, so I assume Dmitry either fixes this
> > up when applying my patches or tells me when I should rebase.
> 
> Please take a look at my rotary-encoder branch. I am waiting to merge it
> into next until I can get some testers. If you have raumfild device that
> would be awesome.

I don't have a raumfeld device. I did a similar conversion and the only
relevant difference is that I used

	.dev_id = "rotary_encoder.0",

while you used

	.dev_id = "rotary-encoder",

in raumfeld_rotary_gpios_table.
I think a mixture of these is the right thing, i.e.

	.dev_id = "rotary-encoder.0",

Your series obsoletes my first two patches, so I will port my third
patch on top of your branch and retest there.

Best regards
Uwe
diff mbox

Patch

diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c
index 386bdb5314e6..0582e851993f 100644
--- a/drivers/input/misc/rotary_encoder.c
+++ b/drivers/input/misc/rotary_encoder.c
@@ -32,58 +32,65 @@ 
 
 struct rotary_encoder {
 	struct input_dev *input;
-	const struct rotary_encoder_platform_data *pdata;
 
+	/* configuration */
+	unsigned int steps;
 	unsigned int axis;
-	unsigned int pos;
+	unsigned int gpio_a;
+	unsigned int gpio_b;
+	unsigned int inverted_a;
+	unsigned int inverted_b;
+	unsigned int steps_per_period;
+	bool relative_axis;
+	bool rollover;
+	bool wakeup_source;
 
 	unsigned int irq_a;
 	unsigned int irq_b;
 
+	/* state */
+	unsigned int pos;
 	bool armed;
 	unsigned char dir;	/* 0 - clockwise, 1 - CCW */
-
 	char last_stable;
 };
 
-static int rotary_encoder_get_state(const struct rotary_encoder_platform_data *pdata)
+static int rotary_encoder_get_state(const struct rotary_encoder *encoder)
 {
-	int a = !!gpio_get_value(pdata->gpio_a);
-	int b = !!gpio_get_value(pdata->gpio_b);
+	int a = !!gpio_get_value(encoder->gpio_a);
+	int b = !!gpio_get_value(encoder->gpio_b);
 
-	a ^= pdata->inverted_a;
-	b ^= pdata->inverted_b;
+	a ^= encoder->inverted_a;
+	b ^= encoder->inverted_b;
 
 	return ((a << 1) | b);
 }
 
 static void rotary_encoder_report_event(struct rotary_encoder *encoder)
 {
-	const struct rotary_encoder_platform_data *pdata = encoder->pdata;
-
-	if (pdata->relative_axis) {
+	if (encoder->relative_axis) {
 		input_report_rel(encoder->input,
-				 pdata->axis, encoder->dir ? -1 : 1);
+				 encoder->axis, encoder->dir ? -1 : 1);
 	} else {
 		unsigned int pos = encoder->pos;
 
 		if (encoder->dir) {
 			/* turning counter-clockwise */
-			if (pdata->rollover)
-				pos += pdata->steps;
+			if (encoder->rollover)
+				pos += encoder->steps;
 			if (pos)
 				pos--;
 		} else {
 			/* turning clockwise */
-			if (pdata->rollover || pos < pdata->steps)
+			if (encoder->rollover || pos < encoder->steps)
 				pos++;
 		}
 
-		if (pdata->rollover)
-			pos %= pdata->steps;
+		if (encoder->rollover)
+			pos %= encoder->steps;
 
 		encoder->pos = pos;
-		input_report_abs(encoder->input, pdata->axis, encoder->pos);
+		input_report_abs(encoder->input, encoder->axis, encoder->pos);
 	}
 
 	input_sync(encoder->input);
@@ -94,7 +101,7 @@  static irqreturn_t rotary_encoder_irq(int irq, void *dev_id)
 	struct rotary_encoder *encoder = dev_id;
 	int state;
 
-	state = rotary_encoder_get_state(encoder->pdata);
+	state = rotary_encoder_get_state(encoder);
 
 	switch (state) {
 	case 0x0:
@@ -123,7 +130,7 @@  static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id)
 	struct rotary_encoder *encoder = dev_id;
 	int state;
 
-	state = rotary_encoder_get_state(encoder->pdata);
+	state = rotary_encoder_get_state(encoder);
 
 	switch (state) {
 	case 0x00:
@@ -149,7 +156,7 @@  static irqreturn_t rotary_encoder_quarter_period_irq(int irq, void *dev_id)
 	unsigned char sum;
 	int state;
 
-	state = rotary_encoder_get_state(encoder->pdata);
+	state = rotary_encoder_get_state(encoder);
 
 	/*
 	 * We encode the previous and the current state using a byte.
@@ -199,38 +206,34 @@  static const struct of_device_id rotary_encoder_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, rotary_encoder_of_match);
 
-static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct device *dev)
+static int rotary_encoder_parse_dt(struct device *dev,
+				   struct rotary_encoder *encoder)
 {
 	const struct of_device_id *of_id =
 				of_match_device(rotary_encoder_of_match, dev);
 	struct device_node *np = dev->of_node;
-	struct rotary_encoder_platform_data *pdata;
 	enum of_gpio_flags flags;
 	int error;
 
 	if (!of_id || !np)
-		return NULL;
-
-	pdata = devm_kzalloc(dev, sizeof(struct rotary_encoder_platform_data),
-			     GFP_KERNEL);
-	if (!pdata)
-		return ERR_PTR(-ENOMEM);
+		return 1;
 
-	of_property_read_u32(np, "rotary-encoder,steps", &pdata->steps);
-	of_property_read_u32(np, "linux,axis", &pdata->axis);
+	of_property_read_u32(np, "rotary-encoder,steps", &encoder->steps);
+	of_property_read_u32(np, "linux,axis", &encoder->axis);
 
-	pdata->gpio_a = of_get_gpio_flags(np, 0, &flags);
-	pdata->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
+	encoder->gpio_a = of_get_gpio_flags(np, 0, &flags);
+	encoder->inverted_a = flags & OF_GPIO_ACTIVE_LOW;
 
-	pdata->gpio_b = of_get_gpio_flags(np, 1, &flags);
-	pdata->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
+	encoder->gpio_b = of_get_gpio_flags(np, 1, &flags);
+	encoder->inverted_b = flags & OF_GPIO_ACTIVE_LOW;
 
-	pdata->relative_axis =
+	encoder->relative_axis =
 		of_property_read_bool(np, "rotary-encoder,relative-axis");
-	pdata->rollover = of_property_read_bool(np, "rotary-encoder,rollover");
+	encoder->rollover =
+		of_property_read_bool(np, "rotary-encoder,rollover");
 
 	error = of_property_read_u32(np, "rotary-encoder,steps-per-period",
-				     &pdata->steps_per_period);
+				     &encoder->steps_per_period);
 	if (error) {
 		/*
 		 * The 'half-period' property has been deprecated, you must use
@@ -238,45 +241,57 @@  static struct rotary_encoder_platform_data *rotary_encoder_parse_dt(struct devic
 		 * need to parse it to maintain compatibility.
 		 */
 		if (of_property_read_bool(np, "rotary-encoder,half-period")) {
-			pdata->steps_per_period = 2;
+			encoder->steps_per_period = 2;
 		} else {
 			/* Fallback to one step per period behavior */
-			pdata->steps_per_period = 1;
+			encoder->steps_per_period = 1;
 		}
 	}
 
-	pdata->wakeup_source = of_property_read_bool(np, "wakeup-source");
+	encoder->wakeup_source = of_property_read_bool(np, "wakeup-source");
 
-	return pdata;
+	return 0;
 }
 #else
-static inline struct rotary_encoder_platform_data *
-rotary_encoder_parse_dt(struct device *dev)
+static inline int rotary_encoder_parse_dt(struct device *dev,
+					  struct rotary_encoder *encoder)
 {
-	return NULL;
+	return 1;
 }
 #endif
 
+static int rotary_encoder_parse_pdata(struct device *dev,
+				      struct rotary_encoder *encoder)
+{
+	const struct rotary_encoder_platform_data *pdata;
+
+	pdata = dev_get_platdata(dev);
+	if (!pdata) {
+		dev_err(dev, "missing platform data\n");
+		return -EINVAL;
+	}
+
+	encoder->steps = pdata->steps;
+	encoder->axis = pdata->axis;
+	encoder->gpio_a = pdata->gpio_a;
+	encoder->gpio_b = pdata->gpio_b;
+	encoder->inverted_a = pdata->inverted_a;
+	encoder->inverted_b = pdata->inverted_b;
+	encoder->steps_per_period = pdata->steps_per_period;
+	encoder->relative_axis = pdata->relative_axis;
+	encoder->rollover = pdata->rollover;
+
+	return 0;
+}
+
 static int rotary_encoder_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
-	const struct rotary_encoder_platform_data *pdata = dev_get_platdata(dev);
 	struct rotary_encoder *encoder;
 	struct input_dev *input;
 	irq_handler_t handler;
 	int err;
 
-	if (!pdata) {
-		pdata = rotary_encoder_parse_dt(dev);
-		if (IS_ERR(pdata))
-			return PTR_ERR(pdata);
-
-		if (!pdata) {
-			dev_err(dev, "missing platform data\n");
-			return -EINVAL;
-		}
-	}
-
 	encoder = devm_kzalloc(dev, sizeof(struct rotary_encoder), GFP_KERNEL);
 	input = devm_input_allocate_device(&pdev->dev);
 	if (!encoder || !input) {
@@ -284,55 +299,62 @@  static int rotary_encoder_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	err = rotary_encoder_parse_dt(dev, encoder);
+	if (err > 0)
+		/* not instatiated by dt */
+		err = rotary_encoder_parse_pdata(dev, encoder);
+
+	if (err < 0)
+		return err;
+
 	encoder->input = input;
-	encoder->pdata = pdata;
 
 	input->name = pdev->name;
 	input->id.bustype = BUS_HOST;
 	input->dev.parent = dev;
 
-	if (pdata->relative_axis) {
+	if (encoder->relative_axis) {
 		input->evbit[0] = BIT_MASK(EV_REL);
-		input->relbit[0] = BIT_MASK(pdata->axis);
+		input->relbit[0] = BIT_MASK(encoder->axis);
 	} else {
 		input->evbit[0] = BIT_MASK(EV_ABS);
 		input_set_abs_params(encoder->input,
-				     pdata->axis, 0, pdata->steps, 0, 1);
+				     encoder->axis, 0, encoder->steps, 0, 1);
 	}
 
 	/* request the GPIOs */
-	err = devm_gpio_request_one(dev, pdata->gpio_a,
+	err = devm_gpio_request_one(dev, encoder->gpio_a,
 				    GPIOF_IN, dev_name(dev));
 	if (err) {
-		dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_a);
+		dev_err(dev, "unable to request GPIO %d\n", encoder->gpio_a);
 		return err;
 	}
 
-	err = devm_gpio_request_one(dev, pdata->gpio_b,
+	err = devm_gpio_request_one(dev, encoder->gpio_b,
 				    GPIOF_IN, dev_name(dev));
 	if (err) {
-		dev_err(dev, "unable to request GPIO %d\n", pdata->gpio_b);
+		dev_err(dev, "unable to request GPIO %d\n", encoder->gpio_b);
 		return err;
 	}
 
-	encoder->irq_a = gpio_to_irq(pdata->gpio_a);
-	encoder->irq_b = gpio_to_irq(pdata->gpio_b);
+	encoder->irq_a = gpio_to_irq(encoder->gpio_a);
+	encoder->irq_b = gpio_to_irq(encoder->gpio_b);
 
-	switch (pdata->steps_per_period) {
+	switch (encoder->steps_per_period) {
 	case 4:
 		handler = &rotary_encoder_quarter_period_irq;
-		encoder->last_stable = rotary_encoder_get_state(pdata);
+		encoder->last_stable = rotary_encoder_get_state(encoder);
 		break;
 	case 2:
 		handler = &rotary_encoder_half_period_irq;
-		encoder->last_stable = rotary_encoder_get_state(pdata);
+		encoder->last_stable = rotary_encoder_get_state(encoder);
 		break;
 	case 1:
 		handler = &rotary_encoder_irq;
 		break;
 	default:
 		dev_err(dev, "'%d' is not a valid steps-per-period value\n",
-			pdata->steps_per_period);
+			encoder->steps_per_period);
 		return -EINVAL;
 	}
 
@@ -358,7 +380,7 @@  static int rotary_encoder_probe(struct platform_device *pdev)
 		return err;
 	}
 
-	device_init_wakeup(&pdev->dev, pdata->wakeup_source);
+	device_init_wakeup(&pdev->dev, encoder->wakeup_source);
 
 	platform_set_drvdata(pdev, encoder);