Exemplo n.º 1
0
static ssize_t ak09911c_get_selftest(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int ret = 0, dac_ret, adc_ret;
	int sf_ret, sf[3] = {0,};
	struct ak09911c_v mag;
	struct ak09911c_p *data = dev_get_drvdata(dev);

	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_POWERDOWN);
		cancel_delayed_work_sync(&data->work);
	}

	sf_ret = ak09911c_selftest(data, &dac_ret, sf);

	adc_ret = ak09911c_read_mag_xyz(data, &mag);

	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_SNG_MEASURE);
		schedule_delayed_work(&data->work,
			nsecs_to_jiffies(atomic_read(&data->delay)));
	}

	ret = sf_ret + dac_ret + adc_ret;

	return snprintf(buf, PAGE_SIZE, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
			ret, sf_ret, sf[0], sf[1], sf[2], dac_ret,
			adc_ret, mag.x, mag.y, mag.z);
}
Exemplo n.º 2
0
static ssize_t ak09911c_get_selftest(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int status, dac_ret = -1, adc_ret = -1;
	int sf_ret, sf[3] = {0,}, retries;
	struct ak09911c_v mag;
	struct ak09911c_p *data = dev_get_drvdata(dev);

	/* STATUS */
	if ((data->asa[0] == 0) | (data->asa[0] == 0xff)
		| (data->asa[1] == 0) | (data->asa[1] == 0xff)
		| (data->asa[2] == 0) | (data->asa[2] == 0xff))
		status = -1;
	else
		status = 0;

	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_POWERDOWN);
		cancel_delayed_work_sync(&data->work);
	}

	sf_ret = ak09911c_selftest(data, &dac_ret, sf);

	for (retries = 0; retries < 5; retries++) {
		if (ak09911c_read_mag_xyz(data, &mag) == 0) {
			if ((mag.x < 1600) && (mag.x > -1600)
				&& (mag.y < 1600) && (mag.y > -1600)
				&& (mag.z < 1600) && (mag.z > -1600))
				adc_ret = 0;
			else
				pr_err("[SENSOR]: %s adc specout %d, %d, %d\n",
					__func__, mag.x, mag.y, mag.z);
			break;
		}

		msleep(20);
		pr_err("%s adc retries %d", __func__, retries);
	}

	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_SNG_MEASURE);
		schedule_delayed_work(&data->work,
			nsecs_to_jiffies(atomic_read(&data->delay)));
	}

	return snprintf(buf, PAGE_SIZE, "%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
			status, sf_ret, sf[0], sf[1], sf[2], dac_ret,
			adc_ret, mag.x, mag.y, mag.z);
}
static int ak09911c_read_mag_xyz(struct ak09911c_p *data,
		struct ak09911c_v *mag)
{
	u8 temp[SENSOR_DATA_SIZE] = {0, };
	int ret = 0, retries = 0;

	mutex_lock(&data->lock);
	ret = ak09911c_ecs_set_mode(data, AK09911C_MODE_SNG_MEASURE);
	if (ret < 0)
		goto exit_i2c_read_err;

again:
	ret = ak09911c_i2c_read(data->client, AK09911C_REG_ST1, &temp[0]);
	if (ret < 0)
		goto exit_i2c_read_err;

	/* Check ST bit */
	if (!(temp[0] & 0x01)) {
		if ((retries++ < 5) && (temp[0] == 0)) {
#if !defined(CONFIG_SEC_BERLUTI_PROJECT)
			mdelay(2);
#endif
			goto again;
		} else {
			ret = -EAGAIN;
			goto exit_i2c_read_fail;
		}
	}

	ret = ak09911c_i2c_read_block(data->client, AK09911C_REG_ST1 + 1,
			&temp[1], SENSOR_DATA_SIZE - 1);
	if (ret < 0)
		goto exit_i2c_read_err;
#if 0
	/* Check ST2 bit */
	if ((temp[8] & 0x08)) {
		ret = -EAGAIN;
		goto exit_i2c_read_fail;
	}
#endif
	mag->x = temp[1] | (temp[2] << 8);
	mag->y = temp[3] | (temp[4] << 8);
	mag->z = temp[5] | (temp[6] << 8);

