Пример #1
0
static int akmd_suspend(struct device *dev)
{
	struct akm8975_data *data = dev_get_drvdata(dev);
	int res = 0;

	akm8975_ecs_set_mode_power_down(data);

	/* Wait at least 300us after changing mode. */
	udelay(300);

	if(data->power_off)
		data->power_off();
#if defined (CONFIG_KOR_MODEL_SHV_E120L)||defined (CONFIG_KOR_MODEL_SHV_E120S)||defined(CONFIG_KOR_MODEL_SHV_E120K)
	if(gpio_free_count != 0){
		 gpio_direction_input(SENSE_SCL);
		 gpio_direction_input(SENSE_SDA);
		 gpio_free(SENSE_SCL);
		 gpio_free(SENSE_SDA);
		 gpio_free_count = 0;
		}
	else{
		gpio_free_count =1;
		}
#endif

	return res;
}
Пример #2
0
static int akmd_resume(struct device *dev)
{
	int res = 0;
	struct akm8975_data *data = dev_get_drvdata(dev);

#if defined (CONFIG_KOR_MODEL_SHV_E120L)||defined (CONFIG_KOR_MODEL_SHV_E120S)||defined(CONFIG_KOR_MODEL_SHV_E120K)
	if(gpio_request_count == 0){
		gpio_request(SENSE_SCL,"SENSE_SCL");
		gpio_request(SENSE_SDA,"SENSE_SDA");
		gpio_request_count =1;
		}
	else{
		gpio_request_count = 0;
		}
#endif
	if(data->power_on)
		data->power_on();

	akm8975_ecs_set_mode_power_down(data);

	/* Wait at least 300us after changing mode. */
	udelay(300);

	return res;
}
Пример #3
0
static int akm8975_wait_for_data_ready(struct akm8975_data *akm)
{
	int data_ready = gpio_get_value_cansleep(PM8058_GPIO_PM_TO_SYS(akm->pdata->gpio_data_ready_int));
	int err;

	if (data_ready)
		return 0;

	enable_irq(akm->irq);

	err = wait_for_completion_timeout(&akm->data_ready, 5*HZ);
	if (err > 0)
		return 0;

	akm8975_disable_irq(akm);

	if (err == 0) {
		pr_err("akm: wait timed out\n");
		akm8975_ecs_set_mode_power_down(akm); /* It will be restart next time */
		
		/* Wait at least 300us after changing mode. */
		udelay(300);
//		return -ETIMEDOUT;
	}

	pr_err("akm: wait restart\n");
	return err;
}
Пример #4
0
static int akm8975_ecs_set_mode(struct akm8975_data *akm, char mode)
{
	s32 ret;

	switch (mode) {
	case AK8975_MODE_SNG_MEASURE:
		ret = i2c_smbus_write_byte_data(akm->this_client,
				AK8975_REG_CNTL, AK8975_MODE_SNG_MEASURE);
		break;
	case AK8975_MODE_FUSE_ACCESS:
		ret = i2c_smbus_write_byte_data(akm->this_client,
				AK8975_REG_CNTL, AK8975_MODE_FUSE_ACCESS);
		break;
	case AK8975_MODE_POWER_DOWN:
		ret = akm8975_ecs_set_mode_power_down(akm);
		break;
	case AK8975_MODE_SELF_TEST:
		ret = i2c_smbus_write_byte_data(akm->this_client,
				AK8975_REG_CNTL, AK8975_MODE_SELF_TEST);
		break;
	default:
		pr_err("%s: wrong mode(%d)\n", __func__, mode);
		return -EINVAL;
	}

	if (ret < 0) {
		pr_err("%s : i2c write failed, mode = %d\n", __func__, mode);
		return ret;
	}

	/* Wait at least 300us after changing mode. */
	udelay(300);

	return 0;
}
static int akm8975_suspend(struct device *dev)
{
	struct akm8975_data *akm = i2c_get_clientdata(this_client);
	akm8975_ecs_set_mode_power_down(akm);
	printk("\n akm8975_suspend+ \n");

  return 0;
}
Пример #6
0
static int akm8975_ecs_set_mode(struct akm8975_data *akm, char mode)
{
	s32 ret;
	
	switch (mode) {
	case AK8975_MODE_SNG_MEASURE:
		ret = i2c_smbus_write_byte_data(akm->this_client,
				AK8975_REG_CNTL, AK8975_MODE_SNG_MEASURE);
		if (ret < 0)
			pr_err("%s: fail to set AK8975_MODE_SNG_MEASURE ret=%d\n", __func__, ret);
		break;
	case AK8975_MODE_FUSE_ACCESS:
		ret = i2c_smbus_write_byte_data(akm->this_client,
				AK8975_REG_CNTL, AK8975_MODE_FUSE_ACCESS);
		if (ret < 0)
			pr_err("%s: fail to set AK8975_MODE_FUSE_ACCESS ret=%d\n", __func__, ret);
		else
			printk("%s: ak8975 set AK8975_MODE_FUSE_ACCESS\n", __func__);
		break;
	case AK8975_MODE_POWER_DOWN:
		ret = akm8975_ecs_set_mode_power_down(akm);
		if (ret < 0)
			pr_err("%s: fail to set AK8975_MODE_POWER_DOWN ret=%d\n", __func__, ret);
		else
			printk("%s: ak8975 set AK8975_MODE_POWER_DOWN\n", __func__);
		break;
	case AK8975_MODE_SELF_TEST:
		ret = i2c_smbus_write_byte_data(akm->this_client,
				AK8975_REG_CNTL, AK8975_MODE_SELF_TEST);
		if (ret < 0)
			pr_err("%s: fail to set AK8975_MODE_SELF_TEST ret=%d\n", __func__, ret);
		else
			printk("%s: ak8975 set AK8975_MODE_SELF_TEST\n", __func__);
		break;
	default:
		return -EINVAL;
	}

	if (ret < 0)
		return ret;

	/* Wait at least 300us after changing mode. */
	udelay(300);

	return 0;
}
Пример #7
0
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");
Пример #8
0
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;
}
Пример #9
0
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;
}