linux-iio.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
@ 2020-11-28 18:51 Jonathan Cameron
  2020-11-28 19:20 ` Linus Walleij
  0 siblings, 1 reply; 5+ messages in thread
From: Jonathan Cameron @ 2020-11-28 18:51 UTC (permalink / raw)
  To: linux-iio; +Cc: Jonathan Cameron, Andy Shevchenko, Linus Walleij

From: Jonathan Cameron <Jonathan.Cameron@huawei.com>

Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().

The whole one time programable memory is treated as a single 64bit
little endian value.  Thus we can avoid a lot of messy handling
of fields overlapping byte boundaries by just loading and manipulating
it as an __le64 converted to a u64.  That lets us just use FIELD_GET()
and GENMASK() to extract the values desired.

Note only build tested.

Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 drivers/iio/gyro/mpu3050-core.c | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/gyro/mpu3050-core.c b/drivers/iio/gyro/mpu3050-core.c
index 00e58060968c..6380fc1bdee3 100644
--- a/drivers/iio/gyro/mpu3050-core.c
+++ b/drivers/iio/gyro/mpu3050-core.c
@@ -13,6 +13,7 @@
  * TODO: add support for setting up the low pass 3dB frequency.
  */
 
+#include <linux/bitfield.h>
 #include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/err.h>
@@ -784,7 +785,8 @@ static int mpu3050_read_mem(struct mpu3050 *mpu3050,
 static int mpu3050_hw_init(struct mpu3050 *mpu3050)
 {
 	int ret;
-	u8 otp[8];
+	__le64 otp_le;
+	u64 otp;
 
 	/* Reset */
 	ret = regmap_update_bits(mpu3050->map,
@@ -815,29 +817,31 @@ static int mpu3050_hw_init(struct mpu3050 *mpu3050)
 				MPU3050_MEM_USER_BANK |
 				MPU3050_MEM_OTP_BANK_0),
 			       0,
-			       sizeof(otp),
-			       otp);
+			       sizeof(otp_le),
+			       (u8 *)&otp_le);
 	if (ret)
 		return ret;
 
 	/* This is device-unique data so it goes into the entropy pool */
-	add_device_randomness(otp, sizeof(otp));
+	add_device_randomness(&otp_le, sizeof(otp_le));
+
+	otp = le64_to_cpu(otp_le);
 
 	dev_info(mpu3050->dev,
-		 "die ID: %04X, wafer ID: %02X, A lot ID: %04X, "
-		 "W lot ID: %03X, WP ID: %01X, rev ID: %02X\n",
+		 "die ID: %04lX, wafer ID: %02lX, A lot ID: %04lX, "
+		 "W lot ID: %03lX, WP ID: %01lX, rev ID: %02lX\n",
 		 /* Die ID, bits 0-12 */
-		 (otp[1] << 8 | otp[0]) & 0x1fff,
+		 FIELD_GET(GENMASK(12, 0), otp),
 		 /* Wafer ID, bits 13-17 */
-		 ((otp[2] << 8 | otp[1]) & 0x03e0) >> 5,
+		 FIELD_GET(GENMASK(17, 13), otp),
 		 /* A lot ID, bits 18-33 */
-		 ((otp[4] << 16 | otp[3] << 8 | otp[2]) & 0x3fffc) >> 2,
+		 FIELD_GET(GENMASK(33, 18), otp),
 		 /* W lot ID, bits 34-45 */
-		 ((otp[5] << 8 | otp[4]) & 0x3ffc) >> 2,
+		 FIELD_GET(GENMASK(45, 34), otp),
 		 /* WP ID, bits 47-49 */
-		 ((otp[6] << 8 | otp[5]) & 0x0380) >> 7,
+		 FIELD_GET(GENMASK(49, 47), otp),
 		 /* rev ID, bits 50-55 */
-		 otp[6] >> 2);
+		 FIELD_GET(GENMASK(55, 50), otp));
 
 	return 0;
 }
-- 
2.29.2


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
  2020-11-28 18:51 [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up Jonathan Cameron
@ 2020-11-28 19:20 ` Linus Walleij
  2020-11-28 23:18   ` Andy Shevchenko
  0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2020-11-28 19:20 UTC (permalink / raw)
  To: Jonathan Cameron; +Cc: linux-iio, Jonathan Cameron, Andy Shevchenko

On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:

> From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
>
> Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
>
> The whole one time programable memory is treated as a single 64bit
> little endian value.  Thus we can avoid a lot of messy handling
> of fields overlapping byte boundaries by just loading and manipulating
> it as an __le64 converted to a u64.  That lets us just use FIELD_GET()
> and GENMASK() to extract the values desired.
>
> Note only build tested.
>
> Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> Cc: Linus Walleij <linus.walleij@linaro.org>

Are there any specific prerequisites? linux-next?

When I apply this and try to compile for an ARMv7 target I get
a lot of noise and an error:

In file included from <command-line>:0:0:
../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
../include/linux/bits.h:36:11: warning: right shift count is negative
[-Wshift-count-negative]
   (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
           ^
./../include/linux/compiler_types.h:299:9: note: in definition of
macro ‘__compiletime_assert’
   if (!(condition))     \
         ^~~~~~~~~
./../include/linux/compiler_types.h:319:2: note: in expansion of macro
‘_compiletime_assert’
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^~~~~~~~~~~~~~~~~~~
../include/linux/build_bug.h:39:37: note: in expansion of macro
‘compiletime_assert’
 #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
                                     ^~~~~~~~~~~~~~~~~~
../include/linux/bitfield.h:46:3: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
   BUILD_BUG_ON_MSG(!__builtin_constant_p(_mask),  \
   ^~~~~~~~~~~~~~~~
../include/linux/bitfield.h:108:3: note: in expansion of macro
‘__BF_FIELD_CHECK’
   __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
   ^~~~~~~~~~~~~~~~
../include/linux/dev_printk.h:118:33: note: in expansion of macro ‘FIELD_GET’
  _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
                                 ^~~~~~~~~~~
../include/linux/bits.h:38:31: note: in expansion of macro ‘__GENMASK’
  (GENMASK_INPUT_CHECK(h, l) + __GENMASK(h, l))
                               ^~~~~~~~~
../include/linux/dev_printk.h:118:33: note: in expansion of macro ‘GENMASK’
  _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
                                 ^~~~~~~~~~~
../drivers/iio/gyro/mpu3050-core.c:830:2: note: in expansion of macro ‘dev_info’
  dev_info(mpu3050->dev,
  ^~~~~~~~
../include/linux/bits.h:36:11: warning: right shift count is negative
[-Wshift-count-negative]
   (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
           ^
./../include/linux/compiler_types.h:299:9: note: in definition of
macro ‘__compiletime_assert’
   if (!(condition))     \
         ^~~~~~~~~
./../include/linux/compiler_types.h:319:2: note: in expansion of macro
‘_compiletime_assert’
  _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__)
  ^~~~~~~~~~~~~~~~~~~
../include/linux/build_bug.h:39:37: note: in expansion of macro
‘compiletime_assert’
 #define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
                                     ^~~~~~~~~~~~~~~~~~
../include/linux/bitfield.h:48:3: note: in expansion of macro ‘BUILD_BUG_ON_MSG’
   BUILD_BUG_ON_MSG((_mask) == 0, _pfx "mask is zero"); \
   ^~~~~~~~~~~~~~~~
../include/linux/bitfield.h:108:3: note: in expansion of macro
‘__BF_FIELD_CHECK’
   __BF_FIELD_CHECK(_mask, _reg, 0U, "FIELD_GET: "); \
   ^~~~~~~~~~~~~~~~
../include/linux/dev_printk.h:118:33: note: in expansion of macro ‘FIELD_GET’
  _dev_info(dev, dev_fmt(fmt), ##__VA_ARGS__)
                                 ^~~~~~~~~~~
(...)

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
  2020-11-28 19:20 ` Linus Walleij
