Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * ADXL345/346 Three-Axis Digital Accelerometers
- *
- * Enter bugs at http://blackfin.uclinux.org/
- *
- * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
- * Licensed under the GPL-2 or later.
- */
- #include <linux/device.h>
- #include <linux/delay.h>
- #include <linux/interrupt.h>
- #include <linux/irq.h>
- #include <linux/slab.h>
- #include <linux/workqueue.h>
- #include <linux/input/adxl34x.h>
- #include <linux/module.h>
- #include "adxl34x.h"
- /* ADXL345/6 Register Map */
- #define DEVID 0x00 /* R Device ID */
- #define THRESH_TAP 0x1D /* R/W Tap threshold */
- #define OFSX 0x1E /* R/W X-axis offset */
- #define OFSY 0x1F /* R/W Y-axis offset */
- #define OFSZ 0x20 /* R/W Z-axis offset */
- #define DUR 0x21 /* R/W Tap duration */
- #define LATENT 0x22 /* R/W Tap latency */
- #define WINDOW 0x23 /* R/W Tap window */
- #define THRESH_ACT 0x24 /* R/W Activity threshold */
- #define THRESH_INACT 0x25 /* R/W Inactivity threshold */
- #define TIME_INACT 0x26 /* R/W Inactivity time */
- #define ACT_INACT_CTL 0x27 /* R/W Axis enable control for activity and */
- /* inactivity detection */
- #define THRESH_FF 0x28 /* R/W Free-fall threshold */
- #define TIME_FF 0x29 /* R/W Free-fall time */
- #define TAP_AXES 0x2A /* R/W Axis control for tap/double tap */
- #define ACT_TAP_STATUS 0x2B /* R Source of tap/double tap */
- #define BW_RATE 0x2C /* R/W Data rate and power mode control */
- #define POWER_CTL 0x2D /* R/W Power saving features control */
- #define INT_ENABLE 0x2E /* R/W Interrupt enable control */
- #define INT_MAP 0x2F /* R/W Interrupt mapping control */
- #define INT_SOURCE 0x30 /* R Source of interrupts */
- #define DATA_FORMAT 0x31 /* R/W Data format control */
- #define DATAX0 0x32 /* R X-Axis Data 0 */
- #define DATAX1 0x33 /* R X-Axis Data 1 */
- #define DATAY0 0x34 /* R Y-Axis Data 0 */
- #define DATAY1 0x35 /* R Y-Axis Data 1 */
- #define DATAZ0 0x36 /* R Z-Axis Data 0 */
- #define DATAZ1 0x37 /* R Z-Axis Data 1 */
- #define FIFO_CTL 0x38 /* R/W FIFO control */
- #define FIFO_STATUS 0x39 /* R FIFO status */
- #define TAP_SIGN 0x3A /* R Sign and source for tap/double tap */
- /* Orientation ADXL346 only */
- #define ORIENT_CONF 0x3B /* R/W Orientation configuration */
- #define ORIENT 0x3C /* R Orientation status */
- /* DEVIDs */
- #define ID_ADXL345 0xE5
- #define ID_ADXL346 0xE6
- /* INT_ENABLE/INT_MAP/INT_SOURCE Bits */
- #define DATA_READY (1 << 7)
- #define SINGLE_TAP (1 << 6)
- #define DOUBLE_TAP (1 << 5)
- #define ACTIVITY (1 << 4)
- #define INACTIVITY (1 << 3)
- #define FREE_FALL (1 << 2)
- #define WATERMARK (1 << 1)
- #define OVERRUN (1 << 0)
- /* ACT_INACT_CONTROL Bits */
- #define ACT_ACDC (1 << 7)
- #define ACT_X_EN (1 << 6)
- #define ACT_Y_EN (1 << 5)
- #define ACT_Z_EN (1 << 4)
- #define INACT_ACDC (1 << 3)
- #define INACT_X_EN (1 << 2)
- #define INACT_Y_EN (1 << 1)
- #define INACT_Z_EN (1 << 0)
- /* TAP_AXES Bits */
- #define SUPPRESS (1 << 3)
- #define TAP_X_EN (1 << 2)
- #define TAP_Y_EN (1 << 1)
- #define TAP_Z_EN (1 << 0)
- /* ACT_TAP_STATUS Bits */
- #define ACT_X_SRC (1 << 6)
- #define ACT_Y_SRC (1 << 5)
- #define ACT_Z_SRC (1 << 4)
- #define ASLEEP (1 << 3)
- #define TAP_X_SRC (1 << 2)
- #define TAP_Y_SRC (1 << 1)
- #define TAP_Z_SRC (1 << 0)
- /* BW_RATE Bits */
- #define LOW_POWER (1 << 4)
- #define RATE(x) ((x) & 0xF)
- /* POWER_CTL Bits */
- #define PCTL_LINK (1 << 5)
- #define PCTL_AUTO_SLEEP (1 << 4)
- #define PCTL_MEASURE (1 << 3)
- #define PCTL_SLEEP (1 << 2)
- #define PCTL_WAKEUP(x) ((x) & 0x3)
- /* DATA_FORMAT Bits */
- #define SELF_TEST (1 << 7)
- #define SPI (1 << 6)
- #define INT_INVERT (1 << 5)
- #define FULL_RES (1 << 3)
- #define JUSTIFY (1 << 2)
- #define RANGE(x) ((x) & 0x3)
- #define RANGE_PM_2g 0
- #define RANGE_PM_4g 1
- #define RANGE_PM_8g 2
- #define RANGE_PM_16g 3
- /*
- * Maximum value our axis may get in full res mode for the input device
- * (signed 13 bits)
- */
- #define ADXL_FULLRES_MAX_VAL 4096
- /*
- * Maximum value our axis may get in fixed res mode for the input device
- * (signed 10 bits)
- */
- #define ADXL_DEBUG
- #define ADXL_X_AXIS 0
- #define ADXL_Y_AXIS 1
- #define ADXL_Z_AXIS 2
- #define AC_READ(ac, reg) ((ac)->bops->read((ac)->dev, reg))
- #define AC_WRITE(ac, reg, val) ((ac)->bops->write((ac)->dev, reg, val))
- struct axis_triple {
- int x;
- int y;
- int z;
- };
- struct adxl34x {
- struct device *dev;
- struct adxl34x_platform_data pdata;
- unsigned model;
- const struct adxl34x_bus_ops *bops;
- };
- static const struct adxl34x_platform_data adxl34x_default_init = {
- .tap_threshold = 35,
- .tap_duration = 3,
- .tap_latency = 20,
- .tap_window = 20,
- .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN,
- .act_axis_control = 0xFF,
- .activity_threshold = 6,
- .inactivity_threshold = 4,
- .inactivity_time = 3,
- .free_fall_threshold = 8,
- .free_fall_time = 0x20,
- .data_rate = 8,
- .data_range = ADXL_FULL_RES,
- .ev_type = EV_ABS,
- .ev_code_x = ABS_X, /* EV_REL */
- .ev_code_y = ABS_Y, /* EV_REL */
- .ev_code_z = ABS_Z, /* EV_REL */
- .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */
- .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
- .fifo_mode = ADXL_FIFO_STREAM,
- .watermark = 0,
- };
- #ifdef ADXL_DEBUG
- static ssize_t adxl34x_write_store(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
- {
- struct adxl34x *ac = dev_get_drvdata(dev);
- unsigned int val;
- int error;
- /*
- * This allows basic ADXL register write access for debug purposes.
- */
- error = kstrtouint(buf, 16, &val);
- if (error)
- return error;
- AC_WRITE(ac, val >> 8, val & 0xFF);
- return count;
- }
- static DEVICE_ATTR(write, 0664, NULL, adxl34x_write_store);
- #endif
- static struct attribute *adxl34x_attributes[] = {
- #ifdef ADXL_DEBUG
- &dev_attr_write.attr,
- #endif
- NULL
- };
- static const struct attribute_group adxl34x_attr_group = {
- .attrs = adxl34x_attributes,
- };
- struct adxl34x *adxl34x_probe(struct device *dev, const struct adxl34x_bus_ops *bops)
- {
- struct adxl34x *ac;
- const struct adxl34x_platform_data *pdata;
- int err, range, i;
- unsigned char revid;
- ac = kzalloc(sizeof(*ac), GFP_KERNEL);
- if (!ac) {
- err = -ENOMEM;
- goto err_free_mem;
- }
- pdata = dev_get_platdata(dev);
- if (!pdata) {
- dev_dbg(dev,
- "No platform data: Using default initialization\n");
- pdata = &adxl34x_default_init;
- }
- ac->pdata = *pdata;
- pdata = &ac->pdata;
- ac->dev = dev;
- ac->bops = bops;
- revid = AC_READ(ac, DEVID);
- switch (revid) {
- case ID_ADXL345:
- ac->model = 345;
- break;
- case ID_ADXL346:
- ac->model = 346;
- break;
- default:
- err = -ENODEV;
- goto err_free_mem;
- }
- //IT WILL CREATE A FILE FOR READ AND WRITE ACCORDING TO THE ATTRIBUTES
- err = sysfs_create_group(&dev->kobj, &adxl34x_attr_group);
- return ac;
- err_remove_attr:
- sysfs_remove_group(&dev->kobj, &adxl34x_attr_group);
- err_free_mem:
- kfree(ac);
- err_out:
- return ERR_PTR(err);
- }
- EXPORT_SYMBOL_GPL(adxl34x_probe);
- int adxl34x_remove(struct adxl34x *ac)
- {
- sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
- dev_dbg(ac->dev, "unregistered accelerometer\n");
- kfree(ac);
- return 0;
- }
- EXPORT_SYMBOL_GPL(adxl34x_remove);
- MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
- MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer Driver");
- MODULE_LICENSE("GPL");
Add Comment
Please, Sign In to add comment