static ssize_t ak09911c_adc(struct device *dev, struct device_attribute *attr, char *buf) { bool success = false; int ret; struct ak09911c_p *data = dev_get_drvdata(dev); struct ak09911c_v mag = data->magdata; if (atomic_read(&data->enable) == 1) { success = true; msleep(20); goto exit; } ret = ak09911c_read_mag_xyz(data, &mag); if (ret < 0) success = false; else success = true; data->magdata = mag; exit: return snprintf(buf, PAGE_SIZE, "%s,%d,%d,%d\n", (success ? "OK" : "NG"), mag.x, mag.y, mag.z); }
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); }
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 ssize_t ak09911c_raw_data_read(struct device *dev, struct device_attribute *attr, char *buf) { struct ak09911c_p *data = dev_get_drvdata(dev); struct ak09911c_v mag = data->magdata; if (atomic_read(&data->enable) == 1) { msleep(20); goto exit; } ak09911c_read_mag_xyz(data, &mag); exit: return snprintf(buf, PAGE_SIZE, "%d,%d,%d\n", mag.x, mag.y, mag.z); }
static void ak09911c_work_func(struct work_struct *work) { struct ak09911c_v mag; struct ak09911c_p *data = container_of((struct delayed_work *)work, struct ak09911c_p, work); unsigned long delay = nsecs_to_jiffies(atomic_read(&data->delay)); int ret; ret = ak09911c_read_mag_xyz(data, &mag); if (ret >= 0) { input_report_rel(data->input, REL_X, mag.x); input_report_rel(data->input, REL_Y, mag.y); input_report_rel(data->input, REL_Z, mag.z); input_sync(data->input); data->magdata = mag; } schedule_delayed_work(&data->work, delay); }