]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
iio: accel: st_accel: Add lis3l02dq support
authorJonathan Cameron <jic23@kernel.org>
Sun, 22 May 2016 19:39:29 +0000 (20:39 +0100)
committerJonathan Cameron <jic23@kernel.org>
Mon, 4 Jul 2016 17:07:44 +0000 (18:07 +0100)
Time to finally kill off the venerable (it was one of my first drivers)
lis3l02dq driver in favour of adding support in the st sensors framework.

This does loose us the event support that driver always had, but I think
that will reappear at some point and in the meantime the maintenance
advantages of dropping the 'special' driver for this one part outweigh
the issues.

It's worth noting this part is ancient and I may well be the only person
who still has any on hardware running recent kernels.

It has a few 'quirks'.
 - No WAI register so that just became optional.
 - A BDU option that really does block updates.  Completely.
   Whatever you do, you don't get any more data with it set.
   It is documented the same as more modern parts but I presume they
   are actually clearing for updates after a read of both bytes!
 - Fixed scale.
 - It's too quick.  Even at slowest rate (280Hz) I can't read out fast
   enough on my board (stargate 2) to beat new data coming in. Linus'
   repeat read patch doesn't help in this case. It just means I get 10
   readings before dying... So in reality this will get used with
   software triggers only unless someone has this long out of production
   device on a quick board.

Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Cc: Denis CIOCCA <denis.ciocca@st.com>
Cc: Crestez Dan Leonard <leonard.crestez@intel.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
drivers/iio/accel/st_accel.h
drivers/iio/accel/st_accel_core.c
drivers/iio/accel/st_accel_i2c.c
drivers/iio/accel/st_accel_spi.c
drivers/iio/common/st_sensors/st_sensors_core.c

index 57f83a67948cc0758d8210e64b4a7a8f4513e9c7..f8dfdb6905632b3e23d2074eb8f0d993f5447ed9 100644 (file)
@@ -29,6 +29,7 @@
 #define LSM330_ACCEL_DEV_NAME          "lsm330_accel"
 #define LSM303AGR_ACCEL_DEV_NAME       "lsm303agr_accel"
 #define LIS2DH12_ACCEL_DEV_NAME                "lis2dh12_accel"
+#define LIS3L02DQ_ACCEL_DEV_NAME       "lis3l02dq"
 
 /**
 * struct st_sensors_platform_data - default accel platform data
index dce289aa40f25f8336fba49565698b50dc8e8e1d..da3fb069ec5c06dc2bdd99868ee1ad4e114b471a 100644 (file)
 #define ST_ACCEL_6_IHL_IRQ_MASK                        0x80
 #define ST_ACCEL_6_MULTIREAD_BIT               true
 
+/* CUSTOM VALUES FOR SENSOR 7 */
+#define ST_ACCEL_7_ODR_ADDR                    0x20
+#define ST_ACCEL_7_ODR_MASK                    0x30
+#define ST_ACCEL_7_ODR_AVL_280HZ_VAL           0x00
+#define ST_ACCEL_7_ODR_AVL_560HZ_VAL           0x01
+#define ST_ACCEL_7_ODR_AVL_1120HZ_VAL          0x02
+#define ST_ACCEL_7_ODR_AVL_4480HZ_VAL          0x03
+#define ST_ACCEL_7_PW_ADDR                     0x20
+#define ST_ACCEL_7_PW_MASK                     0xc0
+#define ST_ACCEL_7_FS_AVL_2_GAIN               IIO_G_TO_M_S_2(488)
+#define ST_ACCEL_7_BDU_ADDR                    0x21
+#define ST_ACCEL_7_BDU_MASK                    0x40
+#define ST_ACCEL_7_DRDY_IRQ_ADDR               0x21
+#define ST_ACCEL_7_DRDY_IRQ_INT1_MASK          0x04
+#define ST_ACCEL_7_MULTIREAD_BIT               false
+
 static const struct iio_chan_spec st_accel_8bit_channels[] = {
        ST_SENSORS_LSM_CHANNELS(IIO_ACCEL,
                        BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
@@ -662,6 +678,54 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
                .multi_read_bit = ST_ACCEL_6_MULTIREAD_BIT,
                .bootime = 2,
        },
+       {
+               /* No WAI register present */
+               .sensors_supported = {
+                       [0] = LIS3L02DQ_ACCEL_DEV_NAME,
+               },
+               .ch = (struct iio_chan_spec *)st_accel_12bit_channels,
+               .odr = {
+                       .addr = ST_ACCEL_7_ODR_ADDR,
+                       .mask = ST_ACCEL_7_ODR_MASK,
+                       .odr_avl = {
+                               { 280, ST_ACCEL_7_ODR_AVL_280HZ_VAL, },
+                               { 560, ST_ACCEL_7_ODR_AVL_560HZ_VAL, },
+                               { 1120, ST_ACCEL_7_ODR_AVL_1120HZ_VAL, },
+                               { 4480, ST_ACCEL_7_ODR_AVL_4480HZ_VAL, },
+                       },
+               },
+               .pw = {
+                       .addr = ST_ACCEL_7_PW_ADDR,
+                       .mask = ST_ACCEL_7_PW_MASK,
+                       .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
+                       .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+               },
+               .enable_axis = {
+                       .addr = ST_SENSORS_DEFAULT_AXIS_ADDR,
+                       .mask = ST_SENSORS_DEFAULT_AXIS_MASK,
+               },
+               .fs = {
+                       .fs_avl = {
+                               [0] = {
+                                       .num = ST_ACCEL_FS_AVL_2G,
+                                       .gain = ST_ACCEL_7_FS_AVL_2_GAIN,
+                               },
+                       },
+               },
+               /*
+                * The part has a BDU bit but if set the data is never
+                * updated so don't set it.
+                */
+               .bdu = {
+               },
+               .drdy_irq = {
+                       .addr = ST_ACCEL_7_DRDY_IRQ_ADDR,
+                       .mask_int1 = ST_ACCEL_7_DRDY_IRQ_INT1_MASK,
+                       .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
+               },
+               .multi_read_bit = ST_ACCEL_7_MULTIREAD_BIT,
+               .bootime = 2,
+       },
 };
 
 static int st_accel_read_raw(struct iio_dev *indio_dev,
index 7333ee9fb11ba8ac4e2f37a2dce111a73df7bfc6..e9d427a5df7ca506e771e487d966c9b5427604bc 100644 (file)
@@ -80,6 +80,10 @@ static const struct of_device_id st_accel_of_match[] = {
                .compatible = "st,h3lis331dl-accel",
                .data = H3LIS331DL_DRIVER_NAME,
        },
+       {
+               .compatible = "st,lis3l02dq",
+               .data = LIS3L02DQ_ACCEL_DEV_NAME,
+       },
        {},
 };
 MODULE_DEVICE_TABLE(of, st_accel_of_match);
