Beispiel #1
0
static int AMI304_Report_Value(int iEnable)
{
	int controlbuf[AMI304_CB_LENGTH];
	struct ami304_i2c_data *data = i2c_get_clientdata(ami304_i2c_client);
	int report_enable = 0;

	if( !iEnable )
		return -1;

	read_lock(&ami304mid_data.ctrllock);
	memcpy(controlbuf, &ami304mid_data.controldata[0], sizeof(controlbuf));
	read_unlock(&ami304mid_data.ctrllock);			

	if(controlbuf[AMI304_CB_ACTIVESENSORS] & AMIT_BIT_ACCELEROMETER) {
		input_report_abs(data->input_dev, ABS_X, ami304mid_data.na.x);/* x-axis raw acceleration */
		input_report_abs(data->input_dev, ABS_Y, ami304mid_data.na.y);/* y-axis raw acceleration */
		input_report_abs(data->input_dev, ABS_Z, ami304mid_data.na.z);/* z-axis raw acceleration */
		report_enable = 1;
	}

	if(controlbuf[AMI304_CB_ACTIVESENSORS] & AMIT_BIT_MAGNETIC_FIELD) {
		input_report_abs(data->input_dev, ABS_HAT0X, ami304mid_data.nm.x); /* x-axis of raw magnetic vector */
		input_report_abs(data->input_dev, ABS_HAT0Y, ami304mid_data.nm.y); /* y-axis of raw magnetic vector */
		input_report_abs(data->input_dev, ABS_BRAKE, ami304mid_data.nm.z); /* z-axis of raw magnetic vector */
		input_report_abs(data->input_dev, ABS_WHEEL, ami304mid_data.status);/* status of magnetic sensor */
		report_enable = 1;
	}

	if(controlbuf[AMI304_CB_ACTIVESENSORS] & AMIT_BIT_ORIENTATION) {
		input_report_abs(data->input_dev, ABS_RX, ami304mid_data.yaw);	/* yaw */
		input_report_abs(data->input_dev, ABS_RY, ami304mid_data.pitch);/* pitch */
		input_report_abs(data->input_dev, ABS_RZ, ami304mid_data.roll);/* roll */
		input_report_abs(data->input_dev, ABS_RUDDER, ami304mid_data.status);/* status of orientation sensor */
		report_enable = 1;
	}

	// LGE_CHANGE [[email protected]] 2010-10-28, not supported
#if 0
	if(controlbuf[AMI304_CB_ACTIVESENSORS] & AMIT_BIT_GYROSCOPE) {
		input_report_abs(data->input_dev, ABS_HAT1X, ami304mid_data.gyro.x);/* x-axis of gyro sensor */
		input_report_abs(data->input_dev, ABS_HAT1Y, ami304mid_data.gyro.y);/* y-axis of gyro sensor */
		input_report_abs(data->input_dev, ABS_THROTTLE, ami304mid_data.gyro.z);/* z-axis of gyro sensor */
		report_enable = 1;
	}
#endif
		

	if (AMI304_DEBUG_DEV_DEBOUNCE & ami304_debug_mask) {
		AMID("yaw: %d, pitch: %d, roll: %d\n", ami304mid_data.yaw, ami304mid_data.pitch, ami304mid_data.roll);
		AMID("nax: %d, nay: %d, naz: %d\n", ami304mid_data.na.x, ami304mid_data.na.y, ami304mid_data.na.z);
		AMID("nmx: %d, nmy: %d, nmz: %d\n", ami304mid_data.nm.x, ami304mid_data.nm.y, ami304mid_data.nm.z);
		AMID("mag_status: %d\n", ami304mid_data.status);
	}

	if (report_enable)
		input_sync(data->input_dev);

	return 0;
}
Beispiel #2
0
static int __init ami304_init(void)
{
	int ret;

	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("AMI304 MI sensor driver: init\n");
	rwlock_init(&ami304mid_data.ctrllock);
	rwlock_init(&ami304mid_data.datalock);
	rwlock_init(&ami304_data.lock);
	memset(&ami304mid_data.controldata[0], 0, sizeof(int)*10);
	ami304mid_data.controldata[0] = 200*1000; //Loop Delay
	ami304mid_data.controldata[1] = 0; // Run
	ami304mid_data.controldata[2] = 0; // Disable Start-AccCali
	ami304mid_data.controldata[3] = 1; // Enable Start-Cali
	ami304mid_data.controldata[4] = 350; // MW-Timout
	ami304mid_data.controldata[5] = 10; // MW-IIRStrength_M
	ami304mid_data.controldata[6] = 10; // MW-IIRStrength_G
	atomic_set(&dev_open_count, 0);
	atomic_set(&hal_open_count, 0);
	atomic_set(&daemon_open_count, 0);

	ret = i2c_add_driver(&ami304_i2c_driver);
	if (ret) {
		AMIE("failed to probe i2c \n");
		i2c_del_driver(&ami304_i2c_driver);
	}

	return ret;
}
Beispiel #3
0
static int ami304hal_open(struct inode *inode, struct file *file)
{
	atomic_inc(&hal_open_count);
	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("Open device node:ami304hal %d times.\n", atomic_read(&hal_open_count));
	return 0;
}
Beispiel #4
0
static int ami304daemon_release(struct inode *inode, struct file *file)
{
	atomic_set(&daemon_open_count, 0);
	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("Release device node:ami304daemon\n");
	return 0;
}
Beispiel #5
0
static int ami304hal_release(struct inode *inode, struct file *file)
{
	atomic_dec(&hal_open_count);
	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("Release ami304hal, remainder is %d times.\n", atomic_read(&hal_open_count));
	return 0;
}
Beispiel #6
0
static int AMI304_Report_Value(int en_dis)
{
	struct ami304_i2c_data *data = i2c_get_clientdata(ami304_i2c_client);
	char report_enable = 0;

	if( !en_dis )
		return 0;

	if(atomic_read(&o_status))
	{
		input_report_abs(data->input_dev, ABS_RX, ami304mid_data.yaw);	/* yaw */
		input_report_abs(data->input_dev, ABS_RY, ami304mid_data.pitch);/* pitch */
		input_report_abs(data->input_dev, ABS_RZ, ami304mid_data.roll);/* roll */
		input_report_abs(data->input_dev, ABS_RUDDER, ami304mid_data.mag_status);/* status of orientation sensor */
		report_enable = 1;
	}

	if(atomic_read(&a_status))
	{
		input_report_abs(data->input_dev, ABS_X, ami304mid_data.nax);/* x-axis raw acceleration */
		input_report_abs(data->input_dev, ABS_Y, ami304mid_data.nay);/* y-axis raw acceleration */
		input_report_abs(data->input_dev, ABS_Z, ami304mid_data.naz);/* z-axis raw acceleration */
		report_enable = 1;
	}

	if(atomic_read(&m_status))
	{
		input_report_abs(data->input_dev, ABS_HAT0X, ami304mid_data.nmx); /* x-axis of raw magnetic vector */
		input_report_abs(data->input_dev, ABS_HAT0Y, ami304mid_data.nmy); /* y-axis of raw magnetic vector */
		input_report_abs(data->input_dev, ABS_BRAKE, ami304mid_data.nmz); /* z-axis of raw magnetic vector */
		input_report_abs(data->input_dev, ABS_WHEEL, ami304mid_data.mag_status);/* status of magnetic sensor */
		report_enable = 1;
	}

	if (AMI304_DEBUG_DEV_DEBOUNCE & ami304_debug_mask)
	{
		AMID("yaw: %d, pitch: %d, roll: %d\n", ami304mid_data.yaw, ami304mid_data.pitch, ami304mid_data.roll);
		AMID("nax: %d, nay: %d, naz: %d\n", ami304mid_data.nax, ami304mid_data.nay, ami304mid_data.naz);
		AMID("nmx: %d, nmy: %d, nmz: %d\n", ami304mid_data.nmx, ami304mid_data.nmy, ami304mid_data.nmz);
		AMID("mag_status: %d\n", ami304mid_data.mag_status);
	}

	if(report_enable)
		input_sync(data->input_dev);

	return 0;
}
Beispiel #7
0
static int AMI304_ReadSensorData(char *buf, int bufsize)
{
	char cmd;
	int mode = 0;
	unsigned char databuf[10] = {0,};
	int res = 0;

	if ((!buf)||(bufsize<=80))
		return -1;
	if (!ami304_i2c_client)
	{
		*buf = 0;
		return -2;
	}

	read_lock(&ami304_data.lock);
	mode = ami304_data.mode;
	read_unlock(&ami304_data.lock);

	databuf[0] = AMI304_REG_CTRL3;
	databuf[1] = AMI304_CTRL3_FORCE_BIT;
	res = i2c_master_send(ami304_i2c_client, databuf, 2);
	if (res<=0) goto exit_AMI304_ReadSensorData;

	// We can read all measured data in once
	cmd = AMI304_REG_DATAXH;
	res = i2c_master_send(ami304_i2c_client, &cmd, 1);
	if (res<=0) goto exit_AMI304_ReadSensorData;
	res = i2c_master_recv(ami304_i2c_client, &(databuf[0]), 6);
	if (res<=0) goto exit_AMI304_ReadSensorData;

	sprintf(buf, "%02x %02x %02x %02x %02x %02x", databuf[0], databuf[1], databuf[2], databuf[3], databuf[4], databuf[5]);

	if (AMI304_DEBUG_DEV_STATUS & ami304_debug_mask)
	{
		int mx, my, mz;
		mx = my = mz = 0;

		mx = (int)(databuf[0] | (databuf[1] << 8));
		my = (int)(databuf[2] | (databuf[3] << 8));
		mz = (int)(databuf[4] | (databuf[5] << 8));

		if (mx>32768)  mx = mx-65536;
		if (my>32768)  my = my-65536;
		if (mz>32768)  mz = mz-65536;

		//AMID("X=%d, Y=%d, Z=%d\n", (int)(databuf[0] | (databuf[1]  << 8)), (int)(databuf[2] | (databuf[3] << 8)), (int)(databuf[4] | (databuf[5] << 8)));
		AMID("X=%d, Y=%d, Z=%d\n", mx, my, mz);
	}

exit_AMI304_ReadSensorData:
	if (res<=0) {
		if(printk_ratelimit())
		AMIE("I2C error: ret value=%d\n", res);
		return -3;
	}
	return 0;
}
Beispiel #8
0
static int ami304_open(struct inode *inode, struct file *file)
{
	int ret = -1;
	if( atomic_cmpxchg(&dev_open_count, 0, 1)==0 ) {
		if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
			AMID("Open device node:ami304\n");
		ret = nonseekable_open(inode, file);
	}
	return ret;
}
Beispiel #9
0
static int ami304daemon_open(struct inode *inode, struct file *file)
{
	int res = -1;

	if (atomic_cmpxchg(&daemon_open_count, 0, 1) == 0) {
		if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
			AMID("Open device node:ami304daemon\n");
		res = 0;
	}
	return res;
}
Beispiel #10
0
static int ami304_suspend(struct device *device)
{
	struct ecom_platform_data* ecom_pdata;

	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("AMI304 suspend....!\n");

	ecom_pdata = ami304_i2c_client->dev.platform_data;
	ecom_pdata->power(0);

	return 0;
}
Beispiel #11
0
static int ami304_resume(struct device *device)
{
	struct ecom_platform_data* ecom_pdata;
	ecom_pdata = ami304_i2c_client->dev.platform_data;

	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("AMI304 resume....!\n");

	ecom_pdata->power(1);
	AMI304_Init(ami304_data.mode);

	return 0;
}
Beispiel #12
0
static int ami304_resume(struct device *device)
{
	struct ecom_platform_data* ecom_pdata;
	ecom_pdata = ami304_i2c_client->dev.platform_data;

	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("AMI304 resume....!\n");

	ecom_pdata->power(1);
	AMI304_Chipset_Init(ami304_data.mode, ami304_data.chipset);

//20110222
	write_lock(&ami304mid_data.ctrllock);
	ami304mid_data.controldata[AMI304_CB_RUN] = 2;         // Run = 1	//resume = 2
	write_unlock(&ami304mid_data.ctrllock);
	return 0;
}
static int __init ami306_init(void)
{
	int res;

	if (AMI306_DEBUG_FUNC_TRACE & ami306_debug_mask)
		AMID("AMI306 MI sensor driver: init\n");
	rwlock_init(&ami306mid_data.ctrllock);
	rwlock_init(&ami306mid_data.datalock);
	rwlock_init(&ami306_data.lock);
	memset(&ami306mid_data.controldata[0], 0, sizeof(int)*10);
	/* LGE_CHANGE 
	 * 200ms is too slow to calibrate, so set 100ms
	 */
	/* LGE_CHANGE 
	 * 20 ms by sprint request
	 */
	ami306mid_data.controldata[AMI306_CB_LOOPDELAY] = 20;  // Loop Delay
	ami306mid_data.controldata[AMI306_CB_RUN] = 1;         // Run	
	ami306mid_data.controldata[AMI306_CB_ACCCALI] = 0;     // Start-AccCali
	ami306mid_data.controldata[AMI306_CB_MAGCALI] = 1;     // Start-MagCali
	ami306mid_data.controldata[AMI306_CB_ACTIVESENSORS] = 0;   // Active Sensors
	ami306mid_data.controldata[AMI306_CB_PD_RESET] = 0;    // Pedometer not reset    
	ami306mid_data.controldata[AMI306_CB_PD_EN_PARAM] = 0; // Disable parameters of Pedometer
	ami306mid_data.controldata[AMI306_CB_QWERTY] =   0;   // Qwerty Keyboard : close -> 0, open -> 1.
	ami306mid_data.controldata[AMI306_CB_CHANGE_WINDOW] =   0;   //ADC_WINDOW_CONTROL: ADC_WINDOW_NORMAL->0 ADC_WINDOW_CHANGED->1 ADC_WINDOW_EXCEEDED->2
	memset(&ami306mid_data.pedometerparam[0], 0, sizeof(int)*AMI306_PD_LENGTH);	
	atomic_set(&dev_open_count, 0);
	atomic_set(&hal_open_count, 0);
	atomic_set(&daemon_open_count, 0);

	res = i2c_add_driver(&ami306_i2c_driver);

	printk(KERN_INFO "[jaekyung83.lee]ami init\n");
	if (res) {
		AMIE("failed to probe i2c \n");
		i2c_del_driver(&ami306_i2c_driver);
	}

	return res;
}
Beispiel #14
0
static int __init ami304_probe(struct i2c_client *client, const struct i2c_device_id * devid)
{
	int err = 0;
	struct ami304_i2c_data *data;
	struct ecom_platform_data* ecom_pdata;

	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("motion start....!\n");

	if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		AMIE("adapter can NOT support I2C_FUNC_I2C.\n");
		return -ENODEV;
	}

	if (!(data = kmalloc(sizeof(struct ami304_i2c_data), GFP_KERNEL))) {
		err = -ENOMEM;
		goto exit;
	}
	memset(data, 0, sizeof(struct ami304_i2c_data));

	i2c_set_clientdata(client, data);
	ami304_i2c_client = client;

	ecom_pdata = ami304_i2c_client->dev.platform_data;
	ecom_pdata->power(1);
	AMI304_Init(AMI304_FORCE_MODE); // default is Force State

	atomic_set(&o_status, 0);
	atomic_set(&m_status, 0);
	atomic_set(&a_status, 0);