@ 2020-11-28 23:18   ` Andy Shevchenko
  2020-11-29  1:11     ` Linus Walleij
  0 siblings, 1 reply; 5+ messages in thread
From: Andy Shevchenko @ 2020-11-28 23:18 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Jonathan Cameron, linux-iio, Jonathan Cameron, Andy Shevchenko

On Sun, Nov 29, 2020 at 12:22 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
>
> > From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> >
> > Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
> >
> > The whole one time programable memory is treated as a single 64bit
> > little endian value.  Thus we can avoid a lot of messy handling
> > of fields overlapping byte boundaries by just loading and manipulating
> > it as an __le64 converted to a u64.  That lets us just use FIELD_GET()
> > and GENMASK() to extract the values desired.
> >
> > Note only build tested.
> >
> > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
>
> Are there any specific prerequisites? linux-next?
>
> When I apply this and try to compile for an ARMv7 target I get
> a lot of noise and an error:
>
> In file included from <command-line>:0:0:
> ../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
> ../include/linux/bits.h:36:11: warning: right shift count is negative
> [-Wshift-count-negative]
>    (~UL(0) >> (BITS_PER_LONG - 1 - (h))))

I think GENMASK_ULL() has to be used.

-- 
With Best Regards,
Andy Shevchenko

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
  2020-11-28 23:18   ` Andy Shevchenko
@ 2020-11-29  1:11     ` Linus Walleij
  2020-11-29 11:28       ` Jonathan Cameron
  0 siblings, 1 reply; 5+ messages in thread
From: Linus Walleij @ 2020-11-29  1:11 UTC (permalink / raw)
  To: Andy Shevchenko
  Cc: Jonathan Cameron, linux-iio, Jonathan Cameron, Andy Shevchenko

On Sun, Nov 29, 2020 at 12:18 AM Andy Shevchenko
<andy.shevchenko@gmail.com> wrote:
> On Sun, Nov 29, 2020 at 12:22 AM Linus Walleij <linus.walleij@linaro.org> wrote:
> > On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
> >
> > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > >
> > > Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
> > >
> > > The whole one time programable memory is treated as a single 64bit
> > > little endian value.  Thus we can avoid a lot of messy handling
> > > of fields overlapping byte boundaries by just loading and manipulating
> > > it as an __le64 converted to a u64.  That lets us just use FIELD_GET()
> > > and GENMASK() to extract the values desired.
> > >
> > > Note only build tested.
> > >
> > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > > Cc: Linus Walleij <linus.walleij@linaro.org>
> >
> > Are there any specific prerequisites? linux-next?
> >
> > When I apply this and try to compile for an ARMv7 target I get
> > a lot of noise and an error:
> >
> > In file included from <command-line>:0:0:
> > ../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
> > ../include/linux/bits.h:36:11: warning: right shift count is negative
> > [-Wshift-count-negative]
> >    (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
>
> I think GENMASK_ULL() has to be used.

Oh indeed. It works as long as one just try to test-compile it on a 64bit
machine of course :D

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up
  2020-11-29  1:11     ` Linus Walleij
