root/drivers/input/misc/mma8450.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mma8450_read
  2. mma8450_write
  3. mma8450_read_block
  4. mma8450_poll
  5. mma8450_open
  6. mma8450_close
  7. mma8450_probe

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  Driver for Freescale's 3-Axis Accelerometer MMA8450
   4  *
   5  *  Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
   6  */
   7 
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/slab.h>
  11 #include <linux/delay.h>
  12 #include <linux/i2c.h>
  13 #include <linux/input-polldev.h>
  14 #include <linux/of_device.h>
  15 
  16 #define MMA8450_DRV_NAME        "mma8450"
  17 
  18 #define MODE_CHANGE_DELAY_MS    100
  19 #define POLL_INTERVAL           100
  20 #define POLL_INTERVAL_MAX       500
  21 
  22 /* register definitions */
  23 #define MMA8450_STATUS          0x00
  24 #define MMA8450_STATUS_ZXYDR    0x08
  25 
  26 #define MMA8450_OUT_X8          0x01
  27 #define MMA8450_OUT_Y8          0x02
  28 #define MMA8450_OUT_Z8          0x03
  29 
  30 #define MMA8450_OUT_X_LSB       0x05
  31 #define MMA8450_OUT_X_MSB       0x06
  32 #define MMA8450_OUT_Y_LSB       0x07
  33 #define MMA8450_OUT_Y_MSB       0x08
  34 #define MMA8450_OUT_Z_LSB       0x09
  35 #define MMA8450_OUT_Z_MSB       0x0a
  36 
  37 #define MMA8450_XYZ_DATA_CFG    0x16
  38 
  39 #define MMA8450_CTRL_REG1       0x38
  40 #define MMA8450_CTRL_REG2       0x39
  41 
  42 /* mma8450 status */
  43 struct mma8450 {
  44         struct i2c_client       *client;
  45         struct input_polled_dev *idev;
  46 };
  47 
  48 static int mma8450_read(struct mma8450 *m, unsigned off)
  49 {
  50         struct i2c_client *c = m->client;
  51         int ret;
  52 
  53         ret = i2c_smbus_read_byte_data(c, off);
  54         if (ret < 0)
  55                 dev_err(&c->dev,
  56                         "failed to read register 0x%02x, error %d\n",
  57                         off, ret);
  58 
  59         return ret;
  60 }
  61 
  62 static int mma8450_write(struct mma8450 *m, unsigned off, u8 v)
  63 {
  64         struct i2c_client *c = m->client;
  65         int error;
  66 
  67         error = i2c_smbus_write_byte_data(c, off, v);
  68         if (error < 0) {
  69                 dev_err(&c->dev,
  70                         "failed to write to register 0x%02x, error %d\n",
  71                         off, error);
  72                 return error;
  73         }
  74 
  75         return 0;
  76 }
  77 
  78 static int mma8450_read_block(struct mma8450 *m, unsigned off,
  79                               u8 *buf, size_t size)
  80 {
  81         struct i2c_client *c = m->client;
  82         int err;
  83 
  84         err = i2c_smbus_read_i2c_block_data(c, off, size, buf);
  85         if (err < 0) {
  86                 dev_err(&c->dev,
  87                         "failed to read block data at 0x%02x, error %d\n",
  88                         MMA8450_OUT_X_LSB, err);
  89                 return err;
  90         }
  91 
  92         return 0;
  93 }
  94 
  95 static void mma8450_poll(struct input_polled_dev *dev)
  96 {
  97         struct mma8450 *m = dev->private;
  98         int x, y, z;
  99         int ret;
 100         u8 buf[6];
 101 
 102         ret = mma8450_read(m, MMA8450_STATUS);
 103         if (ret < 0)
 104                 return;
 105 
 106         if (!(ret & MMA8450_STATUS_ZXYDR))
 107                 return;
 108 
 109         ret = mma8450_read_block(m, MMA8450_OUT_X_LSB, buf, sizeof(buf));
 110         if (ret < 0)
 111                 return;
 112 
 113         x = ((int)(s8)buf[1] << 4) | (buf[0] & 0xf);
 114         y = ((int)(s8)buf[3] << 4) | (buf[2] & 0xf);
 115         z = ((int)(s8)buf[5] << 4) | (buf[4] & 0xf);
 116 
 117         input_report_abs(dev->input, ABS_X, x);
 118         input_report_abs(dev->input, ABS_Y, y);
 119         input_report_abs(dev->input, ABS_Z, z);
 120         input_sync(dev->input);
 121 }
 122 
 123 /* Initialize the MMA8450 chip */
 124 static void mma8450_open(struct input_polled_dev *dev)
 125 {
 126         struct mma8450 *m = dev->private;
 127         int err;
 128 
 129         /* enable all events from X/Y/Z, no FIFO */
 130         err = mma8450_write(m, MMA8450_XYZ_DATA_CFG, 0x07);
 131         if (err)
 132                 return;
 133 
 134         /*
 135          * Sleep mode poll rate - 50Hz
 136          * System output data rate - 400Hz
 137          * Full scale selection - Active, +/- 2G
 138          */
 139         err = mma8450_write(m, MMA8450_CTRL_REG1, 0x01);
 140         if (err < 0)
 141                 return;
 142 
 143         msleep(MODE_CHANGE_DELAY_MS);
 144 }
 145 
 146 static void mma8450_close(struct input_polled_dev *dev)
 147 {
 148         struct mma8450 *m = dev->private;
 149 
 150         mma8450_write(m, MMA8450_CTRL_REG1, 0x00);
 151         mma8450_write(m, MMA8450_CTRL_REG2, 0x01);
 152 }
 153 
 154 /*
 155  * I2C init/probing/exit functions
 156  */
 157 static int mma8450_probe(struct i2c_client *c,
 158                          const struct i2c_device_id *id)
 159 {
 160         struct input_polled_dev *idev;
 161         struct mma8450 *m;
 162         int err;
 163 
 164         m = devm_kzalloc(&c->dev, sizeof(*m), GFP_KERNEL);
 165         if (!m)
 166                 return -ENOMEM;
 167 
 168         idev = devm_input_allocate_polled_device(&c->dev);
 169         if (!idev)
 170                 return -ENOMEM;
 171 
 172         m->client = c;
 173         m->idev = idev;
 174 
 175         idev->private           = m;
 176         idev->input->name       = MMA8450_DRV_NAME;
 177         idev->input->id.bustype = BUS_I2C;
 178         idev->poll              = mma8450_poll;
 179         idev->poll_interval     = POLL_INTERVAL;
 180         idev->poll_interval_max = POLL_INTERVAL_MAX;
 181         idev->open              = mma8450_open;
 182         idev->close             = mma8450_close;
 183 
 184         __set_bit(EV_ABS, idev->input->evbit);
 185         input_set_abs_params(idev->input, ABS_X, -2048, 2047, 32, 32);
 186         input_set_abs_params(idev->input, ABS_Y, -2048, 2047, 32, 32);
 187         input_set_abs_params(idev->input, ABS_Z, -2048, 2047, 32, 32);
 188 
 189         err = input_register_polled_device(idev);
 190         if (err) {
 191                 dev_err(&c->dev, "failed to register polled input device\n");
 192                 return err;
 193         }
 194 
 195         return 0;
 196 }
 197 
 198 static const struct i2c_device_id mma8450_id[] = {
 199         { MMA8450_DRV_NAME, 0 },
 200         { },
 201 };
 202 MODULE_DEVICE_TABLE(i2c, mma8450_id);
 203 
 204 static const struct of_device_id mma8450_dt_ids[] = {
 205         { .compatible = "fsl,mma8450", },
 206         { /* sentinel */ }
 207 };
 208 MODULE_DEVICE_TABLE(of, mma8450_dt_ids);
 209 
 210 static struct i2c_driver mma8450_driver = {
 211         .driver = {
 212                 .name   = MMA8450_DRV_NAME,
 213                 .of_match_table = mma8450_dt_ids,
 214         },
 215         .probe          = mma8450_probe,
 216         .id_table       = mma8450_id,
 217 };
 218 
 219 module_i2c_driver(mma8450_driver);
 220 
 221 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
 222 MODULE_DESCRIPTION("MMA8450 3-Axis Accelerometer Driver");
 223 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */