da380.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095
  1. #include <linux/kernel.h>
  2. #include <linux/module.h>
  3. #include <linux/device.h>
  4. #include <linux/input.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/slab.h>
  7. #include <linux/i2c.h>
  8. #include <linux/delay.h>
  9. #include <linux/gpio.h>
  10. #include <linux/of.h>
  11. #include <linux/of_gpio.h>
  12. #include <linux/workqueue.h>
  13. #include <linux/cdev.h>
  14. #include <linux/device.h>
  15. #include <linux/poll.h>
  16. struct gsensor_data {
  17. short x;
  18. short y;
  19. short z;
  20. short delta_x;
  21. short delta_y;
  22. short delta_z;
  23. };
  24. enum _GSENSOR_SENSITIVITY_LEVEL
  25. {
  26. GSENSOR_OFF = 0,
  27. GSENSOR_LOW,
  28. GSENSOR_MED,
  29. GSENSOR_HIGH,
  30. GSENSOR_ID_MAX
  31. };
  32. enum {
  33. GSENSOR_I2C_GPIO_OUTPUT,
  34. GSENSOR_I2C_GPIO_INPUT
  35. };
  36. enum int_latch{
  37. NONE_LATCH = 0,
  38. LATCH_250MS,
  39. LATCH_500MS,
  40. LATCH_1S,
  41. LATCH_2S,
  42. LATCH_4S,
  43. LATCH_8S,
  44. LATCH_1MS = 10,
  45. LATCH_2MS,
  46. LATCH_25MS,
  47. LATCH_50MS,
  48. LATCH_100MS,
  49. LATCHED
  50. };
  51. //register
  52. #define NSA_REG_SPI_I2C 0x00
  53. #define NSA_REG_WHO_AM_I 0x01
  54. #define NSA_REG_ACC_X_LSB 0x02
  55. #define NSA_REG_ACC_X_MSB 0x03
  56. #define NSA_REG_ACC_Y_LSB 0x04
  57. #define NSA_REG_ACC_Y_MSB 0x05
  58. #define NSA_REG_ACC_Z_LSB 0x06
  59. #define NSA_REG_ACC_Z_MSB 0x07
  60. #define NSA_REG_MOTION_FLAG 0x09
  61. #define NSA_REG_G_RANGE 0x0f
  62. #define NSA_REG_ODR_AXIS_DISABLE 0x10
  63. #define NSA_REG_POWERMODE_BW 0x11
  64. #define NSA_REG_SWAP_POLARITY 0x12
  65. #define NSA_REG_FIFO_CTRL 0x14
  66. #define NSA_REG_INTERRUPT_SETTINGS1 0x16
  67. #define NSA_REG_INTERRUPT_SETTINGS2 0x17
  68. #define NSA_REG_INTERRUPT_MAPPING1 0x19
  69. #define NSA_REG_INTERRUPT_MAPPING2 0x1a
  70. #define NSA_REG_INTERRUPT_MAPPING3 0x1b
  71. #define NSA_REG_INT_PIN_CONFIG 0x20
  72. #define NSA_REG_INT_LATCH 0x21
  73. #define NSA_REG_ACTIVE_DURATION 0x27
  74. #define NSA_REG_ACTIVE_THRESHOLD 0x28
  75. #define NSA_REG_TAP_DURATION 0x2A
  76. #define NSA_REG_TAP_THRESHOLD 0x2B
  77. #define NSA_REG_CUSTOM_OFFSET_X 0x38
  78. #define NSA_REG_CUSTOM_OFFSET_Y 0x39
  79. #define NSA_REG_CUSTOM_OFFSET_Z 0x3a
  80. #define NSA_REG_ENGINEERING_MODE 0x7f
  81. #define NSA_REG_SENSITIVITY_TRIM_X 0x80
  82. #define NSA_REG_SENSITIVITY_TRIM_Y 0x81
  83. #define NSA_REG_SENSITIVITY_TRIM_Z 0x82
  84. #define NSA_REG_COARSE_OFFSET_TRIM_X 0x83
  85. #define NSA_REG_COARSE_OFFSET_TRIM_Y 0x84
  86. #define NSA_REG_COARSE_OFFSET_TRIM_Z 0x85
  87. #define NSA_REG_FINE_OFFSET_TRIM_X 0x86
  88. #define NSA_REG_FINE_OFFSET_TRIM_Y 0x87
  89. #define NSA_REG_FINE_OFFSET_TRIM_Z 0x88
  90. #define NSA_REG_SENS_COMP 0x8c
  91. #define NSA_REG_SENS_COARSE_TRIM 0xd1
  92. // Ioctl command definition
  93. #define GSENSOR_IOCTL_BASE 0xA0
  94. #define GSENSOR_IOCTL_SET_G_RANGE _IOW(GSENSOR_IOCTL_BASE, 0, int)
  95. #define GSENSOR_IOCTL_GET_G_RANGE _IOW(GSENSOR_IOCTL_BASE, 1, int)
  96. #define GSENSOR_IOCTL_GET_GSENSOR_DATA _IOW(GSENSOR_IOCTL_BASE, 2, struct gsensor_data)
  97. #define GSENSOR_IOCTL_GET_BOOT_STATE _IOW(GSENSOR_IOCTL_BASE, 3, int)
  98. #define GSENSOR_IOCTL_SET_INT_LATCH _IOW(GSENSOR_IOCTL_BASE, 4, int)
  99. #define GSENSOR_IOCTL_SET_I2C_GPIO_DIRECTION _IOW(GSENSOR_IOCTL_BASE, 5, int)
  100. #define GSENSOR_IOCTL_SET_LOW_POWER_MODE _IOW(GSENSOR_IOCTL_BASE, 6, int)
  101. //#define DA380_SLAVE_ADDRESS 0x4e
  102. #define DA380_DEFAULT_G_RANGE GSENSOR_HIGH
  103. #define DA380_DEBUG(fmt,arg...) do{ \
  104. if(1) printk(KERN_ALERT "###"fmt,##arg); \
  105. }while(0)
  106. struct da380_private_data {
  107. struct i2c_client *i2c_client;
  108. struct workqueue_struct *work_queue;
  109. struct work_struct work;
  110. struct delayed_work delay_work;
  111. spinlock_t spinlock;
  112. int i2c_gpio_direction;
  113. int gpio_sda;
  114. int gpio_scl;
  115. int gpio_irq;
  116. struct gsensor_data g_data;
  117. short threhold[4];
  118. volatile int is_collision;
  119. int tmp_collision;
  120. int g_range;
  121. //cdev
  122. struct cdev cdev;
  123. struct class *da380_class;
  124. struct device *da380_device;
  125. const char *name;
  126. int major;
  127. int minor_start;
  128. int minor_num;
  129. int num;
  130. int boot_state;
  131. wait_queue_head_t da380_waitq;
  132. };
  133. static struct da380_private_data *g_da380_pdata = NULL;
  134. static int da380_debug = 0;
  135. static unsigned char mir3da_register_read (unsigned char addr,char *rxdata)
  136. {
  137. #if 1
  138. struct i2c_msg msgs[2];
  139. int retries = 0;
  140. char buf[2];
  141. int ret = -1;
  142. if(g_da380_pdata && rxdata)
  143. {
  144. buf[0] = (addr&0xFF);
  145. msgs[0].flags = !I2C_M_RD;
  146. msgs[0].addr = g_da380_pdata->i2c_client->addr;
  147. msgs[0].len = 1;
  148. msgs[0].buf = buf;
  149. msgs[1].flags = I2C_M_RD;
  150. msgs[1].addr = g_da380_pdata->i2c_client->addr;
  151. msgs[1].len = 1;
  152. msgs[1].buf = rxdata;
  153. while(retries < 5)
  154. {
  155. if(i2c_transfer(g_da380_pdata->i2c_client->adapter, msgs, 2) == 2)
  156. {
  157. //if(da380_debug)
  158. //DA380_DEBUG("%s read addr:0x%x,val:0x%x\n",__FUNCTION__, addr, buf[0]);
  159. ret = 0;
  160. break;
  161. }
  162. retries++;
  163. }
  164. if(retries >= 5)
  165. printk(KERN_ERR "%s timeout read reg:0x%x\n", __FUNCTION__, addr);
  166. if(g_da380_pdata->i2c_gpio_direction == GSENSOR_I2C_GPIO_INPUT)
  167. {
  168. if(gpio_is_valid(g_da380_pdata->gpio_scl) && gpio_is_valid(g_da380_pdata->gpio_sda))
  169. {
  170. gpio_direction_input(g_da380_pdata->gpio_scl);
  171. gpio_direction_input(g_da380_pdata->gpio_sda);
  172. }
  173. }
  174. }
  175. return ret;
  176. #else
  177. *rxdata = i2c_smbus_read_byte_data(g_da380_pdata->i2c_client, addr);
  178. return 0;
  179. #endif
  180. }
  181. static int mir3da_register_write (unsigned char addr, unsigned char data)
  182. {
  183. #if 1
  184. struct i2c_msg msg;
  185. u8 retries = 0;
  186. u8 buf[2];
  187. int ret = -1;
  188. if(g_da380_pdata)
  189. {
  190. buf[0] = (addr&0xFF);
  191. buf[1] = (data&0xFF);
  192. msg.flags = !I2C_M_RD;
  193. msg.addr = g_da380_pdata->i2c_client->addr;
  194. msg.len = sizeof(buf);
  195. msg.buf = buf;
  196. while(retries < 5)
  197. {
  198. if(i2c_transfer(g_da380_pdata->i2c_client->adapter, &msg, 1) == 1)
  199. {
  200. //if(da380_debug)
  201. //DA380_DEBUG("%s write addr:0x%x,val:0x%x\n",__FUNCTION__, addr, data);
  202. ret = 0;
  203. break;
  204. }
  205. retries++;
  206. }
  207. if(retries >= 5)
  208. printk(KERN_ERR "%s timeout\n", __FUNCTION__);
  209. if(g_da380_pdata->i2c_gpio_direction == GSENSOR_I2C_GPIO_INPUT)
  210. {
  211. if(gpio_is_valid(g_da380_pdata->gpio_scl) && gpio_is_valid(g_da380_pdata->gpio_sda))
  212. {
  213. gpio_direction_input(g_da380_pdata->gpio_scl);
  214. gpio_direction_input(g_da380_pdata->gpio_sda);
  215. }
  216. }
  217. }
  218. return ret;
  219. #else
  220. //return i2c_smbus_write_byte_data(g_da380_pdata->i2c_client, addr, data);
  221. return da380_i2c_write(addr, data);
  222. #endif
  223. }
  224. static int mir3da_register_mask_write(unsigned char addr, unsigned char mask, unsigned char data)
  225. {
  226. int res = 0;
  227. unsigned char tmp_data;
  228. mir3da_register_read(addr, &tmp_data);
  229. tmp_data &= ~mask;
  230. tmp_data |= (data & mask);
  231. res = mir3da_register_write(addr, tmp_data);
  232. return res;
  233. }
  234. /*return value: 0: is count other: is failed*/
  235. static int i2c_read_block_data( unsigned char base_addr, unsigned char count, unsigned char *data)
  236. {
  237. int i = 0;
  238. for(i = 0; i < count;i++)
  239. {
  240. //if(mir3da_read_byte_data(base_addr+i,(data+i)))
  241. if(mir3da_register_read(base_addr+i,(data+i)))
  242. {
  243. return -1;
  244. }
  245. }
  246. return count;
  247. }
  248. static int mir3da_register_read_continuously( unsigned char addr, unsigned char count, unsigned char *data)
  249. {
  250. int res = 0;
  251. res = ((count==i2c_read_block_data(addr, count, data)) ? 0 : 1);
  252. return res;
  253. }
  254. /*return value: 0: is ok other: is failed*/
  255. static int mir3da_read_data(short *x, short *y, short *z)
  256. {
  257. unsigned char tmp_data[6] = {0};
  258. if (mir3da_register_read_continuously(NSA_REG_ACC_X_LSB, 6, tmp_data) != 0) {
  259. return -1;
  260. }
  261. *x = ((short)(tmp_data[1] << 8 | tmp_data[0]))>> 4;
  262. *y = ((short)(tmp_data[3] << 8 | tmp_data[2]))>> 4;
  263. *z = ((short)(tmp_data[5] << 8 | tmp_data[4]))>> 4;
  264. if(da380_debug)
  265. DA380_DEBUG("oringnal x y z %d %d %d\n",*x,*y,*z);
  266. return 0;
  267. }
  268. static int mir3da_set_enable(char enable)
  269. {
  270. int res = 0;
  271. if(enable)
  272. {
  273. //res = mir3da_register_mask_write(NSA_REG_POWERMODE_BW,0xC0,0x40); //low power mode
  274. res = mir3da_register_mask_write(NSA_REG_POWERMODE_BW,0xC0,0x0); //normal power mode
  275. }
  276. else
  277. {
  278. res = mir3da_register_mask_write(NSA_REG_POWERMODE_BW,0xC0,0x80); //suspend power mode
  279. }
  280. return res;
  281. }
  282. static int mir3da_open_interrupt(int num)
  283. {
  284. int res = 0;
  285. res = mir3da_register_write(NSA_REG_INTERRUPT_SETTINGS1,0x07);
  286. //0x03->active_int_en_y,active_int_en_x;0x07->active_int_en_z,active_int_en_y,active_int_en_x
  287. res = mir3da_register_write(NSA_REG_ACTIVE_DURATION,0x03 );
  288. res = mir3da_register_write(NSA_REG_ACTIVE_THRESHOLD,0x2B/*0x1B*/);
  289. switch(num){
  290. case 0:
  291. res = mir3da_register_write(NSA_REG_INTERRUPT_MAPPING1,0x04 );
  292. break;
  293. case 1:
  294. res = mir3da_register_write(NSA_REG_INTERRUPT_MAPPING3,0x04 );
  295. break;
  296. default:
  297. res = -1;
  298. break;
  299. }
  300. return res;
  301. }
  302. static int mir3da_init(void)
  303. {
  304. int res = 0;
  305. res |=mir3da_register_mask_write(NSA_REG_SPI_I2C, 0x24, 0x24);
  306. mdelay(5);
  307. #if 0
  308. res |=mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 0x02/*0x00*/);// 00: +/-2g. 01: +/-4g 10:+/-8g 11:+/-16g
  309. #else
  310. if(g_da380_pdata->g_range == GSENSOR_LOW)
  311. mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 0);
  312. else if(g_da380_pdata->g_range == GSENSOR_MED)
  313. mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 1);
  314. else //if(g_da380_pdata->g_range == GSENSOR_HIGH)
  315. mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 2);
  316. #endif
  317. //res |=mir3da_register_mask_write(NSA_REG_POWERMODE_BW, 0xFF, 0x5E);
  318. res |=mir3da_register_mask_write(NSA_REG_POWERMODE_BW, 0xFF, 0x1E); //normal power mode
  319. res |=mir3da_register_mask_write(NSA_REG_ODR_AXIS_DISABLE, 0xFF, 0x06);
  320. res |=mir3da_register_mask_write(NSA_REG_INT_PIN_CONFIG, 0x0F, 0x01);//set int_pin level
  321. //res |=mir3da_register_mask_write(NSA_REG_INT_LATCH, 0x8F, 0x81);//clear latch and set latch mode
  322. res |=mir3da_register_mask_write(NSA_REG_INT_LATCH, 0x8F, 0x80|NONE_LATCH);//clear latch and set latch mode
  323. //0x81->250ms,0x82->500ms,0x83->1s,0x84->2s,0x85->4s,0x86->8s,0x8f yiz
  324. res |=mir3da_register_mask_write(NSA_REG_ENGINEERING_MODE, 0xFF, 0x83);
  325. res |=mir3da_register_mask_write(NSA_REG_ENGINEERING_MODE, 0xFF, 0x69);
  326. res |=mir3da_register_mask_write(NSA_REG_ENGINEERING_MODE, 0xFF, 0xBD);
  327. res |=mir3da_register_mask_write(NSA_REG_SWAP_POLARITY, 0xFF, 0x00);
  328. mdelay(10);
  329. return res;
  330. }
  331. static void da380_open_parking_interrupt(int enable)
  332. {
  333. mir3da_init();
  334. mir3da_open_interrupt(0);
  335. if(g_da380_pdata->g_range > GSENSOR_OFF)
  336. {
  337. mir3da_set_enable(1);
  338. }
  339. else
  340. {
  341. mir3da_set_enable(0);
  342. }
  343. mir3da_read_data(&g_da380_pdata->g_data.x,&g_da380_pdata->g_data.y,&g_da380_pdata->g_data.z);
  344. if(da380_debug)
  345. DA380_DEBUG("prev x y z %d %d %d\n",g_da380_pdata->g_data.x,g_da380_pdata->g_data.y,g_da380_pdata->g_data.z);
  346. }
  347. static int da380_identify (void)
  348. {
  349. unsigned char cid = 0, mid = 0;
  350. int loop = 5;
  351. while(loop > 0)
  352. {
  353. mir3da_register_read(NSA_REG_WHO_AM_I,&cid);
  354. mir3da_register_read(NSA_REG_FIFO_CTRL,&mid);
  355. if((cid == 0x13)&&(mid == 0x00))
  356. {
  357. break;
  358. }
  359. loop --;
  360. }
  361. if(loop == 0)
  362. {
  363. return -1;
  364. }
  365. else
  366. {
  367. return 0;
  368. }
  369. }
  370. static void da380_select_pad(void)
  371. {
  372. #if 0
  373. //interrupt pin gpio59
  374. rSYS_PAD_CTRL05 &= ~(0xf<<21);
  375. //SCL pin gpio60
  376. rSYS_PAD_CTRL05 &= ~(0xf<<24);
  377. //SDA pin gpio61
  378. rSYS_PAD_CTRL05 &= ~(0xf<<27);
  379. #endif
  380. }
  381. #if 0
  382. static void da380_work(struct work_struct *work)
  383. {
  384. struct da380_private_data *da380_pdata = container_of(work, struct da380_private_data, work);
  385. short x = 0, y = 0, z = 0;
  386. int level;
  387. if(!da380_pdata)
  388. return -ENODEV;
  389. spin_lock(&da380_pdata->spinlock);
  390. if(mir3da_read_data(&x,&y,&z))
  391. return;
  392. level = da380_pdata->g_range;
  393. if(da380_debug)
  394. {
  395. DA380_DEBUG("old (%d, %d, %d), new (%d, %d, %d)\n", da380_pdata->g_data.x, da380_pdata->g_data.y, da380_pdata->g_data.z, x, y, z);
  396. DA380_DEBUG("dif (%d, %d, %d)\n", abs(x - da380_pdata->g_data.x), abs(y - da380_pdata->g_data.y), abs(z - da380_pdata->g_data.z));
  397. }
  398. da380_pdata->g_data.delta_x = abs(x - da380_pdata->g_data.x);
  399. da380_pdata->g_data.delta_y = abs(y - da380_pdata->g_data.y);
  400. da380_pdata->g_data.delta_z = abs(z - da380_pdata->g_data.z);
  401. if((da380_pdata->g_data.delta_x > da380_pdata->threhold[level])||
  402. (da380_pdata->g_data.delta_y > da380_pdata->threhold[level])||
  403. (da380_pdata->g_data.delta_z > da380_pdata->threhold[level]))
  404. da380_pdata->is_collision = 1;
  405. da380_pdata->g_data.x = x;
  406. da380_pdata->g_data.y = y;
  407. da380_pdata->g_data.z = z;
  408. spin_unlock(&da380_pdata->spinlock);
  409. }
  410. #else
  411. static void da380_work(struct work_struct *work)
  412. {
  413. struct da380_private_data *da380_pdata = container_of(work, struct da380_private_data, work);
  414. short x = 0, y = 0, z = 0;
  415. int level;
  416. if(!da380_pdata)
  417. return;
  418. spin_lock(&da380_pdata->spinlock);
  419. if(mir3da_read_data(&x,&y,&z))
  420. {
  421. spin_unlock(&da380_pdata->spinlock);
  422. return;
  423. }
  424. cancel_delayed_work(&da380_pdata->delay_work);
  425. da380_pdata->tmp_collision = 0;
  426. level = da380_pdata->g_range;
  427. if(da380_debug)
  428. {
  429. DA380_DEBUG("work: old(%d, %d, %d),new(%d, %d, %d),diff(%d, %d, %d)\n",
  430. da380_pdata->g_data.x, da380_pdata->g_data.y, da380_pdata->g_data.z, x, y, z,
  431. abs(x - da380_pdata->g_data.x), abs(y - da380_pdata->g_data.y), abs(z - da380_pdata->g_data.z));
  432. }
  433. da380_pdata->g_data.delta_x = abs(x - da380_pdata->g_data.x);
  434. da380_pdata->g_data.delta_y = abs(y - da380_pdata->g_data.y);
  435. da380_pdata->g_data.delta_z = abs(z - da380_pdata->g_data.z);
  436. if((da380_pdata->g_data.delta_x > da380_pdata->threhold[level])||
  437. (da380_pdata->g_data.delta_y > da380_pdata->threhold[level])||
  438. (da380_pdata->g_data.delta_z > da380_pdata->threhold[level]))
  439. {
  440. da380_pdata->is_collision = 1;
  441. da380_pdata->tmp_collision = 1;
  442. schedule_delayed_work(&da380_pdata->delay_work, msecs_to_jiffies(5000));
  443. }
  444. else
  445. {
  446. schedule_delayed_work(&da380_pdata->delay_work, msecs_to_jiffies(1000));
  447. }
  448. da380_pdata->g_data.x = x;
  449. da380_pdata->g_data.y = y;
  450. da380_pdata->g_data.z = z;
  451. spin_unlock(&da380_pdata->spinlock);
  452. }
  453. #endif
  454. static void da380_delay_work(struct work_struct *work)
  455. {
  456. struct da380_private_data *da380_pdata = container_of(work, struct da380_private_data, delay_work.work);
  457. short x = 0, y = 0, z = 0;
  458. int level;
  459. if(!da380_pdata)
  460. return;
  461. spin_lock(&da380_pdata->spinlock);
  462. if(mir3da_read_data(&x,&y,&z))
  463. {
  464. spin_unlock(&da380_pdata->spinlock);
  465. return;
  466. }
  467. level = da380_pdata->g_range;
  468. if(da380_debug)
  469. {
  470. DA380_DEBUG("delay_work: old(%d, %d, %d),new(%d, %d, %d),diff(%d, %d, %d)\n\n",
  471. da380_pdata->g_data.x, da380_pdata->g_data.y, da380_pdata->g_data.z, x, y, z,
  472. abs(x - da380_pdata->g_data.x), abs(y - da380_pdata->g_data.y), abs(z - da380_pdata->g_data.z));
  473. }
  474. da380_pdata->g_data.delta_x = abs(x - da380_pdata->g_data.x);
  475. da380_pdata->g_data.delta_y = abs(y - da380_pdata->g_data.y);
  476. da380_pdata->g_data.delta_z = abs(z - da380_pdata->g_data.z);
  477. if(!da380_pdata->tmp_collision) //have not collision in da380_work.
  478. {
  479. if((da380_pdata->g_data.delta_x > da380_pdata->threhold[level])||
  480. (da380_pdata->g_data.delta_y > da380_pdata->threhold[level])||
  481. (da380_pdata->g_data.delta_z > da380_pdata->threhold[level]))
  482. {
  483. da380_pdata->is_collision = 1;
  484. }
  485. }
  486. da380_pdata->g_data.x = x;
  487. da380_pdata->g_data.y = y;
  488. da380_pdata->g_data.z = z;
  489. spin_unlock(&da380_pdata->spinlock);
  490. }
  491. static irqreturn_t da380_irq_handler(int irq, void *data)
  492. {
  493. struct da380_private_data *da380_pdata = (struct da380_private_data *)data;
  494. if(da380_pdata)
  495. queue_work(da380_pdata->work_queue, &da380_pdata->work);
  496. return IRQ_HANDLED;
  497. }
  498. static int da380_open(struct inode *inode, struct file *filp)
  499. {
  500. struct da380_private_data *da380_pdata = container_of(inode->i_cdev, struct da380_private_data, cdev);
  501. filp->private_data = da380_pdata;
  502. return 0;
  503. }
  504. static int da380_release(struct inode *inode, struct file *filp)
  505. {
  506. //struct da380_private_data *da380_pdata = container_of(inode->i_cdev, struct da380_private_data, cdev);
  507. filp->private_data = NULL;
  508. return 0;
  509. }
  510. static long da380_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  511. {
  512. struct da380_private_data *da380_pdata = (struct da380_private_data *)filp->private_data;
  513. int ret = 0;
  514. if(!da380_pdata)
  515. return -ENODEV;
  516. spin_lock(&da380_pdata->spinlock);
  517. switch (cmd)
  518. {
  519. case GSENSOR_IOCTL_GET_GSENSOR_DATA:
  520. {
  521. if (copy_to_user((unsigned char *)arg, (unsigned char *)&da380_pdata->g_data, sizeof(struct gsensor_data))) {
  522. printk("%s %d: copy_to_user error\n", __FUNCTION__, __LINE__);
  523. ret = -EINVAL;
  524. break;
  525. }
  526. break;
  527. }
  528. case GSENSOR_IOCTL_SET_G_RANGE:
  529. {
  530. int level = da380_pdata->g_range;
  531. if(level == arg)
  532. break;
  533. switch(arg)
  534. {
  535. case GSENSOR_OFF:
  536. ret = mir3da_set_enable(0);
  537. if(!ret)
  538. da380_pdata->g_range = arg;
  539. break;
  540. case GSENSOR_LOW:
  541. ret = mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 0);
  542. if(!ret)
  543. {
  544. da380_pdata->g_range = arg;
  545. if(level == GSENSOR_OFF)
  546. mir3da_set_enable(1);
  547. }
  548. break;
  549. case GSENSOR_MED:
  550. ret = mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 1);
  551. if(!ret)
  552. {
  553. da380_pdata->g_range = arg;
  554. if(level == GSENSOR_OFF)
  555. mir3da_set_enable(1);
  556. }
  557. break;
  558. case GSENSOR_HIGH:
  559. ret = mir3da_register_mask_write(NSA_REG_G_RANGE, 0x03, 2);
  560. if(!ret)
  561. {
  562. da380_pdata->g_range = arg;
  563. if(level == GSENSOR_OFF)
  564. mir3da_set_enable(1);
  565. }
  566. break;
  567. default:
  568. ret = -EINVAL;
  569. break;
  570. }
  571. break;
  572. }
  573. case GSENSOR_IOCTL_GET_G_RANGE:
  574. {
  575. if (copy_to_user((unsigned char *)arg, (unsigned char *)&da380_pdata->g_range, sizeof(int))) {
  576. printk("%s %d: copy_to_user error\n", __FUNCTION__, __LINE__);
  577. ret = -EINVAL;
  578. break;
  579. }
  580. break;
  581. }
  582. case GSENSOR_IOCTL_GET_BOOT_STATE:
  583. {
  584. if (copy_to_user((unsigned char *)arg, (unsigned char *)&da380_pdata->boot_state, sizeof(int))) {
  585. printk("%s %d: copy_to_user error\n", __FUNCTION__, __LINE__);
  586. ret = -EINVAL;
  587. break;
  588. }
  589. break;
  590. }
  591. case GSENSOR_IOCTL_SET_INT_LATCH:
  592. {
  593. switch(arg)
  594. {
  595. case NONE_LATCH:
  596. case LATCH_250MS:
  597. case LATCH_500MS:
  598. case LATCH_1S:
  599. case LATCH_2S:
  600. case LATCH_4S:
  601. case LATCH_8S:
  602. case LATCH_1MS:
  603. case LATCH_2MS:
  604. case LATCH_25MS:
  605. case LATCH_50MS:
  606. case LATCH_100MS:
  607. case LATCHED:
  608. {
  609. unsigned char value = (arg&0x0f);
  610. ret = mir3da_register_mask_write(NSA_REG_INT_LATCH, 0x8F, 0x80|value);
  611. break;
  612. }
  613. default:
  614. ret = -EBUSY;
  615. break;
  616. }
  617. break;
  618. }
  619. case GSENSOR_IOCTL_SET_I2C_GPIO_DIRECTION:
  620. {
  621. if(arg == GSENSOR_I2C_GPIO_INPUT)
  622. {
  623. mir3da_register_mask_write(NSA_REG_POWERMODE_BW,0xC0,0x40); //low power mode
  624. if(gpio_is_valid(da380_pdata->gpio_scl) && gpio_is_valid(da380_pdata->gpio_sda))
  625. {
  626. da380_pdata->i2c_gpio_direction = GSENSOR_I2C_GPIO_INPUT;
  627. gpio_direction_input(da380_pdata->gpio_scl);
  628. gpio_direction_input(da380_pdata->gpio_sda);
  629. }
  630. }
  631. else
  632. {
  633. if(gpio_is_valid(da380_pdata->gpio_scl) && gpio_is_valid(da380_pdata->gpio_sda))
  634. {
  635. da380_pdata->i2c_gpio_direction = GSENSOR_I2C_GPIO_OUTPUT;
  636. gpio_direction_output(da380_pdata->gpio_scl, 1);
  637. gpio_direction_output(da380_pdata->gpio_sda, 1);
  638. }
  639. }
  640. break;
  641. }
  642. case GSENSOR_IOCTL_SET_LOW_POWER_MODE:
  643. {
  644. ret = mir3da_register_mask_write(NSA_REG_POWERMODE_BW,0xC0,0x40); //low power mode
  645. break;
  646. }
  647. default:
  648. ret = -EINVAL;
  649. break;
  650. }
  651. spin_unlock(&da380_pdata->spinlock);
  652. return ret;
  653. }
  654. static unsigned int da380_poll(struct file *filp, poll_table *wait)
  655. {
  656. struct da380_private_data *da380_pdata = (struct da380_private_data *)filp->private_data;
  657. unsigned int mask = 0;
  658. unsigned long flags;
  659. if(!da380_pdata)
  660. return -ENODEV;
  661. poll_wait(filp, &da380_pdata->da380_waitq, wait);
  662. spin_lock_irqsave(&da380_pdata->spinlock, flags);
  663. if (da380_pdata->is_collision == 1)
  664. {
  665. mask |= POLLIN | POLLRDNORM;
  666. da380_pdata->is_collision = 0;
  667. }
  668. spin_unlock_irqrestore(&da380_pdata->spinlock, flags);
  669. return mask;
  670. }
  671. static struct file_operations da380_fops = {
  672. .owner = THIS_MODULE,
  673. .open = da380_open,
  674. .unlocked_ioctl = da380_ioctl,
  675. .release = da380_release,
  676. .poll = da380_poll,
  677. };
  678. static ssize_t gsensor_get(struct device *dev, struct device_attribute *attr, char *buf)
  679. {
  680. short x = 0, y = 0, z = 0;
  681. if(g_da380_pdata)
  682. {
  683. spin_lock(&g_da380_pdata->spinlock);
  684. if(!mir3da_read_data(&x,&y,&z))
  685. printk(KERN_ALERT "x:%d,y:%d,z:%d\n",x,y,z);
  686. spin_unlock(&g_da380_pdata->spinlock);
  687. printk(KERN_ALERT "gseneor threhold level:%d, [0:off] [1:low(%d)] [2:medium(%d)] [3:hight(%d)]\n",
  688. g_da380_pdata->g_range, g_da380_pdata->threhold[1],g_da380_pdata->threhold[2],g_da380_pdata->threhold[3]);
  689. }
  690. return 0;
  691. }
  692. static ssize_t gsensor_set(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
  693. {
  694. if(!strncmp(buf, "threhold", 7))
  695. {
  696. unsigned int level,val;
  697. sscanf(buf,"%*s%d%d",&level,&val);
  698. if(level < GSENSOR_ID_MAX)
  699. {
  700. if(g_da380_pdata)
  701. {
  702. spin_lock(&g_da380_pdata->spinlock);
  703. g_da380_pdata->threhold[level] = val;
  704. spin_unlock(&g_da380_pdata->spinlock);
  705. printk(KERN_ALERT "set gseneor threhold[%d] = val:%d\n",level,val);
  706. }
  707. }
  708. }
  709. if(!strncmp(buf, "debug", 5))
  710. {
  711. sscanf(buf,"%*s%d",&da380_debug);
  712. printk(KERN_ALERT "gseneor debug %d\n",da380_debug);
  713. }
  714. if(!strncmp(buf, "write", 5))
  715. {
  716. unsigned int reg = 0,val = 0;
  717. sscanf(buf,"%*s%x%x",&reg,&val);
  718. if((reg <= 0xff) && (val <= 0xff))
  719. {
  720. mir3da_register_mask_write(reg, 0xFF, (unsigned char)val);
  721. mir3da_register_read(reg, (char *)&val);
  722. printk(KERN_ALERT "gsensor write reg:0x%x, val:0x%x\n", reg, val);
  723. }
  724. }
  725. if(!strncmp(buf, "read", 4))
  726. {
  727. unsigned int reg = 0,val = 0;
  728. sscanf(buf,"%*s%x",&reg);
  729. if(reg <= 0xff)
  730. {
  731. mir3da_register_read(reg, (char *)&val);
  732. printk(KERN_ALERT "gsensor read reg:0x%x, val:0x%x\n", reg, val);
  733. }
  734. }
  735. return count;
  736. }
  737. static DEVICE_ATTR(gsensor, 0664, gsensor_get, gsensor_set);
  738. static struct attribute *gsensor_sysfs_attrs[] = {
  739. &dev_attr_gsensor.attr,
  740. NULL
  741. };
  742. static const struct attribute_group gsensor_sysfs = {
  743. .attrs = gsensor_sysfs_attrs,
  744. };
  745. static int da380_probe(struct i2c_client *client, const struct i2c_device_id *id)
  746. {
  747. struct da380_private_data *da380_pdata = (struct da380_private_data *)kzalloc(sizeof(struct da380_private_data), GFP_KERNEL);
  748. dev_t dev;
  749. int ret = 0;
  750. if(!da380_pdata || !client)
  751. return -ENOMEM;
  752. da380_pdata->name = "da380";
  753. da380_pdata->major = 0;
  754. da380_pdata->minor_start = 0;
  755. da380_pdata->minor_num = 1;
  756. da380_pdata->num = 1;
  757. da380_pdata->threhold[0] = 10000; //value 10000 means turn off collision check
  758. //da380_pdata->threhold[1] = 1200;
  759. //da380_pdata->threhold[2] = 600;
  760. //da380_pdata->threhold[3] = 300;
  761. da380_pdata->threhold[1] = 700; //600 - 900
  762. da380_pdata->threhold[2] = 500; //400 - 700
  763. da380_pdata->threhold[3] = 250; //120 - 300
  764. da380_pdata->is_collision = 0;
  765. da380_pdata->g_range = DA380_DEFAULT_G_RANGE;
  766. da380_pdata->i2c_client = client;
  767. da380_pdata->boot_state = 0;
  768. da380_pdata->i2c_gpio_direction = GSENSOR_I2C_GPIO_OUTPUT;
  769. if(client->adapter && client->adapter->dev.of_node)
  770. {
  771. da380_pdata->gpio_scl = of_get_gpio(client->adapter->dev.of_node, 0);
  772. da380_pdata->gpio_sda = of_get_gpio(client->adapter->dev.of_node, 1);
  773. if(!gpio_is_valid(da380_pdata->gpio_scl))
  774. da380_pdata->gpio_scl = -1;
  775. if(!gpio_is_valid(da380_pdata->gpio_sda))
  776. da380_pdata->gpio_sda = -1;
  777. }
  778. else
  779. {
  780. da380_pdata->gpio_scl = -1;
  781. da380_pdata->gpio_sda = -1;
  782. }
  783. g_da380_pdata = da380_pdata;
  784. spin_lock_init(&da380_pdata->spinlock);
  785. da380_select_pad();
  786. da380_pdata->gpio_irq = of_get_gpio(client->dev.of_node, 0);
  787. if (!gpio_is_valid(da380_pdata->gpio_irq))
  788. {
  789. printk(KERN_ERR "%s of_get_gpio failure\n",__FUNCTION__);
  790. goto err_gpio;
  791. }
  792. ret = devm_gpio_request(&client->dev, da380_pdata->gpio_irq, "da308_gpio");
  793. if (ret) {
  794. printk(KERN_ERR "%s devm_gpio_request failure\n",__FUNCTION__);
  795. goto err_gpio;
  796. }
  797. gpio_direction_input(da380_pdata->gpio_irq);
  798. da380_pdata->boot_state = gpio_get_value(da380_pdata->gpio_irq);
  799. if(da380_pdata->boot_state)
  800. printk(KERN_ALERT "Gsensor crash boot\n");
  801. da380_pdata->work_queue = alloc_workqueue("da380-workqueue", 0, 1);
  802. if (da380_pdata->work_queue == NULL) {
  803. goto err_gpio;
  804. }
  805. INIT_WORK(&da380_pdata->work, da380_work);
  806. INIT_DELAYED_WORK(&da380_pdata->delay_work, da380_delay_work);
  807. if(da380_identify() < 0)
  808. {
  809. ret = -1;
  810. printk(KERN_ERR "%s da380_identify failure\n",__FUNCTION__);
  811. goto err_work_queue;
  812. }
  813. da380_open_parking_interrupt(1);//
  814. if(!client->dev.of_node)
  815. {
  816. ret = -1;
  817. goto err_work_queue;
  818. }
  819. #if 0
  820. ret = devm_request_irq(&client->dev,
  821. gpio_to_irq(da380_pdata->gpio_irq),
  822. da380_irq_handler,
  823. IRQF_TRIGGER_HIGH, //hight level trigger
  824. "da380_irq",
  825. da380_pdata);
  826. #else
  827. ret = request_irq(gpio_to_irq(da380_pdata->gpio_irq),
  828. da380_irq_handler,
  829. IRQF_TRIGGER_RISING,
  830. "da380_irq",
  831. da380_pdata);
  832. #endif
  833. if(ret)
  834. {
  835. printk(KERN_ERR "%s request irq failure\n",__FUNCTION__);
  836. goto err_work_queue;
  837. }
  838. /* register char device */
  839. if (!da380_pdata->major) {
  840. ret = alloc_chrdev_region(
  841. &dev,
  842. da380_pdata->minor_start,
  843. da380_pdata->num,
  844. da380_pdata->name
  845. );
  846. if (!ret) {
  847. da380_pdata->major = MAJOR(dev);
  848. da380_pdata->minor_start = MINOR(dev);
  849. }
  850. } else {
  851. dev = MKDEV(da380_pdata->major, da380_pdata->minor_start);
  852. ret = register_chrdev_region(dev, da380_pdata->num, (char *)da380_pdata->name);
  853. }
  854. if (ret < 0) {
  855. printk(KERN_ERR "%s %d: register driver error\n", __FUNCTION__, __LINE__);
  856. goto err_irq;
  857. }
  858. /* associate the file operations */
  859. cdev_init(&da380_pdata->cdev, &da380_fops);
  860. da380_pdata->cdev.owner = THIS_MODULE; //driver->owner;
  861. da380_pdata->cdev.ops = &da380_fops;
  862. ret = cdev_add(&da380_pdata->cdev, dev, da380_pdata->num);
  863. if (ret) {
  864. printk(KERN_ERR "%s %d: cdev add error\n", __FUNCTION__, __LINE__);
  865. goto err_cdev_add;
  866. }
  867. da380_pdata->da380_class = class_create(THIS_MODULE, "da380_class");
  868. if(IS_ERR(da380_pdata->da380_class)) {
  869. printk(KERN_ERR "Err: failed in creating da380 class.\n");
  870. da380_pdata->da380_class = NULL;
  871. goto err_cdev_add;
  872. }
  873. da380_pdata->da380_device = device_create(da380_pdata->da380_class, NULL, dev, NULL, "gsensor");
  874. if (IS_ERR(da380_pdata->da380_device)) {
  875. printk(KERN_ERR "Err: failed in creating da380 device.\n");
  876. da380_pdata->da380_device = NULL;
  877. goto err_cdev_add;
  878. }
  879. init_waitqueue_head(&da380_pdata->da380_waitq);
  880. ret = sysfs_create_group(&client->dev.kobj, &gsensor_sysfs);
  881. if (ret){
  882. printk(KERN_ERR "error dvr sysfs_create\n");
  883. goto err_cdev_add;
  884. }
  885. mir3da_read_data(&da380_pdata->g_data.x, &da380_pdata->g_data.y, &da380_pdata->g_data.z);
  886. i2c_set_clientdata(client, da380_pdata);
  887. printk("%s success\n", __FUNCTION__);
  888. return 0;
  889. err_cdev_add:
  890. if (da380_pdata->da380_class) {
  891. if (da380_pdata->da380_device) {
  892. device_destroy(da380_pdata->da380_class, dev);
  893. }
  894. class_destroy(da380_pdata->da380_class);
  895. cdev_del(&da380_pdata->cdev);
  896. }
  897. unregister_chrdev_region(dev, da380_pdata->num);
  898. err_irq:
  899. free_irq(gpio_to_irq(da380_pdata->gpio_irq), da380_pdata);
  900. err_work_queue:
  901. destroy_workqueue(da380_pdata->work_queue);
  902. err_gpio:
  903. g_da380_pdata = NULL;
  904. kfree(da380_pdata);
  905. return ret;
  906. }
  907. static int da380_remove(struct i2c_client *client)
  908. {
  909. struct da380_private_data *da380_pdata = i2c_get_clientdata(client);
  910. dev_t dev;
  911. if(!da380_pdata)
  912. return -ENODEV;
  913. sysfs_remove_group(&client->dev.kobj, &gsensor_sysfs);
  914. dev = MKDEV(da380_pdata->major, da380_pdata->minor_start);
  915. cdev_del(&da380_pdata->cdev);
  916. if (da380_pdata->da380_class) {
  917. if (da380_pdata->da380_device) {
  918. device_destroy(da380_pdata->da380_class, dev);
  919. }
  920. class_destroy(da380_pdata->da380_class);
  921. }
  922. unregister_chrdev_region(dev, da380_pdata->num);
  923. destroy_workqueue(da380_pdata->work_queue);
  924. free_irq(gpio_to_irq(da380_pdata->gpio_irq), da380_pdata);
  925. g_da380_pdata = NULL;
  926. kfree(da380_pdata);
  927. return 0;
  928. }
  929. static const struct of_device_id da380_of_match[] = {
  930. { .compatible = "arkmicro,da380" },
  931. { }
  932. };
  933. MODULE_DEVICE_TABLE(of, da380_of_match);
  934. static const struct i2c_device_id da380_id[] = {
  935. { "da380", 0 },
  936. { }
  937. };
  938. MODULE_DEVICE_TABLE(i2c, imx322_id);
  939. static struct i2c_driver da380_driver = {
  940. .driver = {
  941. .name = "da380",
  942. .of_match_table = of_match_ptr(da380_of_match),
  943. },
  944. .probe = da380_probe,
  945. .remove = da380_remove,
  946. .id_table = da380_id,
  947. };
  948. module_i2c_driver(da380_driver);
  949. MODULE_DESCRIPTION("ArkMicro g_sensor da380 Driver");
  950. MODULE_LICENSE("GPL v2");