@ 2020-11-29 11:28       ` Jonathan Cameron
  0 siblings, 0 replies; 5+ messages in thread
From: Jonathan Cameron @ 2020-11-29 11:28 UTC (permalink / raw)
  To: Linus Walleij
  Cc: Andy Shevchenko, linux-iio, Jonathan Cameron, Andy Shevchenko

On Sun, 29 Nov 2020 02:11:01 +0100
Linus Walleij <linus.walleij@linaro.org> wrote:

> On Sun, Nov 29, 2020 at 12:18 AM Andy Shevchenko
> <andy.shevchenko@gmail.com> wrote:
> > On Sun, Nov 29, 2020 at 12:22 AM Linus Walleij <linus.walleij@linaro.org> wrote:  
> > > On Sat, Nov 28, 2020 at 7:54 PM Jonathan Cameron <jic23@kernel.org> wrote:
> > >  
> > > > From: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > >
> > > > Inspired by Andy Shevchenko's proposal to use get_unaligned_leXX().
> > > >
> > > > The whole one time programable memory is treated as a single 64bit
> > > > little endian value.  Thus we can avoid a lot of messy handling
> > > > of fields overlapping byte boundaries by just loading and manipulating
> > > > it as an __le64 converted to a u64.  That lets us just use FIELD_GET()
> > > > and GENMASK() to extract the values desired.
> > > >
> > > > Note only build tested.
> > > >
> > > > Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
> > > > Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > > > Cc: Linus Walleij <linus.walleij@linaro.org>  
> > >
> > > Are there any specific prerequisites? linux-next?
> > >
> > > When I apply this and try to compile for an ARMv7 target I get
> > > a lot of noise and an error:
> > >
> > > In file included from <command-line>:0:0:
> > > ../drivers/iio/gyro/mpu3050-core.c: In function ‘mpu3050_hw_init’:
> > > ../include/linux/bits.h:36:11: warning: right shift count is negative
> > > [-Wshift-count-negative]
> > >    (~UL(0) >> (BITS_PER_LONG - 1 - (h))))  
> >
> > I think GENMASK_ULL() has to be used.  
> 
> Oh indeed. It works as long as one just try to test-compile it on a 64bit
> machine of course :D

Doh.  That's me being lazy :(

Will flip them all over to GENMASK_ULL and do a 32 bit build test.
I checked that the FIELD_GET would be fine, but forgot to look at
GENMASK.

oops.

Jonathan

> 
> Yours,
> Linus Walleij


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-11-29 11:28 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-28 18:51 [PATCH] iio:gyro:mpu3050 Treat otp value as a __le64 and use FIELD_GET() to break up Jonathan Cameron
2020-11-28 19:20 ` Linus Walleij
2020-11-28 23:18   ` Andy Shevchenko
2020-11-29  1:11     ` Linus Walleij
2020-11-29 11:28       ` Jonathan Cameron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).