	remap_sensor_data(mag->v, data->chip_pos);

	goto exit;

exit_i2c_read_fail:
exit_i2c_read_err:
	pr_err("[SENSOR]: %s - ST1 = %u, ST2 = %u\n",
		__func__, temp[0], temp[8]);
exit:
	mutex_unlock(&data->lock);
	return ret;
}
Exemplo n.º 4
0
static void ak09911c_shutdown(struct i2c_client *client)
{
	struct ak09911c_p *data = i2c_get_clientdata(client);

	pr_info("%s\n", __func__);
	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_POWERDOWN);
		cancel_delayed_work_sync(&data->work);
	}
}
Exemplo n.º 5
0
static void ak09911c_set_enable(struct ak09911c_p *data, int enable)
{
	int pre_enable = atomic_read(&data->enable);

	if (enable) {
		if (pre_enable == 0) {
			ak09911c_ecs_set_mode(data, AK09911C_MODE_SNG_MEASURE);
			schedule_delayed_work(&data->work,
				nsecs_to_jiffies(atomic_read(&data->delay)));
			atomic_set(&data->enable, 1);
		}
	} else {
		if (pre_enable == 1) {
			ak09911c_ecs_set_mode(data, AK09911C_MODE_POWERDOWN);
			cancel_delayed_work_sync(&data->work);
			atomic_set(&data->enable, 0);
		}
	}
}
Exemplo n.º 6
0
static int ak09911c_read_mag_xyz(struct ak09911c_p *data,
	struct ak09911c_v *mag)
{
	u8 temp[SENSOR_DATA_SIZE] = {0, };
	int ret = 0, retries = 0;

	mutex_lock(&data->lock);
	ret = ak09911c_ecs_set_mode(data, AK09911C_MODE_SNG_MEASURE);
	if (ret < 0)
		goto exit_i2c_read_err;

retry:
	ret = ak09911c_smbus_read_byte(data->client,
			AK09911C_REG_ST1, &temp[0]);
	if (ret < 0)
		goto exit_i2c_read_err;

	/* Check ST bit */
	if (!(temp[0] & 0x01)) {
		if ((retries++ < 5) && (temp[0] == 0)) {
			mdelay(2);
			goto retry;
		} else {
			ret = -EAGAIN;
			goto exit_i2c_read_fail;
		}
	}

	ret = ak09911c_smbus_read_byte_block(data->client, AK09911C_REG_ST1 + 1,
			&temp[1], SENSOR_DATA_SIZE - 1);
	if (ret < 0)
		goto exit_i2c_read_err;

	/* Check ST2 bit */
	if ((temp[8] & 0x01)) {
		ret = -EAGAIN;
		goto exit_i2c_read_fail;
	}

	mag->x = temp[1] | (temp[2] << 8);
	mag->y = temp[3] | (temp[4] << 8);
	mag->z = temp[5] | (temp[6] << 8);

	remap_sensor_data(mag->v, data->pdata->chip_pos);

	goto exit;

exit_i2c_read_fail:
exit_i2c_read_err:
	pr_err("%s failed. ret = %d, ST1 = %u, ST2 = %u\n",
			__func__, ret, temp[0], temp[8]);
exit:
	mutex_unlock(&data->lock);
	return ret;
}
Exemplo n.º 7
0
static int ak09911c_suspend(struct device *dev)
{
	struct ak09911c_p *data = dev_get_drvdata(dev);

	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_POWERDOWN);
		cancel_delayed_work_sync(&data->work);
	}

	return 0;
}
Exemplo n.º 8
0
static int ak09911c_resume(struct device *dev)
{
	struct ak09911c_p *data = dev_get_drvdata(dev);

	if (atomic_read(&data->enable) == 1) {
		ak09911c_ecs_set_mode(data, AK09911C_MODE_SNG_MEASURE);
		schedule_delayed_work(&data->work,
		nsecs_to_jiffies(atomic_read(&data->delay)));
	}

	return 0;
}