1b029ffafSHemanth V /* 2b029ffafSHemanth V * VTI CMA3000_D0x Accelerometer driver 3b029ffafSHemanth V * 4b029ffafSHemanth V * Copyright (C) 2010 Texas Instruments 5b029ffafSHemanth V * Author: Hemanth V <hemanthv@ti.com> 6b029ffafSHemanth V * 7b029ffafSHemanth V * This program is free software; you can redistribute it and/or modify it 8b029ffafSHemanth V * under the terms of the GNU General Public License version 2 as published by 9b029ffafSHemanth V * the Free Software Foundation. 10b029ffafSHemanth V * 11b029ffafSHemanth V * This program is distributed in the hope that it will be useful, but WITHOUT 12b029ffafSHemanth V * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13b029ffafSHemanth V * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 14b029ffafSHemanth V * more details. 15b029ffafSHemanth V * 16b029ffafSHemanth V * You should have received a copy of the GNU General Public License along with 17b029ffafSHemanth V * this program. If not, see <http://www.gnu.org/licenses/>. 18b029ffafSHemanth V */ 19b029ffafSHemanth V 20b029ffafSHemanth V #include <linux/types.h> 21b029ffafSHemanth V #include <linux/interrupt.h> 22b029ffafSHemanth V #include <linux/delay.h> 23b029ffafSHemanth V #include <linux/slab.h> 24b029ffafSHemanth V #include <linux/input.h> 25b029ffafSHemanth V #include <linux/input/cma3000.h> 26d2d8442dSPaul Gortmaker #include <linux/module.h> 27b029ffafSHemanth V 28b029ffafSHemanth V #include "cma3000_d0x.h" 29b029ffafSHemanth V 30b029ffafSHemanth V #define CMA3000_WHOAMI 0x00 31b029ffafSHemanth V #define CMA3000_REVID 0x01 32b029ffafSHemanth V #define CMA3000_CTRL 0x02 33b029ffafSHemanth V #define CMA3000_STATUS 0x03 34b029ffafSHemanth V #define CMA3000_RSTR 0x04 35b029ffafSHemanth V #define CMA3000_INTSTATUS 0x05 36b029ffafSHemanth V #define CMA3000_DOUTX 0x06 37b029ffafSHemanth V #define CMA3000_DOUTY 0x07 38b029ffafSHemanth V #define CMA3000_DOUTZ 0x08 39b029ffafSHemanth V #define CMA3000_MDTHR 0x09 40b029ffafSHemanth V #define CMA3000_MDFFTMR 0x0A 41b029ffafSHemanth V #define CMA3000_FFTHR 0x0B 42b029ffafSHemanth V 43b029ffafSHemanth V #define CMA3000_RANGE2G (1 << 7) 44b029ffafSHemanth V #define CMA3000_RANGE8G (0 << 7) 45b029ffafSHemanth V #define CMA3000_BUSI2C (0 << 4) 46b029ffafSHemanth V #define CMA3000_MODEMASK (7 << 1) 47b029ffafSHemanth V #define CMA3000_GRANGEMASK (1 << 7) 48b029ffafSHemanth V 49b029ffafSHemanth V #define CMA3000_STATUS_PERR 1 50b029ffafSHemanth V #define CMA3000_INTSTATUS_FFDET (1 << 2) 51b029ffafSHemanth V 52b029ffafSHemanth V /* Settling time delay in ms */ 53b029ffafSHemanth V #define CMA3000_SETDELAY 30 54b029ffafSHemanth V 55b029ffafSHemanth V /* Delay for clearing interrupt in us */ 56b029ffafSHemanth V #define CMA3000_INTDELAY 44 57b029ffafSHemanth V 58b029ffafSHemanth V 59b029ffafSHemanth V /* 60b029ffafSHemanth V * Bit weights in mg for bit 0, other bits need 61b029ffafSHemanth V * multipy factor 2^n. Eight bit is the sign bit. 62b029ffafSHemanth V */ 63b029ffafSHemanth V #define BIT_TO_2G 18 64b029ffafSHemanth V #define BIT_TO_8G 71 65b029ffafSHemanth V 66b029ffafSHemanth V struct cma3000_accl_data { 67b029ffafSHemanth V const struct cma3000_bus_ops *bus_ops; 68b029ffafSHemanth V const struct cma3000_platform_data *pdata; 69b029ffafSHemanth V 70b029ffafSHemanth V struct device *dev; 71b029ffafSHemanth V struct input_dev *input_dev; 72b029ffafSHemanth V 73b029ffafSHemanth V int bit_to_mg; 74b029ffafSHemanth V int irq; 75b029ffafSHemanth V 76b029ffafSHemanth V int g_range; 77b029ffafSHemanth V u8 mode; 78b029ffafSHemanth V 79b029ffafSHemanth V struct mutex mutex; 80b029ffafSHemanth V bool opened; 81b029ffafSHemanth V bool suspended; 82b029ffafSHemanth V }; 83b029ffafSHemanth V 84b029ffafSHemanth V #define CMA3000_READ(data, reg, msg) \ 85b029ffafSHemanth V (data->bus_ops->read(data->dev, reg, msg)) 86b029ffafSHemanth V #define CMA3000_SET(data, reg, val, msg) \ 87b029ffafSHemanth V ((data)->bus_ops->write(data->dev, reg, val, msg)) 88b029ffafSHemanth V 89b029ffafSHemanth V /* 90b029ffafSHemanth V * Conversion for each of the eight modes to g, depending 91b029ffafSHemanth V * on G range i.e 2G or 8G. Some modes always operate in 92b029ffafSHemanth V * 8G. 93b029ffafSHemanth V */ 94b029ffafSHemanth V 95b029ffafSHemanth V static int mode_to_mg[8][2] = { 96b029ffafSHemanth V { 0, 0 }, 97b029ffafSHemanth V { BIT_TO_8G, BIT_TO_2G }, 98b029ffafSHemanth V { BIT_TO_8G, BIT_TO_2G }, 99b029ffafSHemanth V { BIT_TO_8G, BIT_TO_8G }, 100b029ffafSHemanth V { BIT_TO_8G, BIT_TO_8G }, 101b029ffafSHemanth V { BIT_TO_8G, BIT_TO_2G }, 102b029ffafSHemanth V { BIT_TO_8G, BIT_TO_2G }, 103b029ffafSHemanth V { 0, 0}, 104b029ffafSHemanth V }; 105b029ffafSHemanth V 106b029ffafSHemanth V static void decode_mg(struct cma3000_accl_data *data, int *datax, 107b029ffafSHemanth V int *datay, int *dataz) 108b029ffafSHemanth V { 109b029ffafSHemanth V /* Data in 2's complement, convert to mg */ 110b029ffafSHemanth V *datax = ((s8)*datax) * data->bit_to_mg; 111b029ffafSHemanth V *datay = ((s8)*datay) * data->bit_to_mg; 112b029ffafSHemanth V *dataz = ((s8)*dataz) * data->bit_to_mg; 113b029ffafSHemanth V } 114b029ffafSHemanth V 115b029ffafSHemanth V static irqreturn_t cma3000_thread_irq(int irq, void *dev_id) 116b029ffafSHemanth V { 117b029ffafSHemanth V struct cma3000_accl_data *data = dev_id; 118b029ffafSHemanth V int datax, datay, dataz; 119b029ffafSHemanth V u8 ctrl, mode, range, intr_status; 120b029ffafSHemanth V 121b029ffafSHemanth V intr_status = CMA3000_READ(data, CMA3000_INTSTATUS, "interrupt status"); 122b029ffafSHemanth V if (intr_status < 0) 123b029ffafSHemanth V return IRQ_NONE; 124b029ffafSHemanth V 125b029ffafSHemanth V /* Check if free fall is detected, report immediately */ 126b029ffafSHemanth V if (intr_status & CMA3000_INTSTATUS_FFDET) { 127b029ffafSHemanth V input_report_abs(data->input_dev, ABS_MISC, 1); 128b029ffafSHemanth V input_sync(data->input_dev); 129b029ffafSHemanth V } else { 130b029ffafSHemanth V input_report_abs(data->input_dev, ABS_MISC, 0); 131b029ffafSHemanth V } 132b029ffafSHemanth V 133b029ffafSHemanth V datax = CMA3000_READ(data, CMA3000_DOUTX, "X"); 134b029ffafSHemanth V datay = CMA3000_READ(data, CMA3000_DOUTY, "Y"); 135b029ffafSHemanth V dataz = CMA3000_READ(data, CMA3000_DOUTZ, "Z"); 136b029ffafSHemanth V 137b029ffafSHemanth V ctrl = CMA3000_READ(data, CMA3000_CTRL, "ctrl"); 138b029ffafSHemanth V mode = (ctrl & CMA3000_MODEMASK) >> 1; 139b029ffafSHemanth V range = (ctrl & CMA3000_GRANGEMASK) >> 7; 140b029ffafSHemanth V 141b029ffafSHemanth V data->bit_to_mg = mode_to_mg[mode][range]; 142b029ffafSHemanth V 143b029ffafSHemanth V /* Interrupt not for this device */ 144b029ffafSHemanth V if (data->bit_to_mg == 0) 145b029ffafSHemanth V return IRQ_NONE; 146b029ffafSHemanth V 147b029ffafSHemanth V /* Decode register values to milli g */ 148b029ffafSHemanth V decode_mg(data, &datax, &datay, &dataz); 149b029ffafSHemanth V 150b029ffafSHemanth V input_report_abs(data->input_dev, ABS_X, datax); 151b029ffafSHemanth V input_report_abs(data->input_dev, ABS_Y, datay); 152b029ffafSHemanth V input_report_abs(data->input_dev, ABS_Z, dataz); 153b029ffafSHemanth V input_sync(data->input_dev); 154b029ffafSHemanth V 155b029ffafSHemanth V return IRQ_HANDLED; 156b029ffafSHemanth V } 157b029ffafSHemanth V 158b029ffafSHemanth V static int cma3000_reset(struct cma3000_accl_data *data) 159b029ffafSHemanth V { 160b029ffafSHemanth V int val; 161b029ffafSHemanth V 162b029ffafSHemanth V /* Reset sequence */ 163b029ffafSHemanth V CMA3000_SET(data, CMA3000_RSTR, 0x02, "Reset"); 164b029ffafSHemanth V CMA3000_SET(data, CMA3000_RSTR, 0x0A, "Reset"); 165b029ffafSHemanth V CMA3000_SET(data, CMA3000_RSTR, 0x04, "Reset"); 166b029ffafSHemanth V 167b029ffafSHemanth V /* Settling time delay */ 168b029ffafSHemanth V mdelay(10); 169b029ffafSHemanth V 170b029ffafSHemanth V val = CMA3000_READ(data, CMA3000_STATUS, "Status"); 171b029ffafSHemanth V if (val < 0) { 172b029ffafSHemanth V dev_err(data->dev, "Reset failed\n"); 173b029ffafSHemanth V return val; 174b029ffafSHemanth V } 175b029ffafSHemanth V 176b029ffafSHemanth V if (val & CMA3000_STATUS_PERR) { 177b029ffafSHemanth V dev_err(data->dev, "Parity Error\n"); 178b029ffafSHemanth V return -EIO; 179b029ffafSHemanth V } 180b029ffafSHemanth V 181b029ffafSHemanth V return 0; 182b029ffafSHemanth V } 183b029ffafSHemanth V 184b029ffafSHemanth V static int cma3000_poweron(struct cma3000_accl_data *data) 185b029ffafSHemanth V { 186b029ffafSHemanth V const struct cma3000_platform_data *pdata = data->pdata; 187b029ffafSHemanth V u8 ctrl = 0; 188b029ffafSHemanth V int ret; 189b029ffafSHemanth V 190b029ffafSHemanth V if (data->g_range == CMARANGE_2G) { 191b029ffafSHemanth V ctrl = (data->mode << 1) | CMA3000_RANGE2G; 192b029ffafSHemanth V } else if (data->g_range == CMARANGE_8G) { 193b029ffafSHemanth V ctrl = (data->mode << 1) | CMA3000_RANGE8G; 194b029ffafSHemanth V } else { 195b029ffafSHemanth V dev_info(data->dev, 196b029ffafSHemanth V "Invalid G range specified, assuming 8G\n"); 197b029ffafSHemanth V ctrl = (data->mode << 1) | CMA3000_RANGE8G; 198b029ffafSHemanth V } 199b029ffafSHemanth V 200b029ffafSHemanth V ctrl |= data->bus_ops->ctrl_mod; 201b029ffafSHemanth V 202b029ffafSHemanth V CMA3000_SET(data, CMA3000_MDTHR, pdata->mdthr, 203b029ffafSHemanth V "Motion Detect Threshold"); 204b029ffafSHemanth V CMA3000_SET(data, CMA3000_MDFFTMR, pdata->mdfftmr, 205b029ffafSHemanth V "Time register"); 206b029ffafSHemanth V CMA3000_SET(data, CMA3000_FFTHR, pdata->ffthr, 207b029ffafSHemanth V "Free fall threshold"); 208b029ffafSHemanth V ret = CMA3000_SET(data, CMA3000_CTRL, ctrl, "Mode setting"); 209b029ffafSHemanth V if (ret < 0) 210b029ffafSHemanth V return -EIO; 211b029ffafSHemanth V 212b029ffafSHemanth V msleep(CMA3000_SETDELAY); 213b029ffafSHemanth V 214b029ffafSHemanth V return 0; 215b029ffafSHemanth V } 216b029ffafSHemanth V 217b029ffafSHemanth V static int cma3000_poweroff(struct cma3000_accl_data *data) 218b029ffafSHemanth V { 219b029ffafSHemanth V int ret; 220b029ffafSHemanth V 221b029ffafSHemanth V ret = CMA3000_SET(data, CMA3000_CTRL, CMAMODE_POFF, "Mode setting"); 222b029ffafSHemanth V msleep(CMA3000_SETDELAY); 223b029ffafSHemanth V 224b029ffafSHemanth V return ret; 225b029ffafSHemanth V } 226b029ffafSHemanth V 227b029ffafSHemanth V static int cma3000_open(struct input_dev *input_dev) 228b029ffafSHemanth V { 229b029ffafSHemanth V struct cma3000_accl_data *data = input_get_drvdata(input_dev); 230b029ffafSHemanth V 231b029ffafSHemanth V mutex_lock(&data->mutex); 232b029ffafSHemanth V 233b029ffafSHemanth V if (!data->suspended) 234b029ffafSHemanth V cma3000_poweron(data); 235b029ffafSHemanth V 236b029ffafSHemanth V data->opened = true; 237b029ffafSHemanth V 238b029ffafSHemanth V mutex_unlock(&data->mutex); 239b029ffafSHemanth V 240b029ffafSHemanth V return 0; 241b029ffafSHemanth V } 242b029ffafSHemanth V 243b029ffafSHemanth V static void cma3000_close(struct input_dev *input_dev) 244b029ffafSHemanth V { 245b029ffafSHemanth V struct cma3000_accl_data *data = input_get_drvdata(input_dev); 246b029ffafSHemanth V 247b029ffafSHemanth V mutex_lock(&data->mutex); 248b029ffafSHemanth V 249b029ffafSHemanth V if (!data->suspended) 250b029ffafSHemanth V cma3000_poweroff(data); 251b029ffafSHemanth V 252b029ffafSHemanth V data->opened = false; 253b029ffafSHemanth V 254b029ffafSHemanth V mutex_unlock(&data->mutex); 255b029ffafSHemanth V } 256b029ffafSHemanth V 257b029ffafSHemanth V void cma3000_suspend(struct cma3000_accl_data *data) 258b029ffafSHemanth V { 259b029ffafSHemanth V mutex_lock(&data->mutex); 260b029ffafSHemanth V 261b029ffafSHemanth V if (!data->suspended && data->opened) 262b029ffafSHemanth V cma3000_poweroff(data); 263b029ffafSHemanth V 264b029ffafSHemanth V data->suspended = true; 265b029ffafSHemanth V 266b029ffafSHemanth V mutex_unlock(&data->mutex); 267b029ffafSHemanth V } 268b029ffafSHemanth V EXPORT_SYMBOL(cma3000_suspend); 269b029ffafSHemanth V 270b029ffafSHemanth V 271b029ffafSHemanth V void cma3000_resume(struct cma3000_accl_data *data) 272b029ffafSHemanth V { 273b029ffafSHemanth V mutex_lock(&data->mutex); 274b029ffafSHemanth V 275b029ffafSHemanth V if (data->suspended && data->opened) 276b029ffafSHemanth V cma3000_poweron(data); 277b029ffafSHemanth V 278b029ffafSHemanth V data->suspended = false; 279b029ffafSHemanth V 280b029ffafSHemanth V mutex_unlock(&data->mutex); 281b029ffafSHemanth V } 282b029ffafSHemanth V EXPORT_SYMBOL(cma3000_resume); 283b029ffafSHemanth V 284b029ffafSHemanth V struct cma3000_accl_data *cma3000_init(struct device *dev, int irq, 285b029ffafSHemanth V const struct cma3000_bus_ops *bops) 286b029ffafSHemanth V { 287b029ffafSHemanth V const struct cma3000_platform_data *pdata = dev->platform_data; 288b029ffafSHemanth V struct cma3000_accl_data *data; 289b029ffafSHemanth V struct input_dev *input_dev; 290b029ffafSHemanth V int rev; 291b029ffafSHemanth V int error; 292b029ffafSHemanth V 293b029ffafSHemanth V if (!pdata) { 294b029ffafSHemanth V dev_err(dev, "platform data not found\n"); 295b029ffafSHemanth V error = -EINVAL; 296b029ffafSHemanth V goto err_out; 297b029ffafSHemanth V } 298b029ffafSHemanth V 299b029ffafSHemanth V 300b029ffafSHemanth V /* if no IRQ return error */ 301b029ffafSHemanth V if (irq == 0) { 302b029ffafSHemanth V error = -EINVAL; 303b029ffafSHemanth V goto err_out; 304b029ffafSHemanth V } 305b029ffafSHemanth V 306b029ffafSHemanth V data = kzalloc(sizeof(struct cma3000_accl_data), GFP_KERNEL); 307b029ffafSHemanth V input_dev = input_allocate_device(); 308b029ffafSHemanth V if (!data || !input_dev) { 309b029ffafSHemanth V error = -ENOMEM; 310b029ffafSHemanth V goto err_free_mem; 311b029ffafSHemanth V } 312b029ffafSHemanth V 313b029ffafSHemanth V data->dev = dev; 314b029ffafSHemanth V data->input_dev = input_dev; 315b029ffafSHemanth V data->bus_ops = bops; 316b029ffafSHemanth V data->pdata = pdata; 317b029ffafSHemanth V data->irq = irq; 318b029ffafSHemanth V mutex_init(&data->mutex); 319b029ffafSHemanth V 320b029ffafSHemanth V data->mode = pdata->mode; 321b029ffafSHemanth V if (data->mode < CMAMODE_DEFAULT || data->mode > CMAMODE_POFF) { 322b029ffafSHemanth V data->mode = CMAMODE_MOTDET; 323b029ffafSHemanth V dev_warn(dev, 324b029ffafSHemanth V "Invalid mode specified, assuming Motion Detect\n"); 325b029ffafSHemanth V } 326b029ffafSHemanth V 327b029ffafSHemanth V data->g_range = pdata->g_range; 328b029ffafSHemanth V if (data->g_range != CMARANGE_2G && data->g_range != CMARANGE_8G) { 329b029ffafSHemanth V dev_info(dev, 330b029ffafSHemanth V "Invalid G range specified, assuming 8G\n"); 331b029ffafSHemanth V data->g_range = CMARANGE_8G; 332b029ffafSHemanth V } 333b029ffafSHemanth V 334b029ffafSHemanth V input_dev->name = "cma3000-accelerometer"; 335b029ffafSHemanth V input_dev->id.bustype = bops->bustype; 336b029ffafSHemanth V input_dev->open = cma3000_open; 337b029ffafSHemanth V input_dev->close = cma3000_close; 338b029ffafSHemanth V 339b029ffafSHemanth V __set_bit(EV_ABS, input_dev->evbit); 340b029ffafSHemanth V 341b029ffafSHemanth V input_set_abs_params(input_dev, ABS_X, 342b029ffafSHemanth V -data->g_range, data->g_range, pdata->fuzz_x, 0); 343b029ffafSHemanth V input_set_abs_params(input_dev, ABS_Y, 344b029ffafSHemanth V -data->g_range, data->g_range, pdata->fuzz_y, 0); 345b029ffafSHemanth V input_set_abs_params(input_dev, ABS_Z, 346b029ffafSHemanth V -data->g_range, data->g_range, pdata->fuzz_z, 0); 347b029ffafSHemanth V input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0); 348b029ffafSHemanth V 349b029ffafSHemanth V input_set_drvdata(input_dev, data); 350b029ffafSHemanth V 351b029ffafSHemanth V error = cma3000_reset(data); 352b029ffafSHemanth V if (error) 353b029ffafSHemanth V goto err_free_mem; 354b029ffafSHemanth V 355b029ffafSHemanth V rev = CMA3000_READ(data, CMA3000_REVID, "Revid"); 356b029ffafSHemanth V if (rev < 0) { 357b029ffafSHemanth V error = rev; 358b029ffafSHemanth V goto err_free_mem; 359b029ffafSHemanth V } 360b029ffafSHemanth V 361b029ffafSHemanth V pr_info("CMA3000 Accelerometer: Revision %x\n", rev); 362b029ffafSHemanth V 363b029ffafSHemanth V error = request_threaded_irq(irq, NULL, cma3000_thread_irq, 364b029ffafSHemanth V pdata->irqflags | IRQF_ONESHOT, 365b029ffafSHemanth V "cma3000_d0x", data); 366b029ffafSHemanth V if (error) { 367b029ffafSHemanth V dev_err(dev, "request_threaded_irq failed\n"); 368b029ffafSHemanth V goto err_free_mem; 369b029ffafSHemanth V } 370b029ffafSHemanth V 371b029ffafSHemanth V error = input_register_device(data->input_dev); 372b029ffafSHemanth V if (error) { 373b029ffafSHemanth V dev_err(dev, "Unable to register input device\n"); 374b029ffafSHemanth V goto err_free_irq; 375b029ffafSHemanth V } 376b029ffafSHemanth V 377b029ffafSHemanth V return data; 378b029ffafSHemanth V 379b029ffafSHemanth V err_free_irq: 380b029ffafSHemanth V free_irq(irq, data); 381b029ffafSHemanth V err_free_mem: 382b029ffafSHemanth V input_free_device(input_dev); 383b029ffafSHemanth V kfree(data); 384b029ffafSHemanth V err_out: 385b029ffafSHemanth V return ERR_PTR(error); 386b029ffafSHemanth V } 387b029ffafSHemanth V EXPORT_SYMBOL(cma3000_init); 388b029ffafSHemanth V 389b029ffafSHemanth V void cma3000_exit(struct cma3000_accl_data *data) 390b029ffafSHemanth V { 391b029ffafSHemanth V free_irq(data->irq, data); 392b029ffafSHemanth V input_unregister_device(data->input_dev); 393b029ffafSHemanth V kfree(data); 394b029ffafSHemanth V } 395b029ffafSHemanth V EXPORT_SYMBOL(cma3000_exit); 396b029ffafSHemanth V 397b029ffafSHemanth V MODULE_DESCRIPTION("CMA3000-D0x Accelerometer Driver"); 398b029ffafSHemanth V MODULE_LICENSE("GPL"); 399b029ffafSHemanth V MODULE_AUTHOR("Hemanth V <hemanthv@ti.com>"); 400