2 /* LSM303M motion sensor driver
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
18 #include <linux/interrupt.h>
19 #include <linux/i2c.h>
20 #include <linux/slab.h>
21 #include <linux/irq.h>
22 #include <linux/miscdevice.h>
23 #include <asm/uaccess.h>
24 #include <asm/atomic.h>
25 #include <linux/delay.h>
26 #include <linux/input.h>
27 #include <linux/workqueue.h>
28 #include <linux/kobject.h>
29 #include <linux/platform_device.h>
30 #include <linux/earlysuspend.h>
32 #include <linux/hwmsensor.h>
33 #include <linux/hwmsen_dev.h>
34 #include <linux/sensors_io.h>
39 #include <linux/hwmsen_helper.h>
44 #include <mach/mt_typedefs.h>
45 #include <mach/mt_gpio.h>
46 #include <mach/mt_pm_ldo.h>
50 /*-------------------------MT6516&MT6573 define-------------------------------*/
52 #define POWER_NONE_MACRO MT65XX_POWER_NONE
57 #define SW_CALIBRATION
59 /*----------------------------------------------------------------------------*/
60 #define I2C_DRIVERID_LSM303M 345
61 /*----------------------------------------------------------------------------*/
63 /*----------------------------------------------------------------------------*/
64 #define CONFIG_LSM303M_LOWPASS /*apply low pass filter on output*/
65 /*----------------------------------------------------------------------------*/
66 #define LSM303M_AXIS_X 0
67 #define LSM303M_AXIS_Y 1
68 #define LSM303M_AXIS_Z 2
69 #define LSM303M_AXES_NUM 3
70 #define LSM303M_DATA_LEN 6
71 #define LSM303M_DEV_NAME "lsm303m"
74 static DECLARE_WAIT_QUEUE_HEAD(data_ready_wq
);
75 static DECLARE_WAIT_QUEUE_HEAD(open_wq
);
77 static atomic_t open_flag
= ATOMIC_INIT(0);
78 static atomic_t m_flag
= ATOMIC_INIT(0);
79 static atomic_t o_flag
= ATOMIC_INIT(0);
80 /*----------------------------------------------------------------------------*/
81 static atomic_t dev_open_count
;
83 /*----------------------------------------------------------------------------*/
84 static const struct i2c_device_id lsm303m_i2c_id
[] = {{LSM303M_DEV_NAME
,0},{}};
85 static struct i2c_board_info __initdata i2c_lsm303m
={ I2C_BOARD_INFO("lsm303m", 0x3B>>1)};
86 /*the adapter id will be available in customization*/
87 //static unsigned short lsm303m_force[] = {0x00, LSM303M_I2C_SLAVE_ADDR, I2C_CLIENT_END, I2C_CLIENT_END};
88 //static const unsigned short *const lsm303m_forces[] = { lsm303m_force, NULL };
89 //static struct i2c_client_address_data lsm303m_addr_data = { .forces = lsm303m_forces,};
91 /*----------------------------------------------------------------------------*/
92 static int lsm303m_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
);
93 static int lsm303m_i2c_remove(struct i2c_client
*client
);
94 //static int lsm303m_i2c_detect(struct i2c_client *client, int kind, struct i2c_board_info *info);
95 static int lsm303m_suspend(struct i2c_client
*client
, pm_message_t msg
) ;
96 static int lsm303m_resume(struct i2c_client
*client
);
98 /*----------------------------------------------------------------------------*/
100 ADX_TRC_FILTER
= 0x01,
101 ADX_TRC_RAWDATA
= 0x02,
102 ADX_TRC_IOCTL
= 0x04,
107 /*----------------------------------------------------------------------------*/
112 /*----------------------------------------------------------------------------*/
113 struct data_resolution
{
114 struct scale_factor scalefactor
;
117 /*----------------------------------------------------------------------------*/
118 #define C_MAX_FIR_LENGTH (32)
119 /*----------------------------------------------------------------------------*/
121 s16 raw
[C_MAX_FIR_LENGTH
][LSM303M_AXES_NUM
];
122 int sum
[LSM303M_AXES_NUM
];
126 /*----------------------------------------------------------------------------*/
127 struct _lsm303m_data
{
131 volatile int updated
;
134 /*----------------------------------------------------------------------------*/
135 struct lsm303m_data
{
152 /*----------------------------------------------------------------------------*/
153 struct lsm303m_i2c_data
{
154 struct i2c_client
*client
;
156 struct hwmsen_convert cvt
;
159 struct data_resolution reso
;
165 s16 cali_sw
[LSM303M_AXES_NUM
+1];
168 s8 offset
[LSM303M_AXES_NUM
+1]; /*+1: for 4-byte alignment*/
169 s32 data
[LSM303M_AXES_NUM
+1];
171 #if defined(CONFIG_LSM303M_LOWPASS)
174 struct data_filter fir
;
177 #if defined(CONFIG_HAS_EARLYSUSPEND)
178 struct early_suspend early_drv
;
181 /*----------------------------------------------------------------------------*/
182 static struct i2c_driver lsm303m_i2c_driver
= {
184 // .owner = THIS_MODULE,
185 .name
= LSM303M_DEV_NAME
,
187 .probe
= lsm303m_i2c_probe
,
188 .remove
= lsm303m_i2c_remove
,
189 // .detect = lsm303m_i2c_detect,
190 //#if !defined(CONFIG_HAS_EARLYSUSPEND)
191 .suspend
= lsm303m_suspend
,
192 .resume
= lsm303m_resume
,
194 .id_table
= lsm303m_i2c_id
,
195 //.address_list= lsm303m_forces,
198 /*----------------------------------------------------------------------------*/
199 static struct i2c_client
*lsm303m_i2c_client
= NULL
;
200 static struct platform_driver lsm303m_msensor_driver
;
201 static struct lsm303m_i2c_data
*obj_i2c_data
= NULL
;
202 static bool sensor_power
= false;
203 //static MSENSOR_VECTOR3D msensor_gain;
204 static char selftestRes
[8]= {0};
206 /*----------------------------------------------------------------------------*/
207 #define MSE_TAG "MSENSOR"
208 #define MSE_FUN(f) printk(MSE_TAG" %s\r\n", __FUNCTION__)
209 #define MSE_ERR(fmt, args...) printk(KERN_ERR MSE_TAG" %s %d : \r\n" fmt, __FUNCTION__, __LINE__, ##args)
210 #define MSE_LOG(fmt, args...) printk(MSE_TAG fmt, ##args)
211 #define MSE_VER(fmt, args...) ((void)0)
214 /*----------------------------------------------------------------------------*/
215 static struct data_resolution lsm303m_data_resolution
[] = {
216 /*8 combination by {FULL_RES,RANGE}*/
217 {{ 3, 9}, 256}, /*+/-2g in 10-bit resolution: 3.9 mg/LSB*/
218 {{ 7, 8}, 128}, /*+/-4g in 10-bit resolution: 7.8 mg/LSB*/
219 {{15, 6}, 64}, /*+/-8g in 10-bit resolution: 15.6 mg/LSB*/
220 {{31, 2}, 32}, /*+/-16g in 10-bit resolution: 31.2 mg/LSB*/
221 {{ 3, 9}, 256}, /*+/-2g in 10-bit resolution: 3.9 mg/LSB (full-resolution)*/
222 {{ 3, 9}, 256}, /*+/-4g in 11-bit resolution: 3.9 mg/LSB (full-resolution)*/
223 {{ 3, 9}, 256}, /*+/-8g in 12-bit resolution: 3.9 mg/LSB (full-resolution)*/
224 {{ 3, 9}, 256}, /*+/-16g in 13-bit resolution: 3.9 mg/LSB (full-resolution)*/
226 /*----------------------------------------------------------------------------*/
227 static struct data_resolution lsm303m_offset_resolution
= {{15, 6}, 64};
229 /*--------------------ADXL power control function----------------------------------*/
230 static void lsm303m_power(struct mag_hw
*hw
, unsigned int on
)
232 static unsigned int power_on
= 0;
234 if(hw
->power_id
!= POWER_NONE_MACRO
) // have externel LDO
236 MSE_LOG("power %s\n", on
? "on" : "off");
237 if(power_on
== on
) // power status not change
239 MSE_LOG("ignore power control: %d\n", on
);
241 else if(on
) // power on
243 if(!hwPowerOn(hw
->power_id
, hw
->power_vol
, "LSM303M"))
245 MSE_ERR("power on fails!!\n");
250 if (!hwPowerDown(hw
->power_id
, "LSM303M"))
252 MSE_ERR("power off fail!!\n");
261 /*----------------------------------------- OK -----------------------------------*/
262 static int lsm303m_CheckDeviceID(struct i2c_client
*client
)
264 //MSE_LOG("++++++++++++++++++++++LSM303M_CheckDeviceID!");
269 memset(databuf
, 0, sizeof(u8
)*10);
270 databuf
[0] = LSM303M_REG_DEVID
;
272 res
= i2c_master_send(client
, databuf
, 0x1);
275 goto exit_LSM303M_CheckDeviceID
;
281 res
= i2c_master_recv(client
, databuf
, 0x01);
284 goto exit_LSM303M_CheckDeviceID
;
288 if(databuf
[0]!=LSM303M_FIXED_DEVID
)
290 return LSM303M_ERR_IDENTIFICATION
;
293 exit_LSM303M_CheckDeviceID
:
296 return LSM303M_ERR_I2C
;
299 return LSM303M_SUCCESS
;
304 /*--------------------------------------- YES -------------------------------------*/
305 static int lsm303m_SetPowerMode(struct i2c_client
*client
, bool enable
)
309 u8 addr
= LSM303M_REG_POWER_CTL
;
310 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(client
);
313 if(enable
== sensor_power
)
315 MSE_LOG("Sensor power status is newest!\n");
316 return LSM303M_SUCCESS
;
322 databuf
[0] = LSM303M_MAG_POWER_ON
;
326 databuf
[0] = LSM303M_MAG_POWER_OFF
;
328 databuf
[1] = databuf
[0];
329 databuf
[0] = LSM303M_REG_POWER_CTL
;
332 res
= i2c_master_send(client
, databuf
, 0x2);
336 MSE_LOG("set power mode failed!\n");
337 return LSM303M_ERR_I2C
;
339 else if(atomic_read(&obj
->trace
) & ADX_TRC_INFO
)
341 MSE_LOG("set power mode ok %d!\n", databuf
[1]);
344 sensor_power
= enable
;
349 /*----------------------------------- ok -----------------------------------------*/
350 static int lsm303m_SetBWRate(struct i2c_client
*client
, u8 bwrate
)
357 memset(databuf
, 0, sizeof(u8
)*10);
359 bwrate
= (ODR_MAG_MASK
& bwrate
);
362 databuf
[0] = LSM303M_REG_BW_RATE
;
365 res
= i2c_master_send(client
, databuf
, 0x2);
369 return LSM303M_ERR_I2C
;
372 return LSM303M_SUCCESS
;
376 /*---------------------------------- done ------------------------------------------*/
377 static int lsm303m_SetDataResolution(struct lsm303m_i2c_data
*obj
, u8 new_fs_range
)
384 switch (new_fs_range
) {
385 case LSM303M_MAG_FS_2G
:
386 obj
->reso
.sensitivity
= SENSITIVITY_MAG_2G
;
388 case LSM303M_MAG_FS_4G
:
389 obj
->reso
.sensitivity
= SENSITIVITY_MAG_4G
;
391 case LSM303M_MAG_FS_8G
:
392 obj
->reso
.sensitivity
= SENSITIVITY_MAG_8G
;
394 case LSM303M_MAG_FS_12G
:
395 obj
->reso
.sensitivity
= SENSITIVITY_MAG_12G
;
398 obj
->reso
.sensitivity
= SENSITIVITY_MAG_4G
;
399 MSE_LOG("invalid magnetometer fs range requested: %u\n", new_fs_range
);
409 /*--------------------------------- ok -------------------------------------------*/
410 static int lsm303m_SetDataFormat(struct i2c_client
*client
, u8 dataformat
)
412 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(client
);
418 memset(databuf
, 0, sizeof(u8
)*10);
420 dataformat
= ((LSM303M_MAG_FS_MASK
& dataformat
));
423 databuf
[0] = LSM303M_REG_DATA_FORMAT
;
424 databuf
[1] = dataformat
;
426 res
= i2c_master_send(client
, databuf
, 0x2);
430 return LSM303M_ERR_I2C
;
433 return lsm303m_SetDataResolution(obj
, dataformat
);
441 /*----------------------------------------------------------------------------*/
442 static int lsm303m_ReadChipInfo(struct i2c_client
*client
, char *buf
, int bufsize
)
446 memset(databuf
, 0, sizeof(u8
)*10);
448 if((NULL
== buf
)||(bufsize
<=30))
459 sprintf(buf
, "LSM303M Chip");
464 static int lsm303m_init_client(struct i2c_client
*client
, int reset_cali
)
466 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(client
);
472 res
= lsm303m_CheckDeviceID(client
);
473 if(res
!= LSM303M_SUCCESS
)
475 MSE_ERR("Check ID error\n");
480 res
= lsm303m_SetPowerMode(client
, false);
481 if(res
!= LSM303M_SUCCESS
)
483 MSE_ERR("set power error\n");
488 res
= lsm303m_SetBWRate(client
, LSM303M_MAG_ODR50
);
489 if(res
!= LSM303M_SUCCESS
) //0x2C->BW=100Hz
491 MSE_ERR("set power error\n");
496 res
= lsm303m_SetDataFormat(client
, LSM303M_MAG_FS_4G
);
497 if(res
!= LSM303M_SUCCESS
) //0x2C->BW=100Hz
499 MSE_ERR("set data format error\n");
505 #ifdef CONFIG_LSM303M_LOWPASS
506 memset(&obj
->fir
, 0x00, sizeof(obj
->fir
));
509 return LSM303M_SUCCESS
;
512 /*----------------------------------------------------------------------------*/
513 static int lsm303m_ReadData(struct i2c_client
*client
, s32 data
[LSM303M_AXES_NUM
])
515 struct lsm303m_i2c_data
*priv
= i2c_get_clientdata(client
);
516 u8 addr
= LSM303M_REG_DATAX0
| I2C_AUTO_INCREMENT
;
517 u8 buf
[LSM303M_DATA_LEN
] = {0};
524 else if((err
= hwmsen_read_block(client
, addr
, buf
, 0x06)))
526 MSE_ERR("error: %d\n", err
);
530 data
[LSM303M_AXIS_X
] = ((s32
)( (s16
)((buf
[LSM303M_AXIS_X
*2+1] << 8) | (buf
[LSM303M_AXIS_X
*2]))));
531 data
[LSM303M_AXIS_Y
] = ((s32
)( (s16
)((buf
[LSM303M_AXIS_Y
*2+1] << 8) | (buf
[LSM303M_AXIS_Y
*2]))));
532 data
[LSM303M_AXIS_Z
] = ((s32
)( (s16
)((buf
[LSM303M_AXIS_Z
*2+1] << 8) | (buf
[LSM303M_AXIS_Z
*2]))));
534 //MSE_LOG("lsm303m_ReadData [%08X %08X %08X] => [%5d %5d %5d]\n", data[LSM303M_AXIS_X], data[LSM303M_AXIS_Y], data[LSM303M_AXIS_Z],
535 // data[LSM303M_AXIS_X], data[LSM303M_AXIS_Y], data[LSM303M_AXIS_Z]);
536 if(atomic_read(&priv
->trace
) & ADX_TRC_RAWDATA
)
538 MSE_LOG("[%08X %08X %08X] => [%5d %5d %5d]\n", data
[LSM303M_AXIS_X
], data
[LSM303M_AXIS_Y
], data
[LSM303M_AXIS_Z
],
539 data
[LSM303M_AXIS_X
], data
[LSM303M_AXIS_Y
], data
[LSM303M_AXIS_Z
]);
547 /*----------------------------------------------------------------------------*/
548 static int lsm303m_ReadRawData(struct i2c_client
*client
, char *buf
)
550 struct lsm303m_i2c_data
*obj
= (struct lsm303m_i2c_data
*)i2c_get_clientdata(client
);
558 if((res
= lsm303m_ReadData(client
, obj
->data
)))
560 MSE_ERR("I2C error: ret value=%d", res
);
565 sprintf(buf
, "%04x %04x %04x", obj
->data
[LSM303M_AXIS_X
],
566 obj
->data
[LSM303M_AXIS_Y
], obj
->data
[LSM303M_AXIS_Z
]);
574 /*----------------------------------------------------------------------------*/
575 static int lsm303m_ReadSensorData(struct i2c_client
*client
, char *buf
, int bufsize
)
577 int mag
[LSM303M_DATA_LEN
];
579 struct lsm303m_i2c_data
*obj
= obj_i2c_data
; //(struct lsm303m_i2c_data*)i2c_get_clientdata(client);
580 client
= obj
->client
;
583 //memset(databuf, 0, sizeof(u8)*10);
595 if(sensor_power
== FALSE
)
597 res
= lsm303m_SetPowerMode(client
, true);
600 MSE_ERR("Power on lsm303m error %d!\n", res
);
605 if((res
= lsm303m_ReadData(client
, obj
->data
)))
607 MSE_ERR("I2C error: ret value=%d", res
);
615 mag
[obj
->cvt
.map
[LSM303M_AXIS_X
]] = obj
->cvt
.sign
[LSM303M_AXIS_X
]*obj
->data
[LSM303M_AXIS_X
] * obj
->reso
.sensitivity
/ 1000;
616 mag
[obj
->cvt
.map
[LSM303M_AXIS_Y
]] = obj
->cvt
.sign
[LSM303M_AXIS_Y
]*obj
->data
[LSM303M_AXIS_Y
] * obj
->reso
.sensitivity
/ 1000;
617 mag
[obj
->cvt
.map
[LSM303M_AXIS_Z
]] = obj
->cvt
.sign
[LSM303M_AXIS_Z
]*obj
->data
[LSM303M_AXIS_Z
] * obj
->reso
.sensitivity
/ 1000;
620 mag[obj->cvt.map[LSM303M_AXIS_X]] = obj->cvt.sign[LSM303M_AXIS_X]*obj->data[LSM303M_AXIS_X];
621 mag[obj->cvt.map[LSM303M_AXIS_Y]] = obj->cvt.sign[LSM303M_AXIS_Y]*obj->data[LSM303M_AXIS_Y];
622 mag[obj->cvt.map[LSM303M_AXIS_Z]] = obj->cvt.sign[LSM303M_AXIS_Z]*obj->data[LSM303M_AXIS_Z];
625 //MSE_LOG("Mapped msensor data: %d, %d, %d!\n", mag[LSM303M_AXIS_X], mag[LSM303M_AXIS_Y], mag[LSM303M_AXIS_Z]);
627 sprintf(buf
, "%04x %04x %04x", mag
[LSM303M_AXIS_X
], mag
[LSM303M_AXIS_Y
], mag
[LSM303M_AXIS_Z
]);
628 if(atomic_read(&obj
->trace
) & ADX_TRC_IOCTL
)
630 MSE_LOG("msensor data: %s!\n", buf
);
635 //MSE_LOG("io read msensor data: %d, %d, %d!\n", mag[LSM303M_AXIS_X],mag[LSM303M_AXIS_Y],mag[LSM303M_AXIS_Z]);
641 /*----------------------------------------------------------------------------*/
642 static int lsm303m_InitSelfTest(struct i2c_client
*client
)
646 return LSM303M_SUCCESS
;
648 /*----------------------------------------------------------------------------*/
649 static int lsm303m_JudgeTestResult(struct i2c_client
*client
, s32 prv
[LSM303M_AXES_NUM
], s32 nxt
[LSM303M_AXES_NUM
])
655 /*----------------------------------------------------------------------------*/
656 static ssize_t
show_chipinfo_value(struct device_driver
*ddri
, char *buf
)
658 struct i2c_client
*client
= lsm303m_i2c_client
;
659 char strbuf
[LSM303M_BUFSIZE
];
662 MSE_ERR("i2c client is null!!\n");
666 lsm303m_ReadChipInfo(client
, strbuf
, LSM303M_BUFSIZE
);
667 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
669 /*----------------------------------------------------------------------------*/
670 static ssize_t
show_sensordata_value(struct device_driver
*ddri
, char *buf
)
672 struct i2c_client
*client
= lsm303m_i2c_client
;
673 char strbuf
[LSM303M_BUFSIZE
];
677 MSE_ERR("i2c client is null!!\n");
680 lsm303m_ReadSensorData(client
, strbuf
, LSM303M_BUFSIZE
);
681 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
685 /*--------------------------------- NO -------------------------------------------*/
686 static ssize_t
show_reginfo_value(struct device_driver
*ddri
, char *buffer
)
689 struct i2c_client
*client
= lsm303m_i2c_client
;
691 struct lsm303m_i2c_data
*priv
= i2c_get_clientdata(client
);
692 u8 addr
= LSM303M_REG_CTL0
| I2C_AUTO_INCREMENT
;
702 else if((err
= hwmsen_read_block(client
, addr
, buf
, 0x08)))
704 MSE_ERR("error: %d\n", err
);
707 len
+= snprintf(buffer
+len
, PAGE_SIZE
, "0x%04X , \t 0x%04X , \t 0x%04X, \t0x%04X , \n 0x%04X , \t 0x%04X, \t0x%04X, \t 0x%04X , \t \n ",
708 buf
[0], buf
[1], buf
[2], buf
[3], buf
[4], buf
[5], buf
[6], buf
[7]);
713 /*-------------------------------- NO --------------------------------------------*/
714 static ssize_t
store_selftest_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
716 struct lsm303m_i2c_data
*obj
= obj_i2c_data
;
721 MSE_ERR("i2c data obj is null!!\n");
726 if(1 == sscanf(buf
, "%d", &tmp
))
728 if(atomic_read(&obj
->selftest
) && !tmp
)
730 /*enable -> disable*/
731 lsm303m_init_client(obj
->client
, 0);
733 else if(!atomic_read(&obj
->selftest
) && tmp
)
735 /*disable -> enable*/
736 lsm303m_InitSelfTest(obj
->client
);
739 MSE_LOG("selftest: %d => %d\n", atomic_read(&obj
->selftest
), tmp
);
740 atomic_set(&obj
->selftest
, tmp
);
744 MSE_ERR("invalid content: '%s', length = %d\n", buf
, count
);
749 /*----------------------------------------------------------------------------*/
750 static ssize_t
show_trace_value(struct device_driver
*ddri
, char *buf
)
753 struct lsm303m_i2c_data
*obj
= obj_i2c_data
;
756 MSE_ERR("i2c_data obj is null!!\n");
760 res
= snprintf(buf
, PAGE_SIZE
, "0x%04X\n", atomic_read(&obj
->trace
));
763 /*----------------------------------------------------------------------------*/
764 static ssize_t
store_trace_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
766 struct lsm303m_i2c_data
*obj
= obj_i2c_data
;
770 MSE_ERR("i2c_data obj is null!!\n");
774 if(1 == sscanf(buf
, "0x%x", &trace
))
776 atomic_set(&obj
->trace
, trace
);
780 MSE_ERR("invalid content: '%s', length = %d\n", buf
, count
);
785 /*----------------------------------------------------------------------------*/
786 static ssize_t
show_status_value(struct device_driver
*ddri
, char *buf
)
789 struct lsm303m_i2c_data
*obj
= obj_i2c_data
;
792 MSE_ERR("i2c_data obj is null!!\n");
798 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: %d %d (%d %d)\n",
799 obj
->hw
->i2c_num
, obj
->hw
->direction
, obj
->hw
->power_id
, obj
->hw
->power_vol
);
803 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: NULL\n");
808 static ssize_t
show_power_status_value(struct device_driver
*ddri
, char *buf
)
812 relv
= snprintf(buf
, PAGE_SIZE
, "1\n");
814 relv
= snprintf(buf
, PAGE_SIZE
, "0\n");
820 static ssize_t
store_power_status_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
824 sscanf(buf
, "%d", &mode
);
825 res
= lsm303m_SetPowerMode(lsm303m_i2c_client
, mode
);
831 /*----------------------------------------------------------------------------*/
832 static ssize_t
show_daemon_name(struct device_driver
*ddri
, char *buf
)
834 char strbuf
[LSM303M_BUFSIZE
];
835 sprintf(strbuf
, "lsm303md");
836 return sprintf(buf
, "%s", strbuf
);
838 /*----------------------------------------------------------------------------*/
840 /*----------------------------------------------------------------------------*/
841 static ssize_t
show_debug_value(struct device_driver
*ddri
, char *buf
)
844 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(lsm303m_i2c_client
);
847 MSE_ERR("lsm303m_i2c_data is null!!\n");
851 res
= snprintf(buf
, PAGE_SIZE
, "0x%04X\n", lsm303mmid_data
.controldata
[8]);
855 static ssize_t
store_debug_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
858 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(lsm303m_i2c_client
);
862 MSE_ERR("lsm303m_i2c_data is null!!\n");
866 if(1 == sscanf(buf
, "0x%x", &trace
))
868 //atomic_set(&obj->trace, trace);
869 lsm303mmid_data
.controldata
[8] = trace
;
873 MSE_ERR("invalid content: '%s', length = %d\n", buf
, count
);
879 /*----------------------------------------------------------------------------*/
880 static ssize_t
show_layout_value(struct device_driver
*ddri
, char *buf
)
882 struct i2c_client
*client
= lsm303m_i2c_client
;
883 struct lsm303m_i2c_data
*data
= i2c_get_clientdata(client
);
885 return sprintf(buf
, "(%d, %d)\n[%+2d %+2d %+2d]\n[%+2d %+2d %+2d]\n",
886 data
->hw
->direction
,atomic_read(&data
->layout
), data
->cvt
.sign
[0], data
->cvt
.sign
[1],
887 data
->cvt
.sign
[2],data
->cvt
.map
[0], data
->cvt
.map
[1], data
->cvt
.map
[2]);
890 /*----------------------------------------------------------------------------*/
891 static ssize_t
store_layout_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
893 struct i2c_client
*client
= lsm303m_i2c_client
;
894 struct lsm303m_i2c_data
*data
= i2c_get_clientdata(client
);
897 if(1 == sscanf(buf
, "%d", &layout
))
899 atomic_set(&data
->layout
, layout
);
900 if(!hwmsen_get_convert(layout
, &data
->cvt
))
902 MSE_ERR("HWMSEN_GET_CONVERT function ok!\r\n");
903 data
->hw
->direction
= layout
;
905 else if(!hwmsen_get_convert(data
->hw
->direction
, &data
->cvt
))
907 MSE_ERR("invalid layout: %d, restore to %d, no changed \n", layout
, data
->hw
->direction
);
912 MSE_ERR("invalid layout: (%d, %d)\n", layout
, data
->hw
->direction
);
913 hwmsen_get_convert(0, &data
->cvt
);
914 data
->hw
->direction
= 0;
919 MSE_ERR("invalid format = '%s'\n", buf
);
927 /*----------------------------------------------------------------------------*/
928 static DRIVER_ATTR(daemon
, S_IRUGO
, show_daemon_name
, NULL
);
929 static DRIVER_ATTR(chipinfo
, S_IRUGO
, show_chipinfo_value
, NULL
);
930 static DRIVER_ATTR(sensordata
, S_IRUGO
, show_sensordata_value
, NULL
);
931 static DRIVER_ATTR(reginfo
, S_IRUGO
, show_reginfo_value
, NULL
);
932 static DRIVER_ATTR(debugon
, S_IWUSR
| S_IRUGO
, show_debug_value
, store_debug_value
);
933 static DRIVER_ATTR(trace
, S_IWUSR
| S_IRUGO
, show_trace_value
, store_trace_value
);
934 static DRIVER_ATTR(status
, S_IRUGO
, show_status_value
, NULL
);
935 static DRIVER_ATTR(powerstatus
, S_IWUSR
| S_IRUGO
, show_power_status_value
, store_power_status_value
);
936 static DRIVER_ATTR(layout
, S_IRUGO
| S_IWUSR
, show_layout_value
, store_layout_value
);
939 /*----------------------------------------------------------------------------*/
940 static struct driver_attribute
*lsm303m_attr_list
[] = {
942 &driver_attr_chipinfo
, /*chip information*/
943 &driver_attr_sensordata
, /*dump sensor data*/
944 &driver_attr_reginfo
, /*self test demo*/
945 &driver_attr_debugon
, /*self test demo*/
946 &driver_attr_trace
, /*trace log*/
948 &driver_attr_powerstatus
,
953 /*----------------------------------------------------------------------------*/
954 static int lsm303m_create_attr(struct device_driver
*driver
)
957 int num
= (int)(sizeof(lsm303m_attr_list
)/sizeof(lsm303m_attr_list
[0]));
963 for(idx
= 0; idx
< num
; idx
++)
965 if((err
= driver_create_file(driver
, lsm303m_attr_list
[idx
])))
967 MSE_ERR("driver_create_file (%s) = %d\n", lsm303m_attr_list
[idx
]->attr
.name
, err
);
973 /*----------------------------------------------------------------------------*/
974 static int lsm303m_delete_attr(struct device_driver
*driver
)
977 int num
= (int)(sizeof(lsm303m_attr_list
)/sizeof(lsm303m_attr_list
[0]));
985 for(idx
= 0; idx
< num
; idx
++)
987 driver_remove_file(driver
, lsm303m_attr_list
[idx
]);
995 /*----------------------------------------------------------------------------*/
996 static int lsm303m_ReadCaliData(char *buf
, int bufsize
)
998 if((!buf
)||(bufsize
<=80))
1005 read_lock(&lsm303mmid_data
.datalock
);
1006 sprintf(buf
, "%d %d %d %d %d %d %d", lsm303mmid_data
.nmx
, lsm303mmid_data
.nmy
,
1007 lsm303mmid_data
.nmz
,lsm303mmid_data
.nax
,lsm303mmid_data
.nay
,lsm303mmid_data
.naz
,lsm303mmid_data
.mag_status
);
1008 read_unlock(&lsm303mmid_data
.datalock
);
1013 /*----------------------------------------------------------------------------*/
1014 static int lsm303m_ReadPostureData(char *buf
, int bufsize
)
1018 if((!buf
)||(bufsize
<=80))
1023 read_lock(&lsm303mmid_data
.datalock
);
1024 sprintf(buf
, "%d %d %d %d", lsm303mmid_data
.yaw
, lsm303mmid_data
.pitch
,
1025 lsm303mmid_data
.roll
, lsm303mmid_data
.mag_status
);
1026 read_unlock(&lsm303mmid_data
.datalock
);
1032 /*----------------------------------------------------------------------------*/
1033 int lsm303m_operate(void* self
, uint32_t command
, void* buff_in
, int size_in
,
1034 void* buff_out
, int size_out
, int* actualout
)
1037 int value
, sample_delay
, status
, delay_time
;
1038 hwm_sensor_data
* msensor_data
;
1039 struct lsm303m_i2c_data
*priv
= (struct lsm303m_i2c_data
*)self
;
1040 char buff
[LSM303M_BUFSIZE
];
1051 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
1053 MSE_ERR("Set delay parameter error!\n");
1058 value
= *(int *)buff_in
;
1059 MSE_LOG("Set delay parameter %d!\n", value
);
1062 sample_delay
= LSM303M_MAG_ODR50
;
1064 else if(value
<= 10)
1066 sample_delay
= LSM303M_MAG_ODR50
;
1070 sample_delay
= LSM303M_MAG_ODR50
;
1073 err
= lsm303m_SetBWRate(priv
->client
, sample_delay
);
1074 if(err
!= LSM303M_SUCCESS
) //0x2C->BW=100Hz
1076 MSE_ERR("Set delay parameter error!\n");
1079 value
= *(int *)buff_in
;
1085 lsm303mmid_data
.controldata
[0] = value
; // Loop Delay
1090 //MSE_LOG("***lsm303m SENSOR_ENABLE****");
1091 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
1093 MSE_ERR("Enable sensor parameter error!\n");
1098 value
= *(int *)buff_in
;
1099 read_lock(&lsm303mmid_data
.ctrllock
);
1102 MSE_LOG("lsm303m SENSOR_ENABLE");
1103 lsm303m_SetPowerMode( priv
->client
, 1);
1104 lsm303mmid_data
.controldata
[7] |= SENSOR_MAGNETIC
;
1105 atomic_set(&m_flag
, 1);
1106 atomic_set(&open_flag
, 1);
1110 lsm303m_SetPowerMode( priv
->client
, 0);
1111 lsm303mmid_data
.controldata
[7] &= ~SENSOR_MAGNETIC
;
1112 atomic_set(&m_flag
, 0);
1113 if(atomic_read(&o_flag
) == 0)
1115 atomic_set(&open_flag
, 0);
1119 read_unlock(&lsm303mmid_data
.ctrllock
);
1120 // TODO: turn device into standby or normal mode
1124 case SENSOR_GET_DATA
:
1125 //MSE_LOG("++++++++++++++++++++++++MSENSOR_GET_DATA");
1126 //MSE_LOG("***lsm303m SENSOR_GET_DATA****");
1127 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
1129 MSE_ERR("get sensor data parameter error!\n");
1135 msensor_data
= (hwm_sensor_data
*)buff_out
;
1136 read_lock(&lsm303mmid_data
.datalock
);
1137 msensor_data
->values
[0] = lsm303mmid_data
.nmx
;
1138 msensor_data
->values
[1] = lsm303mmid_data
.nmy
;
1139 msensor_data
->values
[2] = lsm303mmid_data
.nmz
;
1140 msensor_data
->status
= lsm303mmid_data
.mag_status
;
1142 read_unlock(&lsm303mmid_data
.datalock
);
1145 msensor_data
->values
[0] = msensor_data
->values
[0] / 10;
1146 msensor_data
->values
[1] = msensor_data
->values
[1] / 10;
1147 msensor_data
->values
[2] = msensor_data
->values
[2] / 10;
1148 msensor_data
->value_divide
= 1;
1153 msensor_data
->status
= SENSOR_STATUS_ACCURACY_HIGH
;
1156 msensor_data
->status
= SENSOR_STATUS_ACCURACY_MEDIUM
;
1159 msensor_data
->status
= SENSOR_STATUS_ACCURACY_LOW
;
1162 msensor_data
->status
= SENSOR_STATUS_UNRELIABLE
;
1166 msensor_data
->status
= SENSOR_STATUS_ACCURACY_HIGH
;
1168 //MSE_LOG("get msensor data: %d, %d, %d, %d!\n", msensor_data->values[0],msensor_data->values[1], msensor_data->values[2], msensor_data->status);
1173 MSE_ERR("msensor operate function no this parameter %d!\n", command
);
1183 /*----------------------------------------------------------------------------*/
1184 int lsm303m_orientation_operate(void* self
, uint32_t command
, void* buff_in
, int size_in
,
1185 void* buff_out
, int size_out
, int* actualout
)
1188 int value
, sample_delay
, status
=0;
1189 hwm_sensor_data
* osensor_data
=NULL
;
1190 struct lsm303m_i2c_data
*priv
= (struct lsm303m_i2c_data
*)self
;
1198 MSE_LOG("***orientation SENSOR_DELAY****");
1199 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
1201 MSE_ERR("Set delay parameter error!\n");
1206 value
= *(int *)buff_in
;
1213 lsm303mmid_data
.controldata
[0] = sample_delay
; // Loop Delay
1218 MSE_LOG("***orientation SENSOR_ENABLE****");
1219 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
1221 MSE_ERR("Enable sensor parameter error!\n");
1226 value
= *(int *)buff_in
;
1227 read_lock(&lsm303mmid_data
.ctrllock
);
1230 lsm303m_SetPowerMode( priv
->client
, 1);
1231 lsm303mmid_data
.controldata
[7] |= SENSOR_ORIENTATION
;
1232 atomic_set(&o_flag
, 1);
1233 atomic_set(&open_flag
, 1);
1237 lsm303m_SetPowerMode( priv
->client
, 0);
1238 lsm303mmid_data
.controldata
[7] &= ~SENSOR_ORIENTATION
;
1239 atomic_set(&o_flag
, 0);
1240 if(atomic_read(&m_flag
) == 0)
1242 atomic_set(&open_flag
, 0);
1246 read_unlock(&lsm303mmid_data
.ctrllock
);
1251 case SENSOR_GET_DATA
:
1252 //MSE_LOG("+++++++++++MSENSOR_GET_ORIENTATION_DATA");
1253 MSE_LOG("************OSENSOR_GET_DATA***********\r\n");
1254 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
1256 MSE_ERR("get sensor data parameter error!\n");
1261 osensor_data
= (hwm_sensor_data
*)buff_out
;
1262 read_lock(&lsm303mmid_data
.datalock
);
1263 osensor_data
->values
[0] = lsm303mmid_data
.yaw
;
1264 osensor_data
->values
[1] = lsm303mmid_data
.pitch
;
1265 osensor_data
->values
[2] = lsm303mmid_data
.roll
;
1266 status
= lsm303mmid_data
.mag_status
;
1267 read_unlock(&lsm303mmid_data
.datalock
);
1269 osensor_data
->value_divide
= 1;
1272 //MSE_LOG(" get osensor data: %d, %d, %d, %d!\n", osensor_data->values[0],osensor_data->values[1], osensor_data->values[2], osensor_data->status);
1278 osensor_data
->status
= SENSOR_STATUS_ACCURACY_HIGH
;
1281 osensor_data
->status
= SENSOR_STATUS_ACCURACY_MEDIUM
;
1284 osensor_data
->status
= SENSOR_STATUS_ACCURACY_LOW
;
1287 osensor_data
->status
= SENSOR_STATUS_UNRELIABLE
;
1292 MSE_ERR("msensor operate function no this parameter %d!\n", command
);
1302 /******************************************************************************
1303 * Function Configuration
1304 ******************************************************************************/
1305 static int lsm303m_open(struct inode
*inode
, struct file
*file
)
1307 file
->private_data
= lsm303m_i2c_client
;
1308 atomic_inc(&dev_open_count
);
1310 if(file
->private_data
== NULL
)
1312 MSE_ERR("null pointer!!\n");
1315 return nonseekable_open(inode
, file
);
1319 /*----------------------------------------------------------------------------*/
1320 static int lsm303m_release(struct inode
*inode
, struct file
*file
)
1322 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(lsm303m_i2c_client
);
1323 atomic_dec(&dev_open_count
);
1324 file
->private_data
= NULL
;
1325 if(atomic_read(&obj
->trace
) & ADX_TRC_INFO
)
1327 MSE_LOG("Release device node:ami304\n");
1333 static int lsm303m_GetOpenStatus(void)
1335 wait_event_interruptible(open_wq
, (atomic_read(&open_flag
) != 0));
1336 return atomic_read(&open_flag
);
1341 /*----------------------------------------------------------------------------*/
1342 //static int lsm303m_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)//modified here
1343 static long lsm303m_unlocked_ioctl(struct file
*file
, unsigned int cmd
,
1346 void __user
*argp
= (void __user
*)arg
;
1350 char strbuf
[LSM303M_BUFSIZE
];
1354 hwm_sensor_data
* osensor_data
;
1357 int status
; /* for OPEN/CLOSE_STATUS */
1358 short sensor_status
; /* for Orientation and Msensor status */
1359 struct lsm303m_i2c_data
*priv
= obj_i2c_data
;
1368 case MSENSOR_IOCTL_INIT
:
1369 MSE_LOG("===========IOCTL_INIT=======\r\n");
1370 read_lock(&lsm303m_data
.lock
);
1371 mode
= lsm303m_data
.mode
;
1372 read_unlock(&lsm303m_data
.lock
);
1373 lsm303m_init_client(lsm303m_i2c_client
, 0);
1376 case ECOMPASS_IOC_GET_OFLAG
:
1377 sensor_status
= atomic_read(&o_flag
);
1378 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
1380 MSE_ERR("copy_to_user failed.");
1385 case ECOMPASS_IOC_GET_MFLAG
:
1386 sensor_status
= atomic_read(&m_flag
);
1387 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
1389 MSE_ERR("copy_to_user failed.");
1394 case ECOMPASS_IOC_GET_OPEN_STATUS
:
1395 MSE_LOG("===========GET__OPEN_STATU=======\r\n");
1396 status
= lsm303m_GetOpenStatus();
1397 if(copy_to_user(argp
, &status
, sizeof(status
)))
1399 MSE_LOG("copy_to_user failed.");
1402 MSE_LOG("===========GET__OPEN_STATU DONE=======\r\n");
1405 case MSENSOR_IOCTL_SET_POSTURE
:
1406 //MSE_LOG("===========SET_POSTURE=======\r\n");
1407 data
= (void __user
*) arg
;
1410 MSE_ERR("IO parameter pointer is NULL!\r\n");
1414 if(copy_from_user(&valuebuf
, data
, sizeof(valuebuf
)))
1420 write_lock(&lsm303mmid_data
.datalock
);
1421 lsm303mmid_data
.yaw
= valuebuf
[0];
1422 lsm303mmid_data
.pitch
= valuebuf
[1];
1423 lsm303mmid_data
.roll
= valuebuf
[2];
1424 lsm303mmid_data
.mag_status
= valuebuf
[3];
1425 write_unlock(&lsm303mmid_data
.datalock
);
1428 //MSE_LOG("SET_POSTURE osensor data: %d, %d, %d!\n", lsm303mmid_data.yaw ,lsm303mmid_data.pitch ,lsm303mmid_data.pitch);
1432 case MSENSOR_IOCTL_SET_CALIDATA
:
1433 //MSE_LOG("===========IOCTL_SET_YPRdata=======\r\n");
1434 data
= (void __user
*) arg
;
1437 MSE_ERR("IO parameter pointer is NULL!\r\n");
1440 if(copy_from_user(&YPRdata
, data
, sizeof(YPRdata
)))
1446 write_lock(&lsm303mmid_data
.datalock
);
1447 lsm303mmid_data
.nmx
= YPRdata
[0];
1448 lsm303mmid_data
.nmy
= YPRdata
[1];
1449 lsm303mmid_data
.nmz
= YPRdata
[2];
1450 lsm303mmid_data
.mag_status
= YPRdata
[3];
1451 write_unlock(&lsm303mmid_data
.datalock
);
1452 //MSE_LOG("IOCTL_SET_YPRdata msensor data: %d, %d, %d!\n", lsm303mmid_data.nmx ,lsm303mmid_data.nmy ,lsm303mmid_data.nmz);
1455 case MSENSOR_IOCTL_READ_CHIPINFO
:
1456 data
= (void __user
*) arg
;
1459 MSE_ERR("IO parameter pointer is NULL!\r\n");
1463 lsm303m_ReadChipInfo(lsm303m_i2c_client
, strbuf
, LSM303M_BUFSIZE
);
1464 if(copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1471 case MSENSOR_IOCTL_SENSOR_ENABLE
:
1472 //MSE_LOG("===========IOCTL_SENSOR_ENABLE=======\r\n");
1474 data
= (void __user
*) arg
;
1477 MSE_ERR("IO parameter pointer is NULL!\r\n");
1480 if(copy_from_user(&enable
, data
, sizeof(enable
)))
1482 MSE_ERR("copy_from_user failed.");
1487 printk( "MSENSOR_IOCTL_SENSOR_ENABLE enable=%d!\r\n",enable
);
1488 read_lock(&lsm303mmid_data
.ctrllock
);
1491 lsm303m_SetPowerMode( priv
->client
, 1);
1492 lsm303mmid_data
.controldata
[7] |= SENSOR_ORIENTATION
;
1493 atomic_set(&o_flag
, 1);
1494 atomic_set(&open_flag
, 1);
1498 lsm303m_SetPowerMode( priv
->client
, 0);
1499 lsm303mmid_data
.controldata
[7] &= ~SENSOR_ORIENTATION
;
1500 atomic_set(&o_flag
, 0);
1501 if(atomic_read(&m_flag
) == 0)
1503 atomic_set(&open_flag
, 0);
1507 read_unlock(&lsm303mmid_data
.ctrllock
);
1513 case MSENSOR_IOCTL_READ_SENSORDATA
:
1514 //MSE_LOG("===========IOCTL_READ_SENSORDATA=======\r\n");
1515 data
= (void __user
*) arg
;
1518 MSE_ERR("IO parameter pointer is NULL!\r\n");
1521 lsm303m_ReadSensorData(lsm303m_i2c_client
, strbuf
, LSM303M_BUFSIZE
);
1522 if(copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1530 case MSENSOR_IOCTL_READ_FACTORY_SENSORDATA
:
1532 //MSE_LOG("===========IOCTL_READ_FACTORY_SENSORDATA=======\r\n");
1533 data
= (void __user
*) arg
;
1536 MSE_ERR("IO parameter pointer is NULL!\r\n");
1540 osensor_data
= (hwm_sensor_data
*)buff
;
1542 read_lock(&lsm303mmid_data
.datalock
);
1543 osensor_data
->values
[0] = lsm303mmid_data
.yaw
;
1544 osensor_data
->values
[1] = lsm303mmid_data
.pitch
;
1545 osensor_data
->values
[2] = lsm303mmid_data
.roll
;
1546 //status = lsm303mmid_data.mag_status;
1547 read_unlock(&lsm303mmid_data
.datalock
);
1549 osensor_data
->value_divide
= 1;
1551 switch (lsm303mmid_data
.mag_status
)
1554 osensor_data
->status
= SENSOR_STATUS_ACCURACY_HIGH
;
1557 osensor_data
->status
= SENSOR_STATUS_ACCURACY_MEDIUM
;
1560 osensor_data
->status
= SENSOR_STATUS_ACCURACY_LOW
;
1563 osensor_data
->status
= SENSOR_STATUS_UNRELIABLE
;
1568 sprintf(buff
, "%x %x %x %x %x", osensor_data
->values
[0], osensor_data
->values
[1],
1569 osensor_data
->values
[2],osensor_data
->status
,osensor_data
->value_divide
);
1570 if(copy_to_user(data
, buff
, strlen(buff
)+1))
1577 case MSENSOR_IOCTL_READ_POSTUREDATA
:
1578 //MSE_LOG("===========IOCTL_READ_READ_POSTUREDATA=======\r\n");
1579 data
= (void __user
*) arg
;
1582 MSE_ERR("IO parameter pointer is NULL!\r\n");
1586 lsm303m_ReadPostureData(strbuf
, LSM303M_BUFSIZE
);
1587 if(copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1594 case MSENSOR_IOCTL_READ_CALIDATA
:
1595 //MSE_LOG("===========IOCTL_READ_READ_CALIDATA=======\r\n");
1596 data
= (void __user
*) arg
;
1601 lsm303m_ReadCaliData(strbuf
, LSM303M_BUFSIZE
);
1602 if(copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1609 case MSENSOR_IOCTL_READ_CONTROL
:
1610 read_lock(&lsm303mmid_data
.ctrllock
);
1611 memcpy(controlbuf
, &lsm303mmid_data
.controldata
[0], sizeof(controlbuf
));
1612 read_unlock(&lsm303mmid_data
.ctrllock
);
1613 data
= (void __user
*) arg
;
1618 if(copy_to_user(data
, controlbuf
, sizeof(controlbuf
)))
1625 case MSENSOR_IOCTL_SET_CONTROL
:
1626 //MSE_LOG("===========IOCTL_SET_CONTROL=======\r\n");
1627 data
= (void __user
*) arg
;
1632 if(copy_from_user(controlbuf
, data
, sizeof(controlbuf
)))
1637 write_lock(&lsm303mmid_data
.ctrllock
);
1638 memcpy(&lsm303mmid_data
.controldata
[0], controlbuf
, sizeof(controlbuf
));
1639 write_unlock(&lsm303mmid_data
.ctrllock
);
1642 case MSENSOR_IOCTL_SET_MODE
:
1647 MSE_ERR("%s not supported = 0x%04x", __FUNCTION__
, cmd
);
1648 retval
= -ENOIOCTLCMD
;
1653 //MSE_LOG("===========liangruo lsm303m ioctl done err = %d, =======\r\n", retval);
1659 /*----------------------------------------------------------------------------*/
1660 static struct file_operations lsm303m_fops
= {
1661 // .owner = THIS_MODULE,
1662 .open
= lsm303m_open
,
1663 .release
= lsm303m_release
,
1664 .unlocked_ioctl
= lsm303m_unlocked_ioctl
,
1666 /*----------------------------------------------------------------------------*/
1667 static struct miscdevice lsm303m_device
= {
1668 .minor
= MISC_DYNAMIC_MINOR
,
1670 .fops
= &lsm303m_fops
,
1674 /*----------------------------------------------------------------------------*/
1675 //#ifndef CONFIG_HAS_EARLYSUSPEND
1676 /*----------------------------------------------------------------------------*/
1677 static int lsm303m_suspend(struct i2c_client
*client
, pm_message_t msg
)
1679 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(client
);
1683 if(msg
.event
== PM_EVENT_SUSPEND
)
1687 MSE_ERR("null pointer!!\n");
1690 atomic_set(&obj
->suspend
, 1);
1692 if((err = lsm303m_SetPowerMode(obj->client, false)))
1694 MSE_ERR("write power control fail!!\n");
1698 lsm303m_power(obj
->hw
, 0);
1699 MSE_LOG("lsm303m_suspend ok\n");
1703 /*----------------------------------------------------------------------------*/
1704 static int lsm303m_resume(struct i2c_client
*client
)
1706 struct lsm303m_i2c_data
*obj
= i2c_get_clientdata(client
);
1712 MSE_ERR("null pointer!!\n");
1716 lsm303m_power(obj
->hw
, 1);
1718 if((err = lsm303m_SetPowerMode(obj->client, true)))
1720 MSE_ERR("write power control fail!!\n");
1725 atomic_set(&obj
->suspend
, 0);
1726 MSE_LOG("lsm303m_resume ok\n");
1730 /*----------------------------------------------------------------------------*/
1731 //#else /*CONFIG_HAS_EARLY_SUSPEND is defined*/
1732 /*----------------------------------------------------------------------------*/
1733 static void lsm303m_early_suspend(struct early_suspend
*h
)
1735 struct lsm303m_i2c_data
*obj
= container_of(h
, struct lsm303m_i2c_data
, early_drv
);
1741 MSE_ERR("null pointer!!\n");
1744 atomic_set(&obj
->suspend
, 1);
1746 if((err = lsm303m_SetPowerMode(obj->client, false)))
1748 MSE_ERR("write power control fail!!\n");
1753 sensor_power
= false;
1755 lsm303m_power(obj
->hw
, 0);
1757 /*----------------------------------------------------------------------------*/
1758 static void lsm303m_late_resume(struct early_suspend
*h
)
1760 struct lsm303m_i2c_data
*obj
= container_of(h
, struct lsm303m_i2c_data
, early_drv
);
1766 MSE_ERR("null pointer!!\n");
1770 lsm303m_power(obj
->hw
, 1);
1773 if((err = lsm303m_SetPowerMode(obj->client, true)))
1775 MSE_ERR("write power control fail!!\n");
1779 atomic_set(&obj
->suspend
, 0);
1784 /*----------------------------------------------------------------------------*/
1785 static int lsm303m_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
)
1789 struct i2c_client
*new_client
;
1790 struct lsm303m_i2c_data
*data
;
1792 struct hwmsen_object sobj_m
, sobj_o
;
1796 client
->addr
= 0x3C>>1;
1798 if (!(data
= kmalloc(sizeof(struct lsm303m_i2c_data
), GFP_KERNEL
)))
1803 memset(data
, 0, sizeof(struct lsm303m_i2c_data
));
1805 data
->hw
= get_cust_mag_hw();
1806 if((err
= hwmsen_get_convert(data
->hw
->direction
, &data
->cvt
)))
1808 MSE_ERR("invalid direction: %d\n", data
->hw
->direction
);
1812 atomic_set(&data
->layout
, data
->hw
->direction
);
1813 atomic_set(&data
->trace
, 0);
1814 init_waitqueue_head(&data_ready_wq
);
1815 init_waitqueue_head(&open_wq
);
1817 data
->client
= client
;
1818 new_client
= data
->client
;
1819 i2c_set_clientdata(new_client
, data
);
1821 lsm303m_i2c_client
= new_client
;
1822 obj_i2c_data
= data
;
1824 if((err
= lsm303m_init_client(new_client
, 1)))
1826 goto exit_init_failed
;
1829 /* Register sysfs attribute */
1830 if((err
= lsm303m_create_attr(&lsm303m_msensor_driver
.driver
)))
1832 MSE_ERR("create attribute err = %d\n", err
);
1833 goto exit_sysfs_create_group_failed
;
1837 if((err
= misc_register(&lsm303m_device
)))
1839 MSE_ERR("lsm303m_device register failed\n");
1840 goto exit_misc_device_register_failed
;
1845 sobj_m
.sensor_operate
= lsm303m_operate
;
1846 if((err
= hwmsen_attach(ID_MAGNETIC
, &sobj_m
)))
1848 MSE_ERR("attach fail = %d\n", err
);
1854 sobj_o
.sensor_operate
= lsm303m_orientation_operate
;
1855 if((err
= hwmsen_attach(ID_ORIENTATION
, &sobj_o
)))
1857 MSE_ERR("attach fail = %d\n", err
);
1861 #if CONFIG_HAS_EARLYSUSPEND
1862 data
->early_drv
.level
= EARLY_SUSPEND_LEVEL_DISABLE_FB
- 1,
1863 data
->early_drv
.suspend
= lsm303m_early_suspend
,
1864 data
->early_drv
.resume
= lsm303m_late_resume
,
1865 register_early_suspend(&data
->early_drv
);
1868 MSE_LOG("%s: OK\n", __func__
);
1871 exit_sysfs_create_group_failed
:
1873 //i2c_detach_client(new_client);
1874 exit_misc_device_register_failed
:
1878 MSE_ERR("%s: err = %d\n", __func__
, err
);
1885 /*----------------------------------------------------------------------------*/
1886 static int lsm303m_i2c_remove(struct i2c_client
*client
)
1890 if((err
= lsm303m_delete_attr(&lsm303m_msensor_driver
.driver
)))
1892 MSE_ERR("lsm303m_delete_attr fail: %d\n", err
);
1895 if((err
= misc_deregister(&lsm303m_device
)))
1897 MSE_ERR("misc_deregister fail: %d\n", err
);
1900 if((err
= hwmsen_detach(ID_MAGNETIC
)))
1902 MSE_ERR("hwmsen_detach fail: %d\n", err
);
1904 if((err
= hwmsen_detach(ID_ORIENTATION
)))
1906 MSE_ERR("hwmsen_detach fail: %d\n", err
);
1910 lsm303m_i2c_client
= NULL
;
1911 i2c_unregister_device(client
);
1912 kfree(i2c_get_clientdata(client
));
1916 /*----------------------------------------------------------------------------*/
1917 static int lsm303m_probe(struct platform_device
*pdev
)
1919 struct mag_hw
*hw
= get_cust_mag_hw();
1923 lsm303m_power(hw
, 1);
1924 rwlock_init(&lsm303mmid_data
.ctrllock
);
1925 rwlock_init(&lsm303mmid_data
.datalock
);
1926 rwlock_init(&lsm303m_data
.lock
);
1927 memset(&lsm303mmid_data
.controldata
[0], 0, sizeof(int)*10);
1929 atomic_set(&dev_open_count
, 0);
1931 MSE_ERR("i2c add driver \n");
1933 //lsm303m_force[0] = hw->i2c_num;//modified
1934 if(i2c_add_driver(&lsm303m_i2c_driver
))
1936 MSE_ERR("add driver error\n");
1941 /*----------------------------------------------------------------------------*/
1942 static int lsm303m_remove(struct platform_device
*pdev
)
1944 struct mag_hw
*hw
= get_cust_mag_hw();
1947 lsm303m_power(hw
, 0);
1948 atomic_set(&dev_open_count
, 0);
1949 i2c_del_driver(&lsm303m_i2c_driver
);
1952 /*----------------------------------------------------------------------------*/
1954 static struct platform_driver lsm303m_msensor_driver
= {
1955 .probe
= lsm303m_probe
,
1956 .remove
= lsm303m_remove
,
1959 // .owner = THIS_MODULE,
1965 static const struct of_device_id lsm303m_of_match
[] = {
1966 { .compatible
= "mediatek,msensor", },
1971 static struct platform_driver lsm303m_msensor_driver
=
1973 .probe
= lsm303m_probe
,
1974 .remove
= lsm303m_remove
,
1979 .of_match_table
= lsm303m_of_match
,
1984 /*----------------------------------------------------------------------------*/
1985 static int __init
lsm303m_init(void)
1989 struct mag_hw
*hw
= get_cust_mag_hw();
1990 MSE_LOG("%s: i2c_number=%d\n", __func__
,hw
->i2c_num
);
1992 i2c_register_board_info(hw
->i2c_num
, &i2c_lsm303m
, 1);
1993 if(platform_driver_register(&lsm303m_msensor_driver
))
1995 MSE_ERR("failed to register driver");
2000 /*----------------------------------------------------------------------------*/
2001 static void __exit
lsm303m_exit(void)
2004 platform_driver_unregister(&lsm303m_msensor_driver
);
2007 /*----------------------------------------------------------------------------*/
2008 module_init(lsm303m_init
);
2009 module_exit(lsm303m_exit
);
2010 /*----------------------------------------------------------------------------*/
2011 MODULE_AUTHOR("Ruo Liang");
2012 MODULE_DESCRIPTION("LSM303M MI-Sensor driver without DRDY");
2013 MODULE_LICENSE("GPL");
2014 MODULE_VERSION("1.0.1");