#if defined(CONFIG_HAS_EARLYSUSPEND)
	ami304_sensor_early_suspend.suspend = ami304_early_suspend;
	ami304_sensor_early_suspend.resume = ami304_late_resume;
	register_early_suspend(&ami304_sensor_early_suspend);

	atomic_set(&ami304_report_enabled, 1);
#endif

	data->input_dev = input_allocate_device();
	if (!data->input_dev) {
		err = -ENOMEM;
		AMIE("ami304_i2c_detect: Failed to allocate input device\n");
		goto exit_input_dev_alloc_failed;
	}

	set_bit(EV_ABS, data->input_dev->evbit);
	/* yaw */
	input_set_abs_params(data->input_dev, ABS_RX, 0, 360, 0, 0);
	/* pitch */
	input_set_abs_params(data->input_dev, ABS_RY, -180, 180, 0, 0);
	/* roll */
	input_set_abs_params(data->input_dev, ABS_RZ, -90, 90, 0, 0);
	/* status of magnetic sensor */
	input_set_abs_params(data->input_dev, ABS_RUDDER, 0, 5, 0, 0);

	/* x-axis acceleration */
	input_set_abs_params(data->input_dev, ABS_X, -2000, 2000, 0, 0);
	/* y-axis acceleration */
	input_set_abs_params(data->input_dev, ABS_Y, -2000, 2000, 0, 0);
	/* z-axis acceleration */
	input_set_abs_params(data->input_dev, ABS_Z, -2000, 2000, 0, 0);

	/* x-axis of raw magnetic vector */
	input_set_abs_params(data->input_dev, ABS_HAT0X, -3000, 3000, 0, 0);
	/* y-axis of raw magnetic vector */
	input_set_abs_params(data->input_dev, ABS_HAT0Y, -3000, 3000, 0, 0);
	/* z-axis of raw magnetic vector */
	input_set_abs_params(data->input_dev, ABS_BRAKE, -3000, 3000, 0, 0);
	/* status of acceleration sensor */
	input_set_abs_params(data->input_dev, ABS_WHEEL, 0, 5, 0, 0);

	data->input_dev->name = "Acompass";

	err = input_register_device(data->input_dev);
	if (err) {
		AMIE("ami304_i2c_detect: Unable to register input device: %s\n",
		       data->input_dev->name);
		goto exit_input_register_device_failed;
	}
	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
	        AMID("register input device successfully!!!\n");

	err = misc_register(&ami304_device);
	if (err) {
		AMIE("ami304_device register failed\n");
		goto exit_misc_device_register_failed;
	}
	err = device_create_file(&client->dev, &dev_attr_chipinfo);
	err = device_create_file(&client->dev, &dev_attr_sensordata);
	err = device_create_file(&client->dev, &dev_attr_posturedata);
	err = device_create_file(&client->dev, &dev_attr_calidata);
	err = device_create_file(&client->dev, &dev_attr_midcontrol);
	err = device_create_file(&client->dev, &dev_attr_mode);
	/* Test mode attribute */
	err = device_create_file(&client->dev, &dev_attr_pitch);
	err = device_create_file(&client->dev, &dev_attr_roll);

	err = misc_register(&ami304daemon_device);
	if (err) {
		AMIE("ami304daemon_device register failed\n");
		goto exit_misc_device_register_failed;
	}

	err = misc_register(&ami304hal_device);
	if (err) {
		AMIE("ami304hal_device register failed\n");
		goto exit_misc_device_register_failed;
	}

	return 0;
