diff options
Diffstat (limited to 'drivers/staging/iio/accel/sca3000_core.c')
-rw-r--r-- | drivers/staging/iio/accel/sca3000_core.c | 955 |
1 files changed, 349 insertions, 606 deletions
diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 5b06dea6af25..f213b8698eb2 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -40,95 +40,74 @@ enum sca3000_variant { * do not actually appear to be available. */ static const struct sca3000_chip_info sca3000_spi_chip_info_tbl[] = { - { - .name = "sca3000-d01", - .scale = " 0.0073575", + [d01] = { + .scale = 7357, .temp_output = true, .measurement_mode_freq = 250, .option_mode_1 = SCA3000_OP_MODE_BYPASS, .option_mode_1_freq = 250, - }, { - .name = "sca3000-e02", - .scale = "0.00981", + .mot_det_mult_xz = {50, 100, 200, 350, 650, 1300}, + .mot_det_mult_y = {50, 100, 150, 250, 450, 850, 1750}, + }, + [e02] = { + .scale = 9810, .measurement_mode_freq = 125, .option_mode_1 = SCA3000_OP_MODE_NARROW, .option_mode_1_freq = 63, - }, { - .name = "sca3000-e04", - .scale = "0.01962", + .mot_det_mult_xz = {100, 150, 300, 550, 1050, 2050}, + .mot_det_mult_y = {50, 100, 200, 350, 700, 1350, 2700}, + }, + [e04] = { + .scale = 19620, .measurement_mode_freq = 100, .option_mode_1 = SCA3000_OP_MODE_NARROW, .option_mode_1_freq = 50, .option_mode_2 = SCA3000_OP_MODE_WIDE, .option_mode_2_freq = 400, - }, { - .name = "sca3000-e05", - .scale = "0.0613125", + .mot_det_mult_xz = {200, 300, 600, 1100, 2100, 4100}, + .mot_det_mult_y = {100, 200, 400, 7000, 1400, 2700, 54000}, + }, + [e05] = { + .scale = 61313, .measurement_mode_freq = 200, .option_mode_1 = SCA3000_OP_MODE_NARROW, .option_mode_1_freq = 50, .option_mode_2 = SCA3000_OP_MODE_WIDE, .option_mode_2_freq = 400, + .mot_det_mult_xz = {600, 900, 1700, 3200, 6100, 11900}, + .mot_det_mult_y = {300, 600, 1200, 2000, 4100, 7800, 15600}, }, }; - int sca3000_write_reg(struct sca3000_state *st, u8 address, u8 val) { - struct spi_transfer xfer = { - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .tx_buf = st->tx, - }; - struct spi_message msg; - st->tx[0] = SCA3000_WRITE_REG(address); st->tx[1] = val; - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - return spi_sync(st->us, &msg); + return spi_write(st->us, st->tx, 2); } -int sca3000_read_data(struct sca3000_state *st, - uint8_t reg_address_high, - u8 **rx_p, - int len) +int sca3000_read_data_short(struct sca3000_state *st, + uint8_t reg_address_high, + int len) { - int ret; struct spi_message msg; - struct spi_transfer xfer = { - .bits_per_word = 8, - .len = len + 1, - .cs_change = 1, - .tx_buf = st->tx, + struct spi_transfer xfer[2] = { + { + .len = 1, + .tx_buf = st->tx, + }, { + .len = len, + .rx_buf = st->rx, + } }; - - *rx_p = kmalloc(len + 1, GFP_KERNEL); - if (*rx_p == NULL) { - ret = -ENOMEM; - goto error_ret; - } - xfer.rx_buf = *rx_p; st->tx[0] = SCA3000_READ_REG(reg_address_high); spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - - ret = spi_sync(st->us, &msg); - - if (ret) { - dev_err(get_device(&st->us->dev), "problem reading register"); - goto error_free_rx; - } - - return 0; -error_free_rx: - kfree(*rx_p); -error_ret: - return ret; + spi_message_add_tail(&xfer[0], &msg); + spi_message_add_tail(&xfer[1], &msg); + return spi_sync(st->us, &msg); } + /** * sca3000_reg_lock_on() test if the ctrl register lock is on * @@ -136,17 +115,13 @@ error_ret: **/ static int sca3000_reg_lock_on(struct sca3000_state *st) { - u8 *rx; int ret; - ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1); - + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1); if (ret < 0) return ret; - ret = !(rx[1] & SCA3000_LOCKED); - kfree(rx); - return ret; + return !(st->rx[0] & SCA3000_LOCKED); } /** @@ -161,19 +136,15 @@ static int __sca3000_unlock_reg_lock(struct sca3000_state *st) struct spi_message msg; struct spi_transfer xfer[3] = { { - .bits_per_word = 8, .len = 2, .cs_change = 1, .tx_buf = st->tx, }, { - .bits_per_word = 8, .len = 2, .cs_change = 1, .tx_buf = st->tx + 2, }, { - .bits_per_word = 8, .len = 2, - .cs_change = 1, .tx_buf = st->tx + 4, }, }; @@ -236,8 +207,7 @@ error_ret: * Lock must be held. **/ static int sca3000_read_ctrl_reg(struct sca3000_state *st, - u8 ctrl_reg, - u8 **rx_p) + u8 ctrl_reg) { int ret; @@ -253,8 +223,11 @@ static int sca3000_read_ctrl_reg(struct sca3000_state *st, ret = sca3000_write_reg(st, SCA3000_REG_ADDR_CTRL_SEL, ctrl_reg); if (ret) goto error_ret; - ret = sca3000_read_data(st, SCA3000_REG_ADDR_CTRL_DATA, rx_p, 1); - + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_CTRL_DATA, 1); + if (ret) + goto error_ret; + else + return st->rx[0]; error_ret: return ret; } @@ -267,20 +240,18 @@ error_ret: **/ static int sca3000_check_status(struct device *dev) { - u8 *rx; int ret; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_STATUS, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_STATUS, 1); if (ret < 0) goto error_ret; - if (rx[1] & SCA3000_EEPROM_CS_ERROR) + if (st->rx[0] & SCA3000_EEPROM_CS_ERROR) dev_err(dev, "eeprom error\n"); - if (rx[1] & SCA3000_SPI_FRAME_ERROR) + if (st->rx[0] & SCA3000_SPI_FRAME_ERROR) dev_err(dev, "Previous SPI Frame was corrupt\n"); - kfree(rx); error_ret: mutex_unlock(&st->lock); @@ -288,53 +259,7 @@ error_ret: } #endif /* SCA3000_DEBUG */ -/** - * sca3000_read_13bit_signed() sysfs interface to read 13 bit signed registers - * - * These are described as signed 12 bit on the data sheet, which appears - * to be a conventional 2's complement 13 bit. - **/ -static ssize_t sca3000_read_13bit_signed(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int len = 0, ret; - int val; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - u8 *rx; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct sca3000_state *st = indio_dev->dev_data; - - mutex_lock(&st->lock); - ret = sca3000_read_data(st, this_attr->address, &rx, 2); - if (ret < 0) - goto error_ret; - val = sca3000_13bit_convert(rx[1], rx[2]); - len += sprintf(buf + len, "%d\n", val); - kfree(rx); -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} -static ssize_t sca3000_show_scale(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct sca3000_state *st = dev_info->dev_data; - return sprintf(buf, "%s\n", st->info->scale); -} - -static ssize_t sca3000_show_name(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *dev_info = dev_get_drvdata(dev); - struct sca3000_state *st = dev_info->dev_data; - return sprintf(buf, "%s\n", st->info->name); -} /** * sca3000_show_reg() - sysfs interface to read the chip revision number **/ @@ -346,18 +271,14 @@ static ssize_t sca3000_show_rev(struct device *dev, struct iio_dev *dev_info = dev_get_drvdata(dev); struct sca3000_state *st = dev_info->dev_data; - u8 *rx; - mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_REVID, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_REVID, 1); if (ret < 0) goto error_ret; len += sprintf(buf + len, "major=%d, minor=%d\n", - rx[1] & SCA3000_REVID_MAJOR_MASK, - rx[1] & SCA3000_REVID_MINOR_MASK); - kfree(rx); - + st->rx[0] & SCA3000_REVID_MAJOR_MASK, + st->rx[0] & SCA3000_REVID_MINOR_MASK); error_ret: mutex_unlock(&st->lock); @@ -410,15 +331,14 @@ sca3000_show_measurement_mode(struct device *dev, struct iio_dev *dev_info = dev_get_drvdata(dev); struct sca3000_state *st = dev_info->dev_data; int len = 0, ret; - u8 *rx; mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto error_ret; /* mask bottom 2 bits - only ones that are relevant */ - rx[1] &= 0x03; - switch (rx[1]) { + st->rx[0] &= 0x03; + switch (st->rx[0]) { case SCA3000_MEAS_MODE_NORMAL: len += sprintf(buf + len, "0 - normal mode\n"); break; @@ -462,7 +382,6 @@ sca3000_store_measurement_mode(struct device *dev, struct iio_dev *dev_info = dev_get_drvdata(dev); struct sca3000_state *st = dev_info->dev_data; int ret; - u8 *rx; int mask = 0x03; long val; @@ -470,20 +389,18 @@ sca3000_store_measurement_mode(struct device *dev, ret = strict_strtol(buf, 10, &val); if (ret) goto error_ret; - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto error_ret; - rx[1] &= ~mask; - rx[1] |= (val & mask); - ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, rx[1]); + st->rx[0] &= ~mask; + st->rx[0] |= (val & mask); + ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, st->rx[0]); if (ret) - goto error_free_rx; + goto error_ret; mutex_unlock(&st->lock); return len; -error_free_rx: - kfree(rx); error_ret: mutex_unlock(&st->lock); @@ -505,18 +422,70 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR, /* More standard attributes */ -static IIO_DEV_ATTR_NAME(sca3000_show_name); static IIO_DEV_ATTR_REV(sca3000_show_rev); -static IIO_DEVICE_ATTR(accel_scale, S_IRUGO, sca3000_show_scale, - NULL, 0); -static IIO_DEV_ATTR_ACCEL_X(sca3000_read_13bit_signed, - SCA3000_REG_ADDR_X_MSB); -static IIO_DEV_ATTR_ACCEL_Y(sca3000_read_13bit_signed, - SCA3000_REG_ADDR_Y_MSB); -static IIO_DEV_ATTR_ACCEL_Z(sca3000_read_13bit_signed, - SCA3000_REG_ADDR_Z_MSB); +#define SCA3000_INFO_MASK \ + (1 << IIO_CHAN_INFO_SCALE_SHARED) +#define SCA3000_EVENT_MASK \ + (IIO_EV_BIT(IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING)) + +static struct iio_chan_spec sca3000_channels[] = { + IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, SCA3000_INFO_MASK, + 0, 0, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), + IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, SCA3000_INFO_MASK, + 1, 1, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), + IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, SCA3000_INFO_MASK, + 2, 2, IIO_ST('s', 11, 16, 5), SCA3000_EVENT_MASK), +}; + +static u8 sca3000_addresses[3][3] = { + [0] = {SCA3000_REG_ADDR_X_MSB, SCA3000_REG_CTRL_SEL_MD_X_TH, + SCA3000_MD_CTRL_OR_X}, + [1] = {SCA3000_REG_ADDR_Y_MSB, SCA3000_REG_CTRL_SEL_MD_Y_TH, + SCA3000_MD_CTRL_OR_Y}, + [2] = {SCA3000_REG_ADDR_Z_MSB, SCA3000_REG_CTRL_SEL_MD_Z_TH, + SCA3000_MD_CTRL_OR_Z}, +}; +static int sca3000_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + struct sca3000_state *st = indio_dev->dev_data; + int ret; + u8 address; + + switch (mask) { + case 0: + mutex_lock(&st->lock); + if (st->mo_det_use_count) { + mutex_unlock(&st->lock); + return -EBUSY; + } + address = sca3000_addresses[chan->address][0]; + ret = sca3000_read_data_short(st, address, 2); + if (ret < 0) { + mutex_unlock(&st->lock); + return ret; + } + *val = (be16_to_cpup((__be16 *)st->rx) >> 3) & 0x1FFF; + *val = ((*val) << (sizeof(*val)*8 - 13)) >> + (sizeof(*val)*8 - 13); + mutex_unlock(&st->lock); + return IIO_VAL_INT; + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + *val = 0; + if (chan->type == IIO_ACCEL) + *val2 = st->info->scale; + else /* temperature */ + *val2 = 555556; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } +} /** * sca3000_read_av_freq() sysfs function to get available frequencies @@ -532,15 +501,16 @@ static ssize_t sca3000_read_av_freq(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; - int len = 0, ret; - u8 *rx; + int len = 0, ret, val; + mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); + val = st->rx[0]; mutex_unlock(&st->lock); if (ret) goto error_ret; - rx[1] &= 0x03; - switch (rx[1]) { + + switch (val & 0x03) { case SCA3000_MEAS_MODE_NORMAL: len += sprintf(buf + len, "%d %d %d\n", st->info->measurement_mode_freq, @@ -560,7 +530,6 @@ static ssize_t sca3000_read_av_freq(struct device *dev, st->info->option_mode_2_freq/4); break; } - kfree(rx); return len; error_ret: return ret; @@ -575,12 +544,11 @@ static inline int __sca3000_get_base_freq(struct sca3000_state *st, int *base_freq) { int ret; - u8 *rx; - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto error_ret; - switch (0x03 & rx[1]) { + switch (0x03 & st->rx[0]) { case SCA3000_MEAS_MODE_NORMAL: *base_freq = info->measurement_mode_freq; break; @@ -591,7 +559,6 @@ static inline int __sca3000_get_base_freq(struct sca3000_state *st, *base_freq = info->option_mode_2_freq; break; } - kfree(rx); error_ret: return ret; } @@ -605,18 +572,19 @@ static ssize_t sca3000_read_frequency(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; - int ret, len = 0, base_freq = 0; - u8 *rx; + int ret, len = 0, base_freq = 0, val; + mutex_lock(&st->lock); ret = __sca3000_get_base_freq(st, st->info, &base_freq); if (ret) goto error_ret_mut; - ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx); + ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL); mutex_unlock(&st->lock); if (ret) goto error_ret; + val = ret; if (base_freq > 0) - switch (rx[1]&0x03) { + switch (val & 0x03) { case 0x00: case 0x03: len = sprintf(buf, "%d\n", base_freq); @@ -628,7 +596,7 @@ static ssize_t sca3000_read_frequency(struct device *dev, len = sprintf(buf, "%d\n", base_freq/4); break; } - kfree(rx); + return len; error_ret_mut: mutex_unlock(&st->lock); @@ -647,7 +615,7 @@ static ssize_t sca3000_set_frequency(struct device *dev, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; int ret, base_freq = 0; - u8 *rx; + int ctrlval; long val; ret = strict_strtol(buf, 10, &val); @@ -660,21 +628,23 @@ static ssize_t sca3000_set_frequency(struct device *dev, if (ret) goto error_free_lock; - ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, &rx); - if (ret) + ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL); + if (ret < 0) goto error_free_lock; + ctrlval = ret; /* clear the bits */ - rx[1] &= ~0x03; + ctrlval &= ~0x03; if (val == base_freq/2) { - rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_2; + ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_2; } else if (val == base_freq/4) { - rx[1] |= SCA3000_OUT_CTRL_BUF_DIV_4; + ctrlval |= SCA3000_OUT_CTRL_BUF_DIV_4; } else if (val != base_freq) { ret = -EINVAL; goto error_free_lock; } - ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, rx[1]); + ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, + ctrlval); error_free_lock: mutex_unlock(&st->lock); @@ -704,17 +674,14 @@ static ssize_t sca3000_read_temp(struct device *dev, { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; - int len = 0, ret; + int ret; int val; - u8 *rx; - ret = sca3000_read_data(st, SCA3000_REG_ADDR_TEMP_MSB, &rx, 2); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_TEMP_MSB, 2); if (ret < 0) goto error_ret; - val = ((rx[1]&0x3F) << 3) | ((rx[2] & 0xE0) >> 5); - len += sprintf(buf + len, "%d\n", val); - kfree(rx); + val = ((st->rx[0] & 0x3F) << 3) | ((st->rx[1] & 0xE0) >> 5); - return len; + return sprintf(buf, "%d\n", val); error_ret: return ret; @@ -725,80 +692,71 @@ static IIO_CONST_ATTR_TEMP_SCALE("0.555556"); static IIO_CONST_ATTR_TEMP_OFFSET("-214.6"); /** - * sca3000_show_thresh() sysfs query of a threshold + * sca3000_read_thresh() - query of a threshold **/ -static ssize_t sca3000_show_thresh(struct device *dev, - struct device_attribute *attr, - char *buf) +static int sca3000_read_thresh(struct iio_dev *indio_dev, + int e, + int *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + int ret, i; struct sca3000_state *st = indio_dev->dev_data; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - int len = 0, ret; - u8 *rx; - + int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); mutex_lock(&st->lock); - ret = sca3000_read_ctrl_reg(st, - this_attr->address, - &rx); + ret = sca3000_read_ctrl_reg(st, sca3000_addresses[num][1]); mutex_unlock(&st->lock); - if (ret) + if (ret < 0) return ret; - len += sprintf(buf + len, "%d\n", rx[1]); - kfree(rx); + *val = 0; + if (num == 1) + for_each_set_bit(i, (unsigned long *)&ret, + ARRAY_SIZE(st->info->mot_det_mult_y)) + *val += st->info->mot_det_mult_y[i]; + else + for_each_set_bit(i, (unsigned long *)&ret, + ARRAY_SIZE(st->info->mot_det_mult_xz)) + *val += st->info->mot_det_mult_xz[i]; - return len; + return 0; } /** - * sca3000_write_thresh() sysfs control of threshold + * sca3000_write_thresh() control of threshold **/ -static ssize_t sca3000_write_thresh(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static int sca3000_write_thresh(struct iio_dev *indio_dev, + int e, + int val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); int ret; - long val; + int i; + u8 nonlinear = 0; + + if (num == 1) { + i = ARRAY_SIZE(st->info->mot_det_mult_y); + while (i > 0) + if (val >= st->info->mot_det_mult_y[--i]) { + nonlinear |= (1 << i); + val -= st->info->mot_det_mult_y[i]; + } + } else { + i = ARRAY_SIZE(st->info->mot_det_mult_xz); + while (i > 0) + if (val >= st->info->mot_det_mult_xz[--i]) { + nonlinear |= (1 << i); + val -= st->info->mot_det_mult_xz[i]; + } + } - ret = strict_strtol(buf, 10, &val); - if (ret) - return ret; mutex_lock(&st->lock); - ret = sca3000_write_ctrl_reg(st, this_attr->address, val); + ret = sca3000_write_ctrl_reg(st, sca3000_addresses[num][1], nonlinear); mutex_unlock(&st->lock); - return ret ? ret : len; + return ret; } -static IIO_DEVICE_ATTR(accel_x_raw_mag_rising_value, - S_IRUGO | S_IWUSR, - sca3000_show_thresh, - sca3000_write_thresh, - SCA3000_REG_CTRL_SEL_MD_X_TH); - -static IIO_DEVICE_ATTR(accel_y_raw_mag_rising_value, - S_IRUGO | S_IWUSR, - sca3000_show_thresh, - sca3000_write_thresh, - SCA3000_REG_CTRL_SEL_MD_Y_TH); - -static IIO_DEVICE_ATTR(accel_z_raw_mag_rising_value, - S_IRUGO | S_IWUSR, - sca3000_show_thresh, - sca3000_write_thresh, - SCA3000_REG_CTRL_SEL_MD_Z_TH); - static struct attribute *sca3000_attributes[] = { - &iio_dev_attr_name.dev_attr.attr, &iio_dev_attr_revision.dev_attr.attr, - &iio_dev_attr_accel_scale.dev_attr.attr, - &iio_dev_attr_accel_x_raw.dev_attr.attr, - &iio_dev_attr_accel_y_raw.dev_attr.attr, - &iio_dev_attr_accel_z_raw.dev_attr.attr, &iio_dev_attr_measurement_mode_available.dev_attr.attr, &iio_dev_attr_measurement_mode.dev_attr.attr, &iio_dev_attr_sampling_frequency_available.dev_attr.attr, @@ -807,12 +765,7 @@ static struct attribute *sca3000_attributes[] = { }; static struct attribute *sca3000_attributes_with_temp[] = { - &iio_dev_attr_name.dev_attr.attr, &iio_dev_attr_revision.dev_attr.attr, - &iio_dev_attr_accel_scale.dev_attr.attr, - &iio_dev_attr_accel_x_raw.dev_attr.attr, - &iio_dev_attr_accel_y_raw.dev_attr.attr, - &iio_dev_attr_accel_z_raw.dev_attr.attr, &iio_dev_attr_measurement_mode_available.dev_attr.attr, &iio_dev_attr_measurement_mode.dev_attr.attr, &iio_dev_attr_sampling_frequency_available.dev_attr.attr, @@ -836,134 +789,102 @@ static const struct attribute_group sca3000_attribute_group_with_temp = { /* depending on event, push to the ring buffer event chrdev or the event one */ /** - * sca3000_interrupt_handler_bh() - handling ring and non ring events + * sca3000_event_handler() - handling ring and non ring events * * This function is complicated by the fact that the devices can signify ring * and non ring events via the same interrupt line and they can only * be distinguished via a read of the relevant status register. **/ -static void sca3000_interrupt_handler_bh(struct work_struct *work_s) +static irqreturn_t sca3000_event_handler(int irq, void *private) { - struct sca3000_state *st - = container_of(work_s, struct sca3000_state, - interrupt_handler_ws); - u8 *rx; - int ret; + struct iio_dev *indio_dev = private; + struct sca3000_state *st; + int ret, val; + s64 last_timestamp = iio_get_time_ns(); + st = indio_dev->dev_data; /* Could lead if badly timed to an extra read of status reg, * but ensures no interrupt is missed. */ - enable_irq(st->us->irq); mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS, - &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1); + val = st->rx[0]; mutex_unlock(&st->lock); if (ret) goto done; - sca3000_ring_int_process(rx[1], st->indio_dev->ring); + sca3000_ring_int_process(val, st->indio_dev->ring); - if (rx[1] & SCA3000_INT_STATUS_FREE_FALL) + if (val & SCA3000_INT_STATUS_FREE_FALL) iio_push_event(st->indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_X_AND_Y_AND_Z, IIO_EV_TYPE_MAG, IIO_EV_DIR_FALLING), - st->last_timestamp); + last_timestamp); - if (rx[1] & SCA3000_INT_STATUS_Y_TRIGGER) + if (val & SCA3000_INT_STATUS_Y_TRIGGER) iio_push_event(st->indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_Y, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), - st->last_timestamp); + last_timestamp); - if (rx[1] & SCA3000_INT_STATUS_X_TRIGGER) + if (val & SCA3000_INT_STATUS_X_TRIGGER) iio_push_event(st->indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_X, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), - st->last_timestamp); + last_timestamp); - if (rx[1] & SCA3000_INT_STATUS_Z_TRIGGER) + if (val & SCA3000_INT_STATUS_Z_TRIGGER) iio_push_event(st->indio_dev, 0, IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, 0, IIO_EV_MOD_Z, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), - st->last_timestamp); + last_timestamp); done: - kfree(rx); - return; + return IRQ_HANDLED; } /** - * sca3000_handler_th() handles all interrupt events from device - * - * These devices deploy unified interrupt status registers meaning - * all interrupts must be handled together - **/ -static int sca3000_handler_th(struct iio_dev *dev_info, - int index, - s64 timestamp, - int no_test) -{ - struct sca3000_state *st = dev_info->dev_data; - - st->last_timestamp = timestamp; - schedule_work(&st->interrupt_handler_ws); - - return 0; -} - -/** - * sca3000_query_mo_det() is motion detection enabled for this axis - * - * First queries if motion detection is enabled and then if this axis is - * on. + * sca3000_read_event_config() what events are enabled **/ -static ssize_t sca3000_query_mo_det(struct device *dev, - struct device_attribute *attr, - char *buf) +static int sca3000_read_event_config(struct iio_dev *indio_dev, + int e) { - struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); struct sca3000_state *st = indio_dev->dev_data; - struct iio_event_attr *this_attr = to_iio_event_attr(attr); - int ret, len = 0; - u8 *rx; + int ret; u8 protect_mask = 0x03; + int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); /* read current value of mode register */ mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto error_ret; - if ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET) - len += sprintf(buf + len, "0\n"); + if ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET) + ret = 0; else { - kfree(rx); - ret = sca3000_read_ctrl_reg(st, - SCA3000_REG_CTRL_SEL_MD_CTRL, - &rx); - if (ret) + ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL); + if (ret < 0) goto error_ret; /* only supporting logical or's for now */ - len += sprintf(buf + len, "%d\n", - (rx[1] & this_attr->mask) ? 1 : 0); + ret = !!(ret & sca3000_addresses[num][2]); } - kfree(rx); error_ret: mutex_unlock(&st->lock); - return ret ? ret : len; + return ret; } /** * sca3000_query_free_fall_mode() is free fall mode enabled @@ -973,80 +894,20 @@ static ssize_t sca3000_query_free_fall_mode(struct device *dev, char *buf) { int ret, len; - u8 *rx; struct iio_dev *indio_dev = dev_get_drvdata(dev); struct sca3000_state *st = indio_dev->dev_data; + int val; mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); + val = st->rx[0]; mutex_unlock(&st->lock); - if (ret) + if (ret < 0) return ret; len = sprintf(buf, "%d\n", - !!(rx[1] & SCA3000_FREE_FALL_DETECT)); - kfree(rx); - - return len; -} -/** - * sca3000_query_ring_int() is the hardware ring status interrupt enabled - **/ -static ssize_t sca3000_query_ring_int(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_event_attr *this_attr = to_iio_event_attr(attr); - int ret, len; - u8 *rx; - struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); - struct sca3000_state *st = indio_dev->dev_data; - mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1); - mutex_unlock(&st->lock); - if (ret) - return ret; - len = sprintf(buf, "%d\n", (rx[1] & this_attr->mask) ? 1 : 0); - kfree(rx); - + !!(val & SCA3000_FREE_FALL_DETECT)); return len; } -/** - * sca3000_set_ring_int() set state of ring status interrupt - **/ -static ssize_t sca3000_set_ring_int(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); - struct sca3000_state *st = indio_dev->dev_data; - struct iio_event_attr *this_attr = to_iio_event_attr(attr); - - long val; - int ret; - u8 *rx; - - mutex_lock(&st->lock); - ret = strict_strtol(buf, 10, &val); - if (ret) - goto error_ret; - ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1); - if (ret) - goto error_ret; - if (val) - ret = sca3000_write_reg(st, - SCA3000_REG_ADDR_INT_MASK, - rx[1] | this_attr->mask); - else - ret = sca3000_write_reg(st, - SCA3000_REG_ADDR_INT_MASK, - rx[1] & ~this_attr->mask); - kfree(rx); -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} /** * sca3000_set_free_fall_mode() simple on off control for free fall int @@ -1065,7 +926,6 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev, struct sca3000_state *st = indio_dev->dev_data; long val; int ret; - u8 *rx; u8 protect_mask = SCA3000_FREE_FALL_DETECT; mutex_lock(&st->lock); @@ -1074,20 +934,18 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev, goto error_ret; /* read current value of mode register */ - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto error_ret; /*if off and should be on*/ - if (val && !(rx[1] & protect_mask)) + if (val && !(st->rx[0] & protect_mask)) ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - (rx[1] | SCA3000_FREE_FALL_DETECT)); + (st->rx[0] | SCA3000_FREE_FALL_DETECT)); /* if on and should be off */ - else if (!val && (rx[1]&protect_mask)) + else if (!val && (st->rx[0] & protect_mask)) ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - (rx[1] & ~protect_mask)); - - kfree(rx); + (st->rx[0] & ~protect_mask)); error_ret: mutex_unlock(&st->lock); @@ -1103,127 +961,77 @@ error_ret: * There is a complexity in knowing which mode to return to when * this mode is disabled. Currently normal mode is assumed. **/ -static ssize_t sca3000_set_mo_det(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static int sca3000_write_event_config(struct iio_dev *indio_dev, + int e, + int state) { - struct iio_dev *indio_dev = dev_get_drvdata(dev->parent); struct sca3000_state *st = indio_dev->dev_data; - struct iio_event_attr *this_attr = to_iio_event_attr(attr); - long val; - int ret; - u8 *rx; + int ret, ctrlval; u8 protect_mask = 0x03; - ret = strict_strtol(buf, 10, &val); - if (ret) - return ret; + int num = IIO_EVENT_CODE_EXTRACT_MODIFIER(e); mutex_lock(&st->lock); /* First read the motion detector config to find out if * this axis is on*/ - ret = sca3000_read_ctrl_reg(st, - SCA3000_REG_CTRL_SEL_MD_CTRL, - &rx); - if (ret) + ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL); + if (ret < 0) goto exit_point; + ctrlval = ret; /* Off and should be on */ - if (val && !(rx[1] & this_attr->mask)) { + if (state && !(ctrlval & sca3000_addresses[num][2])) { ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL, - rx[1] | this_attr->mask); + ctrlval | + sca3000_addresses[num][2]); if (ret) - goto exit_point_free_rx; + goto exit_point; st->mo_det_use_count++; - } else if (!val && (rx[1]&this_attr->mask)) { + } else if (!state && (ctrlval & sca3000_addresses[num][2])) { ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL, - rx[1] & ~(this_attr->mask)); + ctrlval & + ~(sca3000_addresses[num][2])); if (ret) - goto exit_point_free_rx; + goto exit_point; st->mo_det_use_count--; - } else /* relies on clean state for device on boot */ - goto exit_point_free_rx; - kfree(rx); + } + /* read current value of mode register */ - ret = sca3000_read_data(st, SCA3000_REG_ADDR_MODE, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto exit_point; /*if off and should be on*/ if ((st->mo_det_use_count) - && ((rx[1]&protect_mask) != SCA3000_MEAS_MODE_MOT_DET)) + && ((st->rx[0] & protect_mask) != SCA3000_MEAS_MODE_MOT_DET)) ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - (rx[1] & ~protect_mask) + (st->rx[0] & ~protect_mask) | SCA3000_MEAS_MODE_MOT_DET); /* if on and should be off */ else if (!(st->mo_det_use_count) - && ((rx[1]&protect_mask) == SCA3000_MEAS_MODE_MOT_DET)) + && ((st->rx[0] & protect_mask) == SCA3000_MEAS_MODE_MOT_DET)) ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - (rx[1] & ~protect_mask)); -exit_point_free_rx: - kfree(rx); + (st->rx[0] & ~protect_mask)); exit_point: mutex_unlock(&st->lock); - return ret ? ret : len; + return ret; } -/* Shared event handler for all events as single event status register */ -IIO_EVENT_SH(all, &sca3000_handler_th); - /* Free fall detector related event attribute */ -IIO_EVENT_ATTR_NAMED_SH(accel_xayaz_mag_falling_en, - accel_x&y&z_mag_falling_en, - iio_event_all, - sca3000_query_free_fall_mode, - sca3000_set_free_fall_mode, - 0); - -IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period, - accel_x&y&z_mag_falling_period, - "0.226"); - -/* Motion detector related event attributes */ -IIO_EVENT_ATTR_SH(accel_x_mag_rising_en, - iio_event_all, - sca3000_query_mo_det, - sca3000_set_mo_det, - SCA3000_MD_CTRL_OR_X); - -IIO_EVENT_ATTR_SH(accel_y_mag_rising_en, - iio_event_all, - sca3000_query_mo_det, - sca3000_set_mo_det, - SCA3000_MD_CTRL_OR_Y); - -IIO_EVENT_ATTR_SH(accel_z_mag_rising_en, - iio_event_all, - sca3000_query_mo_det, - sca3000_set_mo_det, - SCA3000_MD_CTRL_OR_Z); - -/* Hardware ring buffer related event attributes */ -IIO_EVENT_ATTR_RING_50_FULL_SH(iio_event_all, - sca3000_query_ring_int, - sca3000_set_ring_int, - SCA3000_INT_MASK_RING_HALF); - -IIO_EVENT_ATTR_RING_75_FULL_SH(iio_event_all, - sca3000_query_ring_int, - sca3000_set_ring_int, - SCA3000_INT_MASK_RING_THREE_QUARTER); +static IIO_DEVICE_ATTR_NAMED(accel_xayaz_mag_falling_en, + accel_x&y&z_mag_falling_en, + S_IRUGO | S_IWUSR, + sca3000_query_free_fall_mode, + sca3000_set_free_fall_mode, + 0); + +static IIO_CONST_ATTR_NAMED(accel_xayaz_mag_falling_period, + accel_x&y&z_mag_falling_period, + "0.226"); static struct attribute *sca3000_event_attributes[] = { - &iio_event_attr_accel_xayaz_mag_falling_en.dev_attr.attr, + &iio_dev_attr_accel_xayaz_mag_falling_en.dev_attr.attr, &iio_const_attr_accel_xayaz_mag_falling_period.dev_attr.attr, - &iio_event_attr_accel_x_mag_rising_en.dev_attr.attr, - &iio_dev_attr_accel_x_raw_mag_rising_value.dev_attr.attr, - &iio_event_attr_accel_y_mag_rising_en.dev_attr.attr, - &iio_dev_attr_accel_y_raw_mag_rising_value.dev_attr.attr, - &iio_event_attr_accel_z_mag_rising_en.dev_attr.attr, - &iio_dev_attr_accel_z_raw_mag_rising_value.dev_attr.attr, - &iio_event_attr_ring_50_full.dev_attr.attr, - &iio_event_attr_ring_75_full.dev_attr.attr, NULL, }; @@ -1241,70 +1049,50 @@ static struct attribute_group sca3000_event_attribute_group = { static int sca3000_clean_setup(struct sca3000_state *st) { int ret; - u8 *rx; mutex_lock(&st->lock); /* Ensure all interrupts have been acknowledged */ - ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_STATUS, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_STATUS, 1); if (ret) goto error_ret; - kfree(rx); /* Turn off all motion detection channels */ - ret = sca3000_read_ctrl_reg(st, - SCA3000_REG_CTRL_SEL_MD_CTRL, - &rx); - if (ret) + ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL); + if (ret < 0) goto error_ret; - ret = sca3000_write_ctrl_reg(st, - SCA3000_REG_CTRL_SEL_MD_CTRL, - rx[1] & SCA3000_MD_CTRL_PROT_MASK); - kfree(rx); + ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_MD_CTRL, + ret & SCA3000_MD_CTRL_PROT_MASK); if (ret) goto error_ret; /* Disable ring buffer */ - sca3000_read_ctrl_reg(st, - SCA3000_REG_CTRL_SEL_OUT_CTRL, - &rx); - /* Frequency of ring buffer sampling deliberately restricted to make - * debugging easier - add control of this later */ - ret = sca3000_write_ctrl_reg(st, - SCA3000_REG_CTRL_SEL_OUT_CTRL, - (rx[1] & SCA3000_OUT_CTRL_PROT_MASK) + ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL); + ret = sca3000_write_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL, + (ret & SCA3000_OUT_CTRL_PROT_MASK) | SCA3000_OUT_CTRL_BUF_X_EN | SCA3000_OUT_CTRL_BUF_Y_EN | SCA3000_OUT_CTRL_BUF_Z_EN | SCA3000_OUT_CTRL_BUF_DIV_4); - kfree(rx); - if (ret) goto error_ret; /* Enable interrupts, relevant to mode and set up as active low */ - ret = sca3000_read_data(st, - SCA3000_REG_ADDR_INT_MASK, - &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1); if (ret) goto error_ret; ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK, - (rx[1] & SCA3000_INT_MASK_PROT_MASK) + (ret & SCA3000_INT_MASK_PROT_MASK) | SCA3000_INT_MASK_ACTIVE_LOW); - kfree(rx); if (ret) goto error_ret; /* Select normal measurement mode, free fall off, ring off */ /* Ring in 12 bit mode - it is fine to overwrite reserved bits 3,5 * as that occurs in one of the example on the datasheet */ - ret = sca3000_read_data(st, - SCA3000_REG_ADDR_MODE, - &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); if (ret) goto error_ret; - ret = sca3000_write_reg(st, - SCA3000_REG_ADDR_MODE, - (rx[1] & SCA3000_MODE_PROT_MASK)); - kfree(rx); + ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, + (st->rx[0] & SCA3000_MODE_PROT_MASK)); st->bpse = 11; error_ret: @@ -1312,8 +1100,29 @@ error_ret: return ret; } -static int __devinit __sca3000_probe(struct spi_device *spi, - enum sca3000_variant variant) +static const struct iio_info sca3000_info = { + .attrs = &sca3000_attribute_group, + .read_raw = &sca3000_read_raw, + .num_interrupt_lines = 1, + .event_attrs = &sca3000_event_attribute_group, + .read_event_value = &sca3000_read_thresh, + .write_event_value = &sca3000_write_thresh, + .read_event_config = &sca3000_read_event_config, + .write_event_config = &sca3000_write_event_config, + .driver_module = THIS_MODULE, +}; + +static const struct iio_info sca3000_info_with_temp = { + .attrs = &sca3000_attribute_group_with_temp, + .read_raw = &sca3000_read_raw, + .read_event_value = &sca3000_read_thresh, + .write_event_value = &sca3000_write_thresh, + .read_event_config = &sca3000_read_event_config, + .write_event_config = &sca3000_write_event_config, + .driver_module = THIS_MODULE, +}; + +static int __devinit sca3000_probe(struct spi_device *spi) { int ret, regdone = 0; struct sca3000_state *st; @@ -1325,75 +1134,57 @@ static int __devinit __sca3000_probe(struct spi_device *spi, } spi_set_drvdata(spi, st); - st->tx = kmalloc(sizeof(*st->tx)*6, GFP_KERNEL); - if (st->tx == NULL) { - ret = -ENOMEM; - goto error_clear_st; - } - st->rx = kmalloc(sizeof(*st->rx)*3, GFP_KERNEL); - if (st->rx == NULL) { - ret = -ENOMEM; - goto error_free_tx; - } st->us = spi; mutex_init(&st->lock); - st->info = &sca3000_spi_chip_info_tbl[variant]; + st->info = &sca3000_spi_chip_info_tbl[spi_get_device_id(spi) + ->driver_data]; - st->indio_dev = iio_allocate_device(); + st->indio_dev = iio_allocate_device(0); if (st->indio_dev == NULL) { ret = -ENOMEM; - goto error_free_rx; + goto error_clear_st; } - st->indio_dev->dev.parent = &spi->dev; - st->indio_dev->num_interrupt_lines = 1; - st->indio_dev->event_attrs = &sca3000_event_attribute_group; + st->indio_dev->name = spi_get_device_id(spi)->name; if (st->info->temp_output) - st->indio_dev->attrs = &sca3000_attribute_group_with_temp; - else - st->indio_dev->attrs = &sca3000_attribute_group; + st->indio_dev->info = &sca3000_info_with_temp; + else { + st->indio_dev->info = &sca3000_info; + st->indio_dev->channels = sca3000_channels; + st->indio_dev->num_channels = ARRAY_SIZE(sca3000_channels); + } st->indio_dev->dev_data = (void *)(st); st->indio_dev->modes = INDIO_DIRECT_MODE; sca3000_configure_ring(st->indio_dev); - ret = iio_device_register(st->indio_dev); if (ret < 0) goto error_free_dev; regdone = 1; - ret = iio_ring_buffer_register(st->indio_dev->ring, 0); + ret = iio_ring_buffer_register_ex(st->indio_dev->ring, 0, + sca3000_channels, + ARRAY_SIZE(sca3000_channels)); if (ret < 0) goto error_unregister_dev; if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { - INIT_WORK(&st->interrupt_handler_ws, - sca3000_interrupt_handler_bh); - ret = iio_register_interrupt_line(spi->irq, - st->indio_dev, - 0, - IRQF_TRIGGER_FALLING, - "sca3000"); + ret = request_threaded_irq(spi->irq, + NULL, + &sca3000_event_handler, + IRQF_TRIGGER_FALLING, + "sca3000", + st->indio_dev); if (ret) goto error_unregister_ring; - /* RFC - * Probably a common situation. All interrupts need an ack - * and there is only one handler so the complicated list system - * is overkill. At very least a simpler registration method - * might be worthwhile. - */ - iio_add_event_to_list( - iio_event_attr_accel_z_mag_rising_en.listel, - &st->indio_dev - ->interrupts[0]->ev_list); } sca3000_register_ring_funcs(st->indio_dev); ret = sca3000_clean_setup(st); if (ret) - goto error_unregister_interrupt_line; + goto error_free_irq; return 0; -error_unregister_interrupt_line: +error_free_irq: if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(st->indio_dev, 0); + free_irq(spi->irq, st->indio_dev); error_unregister_ring: iio_ring_buffer_unregister(st->indio_dev->ring); error_unregister_dev: @@ -1402,10 +1193,6 @@ error_free_dev: iio_device_unregister(st->indio_dev); else iio_free_device(st->indio_dev); -error_free_rx: - kfree(st->rx); -error_free_tx: - kfree(st->tx); error_clear_st: kfree(st); error_ret: @@ -1415,20 +1202,19 @@ error_ret: static int sca3000_stop_all_interrupts(struct sca3000_state *st) { int ret; - u8 *rx; mutex_lock(&st->lock); - ret = sca3000_read_data(st, SCA3000_REG_ADDR_INT_MASK, &rx, 1); + ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1); if (ret) goto error_ret; ret = sca3000_write_reg(st, SCA3000_REG_ADDR_INT_MASK, - (rx[1] & ~(SCA3000_INT_MASK_RING_THREE_QUARTER - | SCA3000_INT_MASK_RING_HALF - | SCA3000_INT_MASK_ALL_INTS))); + (st->rx[0] & + ~(SCA3000_INT_MASK_RING_THREE_QUARTER | + SCA3000_INT_MASK_RING_HALF | + SCA3000_INT_MASK_ALL_INTS))); error_ret: - kfree(rx); + mutex_unlock(&st->lock); return ret; - } static int sca3000_remove(struct spi_device *spi) @@ -1441,87 +1227,44 @@ static int sca3000_remove(struct spi_device *spi) if (ret) return ret; if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) - iio_unregister_interrupt_line(indio_dev, 0); + free_irq(spi->irq, indio_dev); iio_ring_buffer_unregister(indio_dev->ring); sca3000_unconfigure_ring(indio_dev); iio_device_unregister(indio_dev); - kfree(st->tx); - kfree(st->rx); kfree(st); return 0; } -/* These macros save on an awful lot of repeated code */ -#define SCA3000_VARIANT_PROBE(_name) \ - static int __devinit \ - sca3000_##_name##_probe(struct spi_device *spi) \ - { \ - return __sca3000_probe(spi, _name); \ - } - -#define SCA3000_VARIANT_SPI_DRIVER(_name) \ - struct spi_driver sca3000_##_name##_driver = { \ - .driver = { \ - .name = "sca3000_" #_name, \ - .owner = THIS_MODULE, \ - }, \ - .probe = sca3000_##_name##_probe, \ - .remove = __devexit_p(sca3000_remove), \ - } - -SCA3000_VARIANT_PROBE(d01); -static SCA3000_VARIANT_SPI_DRIVER(d01); - -SCA3000_VARIANT_PROBE(e02); -static SCA3000_VARIANT_SPI_DRIVER(e02); - -SCA3000_VARIANT_PROBE(e04); -static SCA3000_VARIANT_SPI_DRIVER(e04); +static const struct spi_device_id sca3000_id[] = { + {"sca3000_d01", d01}, + {"sca3000_e02", e02}, + {"sca3000_e04", e04}, + {"sca3000_e05", e05}, + {} +}; -SCA3000_VARIANT_PROBE(e05); -static SCA3000_VARIANT_SPI_DRIVER(e05); +static struct spi_driver sca3000_driver = { + .driver = { + .name = "sca3000", + .owner = THIS_MODULE, + }, + .probe = sca3000_probe, + .remove = __devexit_p(sca3000_remove), + .id_table = sca3000_id, +}; static __init int sca3000_init(void) { - int ret; - - ret = spi_register_driver(&sca3000_d01_driver); - if (ret) - goto error_ret; - ret = spi_register_driver(&sca3000_e02_driver); - if (ret) - goto error_unreg_d01; - ret = spi_register_driver(&sca3000_e04_driver); - if (ret) - goto error_unreg_e02; - ret = spi_register_driver(&sca3000_e05_driver); - if (ret) - goto error_unreg_e04; - - return 0; - -error_unreg_e04: - spi_unregister_driver(&sca3000_e04_driver); -error_unreg_e02: - spi_unregister_driver(&sca3000_e02_driver); -error_unreg_d01: - spi_unregister_driver(&sca3000_d01_driver); -error_ret: - - return ret; + return spi_register_driver(&sca3000_driver); } +module_init(sca3000_init); static __exit void sca3000_exit(void) { - spi_unregister_driver(&sca3000_e05_driver); - spi_unregister_driver(&sca3000_e04_driver); - spi_unregister_driver(&sca3000_e02_driver); - spi_unregister_driver(&sca3000_d01_driver); + spi_unregister_driver(&sca3000_driver); } - -module_init(sca3000_init); module_exit(sca3000_exit); MODULE_AUTHOR("Jonathan Cameron <jic23@cam.ac.uk>"); |