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"); 224