exit_misc_device_register_failed:
exit_input_register_device_failed:
	input_free_device(data->input_dev);
exit_input_dev_alloc_failed:
	kfree(data);
exit:
	return err;
}
Beispiel #15
0
static int ami304_input_init(struct ami304_i2c_data *data)
{
	int err=0;
	data->input_dev = input_allocate_device();
	if (!data->input_dev) {
		err = -ENOMEM;
		AMIE("ami304_i2c_detect: Failed to allocate input device\n");
		goto exit_input_dev_alloc_failed;
	}

	set_bit(EV_ABS, data->input_dev->evbit);

	/* yaw */
	input_set_abs_params(data->input_dev, ABS_RX, 0, (360*10), 0, 0);
	/* pitch */
	input_set_abs_params(data->input_dev, ABS_RY, -(180*10), (180*10), 0, 0);
	/* roll */
	input_set_abs_params(data->input_dev, ABS_RZ, -(90*10), (90*10), 0, 0);
	/* status of orientation sensor */	
	input_set_abs_params(data->input_dev, ABS_RUDDER, 0, 5, 0, 0);
	
	/* x-axis of raw acceleration and the range is -2g to +2g */
	input_set_abs_params(data->input_dev, ABS_X, -(1000*2), (1000*2), 0, 0);
	/* y-axis of raw acceleration and the range is -2g to +2g */
	input_set_abs_params(data->input_dev, ABS_Y, -(1000*2), (1000*2), 0, 0);
	/* z-axis of raw acceleration and the range is -2g to +2g */
	input_set_abs_params(data->input_dev, ABS_Z, -(1000*2), (1000*2), 0, 0);
	
	/* x-axis of raw magnetic vector and the range is -3g to +3g */
	input_set_abs_params(data->input_dev, ABS_HAT0X, -(4000*3), (4000*3), 0, 0);
	/* y-axis of raw magnetic vector and the range is -3g to +3g */
	input_set_abs_params(data->input_dev, ABS_HAT0Y, -(4000*3), (4000*3), 0, 0);
	/* z-axis of raw magnetic vector and the range is -3g to +3g */
	input_set_abs_params(data->input_dev, ABS_BRAKE, -(4000*3), (4000*3), 0, 0);
	/* status of magnetic sensor */
	input_set_abs_params(data->input_dev, ABS_WHEEL, 0, 5, 0, 0);	

	/* x-axis of gyro sensor */
	input_set_abs_params(data->input_dev, ABS_HAT1X, -10000, 10000, 0, 0);
	/* y-axis of gyro sensor */
	input_set_abs_params(data->input_dev, ABS_HAT1Y, -10000, 10000, 0, 0);
	/* z-axis of gyro sensor */
	input_set_abs_params(data->input_dev, ABS_THROTTLE, -10000, 10000, 0, 0);

	data->input_dev->name = "Acompass";

	err = input_register_device(data->input_dev);
	if (err) {
		AMIE("ami304_i2c_detect: Unable to register input device: %s\n",
		       data->input_dev->name);
		goto exit_input_register_device_failed;
	}
	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
	        AMID("register input device successfully!!!\n");
	return 0;

exit_input_register_device_failed:
	input_free_device(data->input_dev);	
exit_input_dev_alloc_failed:
	return err;	
}
Beispiel #16
0
static int ami304hal_ioctl(struct inode *inode, struct file *file, unsigned int cmd,unsigned long arg)
{
	char strbuf[AMI304_BUFSIZE];
	void __user *data;
	int retval=0;
	unsigned int mode =0;
	int controlbuf[10];

	switch (cmd) {

		case AMI304HAL_IOCTL_GET_SENSORDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadSensorData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304HAL_IOCTL_GET_POSTURE:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadPostureData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
			break;

		case AMI304HAL_IOCTL_GET_CALIDATA:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			AMI304_ReadCaliData(strbuf, AMI304_BUFSIZE);
			if (copy_to_user(data, strbuf, strlen(strbuf)+1)) {
				retval = -EFAULT;
				goto err_out;
			}
	        	break;
		case AMI304HAL_IOCTL_SET_ACTIVE:
			data = (void __user *) arg;
			if (data == NULL)
				break;

			if (copy_from_user(&mode, data, sizeof(mode))) {
				retval = -EFAULT;
				goto err_out;
			}

			if (AMI304_DEBUG_GEN_INFO & ami304_debug_mask)
				AMID("ami304hal active sensor %d\n", mode);

			if(mode & (0x00000001<<AMI_ORIENTATION_SENSOR))
				atomic_set(&o_status, 1);
			else
				atomic_set(&o_status, 0);

			if(mode & (0x00000001<<AMI_MAGNETIC_FIELD_SENSOR))
				atomic_set(&m_status, 1);
			else
				atomic_set(&m_status, 0);

			if(mode & (0x00000001<<AMI_ACCELEROMETER_SENSOR))
				atomic_set(&a_status, 1);
			else
				atomic_set(&a_status, 0);

	        	break;

		case AMI304HAL_IOCTL_GET_CONTROL:
			read_lock(&ami304mid_data.ctrllock);
			memcpy(controlbuf, &ami304mid_data.controldata[0], sizeof(controlbuf));
			read_unlock(&ami304mid_data.ctrllock);
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_to_user(data, controlbuf, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			break;


		case AMI304HAL_IOCTL_SET_CONTROL:
			data = (void __user *) arg;
			if (data == NULL)
				break;
			if (copy_from_user(controlbuf, data, sizeof(controlbuf))) {
				retval = -EFAULT;
				goto err_out;
			}
			write_lock(&ami304mid_data.ctrllock);
			memcpy(&ami304mid_data.controldata[0], controlbuf, sizeof(controlbuf));
			write_unlock(&ami304mid_data.ctrllock);

			if (AMI304_DEBUG_DELAY_SETTING & ami304_debug_mask)
				AMID("Dleay setting = %dms\n", ami304mid_data.controldata[0] / 1000);

			break;

		default:
			if (AMI304_DEBUG_USER_ERROR & ami304_debug_mask)
				AMIE("not supported command= 0x%04x\n", cmd);
			retval = -ENOIOCTLCMD;
			break;
	}

err_out:
	return retval;
}
Beispiel #17
0
static int __devinit ami304_probe(struct i2c_client *client, 
		const struct i2c_device_id * devid)
{
	int err = 0;
	struct ami304_i2c_data *data;
	struct ecom_platform_data* ecom_pdata;
	
	if (AMI304_DEBUG_FUNC_TRACE & ami304_debug_mask)
		AMID("motion start....!\n");

	if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		AMIE("adapter can NOT support I2C_FUNC_I2C.\n");
		return -ENODEV;
	}

	if (!(data = kmalloc(sizeof(struct ami304_i2c_data), GFP_KERNEL))) {
		err = -ENOMEM;
		goto exit;
	}
	memset(data, 0, sizeof(struct ami304_i2c_data));

	data->client = client;
	i2c_set_clientdata(client, data);
	ami304_i2c_client = client;

	ecom_pdata = ami304_i2c_client->dev.platform_data;
	ecom_pdata->power(1);

#if defined(CONFIG_HAS_EARLYSUSPEND)
	ami304_sensor_early_suspend.suspend = ami304_early_suspend;
	ami304_sensor_early_suspend.resume = ami304_late_resume;
	register_early_suspend(&ami304_sensor_early_suspend);

	atomic_set(&ami304_report_enabled, 1);
#endif
	err=Identify_AMI_Chipset();
	if (err != 0) {  //get ami304_data.chipset
		printk(KERN_INFO "Failed to identify AMI_Chipset!\n");	
		goto exit_kfree;
	}

	AMI304_Chipset_Init(AMI304_FORCE_MODE, ami304_data.chipset); // default is Force State	
	dev_info(&client->dev, "%s operating mode\n", ami304_data.mode? "force" : "normal");

	printk(KERN_INFO "Register input device!\n");	
	err = ami304_input_init(data);
	if(err)
		goto exit_kfree;

	//register misc device:ami304	       
	err = misc_register(&ami304_device);
	if (err) {
		AMIE("ami304_device register failed\n");
		goto exit_misc_ami304_device_register_failed;
	}
	//register misc device:ami304daemon	
	err = misc_register(&ami304daemon_device);
	if (err) {
		AMIE("ami304daemon_device register failed\n");
		goto exit_misc_ami304daemon_device_register_failed;
	}
	//register misc device:ami304hal
	err = misc_register(&ami304hal_device);
	if (err) {
		AMIE("ami304hal_device register failed\n");
		goto exit_misc_ami304hal_device_register_failed;
	}

	/* Register sysfs hooks */
	err = sysfs_create_group(&client->dev.kobj, &ami304_attribute_group);
	if (err) {
		AMIE("ami304 sysfs register failed\n");
		goto exit_sysfs_create_group_failed;
	}

	return 0;

exit_sysfs_create_group_failed:	
	sysfs_remove_group(&client->dev.kobj, &ami304_attribute_group);
exit_misc_ami304hal_device_register_failed:
	misc_deregister(&ami304daemon_device);
exit_misc_ami304daemon_device_register_failed:
	misc_deregister(&ami304_device);
exit_misc_ami304_device_register_failed:
	input_unregister_device(data->input_dev);
	input_free_device(data->input_dev);
exit_kfree:
	kfree(data);
exit:
	return err;
}