1/* Industrialio buffer test code.
2 *
3 * Copyright (c) 2012 Invensense Inc.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
8 *
9 * Command line parameters
10 * stress_iio -d time1 -e time2
11 */
12
13#include <unistd.h>
14#include <dirent.h>
15#include <fcntl.h>
16#include <stdio.h>
17#include <errno.h>
18#include <sys/stat.h>
19#include <dirent.h>
20#include <linux/types.h>
21#include <string.h>
22#include <poll.h>
23#include <pthread.h>
24#include "iio_utils.h"
25#include "ml_load_dmp.h"
26#include "ml_sysfs_helper.h"
27#include "authenticate.h"
28
29pthread_mutex_t data_switch_lock = PTHREAD_MUTEX_INITIALIZER;
30
31static int has_compass = 0;
32static int has_pressure = 0;
33static int enable_random_delay = 0;
34static int enable_delay = 10;
35static int disable_delay = 10;
36static int enable_motion_on = 0;
37static int final_output_rate;
38static int first_flag;
39static char dmp_path[200];
40
41static int dev_num;
42static char *dev_dir_name;
43static char *buf_dir_name;
44static char *scan_el_dir;
45static int gyro_data_is_enabled, accel_data_is_enabled, compass_data_is_enabled, quaternion_data_is_enabled;
46static int accel_engine_is_on;
47
48struct dmp_struct {
49	char fname[100];
50	void (*action)(struct dmp_struct *, int);
51};
52
53static void HandleTap(struct dmp_struct *dmp, int tap);
54static void sipmle_print(struct dmp_struct *dmp, int d){
55	printf("%s:%d\n", dmp->fname, d);
56}
57
58static void handle_smd() {
59	printf("write wake lock for SMD\n");
60	//write_sysfs_string_and_verify("wake_lock", "/sys/power/", "hack");
61}
62
63static void pedo_print()
64{
65	struct timespec aa;
66	unsigned long long t;
67
68	clock_gettime(CLOCK_REALTIME, &aa);
69	t = (unsigned long long)aa.tv_sec * 1000000000 + aa.tv_nsec;
70	printf("steps=%lld, time=%lld, system=%lld\n",
71		read_sysfs_poslonglong("pedometer_steps", dev_dir_name),
72		read_sysfs_poslonglong("pedometer_time", dev_dir_name),
73		t);
74}
75
76struct dmp_struct event_file[] = {
77#if 1
78	{
79		.fname = "event_tap",
80		.action = HandleTap,
81	},
82#endif
83	{
84		.fname = "event_smd",
85		.action = handle_smd,
86	},
87	{
88		.fname = "event_accel_motion",
89		.action = sipmle_print,
90	},
91	{
92		.fname = "event_pedometer",
93		.action = pedo_print,
94	},
95};
96
97static void HandleTap(struct dmp_struct *dmp, int tap)
98{
99    int tap_dir = tap/8;
100    int tap_num = tap%8 + 1;
101
102    switch (tap_dir) {
103        case 1:
104            printf("INV_TAP_AXIS_X_POS\n");
105            break;
106        case 2:
107            printf("INV_TAP_AXIS_X_NEG\n");
108            break;
109        case 3:
110            printf("INV_TAP_AXIS_Y_POS\n");
111            break;
112        case 4:
113            printf("INV_TAP_AXIS_Y_NEG\n");
114            break;
115        case 5:
116            printf("INV_TAP_AXIS_Z_POS\n");
117            break;
118        case 6:
119            printf("INV_TAP_AXIS_Z_NEG\n");
120            break;
121        default:
122            break;
123    }
124    printf("Tap number: %d\n", tap_num);
125}
126#define DMP_CODE_SIZE 2799
127static char dmp_img[DMP_CODE_SIZE];
128static void verify_img(){
129    FILE *fp;
130    int i;
131    char dmp_path[] = "/sys/bus/iio/devices/iio:device0/dmp_firmware";
132
133    printf("saving image\n");
134    if ((fp = fopen(dmp_path, "rb")) < 0 ) {
135        perror("dmp fail");
136    }
137
138    i = fread(dmp_img, 1, DMP_CODE_SIZE, fp);
139    printf("Result=%d\n", i);
140    fclose(fp);
141    fp = fopen("/dev/read_img.h", "wt");
142    fprintf(fp, "unsigned char rec[]={\n");
143    for(i=0; i<DMP_CODE_SIZE; i++) {
144      fprintf(fp, "0x%02x, ", dmp_img[i]);
145      //printf( "0x%02x, ", dmp_img[i]);
146      if(((i+1)%16) == 0) {
147        fprintf(fp, "\n");
148        //printf("\n");
149      }
150    }
151    fprintf(fp, "};\n ");
152    fclose(fp);
153    printf("saving image Done\n");
154}
155
156static void inv_set_rate()
157{
158	int ret;
159
160	printf("set rate \n");
161	ret = write_sysfs_int_and_verify("accel_rate", dev_dir_name, 5);
162	ret = write_sysfs_int_and_verify("gyro_rate", dev_dir_name, 5);
163	if (has_compass)
164		ret = write_sysfs_int_and_verify("compass_rate", dev_dir_name, 10);
165	if (has_pressure)
166		ret = write_sysfs_int_and_verify("pressure_rate", dev_dir_name, 30);
167	ret = write_sysfs_int_and_verify("ped_q_rate", dev_dir_name, 5);
168	ret = write_sysfs_int_and_verify("six_axes_q_rate", dev_dir_name, 5);
169	ret = write_sysfs_int_and_verify("three_axes_q_rate", dev_dir_name, 5);
170}
171
172
173static int setup_offset_and_bias()
174{
175	int ret;
176
177	ret = write_sysfs_int_and_verify("in_accel_x_offset", dev_dir_name, 0);
178	if (ret < 0)
179		printf("write accel x offset failed.\n");
180	ret = write_sysfs_int_and_verify("in_accel_y_offset", dev_dir_name, 0);
181	if (ret < 0)
182		printf("write accel y offset failed.\n");
183	ret = write_sysfs_int_and_verify("in_accel_z_offset", dev_dir_name, 0);
184	if (ret < 0)
185		printf("write accel z offset failed.\n");
186
187	ret = write_sysfs_int_and_verify("in_anglvel_x_offset", dev_dir_name, 0);
188	if (ret < 0)
189		printf("write accel x offset failed.\n");
190	ret = write_sysfs_int_and_verify("in_anglvel_y_offset", dev_dir_name, 0);
191	if (ret < 0)
192		printf("write accel y offset failed.\n");
193	ret = write_sysfs_int_and_verify("in_anglvel_z_offset", dev_dir_name, 0);
194	if (ret < 0)
195		printf("write accel z offset failed.\n");
196
197	ret = write_sysfs_int_and_verify("in_accel_x_dmp_bias", dev_dir_name, 0);
198	if (ret < 0)
199		printf("write accel x offset failed.\n");
200	ret = write_sysfs_int_and_verify("in_accel_y_dmp_bias", dev_dir_name, 0);
201	if (ret < 0)
202		printf("write accel y offset failed.\n");
203	ret = write_sysfs_int_and_verify("in_accel_z_dmp_bias", dev_dir_name, 0);
204	if (ret < 0)
205		printf("write accel z offset failed.\n");
206
207	ret = write_sysfs_int_and_verify("in_anglvel_x_dmp_bias", dev_dir_name, 0);
208	if (ret < 0)
209		printf("write gyro x offset failed.\n");
210	ret = write_sysfs_int_and_verify("in_anglvel_y_dmp_bias", dev_dir_name, 0);
211	if (ret < 0)
212		printf("write gyro y offset failed.\n");
213	ret = write_sysfs_int_and_verify("in_anglvel_z_dmp_bias", dev_dir_name, 0);
214	if (ret < 0)
215		printf("write gyro z offset failed.\n");
216
217	return 0;
218}
219
220static void setup_dmp(char *dev_path){
221	char sysfs_path[200];
222	int  ret;
223	FILE *fd;
224	sprintf(sysfs_path, "%s", dev_path);
225	printf("sysfs: %s\n", sysfs_path);
226	ret = write_sysfs_int_and_verify("power_state", sysfs_path, 1);
227	if (ret < 0)
228		return;
229
230	ret = write_sysfs_int("in_accel_scale", dev_path, 0);
231	if (ret < 0)
232		return;
233	ret = write_sysfs_int("in_anglvel_scale", dev_path, 3);
234	if (ret < 0)
235		return;
236	ret = write_sysfs_int("sampling_frequency", sysfs_path, 200);
237	if (ret < 0)
238		return;
239	ret = write_sysfs_int_and_verify("firmware_loaded", sysfs_path, 0);
240	if (ret < 0)
241		return;
242	sprintf(dmp_path, "%s/dmp_firmware", dev_path);
243	if ((fd = fopen(dmp_path, "wb")) < 0 ) {
244		perror("dmp fail");
245	}
246	inv_load_dmp(fd);
247	fclose(fd);
248	printf("firmware_loaded=%d\n", read_sysfs_posint("firmware_loaded", sysfs_path));
249	ret = write_sysfs_int_and_verify("dmp_on", sysfs_path, 1);
250	if (ret < 0)
251		return;
252	ret = write_sysfs_int_and_verify("dmp_int_on", sysfs_path, 1);
253	if (ret < 0)
254		return;
255	/* selelct which event to enable and interrupt on/off here */
256	//enable_glu(sysfs_path, 0);
257//	ret = write_sysfs_int_and_verify("tap_on", sysfs_path, 0);
258//	if (ret < 0)
259//		return;
260	ret = write_sysfs_int_and_verify("pedometer_int_on", sysfs_path, 1);
261	ret = write_sysfs_int_and_verify("pedometer_on", sysfs_path, 1);
262
263	ret = write_sysfs_int_and_verify("dmp_event_int_on", sysfs_path, 1);
264		write_sysfs_int64("pedometer_steps", sysfs_path, 0);
265		write_sysfs_int64("pedometer_time", sysfs_path, 0);
266	if (ret < 0)
267		return;
268
269	ret = setup_offset_and_bias();
270
271	return;
272}
273
274#if 0
275static char reg_dump_arr[2000];
276static int inv_do_reg_dump(void)
277{
278	char reg_dump_name[100];
279	int fd, i;
280
281	sprintf(reg_dump_name, "%s/reg_dump", dev_dir_name);
282	printf("%s\n", reg_dump_name);
283	fd = open(reg_dump_name, O_RDONLY);
284	pread(fd, reg_dump_arr, 2000, 0);
285	close(fd);
286	for ( i = 0; i < 2000; i++) {
287		printf("%c", reg_dump_arr[i]);
288		//if((i+1)%16 == 0)
289			//printf("\n");
290	}
291	return 0;
292}
293#endif
294
295static void *get_dmp_event(void *param) {
296	char file_name[100];
297	int i;
298	int data;
299	char d[4];
300	FILE *fp;
301	struct pollfd pfd[ARRAY_SIZE(event_file)];
302
303	printf("get DMP event: %s\n", dev_dir_name);
304	while(1) {
305		for (i = 0; i < ARRAY_SIZE(event_file); i++) {
306			sprintf(file_name, "%s/%s", dev_dir_name, event_file[i].fname);
307			pfd[i].fd = open(file_name, O_RDONLY | O_NONBLOCK);
308			pfd[i].events = POLLPRI|POLLERR;
309			pfd[i].revents = 0;
310			read(pfd[i].fd, d, 4);
311		}
312
313		poll(pfd, ARRAY_SIZE(event_file), -1);
314		for (i = 0; i < ARRAY_SIZE(event_file); i++) {
315			close(pfd[i].fd);
316		}
317
318		for (i=0; i< ARRAY_SIZE(pfd); i++) {
319			if(pfd[i].revents != 0) {
320				sprintf(file_name, "%s/%s", dev_dir_name, event_file[i].fname);
321				fp = fopen(file_name, "rt");
322				fscanf(fp, "%d\n", &data);
323				event_file[i].action(&event_file[i], data);
324			}
325		}
326	}
327
328	return 0;
329}
330
331static int enable_gyro(int on){
332	int ret;
333	ret = write_sysfs_int_and_verify("gyro_enable", dev_dir_name, on);
334	if (ret < 0)
335		printf("write gyro_enable failed\n");
336
337	return ret;
338}
339
340static int enable_gyro_output(int on){
341	int ret;
342	gyro_data_is_enabled = on;
343	ret = write_sysfs_int_and_verify("gyro_fifo_enable", dev_dir_name, on);
344	if (ret < 0)
345		printf("write gyro_fifo_enable failed\n");
346
347	return ret;
348}
349
350static int enable_compass(int on){
351	int ret;
352
353	compass_data_is_enabled = on;
354	ret = write_sysfs_int_and_verify("compass_enable", dev_dir_name, on);
355	if (ret < 0)
356		printf("write gyro_enable failed\n");
357
358	return ret;
359}
360
361static int enable_pressure(int on){
362	int ret;
363
364	ret = write_sysfs_int_and_verify("pressure_enable", dev_dir_name, on);
365	if (ret < 0)
366		printf("write pressure_enable failed\n");
367
368	return ret;
369}
370
371static int enable_quaternion(int on) {
372	int ret;
373	ret = write_sysfs_int_and_verify("ped_q_on", dev_dir_name, on);
374	if (ret < 0)
375		printf("write quaternion_on failed\n");
376	ret = write_sysfs_int_and_verify("six_axes_q_on", dev_dir_name, on);
377	if (ret < 0)
378		printf("write quaternion_on failed\n");
379	ret = write_sysfs_int_and_verify("three_axes_q_on", dev_dir_name, on);
380	if (ret < 0)
381		printf("write quaternion_on failed\n");
382
383	return ret;
384}
385static int enable_step_detector(int on) {
386	int ret;
387
388	ret = write_sysfs_int_and_verify("step_detector_on", dev_dir_name, on);
389	if (ret < 0)
390		printf("write step detector on failed\n");
391}
392static int enable_step_indicator(int on) {
393	int ret;
394
395	ret = write_sysfs_int_and_verify("step_indicator_on", dev_dir_name, on);
396	if (ret < 0)
397		printf("write step indicator on failed\n");
398}
399
400static int enable_accel(int on){
401	int ret;
402	accel_data_is_enabled = on;
403	accel_engine_is_on = on;
404	ret = write_sysfs_int_and_verify("accel_enable", dev_dir_name, on);
405	if (ret < 0)
406		printf("write accel_enable failed\n");
407	ret = write_sysfs_int_and_verify("accel_fifo_enable", dev_dir_name, on);
408	if (ret < 0)
409		printf("write accel_fifo_enable failed\n");
410
411	return ret;
412}
413static int enable_accel_output(int on) {
414	int ret;
415	accel_data_is_enabled = on;
416
417	ret = write_sysfs_int_and_verify("accel_fifo_enable", dev_dir_name, on);
418	if (ret < 0)
419		printf("write accel_fifo_enable failed\n");
420
421	return ret;
422}
423
424static int enable_enable(int on){
425	int ret;
426
427	if (0 == on) {
428		//pthread_mutex_lock(&data_switch_lock);
429	}
430	ret = write_sysfs_int_and_verify("master_enable", dev_dir_name, on);
431	if (ret < 0)
432		printf("write enable failed\n");
433
434	if (on) {
435		//pthread_mutex_unlock(&data_switch_lock);
436	}
437
438	return 0;
439}
440static int write_dmp_event(int on) {
441	int ret;
442	ret = write_sysfs_int_and_verify("dmp_event_int_on", dev_dir_name, on);
443	if (ret < 0)
444		printf("write dmp_event_int_on failed\n");
445	return 0;
446}
447
448static void random_delay(){
449	int i;
450	float bb;
451
452	i = rand();
453	bb = i * 200.0;
454	bb = i * 10.0;
455	i = 1 + (unsigned int)(bb/(RAND_MAX + 1.0));
456	i *= 2;
457	if (i%2) {
458		printf("sleep %d ms\n", i);
459		usleep(i*1000);
460	} else {
461		printf("sleep %d s\n", i);
462		sleep(i);
463	}
464
465}
466static void dmp_event_control(on){
467	int ret;
468
469	ret = 0;
470
471//	ret = write_sysfs_int_and_verify("tap_on", dev_dir_name, on);
472	ret = write_sysfs_int_and_verify("smd_enable", dev_dir_name, 1);
473	if (ret < 0)
474		return;
475	inv_set_rate();
476
477	//ret = write_sysfs_int_and_verify("batchmode_wake_fifo_full_on", dev_dir_name, 1);
478	ret = write_sysfs_int_and_verify("batchmode_timeout", dev_dir_name, 10000);
479	ret = write_sysfs_int_and_verify("batchmode_timeout", dev_dir_name, 0);
480	//ret = write_sysfs_int_and_verify("smd_delay_threshold", dev_dir_name, 10);
481	if (ret < 0)
482		return;
483	//ret = write_sysfs_int_and_verify("smd_threshold", dev_dir_name, 5000);
484	if (ret < 0)
485		return;
486	//write_sysfs_int_and_verify("motion_lpa_duration", dev_dir_name, 1000);
487	//write_sysfs_int_and_verify("motion_lpa_threshold", dev_dir_name, 200);
488	write_sysfs_int_and_verify("dmp_on", dev_dir_name, 1);
489	ret = write_sysfs_int_and_verify("sampling_frequency", dev_dir_name, 200);
490	//write_sysfs_int_and_verify("motion_lpa_freq", dev_dir_name, 3);
491
492}
493void enable_motion(int on) {
494	int ret;
495
496	ret = write_sysfs_int_and_verify("motion_lpa_on", dev_dir_name, on);
497	if (on) {
498	        gyro_data_is_enabled = 0;
499		compass_data_is_enabled = 0;
500		quaternion_data_is_enabled = 0;
501	}
502}
503bool g, a;
504static int counter = 0;
505static unsigned char data_rate[] = {5, 10, 15, 50, 100, 200};
506static int run_enable_sequence()
507{
508	bool g, a, out;
509
510	counter++;
511	g = rand()%2;
512	a = rand()%2;
513	if (!g && !a)
514		a = true;
515
516	g = true;
517//	g = false;
518	a = true;
519//	a = false;
520	/*disable the master enable */
521	enable_enable(0);
522	if(g) {
523		enable_gyro(1);
524		if (rand()%2) {
525			out = rand()%2;
526			enable_quaternion(out);
527			enable_gyro_output(!out);
528		} else {
529			enable_quaternion(1);
530			enable_gyro_output(1);
531		}
532		enable_quaternion(1);
533		enable_gyro_output(0);
534
535	} else {
536		enable_gyro(0);
537		enable_gyro_output(0);
538		enable_quaternion(0);
539	}
540	if(a) {
541		enable_accel(1);
542		enable_accel_output(0);
543	} else {
544		enable_accel(0);
545		enable_accel_output(0);
546	}
547	if (has_compass) {
548		if(rand()%2)
549			enable_compass(1);
550		else
551			enable_compass(0);
552		enable_compass(counter%2);
553		enable_compass(0);
554	}
555	if (has_pressure) {
556		if(rand()%2)
557			enable_pressure(1);
558		else
559			enable_pressure(0);
560		enable_pressure(counter%3);
561		enable_pressure(0);
562	}
563	enable_step_detector(1);
564	enable_step_indicator(1);
565	enable_step_detector(0);
566	enable_step_indicator(0);
567
568	write_dmp_event(0);
569
570	enable_motion(0);
571	if (accel_engine_is_on)
572		dmp_event_control(1);
573	else
574		dmp_event_control(0);
575	first_flag = 1;
576	/*enable the master enable */
577	enable_enable(1);
578	//enable_enable(0);
579	//verify_img();
580	//while(1);
581	//write_sysfs_string_and_verify("wake_unlock", "/sys/power/", "hack");
582	if (enable_random_delay)
583		random_delay();
584	else {
585		printf("sleep %ds\n", enable_delay);
586		sleep(enable_delay);
587	}
588
589	return 0;
590}
591
592static int run_disable_sequence() {
593	enable_enable(0);
594
595	enable_gyro(0);
596	enable_accel(1);
597	enable_quaternion(0);
598	enable_accel_output(0);
599	write_dmp_event(1);
600	enable_motion(enable_motion_on);
601	if (accel_engine_is_on)
602		dmp_event_control(1);
603	else
604		dmp_event_control(0);
605
606	enable_enable(1);
607	if (enable_random_delay)
608		random_delay();
609	else {
610		printf("sleep %ds\n", disable_delay);
611		sleep(disable_delay);
612	}
613
614	if (has_pressure) {
615		if(rand()%2)
616			enable_pressure(1);
617		else
618			enable_pressure(0);
619		enable_pressure(counter%3);
620		enable_pressure(1);
621	}
622
623	return 0;
624}
625static int run_dmp_off() {
626	bool g, a, out;
627
628	counter++;
629	g = rand()%2;
630	a = rand()%2;
631	if (!g && !a)
632		a = true;
633
634	g = true;
635	a = true;
636	a = false;
637//	g = false;
638	/*disable the master enable */
639	enable_enable(0);
640	if(g) {
641		enable_gyro(1);
642		if (rand()%2) {
643			enable_gyro_output(!out);
644		} else {
645			enable_gyro_output(1);
646		}
647		enable_gyro_output(1);
648
649	} else {
650		enable_gyro(0);
651		enable_gyro_output(0);
652	}
653	if(a) {
654		enable_accel(1);
655		enable_accel_output(1);
656//		enable_accel_output(0);
657	} else {
658		enable_accel(0);
659		enable_accel_output(0);
660	}
661	if (has_compass) {
662		if(rand()%2)
663			enable_compass(1);
664		else
665			enable_compass(0);
666		enable_compass(counter%2);
667		enable_compass(0);
668	}
669	if (has_pressure) {
670		if(rand()%2)
671			enable_pressure(1);
672		else
673			enable_pressure(0);
674		enable_pressure(counter%3);
675		enable_pressure(1);
676	}
677	printf("111111111111111\n");
678
679	write_sysfs_int_and_verify("sampling_frequency", dev_dir_name,15);
680	write_sysfs_int_and_verify("dmp_on", dev_dir_name, 0);
681	first_flag = 1;
682	/*enable the master enable */
683	enable_enable(1);
684	//sleep(2);
685
686	return 0;
687}
688static void *control_switch(void *param)
689{
690	while(1) {
691		run_enable_sequence();
692		//run_dmp_off();
693		printf("sleeping\n");
694		//sleep(1000);
695		run_disable_sequence();
696	}
697	return 0;
698}
699
700void get_sensor_data(char *d, short *sensor)
701{
702	int i;
703
704	for (i = 0; i < 3; i++)
705		sensor[i] = *(short *)(d + 2 + i * 2);
706}
707
708static void *read_data(void *param)
709{
710	char *buffer_access;
711	char data[2048], *dptr, tmp[24];
712	short sensor[3];
713	int q[3], i, ind, left_over_size, buf_size;
714	int ret, fp,read_size;
715	unsigned short hdr;
716	bool done_flag;
717	struct timespec ts_1;
718	unsigned long long t0, t1;
719	int g_count, sq_count;
720
721#define PRESSURE_HDR             0x8000
722#define ACCEL_HDR                0x4000
723#define GYRO_HDR                 0x2000
724#define COMPASS_HDR              0x1000
725#define COMPASS_HDR_2            0x1800
726#define LPQUAT_HDR               0x0800
727#define SIXQUAT_HDR              0x0400
728#define PEDQUAT_HDR              0x0200
729#define STEP_DETECTOR_HDR        0x0100
730#define STEP_INDICATOR_HDR       0x0001
731#define END_MARKER               0x0010
732#define EMPTY_MARKER             0x0020
733
734	printf("read_data Thread: %s\n", dev_dir_name);
735	ret = asprintf(&scan_el_dir, FORMAT_SCAN_ELEMENTS_DIR, dev_dir_name);
736	if (ret < 0)
737		goto error_alloc_scan_el_dir;
738	ret = asprintf(&buffer_access, "/dev/iio:device%d", dev_num);
739	if (ret < 0)
740		goto error_alloc_buffer_access;
741
742	fp = open(buffer_access, O_RDONLY | O_NONBLOCK);
743	if (fp == -1) { /*If it isn't there make the node */
744		printf("Failed to open %s\n", buffer_access);
745		ret = -errno;
746		goto error_open_buffer_access;
747	}
748	ind = 0;
749
750	clock_gettime(CLOCK_REALTIME, &ts_1);
751	t0 = (unsigned long long)ts_1.tv_sec * 1000000000 + ts_1.tv_nsec;
752	while(1) {
753
754		clock_gettime(CLOCK_REALTIME, &ts_1);
755		t1 = (unsigned long long)ts_1.tv_sec * 1000000000 + ts_1.tv_nsec;
756		//printf("diff=%lld, a_count=%d, sq_count=%d\n", (t1-t0), g_count, sq_count);
757		g_count = 0;
758		sq_count = 0;
759		t0 = t1;
760
761		struct pollfd pfd = {
762			.fd = fp,
763			.events = POLLIN,
764		};
765		poll(&pfd, 1, -1);
766
767		if (left_over_size > 0)
768			memcpy(data, tmp, left_over_size);
769		dptr = data + left_over_size;
770		read_size = read(fp,  dptr, 2000);
771		printf("readsize=%d, left_over_size=%d\n", read_size, left_over_size);
772		if (read_size <= 0) {
773			printf("Wrong size=%d\n", read_size);
774			pthread_mutex_unlock(&data_switch_lock);
775			continue;
776		}
777		ind = read_size + left_over_size;
778		dptr = data;
779		//printf("ind=%d\n", ind);
780		buf_size = ind - (dptr - data);
781		done_flag = false;
782
783		while ((buf_size > 0) && (!done_flag)) {
784			hdr = *((short *)(dptr));
785			if ((hdr & 0xf) && (hdr != STEP_INDICATOR_HDR))
786				printf("STEP$$$$$$$$$$$$$$$=%x  ", hdr);
787			switch (hdr & (~0xf)) {
788			case PRESSURE_HDR:
789				if (buf_size >= 16) {
790					get_sensor_data(dptr, sensor);
791					dptr += 8;
792					printf("PRESSURE:%d, %lld\n", (sensor[1] << 16) + (unsigned short)sensor[2],  *(long long *)dptr);
793				} else
794					done_flag = true;
795				break;
796			case ACCEL_HDR:
797				if (buf_size >= 16) {
798					get_sensor_data(dptr, sensor);
799					dptr += 8;
800					printf("A:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
801				} else
802					done_flag = true;
803				break;
804			case GYRO_HDR:
805				if (buf_size >= 16) {
806					get_sensor_data(dptr, sensor);
807					dptr += 8;
808					g_count++;
809					printf("G:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
810				} else
811					done_flag = true;
812				break;
813			case COMPASS_HDR:
814				if (buf_size >= 16) {
815					get_sensor_data(dptr, sensor);
816					dptr += 8;
817					printf("M:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
818				} else
819					done_flag = true;
820				break;
821			case PEDQUAT_HDR:
822				if (buf_size >= 16) {
823					get_sensor_data(dptr, sensor);
824					dptr += 8;
825					printf("PED:%d, %d, %d,  %lld\n", sensor[0], sensor[1], sensor[2],   *(long long *)dptr);
826				}  else
827					done_flag = true;
828				break;
829			case LPQUAT_HDR:
830				if (buf_size >= 24) {
831					q[0] = *(int *)(dptr + 4);
832					dptr += 8;
833					q[1] = *(int *)(dptr);
834					q[2] = *(int *)(dptr + 4);
835					dptr += 8;
836					printf("LPQ:%d, %d, %d,  %lld\n", q[0], q[1], q[2],   *(long long *)dptr);
837				}  else
838					done_flag = true;
839				break;
840			case SIXQUAT_HDR:
841				if (buf_size >= 24) {
842					q[0] = *(int *)(dptr + 4);
843					dptr += 8;
844					q[1] = *(int *)(dptr);
845					q[2] = *(int *)(dptr + 4);
846					dptr += 8;
847					sq_count++;
848					printf("SIXQ:%d, %d, %d,  %lld\n", q[0], q[1], q[2],   *(long long *)dptr);
849				}  else
850					done_flag = true;
851				break;
852			case STEP_DETECTOR_HDR:
853				if (buf_size >= 16) {
854					printf("STEP DETECTOR ");
855					dptr += 8;
856					printf(" %lld\n", *(long long *)dptr);
857				}  else
858					done_flag = true;
859
860				break;
861			default:
862				if (hdr == EMPTY_MARKER) {
863					printf("emptry marker !!!!!!!!!!!\n");
864				} else if (hdr == END_MARKER) {
865					printf("end marker !!!!!\n");
866				} else if (hdr == COMPASS_HDR_2) {
867					printf("bad compass data\n");
868				} else {
869					dptr +=8;
870					printf("%lld\n", *(long long *)dptr);
871				}
872				break;
873			}
874			if (!done_flag)
875				dptr += 8;
876			buf_size = ind - (dptr - data);
877		}
878		if (ind - (dptr - data) > 0)
879			memcpy(tmp, dptr, ind - (dptr - data));
880		left_over_size = ind - (dptr - data);
881	}
882	close(fp);
883
884error_open_buffer_access:
885	free(buffer_access);
886error_alloc_buffer_access:
887	free(scan_el_dir);
888error_alloc_scan_el_dir:
889
890	return 0;
891}
892
893static void inv_create_thread() {
894	pthread_t thread_dmp_event, thread_read_data, thread_control;
895
896	pthread_create(&thread_dmp_event, NULL, &get_dmp_event, (void *)dev_dir_name);
897	pthread_create(&thread_read_data, NULL, &read_data, (void *)dev_dir_name);
898	pthread_create(&thread_control, NULL, &control_switch, (void *)dev_dir_name);
899
900	pthread_join(thread_dmp_event, NULL);
901	pthread_join(thread_read_data, NULL);
902	pthread_join(thread_control, NULL);
903}
904
905static int enable_enable_main(int on){
906	int ret;
907
908	printf("enable_enable: %s=%d\n", dev_dir_name, on);
909	ret = write_sysfs_int_and_verify("enable", buf_dir_name, on);
910	if (ret < 0)
911		printf("write enable failed\n");
912
913	return 0;
914}
915
916int main(int argc, char **argv)
917{
918	unsigned long buf_len = 240;
919
920	int ret, c, i;
921
922	char *trigger_name = NULL;
923
924	int datardytrigger = 1;
925	int trig_num;
926	char *dummy;
927	char chip_name[10];
928	char device_name[10];
929	char sysfs[100];
930
931	gyro_data_is_enabled = 0;
932	accel_data_is_enabled = 0;
933	compass_data_is_enabled = 0;
934	quaternion_data_is_enabled = 0;
935
936	while ((c = getopt(argc, argv, "lcd:e:rmp")) != -1) {
937		switch (c) {
938		case 'c':
939			has_compass = 1;
940			break;
941		case 'p':
942			has_pressure = 1;
943			break;
944		case 'd':
945			disable_delay = strtoul(optarg, &dummy, 10);
946			break;
947		case 'e':
948			enable_delay = strtoul(optarg, &dummy, 10);
949			break;
950		case 'r':
951			enable_random_delay = 1;
952			break;
953		case 'm':
954			enable_motion_on = 1;
955			break;
956		case '?':
957			return -1;
958		}
959	}
960
961	inv_get_sysfs_path(sysfs);
962	printf("sss:::%s\n", sysfs);
963	if (inv_get_chip_name(chip_name) != INV_SUCCESS) {
964		printf("get chip name fail\n");
965		exit(0);
966	}
967	printf("chip_name=%s\n", chip_name);
968	if (INV_SUCCESS != inv_check_key())
969        	printf("key check fail\n");
970	else
971        	printf("key authenticated\n");
972
973	for (i=0; i<strlen(chip_name); i++) {
974		device_name[i] = tolower(chip_name[i]);
975	}
976	device_name[strlen(chip_name)] = '\0';
977	printf("device name: %s\n", device_name);
978
979	/* Find the device requested */
980	dev_num = find_type_by_name(device_name, "iio:device");
981	if (dev_num < 0) {
982		printf("Failed to find the %s\n", device_name);
983		ret = -ENODEV;
984		goto error_ret;
985	}
986	printf("iio device number being used is %d\n", dev_num);
987	asprintf(&dev_dir_name, "%siio:device%d", iio_dir, dev_num);
988	printf("allco=%x\n", (int)dev_dir_name);
989	if (trigger_name == NULL) {
990		/*
991		 * Build the trigger name. If it is device associated it's
992		 * name is <device_name>_dev[n] where n matches the device
993		 * number found above
994		 */
995		ret = asprintf(&trigger_name,
996			       "%s-dev%d", device_name, dev_num);
997		if (ret < 0) {
998			ret = -ENOMEM;
999			goto error_ret;
1000		}
1001	}
1002	/* Verify the trigger exists */
1003	trig_num = find_type_by_name(trigger_name, "trigger");
1004	if (trig_num < 0) {
1005		printf("Failed to find the trigger %s\n", trigger_name);
1006		ret = -ENODEV;
1007		goto error_free_triggername;
1008	}
1009	printf("iio trigger number being used is %d\n", trig_num);
1010	ret = asprintf(&buf_dir_name, "%siio:device%d/buffer", iio_dir, dev_num);
1011	if (ret < 0) {
1012		ret = -ENOMEM;
1013		goto error_free_triggername;
1014	}
1015	enable_enable_main(0);
1016	ret = write_sysfs_int_and_verify("power_state", dev_dir_name, 1);
1017	/*
1018	 * Parse the files in scan_elements to identify what channels are
1019	 * present
1020	 */
1021	ret = 0;
1022	setup_dmp(dev_dir_name);
1023
1024	printf("%s %s\n", dev_dir_name, trigger_name);
1025
1026	/* Set the device trigger to be the data rdy trigger found above */
1027	ret = write_sysfs_string_and_verify("trigger/current_trigger",
1028					dev_dir_name,
1029					trigger_name);
1030	if (ret < 0) {
1031		printf("Failed to write current_trigger file\n");
1032		goto error_free_buf_dir_name;
1033	}
1034	/* Setup ring buffer parameters */
1035	/* length must be even number because iio_store_to_sw_ring is expecting
1036		half pointer to be equal to the read pointer, which is impossible
1037		when buflen is odd number. This is actually a bug in the code */
1038	ret = write_sysfs_int("length", buf_dir_name, buf_len*2);
1039	if (ret < 0)
1040		goto exit_here;
1041	enable_enable_main(1);
1042	inv_create_thread();
1043exit_here:
1044error_free_buf_dir_name:
1045	free(buf_dir_name);
1046error_free_triggername:
1047	if (datardytrigger)
1048		free(trigger_name);
1049error_ret:
1050	return ret;
1051}
1052