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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }