int akm8975_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct akm8975_data *akm; int err; printk("ak8975 probe start!\n"); if (client->dev.platform_data == NULL) { dev_err(&client->dev, "platform data is NULL. exiting.\n"); err = -ENODEV; goto exit_platform_data_null; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C check failed, exiting.\n"); err = -ENODEV; goto exit_check_functionality_failed; } akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL); if (!akm) { dev_err(&client->dev, "failed to allocate memory for module data\n"); err = -ENOMEM; goto exit_alloc_data_failed; } akm->pdata = client->dev.platform_data; mutex_init(&akm->lock); init_completion(&akm->data_ready); i2c_set_clientdata(client, akm); akm->this_client = client; err = akm8975_ecs_set_mode_power_down(akm); if (err < 0) { pr_err("%s: akm8975_ecs_set_mode_power_down failed(%d)\n", __func__, err); goto exit_set_mode_power_down_failed; } err = akm8975_setup_irq(akm); if (err) { pr_err("%s: could not setup irq\n", __func__); goto exit_setup_irq; } akm->akmd_device.minor = MISC_DYNAMIC_MINOR; akm->akmd_device.name = "akm8975"; akm->akmd_device.fops = &akmd_fops; err = misc_register(&akm->akmd_device); if (err) { pr_err("%s misc_register failed\n", __func__); goto exit_akmd_device_register_failed; } init_waitqueue_head(&akm->state_wq); printk("ak8975 probe success!\n"); return 0; exit_akmd_device_register_failed: free_irq(akm->irq, akm); gpio_free(akm->pdata->gpio_data_ready_int); exit_setup_irq: exit_set_mode_power_down_failed: mutex_destroy(&akm->lock); kfree(akm); exit_alloc_data_failed: exit_check_functionality_failed: exit_platform_data_null: return err; }
int akm8975_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct akm8975_data *akm; int err; struct akm8975_platform_data *pdata = client->dev.platform_data; printk("ak8975 probe start!\n"); if (pdata == NULL) { dev_err(&client->dev, "platform data is NULL. exiting.\n"); err = -ENODEV; goto exit_platform_data_null; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C check failed, exiting.\n"); err = -ENODEV; goto exit_check_functionality_failed; } akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL); if (!akm) { dev_err(&client->dev, "failed to allocate memory for module data\n"); err = -ENOMEM; goto exit_alloc_data_failed; } akm->pdata = pdata; if(pdata->power_on) akm->power_on = pdata->power_on; if(pdata->power_off) akm->power_off = pdata->power_off; #if defined (CONFIG_KOR_MODEL_SHV_E110S) || defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) || defined(CONFIG_EUR_MODEL_GT_I9210) \ || defined(CONFIG_USA_MODEL_SGH_I577) #if defined(CONFIG_KOR_MODEL_SHV_E160S) || defined(CONFIG_KOR_MODEL_SHV_E160K) || defined(CONFIG_KOR_MODEL_SHV_E160L) if (get_hw_rev() >= 0x04 ) { #elif defined(CONFIG_USA_MODEL_SGH_I577) if (get_hw_rev() >= 0x06 ) { #else if (get_hw_rev() >= 0x08 ) { #endif /* For Magnetic sensor POR condition */ if(pdata->power_on_mag) pdata->power_on_mag(); msleep(1); if(pdata->power_off_mag) pdata->power_off_mag(); msleep(10); /* For Magnetic sensor POR condition */ } #endif #if defined (CONFIG_USA_MODEL_SGH_I717) if (get_hw_rev() >= 0x5) { /* For Magnetic sensor POR condition */ if(pdata->power_on_mag) pdata->power_on_mag(); msleep(1); if(pdata->power_off_mag) pdata->power_off_mag(); msleep(10); /* For Magnetic sensor POR condition */ } #endif if(akm->power_on) akm->power_on(); mutex_init(&akm->lock); init_completion(&akm->data_ready); i2c_set_clientdata(client, akm); akm->this_client = client; err = akm8975_ecs_set_mode_power_down(akm); if (err < 0) goto exit_set_mode_power_down_failed; err = akm8975_setup_irq(akm); if (err) { pr_err("%s: could not setup irq\n", __func__); goto exit_setup_irq; } akm->akmd_device.minor = MISC_DYNAMIC_MINOR; akm->akmd_device.name = "akm8975"; akm->akmd_device.fops = &akmd_fops; err = misc_register(&akm->akmd_device); if (err) goto exit_akmd_device_register_failed; #if defined(CONFIG_USA_MODEL_SGH_I577) || defined(CONFIG_USA_MODEL_SGH_I757) || defined(CONFIG_CAN_MODEL_SGH_I577R) || defined(CONFIG_CAN_MODEL_SGH_I757M) /* creating class/device for test */ akm->akm8975_class = class_create(THIS_MODULE, "magnetometer"); if(IS_ERR(akm->akm8975_class)) { pr_err("%s: class create failed(magnetometer)\n", __func__); err = PTR_ERR(akm->akm8975_class); goto exit_class_create_failed; } akm->akm8975_dev = device_create(akm->akm8975_class, NULL, 0, "%s", "magnetometer"); if(IS_ERR(akm->akm8975_dev)) { pr_err("%s: device create failed(magnetometer)\n", __func__); err = PTR_ERR(akm->akm8975_dev); goto exit_device_create_failed; } err = device_create_file(akm->akm8975_dev, &dev_attr_raw_data); if (err < 0) { pr_err("%s: failed to create device file(%s)\n", __func__, dev_attr_raw_data.attr.name); goto exit_device_create_file_failed; } dev_set_drvdata(akm->akm8975_dev, akm); #endif init_waitqueue_head(&akm->state_wq); printk("ak8975 probe success!\n"); return 0; #if defined(CONFIG_USA_MODEL_SGH_I577) || defined(CONFIG_USA_MODEL_SGH_I757) || defined(CONFIG_CAN_MODEL_SGH_I577R) || defined(CONFIG_CAN_MODEL_SGH_I757M) exit_device_create_file_failed: device_destroy(akm->akm8975_class, 0); exit_device_create_failed: class_destroy(akm->akm8975_class); exit_class_create_failed: misc_deregister(&akm->akmd_device); #endif exit_akmd_device_register_failed: free_irq(akm->irq, akm); // gpio_free(akm->pdata->gpio_data_ready_int); exit_setup_irq: exit_set_mode_power_down_failed: if(akm->power_off) akm->power_off(); mutex_destroy(&akm->lock); kfree(akm); exit_alloc_data_failed: exit_check_functionality_failed: exit_platform_data_null: return err; } static int __devexit akm8975_remove(struct i2c_client *client) { struct akm8975_data *akm = i2c_get_clientdata(client); misc_deregister(&akm->akmd_device); free_irq(akm->irq, akm); // gpio_free(akm->pdata->gpio_data_ready_int); mutex_destroy(&akm->lock); kfree(akm); return 0; } static const struct i2c_device_id akm8975_id[] = { {AKM8975_I2C_NAME, 0 }, { } }; static struct i2c_driver akm8975_driver = { .probe = akm8975_probe, .remove = akm8975_remove, .id_table = akm8975_id, .driver = { .pm = &akm8975_pm_ops, .name = AKM8975_I2C_NAME, }, }; #ifdef CONFIG_BATTERY_SEC extern unsigned int is_lpcharging_state(void); #endif static int __init akm8975_init(void) { #ifdef CONFIG_BATTERY_SEC if (is_lpcharging_state()) { pr_info("%s : LPM Charging Mode! return 0\n", __func__); return 0; } #endif return i2c_add_driver(&akm8975_driver); } static void __exit akm8975_exit(void) { i2c_del_driver(&akm8975_driver); } module_init(akm8975_init); module_exit(akm8975_exit); MODULE_DESCRIPTION("AKM8975 compass driver"); MODULE_LICENSE("GPL");
int akm8975_probe(struct i2c_client *client, const struct i2c_device_id *devid) { struct akm8975_data *akm; int err; if (client->dev.platform_data == NULL) { dev_err(&client->dev, "platform data is NULL. exiting.\n"); err = -ENODEV; goto exit_platform_data_null; } if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { dev_err(&client->dev, "I2C check failed, exiting.\n"); err = -ENODEV; goto exit_check_functionality_failed; } akm = kzalloc(sizeof(struct akm8975_data), GFP_KERNEL); if (!akm) { dev_err(&client->dev, "failed to allocate memory for module data\n"); err = -ENOMEM; goto exit_alloc_data_failed; } akm->pdata = client->dev.platform_data; mutex_init(&akm->lock); init_completion(&akm->data_ready); i2c_set_clientdata(client, akm); akm->this_client = client; err = akm8975_ecs_set_mode_power_down(akm); if (err < 0) goto exit_set_mode_power_down_failed; akm->irq = client->irq; err = akm8975_setup_irq(akm); if (err) { pr_err("%s: could not setup irq\n", __func__); goto exit_setup_irq; } akm->akmd_device.minor = MISC_DYNAMIC_MINOR; akm->akmd_device.name = "akm8975"; akm->akmd_device.fops = &akmd_fops; err = misc_register(&akm->akmd_device); if (err) goto exit_akmd_device_register_failed; init_waitqueue_head(&akm->state_wq); /* put into fuse access mode to read asa data */ err = i2c_smbus_write_byte_data(client, AK8975_REG_CNTL, REG_CNTL_MODE_FUSE_ROM); if (err) pr_err("%s: unable to enter fuse rom mode\n", __func__); err = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX, sizeof(akm->asa), akm->asa); if (err != sizeof(akm->asa)) pr_err("%s: unable to load factory sensitivity adjust values\n", __func__); else pr_debug("%s: asa_x = %d, asa_y = %d, asa_z = %d\n", __func__, akm->asa[0], akm->asa[1], akm->asa[2]); err = i2c_smbus_write_byte_data(client, AK8975_REG_CNTL, REG_CNTL_MODE_POWER_DOWN); if (err) { dev_err(&client->dev, "Error in setting power down mode\n"); goto exit_device_create_file2; } #if (defined DEBUG) || (defined FACTORY_TEST) ak8975c_selftest(akm); #endif #ifdef FACTORY_TEST err = sensors_register(magnetic_sensor_device, akm, magnetic_sensor_attrs, "magnetic_sensor"); if(err) { printk(KERN_ERR "%s: cound not register magnetic sensor device(%d).\n", __func__, err); } sec_ak8975_dev = device_create(sec_class, NULL, 0, akm, "sec_ak8975"); if (IS_ERR(sec_ak8975_dev)) printk("Failed to create device!"); if (device_create_file(sec_ak8975_dev, &dev_attr_ak8975_asa) < 0) { printk("Failed to create device file(%s)! \n", dev_attr_ak8975_asa.attr.name); goto exit_device_create_file2; } if (device_create_file(sec_ak8975_dev, &dev_attr_ak8975_selftest) < 0) { printk("Failed to create device file(%s)! \n", dev_attr_ak8975_selftest.attr.name); device_remove_file(sec_ak8975_dev, &dev_attr_ak8975_asa); goto exit_device_create_file2; } if (device_create_file(sec_ak8975_dev, &dev_attr_ak8975_chk_registers) < 0) { printk("Failed to create device file(%s)! \n", dev_attr_ak8975_chk_registers.attr.name); device_remove_file(sec_ak8975_dev, &dev_attr_ak8975_asa); device_remove_file(sec_ak8975_dev, &dev_attr_ak8975_selftest); goto exit_device_create_file2; } if (device_create_file(sec_ak8975_dev, &dev_attr_ak8975_chk_cntl) < 0) { printk("Failed to create device file(%s)! \n", dev_attr_ak8975_chk_cntl.attr.name); device_remove_file(sec_ak8975_dev, &dev_attr_ak8975_asa); device_remove_file(sec_ak8975_dev, &dev_attr_ak8975_selftest); device_remove_file(sec_ak8975_dev, &dev_attr_ak8975_chk_registers); goto exit_device_create_file2; } #endif return 0; exit_device_create_file2: exit_akmd_device_register_failed: free_irq(akm->irq, akm); gpio_free(akm->pdata->gpio_data_ready_int); exit_setup_irq: exit_set_mode_power_down_failed: mutex_destroy(&akm->lock); kfree(akm); exit_alloc_data_failed: exit_check_functionality_failed: exit_platform_data_null: return err; }