mr1989

Untitled

May 13th, 2018
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.23 KB | None | 0 0
  1. /*
  2. * ADXL345/346 Three-Axis Digital Accelerometers
  3. *
  4. * Enter bugs at http://blackfin.uclinux.org/
  5. *
  6. * Copyright (C) 2009 Michael Hennerich, Analog Devices Inc.
  7. * Licensed under the GPL-2 or later.
  8. */
  9.  
  10. #include <linux/device.h>
  11. #include <linux/delay.h>
  12. #include <linux/interrupt.h>
  13. #include <linux/irq.h>
  14. #include <linux/slab.h>
  15. #include <linux/workqueue.h>
  16. #include <linux/input/adxl34x.h>
  17. #include <linux/module.h>
  18.  
  19. #include "adxl34x.h"
  20.  
  21. /* ADXL345/6 Register Map */
  22. #define DEVID 0x00 /* R Device ID */
  23. #define THRESH_TAP 0x1D /* R/W Tap threshold */
  24. #define OFSX 0x1E /* R/W X-axis offset */
  25. #define OFSY 0x1F /* R/W Y-axis offset */
  26. #define OFSZ 0x20 /* R/W Z-axis offset */
  27. #define DUR 0x21 /* R/W Tap duration */
  28. #define LATENT 0x22 /* R/W Tap latency */
  29. #define WINDOW 0x23 /* R/W Tap window */
  30. #define THRESH_ACT 0x24 /* R/W Activity threshold */
  31. #define THRESH_INACT 0x25 /* R/W Inactivity threshold */
  32. #define TIME_INACT 0x26 /* R/W Inactivity time */
  33. #define ACT_INACT_CTL 0x27 /* R/W Axis enable control for activity and */
  34. /* inactivity detection */
  35. #define THRESH_FF 0x28 /* R/W Free-fall threshold */
  36. #define TIME_FF 0x29 /* R/W Free-fall time */
  37. #define TAP_AXES 0x2A /* R/W Axis control for tap/double tap */
  38. #define ACT_TAP_STATUS 0x2B /* R Source of tap/double tap */
  39. #define BW_RATE 0x2C /* R/W Data rate and power mode control */
  40. #define POWER_CTL 0x2D /* R/W Power saving features control */
  41. #define INT_ENABLE 0x2E /* R/W Interrupt enable control */
  42. #define INT_MAP 0x2F /* R/W Interrupt mapping control */
  43. #define INT_SOURCE 0x30 /* R Source of interrupts */
  44. #define DATA_FORMAT 0x31 /* R/W Data format control */
  45. #define DATAX0 0x32 /* R X-Axis Data 0 */
  46. #define DATAX1 0x33 /* R X-Axis Data 1 */
  47. #define DATAY0 0x34 /* R Y-Axis Data 0 */
  48. #define DATAY1 0x35 /* R Y-Axis Data 1 */
  49. #define DATAZ0 0x36 /* R Z-Axis Data 0 */
  50. #define DATAZ1 0x37 /* R Z-Axis Data 1 */
  51. #define FIFO_CTL 0x38 /* R/W FIFO control */
  52. #define FIFO_STATUS 0x39 /* R FIFO status */
  53. #define TAP_SIGN 0x3A /* R Sign and source for tap/double tap */
  54. /* Orientation ADXL346 only */
  55. #define ORIENT_CONF 0x3B /* R/W Orientation configuration */
  56. #define ORIENT 0x3C /* R Orientation status */
  57.  
  58. /* DEVIDs */
  59. #define ID_ADXL345 0xE5
  60. #define ID_ADXL346 0xE6
  61.  
  62. /* INT_ENABLE/INT_MAP/INT_SOURCE Bits */
  63. #define DATA_READY (1 << 7)
  64. #define SINGLE_TAP (1 << 6)
  65. #define DOUBLE_TAP (1 << 5)
  66. #define ACTIVITY (1 << 4)
  67. #define INACTIVITY (1 << 3)
  68. #define FREE_FALL (1 << 2)
  69. #define WATERMARK (1 << 1)
  70. #define OVERRUN (1 << 0)
  71.  
  72. /* ACT_INACT_CONTROL Bits */
  73. #define ACT_ACDC (1 << 7)
  74. #define ACT_X_EN (1 << 6)
  75. #define ACT_Y_EN (1 << 5)
  76. #define ACT_Z_EN (1 << 4)
  77. #define INACT_ACDC (1 << 3)
  78. #define INACT_X_EN (1 << 2)
  79. #define INACT_Y_EN (1 << 1)
  80. #define INACT_Z_EN (1 << 0)
  81.  
  82. /* TAP_AXES Bits */
  83. #define SUPPRESS (1 << 3)
  84. #define TAP_X_EN (1 << 2)
  85. #define TAP_Y_EN (1 << 1)
  86. #define TAP_Z_EN (1 << 0)
  87.  
  88. /* ACT_TAP_STATUS Bits */
  89. #define ACT_X_SRC (1 << 6)
  90. #define ACT_Y_SRC (1 << 5)
  91. #define ACT_Z_SRC (1 << 4)
  92. #define ASLEEP (1 << 3)
  93. #define TAP_X_SRC (1 << 2)
  94. #define TAP_Y_SRC (1 << 1)
  95. #define TAP_Z_SRC (1 << 0)
  96.  
  97. /* BW_RATE Bits */
  98. #define LOW_POWER (1 << 4)
  99. #define RATE(x) ((x) & 0xF)
  100.  
  101. /* POWER_CTL Bits */
  102. #define PCTL_LINK (1 << 5)
  103. #define PCTL_AUTO_SLEEP (1 << 4)
  104. #define PCTL_MEASURE (1 << 3)
  105. #define PCTL_SLEEP (1 << 2)
  106. #define PCTL_WAKEUP(x) ((x) & 0x3)
  107.  
  108. /* DATA_FORMAT Bits */
  109. #define SELF_TEST (1 << 7)
  110. #define SPI (1 << 6)
  111. #define INT_INVERT (1 << 5)
  112. #define FULL_RES (1 << 3)
  113. #define JUSTIFY (1 << 2)
  114. #define RANGE(x) ((x) & 0x3)
  115. #define RANGE_PM_2g 0
  116. #define RANGE_PM_4g 1
  117. #define RANGE_PM_8g 2
  118. #define RANGE_PM_16g 3
  119.  
  120. /*
  121. * Maximum value our axis may get in full res mode for the input device
  122. * (signed 13 bits)
  123. */
  124. #define ADXL_FULLRES_MAX_VAL 4096
  125.  
  126. /*
  127. * Maximum value our axis may get in fixed res mode for the input device
  128. * (signed 10 bits)
  129. */
  130.  
  131. #define ADXL_DEBUG
  132.  
  133. #define ADXL_X_AXIS 0
  134. #define ADXL_Y_AXIS 1
  135. #define ADXL_Z_AXIS 2
  136.  
  137. #define AC_READ(ac, reg) ((ac)->bops->read((ac)->dev, reg))
  138. #define AC_WRITE(ac, reg, val) ((ac)->bops->write((ac)->dev, reg, val))
  139.  
  140. struct axis_triple {
  141. int x;
  142. int y;
  143. int z;
  144. };
  145.  
  146. struct adxl34x {
  147. struct device *dev;
  148. struct adxl34x_platform_data pdata;
  149. unsigned model;
  150. const struct adxl34x_bus_ops *bops;
  151. };
  152.  
  153. static const struct adxl34x_platform_data adxl34x_default_init = {
  154. .tap_threshold = 35,
  155. .tap_duration = 3,
  156. .tap_latency = 20,
  157. .tap_window = 20,
  158. .tap_axis_control = ADXL_TAP_X_EN | ADXL_TAP_Y_EN | ADXL_TAP_Z_EN,
  159. .act_axis_control = 0xFF,
  160. .activity_threshold = 6,
  161. .inactivity_threshold = 4,
  162. .inactivity_time = 3,
  163. .free_fall_threshold = 8,
  164. .free_fall_time = 0x20,
  165. .data_rate = 8,
  166. .data_range = ADXL_FULL_RES,
  167.  
  168. .ev_type = EV_ABS,
  169. .ev_code_x = ABS_X, /* EV_REL */
  170. .ev_code_y = ABS_Y, /* EV_REL */
  171. .ev_code_z = ABS_Z, /* EV_REL */
  172.  
  173. .ev_code_tap = {BTN_TOUCH, BTN_TOUCH, BTN_TOUCH}, /* EV_KEY {x,y,z} */
  174. .power_mode = ADXL_AUTO_SLEEP | ADXL_LINK,
  175. .fifo_mode = ADXL_FIFO_STREAM,
  176. .watermark = 0,
  177. };
  178.  
  179. #ifdef ADXL_DEBUG
  180. static ssize_t adxl34x_write_store(struct device *dev,
  181. struct device_attribute *attr,
  182. const char *buf, size_t count)
  183. {
  184. struct adxl34x *ac = dev_get_drvdata(dev);
  185. unsigned int val;
  186. int error;
  187.  
  188. /*
  189. * This allows basic ADXL register write access for debug purposes.
  190. */
  191. error = kstrtouint(buf, 16, &val);
  192. if (error)
  193. return error;
  194.  
  195. AC_WRITE(ac, val >> 8, val & 0xFF);
  196.  
  197. return count;
  198. }
  199.  
  200. static DEVICE_ATTR(write, 0664, NULL, adxl34x_write_store);
  201. #endif
  202.  
  203. static struct attribute *adxl34x_attributes[] = {
  204. #ifdef ADXL_DEBUG
  205. &dev_attr_write.attr,
  206. #endif
  207. NULL
  208. };
  209.  
  210. static const struct attribute_group adxl34x_attr_group = {
  211. .attrs = adxl34x_attributes,
  212. };
  213.  
  214. struct adxl34x *adxl34x_probe(struct device *dev, const struct adxl34x_bus_ops *bops)
  215. {
  216. struct adxl34x *ac;
  217. const struct adxl34x_platform_data *pdata;
  218. int err, range, i;
  219. unsigned char revid;
  220.  
  221. ac = kzalloc(sizeof(*ac), GFP_KERNEL);
  222.  
  223. if (!ac) {
  224. err = -ENOMEM;
  225. goto err_free_mem;
  226. }
  227.  
  228. pdata = dev_get_platdata(dev);
  229. if (!pdata) {
  230. dev_dbg(dev,
  231. "No platform data: Using default initialization\n");
  232. pdata = &adxl34x_default_init;
  233. }
  234.  
  235. ac->pdata = *pdata;
  236. pdata = &ac->pdata;
  237.  
  238. ac->dev = dev;
  239. ac->bops = bops;
  240.  
  241. revid = AC_READ(ac, DEVID);
  242.  
  243. switch (revid) {
  244. case ID_ADXL345:
  245. ac->model = 345;
  246. break;
  247. case ID_ADXL346:
  248. ac->model = 346;
  249. break;
  250. default:
  251. err = -ENODEV;
  252. goto err_free_mem;
  253. }
  254. //IT WILL CREATE A FILE FOR READ AND WRITE ACCORDING TO THE ATTRIBUTES
  255. err = sysfs_create_group(&dev->kobj, &adxl34x_attr_group);
  256.  
  257.  
  258. return ac;
  259.  
  260. err_remove_attr:
  261. sysfs_remove_group(&dev->kobj, &adxl34x_attr_group);
  262. err_free_mem:
  263. kfree(ac);
  264. err_out:
  265. return ERR_PTR(err);
  266. }
  267. EXPORT_SYMBOL_GPL(adxl34x_probe);
  268.  
  269. int adxl34x_remove(struct adxl34x *ac)
  270. {
  271. sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
  272. dev_dbg(ac->dev, "unregistered accelerometer\n");
  273. kfree(ac);
  274.  
  275. return 0;
  276. }
  277. EXPORT_SYMBOL_GPL(adxl34x_remove);
  278.  
  279. MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
  280. MODULE_DESCRIPTION("ADXL345/346 Three-Axis Digital Accelerometer Driver");
  281. MODULE_LICENSE("GPL");
Add Comment
Please, Sign In to add comment