@@ -130,6 +134,7 @@ static const struct i2c_device_id st_accel_id_table[] = {
        { LSM330_ACCEL_DEV_NAME },
        { LSM303AGR_ACCEL_DEV_NAME },
        { LIS2DH12_ACCEL_DEV_NAME },
+       { LIS3L02DQ_ACCEL_DEV_NAME },
        {},
 };
 MODULE_DEVICE_TABLE(i2c, st_accel_id_table);
index fcd5847a3fd34a11531e2db3ae6ed0365cd71bd5..efd43941d45d772e1802d27569c35806708d2a9c 100644 (file)
@@ -59,6 +59,7 @@ static const struct spi_device_id st_accel_id_table[] = {
        { LSM330_ACCEL_DEV_NAME },
        { LSM303AGR_ACCEL_DEV_NAME },
        { LIS2DH12_ACCEL_DEV_NAME },
+       { LIS3L02DQ_ACCEL_DEV_NAME },
        {},
 };
 MODULE_DEVICE_TABLE(spi, st_accel_id_table);
index 6db12ea034d3ad668cc0d33f934856d72dfe6d28..26ce32552448ac70982115dedcc2a7103100b7f5 100644 (file)
@@ -550,7 +550,7 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
                        int num_sensors_list,
                        const struct st_sensor_settings *sensor_settings)
 {
-       int i, n, err;
+       int i, n, err = 0;
        u8 wai;
        struct st_sensor_data *sdata = iio_priv(indio_dev);
 
@@ -570,17 +570,21 @@ int st_sensors_check_device_support(struct iio_dev *indio_dev,
                return -ENODEV;
        }
 
-       err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
-                                       sensor_settings[i].wai_addr, &wai);
-       if (err < 0) {
-               dev_err(&indio_dev->dev, "failed to read Who-Am-I register.\n");
-               return err;
-       }
+       if (sensor_settings[i].wai_addr) {
+               err = sdata->tf->read_byte(&sdata->tb, sdata->dev,
+                                          sensor_settings[i].wai_addr, &wai);
+               if (err < 0) {
+                       dev_err(&indio_dev->dev,
+                               "failed to read Who-Am-I register.\n");
+                       return err;
+               }
 
-       if (sensor_settings[i].wai != wai) {
-               dev_err(&indio_dev->dev, "%s: WhoAmI mismatch (0x%x).\n",
-                                               indio_dev->name, wai);
-               return -EINVAL;
+               if (sensor_settings[i].wai != wai) {
+                       dev_err(&indio_dev->dev,
+                               "%s: WhoAmI mismatch (0x%x).\n",
+                               indio_dev->name, wai);
+                       return -EINVAL;
+               }
        }
 
        sdata->sensor_settings =