static ssize_t akmd_read(struct file *file, char __user *buf, size_t count, loff_t *pos) { struct akm8975_data *akm = container_of(file->private_data, struct akm8975_data, akmd_device); short x = 0, y = 0, z = 0; #if defined (CONFIG_EUR_MODEL_GT_I9210) short tmp = 0; #endif int ret; u8 data[8]; mutex_lock(&akm->lock); ret = akm8975_ecs_set_mode(akm, AK8975_MODE_SNG_MEASURE); if (ret) { mutex_unlock(&akm->lock); goto done; } ret = akm8975_wait_for_data_ready(akm); if (ret) { mutex_unlock(&akm->lock); goto done; } ret = i2c_smbus_read_i2c_block_data(akm->this_client, AK8975_REG_ST1, sizeof(data), data); mutex_unlock(&akm->lock); if (ret != sizeof(data)) { pr_err("%s: failed to read %d bytes of mag data\n", __func__, sizeof(data)); goto done; } if (data[0] & 0x01) { x = (data[2] << 8) + data[1]; y = (data[4] << 8) + data[3]; z = (data[6] << 8) + data[5]; #if defined (CONFIG_EUR_MODEL_GT_I9210) if (get_hw_rev() >= 6 ) { tmp = x; x = y; y = tmp; } #endif } else pr_err("%s: invalid raw data(st1 = %d)\n", __func__, data[0] & 0x01); done: return sprintf(buf, "%d,%d,%d\n", x, y, z); }
static ssize_t ak8975_adc(struct device *dev, struct device_attribute *attr, char *strbuf) { struct akm8975_data *ak_data = dev_get_drvdata(dev); u8 buf[8]; s16 x, y, z; int err, success; printk("ak8975_adc\n"); mutex_lock(&ak_data->lock); /* start ADC conversion */ err = i2c_smbus_write_byte_data(ak_data->this_client, AK8975_REG_CNTL, REG_CNTL_MODE_ONCE); printk("ak8975_adc write err:%d\n", err); /* wait for ADC conversion to complete */ err = akm8975_wait_for_data_ready(ak_data); if (err) { pr_err("%s: wait for data ready failed\n", __func__); return; } msleep(10); /* get the value and report it */ err = i2c_smbus_read_i2c_block_data(ak_data->this_client, AK8975_REG_ST1, sizeof(buf), buf); //printk("ak8975_adc read err:%d\n", err); if (err != sizeof(buf)) { pr_err("%s: read data over i2c failed\n", __func__); return; } mutex_unlock(&ak_data->lock); /* buf[0] is status1, buf[7] is status2 */ if ((buf[0] == 0) | (buf[7] == 1)) success = 0; else success = 1; x = buf[1] | (buf[2] << 8); y = buf[3] | (buf[4] << 8); z = buf[5] | (buf[6] << 8); pr_info("%s: raw x = %d, y = %d, z = %d\n", __func__, x, y, z); return sprintf(strbuf, "%s, %d, %d, %d\n", (success ? "OK" : "NG"), x, y, z); }
/* sysfs for logging Power line noise */ static ssize_t akm8975_rawdata_show(struct device *dev, struct device_attribute *attr, char *buf) { struct akm8975_data *akm = dev_get_drvdata(dev); short x = 0, y = 0, z = 0; int ret; u8 data[8]; mutex_lock(&akm->lock); ret = akm8975_ecs_set_mode(akm, AK8975_MODE_SNG_MEASURE); if (ret) { mutex_unlock(&akm->lock); goto done; } ret = akm8975_wait_for_data_ready(akm); if (ret) { mutex_unlock(&akm->lock); goto done; } ret = i2c_smbus_read_i2c_block_data(akm->this_client, AK8975_REG_ST1, sizeof(data), data); mutex_unlock(&akm->lock); if (ret != sizeof(data)) { pr_err("%s: failed to read %d bytes of mag data\n", __func__, sizeof(data)); goto done; } if (data[0] & 0x01) { x = (data[2] << 8) + data[1]; y = (data[4] << 8) + data[3]; z = (data[6] << 8) + data[5]; } else pr_err("%s: invalid raw data(st1 = %d)\n", __func__, data[0] & 0x01); done: return sprintf(buf, "%d,%d,%d\n", x, y, z); }
static long akmd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; struct akm8975_data *akm = container_of(file->private_data, struct akm8975_data, akmd_device); int ret; union { char raw[RWBUF_SIZE]; int status; char mode; u8 data[8]; } rwbuf; ret = akmd_copy_in(cmd, argp, rwbuf.raw, sizeof(rwbuf)); if (ret) return ret; switch (cmd) { case ECS_IOCTL_WRITE: if ((rwbuf.raw[0] < 2) || (rwbuf.raw[0] > (RWBUF_SIZE - 1))) return -EINVAL; if (copy_from_user(&rwbuf.raw[2], argp+2, rwbuf.raw[0]-1)) return -EFAULT; ret = i2c_smbus_write_i2c_block_data(akm->this_client, rwbuf.raw[1], rwbuf.raw[0] - 1, &rwbuf.raw[2]); break; case ECS_IOCTL_READ: if ((rwbuf.raw[0] < 1) || (rwbuf.raw[0] > (RWBUF_SIZE - 1))) return -EINVAL; ret = i2c_smbus_read_i2c_block_data(akm->this_client, rwbuf.raw[1], rwbuf.raw[0], &rwbuf.raw[1]); if (ret < 0) return ret; if (copy_to_user(argp+1, rwbuf.raw+1, rwbuf.raw[0])) return -EFAULT; return 0; case ECS_IOCTL_SET_MODE: mutex_lock(&akm->lock); ret = akm8975_ecs_set_mode(akm, rwbuf.mode); mutex_unlock(&akm->lock); break; case ECS_IOCTL_GETDATA: mutex_lock(&akm->lock); ret = akm8975_wait_for_data_ready(akm); if (ret) { mutex_unlock(&akm->lock); return ret; } ret = i2c_smbus_read_i2c_block_data(akm->this_client, AK8975_REG_ST1, sizeof(rwbuf.data), rwbuf.data); mutex_unlock(&akm->lock); if (ret != sizeof(rwbuf.data)) { pr_err("%s : failed to read %d bytes of mag data\n", __func__, sizeof(rwbuf.data)); return -EIO; } break; default: return -ENOTTY; } if (ret < 0) return ret; return akmd_copy_out(cmd, argp, rwbuf.raw, sizeof(rwbuf)); }